Annotation of 43BSDReno/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 is only permitted until one year after the first shipment
                      6:  * of 4.4BSD by the Regents.  Otherwise, redistribution and use in source and
                      7:  * binary forms are permitted provided that: (1) source distributions retain
                      8:  * this entire copyright notice and comment, and (2) distributions including
                      9:  * binaries display the following acknowledgement:  This product includes
                     10:  * software developed by the University of California, Berkeley and its
                     11:  * contributors'' in the documentation or other materials provided with the
                     12:  * distribution and in all advertising materials mentioning features or use
                     13:  * of this software.  Neither the name of the University nor the names of
                     14:  * its contributors may be used to endorse or promote products derived from
                     15:  * this software without specific prior written permission.
                     16:  * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
                     17:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
                     18:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     19:  *
                     20:  *     @(#)if.c        7.13 (Berkeley) 6/28/90
                     21:  */
                     22: 
                     23: #include "param.h"
                     24: #include "mbuf.h"
                     25: #include "systm.h"
                     26: #include "socket.h"
                     27: #include "socketvar.h"
                     28: #include "protosw.h"
                     29: #include "user.h"
                     30: #include "kernel.h"
                     31: #include "ioctl.h"
                     32: #include "errno.h"
                     33: 
                     34: #include "if.h"
                     35: #include "af.h"
                     36: #include "if_dl.h"
                     37: #include "if_types.h"
                     38: 
                     39: #include "ether.h"
                     40: 
                     41: int    ifqmaxlen = IFQ_MAXLEN;
                     42: 
                     43: /*
                     44:  * Network interface utility routines.
                     45:  *
                     46:  * Routines with ifa_ifwith* names take sockaddr *'s as
                     47:  * parameters.
                     48:  */
                     49: 
                     50: ifinit()
                     51: {
                     52:        register struct ifnet *ifp;
                     53: 
                     54:        for (ifp = ifnet; ifp; ifp = ifp->if_next)
                     55:                if (ifp->if_snd.ifq_maxlen == 0)
                     56:                        ifp->if_snd.ifq_maxlen = ifqmaxlen;
                     57:        if_slowtimo();
                     58: }
                     59: 
                     60: #ifdef vax
                     61: /*
                     62:  * Call each interface on a Unibus reset.
                     63:  */
                     64: ifubareset(uban)
                     65:        int uban;
                     66: {
                     67:        register struct ifnet *ifp;
                     68: 
                     69:        for (ifp = ifnet; ifp; ifp = ifp->if_next)
                     70:                if (ifp->if_reset)
                     71:                        (*ifp->if_reset)(ifp->if_unit, uban);
                     72: }
                     73: #endif
                     74: 
                     75: int if_index = 0;
                     76: struct ifaddr **ifnet_addrs;
                     77: /*
                     78:  * Attach an interface to the
                     79:  * list of "active" interfaces.
                     80:  */
                     81: if_attach(ifp)
                     82:        struct ifnet *ifp;
                     83: {
                     84:        unsigned socksize, ifasize;
                     85:        int namelen, unitlen;
                     86:        char workbuf[16];
                     87:        register struct ifnet **p = &ifnet;
                     88:        register struct sockaddr_dl *sdl;
                     89:        register struct ifaddr *ifa;
                     90:        static int if_indexlim = 8;
                     91:        extern link_rtrequest(), ether_output();
                     92: 
                     93:        while (*p)
                     94:                p = &((*p)->if_next);
                     95:        *p = ifp;
                     96:        ifp->if_index = ++if_index;
                     97:        if (ifnet_addrs == 0 || if_index >= if_indexlim) {
                     98:                unsigned n = (if_indexlim <<= 1) * sizeof(ifa);
                     99:                struct ifaddr **q = (struct ifaddr **)
                    100:                                        malloc(n, M_IFADDR, M_WAITOK);
                    101:                if (ifnet_addrs) {
                    102:                        bcopy((caddr_t)ifnet_addrs, (caddr_t)q, n/2);
                    103:                        free((caddr_t)ifnet_addrs, M_IFADDR);
                    104:                }
                    105:                ifnet_addrs = q;
                    106:        }
                    107:        /* XXX -- Temporary fix before changing 10 ethernet drivers */
                    108:        if (ifp->if_output == ether_output) {
                    109:                ifp->if_type = IFT_ETHER;
                    110:                ifp->if_addrlen = 6;
                    111:                ifp->if_hdrlen = 14;
                    112:        }
                    113:        /*
                    114:         * create a Link Level name for this device
                    115:         */
                    116:        sprint_d(workbuf, ifp->if_unit);
                    117:        namelen = strlen(ifp->if_name);
                    118:        unitlen = strlen(workbuf);
                    119: #define _offsetof(t, m) ((int)((caddr_t)&((t *)0)->m))
                    120:        socksize = _offsetof(struct sockaddr_dl, sdl_data[0]) +
                    121:                               unitlen + namelen + ifp->if_addrlen;
                    122: #define ROUNDUP(a) (1 + (((a) - 1) | (sizeof(long) - 1)))
                    123:        socksize = ROUNDUP(socksize);
                    124:        if (socksize < sizeof(*sdl))
                    125:                socksize = sizeof(*sdl);
                    126:        ifasize = sizeof(*ifa) + 2 * socksize;
                    127:        ifa = (struct ifaddr *)malloc(ifasize, M_IFADDR, M_WAITOK);
                    128:        if (ifa == 0)
                    129:                return;
                    130:        ifnet_addrs[if_index - 1] = ifa;
                    131:        bzero((caddr_t)ifa, ifasize);
                    132:        sdl = (struct sockaddr_dl *)(ifa + 1);
                    133:        ifa->ifa_addr = (struct sockaddr *)sdl;
                    134:        ifa->ifa_ifp = ifp;
                    135:        sdl->sdl_len = socksize;
                    136:        sdl->sdl_family = AF_LINK;
                    137:        bcopy(ifp->if_name, sdl->sdl_data, namelen);
                    138:        bcopy((caddr_t)workbuf, namelen + (caddr_t)sdl->sdl_data, unitlen);
                    139:        sdl->sdl_nlen = (namelen += unitlen);
                    140:        sdl->sdl_index = ifp->if_index;
                    141:        sdl = (struct sockaddr_dl *)(socksize + (caddr_t)sdl);
                    142:        ifa->ifa_netmask = (struct sockaddr *)sdl;
                    143:        sdl->sdl_len = socksize - ifp->if_addrlen;
                    144:        while (namelen != 0)
                    145:                sdl->sdl_data[--namelen] = 0xff;
                    146:        ifa->ifa_next = ifp->if_addrlist;
                    147:        ifa->ifa_rtrequest = link_rtrequest;
                    148:        ifp->if_addrlist = ifa;
                    149: }
                    150: /*
                    151:  * Locate an interface based on a complete address.
                    152:  */
                    153: /*ARGSUSED*/
                    154: struct ifaddr *
                    155: ifa_ifwithaddr(addr)
                    156:        register struct sockaddr *addr;
                    157: {
                    158:        register struct ifnet *ifp;
                    159:        register struct ifaddr *ifa;
                    160: 
                    161: #define        equal(a1, a2) \
                    162:   (bcmp((caddr_t)(a1), (caddr_t)(a2), ((struct sockaddr *)(a1))->sa_len) == 0)
                    163:        for (ifp = ifnet; ifp; ifp = ifp->if_next)
                    164:            for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {
                    165:                if (ifa->ifa_addr->sa_family != addr->sa_family)
                    166:                        continue;
                    167:                if (equal(addr, ifa->ifa_addr))
                    168:                        return (ifa);
                    169:                if ((ifp->if_flags & IFF_BROADCAST) && ifa->ifa_broadaddr &&
                    170:                    equal(ifa->ifa_broadaddr, addr))
                    171:                        return (ifa);
                    172:        }
                    173:        return ((struct ifaddr *)0);
                    174: }
                    175: /*
                    176:  * Locate the point to point interface with a given destination address.
                    177:  */
                    178: /*ARGSUSED*/
                    179: struct ifaddr *
                    180: ifa_ifwithdstaddr(addr)
                    181:        register struct sockaddr *addr;
                    182: {
                    183:        register struct ifnet *ifp;
                    184:        register struct ifaddr *ifa;
                    185: 
                    186:        for (ifp = ifnet; ifp; ifp = ifp->if_next) 
                    187:            if (ifp->if_flags & IFF_POINTOPOINT)
                    188:                for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {
                    189:                        if (ifa->ifa_addr->sa_family != addr->sa_family)
                    190:                                continue;
                    191:                        if (equal(addr, ifa->ifa_dstaddr))
                    192:                                return (ifa);
                    193:        }
                    194:        return ((struct ifaddr *)0);
                    195: }
                    196: 
                    197: /*
                    198:  * Find an interface on a specific network.  If many, choice
                    199:  * is first found.
                    200:  */
                    201: struct ifaddr *
                    202: ifa_ifwithnet(addr)
                    203:        struct sockaddr *addr;
                    204: {
                    205:        register struct ifnet *ifp;
                    206:        register struct ifaddr *ifa;
                    207:        u_int af = addr->sa_family;
                    208: 
                    209:        if (af >= AF_MAX)
                    210:                return (0);
                    211:        if (af == AF_LINK) {
                    212:            register struct sockaddr_dl *sdl = (struct sockaddr_dl *)addr;
                    213:            if (sdl->sdl_index && sdl->sdl_index <= if_index)
                    214:                return (ifnet_addrs[sdl->sdl_index - 1]);
                    215:        }
                    216:        for (ifp = ifnet; ifp; ifp = ifp->if_next)
                    217:            for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {
                    218:                register char *cp, *cp2, *cp3;
                    219:                register char *cplim;
                    220:                if (ifa->ifa_addr->sa_family != af || ifa->ifa_netmask == 0)
                    221:                        continue;
                    222:                cp = addr->sa_data;
                    223:                cp2 = ifa->ifa_addr->sa_data;
                    224:                cp3 = ifa->ifa_netmask->sa_data;
                    225:                cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask;
                    226:                for (; cp3 < cplim; cp3++)
                    227:                        if ((*cp++ ^ *cp2++) & *cp3)
                    228:                                break;
                    229:                if (cp3 == cplim)
                    230:                        return (ifa);
                    231:            }
                    232:        return ((struct ifaddr *)0);
                    233: }
                    234: 
                    235: /*
                    236:  * Find an interface using a specific address family
                    237:  */
                    238: struct ifaddr *
                    239: ifa_ifwithaf(af)
                    240:        register int af;
                    241: {
                    242:        register struct ifnet *ifp;
                    243:        register struct ifaddr *ifa;
                    244: 
                    245:        for (ifp = ifnet; ifp; ifp = ifp->if_next)
                    246:            for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
                    247:                if (ifa->ifa_addr->sa_family == af)
                    248:                        return (ifa);
                    249:        return ((struct ifaddr *)0);
                    250: }
                    251: 
                    252: /*
                    253:  * Find an interface address specific to an interface best matching
                    254:  * a given address.
                    255:  */
                    256: struct ifaddr *
                    257: ifaof_ifpforaddr(addr, ifp)
                    258:        struct sockaddr *addr;
                    259:        register struct ifnet *ifp;
                    260: {
                    261:        register struct ifaddr *ifa;
                    262:        register char *cp, *cp2, *cp3;
                    263:        register char *cplim;
                    264:        struct ifaddr *ifa_maybe = 0;
                    265:        u_int af = addr->sa_family;
                    266: 
                    267:        if (af >= AF_MAX)
                    268:                return (0);
                    269:        for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {
                    270:                if (ifa->ifa_addr->sa_family != af)
                    271:                        continue;
                    272:                ifa_maybe = ifa;
                    273:                if (ifa->ifa_netmask == 0) {
                    274:                        if (equal(addr, ifa->ifa_addr) ||
                    275:                            (ifa->ifa_dstaddr && equal(addr, ifa->ifa_dstaddr)))
                    276:                                return (ifa);
                    277:                        continue;
                    278:                }
                    279:                cp = addr->sa_data;
                    280:                cp2 = ifa->ifa_addr->sa_data;
                    281:                cp3 = ifa->ifa_netmask->sa_data;
                    282:                cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask;
                    283:                for (; cp3 < cplim; cp3++)
                    284:                        if ((*cp++ ^ *cp2++) & *cp3)
                    285:                                break;
                    286:                if (cp3 == cplim)
                    287:                        return (ifa);
                    288:        }
                    289:        return (ifa_maybe);
                    290: }
                    291: #include "route.h"
                    292: /*
                    293:  * Default action when installing a route with a Link Level gateway.
                    294:  * Lookup an appropriate real ifa to point to.
                    295:  * This should be moved to /sys/net/link.c eventually.
                    296:  */
                    297: link_rtrequest(cmd, rt, sa)
                    298: register struct rtentry *rt;
                    299: struct sockaddr *sa;
                    300: {
                    301:        register struct ifaddr *ifa;
                    302:        struct sockaddr *dst;
                    303:        struct ifnet *ifp, *oldifnet = ifnet;
                    304: 
                    305:        if (cmd != RTM_ADD || ((ifa = rt->rt_ifa) == 0) ||
                    306:            ((ifp = ifa->ifa_ifp) == 0) || ((dst = rt_key(rt)) == 0))
                    307:                return;
                    308:        if (ifa = ifaof_ifpforaddr(dst, ifp)) {
                    309:                rt->rt_ifa = ifa;
                    310:                if (ifa->ifa_rtrequest && ifa->ifa_rtrequest != link_rtrequest)
                    311:                        ifa->ifa_rtrequest(cmd, rt, sa);
                    312:        }
                    313: }
                    314: 
                    315: /*
                    316:  * Mark an interface down and notify protocols of
                    317:  * the transition.
                    318:  * NOTE: must be called at splnet or eqivalent.
                    319:  */
                    320: if_down(ifp)
                    321:        register struct ifnet *ifp;
                    322: {
                    323:        register struct ifaddr *ifa;
                    324: 
                    325:        ifp->if_flags &= ~IFF_UP;
                    326:        for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
                    327:                pfctlinput(PRC_IFDOWN, ifa->ifa_addr);
                    328:        if_qflush(&ifp->if_snd);
                    329: }
                    330: 
                    331: /*
                    332:  * Flush an interface queue.
                    333:  */
                    334: if_qflush(ifq)
                    335:        register struct ifqueue *ifq;
                    336: {
                    337:        register struct mbuf *m, *n;
                    338: 
                    339:        n = ifq->ifq_head;
                    340:        while (m = n) {
                    341:                n = m->m_act;
                    342:                m_freem(m);
                    343:        }
                    344:        ifq->ifq_head = 0;
                    345:        ifq->ifq_tail = 0;
                    346:        ifq->ifq_len = 0;
                    347: }
                    348: 
                    349: /*
                    350:  * Handle interface watchdog timer routines.  Called
                    351:  * from softclock, we decrement timers (if set) and
                    352:  * call the appropriate interface routine on expiration.
                    353:  */
                    354: if_slowtimo()
                    355: {
                    356:        register struct ifnet *ifp;
                    357:        int s = splimp();
                    358: 
                    359:        for (ifp = ifnet; ifp; ifp = ifp->if_next) {
                    360:                if (ifp->if_timer == 0 || --ifp->if_timer)
                    361:                        continue;
                    362:                if (ifp->if_watchdog)
                    363:                        (*ifp->if_watchdog)(ifp->if_unit);
                    364:        }
                    365:        splx(s);
                    366:        timeout(if_slowtimo, (caddr_t)0, hz / IFNET_SLOWHZ);
                    367: }
                    368: 
                    369: /*
                    370:  * Map interface name to
                    371:  * interface structure pointer.
                    372:  */
                    373: struct ifnet *
                    374: ifunit(name)
                    375:        register char *name;
                    376: {
                    377:        register char *cp;
                    378:        register struct ifnet *ifp;
                    379:        int unit;
                    380:        unsigned len;
                    381:        char *ep, c;
                    382: 
                    383:        for (cp = name; cp < name + IFNAMSIZ && *cp; cp++)
                    384:                if (*cp >= '0' && *cp <= '9')
                    385:                        break;
                    386:        if (*cp == '\0' || cp == name + IFNAMSIZ)
                    387:                return ((struct ifnet *)0);
                    388:        /*
                    389:         * Save first char of unit, and pointer to it,
                    390:         * so we can put a null there to avoid matching
                    391:         * initial substrings of interface names.
                    392:         */
                    393:        len = cp - name + 1;
                    394:        c = *cp;
                    395:        ep = cp;
                    396:        for (unit = 0; *cp >= '0' && *cp <= '9'; )
                    397:                unit = unit * 10 + *cp++ - '0';
                    398:        *ep = 0;
                    399:        for (ifp = ifnet; ifp; ifp = ifp->if_next) {
                    400:                if (bcmp(ifp->if_name, name, len))
                    401:                        continue;
                    402:                if (unit == ifp->if_unit)
                    403:                        break;
                    404:        }
                    405:        *ep = c;
                    406:        return (ifp);
                    407: }
                    408: 
                    409: /*
                    410:  * Interface ioctls.
                    411:  */
                    412: ifioctl(so, cmd, data)
                    413:        struct socket *so;
                    414:        int cmd;
                    415:        caddr_t data;
                    416: {
                    417:        register struct ifnet *ifp;
                    418:        register struct ifreq *ifr;
                    419:        int error;
                    420: 
                    421:        switch (cmd) {
                    422: 
                    423:        case SIOCGIFCONF:
                    424:        case OSIOCGIFCONF:
                    425:                return (ifconf(cmd, data));
                    426: 
                    427: #if defined(INET) && NETHER > 0
                    428:        case SIOCSARP:
                    429:        case SIOCDARP:
                    430:                if (error = suser(u.u_cred, &u.u_acflag))
                    431:                        return (error);
                    432:                /* FALL THROUGH */
                    433:        case SIOCGARP:
                    434:        case OSIOCGARP:
                    435:                return (arpioctl(cmd, data));
                    436: #endif
                    437:        }
                    438:        ifr = (struct ifreq *)data;
                    439:        ifp = ifunit(ifr->ifr_name);
                    440:        if (ifp == 0)
                    441:                return (ENXIO);
                    442:        switch (cmd) {
                    443: 
                    444:        case SIOCGIFFLAGS:
                    445:                ifr->ifr_flags = ifp->if_flags;
                    446:                break;
                    447: 
                    448:        case SIOCGIFMETRIC:
                    449:                ifr->ifr_metric = ifp->if_metric;
                    450:                break;
                    451: 
                    452:        case SIOCSIFFLAGS:
                    453:                if (error = suser(u.u_cred, &u.u_acflag))
                    454:                        return (error);
                    455:                if (ifp->if_flags & IFF_UP && (ifr->ifr_flags & IFF_UP) == 0) {
                    456:                        int s = splimp();
                    457:                        if_down(ifp);
                    458:                        splx(s);
                    459:                }
                    460:                ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) |
                    461:                        (ifr->ifr_flags &~ IFF_CANTCHANGE);
                    462:                if (ifp->if_ioctl)
                    463:                        (void) (*ifp->if_ioctl)(ifp, cmd, data);
                    464:                break;
                    465: 
                    466:        case SIOCSIFMETRIC:
                    467:                if (error = suser(u.u_cred, &u.u_acflag))
                    468:                        return (error);
                    469:                ifp->if_metric = ifr->ifr_metric;
                    470:                break;
                    471: 
                    472:        default:
                    473:                if (so->so_proto == 0)
                    474:                        return (EOPNOTSUPP);
                    475: #ifndef COMPAT_43
                    476:                return ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
                    477:                        cmd, data, ifp));
                    478: #else
                    479:            {
                    480:                int ocmd = cmd;
                    481: 
                    482:                switch (cmd) {
                    483: 
                    484:                case SIOCSIFDSTADDR:
                    485:                case SIOCSIFADDR:
                    486:                case SIOCSIFBRDADDR:
                    487:                case SIOCSIFNETMASK:
                    488: #if BYTE_ORDER != BIG_ENDIAN
                    489:                        if (ifr->ifr_addr.sa_family == 0 &&
                    490:                            ifr->ifr_addr.sa_len < 16) {
                    491:                                ifr->ifr_addr.sa_family = ifr->ifr_addr.sa_len;
                    492:                                ifr->ifr_addr.sa_len = 16;
                    493:                        }
                    494: #else
                    495:                        if (ifr->ifr_addr.sa_len == 0)
                    496:                                ifr->ifr_addr.sa_len = 16;
                    497: #endif
                    498:                        break;
                    499: 
                    500:                case OSIOCGIFADDR:
                    501:                        cmd = SIOCGIFADDR;
                    502:                        break;
                    503: 
                    504:                case OSIOCGIFDSTADDR:
                    505:                        cmd = SIOCGIFDSTADDR;
                    506:                        break;
                    507: 
                    508:                case OSIOCGIFBRDADDR:
                    509:                        cmd = SIOCGIFBRDADDR;
                    510:                        break;
                    511: 
                    512:                case OSIOCGIFNETMASK:
                    513:                        cmd = SIOCGIFNETMASK;
                    514:                }
                    515:                error =  ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
                    516:                                                            cmd, data, ifp));
                    517:                switch (ocmd) {
                    518: 
                    519:                case OSIOCGIFADDR:
                    520:                case OSIOCGIFDSTADDR:
                    521:                case OSIOCGIFBRDADDR:
                    522:                case OSIOCGIFNETMASK:
                    523:                        *(u_short *)&ifr->ifr_addr = ifr->ifr_addr.sa_family;
                    524:                }
                    525:                return (error);
                    526: 
                    527:            }
                    528: #endif
                    529:        }
                    530:        return (0);
                    531: }
                    532: 
                    533: /*
                    534:  * Return interface configuration
                    535:  * of system.  List may be used
                    536:  * in later ioctl's (above) to get
                    537:  * other information.
                    538:  */
                    539: /*ARGSUSED*/
                    540: ifconf(cmd, data)
                    541:        int cmd;
                    542:        caddr_t data;
                    543: {
                    544:        register struct ifconf *ifc = (struct ifconf *)data;
                    545:        register struct ifnet *ifp = ifnet;
                    546:        register struct ifaddr *ifa;
                    547:        register char *cp, *ep;
                    548:        struct ifreq ifr, *ifrp;
                    549:        int space = ifc->ifc_len, error = 0;
                    550: 
                    551:        ifrp = ifc->ifc_req;
                    552:        ep = ifr.ifr_name + sizeof (ifr.ifr_name) - 2;
                    553:        for (; space > sizeof (ifr) && ifp; ifp = ifp->if_next) {
                    554:                bcopy(ifp->if_name, ifr.ifr_name, sizeof (ifr.ifr_name) - 2);
                    555:                for (cp = ifr.ifr_name; cp < ep && *cp; cp++)
                    556:                        ;
                    557:                *cp++ = '0' + ifp->if_unit; *cp = '\0';
                    558:                if ((ifa = ifp->if_addrlist) == 0) {
                    559:                        bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
                    560:                        error = copyout((caddr_t)&ifr, (caddr_t)ifrp, sizeof (ifr));
                    561:                        if (error)
                    562:                                break;
                    563:                        space -= sizeof (ifr), ifrp++;
                    564:                } else 
                    565:                    for ( ; space > sizeof (ifr) && ifa; ifa = ifa->ifa_next) {
                    566:                        register struct sockaddr *sa = ifa->ifa_addr;
                    567: #ifdef COMPAT_43
                    568:                        if (cmd == OSIOCGIFCONF) {
                    569:                                struct osockaddr *osa =
                    570:                                         (struct osockaddr *)&ifr.ifr_addr;
                    571:                                ifr.ifr_addr = *sa;
                    572:                                osa->sa_family = sa->sa_family;
                    573:                                error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
                    574:                                                sizeof (ifr));
                    575:                                ifrp++;
                    576:                        } else
                    577: #endif
                    578:                        if (sa->sa_len <= sizeof(*sa)) {
                    579:                                ifr.ifr_addr = *sa;
                    580:                                error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
                    581:                                                sizeof (ifr));
                    582:                                ifrp++;
                    583:                        } else {
                    584:                                space -= sa->sa_len - sizeof(*sa);
                    585:                                if (space < sizeof (ifr))
                    586:                                        break;
                    587:                                error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
                    588:                                                sizeof (ifr.ifr_name));
                    589:                                if (error == 0)
                    590:                                    error = copyout((caddr_t)sa,
                    591:                                      (caddr_t)&ifrp->ifr_addr, sa->sa_len);
                    592:                                ifrp = (struct ifreq *)
                    593:                                        (sa->sa_len + (caddr_t)&ifrp->ifr_addr);
                    594:                        }
                    595:                        if (error)
                    596:                                break;
                    597:                        space -= sizeof (ifr);
                    598:                }
                    599:        }
                    600:        ifc->ifc_len -= space;
                    601:        return (error);
                    602: }
                    603: 
                    604: static sprint_d(cp, n)
                    605: register char *cp;
                    606: u_short n;
                    607: {
                    608:        register int q, m;
                    609:        do {
                    610:            if (n >= 10000) m = 10000;
                    611:                else if (n >= 1000) m = 1000;
                    612:                else if (n >= 100) m = 100;
                    613:                else if (n >= 10) m = 10;
                    614:                else m = 1;
                    615:            q = n / m;
                    616:            n -= m * q;
                    617:            if (q > 9) q = 10; /* For crays with more than 100K interfaces */
                    618:            *cp++ = "0123456789Z"[q];
                    619:        } while (n > 0);
                    620:        *cp++ = 0;
                    621: }

unix.superglobalmegacorp.com

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