Add support for CANbus capture.
Signed-off-by: Guy Harris <guy@alum.mit.edu>
This commit is contained in:
parent
d32a10c10d
commit
1c1816f670
1
CREDITS
1
CREDITS
|
@ -35,6 +35,7 @@ Additional people who have contributed patches:
|
|||
Dustin Spicuzza <dustin at virtualroadside dot com>
|
||||
Eric Anderson <anderse at hpl dot hp dot com>
|
||||
Erik de Castro Lopo <erik dot de dot castro dot lopo at sensorynetworks dot com>
|
||||
Felix Obenhuber <felix at obenhuber dot de>
|
||||
Florent Drouin <Florent dot Drouin at alcatel-lucent dot fr>
|
||||
Franz Schaefer <schaefer at mond dot at>
|
||||
Fulko Hew <fulko dot hew at gmail dot com>
|
||||
|
|
|
@ -80,7 +80,7 @@ YACC = @V_YACC@
|
|||
@rm -f $@
|
||||
$(CC) $(CFLAGS) -c $(srcdir)/$*.c
|
||||
|
||||
PSRC = pcap-@V_PCAP@.c @USB_SRC@ @BT_SRC@
|
||||
PSRC = pcap-@V_PCAP@.c @USB_SRC@ @BT_SRC@ @CAN_SRC@
|
||||
FSRC = fad-@V_FINDALLDEVS@.c
|
||||
SSRC = @SSRC@
|
||||
CSRC = pcap.c inet.c gencode.c optimize.c nametoaddr.c \
|
||||
|
@ -264,6 +264,8 @@ EXTRA_DIST = \
|
|||
pcap-bpf.c \
|
||||
pcap-bt-linux.c \
|
||||
pcap-bt-linux.h \
|
||||
pcap-can-linux.c \
|
||||
pcap-can-linux.h \
|
||||
pcap-config.in \
|
||||
pcap-dag.c \
|
||||
pcap-dag.h \
|
||||
|
|
|
@ -214,6 +214,9 @@
|
|||
/* target host supports Bluetooth sniffing */
|
||||
#undef PCAP_SUPPORT_BT
|
||||
|
||||
/* target host supports CAN sniffing */
|
||||
#undef PCAP_SUPPORT_CAN
|
||||
|
||||
/* target host supports USB sniffing */
|
||||
#undef PCAP_SUPPORT_USB
|
||||
|
||||
|
|
|
@ -698,6 +698,8 @@ PCAP_SUPPORT_USB
|
|||
USB_SRC
|
||||
PCAP_SUPPORT_BT
|
||||
BT_SRC
|
||||
PCAP_SUPPORT_CAN
|
||||
CAN_SRC
|
||||
INSTALL_PROGRAM
|
||||
INSTALL_SCRIPT
|
||||
INSTALL_DATA
|
||||
|
@ -1293,6 +1295,8 @@ Optional Features:
|
|||
--enable-yydebug build parser debugging code
|
||||
--enable-bluetooth enable bluetooth support [default=yes, if support
|
||||
available]
|
||||
--enable-can enable can support [default=yes, if support
|
||||
available]
|
||||
|
||||
Optional Packages:
|
||||
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
|
||||
|
@ -3926,7 +3930,7 @@ if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
|
|||
else
|
||||
ac_cv_header_stdc=no
|
||||
fi
|
||||
rm -f conftest*
|
||||
rm -f -r conftest*
|
||||
|
||||
fi
|
||||
|
||||
|
@ -3947,7 +3951,7 @@ if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
|
|||
else
|
||||
ac_cv_header_stdc=no
|
||||
fi
|
||||
rm -f conftest*
|
||||
rm -f -r conftest*
|
||||
|
||||
fi
|
||||
|
||||
|
@ -5007,7 +5011,7 @@ cat >>confdefs.h <<_ACEOF
|
|||
_ACEOF
|
||||
;;
|
||||
esac
|
||||
rm -f conftest*
|
||||
rm -f -r 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; }
|
||||
|
@ -5128,7 +5132,7 @@ cat >>confdefs.h <<_ACEOF
|
|||
_ACEOF
|
||||
;;
|
||||
esac
|
||||
rm -f conftest*
|
||||
rm -f -r conftest*
|
||||
fi
|
||||
fi
|
||||
|
||||
|
@ -5239,7 +5243,7 @@ cat >>confdefs.h <<_ACEOF
|
|||
_ACEOF
|
||||
;;
|
||||
esac
|
||||
rm -f conftest*
|
||||
rm -f -r 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.
|
||||
|
@ -10337,6 +10341,167 @@ echo "$as_me: no Bluetooth sniffing support" >&6;}
|
|||
esac
|
||||
|
||||
|
||||
fi
|
||||
|
||||
# Check whether --enable-can was given.
|
||||
if test "${enable_can+set}" = set; then
|
||||
enableval=$enable_can;
|
||||
else
|
||||
enable_can=yes
|
||||
fi
|
||||
|
||||
|
||||
if test "x$enable_can" != "xno" ; then
|
||||
case "$host_os" in
|
||||
linux*)
|
||||
if test "${ac_cv_header_linux_can_version_h+set}" = set; then
|
||||
{ echo "$as_me:$LINENO: checking for linux/can/version.h" >&5
|
||||
echo $ECHO_N "checking for linux/can/version.h... $ECHO_C" >&6; }
|
||||
if test "${ac_cv_header_linux_can_version_h+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
fi
|
||||
{ echo "$as_me:$LINENO: result: $ac_cv_header_linux_can_version_h" >&5
|
||||
echo "${ECHO_T}$ac_cv_header_linux_can_version_h" >&6; }
|
||||
else
|
||||
# Is the header compilable?
|
||||
{ echo "$as_me:$LINENO: checking linux/can/version.h usability" >&5
|
||||
echo $ECHO_N "checking linux/can/version.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 <linux/can/version.h>
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext
|
||||
if { (ac_try="$ac_compile"
|
||||
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_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); } && {
|
||||
test -z "$ac_c_werror_flag" ||
|
||||
test ! -s conftest.err
|
||||
} && test -s conftest.$ac_objext; 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 core 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 linux/can/version.h presence" >&5
|
||||
echo $ECHO_N "checking linux/can/version.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 <linux/can/version.h>
|
||||
_ACEOF
|
||||
if { (ac_try="$ac_cpp conftest.$ac_ext"
|
||||
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_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 && {
|
||||
test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
|
||||
test ! -s conftest.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: linux/can/version.h: accepted by the compiler, rejected by the preprocessor!" >&5
|
||||
echo "$as_me: WARNING: linux/can/version.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
|
||||
{ echo "$as_me:$LINENO: WARNING: linux/can/version.h: proceeding with the compiler's result" >&5
|
||||
echo "$as_me: WARNING: linux/can/version.h: proceeding with the compiler's result" >&2;}
|
||||
ac_header_preproc=yes
|
||||
;;
|
||||
no:yes:* )
|
||||
{ echo "$as_me:$LINENO: WARNING: linux/can/version.h: present but cannot be compiled" >&5
|
||||
echo "$as_me: WARNING: linux/can/version.h: present but cannot be compiled" >&2;}
|
||||
{ echo "$as_me:$LINENO: WARNING: linux/can/version.h: check for missing prerequisite headers?" >&5
|
||||
echo "$as_me: WARNING: linux/can/version.h: check for missing prerequisite headers?" >&2;}
|
||||
{ echo "$as_me:$LINENO: WARNING: linux/can/version.h: see the Autoconf documentation" >&5
|
||||
echo "$as_me: WARNING: linux/can/version.h: see the Autoconf documentation" >&2;}
|
||||
{ echo "$as_me:$LINENO: WARNING: linux/can/version.h: section \"Present But Cannot Be Compiled\"" >&5
|
||||
echo "$as_me: WARNING: linux/can/version.h: section \"Present But Cannot Be Compiled\"" >&2;}
|
||||
{ echo "$as_me:$LINENO: WARNING: linux/can/version.h: proceeding with the preprocessor's result" >&5
|
||||
echo "$as_me: WARNING: linux/can/version.h: proceeding with the preprocessor's result" >&2;}
|
||||
{ echo "$as_me:$LINENO: WARNING: linux/can/version.h: in the future, the compiler will take precedence" >&5
|
||||
echo "$as_me: WARNING: linux/can/version.h: in the future, the compiler will take precedence" >&2;}
|
||||
|
||||
;;
|
||||
esac
|
||||
{ echo "$as_me:$LINENO: checking for linux/can/version.h" >&5
|
||||
echo $ECHO_N "checking for linux/can/version.h... $ECHO_C" >&6; }
|
||||
if test "${ac_cv_header_linux_can_version_h+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
ac_cv_header_linux_can_version_h=$ac_header_preproc
|
||||
fi
|
||||
{ echo "$as_me:$LINENO: result: $ac_cv_header_linux_can_version_h" >&5
|
||||
echo "${ECHO_T}$ac_cv_header_linux_can_version_h" >&6; }
|
||||
|
||||
fi
|
||||
if test $ac_cv_header_linux_can_version_h = yes; then
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define PCAP_SUPPORT_CAN 1
|
||||
_ACEOF
|
||||
|
||||
CAN_SRC=pcap-can-linux.c
|
||||
{ echo "$as_me:$LINENO: CAN sniffing is supported" >&5
|
||||
echo "$as_me: CAN sniffing is supported" >&6;}
|
||||
else
|
||||
{ echo "$as_me:$LINENO: CAN sniffing is not supported" >&5
|
||||
echo "$as_me: CAN sniffing is not supported" >&6;}
|
||||
fi
|
||||
|
||||
|
||||
;;
|
||||
*)
|
||||
{ echo "$as_me:$LINENO: no CAN sniffing support implemented for $host_os" >&5
|
||||
echo "$as_me: no CAN sniffing support implemented for $host_os" >&6;}
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
fi
|
||||
|
||||
# Find a good install program. We prefer a C program (faster),
|
||||
|
@ -11135,13 +11300,15 @@ PCAP_SUPPORT_USB!$PCAP_SUPPORT_USB$ac_delim
|
|||
USB_SRC!$USB_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
|
||||
CAN_SRC!$CAN_SRC$ac_delim
|
||||
INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim
|
||||
INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim
|
||||
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` = 88; then
|
||||
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 90; then
|
||||
break
|
||||
elif $ac_last_try; then
|
||||
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
|
||||
|
|
22
configure.in
22
configure.in
|
@ -1283,6 +1283,28 @@ if test "x$enable_bluetooth" != "xno" ; then
|
|||
AC_SUBST(BT_SRC)
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE([can],
|
||||
[AC_HELP_STRING([--enable-can],[enable can support @<:@default=yes, if support available@:>@])],
|
||||
,enable_can=yes)
|
||||
|
||||
if test "x$enable_can" != "xno" ; then
|
||||
dnl check for CAN sniffing support
|
||||
case "$host_os" in
|
||||
linux*)
|
||||
AC_CHECK_HEADER(linux/can/version.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)],
|
||||
AC_MSG_NOTICE(CAN sniffing is not supported) )
|
||||
;;
|
||||
*)
|
||||
AC_MSG_NOTICE(no CAN sniffing support implemented for $host_os)
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(PCAP_SUPPORT_CAN)
|
||||
AC_SUBST(CAN_SRC)
|
||||
fi
|
||||
|
||||
AC_PROG_INSTALL
|
||||
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
|
|
|
@ -0,0 +1,265 @@
|
|||
/*
|
||||
* 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
|
||||
* By Felix Obenhuber <felix@obenhuber.de>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "pcap-int.h"
|
||||
#include "pcap-can-linux.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 <net/if.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 *);
|
||||
|
||||
pcap_t *
|
||||
can_create(const char *device, char *ebuf)
|
||||
{
|
||||
pcap_t* p;
|
||||
|
||||
p = pcap_create_common(device, ebuf);
|
||||
if (p == NULL)
|
||||
return (NULL);
|
||||
|
||||
p->activate_op = can_activate;
|
||||
return (p);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
can_activate(pcap_t* handle)
|
||||
{
|
||||
int err = PCAP_ERROR;
|
||||
struct sockaddr_can addr;
|
||||
struct ifreq ifr;
|
||||
|
||||
/* Initialize some components of the pcap structure. */
|
||||
handle->bufsize = 24;
|
||||
handle->offset = 8;
|
||||
handle->linktype = DLT_CAN_SOCKETCAN;
|
||||
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)
|
||||
{
|
||||
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));
|
||||
strncpy(ifr.ifr_name, handle->opt.source, sizeof(ifr.ifr_name));
|
||||
if ((handle->fd, SIOCGIFINDEX, &ifr) < 0)
|
||||
{
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Unable to get interface index: %s",
|
||||
pcap_strerror(errno));
|
||||
pcap_cleanup_live_common(handle);
|
||||
return PCAP_ERROR;
|
||||
}
|
||||
handle->md.ifindex = ifr.ifr_ifindex;
|
||||
|
||||
/* allocate butter */
|
||||
handle->buffer = malloc(handle->bufsize);
|
||||
if (!handle->buffer)
|
||||
{
|
||||
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 = handle->md.ifindex;
|
||||
if( bind( handle->fd, (struct sockaddr*)&addr, sizeof(addr) ) < 0 )
|
||||
{
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't attach to device %d %d:%s",
|
||||
handle->md.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;
|
||||
}
|
||||
|
||||
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;
|
||||
struct timeval tv;
|
||||
struct iovec iv;
|
||||
struct can_frame* cf;
|
||||
|
||||
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;
|
||||
|
||||
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",
|
||||
errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* adjust capture len according to frame len */
|
||||
cf = (struct can_frame*)&handle->buffer[8];
|
||||
pkth.caplen -= 8 - cf->can_dlc;
|
||||
pkth.len = pkth.caplen;
|
||||
|
||||
cf->can_id = htonl( cf->can_id );
|
||||
|
||||
if( -1 == gettimeofday(&pkth.ts, NULL) )
|
||||
{
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't get time of day %d:%s",
|
||||
errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
callback(user, &pkth, &handle->buffer[8]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
can_inject_linux(pcap_t *handle, const void *buf, size_t size)
|
||||
{
|
||||
/* not yet implemented */
|
||||
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)
|
||||
{
|
||||
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 */
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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);
|
16
pcap-linux.c
16
pcap-linux.c
|
@ -176,6 +176,10 @@ static const char rcsid[] _U_ =
|
|||
#include "pcap-bt-linux.h"
|
||||
#endif
|
||||
|
||||
#ifdef PCAP_SUPPORT_CAN
|
||||
#include "pcap-can-linux.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If PF_PACKET is defined, we can use {SOCK_RAW,SOCK_DGRAM}/PF_PACKET
|
||||
* sockets rather than SOCK_PACKET sockets.
|
||||
|
@ -376,6 +380,12 @@ pcap_create(const char *device, char *ebuf)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef PCAP_SUPPORT_CAN
|
||||
if (strstr(device, "can") || strstr(device, "vcan")) {
|
||||
return can_create(device, ebuf);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PCAP_SUPPORT_USB
|
||||
if (strstr(device, "usbmon")) {
|
||||
return usb_create(device, ebuf);
|
||||
|
@ -2073,6 +2083,12 @@ static void map_arphrd_to_dlt(pcap_t *handle, int arptype, int cooked_ok)
|
|||
case ARPHRD_CHAOS:
|
||||
handle->linktype = DLT_CHAOS;
|
||||
break;
|
||||
#ifndef ARPHRD_CAN
|
||||
#define ARPHRD_CAN 280
|
||||
#endif
|
||||
case ARPHRD_CAN:
|
||||
handle->linktype = DLT_CAN_SOCKETCAN;
|
||||
break;
|
||||
|
||||
#ifndef ARPHRD_IEEE802_TR
|
||||
#define ARPHRD_IEEE802_TR 800 /* From Linux 2.4 */
|
||||
|
|
Reference in New Issue