File: | src/usr.sbin/tcpdump/tcpdump.c |
Warning: | line 288, column 4 Value stored to 'infile' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: tcpdump.c,v 1.95 2020/12/04 11:36:13 mvs 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(*__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 Bflag; /* BPF fildrop setting */ |
65 | int dflag; /* print filter code */ |
66 | int eflag; /* print ethernet header */ |
67 | int fflag; /* don't translate "foreign" IP address */ |
68 | int Iflag; /* include interface in output */ |
69 | int Lflag; /* List available link types */ |
70 | int nflag; /* leave addresses as numbers */ |
71 | int Nflag; /* remove domains from printed host names */ |
72 | int Oflag = 1; /* run filter code optimizer */ |
73 | int oflag; /* print passive OS fingerprints */ |
74 | int pflag; /* don't go promiscuous */ |
75 | int qflag; /* quick (shorter) output */ |
76 | int Sflag; /* print raw TCP sequence numbers */ |
77 | int tflag = 1; /* print packet arrival time */ |
78 | int vflag; /* verbose */ |
79 | int xflag; /* print packet in hex */ |
80 | int Xflag; /* print packet in emacs-hexl style */ |
81 | |
82 | int packettype; |
83 | |
84 | char *program_name; |
85 | char *device = NULL((void *)0); |
86 | |
87 | int32_t thiszone; /* seconds offset from gmt to local time */ |
88 | |
89 | extern volatile pid_t child_pid; |
90 | |
91 | /* Externs */ |
92 | extern void bpf_dump(struct bpf_program *, int); |
93 | extern int esp_init(char *); |
94 | |
95 | /* Forwards */ |
96 | void cleanup(int); |
97 | void gotchld(int); |
98 | extern __dead__attribute__((__noreturn__)) void usage(void); |
99 | |
100 | /* Length of saved portion of packet. */ |
101 | int snaplen = 0; |
102 | |
103 | struct printer { |
104 | pcap_handler f; |
105 | int type; |
106 | }; |
107 | |
108 | /* XXX needed if using old bpf.h */ |
109 | #ifndef DLT_ATM_RFC148311 |
110 | #define DLT_ATM_RFC148311 11 |
111 | #endif |
112 | |
113 | static struct printer printers[] = { |
114 | { ether_if_print, DLT_EN10MB1 }, |
115 | { ether_if_print, DLT_IEEE8026 }, |
116 | { sl_if_print, DLT_SLIP8 }, |
117 | { sl_bsdos_if_print, DLT_SLIP_BSDOS15 }, |
118 | { ppp_if_print, DLT_PPP9 }, |
119 | { ppp_hdlc_if_print, DLT_PPP_SERIAL50 }, |
120 | { fddi_if_print, DLT_FDDI10 }, |
121 | { null_if_print, DLT_NULL0 }, |
122 | { raw_if_print, DLT_RAW14 }, |
123 | { atm_if_print, DLT_ATM_RFC148311 }, |
124 | { loop_if_print, DLT_LOOP12 }, |
125 | { enc_if_print, DLT_ENC13 }, |
126 | { pflog_if_print, DLT_PFLOG117 }, |
127 | { pfsync_if_print, DLT_PFSYNC18 }, |
128 | { ppp_ether_if_print, DLT_PPP_ETHER51 }, |
129 | { ieee802_11_if_print, DLT_IEEE802_11105 }, |
130 | { ieee802_11_radio_if_print, DLT_IEEE802_11_RADIO127 }, |
131 | { ofp_if_print, DLT_OPENFLOW267 }, |
132 | { usbpcap_if_print, DLT_USBPCAP249 }, |
133 | { NULL((void *)0), 0 }, |
134 | }; |
135 | |
136 | static pcap_handler |
137 | lookup_printer(int type) |
138 | { |
139 | struct printer *p; |
140 | |
141 | for (p = printers; p->f; ++p) { |
142 | if (type == p->type) |
143 | return p->f; |
144 | } |
145 | |
146 | error("unknown data link type 0x%x", type); |
147 | /* NOTREACHED */ |
148 | } |
149 | |
150 | static int |
151 | init_pfosfp(void) |
152 | { |
153 | pf_osfp_initialize(); |
154 | if (pfctl_file_fingerprints(-1, |
155 | PF_OPT_QUIET0x00010|PF_OPT_NOACTION0x00008, PF_OSFP_FILE"/etc/pf.os") == 0) |
156 | return 1; |
157 | return 0; |
158 | } |
159 | |
160 | static pcap_t *pd; |
161 | |
162 | /* Multiple DLT support */ |
163 | void pcap_list_linktypes(pcap_t *); |
164 | void pcap_print_linktype(u_int); |
165 | |
166 | void |
167 | pcap_print_linktype(u_int dlt) |
168 | { |
169 | const char *name; |
170 | |
171 | if ((name = pcap_datalink_val_to_name(dlt)) != NULL((void *)0)) |
172 | fprintf(stderr(&__sF[2]), "%s\n", name); |
173 | else |
174 | fprintf(stderr(&__sF[2]), "<unknown: %u>\n", dlt); |
175 | } |
176 | |
177 | void |
178 | pcap_list_linktypes(pcap_t *p) |
179 | { |
180 | int fd = p->fd; |
181 | u_int n; |
182 | |
183 | #define MAXDLT100 100 |
184 | |
185 | u_int dltlist[MAXDLT100]; |
186 | struct bpf_dltlist dl = {MAXDLT100, dltlist}; |
187 | |
188 | if (fd < 0) |
189 | error("Invalid bpf descriptor"); |
190 | |
191 | if (ioctl(fd, BIOCGDLTLIST(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof (struct bpf_dltlist) & 0x1fff) << 16) | ((('B')) << 8) | ((123))), &dl) == -1) |
192 | err(1, "BIOCGDLTLIST"); |
193 | |
194 | if (dl.bfl_len > MAXDLT100) |
195 | error("Invalid number of linktypes: %u", dl.bfl_len); |
196 | |
197 | fprintf(stderr(&__sF[2]), "%d link type%s supported:\n", dl.bfl_len, |
198 | dl.bfl_len == 1 ? "" : "s"); |
199 | |
200 | for (n = 0; n < dl.bfl_len; n++) { |
201 | fprintf(stderr(&__sF[2]), "\t"); |
202 | pcap_print_linktype(dltlist[n]); |
203 | } |
204 | } |
205 | |
206 | int |
207 | main(int argc, char **argv) |
208 | { |
209 | int cnt = -1, op, i; |
210 | bpf_u_int32 localnet, netmask; |
211 | char *cp, *infile = NULL((void *)0), *RFileName = NULL((void *)0); |
212 | char ebuf[PCAP_ERRBUF_SIZE256], *WFileName = NULL((void *)0); |
213 | pcap_handler printer; |
214 | struct bpf_program *fcode; |
215 | u_char *pcap_userdata; |
216 | u_int dirfilt = 0, dlt = (u_int) -1; |
217 | const char *errstr; |
218 | |
219 | if ((cp = strrchr(argv[0], '/')) != NULL((void *)0)) |
220 | program_name = cp + 1; |
221 | else |
222 | program_name = argv[0]; |
223 | |
224 | /* '-P' used internally, exec privileged portion */ |
225 | if (argc >= 2 && strcmp("-P", argv[1]) == 0) |
226 | priv_exec(argc, argv); |
227 | |
228 | if (priv_init(argc, argv)) |
229 | error("Failed to setup privsep"); |
230 | |
231 | /* state: STATE_INIT */ |
232 | |
233 | opterr = 0; |
234 | while ((op = getopt(argc, argv, |
235 | "AaB:c:D:deE:fF:i:IlLnNOopqr:s:StT:vw:xXy:")) != -1) |
236 | switch (op) { |
237 | |
238 | case 'A': |
239 | xflag = 1; |
240 | Aflag = 1; |
241 | break; |
242 | |
243 | case 'a': |
244 | aflag = 1; |
245 | break; |
246 | |
247 | case 'B': |
248 | if (strcasecmp(optarg, "pass") == 0) |
249 | Bflag = BPF_FILDROP_PASS0; |
250 | else if (strcasecmp(optarg, "capture") == 0) |
251 | Bflag = BPF_FILDROP_CAPTURE1; |
252 | else if (strcasecmp(optarg, "drop") == 0) |
253 | Bflag = BPF_FILDROP_DROP2; |
254 | else { |
255 | error("invalid BPF fildrop option: %s", |
256 | optarg); |
257 | } |
258 | break; |
259 | |
260 | case 'c': |
261 | cnt = strtonum(optarg, 1, INT_MAX2147483647, &errstr); |
262 | if (errstr) |
263 | error("invalid packet count %s: %s", |
264 | optarg, errstr); |
265 | break; |
266 | |
267 | case 'D': |
268 | if (strcasecmp(optarg, "in") == 0) |
269 | dirfilt = BPF_DIRECTION_OUT(1 << 1); |
270 | else if (strcasecmp(optarg, "out") == 0) |
271 | dirfilt = BPF_DIRECTION_IN(1 << 0); |
272 | else |
273 | error("invalid traffic direction %s", optarg); |
274 | break; |
275 | |
276 | case 'd': |
277 | ++dflag; |
278 | break; |
279 | case 'e': |
280 | eflag = 1; |
281 | break; |
282 | |
283 | case 'f': |
284 | fflag = 1; |
285 | break; |
286 | |
287 | case 'F': |
288 | infile = optarg; |
Value stored to 'infile' is never read | |
289 | break; |
290 | |
291 | case 'i': |
292 | device = optarg; |
293 | break; |
294 | |
295 | case 'I': |
296 | Iflag = 1; |
297 | break; |
298 | |
299 | case 'l': |
300 | setvbuf(stdout(&__sF[1]), NULL((void *)0), _IOLBF1, 0); |
301 | break; |
302 | case 'L': |
303 | Lflag = 1; |
304 | break; |
305 | case 'n': |
306 | nflag = 1; |
307 | break; |
308 | |
309 | case 'N': |
310 | Nflag = 1; |
311 | break; |
312 | |
313 | case 'O': |
314 | Oflag = 0; |
315 | break; |
316 | |
317 | case 'o': |
318 | oflag = 1; |
319 | break; |
320 | |
321 | case 'p': |
322 | pflag = 1; |
323 | break; |
324 | |
325 | case 'q': |
326 | qflag = 1; |
327 | break; |
328 | |
329 | case 'r': |
330 | RFileName = optarg; |
331 | break; |
332 | |
333 | case 's': |
334 | snaplen = strtonum(optarg, 1, INT_MAX2147483647, &errstr); |
335 | if (errstr) |
336 | error("invalid snaplen %s: %s", optarg, errstr); |
337 | break; |
338 | |
339 | case 'S': |
340 | Sflag = 1; |
341 | break; |
342 | |
343 | case 't': |
344 | --tflag; |
345 | break; |
346 | |
347 | case 'T': |
348 | if (strcasecmp(optarg, "vat") == 0) |
349 | packettype = PT_VAT1; |
350 | else if (strcasecmp(optarg, "wb") == 0) |
351 | packettype = PT_WB2; |
352 | else if (strcasecmp(optarg, "rpc") == 0) |
353 | packettype = PT_RPC3; |
354 | else if (strcasecmp(optarg, "rtp") == 0) |
355 | packettype = PT_RTP4; |
356 | else if (strcasecmp(optarg, "rtcp") == 0) |
357 | packettype = PT_RTCP5; |
358 | else if (strcasecmp(optarg, "cnfp") == 0) |
359 | packettype = PT_CNFP6; |
360 | else if (strcasecmp(optarg, "vrrp") == 0) |
361 | packettype = PT_VRRP7; |
362 | else if (strcasecmp(optarg, "tcp") == 0) |
363 | packettype = PT_TCP8; |
364 | else if (strcasecmp(optarg, "gre") == 0) |
365 | packettype = PT_GRE9; |
366 | else if (strcasecmp(optarg, "vxlan") == 0) |
367 | packettype = PT_VXLAN12; |
368 | else if (strcasecmp(optarg, "geneve") == 0) |
369 | packettype = PT_GENEVE15; |
370 | else if (strcasecmp(optarg, "erspan") == 0) |
371 | packettype = PT_ERSPAN13; |
372 | else if (strcasecmp(optarg, "mpls") == 0) |
373 | packettype = PT_MPLS10; |
374 | else if (strcasecmp(optarg, "tftp") == 0) |
375 | packettype = PT_TFTP11; |
376 | else if (strcasecmp(optarg, "wg") == 0) |
377 | packettype = PT_WIREGUARD14; |
378 | else if (strcasecmp(optarg, "sack") == 0) |
379 | /* |
380 | * kept for compatibility; DEFAULT_SNAPLEN |
381 | * used to be too short to capture SACK. |
382 | */ |
383 | ; |
384 | else |
385 | error("unknown packet type `%s'", optarg); |
386 | break; |
387 | |
388 | case 'v': |
389 | ++vflag; |
390 | break; |
391 | |
392 | case 'w': |
393 | WFileName = optarg; |
394 | break; |
395 | |
396 | case 'y': |
397 | i = pcap_datalink_name_to_val(optarg); |
398 | if (i < 0) |
399 | error("invalid data link type: %s", optarg); |
400 | dlt = (u_int)i; |
401 | break; |
402 | |
403 | case 'x': |
404 | xflag = 1; |
405 | break; |
406 | |
407 | case 'X': |
408 | Xflag = 1; |
409 | xflag = 1; |
410 | break; |
411 | |
412 | case 'E': |
413 | if (esp_init(optarg) < 0) |
414 | error("bad esp specification `%s'", optarg); |
415 | break; |
416 | |
417 | default: |
418 | usage(); |
419 | /* NOTREACHED */ |
420 | } |
421 | |
422 | if (snaplen == 0) { |
423 | switch (dlt) { |
424 | case DLT_IEEE802_11105: |
425 | snaplen = IEEE802_11_SNAPLEN(116 + 30); |
426 | break; |
427 | case DLT_IEEE802_11_RADIO127: |
428 | snaplen = IEEE802_11_RADIO_SNAPLEN((116 + 30) + 64); |
429 | break; |
430 | default: |
431 | snaplen = DEFAULT_SNAPLEN116; |
432 | break; |
433 | } |
434 | } |
435 | |
436 | if (aflag && nflag) |
437 | error("-a and -n options are incompatible"); |
438 | |
439 | if (RFileName != NULL((void *)0)) { |
440 | pd = priv_pcap_offline(RFileName, ebuf); |
441 | if (pd == NULL((void *)0)) |
442 | error("%s", ebuf); |
443 | /* state: STATE_BPF */ |
444 | localnet = 0; |
445 | netmask = 0; |
446 | if (fflag != 0) |
447 | error("-f and -r options are incompatible"); |
448 | } else { |
449 | if (device == NULL((void *)0)) { |
450 | device = pcap_lookupdev(ebuf); |
451 | if (device == NULL((void *)0)) |
452 | error("%s", ebuf); |
453 | } |
454 | pd = priv_pcap_live(device, snaplen, !pflag, 1000, ebuf, |
455 | dlt, dirfilt, Bflag); |
456 | if (pd == NULL((void *)0)) |
457 | error("%s", ebuf); |
458 | |
459 | /* state: STATE_BPF */ |
460 | if (pcap_lookupnet(device, &localnet, &netmask, ebuf)) { |
461 | if (fflag) |
462 | warning("%s", ebuf); |
463 | localnet = 0; |
464 | netmask = 0; |
465 | } |
466 | } |
467 | i = pcap_snapshot(pd); |
468 | if (snaplen < i) { |
469 | warning("snaplen raised from %d to %d", snaplen, i); |
470 | snaplen = i; |
471 | } |
472 | |
473 | if (Lflag) { |
474 | pcap_list_linktypes(pd); |
475 | exit(0); |
476 | } |
477 | |
478 | fcode = priv_pcap_setfilter(pd, Oflag, netmask); |
479 | /* state: STATE_FILTER */ |
480 | if (fcode == NULL((void *)0)) |
481 | error("%s", pcap_geterr(pd)); |
482 | if (dflag) { |
483 | bpf_dump(fcode, dflag); |
484 | exit(0); |
485 | } |
486 | if (oflag) |
487 | oflag = init_pfosfp(); |
488 | init_addrtoname(localnet, netmask); |
489 | |
490 | if (WFileName) { |
491 | pcap_dumper_t *p; |
492 | |
493 | p = priv_pcap_dump_open(pd, WFileName); |
494 | /* state: STATE_RUN */ |
495 | if (p == NULL((void *)0)) |
496 | error("%s", pcap_geterr(pd)); |
497 | { |
498 | FILE *fp = (FILE *)p; /* XXX touching pcap guts! */ |
499 | fflush(fp); |
500 | setvbuf(fp, NULL((void *)0), _IONBF2, 0); |
501 | } |
502 | printer = pcap_dump; |
503 | pcap_userdata = (u_char *)p; |
504 | } else { |
505 | printer = lookup_printer(pcap_datalink(pd)); |
506 | pcap_userdata = NULL((void *)0); |
507 | priv_init_done(); |
508 | /* state: STATE_RUN */ |
509 | } |
510 | if (RFileName == NULL((void *)0)) { |
511 | (void)fprintf(stderr(&__sF[2]), "%s: listening on %s, link-type ", |
512 | program_name, device); |
513 | pcap_print_linktype(pd->linktype); |
514 | (void)fflush(stderr(&__sF[2])); |
515 | } |
516 | |
517 | if (tflag > 0) |
518 | thiszone = gmt2local(0); |
519 | |
520 | if (pledge("stdio", NULL((void *)0)) == -1) |
521 | err(1, "pledge"); |
522 | |
523 | if (pcap_loop(pd, cnt, printer, pcap_userdata) < 0) { |
524 | (void)fprintf(stderr(&__sF[2]), "%s: pcap_loop: %s\n", |
525 | program_name, pcap_geterr(pd)); |
526 | exit(1); |
527 | } |
528 | pcap_close(pd); |
529 | exit(0); |
530 | } |
531 | |
532 | /* make a clean exit on interrupts */ |
533 | void |
534 | cleanup(int signo) |
535 | { |
536 | struct pcap_stat stat; |
537 | sigset_t allsigs; |
538 | |
539 | sigfillset(&allsigs); |
540 | sigprocmask(SIG_BLOCK1, &allsigs, NULL((void *)0)); |
541 | |
542 | /* Can't print the summary if reading from a savefile */ |
543 | dprintf(STDERR_FILENO2, "\n"); |
544 | if (pd != NULL((void *)0) && pcap_file(pd) == NULL((void *)0)) { |
545 | if (priv_pcap_stats(&stat) < 0) { |
546 | dprintf(STDERR_FILENO2, |
547 | "pcap_stats: %s\n", pcap_geterr(pd)); |
548 | } else { |
549 | dprintf(STDERR_FILENO2, |
550 | "%u packets received by filter\n", stat.ps_recv); |
551 | dprintf(STDERR_FILENO2, |
552 | "%u packets dropped by kernel\n", stat.ps_drop); |
553 | } |
554 | } |
555 | _exit(0); |
556 | } |
557 | |
558 | void |
559 | gotchld(int signo) |
560 | { |
561 | pid_t pid; |
562 | int status; |
563 | int save_err = errno(*__errno()); |
564 | |
565 | do { |
566 | pid = waitpid(child_pid, &status, WNOHANG1); |
567 | if (pid > 0 && (WIFEXITED(status)(((status) & 0177) == 0) || WIFSIGNALED(status)(((status) & 0177) != 0177 && ((status) & 0177 ) != 0))) |
568 | cleanup(0); |
569 | } while (pid == -1 && errno(*__errno()) == EINTR4); |
570 | |
571 | if (pid == -1) |
572 | _exit(1); |
573 | |
574 | errno(*__errno()) = save_err; |
575 | } |
576 | |
577 | /* dump the buffer in `emacs-hexl' style */ |
578 | void |
579 | default_print_hexl(const u_char *cp, unsigned int length) |
580 | { |
581 | unsigned int i, j, jm; |
582 | int c; |
583 | char ln[128], buf[128]; |
584 | |
585 | printf("\n"); |
586 | for (i = 0; i < length; i += 0x10) { |
587 | snprintf(ln, sizeof(ln), " %04x: ", (unsigned int)i); |
588 | jm = length - i; |
589 | jm = jm > 16 ? 16 : jm; |
590 | |
591 | for (j = 0; j < jm; j++) { |
592 | if ((j % 2) == 1) |
593 | snprintf(buf, sizeof(buf), "%02x ", |
594 | (unsigned int)cp[i+j]); |
595 | else |
596 | snprintf(buf, sizeof(buf), "%02x", |
597 | (unsigned int)cp[i+j]); |
598 | strlcat(ln, buf, sizeof ln); |
599 | } |
600 | for (; j < 16; j++) { |
601 | if ((j % 2) == 1) |
602 | snprintf(buf, sizeof buf, " "); |
603 | else |
604 | snprintf(buf, sizeof buf, " "); |
605 | strlcat(ln, buf, sizeof ln); |
606 | } |
607 | |
608 | strlcat(ln, " ", sizeof ln); |
609 | for (j = 0; j < jm; j++) { |
610 | c = cp[i+j]; |
611 | c = isprint(c) ? c : '.'; |
612 | buf[0] = c; |
613 | buf[1] = '\0'; |
614 | strlcat(ln, buf, sizeof ln); |
615 | } |
616 | printf("%s\n", ln); |
617 | } |
618 | } |
619 | |
620 | /* dump the text from the buffer */ |
621 | void |
622 | default_print_ascii(const u_char *cp, unsigned int length) |
623 | { |
624 | int c, i; |
625 | |
626 | printf("\n"); |
627 | for (i = 0; i < length; i++) { |
628 | c = cp[i]; |
629 | if (isprint(c) || c == '\t' || c == '\n' || c == '\r') |
630 | putchar(c)(!__isthreaded ? __sputc(c, (&__sF[1])) : (putc)(c, (& __sF[1]))); |
631 | else |
632 | putchar('.')(!__isthreaded ? __sputc('.', (&__sF[1])) : (putc)('.', ( &__sF[1]))); |
633 | } |
634 | } |
635 | |
636 | /* Like default_print() but data need not be aligned */ |
637 | void |
638 | default_print_unaligned(const u_char *cp, u_int length) |
639 | { |
640 | u_int i, s; |
641 | int nshorts; |
642 | |
643 | if (Xflag) { |
644 | /* dump the buffer in `emacs-hexl' style */ |
645 | default_print_hexl(cp, length); |
646 | } else if (Aflag) { |
647 | /* dump the text in the buffer */ |
648 | default_print_ascii(cp, length); |
649 | } else { |
650 | /* dump the buffer in old tcpdump style */ |
651 | nshorts = (u_int) length / sizeof(u_short); |
652 | i = 0; |
653 | while (--nshorts >= 0) { |
654 | if ((i++ % 8) == 0) |
655 | printf("\n\t\t\t"); |
656 | s = *cp++; |
657 | printf(" %02x%02x", s, *cp++); |
658 | } |
659 | if (length & 1) { |
660 | if ((i % 8) == 0) |
661 | printf("\n\t\t\t"); |
662 | printf(" %02x", *cp); |
663 | } |
664 | } |
665 | } |
666 | |
667 | void |
668 | default_print(const u_char *bp, u_int length) |
669 | { |
670 | const u_short *sp; |
671 | u_int i; |
672 | int nshorts; |
673 | |
674 | if (Xflag) { |
675 | /* dump the buffer in `emacs-hexl' style */ |
676 | default_print_hexl(bp, length); |
677 | } else if (Aflag) { |
678 | /* dump the text in the buffer */ |
679 | default_print_ascii(bp, length); |
680 | } else { |
681 | /* dump the buffer in old tcpdump style */ |
682 | if ((long)bp & 1) { |
683 | default_print_unaligned(bp, length); |
684 | return; |
685 | } |
686 | sp = (u_short *)bp; |
687 | nshorts = (u_int) length / sizeof(u_short); |
688 | i = 0; |
689 | while (--nshorts >= 0) { |
690 | if ((i++ % 8) == 0) |
691 | printf("\n\t\t\t"); |
692 | printf(" %04x", ntohs(*sp++)(__uint16_t)(__builtin_constant_p(*sp++) ? (__uint16_t)(((__uint16_t )(*sp++) & 0xffU) << 8 | ((__uint16_t)(*sp++) & 0xff00U) >> 8) : __swap16md(*sp++))); |
693 | } |
694 | if (length & 1) { |
695 | if ((i % 8) == 0) |
696 | printf("\n\t\t\t"); |
697 | printf(" %02x", *(u_char *)sp); |
698 | } |
699 | } |
700 | } |
701 | |
702 | void |
703 | set_slave_signals(void) |
704 | { |
705 | setsignal(SIGTERM15, cleanup); |
706 | setsignal(SIGINT2, cleanup); |
707 | setsignal(SIGCHLD20, gotchld); |
708 | setsignal(SIGHUP1, cleanup); |
709 | } |
710 | |
711 | __dead__attribute__((__noreturn__)) void |
712 | usage(void) |
713 | { |
714 | (void)fprintf(stderr(&__sF[2]), |
715 | "Usage: %s [-AadefILlNnOopqStvXx] [-B fildrop] [-c count] [-D direction]\n", |
716 | program_name); |
717 | (void)fprintf(stderr(&__sF[2]), |
718 | "\t [-E [espalg:]espkey] [-F file] [-i interface] [-r file]\n"); |
719 | (void)fprintf(stderr(&__sF[2]), |
720 | "\t [-s snaplen] [-T type] [-w file] [-y datalinktype] [expression]\n"); |
721 | exit(1); |
722 | } |