--- tcpdump-3.8.1/tcpdump.c.orig 2003-12-18 01:22:57.000000000 +0000 +++ tcpdump-3.8.1/tcpdump.c 2004-03-16 00:30:15.000000000 +0000 @@ -61,6 +61,7 @@ #include #include #include +#include #include "interface.h" #include "addrtoname.h" @@ -107,7 +108,7 @@ /* Forwards */ static RETSIGTYPE cleanup(int); static void usage(void) __attribute__((noreturn)); -static void show_dlts_and_exit(pcap_t *pd) __attribute__((noreturn)); +static void show_dlts_and_exit(char **devnames) __attribute__((noreturn)); static void print_packet(u_char *, const struct pcap_pkthdr *, const u_char *); static void dump_packet_and_trunc(u_char *, const struct pcap_pkthdr *, const u_char *); @@ -222,7 +223,8 @@ /* NOTREACHED */ } -static pcap_t *pd; +static pcap_t **pd; +static int nrdev; extern int optind; extern int opterr; @@ -239,38 +241,41 @@ }; static void -show_dlts_and_exit(pcap_t *pd) +show_dlts_and_exit(char **devnames) { int n_dlts; int *dlts = 0; const char *dlt_name; - - n_dlts = pcap_list_datalinks(pd, &dlts); - if (n_dlts < 0) - error("%s", pcap_geterr(pd)); - else if (n_dlts == 0 || !dlts) - error("No data link types."); - - (void) fprintf(stderr, "Data link types (use option -y to set):\n"); - - while (--n_dlts >= 0) { - dlt_name = pcap_datalink_val_to_name(dlts[n_dlts]); - if (dlt_name != NULL) { - (void) fprintf(stderr, " %s (%s)", dlt_name, - pcap_datalink_val_to_description(dlts[n_dlts])); - - /* - * OK, does tcpdump handle that type? - */ - if (lookup_printer(dlts[n_dlts]) == NULL) - (void) fprintf(stderr, " (not supported)"); - putchar('\n'); - } else { - (void) fprintf(stderr, " DLT %d (not supported)\n", - dlts[n_dlts]); + int i; + + for(i=0; i= 0) { + dlt_name = pcap_datalink_val_to_name(dlts[n_dlts]); + if (dlt_name != NULL) { + (void) fprintf(stderr, "\t%s (%s)", dlt_name, + pcap_datalink_val_to_description(dlts[n_dlts])); + + /* + * OK, does tcpdump handle that type? + */ + if (lookup_printer(dlts[n_dlts]) == NULL) + (void) fprintf(stderr, " (not supported)"); + putchar('\n'); + } else { + (void) fprintf(stderr, " DLT %d (not supported)\n", + dlts[n_dlts]); + } } + free(dlts); } - free(dlts); exit(0); } @@ -301,9 +306,10 @@ int main(int argc, char **argv) { - register int cnt, op, i; + register int cnt, op, i, j; bpf_u_int32 localnet, netmask; - register char *cp, *infile, *cmdbuf, *device, *RFileName, *WFileName; + register char *cp, *infile, *cmdbuf, *RFileName, *WFileName; + char **devices; pcap_handler callback; int type; struct bpf_program fcode; @@ -318,14 +324,14 @@ pcap_if_t *devpointer; int devnum; #endif - int status; + int status, errdev; #ifdef WIN32 u_int UserBufferSize = 1000000; if(wsockinit() != 0) return 1; #endif /* WIN32 */ cnt = -1; - device = NULL; + devices = NULL; infile = NULL; RFileName = NULL; WFileName = NULL; @@ -423,6 +429,7 @@ if (optarg[0] == '0' && optarg[1] == 0) error("Invalid adapter index"); + devices = realloc(devices, sizeof(char*)*(nrdev+1)); #ifdef HAVE_PCAP_FINDALLDEVS /* * If the argument is a number, treat it as @@ -447,11 +454,11 @@ error("Invalid adapter index"); } } - device = devpointer->name; + devices[nrdev++] = devpointer->name; break; } #endif /* HAVE_PCAP_FINDALLDEVS */ - device = optarg; + devices[nrdev++] = optarg; break; case 'l': @@ -614,6 +621,13 @@ if (tflag > 0) thiszone = gmt2local(0); + + if (RFileName != NULL || nrdev < 1) + nrdev = 1; + pd = calloc(nrdev, sizeof(pcap_t*)); + if (pd == NULL) + error("no memory"); + if (RFileName != NULL) { int dlt; const char *dlt_name; @@ -630,10 +644,10 @@ */ setuid(getuid()); #endif /* WIN32 */ - pd = pcap_open_offline(RFileName, ebuf); - if (pd == NULL) + pd[0] = pcap_open_offline(RFileName, ebuf); + if (pd[0] == NULL) error("%s", ebuf); - dlt = pcap_datalink(pd); + dlt = pcap_datalink(pd[0]); dlt_name = pcap_datalink_val_to_name(dlt); if (dlt_name == NULL) { fprintf(stderr, "reading from file %s, link-type %u\n", @@ -649,73 +663,84 @@ if (fflag != 0) error("-f and -r options are incompatible"); } else { - if (device == NULL) { - device = pcap_lookupdev(ebuf); - if (device == NULL) + if (devices == NULL) { + devices = malloc(sizeof(char*)); + devices[0] = pcap_lookupdev(ebuf); + if (devices[0] == NULL) error("%s", ebuf); } + + for(i=0; i= 0) { + if (Lflag) + continue; + + if (dlt >= 0) { #ifdef HAVE_PCAP_SET_DATALINK - if (pcap_set_datalink(pd, dlt) < 0) - error("%s", pcap_geterr(pd)); + if (pcap_set_datalink(pd[i], dlt) < 0) + error("%s: %s", devices[i], pcap_geterr(pd[i])); #else - /* - * We don't actually support changing the - * data link type, so we only let them - * set it to what it already is. - */ - if (dlt != pcap_datalink(pd)) { - error("%s is not one of the DLTs supported by this device\n", - dlt_name); - } + /* + * We don't actually support changing the + * data link type, so we only let them + * set it to what it already is. + */ + if (dlt != pcap_datalink(pd[i])) { + error("%s: %s is not one of the DLTs supported by this device\n", + devices[i], dlt_name); + } #endif - (void)fprintf(stderr, "%s: data link type %s\n", - program_name, dlt_name); - (void)fflush(stderr); - } - i = pcap_snapshot(pd); - if (snaplen < i) { - warning("snaplen raised from %d to %d", snaplen, i); - snaplen = i; - } - if (pcap_lookupnet(device, &localnet, &netmask, ebuf) < 0) { - localnet = 0; - netmask = 0; - warning("%s", ebuf); + (void)fprintf(stderr, "%s: %s: data link type %s\n", + program_name, devices[i], dlt_name); + (void)fflush(stderr); + } + j = pcap_snapshot(pd[i]); + if (snaplen < j) { + warning("snaplen raised from %d to %d", snaplen, j); + snaplen = j; + } + if (i > 0 && pcap_datalink(pd[i]) != pcap_datalink(pd[0])) + error("%s: Differing link types not supported", devices[i]); + if (pcap_lookupnet(devices[i], &localnet, &netmask, ebuf) < 0) { + localnet = 0; + netmask = 0; + warning("%s", ebuf); + } } + + if(Lflag) + show_dlts_and_exit(devices); +#ifndef WIN32 /* * Let user own process after socket has been opened. */ -#ifndef WIN32 setuid(getuid()); #endif /* WIN32 */ } @@ -724,11 +749,12 @@ else cmdbuf = copy_argv(&argv[optind]); - if (pcap_compile(pd, &fcode, cmdbuf, Oflag, netmask) < 0) - error("%s", pcap_geterr(pd)); + if (pcap_compile(pd[0], &fcode, cmdbuf, Oflag, netmask) < 0) + error("%s", pcap_geterr(pd[0])); if (dflag) { bpf_dump(&fcode, dflag); - pcap_close(pd); + for(i=0; i= 0) { + for(i=0; i= 0) { + for(i=0, n=0; i 0 && cnt < 10 ? cnt : 10), callback, pcap_userdata); + if (status < 0) { + errdev = i; + break; + } + if (status > 0) { + n++; + if (cnt > 0) + cnt -= status; + } + } + if (n == 0) + break; + } + } + } + if (WFileName == NULL) { /* * We're printing packets. Flush the printed output, @@ -820,8 +897,8 @@ /* * Error. Report it. */ - (void)fprintf(stderr, "%s: pcap_loop: %s\n", - program_name, pcap_geterr(pd)); + (void)fprintf(stderr, "%s: %s: pcap_loop: %s\n", + program_name, devices[errdev], pcap_geterr(pd[errdev])); } if (RFileName == NULL) { /* @@ -830,7 +907,8 @@ */ info(1); } - pcap_close(pd); + for(i=0; ip = pcap_dump_open(dump_info->pd, name); free(name); if (dump_info->p == NULL) - error("%s", pcap_geterr(pd)); + error("%s", pcap_geterr(dump_info->pd)); } pcap_dump((u_char *)dump_info->p, h, sp);