1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-11-26 07:55:01 +00:00

MFV: libpcap 1.3.0.

MFC after:	4 weeks
This commit is contained in:
Xin LI 2012-10-05 18:42:50 +00:00
commit 15752fa858
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=241231
27 changed files with 3988 additions and 6954 deletions

View File

@ -1,3 +1,22 @@
Friday March 30, 2012. mcr@sandelman.ca
Summary for 1.3.0 libpcap release
Handle DLT_PFSYNC in {FreeBSD, other *BSD+Mac OS X, other}.
Linux: Don't fail if netfilter isn't enabled in the kernel.
Add new link-layer type for NFC Forum LLCP.
Put the CANUSB stuff into EXTRA_DIST, so it shows up in the release tarball.
Add LINKTYPE_NG40/DLT_NG40.
Add DLT_MPEG_2_TS/LINKTYPE_MPEG_2_TS for MPEG-2 transport streams.
[PATCH] Fix AIX-3.5 crash with read failure during stress
AIX fixes.
Introduce --disable-shared configure option.
Added initial support for canusb devices.
Include the pcap(3PCAP) additions as 1.2.1 changes.
many updates to documentation: pcap.3pcap.in
Improve 'inbound'/'outbound' capture filters under Linux.
Note the cleanup of handling of new DLT_/LINKTYPE_ values.
On Lion, don't build for PPC.
For mac80211 devices we need to clean up monitor mode on exit.
Friday December 9, 2011. guy@alum.mit.edu.
Summary for 1.2.1 libpcap release
Update README file.

View File

@ -34,6 +34,7 @@ Additional people who have contributed patches:
David Kaelbling <drk at sgi dot com>
David Young <dyoung at ojctech dot com>
Dean Gaudet <dean at arctic dot org>
dhruv <rsrivat at sourceforge dot net>
Don Ebright <Don dot Ebright at compuware dot com>
Dug Song <dugsong at monkey dot org>
Dustin Spicuzza <dustin at virtualroadside dot com>

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@ @NETFILTER_SRC@
PSRC = pcap-@V_PCAP@.c @USB_SRC@ @BT_SRC@ @CAN_SRC@ @NETFILTER_SRC@ @CANUSB_SRC@
FSRC = fad-@V_FINDALLDEVS@.c
SSRC = @SSRC@
CSRC = pcap.c inet.c gencode.c optimize.c nametoaddr.c etherent.c \
@ -289,6 +289,8 @@ EXTRA_DIST = \
pcap-bt-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 \

View File

@ -1 +1 @@
1.2.1
1.3.0

View File

@ -232,6 +232,9 @@
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION
@ -244,6 +247,9 @@
/* target host supports CAN sniffing */
#undef PCAP_SUPPORT_CAN
/* target host supports canusb */
#undef PCAP_SUPPORT_CANUSB
/* target host supports netfilter sniffing */
#undef PCAP_SUPPORT_NETFILTER

File diff suppressed because it is too large Load Diff

View File

@ -1224,6 +1224,10 @@ solaris*)
;;
esac
AC_ARG_ENABLE(shared,
AC_HELP_STRING([--enable-shared],[build shared libraries @<:@default=yes, if support available@:>@]))
test "x$enable_shared" = "xno" && DYEXT="none"
AC_PROG_RANLIB
AC_CHECK_TOOL([AR], [ar])
@ -1390,6 +1394,32 @@ if test "x$enable_bluetooth" != "xno" ; then
AC_SUBST(BT_SRC)
fi
AC_ARG_ENABLE([canusb],
[AC_HELP_STRING([--enable-canusb],[enable canusb support @<:@default=yes, if support available@:>@])]
,enable_canusb=yes)
if test "x$enable_canusb" != "xno" ; then
dnl check for canusb support
case "$host_os" in
linux*)
AC_CHECK_HEADER(libusb-1.0/libusb.h,
[
AC_DEFINE(PCAP_SUPPORT_CANUSB, 1, [target host supports canusb])
CANUSB_SRC=pcap-canusb-linux.c
LIBS="-lusb-1.0 $LIBS"
AC_MSG_NOTICE(canusb sniffing is supported)
],
AC_MSG_NOTICE(canusb sniffing is not supported; install libusb1.0 lib devel to enable it)
)
;;
*)
AC_MSG_NOTICE(no canusb support implemented for $host_os)
;;
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=yes)

View File

