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

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

unix.superglobalmegacorp.com

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