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

unix.superglobalmegacorp.com

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