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#ifdef HAVE_CONFIG_H
36478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "config.h"
37478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
38478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
39478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/param.h>
40478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/file.h>
41478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/ioctl.h>
42478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/socket.h>
43478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_SYS_SOCKIO_H
44478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/sockio.h>
45478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
46478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/time.h>				/* concession to AIX */
47478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
48478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct mbuf;		/* Squelch compiler warnings on some platforms for */
49478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct rtentry;		/* declarations in <net/if.h> */
50478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <net/if.h>
51478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/in.h>
52478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
53478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <ctype.h>
54478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <errno.h>
55478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <memory.h>
56478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <stdio.h>
57478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <stdlib.h>
58478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <string.h>
59478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <unistd.h>
60478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
61478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "pcap-int.h"
62478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
63478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_OS_PROTO_H
64478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "os-proto.h"
65478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
66478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
67478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
68478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Get a list of all interfaces that are up and that we can open.
69478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Returns -1 on error, 0 otherwise.
70478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * The list, as returned through "alldevsp", may be null if no interfaces
71478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * were up and could be opened.
72478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
73511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * This is the implementation used on platforms that have SIOCGLIFCONF
74478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * but don't have "getifaddrs()".  (Solaris 8 and later; we use
75511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrall * SIOCGLIFCONF rather than SIOCGIFCONF in order to get IPv6 addresses.)
76478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
77478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectint
78511eca30a483e912c274e1d8ba3a0f8f081e2227JP Abgrallpcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
79478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
80478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	pcap_if_t *devlist = NULL;
81478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register int fd4, fd6, fd;
82478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	register struct lifreq *ifrp, *ifend;
83478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct lifnum ifn;
84478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct lifconf ifc;
85478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	char *buf = NULL;
86478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	unsigned buf_size;
87478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_SOLARIS
88478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	char *p, *q;
89478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
90478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct lifreq ifrflags, ifrnetmask, ifrbroadaddr, ifrdstaddr;
91478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct sockaddr *netmask, *broadaddr, *dstaddr;
92478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int ret = 0;
93478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
94478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
95478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * Create a socket from which to fetch the list of interfaces,
96478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * and from which to fetch IPv4 information.
97478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
98478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	fd4 = socket(AF_INET, SOCK_DGRAM, 0);
99478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (fd4 < 0) {
100478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    "socket: %s", pcap_strerror(errno));
102478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return (-1);
103478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
104478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
105478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
106478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * Create a socket from which to fetch IPv6 information.
107478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
108478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	fd6 = socket(AF_INET6, SOCK_DGRAM, 0);
109478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (fd6 < 0) {
110478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
111478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    "socket: %s", pcap_strerror(errno));
112478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		(void)close(fd4);
113478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return (-1);
114478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
115478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
116478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
117478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * How many entries will SIOCGLIFCONF return?
118478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
119478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	ifn.lifn_family = AF_UNSPEC;
120478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	ifn.lifn_flags = 0;
121478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	ifn.lifn_count = 0;
122478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (ioctl(fd4, SIOCGLIFNUM, (char *)&ifn) < 0) {
123478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
124478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    "SIOCGLIFNUM: %s", pcap_strerror(errno));
125478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		(void)close(fd6);
126478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		(void)close(fd4);
127478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return (-1);
128478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
129478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
130478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
131478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * Allocate a buffer for those entries.
132478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
133478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	buf_size = ifn.lifn_count * sizeof (struct lifreq);
134478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	buf = malloc(buf_size);
135478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (buf == NULL) {
136478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
137478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    "malloc: %s", pcap_strerror(errno));
138478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		(void)close(fd6);
139478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		(void)close(fd4);
140478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return (-1);
141478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
142478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
143478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
144478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * Get the entries.
145478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
146478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	ifc.lifc_len = buf_size;
147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	ifc.lifc_buf = buf;
148478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	ifc.lifc_family = AF_UNSPEC;
149478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	ifc.lifc_flags = 0;
150478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	memset(buf, 0, buf_size);
151478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (ioctl(fd4, SIOCGLIFCONF, (char *)&ifc) < 0) {
152478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
153478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    "SIOCGLIFCONF: %s", pcap_strerror(errno));
154478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		(void)close(fd6);
155478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		(void)close(fd4);
156478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		free(buf);
157478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return (-1);
158478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
159478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
160478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
161478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * Loop over the entries.
162478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
163478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	ifrp = (struct lifreq *)buf;
164478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	ifend = (struct lifreq *)(buf + ifc.lifc_len);
165478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
166478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	for (; ifrp < ifend; ifrp++) {
167478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
168478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * IPv6 or not?
169478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
170478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (((struct sockaddr *)&ifrp->lifr_addr)->sa_family == AF_INET6)
171478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			fd = fd6;
172478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		else
173478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			fd = fd4;
174478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
175478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
176478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Skip entries that begin with "dummy".
177478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * XXX - what are these?  Is this Linux-specific?
178478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Are there platforms on which we shouldn't do this?
179478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
180478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (strncmp(ifrp->lifr_name, "dummy", 5) == 0)
181478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			continue;
182478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
183478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_SOLARIS
184478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
185478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Skip entries that have a ":" followed by a number
186478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * at the end - those are Solaris virtual interfaces
187478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * on which you can't capture.
188478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
189478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p = strchr(ifrp->lifr_name, ':');
190478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (p != NULL) {
191478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/*
192478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * We have a ":"; is it followed by a number?
193478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 */
194478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			while (isdigit((unsigned char)*p))
195478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				p++;
196478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (*p == '\0') {
197478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				/*
198478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				 * All digits after the ":" until the end.
199478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				 */
200478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				continue;
201478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
202478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
203478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
204478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
205478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
206d8845d7191ca81aae8aab4c29410fc8a3d012687Elliott Hughes		 * Get the flags for this interface.
207478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
208478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		strncpy(ifrflags.lifr_name, ifrp->lifr_name,
209478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    sizeof(ifrflags.lifr_name));
210478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (ioctl(fd, SIOCGLIFFLAGS, (char *)&ifrflags) < 0) {
211478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (errno == ENXIO)
212478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				continue;
213478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
214478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			    "SIOCGLIFFLAGS: %.*s: %s",
215478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			    (int)sizeof(ifrflags.lifr_name),
216478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			    ifrflags.lifr_name,
217478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			    pcap_strerror(errno));
218478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			ret = -1;
219478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			break;
220478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
221478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
222478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
223478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Get the netmask for this address on this interface.
224478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
225478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		strncpy(ifrnetmask.lifr_name, ifrp->lifr_name,
226478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    sizeof(ifrnetmask.lifr_name));
227478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		memcpy(&ifrnetmask.lifr_addr, &ifrp->lifr_addr,
228478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    sizeof(ifrnetmask.lifr_addr));
229478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (ioctl(fd, SIOCGLIFNETMASK, (char *)&ifrnetmask) < 0) {
230478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (errno == EADDRNOTAVAIL) {
231478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				/*
232478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				 * Not available.
233478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				 */
234478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				netmask = NULL;
235478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			} else {
236478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
237478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				    "SIOCGLIFNETMASK: %.*s: %s",
238478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				    (int)sizeof(ifrnetmask.lifr_name),
239478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				    ifrnetmask.lifr_name,
240478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				    pcap_strerror(errno));
241478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				ret = -1;
242478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				break;
243478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
244478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		} else
245478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			netmask = (struct sockaddr *)&ifrnetmask.lifr_addr;
246478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
247478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
248478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Get the broadcast address for this address on this
249478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * interface (if any).
250478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
251478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (ifrflags.lifr_flags & IFF_BROADCAST) {
252478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			strncpy(ifrbroadaddr.lifr_name, ifrp->lifr_name,
253478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			    sizeof(ifrbroadaddr.lifr_name));
254478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			memcpy(&ifrbroadaddr.lifr_addr, &ifrp->lifr_addr,
255478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			    sizeof(ifrbroadaddr.lifr_addr));
256478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (ioctl(fd, SIOCGLIFBRDADDR,
257478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			    (char *)&ifrbroadaddr) < 0) {
258478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				if (errno == EADDRNOTAVAIL) {
259478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					/*
260478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					 * Not available.
261478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					 */
262478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					broadaddr = NULL;
263478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				} else {
264478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
265478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					    "SIOCGLIFBRDADDR: %.*s: %s",
266478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					    (int)sizeof(ifrbroadaddr.lifr_name),
267478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					    ifrbroadaddr.lifr_name,
268478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					    pcap_strerror(errno));
269478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					ret = -1;
270478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					break;
271478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				}
272478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			} else
273478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				broadaddr = (struct sockaddr *)&ifrbroadaddr.lifr_broadaddr;
274478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		} else {
275478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/*
276478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * Not a broadcast interface, so no broadcast
277478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * address.
278478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 */
279478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			broadaddr = NULL;
280478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
281478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
282478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
283478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Get the destination address for this address on this
284478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * interface (if any).
285478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
286478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (ifrflags.lifr_flags & IFF_POINTOPOINT) {
287478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			strncpy(ifrdstaddr.lifr_name, ifrp->lifr_name,
288478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			    sizeof(ifrdstaddr.lifr_name));
289478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			memcpy(&ifrdstaddr.lifr_addr, &ifrp->lifr_addr,
290478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			    sizeof(ifrdstaddr.lifr_addr));
291478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (ioctl(fd, SIOCGLIFDSTADDR,
292478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			    (char *)&ifrdstaddr) < 0) {
293478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				if (errno == EADDRNOTAVAIL) {
294478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					/*
295478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					 * Not available.
296478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					 */
297478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					dstaddr = NULL;
298478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				} else {
299478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					(void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
300478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					    "SIOCGLIFDSTADDR: %.*s: %s",
301478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					    (int)sizeof(ifrdstaddr.lifr_name),
302478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					    ifrdstaddr.lifr_name,
303478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					    pcap_strerror(errno));
304478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					ret = -1;
305478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					break;
306478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				}
307478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			} else
308478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				dstaddr = (struct sockaddr *)&ifrdstaddr.lifr_dstaddr;
309478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		} else
310478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			dstaddr = NULL;
311478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
312478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_SOLARIS
313478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
314478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * If this entry has a colon followed by a number at
315478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * the end, it's a logical interface.  Those are just
316478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * the way you assign multiple IP addresses to a real
317478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * interface, so an entry for a logical interface should
318478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * be treated like the entry for the real interface;
319478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * we do that by stripping off the ":" and the number.
320478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
321478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p = strchr(ifrp->lifr_name, ':');
322478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (p != NULL) {
323478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/*
324478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * We have a ":"; is it followed by a number?
325478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 */
326478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			q = p + 1;
327478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			while (isdigit((unsigned char)*q))
328478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				q++;
329478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (*q == '\0') {
330478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				/*
331478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				 * All digits after the ":" until the end.
332478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				 * Strip off the ":" and everything after
333478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				 * it.
334478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				 */
335478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				*p = '\0';
336478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
337478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
338478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
339478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
340478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
341478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Add information for this address to the list.
342478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
343478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (add_addr_to_iflist(&devlist, ifrp->lifr_name,
344478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    ifrflags.lifr_flags, (struct sockaddr *)&ifrp->lifr_addr,
345478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    sizeof (struct sockaddr_storage),
346478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    netmask, sizeof (struct sockaddr_storage),
347478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    broadaddr, sizeof (struct sockaddr_storage),
348478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		    dstaddr, sizeof (struct sockaddr_storage), errbuf) < 0) {
349478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			ret = -1;
350478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			break;
351478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
352478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
353478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	free(buf);
354478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	(void)close(fd6);
355478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	(void)close(fd4);
356478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
357478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (ret == -1) {
358478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
359478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * We had an error; free the list we've been constructing.
360478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
361478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (devlist != NULL) {
362478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			pcap_freealldevs(devlist);
363478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			devlist = NULL;
364478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
365478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
366478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
367478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	*alldevsp = devlist;
368478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return (ret);
369478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
370