dect
/
libpcap
Archived
13
0
Fork 0

From Paolo Abeni: Bluetooth support.

This commit is contained in:
guy 2006-10-13 17:34:53 +00:00
parent 6fa38c09d7
commit 50ce2663e8
10 changed files with 578 additions and 15 deletions

1
FILES
View File

@ -81,6 +81,7 @@ pcap/sll.h
pcap/usb.h pcap/usb.h
pcap-bpf.c pcap-bpf.c
pcap-bpf.h pcap-bpf.h
pcap-bt-linux.c
pcap-dag.c pcap-dag.c
pcap-dag.h pcap-dag.h
pcap-dlpi.c pcap-dlpi.c

View File

@ -1,4 +1,4 @@
@(#) $Header: /tcpdump/master/libpcap/INSTALL.txt,v 1.16 2006-10-04 18:09:22 guy Exp $ (LBL) @(#) $Header: /tcpdump/master/libpcap/INSTALL.txt,v 1.17 2006-10-13 17:36:41 guy Exp $ (LBL)
To build libpcap, run "./configure" (a shell script). The configure To build libpcap, run "./configure" (a shell script). The configure
script will determine your system attributes and generate an script will determine your system attributes and generate an
@ -357,6 +357,7 @@ pcap/sll.h - public definition of DLT_LINUX_SLL header
pcap/usb.h - public definition of DLT_USB headeer pcap/usb.h - public definition of DLT_USB headeer
pcap-bpf.c - BSD Packet Filter support pcap-bpf.c - BSD Packet Filter support
pcap-bpf.h - header for backwards compatibility pcap-bpf.h - header for backwards compatibility
pcap-bt-linux.c - Bluetooth capture support for Linux
pcap-dag.c - Endace DAG device capture support pcap-dag.c - Endace DAG device capture support
pcap-dag.h - Endace DAG device capture support pcap-dag.h - Endace DAG device capture support
pcap-dlpi.c - Data Link Provider Interface support pcap-dlpi.c - Data Link Provider Interface support

View File

@ -17,7 +17,7 @@
# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
# #
# @(#) $Header: /tcpdump/master/libpcap/Makefile.in,v 1.104 2006-10-04 18:09:22 guy Exp $ (LBL) # @(#) $Header: /tcpdump/master/libpcap/Makefile.in,v 1.105 2006-10-13 17:34:53 guy Exp $ (LBL)
# #
# Various configurable paths (remember to edit Makefile.in, not Makefile) # Various configurable paths (remember to edit Makefile.in, not Makefile)
@ -72,7 +72,7 @@ YACC = @V_YACC@
@rm -f $@ @rm -f $@
$(CC) $(CFLAGS) -c $(srcdir)/$*.c $(CC) $(CFLAGS) -c $(srcdir)/$*.c
PSRC = pcap-@V_PCAP@.c @USB_SRC@ PSRC = pcap-@V_PCAP@.c @USB_SRC@ @BT_SRC@
FSRC = fad-@V_FINDALLDEVS@.c FSRC = fad-@V_FINDALLDEVS@.c
SSRC = @SSRC@ SSRC = @SSRC@
CSRC = pcap.c inet.c gencode.c optimize.c nametoaddr.c \ CSRC = pcap.c inet.c gencode.c optimize.c nametoaddr.c \

View File

@ -161,6 +161,9 @@
/* /dev/dlpi directory */ /* /dev/dlpi directory */
#undef PCAP_DEV_PREFIX #undef PCAP_DEV_PREFIX
/* target host supports Bluetooth sniffing */
#undef PCAP_SUPPORT_BT
/* target host supports USB sniffing */ /* target host supports USB sniffing */
#undef PCAP_SUPPORT_USB #undef PCAP_SUPPORT_USB

172
configure vendored
View File

@ -1,5 +1,5 @@
#! /bin/sh #! /bin/sh
# From configure.in Revision: 1.131 . # From configure.in Revision: 1.132 .
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.59. # Generated by GNU Autoconf 2.59.
# #
@ -310,7 +310,7 @@ ac_includes_default="\
# include <unistd.h> # include <unistd.h>
#endif" #endif"
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os SHLICC2 CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP LIBOBJS V_LEX V_YACC RANLIB ac_ct_RANLIB V_CCOPT V_DEFS V_INCLS V_LIBS V_PCAP V_FINDALLDEVS V_RANLIB SSRC DYEXT DAGLIBS PCAP_SUPPORT_USB USB_SRC INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LTLIBOBJS' ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os SHLICC2 CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP LIBOBJS V_LEX V_YACC RANLIB ac_ct_RANLIB V_CCOPT V_DEFS V_INCLS V_LIBS V_PCAP V_FINDALLDEVS V_RANLIB SSRC DYEXT DAGLIBS PCAP_SUPPORT_USB USB_SRC PCAP_SUPPORT_BT BT_SRC INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA LTLIBOBJS'
ac_subst_files='' ac_subst_files=''
# Initialize some variables set by options. # Initialize some variables set by options.
@ -7204,6 +7204,172 @@ esac
case "$host_os" in
linux*)
if test "${ac_cv_header_bluetooth_bluetooth_h+set}" = set; then
echo "$as_me:$LINENO: checking for bluetooth/bluetooth.h" >&5
echo $ECHO_N "checking for bluetooth/bluetooth.h... $ECHO_C" >&6
if test "${ac_cv_header_bluetooth_bluetooth_h+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
fi
echo "$as_me:$LINENO: result: $ac_cv_header_bluetooth_bluetooth_h" >&5
echo "${ECHO_T}$ac_cv_header_bluetooth_bluetooth_h" >&6
else
# Is the header compilable?
echo "$as_me:$LINENO: checking bluetooth/bluetooth.h usability" >&5
echo $ECHO_N "checking bluetooth/bluetooth.h usability... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
$ac_includes_default
#include <bluetooth/bluetooth.h>
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_header_compiler=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_header_compiler=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
echo "${ECHO_T}$ac_header_compiler" >&6
# Is the header present?
echo "$as_me:$LINENO: checking bluetooth/bluetooth.h presence" >&5
echo $ECHO_N "checking bluetooth/bluetooth.h presence... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <bluetooth/bluetooth.h>
_ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
ac_cpp_err=$ac_c_preproc_warn_flag
ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
else
ac_cpp_err=
fi
else
ac_cpp_err=yes
fi
if test -z "$ac_cpp_err"; then
ac_header_preproc=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_header_preproc=no
fi
rm -f conftest.err conftest.$ac_ext
echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
echo "${ECHO_T}$ac_header_preproc" >&6
# So? What about this header?
case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
yes:no: )
{ echo "$as_me:$LINENO: WARNING: bluetooth/bluetooth.h: accepted by the compiler, rejected by the preprocessor!" >&5
echo "$as_me: WARNING: bluetooth/bluetooth.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
{ echo "$as_me:$LINENO: WARNING: bluetooth/bluetooth.h: proceeding with the compiler's result" >&5
echo "$as_me: WARNING: bluetooth/bluetooth.h: proceeding with the compiler's result" >&2;}
ac_header_preproc=yes
;;
no:yes:* )
{ echo "$as_me:$LINENO: WARNING: bluetooth/bluetooth.h: present but cannot be compiled" >&5
echo "$as_me: WARNING: bluetooth/bluetooth.h: present but cannot be compiled" >&2;}
{ echo "$as_me:$LINENO: WARNING: bluetooth/bluetooth.h: check for missing prerequisite headers?" >&5
echo "$as_me: WARNING: bluetooth/bluetooth.h: check for missing prerequisite headers?" >&2;}
{ echo "$as_me:$LINENO: WARNING: bluetooth/bluetooth.h: see the Autoconf documentation" >&5
echo "$as_me: WARNING: bluetooth/bluetooth.h: see the Autoconf documentation" >&2;}
{ echo "$as_me:$LINENO: WARNING: bluetooth/bluetooth.h: section \"Present But Cannot Be Compiled\"" >&5
echo "$as_me: WARNING: bluetooth/bluetooth.h: section \"Present But Cannot Be Compiled\"" >&2;}
{ echo "$as_me:$LINENO: WARNING: bluetooth/bluetooth.h: proceeding with the preprocessor's result" >&5
echo "$as_me: WARNING: bluetooth/bluetooth.h: proceeding with the preprocessor's result" >&2;}
{ echo "$as_me:$LINENO: WARNING: bluetooth/bluetooth.h: in the future, the compiler will take precedence" >&5
echo "$as_me: WARNING: bluetooth/bluetooth.h: in the future, the compiler will take precedence" >&2;}
(
cat <<\_ASBOX
## ------------------------------------------ ##
## Report this to the AC_PACKAGE_NAME lists. ##
## ------------------------------------------ ##
_ASBOX
) |
sed "s/^/$as_me: WARNING: /" >&2
;;
esac
echo "$as_me:$LINENO: checking for bluetooth/bluetooth.h" >&5
echo $ECHO_N "checking for bluetooth/bluetooth.h... $ECHO_C" >&6
if test "${ac_cv_header_bluetooth_bluetooth_h+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_cv_header_bluetooth_bluetooth_h=$ac_header_preproc
fi
echo "$as_me:$LINENO: result: $ac_cv_header_bluetooth_bluetooth_h" >&5
echo "${ECHO_T}$ac_cv_header_bluetooth_bluetooth_h" >&6
fi
if test $ac_cv_header_bluetooth_bluetooth_h = yes; then
cat >>confdefs.h <<\_ACEOF
#define PCAP_SUPPORT_BT 1
_ACEOF
BT_SRC=pcap-bt-linux.c
{ echo "$as_me:$LINENO: Bluetooth sniffing is supported" >&5
echo "$as_me: Bluetooth sniffing is supported" >&6;}
else
{ echo "$as_me:$LINENO: Bluetooth sniffing is not supported; install bluez-lib devel to enable it" >&5
echo "$as_me: Bluetooth sniffing is not supported; install bluez-lib devel to enable it" >&6;}
fi
;;
*)
{ echo "$as_me:$LINENO: no Bluetooth sniffing support" >&5
echo "$as_me: no Bluetooth sniffing support" >&6;}
;;
esac
# Find a good install program. We prefer a C program (faster), # Find a good install program. We prefer a C program (faster),
# so one script is as good as another. But avoid the broken or # so one script is as good as another. But avoid the broken or
# incompatible versions: # incompatible versions:
@ -7938,6 +8104,8 @@ s,@DYEXT@,$DYEXT,;t t
s,@DAGLIBS@,$DAGLIBS,;t t s,@DAGLIBS@,$DAGLIBS,;t t
s,@PCAP_SUPPORT_USB@,$PCAP_SUPPORT_USB,;t t s,@PCAP_SUPPORT_USB@,$PCAP_SUPPORT_USB,;t t
s,@USB_SRC@,$USB_SRC,;t t s,@USB_SRC@,$USB_SRC,;t t
s,@PCAP_SUPPORT_BT@,$PCAP_SUPPORT_BT,;t t
s,@BT_SRC@,$BT_SRC,;t t
s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
s,@INSTALL_DATA@,$INSTALL_DATA,;t t s,@INSTALL_DATA@,$INSTALL_DATA,;t t

