1 /* 2 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that: (1) source code distributions 7 * retain the above copyright notice and this paragraph in its entirety, (2) 8 * distributions including binary code include the above copyright notice and 9 * this paragraph in its entirety in the documentation or other materials 10 * provided with the distribution, and (3) all advertising materials mentioning 11 * features or use of this software display the following acknowledgement: 12 * ``This product includes software developed by the University of California, 13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14 * the University nor the names of its contributors may be used to endorse 15 * or promote products derived from this software without specific prior 16 * written permission. 17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20 * 21 * Support for splitting captures into multiple files with a maximum 22 * file size: 23 * 24 * Copyright (c) 2001 25 * Seth Webster <swebster@sst.ll.mit.edu> 26 */ 27 28 #ifndef lint 29 static const char copyright[] _U_ = 30 "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\ 31 The Regents of the University of California. All rights reserved.\n"; 32 static const char rcsid[] _U_ = 33 "@(#) $Header: /tcpdump/master/tcpdump/tcpdump.c,v 1.253.2.13 2007/09/12 19:48:51 guy Exp $ (LBL)"; 34 #endif 35 36 /* $FreeBSD$ */ 37 38 /* 39 * tcpdump - monitor tcp/ip traffic on an ethernet. 40 * 41 * First written in 1987 by Van Jacobson, Lawrence Berkeley Laboratory. 42 * Mercilessly hacked and occasionally improved since then via the 43 * combined efforts of Van, Steve McCanne and Craig Leres of LBL. 44 */ 45 46 #ifdef HAVE_CONFIG_H 47 #include "config.h" 48 #endif 49 50 #include <tcpdump-stdinc.h> 51 52 #ifdef WIN32 53 #include "getopt.h" 54 #include "w32_fzs.h" 55 extern int strcasecmp (const char *__s1, const char *__s2); 56 extern int SIZE_BUF; 57 #define off_t long 58 #define uint UINT 59 #endif /* WIN32 */ 60 61 #ifdef HAVE_SMI_H 62 #include <smi.h> 63 #endif 64 65 #include <pcap.h> 66 #include <signal.h> 67 #include <stdio.h> 68 #include <stdlib.h> 69 #include <string.h> 70 #ifndef WIN32 71 #include <pwd.h> 72 #include <grp.h> 73 #include <errno.h> 74 #endif /* WIN32 */ 75 76 #include "netdissect.h" 77 #include "interface.h" 78 #include "addrtoname.h" 79 #include "machdep.h" 80 #include "setsignal.h" 81 #include "gmt2local.h" 82 #include "pcap-missing.h" 83 84 netdissect_options Gndo; 85 netdissect_options *gndo = &Gndo; 86 87 /* 88 * Define the maximum number of files for the -C flag, and how many 89 * characters can be added to a filename for the -C flag (which 90 * should be enough to handle MAX_CFLAG - 1). 91 */ 92 #define MAX_CFLAG 1000000 93 #define MAX_CFLAG_CHARS 6 94 95 int dflag; /* print filter code */ 96 int Lflag; /* list available data link types and exit */ 97 98 static int infodelay; 99 static int infoprint; 100 101 char *program_name; 102 103 int32_t thiszone; /* seconds offset from gmt to local time */ 104 105 /* Forwards */ 106 static RETSIGTYPE cleanup(int); 107 static void usage(void) __attribute__((noreturn)); 108 static void show_dlts_and_exit(pcap_t *pd) __attribute__((noreturn)); 109 110 static void print_packet(u_char *, const struct pcap_pkthdr *, const u_char *); 111 static void ndo_default_print(netdissect_options *, const u_char *, u_int); 112 static void dump_packet_and_trunc(u_char *, const struct pcap_pkthdr *, const u_char *); 113 static void dump_packet(u_char *, const struct pcap_pkthdr *, const u_char *); 114 static void droproot(const char *, const char *); 115 static void ndo_error(netdissect_options *ndo, const char *fmt, ...); 116 static void ndo_warning(netdissect_options *ndo, const char *fmt, ...); 117 118 #ifdef SIGINFO 119 RETSIGTYPE requestinfo(int); 120 #endif 121 122 #if defined(USE_WIN32_MM_TIMER) 123 #include <MMsystem.h> 124 static UINT timer_id; 125 static void CALLBACK verbose_stats_dump(UINT, UINT, DWORD_PTR, DWORD_PTR, DWORD_PTR); 126 #elif defined(HAVE_ALARM) 127 static void verbose_stats_dump(int sig); 128 #endif 129 130 static void info(int); 131 static u_int packets_captured; 132 133 typedef u_int (*if_printer)(const struct pcap_pkthdr *, const u_char *); 134 135 struct printer { 136 if_printer f; 137 int type; 138 }; 139 140 static struct printer printers[] = { 141 { arcnet_if_print, DLT_ARCNET }, 142 #ifdef DLT_ARCNET_LINUX 143 { arcnet_linux_if_print, DLT_ARCNET_LINUX }, 144 #endif 145 { ether_if_print, DLT_EN10MB }, 146 { token_if_print, DLT_IEEE802 }, 147 #ifdef DLT_LANE8023 148 { lane_if_print, DLT_LANE8023 }, 149 #endif 150 #ifdef DLT_CIP 151 { cip_if_print, DLT_CIP }, 152 #endif 153 #ifdef DLT_ATM_CLIP 154 { cip_if_print, DLT_ATM_CLIP }, 155 #endif 156 { sl_if_print, DLT_SLIP }, 157 #ifdef DLT_SLIP_BSDOS 158 { sl_bsdos_if_print, DLT_SLIP_BSDOS }, 159 #endif 160 { ppp_if_print, DLT_PPP }, 161 #ifdef DLT_PPP_WITHDIRECTION 162 { ppp_if_print, DLT_PPP_WITHDIRECTION }, 163 #endif 164 #ifdef DLT_PPP_BSDOS 165 { ppp_bsdos_if_print, DLT_PPP_BSDOS }, 166 #endif 167 { fddi_if_print, DLT_FDDI }, 168 { null_if_print, DLT_NULL }, 169 #ifdef DLT_LOOP 170 { null_if_print, DLT_LOOP }, 171 #endif 172 { raw_if_print, DLT_RAW }, 173 { atm_if_print, DLT_ATM_RFC1483 }, 174 #ifdef DLT_C_HDLC 175 { chdlc_if_print, DLT_C_HDLC }, 176 #endif 177 #ifdef DLT_HDLC 178 { chdlc_if_print, DLT_HDLC }, 179 #endif 180 #ifdef DLT_PPP_SERIAL 181 { ppp_hdlc_if_print, DLT_PPP_SERIAL }, 182 #endif 183 #ifdef DLT_PPP_ETHER 184 { pppoe_if_print, DLT_PPP_ETHER }, 185 #endif 186 #ifdef DLT_LINUX_SLL 187 { sll_if_print, DLT_LINUX_SLL }, 188 #endif 189 #ifdef DLT_IEEE802_11 190 { ieee802_11_if_print, DLT_IEEE802_11}, 191 #endif 192 #ifdef DLT_LTALK 193 { ltalk_if_print, DLT_LTALK }, 194 #endif 195 #if defined(DLT_PFLOG) && defined(HAVE_NET_PFVAR_H) 196 { pflog_if_print, DLT_PFLOG }, 197 #endif 198 #ifdef DLT_FR 199 { fr_if_print, DLT_FR }, 200 #endif 201 #ifdef DLT_FRELAY 202 { fr_if_print, DLT_FRELAY }, 203 #endif 204 #ifdef DLT_SUNATM 205 { sunatm_if_print, DLT_SUNATM }, 206 #endif 207 #ifdef DLT_IP_OVER_FC 208 { ipfc_if_print, DLT_IP_OVER_FC }, 209 #endif 210 #ifdef DLT_PRISM_HEADER 211 { prism_if_print, DLT_PRISM_HEADER }, 212 #endif 213 #ifdef DLT_IEEE802_11_RADIO 214 { ieee802_11_radio_if_print, DLT_IEEE802_11_RADIO }, 215 #endif 216 #ifdef DLT_ENC 217 { enc_if_print, DLT_ENC }, 218 #endif 219 #ifdef DLT_SYMANTEC_FIREWALL 220 { symantec_if_print, DLT_SYMANTEC_FIREWALL }, 221 #endif 222 #ifdef DLT_APPLE_IP_OVER_IEEE1394 223 { ap1394_if_print, DLT_APPLE_IP_OVER_IEEE1394 }, 224 #endif 225 #ifdef DLT_JUNIPER_ATM1 226 { juniper_atm1_print, DLT_JUNIPER_ATM1 }, 227 #endif 228 #ifdef DLT_JUNIPER_ATM2 229 { juniper_atm2_print, DLT_JUNIPER_ATM2 }, 230 #endif 231 #ifdef DLT_JUNIPER_MFR 232 { juniper_mfr_print, DLT_JUNIPER_MFR }, 233 #endif 234 #ifdef DLT_JUNIPER_MLFR 235 { juniper_mlfr_print, DLT_JUNIPER_MLFR }, 236 #endif 237 #ifdef DLT_JUNIPER_MLPPP 238 { juniper_mlppp_print, DLT_JUNIPER_MLPPP }, 239 #endif 240 #ifdef DLT_JUNIPER_PPPOE 241 { juniper_pppoe_print, DLT_JUNIPER_PPPOE }, 242 #endif 243 #ifdef DLT_JUNIPER_PPPOE_ATM 244 { juniper_pppoe_atm_print, DLT_JUNIPER_PPPOE_ATM }, 245 #endif 246 #ifdef DLT_JUNIPER_GGSN 247 { juniper_ggsn_print, DLT_JUNIPER_GGSN }, 248 #endif 249 #ifdef DLT_JUNIPER_ES 250 { juniper_es_print, DLT_JUNIPER_ES }, 251 #endif 252 #ifdef DLT_JUNIPER_MONITOR 253 { juniper_monitor_print, DLT_JUNIPER_MONITOR }, 254 #endif 255 #ifdef DLT_JUNIPER_SERVICES 256 { juniper_services_print, DLT_JUNIPER_SERVICES }, 257 #endif 258 #ifdef DLT_JUNIPER_ETHER 259 { juniper_ether_print, DLT_JUNIPER_ETHER }, 260 #endif 261 #ifdef DLT_JUNIPER_PPP 262 { juniper_ppp_print, DLT_JUNIPER_PPP }, 263 #endif 264 #ifdef DLT_JUNIPER_FRELAY 265 { juniper_frelay_print, DLT_JUNIPER_FRELAY }, 266 #endif 267 #ifdef DLT_JUNIPER_CHDLC 268 { juniper_chdlc_print, DLT_JUNIPER_CHDLC }, 269 #endif 270 #ifdef DLT_MFR 271 { mfr_if_print, DLT_MFR }, 272 #endif 273 { NULL, 0 }, 274 }; 275 276 static if_printer 277 lookup_printer(int type) 278 { 279 struct printer *p; 280 281 for (p = printers; p->f; ++p) 282 if (type == p->type) 283 return p->f; 284 285 return NULL; 286 /* NOTREACHED */ 287 } 288 289 static pcap_t *pd; 290 291 extern int optind; 292 extern int opterr; 293 extern char *optarg; 294 295 struct print_info { 296 if_printer printer; 297 }; 298 299 struct dump_info { 300 char *WFileName; 301 pcap_t *pd; 302 pcap_dumper_t *p; 303 }; 304 305 static void 306 show_dlts_and_exit(pcap_t *pd) 307 { 308 int n_dlts; 309 int *dlts = 0; 310 const char *dlt_name; 311 312 n_dlts = pcap_list_datalinks(pd, &dlts); 313 if (n_dlts < 0) 314 error("%s", pcap_geterr(pd)); 315 else if (n_dlts == 0 || !dlts) 316 error("No data link types."); 317 318 (void) fprintf(stderr, "Data link types (use option -y to set):\n"); 319 320 while (--n_dlts >= 0) { 321 dlt_name = pcap_datalink_val_to_name(dlts[n_dlts]); 322 if (dlt_name != NULL) { 323 (void) fprintf(stderr, " %s (%s)", dlt_name, 324 pcap_datalink_val_to_description(dlts[n_dlts])); 325 326 /* 327 * OK, does tcpdump handle that type? 328 */ 329 if (lookup_printer(dlts[n_dlts]) == NULL) 330 (void) fprintf(stderr, " (not supported)"); 331 putchar('\n'); 332 } else { 333 (void) fprintf(stderr, " DLT %d (not supported)\n", 334 dlts[n_dlts]); 335 } 336 } 337 free(dlts); 338 exit(0); 339 } 340 341 /* 342 * Set up flags that might or might not be supported depending on the 343 * version of libpcap we're using. 344 */ 345 #ifdef WIN32 346 #define B_FLAG "B:" 347 #define B_FLAG_USAGE " [ -B size ]" 348 #else /* WIN32 */ 349 #define B_FLAG 350 #define B_FLAG_USAGE 351 #endif /* WIN32 */ 352 353 #ifdef HAVE_PCAP_FINDALLDEVS 354 #ifndef HAVE_PCAP_IF_T 355 #undef HAVE_PCAP_FINDALLDEVS 356 #endif 357 #endif 358 359 #ifdef HAVE_PCAP_FINDALLDEVS 360 #define D_FLAG "D" 361 #else 362 #define D_FLAG 363 #endif 364 365 #ifdef HAVE_PCAP_DUMP_FLUSH 366 #define U_FLAG "U" 367 #else 368 #define U_FLAG 369 #endif 370 371 #ifndef WIN32 372 /* Drop root privileges and chroot if necessary */ 373 static void 374 droproot(const char *username, const char *chroot_dir) 375 { 376 struct passwd *pw = NULL; 377 378 if (chroot_dir && !username) { 379 fprintf(stderr, "tcpdump: Chroot without dropping root is insecure\n"); 380 exit(1); 381 } 382 383 pw = getpwnam(username); 384 if (pw) { 385 if (chroot_dir) { 386 if (chroot(chroot_dir) != 0 || chdir ("/") != 0) { 387 fprintf(stderr, "tcpdump: Couldn't chroot/chdir to '%.64s': %s\n", 388 chroot_dir, pcap_strerror(errno)); 389 exit(1); 390 } 391 } 392 if (initgroups(pw->pw_name, pw->pw_gid) != 0 || 393 setgid(pw->pw_gid) != 0 || setuid(pw->pw_uid) != 0) { 394 fprintf(stderr, "tcpdump: Couldn't change to '%.32s' uid=%lu gid=%lu: %s\n", 395 username, 396 (unsigned long)pw->pw_uid, 397 (unsigned long)pw->pw_gid, 398 pcap_strerror(errno)); 399 exit(1); 400 } 401 } 402 else { 403 fprintf(stderr, "tcpdump: Couldn't find user '%.32s'\n", 404 username); 405 exit(1); 406 } 407 } 408 #endif /* WIN32 */ 409 410 static int 411 getWflagChars(int x) 412 { 413 int c = 0; 414 415 x -= 1; 416 while (x > 0) { 417 c += 1; 418 x /= 10; 419 } 420 421 return c; 422 } 423 424 425 static void 426 MakeFilename(char *buffer, char *orig_name, int cnt, int max_chars) 427 { 428 if (cnt == 0 && max_chars == 0) 429 strcpy(buffer, orig_name); 430 else 431 sprintf(buffer, "%s%0*d", orig_name, max_chars, cnt); 432 } 433 434 static int tcpdump_printf(netdissect_options *ndo _U_, 435 const char *fmt, ...) 436 { 437 438 va_list args; 439 int ret; 440 441 va_start(args, fmt); 442 ret=vfprintf(stdout, fmt, args); 443 va_end(args); 444 445 return ret; 446 } 447 448 int 449 main(int argc, char **argv) 450 { 451 register int cnt, op, i; 452 bpf_u_int32 localnet, netmask; 453 register char *cp, *infile, *cmdbuf, *device, *RFileName, *WFileName, *WFileNameAlt; 454 pcap_handler callback; 455 int type; 456 struct bpf_program fcode; 457 #ifndef WIN32 458 RETSIGTYPE (*oldhandler)(int); 459 #endif 460 struct print_info printinfo; 461 struct dump_info dumpinfo; 462 u_char *pcap_userdata; 463 char ebuf[PCAP_ERRBUF_SIZE]; 464 char *username = NULL; 465 char *chroot_dir = NULL; 466 #ifdef HAVE_PCAP_FINDALLDEVS 467 pcap_if_t *devpointer; 468 int devnum; 469 #endif 470 int status; 471 #ifdef WIN32 472 u_int UserBufferSize = 1000000; 473 if(wsockinit() != 0) return 1; 474 #endif /* WIN32 */ 475 476 gndo->ndo_Oflag=1; 477 gndo->ndo_Rflag=1; 478 gndo->ndo_dlt=-1; 479 gndo->ndo_default_print=ndo_default_print; 480 gndo->ndo_printf=tcpdump_printf; 481 gndo->ndo_error=ndo_error; 482 gndo->ndo_warning=ndo_warning; 483 gndo->ndo_snaplen = DEFAULT_SNAPLEN; 484 485 cnt = -1; 486 device = NULL; 487 infile = NULL; 488 RFileName = NULL; 489 WFileName = NULL; 490 if ((cp = strrchr(argv[0], '/')) != NULL) 491 program_name = cp + 1; 492 else 493 program_name = argv[0]; 494 495 if (abort_on_misalignment(ebuf, sizeof(ebuf)) < 0) 496 error("%s", ebuf); 497 498 #ifdef LIBSMI 499 smiInit("tcpdump"); 500 #endif 501 502 opterr = 0; 503 while ( 504 (op = getopt(argc, argv, "aA" B_FLAG "c:C:d" D_FLAG "eE:fF:i:lLm:M:nNOpqr:Rs:StT:u" U_FLAG "vw:W:xXy:YZ:")) != -1) 505 switch (op) { 506 507 case 'a': 508 /* compatibility for old -a */ 509 break; 510 511 case 'A': 512 ++Aflag; 513 break; 514 515 #ifdef WIN32 516 case 'B': 517 UserBufferSize = atoi(optarg)*1024; 518 if (UserBufferSize < 0) 519 error("invalid packet buffer size %s", optarg); 520 break; 521 #endif /* WIN32 */ 522 523 case 'c': 524 cnt = atoi(optarg); 525 if (cnt <= 0) 526 error("invalid packet count %s", optarg); 527 break; 528 529 case 'C': 530 Cflag = atoi(optarg) * 1000000; 531 if (Cflag < 0) 532 error("invalid file size %s", optarg); 533 break; 534 535 case 'd': 536 ++dflag; 537 break; 538 539 #ifdef HAVE_PCAP_FINDALLDEVS 540 case 'D': 541 if (pcap_findalldevs(&devpointer, ebuf) < 0) 542 error("%s", ebuf); 543 else { 544 for (i = 0; devpointer != 0; i++) { 545 printf("%d.%s", i+1, devpointer->name); 546 if (devpointer->description != NULL) 547 printf(" (%s)", devpointer->description); 548 printf("\n"); 549 devpointer = devpointer->next; 550 } 551 } 552 return 0; 553 #endif /* HAVE_PCAP_FINDALLDEVS */ 554 555 case 'L': 556 Lflag++; 557 break; 558 559 case 'e': 560 ++eflag; 561 break; 562 563 case 'E': 564 #ifndef HAVE_LIBCRYPTO 565 warning("crypto code not compiled in"); 566 #endif 567 gndo->ndo_espsecret = optarg; 568 break; 569 570 case 'f': 571 ++fflag; 572 break; 573 574 case 'F': 575 infile = optarg; 576 break; 577 578 case 'i': 579 if (optarg[0] == '0' && optarg[1] == 0) 580 error("Invalid adapter index"); 581 582 #ifdef HAVE_PCAP_FINDALLDEVS 583 /* 584 * If the argument is a number, treat it as 585 * an index into the list of adapters, as 586 * printed by "tcpdump -D". 587 * 588 * This should be OK on UNIX systems, as interfaces 589 * shouldn't have names that begin with digits. 590 * It can be useful on Windows, where more than 591 * one interface can have the same name. 592 */ 593 if ((devnum = atoi(optarg)) != 0) { 594 if (devnum < 0) 595 error("Invalid adapter index"); 596 597 if (pcap_findalldevs(&devpointer, ebuf) < 0) 598 error("%s", ebuf); 599 else { 600 for (i = 0; i < devnum-1; i++){ 601 devpointer = devpointer->next; 602 if (devpointer == NULL) 603 error("Invalid adapter index"); 604 } 605 } 606 device = devpointer->name; 607 break; 608 } 609 #endif /* HAVE_PCAP_FINDALLDEVS */ 610 device = optarg; 611 break; 612 613 case 'l': 614 #ifdef WIN32 615 /* 616 * _IOLBF is the same as _IOFBF in Microsoft's C 617 * libraries; the only alternative they offer 618 * is _IONBF. 619 * 620 * XXX - this should really be checking for MSVC++, 621 * not WIN32, if, for example, MinGW has its own 622 * C library that is more UNIX-compatible. 623 */ 624 setvbuf(stdout, NULL, _IONBF, 0); 625 #else /* WIN32 */ 626 #ifdef HAVE_SETLINEBUF 627 setlinebuf(stdout); 628 #else 629 setvbuf(stdout, NULL, _IOLBF, 0); 630 #endif 631 #endif /* WIN32 */ 632 break; 633 634 case 'n': 635 ++nflag; 636 break; 637 638 case 'N': 639 ++Nflag; 640 break; 641 642 case 'm': 643 #ifdef LIBSMI 644 if (smiLoadModule(optarg) == 0) { 645 error("could not load MIB module %s", optarg); 646 } 647 sflag = 1; 648 #else 649 (void)fprintf(stderr, "%s: ignoring option `-m %s' ", 650 program_name, optarg); 651 (void)fprintf(stderr, "(no libsmi support)\n"); 652 #endif 653 break; 654 655 case 'M': 656 /* TCP-MD5 shared secret */ 657 #ifndef HAVE_LIBCRYPTO 658 warning("crypto code not compiled in"); 659 #endif 660 tcpmd5secret = optarg; 661 break; 662 663 case 'O': 664 Oflag = 0; 665 break; 666 667 case 'p': 668 ++pflag; 669 break; 670 671 case 'q': 672 ++qflag; 673 ++suppress_default_print; 674 break; 675 676 case 'r': 677 RFileName = optarg; 678 break; 679 680 case 'R': 681 Rflag = 0; 682 break; 683 684 case 's': { 685 char *end; 686 687 snaplen = strtol(optarg, &end, 0); 688 if (optarg == end || *end != '\0' 689 || snaplen < 0 || snaplen > 65535) 690 error("invalid snaplen %s", optarg); 691 else if (snaplen == 0) 692 snaplen = 65535; 693 break; 694 } 695 696 case 'S': 697 ++Sflag; 698 break; 699 700 case 't': 701 ++tflag; 702 break; 703 704 case 'T': 705 if (strcasecmp(optarg, "vat") == 0) 706 packettype = PT_VAT; 707 else if (strcasecmp(optarg, "wb") == 0) 708 packettype = PT_WB; 709 else if (strcasecmp(optarg, "rpc") == 0) 710 packettype = PT_RPC; 711 else if (strcasecmp(optarg, "rtp") == 0) 712 packettype = PT_RTP; 713 else if (strcasecmp(optarg, "rtcp") == 0) 714 packettype = PT_RTCP; 715 else if (strcasecmp(optarg, "snmp") == 0) 716 packettype = PT_SNMP; 717 else if (strcasecmp(optarg, "cnfp") == 0) 718 packettype = PT_CNFP; 719 else if (strcasecmp(optarg, "tftp") == 0) 720 packettype = PT_TFTP; 721 else if (strcasecmp(optarg, "aodv") == 0) 722 packettype = PT_AODV; 723 else 724 error("unknown packet type `%s'", optarg); 725 break; 726 727 case 'u': 728 ++uflag; 729 break; 730 731 #ifdef HAVE_PCAP_DUMP_FLUSH 732 case 'U': 733 ++Uflag; 734 break; 735 #endif 736 737 case 'v': 738 ++vflag; 739 break; 740 741 case 'w': 742 WFileName = optarg; 743 break; 744 745 case 'W': 746 Wflag = atoi(optarg); 747 if (Wflag < 0) 748 error("invalid number of output files %s", optarg); 749 WflagChars = getWflagChars(Wflag); 750 break; 751 752 case 'x': 753 ++xflag; 754 ++suppress_default_print; 755 break; 756 757 case 'X': 758 ++Xflag; 759 ++suppress_default_print; 760 break; 761 762 case 'y': 763 gndo->ndo_dltname = optarg; 764 gndo->ndo_dlt = 765 pcap_datalink_name_to_val(gndo->ndo_dltname); 766 if (gndo->ndo_dlt < 0) 767 error("invalid data link type %s", gndo->ndo_dltname); 768 break; 769 770 #if defined(HAVE_PCAP_DEBUG) || defined(HAVE_YYDEBUG) 771 case 'Y': 772 { 773 /* Undocumented flag */ 774 #ifdef HAVE_PCAP_DEBUG 775 extern int pcap_debug; 776 pcap_debug = 1; 777 #else 778 extern int yydebug; 779 yydebug = 1; 780 #endif 781 } 782 break; 783 #endif 784 case 'Z': 785 if (optarg) { 786 username = strdup(optarg); 787 } 788 else { 789 usage(); 790 /* NOTREACHED */ 791 } 792 break; 793 794 default: 795 usage(); 796 /* NOTREACHED */ 797 } 798 799 switch (tflag) { 800 801 case 0: /* Default */ 802 case 4: /* Default + Date*/ 803 thiszone = gmt2local(0); 804 break; 805 806 case 1: /* No time stamp */ 807 case 2: /* Unix timeval style */ 808 case 3: /* Microseconds since previous packet */ 809 break; 810 811 default: /* Not supported */ 812 error("only -t, -tt, -ttt, and -tttt are supported"); 813 break; 814 } 815 816 #ifdef WITH_CHROOT 817 /* if run as root, prepare for chrooting */ 818 if (getuid() == 0 || geteuid() == 0) { 819 /* future extensibility for cmd-line arguments */ 820 if (!chroot_dir) 821 chroot_dir = WITH_CHROOT; 822 } 823 #endif 824 825 #ifdef WITH_USER 826 /* if run as root, prepare for dropping root privileges */ 827 if (getuid() == 0 || geteuid() == 0) { 828 /* Run with '-Z root' to restore old behaviour */ 829 if (!username) 830 username = WITH_USER; 831 } 832 #endif 833 834 if (RFileName != NULL) { 835 int dlt; 836 const char *dlt_name; 837 838 #ifndef WIN32 839 /* 840 * We don't need network access, so relinquish any set-UID 841 * or set-GID privileges we have (if any). 842 * 843 * We do *not* want set-UID privileges when opening a 844 * trace file, as that might let the user read other 845 * people's trace files (especially if we're set-UID 846 * root). 847 */ 848 if (setgid(getgid()) != 0 || setuid(getuid()) != 0 ) 849 fprintf(stderr, "Warning: setgid/setuid failed !\n"); 850 #endif /* WIN32 */ 851 pd = pcap_open_offline(RFileName, ebuf); 852 if (pd == NULL) 853 error("%s", ebuf); 854 dlt = pcap_datalink(pd); 855 dlt_name = pcap_datalink_val_to_name(dlt); 856 if (dlt_name == NULL) { 857 fprintf(stderr, "reading from file %s, link-type %u\n", 858 RFileName, dlt); 859 } else { 860 fprintf(stderr, 861 "reading from file %s, link-type %s (%s)\n", 862 RFileName, dlt_name, 863 pcap_datalink_val_to_description(dlt)); 864 } 865 localnet = 0; 866 netmask = 0; 867 if (fflag != 0) 868 error("-f and -r options are incompatible"); 869 } else { 870 if (device == NULL) { 871 device = pcap_lookupdev(ebuf); 872 if (device == NULL) 873 error("%s", ebuf); 874 } 875 #ifdef WIN32 876 if(strlen(device) == 1) //we assume that an ASCII string is always longer than 1 char 877 { //a Unicode string has a \0 as second byte (so strlen() is 1) 878 fprintf(stderr, "%s: listening on %ws\n", program_name, device); 879 } 880 else 881 { 882 fprintf(stderr, "%s: listening on %s\n", program_name, device); 883 } 884 885 fflush(stderr); 886 #endif /* WIN32 */ 887 *ebuf = '\0'; 888 pd = pcap_open_live(device, snaplen, !pflag, 1000, ebuf); 889 if (pd == NULL) 890 error("%s", ebuf); 891 else if (*ebuf) 892 warning("%s", ebuf); 893 /* 894 * Let user own process after socket has been opened. 895 */ 896 #ifndef WIN32 897 if (setgid(getgid()) != 0 || setuid(getuid()) != 0) 898 fprintf(stderr, "Warning: setgid/setuid failed !\n"); 899 #endif /* WIN32 */ 900 #ifdef WIN32 901 if(UserBufferSize != 1000000) 902 if(pcap_setbuff(pd, UserBufferSize)==-1){ 903 error("%s", pcap_geterr(pd)); 904 } 905 #endif /* WIN32 */ 906 if (Lflag) 907 show_dlts_and_exit(pd); 908 if (gndo->ndo_dlt >= 0) { 909 #ifdef HAVE_PCAP_SET_DATALINK 910 if (pcap_set_datalink(pd, gndo->ndo_dlt) < 0) 911 error("%s", pcap_geterr(pd)); 912 #else 913 /* 914 * We don't actually support changing the 915 * data link type, so we only let them 916 * set it to what it already is. 917 */ 918 if (gndo->ndo_dlt != pcap_datalink(pd)) { 919 error("%s is not one of the DLTs supported by this device\n", 920 gndo->ndo_dltname); 921 } 922 #endif 923 (void)fprintf(stderr, "%s: data link type %s\n", 924 program_name, gndo->ndo_dltname); 925 (void)fflush(stderr); 926 } 927 i = pcap_snapshot(pd); 928 if (snaplen < i) { 929 warning("snaplen raised from %d to %d", snaplen, i); 930 snaplen = i; 931 } 932 if (pcap_lookupnet(device, &localnet, &netmask, ebuf) < 0) { 933 localnet = 0; 934 netmask = 0; 935 warning("%s", ebuf); 936 } 937 } 938 if (infile) 939 cmdbuf = read_infile(infile); 940 else 941 cmdbuf = copy_argv(&argv[optind]); 942 943 if (pcap_compile(pd, &fcode, cmdbuf, Oflag, netmask) < 0) 944 error("%s", pcap_geterr(pd)); 945 if (dflag) { 946 bpf_dump(&fcode, dflag); 947 pcap_close(pd); 948 exit(0); 949 } 950 init_addrtoname(localnet, netmask); 951 952 #ifndef WIN32 953 (void)setsignal(SIGPIPE, cleanup); 954 #endif /* WIN32 */ 955 (void)setsignal(SIGTERM, cleanup); 956 (void)setsignal(SIGINT, cleanup); 957 /* Cooperate with nohup(1) */ 958 #ifndef WIN32 959 if ((oldhandler = setsignal(SIGHUP, cleanup)) != SIG_DFL) 960 (void)setsignal(SIGHUP, oldhandler); 961 #endif /* WIN32 */ 962 963 if (pcap_setfilter(pd, &fcode) < 0) 964 error("%s", pcap_geterr(pd)); 965 if (WFileName) { 966 pcap_dumper_t *p; 967 968 WFileNameAlt = (char *)malloc(strlen(WFileName) + MAX_CFLAG_CHARS + 1); 969 if (WFileNameAlt == NULL) 970 error("malloc of WFileNameAlt"); 971 MakeFilename(WFileNameAlt, WFileName, 0, WflagChars); 972 p = pcap_dump_open(pd, WFileNameAlt); 973 if (p == NULL) 974 error("%s", pcap_geterr(pd)); 975 if (Cflag != 0) { 976 callback = dump_packet_and_trunc; 977 dumpinfo.WFileName = WFileName; 978 dumpinfo.pd = pd; 979 dumpinfo.p = p; 980 pcap_userdata = (u_char *)&dumpinfo; 981 } else { 982 callback = dump_packet; 983 pcap_userdata = (u_char *)p; 984 } 985 } else { 986 type = pcap_datalink(pd); 987 printinfo.printer = lookup_printer(type); 988 if (printinfo.printer == NULL) { 989 gndo->ndo_dltname = pcap_datalink_val_to_name(type); 990 if (gndo->ndo_dltname != NULL) 991 error("unsupported data link type %s", 992 gndo->ndo_dltname); 993 else 994 error("unsupported data link type %d", type); 995 } 996 callback = print_packet; 997 pcap_userdata = (u_char *)&printinfo; 998 } 999 #ifndef WIN32 1000 /* 1001 * We cannot do this earlier, because we want to be able to open 1002 * the file (if done) for writing before giving up permissions. 1003 */ 1004 if (getuid() == 0 || geteuid() == 0) { 1005 if (username || chroot_dir) 1006 droproot(username, chroot_dir); 1007 } 1008 #endif /* WIN32 */ 1009 #ifdef SIGINFO 1010 (void)setsignal(SIGINFO, requestinfo); 1011 #endif 1012 1013 if (vflag > 0 && WFileName) { 1014 /* 1015 * When capturing to a file, "-v" means tcpdump should, 1016 * every 10 secodns, "v"erbosely report the number of 1017 * packets captured. 1018 */ 1019 #ifdef USE_WIN32_MM_TIMER 1020 /* call verbose_stats_dump() each 1000 +/-100msec */ 1021 timer_id = timeSetEvent(1000, 100, verbose_stats_dump, 0, TIME_PERIODIC); 1022 setvbuf(stderr, NULL, _IONBF, 0); 1023 #elif defined(HAVE_ALARM) 1024 (void)setsignal(SIGALRM, verbose_stats_dump); 1025 alarm(1); 1026 #endif 1027 } 1028 1029 #ifndef WIN32 1030 if (RFileName == NULL) { 1031 int dlt; 1032 const char *dlt_name; 1033 1034 if (!vflag && !WFileName) { 1035 (void)fprintf(stderr, 1036 "%s: verbose output suppressed, use -v or -vv for full protocol decode\n", 1037 program_name); 1038 } else 1039 (void)fprintf(stderr, "%s: ", program_name); 1040 dlt = pcap_datalink(pd); 1041 dlt_name = pcap_datalink_val_to_name(dlt); 1042 if (dlt_name == NULL) { 1043 (void)fprintf(stderr, "listening on %s, link-type %u, capture size %u bytes\n", 1044 device, dlt, snaplen); 1045 } else { 1046 (void)fprintf(stderr, "listening on %s, link-type %s (%s), capture size %u bytes\n", 1047 device, dlt_name, 1048 pcap_datalink_val_to_description(dlt), snaplen); 1049 } 1050 (void)fflush(stderr); 1051 } 1052 #endif /* WIN32 */ 1053 status = pcap_loop(pd, cnt, callback, pcap_userdata); 1054 if (WFileName == NULL) { 1055 /* 1056 * We're printing packets. Flush the printed output, 1057 * so it doesn't get intermingled with error output. 1058 */ 1059 if (status == -2) { 1060 /* 1061 * We got interrupted, so perhaps we didn't 1062 * manage to finish a line we were printing. 1063 * Print an extra newline, just in case. 1064 */ 1065 putchar('\n'); 1066 } 1067 (void)fflush(stdout); 1068 } 1069 if (status == -1) { 1070 /* 1071 * Error. Report it. 1072 */ 1073 (void)fprintf(stderr, "%s: pcap_loop: %s\n", 1074 program_name, pcap_geterr(pd)); 1075 } 1076 if (RFileName == NULL) { 1077 /* 1078 * We're doing a live capture. Report the capture 1079 * statistics. 1080 */ 1081 info(1); 1082 } 1083 pcap_close(pd); 1084 exit(status == -1 ? 1 : 0); 1085 } 1086 1087 /* make a clean exit on interrupts */ 1088 static RETSIGTYPE 1089 cleanup(int signo _U_) 1090 { 1091 #ifdef USE_WIN32_MM_TIMER 1092 if (timer_id) 1093 timeKillEvent(timer_id); 1094 timer_id = 0; 1095 #elif defined(HAVE_ALARM) 1096 alarm(0); 1097 #endif 1098 1099 #ifdef HAVE_PCAP_BREAKLOOP 1100 /* 1101 * We have "pcap_breakloop()"; use it, so that we do as little 1102 * as possible in the signal handler (it's probably not safe 1103 * to do anything with standard I/O streams in a signal handler - 1104 * the ANSI C standard doesn't say it is). 1105 */ 1106 pcap_breakloop(pd); 1107 #else 1108 /* 1109 * We don't have "pcap_breakloop()"; this isn't safe, but 1110 * it's the best we can do. Print the summary if we're 1111 * not reading from a savefile - i.e., if we're doing a 1112 * live capture - and exit. 1113 */ 1114 if (pd != NULL && pcap_file(pd) == NULL) { 1115 /* 1116 * We got interrupted, so perhaps we didn't 1117 * manage to finish a line we were printing. 1118 * Print an extra newline, just in case. 1119 */ 1120 putchar('\n'); 1121 (void)fflush(stdout); 1122 info(1); 1123 } 1124 exit(0); 1125 #endif 1126 } 1127 1128 static void 1129 info(register int verbose) 1130 { 1131 struct pcap_stat stat; 1132 1133 if (pcap_stats(pd, &stat) < 0) { 1134 (void)fprintf(stderr, "pcap_stats: %s\n", pcap_geterr(pd)); 1135 infoprint = 0; 1136 return; 1137 } 1138 1139 if (!verbose) 1140 fprintf(stderr, "%s: ", program_name); 1141 1142 (void)fprintf(stderr, "%u packets captured", packets_captured); 1143 if (!verbose) 1144 fputs(", ", stderr); 1145 else 1146 putc('\n', stderr); 1147 (void)fprintf(stderr, "%d packets received by filter", stat.ps_recv); 1148 if (!verbose) 1149 fputs(", ", stderr); 1150 else 1151 putc('\n', stderr); 1152 (void)fprintf(stderr, "%d packets dropped by kernel\n", stat.ps_drop); 1153 infoprint = 0; 1154 } 1155 1156 static void 1157 dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) 1158 { 1159 struct dump_info *dump_info; 1160 char *name; 1161 1162 ++packets_captured; 1163 1164 ++infodelay; 1165 1166 dump_info = (struct dump_info *)user; 1167 1168 /* 1169 * XXX - this won't prevent capture files from getting 1170 * larger than Cflag - the last packet written to the 1171 * file could put it over Cflag. 1172 */ 1173 if (pcap_dump_ftell(dump_info->p) > Cflag) { 1174 /* 1175 * Close the current file and open a new one. 1176 */ 1177 pcap_dump_close(dump_info->p); 1178 Cflag_count++; 1179 if (Wflag > 0) { 1180 if (Cflag_count >= Wflag) 1181 Cflag_count = 0; 1182 } else { 1183 if (Cflag_count >= MAX_CFLAG) 1184 error("too many output files"); 1185 } 1186 name = (char *)malloc(strlen(dump_info->WFileName) + MAX_CFLAG_CHARS + 1); 1187 if (name == NULL) 1188 error("dump_packet_and_trunc: malloc"); 1189 MakeFilename(name, dump_info->WFileName, Cflag_count, WflagChars); 1190 dump_info->p = pcap_dump_open(dump_info->pd, name); 1191 free(name); 1192 if (dump_info->p == NULL) 1193 error("%s", pcap_geterr(pd)); 1194 } 1195 1196 pcap_dump((u_char *)dump_info->p, h, sp); 1197 #ifdef HAVE_PCAP_DUMP_FLUSH 1198 if (Uflag) 1199 pcap_dump_flush(dump_info->p); 1200 #endif 1201 1202 --infodelay; 1203 if (infoprint) 1204 info(0); 1205 } 1206 1207 static void 1208 dump_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) 1209 { 1210 ++packets_captured; 1211 1212 ++infodelay; 1213 1214 pcap_dump(user, h, sp); 1215 #ifdef HAVE_PCAP_DUMP_FLUSH 1216 if (Uflag) 1217 pcap_dump_flush((pcap_dumper_t *)user); 1218 #endif 1219 1220 --infodelay; 1221 if (infoprint) 1222 info(0); 1223 } 1224 1225 static void 1226 print_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) 1227 { 1228 struct print_info *print_info; 1229 u_int hdrlen; 1230 1231 ++packets_captured; 1232 1233 ++infodelay; 1234 ts_print(&h->ts); 1235 1236 print_info = (struct print_info *)user; 1237 1238 /* 1239 * Some printers want to check that they're not walking off the 1240 * end of the packet. 1241 * Rather than pass it all the way down, we set this global. 1242 */ 1243 snapend = sp + h->caplen; 1244 1245 hdrlen = (*print_info->printer)(h, sp); 1246 if (Xflag) { 1247 /* 1248 * Print the raw packet data in hex and ASCII. 1249 */ 1250 if (Xflag > 1) { 1251 /* 1252 * Include the link-layer header. 1253 */ 1254 hex_and_ascii_print("\n\t", sp, h->caplen); 1255 } else { 1256 /* 1257 * Don't include the link-layer header - and if 1258 * we have nothing past the link-layer header, 1259 * print nothing. 1260 */ 1261 if (h->caplen > hdrlen) 1262 hex_and_ascii_print("\n\t", sp + hdrlen, 1263 h->caplen - hdrlen); 1264 } 1265 } else if (xflag) { 1266 /* 1267 * Print the raw packet data in hex. 1268 */ 1269 if (xflag > 1) { 1270 /* 1271 * Include the link-layer header. 1272 */ 1273 hex_print("\n\t", sp, h->caplen); 1274 } else { 1275 /* 1276 * Don't include the link-layer header - and if 1277 * we have nothing past the link-layer header, 1278 * print nothing. 1279 */ 1280 if (h->caplen > hdrlen) 1281 hex_print("\n\t", sp + hdrlen, 1282 h->caplen - hdrlen); 1283 } 1284 } else if (Aflag) { 1285 /* 1286 * Print the raw packet data in ASCII. 1287 */ 1288 if (Aflag > 1) { 1289 /* 1290 * Include the link-layer header. 1291 */ 1292 ascii_print(sp, h->caplen); 1293 } else { 1294 /* 1295 * Don't include the link-layer header - and if 1296 * we have nothing past the link-layer header, 1297 * print nothing. 1298 */ 1299 if (h->caplen > hdrlen) 1300 ascii_print(sp + hdrlen, h->caplen - hdrlen); 1301 } 1302 } 1303 1304 putchar('\n'); 1305 1306 --infodelay; 1307 if (infoprint) 1308 info(0); 1309 } 1310 1311 #ifdef WIN32 1312 /* 1313 * XXX - there should really be libpcap calls to get the version 1314 * number as a string (the string would be generated from #defines 1315 * at run time, so that it's not generated from string constants 1316 * in the library, as, on many UNIX systems, those constants would 1317 * be statically linked into the application executable image, and 1318 * would thus reflect the version of libpcap on the system on 1319 * which the application was *linked*, not the system on which it's 1320 * *running*. 1321 * 1322 * That routine should be documented, unlike the "version[]" 1323 * string, so that UNIX vendors providing their own libpcaps 1324 * don't omit it (as a couple of vendors have...). 1325 * 1326 * Packet.dll should perhaps also export a routine to return the 1327 * version number of the Packet.dll code, to supply the 1328 * "Wpcap_version" information on Windows. 1329 */ 1330 char WDversion[]="current-cvs.tcpdump.org"; 1331 #if !defined(HAVE_GENERATED_VERSION) 1332 char version[]="current-cvs.tcpdump.org"; 1333 #endif 1334 char pcap_version[]="current-cvs.tcpdump.org"; 1335 char Wpcap_version[]="3.1"; 1336 #endif 1337 1338 /* 1339 * By default, print the specified data out in hex and ASCII. 1340 */ 1341 static void 1342 ndo_default_print(netdissect_options *ndo _U_, const u_char *bp, u_int length) 1343 { 1344 hex_and_ascii_print("\n\t", bp, length); /* pass on lf and identation string */ 1345 } 1346 1347 void 1348 default_print(const u_char *bp, u_int length) 1349 { 1350 ndo_default_print(gndo, bp, length); 1351 } 1352 1353 #ifdef SIGINFO 1354 RETSIGTYPE requestinfo(int signo _U_) 1355 { 1356 if (infodelay) 1357 ++infoprint; 1358 else 1359 info(0); 1360 } 1361 #endif 1362 1363 /* 1364 * Called once each second in verbose mode while dumping to file 1365 */ 1366 #ifdef USE_WIN32_MM_TIMER 1367 void CALLBACK verbose_stats_dump (UINT timer_id _U_, UINT msg _U_, DWORD_PTR arg _U_, 1368 DWORD_PTR dw1 _U_, DWORD_PTR dw2 _U_) 1369 { 1370 struct pcap_stat stat; 1371 1372 if (infodelay == 0 && pcap_stats(pd, &stat) >= 0) 1373 fprintf(stderr, "Got %u\r", packets_captured); 1374 } 1375 #elif defined(HAVE_ALARM) 1376 static void verbose_stats_dump(int sig _U_) 1377 { 1378 struct pcap_stat stat; 1379 1380 if (infodelay == 0 && pcap_stats(pd, &stat) >= 0) 1381 fprintf(stderr, "Got %u\r", packets_captured); 1382 alarm(1); 1383 } 1384 #endif 1385 1386 static void 1387 usage(void) 1388 { 1389 extern char version[]; 1390 #ifndef HAVE_PCAP_LIB_VERSION 1391 #if defined(WIN32) || defined(HAVE_PCAP_VERSION) 1392 extern char pcap_version[]; 1393 #else /* defined(WIN32) || defined(HAVE_PCAP_VERSION) */ 1394 static char pcap_version[] = "unknown"; 1395 #endif /* defined(WIN32) || defined(HAVE_PCAP_VERSION) */ 1396 #endif /* HAVE_PCAP_LIB_VERSION */ 1397 1398 #ifdef HAVE_PCAP_LIB_VERSION 1399 #ifdef WIN32 1400 (void)fprintf(stderr, "%s version %s, based on tcpdump version %s\n", program_name, WDversion, version); 1401 #else /* WIN32 */ 1402 (void)fprintf(stderr, "%s version %s\n", program_name, version); 1403 #endif /* WIN32 */ 1404 (void)fprintf(stderr, "%s\n",pcap_lib_version()); 1405 #else /* HAVE_PCAP_LIB_VERSION */ 1406 #ifdef WIN32 1407 (void)fprintf(stderr, "%s version %s, based on tcpdump version %s\n", program_name, WDversion, version); 1408 (void)fprintf(stderr, "WinPcap version %s, based on libpcap version %s\n",Wpcap_version, pcap_version); 1409 #else /* WIN32 */ 1410 (void)fprintf(stderr, "%s version %s\n", program_name, version); 1411 (void)fprintf(stderr, "libpcap version %s\n", pcap_version); 1412 #endif /* WIN32 */ 1413 #endif /* HAVE_PCAP_LIB_VERSION */ 1414 (void)fprintf(stderr, 1415 "Usage: %s [-aAd" D_FLAG "eflLnNOpqRStu" U_FLAG "vxX]" B_FLAG_USAGE " [-c count] [ -C file_size ]\n", program_name); 1416 (void)fprintf(stderr, 1417 "\t\t[ -E algo:secret ] [ -F file ] [ -i interface ] [ -M secret ]\n"); 1418 (void)fprintf(stderr, 1419 "\t\t[ -r file ] [ -s snaplen ] [ -T type ] [ -w file ]\n"); 1420 (void)fprintf(stderr, 1421 "\t\t[ -W filecount ] [ -y datalinktype ] [ -Z user ]\n"); 1422 (void)fprintf(stderr, 1423 "\t\t[ expression ]\n"); 1424 exit(1); 1425 } 1426 1427 1428 1429 /* VARARGS */ 1430 static void 1431 ndo_error(netdissect_options *ndo _U_, const char *fmt, ...) 1432 { 1433 va_list ap; 1434 1435 (void)fprintf(stderr, "%s: ", program_name); 1436 va_start(ap, fmt); 1437 (void)vfprintf(stderr, fmt, ap); 1438 va_end(ap); 1439 if (*fmt) { 1440 fmt += strlen(fmt); 1441 if (fmt[-1] != '\n') 1442 (void)fputc('\n', stderr); 1443 } 1444 exit(1); 1445 /* NOTREACHED */ 1446 } 1447 1448 /* VARARGS */ 1449 static void 1450 ndo_warning(netdissect_options *ndo _U_, const char *fmt, ...) 1451 { 1452 va_list ap; 1453 1454 (void)fprintf(stderr, "%s: WARNING: ", program_name); 1455 va_start(ap, fmt); 1456 (void)vfprintf(stderr, fmt, ap); 1457 va_end(ap); 1458 if (*fmt) { 1459 fmt += strlen(fmt); 1460 if (fmt[-1] != '\n') 1461 (void)fputc('\n', stderr); 1462 } 1463 } 1464 1465