|
|
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: /* ! 26: * Copyright (c) 1996 Apple Computer, Inc. ! 27: * ! 28: * The information contained herein is subject to change without ! 29: * notice and should not be construed as a commitment by Apple ! 30: * Computer, Inc. Apple Computer, Inc. assumes no responsibility ! 31: * for any errors that may appear. ! 32: * ! 33: * Confidential and Proprietary to Apple Computer, Inc. ! 34: * ! 35: * File: ri.c ! 36: */ ! 37: #include <sysglue.h> ! 38: #include <at/appletalk.h> ! 39: #include <lap.h> ! 40: #include <rtmp.h> ! 41: #include <routing_tables.h> ! 42: #define _AURP ! 43: #include <at_aurp.h> ! 44: #include <at/aurp.h> ! 45: ! 46: /* */ ! 47: void AURPsndRIAck(state, m, flags) ! 48: aurp_state_t *state; ! 49: gbuf_t *m; ! 50: unsigned short flags; ! 51: { ! 52: unsigned short sequence_number; ! 53: aurp_hdr_t *hdrp; ! 54: int msize = sizeof(aurp_hdr_t); ! 55: ! 56: if (m) { ! 57: sequence_number = ((aurp_hdr_t *)gbuf_rptr(m))->sequence_number; ! 58: gbuf_wset(m,sizeof(aurp_hdr_t)); ! 59: } else { ! 60: sequence_number = state->rcv_sequence_number; ! 61: if ((m = (gbuf_t *)gbuf_alloc(msize, PRI_MED)) == 0) ! 62: return; ! 63: gbuf_wset(m,msize); ! 64: } ! 65: ! 66: /* construct the RI Ack packet */ ! 67: hdrp = (aurp_hdr_t *)gbuf_rptr(m); ! 68: hdrp->connection_id = state->rcv_connection_id; ! 69: hdrp->sequence_number = sequence_number; ! 70: hdrp->command_code = AURPCMD_RIAck; ! 71: hdrp->flags = flags; ! 72: ! 73: /* send the packet */ ! 74: dPrintf(D_M_AURP, D_L_INFO, ("AURPsndRIAck: node=%d\n", ! 75: state->rem_node)); ! 76: AURPsend(m, AUD_AURP, state->rem_node); ! 77: } ! 78: ! 79: /* */ ! 80: void AURPsndRIReq(state) ! 81: aurp_state_t *state; ! 82: { ! 83: int msize; ! 84: gbuf_t *m; ! 85: aurp_hdr_t *hdrp; ! 86: ! 87: if (state->rcv_state == AURPSTATE_Unconnected) ! 88: return; ! 89: if (state->rcv_tmo && (state->rcv_state != AURPSTATE_WaitingForRIRsp)) ! 90: return; ! 91: ! 92: msize = sizeof(aurp_hdr_t); ! 93: if ((m = (gbuf_t *)gbuf_alloc(msize, PRI_MED)) != 0) { ! 94: gbuf_wset(m,msize); ! 95: ! 96: /* construct the RI request packet */ ! 97: hdrp = (aurp_hdr_t *)gbuf_rptr(m); ! 98: hdrp->connection_id = state->rcv_connection_id; ! 99: hdrp->sequence_number = 0; ! 100: hdrp->command_code = AURPCMD_RIReq; ! 101: hdrp->flags = 0; ! 102: ! 103: /* update state info */ ! 104: state->rcv_state = AURPSTATE_WaitingForRIRsp; ! 105: ! 106: /* send the packet */ ! 107: dPrintf(D_M_AURP, D_L_INFO, ("AURPsndRIReq: node=%d\n", ! 108: state->rem_node)); ! 109: AURPsend(m, AUD_AURP, state->rem_node); ! 110: } ! 111: ! 112: /* start the retry timer */ ! 113: state->rcv_tmo = (void *)atalk_timeout( ! 114: AURPsndRIReq, state, AURP_RetryInterval*HZ); ! 115: } ! 116: ! 117: /* */ ! 118: void AURPsndRIRsp(state) ! 119: aurp_state_t *state; ! 120: { ! 121: gbuf_t *m; ! 122: aurp_hdr_t *hdrp; ! 123: short len = 0; ! 124: int s, msize = 0; ! 125: ! 126: ATDISABLE(s, aurpgen_lock); ! 127: ! 128: /* make sure we're in a valid state to send RI response */ ! 129: if ((state->snd_state == AURPSTATE_Unconnected) || ! 130: (state->snd_state == AURPSTATE_WaitingForRIAck2)) { ! 131: ATENABLE(s, aurpgen_lock); ! 132: return; ! 133: } ! 134: ! 135: /* update state info */ ! 136: state->snd_state = AURPSTATE_WaitingForRIAck1; ! 137: ! 138: if (state->rsp_m == 0) { ! 139: ATENABLE(s, aurpgen_lock); ! 140: msize = sizeof(aurp_hdr_t); ! 141: if ((m = (gbuf_t *)gbuf_alloc(msize+AURP_MaxPktSize, PRI_MED)) == 0) { ! 142: state->snd_tmo = (void *) ! 143: atalk_timeout(AURPsndRIRsp, state, AURP_RetryInterval*HZ); ! 144: return; ! 145: } ! 146: gbuf_wset(m,msize); ! 147: state->rsp_m = m; ! 148: ! 149: /* construct the RI response packet */ ! 150: hdrp = (aurp_hdr_t *)gbuf_rptr(m); ! 151: hdrp->connection_id = state->snd_connection_id; ! 152: hdrp->sequence_number = state->snd_sequence_number; ! 153: hdrp->command_code = AURPCMD_RIRsp; ! 154: hdrp->flags = 0; ! 155: ! 156: /* get routing info of the local networks */ ! 157: state->snd_next_entry = AURPgetri( ! 158: state->snd_next_entry, gbuf_wptr(m), &len); ! 159: gbuf_winc(m,len); ! 160: ! 161: /* set the last flag if this is the last response packet */ ! 162: if (!state->snd_next_entry) ! 163: hdrp->flags = AURPFLG_LAST; ! 164: } ! 165: ! 166: /* keep a copy of the packet for retry */ ! 167: m = (gbuf_t *)gbuf_dupb(state->rsp_m); ! 168: ! 169: /* start the retry timer */ ! 170: state->snd_tmo = (void *) ! 171: atalk_timeout(AURPsndRIRsp, state, AURP_RetryInterval*HZ); ! 172: ! 173: if (msize == 0) ! 174: ATENABLE(s, aurpgen_lock); ! 175: ! 176: /* send the packet */ ! 177: if (m) { ! 178: dPrintf(D_M_AURP, D_L_INFO, ("AURPsndRIRsp: len=%d\n", len)); ! 179: AURPsend(m, AUD_AURP, state->rem_node); ! 180: } ! 181: } ! 182: ! 183: /* */ ! 184: void AURPsndRIUpd(state) ! 185: aurp_state_t *state; ! 186: { ! 187: gbuf_t *m; ! 188: aurp_hdr_t *hdrp; ! 189: short len = 0; ! 190: int s, msize = 0; ! 191: ! 192: ATDISABLE(s, aurpgen_lock); ! 193: ! 194: /* make sure we're in a valid state to send update */ ! 195: if (state->snd_next_entry || (state->upd_m == 0) || ! 196: (state->snd_state == AURPSTATE_Unconnected) || ! 197: (state->snd_state == AURPSTATE_WaitingForRIAck1)) { ! 198: ATENABLE(s, aurpgen_lock); ! 199: return; ! 200: } ! 201: ! 202: /* update state info */ ! 203: state->snd_state = AURPSTATE_WaitingForRIAck2; ! 204: ! 205: if (state->snd_tmo == 0) { ! 206: ATENABLE(s, aurpgen_lock); ! 207: msize = sizeof(aurp_hdr_t); ! 208: m = state->upd_m; ! 209: len = gbuf_len(m); ! 210: gbuf_rdec(m,msize); ! 211: ! 212: /* construct the RI update packet */ ! 213: hdrp = (aurp_hdr_t *)gbuf_rptr(m); ! 214: hdrp->connection_id = state->snd_connection_id; ! 215: hdrp->sequence_number = state->snd_sequence_number; ! 216: hdrp->command_code = AURPCMD_RIUpd; ! 217: hdrp->flags = 0; ! 218: } ! 219: ! 220: /* keep a copy of the packet for retry */ ! 221: m = (gbuf_t *)gbuf_dupb(state->upd_m); ! 222: ! 223: /* start the retry timer */ ! 224: state->snd_tmo = (void *) ! 225: atalk_timeout(AURPsndRIUpd, state, AURP_RetryInterval*HZ); ! 226: ! 227: if (msize == 0) ! 228: ATENABLE(s, aurpgen_lock); ! 229: ! 230: /* send the packet */ ! 231: if (m) { ! 232: dPrintf(D_M_AURP, D_L_INFO, ("AURPsndRIUpd: len=%d\n", len)); ! 233: AURPsend(m, AUD_AURP, state->rem_node); ! 234: } ! 235: } ! 236: ! 237: /* */ ! 238: void AURPrcvRIReq(state, m) ! 239: aurp_state_t *state; ! 240: gbuf_t *m; ! 241: { ! 242: aurp_hdr_t *hdrp = (aurp_hdr_t *)gbuf_rptr(m); ! 243: int s; ! 244: ! 245: ATDISABLE(s, aurpgen_lock); ! 246: ! 247: /* make sure we're in a valid state to accept it */ ! 248: if ((state->snd_state == AURPSTATE_Unconnected) || ! 249: (state->snd_state == AURPSTATE_WaitingForRIAck2)) { ! 250: ATENABLE(s, aurpgen_lock); ! 251: dPrintf(D_M_AURP, D_L_WARNING, ("AURPrcvRIReq: unexpected request\n")); ! 252: gbuf_freem(m); ! 253: return; ! 254: } ! 255: ! 256: /* check for the correct connection id */ ! 257: if (hdrp->connection_id != state->snd_connection_id) { ! 258: ATENABLE(s, aurpgen_lock); ! 259: dPrintf(D_M_AURP, D_L_WARNING, ! 260: ("AURPrcvRIReq: invalid connection id, r=%d, m=%d\n", ! 261: hdrp->connection_id, state->snd_connection_id)); ! 262: gbuf_freem(m); ! 263: return; ! 264: } ! 265: ! 266: if (state->snd_state != AURPSTATE_WaitingForRIAck1) { ! 267: state->snd_next_entry = 0; ! 268: if (state->rsp_m) { ! 269: gbuf_freem(state->rsp_m); ! 270: state->rsp_m = 0; ! 271: } ! 272: ATENABLE(s, aurpgen_lock); ! 273: AURPsndRIRsp(state); ! 274: } else ! 275: ATENABLE(s, aurpgen_lock); ! 276: ! 277: gbuf_freem(m); ! 278: } ! 279: ! 280: /* */ ! 281: void AURPrcvRIRsp(state, m) ! 282: aurp_state_t *state; ! 283: gbuf_t *m; ! 284: { ! 285: aurp_hdr_t *hdrp = (aurp_hdr_t *)gbuf_rptr(m); ! 286: int s; ! 287: ! 288: ATDISABLE(s, aurpgen_lock); ! 289: ! 290: /* make sure we're in a valid state to accept it */ ! 291: if (state->rcv_state != AURPSTATE_WaitingForRIRsp) { ! 292: ATENABLE(s, aurpgen_lock); ! 293: dPrintf(D_M_AURP, D_L_WARNING, ("AURPrcvRIRsp: unexpected response\n")); ! 294: gbuf_freem(m); ! 295: return; ! 296: } ! 297: ! 298: /* check for the correct connection id */ ! 299: if (hdrp->connection_id != state->rcv_connection_id) { ! 300: ATENABLE(s, aurpgen_lock); ! 301: dPrintf(D_M_AURP, D_L_WARNING, ! 302: ("AURPrcvRIRsp: invalid connection id, r=%d, m=%d\n", ! 303: hdrp->connection_id, state->rcv_connection_id)); ! 304: gbuf_freem(m); ! 305: return; ! 306: } ! 307: ! 308: /* check for the correct sequence number */ ! 309: if (hdrp->sequence_number != state->rcv_sequence_number) { ! 310: ATENABLE(s, aurpgen_lock); ! 311: if ( ((state->rcv_sequence_number == AURP_FirstSeqNum) && ! 312: (hdrp->sequence_number == AURP_LastSeqNum)) || ! 313: (hdrp->sequence_number == (state->rcv_sequence_number-1)) ) { ! 314: AURPsndRIAck(state, m, AURPFLG_SZI); ! 315: } else { ! 316: dPrintf(D_M_AURP, D_L_WARNING, ! 317: ("AURPrcvRIRsp: invalid sequence number, r=%d, m=%d\n", ! 318: hdrp->sequence_number, state->rcv_sequence_number)); ! 319: gbuf_freem(m); ! 320: } ! 321: return; ! 322: } ! 323: gbuf_rinc(m,sizeof(*hdrp)); ! 324: if (hdrp->flags & AURPFLG_LAST) ! 325: state->rcv_state = AURPSTATE_Connected; ! 326: ATENABLE(s, aurpgen_lock); ! 327: ! 328: dPrintf(D_M_AURP, D_L_INFO, ("AURPrcvRIRsp: len=%d\n", gbuf_len(m))); ! 329: ! 330: /* cancel the retry timer */ ! 331: atalk_untimeout(AURPsndRIReq, state, state->rcv_tmo); ! 332: state->rcv_tmo = 0; ! 333: ! 334: /* send RI ack */ ! 335: AURPsndRIAck(state, 0, AURPFLG_SZI); ! 336: ! 337: /* update state info */ ! 338: if (++state->rcv_sequence_number == 0) ! 339: state->rcv_sequence_number = AURP_FirstSeqNum; ! 340: ! 341: /* process routing info of the tunnel peer */ ! 342: if (AURPsetri(state->rem_node, m)) { ! 343: dPrintf(D_M_AURP, D_L_ERROR, ("AURPrcvRIRsp: AURPsetri() error\n")); ! 344: } ! 345: gbuf_freem(m); ! 346: ! 347: /* set the get zone flag to get zone info later if required */ ! 348: if (state->rcv_state == AURPSTATE_Connected) ! 349: state->get_zi = 1; ! 350: } ! 351: ! 352: /* */ ! 353: void AURPrcvRIUpd(state, m) ! 354: aurp_state_t *state; ! 355: gbuf_t *m; ! 356: { ! 357: aurp_hdr_t *hdrp = (aurp_hdr_t *)gbuf_rptr(m); ! 358: ! 359: /* make sure we're in a valid state to accept it */ ! 360: if (state->rcv_state == AURPSTATE_Unconnected) { ! 361: dPrintf(D_M_AURP, D_L_WARNING, ("AURPrcvRIUpd: unexpected response\n")); ! 362: gbuf_freem(m); ! 363: return; ! 364: } ! 365: ! 366: /* check for the correct connection id */ ! 367: if (hdrp->connection_id != state->rcv_connection_id) { ! 368: dPrintf(D_M_AURP, D_L_WARNING, ! 369: "AURPrcvRIUpd: invalid connection id, r=%d, m=%d\n", ! 370: hdrp->connection_id, state->rcv_connection_id)); ! 371: gbuf_freem(m); ! 372: return; ! 373: } ! 374: ! 375: /* check for the correct sequence number */ ! 376: if (hdrp->sequence_number != state->rcv_sequence_number) { ! 377: if ( ((state->rcv_sequence_number == AURP_FirstSeqNum) && ! 378: (hdrp->sequence_number == AURP_LastSeqNum)) || ! 379: (hdrp->sequence_number == (state->rcv_sequence_number-1)) ) { ! 380: AURPsndRIAck(state, m, AURPFLG_SZI); ! 381: } else { ! 382: dPrintf(D_M_AURP, D_L_WARNING, ! 383: ("AURPrcvRIUpd: invalid sequence number, r=%d, m=%d\n", ! 384: hdrp->sequence_number, state->rcv_sequence_number)); ! 385: gbuf_freem(m); ! 386: } ! 387: return; ! 388: } ! 389: gbuf_rinc(m,sizeof(*hdrp)); ! 390: ! 391: dPrintf(D_M_AURP, D_L_INFO, ("AURPrcvRIUpd: len=%d\n", gbuf_len(m))); ! 392: ! 393: /* send RI ack */ ! 394: AURPsndRIAck(state, 0, AURPFLG_SZI); ! 395: ! 396: /* update state info */ ! 397: if (++state->rcv_sequence_number == 0) ! 398: state->rcv_sequence_number = AURP_FirstSeqNum; ! 399: ! 400: /* process update routing info of the tunnel peer */ ! 401: if (AURPupdateri(state->rem_node, m)) { ! 402: dPrintf(D_M_AURP, D_L_ERROR, ("AURPrcvRIUpd: AURPupdateri() error\n")); ! 403: } ! 404: ! 405: /* set the get zone flag to get zone info later if required */ ! 406: state->get_zi = 1; ! 407: ! 408: gbuf_freem(m); ! 409: } ! 410: ! 411: /* */ ! 412: void AURPrcvRIAck(state, m) ! 413: aurp_state_t *state; ! 414: gbuf_t *m; ! 415: { ! 416: gbuf_t *dat_m; ! 417: aurp_hdr_t *hdrp = (aurp_hdr_t *)gbuf_rptr(m); ! 418: unsigned char snd_state; ! 419: int s; ! 420: int flag; ! 421: ! 422: dPrintf(D_M_AURP, D_L_INFO, ("AURPrcvRIAck: state=%d\n", ! 423: state->snd_state)); ! 424: ATDISABLE(s, aurpgen_lock); ! 425: ! 426: /* make sure we're in a valid state to accept it */ ! 427: snd_state = state->snd_state; ! 428: if (((snd_state == AURPSTATE_WaitingForRIAck1) || ! 429: (snd_state == AURPSTATE_WaitingForRIAck2)) && ! 430: (hdrp->sequence_number == state->snd_sequence_number)) { ! 431: ! 432: if (snd_state == AURPSTATE_WaitingForRIAck1) { ! 433: /* ack from the tunnel peer to our RI response */ ! 434: atalk_untimeout(AURPsndRIRsp, state, state->snd_tmo); ! 435: dat_m = state->rsp_m; ! 436: state->rsp_m = 0; ! 437: flag = 1; ! 438: } else { ! 439: /* ack from the tunnel peer to our RI update */ ! 440: atalk_untimeout(AURPsndRIUpd, state, state->snd_tmo); ! 441: dat_m = state->upd_m; ! 442: state->upd_m = 0; ! 443: flag = 2; ! 444: } ! 445: state->snd_tmo = 0; ! 446: gbuf_rinc(dat_m,sizeof(aurp_hdr_t)); ! 447: ! 448: /* increment the sequence number */ ! 449: if (++state->snd_sequence_number == 0) ! 450: state->snd_sequence_number = AURP_FirstSeqNum; ! 451: ! 452: /* update state info */ ! 453: state->snd_state = AURPSTATE_Connected; ! 454: ATENABLE(s, aurpgen_lock); ! 455: ! 456: if (state->snd_next_entry) /* more RI responses to send? */ ! 457: AURPsndRIRsp(state); ! 458: ! 459: /* check to see if we need to send ZI responses */ ! 460: if (hdrp->flags & AURPFLG_SZI) ! 461: AURPsndZRsp(state, dat_m, flag); ! 462: else if (dat_m) ! 463: gbuf_freem(dat_m); ! 464: } else ! 465: ATENABLE(s, aurpgen_lock); ! 466: ! 467: gbuf_freem(m); ! 468: } ! 469: ! 470: /* */ ! 471: int AURPgetri(next_entry, buf, len) ! 472: short next_entry; ! 473: unsigned char *buf; ! 474: short *len; ! 475: { ! 476: short entry_num = next_entry; ! 477: RT_entry *entry = (RT_entry *)&RT_table[next_entry]; ! 478: ! 479: for (*len=0; entry_num < RT_maxentry; entry_num++,entry++) { ! 480: if ((net_port != entry->NetPort) && ! 481: !(entry->AURPFlag & AURP_NetHiden)) { ! 482: if ((entry->EntryState & 0x0F) >= RTE_STATE_SUSPECT) { ! 483: if (entry->NetStart) { ! 484: /* route info for extended network */ ! 485: *(short *)buf = entry->NetStart; ! 486: buf += sizeof(short); ! 487: *buf++ = 0x80 | (entry->NetDist & 0x1F); ! 488: *(short *)buf = entry->NetStop; ! 489: buf += sizeof(short); ! 490: *buf++ = 0; ! 491: *len += 6; ! 492: } else { ! 493: /* route info for non-extended network */ ! 494: *(short *)buf = entry->NetStop; ! 495: buf += sizeof(short); ! 496: *buf++ = (entry->NetDist & 0x1F); ! 497: *len += 3; ! 498: } ! 499: } ! 500: } ! 501: if (*len > AURP_MaxPktSize) ! 502: break; ! 503: } ! 504: ! 505: return (entry_num == RT_maxentry) ? 0 : entry_num; ! 506: } ! 507: ! 508: /* */ ! 509: int AURPsetri(node, m) ! 510: unsigned char node; ! 511: gbuf_t *m; ! 512: { ! 513: int tuples_cnt; ! 514: unsigned char *tuples_ptr; ! 515: RT_entry *entry = (RT_entry *)RT_table; ! 516: RT_entry new_rt, *curr_rt; ! 517: ! 518: new_rt.NextIRNet = 0; ! 519: new_rt.NextIRNode = node; ! 520: new_rt.NetPort = net_port; ! 521: ! 522: /* ! 523: * Process all the tuples against our routing table ! 524: */ ! 525: tuples_ptr = (char *)gbuf_rptr(m); ! 526: tuples_cnt = (gbuf_len(m))/3; ! 527: ! 528: while (tuples_cnt--) { ! 529: new_rt.NetDist = TUPLEDIST(tuples_ptr) + 1; ! 530: new_rt.EntryState = RTE_STATE_GOOD; ! 531: new_rt.NetStart = TUPLENET(tuples_ptr); ! 532: tuples_ptr += 3; ! 533: if (tuples_ptr[-1] & 0x80) { ! 534: new_rt.NetStop = TUPLENET((tuples_ptr)); ! 535: tuples_ptr += 3; ! 536: tuples_cnt--; ! 537: } else { ! 538: new_rt.NetStop = new_rt.NetStart; ! 539: new_rt.NetStart = 0; ! 540: } ! 541: if ((new_rt.NetStop == 0) || (new_rt.NetStop < new_rt.NetStart)) { ! 542: dPrintf(D_M_AURP, D_L_WARNING, ! 543: ("AURPsetri: %d, invalid tuple received [%d-%d]\n", ! 544: net_port, new_rt.NetStart, new_rt.NetStop)); ! 545: continue; ! 546: } ! 547: ! 548: if ((curr_rt = RT_lookup(new_rt.NetStop)) != 0) { /* found? */ ! 549: /* ignore loop if present */ ! 550: if (curr_rt->NetPort != net_port) ! 551: continue; ! 552: ! 553: if (new_rt.NetDist < 16) { ! 554: /* ! 555: * check if the definition of the route has changed ! 556: */ ! 557: if ((new_rt.NetStop != curr_rt->NetStop) || ! 558: (new_rt.NetStart != curr_rt->NetStart)) { ! 559: if ((new_rt.NetStop == curr_rt->NetStop) && ! 560: (new_rt.NetStop == curr_rt->NetStart) && ! 561: (new_rt.NetStart == 0)) { ! 562: new_rt.NetStart = new_rt.NetStop; ! 563: } else if ((new_rt.NetStop == curr_rt->NetStop) && ! 564: (new_rt.NetStart == new_rt.NetStop) && ! 565: (curr_rt->NetStart == 0)) { ! 566: dPrintf(D_M_AURP, D_L_WARNING, ! 567: ("AURPsetri: [%d-%d] has changed to [%d-%d], Dist=%d\n", ! 568: curr_rt->NetStart, curr_rt->NetStop, ! 569: new_rt.NetStart, new_rt.NetStop, new_rt.NetDist)); ! 570: new_rt.NetStart = 0; ! 571: } else { ! 572: dPrintf(D_M_AURP, D_L_WARNING, ! 573: ("AURPsetri: Net Conflict, Curr=[%d-%d], New=[%d-%d]\n", ! 574: curr_rt->NetStart,curr_rt->NetStop, ! 575: new_rt.NetStart,new_rt.NetStop)); ! 576: ZT_remove_zones(curr_rt->ZoneBitMap); ! 577: RT_delete(curr_rt->NetStop, curr_rt->NetStart); ! 578: continue; ! 579: } ! 580: } ! 581: } ! 582: ! 583: if ((new_rt.NetDist <= curr_rt->NetDist) && ! 584: (new_rt.NetDist < 16)) { ! 585: /* ! 586: * found a shorter or more recent route, ! 587: * replace with the new entry ! 588: */ ! 589: curr_rt->NetDist = new_rt.NetDist; ! 590: curr_rt->NextIRNode = new_rt.NextIRNode; ! 591: dPrintf(D_M_AURP_LOW,D_L_INFO, ! 592: ("AURPsetri: shorter route found [%d-%d], update\n", ! 593: new_rt.NetStart,new_rt.NetStop)); ! 594: } ! 595: ! 596: } else { /* no entry found */ ! 597: if (new_rt.NetDist < 16) { ! 598: new_rt.EntryState = RTE_STATE_GOOD; ! 599: dPrintf(D_M_AURP, D_L_INFO, ! 600: ("AURPsetri: new_rt [%d-%d], tuple #%d\n", ! 601: new_rt.NetStart, new_rt.NetStop, tuples_cnt)); ! 602: if (RT_insert(new_rt.NetStop, new_rt.NetStart, ! 603: new_rt.NextIRNet, new_rt.NextIRNode, ! 604: new_rt.NetDist, new_rt.NetPort, ! 605: new_rt.EntryState) == (RT_entry *)0) { ! 606: dPrintf(D_M_AURP,D_L_ERROR, ! 607: ("AURPsetri: RTMP table full [%d-%d]\n", ! 608: new_rt.NetStart,new_rt.NetStop)); ! 609: return -1; ! 610: } ! 611: } ! 612: } ! 613: } /* end of main while */ ! 614: ! 615: return 0; ! 616: } ! 617: ! 618: /* */ ! 619: int AURPupdateri(node, m) ! 620: unsigned char node; ! 621: gbuf_t *m; ! 622: { ! 623: char fmt, ev, ev_len; ! 624: RT_entry new_rt, *old_rt; ! 625: ! 626: while (gbuf_len(m) > 0) { ! 627: ev = *gbuf_rptr(m); /* event code */ ! 628: gbuf_rinc(m,1); ! 629: if (gbuf_rptr(m)[2] & 0x80) { ! 630: /* event tuple for extended network */ ! 631: new_rt.NetStart = *(unsigned short *)gbuf_rptr(m); ! 632: new_rt.NetStop = *(unsigned short *)&gbuf_rptr(m)[3]; ! 633: new_rt.NetDist = gbuf_rptr(m)[2] & 0x7f; ! 634: ev_len = 5; ! 635: } else { ! 636: /* event tuple for non-extended network */ ! 637: new_rt.NetStart = 0; ! 638: new_rt.NetStop = *(unsigned short *)gbuf_rptr(m); ! 639: new_rt.NetDist = gbuf_rptr(m)[2]; ! 640: ev_len = 3; ! 641: } ! 642: ! 643: switch (ev) { ! 644: case AURPEV_Null: ! 645: break; ! 646: ! 647: case AURPEV_NetAdded: ! 648: gbuf_rinc(m,ev_len); ! 649: new_rt.NextIRNet = 0; ! 650: new_rt.NextIRNode = node; ! 651: new_rt.NetPort = net_port; ! 652: if ((new_rt.NetDist == 0) || (new_rt.NetStop == 0) || ! 653: (new_rt.NetStop < new_rt.NetStart)) { ! 654: dPrintf(D_M_AURP,D_L_WARNING, ! 655: ("AURPupdateri: %d, invalid NetAdded received [%d-%d]\n", ! 656: net_port, new_rt.NetStart, new_rt.NetStop)); ! 657: break; ! 658: } ! 659: ! 660: if ((old_rt = RT_lookup(new_rt.NetStop)) != 0) { /* found? */ ! 661: if (old_rt->NetPort == net_port) { ! 662: /* ! 663: * process this event as if it was an NDC event; ! 664: * update the route's distance ! 665: */ ! 666: old_rt->NetDist = new_rt.NetDist; ! 667: } ! 668: } else { ! 669: l_add: if ((new_rt.NetDist < 16) && (new_rt.NetDist != NOTIFY_N_DIST)) { ! 670: new_rt.EntryState = RTE_STATE_GOOD; ! 671: dPrintf(D_M_AURP, D_L_INFO, ! 672: ("AURPupdateri: NetAdded [%d-%d]\n", ! 673: new_rt.NetStart, new_rt.NetStop)); ! 674: if (RT_insert(new_rt.NetStop, new_rt.NetStart, ! 675: new_rt.NextIRNet, new_rt.NextIRNode, ! 676: new_rt.NetDist, new_rt.NetPort, ! 677: new_rt.EntryState) == (RT_entry *)0) { ! 678: dPrintf(D_M_AURP, D_L_WARNING, ! 679: ("AURPupdateri: RTMP table full [%d-%d]\n", ! 680: new_rt.NetStart,new_rt.NetStop)); ! 681: return 0; ! 682: } ! 683: } ! 684: } ! 685: break; ! 686: ! 687: case AURPEV_NetDeleted: ! 688: case AURPEV_NetRouteChange: ! 689: gbuf_rinc(m,ev_len); ! 690: l_delete: if ((old_rt = RT_lookup(new_rt.NetStop)) != 0) { /* found? */ ! 691: if (old_rt->NetPort == net_port) { ! 692: ZT_remove_zones(old_rt->ZoneBitMap); ! 693: RT_delete(old_rt->NetStop, old_rt->NetStart); ! 694: } ! 695: } ! 696: break; ! 697: ! 698: case AURPEV_NetDistChange: ! 699: gbuf_rinc(m,ev_len); ! 700: if (new_rt.NetDist == 15) ! 701: goto l_delete; /* process this event as if was an ND event */ ! 702: if ((old_rt = RT_lookup(new_rt.NetStop)) != 0) { /* found? */ ! 703: if (old_rt->NetPort == net_port) { ! 704: /* ! 705: * update the route's distance ! 706: */ ! 707: old_rt->NetDist = new_rt.NetDist; ! 708: } ! 709: } else ! 710: goto l_add; /* process this event as if was an NA event */ ! 711: break; ! 712: ! 713: case AURPEV_NetZoneChange: ! 714: break; ! 715: } ! 716: } ! 717: ! 718: return 0; ! 719: } ! 720: ! 721: /* */ ! 722: void AURPpurgeri(node) ! 723: unsigned char node; ! 724: { ! 725: short entry_num; ! 726: RT_entry *entry = (RT_entry *)RT_table; ! 727: ! 728: /* ! 729: * purge all routes associated with the tunnel peer ! 730: */ ! 731: for (entry_num=0; entry_num < RT_maxentry; entry_num++,entry++) { ! 732: if ((net_port == entry->NetPort) && (node == entry->NextIRNode)) { ! 733: ZT_remove_zones(entry->ZoneBitMap); ! 734: RT_delete(entry->NetStop, entry->NetStart); ! 735: } ! 736: } ! 737: } ! 738: ! 739: /* */ ! 740: void AURPrtupdate(entry, ev) ! 741: RT_entry *entry; ! 742: unsigned char ev; ! 743: { ! 744: unsigned char i, node, ev_len, ev_tuple[6]; ! 745: gbuf_t *m; ! 746: aurp_state_t *state = (aurp_state_t *)&aurp_state[1]; ! 747: int s, msize = sizeof(aurp_hdr_t); ! 748: ! 749: dPrintf(D_M_AURP, D_L_TRACE, ("AURPrtupdate: event=%d, net=[%d-%d]\n", ! 750: ev, entry->NetStart, entry->NetStop)); ! 751: ! 752: /* ! 753: * check that the network can be exported; if not, ! 754: * we must not make it visible beyond the local networks ! 755: */ ! 756: if (net_export) { ! 757: for (i=0; i < net_access_cnt; i++) { ! 758: if ((net_access[i] == entry->NetStart) || ! 759: (net_access[i] == entry->NetStop)) ! 760: break; ! 761: } ! 762: if (i == net_access_cnt) ! 763: return; ! 764: } else { ! 765: for (i=0; i < net_access_cnt; i++) { ! 766: if ((net_access[i] == entry->NetStart) || ! 767: (net_access[i] == entry->NetStop)) ! 768: return; ! 769: } ! 770: } ! 771: ! 772: /* ! 773: * create the update event tuple ! 774: */ ! 775: ev_tuple[0] = ev; /* event code */ ! 776: if (entry->NetStart) { ! 777: *(unsigned short *)&ev_tuple[1] = entry->NetStart; ! 778: ev_tuple[3] = 0x80 | (entry->NetDist & 0x1F); ! 779: *(unsigned short *)&ev_tuple[4] = entry->NetStop; ! 780: ev_len = 6; ! 781: } else { ! 782: *(unsigned short *)&ev_tuple[1] = entry->NetStop; ! 783: ev_tuple[3] = (entry->NetDist & 0x1F); ! 784: ev_len = 4; ! 785: } ! 786: ! 787: for (node=1; node <= dst_addr_cnt; node++, state++) { ! 788: if ((ev == AURPEV_NetAdded) && ! 789: (!(state->snd_sui & AURPFLG_NA))) continue; ! 790: if ((ev == AURPEV_NetDeleted) && ! 791: (!(state->snd_sui & AURPFLG_ND))) continue; ! 792: if ((ev == AURPEV_NetDistChange) && ! 793: (!(state->snd_sui & AURPFLG_NDC))) continue; ! 794: ATDISABLE(s, aurpgen_lock); ! 795: if ((state->snd_state != AURPSTATE_Unconnected) && ! 796: (state->snd_state != AURPSTATE_WaitingForRIAck2)) { ! 797: if ((m = state->upd_m) == 0) { ! 798: /* ! 799: * we don't have the RI update buffer yet, allocate one ! 800: */ ! 801: ATENABLE(s, aurpgen_lock); ! 802: if ((m = (gbuf_t *)gbuf_alloc(msize+AURP_MaxPktSize, PRI_HI)) == 0) ! 803: continue; ! 804: ATDISABLE(s, aurpgen_lock); ! 805: state->upd_m = m; ! 806: gbuf_rinc(m,msize); ! 807: gbuf_wset(m,0); ! 808: } ! 809: ! 810: /* ! 811: * add the update event tuple to the RI update buffer; ! 812: * the RI update buffer will be sent when the periodic update ! 813: * timer expires ! 814: */ ! 815: bcopy(ev_tuple, gbuf_wptr(m), ev_len); ! 816: gbuf_winc(m,ev_len); ! 817: ! 818: /* ! 819: * if the RI update buffer is full, send the RI update now ! 820: */ ! 821: if (gbuf_len(m) > (AURP_MaxPktSize-6)) { ! 822: ATENABLE(s, aurpgen_lock); ! 823: AURPsndRIUpd(state); ! 824: continue; ! 825: } ! 826: } ! 827: ATENABLE(s, aurpgen_lock); ! 828: } ! 829: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.