View File

@ -1,4 +1,4 @@
dnl @(#) $Header: /tcpdump/master/libpcap/configure.in,v 1.131 2006-10-04 16:46:31 guy Exp $ (LBL) dnl @(#) $Header: /tcpdump/master/libpcap/configure.in,v 1.132 2006-10-13 17:34:53 guy Exp $ (LBL)
dnl dnl
dnl Copyright (c) 1994, 1995, 1996, 1997 dnl Copyright (c) 1994, 1995, 1996, 1997
dnl The Regents of the University of California. All rights reserved. dnl The Regents of the University of California. All rights reserved.
@ -6,7 +6,7 @@ dnl
dnl Process this file with autoconf to produce a configure script. dnl Process this file with autoconf to produce a configure script.
dnl dnl
AC_REVISION($Revision: 1.131 $) AC_REVISION($Revision: 1.132 $)
AC_PREREQ(2.50) AC_PREREQ(2.50)
AC_INIT(pcap.c) AC_INIT(pcap.c)
@ -806,6 +806,25 @@ esac
AC_SUBST(PCAP_SUPPORT_USB) AC_SUBST(PCAP_SUPPORT_USB)
AC_SUBST(USB_SRC) AC_SUBST(USB_SRC)
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)
],
AC_MSG_NOTICE(Bluetooth sniffing is not supported; install bluez-lib devel to enable it)
)
;;
*)
AC_MSG_NOTICE(no Bluetooth sniffing support)
;;
esac
AC_SUBST(PCAP_SUPPORT_BT)
AC_SUBST(BT_SRC)
AC_PROG_INSTALL AC_PROG_INSTALL
AC_CONFIG_HEADER(config.h) AC_CONFIG_HEADER(config.h)

