]>
git.saurik.com Git - apple/xnu.git/blob - bsd/netat/ddp_aarp.c
430432ea6b6bd15b79f667d2ea7f3cba0b665818
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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.
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
20 * @APPLE_LICENSE_HEADER_END@
22 /* Copyright (c) 1988, 1989, 1997, 1998 Apple Computer, Inc.
24 * Modified for MP, 1996 by Tuyen Nguyen
25 * Modified, March 17, 1997 by Tuyen Nguyen for MacOSX.
28 /* at_aarp.c: 2.0, 1.17; 10/4/93; Apple Computer, Inc. */;
30 /* This file is at_aarp.c and it contains all the routines used by AARP. This
31 * is part of the LAP layer.
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>
41 #include <sys/filedesc.h>
42 #include <sys/fcntl.h>
44 #include <sys/ioctl.h>
45 #include <sys/malloc.h>
46 #include <sys/socket.h>
47 #include <sys/socketvar.h>
50 #include <net/if_types.h>
52 #include <netat/sysglue.h>
53 #include <netat/appletalk.h>
54 #include <netat/ddp.h>
55 #include <netat/at_snmp.h>
56 #include <netat/at_pcb.h>
57 #include <netat/at_var.h>
58 #include <netat/at_aarp.h>
59 #include <netat/debug.h>
61 #include <sys/kern_event.h>
64 /* Following two variables are used to keep track of how many dynamic addresses
65 * we have tried out at startup.
67 int no_of_nodes_tried
; /* no of node addresses we've tried
68 * so far, within a network number
70 int no_of_nets_tried
; /* no. of network numbers tried
73 struct etalk_addr et_zeroaddr
= {
77 aarp_amt_array
*aarp_table
[IF_TOTAL_MAX
];
79 int aarp_init1(), aarp_init2();
81 int aarp_sched_probe();
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
void aarp_build_pkt();
93 StaticProc
int aarp_sched_req();
94 StaticProc
int aarp_get_rand_node();
95 StaticProc
int aarp_get_next_node();
96 StaticProc
int aarp_get_rand_net();
99 extern void AARPwakeup(aarp_amt_t
*);
100 extern int pat_output(at_ifaddr_t
*, gbuf_t
*, unsigned char *, int);
102 /****************************************************************************
105 ****************************************************************************/
107 int aarp_init1(elapp
)
108 register at_ifaddr_t
*elapp
;
110 elapp
->ifThisNode
.s_net
= 0;
111 elapp
->ifThisNode
.s_node
= 0;
113 if (probing
!= PROBE_TENTATIVE
) /* How do I set the initial probe */
114 probing
= PROBE_IDLE
; /* state ???*/
116 dPrintf(D_M_AARP
,D_L_ERROR
,
117 ("aarp_init: error :probing == PROBE_TENTATIVE\n"));
121 /* pick a random addr or start with what we have from initial_node addr */
122 if (elapp
->initial_addr
.s_net
== 0 && elapp
->initial_addr
.s_node
== 0) {
123 dPrintf(D_M_AARP
, D_L_INFO
,
124 ("aarp_init: pick up a new node number\n"));
125 aarp_get_rand_node(elapp
);
126 aarp_get_rand_net(elapp
);
128 probe_cb
.elapp
= elapp
;
129 probe_cb
.no_of_retries
= 0;
132 no_of_nodes_tried
= 0; /* haven't tried any addresses yet */
133 no_of_nets_tried
= 0;
135 if (aarp_send_probe() == -1) {
136 probing
= PROBE_IDLE
; /* not probing any more */
137 dPrintf(D_M_AARP
, D_L_ERROR
,
138 ("aarp_init: aarp_send_probe returns error\n"));
144 int aarp_init2(elapp
)
145 register at_ifaddr_t
*elapp
;
147 if (probe_cb
.error
!= 0) {
148 probing
= PROBE_IDLE
; /* not probing any more */
149 dPrintf(D_M_AARP
, D_L_ERROR
,
150 ("aarp_init: probe_cb.error creates error =%d\n",
155 if (aarp_table
[elapp
->ifPort
])
156 bzero ((caddr_t
)&aarp_table
[elapp
->ifPort
]->et_aarp_amt
[0],
157 sizeof(aarp_amt_array
));
161 elapp
->ifThisNode
= elapp
->initial_addr
;
162 probing
= PROBE_DONE
;
164 /* AppleTalk was successfully started up. Send event with node and net. */
165 atalk_post_msg(elapp
->aa_ifp
, KEV_ATALK_ENABLED
, &(elapp
->ifThisNode
), 0);
167 /* Set global flag */
168 at_state
.flags
|= AT_ST_STARTED
;
173 /****************************************************************************
177 * (1) The caller must take care of freeing the real storage (gbuf)
178 * (2) The incoming packet is of the form {802.3, 802.2, aarp}.
180 ****************************************************************************/
181 int aarp_rcv_pkt(pkt
, elapp
)
185 switch (pkt
->aarp_cmd
) {
187 return (aarp_req_cmd_in (pkt
, elapp
));
189 return (aarp_resp_cmd_in (pkt
, elapp
));
191 return (aarp_probe_cmd_in (pkt
, elapp
));
197 /****************************************************************************
200 ****************************************************************************/
201 StaticProc
int aarp_req_cmd_in (pkt
, elapp
)
206 kprintf("aarp_req_cmd_in: ifThisNode=%d:%d srcNode=%d:%d dstNode=%d:%d\n",
207 elapp->ifThisNode.s_net,
208 elapp->ifThisNode.s_node,
209 NET_VALUE(pkt->src_at_addr.atalk_net),
210 pkt->src_at_addr.atalk_node,
211 NET_VALUE(pkt->dest_at_addr.atalk_net),
212 pkt->dest_at_addr.atalk_node);
214 if ((probing
== PROBE_DONE
) &&
215 (NET_VALUE(pkt
->dest_at_addr
.atalk_net
) == elapp
->ifThisNode
.s_net
) &&
216 (pkt
->dest_at_addr
.atalk_node
== elapp
->ifThisNode
.s_node
)) {
217 if (aarp_send_resp(elapp
, pkt
) == -1)
220 /* now to glean some info */
221 aarp_glean_info(pkt
, elapp
);
227 /****************************************************************************
230 ****************************************************************************/
231 StaticProc
int aarp_resp_cmd_in (pkt
, elapp
)
235 register aarp_amt_t
*amt_ptr
;
239 case PROBE_TENTATIVE
:
240 if ((NET_VALUE(pkt
->src_at_addr
.atalk_net
) ==
241 probe_cb
.elapp
->initial_addr
.s_net
) &&
242 (pkt
->src_at_addr
.atalk_node
==
243 probe_cb
.elapp
->initial_addr
.s_node
)) {
245 /* this is a response to AARP_PROBE_CMD. There's
246 * someone out there with the address we desire
249 untimeout(aarp_sched_probe
, 0);
250 probe_cb
.no_of_retries
= 0;
251 aarp_get_next_node(probe_cb
.elapp
);
254 if (no_of_nodes_tried
== AARP_MAX_NODES_TRIED
) {
255 aarp_get_rand_net(probe_cb
.elapp
);
256 aarp_get_rand_node(probe_cb
.elapp
);
257 no_of_nodes_tried
= 0;
260 if (no_of_nets_tried
== AARP_MAX_NETS_TRIED
) {
261 /* We have tried enough nodes and nets, give up.
263 probe_cb
.error
= EADDRNOTAVAIL
;
264 AARPwakeup(&probe_cb
);
267 if (aarp_send_probe() == -1) {
268 /* expecting aarp_send_probe to fill in
271 AARPwakeup(&probe_cb
);
275 /* hmmmm! got a response packet while still probing
276 * for AT address and the AT dest address doesn't
278 * What should I do here?? kkkkkkkkk
285 AMT_LOOK(amt_ptr
, pkt
->src_at_addr
, elapp
);
289 untimeout(aarp_sched_req
, amt_ptr
);
293 if (amt_ptr
->m
== NULL
) {
294 /* this may be because of a belated response to
295 * aarp reaquest. Based on an earlier response, we
296 * might have already sent the packet out, so
297 * there's nothing to send now. This is okay, no
302 amt_ptr
->dest_addr
= pkt
->src_addr
;
303 if (FDDI_OR_TOKENRING(elapp
->aa_ifp
->if_type
))
304 ddp_bit_reverse(&amt_ptr
->dest_addr
);
307 pat_output(amt_ptr
->elapp
, m
,
308 (unsigned char *)&amt_ptr
->dest_addr
, 0);
311 /* probing in a weird state?? */
319 /****************************************************************************
320 * aarp_probe_cmd_in()
322 ****************************************************************************/
323 StaticProc
int aarp_probe_cmd_in (pkt
, elapp
)
324 register aarp_pkt_t
*pkt
;
327 register aarp_amt_t
*amt_ptr
;
330 case PROBE_TENTATIVE
:
331 if ((elapp
== probe_cb
.elapp
) &&
332 (NET_VALUE(pkt
->src_at_addr
.atalk_net
) ==
333 probe_cb
.elapp
->initial_addr
.s_net
) &&
334 (pkt
->src_at_addr
.atalk_node
==
335 probe_cb
.elapp
->initial_addr
.s_node
)) {
336 /* some bozo is probing for address I want... and I
337 * can't tell him to shove off!
339 untimeout(aarp_sched_probe
, 0);
340 probe_cb
.no_of_retries
= 0;
341 aarp_get_next_node(probe_cb
.elapp
);
344 if (no_of_nodes_tried
== AARP_MAX_NODES_TRIED
) {
345 aarp_get_rand_net(probe_cb
.elapp
);
346 aarp_get_rand_node(probe_cb
.elapp
);
347 no_of_nodes_tried
= 0;
350 if (no_of_nets_tried
== AARP_MAX_NETS_TRIED
) {
351 /* We have tried enough nodes and nets, give up.
353 probe_cb
.error
= EADDRNOTAVAIL
;
354 AARPwakeup(&probe_cb
);
357 if (aarp_send_probe() == -1) {
358 /* expecting aarp_send_probe to fill in
361 AARPwakeup(&probe_cb
);
365 /* somebody's probing... none of my business yet, so
366 * just ignore the packet
373 if ((NET_VALUE(pkt
->src_at_addr
.atalk_net
) == elapp
->ifThisNode
.s_net
) &&
374 (pkt
->src_at_addr
.atalk_node
== elapp
->ifThisNode
.s_node
)) {
375 if (aarp_send_resp(elapp
, pkt
) == -1)
379 AMT_LOOK(amt_ptr
, pkt
->src_at_addr
, elapp
);
382 aarp_delete_amt_info(amt_ptr
);
385 /* probing in a weird state?? */
393 /****************************************************************************
395 ****************************************************************************/
396 int aarp_chk_addr(ddp_hdrp
, elapp
)
400 if ((ddp_hdrp
->dst_node
== elapp
->ifThisNode
.s_node
) &&
401 (NET_VALUE(ddp_hdrp
->dst_net
) == elapp
->ifThisNode
.s_net
)) {
402 return(0); /* exact match in address */
405 if (AARP_BROADCAST(ddp_hdrp
, elapp
)) {
406 return(0); /* some kind of broadcast address */
408 return (AARP_ERR_NOT_OURS
); /* not for us */
413 /****************************************************************************
417 * 1. The message coming in would be of the form {802.3, 802.2, ddp,...}
419 * 2. The message coming in would be freed here if transmission goes
420 * through okay. If an error is returned by aarp_send_data, the caller
421 * can assume that the message is not freed. The exception to
422 * this scenario is the prepended atalk_addr field. This field
423 * will ALWAYS be removed. If the message is dropped,
424 * it's not an "error".
426 ****************************************************************************/
428 int aarp_send_data(m
, elapp
, dest_at_addr
, loop
)
430 register at_ifaddr_t
*elapp
;
431 struct atalk_addr
*dest_at_addr
;
432 int loop
; /* if true, loopback broadcasts */
434 register aarp_amt_t
*amt_ptr
;
435 register at_ddp_t
*ddp_hdrp
;
439 if (gbuf_len(m
) <= 0)
440 ddp_hdrp
= (at_ddp_t
*)gbuf_rptr(gbuf_cont(m
));
442 ddp_hdrp
= (at_ddp_t
*)gbuf_rptr(m
);
444 if ((ddp_hdrp
->dst_node
== ddp_hdrp
->src_node
) &&
445 (NET_VALUE(ddp_hdrp
->dst_net
) == NET_VALUE(ddp_hdrp
->src_net
))) {
447 * we're sending to ourselves
448 * so loop it back upstream
453 ATDISABLE(s
, arpinp_lock
);
454 AMT_LOOK(amt_ptr
, *dest_at_addr
, elapp
);
460 * there's already a packet awaiting transmission, so
461 * drop this one and let the upper layer retransmit
464 ATENABLE(s
, arpinp_lock
);
468 ATENABLE(s
, arpinp_lock
);
469 return (pat_output(elapp
, m
,
470 (unsigned char *)&amt_ptr
->dest_addr
, 0));
473 * either this is a packet to be broadcasted, or the address
474 * resolution needs to be done
476 if (AARP_BROADCAST(ddp_hdrp
, elapp
)) {
478 struct etalk_addr
*dest_addr
;
480 ATENABLE(s
, arpinp_lock
);
481 dest_addr
= &elapp
->cable_multicast_addr
;
483 newm
= (gbuf_t
*)gbuf_dupm(m
);
485 if ( !(error
= pat_output(elapp
, m
,
486 (unsigned char *)dest_addr
, 0))) {
488 * The message transmitted successfully;
489 * Also loop a copy back up since this
490 * is a broadcast message.
495 ddp_input(newm
, elapp
);
503 NEW_AMT(amt_ptr
, *dest_at_addr
,elapp
);
507 * no non-busy slots available in the cache, so
508 * drop this one and let the upper layer retransmit
511 ATENABLE(s
, arpinp_lock
);
515 amt_ptr
->dest_at_addr
= *dest_at_addr
;
516 amt_ptr
->dest_at_addr
.atalk_unused
= 0;
518 amt_ptr
->last_time
= time
.tv_sec
;
520 amt_ptr
->elapp
= elapp
;
521 amt_ptr
->no_of_retries
= 0;
522 ATENABLE(s
, arpinp_lock
);
524 if ((error
= aarp_send_req(amt_ptr
))) {
525 aarp_delete_amt_info(amt_ptr
);
533 /****************************************************************************
537 * The pkt being passed here is only to "look at". It should neither
538 * be used for transmission, nor freed. Its contents also must not be
541 ****************************************************************************/
542 StaticProc
int aarp_send_resp(elapp
, pkt
)
543 register at_ifaddr_t
*elapp
;
546 register aarp_pkt_t
*new_pkt
;
549 if ((m
= gbuf_alloc(AT_WR_OFFSET
+sizeof(aarp_pkt_t
), PRI_MED
)) == NULL
) {
552 gbuf_rinc(m
,AT_WR_OFFSET
);
555 new_pkt
= (aarp_pkt_t
*)gbuf_rptr(m
);
556 aarp_build_pkt(new_pkt
, elapp
);
558 new_pkt
->aarp_cmd
= AARP_RESP_CMD
;
559 new_pkt
->dest_addr
= pkt
->src_addr
;
561 new_pkt
->dest_at_addr
= pkt
->src_at_addr
;
562 new_pkt
->dest_at_addr
.atalk_unused
= 0;
564 ATALK_ASSIGN(new_pkt
->src_at_addr
, elapp
->ifThisNode
.s_net
,
565 elapp
->ifThisNode
.s_node
, 0);
567 gbuf_winc(m
,sizeof(aarp_pkt_t
));
568 if (FDDI_OR_TOKENRING(elapp
->aa_ifp
->if_type
))
569 ddp_bit_reverse(&new_pkt
->dest_addr
);
571 if (pat_output(elapp
, m
, (unsigned char *)&new_pkt
->dest_addr
,
579 /****************************************************************************
582 ****************************************************************************/
584 StaticProc
int aarp_send_req (amt_ptr
)
585 register aarp_amt_t
*amt_ptr
;
587 register aarp_pkt_t
*pkt
;
591 if ((m
= gbuf_alloc(AT_WR_OFFSET
+sizeof(aarp_pkt_t
), PRI_MED
)) == NULL
) {
594 gbuf_rinc(m
,AT_WR_OFFSET
);
597 pkt
= (aarp_pkt_t
*)gbuf_rptr(m
);
598 aarp_build_pkt(pkt
, amt_ptr
->elapp
);
600 pkt
->aarp_cmd
= AARP_REQ_CMD
;
601 pkt
->dest_addr
= et_zeroaddr
;
602 pkt
->dest_at_addr
= amt_ptr
->dest_at_addr
;
603 pkt
->dest_at_addr
.atalk_unused
= 0;
604 ATALK_ASSIGN(pkt
->src_at_addr
, amt_ptr
->elapp
->ifThisNode
.s_net
,
605 amt_ptr
->elapp
->ifThisNode
.s_node
, 0);
606 gbuf_winc(m
,sizeof(aarp_pkt_t
));
608 amt_ptr
->no_of_retries
++;
609 timeout(aarp_sched_req
, amt_ptr
, AARP_REQ_TIMER_INT
);
611 error
= pat_output(amt_ptr
->elapp
, m
,
612 (unsigned char *)&amt_ptr
->elapp
->cable_multicast_addr
, AARP_AT_TYPE
);
615 untimeout(aarp_sched_req
, amt_ptr
);
625 /****************************************************************************
628 ****************************************************************************/
629 StaticProc
int aarp_send_probe()
631 register aarp_pkt_t
*pkt
;
634 if ((m
= gbuf_alloc(AT_WR_OFFSET
+sizeof(aarp_pkt_t
), PRI_MED
)) == NULL
) {
635 probe_cb
.error
= ENOBUFS
;
638 gbuf_rinc(m
,AT_WR_OFFSET
);
640 pkt
= (aarp_pkt_t
*)gbuf_rptr(m
);
641 aarp_build_pkt(pkt
, probe_cb
.elapp
);
643 pkt
->aarp_cmd
= AARP_PROBE_CMD
;
644 pkt
->dest_addr
= et_zeroaddr
;
646 ATALK_ASSIGN(pkt
->src_at_addr
, probe_cb
.elapp
->initial_addr
.s_net
,
647 probe_cb
.elapp
->initial_addr
.s_node
, 0);
649 ATALK_ASSIGN(pkt
->dest_at_addr
, probe_cb
.elapp
->initial_addr
.s_net
,
650 probe_cb
.elapp
->initial_addr
.s_node
, 0);
652 gbuf_winc(m
,sizeof(aarp_pkt_t
));
654 probe_cb
.error
= pat_output(probe_cb
.elapp
, m
,
655 (unsigned char *)&probe_cb
.elapp
->cable_multicast_addr
, AARP_AT_TYPE
);
656 if (probe_cb
.error
) {
660 probing
= PROBE_TENTATIVE
;
661 probe_cb
.no_of_retries
++;
662 timeout(aarp_sched_probe
, 0, AARP_PROBE_TIMER_INT
);
669 /****************************************************************************
672 ****************************************************************************/
674 StaticProc aarp_amt_t
*aarp_lru_entry(at
)
675 register aarp_amt_t
*at
;
677 register aarp_amt_t
*at_ret
;
682 for (i
= 1, at
++; i
< AMT_BSIZ
; i
++, at
++) {
683 if (at
->last_time
< at_ret
->last_time
&& (at
->m
== NULL
))
691 /****************************************************************************
694 ****************************************************************************/
696 StaticProc
int aarp_glean_info(pkt
, elapp
)
697 register aarp_pkt_t
*pkt
;
700 register aarp_amt_t
*amt_ptr
;
703 ATDISABLE(s
, arpinp_lock
);
704 AMT_LOOK(amt_ptr
, pkt
->src_at_addr
, elapp
);
706 if (amt_ptr
== NULL
) {
708 * amt entry for this address doesn't exist, add it to the cache
710 NEW_AMT(amt_ptr
, pkt
->src_at_addr
,elapp
);
714 ATENABLE(s
, arpinp_lock
);
715 return(0); /* no non-busy slots available in the cache */
717 amt_ptr
->dest_at_addr
= pkt
->src_at_addr
;
718 amt_ptr
->dest_at_addr
.atalk_unused
= 0;
720 amt_ptr
->last_time
= (int)random();
723 * update the ethernet address
726 amt_ptr
->dest_addr
= pkt
->src_addr
;
727 if (FDDI_OR_TOKENRING(elapp
->aa_ifp
->if_type
))
728 ddp_bit_reverse(&amt_ptr
->dest_addr
);
729 ATENABLE(s
, arpinp_lock
);
734 /****************************************************************************
735 * aarp_delete_amt_info()
737 ****************************************************************************/
739 StaticProc
int aarp_delete_amt_info(amt_ptr
)
740 register aarp_amt_t
*amt_ptr
;
744 ATDISABLE(s
, arpinp_lock
);
745 amt_ptr
->last_time
= 0;
746 ATALK_ASSIGN(amt_ptr
->dest_at_addr
, 0, 0, 0);
747 amt_ptr
->no_of_retries
= 0;
752 ATENABLE(s
, arpinp_lock
);
756 ATENABLE(s
, arpinp_lock
);
762 /****************************************************************************
765 ****************************************************************************/
767 int aarp_sched_probe()
769 boolean_t funnel_state
;
771 funnel_state
= thread_funnel_set(network_flock
, TRUE
);
773 if (probe_cb
.no_of_retries
!= AARP_MAX_PROBE_RETRIES
) {
774 if (aarp_send_probe() == -1)
775 AARPwakeup(&probe_cb
);
778 AARPwakeup(&probe_cb
);
781 (void) thread_funnel_set(network_flock
, FALSE
);
787 /****************************************************************************
790 ****************************************************************************/
792 StaticProc
void aarp_build_pkt(pkt
, elapp
)
793 register aarp_pkt_t
*pkt
;
796 pkt
->hardware_type
= AARP_ETHER_HW_TYPE
;
797 pkt
->stack_type
= AARP_AT_PROTO
;
798 pkt
->hw_addr_len
= ETHERNET_ADDR_LEN
;
799 pkt
->stack_addr_len
= AARP_AT_ADDR_LEN
;
800 bcopy(elapp
->xaddr
, pkt
->src_addr
.etalk_addr_octet
, sizeof(elapp
->xaddr
));
801 if (FDDI_OR_TOKENRING(elapp
->aa_ifp
->if_type
))
802 ddp_bit_reverse(pkt
->src_addr
.etalk_addr_octet
);
805 /****************************************************************************
808 ****************************************************************************/
810 StaticProc
int aarp_sched_req(amt_ptr
)
811 register aarp_amt_t
*amt_ptr
;
814 boolean_t funnel_state
;
816 funnel_state
= thread_funnel_set(network_flock
, TRUE
);
819 * make sure pointer still valid in case interface removed
820 * while trying to acquire the funnel. make sure it points
821 * into one of the amt arrays.
823 for (i
= 0; i
< IF_TOTAL_MAX
; i
++) {
824 if (aarp_table
[i
] == NULL
|| amt_ptr
< aarp_table
[i
] || amt_ptr
>= (aarp_table
[i
] + 1))
825 continue; /* no match - try next entry */
828 * found match - pointer is valid
830 ATDISABLE(s
, arpinp_lock
);
831 if (amt_ptr
->tmo
== 0) {
832 ATENABLE(s
, arpinp_lock
);
833 (void) thread_funnel_set(network_flock
, FALSE
);
836 if (amt_ptr
->no_of_retries
< AARP_MAX_REQ_RETRIES
) {
837 ATENABLE(s
, arpinp_lock
);
838 if (aarp_send_req(amt_ptr
) == 0) {
839 (void) thread_funnel_set(network_flock
, FALSE
);
842 ATDISABLE(s
, arpinp_lock
);
844 ATENABLE(s
, arpinp_lock
);
845 aarp_delete_amt_info(amt_ptr
);
848 (void) thread_funnel_set(network_flock
, FALSE
);
855 /****************************************************************************
856 * aarp_get_rand_node()
858 ****************************************************************************/
859 StaticProc
int aarp_get_rand_node(elapp
)
862 register u_char node
;
865 * generate a starting node number in the range 1 thru 0xfd.
866 * we use this as the starting probe point for a given net
867 * To generate a different node number each time we call
870 node
= ((u_char
)(random() & 0xff)) % 0xfd + 2;
872 elapp
->initial_addr
.s_node
= node
;
878 StaticProc
int aarp_get_next_node(elapp
)
881 register u_char node
= elapp
->initial_addr
.s_node
;
884 * return the next node number in the range 1 thru 0xfd.
886 node
= (node
== 0xfd) ? (1) : (node
+1);
888 elapp
->initial_addr
.s_node
= node
;
896 /****************************************************************************
897 * aarp_get_rand_net()
899 ****************************************************************************/
900 StaticProc
int aarp_get_rand_net(elapp
)
901 register at_ifaddr_t
*elapp
;
903 register at_net_al last_net
, new_net
;
905 if (elapp
->ifThisCableStart
) {
906 last_net
= elapp
->initial_addr
.s_net
;
908 * the range of network numbers valid for this
909 * cable is known. Try to choose a number from
912 new_net
= ((at_net_al
)random() & 0xffff);
913 /* two-byte random number generated... now fit it in
914 * the prescribed range
916 new_net
= new_net
% (unsigned) (elapp
->ifThisCableEnd
-
917 elapp
->ifThisCableStart
+ 1)
918 + elapp
->ifThisCableStart
;
920 if (new_net
== last_net
) {
921 if (new_net
== elapp
->ifThisCableEnd
)
922 new_net
= elapp
->ifThisCableStart
;
926 elapp
->initial_addr
.s_net
= new_net
;
928 /* The range of valid network numbers for this cable
929 * is not known... choose a network number from
932 last_net
= (elapp
->initial_addr
.s_net
& 0x00ff);
933 new_net
= (at_net_al
)random() & 0x00ff;
935 if (new_net
== last_net
)
939 elapp
->initial_addr
.s_net
= (DDP_STARTUP_LOW
| new_net
);
945 int getAarpTableSize(elapId
)
946 int elapId
; /* elap_specifics array index (should be
947 * changed when we add a non-ethernet type
948 * of I/F to the mix. Unused for now.
954 int getPhysAddrSize(elapId
)
955 int elapId
; /* elap_specifics array index (should be
956 * changed when we add a non-ethernet type
957 * of I/F to the mix. Unused for now.
960 return(ETHERNET_ADDR_LEN
);
963 #define ENTRY_SIZE sizeof(struct atalk_addr) + sizeof(struct etalk_addr)
965 snmpAarpEnt_t
*getAarp(elapId
)
966 int *elapId
; /* I/F table to retrieve & table
967 size entries on return */
969 /* gets aarp table for specified interface and builds
970 a table in SNMP expected format. Returns pointer to said
971 table and sets elapId to byte size of used portion of table
976 static snmpAarpEnt_t snmp
[AMTSIZE
];
977 snmpAarpEnt_t
*snmpp
;
980 if (*elapId
<0 || *elapId
>= IF_TOTAL_MAX
)
984 for (i
=0, amtp
= &(aarp_table
[*elapId
]->et_aarp_amt
[0]), snmpp
= snmp
;
985 i
< AMTSIZE
; i
++,amtp
++) {
987 /* last_time will be 0 if entry was never used */
988 if (amtp
->last_time
) {
989 /* copy just network & mac address.
990 * For speed, we assume that the atalk_addr
991 * & etalk_addr positions in the aarp_amt_t struct
992 * has not changed and copy both at once
994 bcopy(&amtp
->dest_at_addr
, &snmpp
->ap_ddpAddr
, ENTRY_SIZE
);
1003 /*#endif *//* COMMENTED_OUT */