#include "defs.h"
#include "gdb_string.h"
#include "kod.h"
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#define PBUFSIZ 400
static void (*gdb_kod_display) (char *);
static void (*gdb_kod_query) (char *, char *, int *);
char *
cisco_kod_open (kod_display_callback_ftype *display_func,
kod_query_callback_ftype *query_func)
{
char buffer[PBUFSIZ];
int bufsiz = PBUFSIZ;
int i, count;
gdb_kod_display = display_func;
gdb_kod_query = query_func;
#ifndef FAKE_PACKET
(*gdb_kod_query) ("oI;", buffer, &bufsiz);
#else
strcpy (buffer, "Cisco IOS/Classic/13.4 0.0.0");
#endif
count = 2;
for (i = 0; count && buffer[i] != '\0'; ++i)
{
if (buffer[i] == ' ')
--count;
}
if (buffer[i] == '\0')
error (_("Remote returned malformed packet."));
if (strcmp (&buffer[i], "0.0.0"))
error (_("Remote returned unknown stub version: %s."), &buffer[i]);
return (xstrdup ("gdbkodcisco v0.0.0 - Cisco Kernel Object Display"));
}
void
cisco_kod_close (void)
{
}
static void
bad_packet (void)
{
(*gdb_kod_display) ("Remote target returned malformed packet.\n");
}
void
cisco_kod_request (char *arg, int from_tty)
{
char buffer[PBUFSIZ], command[PBUFSIZ];
int done = 0, i;
int fail = 0;
char **sync_ids = NULL;
int sync_len = 0;
int sync_next = 0;
char *prev_id = NULL;
if (! arg || strcmp (arg, "any"))
{
(*gdb_kod_display) ("List of Cisco Kernel Objects\n");
(*gdb_kod_display) ("Object\tDescription\n");
(*gdb_kod_display) ("any\tAny and all objects\n");
return;
}
while (! done)
{
int off = 0;
long count;
int bufsiz = PBUFSIZ;
char *s_end;
strcpy (command, "aL");
if (prev_id)
{
strcat (command, ",");
strcat (command, prev_id);
}
strcat (command, ";");
#ifndef FAKE_PACKET
(*gdb_kod_query) (command, buffer, &bufsiz);
#else
if (! strncmp (&command[3], "a500005a", 8))
strcpy (buffer, "KAL,01,1,f500005f;f500005f;");
else
strcpy (buffer, "KAL,02,0,a500005a;a500005a;de02869f;");
#endif
if (strlen (buffer) == 0)
{
(*gdb_kod_display) ("Remote target did not recognize kernel object query command.\n");
fail = 1;
break;
}
if (buffer[0] != 'K')
{
(*gdb_kod_display) (buffer);
fail = 1;
break;
}
if (strncmp (buffer, "KAL,", 4))
{
bad_packet ();
fail = 1;
break;
}
off += 4;
count = strtol (&buffer[off], &s_end, 16);
if (s_end - &buffer[off] != 2 || buffer[off + 2] != ',')
{
bad_packet ();
fail = 1;
break;
}
off += 3;
if ((buffer[off] != '0' && buffer[off] != '1')
|| buffer[off + 1] != ',')
{
bad_packet ();
fail = 1;
break;
}
done = buffer[off] == '1';
off += 2;
prev_id = &buffer[off];
if (strlen (prev_id) < 8 || buffer[off + 8] != ';')
{
bad_packet ();
fail = 1;
break;
}
buffer[off + 8] = '\0';
off += 9;
sync_len += count;
sync_ids = (char **) xrealloc (sync_ids, sync_len * sizeof (char *));
for (i = 0; i < count; ++i)
{
if (strlen (&buffer[off]) < 8 || buffer[off + 8] != ';')
{
bad_packet ();
fail = 1;
break;
}
buffer[off + 8] = '\0';
sync_ids[sync_next++] = xstrdup (&buffer[off]);
off += 9;
}
if (buffer[off] != '\0')
{
bad_packet ();
fail = 1;
break;
}
}
if (! fail)
{
(*gdb_kod_display) ("Object ID\tObject Pointer\tThread ID\n");
for (i = 0; i < sync_next; ++i)
{
int off = 0;
int bufsiz = PBUFSIZ;
strcpy (command, "aI,");
strcat (command, sync_ids[i]);
strcat (command, ";");
#ifndef FAKE_PACKET
(*gdb_kod_query) (command, buffer, &bufsiz);
#else
strcpy (buffer, "KAI,");
strcat (buffer, sync_ids[i]);
strcat (buffer, ",ffef00a0,cd00123d;");
#endif
if (strlen (buffer) == 0)
{
(*gdb_kod_display) ("Remote target did not recognize KOD command.\n");
break;
}
if (strncmp (buffer, "KAI,", 4))
{
bad_packet ();
break;
}
off += 4;
if (strncmp (&buffer[off], sync_ids[i], 8)
|| buffer[off + 8] != ',')
{
bad_packet ();
break;
}
off += 9;
if (strlen (&buffer[off]) != 2 * 8 + 2
|| buffer[off + 8] != ','
|| buffer[off + 17] != ';')
{
bad_packet ();
break;
}
buffer[off + 8] = '\0';
buffer[off + 17] = '\0';
(*gdb_kod_display) (sync_ids[i]);
(*gdb_kod_display) ("\t");
(*gdb_kod_display) (&buffer[off]);
(*gdb_kod_display) ("\t");
(*gdb_kod_display) (&buffer[off + 9]);
(*gdb_kod_display) ("\n");
}
}
for (i = 0; i < sync_next; ++i)
xfree (sync_ids[i]);
xfree (sync_ids);
}