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

📄 tcpdump.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.
 */

/* 
 * tcpdump - monitor tcp/ip traffic on an ethernet.
 *
 * First written in 1987 by Van Jacobson, Lawrence Berkeley Laboratory.
 * Mercilessly hacked and occasionally improved since then via the
 * combined efforts of Van, Steve McCanne and Craig Leres of LBL.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <setjmp.h>
#include <time.h>
#include <ctype.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pcap.h>
#include <tcp.h>

#ifdef __DJGPP__
#include <sys/exceptn.h>
#include <crt0.h>
#endif

#include "interfac.h"
#include "a2name.h"
#include "ethertyp.h"

int  aflag  = 0;                 /* translate network & broadcast addresses */
int  fflag  = 0;                 /* don't translate "foreign" IP address */
int  Lflag  = 0;                 /* list available data link types and exit */
int  Hflag  = 0;                 /* append resolved host names to hosts file */
int  nflag  = 0;                 /* leave addresses as numbers */
int  Nflag  = 0;                 /* remove domains from printed host names */
int  pflag  = 0;                 /* don't go promiscuous */
int  Pflag  = 0;                 /* dump protocol info */
int  qflag  = 0;                 /* quick (shorter) output */
int  tflag  = 1;                 /* print packet arrival time */
int  uflag  = 0;                 /* Print undecoded NFS handles */
int  eflag  = 0;                 /* print ethernet header */
int  vflag  = 0;                 /* verbose */
int  xflag  = 0;                 /* print packet in hex */
int  wflag  = 0;                 /* write packets to file */
int  Aflag  = 0;                 /* print packet in ascii */
int  xaflag = 0;                 /* print packet in hex & ascii */
int  Oflag  = 1;                 /* run filter code optimizer */
int  Sflag  = 0;                 /* print raw TCP sequence numbers */
int  sflag  = 0;                 /* use the libsmi to translate OIDs */
int  dflag  = 0;                 /* print filter code */
int  Dflag  = 0;                 /* dump device info */
int  Rflag  = 0;                 /* print packets read from file at real pace */

int  packettype;
int  messagetype;
int  break_mode = 1;             /* ^Break/^C mode (djgpp only) */

int  snaplen = DEFAULT_SNAPLEN;  /* Length of saved portion of packet. */
long thiszone;                   /* seconds offset from gmt to local time */

int  partial_frame;
WORD extracted_ethertype;

char program_name[_MAX_PATH];
char program_path[_MAX_PATH];
char *pcap_device = NULL;
char *espsecret = NULL;          /* ESP secret key */

DWORD localnet;
DWORD netmask;
WORD  protocol_b;

const struct timeval *PacketTimestamp;
const u_char *packetp;
const u_char *snapend;

static pcap_t *pd        = NULL;
static char   *RFileName = NULL;
static char   *WFileName = NULL;

static int dlt = -1;        /* if != -1, ask libpcap for the DLT it names */
static const char *dlt_name = NULL;

static struct bpf_program fcode;

static void program_usage (int details);
static void program_end   (int free_mem);
static void init_handlers (void);
static void dump_stats    (void);
static void dump_ascii    (const u_char *bp, u_int length);
static void dump_hex_ascii(const u_char *bp, u_int length);

struct printer {
       pcap_handler f;
       int          type;
     };

#ifndef DLT_ATM_RFC1483
#define DLT_ATM_RFC1483 11
#endif


static struct printer printers[] = {
              { ether_if_print, DLT_EN10MB      },
              { token_if_print, DLT_IEEE802     },
           // { lane_if_print,  DLT_LANE8023    },
           // { cip_if_print,   DLT_CIP         },
           // { cip_if_print,   DLT_ATM_CLIP    },
              { sl_if_print,    DLT_SLIP        },
              { sl_bs_if_print, DLT_SLIP_BSDOS  },
              { ppp_if_print,   DLT_PPP         },
              { ppp_bs_if_print,DLT_PPP_BSDOS   },
              { fddi_if_print,  DLT_FDDI        },
              { null_if_print,  DLT_NULL        },
           // { null_if_print,  DLT_LOOP        },
              { raw_if_print,   DLT_RAW         },
              { atm_if_print,   DLT_ATM_RFC1483 },
           // { chdlc_if_print, DLT_C_HDLC      },
              { ax25_if_print,  DLT_AX25        },
           // { sll_if_print,   DLT_LINUX_SLL   },
              { NULL,           0               },
            };

static pcap_handler lookup_printer (int type)
{
  struct printer *p;

  for (p = printers; p->f; ++p)
      if (type == p->type)
         return (p->f);

  PERROR (("unknown data link type 0x%x", type));
  return (NULL);
}

