1478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
2478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
3478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Copyright (c) 1994, 1995, 1996, 1997, 1998
4478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *	The Regents of the University of California.  All rights reserved.
5478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
6478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Redistribution and use in source and binary forms, with or without
7478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * modification, are permitted provided that the following conditions
8478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * are met:
9478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
10478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
11478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
12478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
13478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *    documentation and/or other materials provided with the distribution.
14478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 3. All advertising materials mentioning features or use of this software
15478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *    must display the following acknowledgement:
16478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *	This product includes software developed by the Computer Systems
17478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *	Engineering Group at Lawrence Berkeley Laboratory.
18478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 4. Neither the name of the University nor of the Laboratory may be used
19478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *    to endorse or promote products derived from this software without
20478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *    specific prior written permission.
21478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
22478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * SUCH DAMAGE.
33478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
34478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
35478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef lint
36478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic const char rcsid[] _U_ =
37511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall    "@(#) $Header: /tcpdump/master/libpcap/fad-glifc.c,v 1.7 2008-01-30 09:35:48 guy Exp $ (LBL)";
38478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
39478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
40478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_CONFIG_H
41478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "config.h"
42478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
43478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
44478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/param.h>
45478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/file.h>
46478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/ioctl.h>
47478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/socket.h>
48478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_SYS_SOCKIO_H
49478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/sockio.h>
50478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
51478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/time.h>				/* concession to AIX */
52478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
53478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct mbuf;		/* Squelch compiler warnings on some platforms for */
54478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct rtentry;		/* declarations in <net/if.h> */
55478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <net/if.h>
56478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/in.h>
57478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
58478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <ctype.h>
59478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <errno.h>
60478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <memory.h>
61478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <stdio.h>
62478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <stdlib.h>
63478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <string.h>
64478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <unistd.h>
65478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
66478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "pcap-int.h"
67478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
68478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_OS_PROTO_H
69478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "os-proto.h"
70478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
71478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
72478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
73478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Get a list of all interfaces that are up and that we can open.
74478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Returns -1 on error, 0 otherwise.
75478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * The list, as returned through "alldevsp", may be null if no interfaces
76478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * were up and could be opened.
77478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
78511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * This is the implementation used on platforms that have SIOCGLIFCONF
79478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * but don't have "getifaddrs()".  (Solaris 8 and later; we use
80511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * SIOCGLIFCONF rather than SIOCGIFCONF in order to get IPv6 addresses.)
81478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
82478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectint
83511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallpcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
84478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
85478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	pcap_if_t *devlist = NULL;
86478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register int fd4, fd6, fd;
87478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register struct lifreq *ifrp, *ifend;
88478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct lifnum ifn;
89478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct lifconf ifc;
90478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	char *buf = NULL;
91478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	unsigned buf_size;
92478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_SOLARIS
93478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	char *p, *q;
94478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
95478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct lifreq ifrflags, ifrnetmask, ifrbroadaddr, ifrdstaddr;
96478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct sockaddr *netmask, *broadaddr, *dstaddr;
97478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int ret = 0;
98478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
99478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
100478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * Create a socket from which to fetch the list of interfaces,
101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * and from which to fetch IPv4 information.
102478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
103478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	fd4 = socket(AF_INET, SOCK_DGRAM, 0);
104478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (fd4 < 0) {
105478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
106478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    "socket: %s", pcap_strerror(errno));
107478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return (-1);
108478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
109478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
110478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
111478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * Create a socket from which to fetch IPv6 information.
112478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
113478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	fd6 = socket(AF_INET6, SOCK_DGRAM, 0);
114478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (fd6 < 0) {
115478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
116478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    "socket: %s", pcap_strerror(errno));
117478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		(void)close(fd4);
118478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return (-1);
119478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
120478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
121478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
122478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * How many entries will SIOCGLIFCONF return?
123478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
124478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	ifn.lifn_family = AF_UNSPEC;
125478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	ifn.lifn_flags = 0;
126478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	ifn.lifn_count = 0;
127478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (ioctl(fd4, SIOCGLIFNUM, (char *)&ifn) < 0) {
128478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
129478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    "SIOCGLIFNUM: %s", pcap_strerror(errno));
130478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		(void)close(fd6);
131478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		(void)close(fd4);
132478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return (-1);
133478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
134478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
135478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
136478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * Allocate a buffer for those entries.
137478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
138478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	buf_size = ifn.lifn_count * sizeof (struct lifreq);
139478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	buf = malloc(buf_size);
140478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (buf == NULL) {
141478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
142478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    "malloc: %s", pcap_strerror(errno));
143478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		(void)close(fd6);
144478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		(void)close(fd4);
145478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return (-1);
146478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
148478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
149478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * Get the entries.
150478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
151478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	ifc.lifc_len = buf_size;
152478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	ifc.lifc_buf = buf;
153478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	ifc.lifc_family = AF_UNSPEC;
154478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	ifc.lifc_flags = 0;
155478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	memset(buf, 0, buf_size);
156478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (ioctl(fd4, SIOCGLIFCONF, (char *)&ifc) < 0) {
157478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
158478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    "SIOCGLIFCONF: %s", pcap_strerror(errno));
159478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		(void)close(fd6);
160478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		(void)close(fd4);
161478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		free(buf);
162478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return (-1);
163478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
164478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
165478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
166478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * Loop over the entries.
167478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
168478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	ifrp = (struct lifreq *)buf;
169478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	ifend = (struct lifreq *)(buf + ifc.lifc_len);
170478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
171478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	for (; ifrp < ifend; ifrp++) {
172478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
173478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * IPv6 or not?
174478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
175478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (((struct sockaddr *)&ifrp->lifr_addr)->sa_family == AF_INET6)
176478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			fd = fd6;
177478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		else
178478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			fd = fd4;
179478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
180478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
181478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Skip entries that begin with "dummy".
182478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * XXX - what are these?  Is this Linux-specific?
183478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Are there platforms on which we shouldn't do this?
184478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
185478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (strncmp(ifrp->lifr_name, "dummy", 5) == 0)
186478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			continue;
187478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
188478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_SOLARIS
189478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
190478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Skip entries that have a ":" followed by a number
191478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * at the end - those are Solaris virtual interfaces
192478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * on which you can't capture.
193478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
194478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p = strchr(ifrp->lifr_name, ':');
195478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (p != NULL) {
196478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/*
197478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * We have a ":"; is it followed by a number?
198478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 */
199478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			while (isdigit((unsigned char)*p))
200478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				p++;
201478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (*p == '\0') {
202478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				/*
203478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				 * All digits after the ":" until the end.
204478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				 */
205478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				continue;
206478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
207478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
208478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
209478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
210478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
211478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Get the flags for this interface, and skip it if it's
212478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * not up.
213478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
214478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		strncpy(ifrflags.lifr_name, ifrp->lifr_name,
215478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    sizeof(ifrflags.lifr_name));
216478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (ioctl(fd, SIOCGLIFFLAGS, (char *)&ifrflags) < 0) {
217478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (errno == ENXIO)
218478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				continue;
219478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
220478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			    "SIOCGLIFFLAGS: %.*s: %s",
221478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			    (int)sizeof(ifrflags.lifr_name),
222478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			    ifrflags.lifr_name,
223478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			    pcap_strerror(errno));
224478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			ret = -1;
225478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			break;
226478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
227478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (!(ifrflags.lifr_flags & IFF_UP))
228478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			continue;
229478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
230478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
231478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Get the netmask for this address on this interface.
232478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
233478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		strncpy(ifrnetmask.lifr_name, ifrp->lifr_name,
234478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    sizeof(ifrnetmask.lifr_name));
235478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		memcpy(&ifrnetmask.lifr_addr, &ifrp->lifr_addr,
236478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    sizeof(ifrnetmask.lifr_addr));
237478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (ioctl(fd, SIOCGLIFNETMASK, (char *)&ifrnetmask) < 0) {
238478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (errno == EADDRNOTAVAIL) {
239478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				/*
240478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				 * Not available.
241478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				 */
242478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				netmask = NULL;
243478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			} else {
244478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
245478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				    "SIOCGLIFNETMASK: %.*s: %s",
246478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				    (int)sizeof(ifrnetmask.lifr_name),
247478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				    ifrnetmask.lifr_name,
248478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				    pcap_strerror(errno));
249478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				ret = -1;
250478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				break;
251478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
252478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		} else
253478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			netmask = (struct sockaddr *)&ifrnetmask.lifr_addr;
254478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
255478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
256478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Get the broadcast address for this address on this
257478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * interface (if any).
258478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
259478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (ifrflags.lifr_flags & IFF_BROADCAST) {
260478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			strncpy(ifrbroadaddr.lifr_name, ifrp->lifr_name,
261478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			    sizeof(ifrbroadaddr.lifr_name));
262478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			memcpy(&ifrbroadaddr.lifr_addr, &ifrp->lifr_addr,
263478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			    sizeof(ifrbroadaddr.lifr_addr));
264478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (ioctl(fd, SIOCGLIFBRDADDR,
265478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			    (char *)&ifrbroadaddr) < 0) {
266478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				if (errno == EADDRNOTAVAIL) {
267478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					/*
268478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					 * Not available.
269478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					 */
270478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					broadaddr = NULL;
271478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				} else {
272478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
273478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					    "SIOCGLIFBRDADDR: %.*s: %s",
274478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					    (int)sizeof(ifrbroadaddr.lifr_name),
275478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					    ifrbroadaddr.lifr_name,
276478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					    pcap_strerror(errno));
277478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					ret = -1;
278478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					break;
279478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				}
280478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			} else
281478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				broadaddr = (struct sockaddr *)&ifrbroadaddr.lifr_broadaddr;
282478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		} else {
283478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/*
284478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * Not a broadcast interface, so no broadcast
285478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * address.
286478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 */
287478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			broadaddr = NULL;
288478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
289478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
290478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
291478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Get the destination address for this address on this
292478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * interface (if any).
293478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
294478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (ifrflags.lifr_flags & IFF_POINTOPOINT) {
295478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			strncpy(ifrdstaddr.lifr_name, ifrp->lifr_name,
296478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			    sizeof(ifrdstaddr.lifr_name));
297478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			memcpy(&ifrdstaddr.lifr_addr, &ifrp->lifr_addr,
298478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			    sizeof(ifrdstaddr.lifr_addr));
299478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (ioctl(fd, SIOCGLIFDSTADDR,
300478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			    (char *)&ifrdstaddr) < 0) {
301478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				if (errno == EADDRNOTAVAIL) {
302478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					/*
303478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					 * Not available.
304478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					 */
305478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					dstaddr = NULL;
306478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				} else {
307478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
308478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					    "SIOCGLIFDSTADDR: %.*s: %s",
309478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					    (int)sizeof(ifrdstaddr.lifr_name),
310478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					    ifrdstaddr.lifr_name,
311478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					    pcap_strerror(errno));
312478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					ret = -1;
313478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					break;
314478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				}
315478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			} else
316478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				dstaddr = (struct sockaddr *)&ifrdstaddr.lifr_dstaddr;
317478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		} else
318478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			dstaddr = NULL;
319478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
320478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_SOLARIS
321478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
322478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * If this entry has a colon followed by a number at
323478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * the end, it's a logical interface.  Those are just
324478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * the way you assign multiple IP addresses to a real
325478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * interface, so an entry for a logical interface should
326478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * be treated like the entry for the real interface;
327478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * we do that by stripping off the ":" and the number.
328478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
329478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p = strchr(ifrp->lifr_name, ':');
330478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (p != NULL) {
331478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/*
332478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * We have a ":"; is it followed by a number?
333478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 */
334478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			q = p + 1;
335478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			while (isdigit((unsigned char)*q))
336478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				q++;
337478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (*q == '\0') {
338478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				/*
339478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				 * All digits after the ":" until the end.
340478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				 * Strip off the ":" and everything after
341478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				 * it.
342478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				 */
343478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				*p = '\0';
344478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
345478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
346478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
347478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
348478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
349478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Add information for this address to the list.
350478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
351478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (add_addr_to_iflist(&devlist, ifrp->lifr_name,
352478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    ifrflags.lifr_flags, (struct sockaddr *)&ifrp->lifr_addr,
353478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    sizeof (struct sockaddr_storage),
354478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    netmask, sizeof (struct sockaddr_storage),
355478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    broadaddr, sizeof (struct sockaddr_storage),
356478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    dstaddr, sizeof (struct sockaddr_storage), errbuf) < 0) {
357478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			ret = -1;
358478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			break;
359478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
360478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
361478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	free(buf);
362478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	(void)close(fd6);
363478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	(void)close(fd4);
364478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
365478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (ret == -1) {
366478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
367478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * We had an error; free the list we've been constructing.
368478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
369478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (devlist != NULL) {
370478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			pcap_freealldevs(devlist);
371478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			devlist = NULL;
372478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
373478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
374478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
375478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	*alldevsp = devlist;
376478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return (ret);
377478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
378