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 63static void AURPsndRIRsp(aurp_state_t *); 64 65/* */ 66void 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 */ 99void AURPsndRIReq_locked(state) 100 aurp_state_t *state; 101{ 102 atalk_lock(); 103 AURPsndRIReq(state); 104 atalk_unlock(); 105} 106 107/* */ 108void 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 */ 149void AURPsndRIRsp_locked(state) 150 aurp_state_t *state; 151{ 152 atalk_lock(); 153 AURPsndRIRsp(state); 154 atalk_unlock(); 155} 156 157/* */ 158void 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 219void AURPsndRIUpd_locked(state) 220 aurp_state_t *state; 221{ 222 atalk_lock(); 223 AURPsndRIUpd(state); 224 atalk_unlock(); 225} 226 227/* */ 228void 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/* */ 278void 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/* */ 316void 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/* */ 382void 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/* */ 441void 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/* */ 496int 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/* */ 534int 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/* */ 643int 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 { 693l_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); 714l_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/* */ 746void 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/* */ 764void 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 */ 851