From: Guy Harris Date: Thu, 30 Jun 2016 08:42:49 +0000 (-0700) Subject: Don't have pcap_create_common() set opt.device. X-Git-Tag: libpcap-1.8.0-bp~18 X-Git-Url: https://git.tcpdump.org/libpcap/commitdiff_plain/985f531bfaf50ebad71c512bf6c109f0bae6c443 Don't have pcap_create_common() set opt.device. Instead, have pcap_create() do so. Also have pcap_create() on Windows handle converting a little-endian UCS-2/UTF-16 string to ASCII. --- diff --git a/pcap-bpf.c b/pcap-bpf.c index 07700299..b612b04e 100644 --- a/pcap-bpf.c +++ b/pcap-bpf.c @@ -429,11 +429,11 @@ pcap_ack_zbuf(pcap_t *p) #endif /* HAVE_ZEROCOPY_BPF */ pcap_t * -pcap_create_interface(const char *device, char *ebuf) +pcap_create_interface(char *ebuf) { pcap_t *p; - p = pcap_create_common(device, ebuf, sizeof (struct pcap_bpf)); + p = pcap_create_common(ebuf, sizeof (struct pcap_bpf)); if (p == NULL) return (NULL); diff --git a/pcap-dlpi.c b/pcap-dlpi.c index 38f01a8e..623c5c21 100644 --- a/pcap-dlpi.c +++ b/pcap-dlpi.c @@ -1812,14 +1812,14 @@ dlpi_kread(register int fd, register off_t addr, #endif pcap_t * -pcap_create_interface(const char *device, char *ebuf) +pcap_create_interface(char *ebuf) { pcap_t *p; #ifdef DL_HP_RAWDLS struct pcap_dlpi *pd; #endif - p = pcap_create_common(device, ebuf, sizeof (struct pcap_dlpi)); + p = pcap_create_common(ebuf, sizeof (struct pcap_dlpi)); if (p == NULL) return (NULL); diff --git a/pcap-dos.c b/pcap-dos.c index c852817c..f42b394b 100644 --- a/pcap-dos.c +++ b/pcap-dos.c @@ -149,11 +149,11 @@ struct pcap_dos { struct pcap_stat stat; }; -pcap_t *pcap_create_interface (const char *device, char *ebuf) +pcap_t *pcap_create_interface (char *ebuf) { pcap_t *p; - p = pcap_create_common(device, ebuf, sizeof (struct pcap_dos)); + p = pcap_create_common(ebuf, sizeof (struct pcap_dos)); if (p == NULL) return (NULL); diff --git a/pcap-int.h b/pcap-int.h index 62815279..d88331df 100644 --- a/pcap-int.h +++ b/pcap-int.h @@ -446,8 +446,8 @@ int pcap_setnonblock_fd(pcap_t *p, int, char *); * "pcap_create_common()" allocates and fills in a pcap_t, for use * by pcap_create routines. */ -pcap_t *pcap_create_interface(const char *, char *); -pcap_t *pcap_create_common(const char *, char *, size_t); +pcap_t *pcap_create_interface(char *); +pcap_t *pcap_create_common(char *, size_t); int pcap_do_addexit(pcap_t *); void pcap_add_to_pcaps_to_close(pcap_t *); void pcap_remove_from_pcaps_to_close(pcap_t *); diff --git a/pcap-libdlpi.c b/pcap-libdlpi.c index 745c0c77..0bbc96cc 100644 --- a/pcap-libdlpi.c +++ b/pcap-libdlpi.c @@ -426,11 +426,11 @@ pcap_libdlpi_err(const char *linkname, const char *func, int err, char *errbuf) } pcap_t * -pcap_create_interface(const char *device, char *ebuf) +pcap_create_interface(char *ebuf) { pcap_t *p; - p = pcap_create_common(device, ebuf, sizeof (struct pcap_dlpi)); + p = pcap_create_common(ebuf, sizeof (struct pcap_dlpi)); if (p == NULL) return (NULL); diff --git a/pcap-linux.c b/pcap-linux.c index cae2e21a..ea38fff5 100644 --- a/pcap-linux.c +++ b/pcap-linux.c @@ -454,11 +454,11 @@ static struct sock_fprog total_fcode #endif /* SO_ATTACH_FILTER */ pcap_t * -pcap_create_interface(const char *device, char *ebuf) +pcap_create_interface(char *ebuf) { pcap_t *handle; - handle = pcap_create_common(device, ebuf, sizeof (struct pcap_linux)); + handle = pcap_create_common(ebuf, sizeof (struct pcap_linux)); if (handle == NULL) return NULL; diff --git a/pcap-nit.c b/pcap-nit.c index aedd12e5..ce3e52a5 100644 --- a/pcap-nit.c +++ b/pcap-nit.c @@ -355,11 +355,11 @@ pcap_activate_nit(pcap_t *p) } pcap_t * -pcap_create_interface(const char *device, char *ebuf) +pcap_create_interface(char *ebuf) { pcap_t *p; - p = pcap_create_common(device, ebuf, sizeof (struct pcap_nit)); + p = pcap_create_common(ebuf, sizeof (struct pcap_nit)); if (p == NULL) return (NULL); diff --git a/pcap-null.c b/pcap-null.c index 20f6f3ee..af46b8c7 100644 --- a/pcap-null.c +++ b/pcap-null.c @@ -36,7 +36,7 @@ static char nosup[] = "live packet capture not supported on this system"; pcap_t * -pcap_create_interface(const char *device, char *ebuf) +pcap_create_interface(char *ebuf) { (void)strlcpy(ebuf, nosup, PCAP_ERRBUF_SIZE); return (NULL); diff --git a/pcap-pf.c b/pcap-pf.c index f7e7f51f..00e9107e 100644 --- a/pcap-pf.c +++ b/pcap-pf.c @@ -506,11 +506,11 @@ your system may not be properly configured; see the packetfilter(4) man page\n", } pcap_t * -pcap_create_interface(const char *device, char *ebuf) +pcap_create_interface(char *ebuf) { pcap_t *p; - p = pcap_create_common(device, ebuf, sizeof (struct pcap_pf)); + p = pcap_create_common(ebuf, sizeof (struct pcap_pf)); if (p == NULL) return (NULL); diff --git a/pcap-sita.c b/pcap-sita.c index 6ceb38d9..123700d3 100644 --- a/pcap-sita.c +++ b/pcap-sita.c @@ -1014,10 +1014,10 @@ static int pcap_activate_sita(pcap_t *handle) { return 0; } -pcap_t *pcap_create_interface(const char *device, char *ebuf) { +pcap_t *pcap_create_interface(char *ebuf) { pcap_t *p; - p = pcap_create_common(device, ebuf, 0); + p = pcap_create_common(ebuf, 0); if (p == NULL) return (NULL); diff --git a/pcap-snit.c b/pcap-snit.c index f7e70ed7..ae8dd8bd 100644 --- a/pcap-snit.c +++ b/pcap-snit.c @@ -431,11 +431,11 @@ pcap_activate_snit(pcap_t *p) } pcap_t * -pcap_create_interface(const char *device, char *ebuf) +pcap_create_interface(char *ebuf) { pcap_t *p; - p = pcap_create_common(device, ebuf, sizeof (struct pcap_snit)); + p = pcap_create_common(ebuf, sizeof (struct pcap_snit)); if (p == NULL) return (NULL); diff --git a/pcap-snoop.c b/pcap-snoop.c index 7128f0b8..cdee48b5 100644 --- a/pcap-snoop.c +++ b/pcap-snoop.c @@ -406,11 +406,11 @@ pcap_activate_snoop(pcap_t *p) } pcap_t * -pcap_create_interface(const char *device, char *ebuf) +pcap_create_interface(char *ebuf) { pcap_t *p; - p = pcap_create_common(device, ebuf, sizeof (struct pcap_snoop)); + p = pcap_create_common(ebuf, sizeof (struct pcap_snoop)); if (p == NULL) return (NULL); diff --git a/pcap-win32.c b/pcap-win32.c index 2ab6e2af..0e380ea6 100644 --- a/pcap-win32.c +++ b/pcap-win32.c @@ -1062,42 +1062,11 @@ bad: } pcap_t * -pcap_create_interface(const char *device, char *ebuf) +pcap_create_interface(char *ebuf) { pcap_t *p; - if (strlen(device) == 1) - { - /* - * It's probably a unicode string - * Convert to ascii and pass it to pcap_create_common - * - * This wonderful hack is needed because pcap_lookupdev still returns - * unicode strings, and it's used by windump when no device is specified - * in the command line - */ - size_t length; - char* deviceAscii; - - length = wcslen((wchar_t*)device); - - deviceAscii = (char*)malloc(length + 1); - - if (deviceAscii == NULL) - { - pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "Malloc failed"); - return (NULL); - } - - pcap_snprintf(deviceAscii, length + 1, "%ws", (wchar_t*)device); - p = pcap_create_common(deviceAscii, ebuf, sizeof (struct pcap_win)); - free(deviceAscii); - } - else - { - p = pcap_create_common(device, ebuf, sizeof (struct pcap_win)); - } - + p = pcap_create_common(ebuf, sizeof (struct pcap_win)); if (p == NULL) return (NULL); diff --git a/pcap.c b/pcap.c index 9db58cdc..701f9ace 100644 --- a/pcap.c +++ b/pcap.c @@ -428,6 +428,7 @@ pcap_create(const char *device, char *errbuf) size_t i; int is_theirs; pcap_t *p; + char *device_str; /* * A null device name is equivalent to the "any" device - @@ -437,7 +438,39 @@ pcap_create(const char *device, char *errbuf) * the null pointer. */ if (device == NULL) - device = "any"; + device_str = strdup("any"); + else { +#ifdef _WIN32 + /* + * If the string appears to be little-endian UCS-2/UTF-16, + * convert it to ASCII. + * + * XXX - to UTF-8 instead? Or report an error if any + * character isn't ASCII? + */ + if (device[0] != '\0' && device[1] == '\0') { + size_t length; + char *device_ascii; + + length = wcslen((wchar_t *)device); + device_str = (char *)malloc(length + 1); + if (device_str == NULL) { + pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, + "malloc: %s", pcap_strerror(errno)); + return (NULL); + } + + pcap_snprintf(device, length + 1, "%ws", + (wchar_t *)device); + } else +#endif + device_str = strdup(device); + } + if (device_str == NULL) { + pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, + "malloc: %s", pcap_strerror(errno)); + return (NULL); + } /* * Try each of the non-local-network-interface capture @@ -446,7 +479,8 @@ pcap_create(const char *device, char *errbuf) */ for (i = 0; capture_source_types[i].create_op != NULL; i++) { is_theirs = 0; - p = capture_source_types[i].create_op(device, errbuf, &is_theirs); + p = capture_source_types[i].create_op(device_str, errbuf, + &is_theirs); if (is_theirs) { /* * The device name refers to a device of the @@ -457,6 +491,14 @@ pcap_create(const char *device, char *errbuf) * should return that to report the failure * to create. */ + if (p == NULL) { + /* + * We assume the caller filled in errbuf. + */ + free(device_str); + return (NULL); + } + p->opt.device = device_str; return (p); } } @@ -464,7 +506,16 @@ pcap_create(const char *device, char *errbuf) /* * OK, try it as a regular network interface. */ - return (pcap_create_interface(device, errbuf)); + p = pcap_create_interface(errbuf); + if (p == NULL) { + /* + * We assume the caller filled in errbuf. + */ + free(device_str); + return (NULL); + } + p->opt.device = device_str; + return (p); } #endif @@ -558,7 +609,7 @@ pcap_alloc_pcap_t(char *ebuf, size_t size) } pcap_t * -pcap_create_common(const char *device, char *ebuf, size_t size) +pcap_create_common(char *ebuf, size_t size) { pcap_t *p; @@ -566,14 +617,6 @@ pcap_create_common(const char *device, char *ebuf, size_t size) if (p == NULL) return (NULL); - p->opt.device = strdup(device); - if (p->opt.device == NULL) { - pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", - pcap_strerror(errno)); - free(p); - return (NULL); - } - /* * Default to "can't set rfmon mode"; if it's supported by * a platform, the create routine that called us can set @@ -850,13 +893,6 @@ pcap_open_offline_common(char *ebuf, size_t size) return (NULL); p->opt.tstamp_precision = PCAP_TSTAMP_PRECISION_MICRO; - p->opt.device = strdup("(savefile)"); - if (p->opt.device == NULL) { - pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", - pcap_strerror(errno)); - free(p); - return (NULL); - } return (p); }