dect
/
libpcap
Archived
13
0
Fork 0

Import pcap-dect-linux

Signed-off-by: Patrick McHardy <kaber@trash.net>
This commit is contained in:
Patrick McHardy 2010-10-15 02:21:10 +02:00
parent 4d7214cbc5
commit f6e28f8d19
11 changed files with 415 additions and 11 deletions

View File

@ -82,7 +82,7 @@ YACC = @V_YACC@
@rm -f $@
$(CC) $(FULL_CFLAGS) -c $(srcdir)/$*.c
PSRC = pcap-@V_PCAP@.c @USB_SRC@ @BT_SRC@ @CAN_SRC@
PSRC = pcap-@V_PCAP@.c @USB_SRC@ @BT_SRC@ @CAN_SRC@ @DECT_SRC@
FSRC = fad-@V_FINDALLDEVS@.c
SSRC = @SSRC@
CSRC = pcap.c inet.c gencode.c optimize.c nametoaddr.c etherent.c \
@ -313,6 +313,8 @@ EXTRA_DIST = \
pcap-snoop.c \
pcap-usb-linux.c \
pcap-usb-linux.h \
pcap-dect-linux.c \
pcap-dect-linux.h \
pcap-win32.c \
runlex.sh \
scanner.l \

View File

@ -223,6 +223,8 @@
/* target host supports USB sniffing */
#undef PCAP_SUPPORT_USB
#undef PCAP_SUPPORT_DECT
/* include ACN support */
#undef SITA

114
configure vendored
View File

@ -697,6 +697,8 @@ MAN_FILE_FORMATS
MAN_MISC_INFO
PCAP_SUPPORT_USB
USB_SRC
PCAP_SUPPORT_DECT
DECT_SRC
PCAP_SUPPORT_BT
BT_SRC
PCAP_SUPPORT_CAN
@ -3973,7 +3975,7 @@ if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
else
ac_cv_header_stdc=no
fi
rm -f -r conftest*
rm -f conftest*
fi
@ -3994,7 +3996,7 @@ if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
else
ac_cv_header_stdc=no
fi
rm -f -r conftest*
rm -f conftest*
fi
@ -5054,7 +5056,7 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
;;
esac
rm -f -r conftest*
rm -f conftest*
if test $ac_cv_sys_file_offset_bits = unknown; then
{ echo "$as_me:$LINENO: checking for _LARGE_FILES value needed for large files" >&5
echo $ECHO_N "checking for _LARGE_FILES value needed for large files... $ECHO_C" >&6; }
@ -5175,7 +5177,7 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
;;
esac
rm -f -r conftest*
rm -f conftest*
fi
fi
@ -5191,11 +5193,13 @@ _ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <stdio.h>
#include <sys/types.h> /* for off_t */
#include <stdio.h>
int
main ()
{
return fseeko (stdin, 0, 0) && (fseeko) (stdin, 0, 0);
int (*fp) (FILE *, off_t, int) = fseeko;
return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
;
return 0;
}
@ -5235,11 +5239,13 @@ cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#define _LARGEFILE_SOURCE 1
#include <stdio.h>
#include <sys/types.h> /* for off_t */
#include <stdio.h>
int
main ()
{
return fseeko (stdin, 0, 0) && (fseeko) (stdin, 0, 0);
int (*fp) (FILE *, off_t, int) = fseeko;
return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
;
return 0;
}
@ -5286,7 +5292,7 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
;;
esac
rm -f -r conftest*
rm -f conftest*
# We used to try defining _XOPEN_SOURCE=500 too, to work around a bug
# in glibc 2.1.3, but that breaks too many other things.
@ -10542,6 +10548,92 @@ esac
{ echo "$as_me:$LINENO: checking for DECT sniffing support" >&5
echo $ECHO_N "checking for DECT sniffing support... $ECHO_C" >&6; }
case "$host_os" in
linux*)
{ echo "$as_me:$LINENO: checking for nl_dect_cluster_alloc_cache in -lnl-dect" >&5
echo $ECHO_N "checking for nl_dect_cluster_alloc_cache in -lnl-dect... $ECHO_C" >&6; }
if test "${ac_cv_lib_nl_dect_nl_dect_cluster_alloc_cache+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lnl-dect $LIBS"
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char nl_dect_cluster_alloc_cache ();
int
main ()
{
return nl_dect_cluster_alloc_cache ();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (ac_try="$ac_link"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_link") 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); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest$ac_exeext &&
$as_test_x conftest$ac_exeext; then
ac_cv_lib_nl_dect_nl_dect_cluster_alloc_cache=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_lib_nl_dect_nl_dect_cluster_alloc_cache=no
fi
rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ echo "$as_me:$LINENO: result: $ac_cv_lib_nl_dect_nl_dect_cluster_alloc_cache" >&5
echo "${ECHO_T}$ac_cv_lib_nl_dect_nl_dect_cluster_alloc_cache" >&6; }
if test $ac_cv_lib_nl_dect_nl_dect_cluster_alloc_cache = yes; then
cat >>confdefs.h <<\_ACEOF
#define PCAP_SUPPORT_DECT 1
_ACEOF
else
{ echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6; }
fi
DECT_SRC=pcap-dect-linux.c
;;
*)
{ echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6; }
;;
esac
# Check whether --enable-bluetooth was given.
if test "${enable_bluetooth+set}" = set; then
enableval=$enable_bluetooth;
@ -11734,6 +11826,8 @@ MAN_FILE_FORMATS!$MAN_FILE_FORMATS$ac_delim
MAN_MISC_INFO!$MAN_MISC_INFO$ac_delim
PCAP_SUPPORT_USB!$PCAP_SUPPORT_USB$ac_delim
USB_SRC!$USB_SRC$ac_delim
PCAP_SUPPORT_DECT!$PCAP_SUPPORT_DECT$ac_delim
DECT_SRC!$DECT_SRC$ac_delim
PCAP_SUPPORT_BT!$PCAP_SUPPORT_BT$ac_delim
BT_SRC!$BT_SRC$ac_delim
PCAP_SUPPORT_CAN!$PCAP_SUPPORT_CAN$ac_delim
@ -11744,7 +11838,7 @@ INSTALL_DATA!$INSTALL_DATA$ac_delim
LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 91; then
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 93; then
break
elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5

