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

📄 pcdbug.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
{
  if (filter.ARP && !outbound && !MatchArpRarp(arp))
     return (0);

  _inet_ntoa (ip_src, intel(arp->srcIPAddr));
  _inet_ntoa (ip_dst, intel(arp->dstIPAddr));

  return db_fprintf ("ARP:  %s (%d), hw %04X, type %04X\r\n"
                     "      %s (%s) -> %s (%s)\r\n",
                     ArpOpcode(arp->opcode), intel16(arp->opcode),
                     arp->hwType, intel16(arp->protType),
                     MAC_addr (&arp->srcEthAddr), ip_src,
                     MAC_addr (&arp->dstEthAddr), ip_dst);
}

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

static int rarp_dump (const rarp_Header *rarp)
{
  if (filter.RARP && !outbound && !MatchArpRarp(rarp))
     return (0);

  _inet_ntoa (ip_src, intel(rarp->srcIPAddr));
  _inet_ntoa (ip_dst, intel(rarp->dstIPAddr));

  return db_fprintf ("RARP: %s (%d), hw %04X, type %04X\r\n"
                     "      %s (%s) -> %s (%s)\r\n",
                     ArpOpcode(rarp->opcode), intel16(rarp->opcode),
                     rarp->hwType, intel16(rarp->protType),
                     MAC_addr (&rarp->srcEthAddr), ip_src,
                     MAC_addr (&rarp->dstEthAddr), ip_dst);
}

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

static void ip_dump (const in_Header *ip)
{
  WORD  ihl, flg;
  DWORD ofs;
  int   opt_len;

  db_fprintf ("IP:   %s -> %s\r\n", ip_src, ip_dst);

  ihl = in_GetHdrLen (ip);
  if (ihl < sizeof(*ip))
  {
    db_write ("      Bad header\r\n");
    return;
  }

  ofs = intel16 (ip->frag_ofs);
  flg = ofs & ~IP_OFFMASK;
  ofs = (ofs & IP_OFFMASK) << 3;

  db_fprintf ("      IHL %u, ver %u, tos%s, len %u,"
              " ttl %u, prot %s (%d), chksum %s\r\n"
              "      id %04X ofs %lu",
              ihl, (BYTE)ip->ver, TypeOfService(ip->tos), intel16(ip->length),
              (BYTE)ip->ttl, IpProtocol (ip->proto), ip->proto,
              DoCheckSum (ip->checksum, ip, ihl),
              intel16 (ip->identification), ofs);

  if (flg & IP_CE) db_write (", CE");
  if (flg & IP_DF) db_write (", DF");
  if (flg & IP_MF)
  {
    is_frag = TRUE;
    if (ofs == 0)           /* first fragment */
    {
      db_write (", MF");
      first_frag = TRUE;
    }
    else
      db_write (", MF (following header invalid)");
  }
  else if (ofs)             /* last fragment */
  {
    db_write (" (last frag), (following header invalid)");
    is_frag   = TRUE;
    last_frag = TRUE;
  }

  db_putc ('\n');
  opt_len = ihl - sizeof(*ip);
  if (opt_len > 0)
     DumpOptions (1, (const BYTE*)(ip+1), opt_len);
}

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

static int icmp_dump (const in_Header *ip)
{
  WORD  len  = in_GetHdrLen (ip);
  const ICMP_PKT *icmp = (const ICMP_PKT*) ((const BYTE*)ip + len);
  char  buf[100] = "";
  char  mask[20];
  int   type, code;

  len  = intel16 (ip->length) - len;   /* ICMP length */
  type = icmp->unused.type;
  code = icmp->unused.code;

  if (len < sizeof(struct icmp_info))
  {
    db_write ("ICMP: Short header\r\n");
    return (1);
  }

  if (!is_frag)
     switch (type)
     {
       case ICMP_UNREACH:
            if (code < DIM(icmp_unreach_str))
                 sprintf (buf, "%s: %s",
                          icmp_type_str[type], icmp_unreach_str[code]);
            else sprintf (buf, "%s: code %d",
                          icmp_type_str[type], code);
            break;

       case ICMP_TIMXCEED:
            if (code < DIM(icmp_exceed_str))
                 sprintf (buf, "%s: %s",
                          icmp_type_str[type], icmp_exceed_str[code]);
            else sprintf (buf, "%s: code %d",
                          icmp_type_str[type], code);
            break;

       case ICMP_REDIRECT:
            if (code < DIM(icmp_redirect_str))
                  strcpy (buf, icmp_redirect_str[code]);
            else  sprintf (buf, "code %d", code);
            break;

       case ICMP_PARAMPROB:
            if (code)
                 sprintf (buf, "Param prob code %d", code);
            else sprintf (buf, "Param prob at %d", icmp->pointer.pointer);
            break;

       case ICMP_MASKREQ:
       case ICMP_MASKREPLY:
            sprintf (buf, "ICMP %s: %s", icmp_type_str[type],
                     _inet_ntoa(mask, intel(icmp->mask.mask)));
            break;

#if 0 /* to-do: */
       case ICMP_ROUTERADVERT:
       case ICMP_ROUTERSOLICIT:
       case ICMP_TSTAMP:
       case ICMP_TSTAMPREPLY:
       case ICMP_IREQ:
       case ICMP_IREQREPLY:
#endif

       default:
            sprintf (buf, "%s (%d), code %d",
                     type < DIM(icmp_type_str) ?
                       icmp_type_str[type] : "Unknown", type, code);
     }

  if (is_frag)
       db_fprintf ("ICMP: %s -> %s\r\n"
                   "      <%sfragment>\r\n",
                   ip_src, ip_dst, last_frag ? "last " : "");
  else db_fprintf ("ICMP: %s -> %s\r\n"
                   "      %s, chksum %s\r\n",
                   ip_src, ip_dst, buf,
                   DoCheckSum (icmp->unused.checksum, icmp, len));

  if (!is_frag && type == ICMP_PARAMPROB)
  {
    const in_Header *ip2 = &icmp->ip.ip; /* original IP + max 8byte udp/tcp */

    len  = intel16 (ip2->length);
    len  = min (len, sizeof(icmp->ip.ip));
    icmp = (ICMP_PKT*)ip2;
    db_write ("Orig IP:\r\n");  /* !!to-do */
  }
  DumpData ((BYTE*)icmp, len);
  return (1);
}

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