static unsigned short eth_proto_parse (char *id)
{
   if (!strcmp(id, "ip") || !strcmp(id, "ipv4"))
      return htons (ETHERTYPE_IP);
   if (!strcmp(id, "ipv6"))
      return htons (ETHERTYPE_IPV6);
   if (!strcmp(id, "arp"))
      return htons (ETHERTYPE_ARP);
   if (!strcmp(id, "rarp"))
      return htons (ETHERTYPE_RARP);
   if (!strcmp(id, "802.2"))
      return htons (ETHERTYPE_802_2);
   if (!strcmp(id, "802.3"))
      return htons (ETHERTYPE_802_3);
   if (!strcmp(id, "lat"))
      return htons (ETHERTYPE_LAT);
   if (!strcmp(id, "dec"))
      return htons (ETHERTYPE_DEC);
   if (!strcmp(id, "atalk"))
      return htons (ETHERTYPE_ATALK);
   if (!strcmp(id, "aarp"))
      return htons (ETHERTYPE_AARP);
   if (!strcmp(id, "ipx"))
      return htons (ETHERTYPE_IPX);
   if (!strcmp(id, "x25"))
      return htons (ETHERTYPE_X25);
   return htons (atoi(id));
}

static void show_dlts_and_exit (pcap_t *pd)
{
  int *dlts   = NULL;
  int  n_dlts = pcap_list_datalinks (pd, &dlts);

  if (n_dlts < 0)
     error ("%s", pcap_geterr(pd));

  if (n_dlts == 0 || !dlts)
     error ("No data link types.");

  fprintf (stderr, "Data link types (use option -y to set):\n");

  while (--n_dlts >= 0)
  {
    const char *name = pcap_datalink_val_to_name (dlts[n_dlts]);
    if (name)
    {
      fprintf (stderr, "  %s", name);

      /* OK, does tcpdump handle that type?
       */
      if (lookup_printer(dlts[n_dlts]) == NULL)
         fprintf (stderr, " (not supported)");
      putchar ('\n');
    }
    else
      fprintf (stderr, "  DLT %d (not supported)\n", dlts[n_dlts]);
  }
  free (dlts);
  exit (0);
}


/************************************************************************/

