MFV: libpcap 1.4.0.

MFC after:	4 weeks
This commit is contained in:
Xin LI 2013-05-30 08:02:00 +00:00
commit edc89b24f3
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=251129
55 changed files with 8664 additions and 4070 deletions

View file

@ -1,3 +1,35 @@
Monday March 18, 2013 guy@alum.mit.edu
Summary for 1.4.0 libpcap release
Add netfilter/nfqueue interface.
If we don't have support for IPv6 address resolution, support,
in filter expressions, what IPv6 stuff we can.
Checks added for malloc()/realloc()/etc. failures.
Fix pcap-config to include -lpthread if canusb support is
present
Try to fix "pcap_parse not defined" problems when --without-flex
and --without-bison are used when you have Flex and Bison
Fix some issues with the pcap_loop man page.
Fix pcap_getnonblock() and pcap_setnonblock() to fill in the
supplied error message buffer
Fix typo that, it appeared, would cause pcap-libdlpi.c not to
compile (perhaps systems with libdlpi also have BPF and use
that instead)
Catch attempts to call pcap_compile() on a non-activated pcap_t
Fix crash on Linux with CAN-USB support without usbfs
Fix addition of VLAN tags for Linux cooked captures
Check for both EOPNOTSUPP and EINVAL after SIOCETHTOOL ioctl, so
that the driver can report either one if it doesn't support
SIOCETHTOOL
Add DLT_INFINIBAND and DLT_SCTP
Describe "proto XXX" and "protochain XXX" in the pcap-filter man
page
Handle either directories, or symlinks to directories, that
correspond to interfaces in /sys/class/net
Fix handling of VLAN tag insertion to check, on Linux 3.x
kernels, for VLAN tag valid flag
Clean up some man pages
Support libnl3 as well as libnl1 and libnl2 on Linux
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}.

View file

@ -22,6 +22,7 @@ Additional people who have contributed patches:
Armando L. Caro Jr. <acaro at mail dot eecis dot udel dot edu>
Assar Westerlund <assar at sics dot se>
Brian Ginsbach <ginsbach at cray dot com>
Bill Parker <wp02855 at gmail dot com>
Charles M. Hannum <mycroft at netbsd dot org>
Chris G. Demetriou <cgd at netbsd dot org>
Chris Lightfoot <cwrl at users dot sourceforge dot net>
@ -59,6 +60,7 @@ Additional people who have contributed patches:
Henri Doreau <hdoreau at sourceforge dot net>
Hyung Sik Yoon <hsyn at kr dot ibm dot com>
Igor Khristophorov <igor at atdot dot org>
Jakub Zawadzki <darkjames at darkjames dot pl>
Jan-Philip Velders <jpv at veldersjes dot net>
Jason R. Thorpe <thorpej at netbsd dot org>
Javier Achirica <achirica at ttd dot net>
@ -152,4 +154,4 @@ The original LBL crew:
Van Jacobson
Past maintainers:
Jun-ichiro itojun Hagino <itojun at iijlab dot net>
Jun-ichiro itojun Hagino <itojun at iijlab dot net> Also see: http://www.wide.ad.jp/itojun-award/

View file

@ -13,8 +13,11 @@ Anonymous Git is available via:
Version 1.x.y of LIBPCAP can be retrieved with the CVS tag "libpcap_1_{x}rel{y}":
cvs -d :pserver:tcpdump@cvs.tcpdump.org:/tcpdump/master checkout -r libpcap_1_{x}rel{y} libpcap
Please submit patches against the master copy to the libpcap project on
sourceforge.net.
Please submit patches by forking the branch on GitHub at
http://github.com/mcr/libpcap/tree/master
and issuing a pull request.
formerly from Lawrence Berkeley National Laboratory
Network Research Group <libpcap@ee.lbl.gov>
@ -91,15 +94,18 @@ a particular release of libpcap.
Problems, bugs, questions, desirable enhancements, etc. should be sent
to the address "tcpdump-workers@lists.tcpdump.org". Bugs, support
requests, and feature requests may also be submitted on the SourceForge
site for libpcap at
requests, and feature requests may also be submitted on the GitHub issue
tracker for libpcap at
http://sourceforge.net/projects/libpcap/
https://github.com/mcr/libpcap/issues
Source code contributions, etc. should be sent to the email address
submitted as patches on the SourceForge site for libpcap.
above or submitted by forking the branch on GitHub at
Current versions can be found at www.tcpdump.org, or the SourceForge
site for libpcap.
http://github.com/mcr/libpcap/tree/master
and issuing a pull request.
Current versions can be found at www.tcpdump.org.
- The TCPdump team

View file

@ -1 +1 @@
1.3.0
1.4.0

View file

@ -292,11 +292,14 @@ bpf_image(p, n)
break;
}
(void)snprintf(operand, sizeof operand, fmt, v);
(void)snprintf(image, sizeof image,
(BPF_CLASS(p->code) == BPF_JMP &&
BPF_OP(p->code) != BPF_JA) ?
"(%03d) %-8s %-16s jt %d\tjf %d"
: "(%03d) %-8s %s",
n, op, operand, n + 1 + p->jt, n + 1 + p->jf);
if (BPF_CLASS(p->code) == BPF_JMP && BPF_OP(p->code) != BPF_JA) {
(void)snprintf(image, sizeof image,
"(%03d) %-8s %-16s jt %d\tjf %d",
n, op, operand, n + 1 + p->jt, n + 1 + p->jf);
} else {
(void)snprintf(image, sizeof image,
"(%03d) %-8s %s",
n, op, operand);
}
return image;
}

View file

@ -58,6 +58,15 @@
/* if libnl exists and is version 2.x */
#undef HAVE_LIBNL_2_x
/* if libnl exists and is version 3.x */
#undef HAVE_LIBNL_3_x
/* libnl has NLE_FAILURE */
#undef HAVE_LIBNL_NLE
/* libnl has new-style socket api */
#undef HAVE_LIBNL_SOCKETS
/* Define to 1 if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H
@ -211,6 +220,9 @@
/* path for device for USB sniffing */
#undef LINUX_USB_MON_DEV
/* if we need a pcap_parse wrapper around yyparse */
#undef NEED_YYPARSE_WRAPPER
/* Define to 1 if netinet/ether.h declares `ether_hostton' */
#undef NETINET_ETHER_H_DECLARES_ETHER_HOSTTON
@ -232,9 +244,6 @@
/* 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
@ -259,6 +268,9 @@
/* include ACN support */
#undef SITA
/* if struct sockaddr_hci has hci_channel member */
#undef SOCKADDR_HCI_HAS_HCI_CHANNEL
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS

10312
contrib/libpcap/configure vendored

File diff suppressed because it is too large Load diff

View file

@ -430,19 +430,44 @@ linux)
with_libnl=$withval,,)
if test x$with_libnl != xno ; then
have_any_nl="no"
#
# Try libnl 2.x first.
# Try libnl 3.x first.
#
AC_CHECK_LIB(nl, nl_socket_alloc,
AC_CHECK_LIB(nl-3, nl_socket_alloc,
[
#
# Yes, we have libnl 2.x.
# Yes, we have libnl 3.x.
#
LIBS="-lnl-genl -lnl $LIBS"
LIBS="-lnl-genl-3 -lnl-3 $LIBS"
AC_DEFINE(HAVE_LIBNL,1,[if libnl exists])
AC_DEFINE(HAVE_LIBNL_2_x,1,[if libnl exists and is version 2.x])
],
[
AC_DEFINE(HAVE_LIBNL_3_x,1,[if libnl exists and is version 3.x])
AC_DEFINE(HAVE_LIBNL_NLE,1,[libnl has NLE_FAILURE])
AC_DEFINE(HAVE_LIBNL_SOCKETS,1,[libnl has new-style socket api])
V_INCLS="$V_INCLS -I/usr/include/libnl3"
have_any_nl="yes"
])
if test x$have_any_nl = xno ; then
#
# Try libnl 2.x
#
AC_CHECK_LIB(nl, nl_socket_alloc,
[
#
# Yes, we have libnl 2.x.
#
LIBS="-lnl-genl -lnl $LIBS"
AC_DEFINE(HAVE_LIBNL,1,[if libnl exists])
AC_DEFINE(HAVE_LIBNL_2_x,1,[if libnl exists and is version 2.x])
AC_DEFINE(HAVE_LIBNL_NLE,1,[libnl has NLE_FAILURE])
AC_DEFINE(HAVE_LIBNL_SOCKETS,1,[libnl has new-style socket api])
have_any_nl="yes"
])
fi
if test x$have_any_nl = xno ; then
#
# No, we don't; do we have libnl 1.x?
#
@ -453,16 +478,18 @@ linux)
#
LIBS="-lnl $LIBS"
AC_DEFINE(HAVE_LIBNL,1,[if libnl exists])
],
[
#
# No, we don't have libnl at all.
#
if test x$with_libnl = xyes ; then
AC_MSG_ERROR([libnl support requested but libnl not found])
fi
have_any_nl="yes"
])
])
fi
if test x$have_any_nl = xno ; then
#
# No, we don't have libnl at all.
#
if test x$with_libnl = xyes ; then
AC_MSG_ERROR([libnl support requested but libnl not found])
fi
fi
fi
AC_CHECK_HEADERS(linux/ethtool.h,,,
@ -1347,11 +1374,14 @@ linux*)
AC_TRY_COMPILE([
AC_INCLUDES_DEFAULT
#include <sys/socket.h>
#include <netinet/in.h>
#include <linux/types.h>
#include <linux/netlink.h>
#include <linux/netfilter.h>
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nfnetlink_log.h>],
#include <linux/netfilter/nfnetlink_log.h>
#include <linux/netfilter/nfnetlink_queue.h>],
[],
ac_cv_netfilter_can_compile=yes,
ac_cv_netfilter_can_compile=no))
@ -1371,7 +1401,8 @@ AC_SUBST(NETFILTER_SRC)
AC_ARG_ENABLE([bluetooth],
[AC_HELP_STRING([--enable-bluetooth],[enable Bluetooth support @<:@default=yes, if support available@:>@])],
,enable_bluetooth=yes)
[],
[enable_bluetooth=yes])
if test "x$enable_bluetooth" != "xno" ; then
dnl check for Bluetooth sniffing support
@ -1382,6 +1413,26 @@ if test "x$enable_bluetooth" != "xno" ; then
AC_DEFINE(PCAP_SUPPORT_BT, 1, [target host supports Bluetooth sniffing])
BT_SRC=pcap-bt-linux.c
AC_MSG_NOTICE(Bluetooth sniffing is supported)
#
# OK, does struct sockaddr_hci have an hci_channel
# member?
#
AC_MSG_CHECKING(if struct sockaddr_hci has hci_channel member)
AC_CACHE_VAL(ac_cv_lbl_sockaddr_hci_has_hci_channel,
AC_TRY_COMPILE(
[
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
],
[u_int i = sizeof(((struct sockaddr_hci *)0)->hci_channel)],
ac_cv_lbl_sockaddr_hci_has_hci_channel=yes,
ac_cv_lbl_sockaddr_hci_has_hci_channel=no))
AC_MSG_RESULT($ac_cv_lbl_sockaddr_hci_has_hci_channel)
if test $ac_cv_lbl_sockaddr_hci_has_hci_channel = yes ; then
AC_DEFINE(SOCKADDR_HCI_HAS_HCI_CHANNEL,,
[if struct sockaddr_hci has hci_channel member])
fi
],
AC_MSG_NOTICE(Bluetooth sniffing is not supported; install bluez-lib devel to enable it)
)
@ -1395,8 +1446,9 @@ if test "x$enable_bluetooth" != "xno" ; then
fi
AC_ARG_ENABLE([canusb],
[AC_HELP_STRING([--enable-canusb],[enable canusb support @<:@default=yes, if support available@:>@])]
,enable_canusb=yes)
[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
@ -1406,7 +1458,7 @@ if test "x$enable_canusb" != "xno" ; then
[
AC_DEFINE(PCAP_SUPPORT_CANUSB, 1, [target host supports canusb])
CANUSB_SRC=pcap-canusb-linux.c
LIBS="-lusb-1.0 $LIBS"
LIBS="-lusb-1.0 -lpthread $LIBS"
AC_MSG_NOTICE(canusb sniffing is supported)
],
AC_MSG_NOTICE(canusb sniffing is not supported; install libusb1.0 lib devel to enable it)
@ -1422,7 +1474,8 @@ fi
AC_ARG_ENABLE([can],
[AC_HELP_STRING([--enable-can],[enable CAN support @<:@default=yes, if support available@:>@])],
,enable_can=yes)
[],
[enable_can=yes])
if test "x$enable_can" != "xno" ; then
dnl check for CAN sniffing support

View file

@ -141,11 +141,9 @@ get_sa_len(struct sockaddr *addr)
* Returns -1 on error, 0 otherwise.
* The list, as returned through "alldevsp", may be null if no interfaces
* were up and could be opened.
*
* This is the implementation used on platforms that have "getifaddrs()".
*/
int
pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
{
pcap_if_t *devlist = NULL;
struct ifaddrs *ifap, *ifa;
@ -273,15 +271,6 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
freeifaddrs(ifap);
if (ret != -1) {
/*
* We haven't had any errors yet; do any platform-specific
* operations to add devices.
*/
if (pcap_platform_finddevs(&devlist, errbuf) < 0)
ret = -1;
}
if (ret == -1) {
/*
* We had an error; free the list we've been constructing.

View file

@ -133,10 +133,11 @@ struct rtentry; /* declarations in <net/if.h> */
*
* XXX - or platforms that have other, better mechanisms but for which
* we don't yet have code to use that mechanism; I think there's a better
* way on Linux, for example.
* way on Linux, for example, but if that better way is "getifaddrs()",
* we already have that.
*/
int
pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
{
pcap_if_t *devlist = NULL;
register int fd;
@ -409,15 +410,6 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
free(buf);
(void)close(fd);
if (ret != -1) {
/*
* We haven't had any errors yet; do any platform-specific
* operations to add devices.
*/
if (pcap_platform_finddevs(&devlist, errbuf) < 0)
ret = -1;
}
if (ret == -1) {
/*
* We had an error; free the list we've been constructing.

View file

@ -80,7 +80,7 @@ struct rtentry; /* declarations in <net/if.h> */
* SIOCGLIFCONF rather than SIOCGIFCONF in order to get IPv6 addresses.)
*/
int
pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
{
pcap_if_t *devlist = NULL;
register int fd4, fd6, fd;
@ -362,15 +362,6 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
(void)close(fd6);
(void)close(fd4);
if (ret != -1) {
/*
* We haven't had any errors yet; do any platform-specific
* operations to add devices.
*/
if (pcap_platform_finddevs(&devlist, errbuf) < 0)
ret = -1;
}
if (ret == -1) {
/*
* We had an error; free the list we've been constructing.

View file

@ -37,7 +37,7 @@
extern pcap_if_t *acn_if_list; /* pcap's list of available interfaces */
int pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) {
int pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf) {
//printf("pcap_findalldevs()\n"); // fulko

View file

@ -109,6 +109,18 @@ static const char rcsid[] _U_ =
#define ETHERMTU 1500
#ifndef IPPROTO_HOPOPTS
#define IPPROTO_HOPOPTS 0
#endif
#ifndef IPPROTO_ROUTING
#define IPPROTO_ROUTING 43
#endif
#ifndef IPPROTO_FRAGMENT
#define IPPROTO_FRAGMENT 44
#endif
#ifndef IPPROTO_DSTOPTS
#define IPPROTO_DSTOPTS 60
#endif
#ifndef IPPROTO_SCTP
#define IPPROTO_SCTP 132
#endif
@ -263,20 +275,16 @@ static struct block *gen_gateway(const u_char *, bpf_u_int32 **, int, int);
static struct block *gen_ipfrag(void);
static struct block *gen_portatom(int, bpf_int32);
static struct block *gen_portrangeatom(int, bpf_int32, bpf_int32);
#ifdef INET6
static struct block *gen_portatom6(int, bpf_int32);
static struct block *gen_portrangeatom6(int, bpf_int32, bpf_int32);
#endif
struct block *gen_portop(int, int, int);
static struct block *gen_port(int, int, int);
struct block *gen_portrangeop(int, int, int, int);
static struct block *gen_portrange(int, int, int, int);
#ifdef INET6
struct block *gen_portop6(int, int, int);
static struct block *gen_port6(int, int, int);
struct block *gen_portrangeop6(int, int, int, int);
static struct block *gen_portrange6(int, int, int, int);
#endif
static int lookup_proto(const char *, int);
static struct block *gen_protochain(int, int, int);
static struct block *gen_proto(int, int, int);
@ -427,6 +435,15 @@ pcap_compile(pcap_t *p, struct bpf_program *program,
const char * volatile xbuf = buf;
u_int len;
/*
* If this pcap_t hasn't been activated, it doesn't have a
* link-layer type, so we can't use it.
*/
if (!p->activated) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"not-yet-activated pcap_t passed to pcap_compile");
return (-1);
}
no_optimize = 0;
n_errors = 0;
root = NULL;
@ -2834,11 +2851,9 @@ ethertype_to_ppptype(proto)
proto = PPP_IP;
break;
#ifdef INET6
case ETHERTYPE_IPV6:
proto = PPP_IPV6;
break;
#endif
case ETHERTYPE_DN:
proto = PPP_DECNET;
@ -3046,11 +3061,10 @@ gen_linktype(proto)
case ETHERTYPE_IP:
/* Check for a version number of 4. */
return gen_mcmp(OR_LINK, 0, BPF_B, 0x40, 0xF0);
#ifdef INET6
case ETHERTYPE_IPV6:
/* Check for a version number of 6. */
return gen_mcmp(OR_LINK, 0, BPF_B, 0x60, 0xF0);
#endif
default:
return gen_false(); /* always false */
@ -3074,10 +3088,8 @@ gen_linktype(proto)
/*
* Raw IPv6, so no type field.
*/
#ifdef INET6
if (proto == ETHERTYPE_IPV6)
return gen_true(); /* always true */
#endif
/* Checking for something other than IPv6; always false */
return gen_false();
@ -3199,11 +3211,9 @@ gen_linktype(proto)
if (proto == ETHERTYPE_IP)
return (gen_cmp(OR_LINK, offsetof(struct pfloghdr, af),
BPF_B, (bpf_int32)AF_INET));
#ifdef INET6
else if (proto == ETHERTYPE_IPV6)
return (gen_cmp(OR_LINK, offsetof(struct pfloghdr, af),
BPF_B, (bpf_int32)AF_INET6));
#endif /* INET6 */
else
return gen_false();
/*NOTREACHED*/
@ -3221,11 +3231,9 @@ gen_linktype(proto)
default:
return gen_false();
#ifdef INET6
case ETHERTYPE_IPV6:
return (gen_cmp(OR_LINK, off_linktype, BPF_B,
(bpf_int32)ARCTYPE_INET6));
#endif /* INET6 */
case ETHERTYPE_IP:
b0 = gen_cmp(OR_LINK, off_linktype, BPF_B,
@ -3277,13 +3285,11 @@ gen_linktype(proto)
*/
return gen_cmp(OR_LINK, 2, BPF_H, (0x03<<8) | 0xcc);
#ifdef INET6
case ETHERTYPE_IPV6:
/*
* Check for the special NLPID for IPv6.
*/
return gen_cmp(OR_LINK, 2, BPF_H, (0x03<<8) | 0x8e);
#endif
case LLCSAP_ISONS:
/*
@ -3630,7 +3636,7 @@ gen_hostop6(addr, mask, dir, proto, src_off, dst_off)
gen_and(b0, b1);
return b1;
}
#endif /*INET6*/
#endif
static struct block *
gen_ehostop(eaddr, dir)
@ -4508,13 +4514,11 @@ gen_host(addr, mask, proto, dir, type)
case Q_MOPRC:
bpf_error("MOPRC host filtering not implemented");
#ifdef INET6
case Q_IPV6:
bpf_error("'ip6' modifier applied to ip host");
case Q_ICMPV6:
bpf_error("'icmp6' modifier applied to %s", typestr);
#endif /* INET6 */
case Q_AH:
bpf_error("'ah' modifier applied to %s", typestr);
@ -4671,7 +4675,7 @@ gen_host6(addr, mask, proto, dir, type)
}
/* NOTREACHED */
}
#endif /*INET6*/
#endif
#ifndef INET6
static struct block *
@ -4763,26 +4767,20 @@ gen_proto_abbrev(proto)
case Q_SCTP:
b1 = gen_proto(IPPROTO_SCTP, Q_IP, Q_DEFAULT);
#ifdef INET6
b0 = gen_proto(IPPROTO_SCTP, Q_IPV6, Q_DEFAULT);
gen_or(b0, b1);
#endif
break;
case Q_TCP:
b1 = gen_proto(IPPROTO_TCP, Q_IP, Q_DEFAULT);
#ifdef INET6
b0 = gen_proto(IPPROTO_TCP, Q_IPV6, Q_DEFAULT);
gen_or(b0, b1);
#endif
break;
case Q_UDP:
b1 = gen_proto(IPPROTO_UDP, Q_IP, Q_DEFAULT);
#ifdef INET6
b0 = gen_proto(IPPROTO_UDP, Q_IPV6, Q_DEFAULT);
gen_or(b0, b1);
#endif
break;
case Q_ICMP:
@ -4810,10 +4808,8 @@ gen_proto_abbrev(proto)
case Q_PIM:
b1 = gen_proto(IPPROTO_PIM, Q_IP, Q_DEFAULT);
#ifdef INET6
b0 = gen_proto(IPPROTO_PIM, Q_IPV6, Q_DEFAULT);
gen_or(b0, b1);
#endif
break;
#ifndef IPPROTO_VRRP
@ -4875,7 +4871,6 @@ gen_proto_abbrev(proto)
b1 = gen_linktype(ETHERTYPE_MOPRC);
break;
#ifdef INET6
case Q_IPV6:
b1 = gen_linktype(ETHERTYPE_IPV6);
break;
@ -4886,17 +4881,14 @@ gen_proto_abbrev(proto)
case Q_ICMPV6:
b1 = gen_proto(IPPROTO_ICMPV6, Q_IPV6, Q_DEFAULT);
break;
#endif /* INET6 */
#ifndef IPPROTO_AH
#define IPPROTO_AH 51
#endif
case Q_AH:
b1 = gen_proto(IPPROTO_AH, Q_IP, Q_DEFAULT);
#ifdef INET6
b0 = gen_proto(IPPROTO_AH, Q_IPV6, Q_DEFAULT);
gen_or(b0, b1);
#endif
break;
#ifndef IPPROTO_ESP
@ -4904,10 +4896,8 @@ gen_proto_abbrev(proto)
#endif
case Q_ESP:
b1 = gen_proto(IPPROTO_ESP, Q_IP, Q_DEFAULT);
#ifdef INET6
b0 = gen_proto(IPPROTO_ESP, Q_IPV6, Q_DEFAULT);
gen_or(b0, b1);
#endif
break;
case Q_ISO:
@ -5040,7 +5030,6 @@ gen_portatom(off, v)
return gen_cmp(OR_TRAN_IPV4, off, BPF_H, v);
}
#ifdef INET6
static struct block *
gen_portatom6(off, v)
int off;
@ -5048,7 +5037,6 @@ gen_portatom6(off, v)
{
return gen_cmp(OR_TRAN_IPV6, off, BPF_H, v);
}
#endif/*INET6*/
struct block *
gen_portop(port, proto, dir)
@ -5140,7 +5128,6 @@ gen_port(port, ip_proto, dir)
return b1;
}
#ifdef INET6
struct block *
gen_portop6(port, proto, dir)
int port, proto, dir;
@ -5213,7 +5200,6 @@ gen_port6(port, ip_proto, dir)
gen_and(b0, b1);
return b1;
}
#endif /* INET6 */
/* gen_portrange code */
static struct block *
@ -5318,7 +5304,6 @@ gen_portrange(port1, port2, ip_proto, dir)
return b1;
}
#ifdef INET6
static struct block *
gen_portrangeatom6(off, v1, v2)
int off;
@ -5419,7 +5404,6 @@ gen_portrange6(port1, port2, ip_proto, dir)
gen_and(b0, b1);
return b1;
}
#endif /* INET6 */
static int
lookup_proto(name, proto)
@ -5554,7 +5538,7 @@ gen_protochain(v, proto, dir)
s[i]->s.k = off_macpl + off_nl;
i++;
break;
#ifdef INET6
case Q_IPV6:
b0 = gen_linktype(ETHERTYPE_IPV6);
@ -5567,7 +5551,7 @@ gen_protochain(v, proto, dir)
s[i]->s.k = 40;
i++;
break;
#endif
default:
bpf_error("unsupported proto to gen_protochain");
/*NOTREACHED*/
@ -5594,7 +5578,6 @@ gen_protochain(v, proto, dir)
fix2 = i;
i++;
#ifdef INET6
if (proto == Q_IPV6) {
int v6start, v6end, v6advance, j;
@ -5676,9 +5659,7 @@ gen_protochain(v, proto, dir)
/* fixup */
for (j = v6start; j <= v6end; j++)
s[j]->s.jt = s[v6advance];
} else
#endif
{
} else {
/* nop */
s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
s[i]->s.k = 0;
@ -5822,10 +5803,8 @@ 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)
@ -5833,14 +5812,11 @@ gen_proto(v, proto, dir)
switch (proto) {
case Q_DEFAULT:
#ifdef INET6
b0 = gen_proto(v, Q_IP, dir);
b1 = gen_proto(v, Q_IPV6, dir);
gen_or(b0, b1);
return b1;
#else
/*FALLTHROUGH*/
#endif
case Q_IP:
/*
* For FDDI, RFC 1188 says that SNAP encapsulation is used,
@ -5991,7 +5967,6 @@ gen_proto(v, proto, dir)
bpf_error("'carp proto' is bogus");
/* NOTREACHED */
#ifdef INET6
case Q_IPV6:
b0 = gen_linktype(ETHERTYPE_IPV6);
#ifndef CHASE_CHAIN
@ -6012,7 +5987,6 @@ gen_proto(v, proto, dir)
case Q_ICMPV6:
bpf_error("'icmp6 proto' is bogus");
#endif /* INET6 */
case Q_AH:
bpf_error("'ah proto' is bogus");
@ -6269,13 +6243,9 @@ gen_scode(name, q)
bpf_error("illegal port number %d < 0", port);
if (port > 65535)
bpf_error("illegal port number %d > 65535", port);
#ifndef INET6
return gen_port(port, real_proto, dir);
#else
b = gen_port(port, real_proto, dir);
gen_or(gen_port6(port, real_proto, dir), b);
return b;
#endif /* INET6 */
case Q_PORTRANGE:
if (proto != Q_DEFAULT &&
@ -6319,13 +6289,9 @@ gen_scode(name, q)
if (port2 > 65535)
bpf_error("illegal port number %d > 65535", port2);
#ifndef INET6
return gen_portrange(port1, port2, real_proto, dir);
#else
b = gen_portrange(port1, port2, real_proto, dir);
gen_or(gen_portrange6(port1, port2, real_proto, dir), b);
return b;
#endif /* INET6 */
case Q_GATEWAY:
#ifndef INET6
@ -6473,16 +6439,12 @@ gen_ncode(s, v, q)
if (v > 65535)
bpf_error("illegal port number %u > 65535", v);
#ifndef INET6
return gen_port((int)v, proto, dir);
#else
{
struct block *b;
b = gen_port((int)v, proto, dir);
gen_or(gen_port6((int)v, proto, dir), b);
return b;
}
#endif /* INET6 */
case Q_PORTRANGE:
if (proto == Q_UDP)
@ -6499,16 +6461,12 @@ gen_ncode(s, v, q)
if (v > 65535)
bpf_error("illegal port number %u > 65535", v);
#ifndef INET6
return gen_portrange((int)v, (int)v, proto, dir);
#else
{
struct block *b;
b = gen_portrange((int)v, (int)v, proto, dir);
gen_or(gen_portrange6((int)v, (int)v, proto, dir), b);
return b;
}
#endif /* INET6 */
case Q_GATEWAY:
bpf_error("'gateway' requires a name");
@ -6798,9 +6756,7 @@ gen_load(proto, inst, size)
case Q_LAT:
case Q_MOPRC:
case Q_MOPDL:
#ifdef INET6
case Q_IPV6:
#endif
/*
* The offset is relative to the beginning of
* the network-layer header.
@ -6909,16 +6865,12 @@ gen_load(proto, inst, size)
gen_and(gen_proto_abbrev(proto), b = gen_ipfrag());
if (inst->b)
gen_and(inst->b, b);
#ifdef INET6
gen_and(gen_proto_abbrev(Q_IP), b);
#endif
inst->b = b;
break;
#ifdef INET6
case Q_ICMPV6:
bpf_error("IPv6 upper-layer protocol is not supported by proto[x]");
/*NOTREACHED*/
#endif
}
inst->regno = regno;
s = new_stmt(BPF_ST);
@ -7470,13 +7422,11 @@ gen_multicast(proto)
gen_and(b0, b1);
return b1;
#ifdef INET6
case Q_IPV6:
b0 = gen_linktype(ETHERTYPE_IPV6);
b1 = gen_cmp(OR_NET, 24, BPF_B, (bpf_int32)255);
gen_and(b0, b1);
return b1;
#endif /* INET6 */
}
bpf_error("link-layer multicast filters supported only on ethernet/FDDI/token ring/ARCNET/802.11/ATM LANE/Fibre Channel");
/* NOTREACHED */

View file

@ -168,7 +168,7 @@ yyerror(const char *msg)
/* NOTREACHED */
}
#ifndef YYBISON
#ifdef NEED_YYPARSE_WRAPPER
int yyparse(void);
int

View file

@ -249,6 +249,7 @@ pcap_nametoportrange(const char *name, int *port1, int *port2, int *proto)
free(cpy);
return 0;
}
free(cpy);
if (*proto != save_proto)
*proto = PROTO_UNDEF;

View file