#if defined(USE_MULTICAST)
static int igmp_dump (const in_Header *ip)
{
  WORD  len               = in_GetHdrLen (ip);
  const IGMP_packet *igmp = (const IGMP_packet*) ((const BYTE*)ip + len);
  char  type[20], dest[20];

  len = intel16 (ip->length) - len;   /* IGMP length */

  if (len < sizeof(*igmp))
  {
    db_write ("IGMP: Short header\r\n");
    return (1);
  }

  switch (igmp->type)
  {
    case IGMP_QUERY:
         strcpy (type, "Query");
         break;
    case IGMP_REPORT:
         strcpy (type, "Report");
         break;
    default:
         sprintf (type, "type %d?", igmp->type);
         break;
  }

  db_fprintf ("IGMP: %s, ver %d, chksum %s, addr %s\r\n",
              type, igmp->version,
              DoCheckSum(igmp->checksum, igmp, len),
              _inet_ntoa (dest, intel(igmp->address)));

  DumpData ((BYTE*)igmp, len);
  return (1);
}
#endif  /* USE_MULTICAST */

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

#if defined(USE_PPPOE)
static char *pppoe_get_tag (const BYTE *tag)
{
  static char buf[50];
  char  *p = buf;
  WORD   type = *(WORD*)tag;
  WORD   len  = intel16 (*(WORD*)(tag+2));

  switch (type)
  {
    case PPPOE_TAG_END_LIST:
         return ("end");

    case PPPOE_TAG_SERVICE_NAME:
         sprintf (buf, "service-name `%.*s'", len, tag+PPPOE_TAG_HDR_SIZE);
         break;

    case PPPOE_TAG_AC_NAME:
         sprintf (buf, "AC-name `%*.s'", len, tag+PPPOE_TAG_HDR_SIZE);
         break;

    case PPPOE_TAG_AC_COOKIE:
         p   += sprintf (p, "AC-cookie ");
         tag += PPPOE_TAG_HDR_SIZE;
         while (len && p < buf+sizeof(buf)-1)
         {
           p += sprintf (p, "%02X-", *tag);
           tag++;
           len--;
         }
         *(p-1) = '\0';
         break;

    case PPPOE_TAG_HOST_UNIQ:
         p   += sprintf (p, "host-uniq ");
         tag += PPPOE_TAG_HDR_SIZE;
         while (len && p < buf+sizeof(buf)-1)
         {
           p += sprintf (p, "%02X-", *tag);
           tag++;
           len--;
         }
         *(p-1) = '\0';
         break;

    case PPPOE_TAG_VENDOR_SPES:
         sprintf (buf, "vendor spec ID %08lX", *(DWORD*)(tag+4));
         break;

    case PPPOE_TAG_RELAY_SESS:
         sprintf (buf, "relay session %d", *(WORD*)(tag+4));
         break;

    case PPPOE_TAG_HOST_URL:
         sprintf (buf, "host URL `%*.s'", len, tag+PPPOE_TAG_HDR_SIZE);
         break;

    case PPPOE_TAG_MOTM:
         sprintf (buf, "msg-of-the-minute `%*.s'", len, tag+PPPOE_TAG_HDR_SIZE);
         break;

    case PPPOE_TAG_IP_ROUTE_ADD:
         {
           char buf1[20], buf2[20], buf3[20];
           char *dest_net  = _inet_ntoa (buf1, intel(*(DWORD*)(tag+4)));
           char *dest_mask = _inet_ntoa (buf2, intel(*(DWORD*)(tag+8)));
           char *gateway   = _inet_ntoa (buf3, intel(*(DWORD*)(tag+12)));
           DWORD metric    = intel (*(DWORD*)(tag+16));

           sprintf ("route add: %s %s %s / %d",
                    dest_net, dest_mask, gateway, metric);
         }
         break;

    case PPPOE_TAG_SERVICE_ERR:
         return ("service error");

    case PPPOE_TAG_AC_SYSTEM_ERR:
         return ("AC-system err");

    case PPPOE_TAG_GENERIC_ERR:
         return ("generic error");

    default:
         sprintf (buf, "unknown %04X", type);
         break;
  }
  return (buf);
}

