Main Page Modules Data Structures File List Data Fields Globals Related Pages

# inet.c

Go to the documentation of this file.

    00001 /* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
    00002 /*
    00003  * Copyright (c) 1994, 1995, 1996, 1997, 1998
    00004  *  The Regents of the University of California.  All rights reserved.
    00005  *
    00006  * Redistribution and use in source and binary forms, with or without
    00007  * modification, are permitted provided that the following conditions
    00008  * are met:
    00009  * 1. Redistributions of source code must retain the above copyright
    00010  *    notice, this list of conditions and the following disclaimer.
    00011  * 2. Redistributions in binary form must reproduce the above copyright
    00012  *    notice, this list of conditions and the following disclaimer in the
    00013  *    documentation and/or other materials provided with the distribution.
    00014  * 3. All advertising materials mentioning features or use of this software
    00015  *    must display the following acknowledgement:
    00016  *  This product includes software developed by the Computer Systems
    00017  *  Engineering Group at Lawrence Berkeley Laboratory.
    00018  * 4. Neither the name of the University nor of the Laboratory may be used
    00019  *    to endorse or promote products derived from this software without
    00020  *    specific prior written permission.
    00021  *
    00022  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
    00023  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    00024  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    00025  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
    00026  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    00027  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    00028  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    00029  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    00030  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    00031  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    00032  * SUCH DAMAGE.
    00033  */
    00034
    00035 #ifndef lint
    00036 static const char rcsid[] _U_ =
    00037     "@(#) $Header: /tcpdump/master/libpcap/inet.c,v 1.58.2.1 2003/11/15 23:26:41 guy Exp $ (LBL)";
    00038 #endif
    00039
    00040 #ifdef HAVE_CONFIG_H
    00041 #include "config.h"
    00042 #endif
    00043
    00044 #ifdef WIN32
    00045 #include <pcap-stdinc.h>
    00046 #else /* WIN32 */
    00047
    00048 #include <sys/param.h>
    00049 #include <sys/file.h>
    00050 #include <sys/ioctl.h>
    00051 #include <sys/socket.h>
    00052 #ifdef HAVE_SYS_SOCKIO_H
    00053 #include <sys/sockio.h>
    00054 #endif
    00055 #include <sys/time.h>               /* concession to AIX */
    00056
    00057 struct mbuf;        /* Squelch compiler warnings on some platforms for */
    00058 struct rtentry;     /* declarations in <net/if.h> */
    00059 #include <net/if.h>
    00060 #include <netinet/in.h>
    00061 #endif /* WIN32 */
    00062
    00063 #include <ctype.h>
    00064 #include <errno.h>
    00065 #include <memory.h>
    00066 #include <stdio.h>
    00067 #include <stdlib.h>
    00068 #include <string.h>
    00069 #ifndef WIN32
    00070 #include <unistd.h>
    00071 #endif /* WIN32 */
    00072 #ifdef HAVE_LIMITS_H
    00073 #include <limits.h>
    00074 #else
    00075 #define INT_MAX     2147483647
    00076 #endif
    00077 #ifdef HAVE_IFADDRS_H
    00078 #include <ifaddrs.h>
    00079 #endif
    00080
    00081 #include "pcap-int.h"
    00082
    00083 #ifdef HAVE_OS_PROTO_H
    00084 #include "os-proto.h"
    00085 #endif
    00086
    00087 /* Not all systems have IFF_LOOPBACK */
    00088 #ifdef IFF_LOOPBACK
    00089 #define ISLOOPBACK(name, flags) ((flags) & IFF_LOOPBACK)
    00090 #else
    00091 #define ISLOOPBACK(name, flags) ((name)[0] == 'l' && (name)[1] == 'o' && \
    00092     (isdigit((unsigned char)((name)[2])) || (name)[2] == '\0'))
    00093 #endif
    00094
    00095 struct sockaddr *
    00096 dup_sockaddr(struct sockaddr *sa, size_t sa_length)
    00097 {
    00098     struct sockaddr *newsa;
    00099
    00100     if ((newsa = malloc(sa_length)) == NULL)
    00101         return (NULL);
    00102     return (memcpy(newsa, sa, sa_length));
    00103 }
    00104
    00105 static int
    00106 get_instance(const char *name)
    00107 {
    00108     const char *cp, *endcp;
    00109     int n;
    00110
    00111     if (strcmp(name, "any") == 0) {
    00112         /*
    00113          * Give the "any" device an artificially high instance
    00114          * number, so it shows up after all other non-loopback
    00115          * interfaces.
    00116          */
    00117         return INT_MAX;
    00118     }
    00119
    00120     endcp = name + strlen(name);
    00121     for (cp = name; cp < endcp && !isdigit((unsigned char)*cp); ++cp)
    00122         continue;
    00123
    00124     if (isdigit((unsigned char)*cp))
    00125         n = atoi(cp);
    00126     else
    00127         n = 0;
    00128     return (n);
    00129 }
    00130
    00131 int
    00132 add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, const char *name,
    00133     u_int flags, const char *description, char *errbuf)
    00134 {
    00135     pcap_if_t *curdev, *prevdev, *nextdev;
    00136     int this_instance;
    00137
    00138     /*
    00139      * Is there already an entry in the list for this interface?
    00140      */
    00141     for (curdev = *alldevs; curdev != NULL; curdev = curdev->next) {
    00142         if (strcmp(name, curdev->name) == 0)
    00143             break;  /* yes, we found it */
    00144     }
    00145     if (curdev == NULL) {
    00146         /*
    00147          * No, we didn't find it.
    00148          * Allocate a new entry.
    00149          */
    00150         curdev = malloc(sizeof(pcap_if_t));
    00151         if (curdev == NULL) {
    00152             (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
    00153                 "malloc: %s", pcap_strerror(errno));
    00154             return (-1);
    00155         }
    00156
    00157         /*
    00158          * Fill in the entry.
    00159          */
    00160         curdev->next = NULL;
    00161         curdev->name = malloc(strlen(name) + 1);
    00162         strcpy(curdev->name, name);
    00163         if (description != NULL) {
    00164             /*
    00165              * We have a description for this interface.
    00166              */
    00167             curdev->description = malloc(strlen(description) + 1);
    00168             strcpy(curdev->description, description);
    00169         } else {
    00170             /*
    00171              * We don't.
    00172              */
    00173             curdev->description = NULL;
    00174         }
    00175         curdev->addresses = NULL;   /* list starts out as empty */
    00176         curdev->flags = 0;
    00177         if (ISLOOPBACK(name, flags))
    00178             curdev->flags |= PCAP_IF_LOOPBACK;
    00179
    00180         /*
    00181          * Add it to the list, in the appropriate location.
    00182          * First, get the instance number of this interface.
    00183          */
    00184         this_instance = get_instance(name);
    00185
    00186         /*
    00187          * Now look for the last interface with an instance number
    00188          * less than or equal to the new interface's instance
    00189          * number - except that non-loopback interfaces are
    00190          * arbitrarily treated as having interface numbers less
    00191          * than those of loopback interfaces, so the loopback
    00192          * interfaces are put at the end of the list.
    00193          *
    00194          * We start with "prevdev" being NULL, meaning we're before
    00195          * the first element in the list.
    00196          */
    00197         prevdev = NULL;
    00198         for (;;) {
    00199             /*
    00200              * Get the interface after this one.
    00201              */
    00202             if (prevdev == NULL) {
    00203                 /*
    00204                  * The next element is the first element.
    00205                  */
    00206                 nextdev = *alldevs;
    00207             } else
    00208                 nextdev = prevdev->next;
    00209
    00210             /*
    00211              * Are we at the end of the list?
    00212              */
    00213             if (nextdev == NULL) {
    00214                 /*
    00215                  * Yes - we have to put the new entry
    00216                  * after "prevdev".
    00217                  */
    00218                 break;
    00219             }
    00220
    00221             /*
    00222              * Is the new interface a non-loopback interface
    00223              * and the next interface a loopback interface?
    00224              */
    00225             if (!(curdev->flags & PCAP_IF_LOOPBACK) &&
    00226                 (nextdev->flags & PCAP_IF_LOOPBACK)) {
    00227                 /*
    00228                  * Yes, we should put the new entry
    00229                  * before "nextdev", i.e. after "prevdev".
    00230                  */
    00231                 break;
    00232             }
    00233
    00234             /*
    00235              * Is the new interface's instance number less
    00236              * than the next interface's instance number,
    00237              * and is it the case that the new interface is a
    00238              * non-loopback interface or the next interface is
    00239              * a loopback interface?
    00240              *
    00241              * (The goal of both loopback tests is to make
    00242              * sure that we never put a loopback interface
    00243              * before any non-loopback interface and that we
    00244              * always put a non-loopback interface before all
    00245              * loopback interfaces.)
    00246              */
    00247             if (this_instance < get_instance(nextdev->name) &&
    00248                 (!(curdev->flags & PCAP_IF_LOOPBACK) ||
    00249                    (nextdev->flags & PCAP_IF_LOOPBACK))) {
    00250                 /*
    00251                  * Yes - we should put the new entry
    00252                  * before "nextdev", i.e. after "prevdev".
    00253                  */
    00254                 break;
    00255             }
    00256
    00257             prevdev = nextdev;
    00258         }
    00259
    00260         /*
    00261          * Insert before "nextdev".
    00262          */
    00263         curdev->next = nextdev;
    00264
    00265         /*
    00266          * Insert after "prevdev" - unless "prevdev" is null,
    00267          * in which case this is the first interface.
    00268          */
    00269         if (prevdev == NULL) {
    00270             /*
    00271              * This is the first interface.  Pass back a
    00272              * pointer to it, and put "curdev" before
    00273              * "nextdev".
    00274              */
    00275             *alldevs = curdev;
    00276         } else
    00277             prevdev->next = curdev;
    00278     }
    00279
    00280     *curdev_ret = curdev;
    00281     return (0);
    00282 }
    00283
    00284 int
    00285 add_addr_to_iflist(pcap_if_t **alldevs, char *name, u_int flags,
    00286     struct sockaddr *addr, size_t addr_size,
    00287     struct sockaddr *netmask, size_t netmask_size,
    00288     struct sockaddr *broadaddr, size_t broadaddr_size,
    00289     struct sockaddr *dstaddr, size_t dstaddr_size,
    00290     char *errbuf)
    00291 {
    00292     pcap_if_t *curdev;
    00293     pcap_addr_t *curaddr, *prevaddr, *nextaddr;
    00294
    00295     if (add_or_find_if(&curdev, alldevs, name, flags, NULL, errbuf) == -1) {
    00296         /*
    00297          * Error - give up.
    00298          */
    00299         return (-1);
    00300     }
    00301     if (curdev == NULL) {
    00302         /*
    00303          * Device wasn't added because it can't be opened.
    00304          * Not a fatal error.
    00305          */
    00306         return (0);
    00307     }
    00308
    00309     /*
    00310      * "curdev" is an entry for this interface; add an entry for this
    00311      * address to its list of addresses.
    00312      *
    00313      * Allocate the new entry and fill it in.
    00314      */
    00315     curaddr = malloc(sizeof(pcap_addr_t));
    00316     if (curaddr == NULL) {
    00317         (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
    00318             "malloc: %s", pcap_strerror(errno));
    00319         return (-1);
    00320     }
    00321
    00322     curaddr->next = NULL;
    00323     if (addr != NULL) {
    00324         curaddr->addr = dup_sockaddr(addr, addr_size);
    00325         if (curaddr->addr == NULL) {
    00326             (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
    00327                 "malloc: %s", pcap_strerror(errno));
    00328             free(curaddr);
    00329             return (-1);
    00330         }
    00331     } else
    00332         curaddr->addr = NULL;
    00333
    00334     if (netmask != NULL) {
    00335         curaddr->netmask = dup_sockaddr(netmask, netmask_size);
    00336         if (curaddr->netmask == NULL) {
    00337             (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
    00338                 "malloc: %s", pcap_strerror(errno));
    00339             free(curaddr);
    00340             return (-1);
    00341         }
    00342     } else
    00343         curaddr->netmask = NULL;
    00344
    00345     if (broadaddr != NULL) {
    00346         curaddr->broadaddr = dup_sockaddr(broadaddr, broadaddr_size);
    00347         if (curaddr->broadaddr == NULL) {
    00348             (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
    00349                 "malloc: %s", pcap_strerror(errno));
    00350             free(curaddr);
    00351             return (-1);
    00352         }
    00353     } else
    00354         curaddr->broadaddr = NULL;
    00355
    00356     if (dstaddr != NULL) {
    00357         curaddr->dstaddr = dup_sockaddr(dstaddr, dstaddr_size);
    00358         if (curaddr->dstaddr == NULL) {
    00359             (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
    00360                 "malloc: %s", pcap_strerror(errno));
    00361             free(curaddr);
    00362             return (-1);
    00363         }
    00364     } else
    00365         curaddr->dstaddr = NULL;
    00366
    00367     /*
    00368      * Find the end of the list of addresses.
    00369      */
    00370     for (prevaddr = curdev->addresses; prevaddr != NULL; prevaddr = nextaddr) {
    00371         nextaddr = prevaddr->next;
    00372         if (nextaddr == NULL) {
    00373             /*
    00374              * This is the end of the list.
    00375              */
    00376             break;
    00377         }
    00378     }
    00379
    00380     if (prevaddr == NULL) {
    00381         /*
    00382          * The list was empty; this is the first member.
    00383          */
    00384         curdev->addresses = curaddr;
    00385     } else {
    00386         /*
    00387          * "prevaddr" is the last member of the list; append
    00388          * this member to it.
    00389          */
    00390         prevaddr->next = curaddr;
    00391     }
    00392
    00393     return (0);
    00394 }
    00395
    00396 int
    00397 pcap_add_if(pcap_if_t **devlist, char *name, u_int flags,
    00398     const char *description, char *errbuf)
    00399 {
    00400     pcap_if_t *curdev;
    00401
    00402     return (add_or_find_if(&curdev, devlist, name, flags, description,
    00403         errbuf));
    00404 }
    00405
    00406
    00407 /*
    00408  * Free a list of interfaces.
    00409  */
    00410 void
    00411 pcap_freealldevs(pcap_if_t *alldevs)
    00412 {
    00413     pcap_if_t *curdev, *nextdev;
    00414     pcap_addr_t *curaddr, *nextaddr;
    00415
    00416     for (curdev = alldevs; curdev != NULL; curdev = nextdev) {
    00417         nextdev = curdev->next;
    00418
    00419         /*
    00420          * Free all addresses.
    00421          */
    00422         for (curaddr = curdev->addresses; curaddr != NULL; curaddr = nextaddr) {
    00423             nextaddr = curaddr->next;
    00424             if (curaddr->addr)
    00425                 free(curaddr->addr);
    00426             if (curaddr->netmask)
    00427                 free(curaddr->netmask);
    00428             if (curaddr->broadaddr)
    00429                 free(curaddr->broadaddr);
    00430             if (curaddr->dstaddr)
    00431                 free(curaddr->dstaddr);
    00432             free(curaddr);
    00433         }
    00434
    00435         /*
    00436          * Free the name string.
    00437          */
    00438         free(curdev->name);
    00439
    00440         /*
    00441          * Free the description string, if any.
    00442          */
    00443         if (curdev->description != NULL)
    00444             free(curdev->description);
    00445
    00446         /*
    00447          * Free the interface.
    00448          */
    00449         free(curdev);
    00450     }
    00451 }
    00452
    00453 #ifndef WIN32
    00454
    00455 /*
    00456  * Return the name of a network interface attached to the system, or NULL
    00457  * if none can be found.  The interface must be configured up; the
    00458  * lowest unit number is preferred; loopback is ignored.
    00459  */
    00460 char *
    00461 pcap_lookupdev(errbuf)
    00462     register char *errbuf;
    00463 {
    00464     pcap_if_t *alldevs;
    00465 /* for old BSD systems, including bsdi3 */
    00466 #ifndef IF_NAMESIZE
    00467 #define IF_NAMESIZE IFNAMSIZ
    00468 #endif
    00469     static char device[IF_NAMESIZE + 1];
    00470     char *ret;
    00471
    00472     if (pcap_findalldevs(&alldevs, errbuf) == -1)
    00473         return (NULL);
    00474
    00475     if (alldevs == NULL || (alldevs->flags & PCAP_IF_LOOPBACK)) {
    00476         /*
    00477          * There are no devices on the list, or the first device
    00478          * on the list is a loopback device, which means there
    00479          * are no non-loopback devices on the list.  This means
    00480          * we can't return any device.
    00481          *
    00482          * XXX - why not return a loopback device?  If we can't
    00483          * capture on it, it won't be on the list, and if it's
    00484          * on the list, there aren't any non-loopback devices,
    00485          * so why not just supply it as the default device?
    00486          */
    00487         (void)strlcpy(errbuf, "no suitable device found",
    00488             PCAP_ERRBUF_SIZE);
    00489         ret = NULL;
    00490     } else {
    00491         /*
    00492          * Return the name of the first device on the list.
    00493          */
    00494         (void)strlcpy(device, alldevs->name, sizeof(device));
    00495         ret = device;
    00496     }
    00497
    00498     pcap_freealldevs(alldevs);
    00499     return (ret);
    00500 }
    00501
    00502 int
    00503 pcap_lookupnet(device, netp, maskp, errbuf)
    00504     register const char *device;
    00505     register bpf_u_int32 *netp, *maskp;
    00506     register char *errbuf;
    00507 {
    00508     register int fd;
    00509     register struct sockaddr_in *sin;
    00510     struct ifreq ifr;
    00511
    00512     /*
    00513      * The pseudo-device "any" listens on all interfaces and therefore
    00514      * has the network address and -mask "0.0.0.0" therefore catching
    00515      * all traffic. Using NULL for the interface is the same as "any".
    00516      */
    00517     if (!device || strcmp(device, "any") == 0
    00518 #ifdef HAVE_DAG_API
    00519         || strstr(device, "dag") != NULL
    00520 #endif
    00521         ) {
    00522         *netp = *maskp = 0;
    00523         return 0;
    00524     }
    00525
    00526     fd = socket(AF_INET, SOCK_DGRAM, 0);
    00527     if (fd < 0) {
    00528         (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "socket: %s",
    00529             pcap_strerror(errno));
    00530         return (-1);
    00531     }
    00532     memset(&ifr, 0, sizeof(ifr));
    00533 #ifdef linux
    00534     /* XXX Work around Linux kernel bug */
    00535     ifr.ifr_addr.sa_family = AF_INET;
    00536 #endif
    00537     (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
    00538     if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) {
    00539         if (errno == EADDRNOTAVAIL) {
    00540             (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
    00541                 "%s: no IPv4 address assigned", device);
    00542         } else {
    00543             (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
    00544                 "SIOCGIFADDR: %s: %s",
    00545                 device, pcap_strerror(errno));
    00546         }
    00547         (void)close(fd);
    00548         return (-1);
    00549     }
    00550     sin = (struct sockaddr_in *)&ifr.ifr_addr;
    00551     *netp = sin->sin_addr.s_addr;
    00552     if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifr) < 0) {
    00553         (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
    00554             "SIOCGIFNETMASK: %s: %s", device, pcap_strerror(errno));
    00555         (void)close(fd);
    00556         return (-1);
    00557     }
    00558     (void)close(fd);
    00559     *maskp = sin->sin_addr.s_addr;
    00560     if (*maskp == 0) {
    00561         if (IN_CLASSA(*netp))
    00562             *maskp = IN_CLASSA_NET;
    00563         else if (IN_CLASSB(*netp))
    00564             *maskp = IN_CLASSB_NET;
    00565         else if (IN_CLASSC(*netp))
    00566             *maskp = IN_CLASSC_NET;
    00567         else {
    00568             (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
    00569                 "inet class for 0x%x unknown", *netp);
    00570             return (-1);
    00571         }
    00572     }
    00573     *netp &= *maskp;
    00574     return (0);
    00575 }
    00576
    00577 #else /* WIN32 */
    00578
    00579 /*
    00580  * Return the name of a network interface attached to the system, or NULL
    00581  * if none can be found.  The interface must be configured up; the
    00582  * lowest unit number is preferred; loopback is ignored.
    00583  */
    00584 char *
    00585 pcap_lookupdev(errbuf)
    00586     register char *errbuf;
    00587 {
    00588     DWORD dwVersion;
    00589     DWORD dwWindowsMajorVersion;
    00590     dwVersion = GetVersion();   /* get the OS version */
    00591     dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
    00592
    00593     if (dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4) {
    00594         /*
    00595          * Windows 95, 98, ME.
    00596          */
    00597         ULONG NameLength = 8192;
    00598         static char AdaptersName[8192];
    00599
    00600         if (PacketGetAdapterNames(AdaptersName,&NameLength) )
    00601             return (AdaptersName);
    00602         else
    00603             return NULL;
    00604     } else {
    00605         /*
    00606          * Windows NT (NT 4.0, W2K, WXP). Convert the names to UNICODE for backward compatibility
    00607          */
    00608         ULONG NameLength = 8192;
    00609         static WCHAR AdaptersName[8192];
    00610         char *tAstr;
    00611         WCHAR *tUstr;
    00612         WCHAR *TAdaptersName = (WCHAR*)malloc(8192 * sizeof(WCHAR));
    00613         int NAdapts = 0;
    00614
    00615         if(TAdaptersName == NULL)
    00616         {
    00617             (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "memory allocation failure");
    00618             return NULL;
    00619         }
    00620
    00621         if ( !PacketGetAdapterNames((PTSTR)TAdaptersName,&NameLength) )
    00622         {
    00623             (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
    00624                 "PacketGetAdapterNames: %s",
    00625                 pcap_win32strerror());
    00626             free(TAdaptersName);
    00627             return NULL;
    00628         }
    00629
    00630
    00631         tAstr = (char*)TAdaptersName;
    00632         tUstr = (WCHAR*)AdaptersName;
    00633
    00634         /*
    00635          * Convert and copy the device names
    00636          */
    00637         while(sscanf(tAstr, "%S", tUstr) > 0)
    00638         {
    00639             tAstr += strlen(tAstr) + 1;
    00640             tUstr += wcslen(tUstr) + 1;
    00641             NAdapts ++;
    00642         }
    00643
    00644         tAstr++;
    00645         *tUstr = 0;
    00646         tUstr++;
    00647
    00648         /*
    00649          * Copy the descriptions
    00650          */
    00651         while(NAdapts--)
    00652         {
    00653             strcpy((char*)tUstr, tAstr);
    00654             (char*)tUstr += strlen(tAstr) + 1;;
    00655             tAstr += strlen(tAstr) + 1;
    00656         }
    00657
    00658         free(TAdaptersName);
    00659         return (char *)(AdaptersName);
    00660     }
    00661 }
    00662
    00663
    00664 int
    00665 pcap_lookupnet(device, netp, maskp, errbuf)
    00666     const register char *device;
    00667     register bpf_u_int32 *netp, *maskp;
    00668     register char *errbuf;
    00669 {
    00670     /*
    00671      * We need only the first IPv4 address, so we must scan the array returned by PacketGetNetInfo()
    00672      * in order to skip non IPv4 (i.e. IPv6 addresses)
    00673      */
    00674     npf_if_addr if_addrs[MAX_NETWORK_ADDRESSES];
    00675     LONG if_addr_size = 1;
    00676     struct sockaddr_in *t_addr;
    00677     unsigned int i;
    00678
    00679     if (!PacketGetNetInfoEx((void *)device, if_addrs, &if_addr_size)) {
    00680         *netp = *maskp = 0;
    00681         return (0);
    00682     }
    00683
    00684     for(i=0; i<MAX_NETWORK_ADDRESSES; i++)
    00685     {
    00686         if(if_addrs[i].IPAddress.ss_family == AF_INET)
    00687         {
    00688             t_addr = (struct sockaddr_in *) &(if_addrs[i].IPAddress);
    00689             *netp = t_addr->sin_addr.S_un.S_addr;
    00690             t_addr = (struct sockaddr_in *) &(if_addrs[i].SubnetMask);
    00691             *maskp = t_addr->sin_addr.S_un.S_addr;
    00692
    00693             *netp &= *maskp;
    00694             return (0);
    00695         }
    00696
    00697     }
    00698
    00699     *netp = *maskp = 0;
    00700     return (0);
    00701 }
    00702
    00703 #endif /* WIN32 */

documentation. Copyright (c) 2002-2003 Politecnico di Torino. All rights reserved.