tcpdump.c revision 98527
117680Spst/*
298527Sfenner * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
317680Spst *	The Regents of the University of California.  All rights reserved.
417680Spst *
517680Spst * Redistribution and use in source and binary forms, with or without
617680Spst * modification, are permitted provided that: (1) source code distributions
717680Spst * retain the above copyright notice and this paragraph in its entirety, (2)
817680Spst * distributions including binary code include the above copyright notice and
917680Spst * this paragraph in its entirety in the documentation or other materials
1017680Spst * provided with the distribution, and (3) all advertising materials mentioning
1117680Spst * features or use of this software display the following acknowledgement:
1217680Spst * ``This product includes software developed by the University of California,
1317680Spst * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
1417680Spst * the University nor the names of its contributors may be used to endorse
1517680Spst * or promote products derived from this software without specific prior
1617680Spst * written permission.
1717680Spst * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
1817680Spst * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
1917680Spst * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
2098527Sfenner *
2198527Sfenner * Support for splitting captures into multiple files with a maximum
2298527Sfenner * file size:
2398527Sfenner *
2498527Sfenner * Copyright (c) 2001
2598527Sfenner *	Seth Webster <swebster@sst.ll.mit.edu>
2617680Spst */
2717680Spst
2817680Spst#ifndef lint
2926180Sfennerstatic const char copyright[] =
3098527Sfenner    "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
3117680SpstThe Regents of the University of California.  All rights reserved.\n";
3226180Sfennerstatic const char rcsid[] =
3398527Sfenner    "@(#) $Header: /tcpdump/master/tcpdump/tcpdump.c,v 1.173 2001/12/22 22:12:23 guy Exp $ (LBL)";
3417680Spst#endif
3517680Spst
3656648Sarchie/* $FreeBSD: head/contrib/tcpdump/tcpdump.c 98527 2002-06-21 00:49:02Z fenner $ */
3756648Sarchie
3817680Spst/*
3917680Spst * tcpdump - monitor tcp/ip traffic on an ethernet.
4017680Spst *
4117680Spst * First written in 1987 by Van Jacobson, Lawrence Berkeley Laboratory.
4217680Spst * Mercilessly hacked and occasionally improved since then via the
4317680Spst * combined efforts of Van, Steve McCanne and Craig Leres of LBL.
4417680Spst */
4517680Spst
4656896Sfenner#ifdef HAVE_CONFIG_H
4756896Sfenner#include "config.h"
4856896Sfenner#endif
4956896Sfenner
5017680Spst#include <sys/types.h>
5117680Spst#include <sys/time.h>
5217680Spst
5317680Spst#include <netinet/in.h>
5417680Spst
5517680Spst#include <pcap.h>
5617680Spst#include <signal.h>
5717680Spst#include <stdio.h>
5817680Spst#include <stdlib.h>
5917680Spst#include <string.h>
6017680Spst#include <unistd.h>
6156896Sfenner#include <ctype.h>
6217680Spst
6356896Sfenner
6417680Spst#include "interface.h"
6517680Spst#include "addrtoname.h"
6617680Spst#include "machdep.h"
6739297Sfenner#include "setsignal.h"
6839297Sfenner#include "gmt2local.h"
6917680Spst
7039297Sfennerint aflag;			/* translate network and broadcast addresses */
7139297Sfennerint dflag;			/* print filter code */
7239297Sfennerint eflag;			/* print ethernet header */
7317680Spstint fflag;			/* don't translate "foreign" IP address */
7417680Spstint nflag;			/* leave addresses as numbers */
7517680Spstint Nflag;			/* remove domains from printed host names */
7639297Sfennerint Oflag = 1;			/* run filter code optimizer */
7717680Spstint pflag;			/* don't go promiscuous */
7817680Spstint qflag;			/* quick (shorter) output */
7956896Sfennerint Rflag = 1;			/* print sequence # field in AH/ESP*/
8056896Sfennerint sflag = 0;			/* use the libsmi to translate OIDs */
8139297Sfennerint Sflag;			/* print raw TCP sequence numbers */
8217680Spstint tflag = 1;			/* print packet arrival time */
8375118Sfennerint uflag = 0;			/* Print undecoded NFS handles */
8417680Spstint vflag;			/* verbose */
8517680Spstint xflag;			/* print packet in hex */
8656896Sfennerint Xflag;			/* print packet in ascii as well as hex */
8798527Sfenneroff_t Cflag = 0;                /* rotate dump files after this many bytes */
8839297Sfenner
8956896Sfennerchar *espsecret = NULL;		/* ESP secret key */
9056896Sfenner
9117680Spstint packettype;
9217680Spst
9398527Sfennerint infodelay;
9498527Sfennerint infoprint;
9517680Spst
9617680Spstchar *program_name;
9717680Spst
9817680Spstint32_t thiszone;		/* seconds offset from gmt to local time */
9917680Spst
10017680Spst/* Forwards */
10175118Sfennerstatic RETSIGTYPE cleanup(int);
10275118Sfennerstatic void usage(void) __attribute__((noreturn));
10317680Spst
10498527Sfennerstatic void dump_and_trunc(u_char *, const struct pcap_pkthdr *, const u_char *);
10598527Sfenner
10698527Sfenner#ifdef SIGINFO
10798527SfennerRETSIGTYPE requestinfo(int);
10898527Sfenner#endif
10998527Sfenner
11017680Spst/* Length of saved portion of packet. */
11117680Spstint snaplen = DEFAULT_SNAPLEN;
11217680Spst
11317680Spststruct printer {
11417680Spst	pcap_handler f;
11517680Spst	int type;
11617680Spst};
11717680Spst
11817680Spststatic struct printer printers[] = {
11998527Sfenner	{ arcnet_if_print,	DLT_ARCNET },
12017680Spst	{ ether_if_print,	DLT_EN10MB },
12144165Sjulian	{ token_if_print,	DLT_IEEE802 },
12256896Sfenner#ifdef DLT_LANE8023
12356896Sfenner	{ lane_if_print,        DLT_LANE8023 },
12456896Sfenner#endif
12556896Sfenner#ifdef DLT_CIP
12656896Sfenner	{ cip_if_print,         DLT_CIP },
12756896Sfenner#endif
12875118Sfenner#ifdef DLT_ATM_CLIP
12975118Sfenner	{ cip_if_print,         DLT_ATM_CLIP },
13075118Sfenner#endif
13117680Spst	{ sl_if_print,		DLT_SLIP },
13239297Sfenner	{ sl_bsdos_if_print,	DLT_SLIP_BSDOS },
13317680Spst	{ ppp_if_print,		DLT_PPP },
13439297Sfenner	{ ppp_bsdos_if_print,	DLT_PPP_BSDOS },
13517680Spst	{ fddi_if_print,	DLT_FDDI },
13617680Spst	{ null_if_print,	DLT_NULL },
13775118Sfenner#ifdef DLT_LOOP
13875118Sfenner	{ null_if_print,	DLT_LOOP },
13975118Sfenner#endif
14039297Sfenner	{ raw_if_print,		DLT_RAW },
14117680Spst	{ atm_if_print,		DLT_ATM_RFC1483 },
14275118Sfenner#ifdef DLT_C_HDLC
14375118Sfenner	{ chdlc_if_print,	DLT_C_HDLC },
14456896Sfenner#endif
14598527Sfenner#ifdef DLT_HDLC
14698527Sfenner	{ chdlc_if_print,	DLT_HDLC },
14798527Sfenner#endif
14875118Sfenner#ifdef DLT_PPP_SERIAL
14975118Sfenner	{ ppp_hdlc_if_print,    DLT_PPP_SERIAL },
15075118Sfenner#endif
15198527Sfenner#ifdef DLT_PPP_ETHER
15298527Sfenner	{ pppoe_if_print,	DLT_PPP_ETHER },
15398527Sfenner#endif
15475118Sfenner#ifdef DLT_LINUX_SLL
15575118Sfenner	{ sll_if_print,		DLT_LINUX_SLL },
15675118Sfenner#endif
15798527Sfenner#ifdef DLT_IEEE802_11
15898527Sfenner	{ ieee802_11_if_print,	DLT_IEEE802_11},
15998527Sfenner#endif
16098527Sfenner#ifdef DLT_LTALK
16198527Sfenner	{ ltalk_if_print,	DLT_LTALK },
16298527Sfenner#endif
16317680Spst	{ NULL,			0 },
16417680Spst};
16517680Spst
16617680Spststatic pcap_handler
16717680Spstlookup_printer(int type)
16817680Spst{
16917680Spst	struct printer *p;
17017680Spst
17117680Spst	for (p = printers; p->f; ++p)
17217680Spst		if (type == p->type)
17317680Spst			return p->f;
17417680Spst
17575118Sfenner	error("unknown data link type %d", type);
17617680Spst	/* NOTREACHED */
17717680Spst}
17817680Spst
17917680Spststatic pcap_t *pd;
18017680Spst
18117680Spstextern int optind;
18217680Spstextern int opterr;
18317680Spstextern char *optarg;
18417680Spst
18598527Sfennerstruct dump_info {
18698527Sfenner	char	*WFileName;
18798527Sfenner	pcap_t	*pd;
18898527Sfenner	pcap_dumper_t *p;
18998527Sfenner};
19098527Sfenner
19117680Spstint
19217680Spstmain(int argc, char **argv)
19317680Spst{
19417680Spst	register int cnt, op, i;
19517680Spst	bpf_u_int32 localnet, netmask;
19617680Spst	register char *cp, *infile, *cmdbuf, *device, *RFileName, *WFileName;
19717680Spst	pcap_handler printer;
19817680Spst	struct bpf_program fcode;
19939297Sfenner	RETSIGTYPE (*oldhandler)(int);
20098527Sfenner	struct dump_info dumpinfo;
20117680Spst	u_char *pcap_userdata;
20217680Spst	char ebuf[PCAP_ERRBUF_SIZE];
20317680Spst
20417680Spst	cnt = -1;
20517680Spst	device = NULL;
20617680Spst	infile = NULL;
20717680Spst	RFileName = NULL;
20817680Spst	WFileName = NULL;
20917680Spst	if ((cp = strrchr(argv[0], '/')) != NULL)
21017680Spst		program_name = cp + 1;
21117680Spst	else
21217680Spst		program_name = argv[0];
21317680Spst
21475118Sfenner	if (abort_on_misalignment(ebuf, sizeof(ebuf)) < 0)
21526180Sfenner		error("%s", ebuf);
21617680Spst
21756896Sfenner#ifdef LIBSMI
21856896Sfenner	smiInit("tcpdump");
21956896Sfenner#endif
22056896Sfenner
22117680Spst	opterr = 0;
22239297Sfenner	while (
22398527Sfenner	    (op = getopt(argc, argv, "ac:C:deE:fF:i:lm:nNOpqr:Rs:StT:uvw:xXY")) != -1)
22417680Spst		switch (op) {
22539297Sfenner
22639297Sfenner		case 'a':
22739297Sfenner			++aflag;
22839297Sfenner			break;
22939297Sfenner
23017680Spst		case 'c':
23117680Spst			cnt = atoi(optarg);
23217680Spst			if (cnt <= 0)
23317680Spst				error("invalid packet count %s", optarg);
23417680Spst			break;
23517680Spst
23698527Sfenner		case 'C':
23798527Sfenner			Cflag = atoi(optarg) * 1000000;
23898527Sfenner			if (Cflag < 0)
23998527Sfenner				error("invalid file size %s", optarg);
24098527Sfenner			break;
24198527Sfenner
24217680Spst		case 'd':
24317680Spst			++dflag;
24417680Spst			break;
24517680Spst
24617680Spst		case 'e':
24717680Spst			++eflag;
24817680Spst			break;
24917680Spst
25056896Sfenner		case 'E':
25175118Sfenner#ifndef HAVE_LIBCRYPTO
25256896Sfenner			warning("crypto code not compiled in");
25356896Sfenner#endif
25456896Sfenner			espsecret = optarg;
25556896Sfenner			break;
25656896Sfenner
25717680Spst		case 'f':
25817680Spst			++fflag;
25917680Spst			break;
26017680Spst
26117680Spst		case 'F':
26217680Spst			infile = optarg;
26317680Spst			break;
26417680Spst
26517680Spst		case 'i':
26617680Spst			device = optarg;
26717680Spst			break;
26817680Spst
26917680Spst		case 'l':
27017680Spst#ifdef HAVE_SETLINEBUF
27117680Spst			setlinebuf(stdout);
27217680Spst#else
27317680Spst			setvbuf(stdout, NULL, _IOLBF, 0);
27417680Spst#endif
27517680Spst			break;
27617680Spst
27717680Spst		case 'n':
27817680Spst			++nflag;
27917680Spst			break;
28017680Spst
28117680Spst		case 'N':
28217680Spst			++Nflag;
28317680Spst			break;
28417680Spst
28556896Sfenner		case 'm':
28656896Sfenner#ifdef LIBSMI
28756896Sfenner		        if (smiLoadModule(optarg) == 0) {
28856896Sfenner				error("could not load MIB module %s", optarg);
28956896Sfenner		        }
29056896Sfenner			sflag = 1;
29156896Sfenner#else
29256896Sfenner			(void)fprintf(stderr, "%s: ignoring option `-m %s' ",
29356896Sfenner				      program_name, optarg);
29456896Sfenner			(void)fprintf(stderr, "(no libsmi support)\n");
29556896Sfenner#endif
29656896Sfenner
29717680Spst		case 'O':
29817680Spst			Oflag = 0;
29917680Spst			break;
30017680Spst
30117680Spst		case 'p':
30217680Spst			++pflag;
30317680Spst			break;
30417680Spst
30517680Spst		case 'q':
30617680Spst			++qflag;
30717680Spst			break;
30817680Spst
30917680Spst		case 'r':
31017680Spst			RFileName = optarg;
31117680Spst			break;
31217680Spst
31356896Sfenner		case 'R':
31456896Sfenner			Rflag = 0;
31556896Sfenner			break;
31656896Sfenner
31775118Sfenner		case 's': {
31875118Sfenner			char *end;
31975118Sfenner
32075118Sfenner			snaplen = strtol(optarg, &end, 0);
32175118Sfenner			if (optarg == end || *end != '\0'
32275118Sfenner			    || snaplen < 0 || snaplen > 65535)
32317680Spst				error("invalid snaplen %s", optarg);
32475118Sfenner			else if (snaplen == 0)
32575118Sfenner				snaplen = 65535;
32617680Spst			break;
32775118Sfenner		}
32817680Spst
32917680Spst		case 'S':
33017680Spst			++Sflag;
33117680Spst			break;
33217680Spst
33317680Spst		case 't':
33417680Spst			--tflag;
33517680Spst			break;
33617680Spst
33717680Spst		case 'T':
33817680Spst			if (strcasecmp(optarg, "vat") == 0)
33917680Spst				packettype = PT_VAT;
34017680Spst			else if (strcasecmp(optarg, "wb") == 0)
34117680Spst				packettype = PT_WB;
34217680Spst			else if (strcasecmp(optarg, "rpc") == 0)
34317680Spst				packettype = PT_RPC;
34417680Spst			else if (strcasecmp(optarg, "rtp") == 0)
34517680Spst				packettype = PT_RTP;
34617680Spst			else if (strcasecmp(optarg, "rtcp") == 0)
34717680Spst				packettype = PT_RTCP;
34856896Sfenner			else if (strcasecmp(optarg, "snmp") == 0)
34956896Sfenner				packettype = PT_SNMP;
35075118Sfenner			else if (strcasecmp(optarg, "cnfp") == 0)
35175118Sfenner				packettype = PT_CNFP;
35217680Spst			else
35317680Spst				error("unknown packet type `%s'", optarg);
35417680Spst			break;
35517680Spst
35675118Sfenner		case 'u':
35775118Sfenner			++uflag;
35875118Sfenner			break;
35975118Sfenner
36017680Spst		case 'v':
36117680Spst			++vflag;
36217680Spst			break;
36317680Spst
36417680Spst		case 'w':
36517680Spst			WFileName = optarg;
36617680Spst			break;
36756896Sfenner
36856896Sfenner		case 'x':
36956896Sfenner			++xflag;
37056896Sfenner			break;
37156896Sfenner
37256896Sfenner		case 'X':
37375118Sfenner    		        ++xflag;
37456896Sfenner			++Xflag;
37556896Sfenner			break;
37656896Sfenner
37717680Spst#ifdef YYDEBUG
37817680Spst		case 'Y':
37917680Spst			{
38017680Spst			/* Undocumented flag */
38117680Spst			extern int yydebug;
38217680Spst			yydebug = 1;
38317680Spst			}
38417680Spst			break;
38517680Spst#endif
38617680Spst		default:
38717680Spst			usage();
38817680Spst			/* NOTREACHED */
38917680Spst		}
39017680Spst
39139297Sfenner	if (aflag && nflag)
39239297Sfenner		error("-a and -n options are incompatible");
39339297Sfenner
39417680Spst	if (tflag > 0)
39539297Sfenner		thiszone = gmt2local(0);
39617680Spst
39717680Spst	if (RFileName != NULL) {
39817680Spst		/*
39917680Spst		 * We don't need network access, so set it back to the user id.
40017680Spst		 * Also, this prevents the user from reading anyone's
40117680Spst		 * trace file.
40217680Spst		 */
40317680Spst		setuid(getuid());
40417680Spst
40517680Spst		pd = pcap_open_offline(RFileName, ebuf);
40617680Spst		if (pd == NULL)
40726180Sfenner			error("%s", ebuf);
40817680Spst		localnet = 0;
40917680Spst		netmask = 0;
41017680Spst		if (fflag != 0)
41117680Spst			error("-f and -r options are incompatible");
41217680Spst	} else {
41317680Spst		if (device == NULL) {
41417680Spst			device = pcap_lookupdev(ebuf);
41517680Spst			if (device == NULL)
41626180Sfenner				error("%s", ebuf);
41717680Spst		}
41898527Sfenner		*ebuf = '\0';
41917680Spst		pd = pcap_open_live(device, snaplen, !pflag, 1000, ebuf);
42017680Spst		if (pd == NULL)
42126180Sfenner			error("%s", ebuf);
42298527Sfenner		else if (*ebuf)
42398527Sfenner			warning("%s", ebuf);
42417680Spst		i = pcap_snapshot(pd);
42517680Spst		if (snaplen < i) {
42617680Spst			warning("snaplen raised from %d to %d", snaplen, i);
42717680Spst			snaplen = i;
42817680Spst		}
42939297Sfenner		if (pcap_lookupnet(device, &localnet, &netmask, ebuf) < 0) {
43039297Sfenner			localnet = 0;
43139297Sfenner			netmask = 0;
43239297Sfenner			warning("%s", ebuf);
43339297Sfenner		}
43417680Spst		/*
43517680Spst		 * Let user own process after socket has been opened.
43617680Spst		 */
43717680Spst		setuid(getuid());
43817680Spst	}
43917680Spst	if (infile)
44017680Spst		cmdbuf = read_infile(infile);
44117680Spst	else
44217680Spst		cmdbuf = copy_argv(&argv[optind]);
44317680Spst
44417680Spst	if (pcap_compile(pd, &fcode, cmdbuf, Oflag, netmask) < 0)
44526180Sfenner		error("%s", pcap_geterr(pd));
44617680Spst	if (dflag) {
44717680Spst		bpf_dump(&fcode, dflag);
44817680Spst		exit(0);
44917680Spst	}
45039297Sfenner	init_addrtoname(localnet, netmask);
45117680Spst
45239297Sfenner	(void)setsignal(SIGTERM, cleanup);
45339297Sfenner	(void)setsignal(SIGINT, cleanup);
45439297Sfenner	/* Cooperate with nohup(1) */
45539297Sfenner	if ((oldhandler = setsignal(SIGHUP, cleanup)) != SIG_DFL)
45639297Sfenner		(void)setsignal(SIGHUP, oldhandler);
45717680Spst
45817680Spst	if (pcap_setfilter(pd, &fcode) < 0)
45926180Sfenner		error("%s", pcap_geterr(pd));
46017680Spst	if (WFileName) {
46117680Spst		pcap_dumper_t *p = pcap_dump_open(pd, WFileName);
46217680Spst		if (p == NULL)
46326180Sfenner			error("%s", pcap_geterr(pd));
46498527Sfenner		if (Cflag != 0) {
46598527Sfenner			printer = dump_and_trunc;
46698527Sfenner			dumpinfo.WFileName = WFileName;
46798527Sfenner			dumpinfo.pd = pd;
46898527Sfenner			dumpinfo.p = p;
46998527Sfenner			pcap_userdata = (u_char *)&dumpinfo;
47098527Sfenner		} else {
47198527Sfenner			printer = pcap_dump;
47298527Sfenner			pcap_userdata = (u_char *)p;
47398527Sfenner		}
47417680Spst	} else {
47517680Spst		printer = lookup_printer(pcap_datalink(pd));
47617680Spst		pcap_userdata = 0;
47798527Sfenner#ifdef SIGINFO
47898527Sfenner		(void)setsignal(SIGINFO, requestinfo);
47998527Sfenner#endif
48017680Spst	}
48117680Spst	if (RFileName == NULL) {
48217680Spst		(void)fprintf(stderr, "%s: listening on %s\n",
48317680Spst		    program_name, device);
48417680Spst		(void)fflush(stderr);
48517680Spst	}
48617680Spst	if (pcap_loop(pd, cnt, printer, pcap_userdata) < 0) {
48717680Spst		(void)fprintf(stderr, "%s: pcap_loop: %s\n",
48817680Spst		    program_name, pcap_geterr(pd));
48917680Spst		exit(1);
49017680Spst	}
49198527Sfenner	if (RFileName == NULL)
49298527Sfenner		info(1);
49317680Spst	pcap_close(pd);
49417680Spst	exit(0);
49517680Spst}
49617680Spst
49717680Spst/* make a clean exit on interrupts */
49875118Sfennerstatic RETSIGTYPE
49917680Spstcleanup(int signo)
50017680Spst{
50117680Spst
50217680Spst	/* Can't print the summary if reading from a savefile */
50317680Spst	if (pd != NULL && pcap_file(pd) == NULL) {
50417680Spst		(void)fflush(stdout);
50517680Spst		putc('\n', stderr);
50698527Sfenner		info(1);
50717680Spst	}
50817680Spst	exit(0);
50917680Spst}
51017680Spst
51198527Sfennervoid
51298527Sfennerinfo(register int verbose)
51398527Sfenner{
51498527Sfenner	struct pcap_stat stat;
51598527Sfenner
51698527Sfenner	if (pcap_stats(pd, &stat) < 0) {
51798527Sfenner		(void)fprintf(stderr, "pcap_stats: %s\n", pcap_geterr(pd));
51898527Sfenner		return;
51998527Sfenner	}
52098527Sfenner	if (!verbose)
52198527Sfenner		fprintf(stderr, "%s: ", program_name);
52298527Sfenner	(void)fprintf(stderr, "%d packets received by filter", stat.ps_recv);
52398527Sfenner	if (!verbose)
52498527Sfenner		fputs(", ", stderr);
52598527Sfenner	else
52698527Sfenner		putc('\n', stderr);
52798527Sfenner	(void)fprintf(stderr, "%d packets dropped by kernel\n", stat.ps_drop);
52898527Sfenner	infoprint = 0;
52998527Sfenner}
53098527Sfenner
53198527Sfennerstatic void
53298527Sfennerreverse(char *s)
53398527Sfenner{
53498527Sfenner	int i, j, c;
53598527Sfenner
53698527Sfenner	for (i = 0, j = strlen(s) - 1; i < j; i++, j--) {
53798527Sfenner		c = s[i];
53898527Sfenner		s[i] = s[j];
53998527Sfenner		s[j] = c;
54098527Sfenner	}
54198527Sfenner}
54298527Sfenner
54398527Sfenner
54498527Sfennerstatic void
54598527Sfennerswebitoa(unsigned int n, char *s)
54698527Sfenner{
54798527Sfenner	unsigned int i;
54898527Sfenner
54998527Sfenner	i = 0;
55098527Sfenner	do {
55198527Sfenner		s[i++] = n % 10 + '0';
55298527Sfenner	} while ((n /= 10) > 0);
55398527Sfenner
55498527Sfenner	s[i] = '\0';
55598527Sfenner	reverse(s);
55698527Sfenner}
55798527Sfenner
55898527Sfennerstatic void
55998527Sfennerdump_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
56098527Sfenner{
56198527Sfenner	struct dump_info *info;
56298527Sfenner	static uint cnt = 2;
56398527Sfenner	char *name;
56498527Sfenner
56598527Sfenner	info = (struct dump_info *)user;
56698527Sfenner
56798527Sfenner	/*
56898527Sfenner	 * XXX - this won't prevent capture files from getting
56998527Sfenner	 * larger than Cflag - the last packet written to the
57098527Sfenner	 * file could put it over Cflag.
57198527Sfenner	 */
57298527Sfenner	if (ftell((FILE *)info->p) > Cflag) {
57398527Sfenner		name = (char *) malloc(strlen(info->WFileName) + 4);
57498527Sfenner		if (name == NULL)
57598527Sfenner			error("dump_and_trunc: malloc");
57698527Sfenner		strcpy(name, info->WFileName);
57798527Sfenner		swebitoa(cnt, name + strlen(info->WFileName));
57898527Sfenner		cnt++;
57998527Sfenner		pcap_dump_close(info->p);
58098527Sfenner		info->p = pcap_dump_open(info->pd, name);
58198527Sfenner		free(name);
58298527Sfenner		if (info->p == NULL)
58398527Sfenner			error("%s", pcap_geterr(pd));
58498527Sfenner	}
58598527Sfenner
58698527Sfenner	pcap_dump((u_char *)info->p, h, sp);
58798527Sfenner}
58898527Sfenner
58917680Spst/* Like default_print() but data need not be aligned */
59017680Spstvoid
59117680Spstdefault_print_unaligned(register const u_char *cp, register u_int length)
59217680Spst{
59317680Spst	register u_int i, s;
59417680Spst	register int nshorts;
59517680Spst
59656648Sarchie	if (Xflag) {
59756896Sfenner		ascii_print(cp, length);
59856896Sfenner		return;
59917680Spst	}
60056896Sfenner	nshorts = (u_int) length / sizeof(u_short);
60156896Sfenner	i = 0;
60256896Sfenner	while (--nshorts >= 0) {
60356896Sfenner		if ((i++ % 8) == 0)
60456896Sfenner			(void)printf("\n\t\t\t");
60556896Sfenner		s = *cp++;
60656896Sfenner		(void)printf(" %02x%02x", s, *cp++);
60756896Sfenner	}
60856896Sfenner	if (length & 1) {
60956896Sfenner		if ((i % 8) == 0)
61056896Sfenner			(void)printf("\n\t\t\t");
61156896Sfenner		(void)printf(" %02x", *cp);
61256896Sfenner	}
61317680Spst}
61417680Spst
61539297Sfenner/*
61639297Sfenner * By default, print the packet out in hex.
61739297Sfenner */
61817680Spstvoid
61917680Spstdefault_print(register const u_char *bp, register u_int length)
62017680Spst{
62156896Sfenner	default_print_unaligned(bp, length);
62217680Spst}
62317680Spst
62498527Sfenner#ifdef SIGINFO
62598527SfennerRETSIGTYPE requestinfo(int signo)
62698527Sfenner{
62798527Sfenner	if (infodelay)
62898527Sfenner		++infoprint;
62998527Sfenner	else
63098527Sfenner		info(0);
63198527Sfenner}
63298527Sfenner#endif
63398527Sfenner
63475118Sfennerstatic void
63526180Sfennerusage(void)
63617680Spst{
63717680Spst	extern char version[];
63839297Sfenner	extern char pcap_version[];
63917680Spst
64039297Sfenner	(void)fprintf(stderr, "%s version %s\n", program_name, version);
64139297Sfenner	(void)fprintf(stderr, "libpcap version %s\n", pcap_version);
64217680Spst	(void)fprintf(stderr,
64398527Sfenner"Usage: %s [-adeflnNOpqRStuvxX] [ -c count ] [ -C file_size ]\n", program_name);
64417680Spst	(void)fprintf(stderr,
64598527Sfenner"\t\t[ -F file ] [ -i interface ] [ -r file ] [ -s snaplen ]\n");
64617680Spst	(void)fprintf(stderr,
64798527Sfenner"\t\t[ -T type ] [ -w file ] [ -E algo:secret ] [ expression ]\n");
64898527Sfenner	exit(1);
64917680Spst}
650