|
|
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.