diff options
| -rw-r--r-- | package/libpcap/Makefile | 36 | ||||
| -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.patch | 11 | ||||
| -rw-r--r-- | package/libpcap/patches/101-debian_fix_any_intf.patch | 149 | ||||
| -rw-r--r-- | package/libpcap/patches/102-alt-ether.patch | 38 | ||||
| -rw-r--r-- | package/libpcap/patches/102-fix_install.patch | 11 | ||||
| -rw-r--r-- | package/libpcap/patches/103-flex_workaround.patch | 4 | ||||
| -rw-r--r-- | package/libpcap/patches/104-no_rej_files.patch | 469 | ||||
| -rw-r--r-- | package/libpcap/patches/105-space_optimization.patch | 102 | ||||
| -rw-r--r-- | package/libpcap/patches/106-protocol_api.patch | 141 | 
10 files changed, 464 insertions, 605 deletions
| diff --git a/package/libpcap/Makefile b/package/libpcap/Makefile index 7414195d9..bc6417d0e 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 aae77f8e7..76d3729ef 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 2f166c849..000000000 --- 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 000000000..8da6ef223 --- /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 e9cc15ff3..000000000 --- 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 000000000..5264fb2f6 --- /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 014c624d4..5d0334272 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 d3ae58c0a..000000000 --- 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 17265cd66..29c293b62 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 000000000..09e3e880a --- /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 *); | 
