aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2009-04-25 03:30:10 +0000
committerFelix Fietkau <nbd@openwrt.org>2009-04-25 03:30:10 +0000
commit25e9d9025668dc638fcd171e43bbf9cd2895ea31 (patch)
tree8cd67a42e3d96f455272f278298be302efbabd16
parent8ce7b559d0f6533bcbe154f332855426d1d7a368 (diff)
downloadupstream-25e9d9025668dc638fcd171e43bbf9cd2895ea31.tar.gz
upstream-25e9d9025668dc638fcd171e43bbf9cd2895ea31.tar.bz2
upstream-25e9d9025668dc638fcd171e43bbf9cd2895ea31.zip
pcap: update to version 1.0.0, add extension for changing the desired protocol for the internal raw socket (useful for reducing the cpu overhead of capture)
SVN-Revision: 15398
-rw-r--r--package/libpcap/Makefile36
-rw-r--r--package/libpcap/patches/100-debian_shared_lib.patch (renamed from package/libpcap/patches/100-shared-lib.patch)108
-rw-r--r--package/libpcap/patches/101-cross-compile-fix.patch11
-rw-r--r--package/libpcap/patches/101-debian_fix_any_intf.patch149
-rw-r--r--package/libpcap/patches/102-alt-ether.patch38
-rw-r--r--package/libpcap/patches/102-fix_install.patch11
-rw-r--r--package/libpcap/patches/103-flex_workaround.patch4
-rw-r--r--package/libpcap/patches/104-no_rej_files.patch469
-rw-r--r--package/libpcap/patches/105-space_optimization.patch102
-rw-r--r--package/libpcap/patches/106-protocol_api.patch141
10 files changed, 464 insertions, 605 deletions
diff --git a/package/libpcap/Makefile b/package/libpcap/Makefile
index 7414195d95..bc6417d0e5 100644
--- a/package/libpcap/Makefile
+++ b/package/libpcap/Makefile
@@ -8,12 +8,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=libpcap
-PKG_VERSION:=0.9.8
+PKG_VERSION:=1.0.0
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=http://www.tcpdump.org/release/
-PKG_MD5SUM:=5208f24d0328ee7c20b52c43eaa9aa0e
+PKG_MD5SUM:=9ad1358c5dec48456405eac197a46d3d
include $(INCLUDE_DIR)/package.mk
@@ -29,6 +29,21 @@ define Package/libpcap/description
packet capture.
endef
+define Package/libpcap/config
+ config PCAP_HAS_USB
+ bool "Include USB support"
+ depends PACKAGE_libpcap
+ depends PACKAGE_kmod-usb-core
+ default n
+
+ config PCAP_HAS_BT
+ bool "Include bluetooth support"
+ depends PACKAGE_libpcap
+ depends PACKAGE_kmod-bluetooth
+ default n
+
+endef
+
TARGET_CFLAGS += \
-ffunction-sections -fdata-sections
@@ -38,9 +53,15 @@ CONFIGURE_ARGS += \
--disable-yydebug \
--enable-ipv6 \
--with-build-cc="$(HOSTCC)" \
- --with-pcap=linux
+ --with-pcap=linux \
+ --without-septel \
+ --without-dag
define Build/Compile
+ rm -rf $(PKG_INSTALL_DIR)
+ $(if $(CONFIG_PCAP_HAS_USB),,$(SED) '/^#define PCAP_SUPPORT_USB/D' $(PKG_BUILD_DIR)/config.h)
+ $(if $(CONFIG_PCAP_HAS_USB),,$(SED) 's/pcap-usb-linux.c *//' $(PKG_BUILD_DIR)/Makefile)
+ $(if $(CONFIG_PCAP_HAS_BT),,$(SED) '/^#define PCAP_SUPPORT_BT/D' $(PKG_BUILD_DIR)/config.h)
$(MAKE) -C $(PKG_BUILD_DIR) \
CCOPT="$(TARGET_CFLAGS) -I$(BUILD_DIR)/linux/include" \
DESTDIR="$(PKG_INSTALL_DIR)" \
@@ -48,11 +69,12 @@ define Build/Compile
endef
define Build/InstallDev
- mkdir -p $(1)/usr/include
- $(CP) $(PKG_INSTALL_DIR)/usr/include/pcap{,-bpf,-namedb}.h \
+ mkdir -p $(1)/usr/include $(1)/usr/lib
+ $(CP) \
+ $(PKG_INSTALL_DIR)/usr/include/pcap* \
$(1)/usr/include/
- mkdir -p $(1)/usr/lib
- $(CP) $(PKG_INSTALL_DIR)/usr/lib/libpcap.{a,so*} \
+ $(CP) \
+ $(PKG_INSTALL_DIR)/usr/lib/libpcap.{a,so*} \
$(1)/usr/lib/
endef
diff --git a/package/libpcap/patches/100-shared-lib.patch b/package/libpcap/patches/100-debian_shared_lib.patch
index aae77f8e72..76d3729ef9 100644
--- a/package/libpcap/patches/100-shared-lib.patch
+++ b/package/libpcap/patches/100-debian_shared_lib.patch
@@ -1,22 +1,29 @@
+Debian-specific modifications to the upstream Makefile.in to
+build a shared library.
+---
+ Makefile.in | 45 ++++++++++++++++++++++++++++++++++++++++++---
+ configure | 2 +-
+ configure.in | 2 +-
+ 3 files changed, 44 insertions(+), 5 deletions(-)
+
--- a/Makefile.in
+++ b/Makefile.in
-@@ -37,6 +37,15 @@
+@@ -40,6 +40,14 @@ mandir = @mandir@
srcdir = @srcdir@
VPATH = @srcdir@
+# some defines for shared library compilation
-+MAJ=0.9
-+MIN=8
-+VERSION=$(MAJ).$(MIN)
++MAJ=1.0
++LIBVERSION=$(MAJ).0
+LIBNAME=pcap
+LIBRARY=lib$(LIBNAME).a
+SOLIBRARY=lib$(LIBNAME).so
-+SHAREDLIB=$(SOLIBRARY).$(VERSION)
++SHAREDLIB=$(SOLIBRARY).$(LIBVERSION)
+
#
# You shouldn't need to edit anything below.
#
-@@ -52,6 +61,7 @@
+@@ -56,6 +64,7 @@ PROG=libpcap
# Standard CFLAGS
CFLAGS = $(CCOPT) $(INCLS) $(DEFS)
@@ -24,41 +31,49 @@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
-@@ -72,7 +82,12 @@
+@@ -75,7 +84,11 @@ YACC = @V_YACC@
+ # problem if you don't own the file but can write to the directory.
.c.o:
@rm -f $@
- $(CC) $(CFLAGS) -c $(srcdir)/$*.c
+- $(CC) $(CFLAGS) -c $(srcdir)/$*.c
+ $(CC) $(CFLAGS) -c -o $@ $(srcdir)/$*.c
-
++
+%_pic.o: %.c
+ @rm -f $@
+ $(CC) -fPIC $(CFLAGS) -c -o $@ $(srcdir)/$*.c
-+
- PSRC = pcap-@V_PCAP@.c
+
+ PSRC = pcap-@V_PCAP@.c @USB_SRC@ @BT_SRC@
FSRC = fad-@V_FINDALLDEVS@.c
- SSRC = @SSRC@
-@@ -86,6 +101,7 @@
+@@ -90,6 +103,7 @@ SRC = $(PSRC) $(FSRC) $(CSRC) $(SSRC) $(
# We would like to say "OBJ = $(SRC:.c=.o)" but Ultrix's make cannot
# hack the extra indirection
OBJ = $(PSRC:.c=.o) $(FSRC:.c=.o) $(CSRC:.c=.o) $(SSRC:.c=.o) $(GENSRC:.c=.o) $(LIBOBJS)
+OBJ_PIC = $(PSRC:.c=_pic.o) $(FSRC:.c=_pic.o) $(CSRC:.c=_pic.o) $(SSRC:.c=_pic.o) $(GENSRC:.c=_pic.o)
- HDR = pcap.h pcap-int.h pcap-namedb.h pcap-nit.h pcap-pf.h \
- ethertype.h gencode.h gnuc.h
- GENHDR = \
-@@ -97,15 +113,23 @@
+ HDR = \
+ acconfig.h \
+ arcnet.h \
+@@ -122,7 +136,8 @@ TAGHDR = \
TAGFILES = \
$(SRC) $(HDR) $(TAGHDR)
-CLEANFILES = $(OBJ) libpcap.a $(GENSRC) $(GENHDR) lex.yy.c
-+CLEANFILES = $(OBJ) $(OBJ_PIC) libpcap.a $(GENSRC) $(GENHDR) lex.yy.c libpcap.so*
++CLEANFILES = $(OBJ) libpcap.a $(GENSRC) $(GENHDR) lex.yy.c \
++ $(OBJ_PIC) libpcap.so*
+
+ MAN1 = pcap-config.1
+
+@@ -311,7 +326,7 @@ EXTRA_DIST = \
+ Win32/Src/inet_net.c \
+ Win32/Src/inet_pton.c
--all: libpcap.a
-+all: libpcap.a $(SHAREDLIB)
+-all: libpcap.a pcap-config
++all: libpcap.a pcap-config $(SHAREDLIB)
libpcap.a: $(OBJ)
@rm -f $@
- ar rc $@ $(OBJ) $(LIBS)
- $(RANLIB) $@
+@@ -344,6 +359,13 @@ libpcap.dylib: $(OBJ)
+ -compatibility_version 1 \
+ -current_version `sed 's/[^0-9.].*$$//' $(srcdir)/VERSION`
+$(SHAREDLIB): $(OBJ_PIC)
+ -@rm -f $@
@@ -67,28 +82,26 @@
+ ln -s $(SHAREDLIB) $(SOLIBRARY).$(MAJ)
+ ln -s $(SOLIBRARY).$(MAJ) $(SOLIBRARY)
+
-+
- shared: libpcap.$(DYEXT)
-
- #
-@@ -131,6 +155,10 @@
+ scanner.c: $(srcdir)/scanner.l
+ @rm -f $@
+ ./runlex.sh $(LEX) -o$@ $<
+@@ -351,6 +373,9 @@ scanner.c: $(srcdir)/scanner.l
scanner.o: scanner.c tokdefs.h
$(CC) $(CFLAGS) -c scanner.c
+scanner_pic.o: scanner.c tokdefs.h
+ $(CC) -fPIC $(CFLAGS) -o $@ -c scanner.c
+
-+
pcap.o: version.h
tokdefs.h: grammar.c
-@@ -144,9 +172,16 @@
+@@ -364,9 +389,17 @@ grammar.o: grammar.c
@rm -f $@
$(CC) $(CFLAGS) -Dyylval=pcap_lval -c grammar.c
+grammar_pic.o: grammar.c
+ @rm -f $@
-+ $(CC) -fPIC $(CFLAGS) -Dyylval=pcap_lval -o $@ -c grammar.c
++ $(CC) -fPIC $(CFLAGS) -Dyylval=pcap_lval -o $@ -c grammar.c
+
version.o: version.c
$(CC) $(CFLAGS) -c version.c
@@ -96,24 +109,49 @@
+version_pic.o: version.c
+ $(CC) -fPIC $(CFLAGS) -c version.c -o $@
+
++
snprintf.o: $(srcdir)/missing/snprintf.c
$(CC) $(CFLAGS) -o $@ -c $(srcdir)/missing/snprintf.c
-@@ -172,10 +207,17 @@
+@@ -392,6 +425,9 @@ bpf_filter.c: $(srcdir)/bpf/net/bpf_filt
bpf_filter.o: bpf_filter.c
$(CC) $(CFLAGS) -c bpf_filter.c
+bpf_filter_pic.o: bpf_filter.c
+ $(CC) -fPIC $(CFLAGS) -c bpf_filter.c -o $@
+
-+
- install: libpcap.a
- [ -d $(DESTDIR)$(libdir) ] || \
+ #
+ # Generate the pcap-config script.
+ #
+@@ -418,6 +454,9 @@ install: libpcap.a pcap-config
(mkdir -p $(DESTDIR)$(libdir); chmod 755 $(DESTDIR)$(libdir))
$(INSTALL_DATA) libpcap.a $(DESTDIR)$(libdir)/libpcap.a
+ $(RANLIB) $(DESTDIR)$(libdir)/libpcap.a
+ $(INSTALL_DATA) $(SHAREDLIB) $(DESTDIR)$(libdir)/
+ ln -sf $(SHAREDLIB) $(DESTDIR)$(libdir)/$(SOLIBRARY).$(MAJ)
+ ln -sf $(SOLIBRARY).$(MAJ) $(DESTDIR)$(libdir)/$(SOLIBRARY)
- $(RANLIB) $(DESTDIR)$(libdir)/libpcap.a
[ -d $(DESTDIR)$(includedir) ] || \
(mkdir -p $(DESTDIR)$(includedir); chmod 755 $(DESTDIR)$(includedir))
+ [ -d $(DESTDIR)$(includedir)/pcap ] || \
+--- a/configure
++++ b/configure
+@@ -8658,7 +8658,7 @@ irix*)
+ ;;
+
+ linux*)
+- V_CCOPT="$V_CCOPT -fPIC"
++ V_CCOPT="$V_CCOPT"
+ ;;
+
+ osf*)
+--- a/configure.in
++++ b/configure.in
+@@ -943,7 +943,7 @@ irix*)
+ ;;
+
+ linux*)
+- V_CCOPT="$V_CCOPT -fPIC"
++ V_CCOPT="$V_CCOPT"
+ ;;
+
+ osf*)
diff --git a/package/libpcap/patches/101-cross-compile-fix.patch b/package/libpcap/patches/101-cross-compile-fix.patch
deleted file mode 100644
index 2f166c8491..0000000000
--- a/package/libpcap/patches/101-cross-compile-fix.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/Makefile.in
-+++ b/Makefile.in
-@@ -119,7 +119,7 @@
-
- libpcap.a: $(OBJ)
- @rm -f $@
-- ar rc $@ $(OBJ) $(LIBS)
-+ $(AR) rc $@ $(OBJ) $(LIBS)
- $(RANLIB) $@
-
- $(SHAREDLIB): $(OBJ_PIC)
diff --git a/package/libpcap/patches/101-debian_fix_any_intf.patch b/package/libpcap/patches/101-debian_fix_any_intf.patch
new file mode 100644
index 0000000000..8da6ef2237
--- /dev/null
+++ b/package/libpcap/patches/101-debian_fix_any_intf.patch
@@ -0,0 +1,149 @@
+--- a/pcap-linux.c
++++ b/pcap-linux.c
+@@ -297,6 +297,12 @@ pcap_create(const char *device, char *eb
+ {
+ 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);
+@@ -338,10 +344,9 @@ pcap_can_set_rfmon_linux(pcap_t *p)
+ struct iwreq ireq;
+ #endif
+
+- if (p->opt.source == NULL) {
++ if (strcmp(p->opt.source, "any") == 0) {
+ /*
+- * This is equivalent to the "any" device, and we don't
+- * support monitor mode on it.
++ * Monitor mode makes no sense on the "any" device.
+ */
+ return 0;
+ }
+@@ -518,12 +523,11 @@ pcap_activate_linux(pcap_t *handle)
+ handle->stats_op = pcap_stats_linux;
+
+ /*
+- * NULL and "any" are special devices which give us the hint to
+- * monitor all devices.
++ * The "any" device is a special device which causes us not
++ * to bind to a particular device and thus to look at all
++ * devices.
+ */
+- if (!device || strcmp(device, "any") == 0) {
+- device = NULL;
+- handle->md.device = strdup("any");
++ if (strcmp(device, "any") == 0) {
+ if (handle->opt.promisc) {
+ handle->opt.promisc = 0;
+ /* Just a warning. */
+@@ -531,10 +535,9 @@ pcap_activate_linux(pcap_t *handle)
+ "Promiscuous mode not supported on the \"any\" device");
+ status = PCAP_WARNING_PROMISC_NOTSUP;
+ }
++ }
+
+- } else
+- handle->md.device = strdup(device);
+-
++ handle->md.device = strdup(device);
+ if (handle->md.device == NULL) {
+ snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "strdup: %s",
+ pcap_strerror(errno) );
+@@ -1657,19 +1660,21 @@ static int
+ activate_new(pcap_t *handle)
+ {
+ #ifdef HAVE_PF_PACKET_SOCKETS
++ const char *device = handle->opt.source;
++ int is_any_device = (strcmp(device, "any") == 0);
+ int sock_fd = -1, arptype, val;
+ int err = 0;
+ struct packet_mreq mr;
+- const char* device = handle->opt.source;
+
+ /*
+- * Open a socket with protocol family packet. If a device is
+- * given we try to open it in raw mode otherwise we use
+- * the cooked interface.
+- */
+- sock_fd = device ?
+- socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))
+- : socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL));
++ * Open a socket with protocol family packet. If the
++ * "any" device was specified, we open a SOCK_DGRAM
++ * socket for the cooked interface, otherwise we first
++ * try a SOCK_RAW socket for the raw interface.
++ */
++ sock_fd = is_any_device ?
++ socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL)) :
++ socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
+
+ if (sock_fd == -1) {
+ snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "socket: %s",
+@@ -1704,7 +1709,7 @@ activate_new(pcap_t *handle)
+ * to cooked mode if we have an unknown interface type
+ * or a type we know doesn't work well in raw mode.
+ */
+- if (device) {
++ if (!is_any_device) {
+ /* Assume for now we don't need cooked mode. */
+ handle->md.cooked = 0;
+
+@@ -1819,15 +1824,23 @@ activate_new(pcap_t *handle)
+ }
+ } else {
+ /*
+- * This is cooked mode.
++ * The "any" device.
++ */
++ if (handle->opt.rfmon) {
++ /*
++ * It doesn't support monitor mode.
++ */
++ return PCAP_ERROR_RFMON_NOTSUP;
++ }
++
++ /*
++ * It uses cooked mode.
+ */
+ handle->md.cooked = 1;
+ handle->linktype = DLT_LINUX_SLL;
+
+ /*
+ * We're not bound to a device.
+- * XXX - true? Or true only if we're using
+- * the "any" device?
+ * For now, we're using this as an indication
+ * that we can't transmit; stop doing that only
+ * if we figure out how to transmit in cooked
+@@ -1852,10 +1865,13 @@ activate_new(pcap_t *handle)
+
+ /*
+ * Hmm, how can we set promiscuous mode on all interfaces?
+- * I am not sure if that is possible at all.
++ * I am not sure if that is possible at all. For now, we
++ * silently ignore attempts to turn promiscuous mode on
++ * for the "any" device (so you don't have to explicitly
++ * disable it in programs such as tcpdump).
+ */
+
+- if (device && handle->opt.promisc) {
++ if (!is_any_device && handle->opt.promisc) {
+ memset(&mr, 0, sizeof(mr));
+ mr.mr_ifindex = handle->md.ifindex;
+ mr.mr_type = PACKET_MR_PROMISC;
+@@ -3118,7 +3134,7 @@ activate_old(pcap_t *handle)
+
+ /* Bind to the given device */
+
+- if (!device) {
++ if (strcmp(device, "any") == 0) {
+ strncpy(handle->errbuf, "pcap_activate: The \"any\" device isn't supported on 2.0[.x]-kernel systems",
+ PCAP_ERRBUF_SIZE);
+ return PCAP_ERROR;
diff --git a/package/libpcap/patches/102-alt-ether.patch b/package/libpcap/patches/102-alt-ether.patch
deleted file mode 100644
index e9cc15ff36..0000000000
--- a/package/libpcap/patches/102-alt-ether.patch
+++ /dev/null
@@ -1,38 +0,0 @@
---- a/nametoaddr.c
-+++ b/nametoaddr.c
-@@ -410,7 +410,7 @@
- e = ep = (u_char *)malloc(6);
-
- while (*s) {
-- if (*s == ':')
-+ if (*s == ':' || *s == '.')
- s += 1;
- d = xdtoi(*s++);
- if (isxdigit((unsigned char)*s)) {
---- a/scanner.l
-+++ b/scanner.l
-@@ -80,6 +80,7 @@
- N ([0-9]+|(0X|0x)[0-9A-Fa-f]+)
- B ([0-9A-Fa-f][0-9A-Fa-f]?)
- W ([0-9A-Fa-f][0-9A-Fa-f]?[0-9A-Fa-f]?[0-9A-Fa-f]?)
-+X [0-9A-Fa-f]
-
- %a 18400
- %o 21500
-@@ -310,7 +311,7 @@
- {N} { yylval.i = stoi((char *)yytext); return NUM; }
- ({N}\.{N})|({N}\.{N}\.{N})|({N}\.{N}\.{N}\.{N}) {
- yylval.s = sdup((char *)yytext); return HID; }
--{B}:{B}:{B}:{B}:{B}:{B} { yylval.e = pcap_ether_aton((char *)yytext);
-+({B}:{B}:{B}:{B}:{B}:{B})|({B}\.{B}\.{B}\.{B}\.{B}\.{B}) { yylval.e = pcap_ether_aton((char *)yytext);
- return EID; }
- {V6} {
- #ifdef INET6
-@@ -328,6 +329,7 @@
- #endif /*INET6*/
- }
- {B}:+({B}:+)+ { bpf_error("bogus ethernet address %s", yytext); }
-+{X}{12} { yylval.e = pcap_ether_aton((char *)yytext); return EID;}
- icmptype { yylval.i = 0; return NUM; }
- icmpcode { yylval.i = 1; return NUM; }
- icmp-echoreply { yylval.i = 0; return NUM; }
diff --git a/package/libpcap/patches/102-fix_install.patch b/package/libpcap/patches/102-fix_install.patch
new file mode 100644
index 0000000000..5264fb2f68
--- /dev/null
+++ b/package/libpcap/patches/102-fix_install.patch
@@ -0,0 +1,11 @@
+--- a/Makefile.in
++++ b/Makefile.in
+@@ -484,6 +484,8 @@ install: libpcap.a pcap-config
+ $(DESTDIR)$(includedir)/pcap-bpf.h
+ $(INSTALL_DATA) $(srcdir)/pcap-namedb.h \
+ $(DESTDIR)$(includedir)/pcap-namedb.h
++ [ -d $(DESTDIR)$(bindir) ] || \
++ (mkdir -p $(DESTDIR)$(bindir); chmod 755 $(DESTDIR)$(bindir))
+ $(INSTALL_PROGRAM) pcap-config $(DESTDIR)$(bindir)/pcap-config
+ for i in $(MAN1); do \
+ $(INSTALL_DATA) $(srcdir)/$$i \
diff --git a/package/libpcap/patches/103-flex_workaround.patch b/package/libpcap/patches/103-flex_workaround.patch
index 014c624d4a..5d0334272a 100644
--- a/package/libpcap/patches/103-flex_workaround.patch
+++ b/package/libpcap/patches/103-flex_workaround.patch
@@ -3,7 +3,7 @@
--- a/Makefile.in
+++ b/Makefile.in
-@@ -53,7 +53,7 @@
+@@ -55,7 +55,7 @@ SHAREDLIB=$(SOLIBRARY).$(LIBVERSION)
CC = @CC@
CCOPT = @V_CCOPT@
INCLS = -I. @V_INCLS@
@@ -11,4 +11,4 @@
+DEFS = -D_BSD_SOURCE @DEFS@ @V_DEFS@
LIBS = @V_LIBS@
DAGLIBS = @DAGLIBS@
- DYEXT = @DYEXT@
+ DEPLIBS = @DEPLIBS@
diff --git a/package/libpcap/patches/104-no_rej_files.patch b/package/libpcap/patches/104-no_rej_files.patch
deleted file mode 100644
index 0775705faf..0000000000
--- a/package/libpcap/patches/104-no_rej_files.patch
+++ /dev/null
@@ -1,469 +0,0 @@
-diff -urN libpcap-0.9.8/gencode.c.rej libpcap-0.9.8.new/gencode.c.rej
---- libpcap-0.9.8/gencode.c.rej 2007-07-10 21:38:15.000000000 +0200
-+++ libpcap-0.9.8.new/gencode.c.rej 1970-01-01 01:00:00.000000000 +0100
-@@ -1,465 +0,0 @@
--***************
--*** 24,29 ****
-- "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.221.2.51 2007/06/14 20:54:12 gianluca Exp $ (LBL)";
-- #endif
--
-- #ifdef HAVE_CONFIG_H
-- #include "config.h"
-- #endif
----- 24,31 ----
-- "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.221.2.51 2007/06/14 20:54:12 gianluca Exp $ (LBL)";
-- #endif
--
--+ #define ENABLE_WLAN_FILTERING_PATCH
--+
-- #ifdef HAVE_CONFIG_H
-- #include "config.h"
-- #endif
--***************
--*** 144,150 ****
-- OR_NET, /* relative to the network-layer header */
-- OR_NET_NOSNAP, /* relative to the network-layer header, with no SNAP header at the link layer */
-- OR_TRAN_IPV4, /* relative to the transport-layer header, with IPv4 network layer */
--- OR_TRAN_IPV6 /* relative to the transport-layer header, with IPv6 network layer */
-- };
--
-- /*
----- 146,153 ----
-- OR_NET, /* relative to the network-layer header */
-- OR_NET_NOSNAP, /* relative to the network-layer header, with no SNAP header at the link layer */
-- OR_TRAN_IPV4, /* relative to the transport-layer header, with IPv4 network layer */
--+ OR_TRAN_IPV6, /* relative to the transport-layer header, with IPv6 network layer */
--+ OR_LINK_AFTER_WIRELESS_HDR /* After the 802.11 variable length header */
-- };
--
-- /*
--***************
--*** 199,204 ****
-- static struct block *gen_linktype(int);
-- static struct block *gen_snap(bpf_u_int32, bpf_u_int32, u_int);
-- static struct block *gen_llc_linktype(int);
-- static struct block *gen_hostop(bpf_u_int32, bpf_u_int32, int, int, u_int, u_int);
-- #ifdef INET6
-- static struct block *gen_hostop6(struct in6_addr *, struct in6_addr *, int, int, u_int, u_int);
----- 202,208 ----
-- static struct block *gen_linktype(int);
-- static struct block *gen_snap(bpf_u_int32, bpf_u_int32, u_int);
-- static struct block *gen_llc_linktype(int);
--+ static struct block *gen_802_11_llc_linktype(int);
-- static struct block *gen_hostop(bpf_u_int32, bpf_u_int32, int, int, u_int, u_int);
-- #ifdef INET6
-- static struct block *gen_hostop6(struct in6_addr *, struct in6_addr *, int, int, u_int, u_int);
--***************
--*** 242,247 ****
-- static struct slist *xfer_to_a(struct arth *);
-- static struct block *gen_mac_multicast(int);
-- static struct block *gen_len(int, int);
--
-- static struct block *gen_ppi_dlt_check();
-- static struct block *gen_msg_abbrev(int type);
----- 246,252 ----
-- static struct slist *xfer_to_a(struct arth *);
-- static struct block *gen_mac_multicast(int);
-- static struct block *gen_len(int, int);
--+ static struct block *gen_check_802_11_data_frame();
--
-- static struct block *gen_ppi_dlt_check();
-- static struct block *gen_msg_abbrev(int type);
--***************
--*** 1345,1350 ****
-- return s;
-- }
--
--
-- /*
-- * Load a value relative to the beginning of the specified header.
----- 1350,1487 ----
-- return s;
-- }
--
--+ /*
--+ * Load a value relative to the beginning of the link-layer header after the 802.11
--+ * header, i.e. LLC_SNAP.
--+ * The link-layer header doesn't necessarily begin at the beginning
--+ * of the packet data; there might be a variable-length prefix containing
--+ * radio information.
--+ */
--+ static struct slist *
--+ gen_load_ll_after_802_11_rel(offset, size)
--+ u_int offset, size;
--+ {
--+ struct slist *s, *s_load_fc;
--+ struct slist *sjset_qos;
--+ struct slist *s_load;
--+ struct slist *s_ld_a_2;
--+ struct slist *s_add_a_x;
--+ struct slist *s_a_to_x;
--+ struct slist *sjset_data_frame_1;
--+ struct slist *sjset_data_frame_2;
--+ struct slist *s_load_x_0;
--+
--+ /*
--+ * This code is not compatible with the optimizer, as
--+ * we are generating jmp instructions within a normal
--+ * slist of instructions
--+ *
--+ */
--+ no_optimize = 1;
--+
--+ s = gen_llprefixlen();
--+
--+ /*
--+ * If "s" is non-null, it has code to arrange that the X register
--+ * contains the length of the prefix preceding the link-layer
--+ * header.
--+ *
--+ * Otherwise, the length of the prefix preceding the link-layer
--+ * header is "off_ll".
--+ */
--+ if (s != NULL) {
--+ /*
--+ * There's a variable-length prefix preceding the
--+ * link-layer header. "s" points to a list of statements
--+ * that put the length of that prefix into the X register.
--+ * do an indirect load, to use the X register as an offset.
--+ */
--+
--+ /*
--+ * Load the Frame Control field
--+ */
--+ s_load_fc = new_stmt(BPF_LD|BPF_IND|BPF_B);
--+ s_load_fc->s.k = 0;
--+ } else {
--+ /*
--+ * There is no variable-length header preceding the
--+ * link-layer header; add in off_ll, which, if there's
--+ * a fixed-length header preceding the link-layer header,
--+ * is the length of that header.
--+ */
--+
--+ /*
--+ * We need to load the Frame control directly, and
--+ * then load X with a fake 0, i.e. the length of the
--+ * non-existing prepended header
--+ */
--+
--+ /*
--+ * TODO GV: I'm not sure if 0 is the right constant in this
--+ * case. If the link layer has a fixed length prepended header,
--+ * that should be the value that we put here
--+ */
--+
--+ /* Load 0 into X */
--+ s_load_x_0 = new_stmt(BPF_LDX|BPF_IMM);
--+ s_load_x_0->s.k = 0;
--+
--+ /*
--+ * TODO GV: I'm not sure if 0 is the right constant in this
--+ * case. If the link layer has a fixed length prepended header,
--+ * that should be the value that we put here
--+ */
--+
--+ /*
--+ * load the Frame Control with absolute access
--+ */
--+ s_load_fc = new_stmt(BPF_LD|BPF_ABS|BPF_B);
--+ s_load_fc->s.k = 0;
--+ s = s_load_x_0;
--+ }
--+
--+ /*
--+ * Generate the common instructions to check if it's a data frame
--+ * and if so compute the 802.11 header length
--+ */
--+ sjset_data_frame_1 = new_stmt(JMP(BPF_JSET)); // b3 should be 1
--+ sjset_data_frame_1->s.k = 0x8;
--+
--+ sjset_data_frame_2 = new_stmt(JMP(BPF_JSET)); // b2 should be 0
--+ sjset_data_frame_2->s.k = 0x04;
--+
--+ sjset_qos = new_stmt(JMP(BPF_JSET));
--+ sjset_qos->s.k = 0x80; //QOS bit
--+
--+ s_ld_a_2 = new_stmt(BPF_LD|BPF_IMM);
--+ s_ld_a_2->s.k = 2;
--+
--+ s_add_a_x = new_stmt(BPF_ALU|BPF_ADD|BPF_X);
--+ s_a_to_x = new_stmt(BPF_MISC|BPF_TAX);
--+
--+ s_load = new_stmt(BPF_LD|BPF_IND|size);
--+ s_load->s.k = offset;
--+
--+ sjset_data_frame_1->s.jt = sjset_data_frame_2;
--+ sjset_data_frame_1->s.jf = s_load;
--+
--+ sjset_data_frame_2->s.jt = s_load;
--+ sjset_data_frame_2->s.jf = sjset_qos;
--+
--+ sjset_qos->s.jt = s_ld_a_2;
--+ sjset_qos->s.jf = s_load;
--+
--+ sappend(s, s_load_fc);
--+ sappend(s_load_fc, sjset_data_frame_1);
--+ sappend(sjset_data_frame_1, sjset_data_frame_2);
--+ sappend(sjset_data_frame_2, sjset_qos);
--+ sappend(sjset_qos, s_ld_a_2);
--+ sappend(s_ld_a_2, s_add_a_x);
--+ sappend(s_add_a_x,s_a_to_x);
--+ sappend(s_a_to_x, s_load);
--+
--+ return s;
--+ }
--
-- /*
-- * Load a value relative to the beginning of the specified header.
--***************
--*** 1367,1372 ****
-- s = gen_load_llrel(offset, size);
-- break;
--
-- case OR_NET:
-- s = gen_load_llrel(off_nl + offset, size);
-- break;
----- 1504,1525 ----
-- s = gen_load_llrel(offset, size);
-- break;
--
--+ #ifdef ENABLE_WLAN_FILTERING_PATCH
--+
--+ case OR_LINK_AFTER_WIRELESS_HDR:
--+ if (linktype != DLT_IEEE802_11_RADIO
--+ && linktype != DLT_PPI
--+ && linktype != DLT_IEEE802_11
--+ && linktype != DLT_PRISM_HEADER
--+ && linktype != DLT_IEEE802_11_RADIO_AVS)
--+ {
--+ abort();
--+ return NULL;
--+ }
--+ s = gen_load_ll_after_802_11_rel(offset + 24, size);
--+ break;
--+ #endif /* ENABLE_WLAN_FILTERING_PATCH */
--+
-- case OR_NET:
-- s = gen_load_llrel(off_nl + offset, size);
-- break;
--***************
--*** 2163,2173 ****
-- break;
--
-- case DLT_PPI:
-- case DLT_FDDI:
-- case DLT_IEEE802:
--- case DLT_IEEE802_11:
-- case DLT_IEEE802_11_RADIO_AVS:
--- case DLT_IEEE802_11_RADIO:
-- case DLT_PRISM_HEADER:
-- case DLT_ATM_RFC1483:
-- case DLT_ATM_CLIP:
----- 2316,2332 ----
-- break;
--
-- case DLT_PPI:
--+ case DLT_IEEE802_11_RADIO:
--+ case DLT_IEEE802_11:
--+ #ifdef ENABLE_WLAN_FILTERING_PATCH
--+ return gen_802_11_llc_linktype(proto);
--+ /*NOTREACHED*/
--+ break;
--+ #endif /* ENABLE_WLAN_FILTERING_PATCH */
--+
-- case DLT_FDDI:
-- case DLT_IEEE802:
-- case DLT_IEEE802_11_RADIO_AVS:
-- case DLT_PRISM_HEADER:
-- case DLT_ATM_RFC1483:
-- case DLT_ATM_CLIP:
--***************
--*** 2711,2716 ****
-- }
-- }
--
-- static struct block *
-- gen_hostop(addr, mask, dir, proto, src_off, dst_off)
-- bpf_u_int32 addr;
----- 2870,2982 ----
-- }
-- }
--
--+ /*
--+ * Generate code to match a particular packet type, for link-layer types
--+ * using 802.2 LLC headers.
--+ *
--+ * This is *NOT* used for Ethernet; "gen_ether_linktype()" is used
--+ * for that - it handles the D/I/X Ethernet vs. 802.3+802.2 issues.
--+ *
--+ * "proto" is an Ethernet type value, if > ETHERMTU, or an LLC SAP
--+ * value, if <= ETHERMTU. We use that to determine whether to
--+ * match the DSAP or both DSAP and LSAP or to check the OUI and
--+ * protocol ID in a SNAP header.
--+ */
--+ static struct block *
--+ gen_802_11_llc_linktype(proto)
--+ int proto;
--+ {
--+ struct block *b_check_data_frame;
--+ struct block *b_check_linktype;
--+
--+ b_check_data_frame = gen_check_802_11_data_frame();
--+
--+ /*
--+ * XXX - generate the code that discards non data frames
--+ */
--+ switch (proto) {
--+
--+ case LLCSAP_IP:
--+ case LLCSAP_ISONS:
--+ case LLCSAP_NETBEUI:
--+ /*
--+ * XXX - should we check both the DSAP and the
--+ * SSAP, like this, or should we check just the
--+ * DSAP, as we do for other types <= ETHERMTU
--+ * (i.e., other SAP values)?
--+ */
--+ b_check_linktype = gen_cmp(OR_LINK_AFTER_WIRELESS_HDR, 0, BPF_H, (bpf_u_int32)
--+ ((proto << 8) | proto));
--+ break;
--+
--+ case LLCSAP_IPX:
--+ /*
--+ * XXX - are there ever SNAP frames for IPX on
--+ * non-Ethernet 802.x networks?
--+ */
--+ b_check_linktype = gen_cmp(OR_LINK_AFTER_WIRELESS_HDR, 0, BPF_B,
--+ (bpf_int32)LLCSAP_IPX);
--+
--+ break;
--+
--+ #if 0
--+ case ETHERTYPE_ATALK:
--+ /*
--+ * 802.2-encapsulated ETHERTYPE_ATALK packets are
--+ * SNAP packets with an organization code of
--+ * 0x080007 (Apple, for Appletalk) and a protocol
--+ * type of ETHERTYPE_ATALK (Appletalk).
--+ *
--+ * XXX - check for an organization code of
--+ * encapsulated Ethernet as well?
--+ */
--+ return gen_snap(0x080007, ETHERTYPE_ATALK, off_linktype);
--+ #endif
--+ default:
--+ /*
--+ * XXX - we don't have to check for IPX 802.3
--+ * here, but should we check for the IPX Ethertype?
--+ */
--+ if (proto <= ETHERMTU) {
--+ /*
--+ * This is an LLC SAP value, so check
--+ * the DSAP.
--+ */
--+ b_check_linktype = gen_cmp(OR_LINK_AFTER_WIRELESS_HDR, 0, BPF_B,
--+ (bpf_int32)proto);
--+ } else {
--+ /*
--+ * This is an Ethernet type; we assume that it's
--+ * unlikely that it'll appear in the right place
--+ * at random, and therefore check only the
--+ * location that would hold the Ethernet type
--+ * in a SNAP frame with an organization code of
--+ * 0x000000 (encapsulated Ethernet).
--+ *
--+ * XXX - if we were to check for the SNAP DSAP and
--+ * LSAP, as per XXX, and were also to check for an
--+ * organization code of 0x000000 (encapsulated
--+ * Ethernet), we'd do
--+ *
--+ * return gen_snap(0x000000, proto,
--+ * off_linktype);
--+ *
--+ * here; for now, we don't, as per the above.
--+ * I don't know whether it's worth the extra CPU
--+ * time to do the right check or not.
--+ */
--+ b_check_linktype = gen_cmp(OR_LINK_AFTER_WIRELESS_HDR, 0+6, BPF_H,
--+ (bpf_int32)proto);
--+ }
--+ }
--+
--+ gen_and(b_check_data_frame, b_check_linktype);
--+ return b_check_linktype;
--+
--+ }
--+
--+
--+
-- static struct block *
-- gen_hostop(addr, mask, dir, proto, src_off, dst_off)
-- bpf_u_int32 addr;
--***************
--*** 2925,2930 ****
-- register struct block *b0, *b1, *b2;
-- register struct slist *s;
--
-- switch (dir) {
-- case Q_SRC:
-- /*
----- 3191,3207 ----
-- register struct block *b0, *b1, *b2;
-- register struct slist *s;
--
--+ #ifdef ENABLE_WLAN_FILTERING_PATCH
--+ /*
--+ * TODO GV 20070613
--+ * We need to disable the optimizer because the optimizer is buggy
--+ * and wipes out some LD instructions generated by the below
--+ * code to validate the Frame Control bits
--+ *
--+ */
--+ no_optimize = 1;
--+ #endif /* ENABLE_WLAN_FILTERING_PATCH */
--+
-- switch (dir) {
-- case Q_SRC:
-- /*
--***************
--*** 4713,4718 ****
-- #endif
-- }
--
--
-- /*
-- * Generate code that checks whether the packet is a packet for protocol
----- 4990,5021 ----
-- #endif
-- }
--
--+ static struct block *
--+ gen_check_802_11_data_frame()
--+ {
--+ struct slist *s;
--+ struct block *b0, *b1;
--+ /*
--+ * Now check for a data frame.
--+ * I.e, check "link[0] & 0x08".
--+ */
--+ s = gen_load_a(OR_LINK, 0, BPF_B);
--+ b0 = new_block(JMP(BPF_JSET));
--+ b0->s.k = 0x08;
--+ b0->stmts = s;
--+
--+ s = gen_load_a(OR_LINK, 0, BPF_B);
--+ b1 = new_block(JMP(BPF_JSET));
--+ b1->s.k = 0x04;
--+ b1->stmts = s;
--+ gen_not(b1);
--+
--+
--+ gen_and(b1, b0);
--+
--+ return b0;
--+ }
--+
--
-- /*
-- * Generate code that checks whether the packet is a packet for protocol
diff --git a/package/libpcap/patches/105-space_optimization.patch b/package/libpcap/patches/105-space_optimization.patch
index 17265cd665..29c293b623 100644
--- a/package/libpcap/patches/105-space_optimization.patch
+++ b/package/libpcap/patches/105-space_optimization.patch
@@ -1,6 +1,6 @@
--- a/gencode.c
+++ b/gencode.c
-@@ -429,20 +429,6 @@ pcap_compile_nopcap(int snaplen_arg, int
+@@ -439,20 +439,6 @@ pcap_compile_nopcap(int snaplen_arg, int
}
/*
@@ -21,48 +21,9 @@
* Backpatch the blocks in 'list' to 'target'. The 'sense' field indicates
* which of the jt and jf fields has been resolved and which is a pointer
* back to another unresolved block (or nil). At least one of the fields
---- a/optimize.c
-+++ b/optimize.c
-@@ -2263,36 +2263,6 @@ icode_to_fcode(root, lenp)
- return fp;
- }
-
--/*
-- * Make a copy of a BPF program and put it in the "fcode" member of
-- * a "pcap_t".
-- *
-- * If we fail to allocate memory for the copy, fill in the "errbuf"
-- * member of the "pcap_t" with an error message, and return -1;
-- * otherwise, return 0.
-- */
--int
--install_bpf_program(pcap_t *p, struct bpf_program *fp)
--{
-- size_t prog_size;
--
-- /*
-- * Free up any already installed program.
-- */
-- pcap_freecode(&p->fcode);
--
-- prog_size = sizeof(*fp->bf_insns) * fp->bf_len;
-- p->fcode.bf_len = fp->bf_len;
-- p->fcode.bf_insns = (struct bpf_insn *)malloc(prog_size);
-- if (p->fcode.bf_insns == NULL) {
-- snprintf(p->errbuf, sizeof(p->errbuf),
-- "malloc: %s", pcap_strerror(errno));
-- return (-1);
-- }
-- memcpy(p->fcode.bf_insns, fp->bf_insns, prog_size);
-- return (0);
--}
--
- #ifdef BDEBUG
- static void
- opt_dump(root)
--- a/pcap.c
+++ b/pcap.c
-@@ -463,6 +463,52 @@ static const u_char charmap[] = {
+@@ -698,6 +698,59 @@ static const u_char charmap[] = {
(u_char)'\374', (u_char)'\375', (u_char)'\376', (u_char)'\377',
};
@@ -80,7 +41,6 @@
+ }
+}
+
-+
+/*
+ * Make a copy of a BPF program and put it in the "fcode" member of
+ * a "pcap_t".
@@ -95,6 +55,15 @@
+ size_t prog_size;
+
+ /*
++ * Validate the program.
++ */
++ if (!bpf_validate(fp->bf_insns, fp->bf_len)) {
++ snprintf(p->errbuf, sizeof(p->errbuf),
++ "BPF program is not valid");
++ return (-1);
++ }
++
++ /*
+ * Free up any already installed program.
+ */
+ pcap_freecode(&p->fcode);
@@ -111,7 +80,54 @@
+ return (0);
+}
+
-+
int
pcap_strcasecmp(const char *s1, const char *s2)
{
+--- a/optimize.c
++++ b/optimize.c
+@@ -2278,45 +2278,6 @@ icode_to_fcode(root, lenp)
+ return fp;
+ }
+
+-/*
+- * Make a copy of a BPF program and put it in the "fcode" member of
+- * a "pcap_t".
+- *
+- * If we fail to allocate memory for the copy, fill in the "errbuf"
+- * member of the "pcap_t" with an error message, and return -1;
+- * otherwise, return 0.
+- */
+-int
+-install_bpf_program(pcap_t *p, struct bpf_program *fp)
+-{
+- size_t prog_size;
+-
+- /*
+- * Validate the program.
+- */
+- if (!bpf_validate(fp->bf_insns, fp->bf_len)) {
+- snprintf(p->errbuf, sizeof(p->errbuf),
+- "BPF program is not valid");
+- return (-1);
+- }
+-
+- /*
+- * Free up any already installed program.
+- */
+- pcap_freecode(&p->fcode);
+-
+- prog_size = sizeof(*fp->bf_insns) * fp->bf_len;
+- p->fcode.bf_len = fp->bf_len;
+- p->fcode.bf_insns = (struct bpf_insn *)malloc(prog_size);
+- if (p->fcode.bf_insns == NULL) {
+- snprintf(p->errbuf, sizeof(p->errbuf),
+- "malloc: %s", pcap_strerror(errno));
+- return (-1);
+- }
+- memcpy(p->fcode.bf_insns, fp->bf_insns, prog_size);
+- return (0);
+-}
+-
+ #ifdef BDEBUG
+ static void
+ opt_dump(root)
diff --git a/package/libpcap/patches/106-protocol_api.patch b/package/libpcap/patches/106-protocol_api.patch
new file mode 100644
index 0000000000..09e3e880ac
--- /dev/null
+++ b/package/libpcap/patches/106-protocol_api.patch
@@ -0,0 +1,141 @@
+--- a/pcap-int.h
++++ b/pcap-int.h
+@@ -187,6 +187,7 @@ struct pcap_opt {
+ char *source;
+ int promisc;
+ int rfmon;
++ int proto; /* protocol for packet socket (linux) */
+ };
+
+ /*
+--- a/pcap-linux.c
++++ b/pcap-linux.c
+@@ -273,7 +273,7 @@ static int iface_get_id(int fd, const ch
+ static int iface_get_mtu(int fd, const char *device, char *ebuf);
+ static int iface_get_arptype(int fd, const char *device, char *ebuf);
+ #ifdef HAVE_PF_PACKET_SOCKETS
+-static int iface_bind(int fd, int ifindex, char *ebuf);
++static int iface_bind(int fd, int ifindex, char *ebuf, unsigned short proto);
+ static int has_wext(int sock_fd, const char *device, char *ebuf);
+ static int enter_rfmon_mode_wext(pcap_t *handle, int sock_fd,
+ const char *device);
+@@ -362,7 +362,7 @@ pcap_can_set_rfmon_linux(pcap_t *p)
+ * (We assume that if we have Wireless Extensions support
+ * we also have PF_PACKET support.)
+ */
+- sock_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
++ sock_fd = socket(PF_PACKET, SOCK_RAW, handle->opt.proto);
+ if (sock_fd == -1) {
+ (void)snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "socket: %s", pcap_strerror(errno));
+@@ -522,6 +522,9 @@ pcap_activate_linux(pcap_t *handle)
+ handle->read_op = pcap_read_linux;
+ handle->stats_op = pcap_stats_linux;
+
++ if (handle->opt.proto < 0)
++ handle->opt.proto = (int) htons(ETH_P_ALL);
++
+ /*
+ * The "any" device is a special device which causes us not
+ * to bind to a particular device and thus to look at all
+@@ -1673,8 +1676,8 @@ activate_new(pcap_t *handle)
+ * try a SOCK_RAW socket for the raw interface.
+ */
+ sock_fd = is_any_device ?
+- socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL)) :
+- socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
++ socket(PF_PACKET, SOCK_DGRAM, handle->opt.proto) :
++ socket(PF_PACKET, SOCK_RAW, handle->opt.proto);
+
+ if (sock_fd == -1) {
+ snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "socket: %s",
+@@ -1763,7 +1766,7 @@ activate_new(pcap_t *handle)
+ return PCAP_ERROR;
+ }
+ sock_fd = socket(PF_PACKET, SOCK_DGRAM,
+- htons(ETH_P_ALL));
++ handle->opt.proto);
+ if (sock_fd == -1) {
+ snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+ "socket: %s", pcap_strerror(errno));
+@@ -1815,7 +1818,7 @@ activate_new(pcap_t *handle)
+ }
+
+ if ((err = iface_bind(sock_fd, handle->md.ifindex,
+- handle->errbuf)) != 1) {
++ handle->errbuf, handle->opt.proto)) != 1) {
+ close(sock_fd);
+ if (err < 0)
+ return err;
+@@ -2440,7 +2443,7 @@ iface_get_id(int fd, const char *device,
+ * or a PCAP_ERROR_ value on a hard error.
+ */
+ static int
+-iface_bind(int fd, int ifindex, char *ebuf)
++iface_bind(int fd, int ifindex, char *ebuf, unsigned short proto)
+ {
+ struct sockaddr_ll sll;
+ int err;
+@@ -2449,7 +2452,7 @@ iface_bind(int fd, int ifindex, char *eb
+ memset(&sll, 0, sizeof(sll));
+ sll.sll_family = AF_PACKET;
+ sll.sll_ifindex = ifindex;
+- sll.sll_protocol = htons(ETH_P_ALL);
++ sll.sll_protocol = proto;
+
+ if (bind(fd, (struct sockaddr *) &sll, sizeof(sll)) == -1) {
+ if (errno == ENETDOWN) {
+@@ -3119,7 +3122,7 @@ activate_old(pcap_t *handle)
+
+ /* Open the socket */
+
+- handle->fd = socket(PF_INET, SOCK_PACKET, htons(ETH_P_ALL));
++ handle->fd = socket(PF_INET, SOCK_PACKET, handle->opt.proto);
+ if (handle->fd == -1) {
+ snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
+ "socket: %s", pcap_strerror(errno));
+--- a/pcap.c
++++ b/pcap.c
+@@ -152,6 +152,8 @@ pcap_create_common(const char *source, c
+ pcap_set_snaplen(p, 65535); /* max packet size */
+ p->opt.promisc = 0;
+ p->opt.buffer_size = 0;
++ p->opt.proto = -1;
++
+ return (p);
+ }
+
+@@ -212,6 +214,15 @@ pcap_set_buffer_size(pcap_t *p, int buff
+ }
+
+ int
++pcap_set_protocol(pcap_t *p, unsigned short proto)
++{
++ if (pcap_check_activated(p))
++ return PCAP_ERROR_ACTIVATED;
++ p->opt.proto = proto;
++ return 0;
++}
++
++int
+ pcap_activate(pcap_t *p)
+ {
+ int status;
+--- a/pcap/pcap.h
++++ b/pcap/pcap.h
+@@ -61,6 +61,7 @@ extern "C" {
+ #define PCAP_VERSION_MINOR 4
+
+ #define PCAP_ERRBUF_SIZE 256
++#define HAS_PROTO_EXTENSION
+
+ /*
+ * Compatibility for systems that have a bpf.h that
+@@ -263,6 +264,7 @@ int pcap_can_set_rfmon(pcap_t *);
+ int pcap_set_rfmon(pcap_t *, int);
+ int pcap_set_timeout(pcap_t *, int);
+ int pcap_set_buffer_size(pcap_t *, int);
++int pcap_set_protocol(pcap_t *, unsigned short);
+ int pcap_activate(pcap_t *);
+
+ pcap_t *pcap_open_live(const char *, int, int, int, char *);