@ -86,6 +86,11 @@ static const char rcsid[] _U_ =
#include "pcap/sll.h"
#include "pcap/ipnet.h"
#include "arcnet.h"
#if defined(PF_PACKET) && defined(SO_ATTACH_FILTER)
#include <linux/types.h>
#include <linux/if_packet.h>
#include <linux/filter.h>
#endif
#ifdef HAVE_NET_PFVAR_H
#include <sys/socket.h>
#include <net/if.h>
@ -420,7 +425,7 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
{
extern int n_errors;
const char * volatile xbuf = buf;
int len;
u_int len;
no_optimize = 0;
n_errors = 0;
@ -1395,14 +1400,12 @@ init_linktype(p)
off_nl_nosnap = -1;
return;
#ifdef DLT_PFSYNC
case DLT_PFSYNC:
off_linktype = -1;
off_macpl = 4;
off_nl = 0;
off_nl_nosnap = 0;
return;
#endif
case DLT_AX25_KISS:
/*
@ -3358,10 +3361,8 @@ gen_linktype(proto)
case DLT_ERF:
bpf_error("ERF link-layer type filtering not implemented");
#ifdef DLT_PFSYNC
case DLT_PFSYNC:
bpf_error("PFSYNC link-layer type filtering not implemented");
#endif
case DLT_LINUX_LAPD:
bpf_error("LAPD link-layer type filtering not implemented");
@ -5821,6 +5822,11 @@ gen_proto(v, proto, dir)
int dir;
{
struct block *b0, *b1;
#ifdef INET6
#ifndef CHASE_CHAIN
struct block *b2;
#endif
#endif
if (dir != Q_DEFAULT)
bpf_error("direction applied to 'proto'");
@ -5989,7 +5995,15 @@ gen_proto(v, proto, dir)
case Q_IPV6:
b0 = gen_linktype(ETHERTYPE_IPV6);
#ifndef CHASE_CHAIN
b1 = gen_cmp(OR_NET, 6, BPF_B, (bpf_int32)v);
/*
* Also check for a fragment header before the final
* header.
*/
b2 = gen_cmp(OR_NET, 6, BPF_B, IPPROTO_FRAGMENT);
b1 = gen_cmp(OR_NET, 40, BPF_B, (bpf_int32)v);
gen_and(b2, b1);
b2 = gen_cmp(OR_NET, 6, BPF_B, (bpf_int32)v);
gen_or(b2, b1);
#else
b1 = gen_protochain(v, Q_IPV6);
#endif
@ -7470,9 +7484,13 @@ gen_multicast(proto)
}
/*
* generate command for inbound/outbound. It's here so we can
* make it link-type specific. 'dir' = 0 implies "inbound",
* = 1 implies "outbound".
* Filter on inbound (dir == 0) or outbound (dir == 1) traffic.
* Outbound traffic is sent by this machine, while inbound traffic is
* sent by a remote machine (and may include packets destined for a
* unicast or multicast link-layer address we are not subscribing to).
* These are the same definitions implemented by pcap_setdirection().
* Capturing only unicast traffic destined for this host is probably
* better accomplished using a higher-layer filter.
*/
struct block *
gen_inbound(dir)
@ -7502,23 +7520,11 @@ gen_inbound(dir)
break;
case DLT_LINUX_SLL:
if (dir) {
/*
* Match packets sent by this machine.
*/
b0 = gen_cmp(OR_LINK, 0, BPF_H, LINUX_SLL_OUTGOING);
} else {
/*
* Match packets sent to this machine.
* (No broadcast or multicast packets, or
* packets sent to some other machine and
* received promiscuously.)
*
* XXX - packets sent to other machines probably
* shouldn't be matched, but what about broadcast
* or multicast packets we received?
*/
b0 = gen_cmp(OR_LINK, 0, BPF_H, LINUX_SLL_HOST);
/* match outgoing packets */
b0 = gen_cmp(OR_LINK, 0, BPF_H, LINUX_SLL_OUTGOING);
if (!dir) {
/* to filter on inbound traffic, invert the match */
gen_not(b0);
}
break;
@ -7574,10 +7580,38 @@ gen_inbound(dir)
break;
default:
/*
* If we have packet meta-data indicating a direction,
* check it, otherwise give up as this link-layer type
* has nothing in the packet data.
*/
#if defined(PF_PACKET) && defined(SO_ATTACH_FILTER)
/*
* We infer that this is Linux with PF_PACKET support.
* If this is a *live* capture, we can look at
* special meta-data in the filter expression;
* if it's a savefile, we can't.
*/
if (bpf_pcap->sf.rfile != NULL) {
/* We have a FILE *, so this is a savefile */
bpf_error("inbound/outbound not supported on linktype %d when reading savefiles",
linktype);
b0 = NULL;
/* NOTREACHED */
}
/* match outgoing packets */
b0 = gen_cmp(OR_LINK, SKF_AD_OFF + SKF_AD_PKTTYPE, BPF_H,
PACKET_OUTGOING);
if (!dir) {
/* to filter on inbound traffic, invert the match */
gen_not(b0);
}
#else /* defined(PF_PACKET) && defined(SO_ATTACH_FILTER) */
bpf_error("inbound/outbound not supported on linktype %d",
linktype);
b0 = NULL;
/* NOTREACHED */
#endif /* defined(PF_PACKET) && defined(SO_ATTACH_FILTER) */
}
return (b0);
}

