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