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

📄 _ip.c

📁 This directory contains source code for tcpdump, a tool for network monitoring and data acquisition
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 
 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
 *      The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that: (1) source code distributions
 * retain the above copyright notice and this paragraph in its entirety, (2)
 * distributions including binary code include the above copyright notice and
 * this paragraph in its entirety in the documentation or other materials
 * provided with the distribution, and (3) all advertising materials mentioning
 * features or use of this software display the following acknowledgement:
 * ``This product includes software developed by the University of California,
 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
 * the University nor the names of its contributors may be used to endorse
 * or promote products derived from this software without specific prior
 * written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <limits.h>

#include <sys/param.h>
#include <sys/socket.h>

#include "a2name.h"
#include "interfac.h"
#include "extract.h"            /* must come after interface.h */
#include "ip.h"


#ifndef IN_CLASSD
#define IN_CLASSD(i) (((int32_t)(i) & 0xf0000000) == 0xe0000000)
#endif


/* (following from ipmulti/mrouted/prune.h) */

/* 
 * The packet format for a traceroute request.
 */

struct tr_query {
       u_int32_t tr_src;            /* traceroute source */
       u_int32_t tr_dst;            /* traceroute destination */
       u_int32_t tr_raddr;          /* traceroute response address */
       u_int32_t tr_rttlqid;        /* response ttl and qid */
     };

#define TR_GETTTL(x)  (u_int32_t)(((x) >> 24) & 0xff)
#define TR_GETQID(x)  ((x) & 0x00ffffffUL)

/* 
 * Traceroute response format.  A traceroute response has a tr_query at the
 * beginning, followed by one tr_resp for each hop taken.
 */
struct tr_resp {
       u_int32_t tr_qarr;          /* query arrival time */
       u_int32_t tr_inaddr;        /* incoming interface address */
       u_int32_t tr_outaddr;       /* outgoing interface address */
       u_int32_t tr_rmtaddr;       /* parent address in source tree */
       u_int32_t tr_vifin;         /* input packet count on interface */
       u_int32_t tr_vifout;        /* output packet count on interface */
       u_int32_t tr_pktcnt;        /* total incoming packets for src-grp */
       u_int8_t  tr_rproto;        /* routing proto deployed on router */
       u_int8_t  tr_fttl;          /* ttl required to forward on outvif */
       u_int8_t  tr_smask;         /* subnet mask for src addr */
       u_int8_t  tr_rflags;        /* forwarding error codes */
     };

/* defs within mtrace
 */
#define TR_QUERY 1
#define TR_RESP 2

/* fields for tr_rflags (forwarding error codes)
 */
#define TR_NO_ERR       0
#define TR_WRONG_IF     1
#define TR_PRUNED       2
#define TR_OPRUNED      3
#define TR_SCOPED       4
#define TR_NO_RTE       5
#define TR_NO_FWD       7
#define TR_NO_SPACE     0x81
#define TR_OLD_ROUTER   0x82

/* fields for tr_rproto (routing protocol)
 */
#define TR_PROTO_DVMRP  1
#define TR_PROTO_MOSPF  2
#define TR_PROTO_PIM    3
#define TR_PROTO_CBT    4

static void print_mtrace (const u_char *bp, u_int len)
{
  struct tr_query *tr = (struct tr_query*) (bp + 8);

  PRINTF ("mtrace %lu: %s to %s reply-to %s",
          (u_long) TR_GETQID(ntohl(tr->tr_rttlqid)),
          ipaddr_string (&tr->tr_src),
          ipaddr_string (&tr->tr_dst),
          ipaddr_string (&tr->tr_raddr));

  if (IN_CLASSD (ntohl (tr->tr_raddr)))
     PRINTF (" with-ttl %d", TR_GETTTL (ntohl(tr->tr_rttlqid)));
  ARGSUSED (len);
}

static void print_mresp (const u_char *bp, u_int len)
{
  struct tr_query *tr = (struct tr_query *) (bp + 8);

  PRINTF ("mresp %lu: %s to %s reply-to %s",
          (u_long) TR_GETQID(ntohl(tr->tr_rttlqid)),
          ipaddr_string (&tr->tr_src),
          ipaddr_string (&tr->tr_dst),
          ipaddr_string (&tr->tr_raddr));

  if (IN_CLASSD (ntohl (tr->tr_raddr)))
     PRINTF (" with-ttl %d", TR_GETTTL (ntohl (tr->tr_rttlqid)));
  ARGSUSED (len);
}

static void igmp_print (const u_char *bp, u_int len, const u_char *bp2)
{
  const struct ip *ip = (const struct ip*) bp2;

  PRINTF ("%s > %s: ",
          ipaddr_string(&ip->ip_src),
          ipaddr_string(&ip->ip_dst));

  if (qflag)
  {
    PUTS ("igmp");
    return;
  }

  TCHECK2 (bp[0], 8);
  switch (bp[0])
  {
    case 0x11:
         PRINTF ("igmp %s query", bp[1] ? "v2" : "v1");
         if (bp[1] && bp[1] != 100)
            PRINTF (" [intvl %d]", bp[1]);
         PUTS ("igmp query");
         if (EXTRACT_32BITS (&bp[4]))
            PRINTF (" [gaddr %s]", ipaddr_string (&bp[4]));
         if (len != 8)
            PRINTF (" [len %d]", len);
         break;

    case 0x12:
    case 0x16:
         PRINTF ("igmp %s report %s", (bp[0] & 0x0f) == 6 ? "v2" : "v1", ipaddr_string (&bp[4]));
         if (len != 8)
            PRINTF (" [len %d]", len);
         if (bp[1])
            PRINTF (" [b1=0x%x]", bp[1]);
         break;

    case 0x17:
         PRINTF ("igmp leave %s", ipaddr_string (&bp[4]));
         if (len != 8)
            PRINTF (" [len %d]", len);
         if (bp[1])
            PRINTF (" [b1=0x%x]", bp[1]);
         break;

    case 0x13:
         PUTS ("igmp dvmrp");
         if (len < 8)
              PRINTF (" [len %d]", len);
         else dvmrp_print (bp, len);
         break;

    case 0x14:
         PUTS ("igmp pimv1");
         pimv1_print (bp, len);
         break;

    case 0x1e:
         print_mresp (bp, len);
         break;

    case 0x1f:
         print_mtrace (bp, len);
         break;

    default:
         PRINTF ("igmp-%d", bp[0] & 0xf);
         if (bp[1])
            PRINTF (" [b1=0x%02x]", bp[1]);
         break;
  }

  if (vflag && TTEST2 (bp[0], len))
  {
    /* Check the IGMP checksum */
    if (in_cksum ((u_short*)bp, len, 0))
       PRINTF (" bad igmp cksum %x!", EXTRACT_16BITS (&bp[2]));
  }
  return;

trunc:
  PUTS ("[|igmp]");
}


