📄 pcdbug.c
字号:
return (1);
}
/*----------------------------------------------------------------------*/
static int tcp_dump (const tcp_Socket *sock, const in_Header *ip)
{
WORD iplen = intel16 (ip->length) - sizeof(*ip);
int j = in_GetHdrLen (ip);
const tcp_Header *tcp = (const tcp_Header*) ((const BYTE*)ip + j);
int i = tcp->offset << 2;
WORD dlen = intel16 (ip->length) - j - i;
WORD olen = 0;
const BYTE *data = (const BYTE*) tcp + i;
DWORD win = intel16 (tcp->window);
DWORD ack, seq;
char flgBuf [4*6+1] = { 0 };
const char *chk_ok;
if (is_frag || dlen > iplen)
dlen = min (dlen, iplen);
if (i < sizeof(*tcp))
{
db_write (" Bad header\r\n");
return (0);
}
if (is_frag && !first_frag)
{
DumpData ((const BYTE*)tcp, iplen);
return (1);
}
if (tcp->flags & tcp_FlagACK) strcat (flgBuf, " ACK");
if (tcp->flags & tcp_FlagFIN) strcat (flgBuf, " FIN");
if (tcp->flags & tcp_FlagSYN) strcat (flgBuf, " SYN");
if (tcp->flags & tcp_FlagPUSH) strcat (flgBuf, " PSH");
if (tcp->flags & tcp_FlagRST) strcat (flgBuf, " RST");
if (tcp->flags & tcp_FlagURG) strcat (flgBuf, " URG");
if (is_frag)
chk_ok = "n/a";
else chk_ok = udp_tcp_chksum (ip, NULL, tcp);
DumpAdrPort ("TCP", sock, ip);
if (sock)
win <<= outbound ? sock->send_wscale : sock->recv_wscale;
ack = intel (tcp->acknum);
seq = intel (tcp->seqnum);
db_fprintf (" flags%s, win %lu, chksum %04X (%s), urg %u\r\n"
" SEQ %10lu, ACK %10lu\r\n",
flgBuf, win, intel16(tcp->checksum), chk_ok,
intel16(tcp->urgent), seq, ack);
if (sock)
{
UINT state = sock->state;
long delta_seq, delta_ack;
if (outbound)
{
if (state == tcp_StateESTAB && sock->last_acknum[0] == 0)
delta_ack = 0;
else delta_ack = ack - sock->last_acknum[0];
if (state == tcp_StateSYNSENT && sock->last_seqnum[0] == 0)
delta_seq = 0;
else delta_seq = seq - sock->last_seqnum[0];
((tcp_Socket*)sock)->last_seqnum[0] = seq;
((tcp_Socket*)sock)->last_acknum[0] = ack;
}
else
{
if (state == tcp_StateLISTEN || sock->last_seqnum[1] == 0)
delta_seq = 0;
else delta_seq = seq - sock->last_seqnum[1];
if (state == tcp_StateSYNSENT && sock->last_acknum[1] == 0)
delta_ack = 0;
else delta_ack = ack - sock->last_acknum[1];
((tcp_Socket*)sock)->last_seqnum[1] = seq;
((tcp_Socket*)sock)->last_acknum[1] = ack;
}
db_fprintf (" %-8.8s (dSEQ %10ld, dACK %10ld), MS %lu/%lu%s\r\n"
" KC %d, vjSA %lu, vjSD %lu, CW %d, WW %d, RTO %d, RTTdiff %s\r\n",
tcpState[state], delta_seq, delta_ack,
sock->missed_seg[0], sock->missed_seg[1],
sock->unhappy ? ", Unhappy" : "",
sock->karn_count, sock->vj_sa, sock->vj_sd,
sock->cwindow, sock->wwindow, sock->rto,
RTT_str (sock->rtt_time - now));
}
olen = i - sizeof(*tcp);
if (olen > 0)
{
const BYTE *opt = (const BYTE*) (tcp+1);
DumpOptions (0, opt, olen);
}
#if (DEBUG_DNS)
if (dbg_dns_details && dlen > sizeof(struct dhead) &&
((!outbound && tcp->srcPort == intel16(DOM_DST_PORT)) ||
( outbound && tcp->dstPort == intel16(DOM_DST_PORT))))
{
db_flush();
dns_dump (data, dlen);
}
else
#endif
DumpData (data, dlen);
return (1);
}
/*----------------------------------------------------------------------*/
static int db_dump (const void *sock, const in_Header *ip,
const char *fname, unsigned line)
{
static int arp_dumped = 0;
int len = 0;
now = set_timeout (0);
if (!arp_dumped)
{
dump_arp_data();
arp_dumped = 1;
}
db_fprintf ("%s %s (%u), time %s\r\n",
outbound ? "Transmitted:" : "Received: ",
fname, line, time_str(now));
if (!_pktserial) /* PD_ETHER / PD_TOKEN / PD_FDDI */
{
union link_Packet *pkt = (union link_Packet*) MAC_HDR (ip);
WORD type = MAC_TYP (ip);
if (debug.MAC)
len = link_head_dump (pkt);
if (type == ARP_TYPE)
{
if (debug.ARP)
return arp_dump ((const arp_Header*)ip);
return (len);
}
if (type == RARP_TYPE)
{
if (debug.RARP)
return rarp_dump ((const rarp_Header*)ip);
return (len);
}
#if defined(USE_PPPOE)
if (type == PPPOE_DISC_TYPE)
{
len += pppoe_disc_dump (&pkt->pppoe);
return (len);
}
if (type == PPPOE_SESS_TYPE)
len += pppoe_sess_dump (&pkt->pppoe);
#endif
}
if (filter.IP && !outbound && !MatchIpDest(ip))
return (len);
_inet_ntoa (ip_src, intel(ip->source));
_inet_ntoa (ip_dst, intel(ip->destination));
if (debug.IP)
{
ip_dump (ip);
len++;
}
#if defined(USE_MULTICAST)
if (ip->proto == IGMP_PROTO && debug.IGMP) return igmp_dump (ip);
#endif
if (ip->proto == ICMP_PROTO && debug.ICMP) return icmp_dump (ip);
if (ip->proto == UDP_PROTO && debug.UDP) return udp_dump (sock, ip);
if (ip->proto == TCP_PROTO && debug.TCP) return tcp_dump (sock, ip);
if (debug.IP) /* dump unknown IP-network protocol */
{
int len2 = intel16 (ip->length) - in_GetHdrLen(ip);
BYTE *data = (BYTE*)ip + in_GetHdrLen(ip);
DumpData (data, min(MAX_IP_DATA,len2));
}
return (len);
}
/*----------------------------------------------------------------------*/
static void dbg_send (const void *sock, const void *ip,
const char *fname, unsigned line)
{
char buf [STK_BUF_SIZE];
op = buf;
op_min = buf;
op_max = buf + STK_BUF_SIZE - 60;
if (handle < 0)
return;
#if defined(__LARGE__)
watt_largecheck (&buf, sizeof(buf), __FILE__, __LINE__);
#endif
outbound = 1;
first_frag = FALSE;
last_frag = FALSE;
is_frag = FALSE;
if (db_dump(sock,ip,fname,line))
{
db_putc ('\n');
db_flush();
}
}
static void dbg_recv (const void *sock, const void *ip,
const char *fname, unsigned line)
{
char buf [STK_BUF_SIZE];
op = buf;
op_min = buf;
op_max = buf + STK_BUF_SIZE - 60;
if (handle < 0)
return;
#if defined(__LARGE__)
watt_largecheck (&buf, sizeof(buf), __FILE__, __LINE__);
#endif
outbound = 0;
first_frag = FALSE;
last_frag = FALSE;
is_frag = FALSE;
if (db_dump(sock,ip,fname,line))
{
db_putc ('\n');
db_flush();
}
}
/*
* Print IP or TCP-options
*/
static void DumpOptions (int is_ip, const BYTE *opt, int len)
{
const BYTE *start = opt;
char buf[20];
DWORD val;
int i, num;
db_write (" Options:");
while (opt < start+len)
{
switch (*opt) /* Note: IP-option includes copy/class bits */
{
case TCPOPT_EOL:
/* case IPOPT_EOL: */
db_write (" EOL\r\n");
return;
case TCPOPT_NOP:
/* case IPOPT_NOP: */
db_write (" NOP");
opt++;
continue;
case TCPOPT_MAXSEG:
db_fprintf (" MSS %u", intel16(*(WORD*)(opt+2)));
break;
case TCPOPT_WINDOW:
db_fprintf (" Wscale %lu", (2L << *(opt+2)));
break;
case TCPOPT_SACK:
db_write (" SACK ");
num = (*(opt+1) - 2) / 4;
for (i = 0; i < num; i++)
{
DWORD left = intel (*(DWORD*)(opt+2+4*i));
DWORD right = intel (*(DWORD*)(opt+6+4*i));
db_fprintf ("blk %d: %lu/%lu, ", i+1, left, right);
}
break;
case TCPOPT_SACKOK:
db_write (" SACK-OK");
break;
case TCPOPT_ECHO:
val = intel (*(DWORD*)(opt+2));
db_fprintf (" Echo %08lX", val);
break;
case TCPOPT_ECHOREPLY:
/* case IPOPT_RR: */
if (is_ip)
{
db_write (" RR");
for (i = 0; i < *(opt+1) - 3; i += sizeof(DWORD))
{
val = intel (*(DWORD*)(opt+3+i));
db_putc (' ');
db_write (_inet_ntoa(buf,val));
}
}
else
{
val = intel (*(DWORD*)(opt+2));
db_fprintf (" Echoreply %08lX", val);
}
break;
case TCPOPT_TIMESTAMP:
db_fprintf (" Timestamp %lu/%lu",
intel(*(DWORD*)(opt+2)), intel(*(DWORD*)(opt+6)));
break;
case TCPOPT_CC:
val = intel (*(DWORD*)(opt+2));
db_fprintf (" CC %08lX", val);
break;
case TCPOPT_CCNEW:
val = intel (*(DWORD*)(opt+2));
db_fprintf (" CCnew %08lX", val);
break;
case TCPOPT_CCECHO:
val = intel (*(DWORD*)(opt+2));
db_fprintf (" CCecho %08lX", val);
break;
case IPOPT_TS:
{
DWORD ip = intel (*(DWORD*)(opt+4));
DWORD ts = intel (*(DWORD*)(opt+8));
db_fprintf (" TS %s/%lu..", _inet_ntoa(buf,ip), ts);
}
break;
case IPOPT_SECURITY:
val = intel (*(DWORD*)(opt+2));
db_fprintf (" SEC %08lX", val);
break;
case IPOPT_SATID:
db_fprintf (" SATID %04X", intel16(*(WORD*)(opt+2)));
break;
case IPOPT_RA:
db_fprintf (" RA %u", intel16(*(WORD*)(opt+2)));
break;
case IPOPT_LSRR:
case IPOPT_SSRR:
db_write (*opt == IPOPT_LSRR ? " LSRR" : " SSRR");
for (i = 0; i < *(opt+1) - 3; i += sizeof(DWORD))
{
DWORD route = intel (*(DWORD*)(opt+3+i));
db_fprintf (" %s", _inet_ntoa(buf,route));
}
break;
default:
db_fprintf (" opt %d?", *opt);
}
opt += *(opt+1);
}
db_putc ('\n');
}
/*----------------------------------------------------------------------*/
static void DumpData (const BYTE *data, unsigned datalen)
{
unsigned ofs;
if (datalen <= 0 || !dbg_mode_all)
return;
for (ofs = 0; (ofs < datalen) && (op < op_max); ofs += 16)
{
unsigned j;
if (ofs == 0)
db_fprintf ("%4u: %04X: ", datalen, ofs);
else db_fprintf (" %04X: ", ofs);
for (j = 0; j < 16 && j+ofs < datalen; j++)
db_fprintf ("%02X%c", (unsigned)data[j+ofs], j == 7 ? '-' : ' ');
for ( ; j < 16; j++)
db_write (" ");
for (j = 0; j < 16 && j+ofs < datalen; j++)
{
if (data[j+ofs] < ' ')
db_putc ('.');
else db_putc (data[j+ofs]);
}
#if 0 /* might be reassembled packet */
if (ofs > mtu-sizeof(in_Header))
{
db_write ("\r\nMTU exceeded!?\r\n");
break;
}
#endif
db_putc ('\n');
}
}
/*----------------------------------------------------------------------*/
static void set_debug_file (const char *value)
{
strncpy (debugName, value, sizeof(debugName)-2);
debugName [sizeof(debugName)-1] = 0;
dbug_open();
}
static void set_debug_mode (const char *value)
{
if (!strcmp(value,"ALL")) dbg_mode_all = 1;
if (!strncmp(value,"HEADER",6)) dbg_mode_all = 0;
}
static void set_debug_filter (const char *value)
{
if (strstr(value,"ALL"))
memset (&filter, 1, sizeof(filter));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -