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[] = 00037 "@(#) $Header: /tcpdump/master/libpcap/inet.c,v 1.54 2002/12/22 02:36:48 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_t *p; 00136 pcap_if_t *curdev, *prevdev, *nextdev; 00137 int this_instance; 00138 00139 /* 00140 * Can we open this interface for live capture? 00141 */ 00142 p = pcap_open_live(name, 68, 0, 0, errbuf); 00143 if (p == NULL) { 00144 /* 00145 * No. Don't bother including it. 00146 * Don't treat this as an error, though. 00147 */ 00148 *curdev_ret = NULL; 00149 return (0); 00150 } 00151 pcap_close(p); 00152 00153 /* 00154 * Is there already an entry in the list for this interface? 00155 */ 00156 for (curdev = *alldevs; curdev != NULL; curdev = curdev->next) { 00157 if (strcmp(name, curdev->name) == 0) 00158 break; /* yes, we found it */ 00159 } 00160 if (curdev == NULL) { 00161 /* 00162 * No, we didn't find it. 00163 * Allocate a new entry. 00164 */ 00165 curdev = malloc(sizeof(pcap_if_t)); 00166 if (curdev == NULL) { 00167 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 00168 "malloc: %s", pcap_strerror(errno)); 00169 return (-1); 00170 } 00171 00172 /* 00173 * Fill in the entry. 00174 */ 00175 curdev->next = NULL; 00176 curdev->name = malloc(strlen(name) + 1); 00177 strcpy(curdev->name, name); 00178 if (description != NULL) { 00179 /* 00180 * We have a description for this interface. 00181 */ 00182 curdev->description = malloc(strlen(description) + 1); 00183 strcpy(curdev->description, description); 00184 } else { 00185 /* 00186 * We don't. 00187 */ 00188 curdev->description = NULL; 00189 } 00190 curdev->addresses = NULL; /* list starts out as empty */ 00191 curdev->flags = 0; 00192 if (ISLOOPBACK(name, flags)) 00193 curdev->flags |= PCAP_IF_LOOPBACK; 00194 00195 /* 00196 * Add it to the list, in the appropriate location. 00197 * First, get the instance number of this interface. 00198 */ 00199 this_instance = get_instance(name); 00200 00201 /* 00202 * Now look for the last interface with an instance number 00203 * less than or equal to the new interface's instance 00204 * number - except that non-loopback interfaces are 00205 * arbitrarily treated as having interface numbers less 00206 * than those of loopback interfaces, so the loopback 00207 * interfaces are put at the end of the list. 00208 * 00209 * We start with "prevdev" being NULL, meaning we're before 00210 * the first element in the list. 00211 */ 00212 prevdev = NULL; 00213 for (;;) { 00214 /* 00215 * Get the interface after this one. 00216 */ 00217 if (prevdev == NULL) { 00218 /* 00219 * The next element is the first element. 00220 */ 00221 nextdev = *alldevs; 00222 } else 00223 nextdev = prevdev->next; 00224 00225 /* 00226 * Are we at the end of the list? 00227 */ 00228 if (nextdev == NULL) { 00229 /* 00230 * Yes - we have to put the new entry 00231 * after "prevdev". 00232 */ 00233 break; 00234 } 00235 00236 /* 00237 * Is the new interface a non-loopback interface 00238 * and the next interface a loopback interface? 00239 */ 00240 if (!(curdev->flags & PCAP_IF_LOOPBACK) && 00241 (nextdev->flags & PCAP_IF_LOOPBACK)) { 00242 /* 00243 * Yes, we should put the new entry 00244 * before "nextdev", i.e. after "prevdev". 00245 */ 00246 break; 00247 } 00248 00249 /* 00250 * Is the new interface's instance number less 00251 * than the next interface's instance number, 00252 * and is it the case that the new interface is a 00253 * non-loopback interface or the next interface is 00254 * a loopback interface? 00255 * 00256 * (The goal of both loopback tests is to make 00257 * sure that we never put a loopback interface 00258 * before any non-loopback interface and that we 00259 * always put a non-loopback interface before all 00260 * loopback interfaces.) 00261 */ 00262 if (this_instance < get_instance(nextdev->name) && 00263 (!(curdev->flags & PCAP_IF_LOOPBACK) || 00264 (nextdev->flags & PCAP_IF_LOOPBACK))) { 00265 /* 00266 * Yes - we should put the new entry 00267 * before "nextdev", i.e. after "prevdev". 00268 */ 00269 break; 00270 } 00271 00272 prevdev = nextdev; 00273 } 00274 00275 /* 00276 * Insert before "nextdev". 00277 */ 00278 curdev->next = nextdev; 00279 00280 /* 00281 * Insert after "prevdev" - unless "prevdev" is null, 00282 * in which case this is the first interface. 00283 */ 00284 if (prevdev == NULL) { 00285 /* 00286 * This is the first interface. Pass back a 00287 * pointer to it, and put "curdev" before 00288 * "nextdev". 00289 */ 00290 *alldevs = curdev; 00291 } else 00292 prevdev->next = curdev; 00293 } 00294 00295 *curdev_ret = curdev; 00296 return (0); 00297 } 00298 00299 int 00300 add_addr_to_iflist(pcap_if_t **alldevs, char *name, u_int flags, 00301 struct sockaddr *addr, size_t addr_size, 00302 struct sockaddr *netmask, size_t netmask_size, 00303 struct sockaddr *broadaddr, size_t broadaddr_size, 00304 struct sockaddr *dstaddr, size_t dstaddr_size, 00305 char *errbuf) 00306 { 00307 pcap_if_t *curdev; 00308 pcap_addr_t *curaddr, *prevaddr, *nextaddr; 00309 00310 if (add_or_find_if(&curdev, alldevs, name, flags, NULL, errbuf) == -1) { 00311 /* 00312 * Error - give up. 00313 */ 00314 return (-1); 00315 } 00316 if (curdev == NULL) { 00317 /* 00318 * Device wasn't added because it can't be opened. 00319 * Not a fatal error. 00320 */ 00321 return (0); 00322 } 00323 00324 /* 00325 * "curdev" is an entry for this interface; add an entry for this 00326 * address to its list of addresses. 00327 * 00328 * Allocate the new entry and fill it in. 00329 */ 00330 curaddr = malloc(sizeof(pcap_addr_t)); 00331 if (curaddr == NULL) { 00332 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 00333 "malloc: %s", pcap_strerror(errno)); 00334 return (-1); 00335 } 00336 00337 curaddr->next = NULL; 00338 if (addr != NULL) { 00339 curaddr->addr = dup_sockaddr(addr, addr_size); 00340 if (curaddr->addr == NULL) { 00341 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 00342 "malloc: %s", pcap_strerror(errno)); 00343 free(curaddr); 00344 return (-1); 00345 } 00346 } else 00347 curaddr->addr = NULL; 00348 00349 if (netmask != NULL) { 00350 curaddr->netmask = dup_sockaddr(netmask, netmask_size); 00351 if (curaddr->netmask == NULL) { 00352 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 00353 "malloc: %s", pcap_strerror(errno)); 00354 free(curaddr); 00355 return (-1); 00356 } 00357 } else 00358 curaddr->netmask = NULL; 00359 00360 if (broadaddr != NULL) { 00361 curaddr->broadaddr = dup_sockaddr(broadaddr, broadaddr_size); 00362 if (curaddr->broadaddr == NULL) { 00363 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 00364 "malloc: %s", pcap_strerror(errno)); 00365 free(curaddr); 00366 return (-1); 00367 } 00368 } else 00369 curaddr->broadaddr = NULL; 00370 00371 if (dstaddr != NULL) { 00372 curaddr->dstaddr = dup_sockaddr(dstaddr, dstaddr_size); 00373 if (curaddr->dstaddr == NULL) { 00374 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 00375 "malloc: %s", pcap_strerror(errno)); 00376 free(curaddr); 00377 return (-1); 00378 } 00379 } else 00380 curaddr->dstaddr = NULL; 00381 00382 /* 00383 * Find the end of the list of addresses. 00384 */ 00385 for (prevaddr = curdev->addresses; prevaddr != NULL; prevaddr = nextaddr) { 00386 nextaddr = prevaddr->next; 00387 if (nextaddr == NULL) { 00388 /* 00389 * This is the end of the list. 00390 */ 00391 break; 00392 } 00393 } 00394 00395 if (prevaddr == NULL) { 00396 /* 00397 * The list was empty; this is the first member. 00398 */ 00399 curdev->addresses = curaddr; 00400 } else { 00401 /* 00402 * "prevaddr" is the last member of the list; append 00403 * this member to it. 00404 */ 00405 prevaddr->next = curaddr; 00406 } 00407 00408 return (0); 00409 } 00410 00411 int 00412 pcap_add_if(pcap_if_t **devlist, char *name, u_int flags, 00413 const char *description, char *errbuf) 00414 { 00415 pcap_if_t *curdev; 00416 00417 return (add_or_find_if(&curdev, devlist, name, flags, description, 00418 errbuf)); 00419 } 00420 00421 00422 /* 00423 * Free a list of interfaces. 00424 */ 00425 void 00426 pcap_freealldevs(pcap_if_t *alldevs) 00427 { 00428 pcap_if_t *curdev, *nextdev; 00429 pcap_addr_t *curaddr, *nextaddr; 00430 00431 for (curdev = alldevs; curdev != NULL; curdev = nextdev) { 00432 nextdev = curdev->next; 00433 00434 /* 00435 * Free all addresses. 00436 */ 00437 for (curaddr = curdev->addresses; curaddr != NULL; curaddr = nextaddr) { 00438 nextaddr = curaddr->next; 00439 if (curaddr->addr) 00440 free(curaddr->addr); 00441 if (curaddr->netmask) 00442 free(curaddr->netmask); 00443 if (curaddr->broadaddr) 00444 free(curaddr->broadaddr); 00445 if (curaddr->dstaddr) 00446 free(curaddr->dstaddr); 00447 free(curaddr); 00448 } 00449 00450 /* 00451 * Free the name string. 00452 */ 00453 free(curdev->name); 00454 00455 /* 00456 * Free the description string, if any. 00457 */ 00458 if (curdev->description != NULL) 00459 free(curdev->description); 00460 00461 /* 00462 * Free the interface. 00463 */ 00464 free(curdev); 00465 } 00466 } 00467 00468 #ifndef WIN32 00469 00470 /* 00471 * Return the name of a network interface attached to the system, or NULL 00472 * if none can be found. The interface must be configured up; the 00473 * lowest unit number is preferred; loopback is ignored. 00474 */ 00475 char * 00476 pcap_lookupdev(errbuf) 00477 register char *errbuf; 00478 { 00479 pcap_if_t *alldevs; 00480 /* for old BSD systems, including bsdi3 */ 00481 #ifndef IF_NAMESIZE 00482 #define IF_NAMESIZE IFNAMSIZ 00483 #endif 00484 static char device[IF_NAMESIZE + 1]; 00485 char *ret; 00486 00487 if (pcap_findalldevs(&alldevs, errbuf) == -1) 00488 return (NULL); 00489 00490 if (alldevs == NULL || (alldevs->flags & PCAP_IF_LOOPBACK)) { 00491 /* 00492 * There are no devices on the list, or the first device 00493 * on the list is a loopback device, which means there 00494 * are no non-loopback devices on the list. This means 00495 * we can't return any device. 00496 * 00497 * XXX - why not return a loopback device? If we can't 00498 * capture on it, it won't be on the list, and if it's 00499 * on the list, there aren't any non-loopback devices, 00500 * so why not just supply it as the default device? 00501 */ 00502 (void)strlcpy(errbuf, "no suitable device found", 00503 PCAP_ERRBUF_SIZE); 00504 ret = NULL; 00505 } else { 00506 /* 00507 * Return the name of the first device on the list. 00508 */ 00509 (void)strlcpy(device, alldevs->name, sizeof(device)); 00510 ret = device; 00511 } 00512 00513 pcap_freealldevs(alldevs); 00514 return (ret); 00515 } 00516 00517 int 00518 pcap_lookupnet(device, netp, maskp, errbuf) 00519 register const char *device; 00520 register bpf_u_int32 *netp, *maskp; 00521 register char *errbuf; 00522 { 00523 register int fd; 00524 register struct sockaddr_in *sin; 00525 struct ifreq ifr; 00526 00527 /* 00528 * The pseudo-device "any" listens on all interfaces and therefore 00529 * has the network address and -mask "0.0.0.0" therefore catching 00530 * all traffic. Using NULL for the interface is the same as "any". 00531 */ 00532 if (!device || strcmp(device, "any") == 0) { 00533 *netp = *maskp = 0; 00534 return 0; 00535 } 00536 00537 fd = socket(AF_INET, SOCK_DGRAM, 0); 00538 if (fd < 0) { 00539 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "socket: %s", 00540 pcap_strerror(errno)); 00541 return (-1); 00542 } 00543 memset(&ifr, 0, sizeof(ifr)); 00544 #ifdef linux 00545 /* XXX Work around Linux kernel bug */ 00546 ifr.ifr_addr.sa_family = AF_INET; 00547 #endif 00548 (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); 00549 if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) { 00550 if (errno == EADDRNOTAVAIL) { 00551 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 00552 "%s: no IPv4 address assigned", device); 00553 } else { 00554 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 00555 "SIOCGIFADDR: %s: %s", 00556 device, pcap_strerror(errno)); 00557 } 00558 (void)close(fd); 00559 return (-1); 00560 } 00561 sin = (struct sockaddr_in *)&ifr.ifr_addr; 00562 *netp = sin->sin_addr.s_addr; 00563 if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifr) < 0) { 00564 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 00565 "SIOCGIFNETMASK: %s: %s", device, pcap_strerror(errno)); 00566 (void)close(fd); 00567 return (-1); 00568 } 00569 (void)close(fd); 00570 *maskp = sin->sin_addr.s_addr; 00571 if (*maskp == 0) { 00572 if (IN_CLASSA(*netp)) 00573 *maskp = IN_CLASSA_NET; 00574 else if (IN_CLASSB(*netp)) 00575 *maskp = IN_CLASSB_NET; 00576 else if (IN_CLASSC(*netp)) 00577 *maskp = IN_CLASSC_NET; 00578 else { 00579 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 00580 "inet class for 0x%x unknown", *netp); 00581 return (-1); 00582 } 00583 } 00584 *netp &= *maskp; 00585 return (0); 00586 } 00587 00588 #else /* WIN32 */ 00589 00590 /* 00591 * Return the name of a network interface attached to the system, or NULL 00592 * if none can be found. The interface must be configured up; the 00593 * lowest unit number is preferred; loopback is ignored. 00594 */ 00595 char * 00596 pcap_lookupdev(errbuf) 00597 register char *errbuf; 00598 { 00599 DWORD dwVersion; 00600 DWORD dwWindowsMajorVersion; 00601 dwVersion = GetVersion(); /* get the OS version */ 00602 dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion))); 00603 00604 if (dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4) { 00605 /* 00606 * Windows 95, 98, ME. 00607 */ 00608 ULONG NameLength = 8192; 00609 static char AdaptersName[8192]; 00610 00611 PacketGetAdapterNames(AdaptersName,&NameLength); 00612 00613 return (AdaptersName); 00614 } else { 00615 /* 00616 * Windows NT (NT 4.0, W2K, WXP). 00617 */ 00618 ULONG NameLength = 8192; 00619 static WCHAR AdaptersName[8192]; 00620 00621 PacketGetAdapterNames((PTSTR)AdaptersName,&NameLength); 00622 00623 return (char *)(AdaptersName); 00624 } 00625 } 00626 00627 00628 int 00629 pcap_lookupnet(device, netp, maskp, errbuf) 00630 register const char *device; 00631 register bpf_u_int32 *netp, *maskp; 00632 register char *errbuf; 00633 { 00634 /* 00635 * We need only the first address, so we allocate a single 00636 * npf_if_addr structure and we set if_addr_size to 1. 00637 */ 00638 npf_if_addr if_addrs; 00639 LONG if_addr_size = 1; 00640 struct sockaddr_in *t_addr; 00641 00642 if (!PacketGetNetInfoEx((void *)device, &if_addrs, &if_addr_size)) { 00643 *netp = *maskp = 0; 00644 return (0); 00645 } 00646 00647 t_addr = (struct sockaddr_in *) &(if_addrs.IPAddress); 00648 *netp = t_addr->sin_addr.S_un.S_addr; 00649 t_addr = (struct sockaddr_in *) &(if_addrs.SubnetMask); 00650 *maskp = t_addr->sin_addr.S_un.S_addr; 00651 00652 /* 00653 * XXX - will we ever get back a 0 netmask? 00654 * If so, we should presumably make the "if (*maskp == 0)" code 00655 * above common, rather than non-Win32-specific. 00656 */ 00657 00658 *netp &= *maskp; 00659 return (0); 00660 } 00661 00662 #endif /* WIN32 */
documentation. Copyright (c) 2002-2003 Politecnico di Torino. All rights reserved.