int main (int argc, char **argv)
{
  static char *infile = NULL;
  static int   count  = -1;
  static int   rc     = 0;

  pcap_handler printer;
  int          op;
  u_char      *pcap_userdata;
  char         ebuf[PCAP_ERRBUF_SIZE];
  char        *cmdbuf;
  char        *cp = strrchr (argv[0], SLASH);

  if (cp)
  {
    strcpy (program_name, cp+1);
    memcpy (&program_path, argv[0], cp-argv[0]+1);
    program_path [(int)(cp+2-argv[0])] = '\0';
  }
  else
  {
    strcpy (program_name, argv[0]);
    program_path[0] = '\0';
  }
  strlwr (program_name);
  strlwr (program_path);

  opterr = 1;

  while ((op = getopt(argc,argv,"aAb:Cc:dDeLE:fF:Hi:lm:M:nNOpPqRr:s:StT:uvw:xXyh?")) != EOF)
  {
    switch (op)
    {
      case 'a':
           ++aflag;
           break;

      case 'b':
           protocol_b = eth_proto_parse (optarg);
           break;

      case 'C':
           use_conio = 1;
           if (wflag)
              PERROR (("`-C' cannot be used with `-w' flag"));
           break;

      case 'c':
           count = atoi (optarg);
           if (count <= 0)
              PERROR (("invalid packet count %s", optarg));
           break;

      case 'd':
           ++dflag;
           break;

      case 'D':
           ++Dflag;
           break;

      case 'e':
           ++eflag;
           break;

      case 'L':
           Lflag++;
           break;

      case 'E':
#ifndef USE_SSL
           warning ("crypto code not compiled in");
#endif
           espsecret = optarg;
           break;

      case 'f':
           ++fflag;
           break;

      case 'F':
           infile = optarg;
           break;

      case 'H':
           ++Hflag;
           break;

      case 'i':
           pcap_device = optarg;
           break;

      case 'l':
           setvbuf (stdout, NULL, _IOLBF, 0);
           break;

      case 'm':
#ifdef LIBSMI
           if (!smiLoadModule(optarg))
              error ("could not load MIB module %s", optarg);
           sflag = 1;
#else
           fprintf (stderr, "%s: ignoring option `-m %s' ", program_name, optarg);
           fprintf (stderr, "(no libsmi support)\n");
#endif
           break;

      case 'M':
           if (!stricmp(optarg, "oncrpc"))
                messagetype = MT_ONCRPC;
           else if (!stricmp(optarg, "giop"))
                messagetype = MT_GIOP;
           else if (!stricmp(optarg, "w3ng"))
                messagetype = MT_W3NG;
           else if (!stricmp(optarg, "http"))
                messagetype = MT_HTTP;
           else PERROR (("Legal message types are: oncrpc, giop, w3ng and http"));
           break;

      case 'n':
           ++nflag;
           break;

      case 'N':
           ++Nflag;
           break;

      case 'O':
           Oflag = 0;
           break;

      case 'p':
           ++pflag;
           break;

      case 'P':
           ++Pflag;
           break;

      case 'q':
           ++qflag;
           break;

      case 'R':
           ++Rflag;
           break;

      case 'r':
           RFileName = optarg;
           if (strpbrk(RFileName,"?*[]"))
              PERROR (("Wildcard not allowed `%s'",RFileName));
           break;

      case 's':
           snaplen = atoi (optarg);
           if (snaplen <= 0)
              PERROR (("invalid snaplen %s", optarg));
           break;

      case 'S':
           ++Sflag;
           break;

      case 't':
           --tflag;
           break;

      case 'T':
           if (!stricmp(optarg, "vat"))
                packettype = PT_VAT;
           else if (!stricmp(optarg, "wb"))
                packettype = PT_WB;
           else if (!stricmp(optarg, "rpc"))
                packettype = PT_RPC;
           else if (!stricmp(optarg, "rtp"))
                packettype = PT_RTP;
           else if (!stricmp(optarg, "rtcp"))
                packettype = PT_RTCP;
           else if (!stricmp(optarg, "snmp"))
                packettype = PT_SNMP;
           else if (!stricmp(optarg, "sunrpcrm"))
                packettype = PT_SUNRPCRM;
           else if (!stricmp(optarg, "w3mux"))
                packettype = PT_W3MUX;
           else if (!stricmp(optarg, "iiop"))
                packettype = PT_IIOP;
           else if (!stricmp(optarg, "corba"))
                packettype = PT_CORBA;
           else if (!stricmp(optarg, "anep"))
                packettype = PT_ANEP;
           else if (!stricmp(optarg, "srm2"))
                packettype = PT_SRM2;
           else if (!stricmp(optarg, "wc"))
                packettype = PT_WC;
           else if (!stricmp(optarg, "cnfp"))
                packettype = PT_CNFP;
           else PERROR (("Legal packet types are:\n  vat, wb, rpc, "
                         "rtp, rtcp, cnfp, snmp, sunrpcrm, w3mux, iiop, "
                         "corba, anep, srm2 or wc"));
           break;

      case 'u':
           ++uflag;
           break;

      case 'v':
           ++vflag;
           break;

      case 'w':
           ++wflag;
           WFileName = optarg;
           use_conio = 0;
           break;

      case 'x':
           ++xflag;
           break;

      case 'X':
           ++xflag;
           ++xaflag;
           break;

      case 'y':
           dlt_name = optarg;
           dlt = pcap_datalink_name_to_val (dlt_name);
           if (dlt < 0)
              PERROR (("invalid data link type %s", dlt_name));
           break;

      case 'A':
           Aflag++;
           xflag++;
           xaflag = 0;
           break;

      case '?':
      case 'h':
           program_usage (1);
           return (0);

      default:
           program_usage (0);
           return (0);
    }
  }

  if (aflag && nflag)
     PERROR (("-a and -n options are incompatible"));

  if (Hflag && RFileName)
     PERROR (("-H and -r options are incompatible"));

  if (dlt_name && RFileName)
     PERROR (("-y and -r options are incompatible"));

  if (Rflag && !RFileName)
     PERROR (("-R option requires -r <file> option"));

  if (fflag && RFileName)
     PERROR (("-f and -r options are incompatible"));

  if (tflag > 0)
     thiszone = gmt2local (0);

  if (!tcpdump_init(path_program("~/tcpdump.ini")))
     return (0);

  if (Dflag)
  {
    char buf[2048];

    pcap_list_devices (buf, sizeof(buf), 1);
    printf ("Supported network devices:\n%s", buf);
    return (0);
  }

  if (RFileName)
  {
    /*
     * We don't need network access, so just read the capture file
     */
    pd = pcap_open_offline (RFileName, ebuf);
    if (!pd)
       PERROR ((ebuf));

    dlt = pcap_datalink(pd);
    printf ("reading from file %s, link-type %u (", RFileName, dlt);
    dlt_name = pcap_datalink_val_to_name (dlt);
    printf ("%s)\n", dlt_name ? dlt_name : "*unknown*");

    localnet = 0;
    netmask  = 0;
    if (Rflag)
       pcap_set_wait (pd, NULL, 1);
  }
  else    /* open pcap to capture live network packets */
  {
    int i;

    if (!pcap_device)
    {
      pcap_device = pcap_lookupdev (ebuf);

⌨️ 快捷键说明

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