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