1/* 2 * Copyright (c) 1990 Jan-Simon Pendry 3 * Copyright (c) 1990 Imperial College of Science, Technology & Medicine 4 * Copyright (c) 1990, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Jan-Simon Pendry at Imperial College, London. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. Neither the name of the University nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * from: @(#)wire.c 8.1 (Berkeley) 6/6/93 35 * $Id: wire.c,v 1.14 2022/12/28 21:30:15 jmc Exp $ 36 */ 37 38/* 39 * This function returns the subnet (address&netmask) for the primary network 40 * interface. If the resulting address has an entry in the hosts file, the 41 * corresponding name is returned, otherwise the address is returned in 42 * standard internet format. 43 * As a side-effect, a list of local IP/net address is recorded for use 44 * by the islocalnet() function. 45 * 46 * Derived from original by Paul Anderson (23/4/90) 47 * Updates from Dirk Grunwald (11/11/91) 48 * Modified to use getifaddrs() by Todd C. Miller (6/14/2003) 49 */ 50 51#include "am.h" 52 53#include <ifaddrs.h> 54#include <netdb.h> 55#include <net/if.h> 56 57#define NO_SUBNET "notknown" 58 59/* 60 * List of locally connected networks 61 */ 62typedef struct addrlist addrlist; 63struct addrlist { 64 addrlist *ip_next; 65 in_addr_t ip_addr; 66 in_addr_t ip_mask; 67}; 68static addrlist *localnets = 0; 69 70char * 71getwire(void) 72{ 73 struct ifaddrs *ifa, *ifaddrs; 74 struct hostent *hp; 75 addrlist *al; 76 char *s, *netname = NULL; 77 78 if (getifaddrs(&ifaddrs)) 79 return strdup(NO_SUBNET); 80 81 for (ifa = ifaddrs; ifa != NULL; ifa = ifa -> ifa_next) { 82 /* 83 * Ignore non-AF_INET interfaces as well as any that 84 * are down or loopback. 85 */ 86 if (ifa->ifa_addr == NULL || 87 ifa->ifa_addr->sa_family != AF_INET || 88 !(ifa->ifa_flags & IFF_UP) || 89 (ifa->ifa_flags & IFF_LOOPBACK)) 90 continue; 91 92 /* 93 * Add interface to local network list 94 */ 95 al = ALLOC(addrlist); 96 al->ip_addr = 97 ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr; 98 al->ip_mask = 99 ((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr.s_addr; 100 al->ip_next = localnets; 101 localnets = al; 102 103 /* 104 * Look up the host name; fall back to a dotted quad. 105 */ 106 if (netname == NULL) { 107 in_addr_t subnet; 108 char dq[20]; 109 110 subnet = al->ip_addr & al->ip_mask; 111 hp = gethostbyaddr((char *) &subnet, 4, AF_INET); 112 if (hp) 113 s = hp->h_name; 114 else 115 s = inet_dquad(dq, sizeof(dq), subnet); 116 netname = strdup(s); 117 } 118 } 119 freeifaddrs(ifaddrs); 120 return (netname ? netname : strdup(NO_SUBNET)); 121} 122 123/* 124 * Determine whether a network is on a local network 125 * (addr) is in network byte order. 126 */ 127int 128islocalnet(in_addr_t addr) 129{ 130 addrlist *al; 131 132 for (al = localnets; al; al = al->ip_next) 133 if (((addr ^ al->ip_addr) & al->ip_mask) == 0) 134 return TRUE; 135 136#ifdef DEBUG 137 { char buf[16]; 138 plog(XLOG_INFO, "%s is on a remote network", inet_dquad(buf, sizeof(buf), addr)); 139 } 140#endif 141 return FALSE; 142} 143