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  | 
