summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--openwrt/package/libpcap/patches/110-pf_ring.patch613
1 files changed, 0 insertions, 613 deletions
diff --git a/openwrt/package/libpcap/patches/110-pf_ring.patch b/openwrt/package/libpcap/patches/110-pf_ring.patch
deleted file mode 100644
index 1d5124fac8..0000000000
--- a/openwrt/package/libpcap/patches/110-pf_ring.patch
+++ /dev/null
@@ -1,613 +0,0 @@
-diff -urN libpcap.old/pcap-int.h libpcap.dev/pcap-int.h
---- libpcap.old/pcap-int.h 2003-12-15 02:42:24.000000000 +0100
-+++ libpcap.dev/pcap-int.h 2005-10-22 23:20:12.220060500 +0200
-@@ -30,7 +30,7 @@
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
-- * @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.55.2.4 2003/12/15 01:42:24 guy Exp $ (LBL)
-+ * @(#) $Header: /export/home/ntop/PF_RING/userland/libpcap-0.8.1-ring/pcap-int.h,v 1.2 2004/11/25 09:58:00 deri Exp $ (LBL)
- */
-
- #ifndef pcap_int_h
-@@ -46,6 +46,8 @@
- #include <packet32.h>
- #endif /* WIN32 */
-
-+#define RING /* L.Deri */
-+
- /*
- * Savefile
- */
-@@ -93,6 +95,57 @@
- #endif
- };
-
-+/* **************************** */
-+
-+#ifdef RING
-+
-+#include <unistd.h>
-+#include <sys/mman.h>
-+#include <errno.h>
-+#include <sys/poll.h>
-+
-+#define PAGE_SIZE 4096
-+
-+#define HAVE_PCAP
-+#include <linux/ring.h>
-+#endif
-+
-+#ifdef RING
-+
-+#define E1000_RXD_STAT_DD 0x01 /* Descriptor Done */
-+
-+struct e1000_rx_desc {
-+ u_int64_t buffer_addr; /* Address of the descriptor's data buffer */
-+ u_int16_t length; /* Length of data DMAed into data buffer */
-+ u_int16_t csum; /* Packet checksum */
-+ u_int8_t status; /* Descriptor status */
-+ u_int8_t errors; /* Descriptor Errors */
-+ u_int16_t special;
-+};
-+
-+/* Transmit Descriptor */
-+struct e1000_tx_desc {
-+ u_int64_t buffer_addr; /* Address of the descriptor's data buffer */
-+ union {
-+ u_int32_t data;
-+ struct {
-+ u_int16_t length; /* Data buffer length */
-+ u_int8_t cso; /* Checksum offset */
-+ u_int8_t cmd; /* Descriptor control */
-+ } flags;
-+ } lower;
-+ union {
-+ u_int32_t data;
-+ struct {
-+ u_int8_t status; /* Descriptor status */
-+ u_int8_t css; /* Checksum start */
-+ u_int16_t special;
-+ } fields;
-+ } upper;
-+};
-+
-+#endif
-+
- struct pcap {
- #ifdef WIN32
- ADAPTER *adapter;
-@@ -121,6 +174,14 @@
- u_char *bp;
- int cc;
-
-+#ifdef RING
-+ /* PF_RING */
-+ char *ring_buffer, *ring_slots;
-+ int ring_fd;
-+ FlowSlotInfo *slots_info;
-+ u_int page_id, slot_id, pkts_per_page;
-+ u_int poll_sleep;
-+#endif
- /*
- * Place holder for pcap_next().
- */
-diff -urN libpcap.old/pcap-linux.c libpcap.dev/pcap-linux.c
---- libpcap.old/pcap-linux.c 2003-11-21 11:20:46.000000000 +0100
-+++ libpcap.dev/pcap-linux.c 2005-10-22 23:43:59.726120250 +0200
-@@ -27,7 +27,7 @@
-
- #ifndef lint
- static const char rcsid[] _U_ =
-- "@(#) $Header: /tcpdump/master/libpcap/pcap-linux.c,v 1.98.2.4 2003/11/21 10:20:46 guy Exp $ (LBL)";
-+ "@(#) $Header: /export/home/ntop/PF_RING/userland/libpcap-0.8.1-ring/pcap-linux.c,v 1.2 2004/11/25 09:58:00 deri Exp $ (LBL)";
- #endif
-
- /*
-@@ -83,7 +83,7 @@
- #ifdef HAVE_DAG_API
- #include "pcap-dag.h"
- #endif /* HAVE_DAG_API */
--
-+
- #include <errno.h>
- #include <stdlib.h>
- #include <unistd.h>
-@@ -217,6 +217,83 @@
- = { 1, &total_insn };
- #endif
-
-+#define RING /* L.Deri */
-+#define SAFE_RING_MODE /*
-+ Copy the bucket in order to avoid kernel
-+ crash if the application faults
-+ */
-+
-+#ifdef RING
-+unsigned char *write_register;
-+static struct pcap_stat ringStats;
-+u_long numPollCalls = 0, numReadCalls = 0;
-+
-+#define POLL_SLEEP_STEP 10 /* ns = 0.1 ms */
-+#define POLL_SLEEP_MIN POLL_SLEEP_STEP
-+#define POLL_SLEEP_MAX 1000 /* ns */
-+#define POLL_QUEUE_MIN_LEN 500 /* # packets */
-+
-+#ifdef SAFE_RING_MODE
-+static char staticBucket[2048];
-+#endif
-+
-+
-+/* ******************************* */
-+
-+int pcap_set_cluster(pcap_t *handle, u_int clusterId) {
-+ return(handle->ring_fd ? setsockopt(handle->ring_fd, 0, SO_ADD_TO_CLUSTER,
-+ &clusterId, sizeof(clusterId)): -1);
-+}
-+
-+/* ******************************* */
-+
-+int pcap_remove_from_cluster(pcap_t *handle) {
-+ return(handle->ring_fd ?
-+ setsockopt(handle->ring_fd, 0, SO_REMOVE_FROM_CLUSTER, NULL, 0) : -1);
-+}
-+
-+/* ******************************* */
-+
-+int pcap_set_reflector(pcap_t *handle, char *reflectorDevice) {
-+ return(handle->ring_fd ?
-+ setsockopt(handle->ring_fd, 0, SO_SET_REFLECTOR,
-+ &reflectorDevice, strlen(reflectorDevice)) : -1);
-+}
-+
-+/* ******************************* */
-+
-+static int set_if_promisc(const char *device, int set_promisc) {
-+ int sock_fd;
-+ struct ifreq ifr;
-+
-+ if(device == NULL) return(-3);
-+
-+ sock_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
-+ if(sock_fd <= 0) return(-1);
-+
-+ memset(&ifr, 0, sizeof(ifr));
-+ strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
-+ if(ioctl(sock_fd, SIOCGIFFLAGS, &ifr) == -1) {
-+ close(sock_fd);
-+ return(-2);
-+ }
-+
-+ if(set_promisc) {
-+ if((ifr.ifr_flags & IFF_PROMISC) == 0) ifr.ifr_flags |= IFF_PROMISC;
-+ } else {
-+ /* Remove promisc */
-+ if((ifr.ifr_flags & IFF_PROMISC) != 0) ifr.ifr_flags &= ~IFF_PROMISC;
-+ }
-+
-+ if(ioctl(sock_fd, SIOCSIFFLAGS, &ifr) == -1)
-+ return(-1);
-+
-+ close(sock_fd);
-+ return(0);
-+}
-+
-+#endif
-+
- /*
- * Get a handle for a live capture from the given device. You can
- * pass NULL as device to get all packages (without link level
-@@ -258,6 +335,138 @@
- handle->snapshot = snaplen;
- handle->md.timeout = to_ms;
-
-+#ifdef RING
-+ handle->ring_fd = handle->fd = socket(PF_RING, SOCK_RAW, htons(ETH_P_ALL));
-+
-+ printf("Open RING [fd=%d]\n", handle->ring_fd);
-+
-+ if(handle->ring_fd > 0) {
-+ struct sockaddr sa;
-+ int rc;
-+ u_int memSlotsLen;
-+
-+ err = 0;
-+ sa.sa_family = PF_RING;
-+ snprintf(sa.sa_data, sizeof(sa.sa_data), "%s", device);
-+ rc = bind(handle->ring_fd, (struct sockaddr *)&sa, sizeof(sa));
-+
-+ if(rc == 0) {
-+
-+
-+ handle->md.device = strdup(device);
-+ handle->ring_buffer = (char *)mmap(NULL, PAGE_SIZE,
-+ PROT_READ|PROT_WRITE,
-+ MAP_SHARED,
-+ handle->ring_fd, 0);
-+
-+ if(handle->ring_buffer == MAP_FAILED) {
-+ sprintf(ebuf, "mmap() failed");
-+ return (NULL);
-+ }
-+
-+ handle->slots_info = (FlowSlotInfo *)handle->ring_buffer;
-+ if(handle->slots_info->version != RING_FLOWSLOT_VERSION) {
-+ snprintf(ebuf, PCAP_ERRBUF_SIZE, "Wrong RING version: "
-+ "kernel is %i, libpcap was compiled with %i\n",
-+ handle->slots_info->version, RING_FLOWSLOT_VERSION);
-+ return (NULL);
-+ }
-+ memSlotsLen = handle->slots_info->tot_mem;
-+ munmap(handle->ring_buffer, PAGE_SIZE);
-+
-+ handle->ring_buffer = (char *)mmap(NULL, memSlotsLen,
-+ PROT_READ|PROT_WRITE,
-+ MAP_SHARED, handle->ring_fd, 0);
-+
-+ if(handle->ring_buffer == MAP_FAILED) {
-+ sprintf(ebuf, "mmap() failed");
-+ return (NULL);
-+ }
-+
-+ handle->slots_info = (FlowSlotInfo *)handle->ring_buffer;
-+ handle->ring_slots = (char *)(handle->ring_buffer+sizeof(FlowSlotInfo));
-+
-+ /* Safety check */
-+ if(handle->slots_info->remove_idx >= handle->slots_info->tot_slots)
-+ handle->slots_info->remove_idx = 0;
-+
-+ handle->page_id = PAGE_SIZE, handle->slot_id = 0,
-+ handle->pkts_per_page = 0;
-+
-+ if(0) {
-+ int i;
-+
-+ for(i=0; i<handle->slots_info->tot_slots; i++) {
-+ unsigned long idx = i*handle->slots_info->slot_len;
-+ FlowSlot *slot = (FlowSlot*)&handle->ring_slots[idx];
-+
-+ printf("RING: Setting RING_MAGIC_VALUE into slot %d [displacement=%lu]\n", i, idx);
-+ slot->magic = RING_MAGIC_VALUE; slot->slot_state = 0;
-+ printf("RING: slot[%d]: magic=%d, slot_state=%d\n",
-+ slot->magic, slot->slot_state);
-+ }
-+ }
-+
-+
-+ /* Set defaults */
-+ handle->linktype = DLT_EN10MB;
-+ handle->offset = 2;
-+
-+ printf("RING (%s): tot_slots=%d/slot_len=%d/"
-+ "insertIdx=%d/remove_idx=%d/dropped=%d\n",
-+ device,
-+ handle->slots_info->tot_slots,
-+ handle->slots_info->slot_len,
-+ handle->slots_info->insert_idx,
-+ handle->slots_info->remove_idx,
-+ handle->slots_info->tot_lost);
-+
-+ ringStats.ps_recv = handle->slots_info->tot_read;
-+ ringStats.ps_drop = handle->slots_info->tot_lost;
-+
-+ if(promisc) {
-+ struct ifreq ifr;
-+
-+ err = 0;
-+ memset(&ifr, 0, sizeof(ifr));
-+ strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
-+ if (ioctl(handle->fd, SIOCGIFFLAGS, &ifr) == -1) {
-+ snprintf(ebuf, PCAP_ERRBUF_SIZE,
-+ "ioctl: %s", pcap_strerror(errno));
-+ err = 1;
-+ }
-+
-+ if(err == 0) {
-+ if ((ifr.ifr_flags & IFF_PROMISC) == 0) {
-+ /*
-+ * Promiscuous mode isn't currently on,
-+ * so turn it on, and remember that
-+ * we should turn it off when the
-+ * pcap_t is closed.
-+ */
-+
-+ ifr.ifr_flags |= IFF_PROMISC;
-+ if (ioctl(handle->fd, SIOCSIFFLAGS, &ifr) == -1) {
-+ snprintf(ebuf, PCAP_ERRBUF_SIZE,
-+ "ioctl: %s", pcap_strerror(errno));
-+ err = 1;
-+ }
-+ }
-+
-+ if(err == 0)
-+ handle->md.clear_promisc = 1;
-+ }
-+ }
-+
-+ if(err == 0)
-+ goto open_open_live_final;
-+ }
-+
-+ /* Don't put 'else' above... */
-+ close(handle->ring_fd);
-+ /* Continue without ring support */
-+ }
-+#endif
- /*
- * NULL and "any" are special devices which give us the hint to
- * monitor all devices.
-@@ -397,6 +606,9 @@
- return NULL;
- }
-
-+#ifdef RING
-+ open_open_live_final:
-+#endif
- /*
- * "handle->fd" is a socket, so "select()" and "poll()"
- * should work on it.
-@@ -449,6 +661,120 @@
- int packet_len, caplen;
- struct pcap_pkthdr pcap_header;
-
-+#ifdef RING
-+ if(handle->ring_buffer != NULL) {
-+ u_int idx, numRuns = 0, ptrAddr;
-+ FlowSlot *slot;
-+
-+ slot = (FlowSlot*)&handle->ring_slots[handle->slots_info->remove_idx*handle->slots_info->slot_len];
-+
-+ while(1) {
-+ u_int32_t queuedPkts;
-+
-+ if(handle->slots_info->tot_insert >= handle->slots_info->tot_read)
-+ queuedPkts = handle->slots_info->tot_insert - handle->slots_info->tot_read;
-+ else
-+ queuedPkts = handle->slots_info->tot_slots + handle->slots_info->tot_insert - handle->slots_info->tot_read;
-+
-+ if(queuedPkts && (slot->slot_state == 1)) {
-+ char *bucket = &slot->bucket;
-+
-+#ifdef RING_MAGIC
-+ if(slot->magic != RING_MAGIC_VALUE) {
-+ printf("==>> Bad Magic [remove_idx=%u][insert_idx=%u][ptrAddr=%u]\n",
-+ handle->slots_info->remove_idx,
-+ handle->slots_info->insert_idx,
-+ ptrAddr);
-+ slot->magic = RING_MAGIC_VALUE;
-+ }
-+#endif
-+
-+
-+ handle->md.stat.ps_recv++;
-+
-+#ifdef SAFE_RING_MODE
-+ {
-+ struct pcap_pkthdr *hdr = (struct pcap_pkthdr*)bucket;
-+ int bktLen = hdr->caplen;
-+
-+ if(bktLen > sizeof(staticBucket))
-+ bktLen = sizeof(staticBucket);
-+
-+ memcpy(staticBucket, &bucket[sizeof(struct pcap_pkthdr)], bktLen);
-+
-+#ifdef RING_DEBUG
-+ printf("==>> [remove_idx=%u][insert_idx=%u][ptrAddr=%u]\n",
-+ handle->slots_info->remove_idx,
-+ handle->slots_info->insert_idx,
-+ ptrAddr);
-+#endif
-+
-+ callback(userdata, hdr, staticBucket);
-+ }
-+#else
-+ callback(userdata,
-+ (const struct pcap_pkthdr*)bucket,
-+ (const u_char*)&bucket[sizeof(struct pcap_pkthdr)]);
-+#endif
-+
-+ if(handle->slots_info->remove_idx >= (handle->slots_info->tot_slots-1)) {
-+ handle->slots_info->remove_idx = 0;
-+ handle->page_id = PAGE_SIZE, handle->slot_id = 0, handle->pkts_per_page = 0;
-+ } else {
-+ handle->slots_info->remove_idx++;
-+ handle->pkts_per_page++, handle->slot_id += handle->slots_info->slot_len;
-+ }
-+
-+ handle->slots_info->tot_read++;
-+ slot->slot_state = 0;
-+
-+ return(1);
-+ } else {
-+ struct pollfd pfd;
-+ int rc;
-+
-+ /* Sleep when nothing is happening */
-+ pfd.fd = handle->ring_fd;
-+ pfd.events = POLLIN|POLLERR;
-+ pfd.revents = 0;
-+
-+#ifdef RING_DEBUG
-+ printf("==>> poll [remove_idx=%u][insert_idx=%u][loss=%d][queuedPkts=%u]"
-+ "[slot_state=%d][tot_insert=%u][tot_read=%u]\n",
-+ handle->slots_info->remove_idx,
-+ handle->slots_info->insert_idx,
-+ handle->slots_info->tot_lost,
-+ queuedPkts, slot->slot_state,
-+ handle->slots_info->tot_insert,
-+ handle->slots_info->tot_read);
-+ #endif
-+
-+#ifdef RING_DEBUG
-+ printf("==>> poll @ [remove_idx=%u][slot_id=%u]\n", handle->slots_info->remove_idx, handle->slot_id);
-+#endif
-+ errno = 0;
-+ rc = poll(&pfd, 1, -1);
-+#ifdef RING_DEBUG
-+ printf("==>> poll returned %d [%s][errno=%d][break_loop=%d]\n",
-+ rc, strerror(errno), errno, handle->break_loop);
-+#endif
-+ numPollCalls++;
-+
-+ if(rc == -1) {
-+ if(errno == EINTR) {
-+ if(handle->break_loop) {
-+ handle->break_loop = 0;
-+ return(-2);
-+ } else
-+ return(0);
-+ } else
-+ return(-1);
-+ }
-+ }
-+ } /* while() */
-+ }
-+#endif
-+
- #ifdef HAVE_PF_PACKET_SOCKETS
- /*
- * If this is a cooked device, leave extra room for a
-@@ -688,6 +1014,22 @@
- socklen_t len = sizeof (struct tpacket_stats);
- #endif
-
-+#ifdef RING
-+ if(handle->ring_fd > 0) {
-+ stats->ps_recv = handle->slots_info->tot_read-ringStats.ps_recv;
-+ stats->ps_drop = handle->slots_info->tot_lost-ringStats.ps_drop;
-+
-+ printf("RING: numPollCalls=%d [%.1f packets/call]\n",
-+ numPollCalls, (float)stats->ps_recv/(float)numPollCalls);
-+ printf("RING: [tot_pkts=%u][tot_read=%u][tot_lost=%u]\n",
-+ handle->slots_info->tot_pkts,
-+ handle->slots_info->tot_read,
-+ handle->slots_info->tot_lost);
-+
-+ return(0);
-+ }
-+#endif
-+
- #ifdef HAVE_TPACKET_STATS
- /*
- * Try to get the packet counts from the kernel.
-@@ -879,6 +1221,11 @@
- }
- }
-
-+
-+#ifdef RING
-+ if(handle->ring_fd <= 0) can_filter_in_kernel = 0;
-+#endif
-+
- if (can_filter_in_kernel) {
- if ((err = set_kernel_filter(handle, &fcode)) == 0)
- {
-@@ -1348,7 +1695,7 @@
- memset(&mr, 0, sizeof(mr));
- mr.mr_ifindex = device_id;
- mr.mr_type = PACKET_MR_PROMISC;
-- if (setsockopt(sock_fd, SOL_PACKET,
-+ if (setsockopt(sock_fd, 0 /* SOL_PACKET */,
- PACKET_ADD_MEMBERSHIP, &mr, sizeof(mr)) == -1)
- {
- snprintf(ebuf, PCAP_ERRBUF_SIZE,
-@@ -1425,10 +1772,11 @@
-
- /* Any pending errors, e.g., network is down? */
-
-- if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &errlen) == -1) {
-- snprintf(ebuf, PCAP_ERRBUF_SIZE,
-- "getsockopt: %s", pcap_strerror(errno));
-- return -2;
-+ if ((getsockopt(fd, PF_RING, SO_ERROR, &err, &errlen) == -1)
-+ && (getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &errlen) == -1)) {
-+ snprintf(ebuf, PCAP_ERRBUF_SIZE,
-+ "getsockopt: %s", pcap_strerror(errno));
-+ return -2;
- }
-
- if (err > 0) {
-@@ -1482,6 +1830,13 @@
- struct pcap *p, *prevp;
- struct ifreq ifr;
-
-+#ifdef RING
-+ if(handle->ring_buffer != NULL) {
-+ munmap(handle->ring_buffer, handle->slots_info->tot_mem);
-+ handle->ring_buffer = NULL;
-+ }
-+#endif
-+
- if (handle->md.clear_promisc) {
- /*
- * We put the interface into promiscuous mode; take
-@@ -1698,11 +2053,11 @@
- }
-
- /* Any pending errors, e.g., network is down? */
--
-- if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &errlen) == -1) {
-- snprintf(ebuf, PCAP_ERRBUF_SIZE,
-- "getsockopt: %s", pcap_strerror(errno));
-- return -1;
-+ if((getsockopt(fd, PF_RING, SO_ERROR, &err, &errlen) == -1)
-+ && (getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &errlen) == -1)) {
-+ snprintf(ebuf, PCAP_ERRBUF_SIZE,
-+ "getsockopt: %s", pcap_strerror(errno));
-+ return -1;
- }
-
- if (err > 0) {
-@@ -1924,8 +2279,11 @@
- * the filtering done in userland even if it could have been
- * done in the kernel.
- */
-- if (setsockopt(handle->fd, SOL_SOCKET, SO_ATTACH_FILTER,
-- &total_fcode, sizeof(total_fcode)) == 0) {
-+ printf("pcap[setsockopt(%d)]\n", 0);
-+ if (setsockopt(handle->fd, 0 /* SOL_SOCKET */,
-+ SO_ATTACH_FILTER,
-+ &total_fcode,
-+ sizeof(total_fcode)) == 0) {
- char drain[1];
-
- /*
-@@ -1933,6 +2291,9 @@
- */
- total_filter_on = 1;
-
-+#ifdef RING
-+ if(!handle->ring_fd) {
-+#endif
- /*
- * Save the socket's current mode, and put it in
- * non-blocking mode; we drain it by reading packets
-@@ -1955,12 +2316,15 @@
- return -2;
- }
- }
-- }
-+#ifdef RING
-+ }
-+#endif
-+}
-
- /*
- * Now attach the new filter.
- */
-- ret = setsockopt(handle->fd, SOL_SOCKET, SO_ATTACH_FILTER,
-+ ret = setsockopt(handle->fd, 0 /* SOL_SOCKET */, SO_ATTACH_FILTER,
- fcode, sizeof(*fcode));
- if (ret == -1 && total_filter_on) {
- /*
-@@ -1993,7 +2357,8 @@
- /* setsockopt() barfs unless it get a dummy parameter */
- int dummy;
-
-- return setsockopt(handle->fd, SOL_SOCKET, SO_DETACH_FILTER,
-- &dummy, sizeof(dummy));
-+ return setsockopt(handle->fd, handle->ring_fd > 0 ? PF_RING : SOL_SOCKET,
-+ SO_DETACH_FILTER,
-+ &dummy, sizeof(dummy));
- }
- #endif