diff --git a/config.h.in b/config.h.in index 4bbb491ec1..af21786552 100644 --- a/config.h.in +++ b/config.h.in @@ -256,9 +256,6 @@ /* target host supports Bluetooth sniffing */ #undef PCAP_SUPPORT_BT -/* target host supports Bluetooth Monitor */ -#undef PCAP_SUPPORT_BT_MONITOR - /* target host supports CAN sniffing */ #undef PCAP_SUPPORT_CAN @@ -277,9 +274,6 @@ /* include ACN support */ #undef SITA -/* if struct sockaddr_hci has hci_channel member */ -#undef SOCKADDR_HCI_HAS_HCI_CHANNEL - /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS diff --git a/configure b/configure index 1a800f57bd..778eb3ded1 100755 --- a/configure +++ b/configure @@ -8020,117 +8020,17 @@ fi if test "x$enable_bluetooth" != "xno" ; then case "$host_os" in linux*) - ac_fn_c_check_header_mongrel "$LINENO" "bluetooth/bluetooth.h" "ac_cv_header_bluetooth_bluetooth_h" "$ac_includes_default" -if test "x$ac_cv_header_bluetooth_bluetooth_h" = xyes; then : - $as_echo "#define PCAP_SUPPORT_BT 1" >>confdefs.h - BT_SRC=pcap-bt-linux.c - { $as_echo "$as_me:${as_lineno-$LINENO}: Bluetooth sniffing is supported" >&5 + BT_SRC=pcap-bt-linux.c + BT_MONITOR_SRC=pcap-bt-monitor-linux.c + { $as_echo "$as_me:${as_lineno-$LINENO}: Bluetooth sniffing is supported" >&5 $as_echo "$as_me: Bluetooth sniffing is supported" >&6;} - - # - # OK, does struct sockaddr_hci have an hci_channel - # member? - # - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if struct sockaddr_hci has hci_channel member" >&5 -$as_echo_n "checking if struct sockaddr_hci has hci_channel member... " >&6; } - if ${ac_cv_lbl_sockaddr_hci_has_hci_channel+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include -#include - -int -main () -{ -u_int i = sizeof(((struct sockaddr_hci *)0)->hci_channel) - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_lbl_sockaddr_hci_has_hci_channel=yes -else - ac_cv_lbl_sockaddr_hci_has_hci_channel=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lbl_sockaddr_hci_has_hci_channel" >&5 -$as_echo "$ac_cv_lbl_sockaddr_hci_has_hci_channel" >&6; } - if test $ac_cv_lbl_sockaddr_hci_has_hci_channel = yes ; then - -$as_echo "#define SOCKADDR_HCI_HAS_HCI_CHANNEL /**/" >>confdefs.h - - - # - # OK, is HCI_CHANNEL_MONITOR defined? - # - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if HCI_CHANNEL_MONITOR is defined" >&5 -$as_echo_n "checking if HCI_CHANNEL_MONITOR is defined... " >&6; } - if ${ac_cv_lbl_hci_channel_monitor_is_defined+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include -#include - -int -main () -{ -u_int i = HCI_CHANNEL_MONITOR - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_lbl_hci_channel_monitor_is_defined=yes -else - ac_cv_lbl_hci_channel_monitor_is_defined=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lbl_hci_channel_monitor_is_defined" >&5 -$as_echo "$ac_cv_lbl_hci_channel_monitor_is_defined" >&6; } - if test $ac_cv_lbl_hci_channel_monitor_is_defined = yes ; then - -$as_echo "#define PCAP_SUPPORT_BT_MONITOR /**/" >>confdefs.h - - BT_MONITOR_SRC=pcap-bt-monitor-linux.c - fi - fi - ac_lbl_bluetooth_available=yes - -else - ac_lbl_bluetooth_available=no - -fi - - - if test "x$ac_lbl_bluetooth_available" == "xno" ; then - if test "x$enable_bluetooth" = "xyes" ; then - as_fn_error $? "Bluetooth sniffing is not supported; install bluez-lib devel to enable it" "$LINENO" 5 - else - { $as_echo "$as_me:${as_lineno-$LINENO}: Bluetooth sniffing is not supported; install bluez-lib devel to enable it" >&5 -$as_echo "$as_me: Bluetooth sniffing is not supported; install bluez-lib devel to enable it" >&6;} - fi - fi ;; *) - if test "x$enable_bluetooth" = "xyes" ; then - as_fn_error $? "no Bluetooth sniffing support implemented for $host_os" "$LINENO" 5 - else - { $as_echo "$as_me:${as_lineno-$LINENO}: no Bluetooth sniffing support implemented for $host_os" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: no Bluetooth sniffing support implemented for $host_os" >&5 $as_echo "$as_me: no Bluetooth sniffing support implemented for $host_os" >&6;} - fi ;; esac diff --git a/configure.in b/configure.in index 063c645235..5e0721efa1 100644 --- a/configure.in +++ b/configure.in @@ -1468,69 +1468,13 @@ if test "x$enable_bluetooth" != "xno" ; then dnl check for Bluetooth sniffing support case "$host_os" in linux*) - AC_CHECK_HEADER(bluetooth/bluetooth.h, - [ - AC_DEFINE(PCAP_SUPPORT_BT, 1, [target host supports Bluetooth sniffing]) - BT_SRC=pcap-bt-linux.c - AC_MSG_NOTICE(Bluetooth sniffing is supported) - - # - # OK, does struct sockaddr_hci have an hci_channel - # member? - # - AC_MSG_CHECKING(if struct sockaddr_hci has hci_channel member) - AC_CACHE_VAL(ac_cv_lbl_sockaddr_hci_has_hci_channel, - AC_TRY_COMPILE( -[ -#include -#include -], - [u_int i = sizeof(((struct sockaddr_hci *)0)->hci_channel)], - ac_cv_lbl_sockaddr_hci_has_hci_channel=yes, - ac_cv_lbl_sockaddr_hci_has_hci_channel=no)) - AC_MSG_RESULT($ac_cv_lbl_sockaddr_hci_has_hci_channel) - if test $ac_cv_lbl_sockaddr_hci_has_hci_channel = yes ; then - AC_DEFINE(SOCKADDR_HCI_HAS_HCI_CHANNEL,, - [if struct sockaddr_hci has hci_channel member]) - - # - # OK, is HCI_CHANNEL_MONITOR defined? - # - AC_MSG_CHECKING(if HCI_CHANNEL_MONITOR is defined) - AC_CACHE_VAL(ac_cv_lbl_hci_channel_monitor_is_defined, - AC_TRY_COMPILE( -[ -#include -#include -], - [u_int i = HCI_CHANNEL_MONITOR], - ac_cv_lbl_hci_channel_monitor_is_defined=yes, - ac_cv_lbl_hci_channel_monitor_is_defined=no)) - AC_MSG_RESULT($ac_cv_lbl_hci_channel_monitor_is_defined) - if test $ac_cv_lbl_hci_channel_monitor_is_defined = yes ; then - AC_DEFINE(PCAP_SUPPORT_BT_MONITOR,, - [target host supports Bluetooth Monitor]) - BT_MONITOR_SRC=pcap-bt-monitor-linux.c - fi - fi - ac_lbl_bluetooth_available=yes - ], - ac_lbl_bluetooth_available=no - ) - if test "x$ac_lbl_bluetooth_available" == "xno" ; then - if test "x$enable_bluetooth" = "xyes" ; then - AC_MSG_ERROR(Bluetooth sniffing is not supported; install bluez-lib devel to enable it) - else - AC_MSG_NOTICE(Bluetooth sniffing is not supported; install bluez-lib devel to enable it) - fi - fi + AC_DEFINE(PCAP_SUPPORT_BT, 1, [target host supports Bluetooth sniffing]) + BT_SRC=pcap-bt-linux.c + BT_MONITOR_SRC=pcap-bt-monitor-linux.c + AC_MSG_NOTICE(Bluetooth sniffing is supported) ;; *) - if test "x$enable_bluetooth" = "xyes" ; then - AC_MSG_ERROR(no Bluetooth sniffing support implemented for $host_os) - else - AC_MSG_NOTICE(no Bluetooth sniffing support implemented for $host_os) - fi + AC_MSG_NOTICE(no Bluetooth sniffing support implemented for $host_os) ;; esac AC_SUBST(PCAP_SUPPORT_BT) diff --git a/pcap-bt-linux.c b/pcap-bt-linux.c index a32691d348..c910a8b628 100644 --- a/pcap-bt-linux.c +++ b/pcap-bt-linux.c @@ -11,8 +11,8 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS @@ -31,7 +31,7 @@ * By Paolo Abeni * */ - + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -51,10 +51,99 @@ #include #include #include +#include #include -#include -#include +#define HCI_MAX_DEV 15 + +/* Start of copy of unexported Linux Kernel headers */ +#ifndef AF_BLUETOOTH +#define AF_BLUETOOTH 31 +#endif + +#define BTPROTO_HCI 1 + +#define SOL_HCI 0 + +#define HCI_CHANNEL_RAW 0 + +#define HCI_DATA_DIR 1 +#define HCI_FILTER 2 +#define HCI_TIME_STAMP 3 + +#define HCI_CMSG_DIR 0x0001 +#define HCI_CMSG_TSTAMP 0x0002 + +#define HCIGETDEVLIST _IOR('H', 210, int) +#define HCIGETDEVINFO _IOR('H', 211, int) + +struct hci_dev_req { + uint16_t dev_id; + uint32_t dev_opt; +}; + +struct hci_dev_list_req { + uint16_t dev_num; + struct hci_dev_req dev_req[HCI_MAX_DEV]; +}; + +typedef struct { + uint8_t b[6]; +} bdaddr_t; + +struct sockaddr_hci_v1 { + sa_family_t hci_family; + unsigned short hci_dev; +}; + +struct sockaddr_hci_v2 { + sa_family_t hci_family; + unsigned short hci_dev; + unsigned short hci_channel; +}; + +struct hci_filter { + uint32_t type_mask; + uint32_t event_mask[2]; + uint16_t opcode; +}; + +struct hci_dev_stats { + uint32_t err_rx; + uint32_t err_tx; + uint32_t cmd_tx; + uint32_t evt_rx; + uint32_t acl_tx; + uint32_t acl_rx; + uint32_t sco_tx; + uint32_t sco_rx; + uint32_t byte_rx; + uint32_t byte_tx; +}; + +struct hci_dev_info { + uint16_t dev_id; + char name[8]; + + bdaddr_t bdaddr; + + uint32_t flags; + uint8_t type; + + uint8_t features[8]; + + uint32_t pkt_type; + uint32_t link_policy; + uint32_t link_mode; + + uint16_t acl_mtu; + uint16_t acl_pkts; + uint16_t sco_mtu; + uint16_t sco_pkts; + + struct hci_dev_stats stat; +}; +/* End of copy of unexported Linux Kernel headers */ #define BT_IFACE "bluetooth" #define BT_CTRL_SIZE 128 @@ -73,10 +162,10 @@ struct pcap_bt { int dev_id; /* device ID of device we're bound to */ }; -int +int bt_findalldevs(pcap_if_t **alldevsp, char *err_str) { - struct hci_dev_list_req *dev_list; + struct hci_dev_list_req dev_list; struct hci_dev_req *dev_req; int i, sock; int ret = 0; @@ -84,7 +173,7 @@ bt_findalldevs(pcap_if_t **alldevsp, char *err_str) sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); if (sock < 0) { - /* if bluetooth is not supported this this is not fatal*/ + /* if bluetooth is not supported this is not fatal*/ if (errno == EAFNOSUPPORT) return 0; snprintf(err_str, PCAP_ERRBUF_SIZE, @@ -92,34 +181,25 @@ bt_findalldevs(pcap_if_t **alldevsp, char *err_str) return -1; } - dev_list = malloc(HCI_MAX_DEV * sizeof(*dev_req) + sizeof(*dev_list)); - if (!dev_list) - { - snprintf(err_str, PCAP_ERRBUF_SIZE, "Can't allocate %zu bytes for Bluetooth device list", - HCI_MAX_DEV * sizeof(*dev_req) + sizeof(*dev_list)); - ret = -1; - goto done; - } - - dev_list->dev_num = HCI_MAX_DEV; + dev_list.dev_num = HCI_MAX_DEV; - if (ioctl(sock, HCIGETDEVLIST, (void *) dev_list) < 0) + if (ioctl(sock, HCIGETDEVLIST, (void *) &dev_list) < 0) { snprintf(err_str, PCAP_ERRBUF_SIZE, "Can't get Bluetooth device list via ioctl: %s", strerror(errno)); ret = -1; - goto free; + goto done; } - dev_req = dev_list->dev_req; - for (i = 0; i < dev_list->dev_num; i++, dev_req++) { + dev_req = dev_list.dev_req; + for (i = 0; i < dev_list.dev_num; i++) { char dev_name[20], dev_descr[30]; - - snprintf(dev_name, 20, BT_IFACE"%d", dev_req->dev_id); + + snprintf(dev_name, 20, BT_IFACE"%d", dev_req[i].dev_id); snprintf(dev_descr, 30, "Bluetooth adapter number %d", i); - - if (pcap_add_if(alldevsp, dev_name, 0, + + if (pcap_add_if(alldevsp, dev_name, 0, dev_descr, err_str) < 0) { ret = -1; @@ -128,9 +208,6 @@ bt_findalldevs(pcap_if_t **alldevsp, char *err_str) } -free: - free(dev_list); - done: close(sock); return ret; @@ -183,17 +260,24 @@ static int bt_activate(pcap_t* handle) { struct pcap_bt *handlep = handle->priv; - struct sockaddr_hci addr; + struct sockaddr_hci_v1 addr_v1; + struct sockaddr_hci_v2 addr_v2; + struct sockaddr *addr; + int addr_size; int opt; int dev_id; struct hci_filter flt; int err = PCAP_ERROR; + struct utsname uname_data; + unsigned int version_major; + unsigned int version_minor; + unsigned int version_release; /* get bt interface id */ if (sscanf(handle->opt.source, BT_IFACE"%d", &dev_id) != 1) { snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, - "Can't get Bluetooth device index from %s", + "Can't get Bluetooth device index from %s", handle->opt.source); return PCAP_ERROR; } @@ -212,7 +296,7 @@ bt_activate(pcap_t* handle) handle->setnonblock_op = pcap_setnonblock_fd; handle->stats_op = bt_stats_linux; handlep->dev_id = dev_id; - + /* Create HCI socket */ handle->fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); if (handle->fd < 0) { @@ -242,10 +326,10 @@ bt_activate(pcap_t* handle) goto close_fail; } - /* Setup filter, do not call hci function to avoid dependence on + /* Setup filter, do not call hci function to avoid dependence on * external libs */ memset(&flt, 0, sizeof(flt)); - memset((void *) &flt.type_mask, 0xff, sizeof(flt.type_mask)); + memset((void *) &flt.type_mask, 0xff, sizeof(flt.type_mask)); memset((void *) &flt.event_mask, 0xff, sizeof(flt.event_mask)); if (setsockopt(handle->fd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) { snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, @@ -253,14 +337,30 @@ bt_activate(pcap_t* handle) goto close_fail; } + if (!(uname(&uname_data) == 0 && sscanf(uname_data.release, "%u.%u.%u", &version_major, &version_minor, &version_release) == 3)) { + /* Fallback to older kernel version */ + version_major = 2; + version_minor = 6; + version_release = 37; + } + + if (!(version_major >= 2 && version_minor >= 6 && version_release >= 38)) { + addr_v2.hci_family = AF_BLUETOOTH; + addr_v2.hci_dev = handlep->dev_id; + addr_v2.hci_channel = HCI_CHANNEL_RAW; + + addr_size = sizeof(struct sockaddr_hci_v2); + addr = (struct sockaddr *) &addr_v2; + } else { + addr_v1.hci_family = AF_BLUETOOTH; + addr_v1.hci_dev = handlep->dev_id; + + addr_size = sizeof(struct sockaddr_hci_v1); + addr = (struct sockaddr *) &addr_v1; + } /* Bind socket to the HCI device */ - addr.hci_family = AF_BLUETOOTH; - addr.hci_dev = handlep->dev_id; -#ifdef SOCKADDR_HCI_HAS_HCI_CHANNEL - addr.hci_channel = HCI_CHANNEL_RAW; -#endif - if (bind(handle->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + if (bind(handle->fd, addr, addr_size) < 0) { snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't attach to device %d: %s", handlep->dev_id, strerror(errno)); @@ -297,7 +397,7 @@ bt_activate(pcap_t* handle) } static int -bt_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user) +bt_read_linux(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_char *user) { struct cmsghdr *cmsg; struct msghdr msg; @@ -305,11 +405,12 @@ bt_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *us ssize_t ret; struct pcap_pkthdr pkth; pcap_bluetooth_h4_header* bthdr; + int in=0; bthdr = (pcap_bluetooth_h4_header*) &handle->buffer[handle->offset]; iv.iov_base = &handle->buffer[handle->offset+sizeof(pcap_bluetooth_h4_header)]; iv.iov_len = handle->snapshot; - + memset(&msg, 0, sizeof(msg)); msg.msg_iov = &iv; msg.msg_iovlen = 1; @@ -334,22 +435,22 @@ bt_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *us pkth.caplen = ret; - /* get direction and timestamp*/ + /* get direction and timestamp*/ cmsg = CMSG_FIRSTHDR(&msg); - int in=0; + while (cmsg) { switch (cmsg->cmsg_type) { case HCI_CMSG_DIR: memcpy(&in, CMSG_DATA(cmsg), sizeof in); break; - case HCI_CMSG_TSTAMP: - memcpy(&pkth.ts, CMSG_DATA(cmsg), - sizeof pkth.ts); + case HCI_CMSG_TSTAMP: + memcpy(&pkth.ts, CMSG_DATA(cmsg), + sizeof pkth.ts); break; } cmsg = CMSG_NXTHDR(&msg, cmsg); } - if ((in && (handle->direction == PCAP_D_OUT)) || + if ((in && (handle->direction == PCAP_D_OUT)) || ((!in) && (handle->direction == PCAP_D_IN))) return 0; @@ -366,15 +467,15 @@ bt_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *us } static int -bt_inject_linux(pcap_t *handle, const void *buf, size_t size) +bt_inject_linux(pcap_t *handle, const void *buf _U_, size_t size _U_) { snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported on " "bluetooth devices"); return (-1); -} +} -static int +static int bt_stats_linux(pcap_t *handle, struct pcap_stat *stats) { struct pcap_bt *handlep = handle->priv; @@ -382,28 +483,27 @@ bt_stats_linux(pcap_t *handle, struct pcap_stat *stats) struct hci_dev_info dev_info; struct hci_dev_stats * s = &dev_info.stat; dev_info.dev_id = handlep->dev_id; - + /* ignore eintr */ do { ret = ioctl(handle->fd, HCIGETDEVINFO, (void *)&dev_info); } while ((ret == -1) && (errno == EINTR)); - + if (ret < 0) { snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't get stats via ioctl: %s", strerror(errno)); return (-1); - } - /* we receive both rx and tx frames, so comulate all stats */ - stats->ps_recv = s->evt_rx + s->acl_rx + s->sco_rx + s->cmd_tx + + /* we receive both rx and tx frames, so comulate all stats */ + stats->ps_recv = s->evt_rx + s->acl_rx + s->sco_rx + s->cmd_tx + s->acl_tx +s->sco_tx; stats->ps_drop = s->err_rx + s->err_tx; stats->ps_ifdrop = 0; return 0; } -static int +static int bt_setdirection_linux(pcap_t *p, pcap_direction_t d) { p->direction = d; diff --git a/pcap-bt-monitor-linux.c b/pcap-bt-monitor-linux.c index f193e26362..0b07f03adb 100644 --- a/pcap-bt-monitor-linux.c +++ b/pcap-bt-monitor-linux.c @@ -36,23 +36,59 @@ #include #include #include +#include +#include +#include +#include -#include -#include -#include - -#include "pcap/bluetooth.h" #include "pcap-int.h" - +#include "pcap/bluetooth.h" #include "pcap-bt-monitor-linux.h" +/* Start of copy of unexported Linux Kernel headers */ + +#ifndef AF_BLUETOOTH +#define AF_BLUETOOTH 31 +#endif + +#define BTPROTO_HCI 1 + +#define HCI_CHANNEL_MONITOR 2 + +#define HCI_DEV_NONE 0xffff + +struct sockaddr_hci { + sa_family_t hci_family; + unsigned short hci_dev; + unsigned short hci_channel; +}; + +struct mgmt_hdr { + uint16_t opcode; + uint16_t index; + uint16_t len; +}; + +#define MGMT_HDR_SIZE sizeof(struct mgmt_hdr) +/* End of copy of unexported Linux Kernel headers */ + #define BT_CONTROL_SIZE 32 #define INTERFACE_NAME "bluetooth-monitor" int bt_monitor_findalldevs(pcap_if_t **alldevsp, char *err_str) { - int ret = 0; + int ret = 0; + struct utsname uname_data; + unsigned int version_major; + unsigned int version_minor; + unsigned int version_release; + + if (!(uname(&uname_data) == 0 && + sscanf(uname_data.release, "%u.%u.%u", &version_major, &version_minor, &version_release) == 3)) + return 0; + + if (!(version_major >= 3 && version_minor >= 4)) return 0; if (pcap_add_if(alldevsp, INTERFACE_NAME, 0, "Bluetooth Linux Monitor", err_str) < 0) diff --git a/pcap-linux.c b/pcap-linux.c index 379e33388c..6de70315f9 100644 --- a/pcap-linux.c +++ b/pcap-linux.c @@ -25,10 +25,10 @@ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * Modifications: Added PACKET_MMAP support - * Paolo Abeni + * Paolo Abeni * Added TPACKET_V3 support * Gabor Tatarka - * + * * based on previous works of: * Simon Patarin * Phil Wood @@ -47,7 +47,7 @@ * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. @@ -56,12 +56,12 @@ * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. @@ -188,7 +188,7 @@ # endif /* PACKET_HOST */ - /* check for memory mapped access avaibility. We assume every needed + /* check for memory mapped access avaibility. We assume every needed * struct is defined if the macro TPACKET_HDRLEN is defined, because it * uses many ring related structs and macros */ # ifdef TPACKET_HDRLEN @@ -999,7 +999,7 @@ linux_if_drops(const char * if_name) FILE * file; int field_to_convert = 3, if_name_sz = strlen(if_name); long int dropped_pkts = 0; - + file = fopen("/proc/net/dev", "r"); if (!file) return 0; @@ -1014,7 +1014,7 @@ linux_if_drops(const char * if_name) field_to_convert = 4; continue; } - + /* find iface and make sure it actually matches -- space before the name and : after it */ if ((bufptr = strstr(buffer, if_name)) && (bufptr == buffer || *(bufptr-1) == ' ') && @@ -1028,20 +1028,20 @@ linux_if_drops(const char * if_name) while (*bufptr != '\0' && *(bufptr++) == ' '); while (*bufptr != '\0' && *(bufptr++) != ' '); } - + /* get rid of any final spaces */ while (*bufptr != '\0' && *bufptr == ' ') bufptr++; - + if (*bufptr != '\0') dropped_pkts = strtol(bufptr, NULL, 10); break; } } - + fclose(file); return dropped_pkts; -} +} /* @@ -1276,12 +1276,12 @@ pcap_activate_linux(pcap_t *handle) pcap_strerror(errno) ); return PCAP_ERROR; } - + /* copy timeout value */ handlep->timeout = handle->opt.timeout; /* - * If we're in promiscuous mode, then we probably want + * If we're in promiscuous mode, then we probably want * to see when the interface drops packets too, so get an * initial count from /proc/net/dev */ @@ -1401,7 +1401,7 @@ pcap_activate_linux(pcap_t *handle) * error occured. */ static int -pcap_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user) +pcap_read_linux(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_char *user) { /* * Currently, on Linux only one packet is delivered per read, @@ -1734,7 +1734,7 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata) "SIOCGSTAMPNS: %s", pcap_strerror(errno)); return PCAP_ERROR; } - } else + } else #endif { if (ioctl(handle->fd, SIOCGSTAMP, &pcap_header.ts) == -1) { @@ -1742,7 +1742,7 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata) "SIOCGSTAMP: %s", pcap_strerror(errno)); return PCAP_ERROR; } - } + } pcap_header.caplen = caplen; pcap_header.len = packet_len; @@ -1841,7 +1841,7 @@ pcap_inject_linux(pcap_t *handle, const void *buf, size_t size) return (-1); } return (ret); -} +} /* * Get the statistics for the given packet capture handle. @@ -1879,8 +1879,8 @@ pcap_stats_linux(pcap_t *handle, struct pcap_stat *stats) #endif /* HAVE_TPACKET_STATS */ long if_dropped = 0; - - /* + + /* * To fill in ps_ifdrop, we parse /proc/net/dev for the number */ if (handle->opt.promisc) @@ -1910,7 +1910,7 @@ pcap_stats_linux(pcap_t *handle, struct pcap_stat *stats) * dropped by the interface driver. It counts only * packets that passed the filter. * - * See above for ps_ifdrop. + * See above for ps_ifdrop. * * Both statistics include packets not yet read from * the kernel by libpcap, and thus not yet seen by @@ -1939,7 +1939,7 @@ pcap_stats_linux(pcap_t *handle, struct pcap_stat *stats) * "tp_packets" as the count of packets and "tp_drops" * as the count of drops. * - * Keep a running total because each call to + * Keep a running total because each call to * getsockopt(handle->fd, SOL_PACKET, PACKET_STATISTICS, .... * resets the counters to zero. */ @@ -1985,10 +1985,10 @@ pcap_stats_linux(pcap_t *handle, struct pcap_stat *stats) * We maintain the count of packets processed by libpcap in * "handlep->packets_read", for reasons described in the comment * at the end of pcap_read_packet(). We have no idea how many - * packets were dropped by the kernel buffers -- but we know + * packets were dropped by the kernel buffers -- but we know * how many the interface dropped, so we can return that. */ - + stats->ps_recv = handlep->packets_read; stats->ps_drop = 0; stats->ps_ifdrop = handlep->stat.ps_ifdrop; @@ -2604,7 +2604,7 @@ static void map_arphrd_to_dlt(pcap_t *handle, int arptype, const char *device, handle->linktype = DLT_RAW; return; } - + /* * This is (presumably) a real Ethernet capture; give it a * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so @@ -2968,9 +2968,9 @@ static void map_arphrd_to_dlt(pcap_t *handle, int arptype, const char *device, #ifndef ARPHRD_IEEE802154 #define ARPHRD_IEEE802154 804 #endif - case ARPHRD_IEEE802154: - handle->linktype = DLT_IEEE802_15_4_NOFCS; - break; + case ARPHRD_IEEE802154: + handle->linktype = DLT_IEEE802_15_4_NOFCS; + break; #ifndef ARPHRD_NETLINK #define ARPHRD_NETLINK 824 @@ -3388,7 +3388,7 @@ activate_new(pcap_t *handle) * On error, returns -1, and sets *status to the appropriate error code; * if that is PCAP_ERROR, sets handle->errbuf to the appropriate message. */ -static int +static int activate_mmap(pcap_t *handle, int *status) { struct pcap_linux *handlep = handle->priv; @@ -3469,7 +3469,7 @@ activate_mmap(pcap_t *handle, int *status) return 1; } #else /* HAVE_PACKET_RING */ -static int +static int activate_mmap(pcap_t *handle _U_, int *status _U_) { return 0; @@ -3766,12 +3766,12 @@ create_ring(pcap_t *handle, int *status) return -1; } - /* compute the minumum block size that will handle this frame. - * The block has to be page size aligned. - * The max block size allowed by the kernel is arch-dependent and + /* compute the minumum block size that will handle this frame. + * The block has to be page size aligned. + * The max block size allowed by the kernel is arch-dependent and * it's not explicitly checked here. */ req.tp_block_size = getpagesize(); - while (req.tp_block_size < req.tp_frame_size) + while (req.tp_block_size < req.tp_frame_size) req.tp_block_size <<= 1; frames_per_block = req.tp_block_size/req.tp_frame_size; @@ -3869,8 +3869,8 @@ create_ring(pcap_t *handle, int *status) } if (setsockopt(handle->fd, SOL_PACKET, PACKET_TIMESTAMP, (void *)×ource, sizeof(timesource))) { - snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, - "can't set PACKET_TIMESTAMP: %s", + snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, + "can't set PACKET_TIMESTAMP: %s", pcap_strerror(errno)); *status = PCAP_ERROR; return -1; @@ -3885,7 +3885,7 @@ create_ring(pcap_t *handle, int *status) /* req.tp_frame_nr is requested to match frames_per_block*req.tp_block_nr */ req.tp_frame_nr = req.tp_block_nr * frames_per_block; - + #ifdef HAVE_TPACKET3 /* timeout value to retire block - use the configured buffering timeout, or default if <0. */ req.tp_retire_blk_tov = (handlep->timeout>=0)?handlep->timeout:0; @@ -4018,7 +4018,7 @@ pcap_oneshot_mmap(u_char *user, const struct pcap_pkthdr *h, memcpy(handlep->oneshot_buffer, bytes, h->caplen); *sp->pkt = handlep->oneshot_buffer; } - + static void pcap_cleanup_linux_mmap( pcap_t *handle ) { @@ -4034,7 +4034,7 @@ pcap_cleanup_linux_mmap( pcap_t *handle ) static int -pcap_getnonblock_mmap(pcap_t *p, char *errbuf) +pcap_getnonblock_mmap(pcap_t *p, char *errbuf _U_) { struct pcap_linux *handlep = p->priv; @@ -4043,7 +4043,7 @@ pcap_getnonblock_mmap(pcap_t *p, char *errbuf) } static int -pcap_setnonblock_mmap(pcap_t *p, int nonblock, char *errbuf) +pcap_setnonblock_mmap(pcap_t *p, int nonblock, char *errbuf _U_) { struct pcap_linux *handlep = p->priv; @@ -4629,7 +4629,7 @@ pcap_read_linux_mmap_v3(pcap_t *handle, int max_packets, pcap_handler callback, } #endif /* HAVE_TPACKET3 */ -static int +static int pcap_setfilter_linux_mmap(pcap_t *handle, struct bpf_program *filter) { struct pcap_linux *handlep = handle->priv; @@ -5640,7 +5640,7 @@ iface_ethtool_flag_ioctl(pcap_t *handle, int cmd, const char *cmdname) cmdname, strerror(errno)); return -1; } - return eval.data; + return eval.data; } static int diff --git a/pcap-usb-linux.c b/pcap-usb-linux.c index 63eb11eba2..43e06b74c0 100644 --- a/pcap-usb-linux.c +++ b/pcap-usb-linux.c @@ -11,8 +11,8 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior written + * 3. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS @@ -32,7 +32,7 @@ * Modifications: Kris Katterjohn * */ - + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -139,21 +139,21 @@ static int usb_setdirection_linux(pcap_t *, pcap_direction_t); static void usb_cleanup_linux_mmap(pcap_t *); /* facility to add an USB device to the device list*/ -static int +static int usb_dev_add(pcap_if_t** alldevsp, int n, char *err_str) { char dev_name[10]; - char dev_descr[30]; + char dev_descr[30]; snprintf(dev_name, 10, USB_IFACE"%d", n); snprintf(dev_descr, 30, "USB bus number %d", n); - if (pcap_add_if(alldevsp, dev_name, 0, + if (pcap_add_if(alldevsp, dev_name, 0, dev_descr, err_str) < 0) return -1; - return 0; + return 0; } -int +int usb_findalldevs(pcap_if_t **alldevsp, char *err_str) { struct dirent* data; @@ -172,7 +172,7 @@ usb_findalldevs(pcap_if_t **alldevsp, char *err_str) if (strncmp(name, "usb", 3) != 0) continue; - if (sscanf(&name[3], "%d", &n) == 0) + if (sscanf(&name[3], "%d", &n) == 0) continue; ret = usb_dev_add(alldevsp, n, err_str); @@ -193,7 +193,7 @@ usb_findalldevs(pcap_if_t **alldevsp, char *err_str) if ((len < 1) || !isdigit(name[--len])) continue; while (isdigit(name[--len])); - if (sscanf(&name[len+1], "%d", &n) != 1) + if (sscanf(&name[len+1], "%d", &n) != 1) continue; ret = usb_dev_add(alldevsp, n, err_str); @@ -207,12 +207,12 @@ usb_findalldevs(pcap_if_t **alldevsp, char *err_str) return 0; } -static +static int usb_mmap(pcap_t* handle) { struct pcap_usb_linux *handlep = handle->priv; int len = ioctl(handle->fd, MON_IOCQ_RING_SIZE); - if (len < 0) + if (len < 0) return 0; handlep->mmapbuflen = len; @@ -260,7 +260,7 @@ probe_devices(int bus) continue; snprintf(buf, sizeof(buf), "/dev/bus/usb/%03d/%s", bus, data->d_name); - + fd = open(buf, O_RDWR); if (fd == -1) continue; @@ -363,7 +363,7 @@ usb_activate(pcap_t* handle) } /*now select the read method: try to open binary interface */ - snprintf(full_path, USB_LINE_LEN, LINUX_USB_MON_DEV"%d", handlep->bus_index); + snprintf(full_path, USB_LINE_LEN, LINUX_USB_MON_DEV"%d", handlep->bus_index); handle->fd = open(full_path, O_RDONLY, 0); if (handle->fd >= 0) { @@ -402,7 +402,7 @@ usb_activate(pcap_t* handle) } else { /*Binary interface not available, try open text interface */ - snprintf(full_path, USB_LINE_LEN, USB_TEXT_DIR"/%dt", handlep->bus_index); + snprintf(full_path, USB_LINE_LEN, USB_TEXT_DIR"/%dt", handlep->bus_index); handle->fd = open(full_path, O_RDONLY, 0); if (handle->fd < 0) { @@ -412,7 +412,7 @@ usb_activate(pcap_t* handle) * Not found at the new location; try * the old location. */ - snprintf(full_path, USB_LINE_LEN, USB_TEXT_DIR_OLD"/%dt", handlep->bus_index); + snprintf(full_path, USB_LINE_LEN, USB_TEXT_DIR_OLD"/%dt", handlep->bus_index); handle->fd = open(full_path, O_RDONLY, 0); } if (handle->fd < 0) { @@ -453,27 +453,27 @@ usb_activate(pcap_t* handle) return 0; } -static inline int +static inline int ascii_to_int(char c) { return c < 'A' ? c- '0': ((c<'a') ? c - 'A' + 10: c-'a'+10); } /* - * see /Documentation/usb/usbmon.txt and - * /drivers/usb/mon/mon_text.c for urb string + * see /Documentation/usb/usbmon.txt and + * /drivers/usb/mon/mon_text.c for urb string * format description */ static int -usb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user) +usb_read_linux(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_char *user) { /* see: - * /usr/src/linux/Documentation/usb/usbmon.txt + * /usr/src/linux/Documentation/usb/usbmon.txt * for message format */ struct pcap_usb_linux *handlep = handle->priv; - unsigned timestamp; - int tag, cnt, ep_num, dev_addr, dummy, ret, urb_len, data_len; + unsigned int tag, timestamp; + int cnt, ep_num, dev_addr, dummy, ret, urb_len, data_len; char etype, pipeid1, pipeid2, status[16], urb_tag, line[USB_LINE_LEN]; char *string = line; u_char * rawdata = handle->buffer; @@ -501,11 +501,11 @@ usb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *u return -1; } - /* read urb header; %n argument may increment return value, but it's + /* read urb header; %n argument may increment return value, but it's * not mandatory, so does not count on it*/ string[ret] = 0; - ret = sscanf(string, "%x %d %c %c%c:%d:%d %s%n", &tag, ×tamp, &etype, - &pipeid1, &pipeid2, &dev_addr, &ep_num, status, + ret = sscanf(string, "%x %u %c %c%c:%d:%d %s%i", &tag, ×tamp, &etype, + &pipeid1, &pipeid2, &dev_addr, &ep_num, status, &cnt); if (ret < 8) { @@ -521,10 +521,10 @@ usb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *u string += cnt; /* don't use usbmon provided timestamp, since it have low precision*/ - if (gettimeofday(&pkth.ts, NULL) < 0) + if (gettimeofday(&pkth.ts, NULL) < 0) { snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, - "Can't get timestamp for message '%s' %d:%s", + "Can't get timestamp for message '%s' %d:%s", string, errno, strerror(errno)); return -1; } @@ -567,11 +567,11 @@ usb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *u if (ret != 1) { /* this a setup packet, setup data can be filled with underscore if - * usbmon has not been able to read them, so we must parse this fields as + * usbmon has not been able to read them, so we must parse this fields as * strings */ pcap_usb_setup* shdr; char str1[3], str2[3], str3[5], str4[5], str5[5]; - ret = sscanf(string, "%s %s %s %s %s%n", str1, str2, str3, str4, + ret = sscanf(string, "%s %s %s %s %s%n", str1, str2, str3, str4, str5, &cnt); if (ret < 5) { @@ -592,7 +592,7 @@ usb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *u uhdr->setup_flag = 0; } - else + else uhdr->setup_flag = 1; /* read urb data */ @@ -605,7 +605,7 @@ usb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *u } string += cnt; - /* urb tag is not present if urb length is 0, so we can stop here + /* urb tag is not present if urb length is 0, so we can stop here * text parsing */ pkth.len = urb_len+pkth.caplen; uhdr->urb_len = urb_len; @@ -622,7 +622,7 @@ usb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *u return -1; } - if (urb_tag != '=') + if (urb_tag != '=') goto got; /* skip urb tag and following space */ @@ -631,7 +631,7 @@ usb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *u /* if we reach this point we got some urb data*/ uhdr->data_flag = 0; - /* read all urb data; if urb length is greater then the usbmon internal + /* read all urb data; if urb length is greater then the usbmon internal * buffer length used by the kernel to spool the URB, we get only * a partial information. * At least until linux 2.6.17 there is no way to set usbmon intenal buffer @@ -663,14 +663,14 @@ usb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *u } static int -usb_inject_linux(pcap_t *handle, const void *buf, size_t size) +usb_inject_linux(pcap_t *handle, const void *buf _U_, size_t size _U_) { snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported on " "USB devices"); return (-1); } -static int +static int usb_stats_linux(pcap_t *handle, struct pcap_stat *stats) { struct pcap_usb_linux *handlep = handle->priv; @@ -695,7 +695,7 @@ usb_stats_linux(pcap_t *handle, struct pcap_stat *stats) } if (fd < 0) { snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, - "Can't open USB stats file %s: %s", + "Can't open USB stats file %s: %s", string, strerror(errno)); return -1; } @@ -717,11 +717,11 @@ usb_stats_linux(pcap_t *handle, struct pcap_stat *stats) /* extract info on dropped urbs */ for (consumed=0; consumed < ret; ) { - /* from the sscanf man page: - * The C standard says: "Execution of a %n directive does - * not increment the assignment count returned at the completion + /* from the sscanf man page: + * The C standard says: "Execution of a %n directive does + * not increment the assignment count returned at the completion * of execution" but the Corrigendum seems to contradict this. - * Do not make any assumptions on the effect of %n conversions + * Do not make any assumptions on the effect of %n conversions * on the return value and explicitly check for cnt assignmet*/ int ntok; @@ -732,8 +732,8 @@ usb_stats_linux(pcap_t *handle, struct pcap_stat *stats) consumed += cnt; ptr += cnt; if (strcmp(token, "nreaders") == 0) - ret = sscanf(ptr, "%d", &stats->ps_drop); - else + ret = sscanf(ptr, "%u", &stats->ps_drop); + else ret = sscanf(ptr, "%d", &dummy); if (ntok != 1) break; @@ -746,7 +746,7 @@ usb_stats_linux(pcap_t *handle, struct pcap_stat *stats) return 0; } -static int +static int usb_setdirection_linux(pcap_t *p, pcap_direction_t d) { p->direction = d; @@ -754,7 +754,7 @@ usb_setdirection_linux(pcap_t *p, pcap_direction_t d) } -static int +static int usb_stats_linux_bin(pcap_t *handle, struct pcap_stat *stats) { struct pcap_usb_linux *handlep = handle->priv; @@ -775,11 +775,11 @@ usb_stats_linux_bin(pcap_t *handle, struct pcap_stat *stats) } /* - * see /Documentation/usb/usbmon.txt and + * see /Documentation/usb/usbmon.txt and * /drivers/usb/mon/mon_bin.c binary ABI */ static int -usb_read_linux_bin(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user) +usb_read_linux_bin(pcap_t *handle, int max_packets _U_, pcap_handler callback, u_char *user) { struct pcap_usb_linux *handlep = handle->priv; struct mon_bin_get info; @@ -833,7 +833,7 @@ usb_read_linux_bin(pcap_t *handle, int max_packets, pcap_handler callback, u_cha } /* - * see /Documentation/usb/usbmon.txt and + * see /Documentation/usb/usbmon.txt and * /drivers/usb/mon/mon_bin.c binary ABI */ #define VEC_SIZE 32 @@ -887,7 +887,7 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch for (i=0; immapbuf[vec[i]]; - if (hdr->event_type == '@') + if (hdr->event_type == '@') continue; /* we can get less that than really captured from kernel, depending on diff --git a/pcap.c b/pcap.c index 4e9c94a72b..c3ffdf5e68 100644 --- a/pcap.c +++ b/pcap.c @@ -86,9 +86,6 @@ #ifdef PCAP_SUPPORT_BT #include "pcap-bt-linux.h" -#endif - -#ifdef PCAP_SUPPORT_BT_MONITOR #include "pcap-bt-monitor-linux.h" #endif @@ -325,8 +322,6 @@ struct capture_source_type { #endif #ifdef PCAP_SUPPORT_BT { bt_findalldevs, bt_create }, -#endif -#ifdef PCAP_SUPPORT_BT_MONITOR { bt_monitor_findalldevs, bt_monitor_create }, #endif #if PCAP_SUPPORT_CANUSB