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