2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 * Copyright (c) 1996 Apple Computer, Inc.
31 * Created April 8, 1996 by Tuyen Nguyen
32 * Modified, March 17, 1997 by Tuyen Nguyen for MacOSX.
39 #include <sys/errno.h>
40 #include <sys/types.h>
41 #include <sys/param.h>
42 #include <machine/spl.h>
43 #include <sys/systm.h>
44 #include <sys/kernel.h>
46 #include <sys/filedesc.h>
47 #include <sys/fcntl.h>
49 #include <sys/socket.h>
50 #include <sys/socketvar.h>
53 #include <netat/sysglue.h>
54 #include <netat/appletalk.h>
55 #include <netat/at_var.h>
56 #include <netat/rtmp.h>
57 #include <netat/routing_tables.h>
58 #include <netat/at_pcb.h>
59 #include <netat/aurp.h>
60 #include <netat/debug.h>
63 static void AURPsndRIRsp(aurp_state_t
*);
66 void AURPsndRIAck(state
, m
, flags
)
71 unsigned short sequence_number
;
73 int msize
= sizeof(aurp_hdr_t
);
76 sequence_number
= ((aurp_hdr_t
*)gbuf_rptr(m
))->sequence_number
;
77 gbuf_wset(m
,sizeof(aurp_hdr_t
));
79 sequence_number
= state
->rcv_sequence_number
;
80 if ((m
= (gbuf_t
*)gbuf_alloc(msize
, PRI_MED
)) == 0)
85 /* construct the RI Ack packet */
86 hdrp
= (aurp_hdr_t
*)gbuf_rptr(m
);
87 hdrp
->connection_id
= state
->rcv_connection_id
;
88 hdrp
->sequence_number
= sequence_number
;
89 hdrp
->command_code
= AURPCMD_RIAck
;
93 dPrintf(D_M_AURP
, D_L_INFO
, ("AURPsndRIAck: node=%d\n",
95 AURPsend(m
, AUD_AURP
, state
->rem_node
);
98 /* locked version of AURPsndRIReq */
99 void AURPsndRIReq_locked(state
)
108 void AURPsndRIReq(state
)
116 if (state
->rcv_state
== AURPSTATE_Unconnected
) {
119 if (state
->rcv_tmo
&& (state
->rcv_state
!= AURPSTATE_WaitingForRIRsp
)) {
123 msize
= sizeof(aurp_hdr_t
);
124 if ((m
= (gbuf_t
*)gbuf_alloc(msize
, PRI_MED
)) != 0) {
127 /* construct the RI request packet */
128 hdrp
= (aurp_hdr_t
*)gbuf_rptr(m
);
129 hdrp
->connection_id
= state
->rcv_connection_id
;
130 hdrp
->sequence_number
= 0;
131 hdrp
->command_code
= AURPCMD_RIReq
;
134 /* update state info */
135 state
->rcv_state
= AURPSTATE_WaitingForRIRsp
;
137 /* send the packet */
138 dPrintf(D_M_AURP
, D_L_INFO
, ("AURPsndRIReq: node=%d\n",
140 AURPsend(m
, AUD_AURP
, state
->rem_node
);
143 /* start the retry timer */
144 timeout(AURPsndRIReq_locked
, state
, AURP_RetryInterval
*HZ
);
148 /* locked version of AURPsndRIRsp */
149 void AURPsndRIRsp_locked(state
)
158 void AURPsndRIRsp(state
)
167 /* make sure we're in a valid state to send RI response */
168 if ((state
->snd_state
== AURPSTATE_Unconnected
) ||
169 (state
->snd_state
== AURPSTATE_WaitingForRIAck2
)) {
173 /* update state info */
174 state
->snd_state
= AURPSTATE_WaitingForRIAck1
;
176 if (state
->rsp_m
== 0) {
177 msize
= sizeof(aurp_hdr_t
);
178 if ((m
= (gbuf_t
*)gbuf_alloc(msize
+AURP_MaxPktSize
, PRI_MED
)) == 0) {
179 timeout(AURPsndRIRsp_locked
, state
, AURP_RetryInterval
*HZ
);
186 /* construct the RI response packet */
187 hdrp
= (aurp_hdr_t
*)gbuf_rptr(m
);
188 hdrp
->connection_id
= state
->snd_connection_id
;
189 hdrp
->sequence_number
= state
->snd_sequence_number
;
190 hdrp
->command_code
= AURPCMD_RIRsp
;
193 /* get routing info of the local networks */
194 state
->snd_next_entry
= AURPgetri(
195 state
->snd_next_entry
, gbuf_wptr(m
), &len
);
198 /* set the last flag if this is the last response packet */
199 if (!state
->snd_next_entry
)
200 hdrp
->flags
= AURPFLG_LAST
;
203 /* keep a copy of the packet for retry */
204 m
= (gbuf_t
*)gbuf_dupb(state
->rsp_m
);
206 /* start the retry timer */
207 timeout(AURPsndRIRsp_locked
, state
, AURP_RetryInterval
*HZ
);
211 /* send the packet */
213 dPrintf(D_M_AURP
, D_L_INFO
, ("AURPsndRIRsp: len=%d\n", len
));
214 AURPsend(m
, AUD_AURP
, state
->rem_node
);
219 void AURPsndRIUpd_locked(state
)
228 void AURPsndRIUpd(state
)
237 /* make sure we're in a valid state to send update */
238 if (state
->snd_next_entry
|| (state
->upd_m
== 0) ||
239 (state
->snd_state
== AURPSTATE_Unconnected
) ||
240 (state
->snd_state
== AURPSTATE_WaitingForRIAck1
)) {
244 /* update state info */
245 state
->snd_state
= AURPSTATE_WaitingForRIAck2
;
247 if (state
->snd_tmo
== 0) {
248 msize
= sizeof(aurp_hdr_t
);
253 /* construct the RI update packet */
254 hdrp
= (aurp_hdr_t
*)gbuf_rptr(m
);
255 hdrp
->connection_id
= state
->snd_connection_id
;
256 hdrp
->sequence_number
= state
->snd_sequence_number
;
257 hdrp
->command_code
= AURPCMD_RIUpd
;
261 /* keep a copy of the packet for retry */
262 m
= (gbuf_t
*)gbuf_dupb(state
->upd_m
);
264 /* start the retry timer */
265 timeout(AURPsndRIUpd_locked
, state
, AURP_RetryInterval
*HZ
);
269 /* send the packet */
271 dPrintf(D_M_AURP
, D_L_INFO
, ("AURPsndRIUpd: len=%d\n", len
));
272 AURPsend(m
, AUD_AURP
, state
->rem_node
);
278 void AURPrcvRIReq(state
, m
)
282 aurp_hdr_t
*hdrp
= (aurp_hdr_t
*)gbuf_rptr(m
);
286 /* make sure we're in a valid state to accept it */
287 if ((state
->snd_state
== AURPSTATE_Unconnected
) ||
288 (state
->snd_state
== AURPSTATE_WaitingForRIAck2
)) {
289 dPrintf(D_M_AURP
, D_L_WARNING
, ("AURPrcvRIReq: unexpected request\n"));
294 /* check for the correct connection id */
295 if (hdrp
->connection_id
!= state
->snd_connection_id
) {
296 dPrintf(D_M_AURP
, D_L_WARNING
,
297 ("AURPrcvRIReq: invalid connection id, r=%d, m=%d\n",
298 hdrp
->connection_id
, state
->snd_connection_id
));
303 if (state
->snd_state
!= AURPSTATE_WaitingForRIAck1
) {
304 state
->snd_next_entry
= 0;
306 gbuf_freem(state
->rsp_m
);
316 void AURPrcvRIRsp(state
, m
)
320 aurp_hdr_t
*hdrp
= (aurp_hdr_t
*)gbuf_rptr(m
);
323 /* make sure we're in a valid state to accept it */
324 if (state
->rcv_state
!= AURPSTATE_WaitingForRIRsp
) {
325 dPrintf(D_M_AURP
, D_L_WARNING
, ("AURPrcvRIRsp: unexpected response\n"));
330 /* check for the correct connection id */
331 if (hdrp
->connection_id
!= state
->rcv_connection_id
) {
332 dPrintf(D_M_AURP
, D_L_WARNING
,
333 ("AURPrcvRIRsp: invalid connection id, r=%d, m=%d\n",
334 hdrp
->connection_id
, state
->rcv_connection_id
));
339 /* check for the correct sequence number */
340 if (hdrp
->sequence_number
!= state
->rcv_sequence_number
) {
341 if ( ((state
->rcv_sequence_number
== AURP_FirstSeqNum
) &&
342 (hdrp
->sequence_number
== AURP_LastSeqNum
)) ||
343 (hdrp
->sequence_number
== (state
->rcv_sequence_number
-1)) ) {
344 AURPsndRIAck(state
, m
, AURPFLG_SZI
);
346 dPrintf(D_M_AURP
, D_L_WARNING
,
347 ("AURPrcvRIRsp: invalid sequence number, r=%d, m=%d\n",
348 hdrp
->sequence_number
, state
->rcv_sequence_number
));
353 gbuf_rinc(m
,sizeof(*hdrp
));
354 if (hdrp
->flags
& AURPFLG_LAST
)
355 state
->rcv_state
= AURPSTATE_Connected
;
357 dPrintf(D_M_AURP
, D_L_INFO
, ("AURPrcvRIRsp: len=%ld\n", gbuf_len(m
)));
359 /* cancel the retry timer */
360 untimeout(AURPsndRIReq_locked
, state
);
364 AURPsndRIAck(state
, 0, AURPFLG_SZI
);
366 /* update state info */
367 if (++state
->rcv_sequence_number
== 0)
368 state
->rcv_sequence_number
= AURP_FirstSeqNum
;
370 /* process routing info of the tunnel peer */
371 if (AURPsetri(state
->rem_node
, m
)) {
372 dPrintf(D_M_AURP
, D_L_ERROR
, ("AURPrcvRIRsp: AURPsetri() error\n"));
376 /* set the get zone flag to get zone info later if required */
377 if (state
->rcv_state
== AURPSTATE_Connected
)
382 void AURPrcvRIUpd(state
, m
)
386 aurp_hdr_t
*hdrp
= (aurp_hdr_t
*)gbuf_rptr(m
);
388 /* make sure we're in a valid state to accept it */
389 if (state
->rcv_state
== AURPSTATE_Unconnected
) {
390 dPrintf(D_M_AURP
, D_L_WARNING
, ("AURPrcvRIUpd: unexpected response\n"));
395 /* check for the correct connection id */
396 if (hdrp
->connection_id
!= state
->rcv_connection_id
) {
397 dPrintf(D_M_AURP
, D_L_WARNING
,
398 ("AURPrcvRIUpd: invalid connection id, r=%d, m=%d\n",
399 hdrp
->connection_id
, state
->rcv_connection_id
));
404 /* check for the correct sequence number */
405 if (hdrp
->sequence_number
!= state
->rcv_sequence_number
) {
406 if ( ((state
->rcv_sequence_number
== AURP_FirstSeqNum
) &&
407 (hdrp
->sequence_number
== AURP_LastSeqNum
)) ||
408 (hdrp
->sequence_number
== (state
->rcv_sequence_number
-1)) ) {
409 AURPsndRIAck(state
, m
, AURPFLG_SZI
);
411 dPrintf(D_M_AURP
, D_L_WARNING
,
412 ("AURPrcvRIUpd: invalid sequence number, r=%d, m=%d\n",
413 hdrp
->sequence_number
, state
->rcv_sequence_number
));
418 gbuf_rinc(m
,sizeof(*hdrp
));
420 dPrintf(D_M_AURP
, D_L_INFO
, ("AURPrcvRIUpd: len=%ld\n", gbuf_len(m
)));
423 AURPsndRIAck(state
, 0, AURPFLG_SZI
);
425 /* update state info */
426 if (++state
->rcv_sequence_number
== 0)
427 state
->rcv_sequence_number
= AURP_FirstSeqNum
;
429 /* process update routing info of the tunnel peer */
430 if (AURPupdateri(state
->rem_node
, m
)) {
431 dPrintf(D_M_AURP
, D_L_ERROR
, ("AURPrcvRIUpd: AURPupdateri() error\n"));
434 /* set the get zone flag to get zone info later if required */
441 void AURPrcvRIAck(state
, m
)
446 aurp_hdr_t
*hdrp
= (aurp_hdr_t
*)gbuf_rptr(m
);
447 unsigned char snd_state
;
450 dPrintf(D_M_AURP
, D_L_INFO
, ("AURPrcvRIAck: state=%d\n",
453 /* make sure we're in a valid state to accept it */
454 snd_state
= state
->snd_state
;
455 if (((snd_state
== AURPSTATE_WaitingForRIAck1
) ||
456 (snd_state
== AURPSTATE_WaitingForRIAck2
)) &&
457 (hdrp
->sequence_number
== state
->snd_sequence_number
)) {
459 if (snd_state
== AURPSTATE_WaitingForRIAck1
) {
460 /* ack from the tunnel peer to our RI response */
461 untimeout(AURPsndRIRsp_locked
, state
);
462 dat_m
= state
->rsp_m
;
466 /* ack from the tunnel peer to our RI update */
467 untimeout(AURPsndRIUpd_locked
, state
);
468 dat_m
= state
->upd_m
;
473 gbuf_rinc(dat_m
,sizeof(aurp_hdr_t
));
475 /* increment the sequence number */
476 if (++state
->snd_sequence_number
== 0)
477 state
->snd_sequence_number
= AURP_FirstSeqNum
;
479 /* update state info */
480 state
->snd_state
= AURPSTATE_Connected
;
482 if (state
->snd_next_entry
) /* more RI responses to send? */
485 /* check to see if we need to send ZI responses */
486 if (hdrp
->flags
& AURPFLG_SZI
)
487 AURPsndZRsp(state
, dat_m
, flag
);
496 int AURPgetri(next_entry
, buf
, len
)
501 short entry_num
= next_entry
;
502 RT_entry
*entry
= (RT_entry
*)&RT_table
[next_entry
];
504 for (*len
=0; entry_num
< RT_maxentry
; entry_num
++,entry
++) {
505 if ((net_port
!= entry
->NetPort
) &&
506 !(entry
->AURPFlag
& AURP_NetHiden
)) {
507 if ((entry
->EntryState
& 0x0F) >= RTE_STATE_SUSPECT
) {
508 if (entry
->NetStart
) {
509 /* route info for extended network */
510 *(short *)buf
= entry
->NetStart
;
511 buf
+= sizeof(short);
512 *buf
++ = 0x80 | (entry
->NetDist
& 0x1F);
513 *(short *)buf
= entry
->NetStop
;
514 buf
+= sizeof(short);
518 /* route info for non-extended network */
519 *(short *)buf
= entry
->NetStop
;
520 buf
+= sizeof(short);
521 *buf
++ = (entry
->NetDist
& 0x1F);
526 if (*len
> AURP_MaxPktSize
)
530 return (entry_num
== RT_maxentry
) ? 0 : entry_num
;
534 int AURPsetri(node
, m
)
539 unsigned char *tuples_ptr
;
540 RT_entry new_rt
, *curr_rt
;
542 new_rt
.NextIRNet
= 0;
543 new_rt
.NextIRNode
= node
;
544 new_rt
.NetPort
= net_port
;
547 * Process all the tuples against our routing table
549 tuples_ptr
= (char *)gbuf_rptr(m
);
550 tuples_cnt
= (gbuf_len(m
))/3;
552 while (tuples_cnt
--) {
553 new_rt
.NetDist
= TUPLEDIST(tuples_ptr
) + 1;
554 new_rt
.EntryState
= RTE_STATE_GOOD
;
555 new_rt
.NetStart
= TUPLENET(tuples_ptr
);
557 if (tuples_ptr
[-1] & 0x80) {
558 new_rt
.NetStop
= TUPLENET((tuples_ptr
));
562 new_rt
.NetStop
= new_rt
.NetStart
;
565 if ((new_rt
.NetStop
== 0) || (new_rt
.NetStop
< new_rt
.NetStart
)) {
566 dPrintf(D_M_AURP
, D_L_WARNING
,
567 ("AURPsetri: %d, invalid tuple received [%d-%d]\n",
568 net_port
, new_rt
.NetStart
, new_rt
.NetStop
));
572 if ((curr_rt
= rt_blookup(new_rt
.NetStop
)) != 0) { /* found? */
573 /* ignore loop if present */
574 if (curr_rt
->NetPort
!= net_port
)
577 if (new_rt
.NetDist
< 16) {
579 * check if the definition of the route has changed
581 if ((new_rt
.NetStop
!= curr_rt
->NetStop
) ||
582 (new_rt
.NetStart
!= curr_rt
->NetStart
)) {
583 if ((new_rt
.NetStop
== curr_rt
->NetStop
) &&
584 (new_rt
.NetStop
== curr_rt
->NetStart
) &&
585 (new_rt
.NetStart
== 0)) {
586 new_rt
.NetStart
= new_rt
.NetStop
;
587 } else if ((new_rt
.NetStop
== curr_rt
->NetStop
) &&
588 (new_rt
.NetStart
== new_rt
.NetStop
) &&
589 (curr_rt
->NetStart
== 0)) {
590 dPrintf(D_M_AURP
, D_L_WARNING
,
591 ("AURPsetri: [%d-%d] has changed to [%d-%d], Dist=%d\n",
592 curr_rt
->NetStart
, curr_rt
->NetStop
,
593 new_rt
.NetStart
, new_rt
.NetStop
, new_rt
.NetDist
));
596 dPrintf(D_M_AURP
, D_L_WARNING
,
597 ("AURPsetri: Net Conflict, Curr=[%d-%d], New=[%d-%d]\n",
598 curr_rt
->NetStart
,curr_rt
->NetStop
,
599 new_rt
.NetStart
,new_rt
.NetStop
));
600 zt_remove_zones(curr_rt
->ZoneBitMap
);
601 rt_delete(curr_rt
->NetStop
, curr_rt
->NetStart
);
607 if ((new_rt
.NetDist
<= curr_rt
->NetDist
) &&
608 (new_rt
.NetDist
< 16)) {
610 * found a shorter or more recent route,
611 * replace with the new entry
613 curr_rt
->NetDist
= new_rt
.NetDist
;
614 curr_rt
->NextIRNode
= new_rt
.NextIRNode
;
615 dPrintf(D_M_AURP_LOW
,D_L_INFO
,
616 ("AURPsetri: shorter route found [%d-%d], update\n",
617 new_rt
.NetStart
,new_rt
.NetStop
));
620 } else { /* no entry found */
621 if (new_rt
.NetDist
< 16) {
622 new_rt
.EntryState
= RTE_STATE_GOOD
;
623 dPrintf(D_M_AURP
, D_L_INFO
,
624 ("AURPsetri: new_rt [%d-%d], tuple #%d\n",
625 new_rt
.NetStart
, new_rt
.NetStop
, tuples_cnt
));
626 if (rt_insert(new_rt
.NetStop
, new_rt
.NetStart
,
627 new_rt
.NextIRNet
, new_rt
.NextIRNode
,
628 new_rt
.NetDist
, new_rt
.NetPort
,
629 new_rt
.EntryState
) == (RT_entry
*)0) {
630 dPrintf(D_M_AURP
,D_L_ERROR
,
631 ("AURPsetri: RTMP table full [%d-%d]\n",
632 new_rt
.NetStart
,new_rt
.NetStop
));
637 } /* end of main while */
643 int AURPupdateri(node
, m
)
648 RT_entry new_rt
, *old_rt
;
650 while (gbuf_len(m
) > 0) {
651 ev
= *gbuf_rptr(m
); /* event code */
653 if (gbuf_rptr(m
)[2] & 0x80) {
654 /* event tuple for extended network */
655 new_rt
.NetStart
= *(unsigned short *)gbuf_rptr(m
);
656 new_rt
.NetStop
= *(unsigned short *)&gbuf_rptr(m
)[3];
657 new_rt
.NetDist
= gbuf_rptr(m
)[2] & 0x7f;
660 /* event tuple for non-extended network */
662 new_rt
.NetStop
= *(unsigned short *)gbuf_rptr(m
);
663 new_rt
.NetDist
= gbuf_rptr(m
)[2];
671 case AURPEV_NetAdded
:
673 new_rt
.NextIRNet
= 0;
674 new_rt
.NextIRNode
= node
;
675 new_rt
.NetPort
= net_port
;
676 if ((new_rt
.NetDist
== 0) || (new_rt
.NetStop
== 0) ||
677 (new_rt
.NetStop
< new_rt
.NetStart
)) {
678 dPrintf(D_M_AURP
,D_L_WARNING
,
679 ("AURPupdateri: %d, invalid NetAdded received [%d-%d]\n",
680 net_port
, new_rt
.NetStart
, new_rt
.NetStop
));
684 if ((old_rt
= rt_blookup(new_rt
.NetStop
)) != 0) { /* found? */
685 if (old_rt
->NetPort
== net_port
) {
687 * process this event as if it was an NDC event;
688 * update the route's distance
690 old_rt
->NetDist
= new_rt
.NetDist
;
693 l_add
: if ((new_rt
.NetDist
< 16) && (new_rt
.NetDist
!= NOTIFY_N_DIST
)) {
694 new_rt
.EntryState
= RTE_STATE_GOOD
;
695 dPrintf(D_M_AURP
, D_L_INFO
,
696 ("AURPupdateri: NetAdded [%d-%d]\n",
697 new_rt
.NetStart
, new_rt
.NetStop
));
698 if (rt_insert(new_rt
.NetStop
, new_rt
.NetStart
,
699 new_rt
.NextIRNet
, new_rt
.NextIRNode
,
700 new_rt
.NetDist
, new_rt
.NetPort
,
701 new_rt
.EntryState
) == (RT_entry
*)0) {
702 dPrintf(D_M_AURP
, D_L_WARNING
,
703 ("AURPupdateri: RTMP table full [%d-%d]\n",
704 new_rt
.NetStart
,new_rt
.NetStop
));
711 case AURPEV_NetDeleted
:
712 case AURPEV_NetRouteChange
:
714 l_delete
: if ((old_rt
= rt_blookup(new_rt
.NetStop
)) != 0) { /* found? */
715 if (old_rt
->NetPort
== net_port
) {
716 zt_remove_zones(old_rt
->ZoneBitMap
);
717 rt_delete(old_rt
->NetStop
, old_rt
->NetStart
);
722 case AURPEV_NetDistChange
:
724 if (new_rt
.NetDist
== 15)
725 goto l_delete
; /* process this event as if was an ND event */
726 if ((old_rt
= rt_blookup(new_rt
.NetStop
)) != 0) { /* found? */
727 if (old_rt
->NetPort
== net_port
) {
729 * update the route's distance
731 old_rt
->NetDist
= new_rt
.NetDist
;
734 goto l_add
; /* process this event as if was an NA event */
737 case AURPEV_NetZoneChange
:
746 void AURPpurgeri(node
)
750 RT_entry
*entry
= (RT_entry
*)RT_table
;
753 * purge all routes associated with the tunnel peer
755 for (entry_num
=0; entry_num
< RT_maxentry
; entry_num
++,entry
++) {
756 if ((net_port
== entry
->NetPort
) && (node
== entry
->NextIRNode
)) {
757 zt_remove_zones(entry
->ZoneBitMap
);
758 rt_delete(entry
->NetStop
, entry
->NetStart
);
764 void AURPrtupdate(entry
, ev
)
768 unsigned char i
, node
, ev_len
, ev_tuple
[6];
770 aurp_state_t
*state
= (aurp_state_t
*)&aurp_state
[1];
771 int s
, msize
= sizeof(aurp_hdr_t
);
773 dPrintf(D_M_AURP
, D_L_TRACE
, ("AURPrtupdate: event=%d, net=[%d-%d]\n",
774 ev
, entry
->NetStart
, entry
->NetStop
));
777 * check that the network can be exported; if not,
778 * we must not make it visible beyond the local networks
781 for (i
=0; i
< net_access_cnt
; i
++) {
782 if ((net_access
[i
] == entry
->NetStart
) ||
783 (net_access
[i
] == entry
->NetStop
))
786 if (i
== net_access_cnt
)
789 for (i
=0; i
< net_access_cnt
; i
++) {
790 if ((net_access
[i
] == entry
->NetStart
) ||
791 (net_access
[i
] == entry
->NetStop
))
797 * create the update event tuple
799 ev_tuple
[0] = ev
; /* event code */
800 if (entry
->NetStart
) {
801 *(unsigned short *)&ev_tuple
[1] = entry
->NetStart
;
802 ev_tuple
[3] = 0x80 | (entry
->NetDist
& 0x1F);
803 *(unsigned short *)&ev_tuple
[4] = entry
->NetStop
;
806 *(unsigned short *)&ev_tuple
[1] = entry
->NetStop
;
807 ev_tuple
[3] = (entry
->NetDist
& 0x1F);
811 for (node
=1; node
<= dst_addr_cnt
; node
++, state
++) {
812 if ((ev
== AURPEV_NetAdded
) &&
813 (!(state
->snd_sui
& AURPFLG_NA
))) continue;
814 if ((ev
== AURPEV_NetDeleted
) &&
815 (!(state
->snd_sui
& AURPFLG_ND
))) continue;
816 if ((ev
== AURPEV_NetDistChange
) &&
817 (!(state
->snd_sui
& AURPFLG_NDC
))) continue;
818 if ((state
->snd_state
!= AURPSTATE_Unconnected
) &&
819 (state
->snd_state
!= AURPSTATE_WaitingForRIAck2
)) {
820 if ((m
= state
->upd_m
) == 0) {
822 * we don't have the RI update buffer yet, allocate one
824 if ((m
= (gbuf_t
*)gbuf_alloc(msize
+AURP_MaxPktSize
, PRI_HI
)) == 0)
832 * add the update event tuple to the RI update buffer;
833 * the RI update buffer will be sent when the periodic update
836 bcopy(ev_tuple
, gbuf_wptr(m
), ev_len
);
840 * if the RI update buffer is full, send the RI update now
842 if (gbuf_len(m
) > (AURP_MaxPktSize
-6)) {
850 #endif /* AURP_SUPPORT */