Vendor import of libpcap 1.4.0.
This commit is contained in:
parent
3ca61f8b14
commit
59ed764380
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor/libpcap/dist/; revision=251125 svn path=/vendor/libpcap/1.4.0/; revision=251126; tag=vendor/libpcap/1.4.0
32
CHANGES
32
CHANGES
@ -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}.
|
||||
|
4
CREDITS
4
CREDITS
@ -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/
|
||||
|
22
README
22
README
@ -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
|
||||
|
@ -19,11 +19,13 @@ Using BPF:
|
||||
possible a description of the symptoms, including indications of the
|
||||
network link-layer type being wrong or time stamps being wrong).
|
||||
|
||||
If you fix the problems yourself, please submit a patch to
|
||||
If you fix the problems yourself, please submit a patch by forking
|
||||
the branch at
|
||||
|
||||
http://sourceforge.net/projects/libpcap/
|
||||
https://github.com/mcr/libpcap/issues
|
||||
|
||||
so we can incorporate them into the next release.
|
||||
and issuing a pull request, so we can incorporate the fixes into the
|
||||
next release.
|
||||
|
||||
If you don't fix the problems yourself, you can, as a workaround,
|
||||
make libpcap use DLPI instead of BPF.
|
||||
|
20
README.dag
20
README.dag
@ -96,12 +96,20 @@ implemented.
|
||||
DAG cards by default capture entire packets including the L2
|
||||
CRC/FCS. If the card is not configured to discard the CRC/FCS, this
|
||||
can confuse applications that use libpcap if they're not prepared for
|
||||
packets to have an FCS. Libpcap now reads the environment variable
|
||||
ERF_FCS_BITS to determine how many bits of CRC/FCS to strip from the
|
||||
end of the captured frame. This defaults to 32 for use with
|
||||
Ethernet. If the card is configured to strip the CRC/FCS, then set
|
||||
ERF_FCS_BITS=0. If used with a HDLC/PoS/PPP/Frame Relay link with 16
|
||||
bit CRC/FCS, then set ERF_FCS_BITS=16.
|
||||
packets to have an FCS.
|
||||
|
||||
Libpcap now reads the environment variable ERF_FCS_BITS to determine
|
||||
how many bits of CRC/FCS to strip from the end of the captured
|
||||
frame. This defaults to 32 for use with Ethernet. If the card is
|
||||
configured to strip the CRC/FCS, then set ERF_FCS_BITS=0. If used with
|
||||
a HDLC/PoS/PPP/Frame Relay link with 16 bit CRC/FCS, then set
|
||||
ERF_FCS_BITS=16.
|
||||
|
||||
If you wish to create a pcap file that DOES contain the Ethernet FCS,
|
||||
specify the environment variable ERF_DONT_STRIP_FCS. This will cause
|
||||
the existing FCS to be captured into the pcap file. Note some
|
||||
applications may incorrectly report capture errors or oversize packets
|
||||
when reading these files.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
|
21
aclocal.m4
vendored
21
aclocal.m4
vendored
@ -256,7 +256,7 @@ AC_DEFUN(AC_LBL_SHLIBS_INIT,
|
||||
sparc64*)
|
||||
case "$host_os" in
|
||||
|
||||
freebsd*)
|
||||
freebsd*|openbsd*)
|
||||
PIC_OPT=-fPIC
|
||||
;;
|
||||
esac
|
||||
@ -458,7 +458,22 @@ dnl Check for flex, default to lex
|
||||
dnl Require flex 2.4 or higher
|
||||
dnl Check for bison, default to yacc
|
||||
dnl Default to lex/yacc if both flex and bison are not available
|
||||
dnl Define the yy prefix string if using flex and bison
|
||||
dnl
|
||||
dnl If we're using flex and bison, pass -P to flex and -p to bison
|
||||
dnl to define a prefix string for the lexer and parser
|
||||
dnl
|
||||
dnl If we're not using flex and bison, don't pass those options
|
||||
dnl (as they might not work - although if "lex" is a wrapper for
|
||||
dnl Flex and "yacc" is a wrapper for Bison, they will work), and
|
||||
dnl define NEED_YYPARSE_WRAPPER (we *CANNOT* use YYBISON to check
|
||||
dnl whether the wrapper is needed, as some people apparently, for
|
||||
dnl some unknown reason, choose to use --without-flex and
|
||||
dnl --without-bison on systems that have Flex and Bison, which
|
||||
dnl means that the "yacc" they end up using is a wrapper that
|
||||
dnl runs "bison -y", and at least some versions of Bison define
|
||||
dnl YYBISON even if run with "-y", so we end up not compiling
|
||||
dnl the yyparse wrapper and end up with a libpcap that doesn't
|
||||
dnl define pcap_parse())
|
||||
dnl
|
||||
dnl usage:
|
||||
dnl
|
||||
@ -510,6 +525,8 @@ AC_DEFUN(AC_LBL_LEX_AND_YACC,
|
||||
if test "$$1" = flex -a -n "$3" ; then
|
||||
$1="$$1 -P$3"
|
||||
$2="$$2 -p $3"
|
||||
else
|
||||
AC_DEFINE(NEED_YYPARSE_WRAPPER,1,[if we need a pcap_parse wrapper around yyparse])
|
||||
fi])
|
||||
|
||||
dnl
|
||||
|
15
bpf_image.c
15
bpf_image.c
@ -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;
|
||||
}
|
||||
|
18
config.h.in
18
config.h.in
@ -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
|
||||
|
||||
|
97
configure.in
97
configure.in
@ -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
|
||||
|
13
fad-getad.c
13
fad-getad.c
@ -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.
|
||||
|
14
fad-gifc.c
14
fad-gifc.c
@ -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.
|
||||
|
11
fad-glifc.c
11
fad-glifc.c
@ -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.
|
||||
|
@ -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
|
||||
|
||||
|
106
gencode.c
106
gencode.c
@ -107,6 +107,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
|
||||
@ -261,20 +273,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);
|
||||
@ -425,6 +433,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;
|
||||
@ -2832,11 +2849,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;
|
||||
@ -3044,11 +3059,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 */
|
||||
@ -3072,10 +3086,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();
|
||||
@ -3197,11 +3209,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*/
|
||||
@ -3219,11 +3229,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,
|
||||
@ -3275,13 +3283,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:
|
||||
/*
|
||||
@ -3628,7 +3634,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)
|
||||
@ -4506,13 +4512,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);
|
||||
@ -4669,7 +4673,7 @@ gen_host6(addr, mask, proto, dir, type)
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
#endif /*INET6*/
|
||||
#endif
|
||||
|
||||
#ifndef INET6
|
||||
static struct block *
|
||||
@ -4761,26 +4765,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:
|
||||
@ -4808,10 +4806,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
|
||||
@ -4873,7 +4869,6 @@ gen_proto_abbrev(proto)
|
||||
b1 = gen_linktype(ETHERTYPE_MOPRC);
|
||||
break;
|
||||
|
||||
#ifdef INET6
|
||||
case Q_IPV6:
|
||||
b1 = gen_linktype(ETHERTYPE_IPV6);
|
||||
break;
|
||||
@ -4884,17 +4879,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
|
||||
@ -4902,10 +4894,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:
|
||||
@ -5038,7 +5028,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;
|
||||
@ -5046,7 +5035,6 @@ gen_portatom6(off, v)
|
||||
{
|
||||
return gen_cmp(OR_TRAN_IPV6, off, BPF_H, v);
|
||||
}
|
||||
#endif/*INET6*/
|
||||
|
||||
struct block *
|
||||
gen_portop(port, proto, dir)
|
||||
@ -5138,7 +5126,6 @@ gen_port(port, ip_proto, dir)
|
||||
return b1;
|
||||
}
|
||||
|
||||
#ifdef INET6
|
||||
struct block *
|
||||
gen_portop6(port, proto, dir)
|
||||
int port, proto, dir;
|
||||
@ -5211,7 +5198,6 @@ gen_port6(port, ip_proto, dir)
|
||||
gen_and(b0, b1);
|
||||
return b1;
|
||||
}
|
||||
#endif /* INET6 */
|
||||
|
||||
/* gen_portrange code */
|
||||
static struct block *
|
||||
@ -5316,7 +5302,6 @@ gen_portrange(port1, port2, ip_proto, dir)
|
||||
return b1;
|
||||
}
|
||||
|
||||
#ifdef INET6
|
||||
static struct block *
|
||||
gen_portrangeatom6(off, v1, v2)
|
||||
int off;
|
||||
@ -5417,7 +5402,6 @@ gen_portrange6(port1, port2, ip_proto, dir)
|
||||
gen_and(b0, b1);
|
||||
return b1;
|
||||
}
|
||||
#endif /* INET6 */
|
||||
|
||||
static int
|
||||
lookup_proto(name, proto)
|
||||
@ -5552,7 +5536,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);
|
||||
|
||||
@ -5565,7 +5549,7 @@ gen_protochain(v, proto, dir)
|
||||
s[i]->s.k = 40;
|
||||
i++;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
bpf_error("unsupported proto to gen_protochain");
|
||||
/*NOTREACHED*/
|
||||
@ -5592,7 +5576,6 @@ gen_protochain(v, proto, dir)
|
||||
fix2 = i;
|
||||
i++;
|
||||
|
||||
#ifdef INET6
|
||||
if (proto == Q_IPV6) {
|
||||
int v6start, v6end, v6advance, j;
|
||||
|
||||
@ -5674,9 +5657,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;
|
||||
@ -5820,10 +5801,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)
|
||||
@ -5831,14 +5810,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,
|
||||
@ -5989,7 +5965,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
|
||||
@ -6010,7 +5985,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");
|
||||
@ -6267,13 +6241,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 &&
|
||||
@ -6317,13 +6287,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
|
||||
@ -6471,16 +6437,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)
|
||||
@ -6497,16 +6459,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");
|
||||
@ -6796,9 +6754,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.
|
||||
@ -6907,16 +6863,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);
|
||||
@ -7468,13 +7420,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 */
|
||||
|
@ -167,7 +167,7 @@ yyerror(const char *msg)
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
#ifndef YYBISON
|
||||
#ifdef NEED_YYPARSE_WRAPPER
|
||||
int yyparse(void);
|
||||
|
||||
int
|
||||
|
@ -247,6 +247,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;
|
||||
|
192
optimize.c
192
optimize.c
@ -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;
|
||||
|
||||
|
49
pcap-bpf.c
49
pcap-bpf.c
@ -122,14 +122,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
|
||||
@ -218,30 +210,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);
|
||||
@ -407,19 +390,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);
|
||||
@ -1701,7 +1675,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;
|
||||
@ -2283,15 +2257,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);
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
53
pcap-dag.c
53
pcap-dag.c
@ -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))
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 .
|
||||
@ -918,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
|
||||
|
34
pcap-int.h
34
pcap-int.h
@ -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,
|
||||
|
@ -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;
|
||||
|
||||
|
297
pcap-linux.c
297
pcap-linux.c
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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";
|
||||
|
@ -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);
|
||||
|
51
pcap-sita.c
51
pcap-sita.c
@ -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);
|
||||
|
27
pcap-snf.c
27
pcap-snf.c
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
234
pcap.c
234
pcap.c
@ -74,8 +74,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
|
||||
@ -232,6 +259,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)
|
||||
{
|
||||
@ -1023,7 +1217,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);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1041,7 +1246,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);
|
||||
}
|
||||
@ -1055,7 +1260,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)
|
||||
@ -1072,7 +1288,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);
|
||||
}
|
||||
@ -1081,7 +1297,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);
|
||||
}
|
||||
@ -1464,10 +1680,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));
|
||||
|
18
pcap/bpf.h
18
pcap/bpf.h
@ -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
|
||||
|
13
pcap/pcap.h
13
pcap/pcap.h
@ -113,12 +113,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;
|
||||
@ -370,8 +371,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 **);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
16
scanner.l
16
scanner.l
@ -206,20 +206,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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user