@ -112,51 +112,9 @@ static int cur_mark;
static void opt_init(struct block *);
static void opt_cleanup(void);
static void make_marks(struct block *);
static void mark_code(struct block *);
static void intern_blocks(struct block *);
static int eq_slist(struct slist *, struct slist *);
static void find_levels_r(struct block *);
static void find_levels(struct block *);
static void find_dom(struct block *);
static void propedom(struct edge *);
static void find_edom(struct block *);
static void find_closure(struct block *);
static int atomuse(struct stmt *);
static int atomdef(struct stmt *);
static void compute_local_ud(struct block *);
static void find_ud(struct block *);
static void init_val(void);
static int F(int, int, int);
static inline void vstore(struct stmt *, int *, int, int);
static void opt_blk(struct block *, int);
static int use_conflict(struct block *, struct block *);
static void opt_j(struct edge *);
static void or_pullup(struct block *);
static void and_pullup(struct block *);
static void opt_blks(struct block *, int);
static inline void link_inedge(struct edge *, struct block *);
static void find_inedges(struct block *);
static void opt_root(struct block **);
static void opt_loop(struct block *, int);
static void fold_op(struct stmt *, int, int);
static inline struct slist *this_op(struct slist *);
static void opt_not(struct block *);
static void opt_peep(struct block *);
static void opt_stmt(struct stmt *, int[], int);
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 u_int slength(struct slist *);
static int count_blocks(struct block *);
static void number_blks_r(struct block *);
static u_int count_stmts(struct block *);
static int convert_code_r(struct block *);
#ifdef BDEBUG
static void opt_dump(struct block *);
#endif
@ -232,8 +190,7 @@ static uset all_edge_sets;
#endif
static void
find_levels_r(b)
struct block *b;
find_levels_r(struct block *b)
{
int level;
@ -261,8 +218,7 @@ find_levels_r(b)
* with the 'link' field of the struct block.
*/
static void
find_levels(root)
struct block *root;
find_levels(struct block *root)
{
memset((char *)levels, 0, n_blocks * sizeof(*levels));
unMarkAll();
@ -274,8 +230,7 @@ find_levels(root)
* Assumes graph has been leveled.
*/
static void
find_dom(root)
struct block *root;
find_dom(struct block *root)
{
int i;
struct block *b;
@ -305,8 +260,7 @@ find_dom(root)
}
static void
propedom(ep)
struct edge *ep;
propedom(struct edge *ep)
{
SET_INSERT(ep->edom, ep->id);
if (ep->succ) {
@ -320,8 +274,7 @@ propedom(ep)
* Assumes graph has been leveled and predecessors established.
*/
static void
find_edom(root)
struct block *root;
find_edom(struct block *root)
{
int i;
uset x;
@ -350,8 +303,7 @@ find_edom(root)
* Assumes graph has been leveled.
*/
static void
find_closure(root)
struct block *root;
find_closure(struct block *root)
{
int i;
struct block *b;
@ -381,8 +333,7 @@ find_closure(root)
* The implementation should probably change to an array access.
*/
static int
atomuse(s)
struct stmt *s;
atomuse(struct stmt *s)
{
register int c = s->code;
@ -427,8 +378,7 @@ atomuse(s)
* The implementation should probably change to an array access.
*/
static int
atomdef(s)
struct stmt *s;
atomdef(struct stmt *s)
{
if (s->code == NOP)
return -1;
@ -464,8 +414,7 @@ atomdef(s)
* register by a predecessor block of this block.
*/
static void
compute_local_ud(b)
struct block *b;
compute_local_ud(struct block *b)
{
struct slist *s;
atomset def = 0, use = 0, kill = 0;
@ -526,8 +475,7 @@ compute_local_ud(b)
* Assume graph is already leveled.
*/
static void
find_ud(root)
struct block *root;
find_ud(struct block *root)
{
int i, maxlevel;
struct block *p;
@ -582,7 +530,7 @@ struct valnode *vnode_base;
struct valnode *next_vnode;
static void
init_val()
init_val(void)
{
curval = 0;
next_vnode = vnode_base;
@ -592,9 +540,7 @@ init_val()
/* Because we really don't have an IR, this stuff is a little messy. */
static int
F(code, v0, v1)
int code;
int v0, v1;
F(int code, int v0, int v1)
{
u_int hash;
int val;
@ -625,11 +571,7 @@ F(code, v0, v1)
}
static inline void
vstore(s, valp, newval, alter)
struct stmt *s;
int *valp;
int newval;
int alter;
vstore(struct stmt *s, int *valp, int newval, int alter)
{
if (alter && *valp == newval)
s->code = NOP;
@ -638,9 +580,7 @@ vstore(s, valp, newval, alter)
}
static void
fold_op(s, v0, v1)
struct stmt *s;
int v0, v1;
fold_op(struct stmt *s, int v0, int v1)
{
bpf_u_int32 a, b;
@ -695,8 +635,7 @@ fold_op(s, v0, v1)
}
static inline struct slist *
this_op(s)
struct slist *s;
this_op(struct slist *s)
{
while (s != 0 && s->s.code == NOP)
s = s->next;
@ -704,8 +643,7 @@ this_op(s)
}
static void
opt_not(b)
struct block *b;
opt_not(struct block *b)
{
struct block *tmp = JT(b);
@ -714,8 +652,7 @@ opt_not(b)
}
static void
opt_peep(b)
struct block *b;
opt_peep(struct block *b)
{
struct slist *s;
struct slist *next, *last;
@ -978,10 +915,7 @@ opt_peep(b)
* evaluation and code transformations weren't folded together.
*/
static void
opt_stmt(s, val, alter)
struct stmt *s;
int val[];
int alter;
opt_stmt(struct stmt *s, int val[], int alter)
{
int op;
int v;
@ -1166,9 +1100,7 @@ opt_stmt(s, val, alter)
}
static void
deadstmt(s, last)
register struct stmt *s;
register struct stmt *last[];
deadstmt(register struct stmt *s, register struct stmt *last[])
{
register int atom;
@ -1192,8 +1124,7 @@ deadstmt(s, last)
}
static void
opt_deadstores(b)
register struct block *b;
opt_deadstores(register struct block *b)
{
register struct slist *s;
register int atom;
@ -1213,9 +1144,7 @@ opt_deadstores(b)
}
static void
opt_blk(b, do_stmts)
struct block *b;
int do_stmts;
opt_blk(struct block *b, int do_stmts)
{
struct slist *s;
struct edge *p;
@ -1319,8 +1248,7 @@ opt_blk(b, do_stmts)
* from 'b'.
*/
static int
use_conflict(b, succ)
struct block *b, *succ;
use_conflict(struct block *b, struct block *succ)
{
int atom;
atomset use = succ->out_use;
@ -1336,9 +1264,7 @@ use_conflict(b, succ)
}
static struct block *
fold_edge(child, ep)
struct block *child;
struct edge *ep;
fold_edge(struct block *child, struct edge *ep)
{
int sense;
int aval0, aval1, oval0, oval1;
@ -1390,8 +1316,7 @@ fold_edge(child, ep)
}
static void
opt_j(ep)
struct edge *ep;
opt_j(struct edge *ep)
{
register int i, k;
register struct block *target;
@ -1446,8 +1371,7 @@ opt_j(ep)
static void
or_pullup(b)
struct block *b;
or_pullup(struct block *b)
{
int val, at_top;
struct block *pull;
@ -1539,8 +1463,7 @@ or_pullup(b)
}
static void
and_pullup(b)
struct block *b;
and_pullup(struct block *b)
{
int val, at_top;
struct block *pull;
@ -1631,9 +1554,7 @@ and_pullup(b)
}
static void
opt_blks(root, do_stmts)
struct block *root;
int do_stmts;
opt_blks(struct block *root, int do_stmts)
{
int i, maxlevel;
struct block *p;
@ -1670,17 +1591,14 @@ opt_blks(root, do_stmts)
}
static inline void
link_inedge(parent, child)
struct edge *parent;
struct block *child;
link_inedge(struct edge *parent, struct block *child)
{
parent->next = child->in_edges;
child->in_edges = parent;
}
static void
find_inedges(root)
struct block *root;
find_inedges(struct block *root)
{
int i;
struct block *b;
@ -1701,8 +1619,7 @@ find_inedges(root)
}
static void
opt_root(b)
struct block **b;
opt_root(struct block **b)
{
struct slist *tmp, *s;
@ -1726,9 +1643,7 @@ opt_root(b)
}
static void
opt_loop(root, do_stmts)
struct block *root;
int do_stmts;
opt_loop(struct block *root, int do_stmts)
{
#ifdef BDEBUG
@ -1758,8 +1673,7 @@ opt_loop(root, do_stmts)
* Optimize the filter code in its dag representation.
*/
void
bpf_optimize(rootp)
struct block **rootp;
bpf_optimize(struct block **rootp)
{
struct block *root;
@ -1786,8 +1700,7 @@ bpf_optimize(rootp)
}
static void
make_marks(p)
struct block *p;
make_marks(struct block *p)
{
if (!isMarked(p)) {
Mark(p);
@ -1803,8 +1716,7 @@ make_marks(p)
* only for nodes that are alive.
*/
static void
mark_code(p)
struct block *p;
mark_code(struct block *p)
{
cur_mark += 1;
make_marks(p);
@ -1815,8 +1727,7 @@ mark_code(p)
* the accumulator.
*/
static int
eq_slist(x, y)
struct slist *x, *y;
eq_slist(struct slist *x, struct slist *y)
{
while (1) {
while (x && x->s.code == NOP)
@ -1835,8 +1746,7 @@ eq_slist(x, y)
}
static inline int
eq_blk(b0, b1)
struct block *b0, *b1;
eq_blk(struct block *b0, struct block *b1)
{
if (b0->s.code == b1->s.code &&
b0->s.k == b1->s.k &&
@ -1847,8 +1757,7 @@ eq_blk(b0, b1)
}
static void
intern_blocks(root)
struct block *root;
intern_blocks(struct block *root)
{
struct block *p;
int i, j;
@ -1891,7 +1800,7 @@ intern_blocks(root)
}
static void
opt_cleanup()
opt_cleanup(void)
{
free((void *)vnode_base);
free((void *)vmap);
@ -1905,8 +1814,7 @@ opt_cleanup()
* Return the number of stmts in 's'.
*/
static u_int
slength(s)
struct slist *s;
slength(struct slist *s)
{
u_int n = 0;
@ -1921,8 +1829,7 @@ slength(s)
* All nodes should be initially unmarked.
*/
static int
count_blocks(p)
struct block *p;
count_blocks(struct block *p)
{
if (p == 0 || isMarked(p))
return 0;
@ -1935,8 +1842,7 @@ count_blocks(p)
* the basic blocks, and entering them into the 'blocks' array.`
*/
static void
number_blks_r(p)
struct block *p;
number_blks_r(struct block *p)
{
int n;
@ -1971,8 +1877,7 @@ number_blks_r(p)
* an extra long jump if the false branch requires it (p->longjf).
*/
static u_int
count_stmts(p)
struct block *p;
count_stmts(struct block *p)
{
u_int n;
@ -1989,8 +1894,7 @@ count_stmts(p)
* from the total number of blocks and/or statements.
*/
static void
opt_init(root)
struct block *root;
opt_init(struct block *root)
{
bpf_u_int32 *p;
int i, n, max_stmts;
@ -2088,8 +1992,7 @@ int bids[1000];
* properly.
*/
static int
convert_code_r(p)
struct block *p;
convert_code_r(struct block *p)
{
struct bpf_insn *dst;
struct slist *src;
@ -2261,9 +2164,7 @@ convert_code_r(p)
* done with the filter program. See the pcap man page.
*/
struct bpf_insn *
icode_to_fcode(root, lenp)
struct block *root;
u_int *lenp;
icode_to_fcode(struct block *root, u_int *lenp)
{
u_int n;
struct bpf_insn *fp;
@ -2333,8 +2234,7 @@ install_bpf_program(pcap_t *p, struct bpf_program *fp)
#ifdef BDEBUG
static void
opt_dump(root)
struct block *root;
opt_dump(struct block *root)
{
struct bpf_program f;

View file

@ -124,14 +124,6 @@ static int bpf_load(char *errbuf);
#include "pcap-int.h"
#ifdef HAVE_DAG_API
#include "pcap-dag.h"
#endif /* HAVE_DAG_API */
#ifdef HAVE_SNF_API
#include "pcap-snf.h"
#endif /* HAVE_SNF_API */
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
@ -220,30 +212,21 @@ pcap_setnonblock_bpf(pcap_t *p, int nonblock, char *errbuf)
#ifdef HAVE_ZEROCOPY_BPF
if (p->md.zerocopy) {
/*
* Map each value to the corresponding 2's complement, to
* Map each value to their corresponding negation to
* preserve the timeout value provided with pcap_set_timeout.
* (from pcap-linux.c).
*/
if (nonblock) {
if (p->md.timeout >= 0) {
/*
* Timeout is non-negative, so we're not
* currently in non-blocking mode; set it
* to the 2's complement, to make it
* negative, as an indication that we're
* in non-blocking mode.
* Indicate that we're switching to
* non-blocking mode.
*/
p->md.timeout = p->md.timeout * -1 - 1;
p->md.timeout = ~p->md.timeout;
}
} else {
if (p->md.timeout < 0) {
/*
* Timeout is negative, so we're currently
* in blocking mode; reverse the previous
* operation, to make the timeout non-negative
* again.
*/
p->md.timeout = (p->md.timeout + 1) * -1;
p->md.timeout = ~p->md.timeout;
}
}
return (0);
@ -409,19 +392,10 @@ pcap_ack_zbuf(pcap_t *p)
#endif /* HAVE_ZEROCOPY_BPF */
pcap_t *
pcap_create(const char *device, char *ebuf)
pcap_create_interface(const char *device, char *ebuf)
{
pcap_t *p;
#ifdef HAVE_DAG_API
if (strstr(device, "dag"))
return (dag_create(device, ebuf));
#endif /* HAVE_DAG_API */
#ifdef HAVE_SNF_API
if (strstr(device, "snf"))
return (snf_create(device, ebuf));
#endif /* HAVE_SNF_API */
p = pcap_create_common(device, ebuf);
if (p == NULL)
return (NULL);
@ -1720,7 +1694,7 @@ pcap_activate_bpf(pcap_t *p)
pcap_strerror(errno));
goto bad;
}
bzero(&bz, sizeof(bz));
memset(&bz, 0, sizeof(bz)); /* bzero() deprecated, replaced with memset() */
bz.bz_bufa = p->md.zbuf1;
bz.bz_bufb = p->md.zbuf2;
bz.bz_buflen = p->md.zbufsize;
@ -2303,15 +2277,6 @@ pcap_activate_bpf(pcap_t *p)
int
pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
{
#ifdef HAVE_DAG_API
if (dag_platform_finddevs(alldevsp, errbuf) < 0)
return (-1);
#endif /* HAVE_DAG_API */
#ifdef HAVE_SNF_API
if (snf_platform_finddevs(alldevsp, errbuf) < 0)
return (-1);
#endif /* HAVE_SNF_API */
return (0);
}

View file

@ -71,14 +71,14 @@ static int bt_setdirection_linux(pcap_t *, pcap_direction_t);
static int bt_stats_linux(pcap_t *, struct pcap_stat *);
int
bt_platform_finddevs(pcap_if_t **alldevsp, char *err_str)
bt_findalldevs(pcap_if_t **alldevsp, char *err_str)
{
pcap_if_t *found_dev = *alldevsp;
struct hci_dev_list_req *dev_list;
struct hci_dev_req *dev_req;
int i, sock;
int ret = 0;
sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
if (sock < 0)
{
@ -135,10 +135,40 @@ bt_platform_finddevs(pcap_if_t **alldevsp, char *err_str)
}
pcap_t *
bt_create(const char *device, char *ebuf)
bt_create(const char *device, char *ebuf, int *is_ours)
{
const char *cp;
char *cpend;
long devnum;
pcap_t *p;
/* Does this look like a Bluetooth device? */
cp = strrchr(device, '/');
if (cp == NULL)
cp = device;
/* Does it begin with BT_IFACE? */
if (strncmp(cp, BT_IFACE, sizeof BT_IFACE - 1) != 0) {
/* Nope, doesn't begin with BT_IFACE */
*is_ours = 0;
return NULL;
}
/* Yes - is BT_IFACE followed by a number? */
cp += sizeof BT_IFACE - 1;
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(device, ebuf);
if (p == NULL)
return (NULL);
@ -224,6 +254,9 @@ bt_activate(pcap_t* handle)
/* Bind socket to the HCI device */
addr.hci_family = AF_BLUETOOTH;
addr.hci_dev = handle->md.ifindex;
#ifdef SOCKADDR_HCI_HAS_HCI_CHANNEL
addr.hci_channel = HCI_CHANNEL_RAW;
#endif
if (bind(handle->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't attach to device %d: %s", handle->md.ifindex,

View file

@ -36,5 +36,5 @@
/*
* Prototypes for Bluetooth-related functions
*/
int bt_platform_finddevs(pcap_if_t **alldevsp, char *err_str);
pcap_t *bt_create(const char *device, char *ebuf);
int bt_findalldevs(pcap_if_t **alldevsp, char *err_str);
pcap_t *bt_create(const char *device, char *ebuf, int *is_ours);

View file

@ -72,11 +72,58 @@ 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)
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(device, ebuf);
if (p == NULL)
return (NULL);

View file

@ -32,4 +32,5 @@
/*
* Prototypes for SocketCAN related functions
*/
pcap_t* can_create(const char *device, char *ebuf);
pcap_t* can_create(const char *device, char *ebuf, int *is_ours);
int can_findalldevs(pcap_if_t **devlistp, char *errbuf);

View file

@ -75,20 +75,18 @@ struct CAN_Msg
struct canusb_t
{
libusb_context *ctx;
libusb_device_handle *dev;
char* src;
pthread_t worker;
int rdpipe, wrpipe;
volatile int* loop;
libusb_context *ctx;
libusb_device_handle *dev;
char *serial;
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)
int canusb_findalldevs(pcap_if_t **alldevsp, char *err_str)
{
libusb_context *fdctx;
libusb_device** devs;
@ -96,8 +94,15 @@ int canusb_platform_finddevs(pcap_if_t **alldevsp, char *err_str)
unsigned char buf[96];
int cnt, i;
libusb_init(&fdctx);
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++)
@ -108,27 +113,27 @@ int canusb_platform_finddevs(pcap_if_t **alldevsp, char *err_str)
libusb_get_device_descriptor(devs[i],&desc);
if ((desc.idVendor != CANUSB_VID) || (desc.idProduct != CANUSB_PID))
continue; //It is not, check next device
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];
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);
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);
return -1;
}
}
}
@ -199,144 +204,176 @@ static libusb_device_handle* canusb_opendevice(struct libusb_context *ctx, char*
pcap_t *
canusb_create(const char *device, char *ebuf)
canusb_create(const char *device, char *ebuf, int *is_ours)
{
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);
const char *cp;
char *cpend;
long devnum;
pcap_t* p;
libusb_init(&canusb.ctx);
/* 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(device, ebuf);
if (p == NULL)
return (NULL);
memset(&canusb, 0x00, sizeof(canusb));
p->activate_op = canusb_activate;
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++)
struct libusb_context *ctx;
libusb_device_handle *dev;
int i, n;
struct
{
libusb_bulk_transfer(dev, 0x85, (unsigned char*)&msg, sizeof(msg), &sz, 100);
n = write(canusb->wrpipe, &msg, sizeof(msg));
}
uint8_t rxsz, txsz;
} status;
char *serial;
libusb_init(&ctx);
serial = canusb->serial;
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);
libusb_close(dev);
libusb_exit(ctx);
return NULL;
return NULL;
}
static int canusb_startcapture(struct canusb_t* this)
{
int pipefd[2];
int pipefd[2];
if (pipe(pipefd) == -1) return -1;
if (pipe(pipefd) == -1)
return -1;
canusb.rdpipe = pipefd[0];
canusb.wrpipe = pipefd[1];
canusb.loop = &loop;
canusb.rdpipe = pipefd[0];
canusb.wrpipe = pipefd[1];
canusb.loop = &loop;
loop = 1;
pthread_create(&this->worker, NULL, canusb_capture_thread, &canusb);
loop = 1;
pthread_create(&this->worker, NULL, canusb_capture_thread, &canusb);
return canusb.rdpipe;
return canusb.rdpipe;
}
static void canusb_clearbufs(struct canusb_t* this)
{
unsigned char cmd[16];
int al;
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);
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);
libusb_interrupt_transfer(this->dev, 0x1,cmd,16,&al,100);
}
static void canusb_close(pcap_t* handle)
{
loop = 0;
pthread_join(canusb.worker, NULL);
loop = 0;
pthread_join(canusb.worker, NULL);
if (canusb.dev)
{
libusb_close(canusb.dev);
canusb.dev = NULL;
}
if (canusb.dev)
{
libusb_close(canusb.dev);
canusb.dev = NULL;
}
}
static int canusb_activate(pcap_t* handle)
{
handle->read_op = canusb_read_linux;
char *serial;
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;
handle->read_op = canusb_read_linux;
/* Initialize some components of the pcap structure. */
handle->bufsize = 32;
handle->offset = 8;
handle->linktype = DLT_CAN_SOCKETCAN;
handle->set_datalink_op = NULL;
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;
char* serial = handle->opt.source + strlen("canusb");
/* Initialize some components of the pcap structure. */
handle->bufsize = 32;
handle->offset = 8;
handle->linktype = DLT_CAN_SOCKETCAN;
handle->set_datalink_op = NULL;
canusb.dev = canusb_opendevice(canusb.ctx,serial);
if (!canusb.dev)
{
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't open USB Device:");
return PCAP_ERROR;
}
serial = handle->opt.source + strlen(CANUSB_IFACE);
canusb.serial = strdup(serial);
canusb_clearbufs(&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;
}
handle->fd = canusb_startcapture(&canusb);
handle->selectable_fd = handle->fd;
return 0;
canusb_clearbufs(&canusb);
handle->fd = canusb_startcapture(&canusb);
handle->selectable_fd = handle->fd;
return 0;
}
@ -345,83 +382,85 @@ static int canusb_activate(pcap_t* handle)
static int
canusb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
{
static struct timeval firstpacket = { -1, -1};
static struct timeval firstpacket = { -1, -1};
int msgsent = 0;
int i = 0;
struct CAN_Msg msg;
struct pcap_pkthdr pkth;
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)
while(i < max_packets)
{
pkth.ts.tv_usec -= 1000000;
pkth.ts.tv_sec++;
}
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++;
}
callback(user, &pkth, (void*)&msg.id);
i++;
}
return 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);
/* 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;
/* 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;
/* 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;
}
/* 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;
p->direction = d;
return 0;
return 0;
}

View file

@ -32,6 +32,6 @@
/*
* Prototypes for SocketCAN related functions
*/
pcap_t* canusb_create(const char *device, char *ebuf);
int canusb_listdevices(pcap_if_t **pdevlist, char* errbuf);
pcap_t* canusb_create(const char *device, char *ebuf, int *is_ours);
int canusb_findalldevs(pcap_if_t **pdevlist, char* errbuf);

View file

@ -841,7 +841,7 @@
#define LINKTYPE_NETANALYZER_TRANSPARENT 241
/*
* IP-over-Infiniband, as specified by RFC 4391.
* IP-over-InfiniBand, as specified by RFC 4391.
*
* Requested by Petr Sumbera <petr.sumbera@oracle.com>.
*/
@ -883,7 +883,21 @@
*/
#define LINKTYPE_PFSYNC 246
#define LINKTYPE_MATCHING_MAX 246 /* highest value in the "matching" range */
/*
* Raw InfiniBand packets, starting with the Local Routing Header.
*
* Requested by Oren Kladnitsky <orenk@mellanox.com>.
*/
#define LINKTYPE_INFINIBAND 247
/*
* SCTP, with no lower-level protocols (i.e., no IPv4 or IPv6).
*
* Requested by Michael Tuexen <Michael.Tuexen@lurchi.franken.de>.
*/
#define LINKTYPE_SCTP 248
#define LINKTYPE_MATCHING_MAX 248 /* highest value in the "matching" range */
static struct linktype_map {
int dlt;

View file

@ -48,6 +48,12 @@ struct rtentry; /* declarations in <net/if.h> */
#include "pcap-dag.h"
/*
* DAG devices have names beginning with "dag", followed by a number
* from 0 to MAXDAG.
*/
#define MAXDAG 31
#define ATM_CELL_SIZE 52
#define ATM_HDR_SIZE 4
@ -82,15 +88,6 @@ static const unsigned short endian_test_word = 0x0100;
#define IS_BIGENDIAN() (*((unsigned char *)&endian_test_word))
#ifdef DAG_ONLY
/* This code is required when compiling for a DAG device only. */
/* Replace dag function names with pcap equivalent. */
#define dag_create pcap_create
#define dag_platform_finddevs pcap_platform_finddevs
#endif /* DAG_ONLY */
#define MAX_DAG_PACKET 65536
static unsigned char TempPkt[MAX_DAG_PACKET];
@ -835,10 +832,40 @@ static int dag_activate(pcap_t* handle)
return PCAP_ERROR;
}
pcap_t *dag_create(const char *device, char *ebuf)
pcap_t *dag_create(const char *device, char *ebuf, int *is_ours)
{
const char *cp;
char *cpend;
long devnum;
pcap_t *p;
/* Does this look like a DAG device? */
cp = strrchr(device, '/');
if (cp == NULL)
cp = device;
/* Does it begin with "dag"? */
if (strncmp(cp, "dag", 3) != 0) {
/* Nope, doesn't begin with "dag" */
*is_ours = 0;
return NULL;
}
/* Yes - is "dag" followed by a number from 0 to MAXDAG? */
cp += 3;
devnum = strtol(cp, &cpend, 10);
if (cpend == cp || *cpend != '\0') {
/* Not followed by a number. */
*is_ours = 0;
return NULL;
}
if (devnum < 0 || devnum > MAXDAG) {
/* Followed by a non-valid number. */
*is_ours = 0;
return NULL;
}
/* OK, it's probably ours. */
*is_ours = 1;
p = pcap_create_common(device, ebuf);
if (p == NULL)
return NULL;
@ -870,7 +897,7 @@ dag_stats(pcap_t *p, struct pcap_stat *ps) {
* open attempts will still be much less than the naive approach.
*/
int
dag_platform_finddevs(pcap_if_t **devlistp, char *errbuf)
dag_findalldevs(pcap_if_t **devlistp, char *errbuf)
{
char name[12]; /* XXX - pick a size */
int ret = 0;
@ -879,8 +906,8 @@ dag_platform_finddevs(pcap_if_t **devlistp, char *errbuf)
int dagstream;
int dagfd;
/* Try all the DAGs 0-31 */
for (c = 0; c < 32; c++) {
/* Try all the DAGs 0-MAXDAG */
for (c = 0; c <= MAXDAG; c++) {
snprintf(name, 12, "dag%d", c);
if (-1 == dag_parse_name(name, dagname, DAGNAME_BUFSIZE, &dagstream))
{

View file

@ -10,8 +10,8 @@
* @(#) $Header: /tcpdump/master/libpcap/pcap-dag.h,v 1.7 2008-04-04 19:37:45 guy Exp $ (LBL)
*/
pcap_t *dag_create(const char *, char *);
int dag_platform_finddevs(pcap_if_t **devlistp, char *errbuf);
pcap_t *dag_create(const char *, char *, int *);
int dag_findalldevs(pcap_if_t **devlistp, char *errbuf);
#ifndef TYPE_AAL5
#define TYPE_AAL5 4

View file

@ -1693,7 +1693,7 @@ dlpi_kread(register int fd, register off_t addr,
#endif
pcap_t *
pcap_create(const char *device, char *ebuf)
pcap_create_interface(const char *device, char *ebuf)
{
pcap_t *p;

View file

@ -45,6 +45,7 @@ Primitives usually consist of an
There are three
different kinds of qualifier:
.IP \fItype\fP
.I type
qualifiers say what kind of thing the id name or number refers to.
Possible types are
.BR host ,
@ -58,6 +59,7 @@ qualifier,
.B host
is assumed.
.IP \fIdir\fP
.I dir
qualifiers specify a particular transfer direction to and/or from
.IR id .
Possible directions are
@ -93,6 +95,7 @@ and
.B outbound
qualifiers can be used to specify a desired direction.
.IP \fIproto\fP
.I proto
qualifiers restrict the match to a particular protocol.
Possible
protos are:
@ -159,7 +162,7 @@ True if the IPv4/v6 destination field of the packet is \fIhost\fP,
which may be either an address or a name.
.IP "\fBsrc host \fIhost\fR"
True if the IPv4/v6 source field of the packet is \fIhost\fP.
.IP "\fBhost \fIhost\fP
.IP "\fBhost \fIhost\fP"
True if either the IPv4/v6 source or destination of the packet is \fIhost\fP.
.IP
Any of the above host expressions can be prepended with the keywords,
@ -177,17 +180,17 @@ which is equivalent to:
.in -.5i
If \fIhost\fR is a name with multiple IP addresses, each address will
be checked for a match.
.IP "\fBether dst \fIehost\fP
.IP "\fBether dst \fIehost\fP"
True if the Ethernet destination address is \fIehost\fP.
\fIEhost\fP
may be either a name from /etc/ethers or a number (see
.IR ethers (3N)
for numeric format).
.IP "\fBether src \fIehost\fP
.IP "\fBether src \fIehost\fP"
True if the Ethernet source address is \fIehost\fP.
.IP "\fBether host \fIehost\fP
.IP "\fBether host \fIehost\fP"
True if either the Ethernet source or destination address is \fIehost\fP.
.IP "\fBgateway\fP \fIhost\fP
.IP "\fBgateway\fP \fIhost\fP"
True if the packet used \fIhost\fP as a gateway.
I.e., the Ethernet
source or destination address was \fIhost\fP but neither the IP source
@ -302,6 +305,18 @@ Note that this primitive does not chase the protocol header chain.
.IP "\fBip6 proto \fIprotocol\fR"
True if the packet is an IPv6 packet of protocol type \fIprotocol\fP.
Note that this primitive does not chase the protocol header chain.
.IP "\fBproto \fIprotocol\fR"
True if the packet is an IPv4 or IPv6 packet of protocol type
\fIprotocol\fP. Note that this primitive does not chase the protocol
header chain.
.IP "\fBtcp\fR, \fBudp\fR, \fBicmp\fR"
Abbreviations for:
.in +.5i
.nf
\fBproto \fIp\fR\fB
.fi
.in -.5i
where \fIp\fR is one of the above protocols.
.IP "\fBip6 protochain \fIprotocol\fR"
True if the packet is IPv6 packet,
and contains protocol header with type \fIprotocol\fR
@ -321,6 +336,10 @@ cannot be optimized by the BPF optimizer code, so this can be somewhat
slow.
.IP "\fBip protochain \fIprotocol\fR"
Equivalent to \fBip6 protochain \fIprotocol\fR, but this is for IPv4.
.IP "\fBprotochain \fIprotocol\fR"
True if the packet is an IPv4 or IPv6 packet of protocol type
\fIprotocol\fP. Note that this primitive chases the protocol
header chain.
.IP "\fBether broadcast\fR"
True if the packet is an Ethernet broadcast packet.
The \fIether\fP
@ -402,6 +421,25 @@ the filter checks for the IPX etype in an Ethernet frame, the IPX
DSAP in the LLC header, the 802.3-with-no-LLC-header encapsulation of
IPX, and the IPX etype in a SNAP frame.
.RE
.IP "\fBip\fR, \fBip6\fR, \fBarp\fR, \fBrarp\fR, \fBatalk\fR, \fBaarp\fR, \fBdecnet\fR, \fBiso\fR, \fBstp\fR, \fBipx\fR, \fBnetbeui\fP"
Abbreviations for:
.in +.5i
.nf
\fBether proto \fIp\fR
.fi
.in -.5i
where \fIp\fR is one of the above protocols.
.IP "\fBlat\fR, \fBmoprc\fR, \fBmopdl\fR"
Abbreviations for:
.in +.5i
.nf
\fBether proto \fIp\fR
.fi
.in -.5i
where \fIp\fR is one of the above protocols.
Note that not all applications using
.BR pcap (3PCAP)
currently know how to parse these protocols.
.IP "\fBdecnet src \fIhost\fR"
True if the DECNET source address is
.IR host ,
@ -503,25 +541,6 @@ True if the fourth IEEE 802.11 address, if present, is
.IR ehost .
The fourth address field is only used for
WDS (Wireless Distribution System) frames.
.IP "\fBip\fR, \fBip6\fR, \fBarp\fR, \fBrarp\fR, \fBatalk\fR, \fBaarp\fR, \fBdecnet\fR, \fBiso\fR, \fBstp\fR, \fBipx\fR, \fBnetbeui\fP"
Abbreviations for:
.in +.5i
.nf
\fBether proto \fIp\fR
.fi
.in -.5i
where \fIp\fR is one of the above protocols.
.IP "\fBlat\fR, \fBmoprc\fR, \fBmopdl\fR"
Abbreviations for:
.in +.5i
.nf
\fBether proto \fIp\fR
.fi
.in -.5i
where \fIp\fR is one of the above protocols.
Note that not all applications using
.BR pcap (3)
currently know how to parse these protocols.
.IP "\fBtype \fIwlan_type\fR"
True if the IEEE 802.11 frame type matches the specified \fIwlan_type\fR.
Valid \fIwlan_type\fRs are:
@ -652,14 +671,6 @@ For example:
.fi
.in -.5i
filters IPv4 protocols encapsulated in PPPoE.
.IP "\fBtcp\fR, \fBudp\fR, \fBicmp\fR"
Abbreviations for:
.in +.5i
.nf
\fBip proto \fIp\fR\fB or ip6 proto \fIp\fR
.fi
.in -.5i
where \fIp\fR is one of the above protocols.
.IP "\fBiso proto \fIprotocol\fR"
True if the packet is an OSI packet of protocol type \fIprotocol\fP.
\fIProtocol\fP can be a number or one of the names
@ -674,11 +685,11 @@ Abbreviations for:
where \fIp\fR is one of the above protocols.
.IP "\fBl1\fR, \fBl2\fR, \fBiih\fR, \fBlsp\fR, \fBsnp\fR, \fBcsnp\fR, \fBpsnp\fR"
Abbreviations for IS-IS PDU types.
.IP "\fBvpi\fP \fIn\fR
.IP "\fBvpi\fP \fIn\fR"
True if the packet is an ATM packet, for SunATM on Solaris, with a
virtual path identifier of
.IR n .
.IP "\fBvci\fP \fIn\fR
.IP "\fBvci\fP \fIn\fR"
True if the packet is an ATM packet, for SunATM on Solaris, with a
virtual channel identifier of
.IR n .
@ -783,8 +794,7 @@ The following ICMP type field values are available: \fBicmp-echoreply\fP,
The following TCP flags field values are available: \fBtcp-fin\fP,
\fBtcp-syn\fP, \fBtcp-rst\fP, \fBtcp-push\fP,
\fBtcp-ack\fP, \fBtcp-urg\fP, \fBtcp-ece\fP,
\fBtcp-cwr\fP.
\fBtcp-ack\fP, \fBtcp-urg\fP.
.LP
Primitives may be combined using:
.IP
@ -919,27 +929,6 @@ icmp[icmptype] != icmp-echo and icmp[icmptype] != icmp-echoreply
.RE
.SH "SEE ALSO"
pcap(3PCAP)
.SH AUTHORS
The original authors are:
.LP
Van Jacobson,
Craig Leres and
Steven McCanne, all of the
Lawrence Berkeley National Laboratory, University of California, Berkeley, CA.
.LP
It is currently being maintained by tcpdump.org.
.LP
The current version of libpcap is available via http:
.LP
.RS
.I http://www.tcpdump.org/
.RE
.LP
The original distribution is available via anonymous ftp:
.LP
.RS
.I ftp://ftp.ee.lbl.gov/tcpdump.tar.Z
.RE
.SH BUGS
Please send problems, bugs, questions, desirable enhancements, etc. to:
.LP

View file

@ -45,6 +45,7 @@ Primitives usually consist of an
There are three
different kinds of qualifier:
.IP \fItype\fP
.I type
qualifiers say what kind of thing the id name or number refers to.
Possible types are
.BR host ,
@ -58,6 +59,7 @@ qualifier,
.B host
is assumed.
.IP \fIdir\fP
.I dir
qualifiers specify a particular transfer direction to and/or from
.IR id .
Possible directions are
@ -93,6 +95,7 @@ and
.B outbound
qualifiers can be used to specify a desired direction.
.IP \fIproto\fP
.I proto
qualifiers restrict the match to a particular protocol.
Possible
protos are:
@ -159,7 +162,7 @@ True if the IPv4/v6 destination field of the packet is \fIhost\fP,
which may be either an address or a name.
.IP "\fBsrc host \fIhost\fR"
True if the IPv4/v6 source field of the packet is \fIhost\fP.
.IP "\fBhost \fIhost\fP
.IP "\fBhost \fIhost\fP"
True if either the IPv4/v6 source or destination of the packet is \fIhost\fP.
.IP
Any of the above host expressions can be prepended with the keywords,
@ -177,17 +180,17 @@ which is equivalent to:
.in -.5i
If \fIhost\fR is a name with multiple IP addresses, each address will
be checked for a match.
.IP "\fBether dst \fIehost\fP
.IP "\fBether dst \fIehost\fP"
True if the Ethernet destination address is \fIehost\fP.
\fIEhost\fP
may be either a name from /etc/ethers or a number (see
.IR ethers (3N)
for numeric format).
.IP "\fBether src \fIehost\fP
.IP "\fBether src \fIehost\fP"
True if the Ethernet source address is \fIehost\fP.
.IP "\fBether host \fIehost\fP
.IP "\fBether host \fIehost\fP"
True if either the Ethernet source or destination address is \fIehost\fP.
.IP "\fBgateway\fP \fIhost\fP
.IP "\fBgateway\fP \fIhost\fP"
True if the packet used \fIhost\fP as a gateway.
I.e., the Ethernet
source or destination address was \fIhost\fP but neither the IP source
@ -302,6 +305,18 @@ Note that this primitive does not chase the protocol header chain.
.IP "\fBip6 proto \fIprotocol\fR"
True if the packet is an IPv6 packet of protocol type \fIprotocol\fP.
Note that this primitive does not chase the protocol header chain.
.IP "\fBproto \fIprotocol\fR"
True if the packet is an IPv4 or IPv6 packet of protocol type
\fIprotocol\fP. Note that this primitive does not chase the protocol
header chain.
.IP "\fBtcp\fR, \fBudp\fR, \fBicmp\fR"
Abbreviations for:
.in +.5i
.nf
\fBproto \fIp\fR\fB
.fi
.in -.5i
where \fIp\fR is one of the above protocols.
.IP "\fBip6 protochain \fIprotocol\fR"
True if the packet is IPv6 packet,
and contains protocol header with type \fIprotocol\fR
@ -321,6 +336,10 @@ cannot be optimized by the BPF optimizer code, so this can be somewhat
slow.
.IP "\fBip protochain \fIprotocol\fR"
Equivalent to \fBip6 protochain \fIprotocol\fR, but this is for IPv4.
.IP "\fBprotochain \fIprotocol\fR"
True if the packet is an IPv4 or IPv6 packet of protocol type
\fIprotocol\fP. Note that this primitive chases the protocol
header chain.
.IP "\fBether broadcast\fR"
True if the packet is an Ethernet broadcast packet.
The \fIether\fP
@ -402,6 +421,25 @@ the filter checks for the IPX etype in an Ethernet frame, the IPX
DSAP in the LLC header, the 802.3-with-no-LLC-header encapsulation of
IPX, and the IPX etype in a SNAP frame.
.RE
.IP "\fBip\fR, \fBip6\fR, \fBarp\fR, \fBrarp\fR, \fBatalk\fR, \fBaarp\fR, \fBdecnet\fR, \fBiso\fR, \fBstp\fR, \fBipx\fR, \fBnetbeui\fP"
Abbreviations for:
.in +.5i
.nf
\fBether proto \fIp\fR
.fi
.in -.5i
where \fIp\fR is one of the above protocols.
.IP "\fBlat\fR, \fBmoprc\fR, \fBmopdl\fR"
Abbreviations for:
.in +.5i
.nf
\fBether proto \fIp\fR
.fi
.in -.5i
where \fIp\fR is one of the above protocols.
Note that not all applications using
.BR pcap (3PCAP)
currently know how to parse these protocols.
.IP "\fBdecnet src \fIhost\fR"
True if the DECNET source address is
.IR host ,
@ -503,25 +541,6 @@ True if the fourth IEEE 802.11 address, if present, is
.IR ehost .
The fourth address field is only used for
WDS (Wireless Distribution System) frames.
.IP "\fBip\fR, \fBip6\fR, \fBarp\fR, \fBrarp\fR, \fBatalk\fR, \fBaarp\fR, \fBdecnet\fR, \fBiso\fR, \fBstp\fR, \fBipx\fR, \fBnetbeui\fP"
Abbreviations for:
.in +.5i
.nf
\fBether proto \fIp\fR
.fi
.in -.5i
where \fIp\fR is one of the above protocols.
.IP "\fBlat\fR, \fBmoprc\fR, \fBmopdl\fR"
Abbreviations for:
.in +.5i
.nf
\fBether proto \fIp\fR
.fi
.in -.5i
where \fIp\fR is one of the above protocols.
Note that not all applications using
.BR pcap (3)
currently know how to parse these protocols.
.IP "\fBtype \fIwlan_type\fR"
True if the IEEE 802.11 frame type matches the specified \fIwlan_type\fR.
Valid \fIwlan_type\fRs are:
@ -652,14 +671,6 @@ For example:
.fi
.in -.5i
filters IPv4 protocols encapsulated in PPPoE.
.IP "\fBtcp\fR, \fBudp\fR, \fBicmp\fR"
Abbreviations for:
.in +.5i
.nf
\fBip proto \fIp\fR\fB or ip6 proto \fIp\fR
.fi
.in -.5i
where \fIp\fR is one of the above protocols.
.IP "\fBiso proto \fIprotocol\fR"
True if the packet is an OSI packet of protocol type \fIprotocol\fP.
\fIProtocol\fP can be a number or one of the names
@ -674,11 +685,11 @@ Abbreviations for:
where \fIp\fR is one of the above protocols.
.IP "\fBl1\fR, \fBl2\fR, \fBiih\fR, \fBlsp\fR, \fBsnp\fR, \fBcsnp\fR, \fBpsnp\fR"
Abbreviations for IS-IS PDU types.
.IP "\fBvpi\fP \fIn\fR
.IP "\fBvpi\fP \fIn\fR"
True if the packet is an ATM packet, for SunATM on Solaris, with a
virtual path identifier of
.IR n .
.IP "\fBvci\fP \fIn\fR
.IP "\fBvci\fP \fIn\fR"
True if the packet is an ATM packet, for SunATM on Solaris, with a
virtual channel identifier of
.IR n .
@ -919,27 +930,6 @@ icmp[icmptype] != icmp-echo and icmp[icmptype] != icmp-echoreply
.RE
.SH "SEE ALSO"
pcap(3PCAP)
.SH AUTHORS
The original authors are:
.LP
Van Jacobson,
Craig Leres and
Steven McCanne, all of the
Lawrence Berkeley National Laboratory, University of California, Berkeley, CA.
.LP
It is currently being maintained by tcpdump.org.
.LP
The current version of libpcap is available via http:
.LP
.RS
.I http://www.tcpdump.org/
.RE
.LP
The original distribution is available via anonymous ftp:
.LP
.RS
.I ftp://ftp.ee.lbl.gov/tcpdump.tar.Z
.RE
.SH BUGS
Please send problems, bugs, questions, desirable enhancements, etc. to:
.LP

View file

@ -144,6 +144,7 @@ struct pcap_md {
char *mondevice; /* mac80211 monitor device we created */
u_char *mmapbuf; /* memory-mapped region pointer */
size_t mmapbuflen; /* size of region */
int vlan_offset; /* offset at which to insert vlan tags; if -1, don't insert */
u_int tp_version; /* version of tpacket_hdr for mmaped ring */
u_int tp_hdrlen; /* hdrlen of tpacket_hdr for mmaped ring */
u_char *oneshot_buffer; /* buffer for copy of packet */
@ -374,12 +375,13 @@ struct pcap_timeval {
* the old record header as well as files with the new record header
* (using the magic number to determine the header format).
*
* Then supply the changes as a patch at
* Then supply the changes by forking the branch at
*
* http://sourceforge.net/projects/libpcap/
* https://github.com/mcr/libpcap/issues
*
* so that future versions of libpcap and programs that use it (such as
* tcpdump) will be able to read your new capture file format.
* and issuing a pull request, so that future versions of libpcap and
* programs that use it (such as tcpdump) will be able to read your new
* capture file format.
*/
struct pcap_sf_pkthdr {
@ -454,6 +456,18 @@ int pcap_getnonblock_fd(pcap_t *, char *);
int pcap_setnonblock_fd(pcap_t *p, int, char *);
#endif
/*
* Internal interfaces for "pcap_create()".
*
* "pcap_create_interface()" is the routine to do a pcap_create on
* a regular network interface. There are multiple implementations
* of this, one for each platform type (Linux, BPF, DLPI, etc.),
* with the one used chosen by the configure script.
*
* "pcap_create_common()" allocates and fills in a pcap_t, for use
* by pcap_create routines.
*/
pcap_t *pcap_create_interface(const char *, char *);
pcap_t *pcap_create_common(const char *, char *);
int pcap_do_addexit(pcap_t *);
void pcap_add_to_pcaps_to_close(pcap_t *);
@ -465,12 +479,16 @@ int pcap_check_activated(pcap_t *);
/*
* Internal interfaces for "pcap_findalldevs()".
*
* "pcap_platform_finddevs()" is a platform-dependent routine to
* add devices not found by the "standard" mechanisms (SIOCGIFCONF,
* "getifaddrs()", etc..
* "pcap_findalldevs_interfaces()" finds interfaces using the
* "standard" mechanisms (SIOCGIFCONF, "getifaddrs()", etc.).
*
* "pcap_add_if()" adds an interface to the list of interfaces.
* "pcap_platform_finddevs()" is a platform-dependent routine to
* add devices not found by the "standard" mechanisms.
*
* "pcap_add_if()" adds an interface to the list of interfaces, for
* use by various "find interfaces" routines.
*/
int pcap_findalldevs_interfaces(pcap_if_t **, char *);
int pcap_platform_finddevs(pcap_if_t **, char *);
int add_addr_to_iflist(pcap_if_t **, const char *, u_int, struct sockaddr *,
size_t, struct sockaddr *, size_t, struct sockaddr *, size_t,

View file

@ -237,7 +237,7 @@ dlpromiscon(pcap_t *p, bpf_u_int32 level)
{
int err;
retv = dlpi_promiscon(p->hd, level);
retv = dlpi_promiscon(p->dlpi_hd, level);
if (retv != DLPI_SUCCESS) {
if (retv == DL_SYSERR &&
(errno == EPERM || errno == EACCES))
@ -391,7 +391,7 @@ pcap_libdlpi_err(const char *linkname, const char *func, int err, char *errbuf)
}
pcap_t *
pcap_create(const char *device, char *ebuf)
pcap_create_interface(const char *device, char *ebuf)
{
pcap_t *p;

View file

@ -127,11 +127,13 @@ static const char rcsid[] _U_ =
#include <fcntl.h>
#include <string.h>
#include <limits.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/utsname.h>
#include <sys/mman.h>
#include <linux/if.h>
#include <linux/if_packet.h>
#include <netinet/in.h>
#include <linux/if_ether.h>
#include <net/if_arp.h>
@ -142,38 +144,6 @@ static const char rcsid[] _U_ =
#include "pcap/sll.h"
#include "pcap/vlan.h"
#ifdef HAVE_DAG_API
#include "pcap-dag.h"
#endif /* HAVE_DAG_API */
#ifdef HAVE_SEPTEL_API
#include "pcap-septel.h"
#endif /* HAVE_SEPTEL_API */
#ifdef HAVE_SNF_API
#include "pcap-snf.h"
#endif /* HAVE_SNF_API */
#ifdef PCAP_SUPPORT_USB
#include "pcap-usb-linux.h"
#endif
#ifdef PCAP_SUPPORT_BT
#include "pcap-bt-linux.h"
#endif
#ifdef PCAP_SUPPORT_CAN
#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
/*
* If PF_PACKET is defined, we can use {SOCK_RAW,SOCK_DGRAM}/PF_PACKET
* sockets rather than SOCK_PACKET sockets.
@ -387,66 +357,10 @@ static struct sock_fprog total_fcode
#endif /* SO_ATTACH_FILTER */
pcap_t *
pcap_create(const char *device, char *ebuf)
pcap_create_interface(const char *device, char *ebuf)
{
pcap_t *handle;
/*
* A null device name is equivalent to the "any" device.
*/
if (device == NULL)
device = "any";
#ifdef HAVE_DAG_API
if (strstr(device, "dag")) {
return dag_create(device, ebuf);
}
#endif /* HAVE_DAG_API */
#ifdef HAVE_SEPTEL_API
if (strstr(device, "septel")) {
return septel_create(device, ebuf);
}
#endif /* HAVE_SEPTEL_API */
#ifdef HAVE_SNF_API
handle = snf_create(device, ebuf);
if (strstr(device, "snf") || handle != NULL)
return handle;
#endif /* HAVE_SNF_API */
#ifdef PCAP_SUPPORT_BT
if (strstr(device, "bluetooth")) {
return bt_create(device, ebuf);
}
#endif
#if PCAP_SUPPORT_CANUSB
if (strstr(device, "canusb")) {
return canusb_create(device, ebuf);
}
#endif
#ifdef PCAP_SUPPORT_CAN
if ((strncmp(device, "can", 3) == 0 && isdigit(device[3])) ||
(strncmp(device, "vcan", 4) == 0 && isdigit(device[4]))) {
return can_create(device, ebuf);
}
#endif
#ifdef PCAP_SUPPORT_USB
if (strstr(device, "usbmon")) {
return usb_create(device, ebuf);
}
#endif
#ifdef PCAP_SUPPORT_NETFILTER
if (strncmp(device, "nflog", strlen("nflog")) == 0) {
return nflog_create(device, ebuf);
}
#endif
handle = pcap_create_common(device, ebuf);
if (handle == NULL)
return NULL;
@ -564,7 +478,7 @@ get_mac80211_phydev(pcap_t *handle, const char *device, char *phydev_path,
return 1;
}
#ifdef HAVE_LIBNL_2_x
#ifdef HAVE_LIBNL_SOCKETS
#define get_nl_errmsg nl_geterror
#else
/* libnl 2.x compatibility code */
@ -595,7 +509,7 @@ __genl_ctrl_alloc_cache(struct nl_handle *h, struct nl_cache **cache)
return 0;
}
#define genl_ctrl_alloc_cache __genl_ctrl_alloc_cache
#endif /* !HAVE_LIBNL_2_x */
#endif /* !HAVE_LIBNL_SOCKETS */
struct nl80211_state {
struct nl_sock *nl_sock;
@ -680,7 +594,7 @@ add_mon_if(pcap_t *handle, int sock_fd, struct nl80211_state *state,
err = nl_send_auto_complete(state->nl_sock, msg);
if (err < 0) {
#ifdef HAVE_LIBNL_2_x
#if defined HAVE_LIBNL_NLE
if (err == -NLE_FAILURE) {
#else
if (err == -ENFILE) {
@ -708,7 +622,7 @@ add_mon_if(pcap_t *handle, int sock_fd, struct nl80211_state *state,
}
err = nl_wait_for_ack(state->nl_sock);
if (err < 0) {
#ifdef HAVE_LIBNL_2_x
#if defined HAVE_LIBNL_NLE
if (err == -NLE_FAILURE) {
#else
if (err == -ENFILE) {
@ -1618,32 +1532,40 @@ pcap_read_packet(pcap_t *handle, pcap_handler callback, u_char *userdata)
}
#if defined(HAVE_PACKET_AUXDATA) && defined(HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI)
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
struct tpacket_auxdata *aux;
unsigned int len;
struct vlan_tag *tag;
if (handle->md.vlan_offset != -1) {
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
struct tpacket_auxdata *aux;
unsigned int len;
struct vlan_tag *tag;
if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct tpacket_auxdata)) ||
cmsg->cmsg_level != SOL_PACKET ||
cmsg->cmsg_type != PACKET_AUXDATA)
continue;
if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct tpacket_auxdata)) ||
cmsg->cmsg_level != SOL_PACKET ||
cmsg->cmsg_type != PACKET_AUXDATA)
continue;
aux = (struct tpacket_auxdata *)CMSG_DATA(cmsg);
if (aux->tp_vlan_tci == 0)
continue;
aux = (struct tpacket_auxdata *)CMSG_DATA(cmsg);
#if defined(TP_STATUS_VLAN_VALID)
if ((aux->tp_vlan_tci == 0) && !(aux->tp_status & TP_STATUS_VLAN_VALID))
#else
if (aux->tp_vlan_tci == 0) /* this is ambigious but without the
TP_STATUS_VLAN_VALID flag, there is
nothing that we can do */
#endif
continue;
len = packet_len > iov.iov_len ? iov.iov_len : packet_len;
if (len < 2 * ETH_ALEN)
break;
len = packet_len > iov.iov_len ? iov.iov_len : packet_len;
if (len < (unsigned int) handle->md.vlan_offset)
break;
bp -= VLAN_TAG_LEN;
memmove(bp, bp + VLAN_TAG_LEN, 2 * ETH_ALEN);
bp -= VLAN_TAG_LEN;
memmove(bp, bp + VLAN_TAG_LEN, handle->md.vlan_offset);
tag = (struct vlan_tag *)(bp + 2 * ETH_ALEN);
tag->vlan_tpid = htons(ETH_P_8021Q);
tag->vlan_tci = htons(aux->tp_vlan_tci);
tag = (struct vlan_tag *)(bp + handle->md.vlan_offset);
tag->vlan_tpid = htons(ETH_P_8021Q);
tag->vlan_tci = htons(aux->tp_vlan_tci);
packet_len += VLAN_TAG_LEN;
packet_len += VLAN_TAG_LEN;
}
}
#endif /* defined(HAVE_PACKET_AUXDATA) && defined(HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI) */
#endif /* HAVE_PF_PACKET_SOCKETS */
@ -1951,6 +1873,8 @@ scan_sys_class_net(pcap_if_t **devlistp, char *errbuf)
DIR *sys_class_net_d;
int fd;
struct dirent *ent;
char subsystem_path[PATH_MAX+1];
struct stat statb;
char *p;
char name[512]; /* XXX - pick a size */
char *q, *saveq;
@ -1995,11 +1919,42 @@ scan_sys_class_net(pcap_if_t **devlistp, char *errbuf)
}
/*
* Ignore directories (".", "..", and any subdirectories).
* Ignore "." and "..".
*/
if (ent->d_type == DT_DIR)
if (strcmp(ent->d_name, ".") == 0 ||
strcmp(ent->d_name, "..") == 0)
continue;
/*
* Ignore plain files; they do not have subdirectories
* and thus have no attributes.
*/
if (ent->d_type == DT_REG)
continue;
/*
* Is there an "ifindex" file under that name?
* (We don't care whether it's a directory or
* a symlink; older kernels have directories
* for devices, newer kernels have symlinks to
* directories.)
*/
snprintf(subsystem_path, sizeof subsystem_path,
"/sys/class/net/%s/ifindex", ent->d_name);
if (lstat(subsystem_path, &statb) != 0) {
/*
* Stat failed. Either there was an error
* other than ENOENT, and we don't know if
* this is an interface, or it's ENOENT,
* and either some part of "/sys/class/net/{if}"
* disappeared, in which case it probably means
* the interface disappeared, or there's no
* "ifindex" file, which means it's not a
* network interface.
*/
continue;
}
/*
* Get the interface name.
*/
@ -2265,56 +2220,6 @@ pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
if (pcap_add_if(alldevsp, "any", 0, any_descr, errbuf) < 0)
return (-1);
#ifdef HAVE_DAG_API
/*
* Add DAG devices.
*/
if (dag_platform_finddevs(alldevsp, errbuf) < 0)
return (-1);
#endif /* HAVE_DAG_API */
#ifdef HAVE_SEPTEL_API
/*
* Add Septel devices.
*/
if (septel_platform_finddevs(alldevsp, errbuf) < 0)
return (-1);
#endif /* HAVE_SEPTEL_API */
#ifdef HAVE_SNF_API
if (snf_platform_finddevs(alldevsp, errbuf) < 0)
return (-1);
#endif /* HAVE_SNF_API */
#ifdef PCAP_SUPPORT_BT
/*
* Add Bluetooth devices.
*/
if (bt_platform_finddevs(alldevsp, errbuf) < 0)
return (-1);
#endif
#ifdef PCAP_SUPPORT_USB
/*
* Add USB devices.
*/
if (usb_platform_finddevs(alldevsp, errbuf) < 0)
return (-1);
#endif
#ifdef PCAP_SUPPORT_NETFILTER
/*
* Add netfilter devices.
*/
if (netfilter_platform_finddevs(alldevsp, errbuf) < 0)
return (-1);
#endif
#if PCAP_SUPPORT_CANUSB
if (canusb_platform_finddevs(alldevsp, errbuf) < 0)
return (-1);
#endif
return (0);
}
@ -3181,6 +3086,24 @@ activate_new(pcap_t *handle)
}
handle->bufsize = handle->snapshot;
/*
* Set the offset at which to insert VLAN tags.
*/
switch (handle->linktype) {
case DLT_EN10MB:
handle->md.vlan_offset = 2 * ETH_ALEN;
break;
case DLT_LINUX_SLL:
handle->md.vlan_offset = 14;
break;
default:
handle->md.vlan_offset = -1; /* unknown */
break;
}
/* Save the socket FD in the pcap structure */
handle->fd = sock_fd;
@ -3732,27 +3655,21 @@ pcap_getnonblock_mmap(pcap_t *p, char *errbuf)
static int
pcap_setnonblock_mmap(pcap_t *p, int nonblock, char *errbuf)
{
/* map each value to the corresponding 2's complement, to
* preserve the timeout value provided with pcap_set_timeout */
/*
* Map each value to their corresponding negation to
* preserve the timeout value provided with pcap_set_timeout.
*/
if (nonblock) {
if (p->md.timeout >= 0) {
/*
* Timeout is non-negative, so we're not already
* in non-blocking mode; set it to the 2's
* complement, to make it negative, as an
* indication that we're in non-blocking mode.
* Indicate that we're switching to
* non-blocking mode.
*/
p->md.timeout = p->md.timeout*-1 - 1;
p->md.timeout = ~p->md.timeout;
}
} else {
if (p->md.timeout < 0) {
/*
* Timeout is negative, so we're not already
* in blocking mode; reverse the previous
* operation, to make the timeout non-negative
* again.
*/
p->md.timeout = (p->md.timeout+1)*-1;
p->md.timeout = ~p->md.timeout;
}
}
return 0;
@ -4020,14 +3937,20 @@ pcap_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback,
}
#ifdef HAVE_TPACKET2
if (handle->md.tp_version == TPACKET_V2 && h.h2->tp_vlan_tci &&
tp_snaplen >= 2 * ETH_ALEN) {
if ((handle->md.tp_version == TPACKET_V2) &&
#if defined(TP_STATUS_VLAN_VALID)
(h.h2->tp_vlan_tci || (h.h2->tp_status & TP_STATUS_VLAN_VALID)) &&
#else
h.h2->tp_vlan_tci &&
#endif
handle->md.vlan_offset != -1 &&
tp_snaplen >= (unsigned int) handle->md.vlan_offset) {
struct vlan_tag *tag;
bp -= VLAN_TAG_LEN;
memmove(bp, bp + VLAN_TAG_LEN, 2 * ETH_ALEN);
memmove(bp, bp + VLAN_TAG_LEN, handle->md.vlan_offset);
tag = (struct vlan_tag *)(bp + 2 * ETH_ALEN);
tag = (struct vlan_tag *)(bp + handle->md.vlan_offset);
tag->vlan_tpid = htons(ETH_P_8021Q);
tag->vlan_tci = htons(h.h2->tp_vlan_tci);
@ -4935,7 +4858,7 @@ iface_ethtool_ioctl(pcap_t *handle, int cmd, const char *cmdname)
eval.cmd = cmd;
ifr.ifr_data = (caddr_t)&eval;
if (ioctl(handle->fd, SIOCETHTOOL, &ifr) == -1) {
if (errno == EOPNOTSUPP) {
if (errno == EOPNOTSUPP || errno == EINVAL) {
/*
* OK, let's just return 0, which, in our
* case, either means "no, what we're asking
@ -5213,6 +5136,12 @@ activate_old(pcap_t *handle)
*/
handle->offset = 0;
/*
* SOCK_PACKET sockets don't supply information from
* stripped VLAN tags.
*/
handle->md.vlan_offset = -1; /* unknown */
return 1;
}

View file

@ -51,17 +51,33 @@
#include <linux/types.h>
#include <linux/netlink.h>
#include <linux/netfilter.h>
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nfnetlink_log.h>
#include <linux/netfilter/nfnetlink_queue.h>
/* NOTE: if your program drops privilages after pcap_activate() it WON'T work with nfqueue.
* It took me quite some time to debug ;/
*
* Sending any data to nfnetlink socket requires CAP_NET_ADMIN privilages,
* and in nfqueue we need to send verdict reply after recving packet.
*
* In tcpdump you can disable dropping privilages with -Z root
*/
#include "pcap-netfilter-linux.h"
#define HDR_LENGTH (NLMSG_LENGTH(NLMSG_ALIGN(sizeof(struct nfgenmsg))))
#define NFLOG_IFACE "nflog"
#define NFQUEUE_IFACE "nfqueue"
typedef enum { OTHER = -1, NFLOG, NFQUEUE } nftype_t;
static int nfqueue_send_verdict(const pcap_t *handle, u_int16_t group_id, u_int32_t id, u_int32_t verdict);
static int
nflog_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
netfilter_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user)
{
const unsigned char *buf;
int count = 0;
@ -85,6 +101,7 @@ nflog_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char
while (len >= NLMSG_SPACE(0)) {
const struct nlmsghdr *nlh = (const struct nlmsghdr *) buf;
u_int32_t msg_len;
nftype_t type = OTHER;
if (nlh->nlmsg_len < sizeof(struct nlmsghdr) || len < nlh->nlmsg_len) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Message truncated: (got: %d) (nlmsg_len: %u)", len, nlh->nlmsg_len);
@ -93,10 +110,19 @@ nflog_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char
if (NFNL_SUBSYS_ID(nlh->nlmsg_type) == NFNL_SUBSYS_ULOG &&
NFNL_MSG_TYPE(nlh->nlmsg_type) == NFULNL_MSG_PACKET)
{
type = NFLOG;
if (NFNL_SUBSYS_ID(nlh->nlmsg_type) == NFNL_SUBSYS_QUEUE &&
NFNL_MSG_TYPE(nlh->nlmsg_type) == NFQNL_MSG_PACKET)
type = NFQUEUE;
if (type != OTHER) {
const unsigned char *payload = NULL;
struct pcap_pkthdr pkth;
const struct nfgenmsg *nfg;
int id = 0;
if (handle->linktype != DLT_NFLOG) {
const struct nfattr *payload_attr = NULL;
@ -105,15 +131,32 @@ nflog_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char
return -1;
}
nfg = NLMSG_DATA(nlh);
if (nlh->nlmsg_len > HDR_LENGTH) {
struct nfattr *attr = NFM_NFA(NLMSG_DATA(nlh));
struct nfattr *attr = NFM_NFA(nfg);
int attr_len = nlh->nlmsg_len - NLMSG_ALIGN(HDR_LENGTH);
while (NFA_OK(attr, attr_len)) {
switch (NFA_TYPE(attr)) {
case NFULA_PAYLOAD:
payload_attr = attr;
break;
if (type == NFQUEUE) {
switch (NFA_TYPE(attr)) {
case NFQA_PACKET_HDR:
{
const struct nfqnl_msg_packet_hdr *pkt_hdr = (const struct nfqnl_msg_packet_hdr *) NFA_DATA(attr);
id = ntohl(pkt_hdr->packet_id);
break;
}
case NFQA_PAYLOAD:
payload_attr = attr;
break;
}
} else if (type == NFLOG) {
switch (NFA_TYPE(attr)) {
case NFULA_PAYLOAD:
payload_attr = attr;
break;
}
}
attr = NFA_NEXT(attr, attr_len);
}
@ -141,6 +184,11 @@ nflog_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char
count++;
}
}
if (type == NFQUEUE) {
/* XXX, possible responses: NF_DROP, NF_ACCEPT, NF_STOLEN, NF_QUEUE, NF_REPEAT, NF_STOP */
nfqueue_send_verdict(handle, ntohs(nfg->res_id), id, NF_ACCEPT);
}
}
msg_len = NLMSG_ALIGN(nlh->nlmsg_len);
@ -183,7 +231,7 @@ struct my_nfattr {
};
static int
nflog_send_config_msg(const pcap_t *handle, u_int8_t family, u_int16_t res_id, const struct my_nfattr *mynfa)
netfilter_send_config_msg(const pcap_t *handle, u_int16_t msg_type, int ack, u_int8_t family, u_int16_t res_id, const struct my_nfattr *mynfa)
{
char buf[1024] __attribute__ ((aligned));
@ -198,8 +246,8 @@ nflog_send_config_msg(const pcap_t *handle, u_int8_t family, u_int16_t res_id, c
++seq_id;
nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nfgenmsg));
nlh->nlmsg_type = (NFNL_SUBSYS_ULOG << 8) | NFULNL_MSG_CONFIG;
nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
nlh->nlmsg_type = msg_type;
nlh->nlmsg_flags = NLM_F_REQUEST | (ack ? NLM_F_ACK : 0);
nlh->nlmsg_pid = 0; /* to kernel */
nlh->nlmsg_seq = seq_id;
@ -222,6 +270,9 @@ nflog_send_config_msg(const pcap_t *handle, u_int8_t family, u_int16_t res_id, c
if (sendto(handle->fd, nlh, nlh->nlmsg_len, 0, (struct sockaddr *) &snl, sizeof(snl)) == -1)
return -1;
if (!ack)
return 0;
/* waiting for reply loop */
do {
socklen_t addrlen = sizeof(snl);
@ -260,6 +311,12 @@ nflog_send_config_msg(const pcap_t *handle, u_int8_t family, u_int16_t res_id, c
return -1; /* never here */
}
static int
nflog_send_config_msg(const pcap_t *handle, u_int8_t family, u_int16_t group_id, const struct my_nfattr *mynfa)
{
return netfilter_send_config_msg(handle, (NFNL_SUBSYS_ULOG << 8) | NFULNL_MSG_CONFIG, 1, family, group_id, mynfa);
}
static int
nflog_send_config_cmd(const pcap_t *handle, u_int16_t group_id, u_int8_t cmd, u_int8_t family)
{
@ -292,20 +349,79 @@ nflog_send_config_mode(const pcap_t *handle, u_int16_t group_id, u_int8_t copy_m
}
static int
nflog_activate(pcap_t* handle)
nfqueue_send_verdict(const pcap_t *handle, u_int16_t group_id, u_int32_t id, u_int32_t verdict)
{
struct nfqnl_msg_verdict_hdr msg;
struct my_nfattr nfa;
msg.id = htonl(id);
msg.verdict = htonl(verdict);
nfa.data = &msg;
nfa.nfa_type = NFQA_VERDICT_HDR;
nfa.nfa_len = sizeof(msg);
return netfilter_send_config_msg(handle, (NFNL_SUBSYS_QUEUE << 8) | NFQNL_MSG_VERDICT, 0, AF_UNSPEC, group_id, &nfa);
}
static int
nfqueue_send_config_msg(const pcap_t *handle, u_int8_t family, u_int16_t group_id, const struct my_nfattr *mynfa)
{
return netfilter_send_config_msg(handle, (NFNL_SUBSYS_QUEUE << 8) | NFQNL_MSG_CONFIG, 1, family, group_id, mynfa);
}
static int
nfqueue_send_config_cmd(const pcap_t *handle, u_int16_t group_id, u_int8_t cmd, u_int16_t pf)
{
struct nfqnl_msg_config_cmd msg;
struct my_nfattr nfa;
msg.command = cmd;
msg.pf = htons(pf);
nfa.data = &msg;
nfa.nfa_type = NFQA_CFG_CMD;
nfa.nfa_len = sizeof(msg);
return nfqueue_send_config_msg(handle, AF_UNSPEC, group_id, &nfa);
}
static int
nfqueue_send_config_mode(const pcap_t *handle, u_int16_t group_id, u_int8_t copy_mode, u_int32_t copy_range)
{
struct nfqnl_msg_config_params msg;
struct my_nfattr nfa;
msg.copy_range = htonl(copy_range);
msg.copy_mode = copy_mode;
nfa.data = &msg;
nfa.nfa_type = NFQA_CFG_PARAMS;
nfa.nfa_len = sizeof(msg);
return nfqueue_send_config_msg(handle, AF_UNSPEC, group_id, &nfa);
}
static int
netfilter_activate(pcap_t* handle)
{
const char *dev = handle->opt.source;
unsigned short groups[32];
int group_count = 0;
nftype_t type = OTHER;
int i;
if (strncmp(dev, NFLOG_IFACE, strlen(NFLOG_IFACE)) == 0) {
dev += strlen(NFLOG_IFACE);
/* nflog:30,33,42 looks nice, allow it */
if (*dev == ':')
dev++;
if (strncmp(dev, NFLOG_IFACE, strlen(NFLOG_IFACE)) == 0) {
dev += strlen(NFLOG_IFACE);
type = NFLOG;
} else if (strncmp(dev, NFQUEUE_IFACE, strlen(NFQUEUE_IFACE)) == 0) {
dev += strlen(NFQUEUE_IFACE);
type = NFQUEUE;
}
if (type != OTHER && *dev == ':') {
dev++;
while (*dev) {
long int group_id;
char *end_dev;
@ -335,7 +451,7 @@ nflog_activate(pcap_t* handle)
}
}
if (*dev) {
if (type == OTHER || *dev) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't get netfilter group(s) index from %s",
handle->opt.source);
@ -351,8 +467,7 @@ nflog_activate(pcap_t* handle)
/* Initialize some components of the pcap structure. */
handle->bufsize = 128 + handle->snapshot;
handle->offset = 0;
handle->linktype = DLT_NFLOG;
handle->read_op = nflog_read_linux;
handle->read_op = netfilter_read_linux;
handle->inject_op = netfilter_inject_linux;
handle->setfilter_op = install_bpf_program; /* no kernel filtering */
handle->setdirection_op = NULL;
@ -369,12 +484,17 @@ nflog_activate(pcap_t* handle)
return PCAP_ERROR;
}
handle->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
if (handle->dlt_list != NULL) {
handle->dlt_list[0] = DLT_NFLOG;
handle->dlt_list[1] = DLT_IPV4;
handle->dlt_count = 2;
}
if (type == NFLOG) {
handle->linktype = DLT_NFLOG;
handle->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
if (handle->dlt_list != NULL) {
handle->dlt_list[0] = DLT_NFLOG;
handle->dlt_list[1] = DLT_IPV4;
handle->dlt_count = 2;
}
} else
handle->linktype = DLT_IPV4;
handle->buffer = malloc(handle->bufsize);
if (!handle->buffer) {
@ -382,27 +502,53 @@ nflog_activate(pcap_t* handle)
goto close_fail;
}
if (nflog_send_config_cmd(handle, 0, NFULNL_CFG_CMD_PF_UNBIND, AF_INET) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFULNL_CFG_CMD_PF_UNBIND: %s", pcap_strerror(errno));
goto close_fail;
}
if (nflog_send_config_cmd(handle, 0, NFULNL_CFG_CMD_PF_BIND, AF_INET) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFULNL_CFG_CMD_PF_BIND: %s", pcap_strerror(errno));
goto close_fail;
}
/* Bind socket to the nflog groups */
for (i = 0; i < group_count; i++) {
if (nflog_send_config_cmd(handle, groups[i], NFULNL_CFG_CMD_BIND, AF_UNSPEC) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't listen on group group index: %s", pcap_strerror(errno));
if (type == NFLOG) {
if (nflog_send_config_cmd(handle, 0, NFULNL_CFG_CMD_PF_UNBIND, AF_INET) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFULNL_CFG_CMD_PF_UNBIND: %s", pcap_strerror(errno));
goto close_fail;
}
if (nflog_send_config_mode(handle, groups[i], NFULNL_COPY_PACKET, handle->snapshot) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFULNL_COPY_PACKET: %s", pcap_strerror(errno));
if (nflog_send_config_cmd(handle, 0, NFULNL_CFG_CMD_PF_BIND, AF_INET) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFULNL_CFG_CMD_PF_BIND: %s", pcap_strerror(errno));
goto close_fail;
}
/* Bind socket to the nflog groups */
for (i = 0; i < group_count; i++) {
if (nflog_send_config_cmd(handle, groups[i], NFULNL_CFG_CMD_BIND, AF_UNSPEC) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't listen on group group index: %s", pcap_strerror(errno));
goto close_fail;
}
if (nflog_send_config_mode(handle, groups[i], NFULNL_COPY_PACKET, handle->snapshot) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFULNL_COPY_PACKET: %s", pcap_strerror(errno));
goto close_fail;
}
}
} else {
if (nfqueue_send_config_cmd(handle, 0, NFQNL_CFG_CMD_PF_UNBIND, AF_INET) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFQNL_CFG_CMD_PF_UNBIND: %s", pcap_strerror(errno));
goto close_fail;
}
if (nfqueue_send_config_cmd(handle, 0, NFQNL_CFG_CMD_PF_BIND, AF_INET) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFQNL_CFG_CMD_PF_BIND: %s", pcap_strerror(errno));
goto close_fail;
}
/* Bind socket to the nfqueue groups */
for (i = 0; i < group_count; i++) {
if (nfqueue_send_config_cmd(handle, groups[i], NFQNL_CFG_CMD_BIND, AF_UNSPEC) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't listen on group group index: %s", pcap_strerror(errno));
goto close_fail;
}
if (nfqueue_send_config_mode(handle, groups[i], NFQNL_COPY_PACKET, handle->snapshot) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "NFQNL_COPY_PACKET: %s", pcap_strerror(errno));
goto close_fail;
}
}
}
if (handle->opt.rfmon) {
@ -432,20 +578,50 @@ nflog_activate(pcap_t* handle)
}
pcap_t *
nflog_create(const char *device, char *ebuf)
netfilter_create(const char *device, char *ebuf, int *is_ours)
{
const char *cp;
pcap_t *p;
/* Does this look like an netfilter device? */
cp = strrchr(device, '/');
if (cp == NULL)
cp = device;
/* Does it begin with NFLOG_IFACE or NFQUEUE_IFACE? */
if (strncmp(cp, NFLOG_IFACE, sizeof NFLOG_IFACE - 1) == 0)
cp += sizeof NFLOG_IFACE - 1;
else if (strncmp(cp, NFQUEUE_IFACE, sizeof NFQUEUE_IFACE - 1) == 0)
cp += sizeof NFQUEUE_IFACE - 1;
else {
/* Nope, doesn't begin with NFLOG_IFACE nor NFQUEUE_IFACE */
*is_ours = 0;
return NULL;
}
/*
* Yes - is that either the end of the name, or is it followed
* by a colon?
*/
if (*cp != ':' && *cp != '\0') {
/* Nope */
*is_ours = 0;
return NULL;
}
/* OK, it's probably ours. */
*is_ours = 1;
p = pcap_create_common(device, ebuf);
if (p == NULL)
return (NULL);
p->activate_op = nflog_activate;
p->activate_op = netfilter_activate;
return (p);
}
int
netfilter_platform_finddevs(pcap_if_t **alldevsp, char *err_str)
netfilter_findalldevs(pcap_if_t **alldevsp, char *err_str)
{
pcap_if_t *found_dev = *alldevsp;
int sock;
@ -463,6 +639,7 @@ netfilter_platform_finddevs(pcap_if_t **alldevsp, char *err_str)
if (pcap_add_if(&found_dev, NFLOG_IFACE, 0, "Linux netfilter log (NFLOG) interface", err_str) < 0)
return -1;
if (pcap_add_if(&found_dev, NFQUEUE_IFACE, 0, "Linux netfilter queue (NFQUEUE) interface", err_str) < 0)
return -1;
return 0;
}

View file

@ -31,5 +31,5 @@
/*
* Prototypes for netlink-related functions
*/
int netfilter_platform_finddevs(pcap_if_t **alldevsp, char *err_str);
pcap_t *nflog_create(const char *device, char *ebuf);
int netfilter_findalldevs(pcap_if_t **alldevsp, char *err_str);
pcap_t *netfilter_create(const char *device, char *ebuf, int *is_ours);

View file

@ -328,7 +328,7 @@ pcap_activate_nit(pcap_t *p)
}
pcap_t *
pcap_create(const char *device, char *ebuf)
pcap_create_interface(const char *device, char *ebuf)
{
pcap_t *p;

View file

@ -40,7 +40,7 @@ static const char rcsid[] _U_ =
static char nosup[] = "live packet capture not supported on this system";
pcap_t *
pcap_create(const char *device, char *ebuf)
pcap_create_interface(const char *device, char *ebuf)
{
(void)strlcpy(ebuf, nosup, PCAP_ERRBUF_SIZE);
return (NULL);

View file

@ -499,7 +499,7 @@ your system may not be properly configured; see the packetfilter(4) man page\n",
}
pcap_t *
pcap_create(const char *device, char *ebuf)
pcap_create_interface(const char *device, char *ebuf)
{
pcap_t *p;

View file

@ -38,23 +38,14 @@ static const char rcsid[] _U_ =
#include <sys/types.h>
#include <unistd.h>
#ifdef HAVE_SEPTEL_API
#include <msg.h>
#include <ss7_inc.h>
#include <sysgct.h>
#include <pack.h>
#include <system.h>
#endif /* HAVE_SEPTEL_API */
#ifdef SEPTEL_ONLY
/* This code is required when compiling for a Septel device only. */
#include "pcap-septel.h"
/* Replace septel function names with pcap equivalent. */
#define septel_create pcap_create
#define septel_platform_finddevs pcap_platform_finddevs
#endif /* SEPTEL_ONLY */
static int septel_setfilter(pcap_t *p, struct bpf_program *fp);
static int septel_stats(pcap_t *p, struct pcap_stat *ps);
static int septel_setnonblock(pcap_t *p, int nonblock, char *errbuf);
@ -221,9 +212,23 @@ static pcap_t *septel_activate(pcap_t* handle) {
return 0;
}
pcap_t *septel_create(const char *device, char *ebuf) {
pcap_t *septel_create(const char *device, char *ebuf, int *is_ours) {
const char *cp;
pcap_t *p;
/* Does this look like the Septel device? */
cp = strrchr(device, '/');
if (cp == NULL)
cp = device;
if (strcmp(cp, "septel") != 0) {
/* Nope, it's not "septel" */
*is_ours = 0;
return NULL;
}
/* OK, it's probably ours. */
*is_ours = 1;
p = pcap_create_common(device, ebuf);
if (p == NULL)
return NULL;
@ -243,7 +248,7 @@ static int septel_stats(pcap_t *p, struct pcap_stat *ps) {
int
septel_platform_finddevs(pcap_if_t **devlistp, char *errbuf)
septel_findalldevs(pcap_if_t **devlistp, char *errbuf)
{
unsigned char *p;
const char description[512]= "Intel/Septel device";

View file

@ -11,5 +11,5 @@
* @(#) $Header: /tcpdump/master/libpcap/pcap-septel.h,v 1.2 2008-04-04 19:37:45 guy Exp $
*/
pcap_t *septel_create(const char *device, char *ebuf);
pcap_t *septel_create(const char *device, char *ebuf, int *is_ours);
int septel_findalldevs(pcap_if_t **devlistp, char *errbuf);

View file

@ -214,6 +214,9 @@ static void empty_unit(int chassis, int geoslot) {
empty_unit_iface(u);
if (u->imsg) { /* then if an inbound message buffer exists */
u->imsg = (char *)realloc(u->imsg, 1); /* and re-allocate the old large buffer into a new small one */
if (u->imsg == NULL) { /* oops, realloc call failed */
fprintf(stderr, "Warning...call to realloc() failed, value of errno is %d\n", errno);
}
}
@ -311,9 +314,17 @@ static int open_with_IOP(unit_t *u, int flag) {
if (u->serv_addr == NULL) {
u->serv_addr = malloc(sizeof(struct sockaddr_in));
/* since we called malloc(), lets check to see if we actually got the memory */
if (u->serv_addr == NULL) { /* oops, we didn't get the memory requested */
fprintf(stderr, "malloc() request for u->serv_addr failed, value of errno is: %d\n", errno);
return 0;
}
}
ip = u->ip;
bzero((char *)u->serv_addr, sizeof(struct sockaddr_in));
/* bzero() is deprecated, replaced with memset() */
memset((char *)u->serv_addr, 0, sizeof(struct sockaddr_in));
u->serv_addr->sin_family = AF_INET;
u->serv_addr->sin_addr.s_addr = inet_addr(ip);
u->serv_addr->sin_port = htons(IOP_SNIFFER_PORT);
@ -417,11 +428,20 @@ static char *translate_IOP_to_pcap_name(unit_t *u, char *IOPname, bpf_u_int32 if
int IOPportnum = 0;
iface = malloc(sizeof(iface_t)); /* get memory for a structure */
bzero((char *)iface, sizeof(iface_t));
if (iface == NULL) { /* oops, we didn't get the memory requested */
fprintf(stderr, "Error...couldn't allocate memory for interface structure...value of errno is: %d\n", errno);
return NULL;
}
memset((char *)iface, 0, sizeof(iface_t)); /* bzero is deprecated(), replaced with memset() */
iface->iftype = iftype; /* remember the interface type of this interface */
name = malloc(strlen(IOPname) + 1); /* get memory for the IOP's name */
if (name == NULL) { /* oops, we didn't get the memory requested */
fprintf(stderr, "Error...couldn't allocate memory for IOPname...value of errno is: %d\n", errno);
return NULL;
}
strcpy(name, IOPname); /* and copy it in */
iface->IOPname = name; /* and stick it into the structure */
@ -447,6 +467,11 @@ static char *translate_IOP_to_pcap_name(unit_t *u, char *IOPname, bpf_u_int32 if
sprintf(buf, "%s_%s", proto, port); /* compose the user's name for that IOP port name */
name = malloc(strlen(buf) + 1); /* get memory for that name */
if (name == NULL) { /* oops, we didn't get the memory requested */
fprintf(stderr, "Error...couldn't allocate memory for IOP port name...value of errno is: %d\n", errno);
return NULL;
}
strcpy(name, buf); /* and copy it in */
iface->name = name; /* and stick it into the structure */
@ -548,7 +573,7 @@ static int process_client_data (char *errbuf) { /* returns: -1 = error, 0
snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
return -1;
}
bzero((char *)iff, sizeof(pcap_if_t));
memset((char *)iff, 0, sizeof(pcap_if_t)); /* bzero() is deprecated, replaced with memset() */
if (acn_if_list == 0) acn_if_list = iff; /* remember the head of the list */
if (prev_iff) prev_iff->next = iff; /* insert a forward link */
@ -588,7 +613,7 @@ static int process_client_data (char *errbuf) { /* returns: -1 = error, 0
snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
return -1;
}
bzero((char *)addr, sizeof(pcap_addr_t));
+ memset((char *)addr, 0, sizeof(pcap_addr_t)); /* bzero() is deprecated, replaced with memset() */
if (iff->addresses == 0) iff->addresses = addr;
if (prev_addr) prev_addr->next = addr; /* insert a forward link */
if (*ptr) { /* if there is a count for the address */
@ -596,7 +621,7 @@ static int process_client_data (char *errbuf) { /* returns: -1 = error, 0
snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
return -1;
}
bzero((char *)s, sizeof(struct sockaddr_in));
memset((char *)s, 0, sizeof(struct sockaddr_in)); /* bzero() is deprecated, replaced with memset() */
addr->addr = (struct sockaddr *)s;
s->sin_family = AF_INET;
s->sin_addr.s_addr = *(bpf_u_int32 *)(ptr + 1); /* copy the address in */
@ -608,7 +633,9 @@ static int process_client_data (char *errbuf) { /* returns: -1 = error, 0
snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
return -1;
}
bzero((char *)s, sizeof(struct sockaddr_in));
/* bzero() is deprecated, replaced with memset() */
memset((char *)s, 0, sizeof(struct sockaddr_in));
addr->netmask = (struct sockaddr *)s;
s->sin_family = AF_INET;
s->sin_addr.s_addr = *(bpf_u_int32*)(ptr + 1);
@ -620,7 +647,9 @@ static int process_client_data (char *errbuf) { /* returns: -1 = error, 0
snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
return -1;
}
bzero((char *)s, sizeof(struct sockaddr_in));
/* bzero() is deprecated, replaced with memset() */
memset((char *)s, 0, sizeof(struct sockaddr_in));
addr->broadaddr = (struct sockaddr *)s;
s->sin_family = AF_INET;
s->sin_addr.s_addr = *(bpf_u_int32*)(ptr + 1);
@ -632,7 +661,9 @@ static int process_client_data (char *errbuf) { /* returns: -1 = error, 0
snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno));
return -1;
}
bzero((char *)s, sizeof(struct sockaddr_in));
/* bzero() is deprecated, replaced with memset() */
memset((char *)s, 0, sizeof(struct sockaddr_in));
addr->dstaddr = (struct sockaddr *)s;
s->sin_family = AF_INET;
s->sin_addr.s_addr = *(bpf_u_int32*)(ptr + 1);
@ -776,7 +807,7 @@ static int acn_open_live(const char *name, char *errbuf, int *linktype) { /* re
iface_t *p;
pcap_if_t *alldevsp;
pcap_findalldevs(&alldevsp, errbuf);
pcap_findalldevs_interfaces(&alldevsp, errbuf);
for (chassis = 0; chassis <= MAX_CHASSIS; chassis++) { /* scan the table... */
for (geoslot = 0; geoslot <= MAX_GEOSLOT; geoslot++) {
u = &units[chassis][geoslot];
@ -968,7 +999,7 @@ static int pcap_activate_sita(pcap_t *handle) {
return 0;
}
pcap_t *pcap_create(const char *device, char *ebuf) {
pcap_t *pcap_create_interface(const char *device, char *ebuf) {
pcap_t *p;
p = pcap_create_common(device, ebuf);

View file

@ -18,11 +18,6 @@
#include "snf.h"
#include "pcap-int.h"
#ifdef SNF_ONLY
#define snf_create pcap_create
#define snf_platform_finddevs pcap_platform_finddevs
#endif
static int
snf_set_datalink(pcap_t *p, int dlt)
{
@ -249,7 +244,7 @@ snf_activate(pcap_t* p)
}
int
snf_platform_finddevs(pcap_if_t **devlistp, char *errbuf)
snf_findalldevs(pcap_if_t **devlistp, char *errbuf)
{
/*
* There are no platform-specific devices since each device
@ -259,22 +254,28 @@ snf_platform_finddevs(pcap_if_t **devlistp, char *errbuf)
}
pcap_t *
snf_create(const char *device, char *ebuf)
snf_create(const char *device, char *ebuf, int *is_ours)
{
pcap_t *p;
int boardnum = -1;
struct snf_ifaddrs *ifaddrs, *ifa;
size_t devlen;
if (snf_init(SNF_VERSION_API))
if (snf_init(SNF_VERSION_API)) {
/* Can't initialize the API, so no SNF devices */
*is_ours = 0;
return NULL;
}
/*
* Match a given interface name to our list of interface names, from
* which we can obtain the intended board number
*/
if (snf_getifaddrs(&ifaddrs) || ifaddrs == NULL)
if (snf_getifaddrs(&ifaddrs) || ifaddrs == NULL) {
/* Can't get SNF addresses */
*is_ours = 0;
return NULL;
}
devlen = strlen(device) + 1;
ifa = ifaddrs;
while (ifa) {
@ -292,10 +293,16 @@ snf_create(const char *device, char *ebuf)
* and "snf10gX" where X is the board number.
*/
if (sscanf(device, "snf10g%d", &boardnum) != 1 &&
sscanf(device, "snf%d", &boardnum) != 1)
sscanf(device, "snf%d", &boardnum) != 1) {
/* Nope, not a supported name */
*is_ours = 0;
return NULL;
}
}
/* OK, it's probably ours. */
*is_ours = 1;
p = pcap_create_common(device, ebuf);
if (p == NULL)
return NULL;

View file

@ -1,2 +1,2 @@
pcap_t *snf_create(const char *, char *);
int snf_platform_finddevs(pcap_if_t **devlistp, char *errbuf);
pcap_t *snf_create(const char *, char *, int *);
int snf_findalldevs(pcap_if_t **devlistp, char *errbuf);

View file

@ -407,7 +407,7 @@ pcap_activate_snit(pcap_t *p)
}
pcap_t *
pcap_create(const char *device, char *ebuf)
pcap_create_interface(const char *device, char *ebuf)
{
pcap_t *p;

View file

@ -394,7 +394,7 @@ pcap_activate_snoop(pcap_t *p)
}
pcap_t *
pcap_create(const char *device, char *ebuf)
pcap_create_interface(const char *device, char *ebuf)
{
pcap_t *p;

View file

@ -148,7 +148,7 @@ usb_dev_add(pcap_if_t** alldevsp, int n, char *err_str)
}
int
usb_platform_finddevs(pcap_if_t **alldevsp, char *err_str)
usb_findalldevs(pcap_if_t **alldevsp, char *err_str)
{
struct dirent* data;
int ret = 0;
@ -284,10 +284,40 @@ probe_devices(int bus)
}
pcap_t *
usb_create(const char *device, char *ebuf)
usb_create(const char *device, char *ebuf, int *is_ours)
{
const char *cp;
char *cpend;
long devnum;
pcap_t *p;
/* Does this look like a USB monitoring device? */
cp = strrchr(device, '/');
if (cp == NULL)
cp = device;
/* Does it begin with USB_IFACE? */
if (strncmp(cp, USB_IFACE, sizeof USB_IFACE - 1) != 0) {
/* Nope, doesn't begin with USB_IFACE */
*is_ours = 0;
return NULL;
}
/* Yes - is USB_IFACE followed by a number? */
cp += sizeof USB_IFACE - 1;
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(device, ebuf);
if (p == NULL)
return (NULL);

View file

@ -36,5 +36,5 @@
/*
* Prototypes for USB-related functions
*/
int usb_platform_finddevs(pcap_if_t **alldevsp, char *err_str);
pcap_t *usb_create(const char *device, char *ebuf);
int usb_findalldevs(pcap_if_t **alldevsp, char *err_str);
pcap_t *usb_create(const char *device, char *ebuf, int *is_ours);

View file

@ -715,7 +715,7 @@ pcap_activate_win32(pcap_t *p)
}
pcap_t *
pcap_create(const char *device, char *ebuf)
pcap_create_interface(const char *device, char *ebuf)
{
pcap_t *p;
@ -836,7 +836,7 @@ pcap_setnonblock_win32(pcap_t *p, int nonblock, char *errbuf)
newtimeout = p->md.timeout;
}
if (!PacketSetReadTimeout(p->adapter, newtimeout)) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
snprintf(errbuf, PCAP_ERRBUF_SIZE,
"PacketSetReadTimeout: %s", pcap_win32strerror());
return (-1);
}

View file

@ -75,8 +75,35 @@ static const char rcsid[] _U_ =
#include "pcap-int.h"
#ifdef HAVE_DAG_API
#include <dagnew.h>
#include <dagapi.h>
#include "pcap-dag.h"
#endif /* HAVE_DAG_API */
#ifdef HAVE_SEPTEL_API
#include "pcap-septel.h"
#endif /* HAVE_SEPTEL_API */
#ifdef HAVE_SNF_API
#include "pcap-snf.h"
#endif /* HAVE_SNF_API */
#ifdef PCAP_SUPPORT_USB
#include "pcap-usb-linux.h"
#endif
#ifdef PCAP_SUPPORT_BT
#include "pcap-bt-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
int
@ -233,6 +260,173 @@ pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header,
return (p->read_op(p, 1, p->oneshot_callback, (u_char *)&s));
}
#if defined(DAG_ONLY)
int
pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
{
return (dag_findalldevs(alldevsp, errbuf));
}
pcap_t *
pcap_create(const char *source, char *errbuf)
{
return (dag_create(source, errbuf));
}
#elif defined(SEPTEL_ONLY)
int
pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
{
return (septel_findalldevs(alldevsp, errbuf));
}
pcap_t *
pcap_create(const char *source, char *errbuf)
{
return (septel_create(source, errbuf));
}
#elif defined(SNF_ONLY)
int
pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
{
return (snf_findalldevs(alldevsp, errbuf));
}
pcap_t *
pcap_create(const char *source, char *errbuf)
{
return (snf_create(source, errbuf));
}
#else /* regular pcap */
struct capture_source_type {
int (*findalldevs_op)(pcap_if_t **, char *);
pcap_t *(*create_op)(const char *, char *, int *);
} capture_source_types[] = {
#ifdef HAVE_DAG_API
{ dag_findalldevs, dag_create },
#endif
#ifdef HAVE_SEPTEL_API
{ septel_findalldevs, septel_create },
#endif
#ifdef HAVE_SNF_API
{ snf_findalldevs, snf_create },
#endif
#ifdef PCAP_SUPPORT_BT
{ bt_findalldevs, bt_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
#ifdef PCAP_SUPPORT_NETFILTER
{ netfilter_findalldevs, netfilter_create },
#endif
{ NULL, NULL }
};
/*
* Get a list of all capture sources that are up and that we can open.
* Returns -1 on error, 0 otherwise.
* The list, as returned through "alldevsp", may be null if no interfaces
* were up and could be opened.
*/
int
pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
{
size_t i;
/*
* Get the list of regular interfaces first.
*/
if (pcap_findalldevs_interfaces(alldevsp, errbuf) == -1)
return (-1); /* failure */
/*
* Add any interfaces that need a platform-specific mechanism
* to find.
*/
if (pcap_platform_finddevs(alldevsp, errbuf) == -1) {
/*
* We had an error; free the list we've been
* constructing.
*/
if (*alldevsp != NULL) {
pcap_freealldevs(*alldevsp);
*alldevsp = NULL;
}
return (-1);
}
/*
* Ask each of the non-local-network-interface capture
* source types what interfaces they have.
*/
for (i = 0; capture_source_types[i].findalldevs_op != NULL; i++) {
if (capture_source_types[i].findalldevs_op(alldevsp, errbuf) == -1) {
/*
* We had an error; free the list we've been
* constructing.
*/
if (*alldevsp != NULL) {
pcap_freealldevs(*alldevsp);
*alldevsp = NULL;
}
return (-1);
}
}
return (0);
}
pcap_t *
pcap_create(const char *source, char *errbuf)
{
size_t i;
int is_theirs;
pcap_t *p;
/*
* A null source name is equivalent to the "any" device -
* which might not be supported on this platform, but
* this means that you'll get a "not supported" error
* rather than, say, a crash when we try to dereference
* the null pointer.
*/
if (source == NULL)
source = "any";
/*
* Try each of the non-local-network-interface capture
* source types until we find one that works for this
* device or run out of types.
*/
for (i = 0; capture_source_types[i].create_op != NULL; i++) {
is_theirs = 0;
p = capture_source_types[i].create_op(source, errbuf, &is_theirs);
if (is_theirs) {
/*
* The device name refers to a device of the
* type in question; either it succeeded,
* in which case p refers to a pcap_t to
* later activate for the device, or it
* failed, in which case p is null and we
* should return that to report the failure
* to create.
*/
return (p);
}
}
/*
* OK, try it as a regular network interface.
*/
return (pcap_create_interface(source, errbuf));
}
#endif
static void
initialize_ops(pcap_t *p)
{
@ -1024,7 +1218,18 @@ pcap_geterr(pcap_t *p)
int
pcap_getnonblock(pcap_t *p, char *errbuf)
{
return (p->getnonblock_op(p, errbuf));
int ret;
ret = p->getnonblock_op(p, errbuf);
if (ret == -1) {
/*
* In case somebody depended on the bug wherein
* the error message was put into p->errbuf
* by pcap_getnonblock_fd().
*/
strlcpy(p->errbuf, errbuf, PCAP_ERRBUF_SIZE);
}
return (ret);
}
/*
@ -1042,7 +1247,7 @@ pcap_getnonblock_fd(pcap_t *p, char *errbuf)
fdflags = fcntl(p->fd, F_GETFL, 0);
if (fdflags == -1) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
pcap_strerror(errno));
return (-1);
}
@ -1056,7 +1261,18 @@ pcap_getnonblock_fd(pcap_t *p, char *errbuf)
int
pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf)
{
return (p->setnonblock_op(p, nonblock, errbuf));
int ret;
ret = p->setnonblock_op(p, nonblock, errbuf);
if (ret == -1) {
/*
* In case somebody depended on the bug wherein
* the error message was put into p->errbuf
* by pcap_setnonblock_fd().
*/
strlcpy(p->errbuf, errbuf, PCAP_ERRBUF_SIZE);
}
return (ret);
}
#if !defined(WIN32) && !defined(MSDOS)
@ -1073,7 +1289,7 @@ pcap_setnonblock_fd(pcap_t *p, int nonblock, char *errbuf)
fdflags = fcntl(p->fd, F_GETFL, 0);
if (fdflags == -1) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
pcap_strerror(errno));
return (-1);
}
@ -1082,7 +1298,7 @@ pcap_setnonblock_fd(pcap_t *p, int nonblock, char *errbuf)
else
fdflags &= ~O_NONBLOCK;
if (fcntl(p->fd, F_SETFL, fdflags) == -1) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "F_SETFL: %s",
snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_SETFL: %s",
pcap_strerror(errno));
return (-1);
}
@ -1465,10 +1681,10 @@ pcap_close(pcap_t *p)
* the packet doesn't pass and non-zero if the packet does pass.
*/
int
pcap_offline_filter(struct bpf_program *fp, const struct pcap_pkthdr *h,
pcap_offline_filter(const struct bpf_program *fp, const struct pcap_pkthdr *h,
const u_char *pkt)
{
struct bpf_insn *fcode = fp->bf_insns;
const struct bpf_insn *fcode = fp->bf_insns;
if (fcode != NULL)
return (bpf_filter(fcode, pkt, h->len, h->caplen));

View file

@ -1133,7 +1133,7 @@ struct bpf_program {
#define DLT_NETANALYZER_TRANSPARENT 241
/*
* IP-over-Infiniband, as specified by RFC 4391.
* IP-over-InfiniBand, as specified by RFC 4391.
*
* Requested by Petr Sumbera <petr.sumbera@oracle.com>.
*/
@ -1175,7 +1175,21 @@ struct bpf_program {
#define DLT_PFSYNC 246
#endif
#define DLT_MATCHING_MAX 246 /* highest value in the "matching" range */
/*
* Raw InfiniBand packets, starting with the Local Routing Header.
*
* Requested by Oren Kladnitsky <orenk@mellanox.com>.
*/
#define DLT_INFINIBAND 247
/*
* SCTP, with no lower-level protocols (i.e., no IPv4 or IPv6).
*
* Requested by Michael Tuexen <Michael.Tuexen@lurchi.franken.de>.
*/
#define DLT_SCTP 248
#define DLT_MATCHING_MAX 248 /* highest value in the "matching" range */
/*
* DLT and savefile link type values are split into a class and

View file

@ -111,12 +111,13 @@ typedef struct pcap_addr pcap_addr_t;
* the old file header as well as files with the new file header
* (using the magic number to determine the header format).
*
* Then supply the changes as a patch at
* Then supply the changes by forking the branch at
*
* http://sourceforge.net/projects/libpcap/
* https://github.com/mcr/libpcap/issues
*
* so that future versions of libpcap and programs that use it (such as
* tcpdump) will be able to read your new capture file format.
* and issuing a pull request, so that future versions of libpcap and
* programs that use it (such as tcpdump) will be able to read your new
* capture file format.
*/
struct pcap_file_header {
bpf_u_int32 magic;
@ -368,8 +369,8 @@ int pcap_compile(pcap_t *, struct bpf_program *, const char *, int,
int pcap_compile_nopcap(int, int, struct bpf_program *,
const char *, int, bpf_u_int32);
void pcap_freecode(struct bpf_program *);
int pcap_offline_filter(struct bpf_program *, const struct pcap_pkthdr *,
const u_char *);
int pcap_offline_filter(const struct bpf_program *,
const struct pcap_pkthdr *, const u_char *);
int pcap_datalink(pcap_t *);
int pcap_datalink_ext(pcap_t *);
int pcap_list_datalinks(pcap_t *, int **);

View file

@ -58,20 +58,15 @@ if the signal interrupted a call reading packets in a live capture,
when your signal handler returns after calling pcap_breakloop(), the
call will be restarted, and the loop will not terminate until more
packets arrive and the call completes.
.ft R
.PP
.ft B
Note also that, in a multi-threaded application, if one thread is
blocked in
.BR pcap_dispatch() ,
.BR pcap_loop() ,
.BR pcap_next() ,
or
.BR pcap_next_ex() ,
a call to
.B pcap_breakloop()
in a different thread will not unblock that thread; you will need to use
whatever mechanism the OS provides for breaking a thread out of blocking
calls in order to unblock the thread, such as thread cancellation in
systems that support POSIX threads.
blocked in pcap_dispatch(), pcap_loop(), pcap_next(), or pcap_next_ex(),
a call to pcap_breakloop() in a different thread will not unblock that
thread; you will need to use whatever mechanism the OS provides for
breaking a thread out of blocking calls in order to unblock the thread,
such as thread cancellation in systems that support POSIX threads.
.ft R
.PP
Note that

View file

@ -84,7 +84,7 @@ processed when reading a ``savefile''.
\fIcnt\fP
was 0 was undefined; different platforms and devices behaved
differently, so code that must work with older versions of libpcap
should use \-1, nor 0, as the value of
should use \-1, not 0, as the value of
\fIcnt\fP.)
.ft R
.PP
@ -119,8 +119,9 @@ them.
.B pcap_loop()
returns 0 if
.I cnt
is exhausted, \-1 if an error occurs, or \-2 if the loop terminated due
to a call to
is exhausted or if, when reading from a ``savefile'', no more packets
are available. It returns \-1 if an error occurs or \-2 if the loop
terminated due to a call to
.B pcap_breakloop()
before any packets were processed.
It does

View file

@ -29,7 +29,7 @@ pcap_offline_filter \- check whether a filter matches a packet
.ft
.LP
.ft B
int pcap_offline_filter(struct bpf_program *fp,
int pcap_offline_filter(const struct bpf_program *fp,
.ti +8
const struct pcap_pkthdr *h, const u_char *pkt)
.ft

View file

@ -207,20 +207,8 @@ vrrp return VRRP;
carp return CARP;
radio return RADIO;
ip6 {
#ifdef INET6
return IPV6;
#else
bpf_error("%s not supported", yytext);
#endif
}
icmp6 {
#ifdef INET6
return ICMPV6;
#else
bpf_error("%s not supported", yytext);
#endif
}
ip6 return IPV6;
icmp6 return ICMPV6;
ah return AH;
esp return ESP;

View file

@ -62,6 +62,15 @@
/* if libnl exists and is version 2.x */
/* #undef HAVE_LIBNL_2_x */
/* if libnl exists and is version 3.x */
/* #undef HAVE_LIBNL_3_x */
/* libnl has NLE_FAILURE */
/* #undef HAVE_LIBNL_NLE */
/* libnl has new-style socket api */
/* #undef HAVE_LIBNL_SOCKETS */
/* Define to 1 if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1
@ -217,11 +226,14 @@
/* path for device for USB sniffing */
/* #undef LINUX_USB_MON_DEV */
/* if we need a pcap_parse wrapper around yyparse */
#define NEED_YYPARSE_WRAPPER
/* Define to 1 if netinet/ether.h declares `ether_hostton' */
/* #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,9 +250,6 @@
/* 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 ""
@ -265,6 +274,9 @@
/* include ACN support */
/* #undef SITA */
/* if struct sockaddr_hci has hci_channel member */
/* #undef SOCKADDR_HCI_HAS_HCI_CHANNEL */
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1