Annotation of cci/sys/net/if.c, revision 1.1.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.