|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.