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 #include <sys/types.h>
36 #include <sys/socket.h>
37 #include <netinet/in.h>
38
39 #include <net/if.h>
40
41 #include <ctype.h>
42 #include <errno.h>
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <ifaddrs.h>
47 #include <limits.h>
48
49 #include "pcap-int.h"
50
51 static struct sockaddr *
dup_sockaddr(struct sockaddr * sa,size_t sa_length)52 dup_sockaddr(struct sockaddr *sa, size_t sa_length)
53 {
54 struct sockaddr *newsa;
55
56 if ((newsa = malloc(sa_length)) == NULL)
57 return (NULL);
58 return (memcpy(newsa, sa, sa_length));
59 }
60
61 static int
get_instance(const char * name)62 get_instance(const char *name)
63 {
64 const char *cp, *endcp, *errstr;
65 int n;
66
67 if (strcmp(name, "any") == 0) {
68 /*
69 * Give the "any" device an artificially high instance
70 * number, so it shows up after all other non-loopback
71 * interfaces.
72 */
73 return INT_MAX;
74 }
75
76 endcp = name + strlen(name);
77 for (cp = name; cp < endcp && !isdigit((unsigned char)*cp); ++cp)
78 continue;
79
80 n = strtonum(cp, 0, INT_MAX, &errstr);
81 if (errstr != NULL)
82 return -1;
83 return n;
84 }
85
86 static int
add_or_find_if(pcap_if_t ** curdev_ret,pcap_if_t ** alldevs,const char * name,u_int flags,const char * description,char * errbuf)87 add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, const char *name,
88 u_int flags, const char *description, char *errbuf)
89 {
90 pcap_t *p;
91 pcap_if_t *curdev, *prevdev, *nextdev;
92 int this_instance;
93 size_t len;
94
95 /*
96 * Can we open this interface for live capture?
97 *
98 * We do this check so that interfaces that are supplied
99 * by the interface enumeration mechanism we're using
100 * but that don't support packet capture aren't included
101 * in the list. An example of this is loopback interfaces
102 * on Solaris; we don't just omit loopback interfaces
103 * because you *can* capture on loopback interfaces on some
104 * OSes.
105 */
106 p = pcap_open_live(name, 68, 0, 0, errbuf);
107 if (p == NULL) {
108 /*
109 * No. Don't bother including it.
110 * Don't treat this as an error, though.
111 */
112 *curdev_ret = NULL;
113 return (0);
114 }
115 pcap_close(p);
116
117 /*
118 * Is there already an entry in the list for this interface?
119 */
120 for (curdev = *alldevs; curdev != NULL; curdev = curdev->next) {
121 if (strcmp(name, curdev->name) == 0)
122 break; /* yes, we found it */
123 }
124 if (curdev == NULL) {
125 /*
126 * No, we didn't find it.
127 * Allocate a new entry.
128 */
129 curdev = calloc(1, sizeof(pcap_if_t));
130 if (curdev == NULL) {
131 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
132 "calloc: %s", pcap_strerror(errno));
133 goto fail;
134 }
135
136 /*
137 * Fill in the entry.
138 */
139 curdev->next = NULL;
140 len = strlen(name) + 1;
141 curdev->name = malloc(len);
142 if (curdev->name == NULL) {
143 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
144 "malloc: %s", pcap_strerror(errno));
145 goto fail;
146 }
147 strlcpy(curdev->name, name, len);
148 if (description != NULL) {
149 /*
150 * We have a description for this interface.
151 */
152 len = strlen(description) + 1;
153 curdev->description = malloc(len);
154 if (curdev->description == NULL) {
155 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
156 "malloc: %s", pcap_strerror(errno));
157 goto fail;
158 }
159 strlcpy(curdev->description, description, len);
160 }
161 curdev->addresses = NULL; /* list starts out as empty */
162 curdev->flags = 0;
163 if (ISLOOPBACK(name, flags))
164 curdev->flags |= PCAP_IF_LOOPBACK;
165
166 /*
167 * Add it to the list, in the appropriate location.
168 * First, get the instance number of this interface.
169 */
170 if ((this_instance = get_instance(name)) == -1) {
171 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
172 "malformed device name: %s", name);
173 goto fail;
174 }
175
176 /*
177 * Now look for the last interface with an instance number
178 * less than or equal to the new interface's instance
179 * number - except that non-loopback interfaces are
180 * arbitrarily treated as having interface numbers less
181 * than those of loopback interfaces, so the loopback
182 * interfaces are put at the end of the list.
183 *
184 * We start with "prevdev" being NULL, meaning we're before
185 * the first element in the list.
186 */
187 prevdev = NULL;
188 for (;;) {
189 /*
190 * Get the interface after this one.
191 */
192 if (prevdev == NULL) {
193 /*
194 * The next element is the first element.
195 */
196 nextdev = *alldevs;
197 } else
198 nextdev = prevdev->next;
199
200 /*
201 * Are we at the end of the list?
202 */
203 if (nextdev == NULL) {
204 /*
205 * Yes - we have to put the new entry
206 * after "prevdev".
207 */
208 break;
209 }
210
211 /*
212 * Is the new interface a non-loopback interface
213 * and the next interface a loopback interface?
214 */
215 if (!(curdev->flags & PCAP_IF_LOOPBACK) &&
216 (nextdev->flags & PCAP_IF_LOOPBACK)) {
217 /*
218 * Yes, we should put the new entry
219 * before "nextdev", i.e. after "prevdev".
220 */
221 break;
222 }
223
224 /*
225 * Is the new interface's instance number less
226 * than the next interface's instance number,
227 * and is it the case that the new interface is a
228 * non-loopback interface or the next interface is
229 * a loopback interface?
230 *
231 * (The goal of both loopback tests is to make
232 * sure that we never put a loopback interface
233 * before any non-loopback interface and that we
234 * always put a non-loopback interface before all
235 * loopback interfaces.)
236 */
237 if (this_instance < get_instance(nextdev->name) &&
238 (!(curdev->flags & PCAP_IF_LOOPBACK) ||
239 (nextdev->flags & PCAP_IF_LOOPBACK))) {
240 /*
241 * Yes - we should put the new entry
242 * before "nextdev", i.e. after "prevdev".
243 */
244 break;
245 }
246
247 prevdev = nextdev;
248 }
249
250 /*
251 * Insert before "nextdev".
252 */
253 curdev->next = nextdev;
254
255 /*
256 * Insert after "prevdev" - unless "prevdev" is null,
257 * in which case this is the first interface.
258 */
259 if (prevdev == NULL) {
260 /*
261 * This is the first interface. Pass back a
262 * pointer to it, and put "curdev" before
263 * "nextdev".
264 */
265 *alldevs = curdev;
266 } else
267 prevdev->next = curdev;
268 }
269
270 *curdev_ret = curdev;
271 return (0);
272
273 fail:
274 if (curdev != NULL) {
275 free(curdev->name);
276 free(curdev->description);
277 free(curdev);
278 }
279 return (-1);
280 }
281
282 static int
add_addr_to_iflist(pcap_if_t ** alldevs,const char * name,u_int flags,struct sockaddr * addr,size_t addr_size,struct sockaddr * netmask,size_t netmask_size,struct sockaddr * broadaddr,size_t broadaddr_size,struct sockaddr * dstaddr,size_t dstaddr_size,char * errbuf)283 add_addr_to_iflist(pcap_if_t **alldevs, const char *name, u_int flags,
284 struct sockaddr *addr, size_t addr_size,
285 struct sockaddr *netmask, size_t netmask_size,
286 struct sockaddr *broadaddr, size_t broadaddr_size,
287 struct sockaddr *dstaddr, size_t dstaddr_size,
288 char *errbuf)
289 {
290 pcap_if_t *curdev;
291 pcap_addr_t *curaddr, *prevaddr, *nextaddr;
292
293 if (add_or_find_if(&curdev, alldevs, name, flags, NULL, errbuf) == -1) {
294 /*
295 * Error - give up.
296 */
297 return (-1);
298 }
299 if (curdev == NULL) {
300 /*
301 * Device wasn't added because it can't be opened.
302 * Not a fatal error.
303 */
304 return (0);
305 }
306
307 /*
308 * "curdev" is an entry for this interface; add an entry for this
309 * address to its list of addresses.
310 *
311 * Allocate the new entry and fill it in.
312 */
313 curaddr = calloc(1, sizeof(pcap_addr_t));
314 if (curaddr == NULL) {
315 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
316 "calloc: %s", pcap_strerror(errno));
317 goto fail;
318 }
319
320 curaddr->next = NULL;
321 if (addr != NULL) {
322 curaddr->addr = dup_sockaddr(addr, addr_size);
323 if (curaddr->addr == NULL) {
324 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
325 "malloc: %s", pcap_strerror(errno));
326 goto fail;
327 }
328 }
329
330 if (netmask != NULL) {
331 curaddr->netmask = dup_sockaddr(netmask, netmask_size);
332 if (curaddr->netmask == NULL) {
333 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
334 "malloc: %s", pcap_strerror(errno));
335 goto fail;
336 }
337 }
338
339 if (broadaddr != NULL) {
340 curaddr->broadaddr = dup_sockaddr(broadaddr, broadaddr_size);
341 if (curaddr->broadaddr == NULL) {
342 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
343 "malloc: %s", pcap_strerror(errno));
344 goto fail;
345 }
346 }
347
348 if (dstaddr != NULL) {
349 curaddr->dstaddr = dup_sockaddr(dstaddr, dstaddr_size);
350 if (curaddr->dstaddr == NULL) {
351 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
352 "malloc: %s", pcap_strerror(errno));
353 goto fail;
354 }
355 }
356
357 /*
358 * Find the end of the list of addresses.
359 */
360 for (prevaddr = curdev->addresses; prevaddr != NULL;
361 prevaddr = nextaddr) {
362 nextaddr = prevaddr->next;
363 if (nextaddr == NULL) {
364 /*
365 * This is the end of the list.
366 */
367 break;
368 }
369 }
370
371 if (prevaddr == NULL) {
372 /*
373 * The list was empty; this is the first member.
374 */
375 curdev->addresses = curaddr;
376 } else {
377 /*
378 * "prevaddr" is the last member of the list; append
379 * this member to it.
380 */
381 prevaddr->next = curaddr;
382 }
383
384 return (0);
385
386 fail:
387 if (curaddr != NULL) {
388 free(curaddr->addr);
389 free(curaddr->netmask);
390 free(curaddr->broadaddr);
391 free(curaddr->dstaddr);
392 free(curaddr);
393 }
394 return (-1);
395 }
396
397 /*
398 * Get a list of all interfaces that are up and that we can open.
399 * Returns -1 on error, 0 otherwise.
400 * The list, as returned through "alldevsp", may be null if no interfaces
401 * were up and could be opened.
402 *
403 * This is the implementation used on platforms that have "getifaddrs()".
404 */
405 int
pcap_findalldevs(pcap_if_t ** alldevsp,char * errbuf)406 pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
407 {
408 pcap_if_t *devlist = NULL;
409 struct ifaddrs *ifap, *ifa;
410 struct sockaddr *addr, *netmask, *broadaddr, *dstaddr;
411 size_t addr_size, broadaddr_size, dstaddr_size;
412 int ret = 0;
413
414 /*
415 * Get the list of interface addresses.
416 *
417 * Note: this won't return information about interfaces
418 * with no addresses; are there any such interfaces
419 * that would be capable of receiving packets?
420 * (Interfaces incapable of receiving packets aren't
421 * very interesting from libpcap's point of view.)
422 *
423 * LAN interfaces will probably have link-layer
424 * addresses; I don't know whether all implementations
425 * of "getifaddrs()" now, or in the future, will return
426 * those.
427 */
428 if (getifaddrs(&ifap) != 0) {
429 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
430 "getifaddrs: %s", pcap_strerror(errno));
431 return (-1);
432 }
433 for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
434 /*
435 * Is this interface up?
436 */
437 if (!(ifa->ifa_flags & IFF_UP)) {
438 /*
439 * No, so don't add it to the list.
440 */
441 continue;
442 }
443
444 /*
445 * "ifa_addr" was apparently null on at least one
446 * interface on some system.
447 *
448 * "ifa_broadaddr" may be non-null even on
449 * non-broadcast interfaces, and was null on
450 * at least one OpenBSD 3.4 system on at least
451 * one interface with IFF_BROADCAST set.
452 *
453 * "ifa_dstaddr" was, on at least one FreeBSD 4.1
454 * system, non-null on a non-point-to-point
455 * interface.
456 *
457 * Therefore, we supply the address and netmask only
458 * if "ifa_addr" is non-null (if there's no address,
459 * there's obviously no netmask), and supply the
460 * broadcast and destination addresses if the appropriate
461 * flag is set *and* the appropriate "ifa_" entry doesn't
462 * evaluate to a null pointer.
463 */
464 if (ifa->ifa_addr != NULL) {
465 addr = ifa->ifa_addr;
466 addr_size = SA_LEN(addr);
467 netmask = ifa->ifa_netmask;
468 } else {
469 addr = NULL;
470 addr_size = 0;
471 netmask = NULL;
472 }
473 if (ifa->ifa_flags & IFF_BROADCAST &&
474 ifa->ifa_broadaddr != NULL) {
475 broadaddr = ifa->ifa_broadaddr;
476 broadaddr_size = SA_LEN(broadaddr);
477 } else {
478 broadaddr = NULL;
479 broadaddr_size = 0;
480 }
481 if (ifa->ifa_flags & IFF_POINTOPOINT &&
482 ifa->ifa_dstaddr != NULL) {
483 dstaddr = ifa->ifa_dstaddr;
484 dstaddr_size = SA_LEN(ifa->ifa_dstaddr);
485 } else {
486 dstaddr = NULL;
487 dstaddr_size = 0;
488 }
489
490 /*
491 * Add information for this address to the list.
492 */
493 if (add_addr_to_iflist(&devlist, ifa->ifa_name,
494 ifa->ifa_flags, addr, addr_size, netmask, addr_size,
495 broadaddr, broadaddr_size, dstaddr, dstaddr_size,
496 errbuf) < 0) {
497 ret = -1;
498 break;
499 }
500 }
501
502 freeifaddrs(ifap);
503
504 if (ret == -1) {
505 /*
506 * We had an error; free the list we've been constructing.
507 */
508 if (devlist != NULL) {
509 pcap_freealldevs(devlist);
510 devlist = NULL;
511 }
512 }
513
514 *alldevsp = devlist;
515 return (ret);
516 }
517