View File

@ -1398,6 +1398,21 @@ esac
AC_SUBST(PCAP_SUPPORT_USB)
AC_SUBST(USB_SRC)
AC_MSG_CHECKING(for DECT sniffing support)
case "$host_os" in
linux*)
AC_CHECK_LIB([nl-dect],[nl_dect_cluster_alloc_cache],
AC_DEFINE(PCAP_SUPPORT_DECT, 1, [target host supports DECT sniffing]),
AC_MSG_RESULT([no]))
DECT_SRC=pcap-dect-linux.c
;;
*)
AC_MSG_RESULT(no)
;;
esac
AC_SUBST(PCAP_SUPPORT_DECT)
AC_SUBST(DECT_SRC)
AC_ARG_ENABLE([bluetooth],
[AC_HELP_STRING([--enable-bluetooth],[enable Bluetooth support @<:@default=yes, if support available@:>@])],
,enable_bluetooth=yes)

View File

@ -1451,6 +1451,16 @@ init_linktype(p)
off_nl_nosnap = -1;
return;
case DLT_DECT_LINUX:
/*
* Currently, only raw "link[N:M]" filtering is supported.
*/
off_linktype = -1;
off_macpl = -1;
off_nl = -1;
off_nl_nosnap = -1;
return;
case DLT_CAN20B:
/*
* Currently, only raw "link[N:M]" filtering is supported.

3
inet.c
View File

@ -739,6 +739,9 @@ pcap_lookupnet(device, netp, maskp, errbuf)
#endif
#ifdef HAVE_SNF_API
|| strstr(device, "snf") != NULL
#endif
#ifdef PCAP_SUPPORT_DECT
|| strstr(device, "dect") != NULL
#endif
) {
*netp = *maskp = 0;

256
pcap-dect-linux.c Normal file
View File

@ -0,0 +1,256 @@
/*
* Copyright (C) 2009 Patrick McHardy <kaber@trash.net>
*
* Licensed under the same license as libpcap itself.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "pcap-int.h"
#include "pcap-dect-linux.h"
#ifdef NEED_STRERROR_H
#include "strerror.h"
#endif
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/types.h>
#include <linux/dect.h>
#include <linux/netlink.h>
#include <netlink/cache.h>
#include <netlink/dect/cell.h>
#define PF_DECT 38
#define AF_DECT PF_DECT
#define SOL_DECT 279
struct cb_args {
pcap_if_t **alldevsp;
char *err_str;
bool err;
};
static void add_cell_cb(struct nl_object *obj, void *arg)
{
struct cb_args *args = arg;
char dev_name[32];
if (args->err)
return;
snprintf(dev_name, sizeof(dev_name), "dect-%s",
nl_dect_cell_get_name((struct nl_dect_cell *)obj));
if (pcap_add_if(args->alldevsp, dev_name, 0, NULL, args->err_str) < 0)
args->err = true;
}
int dect_platform_finddevs(pcap_if_t **alldevsp, char *err_str)
{
struct nl_sock *sock;
struct nl_cache *cell_cache;
struct cb_args args = {
.alldevsp = alldevsp,
.err_str = err_str,
};
sock = nl_socket_alloc();
if (sock == NULL) {
snprintf(err_str, PCAP_ERRBUF_SIZE, "socket: %s",
pcap_strerror(errno));
return -1;
}
if (nl_connect(sock, NETLINK_DECT) < 0) {
snprintf(err_str, PCAP_ERRBUF_SIZE, "connect: %s",
pcap_strerror(errno));
return -1;
}
if (nl_dect_cell_alloc_cache(sock, &cell_cache) < 0) {
snprintf(err_str, PCAP_ERRBUF_SIZE, "cache: %s",
pcap_strerror(errno));
return -1;
}
nl_cache_foreach(cell_cache, add_cell_cb, &args);
nl_socket_free(sock);
return args.err ? -1 : 0;
}
/*
* compatible header to what wireshark is expecting from the CoA
* character device for now.
*/
struct dect_dummy_hdr {
uint8_t etheraddrs[2 * 6];
uint16_t ethertype;
uint8_t trxmode;
uint8_t channel;
uint16_t slot;
uint8_t frame;
uint8_t rssi;
uint8_t preamble[3];
uint16_t packettype;
} __attribute__((packed));
static int dect_read_linux(pcap_t *handle, int max_packets,
pcap_handler callback, u_char *user)
{
struct pcap_pkthdr hdr;
struct dect_dummy_hdr *dhdr;
struct iovec iov;
struct msghdr msg;
struct dect_raw_auxdata *aux;
struct cmsghdr *cmsg;
union {
struct cmsghdr cmsg;
char buf[CMSG_SPACE(sizeof(*aux))];
} cmsg_buf;
ssize_t len;
/* refuse anything below dummy header size for simplicity */
if (handle->bufsize < sizeof(*dhdr))
return -1;
dhdr = (struct dect_dummy_hdr *)handle->buffer;
memset(dhdr, 0, sizeof(*dhdr));
dhdr->ethertype = 0x2323;
dhdr->trxmode = 0;
dhdr->channel = 0;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = &cmsg_buf;
msg.msg_controllen = sizeof(cmsg_buf);
msg.msg_flags = 0;
iov.iov_len = handle->bufsize - sizeof(*dhdr);
iov.iov_base = handle->buffer + sizeof(*dhdr);
do {
if (handle->break_loop) {
handle->break_loop = 0;
return -2;
}
len = recvmsg(handle->fd, &msg, 0);
} while (len == -1 && (errno == EINTR || errno == ENETDOWN));
if (len == -1) {
if (errno == EAGAIN)
return 0;
else {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"recvfrom: %s", pcap_strerror(errno));
return -1;
}
}
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
cmsg = CMSG_NXTHDR(&msg, cmsg)) {
if (cmsg->cmsg_level != SOL_DECT ||
cmsg->cmsg_type != DECT_RAW_AUXDATA ||
cmsg->cmsg_len < CMSG_LEN(sizeof(*aux)))
continue;
aux = (struct dect_raw_auxdata *)CMSG_DATA(cmsg);
dhdr->slot = htons(aux->slot);
dhdr->rssi = aux->rssi;
dhdr->frame = aux->frame;
if (aux->slot < 12)
dhdr->packettype = htons(0xe98a);
else
dhdr->packettype = htons(0x1675);
}
gettimeofday(&hdr.ts, NULL);
hdr.caplen = len + sizeof(*dhdr);
hdr.len = len + sizeof(*dhdr);
callback(user, &hdr, handle->buffer);
return 1;
}
static int dect_setfilter_linux(pcap_t *handle, struct bpf_program *fp)
{
return 0;
}
static int dect_setdirection_linux(pcap_t *handle, pcap_direction_t d)
{
handle->direction = d;
return 0;
}
static int dect_activate(pcap_t *handle)
{
struct sockaddr_dect da;
handle->bufsize = handle->snapshot;
handle->offset = 0;
#if 0
handle->linktype = DLT_DECT_LINUX;
#else
handle->linktype = DLT_EN10MB;
#endif
handle->inject_op = NULL;
handle->setfilter_op = dect_setfilter_linux;
handle->setdirection_op = dect_setdirection_linux;
handle->set_datalink_op = NULL;
handle->getnonblock_op = pcap_getnonblock_fd;
handle->setnonblock_op = pcap_setnonblock_fd;
handle->read_op = dect_read_linux;
handle->fd = socket(PF_DECT, SOCK_RAW, 0);
if (handle->fd < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't open PF_DECT socket: %s",
pcap_strerror(errno));
return PCAP_ERROR;
}
memset(&da, 0, sizeof(da));
da.dect_family = AF_DECT;
if (bind(handle->fd, (struct sockaddr *)&da, sizeof(da)) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't bind PF_DECT socket: %s",
pcap_strerror(errno));
return PCAP_ERROR;
}
handle->selectable_fd = handle->fd;
handle->buffer = malloc(handle->bufsize);
if (!handle->buffer) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't allocate packet buffer: %s",
pcap_strerror(errno));
return PCAP_ERROR;
}
return 0;
}
pcap_t *dect_create(const char *device, char *ebuf)
{
pcap_t *p;
p = pcap_create_common(device, ebuf);
if (p == NULL)
return NULL;
p->activate_op = dect_activate;
return p;
}

