Annotation of XNU/bsd/netat/ddp_aarp.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: /*     Copyright (c) 1988, 1989, 1997, 1998 Apple Computer, Inc. 
                     23:  *
                     24:  *    Modified for MP, 1996 by Tuyen Nguyen
                     25:  *   Modified, March 17, 1997 by Tuyen Nguyen for MacOSX.
                     26:  */
                     27: 
                     28: /* at_aarp.c: 2.0, 1.17; 10/4/93; Apple Computer, Inc. */;
                     29: 
                     30: /* This file is at_aarp.c and it contains all the routines used by AARP. This
                     31:  * is part of the LAP layer.
                     32:  */
                     33: 
                     34: #include <sys/errno.h>
                     35: #include <sys/types.h>
                     36: #include <sys/param.h>
                     37: #include <machine/spl.h>
                     38: #include <sys/systm.h>
                     39: #include <sys/kernel.h>
                     40: #include <sys/proc.h>
                     41: #include <sys/filedesc.h>
                     42: #include <sys/fcntl.h>
                     43: #include <sys/mbuf.h>
                     44: #include <sys/ioctl.h>
                     45: #include <sys/malloc.h>
                     46: #include <sys/socket.h>
                     47: #include <sys/socketvar.h>
                     48: 
                     49: #include <net/if.h>
                     50: #include <net/if_types.h>
                     51: #include <net/if_blue.h>
                     52: 
                     53: #include <netat/sysglue.h>
                     54: #include <netat/appletalk.h>
                     55: #include <netat/ddp.h>
                     56: #include <netat/lap.h>
                     57: #include <netat/at_snmp.h>
                     58: #include <netat/at_pcb.h>
                     59: #include <netat/at_var.h>
                     60: #include <netat/at_aarp.h>
                     61: #include <netat/debug.h>
                     62: #include <netat/at_config.h>
                     63: 
                     64: static int     probing;
                     65: /* Following two variables are used to keep track of how many dynamic addresses
                     66:  * we have tried out at startup.
                     67:  */
                     68: int    no_of_nodes_tried;      /* no of node addresses we've tried 
                     69:                                 * so far, within a network number
                     70:                                 */
                     71: int    no_of_nets_tried;       /* no. of network numbers tried
                     72:                                 */
                     73: 
                     74: struct etalk_addr      et_zeroaddr = {
                     75:        {0, 0, 0, 0, 0, 0}};
                     76: 
                     77: aarp_amt_t             probe_cb;
                     78: aarp_amt_array *aarp_table[IF_TOTAL_MAX];
                     79: 
                     80: int aarp_init1(), aarp_init2();
                     81: int aarp_send_data();
                     82: 
                     83: StaticProc int aarp_req_cmd_in();
                     84: StaticProc int aarp_resp_cmd_in();
                     85: StaticProc int aarp_probe_cmd_in();
                     86: StaticProc int aarp_send_resp();
                     87: StaticProc int aarp_send_req();
                     88: StaticProc int aarp_send_probe();
                     89: StaticProc aarp_amt_t *aarp_lru_entry();
                     90: StaticProc int aarp_glean_info();
                     91: StaticProc int aarp_delete_amt_info();
                     92: StaticProc int aarp_sched_probe();
                     93: StaticProc void aarp_build_pkt();
                     94: StaticProc int aarp_sched_req();
                     95: StaticProc int aarp_get_rand_node();
                     96: StaticProc int aarp_get_next_node();
                     97: StaticProc int aarp_get_rand_net();
                     98: atlock_t arpinp_lock;
                     99: 
                    100: extern void AARPwakeup(aarp_amt_t *);
                    101: extern int pat_output(at_ifaddr_t *, gbuf_t *, unsigned char *, int);
                    102: 
                    103: /****************************************************************************
                    104:  * aarp_init()
                    105:  *
                    106:  ****************************************************************************/
                    107: static int is_registered = 0;  /* For y-adapter */
                    108: 
                    109: extern struct BlueFilter RhapFilter[];
                    110: #ifdef BF_if
                    111: extern at_register_addr(struct BlueFilter *);
                    112: #else
                    113: extern at_register_addr(struct BlueFilter *, struct ifnet *);
                    114: #endif
                    115: 
                    116: int aarp_init1(elapp)
                    117:      register at_ifaddr_t      *elapp;
                    118: {
                    119:        elapp->ifThisNode.s_net = 0;
                    120:        elapp->ifThisNode.s_node = 0;
                    121: 
                    122:        if (is_registered)
                    123:        {       is_registered = 0;
                    124:                RhapFilter[BFS_ATALK].BF_flags = 0;
                    125:        }
                    126: 
                    127:        if (probing != PROBE_TENTATIVE) /* How do I set the initial probe */
                    128:                probing = PROBE_IDLE;   /* state ???*/
                    129:        else {
                    130:                dPrintf(D_M_AARP,D_L_ERROR, 
                    131:                        ("aarp_init: error :probing == PROBE_TENTATIVE\n"));
                    132:                return(-1);
                    133:        }
                    134: 
                    135:        /* pick a random addr or start with what we have from initial_node addr */
                    136:        if (elapp->initial_addr.s_net == 0 && elapp->initial_addr.s_node == 0) {
                    137:                dPrintf(D_M_AARP, D_L_INFO, 
                    138:                        ("aarp_init: pick up a new node number\n"));
                    139:                aarp_get_rand_node(elapp);
                    140:                aarp_get_rand_net(elapp);
                    141:        }
                    142:        probe_cb.elapp = elapp;
                    143:        probe_cb.no_of_retries = 0;
                    144:        probe_cb.error = 0;
                    145: 
                    146:        no_of_nodes_tried = 0; /* haven't tried any addresses yet */
                    147:        no_of_nets_tried = 0;
                    148: 
                    149:        if (aarp_send_probe() == -1) {
                    150:                probing = PROBE_IDLE;   /* not probing any more */
                    151:                dPrintf(D_M_AARP, D_L_ERROR, 
                    152:                        ("aarp_init: aarp_send_probe returns error\n"));
                    153:                return(-1);
                    154:        }
                    155:        return(ENOTREADY);
                    156: }
                    157: 
                    158: int aarp_init2(elapp)
                    159:      register at_ifaddr_t      *elapp;
                    160: {
                    161:        struct BlueFilter BF, *bf = &BF;
                    162: 
                    163:        if (probe_cb.error != 0) {
                    164:                probing = PROBE_IDLE;   /* not probing any more */
                    165:                dPrintf(D_M_AARP, D_L_ERROR,
                    166:                        ("aarp_init: probe_cb.error creates error =%d\n", 
                    167:                         probe_cb.error));
                    168:                return(-1);
                    169:        }
                    170: 
                    171:        if (aarp_table[elapp->ifPort])
                    172:                bzero ((caddr_t)&aarp_table[elapp->ifPort]->et_aarp_amt[0], 
                    173:                       sizeof(aarp_amt_array));
                    174:        else
                    175:                return(-1);
                    176: 
                    177:        elapp->ifThisNode = elapp->initial_addr;
                    178:        probing = PROBE_DONE;
                    179: 
                    180:        /* Register our node address with the y-adapter */
                    181:        bf->BF_flags = (BF_VALID|BF_ATALK);
                    182:        bf->BF_address = elapp->ifThisNode.s_net;
                    183:        bf->BF_node = elapp->ifThisNode.s_node;
                    184: #ifdef BF_ifp
                    185:        bf->BF_ifp = elapp->aa_ifp;
                    186: #endif
                    187: 
                    188: #ifdef BF_ifp
                    189:        at_register_addr(bf);
                    190: #else
                    191:        at_register_addr(bf, elapp->aa_ifp);
                    192: #endif
                    193:        is_registered = 1;
                    194: 
                    195:        return(0);
                    196: }
                    197: 
                    198: /*
                    199:  * Register an appletalk address:
                    200:  *  plant the info in a filter for the Y-adapter, if enabled
                    201:  */
                    202: int
                    203: at_register_addr(register struct BlueFilter *bf,
                    204: #ifndef BF_ifp
                    205:                 register struct ifnet *ifp
                    206: #endif
                    207:                 )
                    208: {      register struct BlueFilter *bf1;
                    209:        extern struct ifnet_blue *blue_if;
                    210: #ifdef BF_ifp
                    211:        register struct ifnet *ifp = bf->BF_ifp;
                    212: #endif
                    213:        if (blue_if != 0) {
                    214:                bf1=&blue_if->filter[BFS_ATALK];
                    215:                if (bf1->BF_flags & BF_VALID) { 
                    216:                        kprintf("Dammit, Rodney, how can I work with all these interruptions?\n");
                    217:                        return(1);
                    218:                }
                    219:                *bf1 = *bf;
                    220:                bf1->BF_flags |= BF_VALID;
                    221:        }
                    222:        return(0);
                    223: }
                    224: 
                    225: /****************************************************************************
                    226:  * aarp_rcv_pkt()
                    227:  *
                    228:  * remarks :
                    229:  *     (1) The caller must take care of freeing the real storage (gbuf)
                    230:  *     (2) The incoming packet is of the form {802.3, 802.2, aarp}.
                    231:  *
                    232:  ****************************************************************************/
                    233: int aarp_rcv_pkt(pkt, elapp)
                    234:      aarp_pkt_t *pkt;
                    235:      at_ifaddr_t *elapp;
                    236: {
                    237:        switch (pkt->aarp_cmd) {
                    238:        case AARP_REQ_CMD:
                    239:                return (aarp_req_cmd_in (pkt, elapp));
                    240:        case AARP_RESP_CMD:
                    241:                return (aarp_resp_cmd_in (pkt, elapp));
                    242:        case AARP_PROBE_CMD:
                    243:                return (aarp_probe_cmd_in (pkt, elapp));
                    244:        default:
                    245:                return (-1);
                    246:        }/* end of switch*/
                    247: }
                    248: 
                    249: /****************************************************************************
                    250:  *  aarp_req_cmd_in()
                    251:  *
                    252:  ****************************************************************************/
                    253: StaticProc   int       aarp_req_cmd_in (pkt, elapp)
                    254: aarp_pkt_t             *pkt;
                    255: at_ifaddr_t    *elapp;
                    256: {
                    257: /*
                    258:        kprintf("aarp_req_cmd_in: ifThisNode=%d:%d srcNode=%d:%d dstNode=%d:%d\n",
                    259:                        elapp->ifThisNode.s_net,
                    260:                        elapp->ifThisNode.s_node,
                    261:                        NET_VALUE(pkt->src_at_addr.atalk_net),
                    262:                        pkt->src_at_addr.atalk_node,
                    263:                        NET_VALUE(pkt->dest_at_addr.atalk_net),
                    264:                        pkt->dest_at_addr.atalk_node);
                    265: */
                    266:        if ((probing == PROBE_DONE) && 
                    267:            (NET_VALUE(pkt->dest_at_addr.atalk_net) == elapp->ifThisNode.s_net) &&
                    268:            (pkt->dest_at_addr.atalk_node == elapp->ifThisNode.s_node)) {
                    269:                if (aarp_send_resp(elapp, pkt) == -1)
                    270:                        return(-1);
                    271:        }
                    272:        /* now to glean some info */
                    273:        aarp_glean_info(pkt, elapp);
                    274:        return (0);
                    275: }
                    276: 
                    277: 
                    278: 
                    279: /****************************************************************************
                    280:  *  aarp_resp_cmd_in()
                    281:  *
                    282:  ****************************************************************************/
                    283: StaticProc int aarp_resp_cmd_in (pkt, elapp)
                    284:      aarp_pkt_t                *pkt;
                    285:      at_ifaddr_t       *elapp;
                    286: {
                    287:        register aarp_amt_t     *amt_ptr;
                    288:        gbuf_t                  *m;
                    289: 
                    290:        switch (probing) {
                    291:        case PROBE_TENTATIVE :
                    292:                if ((NET_VALUE(pkt->src_at_addr.atalk_net) == 
                    293:                     probe_cb.elapp->initial_addr.s_net) &&
                    294:                    (pkt->src_at_addr.atalk_node == 
                    295:                     probe_cb.elapp->initial_addr.s_node)) {
                    296: 
                    297:                        /* this is a response to AARP_PROBE_CMD.  There's
                    298:                         * someone out there with the address we desire
                    299:                         * for ourselves.
                    300:                         */
                    301:                        untimeout(aarp_sched_probe, 0);
                    302:                        probe_cb.no_of_retries = 0;
                    303:                        aarp_get_next_node(probe_cb.elapp);
                    304:                        no_of_nodes_tried++;
                    305: 
                    306:                        if (no_of_nodes_tried == AARP_MAX_NODES_TRIED) {
                    307:                                aarp_get_rand_net(probe_cb.elapp);
                    308:                                aarp_get_rand_node(probe_cb.elapp);
                    309:                                no_of_nodes_tried = 0;
                    310:                                no_of_nets_tried++;
                    311:                        }
                    312:                        if (no_of_nets_tried == AARP_MAX_NETS_TRIED) {
                    313:                                /* We have tried enough nodes and nets, give up.
                    314:                                 */
                    315:                                probe_cb.error = EADDRNOTAVAIL;
                    316:                                AARPwakeup(&probe_cb);
                    317:                                return(0);
                    318:                        }
                    319:                        if (aarp_send_probe() == -1) {
                    320:                                /* expecting aarp_send_probe to fill in 
                    321:                                 * probe_cb.error
                    322:                                 */
                    323:                                AARPwakeup(&probe_cb);
                    324:                                return(-1);
                    325:                        }
                    326:                } else {
                    327:                        /* hmmmm! got a response packet while still probing
                    328:                         * for AT address and the AT dest address doesn't
                    329:                         * match!!
                    330:                         * What should I do here??  kkkkkkkkk
                    331:                         */
                    332:                         return(-1);
                    333:                }
                    334:                break;
                    335: 
                    336:        case PROBE_DONE :
                    337:                AMT_LOOK(amt_ptr, pkt->src_at_addr, elapp);
                    338:                if (amt_ptr == NULL)
                    339:                        return(-1);
                    340:                if (amt_ptr->tmo) {
                    341:                        untimeout(aarp_sched_req, amt_ptr);
                    342:                        amt_ptr->tmo = 0;
                    343:                }
                    344: 
                    345:                if (amt_ptr->m == NULL) {
                    346:                        /* this may be because of a belated response to 
                    347:                         * aarp reaquest.  Based on an earlier response, we
                    348:                         * might have already sent the packet out, so 
                    349:                         * there's nothing to send now.  This is okay, no 
                    350:                         * error.
                    351:                         */
                    352:                        return(0);
                    353:                }
                    354:                amt_ptr->dest_addr = pkt->src_addr;
                    355:                if (FDDI_OR_TOKENRING(elapp->aa_ifp->if_type))
                    356:                        ddp_bit_reverse(&amt_ptr->dest_addr);
                    357:                m = amt_ptr->m;
                    358:                amt_ptr->m = NULL;
                    359:                pat_output(amt_ptr->elapp, m,
                    360:                           (unsigned char *)&amt_ptr->dest_addr, 0);
                    361:                break;
                    362:        default :
                    363:                /* probing in a weird state?? */
                    364:                return(-1);
                    365:        }
                    366:        return(0);
                    367: }
                    368: 
                    369: 
                    370: 
                    371: /****************************************************************************
                    372:  *  aarp_probe_cmd_in()
                    373:  *
                    374:  ****************************************************************************/
                    375: StaticProc   int       aarp_probe_cmd_in (pkt, elapp)
                    376: register aarp_pkt_t    *pkt;
                    377: at_ifaddr_t    *elapp;
                    378: {
                    379:        register aarp_amt_t     *amt_ptr;
                    380: 
                    381:        switch (probing) {
                    382:        case PROBE_TENTATIVE :
                    383:                if ((elapp == probe_cb.elapp) &&
                    384:                    (NET_VALUE(pkt->src_at_addr.atalk_net) == 
                    385:                     probe_cb.elapp->initial_addr.s_net) &&
                    386:                    (pkt->src_at_addr.atalk_node == 
                    387:                     probe_cb.elapp->initial_addr.s_node)) {
                    388:                        /* some bozo is probing for address I want... and I 
                    389:                         * can't tell him to shove off!
                    390:                         */
                    391:                        untimeout(aarp_sched_probe, 0);
                    392:                        probe_cb.no_of_retries = 0;
                    393:                        aarp_get_next_node(probe_cb.elapp);
                    394:                        no_of_nodes_tried++;
                    395: 
                    396:                        if (no_of_nodes_tried == AARP_MAX_NODES_TRIED) {
                    397:                                aarp_get_rand_net(probe_cb.elapp);
                    398:                                aarp_get_rand_node(probe_cb.elapp);
                    399:                                no_of_nodes_tried = 0;
                    400:                                no_of_nets_tried++;
                    401:                        }
                    402:                        if (no_of_nets_tried == AARP_MAX_NETS_TRIED) {
                    403:                                /* We have tried enough nodes and nets, give up.
                    404:                                 */
                    405:                                probe_cb.error = EADDRNOTAVAIL;
                    406:                                AARPwakeup(&probe_cb);
                    407:                                return(0);
                    408:                        }
                    409:                        if (aarp_send_probe() == -1) {
                    410:                                /* expecting aarp_send_probe to fill in 
                    411:                                 * probe_cb.error
                    412:                                 */
                    413:                                AARPwakeup(&probe_cb);
                    414:                                return(-1);
                    415:                        }
                    416:                } else {
                    417:                        /* somebody's probing... none of my business yet, so
                    418:                         * just ignore the packet
                    419:                         */
                    420:                        return (0);
                    421:                }
                    422:                break;
                    423: 
                    424:        case PROBE_DONE :
                    425:                if ((NET_VALUE(pkt->src_at_addr.atalk_net) == elapp->ifThisNode.s_net) &&
                    426:                    (pkt->src_at_addr.atalk_node == elapp->ifThisNode.s_node)) {
                    427:                        if (aarp_send_resp(elapp, pkt) == -1)
                    428:                                return (-1);
                    429:                        return (0);
                    430:                }
                    431:                AMT_LOOK(amt_ptr, pkt->src_at_addr, elapp);
                    432: 
                    433:                if (amt_ptr)
                    434:                        aarp_delete_amt_info(amt_ptr);
                    435:                break;
                    436:        default :
                    437:                /* probing in a weird state?? */
                    438:                return (-1);
                    439:        }
                    440:        return (0);
                    441: }
                    442: 
                    443: 
                    444: 
                    445: /****************************************************************************
                    446:  *  aarp_chk_addr()
                    447:  ****************************************************************************/
                    448: int aarp_chk_addr(ddp_hdrp, elapp)
                    449:      at_ddp_t  *ddp_hdrp;
                    450:      at_ifaddr_t *elapp;
                    451: {
                    452:        if ((ddp_hdrp->dst_node == elapp->ifThisNode.s_node) &&
                    453:            (NET_VALUE(ddp_hdrp->dst_net) == elapp->ifThisNode.s_net)) {
                    454:                return(0);          /* exact match in address */
                    455:                }
                    456: 
                    457:        if (AARP_BROADCAST(ddp_hdrp, elapp)) {
                    458:                return(0);          /* some kind of broadcast address */
                    459:        }
                    460:        return (AARP_ERR_NOT_OURS); /* not for us */
                    461: }
                    462: 
                    463: 
                    464: 
                    465: /****************************************************************************
                    466:  *  aarp_send_data()
                    467:  *
                    468:  * remarks :
                    469:  *     1. The message coming in would be of the form {802.3, 802.2, ddp,...} 
                    470:  *
                    471:  *     2. The message coming in would be freed here if transmission goes 
                    472:  *     through okay. If an error is returned by aarp_send_data, the caller 
                    473:  *     can assume that the message is not freed.  The exception to 
                    474:  *     this scenario is the prepended atalk_addr field.  This field
                    475:  *     will ALWAYS be removed.  If the message is dropped,
                    476:  *     it's not an "error".
                    477:  *
                    478:  ****************************************************************************/
                    479: 
                    480: int    aarp_send_data(m, elapp, dest_at_addr, loop)
                    481:      register gbuf_t   *m;
                    482:      register at_ifaddr_t  *elapp;
                    483:      struct  atalk_addr           *dest_at_addr;
                    484:      int               loop;                   /* if true, loopback broadcasts */
                    485: {
                    486:        register aarp_amt_t     *amt_ptr;
                    487:        register at_ddp_t       *ddp_hdrp;
                    488:        int                     error;
                    489:        int s;
                    490: 
                    491:        if (gbuf_len(m) <= 0)
                    492:                ddp_hdrp = (at_ddp_t *)gbuf_rptr(gbuf_cont(m));
                    493:        else
                    494:                ddp_hdrp = (at_ddp_t *)gbuf_rptr(m);
                    495: 
                    496:        if ((ddp_hdrp->dst_node == ddp_hdrp->src_node) &&
                    497:            (NET_VALUE(ddp_hdrp->dst_net)  == NET_VALUE(ddp_hdrp->src_net))) {
                    498:                /*
                    499:                 * we're sending to ourselves
                    500:                 * so loop it back upstream
                    501:                 */
                    502:                ddp_input(m, elapp);
                    503:                return(0);
                    504:        }
                    505:        ATDISABLE(s, arpinp_lock);
                    506:        AMT_LOOK(amt_ptr, *dest_at_addr, elapp);
                    507: 
                    508: 
                    509:        if (amt_ptr) {
                    510:                if (amt_ptr->m) {
                    511:                        /*
                    512:                         * there's already a packet awaiting transmission, so
                    513:                         * drop this one and let the upper layer retransmit
                    514:                         * later.
                    515:                         */
                    516:                        ATENABLE(s, arpinp_lock);
                    517:                        gbuf_freel(m);
                    518:                        return (0);
                    519:                }
                    520:                ATENABLE(s, arpinp_lock);
                    521:                return (pat_output(elapp, m,
                    522:                                   (unsigned char *)&amt_ptr->dest_addr, 0));
                    523:         }
                    524:        /*
                    525:         * either this is a packet to be broadcasted, or the address
                    526:         * resolution needs to be done
                    527:         */
                    528:        if (AARP_BROADCAST(ddp_hdrp, elapp)) {
                    529:                gbuf_t               *newm = 0;
                    530:                struct  etalk_addr   *dest_addr;
                    531: 
                    532:                ATENABLE(s, arpinp_lock);
                    533:                dest_addr =  &elapp->cable_multicast_addr;
                    534:                if (loop)
                    535:                        newm = (gbuf_t *)gbuf_dupm(m);
                    536: 
                    537:                if ( !(error = pat_output(elapp, m,
                    538:                                          (unsigned char *)dest_addr, 0))) { 
                    539:                        /*
                    540:                         * The message transmitted successfully;
                    541:                         * Also loop a copy back up since this
                    542:                         * is a broadcast message.
                    543:                         */
                    544:                        if (loop) {
                    545:                                if (newm == NULL)
                    546:                                        return (error);
                    547:                                ddp_input(newm, elapp);
                    548:                        } /* endif loop */
                    549:                } else {
                    550:                        if (newm)
                    551:                                gbuf_freem(newm);
                    552:                }
                    553:                return (error);
                    554:        }
                    555:        NEW_AMT(amt_ptr, *dest_at_addr,elapp);
                    556: 
                    557:         if (amt_ptr->m) {
                    558:                /*
                    559:                 * no non-busy slots available in the cache, so
                    560:                 * drop this one and let the upper layer retransmit
                    561:                 * later.
                    562:                 */
                    563:                ATENABLE(s, arpinp_lock);
                    564:                gbuf_freel(m);
                    565:                return (0);
                    566:        }
                    567:        amt_ptr->dest_at_addr = *dest_at_addr;
                    568:        amt_ptr->dest_at_addr.atalk_unused = 0;
                    569: 
                    570:        amt_ptr->last_time = time.tv_sec;
                    571:        amt_ptr->m = m;
                    572:        amt_ptr->elapp = elapp;
                    573:        amt_ptr->no_of_retries = 0;
                    574:        ATENABLE(s, arpinp_lock);
                    575: 
                    576:        if ((error = aarp_send_req(amt_ptr))) {
                    577:                aarp_delete_amt_info(amt_ptr);
                    578:                return(error);
                    579:        }
                    580:        return(0);
                    581: }
                    582: 
                    583: 
                    584: 
                    585: /****************************************************************************
                    586:  * aarp_send_resp()
                    587:  *
                    588:  * remarks :
                    589:  *     The pkt being passed here is only to "look at".  It should neither
                    590:  *     be used for transmission, nor freed.  Its contents also must not be
                    591:  *     altered.
                    592:  *
                    593:  ****************************************************************************/
                    594: StaticProc   int       aarp_send_resp(elapp, pkt)
                    595:      register at_ifaddr_t   *elapp;
                    596:      aarp_pkt_t                    *pkt;
                    597: {
                    598:        register aarp_pkt_t     *new_pkt;
                    599:        register gbuf_t         *m;
                    600: 
                    601:        if ((m = gbuf_alloc(AT_WR_OFFSET+sizeof(aarp_pkt_t), PRI_MED)) == NULL) {
                    602:                return (-1);
                    603:        }
                    604:        gbuf_rinc(m,AT_WR_OFFSET);
                    605:        gbuf_wset(m,0);
                    606: 
                    607:        new_pkt = (aarp_pkt_t *)gbuf_rptr(m);
                    608:        aarp_build_pkt(new_pkt, elapp);
                    609: 
                    610:        new_pkt->aarp_cmd = AARP_RESP_CMD;
                    611:        new_pkt->dest_addr =  pkt->src_addr;
                    612: 
                    613:        new_pkt->dest_at_addr = pkt->src_at_addr;
                    614:        new_pkt->dest_at_addr.atalk_unused = 0;
                    615: 
                    616:        ATALK_ASSIGN(new_pkt->src_at_addr, elapp->ifThisNode.s_net,
                    617:                     elapp->ifThisNode.s_node, 0);
                    618: 
                    619:        gbuf_winc(m,sizeof(aarp_pkt_t));
                    620:        if (FDDI_OR_TOKENRING(elapp->aa_ifp->if_type))
                    621:                ddp_bit_reverse(&new_pkt->dest_addr);
                    622: 
                    623:        if (pat_output(elapp, m, (unsigned char *)&new_pkt->dest_addr,
                    624:                       AARP_AT_TYPE))
                    625:                return(-1);
                    626:        return(0);
                    627: }
                    628: 
                    629: 
                    630: 
                    631: /****************************************************************************
                    632:  * aarp_send_req()
                    633:  *
                    634:  ****************************************************************************/
                    635: 
                    636: StaticProc   int       aarp_send_req (amt_ptr)
                    637: register aarp_amt_t    *amt_ptr;
                    638: {
                    639:        register aarp_pkt_t  *pkt;
                    640:        register gbuf_t      *m;
                    641:        int                  error;
                    642: 
                    643:        if ((m = gbuf_alloc(AT_WR_OFFSET+sizeof(aarp_pkt_t), PRI_MED)) == NULL) {
                    644:                return (ENOBUFS);
                    645:        }
                    646:        gbuf_rinc(m,AT_WR_OFFSET);
                    647:        gbuf_wset(m,0);
                    648: 
                    649:        pkt = (aarp_pkt_t *)gbuf_rptr(m);
                    650:        aarp_build_pkt(pkt, amt_ptr->elapp);
                    651: 
                    652:        pkt->aarp_cmd = AARP_REQ_CMD;
                    653:        pkt->dest_addr = et_zeroaddr;
                    654:        pkt->dest_at_addr = amt_ptr->dest_at_addr;
                    655:        pkt->dest_at_addr.atalk_unused = 0;
                    656:        ATALK_ASSIGN(pkt->src_at_addr, amt_ptr->elapp->ifThisNode.s_net,
                    657:                     amt_ptr->elapp->ifThisNode.s_node, 0);
                    658:        gbuf_winc(m,sizeof(aarp_pkt_t));
                    659:        
                    660:        amt_ptr->no_of_retries++;
                    661:        timeout(aarp_sched_req, amt_ptr, AARP_REQ_TIMER_INT);
                    662:        amt_ptr->tmo = 1;
                    663:        error = pat_output(amt_ptr->elapp, m,
                    664:                           (unsigned char *)&amt_ptr->elapp->cable_multicast_addr, AARP_AT_TYPE);
                    665:        if (error)
                    666:        {
                    667:                untimeout(aarp_sched_req, amt_ptr);
                    668:                amt_ptr->tmo = 0;
                    669:                return(error);
                    670:        }
                    671: 
                    672:        return(0);
                    673: }
                    674: 
                    675: 
                    676: 
                    677: /****************************************************************************
                    678:  * aarp_send_probe()
                    679:  *
                    680:  ****************************************************************************/
                    681: StaticProc  int        aarp_send_probe()
                    682: {
                    683:        register aarp_pkt_t  *pkt;
                    684:        register gbuf_t      *m;
                    685: 
                    686:        if ((m = gbuf_alloc(AT_WR_OFFSET+sizeof(aarp_pkt_t), PRI_MED)) == NULL) {
                    687:                probe_cb.error = ENOBUFS;
                    688:                return (-1);
                    689:        }
                    690:        gbuf_rinc(m,AT_WR_OFFSET);
                    691:        gbuf_wset(m,0);
                    692:        pkt = (aarp_pkt_t *)gbuf_rptr(m);
                    693:        aarp_build_pkt(pkt, probe_cb.elapp);
                    694: 
                    695:        pkt->aarp_cmd = AARP_PROBE_CMD;
                    696:        pkt->dest_addr = et_zeroaddr;
                    697: 
                    698:        ATALK_ASSIGN(pkt->src_at_addr, probe_cb.elapp->initial_addr.s_net,
                    699:                     probe_cb.elapp->initial_addr.s_node, 0);
                    700: 
                    701:        gbuf_winc(m,sizeof(aarp_pkt_t));
                    702: 
                    703:        probe_cb.error = pat_output(probe_cb.elapp, m,
                    704:                (unsigned char *)&probe_cb.elapp->cable_multicast_addr, AARP_AT_TYPE);
                    705:        if (probe_cb.error) {
                    706:                return(-1);
                    707:        }
                    708: 
                    709:        probing = PROBE_TENTATIVE;
                    710:        probe_cb.no_of_retries++;
                    711:        timeout(aarp_sched_probe, 0, AARP_PROBE_TIMER_INT);
                    712: 
                    713:        return(0);
                    714: }
                    715: 
                    716: 
                    717: 
                    718: /****************************************************************************
                    719:  * aarp_lru_entry()
                    720:  *
                    721:  ****************************************************************************/
                    722: 
                    723: StaticProc   aarp_amt_t        *aarp_lru_entry(at)
                    724: register aarp_amt_t    *at;
                    725: {
                    726:        register aarp_amt_t  *at_ret;
                    727:        register int         i;
                    728: 
                    729:        at_ret = at;
                    730: 
                    731:        for (i = 1, at++; i < AMT_BSIZ; i++, at++) {
                    732:                if (at->last_time < at_ret->last_time && (at->m == NULL))
                    733:                        at_ret = at;
                    734:        }
                    735:         return(at_ret);
                    736: }
                    737: 
                    738: 
                    739: 
                    740: /****************************************************************************
                    741:  * aarp_glean_info()
                    742:  *
                    743:  ****************************************************************************/
                    744: 
                    745: StaticProc   int       aarp_glean_info(pkt, elapp)
                    746: register aarp_pkt_t    *pkt;
                    747: at_ifaddr_t    *elapp;
                    748: {
                    749:     register aarp_amt_t   *amt_ptr;
                    750:        int s;
                    751: 
                    752:        ATDISABLE(s, arpinp_lock);
                    753:        AMT_LOOK(amt_ptr, pkt->src_at_addr, elapp);
                    754: 
                    755:        if (amt_ptr == NULL) {
                    756:                /*
                    757:                 * amt entry for this address doesn't exist, add it to the cache
                    758:                 */
                    759:                NEW_AMT(amt_ptr, pkt->src_at_addr,elapp); 
                    760: 
                    761:                if (amt_ptr->m)
                    762:                {
                    763:                ATENABLE(s, arpinp_lock);
                    764:                        return(0);     /* no non-busy slots available in the cache */
                    765:                }
                    766:                amt_ptr->dest_at_addr = pkt->src_at_addr;
                    767:                amt_ptr->dest_at_addr.atalk_unused = 0;
                    768: 
                    769:                amt_ptr->last_time = (int)random();
                    770:        }
                    771:        /*
                    772:         * update the ethernet address
                    773:         * in either case
                    774:         */
                    775:        amt_ptr->dest_addr = pkt->src_addr;
                    776:        if (FDDI_OR_TOKENRING(elapp->aa_ifp->if_type))
                    777:                ddp_bit_reverse(&amt_ptr->dest_addr);
                    778:        ATENABLE(s, arpinp_lock);
                    779:        return(1);
                    780: }
                    781: 
                    782: 
                    783: /****************************************************************************
                    784:  * aarp_delete_amt_info()
                    785:  *
                    786:  ****************************************************************************/
                    787: 
                    788: StaticProc   int       aarp_delete_amt_info(amt_ptr)
                    789: register aarp_amt_t    *amt_ptr;
                    790: {
                    791:        register s;
                    792:        register gbuf_t         *m;
                    793:        ATDISABLE(s, arpinp_lock);
                    794:        amt_ptr->last_time = 0;
                    795:        ATALK_ASSIGN(amt_ptr->dest_at_addr, 0, 0, 0);
                    796:        amt_ptr->no_of_retries = 0;
                    797: 
                    798:        if (amt_ptr->m) {
                    799:            m = amt_ptr->m;
                    800:            amt_ptr->m = NULL;    
                    801:            ATENABLE(s, arpinp_lock);
                    802:            gbuf_freel(m);
                    803:         }
                    804:        else
                    805:                ATENABLE(s, arpinp_lock);
                    806:        return(0);
                    807: }
                    808: 
                    809: 
                    810: 
                    811: /****************************************************************************
                    812:  * aarp_sched_probe()
                    813:  *
                    814:  ****************************************************************************/
                    815: 
                    816: StaticProc  int        aarp_sched_probe()
                    817: {
                    818:        if (probe_cb.no_of_retries != AARP_MAX_PROBE_RETRIES) {
                    819:                if (aarp_send_probe() == -1)
                    820:                        AARPwakeup(&probe_cb);
                    821:        } else {
                    822:                probe_cb.error = 0;
                    823:                AARPwakeup(&probe_cb);
                    824:        }
                    825: 
                    826:        return(0);
                    827: }
                    828: 
                    829: 
                    830: 
                    831: /****************************************************************************
                    832:  * aarp_build_pkt()
                    833:  *
                    834:  ****************************************************************************/
                    835: 
                    836: StaticProc void aarp_build_pkt(pkt, elapp)
                    837:      register aarp_pkt_t *pkt;
                    838:      at_ifaddr_t *elapp;
                    839: {
                    840:        pkt->hardware_type = AARP_ETHER_HW_TYPE;
                    841:        pkt->stack_type = AARP_AT_PROTO;
                    842:        pkt->hw_addr_len = ETHERNET_ADDR_LEN;
                    843:        pkt->stack_addr_len = AARP_AT_ADDR_LEN;
                    844:        bcopy(elapp->xaddr, pkt->src_addr.etalk_addr_octet, sizeof(elapp->xaddr));
                    845:        if (FDDI_OR_TOKENRING(elapp->aa_ifp->if_type))
                    846:                ddp_bit_reverse(pkt->src_addr.etalk_addr_octet);
                    847: }
                    848: 
                    849: /****************************************************************************
                    850:  * aarp_sched_req()
                    851:  *
                    852:  ****************************************************************************/
                    853: 
                    854: StaticProc   int       aarp_sched_req(amt_ptr)
                    855:      register aarp_amt_t *amt_ptr;
                    856: {
                    857:        int s;
                    858: 
                    859:        ATDISABLE(s, arpinp_lock);
                    860:        if (amt_ptr->tmo == 0)
                    861:        {
                    862:                ATENABLE(s, arpinp_lock);
                    863:                return(0);
                    864:        }
                    865:        if (amt_ptr->no_of_retries < AARP_MAX_REQ_RETRIES) {
                    866:                ATENABLE(s, arpinp_lock);
                    867:                if (aarp_send_req(amt_ptr) == 0)
                    868:                        return(0);
                    869:                ATDISABLE(s, arpinp_lock);
                    870:        }
                    871:        ATENABLE(s, arpinp_lock);
                    872:        aarp_delete_amt_info(amt_ptr);
                    873:        return(0);
                    874: }
                    875: 
                    876: 
                    877: 
                    878: /****************************************************************************
                    879:  * aarp_get_rand_node()
                    880:  *
                    881:  ****************************************************************************/
                    882: StaticProc   int       aarp_get_rand_node(elapp)
                    883: at_ifaddr_t    *elapp;
                    884: {
                    885:        register u_char node;
                    886: 
                    887:        /*
                    888:         * generate a starting node number in the range 1 thru 0xfd.
                    889:         * we use this as the starting probe point for a given net
                    890:         * To generate a different node number each time we call
                    891:          * aarp_get_next_node
                    892:         */
                    893:        node = ((u_char)(random() & 0xff)) % 0xfd + 2;
                    894:        
                    895:        elapp->initial_addr.s_node = node;
                    896:        return(0);
                    897: }
                    898: 
                    899: 
                    900: 
                    901: StaticProc   int       aarp_get_next_node(elapp)
                    902: at_ifaddr_t    *elapp;
                    903: {
                    904:        register u_char node = elapp->initial_addr.s_node;
                    905: 
                    906:        /*
                    907:         * return the next node number in the range 1 thru 0xfd.
                    908:         */
                    909:        node = (node == 0xfd) ? (1) : (node+1);
                    910: 
                    911:        elapp->initial_addr.s_node = node;
                    912:        return(0);
                    913: }
                    914: 
                    915: 
                    916: 
                    917: 
                    918: 
                    919: /****************************************************************************
                    920:  * aarp_get_rand_net()
                    921:  *
                    922:  ****************************************************************************/
                    923: StaticProc   int       aarp_get_rand_net(elapp)
                    924: register at_ifaddr_t   *elapp;
                    925: {
                    926:        register at_net_al       last_net, new_net;
                    927: 
                    928:        if (elapp->ifThisCableStart) {
                    929:                last_net = elapp->initial_addr.s_net;
                    930:                /*
                    931:                 * the range of network numbers valid for this
                    932:                 * cable is known.  Try to choose a number from
                    933:                 * this range only.  
                    934:                 */
                    935:                new_net= ((at_net_al)random() & 0xffff);
                    936:                /* two-byte random number generated... now fit it in 
                    937:                 * the prescribed range 
                    938:                 */
                    939:                new_net = new_net % (unsigned) (elapp->ifThisCableEnd - 
                    940:                                     elapp->ifThisCableStart + 1)
                    941:                          + elapp->ifThisCableStart;
                    942: 
                    943:                if (new_net == last_net) {
                    944:                        if (new_net == elapp->ifThisCableEnd)
                    945:                                new_net = elapp->ifThisCableStart;
                    946:                        else
                    947:                                new_net++;
                    948:                }
                    949:                elapp->initial_addr.s_net = new_net;
                    950:        } else {
                    951:                /* The range of valid network numbers for this cable
                    952:                 * is not known... choose a network number from
                    953:                 * startup range.
                    954:                 */
                    955:                last_net = (elapp->initial_addr.s_net & 0x00ff);
                    956:                new_net = (at_net_al)random() & 0x00ff;
                    957: 
                    958:                if (new_net == last_net)
                    959:                        new_net++;
                    960:                if (new_net == 0xff)
                    961:                        new_net = 0;
                    962:                elapp->initial_addr.s_net = (DDP_STARTUP_LOW | new_net);
                    963:        }
                    964:        return(0);
                    965: }
                    966: 
                    967: 
                    968: int getAarpTableSize(elapId)
                    969:      int       elapId;                 /* elap_specifics array index (should be
                    970:                                         * changed when we add a non-ethernet type
                    971:                                         * of I/F to the mix. Unused for now.
                    972:                                         */
                    973: {
                    974:        return(AMTSIZE);
                    975: }
                    976: 
                    977: int getPhysAddrSize(elapId)
                    978:      int       elapId;                 /* elap_specifics array index (should be
                    979:                                         * changed when we add a non-ethernet type
                    980:                                         * of I/F to the mix. Unused for now.
                    981:                                         */
                    982: {
                    983:        return(ETHERNET_ADDR_LEN);
                    984: }
                    985: 
                    986: #define ENTRY_SIZE     sizeof(struct atalk_addr) + sizeof(struct etalk_addr)
                    987: 
                    988: snmpAarpEnt_t *getAarp(elapId)
                    989:      int               *elapId;                /* I/F table to retrieve & table
                    990:                                           size entries on return */
                    991: 
                    992: /* gets aarp table for specified interface and builds
                    993:    a table in SNMP expected format. Returns pointer to said
                    994:    table and sets elapId to byte size of used portion of table
                    995: */
                    996: {
                    997:        int i, cnt=0;
                    998:        aarp_amt_t *amtp;
                    999:        static snmpAarpEnt_t  snmp[AMTSIZE];
                   1000:        snmpAarpEnt_t  *snmpp;
                   1001: 
                   1002: 
                   1003:        if (*elapId <0 || *elapId >= IF_TOTAL_MAX)
                   1004:                return NULL;
                   1005:        
                   1006:        
                   1007:        for (i=0, amtp = &(aarp_table[*elapId]->et_aarp_amt[0]), snmpp = snmp;
                   1008:                 i < AMTSIZE; i++,amtp++)       {
                   1009: 
                   1010:                /* last_time will be 0 if entry was never used */
                   1011:                if (amtp->last_time) {
                   1012:                                /* copy just network & mac address.
                   1013:                                 * For speed, we assume that the atalk_addr
                   1014:                                 * & etalk_addr positions in the aarp_amt_t struct
                   1015:                                 * has not changed and copy both at once
                   1016:                                 */
                   1017:                        bcopy(&amtp->dest_at_addr, &snmpp->ap_ddpAddr, ENTRY_SIZE);
                   1018:                        snmpp++;
                   1019:                        cnt++;
                   1020:                        
                   1021:                }
                   1022:        }
                   1023:        *elapId = cnt;
                   1024:        return(snmp);
                   1025: }
                   1026: /*#endif *//*  COMMENTED_OUT */
                   1027: 

unix.superglobalmegacorp.com

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