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

📄 tcpdump.c

📁 Windump3.6.2源代码
💻 C
字号:
/* * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 *	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. */#ifndef lintstatic const char copyright[] =    "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997\n\The Regents of the University of California.  All rights reserved.\n";static const char rcsid[] =    "@(#) $Header: /tcpdump/master/tcpdump/tcpdump.c,v 1.158 2000/12/21 10:43:24 guy Exp $ (LBL)";#endif/* * 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. */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <sys/types.h>#ifndef WIN32
#include <sys/time.h>

#include <netinet/in.h>
#else
#include "bittypes.h"
#include "getopt.h"
#include "w32_fzs.h"
extern int strcasecmp (const char *__s1, const char *__s2);
extern int SIZE_BUF;
#endif /* WIN32 */
#include <pcap.h>#include <signal.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <ctype.h>#include "interface.h"#include "addrtoname.h"#include "machdep.h"#include "setsignal.h"#include "gmt2local.h"int aflag;			/* translate network and broadcast addresses */int dflag;			/* print filter code */int eflag;			/* print ethernet header */int fflag;			/* don't translate "foreign" IP address */int nflag;			/* leave addresses as numbers */int Nflag;			/* remove domains from printed host names */int Oflag = 1;			/* run filter code optimizer */int pflag;			/* don't go promiscuous */int qflag;			/* quick (shorter) output */int Rflag = 1;			/* print sequence # field in AH/ESP*/int sflag = 0;			/* use the libsmi to translate OIDs */int Sflag;			/* print raw TCP sequence numbers */int tflag = 1;			/* print packet arrival time */int uflag = 0;			/* Print undecoded NFS handles */int vflag;			/* verbose */int xflag;			/* print packet in hex */int Xflag;			/* print packet in ascii as well as hex */char *espsecret = NULL;		/* ESP secret key */int packettype;char *program_name;int32_t thiszone;		/* seconds offset from gmt to local time *//* Forwards */static RETSIGTYPE cleanup(int);static void usage(void) __attribute__((noreturn));/* Length of saved portion of packet. */int snaplen = DEFAULT_SNAPLEN;struct printer {	pcap_handler f;	int type;};static struct printer printers[] = {	{ ether_if_print,	DLT_EN10MB },	{ token_if_print,	DLT_IEEE802 },#ifdef DLT_LANE8023	{ lane_if_print,        DLT_LANE8023 },#endif#ifdef DLT_CIP	{ cip_if_print,         DLT_CIP },#endif#ifdef DLT_ATM_CLIP	{ cip_if_print,         DLT_ATM_CLIP },#endif	{ sl_if_print,		DLT_SLIP },	{ sl_bsdos_if_print,	DLT_SLIP_BSDOS },	{ ppp_if_print,		DLT_PPP },	{ ppp_bsdos_if_print,	DLT_PPP_BSDOS },	{ fddi_if_print,	DLT_FDDI },	{ null_if_print,	DLT_NULL },#ifdef DLT_LOOP	{ null_if_print,	DLT_LOOP },#endif	{ raw_if_print,		DLT_RAW },	{ atm_if_print,		DLT_ATM_RFC1483 },#ifdef DLT_C_HDLC	{ chdlc_if_print,	DLT_C_HDLC },#endif#ifdef DLT_PPP_SERIAL	{ ppp_hdlc_if_print,    DLT_PPP_SERIAL },#endif#ifdef DLT_LINUX_SLL	{ sll_if_print,		DLT_LINUX_SLL },#endif	{ NULL,			0 },};static pcap_handlerlookup_printer(int type){	struct printer *p;	for (p = printers; p->f; ++p)		if (type == p->type)			return p->f;	error("unknown data link type %d", type);	/* NOTREACHED */}static pcap_t *pd;#ifndef WIN32
extern int optind;
extern int opterr;
extern char *optarg;
#else
__declspec( dllimport) int optind;
__declspec( dllimport) int opterr;
__declspec( dllimport) char *optarg;
#endif /* WIN32 */
intmain(int argc, char **argv){	register int cnt, op, i;	bpf_u_int32 localnet, netmask;	register char *cp, *infile, *cmdbuf, *device, *RFileName, *WFileName;	pcap_handler printer;	struct bpf_program fcode;	RETSIGTYPE (*oldhandler)(int);	u_char *pcap_userdata;	char ebuf[PCAP_ERRBUF_SIZE];
#ifdef WIN32
	char *devicet;
	int ii;
	DWORD dwVersion;
	DWORD dwWindowsMajorVersion;
	u_int UserBufferSize=1000000;

	dwVersion=GetVersion();		/* get the OS version */
	dwWindowsMajorVersion =  (DWORD)(LOBYTE(LOWORD(dwVersion)));
	if(wsockinit()!=0) return 1;
#endif /* WIN32 */
	cnt = -1;	device = NULL;	infile = NULL;	RFileName = NULL;	WFileName = NULL;	if ((cp = strrchr(argv[0], '/')) != NULL)		program_name = cp + 1;	else		program_name = argv[0];	if (abort_on_misalignment(ebuf, sizeof(ebuf)) < 0)		error("%s", ebuf);#ifdef LIBSMI	smiInit("tcpdump");#endif		opterr = 0;	while (#ifdef WIN32
	    (op = getopt(argc, argv, "a:B:c:dDeE:fF:i:lnNm:Opqr:Rs:StT:vw:xXY")) != EOF)
