Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 794 lines (716 sloc) 20.019 kb
478ab6c auto import from //depot/cupcake/@135843
The Android Open Source Project authored
1 /* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
2 /*
3 * Copyright (c) 1994, 1995, 1996, 1997, 1998
4 * The Regents of the University of California. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by the Computer Systems
17 * Engineering Group at Lawrence Berkeley Laboratory.
18 * 4. Neither the name of the University nor of the Laboratory may be used
19 * to endorse or promote products derived from this software without
20 * specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35 #ifndef lint
36 static const char rcsid[] _U_ =
37 "@(#) $Header: /tcpdump/master/libpcap/inet.c,v 1.66.2.6 2007/06/11 09:52:04 guy Exp $ (LBL)";
38 #endif
39
40 #ifdef HAVE_CONFIG_H
41 #include "config.h"
42 #endif
43
44 #ifdef WIN32
45 #include <pcap-stdinc.h>
46 #else /* WIN32 */
47
48 #include <sys/param.h>
49 #ifndef MSDOS
50 #include <sys/file.h>
51 #endif
52 #include <sys/ioctl.h>
53 #include <sys/socket.h>
54 #ifdef HAVE_SYS_SOCKIO_H
55 #include <sys/sockio.h>
56 #endif
57
58 struct mbuf; /* Squelch compiler warnings on some platforms for */
59 struct rtentry; /* declarations in <net/if.h> */
60 #include <net/if.h>
61 #include <netinet/in.h>
62 #endif /* WIN32 */
63
64 #include <ctype.h>
65 #include <errno.h>
66 #include <memory.h>
67 #include <stdio.h>
68 #include <stdlib.h>
69 #include <string.h>
70 #if !defined(WIN32) && !defined(__BORLANDC__)
71 #include <unistd.h>
72 #endif /* !WIN32 && !__BORLANDC__ */
73 #ifdef HAVE_LIMITS_H
74 #include <limits.h>
75 #else
76 #define INT_MAX 2147483647
77 #endif
78
79 #include "pcap-int.h"
80
81 #ifdef HAVE_OS_PROTO_H
82 #include "os-proto.h"
83 #endif
84
85 /* Not all systems have IFF_LOOPBACK */
86 #ifdef IFF_LOOPBACK
87 #define ISLOOPBACK(name, flags) ((flags) & IFF_LOOPBACK)
88 #else
89 #define ISLOOPBACK(name, flags) ((name)[0] == 'l' && (name)[1] == 'o' && \
90 (isdigit((unsigned char)((name)[2])) || (name)[2] == '\0'))
91 #endif
92
93 struct sockaddr *
94 dup_sockaddr(struct sockaddr *sa, size_t sa_length)
95 {
96 struct sockaddr *newsa;
97
98 if ((newsa = malloc(sa_length)) == NULL)
99 return (NULL);
100 return (memcpy(newsa, sa, sa_length));
101 }
102
103 static int
104 get_instance(const char *name)
105 {
106 const char *cp, *endcp;
107 int n;
108
109 if (strcmp(name, "any") == 0) {
110 /*
111 * Give the "any" device an artificially high instance
112 * number, so it shows up after all other non-loopback
113 * interfaces.
114 */
115 return INT_MAX;
116 }
117
118 endcp = name + strlen(name);
119 for (cp = name; cp < endcp && !isdigit((unsigned char)*cp); ++cp)
120 continue;
121
122 if (isdigit((unsigned char)*cp))
123 n = atoi(cp);
124 else
125 n = 0;
126 return (n);
127 }
128
129 int
130 add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, const char *name,
131 u_int flags, const char *description, char *errbuf)
132 {
133 pcap_t *p;
134 pcap_if_t *curdev, *prevdev, *nextdev;
135 int this_instance;
136
137 /*
138 * Is there already an entry in the list for this interface?
139 */
140 for (curdev = *alldevs; curdev != NULL; curdev = curdev->next) {
141 if (strcmp(name, curdev->name) == 0)
142 break; /* yes, we found it */
143 }
144
145 if (curdev == NULL) {
146 /*
147 * No, we didn't find it.
148 *
149 * Can we open this interface for live capture?
150 *
151 * We do this check so that interfaces that are
152 * supplied by the interface enumeration mechanism
153 * we're using but that don't support packet capture
154 * aren't included in the list. Loopback interfaces
155 * on Solaris are an example of this; we don't just
156 * omit loopback interfaces on all platforms because
157 * you *can* capture on loopback interfaces on some
158 * OSes.
159 *
160 * On OS X, we don't do this check if the device
161 * name begins with "wlt"; at least some versions
162 * of OS X offer monitor mode capturing by having
163 * a separate "monitor mode" device for each wireless
164 * adapter, rather than by implementing the ioctls
165 * that {Free,Net,Open,DragonFly}BSD provide.
166 * Opening that device puts the adapter into monitor
167 * mode, which, at least for some adapters, causes
168 * them to deassociate from the network with which
169 * they're associated.
170 *
171 * Instead, we try to open the corresponding "en"
172 * device (so that we don't end up with, for users
173 * without sufficient privilege to open capture
174 * devices, a list of adapters that only includes
175 * the wlt devices).
176 */
177 #ifdef __APPLE__
178 if (strncmp(name, "wlt", 3) == 0) {
179 char *en_name;
180 size_t en_name_len;
181
182 /*
183 * Try to allocate a buffer for the "en"
184 * device's name.
185 */
186 en_name_len = strlen(name) - 1;
187 en_name = malloc(en_name_len + 1);
188 if (en_name == NULL) {
189 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
190 "malloc: %s", pcap_strerror(errno));
191 return (-1);
192 }
193 strcpy(en_name, "en");
194 strcat(en_name, name + 3);
195 p = pcap_open_live(en_name, 68, 0, 0, errbuf);
196 free(en_name);
197 } else
198 #endif /* __APPLE */
199 p = pcap_open_live(name, 68, 0, 0, errbuf);
200 if (p == NULL) {
201 /*
202 * No. Don't bother including it.
203 * Don't treat this as an error, though.
204 */
205 *curdev_ret = NULL;
206 return (0);
207 }
208 pcap_close(p);
209
210 /*
211 * Yes, we can open it.
212 * Allocate a new entry.
213 */
214 curdev = malloc(sizeof(pcap_if_t));
215 if (curdev == NULL) {
216 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
217 "malloc: %s", pcap_strerror(errno));
218 return (-1);
219 }
220
221 /*
222 * Fill in the entry.
223 */
224 curdev->next = NULL;
225 curdev->name = strdup(name);
226 if (curdev->name == NULL) {
227 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
228 "malloc: %s", pcap_strerror(errno));
229 free(curdev);
230 return (-1);
231 }
232 if (description != NULL) {
233 /*
234 * We have a description for this interface.
235 */
236 curdev->description = strdup(description);
237 if (curdev->description == NULL) {
238 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
239 "malloc: %s", pcap_strerror(errno));
240 free(curdev->name);
241 free(curdev);
242 return (-1);
243 }
244 } else {
245 /*
246 * We don't.
247 */
248 curdev->description = NULL;
249 }
250 curdev->addresses = NULL; /* list starts out as empty */
251 curdev->flags = 0;
252 if (ISLOOPBACK(name, flags))
253 curdev->flags |= PCAP_IF_LOOPBACK;
254
255 /*
256 * Add it to the list, in the appropriate location.
257 * First, get the instance number of this interface.
258 */
259 this_instance = get_instance(name);
260
261 /*
262 * Now look for the last interface with an instance number
263 * less than or equal to the new interface's instance
264 * number - except that non-loopback interfaces are
265 * arbitrarily treated as having interface numbers less
266 * than those of loopback interfaces, so the loopback
267 * interfaces are put at the end of the list.
268 *
269 * We start with "prevdev" being NULL, meaning we're before
270 * the first element in the list.
271 */
272 prevdev = NULL;
273 for (;;) {
274 /*
275 * Get the interface after this one.
276 */
277 if (prevdev == NULL) {
278 /*
279 * The next element is the first element.
280 */
281 nextdev = *alldevs;
282 } else
283 nextdev = prevdev->next;
284
285 /*
286 * Are we at the end of the list?
287 */
288 if (nextdev == NULL) {
289 /*
290 * Yes - we have to put the new entry
291 * after "prevdev".
292 */
293 break;
294 }
295
296 /*
297 * Is the new interface a non-loopback interface
298 * and the next interface a loopback interface?
299 */
300 if (!(curdev->flags & PCAP_IF_LOOPBACK) &&
301 (nextdev->flags & PCAP_IF_LOOPBACK)) {
302 /*
303 * Yes, we should put the new entry
304 * before "nextdev", i.e. after "prevdev".
305 */
306 break;
307 }
308
309 /*
310 * Is the new interface's instance number less
311 * than the next interface's instance number,
312 * and is it the case that the new interface is a
313 * non-loopback interface or the next interface is
314 * a loopback interface?
315 *
316 * (The goal of both loopback tests is to make
317 * sure that we never put a loopback interface
318 * before any non-loopback interface and that we
319 * always put a non-loopback interface before all
320 * loopback interfaces.)
321 */
322 if (this_instance < get_instance(nextdev->name) &&
323 (!(curdev->flags & PCAP_IF_LOOPBACK) ||
324 (nextdev->flags & PCAP_IF_LOOPBACK))) {
325 /*
326 * Yes - we should put the new entry
327 * before "nextdev", i.e. after "prevdev".
328 */
329 break;
330 }
331
332 prevdev = nextdev;
333 }
334
335 /*
336 * Insert before "nextdev".
337 */
338 curdev->next = nextdev;
339
340 /*
341 * Insert after "prevdev" - unless "prevdev" is null,
342 * in which case this is the first interface.
343 */
344 if (prevdev == NULL) {
345 /*
346 * This is the first interface. Pass back a
347 * pointer to it, and put "curdev" before
348 * "nextdev".
349 */
350 *alldevs = curdev;
351 } else
352 prevdev->next = curdev;
353 }
354
355 *curdev_ret = curdev;
356 return (0);
357 }
358
359 int
360 add_addr_to_iflist(pcap_if_t **alldevs, const char *name, u_int flags,
361 struct sockaddr *addr, size_t addr_size,
362 struct sockaddr *netmask, size_t netmask_size,
363 struct sockaddr *broadaddr, size_t broadaddr_size,
364 struct sockaddr *dstaddr, size_t dstaddr_size,
365 char *errbuf)
366 {
367 pcap_if_t *curdev;
368 pcap_addr_t *curaddr, *prevaddr, *nextaddr;
369
370 if (add_or_find_if(&curdev, alldevs, name, flags, NULL, errbuf) == -1) {
371 /*
372 * Error - give up.
373 */
374 return (-1);
375 }
376 if (curdev == NULL) {
377 /*
378 * Device wasn't added because it can't be opened.
379 * Not a fatal error.
380 */
381 return (0);
382 }
383
384 /*
385 * "curdev" is an entry for this interface; add an entry for this
386 * address to its list of addresses.
387 *
388 * Allocate the new entry and fill it in.
389 */
390 curaddr = malloc(sizeof(pcap_addr_t));
391 if (curaddr == NULL) {
392 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
393 "malloc: %s", pcap_strerror(errno));
394 return (-1);
395 }
396
397 curaddr->next = NULL;
398 if (addr != NULL) {
399 curaddr->addr = dup_sockaddr(addr, addr_size);
400 if (curaddr->addr == NULL) {
401 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
402 "malloc: %s", pcap_strerror(errno));
403 free(curaddr);
404 return (-1);
405 }
406 } else
407 curaddr->addr = NULL;
408
409 if (netmask != NULL) {
410 curaddr->netmask = dup_sockaddr(netmask, netmask_size);
411 if (curaddr->netmask == NULL) {
412 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
413 "malloc: %s", pcap_strerror(errno));
414 if (curaddr->addr != NULL)
415 free(curaddr->addr);
416 free(curaddr);
417 return (-1);
418 }
419 } else
420 curaddr->netmask = NULL;
421
422 if (broadaddr != NULL) {
423 curaddr->broadaddr = dup_sockaddr(broadaddr, broadaddr_size);
424 if (curaddr->broadaddr == NULL) {
425 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
426 "malloc: %s", pcap_strerror(errno));
427 if (curaddr->netmask != NULL)
428 free(curaddr->netmask);
429 if (curaddr->addr != NULL)
430 free(curaddr->addr);
431 free(curaddr);
432 return (-1);
433 }
434 } else
435 curaddr->broadaddr = NULL;
436
437 if (dstaddr != NULL) {
438 curaddr->dstaddr = dup_sockaddr(dstaddr, dstaddr_size);
439 if (curaddr->dstaddr == NULL) {
440 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
441 "malloc: %s", pcap_strerror(errno));
442 if (curaddr->broadaddr != NULL)
443 free(curaddr->broadaddr);
444 if (curaddr->netmask != NULL)
445 free(curaddr->netmask);
446 if (curaddr->addr != NULL)
447 free(curaddr->addr);
448 free(curaddr);
449 return (-1);
450 }
451 } else
452 curaddr->dstaddr = NULL;
453
454 /*
455 * Find the end of the list of addresses.
456 */
457 for (prevaddr = curdev->addresses; prevaddr != NULL; prevaddr = nextaddr) {
458 nextaddr = prevaddr->next;
459 if (nextaddr == NULL) {
460 /*
461 * This is the end of the list.
462 */
463 break;
464 }
465 }
466
467 if (prevaddr == NULL) {
468 /*
469 * The list was empty; this is the first member.
470 */
471 curdev->addresses = curaddr;
472 } else {
473 /*
474 * "prevaddr" is the last member of the list; append
475 * this member to it.
476 */
477 prevaddr->next = curaddr;
478 }
479
480 return (0);
481 }
482
483 int
484 pcap_add_if(pcap_if_t **devlist, const char *name, u_int flags,
485 const char *description, char *errbuf)
486 {
487 pcap_if_t *curdev;
488
489 return (add_or_find_if(&curdev, devlist, name, flags, description,
490 errbuf));
491 }
492
493
494 /*
495 * Free a list of interfaces.
496 */
497 void
498 pcap_freealldevs(pcap_if_t *alldevs)
499 {
500 pcap_if_t *curdev, *nextdev;
501 pcap_addr_t *curaddr, *nextaddr;
502
503 for (curdev = alldevs; curdev != NULL; curdev = nextdev) {
504 nextdev = curdev->next;
505
506 /*
507 * Free all addresses.
508 */
509 for (curaddr = curdev->addresses; curaddr != NULL; curaddr = nextaddr) {
510 nextaddr = curaddr->next;
511 if (curaddr->addr)
512 free(curaddr->addr);
513 if (curaddr->netmask)
514 free(curaddr->netmask);
515 if (curaddr->broadaddr)
516 free(curaddr->broadaddr);
517 if (curaddr->dstaddr)
518 free(curaddr->dstaddr);
519 free(curaddr);
520 }
521
522 /*
523 * Free the name string.
524 */
525 free(curdev->name);
526
527 /*
528 * Free the description string, if any.
529 */
530 if (curdev->description != NULL)
531 free(curdev->description);
532
533 /*
534 * Free the interface.
535 */
536 free(curdev);
537 }
538 }
539
540 #if !defined(WIN32) && !defined(MSDOS)
541
542 /*
543 * Return the name of a network interface attached to the system, or NULL
544 * if none can be found. The interface must be configured up; the
545 * lowest unit number is preferred; loopback is ignored.
546 */
547 char *
548 pcap_lookupdev(errbuf)
549 register char *errbuf;
550 {
551 pcap_if_t *alldevs;
552 /* for old BSD systems, including bsdi3 */
553 #ifndef IF_NAMESIZE
554 #define IF_NAMESIZE IFNAMSIZ
555 #endif
556 static char device[IF_NAMESIZE + 1];
557 char *ret;
558
559 if (pcap_findalldevs(&alldevs, errbuf) == -1)
560 return (NULL);
561
562 if (alldevs == NULL || (alldevs->flags & PCAP_IF_LOOPBACK)) {
563 /*
564 * There are no devices on the list, or the first device
565 * on the list is a loopback device, which means there
566 * are no non-loopback devices on the list. This means
567 * we can't return any device.
568 *
569 * XXX - why not return a loopback device? If we can't
570 * capture on it, it won't be on the list, and if it's
571 * on the list, there aren't any non-loopback devices,
572 * so why not just supply it as the default device?
573 */
574 (void)strlcpy(errbuf, "no suitable device found",
575 PCAP_ERRBUF_SIZE);
576 ret = NULL;
577 } else {
578 /*
579 * Return the name of the first device on the list.
580 */
581 (void)strlcpy(device, alldevs->name, sizeof(device));
582 ret = device;
583 }
584
585 pcap_freealldevs(alldevs);
586 return (ret);
587 }
588
589 int
590 pcap_lookupnet(device, netp, maskp, errbuf)
591 register const char *device;
592 register bpf_u_int32 *netp, *maskp;
593 register char *errbuf;
594 {
595 register int fd;
596 register struct sockaddr_in *sin4;
597 struct ifreq ifr;
598
599 /*
600 * The pseudo-device "any" listens on all interfaces and therefore
601 * has the network address and -mask "0.0.0.0" therefore catching
602 * all traffic. Using NULL for the interface is the same as "any".
603 */
604 if (!device || strcmp(device, "any") == 0
605 #ifdef HAVE_DAG_API
606 || strstr(device, "dag") != NULL
607 #endif
608 #ifdef HAVE_SEPTEL_API
609 || strstr(device, "septel") != NULL
610 #endif
611 ) {
612 *netp = *maskp = 0;
613 return 0;
614 }
615
616 fd = socket(AF_INET, SOCK_DGRAM, 0);
617 if (fd < 0) {
618 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "socket: %s",
619 pcap_strerror(errno));
620 return (-1);
621 }
622 memset(&ifr, 0, sizeof(ifr));
623 #ifdef linux
624 /* XXX Work around Linux kernel bug */
625 ifr.ifr_addr.sa_family = AF_INET;
626 #endif
627 (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
628 if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) {
629 if (errno == EADDRNOTAVAIL) {
630 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
631 "%s: no IPv4 address assigned", device);
632 } else {
633 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
634 "SIOCGIFADDR: %s: %s",
635 device, pcap_strerror(errno));
636 }
637 (void)close(fd);
638 return (-1);
639 }
640 sin4 = (struct sockaddr_in *)&ifr.ifr_addr;
641 *netp = sin4->sin_addr.s_addr;
642 if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifr) < 0) {
643 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
644 "SIOCGIFNETMASK: %s: %s", device, pcap_strerror(errno));
645 (void)close(fd);
646 return (-1);
647 }
648 (void)close(fd);
649 *maskp = sin4->sin_addr.s_addr;
650 if (*maskp == 0) {
651 if (IN_CLASSA(*netp))
652 *maskp = IN_CLASSA_NET;
653 else if (IN_CLASSB(*netp))
654 *maskp = IN_CLASSB_NET;
655 else if (IN_CLASSC(*netp))
656 *maskp = IN_CLASSC_NET;
657 else {
658 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
659 "inet class for 0x%x unknown", *netp);
660 return (-1);
661 }
662 }
663 *netp &= *maskp;
664 return (0);
665 }
666
667 #elif defined(WIN32)
668
669 /*
670 * Return the name of a network interface attached to the system, or NULL
671 * if none can be found. The interface must be configured up; the
672 * lowest unit number is preferred; loopback is ignored.
673 */
674 char *
675 pcap_lookupdev(errbuf)
676 register char *errbuf;
677 {
678 DWORD dwVersion;
679 DWORD dwWindowsMajorVersion;
680 dwVersion = GetVersion(); /* get the OS version */
681 dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
682
683 if (dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4) {
684 /*
685 * Windows 95, 98, ME.
686 */
687 ULONG NameLength = 8192;
688 static char AdaptersName[8192];
689
690 if (PacketGetAdapterNames(AdaptersName,&NameLength) )
691 return (AdaptersName);
692 else
693 return NULL;
694 } else {
695 /*
696 * Windows NT (NT 4.0, W2K, WXP). Convert the names to UNICODE for backward compatibility
697 */
698 ULONG NameLength = 8192;
699 static WCHAR AdaptersName[8192];
700 char *tAstr;
701 WCHAR *tUstr;
702 WCHAR *TAdaptersName = (WCHAR*)malloc(8192 * sizeof(WCHAR));
703 int NAdapts = 0;
704
705 if(TAdaptersName == NULL)
706 {
707 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "memory allocation failure");
708 return NULL;
709 }
710
711 if ( !PacketGetAdapterNames((PTSTR)TAdaptersName,&NameLength) )
712 {
713 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
714 "PacketGetAdapterNames: %s",
715 pcap_win32strerror());
716 free(TAdaptersName);
717 return NULL;
718 }
719
720
721 tAstr = (char*)TAdaptersName;
722 tUstr = (WCHAR*)AdaptersName;
723
724 /*
725 * Convert and copy the device names
726 */
727 while(sscanf(tAstr, "%S", tUstr) > 0)
728 {
729 tAstr += strlen(tAstr) + 1;
730 tUstr += wcslen(tUstr) + 1;
731 NAdapts ++;
732 }
733
734 tAstr++;
735 *tUstr = 0;
736 tUstr++;
737
738 /*
739 * Copy the descriptions
740 */
741 while(NAdapts--)
742 {
743 strcpy((char*)tUstr, tAstr);
744 (char*)tUstr += strlen(tAstr) + 1;;
745 tAstr += strlen(tAstr) + 1;
746 }
747
748 free(TAdaptersName);
749 return (char *)(AdaptersName);
750 }
751 }
752
753
754 int
755 pcap_lookupnet(device, netp, maskp, errbuf)
756 register const char *device;
757 register bpf_u_int32 *netp, *maskp;
758 register char *errbuf;
759 {
760 /*
761 * We need only the first IPv4 address, so we must scan the array returned by PacketGetNetInfo()
762 * in order to skip non IPv4 (i.e. IPv6 addresses)
763 */
764 npf_if_addr if_addrs[MAX_NETWORK_ADDRESSES];
765 LONG if_addr_size = 1;
766 struct sockaddr_in *t_addr;
767 unsigned int i;
768
769 if (!PacketGetNetInfoEx((void *)device, if_addrs, &if_addr_size)) {
770 *netp = *maskp = 0;
771 return (0);
772 }
773
774 for(i=0; i<MAX_NETWORK_ADDRESSES; i++)
775 {
776 if(if_addrs[i].IPAddress.ss_family == AF_INET)
777 {
778 t_addr = (struct sockaddr_in *) &(if_addrs[i].IPAddress);
779 *netp = t_addr->sin_addr.S_un.S_addr;
780 t_addr = (struct sockaddr_in *) &(if_addrs[i].SubnetMask);
781 *maskp = t_addr->sin_addr.S_un.S_addr;
782
783 *netp &= *maskp;
784 return (0);
785 }
786
787 }
788
789 *netp = *maskp = 0;
790 return (0);
791 }
792
793 #endif /* !WIN32 && !MSDOS */
Something went wrong with that request. Please try again.