5
inet.c
View File

@ -34,7 +34,7 @@
#ifndef lint #ifndef lint
static const char rcsid[] _U_ = static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/inet.c,v 1.71 2006-10-13 09:06:05 guy Exp $ (LBL)"; "@(#) $Header: /tcpdump/master/libpcap/inet.c,v 1.72 2006-10-13 17:34:53 guy Exp $ (LBL)";
#endif #endif
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
@ -582,6 +582,9 @@ pcap_lookupnet(device, netp, maskp, errbuf)
#ifdef HAVE_SEPTEL_API #ifdef HAVE_SEPTEL_API
|| strstr(device, "septel") != NULL || strstr(device, "septel") != NULL
#endif #endif
#ifdef PCAP_SUPPORT_BT
|| strstr(device, "bluetooth") != NULL
#endif
#ifdef PCAP_SUPPORT_USB #ifdef PCAP_SUPPORT_USB
|| strstr(device, "usb") != NULL || strstr(device, "usb") != NULL
#endif #endif

342
pcap-bt-linux.c Normal file
View File

@ -0,0 +1,342 @@
/*
* Copyright (c) 2006 Paolo Abeni (Italy)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* 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.
* 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. Neither the name of the Politecnico di Torino, CACE Technologies
* nor the names of its contributors may 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
* "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. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS 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, 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.
*
* USB sniffig API implementation for linux platform
* By Paolo Abeni <paolo.abeni@email.com>
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "pcap-int.h"
#ifdef NEED_STRERROR_H
#include "strerror.h"
#endif
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#define BT_IFACE "bluetooth"
#define BT_CTRL_SIZE 128
/* forward declaration */
static int bt_read_linux(pcap_t *, int , pcap_handler , u_char *);
static int bt_inject_linux(pcap_t *, const void *, size_t);
static int bt_setfilter_linux(pcap_t *, struct bpf_program *);
static int bt_setdirection_linux(pcap_t *, pcap_direction_t);
static int bt_stats_linux(pcap_t *, struct pcap_stat *);
static void bt_close_linux(pcap_t *);
int
bt_platform_finddevs(pcap_if_t **alldevsp, char *err_str)
{
pcap_if_t *found_dev = *alldevsp;
struct hci_dev_list_req *dev_list;
struct hci_dev_req *dev_req;
int i, sock;
int ret = 0;
sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
if (sock < 0)
{
snprintf(err_str, PCAP_ERRBUF_SIZE, "can't open raw by socket %d:%s",
errno, strerror(errno));
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 %d bytes for dev cache",
HCI_MAX_DEV * sizeof(*dev_req) + sizeof(*dev_list));
ret = -1;
goto done;
}
dev_list->dev_num = HCI_MAX_DEV;
if (ioctl(sock, HCIGETDEVLIST, (void *) dev_list) < 0)
{
snprintf(err_str, PCAP_ERRBUF_SIZE, "can't get dev list via ioctl %d:%s",
errno, strerror(errno));
ret = -1;
goto free;
}
dev_req = dev_list->dev_req;
for (i = 0; i < dev_list->dev_num; i++, dev_req++) {
char dev_name[20], dev_descr[30];
snprintf(dev_name, 20, BT_IFACE"%d", dev_req->dev_id);
snprintf(dev_descr, 30, "bluetooth adapter number %d", i);
if (pcap_add_if(&found_dev, dev_name, 0,
dev_descr, err_str) < 0)
{
ret = -1;
break;
}
}
free:
free(dev_list);
done:
close(sock);
return ret;
}
pcap_t*
bt_open_live(const char* bus, int snaplen, int promisc , int to_ms, char* errmsg)
{
struct sockaddr_hci addr;
int opt;
pcap_t *handle;
int dev_id;
struct hci_filter flt;
/* get bt interface id */
if (sscanf(bus, BT_IFACE"%d", &dev_id) != 1)
{
snprintf(errmsg, PCAP_ERRBUF_SIZE,
"Can't get usb bus index from %s", bus);
return NULL;
}
/* Allocate a handle for this session. */
handle = malloc(sizeof(*handle));
if (handle == NULL) {
snprintf(errmsg, PCAP_ERRBUF_SIZE, "malloc: %s",
pcap_strerror(errno));
return NULL;
}
/* Initialize some components of the pcap structure. */
memset(handle, 0, sizeof(*handle));
handle->snapshot = snaplen;
handle->md.timeout = to_ms;
handle->bufsize = snaplen+BT_CTRL_SIZE;
handle->offset = BT_CTRL_SIZE;
handle->linktype = DLT_BLUETOOTH_HCI_H4;
handle->read_op = bt_read_linux;
handle->inject_op = bt_inject_linux;
handle->setfilter_op = bt_setfilter_linux;
handle->setdirection_op = bt_setdirection_linux;
handle->set_datalink_op = NULL; /* can't change data link type */
handle->getnonblock_op = pcap_getnonblock_fd;
handle->setnonblock_op = pcap_setnonblock_fd;
handle->stats_op = bt_stats_linux;
handle->close_op = bt_close_linux;
handle->md.ifindex = dev_id;
/* Create HCI socket */
handle->fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
if (handle->fd < 0) {
snprintf(errmsg, PCAP_ERRBUF_SIZE, "Can't create raw socket %d:%s",
errno, strerror(errno));
free(handle);
return NULL;
}
handle->buffer = malloc(snaplen+BT_CTRL_SIZE);
if (!handle->buffer) {
snprintf(errmsg, PCAP_ERRBUF_SIZE, "Can't allocate dump buffer: %s",
pcap_strerror(errno));
pcap_close(handle);
return NULL;
}
opt = 1;
if (setsockopt(handle->fd, SOL_HCI, HCI_DATA_DIR, &opt, sizeof(opt)) < 0) {
snprintf(errmsg, PCAP_ERRBUF_SIZE, "Can't enable data direction info %d:%s",
errno, strerror(errno));
pcap_close(handle);
return NULL;
}
opt = 1;
if (setsockopt(handle->fd, SOL_HCI, HCI_TIME_STAMP, &opt, sizeof(opt)) < 0) {
snprintf(errmsg, PCAP_ERRBUF_SIZE, "Can't enable time stamp %d:%s",
errno, strerror(errno));
pcap_close(handle);
return NULL;
}
/* 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.event_mask, 0xff, sizeof(flt.event_mask));
if (setsockopt(handle->fd, SOL_HCI, HCI_FILTER, &flt, sizeof(flt)) < 0) {
snprintf(errmsg, PCAP_ERRBUF_SIZE, "Can't set filter %d:%s",
errno, strerror(errno));
pcap_close(handle);
return NULL;
}
/* Bind socket to the HCI device */
addr.hci_family = AF_BLUETOOTH;
addr.hci_dev = handle->md.ifindex;
if (bind(handle->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
snprintf(errmsg, PCAP_ERRBUF_SIZE, "Can't attach to device %d %d:%s",
handle->md.ifindex, errno, strerror(errno));
pcap_close(handle);
return NULL;
}
handle->selectable_fd = handle->fd;
return handle;
}
static int
bt_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
{
struct cmsghdr *cmsg;
struct msghdr msg;
struct iovec iv;
struct pcap_pkthdr pkth;
iv.iov_base = &handle->buffer[handle->offset];
iv.iov_len = handle->snapshot;
memset(&msg, 0, sizeof(msg));
msg.msg_iov = &iv;
msg.msg_iovlen = 1;
msg.msg_control = handle->buffer;
msg.msg_controllen = handle->offset;
/* ignore interrupt system call error */
do {
pkth.caplen = recvmsg(handle->fd, &msg, 0);
if (handle->break_loop)
{
handle->break_loop = 0;
return -2;
}
} while ((pkth.caplen == -1) && (errno == EINTR));
if (pkth.caplen < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't receive packet %d:%s",
handle->md.ifindex, errno, strerror(errno));
return -1;
}
/* get direction and timestamp*/
cmsg = CMSG_FIRSTHDR(&msg);
while (cmsg) {
int in;
switch (cmsg->cmsg_type) {
case HCI_CMSG_DIR:
in = *((int *) CMSG_DATA(cmsg));
break;
case HCI_CMSG_TSTAMP:
pkth.ts = *((struct timeval *) CMSG_DATA(cmsg));
break;
}
cmsg = CMSG_NXTHDR(&msg, cmsg);
}
pkth.len = pkth.caplen;
callback(user, &pkth, iv.iov_base);
return 1;
}
static int
bt_inject_linux(pcap_t *handle, const void *buf, size_t size)
{
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported on "
"bluetooth devices");
return (-1);
}
static void
bt_close_linux(pcap_t* handle)
{
close(handle->fd);
free(handle->buffer);
}
static int
bt_stats_linux(pcap_t *handle, struct pcap_stat *stats)
{
int ret;
struct hci_dev_info dev_info;
struct hci_dev_stats * s = &dev_info.stat;
dev_info.dev_id = handle->md.ifindex;
/* ingnore 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 get stats"
" via ioctl %d:%s", errno, 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 +
s->acl_tx +s->sco_tx;
stats->ps_drop = s->err_rx + s->err_tx;
stats->ps_ifdrop = 0;
return 0;
}
static int
bt_setfilter_linux(pcap_t *p, struct bpf_program *fp)
{
return 0;
}
static int
bt_setdirection_linux(pcap_t *p, pcap_direction_t d)
{
p->direction = d;
return 0;
}

View File

@ -27,7 +27,7 @@
#ifndef lint #ifndef lint
static const char rcsid[] _U_ = static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-linux.c,v 1.126 2006-10-12 17:26:06 guy Exp $ (LBL)"; "@(#) $Header: /tcpdump/master/libpcap/pcap-linux.c,v 1.127 2006-10-13 17:34:53 guy Exp $ (LBL)";
#endif #endif
/* /*
@ -184,11 +184,21 @@ typedef int socklen_t;
*/ */
#define BIGGER_THAN_ALL_MTUS (64*1024) #define BIGGER_THAN_ALL_MTUS (64*1024)
#ifdef PCAP_SUPPORT_USB
/* /*
* Prototypes for usb related functions * Prototypes for USB-related functions
*/ */
int usb_platform_finddevs(pcap_if_t **alldevsp, char *err_str); int usb_platform_finddevs(pcap_if_t **alldevsp, char *err_str);
pcap_t* usb_open_live(const char* bus, int snaplen, int promisc , int to_ms, char* errmsg); pcap_t* usb_open_live(const char* bus, int snaplen, int promisc , int to_ms, char* errmsg);
#endif
#ifdef PCAP_SUPPORT_BT
/*
* Prototypes for Bluetooth-related functions
*/
int bt_platform_finddevs(pcap_if_t **alldevsp, char *err_str);
pcap_t* bt_open_live(const char* bus, int snaplen, int promisc , int to_ms, char* errmsg);
#endif
/* /*
@ -262,9 +272,16 @@ pcap_open_live(const char *device, int snaplen, int promisc, int to_ms,
} }
#endif /* HAVE_SEPTEL_API */ #endif /* HAVE_SEPTEL_API */
if (strstr(device, "usb")) { #ifdef PCAP_SUPPORT_BT
return usb_open_live(device, snaplen, promisc, to_ms, ebuf); if (strstr(device, "bluetooth")) {
} return bt_open_live(device, snaplen, promisc, to_ms, ebuf);
}
#endif
if (strstr(device, "usb")) {
return usb_open_live(device, snaplen, promisc, to_ms, ebuf);
}
/* Allocate a handle for this session. */ /* Allocate a handle for this session. */
@ -926,8 +943,15 @@ pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
return (-1); return (-1);
#endif /* HAVE_SEPTEL_API */ #endif /* HAVE_SEPTEL_API */
#ifdef PCAP_SUPPORT_BT
if (bt_platform_finddevs(alldevsp, errbuf) < 0)
return (-1);
#endif
#ifdef PCAP_SUPPORT_USB
if (usb_platform_finddevs(alldevsp, errbuf) < 0) if (usb_platform_finddevs(alldevsp, errbuf) < 0)
return (-1); return (-1);
#endif
return (0); return (0);
} }

View File

@ -406,7 +406,8 @@ usb_stats_linux(pcap_t *handle, struct pcap_stat *stats)
if (fd < 0) if (fd < 0)
{ {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't open usb stats file %s: %s", string, strerror(errno)); "Can't open usb stats file %s: %s",
string, strerror(errno));
return -1; return -1;
} }
@ -429,7 +430,8 @@ usb_stats_linux(pcap_t *handle, struct pcap_stat *stats)
if (ret != 2) if (ret != 2)
{ {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't parse stat line '%s' expected 2 token got %d", string, ret); "Can't parse stat line '%s' expected 2 token got %d",
string, ret);
return -1; return -1;
} }