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-bpf.c
pcap-bpf.h
pcap-bt-linux.c
pcap-dag.c
pcap-dag.h
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
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-bpf.c - BSD Packet Filter support
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.h - Endace DAG device capture support
pcap-dlpi.c - Data Link Provider Interface support

View File

@ -17,7 +17,7 @@
# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
# 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)
@ -72,7 +72,7 @@ YACC = @V_YACC@
@rm -f $@
$(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
SSRC = @SSRC@
CSRC = pcap.c inet.c gencode.c optimize.c nametoaddr.c \

View File

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

172
configure vendored
View File

@ -1,5 +1,5 @@
#! /bin/sh
# From configure.in Revision: 1.131 .
# From configure.in Revision: 1.132 .
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.59.
#
@ -310,7 +310,7 @@ ac_includes_default="\
# include <unistd.h>
#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=''
# 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),
# so one script is as good as another. But avoid the broken or
# incompatible versions:
@ -7938,6 +8104,8 @@ s,@DYEXT@,$DYEXT,;t t
s,@DAGLIBS@,$DAGLIBS,;t t
s,@PCAP_SUPPORT_USB@,$PCAP_SUPPORT_USB,;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_SCRIPT@,$INSTALL_SCRIPT,;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 Copyright (c) 1994, 1995, 1996, 1997
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
AC_REVISION($Revision: 1.131 $)
AC_REVISION($Revision: 1.132 $)
AC_PREREQ(2.50)
AC_INIT(pcap.c)
@ -806,6 +806,25 @@ esac
AC_SUBST(PCAP_SUPPORT_USB)
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_CONFIG_HEADER(config.h)

5
inet.c
View File

@ -34,7 +34,7 @@
#ifndef lint
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
#ifdef HAVE_CONFIG_H
@ -582,6 +582,9 @@ pcap_lookupnet(device, netp, maskp, errbuf)
#ifdef HAVE_SEPTEL_API
|| strstr(device, "septel") != NULL
#endif
#ifdef PCAP_SUPPORT_BT
|| strstr(device, "bluetooth") != NULL
#endif
#ifdef PCAP_SUPPORT_USB
|| strstr(device, "usb") != NULL
#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
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
/*
@ -184,11 +184,21 @@ typedef int socklen_t;
*/
#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);
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 */
if (strstr(device, "usb")) {
return usb_open_live(device, snaplen, promisc, to_ms, ebuf);
}
#ifdef PCAP_SUPPORT_BT
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. */
@ -926,8 +943,15 @@ pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
return (-1);
#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)
return (-1);
#endif
return (0);
}

View File

@ -406,7 +406,8 @@ 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", string, strerror(errno));
"Can't open usb stats file %s: %s",
string, strerror(errno));
return -1;
}
@ -429,7 +430,8 @@ usb_stats_linux(pcap_t *handle, struct pcap_stat *stats)
if (ret != 2)
{
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;
}