Home | History | Annotate | Line # | Download | only in mrouted
      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