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_ = 37478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "@(#) $Header: /tcpdump/master/libpcap/fad-gifc.c,v 1.8.2.2 2005/06/29 06:43:31 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 * This is fun. 74478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 75478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * In older BSD systems, socket addresses were fixed-length, and 76478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "sizeof (struct sockaddr)" gave the size of the structure. 77478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * All addresses fit within a "struct sockaddr". 78478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 79478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * In newer BSD systems, the socket address is variable-length, and 80478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * there's an "sa_len" field giving the length of the structure; 81478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * this allows socket addresses to be longer than 2 bytes of family 82478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * and 14 bytes of data. 83478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 84478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Some commercial UNIXes use the old BSD scheme, some use the RFC 2553 85478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * variant of the old BSD scheme (with "struct sockaddr_storage" rather 86478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * than "struct sockaddr"), and some use the new BSD scheme. 87478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 88478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Some versions of GNU libc use neither scheme, but has an "SA_LEN()" 89478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * macro that determines the size based on the address family. Other 90478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * versions don't have "SA_LEN()" (as it was in drafts of RFC 2553 91478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * but not in the final version). 92478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 93478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * We assume that a UNIX that doesn't have "getifaddrs()" and doesn't have 94478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * SIOCGLIFCONF, but has SIOCGIFCONF, uses "struct sockaddr" for the 95478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * address in an entry returned by SIOCGIFCONF. 96478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 97478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef SA_LEN 98478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_SOCKADDR_SA_LEN 99478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define SA_LEN(addr) ((addr)->sa_len) 100478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else /* HAVE_SOCKADDR_SA_LEN */ 101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define SA_LEN(addr) (sizeof (struct sockaddr)) 102478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* HAVE_SOCKADDR_SA_LEN */ 103478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* SA_LEN */ 104478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 105478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 106478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This is also fun. 107478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 108478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * There is no ioctl that returns the amount of space required for all 109478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the data that SIOCGIFCONF could return, and if a buffer is supplied 110478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * that's not large enough for all the data SIOCGIFCONF could return, 111478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * on at least some platforms it just returns the data that'd fit with 112478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * no indication that there wasn't enough room for all the data, much 113478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * less an indication of how much more room is required. 114478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 115478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * The only way to ensure that we got all the data is to pass a buffer 116478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * large enough that the amount of space in the buffer *not* filled in 117478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * is greater than the largest possible entry. 118478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 119478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * We assume that's "sizeof(ifreq.ifr_name)" plus 255, under the assumption 120478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * that no address is more than 255 bytes (on systems where the "sa_len" 121478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * field in a "struct sockaddr" is 1 byte, e.g. newer BSDs, that's the 122478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * case, and addresses are unlikely to be bigger than that in any case). 123478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 124478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define MAX_SA_LEN 255 125478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 126478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_PROC_NET_DEV 127478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 128478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Get from "/proc/net/dev" all interfaces listed there; if they're 129478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * already in the list of interfaces we have, that won't add another 130478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * instance, but if they're not, that'll add them. 131478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 132478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * We don't bother getting any addresses for them; it appears you can't 133478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * use SIOCGIFADDR on Linux to get IPv6 addresses for interfaces, and, 134478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * although some other types of addresses can be fetched with SIOCGIFADDR, 135478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * we don't bother with them for now. 136478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 137478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * We also don't fail if we couldn't open "/proc/net/dev"; we just leave 138478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the list of interfaces as is. 139478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 140478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int 141478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectscan_proc_net_dev(pcap_if_t **devlistp, int fd, char *errbuf) 142478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 143478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project FILE *proc_net_f; 144478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project char linebuf[512]; 145478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int linenum; 146478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project unsigned char *p; 147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project char name[512]; /* XXX - pick a size */ 148478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project char *q, *saveq; 149478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct ifreq ifrflags; 150478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int ret = 0; 151478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 152478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project proc_net_f = fopen("/proc/net/dev", "r"); 153478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (proc_net_f == NULL) 154478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (0); 155478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 156478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project for (linenum = 1; 157478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project fgets(linebuf, sizeof linebuf, proc_net_f) != NULL; linenum++) { 158478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 159478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Skip the first two lines - they're headers. 160478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 161478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (linenum <= 2) 162478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 163478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 164478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p = &linebuf[0]; 165478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 166478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 167478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Skip leading white space. 168478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 169478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project while (*p != '\0' && isspace(*p)) 170478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p++; 171478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (*p == '\0' || *p == '\n') 172478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; /* blank line */ 173478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 174478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 175478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Get the interface name. 176478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 177478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project q = &name[0]; 178478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project while (*p != '\0' && !isspace(*p)) { 179478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (*p == ':') { 180478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 181478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This could be the separator between a 182478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * name and an alias number, or it could be 183478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the separator between a name with no 184478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * alias number and the next field. 185478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 186478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If there's a colon after digits, it 187478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * separates the name and the alias number, 188478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * otherwise it separates the name and the 189478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * next field. 190478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 191478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project saveq = q; 192478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project while (isdigit(*p)) 193478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *q++ = *p++; 194478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (*p != ':') { 195478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 196478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * That was the next field, 197478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * not the alias number. 198478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 199478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project q = saveq; 200478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 201478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 202478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else 203478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *q++ = *p++; 204478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 205478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *q = '\0'; 206478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 207478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 208478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Get the flags for this interface, and skip it if 209478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * it's not up. 210478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 211478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project strncpy(ifrflags.ifr_name, name, sizeof(ifrflags.ifr_name)); 212478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifrflags) < 0) { 213478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (errno == ENXIO) 214478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 215478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 216478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "SIOCGIFFLAGS: %.*s: %s", 217478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (int)sizeof(ifrflags.ifr_name), 218478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ifrflags.ifr_name, 219478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 220478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ret = -1; 221478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 222478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 223478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (!(ifrflags.ifr_flags & IFF_UP)) 224478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 225478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 226478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 227478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Add an entry for this interface, with no addresses. 228478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 229478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (pcap_add_if(devlistp, name, ifrflags.ifr_flags, NULL, 230478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project errbuf) == -1) { 231478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 232478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Failure. 233478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 234478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ret = -1; 235478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 236478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 237478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 238478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ret != -1) { 239478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 240478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Well, we didn't fail for any other reason; did we 241478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * fail due to an error reading the file? 242478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 243478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ferror(proc_net_f)) { 244478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 245478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "Error reading /proc/net/dev: %s", 246478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 247478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ret = -1; 248478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 249478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 250478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 251478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void)fclose(proc_net_f); 252478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (ret); 253478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 254478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* HAVE_PROC_NET_DEV */ 255478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 256478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* 257478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Get a list of all interfaces that are up and that we can open. 258478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Returns -1 on error, 0 otherwise. 259478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * The list, as returned through "alldevsp", may be null if no interfaces 260478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * were up and could be opened. 261478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 262478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This is the implementation used on platforms that have SIOCGIFCONF but 263478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * don't have any other mechanism for getting a list of interfaces. 264478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 265478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - or platforms that have other, better mechanisms but for which 266478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * we don't yet have code to use that mechanism; I think there's a better 267478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * way on Linux, for example. 268478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 269478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectint 270478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) 271478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{ 272478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_if_t *devlist = NULL; 273478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register int fd; 274478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project register struct ifreq *ifrp, *ifend, *ifnext; 275478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int n; 276478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct ifconf ifc; 277478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project char *buf = NULL; 278478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project unsigned buf_size; 279478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#if defined (HAVE_SOLARIS) || defined (HAVE_HPUX10_20_OR_LATER) 280478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project char *p, *q; 281478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 282478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct ifreq ifrflags, ifrnetmask, ifrbroadaddr, ifrdstaddr; 283478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project struct sockaddr *netmask, *broadaddr, *dstaddr; 284478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project size_t netmask_size, broadaddr_size, dstaddr_size; 285478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project int ret = 0; 286478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 287478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 288478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Create a socket from which to fetch the list of interfaces. 289478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 290478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project fd = socket(AF_INET, SOCK_DGRAM, 0); 291478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (fd < 0) { 292478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 293478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "socket: %s", pcap_strerror(errno)); 294478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 295478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 296478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 297478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 298478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Start with an 8K buffer, and keep growing the buffer until 299478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * we have more than "sizeof(ifrp->ifr_name) + MAX_SA_LEN" 300478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * bytes left over in the buffer or we fail to get the 301478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * interface list for some reason other than EINVAL (which is 302478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * presumed here to mean "buffer is too small"). 303478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 304478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project buf_size = 8192; 305478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project for (;;) { 306478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project buf = malloc(buf_size); 307478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (buf == NULL) { 308478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 309478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "malloc: %s", pcap_strerror(errno)); 310478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void)close(fd); 311478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 312478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 313478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 314478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ifc.ifc_len = buf_size; 315478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ifc.ifc_buf = buf; 316478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project memset(buf, 0, buf_size); 317478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(fd, SIOCGIFCONF, (char *)&ifc) < 0 318478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project && errno != EINVAL) { 319478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 320478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "SIOCGIFCONF: %s", pcap_strerror(errno)); 321478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void)close(fd); 322478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project free(buf); 323478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (-1); 324478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 325478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ifc.ifc_len < buf_size && 326478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (buf_size - ifc.ifc_len) > sizeof(ifrp->ifr_name) + MAX_SA_LEN) 327478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 328478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project free(buf); 329478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project buf_size *= 2; 330478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 331478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 332478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ifrp = (struct ifreq *)buf; 333478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ifend = (struct ifreq *)(buf + ifc.ifc_len); 334478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 335478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project for (; ifrp < ifend; ifrp = ifnext) { 336478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 337478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - what if this isn't an IPv4 address? Can 338478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * we still get the netmask, etc. with ioctls on 339478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * an IPv4 socket? 340478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * 341478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * The answer is probably platform-dependent, and 342478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * if the answer is "no" on more than one platform, 343478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the way you work around it is probably platform- 344478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * dependent as well. 345478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 346478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project n = SA_LEN(&ifrp->ifr_addr) + sizeof(ifrp->ifr_name); 347478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (n < sizeof(*ifrp)) 348478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ifnext = ifrp + 1; 349478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project else 350478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ifnext = (struct ifreq *)((char *)ifrp + n); 351478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 352478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 353478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - The 32-bit compatibility layer for Linux on IA-64 354478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * is slightly broken. It correctly converts the structures 355478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * to and from kernel land from 64 bit to 32 bit but 356478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * doesn't update ifc.ifc_len, leaving it larger than the 357478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * amount really used. This means we read off the end 358478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * of the buffer and encounter an interface with an 359478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * "empty" name. Since this is highly unlikely to ever 360478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * occur in a valid case we can just finish looking for 361478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * interfaces if we see an empty name. 362478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 363478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (!(*ifrp->ifr_name)) 364478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 365478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 366478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 367478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Skip entries that begin with "dummy". 368478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * XXX - what are these? Is this Linux-specific? 369478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Are there platforms on which we shouldn't do this? 370478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 371478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (strncmp(ifrp->ifr_name, "dummy", 5) == 0) 372478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 373478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 374478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 375478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Get the flags for this interface, and skip it if it's 376478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * not up. 377478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 378478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project strncpy(ifrflags.ifr_name, ifrp->ifr_name, 379478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sizeof(ifrflags.ifr_name)); 380478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifrflags) < 0) { 381478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (errno == ENXIO) 382478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 383478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 384478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "SIOCGIFFLAGS: %.*s: %s", 385478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (int)sizeof(ifrflags.ifr_name), 386478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ifrflags.ifr_name, 387478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 388478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ret = -1; 389478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 390478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 391478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (!(ifrflags.ifr_flags & IFF_UP)) 392478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project continue; 393478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 394478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 395478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Get the netmask for this address on this interface. 396478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 397478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project strncpy(ifrnetmask.ifr_name, ifrp->ifr_name, 398478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sizeof(ifrnetmask.ifr_name)); 399478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project memcpy(&ifrnetmask.ifr_addr, &ifrp->ifr_addr, 400478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sizeof(ifrnetmask.ifr_addr)); 401478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifrnetmask) < 0) { 402478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (errno == EADDRNOTAVAIL) { 403478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 404478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Not available. 405478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 406478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project netmask = NULL; 407478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project netmask_size = 0; 408478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 409478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 410478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "SIOCGIFNETMASK: %.*s: %s", 411478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (int)sizeof(ifrnetmask.ifr_name), 412478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ifrnetmask.ifr_name, 413478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 414478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ret = -1; 415478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 416478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 417478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 418478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project netmask = &ifrnetmask.ifr_addr; 419478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project netmask_size = SA_LEN(netmask); 420478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 421478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 422478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 423478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Get the broadcast address for this address on this 424478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * interface (if any). 425478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 426478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ifrflags.ifr_flags & IFF_BROADCAST) { 427478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project strncpy(ifrbroadaddr.ifr_name, ifrp->ifr_name, 428478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sizeof(ifrbroadaddr.ifr_name)); 429478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project memcpy(&ifrbroadaddr.ifr_addr, &ifrp->ifr_addr, 430478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sizeof(ifrbroadaddr.ifr_addr)); 431478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(fd, SIOCGIFBRDADDR, 432478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (char *)&ifrbroadaddr) < 0) { 433478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (errno == EADDRNOTAVAIL) { 434478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 435478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Not available. 436478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 437478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project broadaddr = NULL; 438478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project broadaddr_size = 0; 439478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 440478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 441478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "SIOCGIFBRDADDR: %.*s: %s", 442478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (int)sizeof(ifrbroadaddr.ifr_name), 443478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ifrbroadaddr.ifr_name, 444478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 445478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ret = -1; 446478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 447478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 448478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 449478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project broadaddr = &ifrbroadaddr.ifr_broadaddr; 450478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project broadaddr_size = SA_LEN(broadaddr); 451478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 452478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 453478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 454478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Not a broadcast interface, so no broadcast 455478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * address. 456478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 457478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project broadaddr = NULL; 458478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project broadaddr_size = 0; 459478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 460478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 461478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 462478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Get the destination address for this address on this 463478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * interface (if any). 464478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 465478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ifrflags.ifr_flags & IFF_POINTOPOINT) { 466478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project strncpy(ifrdstaddr.ifr_name, ifrp->ifr_name, 467478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sizeof(ifrdstaddr.ifr_name)); 468478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project memcpy(&ifrdstaddr.ifr_addr, &ifrp->ifr_addr, 469478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project sizeof(ifrdstaddr.ifr_addr)); 470478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ioctl(fd, SIOCGIFDSTADDR, 471478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (char *)&ifrdstaddr) < 0) { 472478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (errno == EADDRNOTAVAIL) { 473478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 474478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Not available. 475478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 476478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project dstaddr = NULL; 477478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project dstaddr_size = 0; 478478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 479478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 480478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project "SIOCGIFDSTADDR: %.*s: %s", 481478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (int)sizeof(ifrdstaddr.ifr_name), 482478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ifrdstaddr.ifr_name, 483478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_strerror(errno)); 484478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ret = -1; 485478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 486478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 487478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 488478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project dstaddr = &ifrdstaddr.ifr_dstaddr; 489478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project dstaddr_size = SA_LEN(dstaddr); 490478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 491478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } else { 492478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 493478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Not a point-to-point interface, so no destination 494478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * address. 495478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 496478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project dstaddr = NULL; 497478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project dstaddr_size = 0; 498478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 499478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 500478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#if defined (HAVE_SOLARIS) || defined (HAVE_HPUX10_20_OR_LATER) 501478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 502478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If this entry has a colon followed by a number at 503478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the end, it's a logical interface. Those are just 504478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the way you assign multiple IP addresses to a real 505478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * interface, so an entry for a logical interface should 506478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * be treated like the entry for the real interface; 507478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * we do that by stripping off the ":" and the number. 508478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 509478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project p = strchr(ifrp->ifr_name, ':'); 510478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (p != NULL) { 511478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 512478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * We have a ":"; is it followed by a number? 513478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 514478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project q = p + 1; 515478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project while (isdigit((unsigned char)*q)) 516478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project q++; 517478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (*q == '\0') { 518478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 519478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * All digits after the ":" until the end. 520478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Strip off the ":" and everything after 521478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * it. 522478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 523478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *p = '\0'; 524478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 525478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 526478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 527478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 528478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 529478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Add information for this address to the list. 530478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 531478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (add_addr_to_iflist(&devlist, ifrp->ifr_name, 532478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ifrflags.ifr_flags, &ifrp->ifr_addr, 533478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project SA_LEN(&ifrp->ifr_addr), netmask, netmask_size, 534478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project broadaddr, broadaddr_size, dstaddr, dstaddr_size, 535478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project errbuf) < 0) { 536478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ret = -1; 537478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project break; 538478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 539478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 540478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project free(buf); 541478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 542478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_PROC_NET_DEV 543478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ret != -1) { 544478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 545478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * We haven't had any errors yet; now read "/proc/net/dev", 546478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * and add to the list of interfaces all interfaces listed 547478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * there that we don't already have, because, on Linux, 548478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * SIOCGIFCONF reports only interfaces with IPv4 addresses, 549478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * so you need to read "/proc/net/dev" to get the names of 550478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the rest of the interfaces. 551478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 552478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ret = scan_proc_net_dev(&devlist, fd, errbuf); 553478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 554478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif 555478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project (void)close(fd); 556478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 557478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ret != -1) { 558478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 559478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * We haven't had any errors yet; do any platform-specific 560478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * operations to add devices. 561478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 562478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (pcap_platform_finddevs(&devlist, errbuf) < 0) 563478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project ret = -1; 564478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 565478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 566478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (ret == -1) { 567478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project /* 568478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * We had an error; free the list we've been constructing. 569478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */ 570478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project if (devlist != NULL) { 571478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project pcap_freealldevs(devlist); 572478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project devlist = NULL; 573478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 574478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project } 575478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project 576478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *alldevsp = devlist; 577478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project return (ret); 578478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} 579