diff -ubBrN libpcap0.8-0.9.8.orig/debian/patches/60_ring.diff libpcap0.8-0.9.8/debian/patches/60_ring.diff --- libpcap0.8-0.9.8.orig/debian/patches/60_ring.diff 1970-01-01 09:00:00.000000000 +0900 +++ libpcap0.8-0.9.8/debian/patches/60_ring.diff 2008-06-17 23:26:30.000000000 +0900 @@ -0,0 +1,686 @@ +diff -ubBrN libpcap0.8-0.9.8.orig/FILES libpcap0.8-0.9.8/FILES +--- libpcap0.8-0.9.8.orig/FILES 2007-09-26 11:09:45.000000000 +0900 ++++ libpcap0.8-0.9.8/FILES 2008-06-17 23:02:46.000000000 +0900 +@@ -82,6 +82,8 @@ + pcap-enet.c + pcap-int.h + pcap-linux.c ++pcap-ring.h ++pcap-ring.c + pcap-namedb.h + pcap-nit.c + pcap-nit.h +diff -ubBrN libpcap0.8-0.9.8.orig/Makefile.in libpcap0.8-0.9.8/Makefile.in +--- libpcap0.8-0.9.8.orig/Makefile.in 2008-06-17 23:00:09.000000000 +0900 ++++ libpcap0.8-0.9.8/Makefile.in 2008-06-17 23:02:46.000000000 +0900 +@@ -91,17 +91,18 @@ + PSRC = pcap-@V_PCAP@.c + FSRC = fad-@V_FINDALLDEVS@.c + SSRC = @SSRC@ ++RSRC = @RSRC@ + CSRC = pcap.c inet.c gencode.c optimize.c nametoaddr.c \ + etherent.c savefile.c bpf_filter.c bpf_image.c bpf_dump.c + GENSRC = scanner.c grammar.c version.c + LIBOBJS = @LIBOBJS@ + +-SRC = $(PSRC) $(FSRC) $(CSRC) $(SSRC) $(GENSRC) ++SRC = $(PSRC) $(FSRC) $(CSRC) $(SSRC) $(RSRC) $(GENSRC) + + # 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) ++OBJ = $(PSRC:.c=.o) $(FSRC:.c=.o) $(CSRC:.c=.o) $(SSRC:.c=.o) $(RSRC:.c=.o) $(GENSRC:.c=.o) $(LIBOBJS) ++OBJ_PIC = $(PSRC:.c=_pic.o) $(FSRC:.c=_pic.o) $(CSRC:.c=_pic.o) $(SSRC:.c=_pic.o) $(RSRC:.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 = \ +@@ -157,6 +158,12 @@ + scanner_pic.o: scanner.c tokdefs.h + $(CC) -fPIC $(CFLAGS) -o $@ -c scanner.c + ++pcap-ring.o: pcap-ring.c pcap-ring.h ++ $(CC) $(CFLAGS) -c pcap-ring.c ++ ++pcap-ring_pic.o: pcap-ring.c pcap-ring.h ++ $(CC) -fPIC $(CFLAGS) -o $@ -c pcap-ring.c ++ + pcap.o: version.h + + tokdefs.h: grammar.c +diff -ubBrN libpcap0.8-0.9.8.orig/config.h.in libpcap0.8-0.9.8/config.h.in +--- libpcap0.8-0.9.8.orig/config.h.in 2007-09-26 11:09:45.000000000 +0900 ++++ libpcap0.8-0.9.8/config.h.in 2008-06-17 23:02:46.000000000 +0900 +@@ -134,6 +134,9 @@ + /* Define to 1 if you have the `vsnprintf' function. */ + #undef HAVE_VSNPRINTF + ++/* PACKET_RX_RING */ ++#undef DO_RING ++ + /* define if your compiler has __attribute__ */ + #undef HAVE___ATTRIBUTE__ + +diff -ubBrN libpcap0.8-0.9.8.orig/configure libpcap0.8-0.9.8/configure +--- libpcap0.8-0.9.8.orig/configure 2008-06-17 23:00:10.000000000 +0900 ++++ libpcap0.8-0.9.8/configure 2008-06-17 23:02:46.000000000 +0900 +@@ -686,6 +686,7 @@ + V_FINDALLDEVS + V_RANLIB + SSRC ++RSRC + DYEXT + DAGLIBS + INSTALL_PROGRAM +@@ -6338,6 +6339,75 @@ + _ACEOF + + fi ++ ++ { echo "$as_me:$LINENO: checking set PACKET_RX_RING socket option" >&5 ++echo $ECHO_N "checking set PACKET_RX_RING socket option... $ECHO_C" >&6; } ++ if test "$cross_compiling" = yes; then ++ enable_packet_mmap=yes ++else ++ cat >conftest.$ac_ext <<_ACEOF ++/* confdefs.h. */ ++_ACEOF ++cat confdefs.h >>conftest.$ac_ext ++cat >>conftest.$ac_ext <<_ACEOF ++/* end confdefs.h. */ ++#include ++ #include ++ #include ++ #include ++ #include ++ int main(int argc, char **argv) { ++ int fd; ++ struct tpacket_req req = {0, 1, 0, 1}; ++ req.tp_block_size = req.tp_frame_size = getpagesize(); ++ fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); ++ if (fd < 0) return -1; ++ return setsockopt(fd, SOL_PACKET, PACKET_RX_RING, (void *) &req, sizeof(req)); ++ } ++_ACEOF ++rm -f conftest$ac_exeext ++if { (ac_try="$ac_link" ++case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++ (eval "$ac_link") 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } && { ac_try='./conftest$ac_exeext' ++ { (case "(($ac_try" in ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; ++ *) ac_try_echo=$ac_try;; ++esac ++eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 ++ (eval "$ac_try") 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); }; }; then ++ enable_packet_mmap=yes ++else ++ echo "$as_me: program exited with status $ac_status" >&5 ++echo "$as_me: failed program was:" >&5 ++sed 's/^/| /' conftest.$ac_ext >&5 ++ ++( exit $ac_status ) ++enable_packet_mmap=no ++fi ++rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext ++fi ++ ++ ++ if test "$enable_packet_mmap" = "yes"; then ++ ++cat >>confdefs.h <<\_ACEOF ++#define DO_RING 1 ++_ACEOF ++ ++ RSRC="pcap-ring.c" ++ fi ++ { echo "$as_me:$LINENO: result: ${enable_packet_mmap-no}" >&5 ++echo "${ECHO_T}${enable_packet_mmap-no}" >&6; } + ;; + + dag) +@@ -8373,6 +8443,7 @@ + V_FINDALLDEVS!$V_FINDALLDEVS$ac_delim + V_RANLIB!$V_RANLIB$ac_delim + SSRC!$SSRC$ac_delim ++RSRC!$RSRC$ac_delim + DYEXT!$DYEXT$ac_delim + DAGLIBS!$DAGLIBS$ac_delim + INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim +@@ -8381,7 +8452,7 @@ + LTLIBOBJS!$LTLIBOBJS$ac_delim + _ACEOF + +- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 78; then ++ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 79; then + break + elif $ac_last_try; then + { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +diff -ubBrN libpcap0.8-0.9.8.orig/configure.in libpcap0.8-0.9.8/configure.in +--- libpcap0.8-0.9.8.orig/configure.in 2008-06-17 23:00:09.000000000 +0900 ++++ libpcap0.8-0.9.8/configure.in 2008-06-17 23:02:46.000000000 +0900 +@@ -372,6 +372,30 @@ + AC_MSG_ERROR(version 2 or higher required; see the INSTALL doc for more info) + fi + AC_LBL_TPACKET_STATS ++ ++ AC_MSG_CHECKING(set PACKET_RX_RING socket option) ++ AC_TRY_RUN( ++ [#include ++ #include ++ #include ++ #include ++ #include ++ int main(int argc, char **argv) { ++ int fd; ++ struct tpacket_req req = {0, 1, 0, 1}; ++ req.tp_block_size = req.tp_frame_size = getpagesize(); ++ fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); ++ if (fd < 0) return -1; ++ return setsockopt(fd, SOL_PACKET, PACKET_RX_RING, (void *) &req, sizeof(req)); ++ }], ++ enable_packet_mmap=yes, ++ enable_packet_mmap=no, ++ enable_packet_mmap=yes) ++ if test "$enable_packet_mmap" = "yes"; then ++ AC_DEFINE(DO_RING,1,[PACKT_RX_RING]) ++ RSRC="pcap-ring.c" ++ fi ++ AC_MSG_RESULT(${enable_packet_mmap-no}) + ;; + + dag) +@@ -813,6 +837,7 @@ + AC_SUBST(V_RANLIB) + AC_SUBST(V_YACC) + AC_SUBST(SSRC) ++AC_SUBST(RSRC) + AC_SUBST(DYEXT) + AC_SUBST(DAGLIBS) + +diff -ubBrN libpcap0.8-0.9.8.orig/pcap-int.h libpcap0.8-0.9.8/pcap-int.h +--- libpcap0.8-0.9.8.orig/pcap-int.h 2007-07-05 22:56:00.000000000 +0900 ++++ libpcap0.8-0.9.8/pcap-int.h 2008-06-17 23:02:46.000000000 +0900 +@@ -64,6 +64,10 @@ + ((ull & 0x000000000000ff00LL) << 40) | \ + ((ull & 0x00000000000000ffLL) << 56) + ++#ifdef DO_RING ++# include ++#endif ++ + /* + * Savefile + */ +@@ -164,6 +168,9 @@ + + struct pcap_sf sf; + struct pcap_md md; ++#ifdef DO_RING ++ struct pcap_ring rg; ++#endif /* DO_RING */ + + /* + * Read buffer. +diff -ubBrN libpcap0.8-0.9.8.orig/pcap-linux.c libpcap0.8-0.9.8/pcap-linux.c +--- libpcap0.8-0.9.8.orig/pcap-linux.c 2007-06-12 04:34:28.000000000 +0900 ++++ libpcap0.8-0.9.8/pcap-linux.c 2008-06-17 23:02:46.000000000 +0900 +@@ -409,8 +409,13 @@ + + /* Allocate the buffer */ + ++#ifdef DO_RING ++ handle->buffer = NULL; ++ err = packet_tring_setup(handle, ebuf); ++ if (err == -1) { /* err == -2, means hard failure ring wise */ ++#endif /* DO_RING */ + handle->buffer = malloc(handle->bufsize + handle->offset); +- if (!handle->buffer) { ++ if (!handle->buffer && err) { + snprintf(ebuf, PCAP_ERRBUF_SIZE, + "malloc: %s", pcap_strerror(errno)); + pcap_close_linux(handle); +@@ -418,6 +423,9 @@ + return NULL; + } + ++#ifdef DO_RING ++ } ++#endif + /* + * "handle->fd" is a socket, so "select()" and "poll()" + * should work on it. +@@ -445,6 +453,11 @@ + static int + pcap_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *user) + { ++#ifdef DO_RING ++ if (handle->buffer == NULL) ++ return pcap_ring_recv(handle, max_packets, callback, user); ++#endif /* DO_RING */ ++ + /* + * Currently, on Linux only one packet is delivered per read, + * so we don't loop. +@@ -1702,6 +1715,10 @@ + struct pcap *p, *prevp; + struct ifreq ifr; + ++#ifdef DO_RING ++ packet_ring_close(handle); ++ fflush(stderr); ++#endif /* DO_RING */ + if (handle->md.clear_promisc) { + /* + * We put the interface into promiscuous mode; take +@@ -2149,6 +2166,11 @@ + * Note that we've put the total filter onto the socket. + */ + total_filter_on = 1; ++#ifdef DO_RING ++ if (handle->rg.iovec) ++ packet_ring_discard(handle); ++ else { ++#endif /* DO_RING */ + + /* + * Save the socket's current mode, and put it in +@@ -2172,6 +2194,9 @@ + return -2; + } + } ++#ifdef DO_RING ++ } ++#endif /* DO_RING */ + } + + /* +diff -ubBrN libpcap0.8-0.9.8.orig/pcap-ring.c libpcap0.8-0.9.8/pcap-ring.c +--- libpcap0.8-0.9.8.orig/pcap-ring.c 1970-01-01 09:00:00.000000000 +0900 ++++ libpcap0.8-0.9.8/pcap-ring.c 2008-06-17 23:15:22.000000000 +0900 +@@ -0,0 +1,318 @@ ++/* Copyright (c) 2006, ++ * Regents of the University of California All rights reserved. ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * * Neither the name of the Los Alamos National Laboratory nor the ++ * names of its contributors may be used to endorse or promote products ++ * derived from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED ++ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR ++ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++#ifndef lint ++static const char rcsid[] _U_ = "@#( $Header: /n/CVS/sirt/libpcap/pcap-ring.c,v 0.9 2005/06/10 23:06:31 cpw Exp $ (CPW)"; ++#endif ++ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#ifdef PACKET_HOST ++#define HAVE_PF_PACKET_SOCKETS ++#endif /* PACKET_HOST */ ++ ++#include "pcap-int.h" ++#include "sll.h" ++ ++#define DEFAULT_RING_SIZE 8 * 1024 * 1024 /* 8Mbyes */ ++ ++#define RING_DEBUG ++/* #undef RING_DEBUG */ ++#ifdef RING_DEBUG ++#define DPRINTF(format, args...) fprintf(stderr, format,##args) ++#else ++#define DPRINTF(format, args...) ++#endif ++ ++unsigned clp2(unsigned x) ++{ ++ x = x - 1; ++ x = x | (x >> 1); ++ x = x | (x >> 2); ++ x = x | (x >> 4); ++ x = x | (x >> 8); ++ x = x | (x >>16); ++ return x + 1; ++} ++ ++int ++packet_tring_setup(pcap_t *p, char *ebuf) ++{ ++ int i, size = p->snapshot; ++ struct tpacket_req req; ++ struct iovec *ring; ++ unsigned long mem = 0; ++ char *endptr, *str; ++ ++ str = getenv("PCAP_MMAP_MEMSIZE"); ++ if (str) ++ mem = strtoul(str, &endptr, 10); ++ if (mem < getpagesize() || endptr == str) ++ mem = DEFAULT_RING_SIZE; /* XXX: use getenv() ? */ ++ ++ if (p->md.cooked) ++ size += SLL_HDR_LEN; ++ ++ req.tp_block_size = getpagesize(); ++ req.tp_block_nr = mem / req.tp_block_size; ++ req.tp_frame_size = clp2(TPACKET_ALIGN(TPACKET_HDRLEN) + TPACKET_ALIGN(size)); ++ req.tp_frame_nr = req.tp_block_size / req.tp_frame_size * req.tp_block_nr; ++ ++ p->rg.ct = req.tp_frame_nr; ++ ++ if (setsockopt(p->fd, SOL_PACKET, PACKET_RX_RING, (void*)&req, ++ sizeof(req))) { ++ snprintf(ebuf, PCAP_ERRBUF_SIZE, "PACKET_RX_RING: %s", ++ pcap_strerror(errno)); ++ return -1; ++ } ++ ++ ring = (struct iovec *) malloc(p->rg.ct * sizeof(struct iovec)); ++ if (!ring) { ++ snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", ++ pcap_strerror(errno)); ++ return -1; ++ } ++ ++ p->rg.buf = (void*)mmap(NULL, req.tp_block_nr * req.tp_block_size, ++ PROT_READ|PROT_WRITE, MAP_SHARED, p->fd, 0); ++ if (p->rg.buf == MAP_FAILED) { ++ snprintf(ebuf, PCAP_ERRBUF_SIZE, "mmap: %s", ++ pcap_strerror(errno)); ++ ++ memset(&req, 0, sizeof(req)); ++ p->rg.buf = NULL; ++ if (setsockopt(p->fd, SOL_PACKET, PACKET_RX_RING, (void*)&req, ++ sizeof(req))) { ++ snprintf(ebuf, PCAP_ERRBUF_SIZE, "mmap and unset PACKET_RX_RING: %s", ++ pcap_strerror(errno)); ++ } ++ free(ring); ++ return -2; ++ } ++ ++ for (i = 0; i < req.tp_frame_nr; i++) { ++ ring[i].iov_base = (unsigned char *)((unsigned long)p->rg.buf) + i * req.tp_frame_size; ++ ring[i].iov_len = req.tp_frame_size; ++ } ++ ++ p->rg.bufsize = req.tp_block_nr * req.tp_block_size; ++ p->rg.iovhead = 0; ++ p->rg.iovmax = p->rg.ct - 1; ++ p->rg.iovec = ring; ++ ++ DPRINTF("use PACKET_MMAP, packet buffer size - pkts: %d\n", req.tp_frame_nr); ++ ++ return 0; ++} ++ ++int ++pcap_ring_recv(pcap_t *handle, int cnt, pcap_handler callback, u_char *userdata) ++{ ++ struct iovec *ring = handle->rg.iovec; ++ struct tpacket_hdr *h; ++ struct sockaddr_ll *sll; ++ unsigned char *bp; ++ struct pcap_pkthdr pcap_header; ++ struct sll_header *hdrp; ++ struct pollfd pfd; ++ int n = 0; ++ ++ if (handle->rg.iovec == NULL) ++ return -1; /* called inappropriately - no ring defined */ ++ ++ pfd.fd = handle->fd; ++ pfd.events = POLLIN | POLLERR; ++ pfd.revents = 0; ++ ++ while (1) { ++ while (*(unsigned long *) ring[handle->rg.iovhead].iov_base == 0) { ++ if (poll(&pfd, 1, -1) < 0) ++ return -1; /* XXX: in case of EINTR? */ ++ } ++ if (handle->break_loop) { ++ handle->break_loop = 0; ++ return -2; ++ } ++ ++ h = ring[handle->rg.iovhead].iov_base; ++ sll = (void*)h + TPACKET_ALIGN(sizeof(*h)); ++ bp = (unsigned char*)h + h->tp_mac; ++ ++#ifdef HAVE_PF_PACKET_SOCKETS ++ /* ++ * >>>> see original pcap_read_packet() in pcap-linux.c ++ */ ++ if (!handle->md.sock_packet) { ++ if (handle->md.ifindex != -1 && ++ sll->sll_ifindex != handle->md.ifindex) ++ goto clear_status; ++ ++ if (sll->sll_pkttype == PACKET_OUTGOING) { ++ if (sll->sll_ifindex == handle->md.lo_ifindex) ++ goto clear_status; ++ ++ if (handle->direction == PCAP_D_IN) ++ goto clear_status; ++ } else { ++ if (handle->direction == PCAP_D_OUT) ++ goto clear_status; ++ } ++ } ++#endif ++ ++#ifdef HAVE_PF_PACKET_SOCKETS ++ if (handle->md.cooked) { ++ hdrp = (struct sll_header *)((char *)bp - sizeof(struct sll_header)); ++ switch (sll->sll_pkttype) { ++ case PACKET_HOST: ++ hdrp->sll_pkttype = htons(LINUX_SLL_HOST); ++ break; ++ ++ case PACKET_BROADCAST: ++ hdrp->sll_pkttype = htons(LINUX_SLL_BROADCAST); ++ break; ++ ++ case PACKET_MULTICAST: ++ hdrp->sll_pkttype = htons(LINUX_SLL_MULTICAST); ++ break; ++ ++ case PACKET_OTHERHOST: ++ hdrp->sll_pkttype = htons(LINUX_SLL_OTHERHOST); ++ break; ++ ++ case PACKET_OUTGOING: ++ hdrp->sll_pkttype = htons(LINUX_SLL_OUTGOING); ++ break; ++ ++ default: ++ hdrp->sll_pkttype = -1; ++ break; ++ } ++ ++ hdrp->sll_hatype = htons(sll->sll_hatype); ++ hdrp->sll_halen = htons(sll->sll_halen); ++ memcpy(hdrp->sll_addr, sll->sll_addr, ++ (sll->sll_halen > SLL_ADDRLEN) ? ++ SLL_ADDRLEN : ++ sll->sll_halen); ++ hdrp->sll_protocol = sll->sll_protocol; ++ } ++#endif ++ if (!handle->md.use_bpf && handle->fcode.bf_insns) { ++ /* XXX: call after bp was adjusted ? */ ++ if (bpf_filter(handle->fcode.bf_insns, bp, ++ h->tp_len, h->tp_snaplen)) ++ { ++ goto clear_status; ++ } ++ } ++ /* ++ * <<<< original pcap_read_packet() in pcap-linux.c ++ */ ++ ++ pcap_header.ts.tv_sec = h->tp_sec; ++ pcap_header.ts.tv_usec = h->tp_usec; ++ pcap_header.caplen = h->tp_snaplen; ++ pcap_header.len = h->tp_len; ++ if (handle->md.cooked) { ++ pcap_header.caplen += SLL_HDR_LEN; ++ pcap_header.len += SLL_HDR_LEN; ++ bp -= SLL_HDR_LEN; ++ } ++ ++ handle->md.packets_read++; ++ (*callback)(userdata, &pcap_header, bp); ++ ++ clear_status: ++ h->tp_status = 0; ++ /* mb(); */ ++ handle->rg.iovhead = handle->rg.iovhead == handle->rg.iovmax ++ ? 0 ++ : handle->rg.iovhead + 1; ++ ++ if (++n >= cnt && cnt > 0) ++ return n; ++ } ++ ++ return n; ++} ++ ++void ++packet_ring_close(pcap_t * p) ++{ ++ if (p->rg.iovec != NULL) ++ free(p->rg.iovec); ++ p->rg.iovec = NULL; ++ ++ if (p->rg.buf != NULL) { ++ munmap(p->rg.buf, p->rg.bufsize); ++ p->rg.buf = NULL; ++ } ++} ++ ++/* ++ * packet_discard (pcap_t *) ++ * marks any entries in the ring buffer as read ++ * presumably called after setting a new filter. ++ */ ++int ++packet_ring_discard (pcap_t * p) ++{ ++ struct iovec *ring = p->rg.iovec; ++ struct tpacket_stats tps = { 0 }; ++ socklen_t olen = sizeof (tps); ++ int discarded = 0; ++ int start = p->rg.iovhead; ++ ++ if (!p->rg.iovec) ++ return 0; ++ ++ while (*(unsigned long *) ring[p->rg.iovhead].iov_base) { ++ *(unsigned long *) ring[p->rg.iovhead].iov_base = 0; ++ discarded++; ++ p->rg.iovhead = (p->rg.iovhead == p->rg.iovmax) ? 0 : p->rg.iovhead + 1; ++ if (p->rg.iovhead == start) /* one turn only */ ++ break; ++ } ++ ++ /* clear packet stats */ ++ getsockopt(p->fd, SOL_PACKET, PACKET_STATISTICS, (void *) &tps, &olen); ++ ++ return discarded; ++} +diff -ubBrN libpcap0.8-0.9.8.orig/pcap-ring.h libpcap0.8-0.9.8/pcap-ring.h +--- libpcap0.8-0.9.8.orig/pcap-ring.h 1970-01-01 09:00:00.000000000 +0900 ++++ libpcap0.8-0.9.8/pcap-ring.h 2008-06-17 23:02:46.000000000 +0900 +@@ -0,0 +1,54 @@ ++/* ++Copyright (c) 2005, Regents of the University of California All rights reserved. ++ ++ Redistribution and use in source and binary forms, with or without ++ modification, are permitted provided that the following conditions ++ are met: ++ ++ * Redistributions of source code must retain the above copyright ++ notice, this list of conditions and the following disclaimer. ++ * Redistributions in binary form must reproduce the above copyright ++ notice, this list of conditions and the following disclaimer in the ++ documentation and/or other materials provided with the distribution. ++ * Neither the name of the Los Alamos National Laboratory nor the ++ names of its contributors may be used to endorse or promote products ++ derived from this software without specific prior written permission. ++ ++ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED ++ TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR ++ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ++ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING ++ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ++ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ @(#) $Header: /n/CVS/sirt/libpcap/pcap-ring.h,v 0.10 2005/07/18 16:05:12 cpw Exp $ (CPW) ++*/ ++#ifndef PCAP_RING_H ++#define PCAP_RING_H 1 ++ ++#include ++#include ++#include ++ ++#ifndef SOL_PACKET /* */ ++#define SOL_PACKET 263 /* */ ++#endif /* SOL_PACKET */ ++ ++typedef struct pcap_ring { ++ char *buf; ++ void *iovec; /* non zero implies ring use */ ++ unsigned int bufsize; ++ unsigned int iovmax; ++ unsigned int iovhead; ++ long ct; /* size of ring in packets */ ++} pcap_ring; ++ ++void packet_ring_close (pcap_t *); ++int packet_tring_setup(pcap_t *, char *); ++int packet_ring_discard(pcap_t *); ++ ++#endif diff -ubBrN libpcap0.8-0.9.8.orig/debian/patches/series libpcap0.8-0.9.8/debian/patches/series --- libpcap0.8-0.9.8.orig/debian/patches/series 2008-06-17 22:58:18.000000000 +0900 +++ libpcap0.8-0.9.8/debian/patches/series 2008-06-17 23:26:37.000000000 +0900 @@ -3,3 +3,4 @@ 30_man_fixes.diff 50_kfreebsd.diff 50_autotools-dev.diff +60_ring.diff