View File

@ -240,8 +240,8 @@ struct block {
struct slist *stmts; /* side effect stmts */
struct stmt s; /* branch stmt */
int mark;
int longjt; /* jt branch requires long jump */
int longjf; /* jf branch requires long jump */
u_int longjt; /* jt branch requires long jump */
u_int longjf; /* jf branch requires long jump */
int level;
int offset;
int sense;
@ -330,7 +330,7 @@ void bpf_error(const char *, ...)
void finish_parse(struct block *);
char *sdup(const char *);
struct bpf_insn *icode_to_fcode(struct block *, int *);
struct bpf_insn *icode_to_fcode(struct block *, u_int *);
int pcap_parse(void);
void lex_init(const char *);
void lex_cleanup(void);

View File

@ -152,10 +152,10 @@ static void deadstmt(struct stmt *, struct stmt *[]);
static void opt_deadstores(struct block *);
static struct block *fold_edge(struct block *, struct edge *);
static inline int eq_blk(struct block *, struct block *);
static int slength(struct slist *);
static u_int slength(struct slist *);
static int count_blocks(struct block *);
static void number_blks_r(struct block *);
static int count_stmts(struct block *);
static u_int count_stmts(struct block *);
static int convert_code_r(struct block *);
#ifdef BDEBUG
static void opt_dump(struct block *);
@ -1904,11 +1904,11 @@ opt_cleanup()
/*
* Return the number of stmts in 's'.
*/
static int
static u_int
slength(s)
struct slist *s;
{
int n = 0;
u_int n = 0;
for (; s; s = s->next)
if (s->s.code != NOP)
@ -1970,11 +1970,11 @@ number_blks_r(p)
*
* an extra long jump if the false branch requires it (p->longjf).
*/
static int
static u_int
count_stmts(p)
struct block *p;
{
int n;
u_int n;
if (p == 0 || isMarked(p))
return 0;
@ -2263,9 +2263,9 @@ convert_code_r(p)
struct bpf_insn *
icode_to_fcode(root, lenp)
struct block *root;
int *lenp;
u_int *lenp;
{
int n;
u_int n;
struct bpf_insn *fp;
/*

View File

@ -66,8 +66,10 @@ rm -rf $RPM_BUILD_ROOT
%files devel
%defattr(-,root,root)
%{_bindir}/pcap-config
%{_includedir}/pcap*.h
%{_includedir}/pcap/*.h
%{_includedir}/pcap.h
%{_includedir}/pcap-bpf.h
%{_includedir}/pcap-namedb.h
%{_libdir}/libpcap.so
%{_libdir}/libpcap.a
%{_mandir}/man1/pcap-config.1*

View File

@ -157,6 +157,10 @@ static void remove_802_11(pcap_t *);
#endif /* BIOCGDLTLIST */
#if defined(sun) && defined(LIFNAMSIZ) && defined(lifr_zoneid)
#include <zone.h>
#endif
/*
* We include the OS's <net/bpf.h>, not our "pcap/bpf.h", so we probably
* don't get DLT_DOCSIS defined.
@ -1454,8 +1458,16 @@ check_setif_failure(pcap_t *p, int error)
* Default capture buffer size.
* 32K isn't very much for modern machines with fast networks; we
* pick .5M, as that's the maximum on at least some systems with BPF.
*
* However, on AIX 3.5, the larger buffer sized caused unrecoverable
* read failures under stress, so we leave it as 32K; yet another
* place where AIX's BPF is broken.
*/
#ifdef _AIX
#define DEFAULT_BUFSIZE 32768
#else
#define DEFAULT_BUFSIZE 524288
#endif
static int
pcap_activate_bpf(pcap_t *p)
@ -1463,6 +1475,7 @@ pcap_activate_bpf(pcap_t *p)
int status = 0;
int fd;
#ifdef LIFNAMSIZ
char *zonesep;
struct lifreq ifr;
char *ifrname = ifr.lifr_name;
const size_t ifnamsiz = sizeof(ifr.lifr_name);
@ -1526,6 +1539,29 @@ pcap_activate_bpf(pcap_t *p)
goto bad;
}
#if defined(LIFNAMSIZ) && defined(ZONENAME_MAX) && defined(lifr_zoneid)
/*
* Check if the given source network device has a '/' separated
* zonename prefix string. The zonename prefixed source device
* can be used by libpcap consumers to capture network traffic
* in non-global zones from the global zone on Solaris 11 and
* above. If the zonename prefix is present then we strip the
* prefix and pass the zone ID as part of lifr_zoneid.
*/
if ((zonesep = strchr(p->opt.source, '/')) != NULL) {
char zonename[ZONENAME_MAX];
int znamelen;
char *lnamep;
znamelen = zonesep - p->opt.source;
(void) strlcpy(zonename, p->opt.source, znamelen + 1);
lnamep = strdup(zonesep + 1);
ifr.lifr_zoneid = getzoneidbyname(zonename);
free(p->opt.source);
p->opt.source = lnamep;
}
#endif
p->md.device = strdup(p->opt.source);
if (p->md.device == NULL) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "strdup: %s",

View File

@ -0,0 +1,428 @@
/*
* 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
* By Felix Obenhuber <felix@obenhuber.de>
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <libusb-1.0/libusb.h>
#include "pcap-int.h"
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.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];
};
struct canusb_t
{
libusb_context *ctx;
libusb_device_handle *dev;
char* src;
pthread_t worker;
int rdpipe, wrpipe;
volatile int* loop;
};
static struct canusb_t canusb;
static volatile int loop;
int canusb_platform_finddevs(pcap_if_t **alldevsp, char *err_str)
{
libusb_context *fdctx;
libusb_device** devs;
unsigned char sernum[65];
unsigned char buf[96];
int cnt, i;
libusb_init(&fdctx);
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_get_device_descriptor(devs[i],&desc);
if ((desc.idVendor != CANUSB_VID) || (desc.idProduct != CANUSB_PID))
continue; //It is not, check next device
//It is!
libusb_device_handle *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;
snprintf(dev_name, 30, CANUSB_IFACE"%s", sernum);
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);
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_handle* dh;
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_get_device_descriptor(devs[i],&desc);
if ((desc.idVendor != CANUSB_VID) || (desc.idProduct != CANUSB_PID))
continue;
//Found one!
libusb_device_handle *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(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)
{
pcap_t* p;
libusb_init(&canusb.ctx);
p = pcap_create_common(device, ebuf);
if (p == NULL)
return (NULL);
memset(&canusb, 0x00, sizeof(canusb));
p->activate_op = canusb_activate;
canusb.src = strdup(p->opt.source);
return (p);
}
static void* canusb_capture_thread(struct canusb_t *canusb)
{
struct libusb_context *ctx;
libusb_device_handle *dev;
int i, n;
struct
{
uint8_t rxsz, txsz;
} status;
libusb_init(&ctx);
char *serial = canusb->src + strlen(CANUSB_IFACE);
dev = canusb_opendevice(ctx, serial);
fcntl(canusb->wrpipe, F_SETFL, O_NONBLOCK);
while(*canusb->loop)
{
int sz, ret;
struct CAN_Msg msg;
libusb_interrupt_transfer(dev, 0x81, (unsigned char*)&status, sizeof(status), &sz, 100);
//HACK!!!!! -> drop buffered data, read new one by reading twice.
ret = libusb_interrupt_transfer(dev, 0x81, (unsigned char*)&status, sizeof(status), &sz, 100);
for(i = 0; i<status.rxsz; i++)
{
libusb_bulk_transfer(dev, 0x85, (unsigned char*)&msg, sizeof(msg), &sz, 100);
n = write(canusb->wrpipe, &msg, sizeof(msg));
}
}
libusb_close(dev);
libusb_exit(ctx);
return NULL;
}
static int canusb_startcapture(struct canusb_t* this)
{
int pipefd[2];
if (pipe(pipefd) == -1) return -1;
canusb.rdpipe = pipefd[0];
canusb.wrpipe = pipefd[1];
canusb.loop = &loop;
loop = 1;
pthread_create(&this->worker, NULL, canusb_capture_thread, &canusb);
return canusb.rdpipe;
}
static void canusb_clearbufs(struct canusb_t* 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)
{
loop = 0;
pthread_join(canusb.worker, NULL);
if (canusb.dev)
{
libusb_close(canusb.dev);
canusb.dev = NULL;
}
}
static int canusb_activate(pcap_t* handle)
{
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;
handle->set_datalink_op = NULL;
char* serial = handle->opt.source + strlen("canusb");
canusb.dev = canusb_opendevice(canusb.ctx,serial);
if (!canusb.dev)
{
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 msgsent = 0;
int i = 0;
struct CAN_Msg msg;
struct pcap_pkthdr pkth;
while(i < max_packets)
{
usleep(10 * 1000);
int 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 */
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)
{
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 */

View File

@ -0,0 +1,37 @@
/*
* 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 canusb_listdevices(pcap_if_t **pdevlist, char* errbuf);

View File

@ -118,7 +118,7 @@
#define LINKTYPE_AX25 DLT_AX25
#define LINKTYPE_PRONET DLT_PRONET
#define LINKTYPE_CHAOS DLT_CHAOS
#define LINKTYPE_TOKEN_RING DLT_IEEE802 /* DLT_IEEE802 is used for Token Ring */
#define LINKTYPE_IEEE802_5 DLT_IEEE802 /* DLT_IEEE802 is used for 802.5 Token Ring */
#define LINKTYPE_ARCNET_BSD DLT_ARCNET /* BSD-style headers */
#define LINKTYPE_SLIP DLT_SLIP
#define LINKTYPE_PPP DLT_PPP
@ -193,8 +193,8 @@
#define LINKTYPE_PFLOG 117 /* OpenBSD DLT_PFLOG */
#define LINKTYPE_CISCO_IOS 118 /* For Cisco-internal use */
#define LINKTYPE_PRISM_HEADER 119 /* 802.11+Prism II monitor mode */
#define LINKTYPE_AIRONET_HEADER 120 /* FreeBSD Aironet driver stuff */
#define LINKTYPE_IEEE802_11_PRISM 119 /* 802.11 plus Prism II monitor mode radio metadata header */
#define LINKTYPE_IEEE802_11_AIRONET 120 /* 802.11 plus FreeBSD Aironet driver radio metadata header */
/*
* Reserved for Siemens HiPath HDLC.
@ -212,7 +212,7 @@
#define LINKTYPE_PCI_EXP 125 /* PCI Express */
#define LINKTYPE_AURORA 126 /* Xilinx Aurora link layer */
#define LINKTYPE_IEEE802_11_RADIO 127 /* 802.11 plus BSD radio header */
#define LINKTYPE_IEEE802_11_RADIOTAP 127 /* 802.11 plus radiotap radio metadata header */
/*
* Reserved for the TZSP encapsulation, as per request from
@ -307,11 +307,8 @@
* including radio information:
*
* http://www.shaftnet.org/~pizza/software/capturefrm.txt
*
* but could and arguably should also be used by non-AVS Linux
* 802.11 drivers; that may happen in the future.
*/
#define LINKTYPE_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */
#define LINKTYPE_IEEE802_11_AVS 163 /* 802.11 plus AVS radio metadata header */
/*
* Juniper-private data link type, as per request from
@ -322,7 +319,7 @@
#define LINKTYPE_JUNIPER_MONITOR 164
/*
* Reserved for BACnet MS/TP.
* BACnet MS/TP frames.
*/
#define LINKTYPE_BACNET_MS_TP 165
@ -850,7 +847,43 @@
*/
#define LINKTYPE_IPOIB 242
#define LINKTYPE_MATCHING_MAX 242 /* highest value in the "matching" range */
/*
* MPEG-2 transport stream (ISO 13818-1/ITU-T H.222.0).
*
* Requested by Guy Martin <gmsoft@tuxicoman.be>.
*/
#define LINKTYPE_MPEG_2_TS 243
/*
* ng4T GmbH's UMTS Iub/Iur-over-ATM and Iub/Iur-over-IP format as
* used by their ng40 protocol tester.
*
* Requested by Jens Grimmer <jens.grimmer@ng4t.com>.
*/
#define LINKTYPE_NG40 244
/*
* Pseudo-header giving adapter number and flags, followed by an NFC
* (Near-Field Communications) Logical Link Control Protocol (LLCP) PDU,
* as specified by NFC Forum Logical Link Control Protocol Technical
* Specification LLCP 1.1.
*
* Requested by Mike Wakerly <mikey@google.com>.
*/
#define LINKTYPE_NFC_LLCP 245
/*
* pfsync output; DLT_PFSYNC is 18, which collides with DLT_CIP in
* SuSE 6.3, on OpenBSD, NetBSD, DragonFly BSD, and Mac OS X, and
* is 121, which collides with DLT_HHDLC, in FreeBSD. We pick a
* shiny new link-layer header type value that doesn't collide with
* anything, in the hopes that future pfsync savefiles, if any,
* won't require special hacks to distinguish from other savefiles.
*
*/
#define LINKTYPE_PFSYNC 246
#define LINKTYPE_MATCHING_MAX 246 /* highest value in the "matching" range */
static struct linktype_map {
int dlt;
@ -866,11 +899,12 @@ static struct linktype_map {
{ DLT_AX25, LINKTYPE_AX25 },
{ DLT_PRONET, LINKTYPE_PRONET },
{ DLT_CHAOS, LINKTYPE_CHAOS },
{ DLT_IEEE802, LINKTYPE_TOKEN_RING },
{ DLT_IEEE802, LINKTYPE_IEEE802_5 },
{ DLT_ARCNET, LINKTYPE_ARCNET_BSD },
{ DLT_SLIP, LINKTYPE_SLIP },
{ DLT_PPP, LINKTYPE_PPP },
{ DLT_FDDI, LINKTYPE_FDDI },
{ DLT_SYMANTEC_FIREWALL, LINKTYPE_SYMANTEC_FIREWALL },
/*
* These DLT_* codes have different values on different
@ -883,7 +917,6 @@ static struct linktype_map {
{ DLT_FR, LINKTYPE_FRELAY },
#endif
{ DLT_SYMANTEC_FIREWALL, LINKTYPE_SYMANTEC_FIREWALL },
{ DLT_ATM_RFC1483, LINKTYPE_ATM_RFC1483 },
{ DLT_RAW, LINKTYPE_RAW },
{ DLT_SLIP_BSDOS, LINKTYPE_SLIP_BSDOS },
@ -922,6 +955,12 @@ dlt_to_linktype(int dlt)
{
int i;
/*
* Map DLT_PFSYNC, whatever it might be, to LINKTYPE_PFSYNC.
*/
if (dlt == DLT_PFSYNC)
return (LINKTYPE_PFSYNC);
/*
* Map the values in the matching range.
*/
@ -949,6 +988,15 @@ linktype_to_dlt(int linktype)
{
int i;
/*
* Map LINKTYPE_PFSYNC to DLT_PFSYNC, whatever it might be.
* LINKTYPE_PFSYNC is in the matching range, to make sure
* it's as safe from reuse as we can arrange, so we do
* this test first.
*/
if (linktype == LINKTYPE_PFSYNC)
return (DLT_PFSYNC);
/*
* Map the values in the matching range.
*/

View File

@ -166,6 +166,10 @@ static const char rcsid[] _U_ =
#include "pcap-can-linux.h"
#endif
#if PCAP_SUPPORT_CANUSB
#include "pcap-canusb-linux.h"
#endif
#ifdef PCAP_SUPPORT_NETFILTER
#include "pcap-netfilter-linux.h"
#endif
@ -418,8 +422,15 @@ pcap_create(const char *device, char *ebuf)
}
#endif
#if PCAP_SUPPORT_CANUSB
if (strstr(device, "canusb")) {
return canusb_create(device, ebuf);
}
#endif
#ifdef PCAP_SUPPORT_CAN
if (strstr(device, "can") || strstr(device, "vcan")) {
if ((strncmp(device, "can", 3) == 0 && isdigit(device[3])) ||
(strncmp(device, "vcan", 4) == 0 && isdigit(device[4]))) {
return can_create(device, ebuf);
}
#endif
@ -2299,6 +2310,11 @@ pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
return (-1);
#endif
#if PCAP_SUPPORT_CANUSB
if (canusb_platform_finddevs(alldevsp, errbuf) < 0)
return (-1);
#endif
return (0);
}
@ -5403,13 +5419,19 @@ fix_offset(struct bpf_insn *p)
* header.
*/
p->k -= SLL_HDR_LEN;
} else if (p->k == 0) {
/*
* It's the packet type field; map it to the special magic
* kernel offset for that field.
*/
p->k = SKF_AD_OFF + SKF_AD_PKTTYPE;
} else if (p->k == 14) {
/*
* It's the protocol field; map it to the special magic
* kernel offset for that field.
*/
p->k = SKF_AD_OFF + SKF_AD_PROTOCOL;
} else {
} else if ((bpf_int32)(p->k) > 0) {
/*
* It's within the header, but it's not one of those
* fields; we can't do that in the kernel, so punt

View File

@ -452,8 +452,8 @@ netfilter_platform_finddevs(pcap_if_t **alldevsp, char *err_str)
sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_NETFILTER);
if (sock < 0) {
/* if netlink is not supported this this is not fatal */
if (errno == EAFNOSUPPORT)
/* if netlink is not supported this is not fatal */
if (errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT)
return 0;
snprintf(err_str, PCAP_ERRBUF_SIZE, "Can't open netlink socket %d:%s",
errno, pcap_strerror(errno));

View File

@ -787,6 +787,7 @@ static struct dlt_choice dlt_choices[] = {
DLT_CHOICE(DLT_LINUX_SLL, "Linux cooked"),
DLT_CHOICE(DLT_LTALK, "Localtalk"),
DLT_CHOICE(DLT_PFLOG, "OpenBSD pflog file"),
DLT_CHOICE(DLT_PFSYNC, "Packet filter state syncing"),
DLT_CHOICE(DLT_PRISM_HEADER, "802.11 plus Prism header"),
DLT_CHOICE(DLT_IP_OVER_FC, "RFC 2625 IP-over-Fibre Channel"),
DLT_CHOICE(DLT_SUNATM, "Sun raw ATM"),

View File

@ -177,11 +177,37 @@ struct bpf_program {
#endif
/*
* 17 is used for DLT_OLD_PFLOG in OpenBSD;
* OBSOLETE: DLT_PFLOG is 117 in OpenBSD now as well. See below.
* 18 is used for DLT_PFSYNC in OpenBSD; don't use it for anything else.
* 17 was used for DLT_PFLOG in OpenBSD; it no longer is.
*
* It was DLT_LANE8023 in SuSE 6.3, so we defined LINKTYPE_PFLOG
* as 117 so that pflog captures would use a link-layer header type
* value that didn't collide with any other values. On all
* platforms other than OpenBSD, we defined DLT_PFLOG as 117,
* and we mapped between LINKTYPE_PFLOG and DLT_PFLOG.
*
* OpenBSD eventually switched to using 117 for DLT_PFLOG as well.
*
* Don't use 17 for anything else.
*/
/*
* 18 is used for DLT_PFSYNC in OpenBSD, NetBSD, DragonFly BSD and
* Mac OS X; don't use it for anything else. (FreeBSD uses 121,
* which collides with DLT_HHDLC, even though it doesn't use 18
* for anything and doesn't appear to have ever used it for anything.)
*
* We define it as 18 on those platforms; it is, unfortunately, used
* for DLT_CIP in Suse 6.3, so we don't define it as DLT_PFSYNC
* in general. As the packet format for it, like that for
* DLT_PFLOG, is not only OS-dependent but OS-version-dependent,
* we don't support printing it in tcpdump except on OSes that
* have the relevant header files, so it's not that useful on
* other platforms.
*/
#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__APPLE__)
#define DLT_PFSYNC 18
#endif
#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */
/*
@ -312,15 +338,8 @@ struct bpf_program {
#define DLT_IPFILTER 116
/*
* OpenBSD DLT_PFLOG; DLT_PFLOG is 17 in OpenBSD, but that's DLT_LANE8023
* in SuSE 6.3, so we can't use 17 for it in capture-file headers.
*
* XXX: is there a conflict with DLT_PFSYNC 18 as well?
* OpenBSD DLT_PFLOG.
*/
#ifdef __OpenBSD__
#define DLT_OLD_PFLOG 17
#define DLT_PFSYNC 18
#endif
#define DLT_PFLOG 117
/*
@ -342,9 +361,48 @@ struct bpf_program {
#define DLT_AIRONET_HEADER 120
/*
* Reserved for Siemens HiPath HDLC.
* Sigh.
*
* This was reserved for Siemens HiPath HDLC on 2002-01-25, as
* requested by Tomas Kukosa.
*
* On 2004-02-25, a FreeBSD checkin to sys/net/bpf.h was made that
* assigned 121 as DLT_PFSYNC. Its libpcap does DLT_ <-> LINKTYPE_
* mapping, so it probably supports capturing on the pfsync device
* but not saving the captured data to a pcap file.
*
* OpenBSD, from which pf came, however, uses 18 for DLT_PFSYNC;
* their libpcap does no DLT_ <-> LINKTYPE_ mapping, so it would
* use 18 in pcap files as well.
*
* NetBSD and DragonFly BSD also use 18 for DLT_PFSYNC; their
* libpcaps do DLT_ <-> LINKTYPE_ mapping, and neither has an entry
* for DLT_PFSYNC, so it might not be able to write out dump files
* with 18 as the link-layer header type. (Earlier versions might
* not have done mapping, in which case they'd work the same way
* OpenBSD does.)
*
* Mac OS X defines it as 18, but doesn't appear to use it as of
* Mac OS X 10.7.3. Its libpcap does DLT_ <-> LINKTYPE_ mapping.
*
* We'll define DLT_PFSYNC as 121 on FreeBSD and define it as 18 on
* all other platforms. We'll define DLT_HHDLC as 121 on everything
* except for FreeBSD; anybody who wants to compile, on FreeBSD, code
* that uses DLT_HHDLC is out of luck.
*
* We'll define LINKTYPE_PFSYNC as 18, *even on FreeBSD*, and map
* it, so that savefiles won't use 121 for PFSYNC - they'll all
* use 18. Code that uses pcap_datalink() to determine the link-layer
* header type of a savefile won't, when built and run on FreeBSD,
* be able to distinguish between LINKTYPE_PFSYNC and LINKTYPE_HHDLC
* capture files; code that doesn't, such as the code in Wireshark,
* will be able to distinguish between them.
*/
#ifdef __FreeBSD__
#define DLT_PFSYNC 121
#else
#define DLT_HHDLC 121
#endif
/*
* This is for RFC 2625 IP-over-Fibre Channel.
@ -542,7 +600,7 @@ struct bpf_program {
#define DLT_JUNIPER_MONITOR 164
/*
* Reserved for BACnet MS/TP.
* BACnet MS/TP frames.
*/
#define DLT_BACNET_MS_TP 165
@ -1081,7 +1139,43 @@ struct bpf_program {
*/
#define DLT_IPOIB 242
#define DLT_MATCHING_MAX 242 /* highest value in the "matching" range */
/*
* MPEG-2 transport stream (ISO 13818-1/ITU-T H.222.0).
*
* Requested by Guy Martin <gmsoft@tuxicoman.be>.
*/
#define DLT_MPEG_2_TS 243
/*
* ng4T GmbH's UMTS Iub/Iur-over-ATM and Iub/Iur-over-IP format as
* used by their ng40 protocol tester.
*
* Requested by Jens Grimmer <jens.grimmer@ng4t.com>.
*/
#define DLT_NG40 244
/*
* Pseudo-header giving adapter number and flags, followed by an NFC
* (Near-Field Communications) Logical Link Control Protocol (LLCP) PDU,
* as specified by NFC Forum Logical Link Control Protocol Technical
* Specification LLCP 1.1.
*
* Requested by Mike Wakerly <mikey@google.com>.
*/
#define DLT_NFC_LLCP 245
/*
* 245 is used as LINKTYPE_PFSYNC; do not use it for any other purpose.
*
* DLT_PFSYNC has different values on different platforms, and all of
* them collide with something used elsewhere. On platforms that
* don't already define it, define it as 245.
*/
#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__DragonFly__) && !defined(__APPLE__)
#define DLT_PFSYNC 246
#endif
#define DLT_MATCHING_MAX 246 /* highest value in the "matching" range */
/*
* DLT and savefile link type values are split into a class and

View File

@ -221,7 +221,7 @@
/* #undef NETINET_ETHER_H_DECLARES_ETHER_HOSTTON */
/* Define to 1 if netinet/if_ether.h declares `ether_hostton' */
#define NETINET_IF_ETHER_H_DECLARES_ETHER_HOSTTON
#define NETINET_IF_ETHER_H_DECLARES_ETHER_HOSTTON /**/
/* do not use protochain */
/* #undef NO_PROTOCHAIN */
@ -238,6 +238,9 @@
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME ""
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION ""
@ -250,6 +253,9 @@
/* target host supports CAN sniffing */
/* #undef PCAP_SUPPORT_CAN */
/* target host supports canusb */
/* #undef PCAP_SUPPORT_CANUSB */
/* target host supports netfilter sniffing */
/* #undef PCAP_SUPPORT_NETFILTER */

View File

@ -1099,7 +1099,43 @@ struct bpf_zbuf_header {
*/
#define DLT_IPOIB 242
#define DLT_MATCHING_MAX 242 /* highest value in the "matching" range */
/*
* MPEG-2 transport stream (ISO 13818-1/ITU-T H.222.0).
*
* Requested by Guy Martin <gmsoft@tuxicoman.be>.
*/
#define DLT_MPEG_2_TS 243
/*
* ng4T GmbH's UMTS Iub/Iur-over-ATM and Iub/Iur-over-IP format as
* used by their ng40 protocol tester.
*
* Requested by Jens Grimmer <jens.grimmer@ng4t.com>.
*/
#define DLT_NG40 244
/*
* Pseudo-header giving adapter number and flags, followed by an NFC
* (Near-Field Communications) Logical Link Control Protocol (LLCP) PDU,
* as specified by NFC Forum Logical Link Control Protocol Technical
* Specification LLCP 1.1.
*
* Requested by Mike Wakerly <mikey@google.com>.
*/
#define DLT_NFC_LLCP 245
/*
* 245 is used as LINKTYPE_PFSYNC; do not use it for any other purpose.
*
* DLT_PFSYNC has different values on different platforms, and all of
* them collide with something used elsewhere. On platforms that
* don't already define it, define it as 245.
*/
#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__DragonFly__) && !defined(__APPLE__)
#define DLT_PFSYNC 246
#endif
#define DLT_MATCHING_MAX 246 /* highest value in the "matching" range */
/*
* DLT and savefile link type values are split into a class and