Annotation of cci/sys/net/if.c, revision 1.1

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

unix.superglobalmegacorp.com

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