1 1.13 dsl /* $NetBSD: config.c,v 1.13 2003/05/16 22:59:50 dsl Exp $ */ 2 1.5 thorpej 3 1.1 brezak /* 4 1.1 brezak * The mrouted program is covered by the license in the accompanying file 5 1.1 brezak * named "LICENSE". Use of the mrouted program represents acceptance of 6 1.1 brezak * the terms and conditions listed in that file. 7 1.1 brezak * 8 1.1 brezak * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of 9 1.1 brezak * Leland Stanford Junior University. 10 1.1 brezak */ 11 1.1 brezak 12 1.1 brezak #include "defs.h" 13 1.8 itojun #include <net/if.h> 14 1.8 itojun #include <ifaddrs.h> 15 1.1 brezak 16 1.1 brezak 17 1.1 brezak /* 18 1.1 brezak * Query the kernel to find network interfaces that are multicast-capable 19 1.1 brezak * and install them in the uvifs array. 20 1.1 brezak */ 21 1.6 mycroft void 22 1.7 wiz config_vifs_from_kernel(void) 23 1.1 brezak { 24 1.8 itojun struct ifaddrs *ifa, *ifap; 25 1.7 wiz struct uvif *v; 26 1.7 wiz vifi_t vifi; 27 1.4 mycroft u_int32_t addr, mask, subnet; 28 1.1 brezak short flags; 29 1.1 brezak 30 1.8 itojun if (getifaddrs(&ifap) < 0) 31 1.11 wiz logit(LOG_ERR, errno, "getifaddrs"); 32 1.8 itojun 33 1.8 itojun for (ifa = ifap; ifa; ifa = ifa->ifa_next) { 34 1.1 brezak /* 35 1.1 brezak * Ignore any interface for an address family other than IP. 36 1.1 brezak */ 37 1.8 itojun if (ifa->ifa_addr->sa_family != AF_INET) 38 1.1 brezak continue; 39 1.1 brezak 40 1.9 itojun addr = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr; 41 1.1 brezak 42 1.1 brezak /* 43 1.1 brezak * Ignore loopback interfaces and interfaces that do not support 44 1.1 brezak * multicast. 45 1.1 brezak */ 46 1.8 itojun flags = ifa->ifa_flags; 47 1.8 itojun if ((flags & (IFF_LOOPBACK|IFF_MULTICAST)) != IFF_MULTICAST) 48 1.8 itojun continue; 49 1.1 brezak 50 1.1 brezak /* 51 1.1 brezak * Ignore any interface whose address and mask do not define a 52 1.1 brezak * valid subnet number, or whose address is of the form {subnet,0} 53 1.1 brezak * or {subnet,-1}. 54 1.1 brezak */ 55 1.9 itojun mask = ((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr.s_addr; 56 1.1 brezak subnet = addr & mask; 57 1.1 brezak if (!inet_valid_subnet(subnet, mask) || 58 1.1 brezak addr == subnet || 59 1.1 brezak addr == (subnet | ~mask)) { 60 1.11 wiz logit(LOG_WARNING, 0, 61 1.4 mycroft "ignoring %s, has invalid address (%s) and/or mask (%s)", 62 1.13 dsl ifa->ifa_name, inet_fmt(addr), 63 1.13 dsl inet_fmt(mask)); 64 1.1 brezak continue; 65 1.1 brezak } 66 1.1 brezak 67 1.1 brezak /* 68 1.1 brezak * Ignore any interface that is connected to the same subnet as 69 1.1 brezak * one already installed in the uvifs array. 70 1.1 brezak */ 71 1.1 brezak for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) { 72 1.1 brezak if ((addr & v->uv_subnetmask) == v->uv_subnet || 73 1.1 brezak (v->uv_subnet & mask) == subnet) { 74 1.11 wiz logit(LOG_WARNING, 0, "ignoring %s, same subnet as %s", 75 1.8 itojun ifa->ifa_name, v->uv_name); 76 1.1 brezak break; 77 1.1 brezak } 78 1.1 brezak } 79 1.8 itojun if (vifi != numvifs) 80 1.8 itojun continue; 81 1.1 brezak 82 1.1 brezak /* 83 1.1 brezak * If there is room in the uvifs array, install this interface. 84 1.1 brezak */ 85 1.1 brezak if (numvifs == MAXVIFS) { 86 1.11 wiz logit(LOG_WARNING, 0, "too many vifs, ignoring %s", ifa->ifa_name); 87 1.1 brezak continue; 88 1.1 brezak } 89 1.1 brezak v = &uvifs[numvifs]; 90 1.1 brezak v->uv_flags = 0; 91 1.1 brezak v->uv_metric = DEFAULT_METRIC; 92 1.4 mycroft v->uv_rate_limit = DEFAULT_PHY_RATE_LIMIT; 93 1.1 brezak v->uv_threshold = DEFAULT_THRESHOLD; 94 1.1 brezak v->uv_lcl_addr = addr; 95 1.1 brezak v->uv_rmt_addr = 0; 96 1.1 brezak v->uv_subnet = subnet; 97 1.1 brezak v->uv_subnetmask = mask; 98 1.1 brezak v->uv_subnetbcast = subnet | ~mask; 99 1.8 itojun strlcpy(v->uv_name, ifa->ifa_name, sizeof(v->uv_name)); 100 1.1 brezak v->uv_groups = NULL; 101 1.1 brezak v->uv_neighbors = NULL; 102 1.4 mycroft v->uv_acl = NULL; 103 1.4 mycroft v->uv_addrs = NULL; 104 1.1 brezak 105 1.11 wiz logit(LOG_INFO,0,"installing %s (%s on subnet %s) as vif #%u - rate=%d", 106 1.13 dsl v->uv_name, inet_fmt(addr), 107 1.13 dsl inet_fmts(subnet, mask), 108 1.4 mycroft numvifs, v->uv_rate_limit); 109 1.1 brezak 110 1.1 brezak ++numvifs; 111 1.1 brezak 112 1.1 brezak /* 113 1.1 brezak * If the interface is not yet up, set the vifs_down flag to 114 1.1 brezak * remind us to check again later. 115 1.1 brezak */ 116 1.1 brezak if (!(flags & IFF_UP)) { 117 1.1 brezak v->uv_flags |= VIFF_DOWN; 118 1.1 brezak vifs_down = TRUE; 119 1.1 brezak } 120 1.1 brezak } 121 1.8 itojun 122 1.8 itojun freeifaddrs(ifap); 123 1.1 brezak } 124