2
pcap-dect-linux.h Normal file
View File

@ -0,0 +1,2 @@
int dect_platform_finddevs(pcap_if_t **alldevsp, char *err_str);
pcap_t *dect_create(const char *device, char *ebuf);

View File

@ -191,6 +191,10 @@ static const char rcsid[] _U_ =
#include "pcap-can-linux.h"
#endif
#ifdef PCAP_SUPPORT_DECT
#include "pcap-dect-linux.h"
#endif
/*
* If PF_PACKET is defined, we can use {SOCK_RAW,SOCK_DGRAM}/PF_PACKET
* sockets rather than SOCK_PACKET sockets.
@ -410,6 +414,12 @@ pcap_create(const char *device, char *ebuf)
}
#endif
#ifdef PCAP_SUPPORT_DECT
if (strstr(device, "dect")) {
return dect_create(device, ebuf);
}
#endif
handle = pcap_create_common(device, ebuf);
if (handle == NULL)
return NULL;
@ -2164,6 +2174,10 @@ pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
return (-1);
#endif
#ifdef PCAP_SUPPORT_DECT
if (dect_platform_finddevs(alldevsp, errbuf) < 0)
return (-1);
#endif
return (0);
}

1
pcap.c
View File

@ -820,6 +820,7 @@ static struct dlt_choice dlt_choices[] = {
DLT_CHOICE(DLT_BLUETOOTH_HCI_H4, "Bluetooth HCI UART transport layer"),
DLT_CHOICE(DLT_IEEE802_16_MAC_CPS, "IEEE 802.16 MAC Common Part Sublayer"),
DLT_CHOICE(DLT_USB_LINUX, "USB with Linux header"),
DLT_CHOICE(DLT_DECT_LINUX, "DECT with Linux header"),
DLT_CHOICE(DLT_CAN20B, "Controller Area Network (CAN) v. 2.0B"),
DLT_CHOICE(DLT_IEEE802_15_4_LINUX, "IEEE 802.15.4 with Linux padding"),
DLT_CHOICE(DLT_PPI, "Per-Packet Information"),

View File

@ -969,6 +969,11 @@ struct bpf_version {
*/
#define DLT_IEEE802_15_4_NOFCS 230
/*
* DECT
*/
#define DLT_DECT_LINUX 231
/*
* DLT and savefile link type values are split into a class and
* a member of that class. A class value of 0 indicates a regular