From 4068214e84302cbbba5d80255b57cec2126526c6 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 25 Apr 2009 03:30:10 +0000 Subject: pcap: update to version 1.0.0, add extension for changing the desired protocol for the internal raw socket (useful for reducing the cpu overhead of capture) git-svn-id: svn://svn.openwrt.org/openwrt/trunk@15398 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- .../libpcap/patches/101-debian_fix_any_intf.patch | 149 +++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 package/libpcap/patches/101-debian_fix_any_intf.patch (limited to 'package/libpcap/patches/101-debian_fix_any_intf.patch') diff --git a/package/libpcap/patches/101-debian_fix_any_intf.patch b/package/libpcap/patches/101-debian_fix_any_intf.patch new file mode 100644 index 0000000000..8da6ef2237 --- /dev/null +++ b/package/libpcap/patches/101-debian_fix_any_intf.patch @@ -0,0 +1,149 @@ +--- a/pcap-linux.c ++++ b/pcap-linux.c +@@ -297,6 +297,12 @@ pcap_create(const char *device, char *eb + { + pcap_t *handle; + ++ /* ++ * A null device name is equivalent to the "any" device. ++ */ ++ if (device == NULL) ++ device = "any"; ++ + #ifdef HAVE_DAG_API + if (strstr(device, "dag")) { + return dag_create(device, ebuf); +@@ -338,10 +344,9 @@ pcap_can_set_rfmon_linux(pcap_t *p) + struct iwreq ireq; + #endif + +- if (p->opt.source == NULL) { ++ if (strcmp(p->opt.source, "any") == 0) { + /* +- * This is equivalent to the "any" device, and we don't +- * support monitor mode on it. ++ * Monitor mode makes no sense on the "any" device. + */ + return 0; + } +@@ -518,12 +523,11 @@ pcap_activate_linux(pcap_t *handle) + handle->stats_op = pcap_stats_linux; + + /* +- * NULL and "any" are special devices which give us the hint to +- * monitor all devices. ++ * The "any" device is a special device which causes us not ++ * to bind to a particular device and thus to look at all ++ * devices. + */ +- if (!device || strcmp(device, "any") == 0) { +- device = NULL; +- handle->md.device = strdup("any"); ++ if (strcmp(device, "any") == 0) { + if (handle->opt.promisc) { + handle->opt.promisc = 0; + /* Just a warning. */ +@@ -531,10 +535,9 @@ pcap_activate_linux(pcap_t *handle) + "Promiscuous mode not supported on the \"any\" device"); + status = PCAP_WARNING_PROMISC_NOTSUP; + } ++ } + +- } else +- handle->md.device = strdup(device); +- ++ handle->md.device = strdup(device); + if (handle->md.device == NULL) { + snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "strdup: %s", + pcap_strerror(errno) ); +@@ -1657,19 +1660,21 @@ static int + activate_new(pcap_t *handle) + { + #ifdef HAVE_PF_PACKET_SOCKETS ++ const char *device = handle->opt.source; ++ int is_any_device = (strcmp(device, "any") == 0); + int sock_fd = -1, arptype, val; + int err = 0; + struct packet_mreq mr; +- const char* device = handle->opt.source; + + /* +- * Open a socket with protocol family packet. If a device is +- * given we try to open it in raw mode otherwise we use +- * the cooked interface. +- */ +- sock_fd = device ? +- socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)) +- : socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL)); ++ * Open a socket with protocol family packet. If the ++ * "any" device was specified, we open a SOCK_DGRAM ++ * socket for the cooked interface, otherwise we first ++ * try a SOCK_RAW socket for the raw interface. ++ */ ++ sock_fd = is_any_device ? ++ socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL)) : ++ socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); + + if (sock_fd == -1) { + snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "socket: %s", +@@ -1704,7 +1709,7 @@ activate_new(pcap_t *handle) + * to cooked mode if we have an unknown interface type + * or a type we know doesn't work well in raw mode. + */ +- if (device) { ++ if (!is_any_device) { + /* Assume for now we don't need cooked mode. */ + handle->md.cooked = 0; + +@@ -1819,15 +1824,23 @@ activate_new(pcap_t *handle) + } + } else { + /* +- * This is cooked mode. ++ * The "any" device. ++ */ ++ if (handle->opt.rfmon) { ++ /* ++ * It doesn't support monitor mode. ++ */ ++ return PCAP_ERROR_RFMON_NOTSUP; ++ } ++ ++ /* ++ * It uses cooked mode. + */ + handle->md.cooked = 1; + handle->linktype = DLT_LINUX_SLL; + + /* + * We're not bound to a device. +- * XXX - true? Or true only if we're using +- * the "any" device? + * For now, we're using this as an indication + * that we can't transmit; stop doing that only + * if we figure out how to transmit in cooked +@@ -1852,10 +1865,13 @@ activate_new(pcap_t *handle) + + /* + * Hmm, how can we set promiscuous mode on all interfaces? +- * I am not sure if that is possible at all. ++ * I am not sure if that is possible at all. For now, we ++ * silently ignore attempts to turn promiscuous mode on ++ * for the "any" device (so you don't have to explicitly ++ * disable it in programs such as tcpdump). + */ + +- if (device && handle->opt.promisc) { ++ if (!is_any_device && handle->opt.promisc) { + memset(&mr, 0, sizeof(mr)); + mr.mr_ifindex = handle->md.ifindex; + mr.mr_type = PACKET_MR_PROMISC; +@@ -3118,7 +3134,7 @@ activate_old(pcap_t *handle) + + /* Bind to the given device */ + +- if (!device) { ++ if (strcmp(device, "any") == 0) { + strncpy(handle->errbuf, "pcap_activate: The \"any\" device isn't supported on 2.0[.x]-kernel systems", + PCAP_ERRBUF_SIZE); + return PCAP_ERROR; -- cgit v1.2.3