X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/8354e31273344ec927e4d6d2596e8fd79edb15f0..25d016f61a3b38e9c048090980c6921b30d047f3:/tcpdump.c?ds=sidebyside diff --git a/tcpdump.c b/tcpdump.c index 24289869..19d7f2b4 100644 --- a/tcpdump.c +++ b/tcpdump.c @@ -29,8 +29,6 @@ static const char copyright[] _U_ = "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\ The Regents of the University of California. All rights reserved.\n"; -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/tcpdump.c,v 1.283 2008-09-25 21:45:50 guy Exp $ (LBL)"; #endif /* @@ -100,6 +98,7 @@ extern int SIZE_BUF; netdissect_options Gndo; netdissect_options *gndo = &Gndo; +static int Dflag; /* list available devices and exit */ static int dflag; /* print filter code */ static int Lflag; /* list available data link types and exit */ #ifdef HAVE_PCAP_SET_TSTAMP_TYPE @@ -167,7 +166,7 @@ struct ndo_printer { }; -static struct printer printers[] = { +static const struct printer printers[] = { { arcnet_if_print, DLT_ARCNET }, #ifdef DLT_ARCNET_LINUX { arcnet_linux_if_print, DLT_ARCNET_LINUX }, @@ -322,7 +321,7 @@ static struct printer printers[] = { { NULL, 0 }, }; -static struct ndo_printer ndo_printers[] = { +static const struct ndo_printer ndo_printers[] = { { ether_if_print, DLT_EN10MB }, #ifdef DLT_IPNET { ipnet_if_print, DLT_IPNET }, @@ -348,10 +347,21 @@ static struct ndo_printer ndo_printers[] = { { NULL, 0 }, }; +static const struct tok status_flags[] = { +#ifdef PCAP_IF_UP + { PCAP_IF_UP, "Up" }, +#endif +#ifdef PCAP_IF_RUNNING + { PCAP_IF_RUNNING, "Running" }, +#endif + { PCAP_IF_LOOPBACK, "Loopback" }, + { 0, NULL } +}; + if_printer lookup_printer(int type) { - struct printer *p; + const struct printer *p; for (p = printers; p->f; ++p) if (type == p->type) @@ -364,7 +374,7 @@ lookup_printer(int type) if_ndo_printer lookup_ndo_printer(int type) { - struct ndo_printer *p; + const struct ndo_printer *p; for (p = ndo_printers; p->f; ++p) if (type == p->type) @@ -485,6 +495,31 @@ show_dlts_and_exit(const char *device, pcap_t *pd) exit(0); } +#ifdef HAVE_PCAP_FINDALLDEVS +static void +show_devices_and_exit (void) +{ + pcap_if_t *devpointer; + char ebuf[PCAP_ERRBUF_SIZE]; + int i; + + if (pcap_findalldevs(&devpointer, ebuf) < 0) + error("%s", ebuf); + else { + for (i = 0; devpointer != NULL; i++) { + printf("%d.%s", i+1, devpointer->name); + if (devpointer->description != NULL) + printf(" (%s)", devpointer->description); + if (devpointer->flags != 0) + printf(" [%s]", bittok2str(status_flags, "none", devpointer->flags)); + printf("\n"); + devpointer = devpointer->next; + } + } + exit(0); +} +#endif /* HAVE_PCAP_FINDALLDEVS */ + /* * Set up flags that might or might not be supported depending on the * version of libpcap we're using. @@ -548,7 +583,7 @@ droproot(const char *username, const char *chroot_dir) fprintf(stderr, "tcpdump: Chroot without dropping root is insecure\n"); exit(1); } - + pw = getpwnam(username); if (pw) { if (chroot_dir) { @@ -574,7 +609,7 @@ droproot(const char *username, const char *chroot_dir) if (initgroups(pw->pw_name, pw->pw_gid) != 0 || setgid(pw->pw_gid) != 0 || setuid(pw->pw_uid) != 0) { fprintf(stderr, "tcpdump: Couldn't change to '%.32s' uid=%lu gid=%lu: %s\n", - username, + username, (unsigned long)pw->pw_uid, (unsigned long)pw->pw_gid, pcap_strerror(errno)); @@ -641,7 +676,7 @@ MakeFilename(char *buffer, char *orig_name, int cnt, int max_chars) static int tcpdump_printf(netdissect_options *ndo _U_, const char *fmt, ...) { - + va_list args; int ret; @@ -733,7 +768,7 @@ main(int argc, char **argv) gndo->ndo_error=ndo_error; gndo->ndo_warning=ndo_warning; gndo->ndo_snaplen = DEFAULT_SNAPLEN; - + cnt = -1; device = NULL; infile = NULL; @@ -794,21 +829,9 @@ main(int argc, char **argv) ++dflag; break; -#ifdef HAVE_PCAP_FINDALLDEVS case 'D': - if (pcap_findalldevs(&devpointer, ebuf) < 0) - error("%s", ebuf); - else { - for (i = 0; devpointer != 0; i++) { - printf("%d.%s", i+1, devpointer->name); - if (devpointer->description != NULL) - printf(" (%s)", devpointer->description); - printf("\n"); - devpointer = devpointer->next; - } - } - return 0; -#endif /* HAVE_PCAP_FINDALLDEVS */ + Dflag++; + break; case 'L': Lflag++; @@ -859,7 +882,7 @@ main(int argc, char **argv) case 'i': if (optarg[0] == '0' && optarg[1] == 0) error("Invalid adapter index"); - + #ifdef HAVE_PCAP_FINDALLDEVS /* * If the argument is a number, treat it as @@ -1082,7 +1105,7 @@ main(int argc, char **argv) case 'W': Wflag = atoi(optarg); - if (Wflag < 0) + if (Wflag < 0) error("invalid number of output files %s", optarg); WflagChars = getWflagChars(Wflag); break; @@ -1120,22 +1143,11 @@ main(int argc, char **argv) break; #endif case 'z': - if (optarg) { - zflag = strdup(optarg); - } else { - usage(); - /* NOTREACHED */ - } + zflag = strdup(optarg); break; case 'Z': - if (optarg) { - username = strdup(optarg); - } - else { - usage(); - /* NOTREACHED */ - } + username = strdup(optarg); break; default: @@ -1143,6 +1155,11 @@ main(int argc, char **argv) /* NOTREACHED */ } +#ifdef HAVE_PCAP_FINDALLDEVS + if (Dflag) + show_devices_and_exit(); +#endif + switch (tflag) { case 0: /* Default */ @@ -1179,7 +1196,7 @@ main(int argc, char **argv) #ifdef WITH_USER /* if run as root, prepare for dropping root privileges */ if (getuid() == 0 || geteuid() == 0) { - /* Run with '-Z root' to restore old behaviour */ + /* Run with '-Z root' to restore old behaviour */ if (!username) username = WITH_USER; } @@ -1262,7 +1279,7 @@ main(int argc, char **argv) fprintf(stderr, "%s: listening on %s\n", program_name, device); } - fflush(stderr); + fflush(stderr); #endif /* WIN32 */ #ifdef HAVE_PCAP_CREATE pd = pcap_create(device, ebuf); @@ -1420,7 +1437,7 @@ main(int argc, char **argv) init_addrtoname(localnet, netmask); init_checksum(); -#ifndef WIN32 +#ifndef WIN32 (void)setsignal(SIGPIPE, cleanup); (void)setsignal(SIGTERM, cleanup); (void)setsignal(SIGINT, cleanup); @@ -1429,7 +1446,7 @@ main(int argc, char **argv) (void)setsignal(SIGCHLD, child_cleanup); #endif /* Cooperate with nohup(1) */ -#ifndef WIN32 +#ifndef WIN32 if ((oldhandler = setsignal(SIGHUP, cleanup)) != SIG_DFL) (void)setsignal(SIGHUP, oldhandler); #endif /* WIN32 */ @@ -1849,6 +1866,13 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s dump_info->CurrentFileName = (char *)malloc(PATH_MAX + 1); if (dump_info->CurrentFileName == NULL) error("dump_packet_and_trunc: malloc"); + /* + * Gflag was set otherwise we wouldn't be here. Reset the count + * so multiple files would end with 1,2,3 in the filename. + * The counting is handled with the -C flow after this. + */ + Cflag_count = 0; + /* * This is always the first file in the Cflag * rotation: e.g. 0 @@ -1941,6 +1965,7 @@ print_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) { struct print_info *print_info; u_int hdrlen; + netdissect_options *ndo; ++packets_captured; @@ -1948,25 +1973,26 @@ print_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) ts_print(&h->ts); print_info = (struct print_info *)user; + ndo = print_info->ndo; /* * Some printers want to check that they're not walking off the * end of the packet. * Rather than pass it all the way down, we set this global. */ - snapend = sp + h->caplen; + ndo->ndo_snapend = sp + h->caplen; if(print_info->ndo_type) { hdrlen = (*print_info->p.ndo_printer)(print_info->ndo, h, sp); } else { hdrlen = (*print_info->p.printer)(h, sp); } - - if (Xflag) { + + if (ndo->ndo_Xflag) { /* * Print the raw packet data in hex and ASCII. */ - if (Xflag > 1) { + if (ndo->ndo_Xflag > 1) { /* * Include the link-layer header. */ @@ -1981,15 +2007,15 @@ print_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) hex_and_ascii_print("\n\t", sp + hdrlen, h->caplen - hdrlen); } - } else if (xflag) { + } else if (ndo->ndo_xflag) { /* * Print the raw packet data in hex. */ - if (xflag > 1) { + if (ndo->ndo_xflag > 1) { /* * Include the link-layer header. */ - hex_print("\n\t", sp, h->caplen); + hex_print(ndo, "\n\t", sp, h->caplen); } else { /* * Don't include the link-layer header - and if @@ -1997,14 +2023,14 @@ print_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) * print nothing. */ if (h->caplen > hdrlen) - hex_print("\n\t", sp + hdrlen, - h->caplen - hdrlen); + hex_print(ndo, "\n\t", sp + hdrlen, + h->caplen - hdrlen); } - } else if (Aflag) { + } else if (ndo->ndo_Aflag) { /* * Print the raw packet data in ASCII. */ - if (Aflag > 1) { + if (ndo->ndo_Aflag > 1) { /* * Include the link-layer header. */ @@ -2046,11 +2072,11 @@ print_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) * version number of the Packet.dll code, to supply the * "Wpcap_version" information on Windows. */ - char WDversion[]="current-cvs.tcpdump.org"; + char WDversion[]="current-git.tcpdump.org"; #if !defined(HAVE_GENERATED_VERSION) - char version[]="current-cvs.tcpdump.org"; + char version[]="current-git.tcpdump.org"; #endif - char pcap_version[]="current-cvs.tcpdump.org"; + char pcap_version[]="current-git.tcpdump.org"; char Wpcap_version[]="3.1"; #endif @@ -2186,3 +2212,9 @@ ndo_warning(netdissect_options *ndo _U_, const char *fmt, ...) (void)fputc('\n', stderr); } } +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */