Annotation of cci/sys/netinet/if_ether.c, revision 1.1.1.2

1.1       root        1: /*     if_ether.c      6.2     83/08/28        */
                      2: 
                      3: /*
                      4:  * Ethernet address resolution protocol.
                      5:  */
                      6: 
                      7: #include "../h/param.h"
                      8: #include "../h/systm.h"
                      9: #include "../h/mbuf.h"
                     10: #include "../h/socket.h"
                     11: #include "../h/time.h"
                     12: #include "../h/kernel.h"
                     13: #include "../h/errno.h"
                     14: 
                     15: #include "../net/if.h"
                     16: #include "../netinet/in.h"
                     17: #include "../netinet/if_ether.h"
1.1.1.2 ! root       18: #include "../tahoeif/if_acereg.h"
        !            19: #include "../tahoeif/if_enp.h"
1.1       root       20: 
                     21: /*
                     22:  * changes:
                     23:  *
                     24:  *     . always return 0 after calling looutput().
                     25:  *
                     26:  *     . forces messages going to net if flag gotoether is set.
                     27:  *       (set this flag through "adb" for debugging purposes).
                     28:  *
                     29:  *     . add symbolic return code to arpresolve(). See comments in 
                     30:  *       arpresolve().
1.1.1.2 ! root       31:  *
        !            32:  *     . add test to check if the broadcast message originated from
        !            33:  *       the other controllers on the same host.  If so, there is no
        !            34:  *       need to print out error message that warns about duplicate
        !            35:  *       ip address.
1.1       root       36:  */
                     37: 
                     38: /*
                     39:  * Internet to ethernet address resolution table.
                     40:  */
                     41: struct arptab {
                     42:        struct  in_addr at_iaddr;       /* internet address */
                     43:        u_char  at_enaddr[6];           /* ethernet address */
                     44:        struct  mbuf *at_hold;          /* last packet until resolved/timeout */
                     45:        u_char  at_timer;               /* minutes since last reference */
                     46:        u_char  at_flags;               /* flags */
                     47: };
                     48: /* at_flags field values */
                     49: #define        ATF_INUSE       1               /* entry in use */
                     50: #define ATF_COM                2               /* completed entry (enaddr valid) */
                     51: 
                     52: #define        ARPTAB_BSIZ     5               /* bucket size */
                     53: #define        ARPTAB_NB       19              /* number of buckets */
                     54: #define        ARPTAB_SIZE     (ARPTAB_BSIZ * ARPTAB_NB)
                     55: struct arptab arptab[ARPTAB_SIZE];
                     56: 
                     57: #define        ARPTAB_HASH(a) \
                     58:        ((short)((((a) >> 16) ^ (a)) & 0x7fff) % ARPTAB_NB)
                     59: 
                     60: #define        ARPTAB_LOOK(at,addr) { \
                     61:        register n; \
                     62:        at = &arptab[ARPTAB_HASH(addr) * ARPTAB_BSIZ]; \
                     63:        for (n = 0 ; n < ARPTAB_BSIZ ; n++,at++) \
                     64:                if (at->at_iaddr.s_addr == addr) \
                     65:                        break; \
                     66:        if (n >= ARPTAB_BSIZ) \
                     67:                at = 0; }
                     68: 
                     69: struct arpcom *arpcom;         /* chain of active ether interfaces */
                     70: int    arpt_age;               /* aging timer */
                     71: int    gotoether;              /* force traffic to Ethernet; no software
                     72:                                   loopback */
                     73: 
                     74: /* timer values */
                     75: #define        ARPT_AGE        (60*1)  /* aging timer, 1 min. */
                     76: #define        ARPT_KILLC      20      /* kill completed entry in 20 mins. */
                     77: #define        ARPT_KILLI      3       /* kill incomplete entry in 3 minutes */
                     78: 
                     79: u_char etherbroadcastaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
                     80: extern struct ifnet loif;
