* 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;
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);
}
{
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);
* 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,
}
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);
}
{
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;
((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;
* 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
* 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:
/* The name is too long, so it can't possibly exist. */
return (PCAP_ERROR_NO_SUCH_DEVICE);
}
- (void)strncpy(ifr.lifr_name, name, sizeof(ifr.lifr_name));
+ (void)pcap_strlcpy(ifr.lifr_name, name, sizeof(ifr.lifr_name));
status = ioctl(fd, BIOCSETLIF, (caddr_t)&ifr);
#else
struct ifreq ifr;
/* The name is too long, so it can't possibly exist. */
return (PCAP_ERROR_NO_SUCH_DEVICE);
}
- (void)strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+ (void)pcap_strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
status = ioctl(fd, BIOCSETIF, (caddr_t)&ifr);
#endif
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:
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",
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)strncpy(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)) {
/* The name is too long, so it can't possibly exist. */
return (PCAP_ERROR_NO_SUCH_DEVICE);
}
- (void)strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+ (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) {
*/
return (0);
}
+#endif
#ifdef BIOCGDLTLIST
static int
/*
* 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)
strerror(errno));
} else {
memset(&req, 0, sizeof(req));
- strncpy(req.ifm_name, pb->device,
+ pcap_strlcpy(req.ifm_name, pb->device,
sizeof(req.ifm_name));
if (ioctl(sock, SIOCGIFMEDIA, &req) < 0) {
fprintf(stderr,
* turn it off.
*/
memset(&ifr, 0, sizeof(ifr));
- (void)strncpy(ifr.ifr_name,
+ (void)pcap_strlcpy(ifr.ifr_name,
pb->device,
sizeof(ifr.ifr_name));
ifr.ifr_media =
pcap_cleanup_live_common(p);
}
+#ifdef __APPLE__
static int
check_setif_failure(pcap_t *p, int error)
{
-#ifdef __APPLE__
int fd;
int err;
-#endif
if (error == PCAP_ERROR_NO_SUCH_DEVICE) {
/*
* No such device exists.
*/
-#ifdef __APPLE__
if (p->opt.rfmon && strncmp(p->opt.device, "wlt", 3) == 0) {
/*
* Monitor mode was requested, and we're trying
}
return (err);
}
-#endif
+
/*
* No such device.
*/
*/
return (error);
}
+#else
+static int
+check_setif_failure(pcap_t *p _U_, int error)
+{
+ /*
+ * Just return the error status; it's what we want, and, if it's
+ * PCAP_ERROR, the error string has been filled in.
+ */
+ return (error);
+}
+#endif
/*
* Default capture buffer size.
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;
* it when the pcap_t is closed.
*/
int s;
+ struct ifreq ifr;
/*
* Open a socket to use for ioctls to
*
* 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
return (-1);
}
memset(&req, 0, sizeof(req));
- strncpy(req.ifm_name, name, sizeof(req.ifm_name));
+ pcap_strlcpy(req.ifm_name, name, sizeof(req.ifm_name));
if (ioctl(sock, SIOCGIFMEDIA, &req) < 0) {
if (errno == EOPNOTSUPP || errno == EINVAL || errno == ENOTTY ||
errno == ENODEV || errno == EPERM
}
#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
}
memset(&req, 0, sizeof req);
- strncpy(req.ifm_name, p->opt.device, sizeof req.ifm_name);
+ pcap_strlcpy(req.ifm_name, p->opt.device, sizeof req.ifm_name);
/*
* Find out how many media types we have.
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);
return (PCAP_ERROR);
}
memset(&ifr, 0, sizeof(ifr));
- (void)strncpy(ifr.ifr_name, p->opt.device,
+ (void)pcap_strlcpy(ifr.ifr_name, p->opt.device,
sizeof(ifr.ifr_name));
ifr.ifr_media = req.ifm_current | IFM_IEEE80211_MONITOR;
if (ioctl(sock, SIOCSIFMEDIA, &ifr) == -1) {