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

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"
1.1.1.2 ! root       12: #include "../h/mbuf.h"
1.1       root       13: 
                     14: #include "../net/if.h"
                     15: #include "../net/af.h"
1.1.1.2 ! root       16: #include "../net/route.h"
1.1       root       17: 
                     18: int    ifqmaxlen = IFQ_MAXLEN;
                     19: 
                     20: /*
                     21:  * Change:
                     22:  *     . Add the check to make sure that only superuser can
                     23:  *       assign Ethernet station address with ioctl(SIOCSETETADDR).
1.1.1.2 ! root       24:  *     . 01/15/86. Add new ioctl SIOCGETETADDR
        !            25:  *     . 01/15/86. if_ifwithnet(), if_ifwithaddr(): Add check for whether
        !            26:  *       an interface is up before qualifying it for further tests.
        !            27:  *     . 01/19/86. Add new routine if_ifptop(). See description below.
        !            28:  *     . 01/22/86. if_down(). Delete routing entry for inactive interface.
        !            29:  *     . 01/22/86. if_ioctl(). Add new routing entry for an inactive interface
        !            30:  *                 which is being brought up.
1.1       root       31:  */
                     32: 
                     33: /*
                     34:  * Network interface utility routines.
                     35:  *
                     36:  * Routines with if_ifwith* names take sockaddr *'s as
                     37:  * parameters.  Other routines take value parameters,
                     38:  * e.g. if_ifwithnet takes the network number.
                     39:  */
                     40: 
                     41: ifinit()
                     42: {
                     43:        register struct ifnet *ifp;
                     44: 
                     45:        for (ifp = ifnet; ifp; ifp = ifp->if_next)
                     46:                if (ifp->if_init) {
                     47:                        (*ifp->if_init)(ifp->if_unit);
                     48:                        if (ifp->if_snd.ifq_maxlen == 0)
                     49:                                ifp->if_snd.ifq_maxlen = ifqmaxlen;
                     50:                }
                     51:        if_slowtimo();
                     52: }
                     53: 
                     54: #ifdef vax
                     55: /*
                     56:  * Call each interface on a Unibus reset.
                     57:  */
                     58: ifubareset(uban)
                     59:        int uban;
                     60: {
                     61:        register struct ifnet *ifp;
                     62: 
                     63:        for (ifp = ifnet; ifp; ifp = ifp->if_next)
                     64:                if (ifp->if_reset)
                     65:                        (*ifp->if_reset)(ifp->if_unit, uban);
                     66: }
                     67: #endif
                     68: 
                     69: /*
                     70:  * Attach an interface to the
                     71:  * list of "active" interfaces.
                     72:  */
                     73: if_attach(ifp)
                     74:        struct ifnet *ifp;
                     75: {
                     76:        register struct ifnet **p = &ifnet;
                     77: 
                     78:        while (*p)
                     79:                p = &((*p)->if_next);
                     80:        *p = ifp;
                     81: }
                     82: 
                     83: /*
                     84:  * Detach an interface from the
                     85:  * list of "active" interfaces.
                     86:  */
                     87: if_detach(ifp)
                     88:        struct ifnet *ifp;
                     89: {
                     90:        short   s = splimp();
                     91:        register struct ifnet **p = &ifnet;
1.1.1.2 ! root       92:        register struct mbuf *m;
1.1       root       93: 
                     94:        while (*p) {
                     95:                if ((*p) == ifp) {
1.1.1.2 ! root       96:                        /* Deallocate output bufs */
        !            97:                        while (ifp->if_snd.ifq_head) {
        !            98:                                IF_DEQUEUE(&ifp->if_snd, m)
        !            99:                                m_freem(m);
        !           100:                        }
1.1       root      101:                        (*p) = (struct ifnet *)ifp->if_next;
                    102:                        ifp->if_next = (struct ifnet *)0;
                    103:                        break;
                    104:                }
                    105:                else p = &((*p)->if_next);
                    106:        }
                    107: 
                    108:        splx(s);
                    109: }
                    110: 
                    111: /*
                    112:  * Locate an interface based on a complete address.
                    113:  */
                    114: /*ARGSUSED*/
                    115: struct ifnet *
                    116: if_ifwithaddr(addr)
                    117:        struct sockaddr *addr;
                    118: {
                    119:        register struct ifnet *ifp;
                    120: 
                    121: #define        equal(a1, a2) \
                    122:        (bcmp((caddr_t)((a1)->sa_data), (caddr_t)((a2)->sa_data), 14) == 0)
                    123:        for (ifp = ifnet; ifp; ifp = ifp->if_next) {
1.1.1.2 ! root      124:                if ((ifp->if_addr.sa_family != addr->sa_family) ||
        !           125:                    !(ifp->if_flags & IFF_UP))
1.1       root      126:                        continue;
                    127:                if (equal(&ifp->if_addr, addr))
                    128:                        break;
                    129:                if ((ifp->if_flags & IFF_BROADCAST) &&
                    130:                    equal(&ifp->if_broadaddr, addr))
                    131:                        break;
                    132:        }
                    133:        return (ifp);
                    134: }
                    135: 
                    136: /*
                    137:  * Find an interface on a specific network.  If many, choice
                    138:  * is first found.
                    139:  */
                    140: struct ifnet *
                    141: if_ifwithnet(addr)
                    142:        register struct sockaddr *addr;
                    143: {
                    144:        register struct ifnet *ifp;
                    145:        register u_int af = addr->sa_family;
                    146:        register int (*netmatch)();
                    147: 
                    148:        if (af >= AF_MAX)
                    149:                return (0);
                    150:        netmatch = afswitch[af].af_netmatch;
                    151:        for (ifp = ifnet; ifp; ifp = ifp->if_next) {
1.1.1.2 ! root      152:                if ((af != ifp->if_addr.sa_family) || !(ifp->if_flags & IFF_UP))
1.1       root      153:                        continue;
                    154:                if ((*netmatch)(addr, &ifp->if_addr))
                    155:                        break;
                    156:        }
                    157:        return (ifp);
                    158: }
                    159: 
                    160: /*
                    161:  * As above, but parameter is network number.
                    162:  */
                    163: struct ifnet *
                    164: if_ifonnetof(net)
                    165:        register int net;
                    166: {
                    167:        register struct ifnet *ifp;
                    168: 
                    169:        for (ifp = ifnet; ifp; ifp = ifp->if_next)
                    170:                if (ifp->if_net == net)
                    171:                        break;
                    172:        return (ifp);
                    173: }
                    174: 
                    175: /*
                    176:  * Find an interface using a specific address family
                    177:  */
                    178: struct ifnet *
                    179: if_ifwithaf(af)
                    180:        register int af;
                    181: {
                    182:        register struct ifnet *ifp;
                    183: 
                    184:        for (ifp = ifnet; ifp; ifp = ifp->if_next)
                    185:                if (ifp->if_addr.sa_family == af)
                    186:                        break;
                    187:        return (ifp);
                    188: }
                    189: 
                    190: /*
                    191:  * Mark an interface down and notify protocols of
                    192:  * the transition.
1.1.1.2 ! root      193:  * NOTE: must be called at splnet or equivalent.
1.1       root      194:  */
                    195: if_down(ifp)
                    196:        register struct ifnet *ifp;
                    197: {
                    198: 
                    199:        ifp->if_flags &= ~IFF_UP;
                    200:        pfctlinput(PRC_IFDOWN, (caddr_t)&ifp->if_addr);
1.1.1.2 ! root      201:        if_rtinit(ifp, -1);     /* delete routing entry */
1.1       root      202: }
                    203: 
                    204: /*
                    205:  * Handle interface watchdog timer routines.  Called
                    206:  * from softclock, we decrement timers (if set) and
                    207:  * call the appropriate interface routine on expiration.
                    208:  */
                    209: if_slowtimo()
                    210: {
                    211:        register struct ifnet *ifp;
                    212: 
                    213:        for (ifp = ifnet; ifp; ifp = ifp->if_next) {
                    214:                if (ifp->if_timer == 0 || --ifp->if_timer)
                    215:                        continue;
                    216:                if (ifp->if_watchdog)
                    217:                        (*ifp->if_watchdog)(ifp->if_unit);
                    218:        }
                    219:        timeout(if_slowtimo, (caddr_t)0, hz / IFNET_SLOWHZ);
                    220: }
                    221: 
                    222: /*
                    223:  * Map interface name to
                    224:  * interface structure pointer.
                    225:  */
                    226: struct ifnet *
                    227: ifunit(name)
                    228:        register char *name;
                    229: {
                    230:        register char *cp;
                    231:        register struct ifnet *ifp;
                    232:        int unit;
                    233: 
                    234:        for (cp = name; cp < name + IFNAMSIZ && *cp; cp++)
                    235:                if (*cp >= '0' && *cp <= '9')
                    236:                        break;
                    237:        if (*cp == '\0' || cp == name + IFNAMSIZ)
                    238:                return ((struct ifnet *)0);
                    239:        unit = *cp - '0', *cp = 0;
                    240:        for (ifp = ifnet; ifp; ifp = ifp->if_next) {
                    241:                if (bcmp(ifp->if_name, name, (unsigned)(cp - name)))
                    242:                        continue;
                    243:                if (unit == ifp->if_unit)
                    244:                        break;
                    245:        }
                    246:        return (ifp);
                    247: }
                    248: 
                    249: /*
                    250:  * Interface ioctls.
                    251:  */
                    252: ifioctl(cmd, data)
                    253:        int cmd;
                    254:        caddr_t data;
                    255: {
                    256:        register struct ifnet *ifp;
                    257:        register struct ifreq *ifr;
                    258: 
                    259:        switch (cmd) {
                    260: 
                    261:        case SIOCGIFCONF:
                    262:                return (ifconf(cmd, data));
                    263: 
                    264:        case SIOCSIFADDR:
                    265:        case SIOCSIFFLAGS:
                    266:        case SIOCSIFDSTADDR:
                    267:        case SIOCSETETADDR:
1.1.1.2 ! root      268:        case SIOCIFDETACH:
1.1       root      269:                if (!suser())
                    270:                        return (u.u_error);
1.1.1.2 ! root      271:        case SIOCGETETADDR:
        !           272:        default:
1.1       root      273:                break;
                    274:        }
                    275:        ifr = (struct ifreq *)data;
                    276:        ifp = ifunit(ifr->ifr_name);
                    277:        if (ifp == 0)
                    278:                return (ENXIO);
                    279:        switch (cmd) {
                    280: 
                    281:        case SIOCGIFADDR:
                    282:                ifr->ifr_addr = ifp->if_addr;
                    283:                break;
                    284: 
                    285:        case SIOCGIFDSTADDR:
                    286:                if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
                    287:                        return (EINVAL);
                    288:                ifr->ifr_dstaddr = ifp->if_dstaddr;
                    289:                break;
                    290: 
                    291:        case SIOCGIFFLAGS:
                    292:                ifr->ifr_flags = ifp->if_flags;
                    293:                break;
                    294: 
                    295:        case SIOCSIFFLAGS:
                    296:                if (ifp->if_flags & IFF_UP && (ifr->ifr_flags & IFF_UP) == 0) {
                    297:                        int s = splimp();
                    298:                        if_down(ifp);
                    299:                        splx(s);
                    300:                }
1.1.1.2 ! root      301:                /* 
        !           302:                 * if interface was inactive and being brought up now,
        !           303:                 * We should add routing entry for it because its old entry
        !           304:                 * was deleted when we brought it down earlier.
        !           305:                 */ 
        !           306:                if (!(ifp->if_flags & IFF_UP) && (ifr->ifr_flags & IFF_UP))
        !           307:                        if_rtinit(ifp, RTF_UP);
1.1       root      308:                ifp->if_flags = ifr->ifr_flags;
                    309:                break;
                    310: 
                    311:        default:
                    312:                if (ifp->if_ioctl == 0)
                    313:                        return (EOPNOTSUPP);
                    314:                return ((*ifp->if_ioctl)(ifp, cmd, data));
                    315:        }
                    316:        return (0);
                    317: }
                    318: 
                    319: /*
                    320:  * Return interface configuration
                    321:  * of system.  List may be used
                    322:  * in later ioctl's (above) to get
                    323:  * other information.
                    324:  */
                    325: /*ARGSUSED*/
                    326: ifconf(cmd, data)
                    327:        int cmd;
                    328:        caddr_t data;
                    329: {
                    330:        register struct ifconf *ifc = (struct ifconf *)data;
                    331:        register struct ifnet *ifp = ifnet;
                    332:        register char *cp, *ep;
                    333:        struct ifreq ifr, *ifrp;
                    334:        int space = ifc->ifc_len, error = 0;
                    335: 
                    336:        ifrp = ifc->ifc_req;
                    337:        ep = ifr.ifr_name + sizeof (ifr.ifr_name) - 2;
                    338:        for (; space > sizeof (ifr) && ifp; ifp = ifp->if_next) {
                    339:                bcopy(ifp->if_name, ifr.ifr_name, sizeof (ifr.ifr_name) - 2);
                    340:                for (cp = ifr.ifr_name; cp < ep && *cp; cp++)
                    341:                        ;
                    342:                *cp++ = '0' + ifp->if_unit; *cp = '\0';
                    343:                ifr.ifr_addr = ifp->if_addr;
                    344:                error = copyout((caddr_t)&ifr, (caddr_t)ifrp, sizeof (ifr));
                    345:                if (error)
                    346:                        break;
                    347:                space -= sizeof (ifr), ifrp++;
                    348:        }
                    349:        ifc->ifc_len -= space;
                    350:        return (error);
                    351: }
1.1.1.2 ! root      352: /*
        !           353:  *     Search for a point-to-point link connected to 
        !           354:  *     (destination or gateway) host.
        !           355:  */
        !           356: struct ifnet *
        !           357: if_ifptop(rt)
        !           358: register struct rtentry *rt;
        !           359: {
        !           360:    register struct ifnet *ifp;
        !           361: 
        !           362:        /* When adding a route that use POINTTOPOINT interface, we
        !           363:           give priority to a direct connection before looking for
        !           364:           a gateway.
        !           365:        */
        !           366:        for (ifp = ifnet; ifp; ifp = ifp->if_next) {
        !           367:                if (ifp->if_addr.sa_family != rt->rt_dst.sa_family ||
        !           368:                    !(ifp->if_flags&IFF_UP))
        !           369:                        continue;
        !           370:                if ((ifp->if_flags & IFF_POINTOPOINT) &&
        !           371:                        (bcmp(ifp->if_dstaddr.sa_data,
        !           372:                                rt->rt_dst.sa_data, 14) == 0 ))
        !           373:                        break;
        !           374:        }
        !           375:        if (ifp == 0) {
        !           376:                for (ifp = ifnet; ifp; ifp = ifp->if_next) {
        !           377:                        if (ifp->if_addr.sa_family != 
        !           378:                                rt->rt_dst.sa_family ||
        !           379:                                        !(ifp->if_flags&IFF_UP))
        !           380:                                continue;
        !           381:                        if ((ifp->if_flags & IFF_POINTOPOINT) &&
        !           382:                                (bcmp(ifp->if_dstaddr.sa_data, 
        !           383:                                   rt->rt_gateway.sa_data, 14) == 0))
        !           384:                        break;
        !           385:                }
        !           386:        }
        !           387:    return(ifp);
        !           388: }
        !           389: 

unix.superglobalmegacorp.com

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