static char *pppoe_get_code (WORD code)
{
  switch (code)
  {
    case PPPOE_CODE_PADI:
         return ("PADI");
    case PPPOE_CODE_PADO:
         return ("PADO");
    case PPPOE_CODE_PADR:
         return ("PADR");
    case PPPOE_CODE_PADS:
         return ("PADS");
    case PPPOE_CODE_PADT:
         return ("PADT");
    case PPPOE_CODE_PADM:
         return ("PADM");
    case PPPOE_CODE_PADN:
         return ("PADN");
    default:
         return ("??");
  }
}

static __inline int pppoe_head_dump (const struct pppoe_Header *pppoe,
                                     const char *proto)
{
  if (pppoe->ver != 1 || pppoe->type != 1)
  {
    db_write ("PPPOE: bogus header\r\n");
    return (0);
  }
  db_fprintf ("PPPOE: %s, %s (%04X), session %d\r\n",
              proto, pppoe_get_code(pppoe->code), pppoe->code,
              intel16(pppoe->session));
  return (1);
}

static int pppoe_disc_dump (const struct pppoe_Packet *pppoe)
{
  WORD  tlen = intel16 (pppoe->head.length);
  BYTE *tags;

  if (!pppoe_head_dump(&pppoe->head, "Discovery"))
     return (1);

  tags = (BYTE*)&pppoe->data;
  while (tlen > 0)
  {
    WORD tag_len = intel16 (*(WORD*)(tags+2));

    db_fprintf ("       tag: %s\r\n", pppoe_get_tag(tags));
    tlen -= (PPPOE_TAG_HDR_SIZE + tag_len);
    tags += (PPPOE_TAG_HDR_SIZE + tag_len);
  }
  db_write ("\r\n");
  return (1);
}

static int pppoe_sess_dump (const struct pppoe_Packet *pppoe)
{
  if (!pppoe_head_dump(&pppoe->head, "Session"))
     return (1);
  /* !! to-do */
  return (1);
}
#endif

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

static const char *udp_tcp_chksum (const in_Header  *ip,
                                   const udp_Header *udp,
                                   const tcp_Header *tcp)
{
  tcp_PseudoHeader ph;
  int              len;

  memset (&ph, 0, sizeof(ph));
  if (udp)
  {
    len = intel16 (udp->length);
    ph.protocol = UDP_PROTO;
    ph.checksum = checksum (udp, len);
  }
  else
  {
    len = intel16 (ip->length) - in_GetHdrLen (ip);
    ph.protocol = TCP_PROTO;
    ph.checksum = checksum (tcp, len);
  }

  ph.src    = ip->source;
  ph.dst    = ip->destination;
  ph.length = intel16 (len);

  if (checksum(&ph,sizeof(ph)) == 0xFFFF)
     return ("ok");
  return ("ERROR");
}

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

static int udp_dump (const tcp_Socket *sock, const in_Header *ip)
{
  const char *chk_ok    = "n/a";
  WORD  iplen           = intel16 (ip->length) - sizeof(*ip);
  const udp_Header *udp = (const udp_Header*) ((BYTE*)ip + in_GetHdrLen(ip));
  WORD  udplen          = intel16 (udp->length) - sizeof(*udp);
  const BYTE *data      = (const BYTE*) (udp+1);

  if (udp->checksum && !is_frag)
     chk_ok = udp_tcp_chksum (ip, udp, NULL);

  if (is_frag || udplen > iplen)
     udplen = min (udplen, iplen);

  if (is_frag && !first_frag)
  {
    DumpData ((const BYTE*)udp, iplen);
    return (1);
  }

  DumpAdrPort ("UDP", sock, ip);

  db_fprintf ("      len %d, chksum %04X (%s)\r\n",
              intel16(udp->length), intel16(udp->checksum), chk_ok);

#if (DEBUG_DNS)
  if (dbg_dns_details && udplen > sizeof(struct dhead) &&
      ((!outbound && udp->srcPort == intel16(DOM_DST_PORT)) ||
       ( outbound && udp->dstPort == intel16(DOM_DST_PORT))))
  {
    db_flush();
    dns_dump (data, udplen);
  }
  else
#endif

  DumpData (data, udplen);

⌨️ 快捷键说明

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