@rm -f $@
$(CC) $(FULL_CFLAGS) -c $(srcdir)/$*.c
-PSRC = pcap-@
[email protected] @USB_SRC@ @BT_SRC@ @BT_MONITOR_SRC@ @
CAN_SRC@ @NETFILTER_SRC@ @CANUSB_SRC@ @DBUS_SRC@
+PSRC = pcap-@
[email protected] @USB_SRC@ @BT_SRC@ @BT_MONITOR_SRC@ @
NETFILTER_SRC@ @DBUS_SRC@
FSRC = @V_FINDALLDEVS@
SSRC = @SSRC@
CSRC = pcap.c inet.c fad-helpers.c gencode.c optimize.c nametoaddr.c \
pcap-bt-linux.h \
pcap-bt-monitor-linux.c \
pcap-bt-monitor-linux.h \
- pcap-can-linux.c \
- pcap-can-linux.h \
- pcap-canusb-linux.c \
- pcap-canusb-linux.h \
pcap-config.in \
pcap-dag.c \
pcap-dag.h \
/* target host supports Bluetooth Monitor */
#cmakedefine PCAP_SUPPORT_BT_MONITOR 1
-/* target host supports CAN sniffing */
-#cmakedefine PCAP_SUPPORT_CAN 1
-
-/* target host supports canusb */
-#cmakedefine PCAP_SUPPORT_CANUSB 1
-
/* support D-Bus sniffing */
#cmakedefine PCAP_SUPPORT_DBUS 1
/* target host supports Bluetooth Monitor */
#undef PCAP_SUPPORT_BT_MONITOR
-/* target host supports CAN sniffing */
-#undef PCAP_SUPPORT_CAN
-
-/* target host supports canusb */
-#undef PCAP_SUPPORT_CANUSB
-
/* support D-Bus sniffing */
#undef PCAP_SUPPORT_DBUS
DBUS_SRC
PCAP_SUPPORT_DBUS
PKGCONFIG
-CAN_SRC
-PCAP_SUPPORT_CAN
-CANUSB_SRC
-PCAP_SUPPORT_CANUSB
BT_MONITOR_SRC
BT_SRC
PCAP_SUPPORT_BT
enable_shared
enable_usb
enable_bluetooth
-enable_canusb
-enable_can
enable_dbus
enable_packet_ring
'
available]
--enable-bluetooth enable Bluetooth support [default=yes, if support
available]
- --enable-canusb enable canusb support [default=yes, if support
- available]
- --enable-can enable CAN support [default=yes, if support
- available]
--enable-dbus enable D-Bus capture support [default=yes, if
support available]
--enable-packet-ring enable Linux packet ring support [default=yes]
-fi
-
-# Check whether --enable-canusb was given.
-if test "${enable_canusb+set}" = set; then :
- enableval=$enable_canusb;
-else
- enable_canusb=ifsupportavailable
-fi
-
-
-if test "xxx_only" = yes; then
- # User requested something-else-only pcap, so they don't
- # want canusb support.
- enable_canusb=no
-fi
-
-if test "x$enable_canusb" != "xno" ; then
- case "$host_os" in
- linux*|uclinux*)
- ac_fn_c_check_header_mongrel "$LINENO" "libusb-1.0/libusb.h" "ac_cv_header_libusb_1_0_libusb_h" "$ac_includes_default"
-if test "x$ac_cv_header_libusb_1_0_libusb_h" = xyes; then :
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libusb_init in -lusb-1.0" >&5
-$as_echo_n "checking for libusb_init in -lusb-1.0... " >&6; }
-if ${ac_cv_lib_usb_1_0_libusb_init+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lusb-1.0 -lpthread
- $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* 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 libusb_init ();
-int
-main ()
-{
-return libusb_init ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_usb_1_0_libusb_init=yes
-else
- ac_cv_lib_usb_1_0_libusb_init=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_usb_1_0_libusb_init" >&5
-$as_echo "$ac_cv_lib_usb_1_0_libusb_init" >&6; }
-if test "x$ac_cv_lib_usb_1_0_libusb_init" = xyes; then :
-
-
-$as_echo "#define PCAP_SUPPORT_CANUSB 1" >>confdefs.h
-
- CANUSB_SRC=pcap-canusb-linux.c
- LIBS="-lusb-1.0 -lpthread $LIBS"
- ac_lbl_has_libusb=yes
-
-else
- ac_lbl_has_libusb=no
-fi
-
-
-else
- ac_lbl_has_libusb=no
-
-fi
-
-
- if test "x$ac_lbl_has_libusb" = "xyes" ; then
- { $as_echo "$as_me:${as_lineno-$LINENO}: canusb sniffing is supported" >&5
-$as_echo "$as_me: canusb sniffing is supported" >&6;}
- else
- if test "x$enable_canusb" = "xyes" ; then
- as_fn_error $? "canusb sniffing is not supported; install libusb1.0 lib devel to enable it" "$LINENO" 5
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: canusb sniffing is not supported; install libusb1.0 lib devel to enable it" >&5
-$as_echo "$as_me: canusb sniffing is not supported; install libusb1.0 lib devel to enable it" >&6;}
- fi
- fi
- ;;
- *)
- if test "x$enable_canusb" = "xyes" ; then
- as_fn_error $? "no canusb support implemented for $host_os" "$LINENO" 5
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: no canusb support implemented for $host_os" >&5
-$as_echo "$as_me: no canusb support implemented for $host_os" >&6;}
- fi
- ;;
- esac
-
-
-fi
-
-# Check whether --enable-can was given.
-if test "${enable_can+set}" = set; then :
- enableval=$enable_can;
-else
- enable_can=ifsupportavailable
-fi
-
-
-if test "xxx_only" = yes; then
- # User requested something-else-only pcap, so they don't
- # want CAN support.
- enable_can=no
-fi
-
-if test "x$enable_can" != "xno" ; then
- case "$host_os" in
- linux*)
- ac_fn_c_check_header_compile "$LINENO" "linux/can.h" "ac_cv_header_linux_can_h" "#include <sys/socket.h>
-
-"
-if test "x$ac_cv_header_linux_can_h" = xyes; then :
-
-
-$as_echo "#define PCAP_SUPPORT_CAN 1" >>confdefs.h
-
- CAN_SRC=pcap-can-linux.c
- { $as_echo "$as_me:${as_lineno-$LINENO}: CAN sniffing is supported" >&5
-$as_echo "$as_me: CAN sniffing is supported" >&6;}
-
-else
-
- if test "x$enable_can" = "xyes" ; then
- as_fn_error $? "CAN sniffing is not supported" "$LINENO" 5
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: CAN sniffing is not supported" >&5
-$as_echo "$as_me: CAN sniffing is not supported" >&6;}
- fi
-
-fi
-
-
- ;;
- *)
- if test "x$enable_can" = "xyes" ; then
- as_fn_error $? "no CAN sniffing support implemented for $host_os" "$LINENO" 5
- else
- { $as_echo "$as_me:${as_lineno-$LINENO}: no CAN sniffing support implemented for $host_os" >&5
-$as_echo "$as_me: no CAN sniffing support implemented for $host_os" >&6;}
- fi
- ;;
- esac
-
-
fi
# Check whether --enable-dbus was given.
AC_SUBST(BT_MONITOR_SRC)
fi
-AC_ARG_ENABLE([canusb],
-[AC_HELP_STRING([--enable-canusb],[enable canusb support @<:@default=yes, if support available@:>@])],
- [],
- [enable_canusb=ifsupportavailable])
-
-if test "xxx_only" = yes; then
- # User requested something-else-only pcap, so they don't
- # want canusb support.
- enable_canusb=no
-fi
-
-if test "x$enable_canusb" != "xno" ; then
- dnl check for canusb support
- case "$host_os" in
- linux*|uclinux*)
- AC_CHECK_HEADER(libusb-1.0/libusb.h,
- [
- AC_CHECK_LIB(usb-1.0, libusb_init,
- [
- AC_DEFINE(PCAP_SUPPORT_CANUSB, 1, [target host supports canusb])
- CANUSB_SRC=pcap-canusb-linux.c
- LIBS="-lusb-1.0 -lpthread $LIBS"
- ac_lbl_has_libusb=yes
- ],
- ac_lbl_has_libusb=no,
- -lpthread
- )
- ],
- ac_lbl_has_libusb=no
- )
- if test "x$ac_lbl_has_libusb" = "xyes" ; then
- AC_MSG_NOTICE(canusb sniffing is supported)
- else
- if test "x$enable_canusb" = "xyes" ; then
- AC_MSG_ERROR(canusb sniffing is not supported; install libusb1.0 lib devel to enable it)
- else
- AC_MSG_NOTICE(canusb sniffing is not supported; install libusb1.0 lib devel to enable it)
- fi
- fi
- ;;
- *)
- if test "x$enable_canusb" = "xyes" ; then
- AC_MSG_ERROR(no canusb support implemented for $host_os)
- else
- AC_MSG_NOTICE(no canusb support implemented for $host_os)
- fi
- ;;
- esac
- AC_SUBST(PCAP_SUPPORT_CANUSB)
- AC_SUBST(CANUSB_SRC)
-fi
-
-AC_ARG_ENABLE([can],
-[AC_HELP_STRING([--enable-can],[enable CAN support @<:@default=yes, if support available@:>@])],
- [],
- [enable_can=ifsupportavailable])
-
-if test "xxx_only" = yes; then
- # User requested something-else-only pcap, so they don't
- # want CAN support.
- enable_can=no
-fi
-
-if test "x$enable_can" != "xno" ; then
- dnl check for CAN sniffing support
- case "$host_os" in
- linux*)
- AC_CHECK_HEADER(linux/can.h,
- [
- AC_DEFINE(PCAP_SUPPORT_CAN, 1, [target host supports CAN sniffing])
- CAN_SRC=pcap-can-linux.c
- AC_MSG_NOTICE(CAN sniffing is supported)
- ],
- [
- if test "x$enable_can" = "xyes" ; then
- AC_MSG_ERROR(CAN sniffing is not supported)
- else
- AC_MSG_NOTICE(CAN sniffing is not supported)
- fi
- ],
- [#include <sys/socket.h>]
- )
- ;;
- *)
- if test "x$enable_can" = "xyes" ; then
- AC_MSG_ERROR(no CAN sniffing support implemented for $host_os)
- else
- AC_MSG_NOTICE(no CAN sniffing support implemented for $host_os)
- fi
- ;;
- esac
- AC_SUBST(PCAP_SUPPORT_CAN)
- AC_SUBST(CAN_SRC)
-fi
-
AC_ARG_ENABLE([dbus],
[AC_HELP_STRING([--enable-dbus],[enable D-Bus capture support @<:@default=yes, if support available@:>@])],
[],
bpf_error(cstate, "Bluetooth link-layer type filtering not implemented");
case DLT_CAN20B:
- case DLT_CAN_SOCKETCAN_BIGENDIAN:
- case DLT_CAN_SOCKETCAN_HOSTENDIAN:
+ case DLT_CAN_SOCKETCAN:
bpf_error(cstate, "CAN link-layer type filtering not implemented");
case DLT_IEEE802_15_4:
+++ /dev/null
-/*
- * Copyright (c) 2009 Felix Obenhuber
- * 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. 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
- * "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.
- *
- * SocketCan sniffing API implementation for Linux platform
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "pcap-int.h"
-#include "pcap-can-linux.h"
-
-#define CAN_CONTROL_SIZE 8
-
-#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 <net/if.h>
-#include <arpa/inet.h>
-
-#include <linux/can.h>
-#include <linux/can/raw.h>
-
-/* not yet defined anywhere */
-#ifndef PF_CAN
-#define PF_CAN 29
-#endif
-#ifndef AF_CAN
-#define AF_CAN PF_CAN
-#endif
-
-/* forward declaration */
-static int can_activate(pcap_t *);
-static int can_read_linux(pcap_t *, int , pcap_handler , u_char *);
-static int can_inject_linux(pcap_t *, const void *, size_t);
-static int can_setfilter_linux(pcap_t *, struct bpf_program *);
-static int can_setdirection_linux(pcap_t *, pcap_direction_t);
-static int can_stats_linux(pcap_t *, struct pcap_stat *);
-
-/*
- * Private data for capturing on Linux CANbus devices.
- */
-struct pcap_can {
- int ifindex; /* interface index of device we're bound to */
-};
-
-int
-can_findalldevs(pcap_if_t **devlistp, char *errbuf)
-{
- /*
- * There are no platform-specific devices since each device
- * exists as a regular network interface.
- *
- * XXX - true?
- */
- return 0;
-}
-
-pcap_t *
-can_create(const char *device, char *ebuf, int *is_ours)
-{
- const char *cp;
- char *cpend;
- long devnum;
- pcap_t* p;
-
- /* Does this look like a CANbus device? */
- cp = strrchr(device, '/');
- if (cp == NULL)
- cp = device;
- /* Does it begin with "can" or "vcan"? */
- if (strncmp(cp, "can", 3) == 0) {
- /* Begins with "can" */
- cp += 3; /* skip past "can" */
- } else if (strncmp(cp, "vcan", 4) == 0) {
- /* Begins with "vcan" */
- cp += 4;
- } else {
- /* Nope, doesn't begin with "can" or "vcan" */
- *is_ours = 0;
- return NULL;
- }
- /* Yes - is "can" or "vcan" followed by a number from 0? */
- devnum = strtol(cp, &cpend, 10);
- if (cpend == cp || *cpend != '\0') {
- /* Not followed by a number. */
- *is_ours = 0;
- return NULL;
- }
- if (devnum < 0) {
- /* Followed by a non-valid number. */
- *is_ours = 0;
- return NULL;
- }
-
- /* OK, it's probably ours. */
- *is_ours = 1;
-
- p = pcap_create_common(ebuf, sizeof (struct pcap_can));
- if (p == NULL)
- return (NULL);
-
- p->activate_op = can_activate;
- return (p);
-}
-
-
-static int
-can_activate(pcap_t* handle)
-{
- struct pcap_can *handlep = handle->priv;
- struct sockaddr_can addr;
- struct ifreq ifr;
-
- /* Initialize some components of the pcap structure. */
- handle->bufsize = CAN_CONTROL_SIZE + 16;
- handle->linktype = DLT_CAN_SOCKETCAN_BIGENDIAN;
- handle->read_op = can_read_linux;
- handle->inject_op = can_inject_linux;
- handle->setfilter_op = can_setfilter_linux;
- handle->setdirection_op = can_setdirection_linux;
- handle->set_datalink_op = NULL;
- handle->getnonblock_op = pcap_getnonblock_fd;
- handle->setnonblock_op = pcap_setnonblock_fd;
- handle->stats_op = can_stats_linux;
-
- /* Create socket */
- handle->fd = socket(PF_CAN, SOCK_RAW, CAN_RAW);
- if (handle->fd < 0)
- {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't create raw socket %d:%s",
- errno, strerror(errno));
- return PCAP_ERROR;
- }
-
- /* get interface index */
- memset(&ifr, 0, sizeof(ifr));
- strlcpy(ifr.ifr_name, handle->opt.device, sizeof(ifr.ifr_name));
- if (ioctl(handle->fd, SIOCGIFINDEX, &ifr) < 0)
- {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
- "Unable to get interface index: %s",
- pcap_strerror(errno));
- pcap_cleanup_live_common(handle);
- return PCAP_ERROR;
- }
- handlep->ifindex = ifr.ifr_ifindex;
-
- /* allocate butter */
- handle->buffer = malloc(handle->bufsize);
- if (!handle->buffer)
- {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate dump buffer: %s",
- pcap_strerror(errno));
- pcap_cleanup_live_common(handle);
- return PCAP_ERROR;
- }
-
- /* Bind to the socket */
- addr.can_family = AF_CAN;
- addr.can_ifindex = handlep->ifindex;
- if( bind( handle->fd, (struct sockaddr*)&addr, sizeof(addr) ) < 0 )
- {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't attach to device %d %d:%s",
- handlep->ifindex, errno, strerror(errno));
- pcap_cleanup_live_common(handle);
- return PCAP_ERROR;
- }
-
- if (handle->opt.rfmon)
- {
- /* Monitor mode doesn't apply to CAN devices. */
- pcap_cleanup_live_common(handle);
- return PCAP_ERROR_RFMON_NOTSUP;
- }
-
- handle->selectable_fd = handle->fd;
- return 0;
-
-}
-
-
-static int
-can_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
-{
- struct msghdr msg;
- struct pcap_pkthdr pkth;
- u_char *pktd;
- struct iovec iv;
- struct can_frame* cf;
- int len;
-
- pktd = (u_char *)handle->buffer + CAN_CONTROL_SIZE;
- iv.iov_base = pktd;
- 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 = CAN_CONTROL_SIZE;
-
- do
- {
- len = recvmsg(handle->fd, &msg, 0);
- if (handle->break_loop)
- {
- handle->break_loop = 0;
- return -2;
- }
- } while ((len == -1) && (errno == EINTR));
-
- if (len == -1)
- {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't receive packet %d:%s",
- errno, strerror(errno));
- return -1;
- }
- pkth.caplen = (bpf_u_int32)len;
-
- /* adjust capture len according to frame len */
- cf = (struct can_frame*)(void *)pktd;
- pkth.caplen -= CAN_CONTROL_SIZE - cf->can_dlc;
- pkth.len = pkth.caplen;
-
- cf->can_id = htonl( cf->can_id );
-
- if( -1 == gettimeofday(&pkth.ts, NULL) )
- {
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't get time of day %d:%s",
- errno, strerror(errno));
- return -1;
- }
-
- callback(user, &pkth, pktd);
-
- return 1;
-}
-
-
-static int
-can_inject_linux(pcap_t *handle, const void *buf, size_t size)
-{
- /* not yet implemented */
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported on "
- "can devices");
- return (-1);
-}
-
-
-static int
-can_stats_linux(pcap_t *handle, struct pcap_stat *stats)
-{
- /* not yet implemented */
- stats->ps_recv = 0; /* number of packets received */
- stats->ps_drop = 0; /* number of packets dropped */
- stats->ps_ifdrop = 0; /* drops by interface -- only supported on some platforms */
- return 0;
-}
-
-
-static int
-can_setfilter_linux(pcap_t *p, struct bpf_program *fp)
-{
- /* not yet implemented */
- return 0;
-}
-
-
-static int
-can_setdirection_linux(pcap_t *p, pcap_direction_t d)
-{
- /* no support for PCAP_D_OUT */
- if (d == PCAP_D_OUT)
- {
- pcap_snprintf(p->errbuf, sizeof(p->errbuf),
- "Setting direction to PCAP_D_OUT is not supported on can");
- return -1;
- }
-
- p->direction = d;
-
- return 0;
-}
-
-
-/* eof */
+++ /dev/null
-/*
- * Copyright (c) 2009 Felix Obenhuber
- * 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. 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
- * "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.
- *
- */
-
-/*
- * Prototypes for SocketCAN related functions
- */
-pcap_t* can_create(const char *device, char *ebuf, int *is_ours);
-int can_findalldevs(pcap_if_t **devlistp, char *errbuf);
+++ /dev/null
-/*
- * Copyright (c) 2009 Felix Obenhuber
- * 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. 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
- * "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.
- *
- * Sockettrace sniffing API implementation for Linux platform
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <libusb-1.0/libusb.h>
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <string.h>
-#include <pthread.h>
-
-#include "pcap-int.h"
-#include "pcap-canusb-linux.h"
-
-#define CANUSB_IFACE "canusb"
-
-#define CANUSB_VID 0x0403
-#define CANUSB_PID 0x8990
-
-#define USE_THREAD 1
-
-#if USE_THREAD == 0
-#include <signal.h>
-#endif
-
-
-/* forward declaration */
-static int canusb_activate(pcap_t *);
-static int canusb_read_linux(pcap_t *, int , pcap_handler , u_char *);
-static int canusb_inject_linux(pcap_t *, const void *, size_t);
-static int canusb_setfilter_linux(pcap_t *, struct bpf_program *);
-static int canusb_setdirection_linux(pcap_t *, pcap_direction_t);
-static int canusb_stats_linux(pcap_t *, struct pcap_stat *);
-
-struct CAN_Msg
-{
- uint32_t timestamp;
- uint32_t id;
- uint32_t length;
- uint8_t data[8];
-};
-
-/*
- * Private data for capturing on Linux CANbus USB devices.
- */
-struct pcap_canusb {
- libusb_context *ctx;
- libusb_device_handle *dev;
- pthread_t worker;
- int rdpipe, wrpipe;
- volatile int loop;
-};
-
-int canusb_findalldevs(pcap_if_t **alldevsp, char *err_str)
-{
- libusb_context *fdctx;
- libusb_device** devs;
- unsigned char sernum[65];
- int cnt, i;
-
- if (libusb_init(&fdctx) != 0) {
- /*
- * XXX - if this doesn't just mean "no USB file system mounted",
- * perhaps we should report a real error rather than just
- * saying "no CANUSB devices".
- */
- return 0;
- }
-
- cnt = libusb_get_device_list(fdctx,&devs);
-
- for(i=0;i<cnt;i++)
- {
- int ret;
- /* Check if this device is interesting. */
- struct libusb_device_descriptor desc;
- libusb_device_handle *dh;
-
- libusb_get_device_descriptor(devs[i],&desc);
-
- if ((desc.idVendor != CANUSB_VID) || (desc.idProduct != CANUSB_PID))
- continue; /* It is not, check next device */
-
- /* It is! */
- dh = NULL;
-
- if ((ret = libusb_open(devs[i],&dh)) == 0)
- {
- char dev_name[30];
- char dev_descr[50];
- int n = libusb_get_string_descriptor_ascii(dh,desc.iSerialNumber,sernum,64);
- sernum[n] = 0;
-
- pcap_snprintf(dev_name, 30, CANUSB_IFACE"%s", sernum);
- pcap_snprintf(dev_descr, 50, "CanUSB [%s]", sernum);
-
- libusb_close(dh);
-
- if (pcap_add_if(alldevsp, dev_name, 0, dev_descr, err_str) < 0)
- {
- libusb_free_device_list(devs,1);
- libusb_exit(fdctx);
- return -1;
- }
- }
- }
-
- libusb_free_device_list(devs,1);
- libusb_exit(fdctx);
- return 0;
-}
-
-static libusb_device_handle* canusb_opendevice(struct libusb_context *ctx, char* devserial)
-{
- libusb_device** devs;
- unsigned char serial[65];
- int cnt,i,n;
-
- cnt = libusb_get_device_list(ctx,&devs);
-
- for(i=0;i<cnt;i++)
- {
- /* Check if this device is interesting. */
- struct libusb_device_descriptor desc;
- libusb_device_handle *dh;
-
- libusb_get_device_descriptor(devs[i],&desc);
-
- if ((desc.idVendor != CANUSB_VID) || (desc.idProduct != CANUSB_PID))
- continue;
-
- /* Found one! */
- dh = NULL;
-
- if (libusb_open(devs[i],&dh) != 0) continue;
-
- n = libusb_get_string_descriptor_ascii(dh,desc.iSerialNumber,serial,64);
- serial[n] = 0;
-
- if ((devserial) && (strcmp((char *)serial,devserial) != 0))
- {
- libusb_close(dh);
- continue;
- }
-
- if ((libusb_kernel_driver_active(dh,0)) && (libusb_detach_kernel_driver(dh,0) != 0))
- {
- libusb_close(dh);
- continue;
- }
-
- if (libusb_set_configuration(dh,1) != 0)
- {
- libusb_close(dh);
- continue;
- }
-
- if (libusb_claim_interface(dh,0) != 0)
- {
- libusb_close(dh);
- continue;
- }
-
- /* Fount it! */
- libusb_free_device_list(devs,1);
- return dh;
- }
-
- libusb_free_device_list(devs,1);
- return NULL;
-}
-
-
-pcap_t *
-canusb_create(const char *device, char *ebuf, int *is_ours)
-{
- const char *cp;
- char *cpend;
- long devnum;
- pcap_t* p;
- struct pcap_canusb *canusb;
-
- /* Does this look like a DAG device? */
- cp = strrchr(device, '/');
- if (cp == NULL)
- cp = device;
- /* Does it begin with "canusb"? */
- if (strncmp(cp, "canusb", 6) != 0) {
- /* Nope, doesn't begin with "canusb" */
- *is_ours = 0;
- return NULL;
- }
- /* Yes - is "canusb" followed by a number? */
- cp += 6;
- devnum = strtol(cp, &cpend, 10);
- if (cpend == cp || *cpend != '\0') {
- /* Not followed by a number. */
- *is_ours = 0;
- return NULL;
- }
- if (devnum < 0) {
- /* Followed by a non-valid number. */
- *is_ours = 0;
- return NULL;
- }
-
- /* OK, it's probably ours. */
- *is_ours = 1;
-
- p = pcap_create_common(ebuf, sizeof (struct pcap_canusb));
- if (p == NULL)
- return (NULL);
-
- canusb = p->priv;
- canusb->ctx = NULL;
- canusb->dev = NULL;
- canusb->rdpipe = -1;
- canusb->wrpipe = -1;
-
- p->activate_op = canusb_activate;
-
- return (p);
-}
-
-
-static void* canusb_capture_thread(void *arg)
-{
- struct pcap_canusb *canusb = arg;
- int i;
- struct
- {
- uint8_t rxsz, txsz;
- } status;
-
- fcntl(canusb->wrpipe, F_SETFL, O_NONBLOCK);
-
- while(canusb->loop)
- {
- int sz;
- struct CAN_Msg msg;
-
- libusb_interrupt_transfer(canusb->dev, 0x81, (unsigned char*)&status, sizeof(status), &sz, 100);
- /* HACK!!!!! -> drop buffered data, read new one by reading twice. */
- libusb_interrupt_transfer(canusb->dev, 0x81, (unsigned char*)&status, sizeof(status), &sz, 100);
-
- for(i = 0; i<status.rxsz; i++)
- {
- libusb_bulk_transfer(canusb->dev, 0x85, (unsigned char*)&msg, sizeof(msg), &sz, 100);
- if(write(canusb->wrpipe, &msg, sizeof(msg)) < 0)
- fprintf(stderr,"write() error: %s\n", strerror(errno));
- }
-
- }
-
- return NULL;
-}
-
-static int canusb_startcapture(struct pcap_canusb* this)
-{
- int pipefd[2];
-
- if (pipe(pipefd) == -1)
- return -1;
-
- this->rdpipe = pipefd[0];
- this->wrpipe = pipefd[1];
-
- this->loop = 1;
- pthread_create(&this->worker, NULL, canusb_capture_thread, this);
-
- return this->rdpipe;
-}
-
-static void canusb_clearbufs(struct pcap_canusb* this)
-{
- unsigned char cmd[16];
- int al;
-
- cmd[0] = 1; /* Empty incoming buffer */
- cmd[1] = 1; /* Empty outgoing buffer */
- cmd[3] = 0; /* Not a write to serial number */
- memset(&cmd[4],0,16-4);
-
- libusb_interrupt_transfer(this->dev, 0x1,cmd,16,&al,100);
-}
-
-
-static void canusb_close(pcap_t* handle)
-{
- struct pcap_canusb *canusb = handle->priv;
-
- canusb->loop = 0;
- pthread_join(canusb->worker, NULL);
-
- if (canusb->dev)
- {
- libusb_close(canusb->dev);
- canusb->dev = NULL;
- }
- if (canusb->ctx)
- {
- libusb_exit(canusb->ctx);
- canusb->ctx = NULL;
- }
-}
-
-
-
-static int canusb_activate(pcap_t* handle)
-{
- struct pcap_canusb *canusb = handle->priv;
- char *serial;
-
- if (libusb_init(&canusb->ctx) != 0) {
- /*
- * XXX - what causes this to fail?
- */
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "libusb_init() failed");
- return PCAP_ERROR;
- }
-
- handle->read_op = canusb_read_linux;
-
- handle->inject_op = canusb_inject_linux;
- handle->setfilter_op = canusb_setfilter_linux;
- handle->setdirection_op = canusb_setdirection_linux;
- handle->getnonblock_op = pcap_getnonblock_fd;
- handle->setnonblock_op = pcap_setnonblock_fd;
- handle->stats_op = canusb_stats_linux;
- handle->cleanup_op = canusb_close;
-
- /* Initialize some components of the pcap structure. */
- handle->bufsize = 32;
- handle->offset = 8;
- handle->linktype = DLT_CAN_SOCKETCAN_HOSTENDIAN;
- handle->set_datalink_op = NULL;
-
- serial = handle->opt.device + strlen(CANUSB_IFACE);
-
- canusb->dev = canusb_opendevice(canusb->ctx, serial);
- if (!canusb->dev)
- {
- libusb_exit(canusb->ctx);
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't open USB Device");
- return PCAP_ERROR;
- }
-
- canusb_clearbufs(canusb);
-
- handle->fd = canusb_startcapture(canusb);
- handle->selectable_fd = handle->fd;
-
- return 0;
-}
-
-
-
-
-static int
-canusb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
-{
- static struct timeval firstpacket = { -1, -1};
- int i = 0;
- struct CAN_Msg msg;
- struct pcap_pkthdr pkth;
-
- while(i < max_packets)
- {
- int n;
- usleep(10 * 1000);
- n = read(handle->fd, &msg, sizeof(msg));
- if (n <= 0)
- break;
- pkth.caplen = pkth.len = n;
- pkth.caplen -= 4;
- pkth.caplen -= 8 - msg.length;
-
- if ((firstpacket.tv_sec == -1) && (firstpacket.tv_usec == -1))
- gettimeofday(&firstpacket, NULL);
-
- pkth.ts.tv_usec = firstpacket.tv_usec + (msg.timestamp % 100) * 10000;
- pkth.ts.tv_sec = firstpacket.tv_usec + (msg.timestamp / 100);
- if (pkth.ts.tv_usec > 1000000)
- {
- pkth.ts.tv_usec -= 1000000;
- pkth.ts.tv_sec++;
- }
-
- callback(user, &pkth, (void*)&msg.id);
- i++;
- }
-
- return i;
-}
-
-
-static int
-canusb_inject_linux(pcap_t *handle, const void *buf, size_t size)
-{
- /* not yet implemented */
- pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "inject not supported on canusb devices");
- return (-1);
-}
-
-
-static int
-canusb_stats_linux(pcap_t *handle, struct pcap_stat *stats)
-{
- /* not yet implemented */
- stats->ps_recv = 0; /* number of packets received */
- stats->ps_drop = 0; /* number of packets dropped */
- stats->ps_ifdrop = 0; /* drops by interface -- only supported on some platforms */
- return 0;
-}
-
-
-static int
-canusb_setfilter_linux(pcap_t *p, struct bpf_program *fp)
-{
- /* not yet implemented */
- return 0;
-}
-
-
-static int
-canusb_setdirection_linux(pcap_t *p, pcap_direction_t d)
-{
- /* no support for PCAP_D_OUT */
- if (d == PCAP_D_OUT)
- {
- pcap_snprintf(p->errbuf, sizeof(p->errbuf),
- "Setting direction to PCAP_D_OUT is not supported on this interface");
- return -1;
- }
-
- p->direction = d;
-
- return 0;
-}
-
-
-/* eof */
+++ /dev/null
-/*
- * Copyright (c) 2009 Felix Obenhuber
- * 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. 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
- * "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.
- *
- */
-
-/*
- * Prototypes for SocketCAN related functions
- */
-pcap_t* canusb_create(const char *device, char *ebuf, int *is_ours);
-int canusb_findalldevs(pcap_if_t **pdevlist, char* errbuf);
-
*
*/
-#define LINKTYPE_CAN_SOCKETCAN_BIGENDIAN 227
+#define LINKTYPE_CAN_SOCKETCAN 227
/*
* Raw IPv4/IPv6; different from DLT_RAW in that the DLT_ value specifies
*/
#define LINKTYPE_ISO_14443 264
-/*
- * CAN (Controller Area Network) frames, with a pseudo-header as supplied
- * by Linux SocketCAN, and with multi-byte numerical fields in that header
- * in host byte order.
- *
- * See Documentation/networking/can.txt in the Linux source.
- */
-#define LINKTYPE_CAN_SOCKETCAN_HOSTENDIAN 265
-
-#define LINKTYPE_MATCHING_MAX 265 /* highest value in the "matching" range */
+#define LINKTYPE_MATCHING_MAX 264 /* highest value in the "matching" range */
static struct linktype_map {
int dlt;
#define EXTRACT_
/*
- * DLT_LINUX_SLL packets with a protocol type of LINUX_SLL_P_CAN have
- * SocketCAN headers in front of the payload, with the CAN ID being
- * in host byte order.
+ * DLT_LINUX_SLL packets with a protocol type of LINUX_SLL_P_CAN or
+ * LINUX_SLL_P_CANFD have SocketCAN headers in front of the payload,
+ * with the CAN ID being in host byte order.
*
* When reading a DLT_LINUX_SLL capture file, we need to check for those
* packets and convert the CAN ID from the byte order of the host that
}
protocol = EXTRACT_16BITS(&shdr->sll_protocol);
- if (protocol != LINUX_SLL_P_CAN)
+ if (protocol != LINUX_SLL_P_CAN && protocol != LINUX_SLL_P_CANFD)
return;
/*
}
}
-/*
- * The CAN ID in the DLT_CAN_SOCKETCAN_HOSTENDIAN header is in host byte
- * order when capturing (the header is filled in by the kernel and provided
- * on a PF_PACKET socket).
- *
- * When reading a DLT_CAN_SOCKETCAN_HOSTENDIAN capture file, we need to
- * convert it from the byte order of the host that wrote the file to
- * this host's byte order.
- */
-static void
-swap_can_socketcan_header(const struct pcap_pkthdr *hdr, u_char *buf)
-{
- u_int caplen = hdr->caplen;
- u_int length = hdr->len;
- pcap_can_socketcan_hdr *chdr = (pcap_can_socketcan_hdr *)buf;
-
- if (caplen < (u_int) sizeof(chdr->can_id) ||
- length < (u_int) sizeof(chdr->can_id)) {
- /* Not enough data to have the CAN ID */
- return;
- }
-
- chdr->can_id = SWAPLONG(chdr->can_id);
-}
-
void
swap_pseudo_headers(int linktype, struct pcap_pkthdr *hdr, u_char *data)
{
case DLT_NFLOG:
swap_nflog_header(hdr, data);
break;
-
- case DLT_CAN_SOCKETCAN_HOSTENDIAN:
- swap_can_socketcan_header(hdr, data);
- break;
}
}
#endif
case ARPHRD_CAN:
/*
- * DLT_CAN_SOCKETCAN_BIGENDIAN is defined to have the
- * can_id field of the pseudo-header in big-endian
- * (network) byte order.
- *
- * The packets delivered to sockets have that field
- * in host byte order.
- *
- * The code that implements it in packet-can-linux.c
- * passes that field to htonl() to put it into network
- * byte order.
- *
- * The code that reads from a PF_PACKET socket doesn't
- * change the byte order of that field, so we define
- * a new DLT_CAN_SOCKETCAN_HOSTENDIAN, where the can_id
- * is in host byte order.
+ * Map this to DLT_LINUX_SLL; that way, CAN frames will
+ * have ETH_P_CAN/LINUX_SLL_P_CAN as the protocol and
+ * CAN FD frames will have ETH_P_CANFD/LINUX_SLL_P_CANFD
+ * as the protocol, so they can be distinguished by the
+ * protocol in the SLL header.
*/
- handle->linktype = DLT_CAN_SOCKETCAN_HOSTENDIAN;
+ handle->linktype = DLT_LINUX_SLL;
break;
#ifndef ARPHRD_IEEE802_TR
#include "pcap-bt-monitor-linux.h"
#endif
-#ifdef PCAP_SUPPORT_CAN
-#include "pcap-can-linux.h"
-#endif
-
-#ifdef PCAP_SUPPORT_CANUSB
-#include "pcap-canusb-linux.h"
-#endif
-
#ifdef PCAP_SUPPORT_NETFILTER
#include "pcap-netfilter-linux.h"
#endif
#ifdef PCAP_SUPPORT_BT_MONITOR
{ bt_monitor_findalldevs, bt_monitor_create },
#endif
-#if PCAP_SUPPORT_CANUSB
- { canusb_findalldevs, canusb_create },
-#endif
-#ifdef PCAP_SUPPORT_CAN
- { can_findalldevs, can_create },
-#endif
#ifdef PCAP_SUPPORT_USB
{ usb_findalldevs, usb_create },
#endif
DLT_CHOICE(DLT_FC_2, "Fibre Channel FC-2"),
DLT_CHOICE(DLT_FC_2_WITH_FRAME_DELIMS, "Fibre Channel FC-2 with frame delimiters"),
DLT_CHOICE(DLT_IPNET, "Solaris ipnet"),
- DLT_CHOICE(DLT_CAN_SOCKETCAN_BIGENDIAN, "CAN-bus with big-endian CAN ID"),
+ DLT_CHOICE(DLT_CAN_SOCKETCAN, "CAN-bus with SocketCAN headers"),
DLT_CHOICE(DLT_IPV4, "Raw IPv4"),
DLT_CHOICE(DLT_IPV6, "Raw IPv6"),
DLT_CHOICE(DLT_IEEE802_15_4_NOFCS, "IEEE 802.15.4 without FCS"),
DLT_CHOICE(DLT_PROFIBUS_DL, "PROFIBUS data link layer"),
DLT_CHOICE(DLT_PKTAP, "Apple DLT_PKTAP"),
DLT_CHOICE(DLT_EPON, "Ethernet with 802.3 Clause 65 EPON preamble"),
- DLT_CHOICE(DLT_CAN_SOCKETCAN_HOSTENDIAN, "CAN-bus with host-endian CAN ID"),
DLT_CHOICE_SENTINEL
};
*
*/
-#define DLT_CAN_SOCKETCAN_BIGENDIAN 227
#define DLT_CAN_SOCKETCAN 227
/*
*/
#define DLT_ISO_14443 264
-/*
- * CAN (Controller Area Network) frames, with a pseudo-header as supplied
- * by Linux SocketCAN, and with multi-byte numerical fields in that header
- * in host byte order.
- *
- * See Documentation/networking/can.txt in the Linux source.
- */
-#define DLT_CAN_SOCKETCAN_HOSTENDIAN 265
-
/*
* In case the code that includes this file (directly or indirectly)
* has also included OS files that happen to define DLT_MATCHING_MAX,
#ifdef DLT_MATCHING_MAX
#undef DLT_MATCHING_MAX
#endif
-#define DLT_MATCHING_MAX 265 /* highest value in the "matching" range */
+#define DLT_MATCHING_MAX 264 /* highest value in the "matching" range */
/*
* DLT and savefile link type values are split into a class and
#define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */
#define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */
#define LINUX_SLL_P_CAN 0x000C /* CAN frames, with SocketCAN pseudo-headers */
+#define LINUX_SLL_P_CANFD 0x000D /* CAN FD frames, with SocketCAN pseudo-headers */
#endif