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