dect
/
libpcap
Archived
13
0
Fork 0

Add support for CANbus capture.

Signed-off-by: Guy Harris <guy@alum.mit.edu>
This commit is contained in:
Felix Obenhuber 2009-12-29 01:04:20 -08:00 committed by Guy Harris
parent d32a10c10d
commit 1c1816f670
8 changed files with 518 additions and 7 deletions

View File

@ -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>

View File

@ -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 \

View File

@ -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

179
configure vendored
View File

@ -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

View File

@ -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)

265
pcap-can-linux.c Normal file
View File

@ -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 */

35
pcap-can-linux.h Normal file
View File

@ -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);

View File

@ -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 */