📄 pcdbug.c
字号:
else if (strstr(value,"NONE"))
memset (&filter, 0, sizeof(filter));
else
{
filter.MAC = (strstr(value,"ETH" ) != NULL) || (strstr(value,"MAC") != NULL);
filter.ARP = (strstr(value,"ARP" ) != NULL);
filter.RARP = (strstr(value,"RARP") != NULL);
filter.IP = (strstr(value,"IP" ) != NULL);
filter.BCAST = (strstr(value,"BCAST") != NULL);
}
}
static void set_debug_proto (const char *value)
{
if (!strcmp(value,"ALL"))
memset (&debug, 1, sizeof(debug));
else
{
memset (&debug, 0, sizeof(debug));
debug.MAC = (strstr(value,"ETH" ) != NULL) || (strstr(value,"MAC") != NULL);
debug.ARP = (strstr(value,"ARP" ) != NULL);
debug.RARP = (strstr(value,"RARP") != NULL);
debug.IP = (strstr(value,"IP" ) != NULL);
debug.TCP = (strstr(value,"TCP" ) != NULL);
debug.UDP = (strstr(value,"UDP" ) != NULL);
debug.ICMP = (strstr(value,"ICMP") != NULL);
debug.IGMP = (strstr(value,"IGMP") != NULL);
}
}
static void ourinit (const char *name, const char *value)
{
static struct config_table debug_cfg[] = {
{ "FILE", ARG_FUNC, (void*)set_debug_file },
{ "MODE", ARG_FUNC, (void*)set_debug_mode },
{ "FILTER", ARG_FUNC, (void*)set_debug_filter },
{ "PROTO", ARG_FUNC, (void*)set_debug_proto },
{ "STAT", ARG_ATOI, (void*)&dbg_print_stat },
{ "DNS", ARG_ATOI, (void*)&dbg_dns_details },
{ "RTP", ARG_ATOI, (void*)&dbg_rtp_details },
{ NULL }
};
char val[80];
strncpy (val, value, sizeof(val)-1);
val [sizeof(val)-1] = '\0';
strupr (val);
if (!parse_config_table(&debug_cfg[0], "DEBUG.", name, val) && prev_hook)
(*prev_hook) (name, value);
}
#define CHECK_TRUNCATED() \
do { \
if (op > op_max - 12) { \
strncpy (op,"\r\n<more>\r\n\r\n",12); \
op += 12; \
} \
} while (0)
static int db_fprintf (const char *format, ...)
{
int len = 0;
if (handle > 0 && op < op_max)
{
va_list arg;
va_start (arg, format);
#if defined(__HIGHC__) || defined(__WATCOMC__)
len = _vbprintf (op, op_max-op-1, format, arg);
if (len < 0)
{
op = op_max;
len = abs (len);
}
else
op += len;
#else
len = vsprintf (op, format, arg);
op += len;
#endif
va_end (arg);
CHECK_TRUNCATED();
}
return (len);
}
void dbug_write_raw (const char *buf)
{
if (handle > 0)
write (handle, buf, strlen(buf));
}
static void db_flush (void)
{
if (handle > 0 && op > op_min)
write (handle, op_min, op - op_min);
op = op_min;
}
static int db_write (const char *buf)
{
int len = strlen (buf);
if (op+len < op_max)
{
memcpy (op, buf, len);
op += len;
CHECK_TRUNCATED();
}
return (len);
}
static void db_putc (int ch)
{
if (op+2 < op_max)
{
if (ch == '\n')
*op++ = '\r';
*op++ = ch;
}
}
/*
* Public initialisation
*/
void dbug_init (void)
{
prev_hook = usr_init;
usr_init = ourinit;
_dbugxmit = dbg_send;
_dbugrecv = dbg_recv;
#if defined(USE_BSD_FUNC)
{
extern void _sock_dbug_init (void); /* in bsddbug.c */
_sock_dbug_init();
}
#endif
/* Give user a warning
*/
if (_watt_is_init)
{
fprintf (stderr, "`dbug_init()' called after `sock_init()'.\n");
sleep (1);
}
}
static void dbg_dump_stats (void)
{
#if defined(USE_STATISTICS)
int (*_save_printf) (const char *fmt,...) = _printf;
char buf [STK_BUF_SIZE];
op = buf;
op_min = buf;
op_max = buf + STK_BUF_SIZE - 60;
_printf = db_fprintf;
print_all_stats();
db_flush();
_printf = _save_printf;
#endif
}
#else /* USE_DEBUG */
void dbug_init (void)
{
outsnl ("Debug-mode disabled");
}
#endif
/*
* dbug_exit - Print statistics counters to debug-file.
*
* Should not be called from atexit() function, because order is unspecified.
* Called from tcp_shutdown() after DHCP_release() and tcp_abort() but
* before _eth_release() is called. pkt-drop counters are not available
* once _eth_release() has been called.
*/
void dbug_exit (void)
{
#if defined(USE_DEBUG)
if (handle > 0)
{
if (!_watt_fatal_error && dbg_print_stat)
dbg_dump_stats();
close (handle);
handle = -1;
}
#endif /* USE_DEBUG */
}
#if defined(USE_DEBUG) && (DEBUG_DNS)
/*
* Debug of DNS (udp) records
*
* Author: Mike Borella <mike_borella@mw.3com.com>
*
* Changed for WatTCP and pcdbug.c by G.Vanem 1998 <giva@bgnett.no>
*
* !! to-do: parse the SRV resource record (RFC 2052)
*/
struct DNSHdr {
WORD dns_id;
WORD dns_fl_rcode : 4;
WORD dns_fl_zero : 3;
WORD dns_fl_ra : 1;
WORD dns_fl_rd : 1;
WORD dns_fl_tc : 1;
WORD dns_fl_aa : 1;
WORD dns_fl_opcode: 4;
WORD dns_fl_qr : 1;
WORD dns_num_q;
WORD dns_num_ans;
WORD dns_num_auth;
WORD dns_num_add;
};
static char *dns_opcodes[] = {
"standard", "inverse", "server status"
};
static char *dns_responses[] = {
"no error", "format error", "server error",
"name error", "not implemented", "service refused"
};
/*
* dns_query()
*
* Return a string describing the numeric value of a DNS query type
*/
#if defined(USE_BIND)
#define dns_query(type) __p_type(type)
#else
static __inline char *dns_query (WORD type)
{
switch (type)
{
case T_A: return ("A");
case T_NS: return ("NS");
case T_CNAME: return ("CNAME");
case T_PTR: return ("PTR");
case T_HINFO: return ("HINFO");
case T_MX: return ("MX");
case T_AXFR: return ("AXFR");
case T_ANY: return ("ANY");
default: return ("??");
}
}
#endif
/*
* dns_dump()
*
* Parse DNS packet and dump fields
*/
static void dns_dump (const BYTE *bp, unsigned length)
{
struct DNSHdr *dns = (struct DNSHdr*) bp;
BYTE *p = (BYTE*)bp + sizeof(*dns);
BYTE *ep = (BYTE*)bp + length;
char *oc = dns->dns_fl_opcode < DIM(dns_opcodes) ?
dns_opcodes [dns->dns_fl_opcode] : NULL;
char *ra = dns->dns_fl_rcode < DIM(dns_responses) ?
dns_responses [dns->dns_fl_rcode] : NULL;
int i, t;
db_fprintf ("DNS: Ident %u, %s, Opcode: %s\r\n",
intel16(dns->dns_id), dns->dns_fl_qr ? "Response" : "Query",
oc ? oc : "??");
db_fprintf (" auth answer %d, truncated %d, rec-req %d, rec-avail %d,"
" zero %d, %s\r\n",
dns->dns_fl_aa, dns->dns_fl_tc, dns->dns_fl_rd, dns->dns_fl_ra,
dns->dns_fl_zero, ra ? ra : "??");
if (!op || !ra)
{
db_write (" Looks like a bogus packet\r\n");
return;
}
/* Do the question part of the packet.
*/
i = intel16 (dns->dns_num_q);
while (i > 0)
{
WORD qtype, qclass;
db_write (" Question: query name ");
p = dns_labels (p, (BYTE*)bp, ep);
qtype = intel16 (*(WORD*)p); p += sizeof(qtype);
qclass = intel16 (*(WORD*)p); p += sizeof(qclass);
db_fprintf (" query type %d (%s), class %d\r\n",
qtype, dns_query(qtype), qclass);
i--;
}
/* dump the resource records for the answers
*/
i = intel16 (dns->dns_num_ans);
t = i;
while (i > 0)
{
db_fprintf (" Answer %d: ", t-i+1);
p = dns_resource (p, (BYTE*)bp, ep);
i--;
}
/* dump the resource records for the authoritative answers
*/
i = intel16 (dns->dns_num_auth);
t = i;
while (i > 0)
{
db_fprintf (" Auth %d: ", t-i+1);
p = dns_resource (p, (BYTE*)bp, ep);
i--;
}
/* dump the resource records for the additional info
*/
i = intel16 (dns->dns_num_add);
t = i;
while (i > 0)
{
db_fprintf (" Additional %d: ", t-i+1);
p = dns_resource (p, (BYTE*)bp, ep);
i--;
}
}
/*
* dns_resource()
*
* Print the contents of a resource record
*/
static BYTE *dns_resource (BYTE *p, BYTE *bp, BYTE *ep)
{
int i;
DWORD ttl;
WORD qtype, qclass, reslen;
db_write ("server name: ");
p = dns_labels (p, bp, ep);
/* Do query type, class, ttl and resource length
*/
qtype = intel16 (*(WORD*)p); p += sizeof(qtype);
qclass = intel16 (*(WORD*)p); p += sizeof(qclass);
ttl = intel (*(DWORD*)p); p += sizeof(ttl);
reslen = intel16 (*(WORD*)p); p += sizeof(reslen);
db_fprintf (" type %d (%s), class %d, ttl %luh, length %d\r\n",
qtype, dns_query(qtype), qclass, ttl/3600UL, reslen);
/* Do resource data.
*/
switch (qtype)
{
case T_A: /* A record; ip address(es) */
for (i = 1; i <= reslen; i += sizeof(DWORD))
{
char buf[20];
char *ip = _inet_ntoa (buf, intel(*(DWORD*)p));
db_fprintf (" IP address: %s\r\n", ip);
p += sizeof(DWORD);
}
break;
case T_NS: /* NS record; Name Server */
db_write (" auth host: ");
p = dns_labels (p, bp, ep);
break;
case T_CNAME: /* CNAME record; canonical name */
db_write (" canon host: ");
p = dns_labels (p, bp, ep);
break;
case T_PTR: /* PTR record; hostname for IP */
db_write (" host name: ");
p = dns_labels (p, bp, ep);
break;
default:
p += reslen;
}
return (p);
}
/*
* dns_labels()
*
* Recursively parse a label entry in a DNS packet
*/
static BYTE *dns_labels (BYTE *p, BYTE *bp, BYTE *ep)
{
while (1)
{
BYTE count = *p++;
if (count >= 192)
{
/* There's a pointer in this label. Sigh. Let's grab the
* 14 low-order bits and run with them...
*/
WORD offset = ((unsigned)(count - 192) << 8) + *p++;
dns_labels (bp+offset, bp, ep);
return (p);
}
if (count == 0)
break;
while (count > 0)
{
if (p <= ep)
db_putc (*p++);
else
{
db_write ("\nPacket length exceeded");
goto quit;
}
count--;
}
db_putc ('.');
}
quit:
db_putc ('\n');
return (p);
}
#endif /* USE_DEBUG && DEBUG_DNS */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -