GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/tcpdump/tcpdump.c Lines: 0 290 0.0 %
Date: 2017-11-07 Branches: 0 194 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: tcpdump.c,v 1.80 2017/09/08 19:10:57 brynet Exp $	*/
2
3
/*
4
 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
5
 *	The Regents of the University of California.  All rights reserved.
6
 *
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that: (1) source code distributions
9
 * retain the above copyright notice and this paragraph in its entirety, (2)
10
 * distributions including binary code include the above copyright notice and
11
 * this paragraph in its entirety in the documentation or other materials
12
 * provided with the distribution, and (3) all advertising materials mentioning
13
 * features or use of this software display the following acknowledgement:
14
 * ``This product includes software developed by the University of California,
15
 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
16
 * the University nor the names of its contributors may be used to endorse
17
 * or promote products derived from this software without specific prior
18
 * written permission.
19
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
20
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
21
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22
 */
23
24
/*
25
 * tcpdump - monitor tcp/ip traffic on an ethernet.
26
 *
27
 * First written in 1987 by Van Jacobson, Lawrence Berkeley Laboratory.
28
 * Mercilessly hacked and occasionally improved since then via the
29
 * combined efforts of Van, Steve McCanne and Craig Leres of LBL.
30
 */
31
32
#include <sys/types.h>
33
#include <sys/time.h>
34
#include <sys/ioctl.h>
35
#include <sys/wait.h>
36
37
#include <netinet/in.h>
38
39
#include <pcap.h>
40
#include <signal.h>
41
#include <stdio.h>
42
#include <stdlib.h>
43
#include <string.h>
44
#include <unistd.h>
45
#include <limits.h>
46
#include <ctype.h>
47
#include <err.h>
48
#include <errno.h>
49
50
#include "interface.h"
51
#include "addrtoname.h"
52
#include "setsignal.h"
53
#include "gmt2local.h"
54
55
#include <sys/socket.h>
56
#include <net/if.h>
57
#include <net/pfvar.h>
58
#include "pfctl.h"
59
#include "pfctl_parser.h"
60
#include "privsep.h"
61
62
int Aflag;			/* dump ascii */
63
int aflag;			/* translate network and broadcast addresses */
64
int dflag;			/* print filter code */
65
int eflag;			/* print ethernet header */
66
int fflag;			/* don't translate "foreign" IP address */
67
int Iflag;			/* include interface in output */
68
int Lflag;			/* List available link types */
69
int nflag;			/* leave addresses as numbers */
70
int Nflag;			/* remove domains from printed host names */
71
int Oflag = 1;			/* run filter code optimizer */
72
int oflag;			/* print passive OS fingerprints */
73
int pflag;			/* don't go promiscuous */
74
int qflag;			/* quick (shorter) output */
75
int Sflag;			/* print raw TCP sequence numbers */
76
int tflag = 1;			/* print packet arrival time */
77
int vflag;			/* verbose */
78
int xflag;			/* print packet in hex */
79
int Xflag;			/* print packet in emacs-hexl style */
80
81
int packettype;
82
83
char *program_name;
84
char *device = NULL;
85
86
int32_t thiszone;		/* seconds offset from gmt to local time */
87
88
extern volatile pid_t child_pid;
89
90
/* Externs */
91
extern void bpf_dump(struct bpf_program *, int);
92
extern int esp_init(char *);
93
94
/* Forwards */
95
void	cleanup(int);
96
void	gotchld(int);
97
extern __dead void usage(void);
98
99
/* Length of saved portion of packet. */
100
int snaplen = 0;
101
102
struct printer {
103
	pcap_handler f;
104
	int type;
105
};
106
107
/* XXX needed if using old bpf.h */
108
#ifndef DLT_ATM_RFC1483
109
#define DLT_ATM_RFC1483 11
110
#endif
111
112
static struct printer printers[] = {
113
	{ ether_if_print,		DLT_EN10MB },
114
	{ ether_if_print,		DLT_IEEE802 },
115
	{ sl_if_print,			DLT_SLIP },
116
	{ sl_bsdos_if_print,		DLT_SLIP_BSDOS },
117
	{ ppp_if_print,			DLT_PPP },
118
	{ fddi_if_print,		DLT_FDDI },
119
	{ null_if_print,		DLT_NULL },
120
	{ raw_if_print,			DLT_RAW },
121
	{ atm_if_print,			DLT_ATM_RFC1483 },
122
	{ loop_if_print,		DLT_LOOP },
123
	{ enc_if_print,			DLT_ENC },
124
	{ pflog_if_print,		DLT_PFLOG },
125
	{ pfsync_if_print,		DLT_PFSYNC },
126
	{ ppp_ether_if_print,		DLT_PPP_ETHER },
127
	{ ieee802_11_if_print,		DLT_IEEE802_11 },
128
	{ ieee802_11_radio_if_print,	DLT_IEEE802_11_RADIO },
129
	{ ofp_if_print,			DLT_OPENFLOW },
130
	{ NULL,				0 },
131
};
132
133
static pcap_handler
134
lookup_printer(int type)
135
{
136
	struct printer *p;
137
138
	for (p = printers; p->f; ++p) {
139
		if (type == p->type)
140
			return p->f;
141
	}
142
143
	error("unknown data link type 0x%x", type);
144
	/* NOTREACHED */
145
}
146
147
static int
148
init_pfosfp(void)
149
{
150
	pf_osfp_initialize();
151
	if (pfctl_file_fingerprints(-1,
152
	    PF_OPT_QUIET|PF_OPT_NOACTION, PF_OSFP_FILE) == 0)
153
		return 1;
154
	return 0;
155
}
156
157
static pcap_t *pd;
158
159
/* Multiple DLT support */
160
void		 pcap_list_linktypes(pcap_t *);
161
void		 pcap_print_linktype(u_int);
162
163
void
164
pcap_print_linktype(u_int dlt)
165
{
166
	const char *name;
167
168
	if ((name = pcap_datalink_val_to_name(dlt)) != NULL)
169
		fprintf(stderr, "%s\n", name);
170
	else
171
		fprintf(stderr, "<unknown: %u>\n", dlt);
172
}
173
174
void
175
pcap_list_linktypes(pcap_t *p)
176
{
177
	int fd = p->fd;
178
	u_int n;
179
180
#define MAXDLT	100
181
182
	u_int dltlist[MAXDLT];
183
	struct bpf_dltlist dl = {MAXDLT, dltlist};
184
185
	if (fd < 0)
186
		error("Invalid bpf descriptor");
187
188
	if (ioctl(fd, BIOCGDLTLIST, &dl) < 0)
189
		err(1, "BIOCGDLTLIST");
190
191
	if (dl.bfl_len > MAXDLT)
192
		error("Invalid number of linktypes: %u", dl.bfl_len);
193
194
	fprintf(stderr, "%d link type%s supported:\n", dl.bfl_len,
195
	    dl.bfl_len == 1 ? "" : "s");
196
197
	for (n = 0; n < dl.bfl_len; n++) {
198
		fprintf(stderr, "\t");
199
		pcap_print_linktype(dltlist[n]);
200
	}
201
}
202
203
int
204
main(int argc, char **argv)
205
{
206
	int cnt = -1, op, i;
207
	bpf_u_int32 localnet, netmask;
208
	char *cp, *infile = NULL, *RFileName = NULL;
209
	char ebuf[PCAP_ERRBUF_SIZE], *WFileName = NULL;
210
	pcap_handler printer;
211
	struct bpf_program *fcode;
212
	u_char *pcap_userdata;
213
	u_int dirfilt = 0, dlt = (u_int) -1;
214
	const char *errstr;
215
216
	if ((cp = strrchr(argv[0], '/')) != NULL)
217
		program_name = cp + 1;
218
	else
219
		program_name = argv[0];
220
221
	/* '-P' used internally, exec privileged portion */
222
	if (argc >= 2 && strcmp("-P", argv[1]) == 0)
223
		priv_exec(argc, argv);
224
225
	if (priv_init(argc, argv))
226
		error("Failed to setup privsep");
227
228
	/* state: STATE_INIT */
229
230
	opterr = 0;
231
	while ((op = getopt(argc, argv,
232
	    "Aac:D:deE:fF:i:IlLnNOopqr:s:StT:vw:xXy:Y")) != -1)
233
		switch (op) {
234
235
		case 'A':
236
			xflag = 1;
237
			Aflag = 1;
238
			break;
239
240
		case 'a':
241
			aflag = 1;
242
			break;
243
244
		case 'c':
245
			cnt = strtonum(optarg, 1, INT_MAX, &errstr);
246
			if (errstr)
247
				error("invalid packet count %s: %s",
248
				    optarg, errstr);
249
			break;
250
251
		case 'D':
252
			if (strcasecmp(optarg, "in") == 0)
253
				dirfilt = BPF_DIRECTION_OUT;
254
			else if (strcasecmp(optarg, "out") == 0)
255
				dirfilt = BPF_DIRECTION_IN;
256
			else
257
				error("invalid traffic direction %s", optarg);
258
			break;
259
260
		case 'd':
261
			++dflag;
262
			break;
263
		case 'e':
264
			eflag = 1;
265
			break;
266
267
		case 'f':
268
			fflag = 1;
269
			break;
270
271
		case 'F':
272
			infile = optarg;
273
			break;
274
275
		case 'i':
276
			device = optarg;
277
			break;
278
279
		case 'I':
280
			Iflag = 1;
281
			break;
282
283
		case 'l':
284
			setvbuf(stdout, NULL, _IOLBF, 0);
285
			break;
286
		case 'L':
287
			Lflag = 1;
288
			break;
289
		case 'n':
290
			nflag = 1;
291
			break;
292
293
		case 'N':
294
			Nflag = 1;
295
			break;
296
297
		case 'O':
298
			Oflag = 0;
299
			break;
300
301
		case 'o':
302
			oflag = 1;
303
			break;
304
305
		case 'p':
306
			pflag = 1;
307
			break;
308
309
		case 'q':
310
			qflag = 1;
311
			break;
312
313
		case 'r':
314
			RFileName = optarg;
315
			break;
316
317
		case 's':
318
			snaplen = strtonum(optarg, 1, INT_MAX, &errstr);
319
			if (errstr)
320
				error("invalid snaplen %s: %s", optarg, errstr);
321
			break;
322
323
		case 'S':
324
			Sflag = 1;
325
			break;
326
327
		case 't':
328
			--tflag;
329
			break;
330
331
		case 'T':
332
			if (strcasecmp(optarg, "vat") == 0)
333
				packettype = PT_VAT;
334
			else if (strcasecmp(optarg, "wb") == 0)
335
				packettype = PT_WB;
336
			else if (strcasecmp(optarg, "rpc") == 0)
337
				packettype = PT_RPC;
338
			else if (strcasecmp(optarg, "rtp") == 0)
339
				packettype = PT_RTP;
340
			else if (strcasecmp(optarg, "rtcp") == 0)
341
				packettype = PT_RTCP;
342
			else if (strcasecmp(optarg, "cnfp") == 0)
343
				packettype = PT_CNFP;
344
			else if (strcasecmp(optarg, "vrrp") == 0)
345
				packettype = PT_VRRP;
346
			else if (strcasecmp(optarg, "tcp") == 0)
347
				packettype = PT_TCP;
348
			else if (strcasecmp(optarg, "sack") == 0)
349
				/*
350
				 * kept for compatibility; DEFAULT_SNAPLEN
351
				 * used to be too short to capture SACK.
352
				 */
353
				;
354
			else
355
				error("unknown packet type `%s'", optarg);
356
			break;
357
358
		case 'v':
359
			++vflag;
360
			break;
361
362
		case 'w':
363
			WFileName = optarg;
364
			break;
365
#ifdef YYDEBUG
366
		case 'Y':
367
			{
368
			/* Undocumented flag */
369
			extern int yydebug;
370
			yydebug = 1;
371
			}
372
			break;
373
#endif
374
		case 'y':
375
			i = pcap_datalink_name_to_val(optarg);
376
			if (i < 0)
377
				error("invalid data link type: %s", optarg);
378
			dlt = (u_int)i;
379
			break;
380
381
		case 'x':
382
			xflag = 1;
383
			break;
384
385
		case 'X':
386
			Xflag = 1;
387
			xflag = 1;
388
			break;
389
390
		case 'E':
391
			if (esp_init(optarg) < 0)
392
				error("bad esp specification `%s'", optarg);
393
			break;
394
395
		default:
396
			usage();
397
			/* NOTREACHED */
398
		}
399
400
	if (snaplen == 0) {
401
		switch (dlt) {
402
		case DLT_IEEE802_11:
403
			snaplen = IEEE802_11_SNAPLEN;
404
			break;
405
		case DLT_IEEE802_11_RADIO:
406
			snaplen = IEEE802_11_RADIO_SNAPLEN;
407
			break;
408
		default:
409
			snaplen = DEFAULT_SNAPLEN;
410
			break;
411
		}
412
	}
413
414
	if (aflag && nflag)
415
		error("-a and -n options are incompatible");
416
417
	if (RFileName != NULL) {
418
		pd = priv_pcap_offline(RFileName, ebuf);
419
		if (pd == NULL)
420
			error("%s", ebuf);
421
		/* state: STATE_BPF */
422
		localnet = 0;
423
		netmask = 0;
424
		if (fflag != 0)
425
			error("-f and -r options are incompatible");
426
	} else {
427
		if (device == NULL) {
428
			device = pcap_lookupdev(ebuf);
429
			if (device == NULL)
430
				error("%s", ebuf);
431
		}
432
		pd = priv_pcap_live(device, snaplen, !pflag, 1000, ebuf,
433
		    dlt, dirfilt);
434
		if (pd == NULL)
435
			error("%s", ebuf);
436
437
		/* state: STATE_BPF */
438
		if (pcap_lookupnet(device, &localnet, &netmask, ebuf)) {
439
			if (fflag)
440
				warning("%s", ebuf);
441
			localnet = 0;
442
			netmask = 0;
443
		}
444
	}
445
	i = pcap_snapshot(pd);
446
	if (snaplen < i) {
447
		warning("snaplen raised from %d to %d", snaplen, i);
448
		snaplen = i;
449
	}
450
451
	if (Lflag) {
452
		pcap_list_linktypes(pd);
453
		exit(0);
454
	}
455
456
	fcode = priv_pcap_setfilter(pd, Oflag, netmask);
457
	/* state: STATE_FILTER */
458
	if (fcode == NULL)
459
		error("%s", pcap_geterr(pd));
460
	if (dflag) {
461
		bpf_dump(fcode, dflag);
462
		exit(0);
463
	}
464
	init_addrtoname(localnet, netmask);
465
466
	if (WFileName) {
467
		pcap_dumper_t *p;
468
469
		p = priv_pcap_dump_open(pd, WFileName);
470
		/* state: STATE_RUN */
471
		if (p == NULL)
472
			error("%s", pcap_geterr(pd));
473
		{
474
			FILE *fp = (FILE *)p;	/* XXX touching pcap guts! */
475
			fflush(fp);
476
			setvbuf(fp, NULL, _IONBF, 0);
477
		}
478
		printer = pcap_dump;
479
		pcap_userdata = (u_char *)p;
480
	} else {
481
		printer = lookup_printer(pcap_datalink(pd));
482
		pcap_userdata = NULL;
483
		priv_init_done();
484
		/* state: STATE_RUN */
485
	}
486
	if (RFileName == NULL) {
487
		(void)fprintf(stderr, "%s: listening on %s, link-type ",
488
		    program_name, device);
489
		pcap_print_linktype(pd->linktype);
490
		(void)fflush(stderr);
491
	}
492
493
	if (oflag)
494
		oflag = init_pfosfp();
495
	if (tflag > 0)
496
		thiszone = gmt2local(0);
497
498
	if (pledge("stdio flock rpath cpath wpath", NULL) == -1)
499
		err(1, "pledge");
500
501
	if (pcap_loop(pd, cnt, printer, pcap_userdata) < 0) {
502
		(void)fprintf(stderr, "%s: pcap_loop: %s\n",
503
		    program_name, pcap_geterr(pd));
504
		exit(1);
505
	}
506
	pcap_close(pd);
507
	exit(0);
508
}
509
510
/* make a clean exit on interrupts */
511
void
512
cleanup(int signo)
513
{
514
	struct pcap_stat stat;
515
	sigset_t allsigs;
516
	char buf[1024];
517
518
	sigfillset(&allsigs);
519
	sigprocmask(SIG_BLOCK, &allsigs, NULL);
520
521
	/* Can't print the summary if reading from a savefile */
522
	(void)write(STDERR_FILENO, "\n", 1);
523
	if (pd != NULL && pcap_file(pd) == NULL) {
524
		if (priv_pcap_stats(&stat) < 0) {
525
			(void)snprintf(buf, sizeof buf,
526
			    "pcap_stats: %s\n", pcap_geterr(pd));
527
			write(STDERR_FILENO, buf, strlen(buf));
528
		} else {
529
			(void)snprintf(buf, sizeof buf,
530
			    "%u packets received by filter\n", stat.ps_recv);
531
			write(STDERR_FILENO, buf, strlen(buf));
532
			(void)snprintf(buf, sizeof buf,
533
			    "%u packets dropped by kernel\n", stat.ps_drop);
534
			write(STDERR_FILENO, buf, strlen(buf));
535
		}
536
	}
537
	_exit(0);
538
}
539
540
void
541
gotchld(int signo)
542
{
543
	pid_t pid;
544
	int status;
545
	int save_err = errno;
546
547
	do {
548
		pid = waitpid(child_pid, &status, WNOHANG);
549
		if (pid > 0 && (WIFEXITED(status) || WIFSIGNALED(status)))
550
			cleanup(0);
551
	} while (pid == -1 && errno == EINTR);
552
553
	if (pid == -1)
554
		_exit(1);
555
556
	errno = save_err;
557
}
558
559
/* dump the buffer in `emacs-hexl' style */
560
void
561
default_print_hexl(const u_char *cp, unsigned int length)
562
{
563
	unsigned int i, j, jm;
564
	int c;
565
	char ln[128], buf[128];
566
567
	printf("\n");
568
	for (i = 0; i < length; i += 0x10) {
569
		snprintf(ln, sizeof(ln), "  %04x: ", (unsigned int)i);
570
		jm = length - i;
571
		jm = jm > 16 ? 16 : jm;
572
573
		for (j = 0; j < jm; j++) {
574
			if ((j % 2) == 1)
575
				snprintf(buf, sizeof(buf), "%02x ",
576
				    (unsigned int)cp[i+j]);
577
			else
578
				snprintf(buf, sizeof(buf), "%02x",
579
				    (unsigned int)cp[i+j]);
580
			strlcat(ln, buf, sizeof ln);
581
		}
582
		for (; j < 16; j++) {
583
			if ((j % 2) == 1)
584
				snprintf(buf, sizeof buf, "   ");
585
			else
586
				snprintf(buf, sizeof buf, "  ");
587
			strlcat(ln, buf, sizeof ln);
588
		}
589
590
		strlcat(ln, " ", sizeof ln);
591
		for (j = 0; j < jm; j++) {
592
			c = cp[i+j];
593
			c = isprint(c) ? c : '.';
594
			buf[0] = c;
595
			buf[1] = '\0';
596
			strlcat(ln, buf, sizeof ln);
597
		}
598
		printf("%s\n", ln);
599
	}
600
}
601
602
/* dump the text from the buffer */
603
void
604
default_print_ascii(const u_char *cp, unsigned int length)
605
{
606
	int c, i;
607
608
	printf("\n");
609
	for (i = 0; i < length; i++) {
610
		c = cp[i];
611
		if (isprint(c) || c == '\t' || c == '\n' || c == '\r')
612
			putchar(c);
613
		else
614
			putchar('.');
615
	}
616
}
617
618
/* Like default_print() but data need not be aligned */
619
void
620
default_print_unaligned(const u_char *cp, u_int length)
621
{
622
	u_int i, s;
623
	int nshorts;
624
625
	if (Xflag) {
626
		/* dump the buffer in `emacs-hexl' style */
627
		default_print_hexl(cp, length);
628
	} else if (Aflag) {
629
		/* dump the text in the buffer */
630
		default_print_ascii(cp, length);
631
	} else {
632
		/* dump the buffer in old tcpdump style */
633
		nshorts = (u_int) length / sizeof(u_short);
634
		i = 0;
635
		while (--nshorts >= 0) {
636
			if ((i++ % 8) == 0)
637
				(void)printf("\n\t\t\t");
638
			s = *cp++;
639
			(void)printf(" %02x%02x", s, *cp++);
640
		}
641
		if (length & 1) {
642
			if ((i % 8) == 0)
643
				(void)printf("\n\t\t\t");
644
			(void)printf(" %02x", *cp);
645
		}
646
	}
647
}
648
649
void
650
default_print(const u_char *bp, u_int length)
651
{
652
	const u_short *sp;
653
	u_int i;
654
	int nshorts;
655
656
	if (Xflag) {
657
		/* dump the buffer in `emacs-hexl' style */
658
		default_print_hexl(bp, length);
659
	} else if (Aflag) {
660
		/* dump the text in the buffer */
661
		default_print_ascii(bp, length);
662
	} else {
663
		/* dump the buffer in old tcpdump style */
664
		if ((long)bp & 1) {
665
			default_print_unaligned(bp, length);
666
			return;
667
		}
668
		sp = (u_short *)bp;
669
		nshorts = (u_int) length / sizeof(u_short);
670
		i = 0;
671
		while (--nshorts >= 0) {
672
			if ((i++ % 8) == 0)
673
				(void)printf("\n\t\t\t");
674
			(void)printf(" %04x", ntohs(*sp++));
675
		}
676
		if (length & 1) {
677
			if ((i % 8) == 0)
678
				(void)printf("\n\t\t\t");
679
			(void)printf(" %02x", *(u_char *)sp);
680
		}
681
	}
682
}
683
684
void
685
set_slave_signals(void)
686
{
687
	setsignal(SIGTERM, cleanup);
688
	setsignal(SIGINT, cleanup);
689
	setsignal(SIGCHLD, gotchld);
690
	setsignal(SIGHUP, cleanup);
691
}
692
693
__dead void
694
usage(void)
695
{
696
	(void)fprintf(stderr,
697
"Usage: %s [-AadefILlNnOopqStvXx] [-c count] [-D direction]\n",
698
	    program_name);
699
	(void)fprintf(stderr,
700
"\t       [-E [espalg:]espkey] [-F file] [-i interface] [-r file]\n");
701
	(void)fprintf(stderr,
702
"\t       [-s snaplen] [-T type] [-w file] [-y datalinktype] [expression]\n");
703
	exit(1);
704
}