Annotation of embedaddon/mrouted/config.c, revision 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>