1.1.1.2 ! root       81: extern struct ace_softc        ace_softc[];
        !            82: extern struct enp_softc        enp_softc[];
        !            83: extern int numace;
        !            84: extern int numenp;
1.1       root       85: /*------------- debug tools ---------------*/
                     86: #ifdef ARPPRINTFS
                     87:        int     arpprintfs;
                     88: #      define ARPTRACE(X)      {if (arpprintfs) X }
                     89: #else  ARPPRINTFS
                     90: #      define ARPTRACE(X)
                     91: #endif ARPPRINTFS
                     92: 
                     93: /*
                     94:  * Local addresses in the range oldmap to infinity are
                     95:  * mapped according to the old mapping scheme.  That is,
                     96:  * mapping of Internet to Ethernet addresses is performed
                     97:  * by taking the high three bytes of the network interface's
                     98:  * address and the low three bytes of the local address part.
                     99:  * This only allows boards from the same manufacturer to
                    100:  * communicate unless the on-board address is overridden
                    101:  * (not possible in many manufacture's hardware).
                    102:  *
                    103:  * NB: setting oldmap to zero completely disables ARP
                    104:  *     (i.e. identical to setting IFF_NOARP with an ioctl).
                    105:  */
1.1.1.2 ! root      106: /* int oldmap = 1024; we remove this reference for ARP usr */
1.1       root      107: 
                    108: /*
                    109:  * Attach an ethernet interface to the list "arpcom" where
                    110:  * arptimer() can find it.  If first time 
                    111:  * initialization, start arptimer().
                    112:  */
                    113: arpattach(ac)
                    114:        register struct arpcom *ac;
                    115: {
                    116:        register struct arpcom *acp;
                    117: 
                    118:        for (acp = arpcom; acp != (struct arpcom *)0; acp = acp->ac_ac)
                    119:                if (acp == ac)          /* if already on list */
                    120:                        return;
                    121:        ac->ac_ac = arpcom;
                    122:        arpcom = ac;
                    123:        if (arpcom->ac_ac == 0)         /* very first time */
                    124:                arptimer();
                    125: }
                    126: 
                    127: /*
                    128:  * Timeout routine.  Age arp_tab entries once a minute.
                    129:  */
                    130: arptimer()
                    131: {
                    132:        register struct arptab *at;
                    133:        register i;
                    134: 
                    135:        timeout(arptimer, (caddr_t)0, hz);
                    136: #ifdef notdef
                    137:        if (++arpt_sanity > ARPT_SANITY) {
                    138:                register struct arpcom *ac;
                    139: 
                    140:                /*
                    141:                 * Randomize sanity timer based on my host address.
                    142:                 * Ask who has my own address;  if someone else replies,
                    143:                 * then they are impersonating me.
                    144:                 */
                    145:                arpt_sanity = arpcom->ac_enaddr[5] & 0x3f;
                    146:                for (ac = arpcom; ac != (struct arpcom *)-1; ac = ac->ac_ac)
                    147:                        arpwhohas(ac, &((struct sockaddr_in *)
                    148:                            &ac->ac_if.if_addr)->sin_addr);
                    149:        }
                    150: #endif
                    151:        if (++arpt_age > ARPT_AGE) {
                    152:                arpt_age = 0;
                    153:                at = &arptab[0];
                    154:                for (i = 0; i < ARPTAB_SIZE; i++, at++) {
                    155:                        if (at->at_flags == 0)
                    156:                                continue;
                    157:                        if (++at->at_timer < ((at->at_flags&ATF_COM) ?
                    158:                            ARPT_KILLC : ARPT_KILLI))
                    159:                                continue;
                    160:                        /* timer has expired, clear entry */
                    161:                        arptfree(at);
                    162:                }
                    163:        }
                    164: }
                    165: 
                    166: /*
                    167:  * Broadcast an ARP packet, asking who has addr on interface ac.
                    168:  */
                    169: arpwhohas(ac, addr)
                    170:        register struct arpcom *ac;
                    171:        struct in_addr *addr;
                    172: {
                    173:        register struct mbuf *m;
                    174:        register struct ether_header *eh;
                    175:        register struct ether_arp *ea;
                    176:        struct sockaddr sa;
                    177: 
                    178:        m = m_get(M_DONTWAIT, MT_DATA);
                    179:        MBUFNULL(5,m);                  /* for debugging */
                    180:        if (m == NULL)
                    181:                return;
                    182:        m->m_len = sizeof *ea + SIZEOF_ETHEADER;
                    183:        m->m_off = MMAXOFF - m->m_len;
                    184:        ea = mtod(m, struct ether_arp *);
                    185:        eh = (struct ether_header *)sa.sa_data;
                    186:        bzero((caddr_t)ea, sizeof (*ea));
                    187:        bcopy((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
                    188:           sizeof (etherbroadcastaddr));
                    189:        eh->ether_type = ETHERPUP_ARPTYPE;      /* if_output will swap */
                    190:        ea->arp_hrd = htons(ARPHRD_ETHER);
                    191:        ea->arp_pro = htons(ETHERPUP_IPTYPE);
                    192:        ea->arp_hln = sizeof ea->arp_sha;       /* hardware address length */
                    193:        ea->arp_pln = sizeof ea->arp_spa;       /* protocol address length */
                    194:        ea->arp_op = htons(ARPOP_REQUEST);
                    195:        bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->arp_sha,
                    196:           sizeof (ea->arp_sha));
                    197:        bcopy((caddr_t)&((struct sockaddr_in *)&ac->ac_if.if_addr)->sin_addr,
                    198:           (caddr_t)ea->arp_spa, sizeof (ea->arp_spa));
                    199:        bcopy((caddr_t)addr, (caddr_t)ea->arp_tpa, sizeof (ea->arp_tpa));
                    200:        sa.sa_family = AF_UNSPEC;
                    201:        ARPTRACE(printf("arpwhohas:broadcast through %s%d for addr %lx\n",
                    202:                ac->ac_if.if_name, ac->ac_if.if_unit, addr->s_addr);)
                    203:        (void) (*ac->ac_if.if_output)(&ac->ac_if, m, &sa);
                    204: }
                    205: 
                    206: /*
                    207:  *
                    208:  * Resolve an IP address into an ethernet address.  If success, 
                    209:  * desten is filled in and 1 is returned.  If there is no entry
                    210:  * in arptab, set one up and broadcast a request 
                    211:  * for the IP address;  return 0.  Hold onto this mbuf and 
                    212:  * resend it once the address is finally resolved.
                    213:  *
                    214:  * We do some (conservative) locking here at splimp, since
                    215:  * arptab is also altered from input interrupt service (ecintr/ilintr
                    216:  * calls arpinput when ETHERPUP_ARPTYPE packets come in).
                    217:  *
                    218:  * Returns:
                    219:  *
                    220:  * ARPRESOLVE_WILLSEND
                    221:  *             arpresolve() cannot resolve the address. It will send the
                    222:  *             packet when it the address is resolved. However, if the 
                    223:  *             destination is same as origination, arpresolve() does not
                    224:  *             resolve address, it routes the packet to software loopback.
                    225:  *
                    226:  * ARPRESOLVE_OK
                    227:  *             arpresolve() successfully resolves the address. The calling
                    228:  *             routine is responsible for sending out the packet. Address
                    229:  *             is not a wild-card (not broadcast).
                    230:  *
                    231:  * ARPRESOLVE_BROADCAST
                    232:  *             arpresovle() successfully resolves the address which is
                    233:  *             a wildcard. If the controller is NOT capable of listening to
                    234:  *             its own broadcast, the device driver is responsible for
                    235:  *             routing a copy of the packet to the software loopback.
                    236:  *
                    237:  */
                    238: arpresolve(ac, m, destip, desten)
                    239:        register struct arpcom *ac;
                    240:        struct mbuf *m;
                    241:        register struct in_addr *destip;
                    242:        register u_char *desten;
                    243: {
                    244:        register struct arptab *at;
                    245:        register struct ifnet *ifp;
                    246:        struct sockaddr_in sin;
                    247:        int s, lna;
                    248: 
                    249:        lna = in_lnaof(*destip);
                    250:        if (lna == INADDR_ANY) {        /* broadcast address */
                    251:                bcopy((caddr_t)etherbroadcastaddr, (caddr_t)desten,
                    252:                   sizeof (etherbroadcastaddr));
1.1.1.2 ! root      253: 
        !           254:            ARPTRACE(printf("\tarpresolve(%s%d)target: %lx, %x.%x.%x.%x.%x.%x\n",
        !           255:                ac->ac_if.if_name, ac->ac_if.if_unit,
        !           256:                destip->s_addr, 
        !           257:                desten[0] & 0xff, desten[1] & 0xff,
        !           258:                desten[2] & 0xff, desten[3] & 0xff,
        !           259:                desten[4] & 0xff, desten[5] & 0xff);)
        !           260: 
1.1       root      261:                return (ARPRESOLVE_BROADCAST);
                    262:        }
                    263:        ifp = &ac->ac_if;
                    264:        /* if for us, then use software loopback driver */
                    265:        if ((destip->s_addr ==
                    266:            ((struct sockaddr_in *)&ifp->if_addr)-> sin_addr.s_addr) &&
                    267:            (gotoether==0)) {
                    268:                sin.sin_family = AF_INET;
                    269:                sin.sin_addr = *destip;
                    270:                looutput(&loif, m, (struct sockaddr *)&sin);
                    271:                return(ARPRESOLVE_WILLSEND);
                    272:        }
1.1.1.2 ! root      273:        /* if ((ifp->if_flags & IFF_NOARP) || lna >= oldmap) { */
        !           274:        if (ifp->if_flags & IFF_NOARP) {
1.1       root      275:                bcopy((caddr_t)ac->ac_enaddr, (caddr_t)desten, 3);
                    276:                desten[3] = (lna >> 16) & 0x7f;
                    277:                desten[4] = (lna >> 8) & 0xff;
                    278:                desten[5] = lna & 0xff;
1.1.1.2 ! root      279:            ARPTRACE(printf("\tarpresolve2(%s%d)target: %lx, %x.%x.%x.%x.%x.%x\n",
        !           280:                ac->ac_if.if_name, ac->ac_if.if_unit,
        !           281:                destip->s_addr, 
        !           282:                desten[0] & 0xff, desten[1] & 0xff,
        !           283:                desten[2] & 0xff, desten[3] & 0xff,
        !           284:                desten[4] & 0xff, desten[5] & 0xff);)
        !           285:        
1.1       root      286:                return (ARPRESOLVE_OK);
                    287:        }
                    288:        s = splimp();
                    289:        ARPTAB_LOOK(at, destip->s_addr);
                    290:        if (at == 0) {                  /* not found */
                    291:                at = arptnew(destip);
                    292:                ARPTRACE(printf("arpresolve(%s%d) (m=%lx), arptab empty\n",
                    293:                        ac->ac_if.if_name, ac->ac_if.if_unit, m);)
                    294: 
                    295:                ARPTRACE(if (at->at_hold)
                    296:                                printf("arpresolve: LOOSE mbuf %lx\n",m);)
                    297:                at->at_hold = m;
                    298:                arpwhohas(ac, destip);
                    299:                splx(s);
                    300:                return (ARPRESOLVE_WILLSEND);
                    301:        }
                    302:        at->at_timer = 0;               /* restart the timer */
                    303:        if (at->at_flags & ATF_COM) {   /* entry IS complete */
                    304:                bcopy((caddr_t)at->at_enaddr, (caddr_t)desten, 6);
                    305:                splx(s);
1.1.1.2 ! root      306:        
        !           307:            ARPTRACE(printf("\tarpresolve3(%s%d)target: %lx, %x.%x.%x.%x.%x.%x\n",
        !           308:                ac->ac_if.if_name, ac->ac_if.if_unit,
        !           309:                destip->s_addr, 
        !           310:                desten[0] & 0xff, desten[1] & 0xff,
        !           311:                desten[2] & 0xff, desten[3] & 0xff,
        !           312:                desten[4] & 0xff, desten[5] & 0xff);)
        !           313: 
1.1       root      314:                return (ARPRESOLVE_OK);
                    315:        }
                    316:        /*
                    317:         * There is an arptab entry, but no ethernet address
                    318:         * response yet.  Replace the held mbuf with this
                    319:         * latest one.
                    320:         */
                    321:        ARPTRACE(printf("arpresolve(%s%d) (m=%lx), arptab not completed\n",
                    322:                ac->ac_if.if_name, ac->ac_if.if_unit, m);)
                    323:        if (at->at_hold)
                    324:                m_freem(at->at_hold);
                    325:        at->at_hold = m;
                    326:        arpwhohas(ac, destip);          /* ask again */
                    327:        splx(s);
                    328:        return (ARPRESOLVE_WILLSEND);
                    329: }
                    330: 
                    331: /*
                    332:  * Find my own IP address.  It will either be waiting for us in
                    333:  * monitor RAM, or can be obtained via broadcast to the file/boot
                    334:  * server (not necessarily using the ARP packet format).
                    335:  *
                    336:  * Unimplemented at present, return 0 and assume that the host
                    337:  * will set his own IP address via the SIOCSIFADDR ioctl.
                    338:  */
                    339: /*ARGSUSED*/
                    340: struct in_addr
                    341: arpmyaddr(ac)
                    342:        register struct arpcom *ac;
                    343: {
                    344:        static struct in_addr addr;
                    345: 
                    346: #ifdef lint
                    347:        ac = ac;
                    348: #endif
                    349:        addr.s_addr = 0;
                    350:        return (addr);
                    351: }
                    352: 
                    353: /*
                    354:  * Called from ecintr/ilintr when ether packet type ETHERPUP_ARP
                    355:  * is received.  Algorithm is exactly that given in RFC 826.
                    356:  * In addition, a sanity check is performed on the sender
                    357:  * protocol address, to catch impersonators.
                    358:  */
                    359: arpinput(ac, m)
                    360:        register struct arpcom *ac;
                    361:        struct mbuf *m;
                    362: {
                    363:        register struct ether_arp *ea;
                    364:        struct ether_header *eh;
                    365:        register struct arptab *at = 0;  /* same as "merge" flag */
                    366:        struct sockaddr_in sin;
                    367:        struct sockaddr sa;
                    368:        struct mbuf *mhold;
                    369:        struct in_addr isaddr,itaddr,myaddr;
                    370: 
1.1.1.2 ! root      371:        ARPTRACE(printf("arpinput through %s%d (m=%lx, m->m_len=%d)\n",
        !           372:                ac->ac_if.if_name, ac->ac_if.if_unit, m,m->m_len);)
1.1       root      373: 
                    374:        if (m->m_len < sizeof *ea)
                    375:                goto out;
                    376: 
                    377:        myaddr = ((struct sockaddr_in *)&ac->ac_if.if_addr)->sin_addr;
                    378:        ea = mtod(m, struct ether_arp *);
                    379:        if (ntohs(ea->arp_pro) != ETHERPUP_IPTYPE)
                    380:                goto out;
                    381:        bcopy((caddr_t)ea->arp_spa, (caddr_t)&isaddr.s_addr,
                    382:                sizeof (ea->arp_spa));
                    383: /*     isaddr.s_addr = ((struct in_addr *)ea->arp_spa)->s_addr;*/
                    384:        bcopy((caddr_t)ea->arp_tpa, (caddr_t)&itaddr.s_addr,
                    385:                sizeof (ea->arp_spa));
                    386: /*     itaddr.s_addr = ((struct in_addr *)ea->arp_tpa)->s_addr;*/
                    387:        if (!bcmp((caddr_t)ea->arp_sha, (caddr_t)ac->ac_enaddr,
                    388:          sizeof (ac->ac_enaddr)))
                    389:                goto out;       /* it's from me, ignore it. */
                    390: 
1.1.1.2 ! root      391:        ARPTRACE(printf("\tarpinput (%s%d) sender: %lx, %x.%x.%x.%x.%x.%x, target:  %lx\n", 
1.1       root      392:                ac->ac_if.if_name, ac->ac_if.if_unit,
                    393:                isaddr.s_addr, 
                    394:                ea->arp_sha[0] & 0xff, ea->arp_sha[1] & 0xff,
                    395:                ea->arp_sha[2] & 0xff, ea->arp_sha[3] & 0xff,
                    396:                ea->arp_sha[4] & 0xff, ea->arp_sha[5] & 0xff,
1.1.1.2 ! root      397:                itaddr.s_addr );)
1.1       root      398:                
                    399:        if (isaddr.s_addr == myaddr.s_addr) {
1.1.1.2 ! root      400:                if (!fromme(ea->arp_sha)) {
        !           401:                        printf("duplicate IP address!! sent from ethernet address: ");
        !           402:                        printf("%x %x %x %x %x %x\n", ea->arp_sha[0], ea->arp_sha[1],
        !           403:                        ea->arp_sha[2], ea->arp_sha[3],
        !           404:                        ea->arp_sha[4], ea->arp_sha[5]);
        !           405:                        if (ntohs(ea->arp_op) == ARPOP_REQUEST)
        !           406:                                goto reply;
        !           407:                        goto out;
        !           408:                }
1.1       root      409:        }
                    410:        ARPTAB_LOOK(at, isaddr.s_addr);
                    411:        if (at) {
                    412:                bcopy((caddr_t)ea->arp_sha, (caddr_t)at->at_enaddr,
                    413:                   sizeof (ea->arp_sha));
                    414:                ARPTRACE(printf("\tarpinput(%s%d). Update sender addr\n",
                    415:                        ac->ac_if.if_name, ac->ac_if.if_unit);)
                    416:        
                    417:                at->at_flags |= ATF_COM;
                    418:                if (at->at_hold) {
                    419:                        mhold = at->at_hold;
                    420:                        at->at_hold = 0;
                    421:                        sin.sin_family = AF_INET;
                    422:                        sin.sin_addr = isaddr;
                    423:                        (*ac->ac_if.if_output)(&ac->ac_if, 
                    424:                            mhold, (struct sockaddr *)&sin);
                    425:                }
                    426:        }
                    427:        if (itaddr.s_addr != myaddr.s_addr) {
                    428:                ARPTRACE(printf("\tarpinput(%s%d) Iam not the target\n",
                    429:                        ac->ac_if.if_name, ac->ac_if.if_unit);)
                    430:                goto out;       /* if I am not the target */
                    431:        }
                    432:        if (at == 0) {          /* ensure we have a table entry */
                    433:                ARPTRACE(printf("\tarpinput(%s%d). New entry for sender addr\n",
                    434:                        ac->ac_if.if_name, ac->ac_if.if_unit);)
                    435:                at = arptnew(&isaddr);
                    436:                bcopy((caddr_t)ea->arp_sha, (caddr_t)at->at_enaddr,
                    437:                   sizeof (ea->arp_sha));
                    438:                at->at_flags |= ATF_COM;
                    439:        }
                    440:        if (ntohs(ea->arp_op) != ARPOP_REQUEST)
                    441:                goto out;
                    442: reply:
                    443:        bcopy((caddr_t)ea->arp_sha, (caddr_t)ea->arp_tha,
                    444:           sizeof (ea->arp_sha));
                    445:        bcopy((caddr_t)ea->arp_spa, (caddr_t)ea->arp_tpa,
                    446:           sizeof (ea->arp_spa));
                    447:        bcopy((caddr_t)ac->ac_enaddr, (caddr_t)ea->arp_sha,
                    448:           sizeof (ea->arp_sha));
                    449:        bcopy((caddr_t)&myaddr, (caddr_t)ea->arp_spa,
                    450:           sizeof (ea->arp_spa));
                    451:        ea->arp_op = htons(ARPOP_REPLY);
                    452:        eh = (struct ether_header *)sa.sa_data;
                    453:        bcopy((caddr_t)ea->arp_tha, (caddr_t)eh->ether_dhost,
                    454:           sizeof (eh->ether_dhost));
                    455:        eh->ether_type = ETHERPUP_ARPTYPE;
                    456:        sa.sa_family = AF_UNSPEC;
                    457: 
                    458:        ARPTRACE(bcopy((caddr_t)ea->arp_tpa, (caddr_t)&itaddr.s_addr,
                    459:                sizeof (ea->arp_tpa));)
                    460:        ARPTRACE(printf("\tarpinput(%s%d). Send reply to %lx\n",
                    461:                ac->ac_if.if_name, ac->ac_if.if_unit,itaddr.s_addr);)
                    462: 
                    463:        (*ac->ac_if.if_output)(&ac->ac_if, m, &sa);
                    464:        return;
                    465: out:
                    466:        m_freem(m);
                    467:        return;
                    468: }
                    469: 
                    470: /*
                    471:  * Free an arptab entry.
                    472:  */
                    473: arptfree(at)
                    474:        register struct arptab *at;
                    475: {
                    476:        int s = splimp();
                    477: 
                    478:        if (at->at_hold)
                    479:                m_freem(at->at_hold);
                    480:        at->at_hold = 0;
                    481:        at->at_timer = at->at_flags = 0;
                    482:        at->at_iaddr.s_addr = 0;
                    483:        splx(s);
                    484: }
                    485: 
                    486: /*
                    487:  * Enter a new address in arptab, pushing out the oldest entry 
                    488:  * from the bucket if there is no room.
                    489:  */
                    490: struct arptab *
                    491: arptnew(addr)
                    492:        struct in_addr *addr;
                    493: {
                    494:        register n;
                    495:        int oldest = 0;
                    496:        register struct arptab *at, *ato;
                    497: 
                    498:        ato = at = &arptab[ARPTAB_HASH(addr->s_addr) * ARPTAB_BSIZ];
                    499:        for (n = 0 ; n < ARPTAB_BSIZ ; n++,at++) {
                    500:                if (at->at_flags == 0)
                    501:                        goto out;        /* found an empty entry */
                    502:                if (at->at_timer > oldest) {
                    503:                        oldest = at->at_timer;
                    504:                        ato = at;
                    505:                }
                    506:        }
                    507:        at = ato;
                    508:        arptfree(at);
                    509: out:
                    510:        at->at_iaddr = *addr;
                    511:        at->at_flags = ATF_INUSE;
                    512:        return (at);
                    513: }
                    514: 
                    515: arpremove(addr)
                    516: struct sockaddr *addr;
                    517: {
                    518:        register struct arptab *at;
                    519:        struct in_addr *idst;
                    520:        register long x;
                    521: 
                    522:        idst = &((struct sockaddr_in *)addr)->sin_addr;
                    523:        x = splimp();
                    524:        ARPTAB_LOOK(at, idst->s_addr);
                    525:        if (at) arptfree(at);
                    526:        splx(x);
                    527: }
                    528: 
1.1.1.2 ! root      529: fromme(ea)
        !           530: char *ea;
        !           531: {
        !           532:        int i;
        !           533: 
        !           534:        for (i = 0; i < numace; i++) {
        !           535:                if (!bcmp(ea, ace_softc[i].is_addr, 6))
        !           536:                        return(1);
        !           537:        }
        !           538:        for (i = 0; i < numenp; i++) {
        !           539:                if (!bcmp(ea, enp_softc[i].es_enaddr, 6))
        !           540:                        return(1);
        !           541:        }
        !           542:        return(0);
        !           543: }

unix.superglobalmegacorp.com

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