Annotation of embedaddon/mrouted/config.c, revision 1.1.1.1

1.1       misho       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>