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

📄 _ip.c

📁 This directory contains source code for tcpdump, a tool for network monitoring and data acquisition
💻 C
📖 第 1 页 / 共 2 页
字号:
           break;
    }
  }
}

#if !defined(USE_FAST_CKSUM) /* if not using fast version in libwatt.a */
/* 
 * compute an IP header checksum.
 * don't modifiy the packet.
 */
u_short in_cksum (register u_short *addr, register int len, u_short csum)
{
   register int     nleft = len;
   register u_short *w    = addr;
   register u_short answer;
   register int sum = csum;

  /*
   * Our algorithm is simple, using a 32 bit accumulator (sum),
   * we add sequential 16 bit words to it, and at the end, fold
   * back all the carry bits from the top 16 bits into the lower
   * 16 bits.
   */
  while (nleft > 1)
  {
    sum += *w++;
    nleft -= 2;
  }

  /* mop up an odd byte, if necessary
   */
  if (nleft == 1)
     sum += htons (*(u_char*)w << 8);

  /* add back carry outs from top 16 bits to low 16 bits
   */
  sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
  sum += (sum >> 16);                 /* add carry */
  answer = ~sum;                      /* truncate to 16 bits */
  return (answer);
}
#endif


/* 
 * print an IP datagram.
 */
void ip_print (const u_char *bp, u_int length)
{
  const  struct ip *ip = (const struct ip *) bp;
  const  u_char *cp;
  u_int  hlen, len, len0, off;
  u_char nh;
  u_long advance;
  int    enh;        /* encapsulated header */

#ifdef TCPDUMP_ALIGN
  /*
   * If the IP header is not aligned, copy into abuf.
   * This will never happen with BPF.  It does happen raw packet
   * dumps from -r.
   */
  if ((long) ip & 3)
  {
    static u_char *abuf = NULL;
    static int didwarn = 0;

    if (abuf == NULL)
    {
      abuf = malloc (snaplen);
      if (abuf == NULL)
        error ("ip_print: malloc");
    }
    memcpy (abuf, (char*)ip, min(length, snaplen));
    snapend += abuf - (u_char *) ip;
    packetp = abuf;
    ip = (struct ip *) abuf;
    /* We really want libpcap to give us aligned packets */
    if (!didwarn)
    {
      warning ("compensating for unaligned libpcap packets");
      ++didwarn;
    }
  }
#endif

  if ((u_char*)(ip+1) > snapend)
  {
    PUTS ("[|ip]");
    return;
  }

  if (length < sizeof(struct ip))
  {
    if (partial_frame)
         PRINTF ("[||ip]");
    else PRINTF ("truncated-ip %d\n", length);
    return;
  }

  if (IP_HL(ip) == 0)
  {
    PUTS ("bad packet - header length = 0");
    return;
  }

  hlen = IP_HL(ip) * 4;
  if (hlen < sizeof(struct ip))
  {
    PRINTF ("bad-hlen %d", hlen);
    return;
  }

  len = ntohs (ip->ip_len);
  if (length < len && !partial_frame)
     PRINTF ("truncated-ip - %d bytes missing!\n", len - length);

  len -= hlen;
  len0 = len;

  /*
   * If this is fragment zero, hand it to the next higher
   * level protocol.
   */
  off = ntohs (ip->ip_off);
  if (off & 0x2000)
     partial_frame++;

  if ((off & 0x1fff) == 0)
  {
    cp = (const u_char *) ip + hlen;
    nh = ip->ip_p;

    if (nh != IPPROTO_TCP && nh != IPPROTO_UDP)
       PRINTF ("%s > %s: ",
               ipaddr_string (&ip->ip_src),
               ipaddr_string (&ip->ip_dst));
again:
    switch (nh)
    {
      case IPPROTO_AH:
           nh = *cp;
           advance = ah_print (cp);
           cp  += advance;
           len -= advance;
           if (advance >= USHRT_MAX)
              break;
           goto again;

      case IPPROTO_ESP:
           advance = esp_print (cp, (const u_char*)ip, &enh);
           cp  += advance;
           len -= advance;
           if (enh < 0 || advance >= USHRT_MAX)
              break;
           nh = enh & 0xff;
           goto again;

      case IPPROTO_IPCOMP:
           advance = ipcomp_print (cp, (const u_char *) ip, &enh);
           cp  += advance;
           len -= advance;
           if (enh < 0 || advance >= USHRT_MAX)
              break;
           nh = enh & 0xff;
           goto again;

      case IPPROTO_TCP:
           tcp_print (cp, len, (const u_char *)ip, (off & ~0x6000));
           break;

      case IPPROTO_UDP:
           udp_print (cp, len, (const u_char *)ip, (off & ~0x6000));
           break;

      case IPPROTO_XTP:
           xtp_print (cp, len, (const u_char *)ip);
           break;

      case IPPROTO_ICMP:
           icmp_print (cp, len, (const u_char *)ip);
           break;

      case IPPROTO_IGRP:
           igrp_print (cp, len, (const u_char *) ip);
           break;

      case IPPROTO_ND:
           PRINTF (" nd %d", len);
           break;

      case IPPROTO_EGP:
           egp_print (cp, len, (const u_char *) ip);
           break;

      case IPPROTO_OSPF:
           ospf_print (cp, len, (const u_char *) ip);
           break;

      case IPPROTO_IGMP:
           igmp_print (cp, len, (const u_char *) ip);
           break;

      case IPPROTO_DVMRP:  /* multicast tunnel (ip-in-ip encapsulation) */
           ip_print (cp, len);
           if (!vflag)
           {
             PUTS (" (ipip)");
             return;
           }
           break;

#ifdef USE_INET6
      case IP6PROTO_ENCAP:     /* ip6-in-ip encapsulation */
      case IPPROTO_IPV6:
           ip6_print (cp, len);
           if (!vflag)
           {
             PUTS (" (encap)");
             return;
           }
           break;
#endif
      case IPPROTO_GRE:
           gre_print (cp, len);
           if (!vflag)
           {
             PUTS (" (gre encap)");
             return;
           }
           break;
 
      case IPPROTO_MOBILE:
           mobile_print (cp, len);
           if (!vflag)
           {
             PUTS (" (mobile encap)");
             return;
           }
           break;

      case IPPROTO_PIM:
           pim_print (cp, len);
           break;

      case IPPROTO_RSVP:
           PUTS (" rsvp");
#ifdef USE_RSVP
           ntoh_rsvp_packet (cp, len);
           rsvp_print_pkt (cp, len);
#endif
           break;

      case IPPROTO_AXIP:
           axip_print (cp, len, (const u_char *)ip);
           break;

#ifndef IPPROTO_VRRP
#define IPPROTO_VRRP	112
#endif
      case IPPROTO_VRRP:
           if (vflag)
              PRINTF ("vrrp %s > %s: ",
                      ipaddr_string (&ip->ip_src),
                      ipaddr_string (&ip->ip_dst));
           vrrp_print (cp, len, ip->ip_ttl);
           break;

      default:
           PRINTF (" ip-proto-%d %d", nh, len);
           break;
    }
  }
  if (off & 0x2000)
      partial_frame--;

  /* Ultra quiet now means that all this stuff should be suppressed
   */
  if (qflag > 1)
     return;

  /*
   * for fragmented datagrams, print id:size@offset.  On all
   * but the last stick a "+".  For unfragmented datagrams, note
   * the don't fragment flag.
   */
  len = len0;             /* get the original length */
  if (off & 0x3fff)
  {
    /*
     * if this isn't the first frag, we're missing the
     * next level protocol header.  print the ip addr.
     */
    if (off & 0x1fff)
       PRINTF ("%s > %s:", ipaddr_string (&ip->ip_src),
               ipaddr_string (&ip->ip_dst));
    PRINTF (" (frag %d:%d@%d%s)", ntohs (ip->ip_id), len,
            (off & 0x1fff) * 8,
            (off & IP_MF) ? "+" : "");
  }
  else if (off & IP_DF)
          PUTS (" (DF)");

  if (ip->ip_tos)
  {
    PRINTF (" [tos 0x%x", (int) ip->ip_tos);
    /* ECN bits */
    if (ip->ip_tos &0x01)
       PUTS (",CE");
    if (ip->ip_tos &0x02)
       PUTS (",ECT");
    PUTS ("] ");
  }

  if (ip->ip_ttl <= 1)
     PRINTF (" [ttl %d]", (int) ip->ip_ttl);

  if (vflag)
  {
    int  sum;
    char *sep = "";

    PUTS (" (");
    if (ip->ip_ttl > 1)
    {
      PRINTF ("%sttl %d", sep, (int)ip->ip_ttl);
      sep = ", ";
    }
    if ((off & 0x3fff) == 0)
    {
      PRINTF ("%sid %d", sep, (int)ntohs(ip->ip_id));
      sep = ", ";
    }
    if ((u_char*)ip + hlen <= snapend)
    {
      sum = in_cksum ((u_short*)ip, hlen, 0);
      if (sum != 0)
      {
        PRINTF ("%sbad cksum %x!", sep, ntohs(ip->ip_sum));
        sep = ", ";
      }
    }
    hlen -= sizeof(struct ip);
    if (hlen > 0)
    {
      PRINTF ("%soptlen=%d", sep, hlen);
      ip_optprint ((u_char *) (ip + 1), hlen);
    }
    PUTCHAR (')');
  }
}

void ipN_print (const u_char * bp, u_int length)
{
  struct ip *ip, hdr;

  ip = (struct ip *) bp;
  if (length < 4)
  {
    PRINTF ("truncated-ip %d", length);
    return;
  }
  memcpy (&hdr, (char*)ip, 4);
  switch (IP_V (&hdr))
  {
    case 4:
         ip_print (bp, length);
         return;
#ifdef USE_INET6
    case 6:
         ip6_print (bp, length);
         return;
#endif
    default:
         PRINTF ("unknown ip %d", IP_V(&hdr));
         return;
  }
}

⌨️ 快捷键说明

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