]> git.saurik.com Git - apple/xnu.git/blob - bsd/netat/aurp_ri.c
xnu-1228.3.13.tar.gz
[apple/xnu.git] / bsd / netat / aurp_ri.c
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
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.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
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.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28 /*
29 * Copyright (c) 1996 Apple Computer, Inc.
30 *
31 * Created April 8, 1996 by Tuyen Nguyen
32 * Modified, March 17, 1997 by Tuyen Nguyen for MacOSX.
33 *
34 * File: ri.c
35 */
36
37 #ifdef AURP_SUPPORT
38
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>
45 #include <sys/proc.h>
46 #include <sys/filedesc.h>
47 #include <sys/fcntl.h>
48 #include <sys/mbuf.h>
49 #include <sys/socket.h>
50 #include <sys/socketvar.h>
51 #include <net/if.h>
52
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>
61
62
63 static void AURPsndRIRsp(aurp_state_t *);
64
65 /* */
66 void AURPsndRIAck(state, m, flags)
67 aurp_state_t *state;
68 gbuf_t *m;
69 unsigned short flags;
70 {
71 unsigned short sequence_number;
72 aurp_hdr_t *hdrp;
73 int msize = sizeof(aurp_hdr_t);
74
75 if (m) {
76 sequence_number = ((aurp_hdr_t *)gbuf_rptr(m))->sequence_number;
77 gbuf_wset(m,sizeof(aurp_hdr_t));
78 } else {
79 sequence_number = state->rcv_sequence_number;
80 if ((m = (gbuf_t *)gbuf_alloc(msize, PRI_MED)) == 0)
81 return;
82 gbuf_wset(m,msize);
83 }
84
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;
90 hdrp->flags = flags;
91
92 /* send the packet */
93 dPrintf(D_M_AURP, D_L_INFO, ("AURPsndRIAck: node=%d\n",
94 state->rem_node));
95 AURPsend(m, AUD_AURP, state->rem_node);
96 }
97
98 /* locked version of AURPsndRIReq */
99 void AURPsndRIReq_locked(state)
100 aurp_state_t *state;
101 {
102 atalk_lock();
103 AURPsndRIReq(state);
104 atalk_unlock();
105 }
106
107 /* */
108 void AURPsndRIReq(state)
109 aurp_state_t *state;
110 {
111 int msize;
112 gbuf_t *m;
113 aurp_hdr_t *hdrp;
114
115
116 if (state->rcv_state == AURPSTATE_Unconnected) {
117 return;
118 }
119 if (state->rcv_tmo && (state->rcv_state != AURPSTATE_WaitingForRIRsp)) {
120 return;
121 }
122
123 msize = sizeof(aurp_hdr_t);
124 if ((m = (gbuf_t *)gbuf_alloc(msize, PRI_MED)) != 0) {
125 gbuf_wset(m,msize);
126
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;
132 hdrp->flags = 0;
133
134 /* update state info */
135 state->rcv_state = AURPSTATE_WaitingForRIRsp;
136
137 /* send the packet */
138 dPrintf(D_M_AURP, D_L_INFO, ("AURPsndRIReq: node=%d\n",
139 state->rem_node));
140 AURPsend(m, AUD_AURP, state->rem_node);
141 }
142
143 /* start the retry timer */
144 timeout(AURPsndRIReq_locked, state, AURP_RetryInterval*HZ);
145 state->rcv_tmo = 1;
146 }
147
148 /* locked version of AURPsndRIRsp */
149 void AURPsndRIRsp_locked(state)
150 aurp_state_t *state;
151 {
152 atalk_lock();
153 AURPsndRIRsp(state);
154 atalk_unlock();
155 }
156
157 /* */
158 void AURPsndRIRsp(state)
159 aurp_state_t *state;
160 {
161 gbuf_t *m;
162 aurp_hdr_t *hdrp;
163 short len = 0;
164 int msize = 0;
165
166
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)) {
170 return;
171 }
172
173 /* update state info */
174 state->snd_state = AURPSTATE_WaitingForRIAck1;
175
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);
180 state->snd_tmo = 1;
181 return;
182 }
183 gbuf_wset(m,msize);
184 state->rsp_m = m;
185
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;
191 hdrp->flags = 0;
192
193 /* get routing info of the local networks */
194 state->snd_next_entry = AURPgetri(
195 state->snd_next_entry, gbuf_wptr(m), &len);
196 gbuf_winc(m,len);
197
198 /* set the last flag if this is the last response packet */
199 if (!state->snd_next_entry)
200 hdrp->flags = AURPFLG_LAST;
201 }
202
203 /* keep a copy of the packet for retry */
204 m = (gbuf_t *)gbuf_dupb(state->rsp_m);
205
206 /* start the retry timer */
207 timeout(AURPsndRIRsp_locked, state, AURP_RetryInterval*HZ);
208 state->snd_tmo = 1;
209
210
211 /* send the packet */
212 if (m) {
213 dPrintf(D_M_AURP, D_L_INFO, ("AURPsndRIRsp: len=%d\n", len));
214 AURPsend(m, AUD_AURP, state->rem_node);
215 }
216
217 }
218
219 void AURPsndRIUpd_locked(state)
220 aurp_state_t *state;
221 {
222 atalk_lock();
223 AURPsndRIUpd(state);
224 atalk_unlock();
225 }
226
227 /* */
228 void AURPsndRIUpd(state)
229 aurp_state_t *state;
230 {
231 gbuf_t *m;
232 aurp_hdr_t *hdrp;
233 short len = 0;
234 int s, msize = 0;
235
236
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)) {
241 return;
242 }
243
244 /* update state info */
245 state->snd_state = AURPSTATE_WaitingForRIAck2;
246
247 if (state->snd_tmo == 0) {
248 msize = sizeof(aurp_hdr_t);
249 m = state->upd_m;
250 len = gbuf_len(m);
251 gbuf_rdec(m,msize);
252
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;
258 hdrp->flags = 0;
259 }
260
261 /* keep a copy of the packet for retry */
262 m = (gbuf_t *)gbuf_dupb(state->upd_m);
263
264 /* start the retry timer */
265 timeout(AURPsndRIUpd_locked, state, AURP_RetryInterval*HZ);
266 state->snd_tmo = 1;
267
268
269 /* send the packet */
270 if (m) {
271 dPrintf(D_M_AURP, D_L_INFO, ("AURPsndRIUpd: len=%d\n", len));
272 AURPsend(m, AUD_AURP, state->rem_node);
273 }
274
275 }
276
277 /* */
278 void AURPrcvRIReq(state, m)
279 aurp_state_t *state;
280 gbuf_t *m;
281 {
282 aurp_hdr_t *hdrp = (aurp_hdr_t *)gbuf_rptr(m);
283 int s;
284
285
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"));
290 gbuf_freem(m);
291 return;
292 }
293
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));
299 gbuf_freem(m);
300 return;
301 }
302
303 if (state->snd_state != AURPSTATE_WaitingForRIAck1) {
304 state->snd_next_entry = 0;
305 if (state->rsp_m) {
306 gbuf_freem(state->rsp_m);
307 state->rsp_m = 0;
308 }
309 AURPsndRIRsp(state);
310 }
311
312 gbuf_freem(m);
313 }
314
315 /* */
316 void AURPrcvRIRsp(state, m)
317 aurp_state_t *state;
318 gbuf_t *m;
319 {
320 aurp_hdr_t *hdrp = (aurp_hdr_t *)gbuf_rptr(m);
321
322
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"));
326 gbuf_freem(m);
327 return;
328 }
329
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));
335 gbuf_freem(m);
336 return;
337 }
338
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);
345 } else {
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));
349 gbuf_freem(m);
350 }
351 return;
352 }
353 gbuf_rinc(m,sizeof(*hdrp));
354 if (hdrp->flags & AURPFLG_LAST)
355 state->rcv_state = AURPSTATE_Connected;
356
357 dPrintf(D_M_AURP, D_L_INFO, ("AURPrcvRIRsp: len=%ld\n", gbuf_len(m)));
358
359 /* cancel the retry timer */
360 untimeout(AURPsndRIReq_locked, state);
361 state->rcv_tmo = 0;
362
363 /* send RI ack */
364 AURPsndRIAck(state, 0, AURPFLG_SZI);
365
366 /* update state info */
367 if (++state->rcv_sequence_number == 0)
368 state->rcv_sequence_number = AURP_FirstSeqNum;
369
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"));
373 }
374 gbuf_freem(m);
375
376 /* set the get zone flag to get zone info later if required */
377 if (state->rcv_state == AURPSTATE_Connected)
378 state->get_zi = 1;
379 }
380
381 /* */
382 void AURPrcvRIUpd(state, m)
383 aurp_state_t *state;
384 gbuf_t *m;
385 {
386 aurp_hdr_t *hdrp = (aurp_hdr_t *)gbuf_rptr(m);
387
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"));
391 gbuf_freem(m);
392 return;
393 }
394
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));
400 gbuf_freem(m);
401 return;
402 }
403
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);
410 } else {
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));
414 gbuf_freem(m);
415 }
416 return;
417 }
418 gbuf_rinc(m,sizeof(*hdrp));
419
420 dPrintf(D_M_AURP, D_L_INFO, ("AURPrcvRIUpd: len=%ld\n", gbuf_len(m)));
421
422 /* send RI ack */
423 AURPsndRIAck(state, 0, AURPFLG_SZI);
424
425 /* update state info */
426 if (++state->rcv_sequence_number == 0)
427 state->rcv_sequence_number = AURP_FirstSeqNum;
428
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"));
432 }
433
434 /* set the get zone flag to get zone info later if required */
435 state->get_zi = 1;
436
437 gbuf_freem(m);
438 }
439
440 /* */
441 void AURPrcvRIAck(state, m)
442 aurp_state_t *state;
443 gbuf_t *m;
444 {
445 gbuf_t *dat_m;
446 aurp_hdr_t *hdrp = (aurp_hdr_t *)gbuf_rptr(m);
447 unsigned char snd_state;
448 int flag;
449
450 dPrintf(D_M_AURP, D_L_INFO, ("AURPrcvRIAck: state=%d\n",
451 state->snd_state));
452
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)) {
458
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;
463 state->rsp_m = 0;
464 flag = 1;
465 } else {
466 /* ack from the tunnel peer to our RI update */
467 untimeout(AURPsndRIUpd_locked, state);
468 dat_m = state->upd_m;
469 state->upd_m = 0;
470 flag = 2;
471 }
472 state->snd_tmo = 0;
473 gbuf_rinc(dat_m,sizeof(aurp_hdr_t));
474
475 /* increment the sequence number */
476 if (++state->snd_sequence_number == 0)
477 state->snd_sequence_number = AURP_FirstSeqNum;
478
479 /* update state info */
480 state->snd_state = AURPSTATE_Connected;
481
482 if (state->snd_next_entry) /* more RI responses to send? */
483 AURPsndRIRsp(state);
484
485 /* check to see if we need to send ZI responses */
486 if (hdrp->flags & AURPFLG_SZI)
487 AURPsndZRsp(state, dat_m, flag);
488 else if (dat_m)
489 gbuf_freem(dat_m);
490 }
491
492 gbuf_freem(m);
493 }
494
495 /* */
496 int AURPgetri(next_entry, buf, len)
497 short next_entry;
498 unsigned char *buf;
499 short *len;
500 {
501 short entry_num = next_entry;
502 RT_entry *entry = (RT_entry *)&RT_table[next_entry];
503
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);
515 *buf++ = 0;
516 *len += 6;
517 } else {
518 /* route info for non-extended network */
519 *(short *)buf = entry->NetStop;
520 buf += sizeof(short);
521 *buf++ = (entry->NetDist & 0x1F);
522 *len += 3;
523 }
524 }
525 }
526 if (*len > AURP_MaxPktSize)
527 break;
528 }
529
530 return (entry_num == RT_maxentry) ? 0 : entry_num;
531 }
532
533 /* */
534 int AURPsetri(node, m)
535 unsigned char node;
536 gbuf_t *m;
537 {
538 int tuples_cnt;
539 unsigned char *tuples_ptr;
540 RT_entry new_rt, *curr_rt;
541
542 new_rt.NextIRNet = 0;
543 new_rt.NextIRNode = node;
544 new_rt.NetPort = net_port;
545
546 /*
547 * Process all the tuples against our routing table
548 */
549 tuples_ptr = (char *)gbuf_rptr(m);
550 tuples_cnt = (gbuf_len(m))/3;
551
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);
556 tuples_ptr += 3;
557 if (tuples_ptr[-1] & 0x80) {
558 new_rt.NetStop = TUPLENET((tuples_ptr));
559 tuples_ptr += 3;
560 tuples_cnt--;
561 } else {
562 new_rt.NetStop = new_rt.NetStart;
563 new_rt.NetStart = 0;
564 }
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));
569 continue;
570 }
571
572 if ((curr_rt = rt_blookup(new_rt.NetStop)) != 0) { /* found? */
573 /* ignore loop if present */
574 if (curr_rt->NetPort != net_port)
575 continue;
576
577 if (new_rt.NetDist < 16) {
578 /*
579 * check if the definition of the route has changed
580 */
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));
594 new_rt.NetStart = 0;
595 } else {
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);
602 continue;
603 }
604 }
605 }
606
607 if ((new_rt.NetDist <= curr_rt->NetDist) &&
608 (new_rt.NetDist < 16)) {
609 /*
610 * found a shorter or more recent route,
611 * replace with the new entry
612 */
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));
618 }
619
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));
633 return -1;
634 }
635 }
636 }
637 } /* end of main while */
638
639 return 0;
640 }
641
642 /* */
643 int AURPupdateri(node, m)
644 unsigned char node;
645 gbuf_t *m;
646 {
647 char ev, ev_len;
648 RT_entry new_rt, *old_rt;
649
650 while (gbuf_len(m) > 0) {
651 ev = *gbuf_rptr(m); /* event code */
652 gbuf_rinc(m,1);
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;
658 ev_len = 5;
659 } else {
660 /* event tuple for non-extended network */
661 new_rt.NetStart = 0;
662 new_rt.NetStop = *(unsigned short *)gbuf_rptr(m);
663 new_rt.NetDist = gbuf_rptr(m)[2];
664 ev_len = 3;
665 }
666
667 switch (ev) {
668 case AURPEV_Null:
669 break;
670
671 case AURPEV_NetAdded:
672 gbuf_rinc(m,ev_len);
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));
681 break;
682 }
683
684 if ((old_rt = rt_blookup(new_rt.NetStop)) != 0) { /* found? */
685 if (old_rt->NetPort == net_port) {
686 /*
687 * process this event as if it was an NDC event;
688 * update the route's distance
689 */
690 old_rt->NetDist = new_rt.NetDist;
691 }
692 } else {
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));
705 return 0;
706 }
707 }
708 }
709 break;
710
711 case AURPEV_NetDeleted:
712 case AURPEV_NetRouteChange:
713 gbuf_rinc(m,ev_len);
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);
718 }
719 }
720 break;
721
722 case AURPEV_NetDistChange:
723 gbuf_rinc(m,ev_len);
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) {
728 /*
729 * update the route's distance
730 */
731 old_rt->NetDist = new_rt.NetDist;
732 }
733 } else
734 goto l_add; /* process this event as if was an NA event */
735 break;
736
737 case AURPEV_NetZoneChange:
738 break;
739 }
740 }
741
742 return 0;
743 }
744
745 /* */
746 void AURPpurgeri(node)
747 unsigned char node;
748 {
749 short entry_num;
750 RT_entry *entry = (RT_entry *)RT_table;
751
752 /*
753 * purge all routes associated with the tunnel peer
754 */
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);
759 }
760 }
761 }
762
763 /* */
764 void AURPrtupdate(entry, ev)
765 RT_entry *entry;
766 unsigned char ev;
767 {
768 unsigned char i, node, ev_len, ev_tuple[6];
769 gbuf_t *m;
770 aurp_state_t *state = (aurp_state_t *)&aurp_state[1];
771 int s, msize = sizeof(aurp_hdr_t);
772
773 dPrintf(D_M_AURP, D_L_TRACE, ("AURPrtupdate: event=%d, net=[%d-%d]\n",
774 ev, entry->NetStart, entry->NetStop));
775
776 /*
777 * check that the network can be exported; if not,
778 * we must not make it visible beyond the local networks
779 */
780 if (net_export) {
781 for (i=0; i < net_access_cnt; i++) {
782 if ((net_access[i] == entry->NetStart) ||
783 (net_access[i] == entry->NetStop))
784 break;
785 }
786 if (i == net_access_cnt)
787 return;
788 } else {
789 for (i=0; i < net_access_cnt; i++) {
790 if ((net_access[i] == entry->NetStart) ||
791 (net_access[i] == entry->NetStop))
792 return;
793 }
794 }
795
796 /*
797 * create the update event tuple
798 */
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;
804 ev_len = 6;
805 } else {
806 *(unsigned short *)&ev_tuple[1] = entry->NetStop;
807 ev_tuple[3] = (entry->NetDist & 0x1F);
808 ev_len = 4;
809 }
810
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) {
821 /*
822 * we don't have the RI update buffer yet, allocate one
823 */
824 if ((m = (gbuf_t *)gbuf_alloc(msize+AURP_MaxPktSize, PRI_HI)) == 0)
825 continue;
826 state->upd_m = m;
827 gbuf_rinc(m,msize);
828 gbuf_wset(m,0);
829 }
830
831 /*
832 * add the update event tuple to the RI update buffer;
833 * the RI update buffer will be sent when the periodic update
834 * timer expires
835 */
836 bcopy(ev_tuple, gbuf_wptr(m), ev_len);
837 gbuf_winc(m,ev_len);
838
839 /*
840 * if the RI update buffer is full, send the RI update now
841 */
842 if (gbuf_len(m) > (AURP_MaxPktSize-6)) {
843 AURPsndRIUpd(state);
844 continue;
845 }
846 }
847 }
848 }
849
850 #endif /* AURP_SUPPORT */