diff options
Diffstat (limited to 'package')
-rw-r--r-- | package/libpcap/patches/110-pf_ring.patch | 613 |
1 files changed, 0 insertions, 613 deletions
diff --git a/package/libpcap/patches/110-pf_ring.patch b/package/libpcap/patches/110-pf_ring.patch deleted file mode 100644 index 1d5124fac..000000000 --- a/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 |