📄 tcpdump.c
字号:
/*
* 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 + -