Annotation of 43BSD/sys/net/if.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1980, 1986 Regents of the University of California.
        !             3:  * All rights reserved.  The Berkeley software License Agreement
        !             4:  * specifies the terms and conditions for redistribution.
        !             5:  *
        !             6:  *     @(#)if.c        7.1 (Berkeley) 6/4/86
        !             7:  */
        !             8: 
        !             9: #include "param.h"
        !            10: #include "systm.h"
        !            11: #include "socket.h"
        !            12: #include "socketvar.h"
        !            13: #include "protosw.h"
        !            14: #include "dir.h"
        !            15: #include "user.h"
        !            16: #include "kernel.h"
        !            17: #include "ioctl.h"
        !            18: #include "errno.h"
        !            19: 
        !            20: #include "if.h"
        !            21: #include "af.h"
        !            22: 
        !            23: #include "ether.h"
        !            24: 
        !            25: int    ifqmaxlen = IFQ_MAXLEN;
        !            26: 
        !            27: /*
        !            28:  * Network interface utility routines.
        !            29:  *
        !            30:  * Routines with ifa_ifwith* names take sockaddr *'s as
        !            31:  * parameters.
        !            32:  */
        !            33: 
        !            34: ifinit()
        !            35: {
        !            36:        register struct ifnet *ifp;
        !            37: 
        !            38:        for (ifp = ifnet; ifp; ifp = ifp->if_next)
        !            39:                if (ifp->if_snd.ifq_maxlen == 0)
        !            40:                        ifp->if_snd.ifq_maxlen = ifqmaxlen;
        !            41:        if_slowtimo();
        !            42: }
        !            43: 
        !            44: #ifdef vax
        !            45: /*
        !            46:  * Call each interface on a Unibus reset.
        !            47:  */
        !            48: ifubareset(uban)
        !            49:        int uban;
        !            50: {
        !            51:        register struct ifnet *ifp;
        !            52: 
        !            53:        for (ifp = ifnet; ifp; ifp = ifp->if_next)
        !            54:                if (ifp->if_reset)
        !            55:                        (*ifp->if_reset)(ifp->if_unit, uban);
        !            56: }
        !            57: #endif
        !            58: 
        !            59: /*
        !            60:  * Attach an interface to the
        !            61:  * list of "active" interfaces.
        !            62:  */
        !            63: if_attach(ifp)
        !            64:        struct ifnet *ifp;
        !            65: {
        !            66:        register struct ifnet **p = &ifnet;
        !            67: 
        !            68:        while (*p)
        !            69:                p = &((*p)->if_next);
        !            70:        *p = ifp;
        !            71: }
        !            72: 
        !            73: /*
        !            74:  * Locate an interface based on a complete address.
        !            75:  */
        !            76: /*ARGSUSED*/
        !            77: struct ifaddr *
        !            78: ifa_ifwithaddr(addr)
        !            79:        struct sockaddr *addr;
        !            80: {
        !            81:        register struct ifnet *ifp;
        !            82:        register struct ifaddr *ifa;
        !            83: 
        !            84: #define        equal(a1, a2) \
        !            85:        (bcmp((caddr_t)((a1)->sa_data), (caddr_t)((a2)->sa_data), 14) == 0)
        !            86:        for (ifp = ifnet; ifp; ifp = ifp->if_next)
        !            87:            for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {
        !            88:                if (ifa->ifa_addr.sa_family != addr->sa_family)
        !            89:                        continue;
        !            90:                if (equal(&ifa->ifa_addr, addr))
        !            91:                        return (ifa);
        !            92:                if ((ifp->if_flags & IFF_BROADCAST) &&
        !            93:                    equal(&ifa->ifa_broadaddr, addr))
        !            94:                        return (ifa);
        !            95:        }
        !            96:        return ((struct ifaddr *)0);
        !            97: }
        !            98: /*
        !            99:  * Locate the point to point interface with a given destination address.
        !           100:  */
        !           101: /*ARGSUSED*/
        !           102: struct ifaddr *
        !           103: ifa_ifwithdstaddr(addr)
        !           104:        struct sockaddr *addr;
        !           105: {
        !           106:        register struct ifnet *ifp;
        !           107:        register struct ifaddr *ifa;
        !           108: 
        !           109:        for (ifp = ifnet; ifp; ifp = ifp->if_next) 
        !           110:            if (ifp->if_flags & IFF_POINTOPOINT)
        !           111:                for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {
        !           112:                        if (ifa->ifa_addr.sa_family != addr->sa_family)
        !           113:                                continue;
        !           114:                        if (equal(&ifa->ifa_dstaddr, addr))
        !           115:                                return (ifa);
        !           116:        }
        !           117:        return ((struct ifaddr *)0);
        !           118: }
        !           119: 
        !           120: /*
        !           121:  * Find an interface on a specific network.  If many, choice
        !           122:  * is first found.
        !           123:  */
        !           124: struct ifaddr *
        !           125: ifa_ifwithnet(addr)
        !           126:        register struct sockaddr *addr;
        !           127: {
        !           128:        register struct ifnet *ifp;
        !           129:        register struct ifaddr *ifa;
        !           130:        register u_int af = addr->sa_family;
        !           131:        register int (*netmatch)();
        !           132: 
        !           133:        if (af >= AF_MAX)
        !           134:                return (0);
        !           135:        netmatch = afswitch[af].af_netmatch;
        !           136:        for (ifp = ifnet; ifp; ifp = ifp->if_next)
        !           137:            for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {
        !           138:                if (ifa->ifa_addr.sa_family != addr->sa_family)
        !           139:                        continue;
        !           140:                if ((*netmatch)(&ifa->ifa_addr, addr))
        !           141:                        return (ifa);
        !           142:        }
        !           143:        return ((struct ifaddr *)0);
        !           144: }
        !           145: 
        !           146: #ifdef notdef
        !           147: /*
        !           148:  * Find an interface using a specific address family
        !           149:  */
        !           150: struct ifaddr *
        !           151: ifa_ifwithaf(af)
        !           152:        register int af;
        !           153: {
        !           154:        register struct ifnet *ifp;
        !           155:        register struct ifaddr *ifa;
        !           156: 
        !           157:        for (ifp = ifnet; ifp; ifp = ifp->if_next)
        !           158:            for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
        !           159:                if (ifa->ifa_addr.sa_family == af)
        !           160:                        return (ifa);
        !           161:        return ((struct ifaddr *)0);
        !           162: }
        !           163: #endif
        !           164: 
        !           165: /*
        !           166:  * Mark an interface down and notify protocols of
        !           167:  * the transition.
        !           168:  * NOTE: must be called at splnet or eqivalent.
        !           169:  */
        !           170: if_down(ifp)
        !           171:        register struct ifnet *ifp;
        !           172: {
        !           173:        register struct ifaddr *ifa;
        !           174: 
        !           175:        ifp->if_flags &= ~IFF_UP;
        !           176:        for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
        !           177:                pfctlinput(PRC_IFDOWN, &ifa->ifa_addr);
        !           178: }
        !           179: 
        !           180: /*
        !           181:  * Handle interface watchdog timer routines.  Called
        !           182:  * from softclock, we decrement timers (if set) and
        !           183:  * call the appropriate interface routine on expiration.
        !           184:  */
        !           185: if_slowtimo()
        !           186: {
        !           187:        register struct ifnet *ifp;
        !           188: 
        !           189:        for (ifp = ifnet; ifp; ifp = ifp->if_next) {
        !           190:                if (ifp->if_timer == 0 || --ifp->if_timer)
        !           191:                        continue;
        !           192:                if (ifp->if_watchdog)
        !           193:                        (*ifp->if_watchdog)(ifp->if_unit);
        !           194:        }
        !           195:        timeout(if_slowtimo, (caddr_t)0, hz / IFNET_SLOWHZ);
        !           196: }
        !           197: 
        !           198: /*
        !           199:  * Map interface name to
        !           200:  * interface structure pointer.
        !           201:  */
        !           202: struct ifnet *
        !           203: ifunit(name)
        !           204:        register char *name;
        !           205: {
        !           206:        register char *cp;
        !           207:        register struct ifnet *ifp;
        !           208:        int unit;
        !           209: 
        !           210:        for (cp = name; cp < name + IFNAMSIZ && *cp; cp++)
        !           211:                if (*cp >= '0' && *cp <= '9')
        !           212:                        break;
        !           213:        if (*cp == '\0' || cp == name + IFNAMSIZ)
        !           214:                return ((struct ifnet *)0);
        !           215:        unit = *cp - '0';
        !           216:        for (ifp = ifnet; ifp; ifp = ifp->if_next) {
        !           217:                if (bcmp(ifp->if_name, name, (unsigned)(cp - name)))
        !           218:                        continue;
        !           219:                if (unit == ifp->if_unit)
        !           220:                        break;
        !           221:        }
        !           222:        return (ifp);
        !           223: }
        !           224: 
        !           225: /*
        !           226:  * Interface ioctls.
        !           227:  */
        !           228: ifioctl(so, cmd, data)
        !           229:        struct socket *so;
        !           230:        int cmd;
        !           231:        caddr_t data;
        !           232: {
        !           233:        register struct ifnet *ifp;
        !           234:        register struct ifreq *ifr;
        !           235: 
        !           236:        switch (cmd) {
        !           237: 
        !           238:        case SIOCGIFCONF:
        !           239:                return (ifconf(cmd, data));
        !           240: 
        !           241: #if defined(INET) && NETHER > 0
        !           242:        case SIOCSARP:
        !           243:        case SIOCDARP:
        !           244:                if (!suser())
        !           245:                        return (u.u_error);
        !           246:                /* FALL THROUGH */
        !           247:        case SIOCGARP:
        !           248:                return (arpioctl(cmd, data));
        !           249: #endif
        !           250:        }
        !           251:        ifr = (struct ifreq *)data;
        !           252:        ifp = ifunit(ifr->ifr_name);
        !           253:        if (ifp == 0)
        !           254:                return (ENXIO);
        !           255:        switch (cmd) {
        !           256: 
        !           257:        case SIOCGIFFLAGS:
        !           258:                ifr->ifr_flags = ifp->if_flags;
        !           259:                break;
        !           260: 
        !           261:        case SIOCGIFMETRIC:
        !           262:                ifr->ifr_metric = ifp->if_metric;
        !           263:                break;
        !           264: 
        !           265:        case SIOCSIFFLAGS:
        !           266:                if (!suser())
        !           267:                        return (u.u_error);
        !           268:                if (ifp->if_flags & IFF_UP && (ifr->ifr_flags & IFF_UP) == 0) {
        !           269:                        int s = splimp();
        !           270:                        if_down(ifp);
        !           271:                        splx(s);
        !           272:                }
        !           273:                ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) |
        !           274:                        (ifr->ifr_flags &~ IFF_CANTCHANGE);
        !           275:                if (ifp->if_ioctl)
        !           276:                        (void) (*ifp->if_ioctl)(ifp, cmd, data);
        !           277:                break;
        !           278: 
        !           279:        case SIOCSIFMETRIC:
        !           280:                if (!suser())
        !           281:                        return (u.u_error);
        !           282:                ifp->if_metric = ifr->ifr_metric;
        !           283:                break;
        !           284: 
        !           285:        default:
        !           286:                if (so->so_proto == 0)
        !           287:                        return (EOPNOTSUPP);
        !           288:                return ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
        !           289:                        cmd, data, ifp));
        !           290:        }
        !           291:        return (0);
        !           292: }
        !           293: 
        !           294: /*
        !           295:  * Return interface configuration
        !           296:  * of system.  List may be used
        !           297:  * in later ioctl's (above) to get
        !           298:  * other information.
        !           299:  */
        !           300: /*ARGSUSED*/
        !           301: ifconf(cmd, data)
        !           302:        int cmd;
        !           303:        caddr_t data;
        !           304: {
        !           305:        register struct ifconf *ifc = (struct ifconf *)data;
        !           306:        register struct ifnet *ifp = ifnet;
        !           307:        register struct ifaddr *ifa;
        !           308:        register char *cp, *ep;
        !           309:        struct ifreq ifr, *ifrp;
        !           310:        int space = ifc->ifc_len, error = 0;
        !           311: 
        !           312:        ifrp = ifc->ifc_req;
        !           313:        ep = ifr.ifr_name + sizeof (ifr.ifr_name) - 2;
        !           314:        for (; space > sizeof (ifr) && ifp; ifp = ifp->if_next) {
        !           315:                bcopy(ifp->if_name, ifr.ifr_name, sizeof (ifr.ifr_name) - 2);
        !           316:                for (cp = ifr.ifr_name; cp < ep && *cp; cp++)
        !           317:                        ;
        !           318:                *cp++ = '0' + ifp->if_unit; *cp = '\0';
        !           319:                if ((ifa = ifp->if_addrlist) == 0) {
        !           320:                        bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
        !           321:                        error = copyout((caddr_t)&ifr, (caddr_t)ifrp, sizeof (ifr));
        !           322:                        if (error)
        !           323:                                break;
        !           324:                        space -= sizeof (ifr), ifrp++;
        !           325:                } else 
        !           326:                    for ( ; space > sizeof (ifr) && ifa; ifa = ifa->ifa_next) {
        !           327:                        ifr.ifr_addr = ifa->ifa_addr;
        !           328:                        error = copyout((caddr_t)&ifr, (caddr_t)ifrp, sizeof (ifr));
        !           329:                        if (error)
        !           330:                                break;
        !           331:                        space -= sizeof (ifr), ifrp++;
        !           332:                }
        !           333:        }
        !           334:        ifc->ifc_len -= space;
        !           335:        return (error);
        !           336: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.