⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcdbug.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
 *  WatTCP protocol debugger. Writes to `debug.file' specified in
 *  config-file. File may be stdout/stderr/nul.
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>
#include <io.h>

#ifdef __DJGPP__
#include <unistd.h>
#endif

#include "wattcp.h"
#include "strings.h"
#include "udp_dom.h"
#include "misc.h"
#include "sock_ini.h"
#include "chksum.h"
#include "pctcp.h"
#include "pcbsd.h"
#include "pcsed.h"
#include "pcarp.h"
#include "pcqueue.h"
#include "pcpkt.h"
#include "pcstat.h"
#include "pcconfig.h"
#include "pcicmp.h"
#include "pppoe.h"
#include "pcdbug.h"

#define DEBUG_DNS 1       /* 1 = include detailed DNS debugging */
#define DEBUG_RTP 1       /* 1 = include detailed RTP debugging, to-do */

/*
 * tcpState[] is also used in sock_dbu.c/sock_dat.c
 */
const char *tcpState[] = {
           "LISTEN",   "SYNSENT", "SYNREC", "ESTAB",
           "ESTCLOSE", "FINWT1",  "FINWT2", "CLOSWT",
           "CLOSING",  "LASTACK", "TIMEWT", "CLOSED"
         };

#if defined(USE_DEBUG)

#if (DEBUG_DNS)
#include <arpa/nameser.h>
#include <resolv.h>
#endif

/*@-observertrans@*/

/*
 * We don't use language translation in printouts (only in the ourinit()
 * routine). That would make debug-dumps / problem-reports difficult.
 */

#ifdef __HIGHC__          /* disable stack-checking here */
#pragma Off (check_stack)
#pragma stack_size_warn (220000)
#endif

#ifdef __WATCOMC__
#pragma Off (check_stack)
#endif

#ifdef __TURBOC__
  #ifndef OLD_TURBOC
  #pragma option -N-
  #endif
extern unsigned _stklen = 20000;
#endif

#if (DOSX) && defined(USE_FRAGMENTS)
#define STK_BUF_SIZE  200000
#else
#define STK_BUF_SIZE  8500
#endif

#ifndef STDOUT_FILENO
#define STDOUT_FILENO 1
#endif

static int db_fprintf (const char *format, ...)
#ifdef __GNUC__
  __attribute__((format(printf,1,2)))
#endif
;

static int  db_write    (const char *buf);
static void db_putc     (int ch);
static void db_flush    (void);
static void DumpData    (const BYTE *data, unsigned datalen);
static void DumpOptions (int is_ip, const BYTE *opt, int len);

#if (DEBUG_DNS)
  static void  dns_dump    (const BYTE *, unsigned);
  static BYTE *dns_resource(BYTE *, BYTE *, BYTE *);
  static BYTE *dns_labels  (BYTE *, BYTE *, BYTE *);
#endif

static void (*prev_hook) (const char*, const char*) = NULL;
static char  debugName [128] = "WATTCP.DBG";
static char  ip_src [20];
static char  ip_dst [20];
static int   handle = -1;
static DWORD now;         /* ticks or milli-sec      */
static int   outbound;    /* transmitting packet?    */
static int   is_frag;     /* is this a fragment?     */
static int   first_frag;  /* is this 1st fragment?   */
static int   last_frag;   /* is this last fragment?  */
static char *op;          /* out-buffer pointer      */
static char *op_min;      /* first position for 'op' */
static char *op_max;      /* last position for 'op'  */

static struct {
       char MAC;
       char ARP;
       char RARP;
       char IP;
       char BCAST;
     } filter = { 0,0,0,0,0 };

static struct {
       char MAC;
       char ARP;
       char RARP;
       char IP;
       char UDP;
       char TCP;
       char ICMP;
       char IGMP;
     } debug = { 0,1,1,1,1,1,1,1 };

/* These are public so they can be set by application if
 * running without a config-file
 */
BOOL dbg_mode_all    = 1;
BOOL dbg_print_stat  = 1;
BOOL dbg_dns_details = DEBUG_DNS;
BOOL dbg_rtp_details = DEBUG_RTP;   /* !!to-do */


/*----------------------------------------------------------------------*/

/*
 * Other link-layer drivers (ppp/capi/pktdrvr32) can write to same file,
 * but NOT close it.
 */
const int dbug_handle (void)
{
  return (handle);
}

void dbug_open (void)
{
  if (handle < 0)
  {
    if (!stricmp(debugName,"con"))
       handle = STDOUT_FILENO;
    else
    {
      int mode = _fmode;
      _fmode = O_BINARY;    /* Borland defaults to O_TEXT */
      handle = creat (debugName, S_IWRITE);
      _fmode = mode;
    }
    if (handle < 0)
    {
      outsnl ("ERROR: unable to open debug file!");
      exit (3);
    }
  }
}

/*
 * Return TRUE if MAC destination address of received/sent link-layer
 * packet:
 *  - matches our link-layer address.
 *  - is broadcast and we don't filter broadcast.
 */
static __inline int MatchLinkDestination (const mac_address *dst)
{
  if (!memcmp(dst, &_eth_addr, sizeof(_eth_addr)) ||
      (!filter.BCAST && !memcmp(dst, &_eth_brdcast, sizeof(_eth_brdcast))))
     return (1);
  return (0);
}

/*
 * Return TRUE if destination address of received/sent ARP packet:
 *  - matches our ether-address.
 *  - is broadcast and we don't filter broadcast.
 */
static __inline int MatchArpRarp (const arp_Header *arp)
{
  if (!memcmp(&arp->dstEthAddr, &_eth_addr, sizeof(_eth_addr)))
     return (1);
  if (!filter.BCAST &&
      !memcmp(&arp->dstEthAddr, &_eth_brdcast, sizeof(_eth_brdcast)))
     return (1);
  return (0);
}

/*
 * Return TRUE if destination address of received/sent IP packet:
 *  - matches our IP-address.
 *  - is broadcast and we don't filter (directed) IP-broadcast.
 */
static __inline int MatchIpDest (const in_Header *ip)
{
  DWORD destin = intel (ip->destination);

  if (is_local_addr(destin) ||
      (!filter.BCAST && is_ip_brdcast(ip)))
     return (1);
  return (0);
}

/*
 * Return checksum and print "ok" or "ERROR"
 */
static __inline const char *DoCheckSum (WORD value, const void *p, int len)
{
  static char buf[20];
  sprintf (buf, "%04X (%s)", value,
           checksum(p,len) == 0xFFFF ? "ok" : "ERROR");
  return (buf);
}

/*
 * Return name of some known link-layer protocols.
 */
static __inline const char *LinkProtocol (WORD type)
{
  switch (intel16(type))
  {
    case IP_TYPE:   return ("IP");
    case ARP_TYPE:  return ("ARP");
    case RARP_TYPE: return ("RARP");
    default:        return ("unknown");
  }
}

/*
 * Return name of known IP-protocols.
 */
static __inline const char *IpProtocol (WORD prot)
{
  switch (prot)
  {
    case UDP_PROTO:  return ("UDP");
    case TCP_PROTO:  return ("TCP");
    case ICMP_PROTO: return ("ICMP");
    case IGMP_PROTO: return ("IGMP");
    default:         return ("unknown");
  }
}

/*
 * Return name for IP's "Type Of Service".
 */
static __inline const char *TypeOfService (BYTE tos)
{
  static char buf[20];

  buf[0] = 0;
  if (tos & 0x04) strcat (buf," Rel");
  if (tos & 0x08) strcat (buf," ThPut");
  if (tos & 0x10) strcat (buf," LwDly");
  if (buf[0] == 0)
     sprintf (buf, " %d", tos);
  return (buf);
}

/*
 * Format time for "Round Trip Time".
 */
static __inline const char *RTT_str (DWORD delta)
{
  return (delta > 0UL ? time_str(delta) : "--");
}

/*
 * Return string for ARP/RARP opcodes.
 */
static __inline const char *ArpOpcode (WORD code)
{
  if (code == ARP_REQUEST || code == RARP_REQUEST)
     return ("Request");

  if (code == ARP_REPLY || code == RARP_REPLY)
     return ("Reply");

  return ("? op");
}

/*
 * Return hexa-decimal string for an 6 byte MAC-address.
 * Use 2 buffers in round-robin.
 */
static __inline const char *MAC_addr (const void *adr)
{
  static char buf[2][20];
  static char idx = 0;
  char  *rc = buf [(int)idx];
  char  *a  = (char*)adr;

  sprintf (rc, "%02X:%02X:%02X:%02X:%02X:%02X",
           a[0] & 255, a[1] & 255, a[2] & 255,
           a[3] & 255, a[4] & 255, a[5] & 255);
  idx ^= 1;
  return (rc);
}

/*
 * Print IP source/destination addresses and ports;
 *   "host1 (a) -> host2 (b)"
 */
static void DumpAdrPort (const char       *proto,
                         const tcp_Socket *sock,
                         const in_Header  *ip)
{
  const tcp_Header *tcp = (const tcp_Header*) ((BYTE*)ip + in_GetHdrLen(ip));
  char  dst[20];
  char  src[20];

  if (!sock)
       db_fprintf ("%s:  NO SOCKET : %s (%d) -> %s (%d)\n", proto,
                   ip_src, intel16(tcp->srcPort),
                   ip_dst, intel16(tcp->dstPort));

  else if (outbound)
       db_fprintf ("%s:  %s (%d) -> %s (%d)\n", proto,
                   _inet_ntoa(src,my_ip_addr),   sock->myport,
                   _inet_ntoa(dst,sock->hisaddr),sock->hisport);

  else db_fprintf ("%s:  %s (%d) -> %s (%d)\n", proto,
                   _inet_ntoa(src,sock->hisaddr),sock->hisport,
                   _inet_ntoa(dst,my_ip_addr),   sock->myport);
}

/*----------------------------------------------------------------------*/

static int link_head_dump (const union link_Packet *pkt)
{
  WORD type;
  int  len;

  if (_pktdevclass == PD_TOKEN)
  {
    const struct tok_Header *tok = &pkt->tok.head;

    if (filter.MAC && !outbound && !MatchLinkDestination(&tok->destination))
       return (0);

    db_fprintf ("TR:   destin %s, AC %02X, FC %02X\r\n"
                "      source %s, DSAP %02X, SSAP %02X, Ctrl %02X\r\n",
                MAC_addr (&tok->destination), tok->accessCtrl, tok->frameCtrl,
                MAC_addr (&tok->source), tok->DSAP, tok->SSAP, tok->ctrl);
    type = intel16 (tok->type);
    len  = db_fprintf ("      type %s (%04X)", LinkProtocol(type), type);
  }
  else if (_pktdevclass == PD_FDDI)
  {
    const struct fddi_Header *fddi = &pkt->fddi.head;

    if (filter.MAC && !outbound && !MatchLinkDestination(&fddi->destination))
       return (0);

    db_fprintf ("FDDI: destin %s, FC %02X\r\n"
                "      source %s, DSAP %02X, SSAP %02X, Ctrl %02X\r\n",
                MAC_addr (&fddi->destination), fddi->frameCtrl,
                MAC_addr (&fddi->source), fddi->DSAP, fddi->SSAP, fddi->ctrl);
    type = intel16 (fddi->type);
    len  = db_fprintf ("      type %s (%04X)", LinkProtocol(type), type);
  }
  else  /* PD_ETHER */
  {
    const struct eth_Header *eth = &pkt->eth.head;

    if (filter.MAC && !outbound && !MatchLinkDestination(&eth->destination))
       return (0);

    db_fprintf ("ETH:  destin %s\r\n"
                "      source %s\r\n",
                MAC_addr (&eth->destination),
                MAC_addr (&eth->source));
    type = intel16 (eth->type);

    if (type < ETH_MAX_DATA)  /* LLC length field */
         len = db_fprintf ("      IEEE 802.3 encap (LLC) not supported");
    else len = db_fprintf ("      type %s (%04X)", LinkProtocol(type), type);

  }
  db_putc ('\n');
  return (len);
}

/*----------------------------------------------------------------------*/

static void dump_arp_data (void)
{
  char buf[30];
  int  i, printed;

  db_fprintf ("Routing data:\r\n");
  for (i = 0; i < arp_last_gateway; i++)
  {
    struct gate_table *gw = arp_gate_list + i;
  
    db_write ("      ");
    db_fprintf ("network: %-15s ", _inet_ntoa(buf, gw->subnet));
    db_fprintf ("router: %-15s ",  _inet_ntoa(buf, gw->gate_ip));
    db_fprintf ("mask: %s\n", _inet_ntoa(buf, gw->mask ? gw->mask : sin_mask));
  }

  for (i = printed = 0; i < MAX_ARP_DATA; i++)
  {
    struct arp_table *arp = arp_cache_data + i;

    if (arp->flags >= ARP_FLAG_FOUND)
    {
      if (!printed)
         db_fprintf ("ARP Cache:\r\n");
      printed = 1;

      db_fprintf ("      IP: %-15s -> %s, expires: ",
                  _inet_ntoa(buf, arp->ip), MAC_addr (&arp->hardware));

      if (arp->flags == ARP_FLAG_FIXED)
           db_write ("never");
      else if (arp->expiry > now)
           db_fprintf ("%ss", time_str(arp->expiry - now));
      else db_write ("yes");
      db_putc ('\n');
    }
  }
  if (_bootpon || _dhcpon || _rarpon)
     db_write ("      Above routing data may be overridden by "
               "DHCP/BOOTP/RARP\r\n");
  db_putc ('\n');
}

/*----------------------------------------------------------------------*/

static int arp_dump (const arp_Header *arp)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -