File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / mrouted / config.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 23:10:48 2012 UTC (12 years, 3 months ago) by misho
Branches: mrouted, MAIN
CVS tags: v3_9_6p0, v3_9_6, v3_9_5, HEAD
mrouted

    1: /*
    2:  * The mrouted program is covered by the license in the accompanying file
    3:  * named "LICENSE".  Use of the mrouted program represents acceptance of
    4:  * the terms and conditions listed in that file.
    5:  *
    6:  * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
    7:  * Leland Stanford Junior University.
    8:  */
    9: 
   10: #include "defs.h"
   11: #include <ifaddrs.h>
   12: 
   13: /*
   14:  * Query the kernel to find network interfaces that are multicast-capable
   15:  * and install them in the uvifs array.
   16:  */
   17: void
   18: config_vifs_from_kernel()
   19: {
   20:     struct ifaddrs *ifa, *ifap;
   21:     register struct uvif *v;
   22:     register vifi_t vifi;
   23:     u_int32 addr, mask, subnet;
   24:     int flags;
   25: 
   26:     if (getifaddrs(&ifap) < 0)
   27: 	logit(LOG_ERR, errno, "getifaddrs");
   28:     /*
   29:      * Loop through all of the interfaces.
   30:      */
   31:     for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
   32: 	/*
   33: 	 * Ignore any interface for an address family other than IP.
   34: 	 */
   35: 	if (!ifa->ifa_addr || ifa->ifa_addr->sa_family != AF_INET)
   36: 	    continue;
   37: 
   38: 	/*
   39: 	 * Ignore loopback interfaces and interfaces that do not support
   40: 	 * multicast.
   41: 	 */
   42: 	flags = ifa->ifa_flags;
   43: 	if ((flags & (IFF_LOOPBACK|IFF_MULTICAST)) != IFF_MULTICAST)
   44: 	    continue;
   45: 
   46: 	/*
   47: 	 * Perform some sanity checks on the address and subnet, ignore any
   48: 	 * interface whose address and netmask do not define a valid subnet.
   49: 	 */
   50: 	addr = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr;
   51: 	mask = ((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr.s_addr;
   52: 	subnet = addr & mask;
   53: 	if (!inet_valid_subnet(subnet, mask) || (addr != subnet && addr == (subnet & ~mask))) {
   54: 	    logit(LOG_WARNING, 0, "ignoring %s, has invalid address (%s) and/or mask (%s)",
   55: 		  ifa->ifa_name, inet_fmt(addr, s1, sizeof(s1)), inet_fmt(mask, s2, sizeof(s2)));
   56: 	    continue;
   57: 	}
   58: 
   59: 	/*
   60: 	 * Ignore any interface that is connected to the same subnet as
   61: 	 * one already installed in the uvifs array.
   62: 	 */
   63: 	for (vifi = 0, v = uvifs; vifi < numvifs; ++vifi, ++v) {
   64: 	    if (strcmp(v->uv_name, ifa->ifa_name) == 0) {
   65: 		logit(LOG_DEBUG, 0, "skipping %s (%s on subnet %s) (alias for vif#%u?)",
   66: 			v->uv_name, inet_fmt(addr, s1, sizeof(s1)),
   67: 			inet_fmts(subnet, mask, s2, sizeof(s2)), vifi);
   68: 		break;
   69: 	    }
   70: 	    if ((addr & v->uv_subnetmask) == v->uv_subnet ||
   71: 		(v->uv_subnet & mask) == subnet) {
   72: 		logit(LOG_WARNING, 0, "ignoring %s, same subnet as %s",
   73: 		    ifa->ifa_name, v->uv_name);
   74: 		break;
   75: 	    }
   76: 	}
   77: 	if (vifi != numvifs) continue;
   78: 
   79: 	/*
   80: 	 * If there is room in the uvifs array, install this interface.
   81: 	 */
   82: 	if (numvifs == MAXVIFS) {
   83: 	    logit(LOG_WARNING, 0, "too many vifs, ignoring %s", ifa->ifa_name);
   84: 	    continue;
   85: 	}
   86: 	v  = &uvifs[numvifs];
   87: 	zero_vif(v, 0);
   88: 	v->uv_lcl_addr    = addr;
   89: 	v->uv_subnet      = subnet;
   90: 	v->uv_subnetmask  = mask;
   91: 	v->uv_subnetbcast = subnet | ~mask;
   92: 	strncpy(v->uv_name, ifa->ifa_name, sizeof(v->uv_name));
   93: 
   94: 	if (flags & IFF_POINTOPOINT)
   95: 	    v->uv_flags |= VIFF_REXMIT_PRUNES;
   96: 
   97: 	logit(LOG_INFO,0,"installing %s (%s on subnet %s) as vif #%u - rate=%d",
   98: 	    v->uv_name, inet_fmt(addr, s1, sizeof(s1)), inet_fmts(subnet, mask, s2, sizeof(s2)),
   99: 	    numvifs, v->uv_rate_limit);
  100: 
  101: 	++numvifs;
  102: 
  103: 	/*
  104: 	 * If the interface is not yet up, set the vifs_down flag to
  105: 	 * remind us to check again later.
  106: 	 */
  107: 	if (!(flags & IFF_UP)) {
  108: 	    v->uv_flags |= VIFF_DOWN;
  109: 	    vifs_down = TRUE;
  110: 	}
  111:     }
  112: 
  113:     freeifaddrs(ifap);
  114: }
  115: 
  116: /**
  117:  * Local Variables:
  118:  *  version-control: t
  119:  *  indent-tabs-mode: t
  120:  *  c-file-style: "ellemtel"
  121:  *  c-basic-offset: 4
  122:  * End:
  123:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>