/* 
 * print the recorded route in an IP RR, LSRR or SSRR option.
 */
static void ip_printroute (const char *type, const u_char * cp, u_int length)
{
  u_int ptr = cp[2] - 1;
  u_int len;

  PRINTF (" %s{", type);
  if ((length + 1) & 3)
     PRINTF (" [bad length %d]", length);
  if (ptr < 3 || ((ptr + 1) & 3) || ptr > length + 1)
     PRINTF (" [bad ptr %d]", cp[2]);

  type = "";
  for (len = 3; len < length; len += 4)
  {
    if (ptr == len)
       type = "#";
    PRINTF ("%s%s", type, ipaddr_string (&cp[len]));
    type = " ";
  }
  PRINTF ("%s}", ptr == len ? "#" : "");
}

/*
 * print the timestamp in the IPOPT_TS option
 */
static void ip_printts (const u_char *cp, u_int length)
{
  u_int ptr = cp[2] - 1;
  u_int len = 0;
  int   hoplen;
  char *type;

  PUTS (" TS{");
  hoplen = ((cp[3] & 0xF) != IPOPT_TS_TSONLY) ? 8 : 4;

  if ((length - 4) & (hoplen-1))
     PRINTF ("[bad length %d]", length);

  if (ptr < 4 || ((ptr - 4) & (hoplen-1)) || ptr > length + 1)
     PRINTF ("[bad ptr %d]", cp[2]);

  switch (cp[3] & 0xF)
  {
    case IPOPT_TS_TSONLY:
         PUTS ("TSONLY");
         break;
    case IPOPT_TS_TSANDADDR:
         PUTS ("TS+ADDR");
         break;

        /*
         * prespecified should really be 3, but some ones might send 2
         * instead, and the IPOPT_TS_PRESPEC constant can apparently
         * have both values, so we have to hard-code it here.
         */
    case 2:
         PUTS ("PRESPEC2.0");
         break;
    case IPOPT_TS_PRESPEC:
         PUTS ("PRESPEC");
         break;
    default:
         PRINTF ("[bad ts type %d]", cp[3] & 0xF);
         goto done;
  }

  type = " ";
  for (len = 4; len < length; len += hoplen)
  {
    if (ptr == len)
       type = " ^ ";
    PRINTF ("%s%ld@%s", type, EXTRACT_32BITS (&cp[len+hoplen-4]),
            hoplen != 8 ? "" : ipaddr_string (&cp[len]));
    type = " ";
  }

done:
  PRINTF ("%s", ptr == len ? " ^ " : "");

  if (cp[3]>>4)
       PRINTF (" [%d hops not recorded]} ", cp[3] >> 4);
  else PUTCHAR ('}');
}


/* 
 * print IP options.
 */
static void ip_optprint (const u_char * cp, u_int length)
{
  u_int len;

  for (; length > 0; cp += len, length -= len)
  {
    int tt = *cp;

    if (tt == IPOPT_NOP || tt == IPOPT_EOL)
       len = 1;
    else
    {
      if (&cp[1] >= snapend)
      {
        PUTS ("[|ip]");
        return;
      }
      len = cp[1];
    }
    if (len <= 0)
    {
      PRINTF ("[|ip op len %d]", len);
      return;
    }
    if (&cp[1] >= snapend || cp + len > snapend)
    {
      PUTS ("[|ip]");
      return;
    }
    switch (tt)
    {
      case IPOPT_EOL:
           PUTS (" EOL");
           if (length > 1)
              PRINTF ("-%d", length - 1);
           return;

      case IPOPT_NOP:
           PUTS (" NOP");
           break;

      case IPOPT_TS:
           ip_printts(cp, len);
           break;

      case IPOPT_SECURITY:
           PRINTF (" SECURITY{%d}", len);
           break;

      case IPOPT_RR:
           ip_printroute ("RR", cp, len);
           break;

      case IPOPT_SSRR:
           ip_printroute ("SSRR", cp, len);
           break;

      case IPOPT_LSRR:
           ip_printroute ("LSRR", cp, len);
           break;

#ifndef IPOPT_RA
#define IPOPT_RA 148            /* router alert */
#endif
      case IPOPT_RA:
           PUTS (" RA");
           if (len != 4)
              PRINTF ("{%d}", len);
           else if (cp[2] || cp[3])
              PRINTF ("%d.%d", cp[2], cp[3]);
           break;

      default:
           PRINTF (" IPOPT-%d{%d}", cp[0], len);

⌨️ 快捷键说明

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