Annotation of 42BSD/sys/netimp/if_imp.c, revision 1.1.1.1

1.1       root        1: /*     if_imp.c        6.1     83/07/29        */
                      2: 
                      3: #include "imp.h"
                      4: #if NIMP > 0
                      5: /*
                      6:  * ARPANET IMP interface driver.
                      7:  *
                      8:  * The IMP-host protocol is handled here, leaving
                      9:  * hardware specifics to the lower level interface driver.
                     10:  *
                     11:  * NB: only handles IMPS on class A networks.
                     12:  */
                     13: #include "../machine/pte.h"
                     14: 
                     15: #include "../h/param.h"
                     16: #include "../h/systm.h"
                     17: #include "../h/mbuf.h"
                     18: #include "../h/buf.h"
                     19: #include "../h/protosw.h"
                     20: #include "../h/socket.h"
                     21: #include "../h/vmmac.h"
                     22: #include "../h/time.h"
                     23: #include "../h/kernel.h"
                     24: #include "../h/errno.h"
                     25: #include "../h/ioctl.h"
                     26: 
                     27: #include "../vax/cpu.h"
                     28: #include "../vax/mtpr.h"
                     29: #include "../vaxuba/ubareg.h"
                     30: #include "../vaxuba/ubavar.h"
                     31: 
                     32: #include "../net/if.h"
                     33: #include "../net/route.h"
                     34: 
                     35: #include "../net/netisr.h"
                     36: #include "../netinet/in.h"
                     37: #include "../netinet/in_systm.h"
                     38: #include "../netinet/ip.h"
                     39: #include "../netinet/ip_var.h"
                     40: /* define IMPLEADERS here to get leader printing code */
                     41: #include "../netimp/if_imp.h"
                     42: #include "../netimp/if_imphost.h"
                     43: 
                     44: /*
                     45:  * IMP software status per interface.
                     46:  * (partially shared with the hardware specific module)
                     47:  *
                     48:  * Each interface is referenced by a network interface structure,
                     49:  * imp_if, which the routing code uses to locate the interface.
                     50:  * This structure contains the output queue for the interface, its
                     51:  * address, ...  IMP specific structures used in connecting the
                     52:  * IMP software modules to the hardware specific interface routines
                     53:  * are stored here.  The common structures are made visible to the
                     54:  * interface driver by passing a pointer to the hardware routine
                     55:  * at "attach" time.
                     56:  *
                     57:  * NOTE: imp_if and imp_cb are assumed adjacent in hardware code.
                     58:  */
                     59: struct imp_softc {
                     60:        struct  ifnet imp_if;           /* network visible interface */
                     61:        struct  impcb imp_cb;           /* hooks to hardware module */
                     62:        u_char  imp_state;              /* current state of IMP */
                     63:        char    imp_dropcnt;            /* used during initialization */
                     64: } imp_softc[NIMP];
                     65: 
                     66: /*
                     67:  * Messages from IMP regarding why
                     68:  * it's going down.
                     69:  */
                     70: static char *impmessage[] = {
                     71:        "in 30 seconds",
                     72:        "for hardware PM",
                     73:        "to reload software",
                     74:        "for emergency reset"
                     75: };
                     76: 
                     77: int    impdown(), impinit(), impioctl(), impoutput();
                     78: 
                     79: /*
                     80:  * IMP attach routine.  Called from hardware device attach routine
                     81:  * at configuration time with a pointer to the UNIBUS device structure.
                     82:  * Sets up local state and returns pointer to base of ifnet+impcb
                     83:  * structures.  This is then used by the device's attach routine
                     84:  * set up its back pointers. 
                     85:  */
                     86: impattach(ui, reset)
                     87:        struct uba_device *ui;
                     88:        int (*reset)();
                     89: {
                     90:        struct imp_softc *sc = &imp_softc[ui->ui_unit];
                     91:        register struct ifnet *ifp = &sc->imp_if;
                     92: 
                     93:        /* UNIT COULD BE AMBIGUOUS */
                     94:        ifp->if_unit = ui->ui_unit;
                     95:        ifp->if_name = "imp";
                     96:        ifp->if_mtu = IMPMTU - sizeof(struct imp_leader);
                     97:        ifp->if_reset = reset;
                     98:        ifp->if_init = impinit;
                     99:        ifp->if_ioctl = impioctl;
                    100:        ifp->if_output = impoutput;
                    101:        /* reset is handled at the hardware level */
                    102:        if_attach(ifp);
                    103:        return ((int)&sc->imp_if);
                    104: }
                    105: 
                    106: /*
                    107:  * IMP initialization routine: call hardware module to
                    108:  * setup UNIBUS resources, init state and get ready for
                    109:  * NOOPs the IMP should send us, and that we want to drop.
                    110:  */
                    111: impinit(unit)
                    112:        int unit;
                    113: {
                    114:        int s = splimp();
                    115:        register struct imp_softc *sc = &imp_softc[unit];
                    116:        struct sockaddr_in *sin;
                    117: 
                    118:        sin = (struct sockaddr_in *)&sc->imp_if.if_addr;
                    119:        if (in_netof(sin->sin_addr) == 0)
                    120:                return;
                    121:        if ((*sc->imp_cb.ic_init)(unit) == 0) {
                    122:                sc->imp_state = IMPS_DOWN;
                    123:                sc->imp_if.if_flags &= ~IFF_UP;
                    124:                splx(s);
                    125:                return;
                    126:        }
                    127:        sc->imp_if.if_flags |= IFF_RUNNING;
                    128:        sc->imp_state = IMPS_INIT;
                    129:        impnoops(sc);
                    130:        splx(s);
                    131: }
                    132: 
                    133: struct sockproto impproto = { PF_IMPLINK };
                    134: struct sockaddr_in impdst = { AF_IMPLINK };
                    135: struct sockaddr_in impsrc = { AF_IMPLINK };
                    136: #ifdef IMPLEADERS
                    137: int    impprintfs = 0;
                    138: #endif
                    139: 
                    140: /*
                    141:  * ARPAnet 1822 input routine.
                    142:  * Called from hardware input interrupt routine to handle 1822
                    143:  * IMP-host messages.  Type 0 messages (non-control) are
                    144:  * passed to higher level protocol processors on the basis
                    145:  * of link number.  Other type messages (control) are handled here.
                    146:  */
                    147: impinput(unit, m)
                    148:        int unit;
                    149:        register struct mbuf *m;
                    150: {
                    151:        register struct imp_leader *ip;
                    152:        register struct imp_softc *sc = &imp_softc[unit];
                    153:        register struct host *hp;
                    154:        register struct ifqueue *inq;
                    155:        struct control_leader *cp;
                    156:        struct in_addr addr;
                    157:        struct mbuf *next;
                    158:        struct sockaddr_in *sin;
                    159: 
                    160:        /* verify leader length. */
                    161:        if (m->m_len < sizeof(struct control_leader) &&
                    162:            (m = m_pullup(m, sizeof(struct control_leader))) == 0)
                    163:                return;
                    164:        cp = mtod(m, struct control_leader *);
                    165:        if (cp->dl_mtype == IMPTYPE_DATA)
                    166:                if (m->m_len < sizeof(struct imp_leader) &&
                    167:                    (m = m_pullup(m, sizeof(struct imp_leader))) == 0)
                    168:                        return;
                    169:        ip = mtod(m, struct imp_leader *);
                    170: #ifdef IMPLEADERS
                    171:        if (impprintfs)
                    172:                printleader("impinput", ip);
                    173: #endif
                    174: 
                    175:        /* check leader type */
                    176:        if (ip->il_format != IMP_NFF) {
                    177:                sc->imp_if.if_collisions++;     /* XXX */
                    178:                goto drop;
                    179:        }
                    180: 
                    181:        if (ip->il_mtype != IMPTYPE_DATA) {
                    182: #ifdef notdef
                    183:                addr.s_net = ip->il_network;
                    184: #else
                    185:                addr.s_net = sc->imp_if.if_net;
                    186: #endif
                    187:                addr.s_imp = ip->il_imp;
                    188:                addr.s_host = ip->il_host;
                    189:        }
                    190:        switch (ip->il_mtype) {
                    191: 
                    192:        case IMPTYPE_DATA:
                    193:                break;
                    194: 
                    195:        /*
                    196:         * IMP leader error.  Reset the IMP and discard the packet.
                    197:         */
                    198:        case IMPTYPE_BADLEADER:
                    199:                /*
                    200:                 * According to 1822 document, this message
                    201:                 * will be generated in response to the
                    202:                 * first noop sent to the IMP after
                    203:                 * the host resets the IMP interface.
                    204:                 */
                    205:                if (sc->imp_state != IMPS_INIT) {
                    206:                        impmsg(sc, "leader error");
                    207:                        hostreset(sc->imp_if.if_net);
                    208:                        impnoops(sc);
                    209:                }
                    210:                goto drop;
                    211: 
                    212:        /*
                    213:         * IMP going down.  Print message, and if not immediate,
                    214:         * set off a timer to insure things will be reset at the
                    215:         * appropriate time.
                    216:         */
                    217:        case IMPTYPE_DOWN:
                    218:                if (sc->imp_state < IMPS_INIT)
                    219:                        goto drop;
                    220:                if ((ip->il_link & IMP_DMASK) == 0) {
                    221:                        sc->imp_state = IMPS_GOINGDOWN;
                    222:                        timeout(impdown, (caddr_t)sc, 30 * hz);
                    223:                }
                    224:                impmsg(sc, "going down %s",
                    225:                        (u_int)impmessage[ip->il_link&IMP_DMASK]);
                    226:                goto drop;
                    227: 
                    228:        /*
                    229:         * A NOP usually seen during the initialization sequence.
                    230:         * Compare the local address with that in the message.
                    231:         * Reset the local address notion if it doesn't match.
                    232:         */
                    233:        case IMPTYPE_NOOP:
                    234:                if (sc->imp_state == IMPS_DOWN) {
                    235:                        sc->imp_state = IMPS_INIT;
                    236:                        sc->imp_dropcnt = IMP_DROPCNT;
                    237:                }
                    238:                if (sc->imp_state == IMPS_INIT && --sc->imp_dropcnt > 0)
                    239:                        goto drop;
                    240:                sin = (struct sockaddr_in *)&sc->imp_if.if_addr;
                    241:                if (sin->sin_addr.s_host != ip->il_host ||
                    242:                    sin->sin_addr.s_imp != ip->il_imp) {
                    243:                        sc->imp_if.if_host[0] =
                    244:                                sin->sin_addr.s_host = ip->il_host;
                    245:                        sin->sin_addr.s_imp = ip->il_imp;
                    246:                        impmsg(sc, "reset (host %d/imp %d)", (u_int)ip->il_host,
                    247:                                ntohs(ip->il_imp));
                    248:                }
                    249:                sc->imp_state = IMPS_UP;
                    250:                sc->imp_if.if_flags |= IFF_UP;
                    251:                if_rtinit(&sc->imp_if, RTF_UP);
                    252:                goto drop;
                    253: 
                    254:        /*
                    255:         * RFNM or INCOMPLETE message, send next
                    256:         * message on the q.  We could pass incomplete's
                    257:         * up to the next level, but this currently isn't
                    258:         * needed.
                    259:         */
                    260:        case IMPTYPE_RFNM:
                    261:        case IMPTYPE_INCOMPLETE:
                    262:                if (hp = hostlookup(addr)) {
                    263:                        if (hp->h_rfnm == 0)
                    264:                                hp->h_flags &= ~HF_INUSE;
                    265:                        else if (next = hostdeque(hp))
                    266:                                (void) impsnd(&sc->imp_if, next);
                    267:                }
                    268:                goto drop;
                    269: 
                    270:        /*
                    271:         * Host or IMP can't be reached.  Flush any packets
                    272:         * awaiting transmission and release the host structure.
                    273:         */
                    274:        case IMPTYPE_HOSTDEAD:
                    275:        case IMPTYPE_HOSTUNREACH:
                    276:                impnotify((int)ip->il_mtype, (struct control_leader *)ip,
                    277:                    hostlookup(addr));
                    278:                goto rawlinkin;
                    279: 
                    280:        /*
                    281:         * Error in data.  Clear RFNM status for this host and send
                    282:         * noops to the IMP to clear the interface.
                    283:         */
                    284:        case IMPTYPE_BADDATA:
                    285:                impmsg(sc, "data error");
                    286:                if (hp = hostlookup(addr))
                    287:                        hp->h_rfnm = 0;
                    288:                impnoops(sc);
                    289:                goto drop;
                    290: 
                    291:        /*
                    292:         * Interface reset.
                    293:         */
                    294:        case IMPTYPE_RESET:
                    295:                impmsg(sc, "interface reset");
                    296:                impnoops(sc);
                    297:                goto drop;
                    298: 
                    299:        default:
                    300:                sc->imp_if.if_collisions++;             /* XXX */
                    301:                goto drop;
                    302:        }
                    303: 
                    304:        /*
                    305:         * Data for a protocol.  Dispatch to the appropriate
                    306:         * protocol routine (running at software interrupt).
                    307:         * If this isn't a raw interface, advance pointer
                    308:         * into mbuf past leader.
                    309:         */
                    310:        switch (ip->il_link) {
                    311: 
                    312: #ifdef INET
                    313:        case IMPLINK_IP:
                    314:                m->m_len -= sizeof(struct imp_leader);
                    315:                m->m_off += sizeof(struct imp_leader);
                    316:                schednetisr(NETISR_IP);
                    317:                inq = &ipintrq;
                    318:                break;
                    319: #endif
                    320: 
                    321:        default:
                    322:        rawlinkin:
                    323:                impproto.sp_protocol = ip->il_link;
                    324:                sin = (struct sockaddr_in *)&sc->imp_if.if_addr;
                    325:                impdst.sin_addr = sin->sin_addr;;
                    326:                impsrc.sin_addr.s_net = ip->il_network;
                    327:                impsrc.sin_addr.s_host = ip->il_host;
                    328:                impsrc.sin_addr.s_imp = ip->il_imp;
                    329:                raw_input(m, &impproto, (struct sockaddr *)&impsrc,
                    330:                  (struct sockaddr *)&impdst);
                    331:                return;
                    332:        }
                    333:        if (IF_QFULL(inq)) {
                    334:                IF_DROP(inq);
                    335:                goto drop;
                    336:        }
                    337:        IF_ENQUEUE(inq, m);
                    338:        return;
                    339: 
                    340: drop:
                    341:        m_freem(m);
                    342: }
                    343: 
                    344: /*
                    345:  * Bring the IMP down after notification.
                    346:  */
                    347: impdown(sc)
                    348:        struct imp_softc *sc;
                    349: {
                    350:        int s = splimp();
                    351: 
                    352:        sc->imp_state = IMPS_DOWN;
                    353:        impmsg(sc, "marked down");
                    354:        hostreset(sc->imp_if.if_net);
                    355:        if_down(&sc->imp_if);
                    356:        splx(s);
                    357: }
                    358: 
                    359: /*VARARGS*/
                    360: impmsg(sc, fmt, a1, a2)
                    361:        struct imp_softc *sc;
                    362:        char *fmt;
                    363:        u_int a1;
                    364: {
                    365: 
                    366:        printf("imp%d: ", sc->imp_if.if_unit);
                    367:        printf(fmt, a1, a2);
                    368:        printf("\n");
                    369: }
                    370: 
                    371: /*
                    372:  * Process an IMP "error" message, passing this
                    373:  * up to the higher level protocol.
                    374:  */
                    375: impnotify(what, cp, hp)
                    376:        int what;
                    377:        struct control_leader *cp;
                    378:        struct host *hp;
                    379: {
                    380:        struct in_addr in;
                    381: 
                    382: #ifdef notdef
                    383:        in.s_net = cp->dl_network;
                    384: #else
                    385:        in.s_net = 10;                  /* XXX */
                    386: #endif
                    387:        in.s_host = cp->dl_host;
                    388:        in.s_imp = cp->dl_imp;
                    389:        if (cp->dl_link != IMPLINK_IP)
                    390:                raw_ctlinput(what, (caddr_t)&in);
                    391:        else
                    392:                ip_ctlinput(what, (caddr_t)&in);
                    393:        if (hp) {
                    394:                hp->h_flags |= (1 << what);
                    395:                hostfree(hp);
                    396:        }
                    397: }
                    398: 
                    399: /*
                    400:  * ARPAnet 1822 output routine.
                    401:  * Called from higher level protocol routines to set up messages for
                    402:  * transmission to the imp.  Sets up the header and calls impsnd to
                    403:  * enqueue the message for this IMP's hardware driver.
                    404:  */
                    405: impoutput(ifp, m0, dst)
                    406:        register struct ifnet *ifp;
                    407:        struct mbuf *m0;
                    408:        struct sockaddr *dst;
                    409: {
                    410:        register struct imp_leader *imp;
                    411:        register struct mbuf *m = m0;
                    412:        int dhost, dimp, dlink, len, dnet;
                    413:        int error = 0;
                    414: 
                    415:        /*
                    416:         * Don't even try if the IMP is unavailable.
                    417:         */
                    418:        if (imp_softc[ifp->if_unit].imp_state != IMPS_UP) {
                    419:                error = ENETDOWN;
                    420:                goto drop;
                    421:        }
                    422: 
                    423:        switch (dst->sa_family) {
                    424: 
                    425: #ifdef INET
                    426:        case AF_INET: {
                    427:                struct ip *ip = mtod(m0, struct ip *);
                    428:                struct sockaddr_in *sin = (struct sockaddr_in *)dst;
                    429: 
                    430:                dhost = sin->sin_addr.s_host;
                    431:                dimp = sin->sin_addr.s_impno;
                    432:                dlink = IMPLINK_IP;
                    433:                dnet = 0;
                    434:                len = ntohs((u_short)ip->ip_len);
                    435:                break;
                    436:        }
                    437: #endif
                    438:        case AF_IMPLINK:
                    439:                goto leaderexists;
                    440: 
                    441:        default:
                    442:                printf("imp%d: can't handle af%d\n", ifp->if_unit, 
                    443:                        dst->sa_family);
                    444:                error = EAFNOSUPPORT;
                    445:                goto drop;
                    446:        }
                    447: 
                    448:        /*
                    449:         * Add IMP leader.  If there's not enough space in the
                    450:         * first mbuf, allocate another.  If that should fail, we
                    451:         * drop this sucker.
                    452:         */
                    453:        if (m->m_off > MMAXOFF ||
                    454:            MMINOFF + sizeof(struct imp_leader) > m->m_off) {
                    455:                m = m_get(M_DONTWAIT, MT_HEADER);
                    456:                if (m == 0) {
                    457:                        error = ENOBUFS;
                    458:                        goto drop;
                    459:                }
                    460:                m->m_next = m0;
                    461:                m->m_len = sizeof(struct imp_leader);
                    462:        } else {
                    463:                m->m_off -= sizeof(struct imp_leader);
                    464:                m->m_len += sizeof(struct imp_leader);
                    465:        }
                    466:        imp = mtod(m, struct imp_leader *);
                    467:        imp->il_format = IMP_NFF;
                    468:        imp->il_mtype = IMPTYPE_DATA;
                    469:        imp->il_network = dnet;
                    470:        imp->il_host = dhost;
                    471:        imp->il_imp = htons((u_short)dimp);
                    472:        imp->il_length =
                    473:                htons((u_short)(len + sizeof(struct imp_leader)) << 3);
                    474:        imp->il_link = dlink;
                    475:        imp->il_flags = imp->il_htype = imp->il_subtype = 0;
                    476: 
                    477: leaderexists:
                    478:        return (impsnd(ifp, m));
                    479: drop:
                    480:        m_freem(m0);
                    481:        return (error);
                    482: }
                    483: 
                    484: /* 
                    485:  * Put a message on an interface's output queue. 
                    486:  * Perform RFNM counting: no more than 8 message may be
                    487:  * in flight to any one host.
                    488:  */
                    489: impsnd(ifp, m)             
                    490:        struct ifnet *ifp;
                    491:        struct mbuf *m;
                    492: {
                    493:        register struct imp_leader *ip;
                    494:        register struct host *hp;
                    495:        struct impcb *icp;
                    496:        int s, error;
                    497: 
                    498:        ip = mtod(m, struct imp_leader *);
                    499: 
                    500:        /*
                    501:         * Do RFNM counting for data messages
                    502:         * (no more than 8 outstanding to any host)
                    503:         */ 
                    504:        s = splimp();
                    505:        if (ip->il_mtype == IMPTYPE_DATA) {
                    506:                struct in_addr addr;
                    507: 
                    508: #ifdef notdef
                    509:                 addr.s_net = ip->il_network;
                    510: #else
                    511:                addr.s_net = ifp->if_net;       /* XXX */
                    512: #endif
                    513:                 addr.s_host = ip->il_host;
                    514:                 addr.s_imp = ip->il_imp;
                    515:                if ((hp = hostlookup(addr)) == 0)
                    516:                        hp = hostenter(addr);
                    517:                if (hp && (hp->h_flags & (HF_DEAD|HF_UNREACH))) {
                    518:                        error = hp->h_flags&HF_DEAD ? EHOSTDOWN : EHOSTUNREACH;
                    519:                        hp->h_timer = HOSTTIMER;
                    520:                        hp->h_flags &= ~HF_INUSE;
                    521:                        goto bad;
                    522:                }
                    523: 
                    524:                /*
                    525:                 * If IMP would block, queue until RFNM
                    526:                 */
                    527:                if (hp) {
                    528:                        if (hp->h_rfnm < 8) {
                    529:                                hp->h_rfnm++;
                    530:                                goto enque;
                    531:                        }
                    532:                        if (hp->h_qcnt < 8) {   /* high water mark */
                    533:                                HOST_ENQUE(hp, m);
                    534:                                goto start;
                    535:                        }
                    536:                }
                    537:                error = ENOBUFS;
                    538:                goto bad;
                    539:        }
                    540: enque:
                    541:        if (IF_QFULL(&ifp->if_snd)) {
                    542:                IF_DROP(&ifp->if_snd);
                    543:                error = ENOBUFS;
                    544: bad:
                    545:                m_freem(m);
                    546:                splx(s);
                    547:                return (error);
                    548:        }
                    549:        IF_ENQUEUE(&ifp->if_snd, m);
                    550: start:
                    551:        icp = &imp_softc[ifp->if_unit].imp_cb;
                    552:        if (icp->ic_oactive == 0)
                    553:                (*icp->ic_start)(ifp->if_unit);
                    554:        splx(s);
                    555:        return (0);
                    556: }
                    557: 
                    558: /*
                    559:  * Put three 1822 NOOPs at the head of the output queue. 
                    560:  * Part of host-IMP initialization procedure.
                    561:  * (Should return success/failure, but noone knows
                    562:  * what to do with this, so why bother?)
                    563:  * This routine is always called at splimp, so we don't
                    564:  * protect the call to IF_PREPEND.
                    565:  */
                    566: impnoops(sc)             
                    567:        register struct imp_softc *sc;
                    568: {
                    569:        register i;
                    570:        register struct mbuf *m;
                    571:        register struct control_leader *cp;
                    572: 
                    573:        sc->imp_dropcnt = IMP_DROPCNT;
                    574:        for (i = 0; i < IMP_DROPCNT + 1; i++ ) { 
                    575:                if ((m = m_getclr(M_DONTWAIT, MT_HEADER)) == 0) 
                    576:                        return;
                    577:                m->m_len = sizeof(struct control_leader);
                    578:                cp = mtod(m, struct control_leader *);
                    579:                cp->dl_format = IMP_NFF;
                    580:                 cp->dl_link = i;
                    581:                 cp->dl_mtype = IMPTYPE_NOOP;
                    582:                IF_PREPEND(&sc->imp_if.if_snd, m);
                    583:        }
                    584:        if (sc->imp_cb.ic_oactive == 0)
                    585:                (*sc->imp_cb.ic_start)(sc->imp_if.if_unit);
                    586: }
                    587: 
                    588: /*
                    589:  * Process an ioctl request.
                    590:  */
                    591: impioctl(ifp, cmd, data)
                    592:        register struct ifnet *ifp;
                    593:        int cmd;
                    594:        caddr_t data;
                    595: {
                    596:        struct ifreq *ifr = (struct ifreq *)data;
                    597:        struct sockaddr_in *sin;
                    598:        int s = splimp(), error = 0;
                    599: 
                    600:        switch (cmd) {
                    601: 
                    602:        case SIOCSIFADDR:
                    603:                if (ifp->if_flags & IFF_RUNNING)
                    604:                        if_rtinit(ifp, -1);     /* delete previous route */
                    605:                sin = (struct sockaddr_in *)&ifr->ifr_addr;
                    606:                ifp->if_net = in_netof(sin->sin_addr);
                    607:                sin = (struct sockaddr_in *)&ifp->if_addr;
                    608:                sin->sin_family = AF_INET;
                    609:                /* host number filled in already, or filled in later */
                    610:                sin->sin_addr = if_makeaddr(ifp->if_net, ifp->if_host[0]);
                    611:                if (ifp->if_flags & IFF_RUNNING)
                    612:                        if_rtinit(ifp, RTF_UP);
                    613:                else
                    614:                        impinit(ifp->if_unit);
                    615:                break;
                    616: 
                    617:        default:
                    618:                error = EINVAL;
                    619:        }
                    620:        splx(s);
                    621:        return (error);
                    622: }
                    623: 
                    624: #ifdef IMPLEADERS
                    625: printleader(routine, ip)
                    626:        char *routine;
                    627:        register struct imp_leader *ip;
                    628: {
                    629:        printf("%s: ", routine);
                    630:        printbyte((char *)ip, 12);
                    631:        printf("<fmt=%x,net=%x,flags=%x,mtype=", ip->il_format, ip->il_network,
                    632:                ip->il_flags);
                    633:        if (ip->il_mtype <= IMPTYPE_READY)
                    634:                printf("%s,", impleaders[ip->il_mtype]);
                    635:        else
                    636:                printf("%x,", ip->il_mtype);
                    637:        printf("htype=%x,host=%x,imp=%x,link=", ip->il_htype, ip->il_host,
                    638:                ntohs(ip->il_imp));
                    639:        if (ip->il_link == IMPLINK_IP)
                    640:                printf("ip,");
                    641:        else
                    642:                printf("%x,", ip->il_link);
                    643:        printf("subtype=%x,len=%x>\n",ip->il_subtype,ntohs(ip->il_length)>>3);
                    644: }
                    645: 
                    646: printbyte(cp, n)
                    647:        register char *cp;
                    648:        int n;
                    649: {
                    650:        register i, j, c;
                    651: 
                    652:        for (i=0; i<n; i++) {
                    653:                c = *cp++;
                    654:                for (j=0; j<2; j++)
                    655:                        putchar("0123456789abcdef"[(c>>((1-j)*4))&0xf]);
                    656:                putchar(' ');
                    657:        }
                    658:        putchar('\n');
                    659: }
                    660: #endif
                    661: #endif

unix.superglobalmegacorp.com

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