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

unix.superglobalmegacorp.com

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