]> The Tcpdump Group git mirrors - libpcap/blob - inet.c
As per Ayamura Kikuchi, on some UNIXes, such as IRIX, "sa_len" is
[libpcap] / inet.c
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[] =
37 "@(#) $Header: /tcpdump/master/libpcap/inet.c,v 1.53 2002-11-13 06:46:16 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 #include <sys/file.h>
50 #include <sys/ioctl.h>
51 #include <sys/socket.h>
52 #ifdef HAVE_SYS_SOCKIO_H
53 #include <sys/sockio.h>
54 #endif
55 #include <sys/time.h> /* concession to AIX */
56
57 struct mbuf; /* Squelch compiler warnings on some platforms for */
58 struct rtentry; /* declarations in <net/if.h> */
59 #include <net/if.h>
60 #include <netinet/in.h>
61 #endif /* WIN32 */
62
63 #include <ctype.h>
64 #include <errno.h>
65 #include <memory.h>
66 #include <stdio.h>
67 #include <stdlib.h>
68 #include <string.h>
69 #ifndef WIN32
70 #include <unistd.h>
71 #endif /* WIN32 */
72 #ifdef HAVE_LIMITS_H
73 #include <limits.h>
74 #else
75 #define INT_MAX 2147483647
76 #endif
77 #ifdef HAVE_IFADDRS_H
78 #include <ifaddrs.h>
79 #endif
80
81 #include "pcap-int.h"
82
83 #ifdef HAVE_OS_PROTO_H
84 #include "os-proto.h"
85 #endif
86
87 /* Not all systems have IFF_LOOPBACK */
88 #ifdef IFF_LOOPBACK
89 #define ISLOOPBACK(name, flags) ((flags) & IFF_LOOPBACK)
90 #else
91 #define ISLOOPBACK(name, flags) ((name)[0] == 'l' && (name)[1] == 'o' && \
92 (isdigit((unsigned char)((name)[2])) || (name)[2] == '\0'))
93 #endif
94
95 struct sockaddr *
96 dup_sockaddr(struct sockaddr *sa, size_t sa_length)
97 {
98 struct sockaddr *newsa;
99
100 if ((newsa = malloc(sa_length)) == NULL)
101 return (NULL);
102 return (memcpy(newsa, sa, sa_length));
103 }
104
105 static int
106 get_instance(char *name)
107 {
108 char *cp, *endcp;
109 int n;
110
111 if (strcmp(name, "any") == 0) {
112 /*
113 * Give the "any" device an artificially high instance
114 * number, so it shows up after all other non-loopback
115 * interfaces.
116 */
117 return INT_MAX;
118 }
119
120 endcp = name + strlen(name);
121 for (cp = name; cp < endcp && !isdigit((unsigned char)*cp); ++cp)
122 continue;
123
124 if (isdigit((unsigned char)*cp))
125 n = atoi(cp);
126 else
127 n = 0;
128 return (n);
129 }
130
131 int
132 add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, char *name,
133 u_int flags, const char *description, char *errbuf)
134 {
135 pcap_t *p;
136 pcap_if_t *curdev, *prevdev, *nextdev;
137 int this_instance;
138
139 /*
140 * Can we open this interface for live capture?
141 */
142 p = pcap_open_live(name, 68, 0, 0, errbuf);
143 if (p == NULL) {
144 /*
145 * No. Don't bother including it.
146 * Don't treat this as an error, though.
147 */
148 *curdev_ret = NULL;
149 return (0);
150 }
151 pcap_close(p);
152
153 /*
154 * Is there already an entry in the list for this interface?
155 */
156 for (curdev = *alldevs; curdev != NULL; curdev = curdev->next) {
157 if (strcmp(name, curdev->name) == 0)
158 break; /* yes, we found it */
159 }
160 if (curdev == NULL) {
161 /*
162 * No, we didn't find it.
163 * Allocate a new entry.
164 */
165 curdev = malloc(sizeof(pcap_if_t));
166 if (curdev == NULL) {
167 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
168 "malloc: %s", pcap_strerror(errno));
169 return (-1);
170 }
171
172 /*
173 * Fill in the entry.
174 */
175 curdev->next = NULL;
176 curdev->name = malloc(strlen(name) + 1);
177 strcpy(curdev->name, name);
178 if (description != NULL) {
179 /*
180 * We have a description for this interface.
181 */
182 curdev->description = malloc(strlen(description) + 1);
183 strcpy(curdev->description, description);
184 } else {
185 /*
186 * We don't.
187 */
188 curdev->description = NULL;
189 }
190 curdev->addresses = NULL; /* list starts out as empty */
191 curdev->flags = 0;
192 if (ISLOOPBACK(name, flags))
193 curdev->flags |= PCAP_IF_LOOPBACK;
194
195 /*
196 * Add it to the list, in the appropriate location.
197 * First, get the instance number of this interface.
198 */
199 this_instance = get_instance(name);
200
201 /*
202 * Now look for the last interface with an instance number
203 * less than or equal to the new interface's instance
204 * number - except that non-loopback interfaces are
205 * arbitrarily treated as having interface numbers less
206 * than those of loopback interfaces, so the loopback
207 * interfaces are put at the end of the list.
208 *
209 * We start with "prevdev" being NULL, meaning we're before
210 * the first element in the list.
211 */
212 prevdev = NULL;
213 for (;;) {
214 /*
215 * Get the interface after this one.
216 */
217 if (prevdev == NULL) {
218 /*
219 * The next element is the first element.
220 */
221 nextdev = *alldevs;
222 } else
223 nextdev = prevdev->next;
224
225 /*
226 * Are we at the end of the list?
227 */
228 if (nextdev == NULL) {
229 /*
230 * Yes - we have to put the new entry
231 * after "prevdev".
232 */
233 break;
234 }
235
236 /*
237 * Is the new interface a non-loopback interface
238 * and the next interface a loopback interface?
239 */
240 if (!(curdev->flags & PCAP_IF_LOOPBACK) &&
241 (nextdev->flags & PCAP_IF_LOOPBACK)) {
242 /*
243 * Yes, we should put the new entry
244 * before "nextdev", i.e. after "prevdev".
245 */
246 break;
247 }
248
249 /*
250 * Is the new interface's instance number less
251 * than the next interface's instance number,
252 * and is it the case that the new interface is a
253 * non-loopback interface or the next interface is
254 * a loopback interface?
255 *
256 * (The goal of both loopback tests is to make
257 * sure that we never put a loopback interface
258 * before any non-loopback interface and that we
259 * always put a non-loopback interface before all
260 * loopback interfaces.)
261 */
262 if (this_instance < get_instance(nextdev->name) &&
263 (!(curdev->flags & PCAP_IF_LOOPBACK) ||
264 (nextdev->flags & PCAP_IF_LOOPBACK))) {
265 /*
266 * Yes - we should put the new entry
267 * before "nextdev", i.e. after "prevdev".
268 */
269 break;
270 }
271
272 prevdev = nextdev;
273 }
274
275 /*
276 * Insert before "nextdev".
277 */
278 curdev->next = nextdev;
279
280 /*
281 * Insert after "prevdev" - unless "prevdev" is null,
282 * in which case this is the first interface.
283 */
284 if (prevdev == NULL) {
285 /*
286 * This is the first interface. Pass back a
287 * pointer to it, and put "curdev" before
288 * "nextdev".
289 */
290 *alldevs = curdev;
291 } else
292 prevdev->next = curdev;
293 }
294
295 *curdev_ret = curdev;
296 return (0);
297 }
298
299 int
300 add_addr_to_iflist(pcap_if_t **alldevs, char *name, u_int flags,
301 struct sockaddr *addr, size_t addr_size,
302 struct sockaddr *netmask, size_t netmask_size,
303 struct sockaddr *broadaddr, size_t broadaddr_size,
304 struct sockaddr *dstaddr, size_t dstaddr_size,
305 char *errbuf)
306 {
307 pcap_if_t *curdev;
308 pcap_addr_t *curaddr, *prevaddr, *nextaddr;
309
310 if (add_or_find_if(&curdev, alldevs, name, flags, NULL, errbuf) == -1) {
311 /*
312 * Error - give up.
313 */
314 return (-1);
315 }
316 if (curdev == NULL) {
317 /*
318 * Device wasn't added because it can't be opened.
319 * Not a fatal error.
320 */
321 return (0);
322 }
323
324 /*
325 * "curdev" is an entry for this interface; add an entry for this
326 * address to its list of addresses.
327 *
328 * Allocate the new entry and fill it in.
329 */
330 curaddr = malloc(sizeof(pcap_addr_t));
331 if (curaddr == NULL) {
332 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
333 "malloc: %s", pcap_strerror(errno));
334 return (-1);
335 }
336
337 curaddr->next = NULL;
338 if (addr != NULL) {
339 curaddr->addr = dup_sockaddr(addr, addr_size);
340 if (curaddr->addr == NULL) {
341 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
342 "malloc: %s", pcap_strerror(errno));
343 free(curaddr);
344 return (-1);
345 }
346 } else
347 curaddr->addr = NULL;
348
349 if (netmask != NULL) {
350 curaddr->netmask = dup_sockaddr(netmask, netmask_size);
351 if (curaddr->netmask == NULL) {
352 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
353 "malloc: %s", pcap_strerror(errno));
354 free(curaddr);
355 return (-1);
356 }
357 } else
358 curaddr->netmask = NULL;
359
360 if (broadaddr != NULL) {
361 curaddr->broadaddr = dup_sockaddr(broadaddr, broadaddr_size);
362 if (curaddr->broadaddr == NULL) {
363 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
364 "malloc: %s", pcap_strerror(errno));
365 free(curaddr);
366 return (-1);
367 }
368 } else
369 curaddr->broadaddr = NULL;
370
371 if (dstaddr != NULL) {
372 curaddr->dstaddr = dup_sockaddr(dstaddr, dstaddr_size);
373 if (curaddr->dstaddr == NULL) {
374 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
375 "malloc: %s", pcap_strerror(errno));
376 free(curaddr);
377 return (-1);
378 }
379 } else
380 curaddr->dstaddr = NULL;
381
382 /*
383 * Find the end of the list of addresses.
384 */
385 for (prevaddr = curdev->addresses; prevaddr != NULL; prevaddr = nextaddr) {
386 nextaddr = prevaddr->next;
387 if (nextaddr == NULL) {
388 /*
389 * This is the end of the list.
390 */
391 break;
392 }
393 }
394
395 if (prevaddr == NULL) {
396 /*
397 * The list was empty; this is the first member.
398 */
399 curdev->addresses = curaddr;
400 } else {
401 /*
402 * "prevaddr" is the last member of the list; append
403 * this member to it.
404 */
405 prevaddr->next = curaddr;
406 }
407
408 return (0);
409 }
410
411 int
412 pcap_add_if(pcap_if_t **devlist, char *name, u_int flags,
413 const char *description, char *errbuf)
414 {
415 pcap_if_t *curdev;
416
417 return (add_or_find_if(&curdev, devlist, name, flags, description,
418 errbuf));
419 }
420
421
422 /*
423 * Free a list of interfaces.
424 */
425 void
426 pcap_freealldevs(pcap_if_t *alldevs)
427 {
428 pcap_if_t *curdev, *nextdev;
429 pcap_addr_t *curaddr, *nextaddr;
430
431 for (curdev = alldevs; curdev != NULL; curdev = nextdev) {
432 nextdev = curdev->next;
433
434 /*
435 * Free all addresses.
436 */
437 for (curaddr = curdev->addresses; curaddr != NULL; curaddr = nextaddr) {
438 nextaddr = curaddr->next;
439 if (curaddr->addr)
440 free(curaddr->addr);
441 if (curaddr->netmask)
442 free(curaddr->netmask);
443 if (curaddr->broadaddr)
444 free(curaddr->broadaddr);
445 if (curaddr->dstaddr)
446 free(curaddr->dstaddr);
447 free(curaddr);
448 }
449
450 /*
451 * Free the name string.
452 */
453 free(curdev->name);
454
455 /*
456 * Free the description string, if any.
457 */
458 if (curdev->description != NULL)
459 free(curdev->description);
460
461 /*
462 * Free the interface.
463 */
464 free(curdev);
465 }
466 }
467
468 #ifndef WIN32
469
470 /*
471 * Return the name of a network interface attached to the system, or NULL
472 * if none can be found. The interface must be configured up; the
473 * lowest unit number is preferred; loopback is ignored.
474 */
475 char *
476 pcap_lookupdev(errbuf)
477 register char *errbuf;
478 {
479 pcap_if_t *alldevs;
480 /* for old BSD systems, including bsdi3 */
481 #ifndef IF_NAMESIZE
482 #define IF_NAMESIZE IFNAMSIZ
483 #endif
484 static char device[IF_NAMESIZE + 1];
485 char *ret;
486
487 if (pcap_findalldevs(&alldevs, errbuf) == -1)
488 return (NULL);
489
490 if (alldevs == NULL || (alldevs->flags & PCAP_IF_LOOPBACK)) {
491 /*
492 * There are no devices on the list, or the first device
493 * on the list is a loopback device, which means there
494 * are no non-loopback devices on the list. This means
495 * we can't return any device.
496 *
497 * XXX - why not return a loopback device? If we can't
498 * capture on it, it won't be on the list, and if it's
499 * on the list, there aren't any non-loopback devices,
500 * so why not just supply it as the default device?
501 */
502 (void)strlcpy(errbuf, "no suitable device found",
503 PCAP_ERRBUF_SIZE);
504 ret = NULL;
505 } else {
506 /*
507 * Return the name of the first device on the list.
508 */
509 (void)strlcpy(device, alldevs->name, sizeof(device));
510 ret = device;
511 }
512
513 pcap_freealldevs(alldevs);
514 return (ret);
515 }
516
517 int
518 pcap_lookupnet(device, netp, maskp, errbuf)
519 register char *device;
520 register bpf_u_int32 *netp, *maskp;
521 register char *errbuf;
522 {
523 register int fd;
524 register struct sockaddr_in *sin;
525 struct ifreq ifr;
526
527 /*
528 * The pseudo-device "any" listens on all interfaces and therefore
529 * has the network address and -mask "0.0.0.0" therefore catching
530 * all traffic. Using NULL for the interface is the same as "any".
531 */
532 if (!device || strcmp(device, "any") == 0) {
533 *netp = *maskp = 0;
534 return 0;
535 }
536
537 fd = socket(AF_INET, SOCK_DGRAM, 0);
538 if (fd < 0) {
539 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "socket: %s",
540 pcap_strerror(errno));
541 return (-1);
542 }
543 memset(&ifr, 0, sizeof(ifr));
544 #ifdef linux
545 /* XXX Work around Linux kernel bug */
546 ifr.ifr_addr.sa_family = AF_INET;
547 #endif
548 (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
549 if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) {
550 if (errno == EADDRNOTAVAIL) {
551 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
552 "%s: no IPv4 address assigned", device);
553 } else {
554 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
555 "SIOCGIFADDR: %s: %s",
556 device, pcap_strerror(errno));
557 }
558 (void)close(fd);
559 return (-1);
560 }
561 sin = (struct sockaddr_in *)&ifr.ifr_addr;
562 *netp = sin->sin_addr.s_addr;
563 if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifr) < 0) {
564 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
565 "SIOCGIFNETMASK: %s: %s", device, pcap_strerror(errno));
566 (void)close(fd);
567 return (-1);
568 }
569 (void)close(fd);
570 *maskp = sin->sin_addr.s_addr;
571 if (*maskp == 0) {
572 if (IN_CLASSA(*netp))
573 *maskp = IN_CLASSA_NET;
574 else if (IN_CLASSB(*netp))
575 *maskp = IN_CLASSB_NET;
576 else if (IN_CLASSC(*netp))
577 *maskp = IN_CLASSC_NET;
578 else {
579 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
580 "inet class for 0x%x unknown", *netp);
581 return (-1);
582 }
583 }
584 *netp &= *maskp;
585 return (0);
586 }
587
588 #else /* WIN32 */
589
590 /*
591 * Return the name of a network interface attached to the system, or NULL
592 * if none can be found. The interface must be configured up; the
593 * lowest unit number is preferred; loopback is ignored.
594 */
595 char *
596 pcap_lookupdev(errbuf)
597 register char *errbuf;
598 {
599 DWORD dwVersion;
600 DWORD dwWindowsMajorVersion;
601 dwVersion = GetVersion(); /* get the OS version */
602 dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
603
604 if (dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4) {
605 /*
606 * Windows 95, 98, ME.
607 */
608 ULONG NameLength = 8192;
609 static char AdaptersName[8192];
610
611 PacketGetAdapterNames(AdaptersName,&NameLength);
612
613 return (AdaptersName);
614 } else {
615 /*
616 * Windows NT (NT 4.0, W2K, WXP).
617 */
618 ULONG NameLength = 8192;
619 static WCHAR AdaptersName[8192];
620
621 PacketGetAdapterNames((PTSTR)AdaptersName,&NameLength);
622
623 return (char *)(AdaptersName);
624 }
625 }
626
627
628 int
629 pcap_lookupnet(device, netp, maskp, errbuf)
630 register char *device;
631 register bpf_u_int32 *netp, *maskp;
632 register char *errbuf;
633 {
634 /*
635 * We need only the first address, so we allocate a single
636 * npf_if_addr structure and we set if_addr_size to 1.
637 */
638 npf_if_addr if_addrs;
639 LONG if_addr_size = 1;
640 struct sockaddr_in *t_addr;
641
642 if (!PacketGetNetInfoEx((void *)device, &if_addrs, &if_addr_size)) {
643 *netp = *maskp = 0;
644 return (0);
645 }
646
647 t_addr = (struct sockaddr_in *) &(if_addrs.IPAddress);
648 *netp = t_addr->sin_addr.S_un.S_addr;
649 t_addr = (struct sockaddr_in *) &(if_addrs.SubnetMask);
650 *maskp = t_addr->sin_addr.S_un.S_addr;
651
652 /*
653 * XXX - will we ever get back a 0 netmask?
654 * If so, we should presumably make the "if (*maskp == 0)" code
655 * above common, rather than non-Win32-specific.
656 */
657
658 *netp &= *maskp;
659 return (0);
660 }
661
662 #endif /* WIN32 */