diff options
-rw-r--r-- | inet.c | 87 | ||||
-rw-r--r-- | pcap.c | 64 |
2 files changed, 44 insertions, 107 deletions
@@ -107,29 +107,53 @@ dup_sockaddr(struct sockaddr *sa, size_t sa_length) return (memcpy(newsa, sa, sa_length)); } -static int -get_instance(const char *name) +/* + * Construct a "figure of merit" for an interface, for use when sorting + * the list of interfaces, in which interfaces that are up are superior + * to interfaces that aren't up, interfaces that are up and running are + * superior to interfaces that are up but not running, and non-loopback + * interfaces that are up and running are superior to loopback interfaces, + * and interfaces with the same flags have a figure of merit that's higher + * the lower the instance number. + * + * The goal is to try to put the interfaces most likely to be useful for + * capture at the beginning of the list. + * + * The figure of merit, which is lower the "better" the interface is, + * has the uppermost bit set if the interface isn't running, the bit + * below that set if the interface isn't up, the bit below that set + * if the interface is a loopback interface, and the interface index + * in the 29 bits below that. (Yes, we assume u_int is 32 bits.) + */ +static u_int +get_figure_of_merit(pcap_if_t *dev) { const char *cp, *endcp; - int n; + u_int n; - if (strcmp(name, "any") == 0) { + if (strcmp(dev->name, "any") == 0) { /* * Give the "any" device an artificially high instance * number, so it shows up after all other non-loopback * interfaces. */ - return INT_MAX; + n = 0x1FFFFFFF; /* 29 all-1 bits */ } - endcp = name + strlen(name); - for (cp = name; cp < endcp && !isdigit((unsigned char)*cp); ++cp) + endcp = dev->name + strlen(dev->name); + for (cp = dev->name; cp < endcp && !isdigit((unsigned char)*cp); ++cp) continue; if (isdigit((unsigned char)*cp)) n = atoi(cp); else n = 0; + if (!(dev->flags & PCAP_IF_RUNNING)) + n |= 0x80000000; + if (!(dev->flags & PCAP_IF_UP)) + n |= 0x40000000; + if (dev->flags & PCAP_IF_LOOPBACK) + n |= 0x20000000; return (n); } @@ -139,7 +163,7 @@ add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, const char *name, { pcap_t *p; pcap_if_t *curdev, *prevdev, *nextdev; - int this_instance; + u_int this_figure_of_merit, nextdev_figure_of_merit; char open_errbuf[PCAP_ERRBUF_SIZE]; /* @@ -266,17 +290,15 @@ add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, const char *name, /* * Add it to the list, in the appropriate location. - * First, get the instance number of this interface. + * First, get the "figure of merit" for this + * interface. */ - this_instance = get_instance(name); + this_figure_of_merit = get_figure_of_merit(curdev); /* - * Now look for the last interface with an instance number - * less than or equal to the new interface's instance - * number - except that non-loopback interfaces are - * arbitrarily treated as having interface numbers less - * than those of loopback interfaces, so the loopback - * interfaces are put at the end of the list. + * Now look for the last interface with an figure of merit + * less than or equal to the new interface's figure of + * merit. * * We start with "prevdev" being NULL, meaning we're before * the first element in the list. @@ -306,34 +328,13 @@ add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, const char *name, } /* - * Is the new interface a non-loopback interface - * and the next interface a loopback interface? - */ - if (!(curdev->flags & PCAP_IF_LOOPBACK) && - (nextdev->flags & PCAP_IF_LOOPBACK)) { - /* - * Yes, we should put the new entry - * before "nextdev", i.e. after "prevdev". - */ - break; - } - - /* - * Is the new interface's instance number less - * than the next interface's instance number, - * and is it the case that the new interface is a - * non-loopback interface or the next interface is - * a loopback interface? - * - * (The goal of both loopback tests is to make - * sure that we never put a loopback interface - * before any non-loopback interface and that we - * always put a non-loopback interface before all - * loopback interfaces.) + * Is the new interface's figure of merit less + * than the next interface's figure of merit, + * meaning that the new interface is better + * than the next interface? */ - if (this_instance < get_instance(nextdev->name) && - (!(curdev->flags & PCAP_IF_LOOPBACK) || - (nextdev->flags & PCAP_IF_LOOPBACK))) { + nextdev_figure_of_merit = get_figure_of_merit(nextdev); + if (this_figure_of_merit < nextdev_figure_of_merit) { /* * Yes - we should put the new entry * before "nextdev", i.e. after "prevdev". @@ -266,64 +266,6 @@ pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header, return (p->read_op(p, 1, p->oneshot_callback, (u_char *)&s)); } -/* - * Sort the interfaces in order to have UP & RUNNING ones first - */ -static int -pcap_if_sort(pcap_if_t **alldevsp, char* errbuf) -{ - pcap_if_t* newlist = NULL; - pcap_if_t* curdev; - - /* Group 1: PCAP_IF_RUNNING - PCAP_IF_UP - !PCAP_IF_LOOPBACK */ - for (curdev = *alldevsp; curdev != NULL; curdev = curdev->next) { - if ((curdev->flags & PCAP_IF_RUNNING) && (curdev->flags & PCAP_IF_UP) && - !(curdev->flags & PCAP_IF_LOOPBACK)) { - if (pcap_add_if(&newlist, curdev->name, curdev->flags, - curdev->description, errbuf) == -1) { - return (-1); - } - } - } - - /* Group 2: !PCAP_IF_RUNNING - PCAP_IF_UP - !PCAP_IF_LOOPBACK */ - for (curdev = *alldevsp; curdev != NULL; curdev = curdev->next) { - if (!(curdev->flags & PCAP_IF_RUNNING) && (curdev->flags & PCAP_IF_UP) && - !(curdev->flags & PCAP_IF_LOOPBACK)) { - if (pcap_add_if(&newlist, curdev->name, curdev->flags, - curdev->description, errbuf) == -1) { - return (-1); - } - } - } - - /* Group 3: !PCAP_IF_RUNNING - !PCAP_IF_UP - !PCAP_IF_LOOPBACK */ - for (curdev = *alldevsp; curdev != NULL; curdev = curdev->next) { - if (!(curdev->flags & PCAP_IF_RUNNING) && !(curdev->flags & PCAP_IF_UP) && - !(curdev->flags & PCAP_IF_LOOPBACK)) { - if (pcap_add_if(&newlist, curdev->name, curdev->flags, - curdev->description, errbuf) == -1) { - return (-1); - } - } - } - - /* Group 4: PCAP_IF_LOOPBACK */ - for (curdev = *alldevsp; curdev != NULL; curdev = curdev->next) { - if (curdev->flags & PCAP_IF_LOOPBACK) { - if (pcap_add_if(&newlist, curdev->name, curdev->flags, - curdev->description, errbuf) == -1) { - return (-1); - } - } - } - - pcap_freealldevs(*alldevsp); - *alldevsp = newlist; - - return (0); -} - #if defined(DAG_ONLY) int pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) @@ -446,12 +388,6 @@ pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) } } - if (pcap_if_sort(alldevsp, errbuf) == -1) { - pcap_freealldevs(*alldevsp); - *alldevsp = NULL; - return (-1); - } - return (0); } |