X-Git-Url: https://git.tcpdump.org/libpcap/blobdiff_plain/e9288160d83cfb5bb79e7754c1103bf9eb250235..09b51d326c38ea8e10ce4da09c09d50e08c5aeb8:/pcap-bpf.c diff --git a/pcap-bpf.c b/pcap-bpf.c index 02ebd705..2898e598 100644 --- a/pcap-bpf.c +++ b/pcap-bpf.c @@ -152,7 +152,7 @@ struct pcap_bpf { * As there is a header on the front size of the mmap'd buffer, only * some of the buffer is exposed to libpcap as a whole via bufsize; * zbufsize is the true size. zbuffer tracks the current zbuf - * assocated with buffer so that it can be used to decide which the + * associated with buffer so that it can be used to decide which the * next buffer to read will be. */ u_char *zbuf1, *zbuf2, *zbuffer; @@ -312,7 +312,7 @@ pcap_next_zbuf_shm(pcap_t *p, int *cc) atomic_load_acq_int(&bzh->bzh_kernel_gen)) { pb->bzh = bzh; pb->zbuffer = (u_char *)pb->zbuf2; - p->buffer = pb->zbuffer + sizeof(*bzh); + p->buffer = pb->zbuffer + sizeof(*bzh); *cc = bzh->bzh_kernel_len; return (1); } @@ -444,7 +444,7 @@ pcap_create_interface(const char *device _U_, char *ebuf) { pcap_t *p; - p = pcap_create_common(ebuf, sizeof (struct pcap_bpf)); + p = PCAP_CREATE_COMMON(ebuf, struct pcap_bpf); if (p == NULL) return (NULL); @@ -455,7 +455,6 @@ pcap_create_interface(const char *device _U_, char *ebuf) * We claim that we support microsecond and nanosecond time * stamps. */ - p->tstamp_precision_count = 2; p->tstamp_precision_list = malloc(2 * sizeof(u_int)); if (p->tstamp_precision_list == NULL) { pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, errno, @@ -465,6 +464,7 @@ pcap_create_interface(const char *device _U_, char *ebuf) } p->tstamp_precision_list[0] = PCAP_TSTAMP_PRECISION_MICRO; p->tstamp_precision_list[1] = PCAP_TSTAMP_PRECISION_NANO; + p->tstamp_precision_count = 2; #endif /* BIOCSTSTAMP */ return (p); } @@ -478,7 +478,7 @@ bpf_open(char *errbuf) { int fd = -1; static const char cloning_device[] = "/dev/bpf"; - int n = 0; + u_int n = 0; char device[sizeof "/dev/bpf0000000000"]; static int no_cloning_bpf = 0; @@ -503,12 +503,17 @@ bpf_open(char *errbuf) ((errno != EACCES && errno != ENOENT) || (fd = open(cloning_device, O_RDONLY)) == -1)) { if (errno != ENOENT) { - if (errno == EACCES) + if (errno == EACCES) { fd = PCAP_ERROR_PERM_DENIED; - else + snprintf(errbuf, PCAP_ERRBUF_SIZE, + "Attempt to open %s failed - root privileges may be required", + cloning_device); + } else { fd = PCAP_ERROR; - pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, - errno, "(cannot open device) %s", cloning_device); + pcap_fmt_errmsg_for_errno(errbuf, + PCAP_ERRBUF_SIZE, errno, + "(cannot open device) %s", cloning_device); + } return (fd); } no_cloning_bpf = 1; @@ -521,7 +526,7 @@ bpf_open(char *errbuf) * that isn't in use. */ do { - (void)snprintf(device, sizeof(device), "/dev/bpf%d", n++); + (void)snprintf(device, sizeof(device), "/dev/bpf%u", n++); /* * Initially try a read/write open (to allow the inject * method to work). If that fails due to permission @@ -577,8 +582,9 @@ bpf_open(char *errbuf) * if any. */ fd = PCAP_ERROR_PERM_DENIED; - pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, - errno, "(cannot open BPF device) %s", device); + snprintf(errbuf, PCAP_ERRBUF_SIZE, + "Attempt to open %s failed - root privileges may be required", + device); break; default: @@ -655,7 +661,11 @@ bpf_bind(int fd, const char *name, char *errbuf) case ENXIO: /* * There's no such device. + * + * There's nothing more to say, so clear out the + * error message. */ + errbuf[0] = '\0'; return (PCAP_ERROR_NO_SUCH_DEVICE); case ENETDOWN: @@ -680,7 +690,7 @@ bpf_bind(int fd, const char *name, char *errbuf) errno, "The requested buffer size for %s is too large", name); return (BPF_BIND_BUFFER_TOO_BIG); - + default: pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE, errno, "Binding interface %s to BPF device failed", @@ -735,20 +745,11 @@ bpf_open_and_bind(const char *name, char *errbuf) return (fd); } +#ifdef __APPLE__ static int device_exists(int fd, const char *name, char *errbuf) { int status; -#ifdef LIFNAMSIZ - struct lifreq ifr; - - if (strlen(name) >= sizeof(ifr.lifr_name)) { - /* The name is too long, so it can't possibly exist. */ - return (PCAP_ERROR_NO_SUCH_DEVICE); - } - (void)pcap_strlcpy(ifr.lifr_name, name, sizeof(ifr.lifr_name)); - status = ioctl(fd, SIOCGLIFFLAGS, (caddr_t)&ifr); -#else struct ifreq ifr; if (strlen(name) >= sizeof(ifr.ifr_name)) { @@ -757,7 +758,6 @@ device_exists(int fd, const char *name, char *errbuf) } (void)pcap_strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); status = ioctl(fd, SIOCGIFFLAGS, (caddr_t)&ifr); -#endif if (status < 0) { if (errno == ENXIO || errno == EINVAL) { @@ -784,6 +784,7 @@ device_exists(int fd, const char *name, char *errbuf) */ return (0); } +#endif #ifdef BIOCGDLTLIST static int @@ -1186,6 +1187,9 @@ pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user) /* * Loop through each packet. + * + * This assumes that a single buffer of packets will have + * <= INT_MAX packets, so the packet count doesn't overflow. */ #ifdef BIOCSTSTAMP #define bhp ((struct bpf_xhdr *)bp) @@ -1760,7 +1764,8 @@ pcap_activate_bpf(pcap_t *p) int retv; #endif int fd; -#ifdef LIFNAMSIZ +#if defined(LIFNAMSIZ) && defined(ZONENAME_MAX) && defined(lifr_zoneid) + struct lifreq ifr; char *zonesep; #endif struct bpf_version bv; @@ -2199,7 +2204,7 @@ pcap_activate_bpf(pcap_t *p) * * Otherwise, fail. */ - if (errno != BPF_BIND_BUFFER_TOO_BIG) { + if (status != BPF_BIND_BUFFER_TOO_BIG) { /* * Special checks on macOS to deal * with the way monitor mode was @@ -2976,7 +2981,7 @@ get_if_flags(const char *name, bpf_u_int32 *flags, char *errbuf) } #else static int -get_if_flags(const char *name _U_, bpf_u_int32 *flags _U_, char *errbuf _U_) +get_if_flags(const char *name _U_, bpf_u_int32 *flags, char *errbuf _U_) { /* * Nothing we can do other than mark loopback devices as "the @@ -3051,7 +3056,11 @@ monitor_mode(pcap_t *p, int set) case ENXIO: /* * There's no such device. + * + * There's nothing more to say, so clear the + * error message. */ + p->errbuf[0] = '\0'; close(sock); return (PCAP_ERROR_NO_SUCH_DEVICE);