diff options
Diffstat (limited to 'freebsd/contrib/libpcap/pcap-bpf.c')
-rw-r--r-- | freebsd/contrib/libpcap/pcap-bpf.c | 104 |
1 files changed, 75 insertions, 29 deletions
diff --git a/freebsd/contrib/libpcap/pcap-bpf.c b/freebsd/contrib/libpcap/pcap-bpf.c index dc2942af..2ae88397 100644 --- a/freebsd/contrib/libpcap/pcap-bpf.c +++ b/freebsd/contrib/libpcap/pcap-bpf.c @@ -208,7 +208,7 @@ static int monitor_mode(pcap_t *, int); # endif # if defined(__APPLE__) -static void remove_en(pcap_t *); +static void remove_non_802_11(pcap_t *); static void remove_802_11(pcap_t *); # endif @@ -739,10 +739,10 @@ get_dlt_list(int fd, int v, struct bpf_dltlist *bdlp, char *ebuf) } #endif +#if defined(__APPLE__) static int pcap_can_set_rfmon_bpf(pcap_t *p) { -#if defined(__APPLE__) struct utsname osinfo; struct ifreq ifr; int fd; @@ -801,8 +801,8 @@ pcap_can_set_rfmon_bpf(pcap_t *p) errno, "socket"); return (PCAP_ERROR); } - strlcpy(ifr.ifr_name, "wlt", sizeof(ifr.ifr_name)); - strlcat(ifr.ifr_name, p->opt.device + 2, sizeof(ifr.ifr_name)); + pcap_strlcpy(ifr.ifr_name, "wlt", sizeof(ifr.ifr_name)); + pcap_strlcat(ifr.ifr_name, p->opt.device + 2, sizeof(ifr.ifr_name)); if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0) { /* * No such device? @@ -882,7 +882,11 @@ pcap_can_set_rfmon_bpf(pcap_t *p) close(fd); #endif /* BIOCGDLTLIST */ return (0); +} #elif defined(HAVE_BSD_IEEE80211) +static int +pcap_can_set_rfmon_bpf(pcap_t *p) +{ int ret; ret = monitor_mode(p, 0); @@ -891,10 +895,14 @@ pcap_can_set_rfmon_bpf(pcap_t *p) if (ret == 0) return (1); /* success */ return (ret); +} #else +static int +pcap_can_set_rfmon_bpf(pcap_t *p _U_) +{ return (0); -#endif } +#endif static int pcap_stats_bpf(pcap_t *p, struct pcap_stat *ps) @@ -1014,18 +1022,21 @@ pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user) case EWOULDBLOCK: return (0); - case ENXIO: + case ENXIO: /* FreeBSD, DragonFly BSD, and Darwin */ + case EIO: /* OpenBSD */ + /* NetBSD appears not to return an error in this case */ /* * The device on which we're capturing * went away. * * XXX - we should really return - * PCAP_ERROR_IFACE_NOT_UP, but - * pcap_dispatch() etc. aren't - * defined to retur that. + * an appropriate error for that, + * but pcap_dispatch() etc. aren't + * documented as having error returns + * other than PCAP_ERROR or PCAP_ERROR_BREAK. */ pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, - "The interface went down"); + "The interface disappeared"); return (PCAP_ERROR); #if defined(sun) && !defined(BSD) && !defined(__svr4__) && !defined(__SVR4) @@ -1360,8 +1371,8 @@ bpf_load(char *errbuf) /* Check if the driver is loaded */ memset(&cfg_ld, 0x0, sizeof(cfg_ld)); + pcap_snprintf(buf, sizeof(buf), "%s/%s", DRIVER_PATH, BPF_NAME); cfg_ld.path = buf; - pcap_snprintf(cfg_ld.path, sizeof(cfg_ld.path), "%s/%s", DRIVER_PATH, BPF_NAME); if ((sysconfig(SYS_QUERYLOAD, (void *)&cfg_ld, sizeof(cfg_ld)) == -1) || (cfg_ld.kmid == 0)) { /* Driver isn't loaded, load it now */ @@ -1471,7 +1482,7 @@ pcap_cleanup_bpf(pcap_t *p) s = socket(AF_LOCAL, SOCK_DGRAM, 0); if (s >= 0) { - strlcpy(ifr.ifr_name, pb->device, + pcap_strlcpy(ifr.ifr_name, pb->device, sizeof(ifr.ifr_name)); ioctl(s, SIOCIFDESTROY, &ifr); close(s); @@ -1534,9 +1545,9 @@ check_setif_failure(pcap_t *p, int error) */ fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd != -1) { - strlcpy(ifr.ifr_name, "en", + pcap_strlcpy(ifr.ifr_name, "en", sizeof(ifr.ifr_name)); - strlcat(ifr.ifr_name, p->opt.device + 3, + pcap_strlcat(ifr.ifr_name, p->opt.device + 3, sizeof(ifr.ifr_name)); if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0) { /* @@ -1723,7 +1734,7 @@ pcap_activate_bpf(pcap_t *p) goto bad; } znamelen = zonesep - p->opt.device; - (void) strlcpy(path_zname, p->opt.device, znamelen + 1); + (void) pcap_strlcpy(path_zname, p->opt.device, znamelen + 1); ifr.lifr_zoneid = getzoneidbyname(path_zname); if (ifr.lifr_zoneid == -1) { pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, @@ -1788,7 +1799,7 @@ pcap_activate_bpf(pcap_t *p) */ sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd != -1) { - strlcpy(ifrname, + pcap_strlcpy(ifrname, p->opt.device, ifnamsiz); if (ioctl(sockfd, SIOCGIFFLAGS, (char *)&ifr) < 0) { @@ -1890,7 +1901,7 @@ pcap_activate_bpf(pcap_t *p) /* * Create the interface. */ - strlcpy(ifr.ifr_name, p->opt.device, sizeof(ifr.ifr_name)); + pcap_strlcpy(ifr.ifr_name, p->opt.device, sizeof(ifr.ifr_name)); if (ioctl(s, SIOCIFCREATE2, &ifr) < 0) { if (errno == EINVAL) { pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, @@ -2189,7 +2200,7 @@ pcap_activate_bpf(pcap_t *p) * of link-layer types, as selecting * it will keep monitor mode off. */ - remove_en(p); + remove_non_802_11(p); /* * If the new mode we want isn't @@ -2750,12 +2761,21 @@ get_if_flags(const char *name, bpf_u_int32 *flags, char *errbuf) strncpy(req.ifm_name, name, sizeof(req.ifm_name)); if (ioctl(sock, SIOCGIFMEDIA, &req) < 0) { if (errno == EOPNOTSUPP || errno == EINVAL || errno == ENOTTY || - errno == ENODEV) { + errno == ENODEV || errno == EPERM) { /* * Not supported, so we can't provide any * additional information. Assume that * this means that "connected" vs. * "disconnected" doesn't apply. + * + * The ioctl routine for Apple's pktap devices, + * annoyingly, checks for "are you root?" before + * checking whether the ioctl is valid, so it + * returns EPERM, rather than ENOTSUP, for the + * invalid SIOCGIFMEDIA, unless you're root. + * So, just as we do for some ethtool ioctls + * on Linux, which makes the same mistake, we + * also treat EPERM as meaning "not supported". */ *flags |= PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE; close(sock); @@ -2892,7 +2912,7 @@ monitor_mode(pcap_t *p, int set) default: pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, - errno, "SIOCGIFMEDIA 1"); + errno, "SIOCGIFMEDIA"); close(sock); return (PCAP_ERROR); } @@ -3034,8 +3054,12 @@ find_802_11(struct bpf_dltlist *bdlp) new_dlt = bdlp->bfl_list[i]; break; +#ifdef DLT_PRISM_HEADER case DLT_PRISM_HEADER: +#endif +#ifdef DLT_AIRONET_HEADER case DLT_AIRONET_HEADER: +#endif case DLT_IEEE802_11_RADIO_AVS: /* * 802.11 with radio, but not radiotap. @@ -3070,24 +3094,25 @@ find_802_11(struct bpf_dltlist *bdlp) #if defined(__APPLE__) && defined(BIOCGDLTLIST) /* - * Remove DLT_EN10MB from the list of DLT_ values, as we're in monitor mode, - * and DLT_EN10MB isn't supported in monitor mode. + * Remove non-802.11 header types from the list of DLT_ values, as we're in + * monitor mode, and those header types aren't supported in monitor mode. */ static void -remove_en(pcap_t *p) +remove_non_802_11(pcap_t *p) { int i, j; /* - * Scan the list of DLT_ values and discard DLT_EN10MB. + * Scan the list of DLT_ values and discard non-802.11 ones. */ j = 0; for (i = 0; i < p->dlt_count; i++) { switch (p->dlt_list[i]) { case DLT_EN10MB: + case DLT_RAW: /* - * Don't offer this one. + * Not 802.11. Don't offer this one. */ continue; @@ -3129,10 +3154,17 @@ remove_802_11(pcap_t *p) switch (p->dlt_list[i]) { case DLT_IEEE802_11: +#ifdef DLT_PRISM_HEADER case DLT_PRISM_HEADER: +#endif +#ifdef DLT_AIRONET_HEADER case DLT_AIRONET_HEADER: +#endif case DLT_IEEE802_11_RADIO: case DLT_IEEE802_11_RADIO_AVS: +#ifdef DLT_PPI + case DLT_PPI: +#endif /* * 802.11. Don't offer this one. */ @@ -3224,10 +3256,10 @@ pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp) * Set direction flag: Which packets do we accept on a forwarding * single device? IN, OUT or both? */ +#if defined(BIOCSDIRECTION) static int pcap_setdirection_bpf(pcap_t *p, pcap_direction_t d) { -#if defined(BIOCSDIRECTION) u_int direction; direction = (d == PCAP_D_IN) ? BPF_D_IN : @@ -3240,7 +3272,11 @@ pcap_setdirection_bpf(pcap_t *p, pcap_direction_t d) return (-1); } return (0); +} #elif defined(BIOCSSEESENT) +static int +pcap_setdirection_bpf(pcap_t *p, pcap_direction_t d) +{ u_int seesent; /* @@ -3260,25 +3296,35 @@ pcap_setdirection_bpf(pcap_t *p, pcap_direction_t d) return (-1); } return (0); +} #else +static int +pcap_setdirection_bpf(pcap_t *p, pcap_direction_t d _U_) +{ (void) pcap_snprintf(p->errbuf, sizeof(p->errbuf), "This system doesn't support BIOCSSEESENT, so the direction can't be set"); return (-1); -#endif } +#endif +#ifdef BIOCSDLT static int pcap_set_datalink_bpf(pcap_t *p, int dlt) { -#ifdef BIOCSDLT if (ioctl(p->fd, BIOCSDLT, &dlt) == -1) { pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf), errno, "Cannot set DLT %d", dlt); return (-1); } -#endif return (0); } +#else +static int +pcap_set_datalink_bpf(pcap_t *p _U_, int dlt _U_) +{ + return (0); +} +#endif /* * Platform-specific information. |