/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */1/*2* Copyright (c) 1994, 1995, 1996, 1997, 19983* The Regents of the University of California. All rights reserved.4*5* Redistribution and use in source and binary forms, with or without6* modification, are permitted provided that the following conditions7* are met:8* 1. Redistributions of source code must retain the above copyright9* notice, this list of conditions and the following disclaimer.10* 2. Redistributions in binary form must reproduce the above copyright11* notice, this list of conditions and the following disclaimer in the12* documentation and/or other materials provided with the distribution.13* 3. All advertising materials mentioning features or use of this software14* must display the following acknowledgement:15* This product includes software developed by the Computer Systems16* Engineering Group at Lawrence Berkeley Laboratory.17* 4. Neither the name of the University nor of the Laboratory may be used18* to endorse or promote products derived from this software without19* specific prior written permission.20*21* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND22* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE23* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE24* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE25* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL26* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS27* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)28* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT29* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY30* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF31* SUCH DAMAGE.32*/3334#include <config.h>3536#include <sys/types.h>37#include <sys/socket.h>38#include <netinet/in.h>3940#include <net/if.h>4142#include <errno.h>43#include <stdio.h>44#include <stdlib.h>45#include <string.h>46#include <ifaddrs.h>4748#include "pcap-int.h"4950#ifdef HAVE_OS_PROTO_H51#include "os-proto.h"52#endif5354/*55* We don't do this on Solaris 11 and later, as it appears there aren't56* any AF_PACKET addresses on interfaces, so we don't need this, and57* we end up including both the OS's <net/bpf.h> and our <pcap/bpf.h>,58* and their definitions of some data structures collide.59*/60#if (defined(__linux__) || defined(__Lynx__)) && defined(AF_PACKET)61# ifdef HAVE_NETPACKET_PACKET_H62/* Linux distributions with newer glibc */63# include <netpacket/packet.h>64# else /* HAVE_NETPACKET_PACKET_H */65/* LynxOS, Linux distributions with older glibc */66# ifdef __Lynx__67/* LynxOS */68# include <netpacket/if_packet.h>69# else /* __Lynx__ */70/* Linux */71# include <linux/types.h>72# include <linux/if_packet.h>73# endif /* __Lynx__ */74# endif /* HAVE_NETPACKET_PACKET_H */75#endif /* (defined(__linux__) || defined(__Lynx__)) && defined(AF_PACKET) */7677/*78* This is fun.79*80* In older BSD systems, socket addresses were fixed-length, and81* "sizeof (struct sockaddr)" gave the size of the structure.82* All addresses fit within a "struct sockaddr".83*84* In newer BSD systems, the socket address is variable-length, and85* there's an "sa_len" field giving the length of the structure;86* this allows socket addresses to be longer than 2 bytes of family87* and 14 bytes of data.88*89* Some commercial UNIXes use the old BSD scheme, some use the RFC 255390* variant of the old BSD scheme (with "struct sockaddr_storage" rather91* than "struct sockaddr"), and some use the new BSD scheme.92*93* Some versions of GNU libc use neither scheme, but has an "SA_LEN()"94* macro that determines the size based on the address family. Other95* versions don't have "SA_LEN()" (as it was in drafts of RFC 255396* but not in the final version). On the latter systems, we explicitly97* check the AF_ type to determine the length; we assume that on98* all those systems we have "struct sockaddr_storage".99*100* OSes that use this file are:101* - FreeBSD (HAVE_STRUCT_SOCKADDR_SA_LEN is defined)102* - Haiku (HAVE_STRUCT_SOCKADDR_SA_LEN is defined)103* - Hurd (HAVE_STRUCT_SOCKADDR_SA_LEN is defined)104* - illumos (HAVE_STRUCT_SOCKADDR_SA_LEN is not defined)105* - Linux (HAVE_STRUCT_SOCKADDR_SA_LEN is not defined)106* - macOS (HAVE_STRUCT_SOCKADDR_SA_LEN is defined)107* - NetBSD (HAVE_STRUCT_SOCKADDR_SA_LEN is defined)108* - OpenBSD (SA_LEN() is defined)109* - Solaris 11 (HAVE_STRUCT_SOCKADDR_SA_LEN is not defined)110*/111#ifndef SA_LEN112#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN113#define SA_LEN(addr) ((addr)->sa_len)114#else /* HAVE_STRUCT_SOCKADDR_SA_LEN */115#ifdef HAVE_STRUCT_SOCKADDR_STORAGE116static size_t117get_sa_len(struct sockaddr *addr)118{119switch (addr->sa_family) {120121#ifdef AF_INET122case AF_INET:123return (sizeof (struct sockaddr_in));124#endif125126#ifdef AF_INET6127case AF_INET6:128return (sizeof (struct sockaddr_in6));129#endif130131#if (defined(__linux__) || defined(__Lynx__)) && defined(AF_PACKET)132case AF_PACKET:133return (sizeof (struct sockaddr_ll));134#endif135136#ifdef AF_LINK137case AF_LINK:138return (sizeof (struct sockaddr_dl));139#endif140141default:142return (sizeof (struct sockaddr));143}144}145#define SA_LEN(addr) (get_sa_len(addr))146#else /* HAVE_STRUCT_SOCKADDR_STORAGE */147#define SA_LEN(addr) (sizeof (struct sockaddr))148#endif /* HAVE_STRUCT_SOCKADDR_STORAGE */149#endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */150#endif /* SA_LEN */151152/*153* Get a list of all interfaces that are up and that we can open.154* Returns -1 on error, 0 otherwise.155* The list, as returned through "alldevsp", may be null if no interfaces156* could be opened.157*/158int159pcapint_findalldevs_interfaces(pcap_if_list_t *devlistp, char *errbuf,160int (*check_usable)(const char *), get_if_flags_func get_flags_func)161{162struct ifaddrs *ifap, *ifa;163struct sockaddr *addr, *netmask, *broadaddr, *dstaddr;164size_t addr_size, broadaddr_size, dstaddr_size;165int ret = 0;166char *p, *q;167168/*169* Get the list of interface addresses.170*171* Note: this won't return information about interfaces172* with no addresses, so, if a platform has interfaces173* with no interfaces on which traffic can be captured,174* we must check for those interfaces as well (see, for175* example, what's done on Linux).176*177* LAN interfaces will probably have link-layer178* addresses; I don't know whether all implementations179* of "getifaddrs()" now, or in the future, will return180* those.181*/182if (getifaddrs(&ifap) != 0) {183pcapint_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,184errno, "getifaddrs");185return (-1);186}187for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {188/*189* If this entry has a colon followed by a number at190* the end, we assume it's a logical interface. Those191* are just the way you assign multiple IP addresses to192* a real interface on Linux, so an entry for a logical193* interface should be treated like the entry for the194* real interface; we do that by stripping off the ":"195* and the number.196*197* XXX - should we do this only on Linux?198*/199p = strchr(ifa->ifa_name, ':');200if (p != NULL) {201/*202* We have a ":"; is it followed by a number?203*/204q = p + 1;205while (PCAP_ISDIGIT(*q))206q++;207if (*q == '\0') {208/*209* All digits after the ":" until the end.210* Strip off the ":" and everything after211* it.212*/213*p = '\0';214}215}216217/*218* Can we capture on this device?219*/220if (!(*check_usable)(ifa->ifa_name)) {221/*222* No.223*/224continue;225}226227/*228* "ifa_addr" was apparently null on at least one229* interface on some system. Therefore, we supply230* the address and netmask only if "ifa_addr" is231* non-null (if there's no address, there's obviously232* no netmask).233*/234if (ifa->ifa_addr != NULL) {235addr = ifa->ifa_addr;236addr_size = SA_LEN(addr);237netmask = ifa->ifa_netmask;238} else {239addr = NULL;240addr_size = 0;241netmask = NULL;242}243244/*245* Note that, on some platforms, ifa_broadaddr and246* ifa_dstaddr could be the same field (true on at247* least some versions of *BSD and macOS), so we248* can't just check whether the broadcast address249* is null and add it if so and check whether the250* destination address is null and add it if so.251*252* Therefore, we must also check the IFF_BROADCAST253* flag, and only add a broadcast address if it's254* set, and check the IFF_POINTTOPOINT flag, and255* only add a destination address if it's set (as256* per man page recommendations on some of those257* platforms).258*/259if (ifa->ifa_flags & IFF_BROADCAST &&260ifa->ifa_broadaddr != NULL) {261broadaddr = ifa->ifa_broadaddr;262broadaddr_size = SA_LEN(broadaddr);263} else {264broadaddr = NULL;265broadaddr_size = 0;266}267if (ifa->ifa_flags & IFF_POINTOPOINT &&268ifa->ifa_dstaddr != NULL) {269dstaddr = ifa->ifa_dstaddr;270dstaddr_size = SA_LEN(ifa->ifa_dstaddr);271} else {272dstaddr = NULL;273dstaddr_size = 0;274}275276/*277* Add information for this address to the list.278*/279if (pcapint_add_addr_to_if(devlistp, ifa->ifa_name, ifa->ifa_flags,280get_flags_func,281addr, addr_size, netmask, addr_size,282broadaddr, broadaddr_size, dstaddr, dstaddr_size,283errbuf) < 0) {284ret = -1;285break;286}287}288289freeifaddrs(ifap);290291return (ret);292}293294295