#else
	    (op = getopt(argc, argv, "ac:deE:fF:i:lnNm:Opqr:Rs:StT:vw:xXY")) != EOF)
#endif /* WIN32 */
		switch (op) {		case 'a':			++aflag;			break;

#ifdef WIN32
		case 'B':
			UserBufferSize = atoi(optarg)*1024;
			if (UserBufferSize < 0)
				error("invalid packet buffer size %s", optarg);
			break;
#endif /* WIN32 */		case 'c':			cnt = atoi(optarg);			if (cnt <= 0)				error("invalid packet count %s", optarg);			break;		case 'd':			++dflag;			break;
#ifdef WIN32
		case 'D':
			device = pcap_lookupdev(ebuf);
			if (device == NULL)
				error("%s", ebuf);
			PrintDeviceList(device);
			return 0;
#endif
		case 'e':			++eflag;			break;		case 'E':#ifndef HAVE_LIBCRYPTO			warning("crypto code not compiled in");#endif			espsecret = optarg;			break;		case 'f':			++fflag;			break;		case 'F':			infile = optarg;			break;		case 'i':#ifdef WIN32
			if(optarg[0]=='0' && optarg[1]==0){
				error("Invalid adapter's index");
			}
			
			devicet=NULL;

			if((i=atoi(optarg))!=0){
				if(i<0){
					error("Invalid adapter's index");
				}

				devicet = pcap_lookupdev(ebuf);
				if (devicet == NULL)
					error("%s", ebuf);
				
				device=GetAdapterFromList(devicet,i);
				if (device == NULL){
					error("Invalid adapter's index");
				}
				break;
			}
#endif
			device = optarg;
			break;
		case 'l':#ifdef HAVE_SETLINEBUF			setlinebuf(stdout);#else			setvbuf(stdout, NULL, _IOLBF, 0);#endif			break;		case 'n':			++nflag;			break;		case 'N':			++Nflag;			break;		case 'm':#ifdef LIBSMI		        if (smiLoadModule(optarg) == 0) {				error("could not load MIB module %s", optarg);		        }			sflag = 1;#else			(void)fprintf(stderr, "%s: ignoring option `-m %s' ",				      program_name, optarg);			(void)fprintf(stderr, "(no libsmi support)\n");#endif					case 'O':			Oflag = 0;			break;		case 'p':			++pflag;			break;		case 'q':			++qflag;			break;		case 'r':			RFileName = optarg;			break;		case 'R':			Rflag = 0;			break;		case 's': {			char *end;			snaplen = strtol(optarg, &end, 0);			if (optarg == end || *end != '\0'			    || snaplen < 0 || snaplen > 65535)				error("invalid snaplen %s", optarg);			else if (snaplen == 0)				snaplen = 65535;			break;		}		case 'S':			++Sflag;			break;		case 't':			--tflag;			break;		case 'T':			if (strcasecmp(optarg, "vat") == 0)				packettype = PT_VAT;			else if (strcasecmp(optarg, "wb") == 0)				packettype = PT_WB;			else if (strcasecmp(optarg, "rpc") == 0)				packettype = PT_RPC;			else if (strcasecmp(optarg, "rtp") == 0)				packettype = PT_RTP;			else if (strcasecmp(optarg, "rtcp") == 0)				packettype = PT_RTCP;			else if (strcasecmp(optarg, "snmp") == 0)				packettype = PT_SNMP;			else if (strcasecmp(optarg, "cnfp") == 0)				packettype = PT_CNFP;			else				error("unknown packet type `%s'", optarg);			break;		case 'u':			++uflag;			break;					case 'v':			++vflag;			break;		case 'w':			WFileName = optarg;			break;		case 'x':			++xflag;			break;		case 'X':    		        ++xflag;			++Xflag;			break;#ifdef YYDEBUG		case 'Y':			{			/* Undocumented flag */			extern int yydebug;			yydebug = 1;			}			break;#endif		default:			usage();			/* NOTREACHED */		}	if (aflag && nflag)		error("-a and -n options are incompatible");	if (tflag > 0)		thiszone = gmt2local(0);	if (RFileName != NULL) {		/*		 * We don't need network access, so set it back to the user id.		 * Also, this prevents the user from reading anyone's		 * trace file.		 */#ifndef WIN32
		setuid(getuid());#endif /* WIN32 */
		pd = pcap_open_offline(RFileName, ebuf);		if (pd == NULL)			error("%s", ebuf);		localnet = 0;		netmask = 0;		if (fflag != 0)			error("-f and -r options are incompatible");	} else {		if (device == NULL) {			device = pcap_lookupdev(ebuf);			if (device == NULL)				error("%s", ebuf);		}
#ifdef WIN32
		else
		{
			if (!(dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4))			/* Windows '95 */
			{
				if(device[1]!=0)
					device=(char*)SChar2WChar(device);
			}
			else{
				for (ii=0;ii<(signed)strlen(device);ii++)
				for (ii=strlen(device)-1;ii>0&&(device[ii]==' '||device[ii]=='\t');ii--)device[ii]='\0';
				for (ii=0;ii<(signed)strlen(device)&&(device[ii]==' '||device[ii]=='\t');ii++);
				strcpy(device,device+ii);
			}
		}
		PrintCapBegins (program_name,device);
#endif
		pd = pcap_open_live(device, snaplen, !pflag, 1000, ebuf);		if (pd == NULL)			error("%s", ebuf);#ifdef WIN32
		if(UserBufferSize!=1000000)
			if(pcap_setbuff(pd, UserBufferSize)==-1){
				error("%s", pcap_geterr(pd));
			}
#endif /* WIN32 */
		i = pcap_snapshot(pd);		if (snaplen < i) {			warning("snaplen raised from %d to %d", snaplen, i);			snaplen = i;		}		if (pcap_lookupnet(device, &localnet, &netmask, ebuf) < 0) {			localnet = 0;			netmask = 0;			warning("%s", ebuf);		}		/*		 * Let user own process after socket has been opened.		 */#ifndef WIN32
		setuid(getuid());#endif /* WIN32 */
	}	if (infile)		cmdbuf = read_infile(infile);	else		cmdbuf = copy_argv(&argv[optind]);	if (pcap_compile(pd, &fcode, cmdbuf, Oflag, netmask) < 0)		error("%s", pcap_geterr(pd));	if (dflag) {		bpf_dump(&fcode, dflag);#ifdef WIN32
    pcap_close(pd);
#endif /* WIN32 */
		exit(0);	}	init_addrtoname(localnet, netmask);	(void)setsignal(SIGTERM, cleanup);	(void)setsignal(SIGINT, cleanup);	/* Cooperate with nohup(1) */#ifndef WIN32	
	if ((oldhandler = setsignal(SIGHUP, cleanup)) != SIG_DFL)		(void)setsignal(SIGHUP, oldhandler);#endif /* WIN32 */
	if (pcap_setfilter(pd, &fcode) < 0)		error("%s", pcap_geterr(pd));	if (WFileName) {		pcap_dumper_t *p = pcap_dump_open(pd, WFileName);		if (p == NULL)			error("%s", pcap_geterr(pd));		printer = pcap_dump;		pcap_userdata = (u_char *)p;	} else {		printer = lookup_printer(pcap_datalink(pd));		pcap_userdata = 0;	}	if (RFileName == NULL) {#ifndef WIN32
		(void)fprintf(stderr, "%s: listening on %s\n",		    program_name, device);		(void)fflush(stderr);
#endif /* WIN32 */	}	if (pcap_loop(pd, cnt, printer, pcap_userdata) < 0) {		(void)fprintf(stderr, "%s: pcap_loop: %s\n",		    program_name, pcap_geterr(pd));		exit(1);	}	pcap_close(pd);	exit(0);}/* make a clean exit on interrupts */static RETSIGTYPEcleanup(int signo){	struct pcap_stat stat;	/* Can't print the summary if reading from a savefile */	if (pd != NULL && pcap_file(pd) == NULL) {		(void)fflush(stdout);		putc('\n', stderr);		if (pcap_stats(pd, &stat) < 0)			(void)fprintf(stderr, "pcap_stats: %s\n",			    pcap_geterr(pd));		else {			(void)fprintf(stderr, "%d packets received by filter\n",			    stat.ps_recv);			(void)fprintf(stderr, "%d packets dropped by kernel\n",			    stat.ps_drop);		}	}	exit(0);}/* Like default_print() but data need not be aligned */voiddefault_print_unaligned(register const u_char *cp, register u_int length){	register u_int i, s;	register int nshorts;	if (Xflag) {		ascii_print(cp, length);		return;	}	nshorts = (u_int) length / sizeof(u_short);	i = 0;	while (--nshorts >= 0) {		if ((i++ % 8) == 0)			(void)printf("\n\t\t\t");		s = *cp++;		(void)printf(" %02x%02x", s, *cp++);	}	if (length & 1) {		if ((i % 8) == 0)			(void)printf("\n\t\t\t");		(void)printf(" %02x", *cp);	}}/* * By default, print the packet out in hex. */voiddefault_print(register const u_char *bp, register u_int length){	default_print_unaligned(bp, length);}
#ifdef WIN32
	char WDversion[]="3.6.2";
	char version[]="3.6.2";
	char pcap_version[]="0.6.2";
	char Wpcap_version[]="2.3";
#endif
static voidusage(void){	extern char version[];	extern char pcap_version[];#ifdef WIN32
	(void)fprintf(stderr, "%s version %s, based on tcpdump version %s\n", program_name, WDversion, version);
	(void)fprintf(stderr, "WinPcap version %s, based on libpcap version %s\n",Wpcap_version, pcap_version);
#else	
	(void)fprintf(stderr, "%s version %s\n", program_name, version);	(void)fprintf(stderr, "libpcap version %s\n", pcap_version);#endif /* WIN32 */
	(void)fprintf(stderr,#ifdef WIN32
"Usage: %s [-adDeflnNOpqStuvxX] [-B size] [-c count] [ -F file ]\n", program_name);#else
"Usage: %s [-adeflnNOpqStuvxX] [-c count] [ -F file ]\n", program_name);
#endif
	(void)fprintf(stderr,"\t\t[ -i interface ] [ -r file ] [ -s snaplen ]\n");	(void)fprintf(stderr,"\t\t[ -T type ] [ -w file ] [ expression ]\n");	exit(-1);}

⌨️ 快捷键说明

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