|
|
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) 1993-1998 Apple Computer, Inc. ! 27: * All Rights Reserved. ! 28: * ! 29: * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF APPLE COMPUTER, INC. ! 30: * The copyright notice above does not evidence any actual or ! 31: * intended publication of such source code. ! 32: */ ! 33: ! 34: #include <sysglue.h> ! 35: ! 36: #include <at/appletalk.h> ! 37: #include <at/ddp.h> ! 38: #include <rtmp.h> ! 39: #include <lap.h> ! 40: ! 41: #include <at/at_lap.h> ! 42: #include <at_ddp.h> ! 43: #include <at_zip.h> ! 44: #include <routing_tables.h> ! 45: #include <atlog.h> ! 46: ! 47: extern void *atalk_timeout(); ! 48: extern void atalk_untimeout(); ! 49: extern void rtmp_router_input(); ! 50: ! 51: /****************************************************************/ ! 52: /* */ ! 53: /* */ ! 54: /* RTMP Protocol */ ! 55: /* */ ! 56: /* */ ! 57: /****************************************************************/ ! 58: ! 59: ! 60: /* rtmp.c: , 1.6; 2/26/93; Apple Computer, Inc." */ ! 61: ! 62: ! 63: #define NROUTERS2TRAK 8 ! 64: #define FIFTYSECS 10 ! 65: #define NODE(r) ((r)->ifARouter.atalk_node) ! 66: #define NET(r) ((r)->ifARouter.atalk_net) ! 67: #define INUSE(r) (NODE(r)) ! 68: ! 69: void ddp_age_router(); ! 70: ! 71: ! 72: ! 73: static struct routerinfo { ! 74: struct atalk_addr ifARouter; ! 75: at_if_t *ifID; ! 76: void *tmo; ! 77: } trackedrouters[NROUTERS2TRAK]; ! 78: ! 79: void trackrouter_rem_if(ifID) ! 80: register at_if_t *ifID; ! 81: { ! 82: register i; ! 83: register struct routerinfo *router; ! 84: ! 85: for (i = NROUTERS2TRAK; --i >= 0;) { ! 86: router = &trackedrouters[i]; ! 87: if (trackedrouters[i].ifID == ifID) { ! 88: atalk_untimeout(ddp_age_router, (caddr_t) router, router->tmo); ! 89: break; ! 90: } ! 91: } ! 92: } ! 93: ! 94: ! 95: void routershutdown() ! 96: { ! 97: register i; ! 98: ! 99: for (i = NROUTERS2TRAK; --i >= 0;) { ! 100: register struct routerinfo *router; ! 101: ! 102: router = &trackedrouters[i]; ! 103: if (INUSE(router)) { ! 104: atalk_untimeout(ddp_age_router, (caddr_t) router, router->tmo); ! 105: bzero((caddr_t) router, sizeof(struct routerinfo)); ! 106: } ! 107: } ! 108: } ! 109: ! 110: int router_added = 0; ! 111: int router_killed = 0; ! 112: ! 113: ! 114: ! 115: void trackrouter(ifID, net, node) ! 116: register at_if_t *ifID; ! 117: register unsigned short net; ! 118: register unsigned char node; ! 119: { ! 120: register struct routerinfo *unused = NULL; ! 121: register i; ! 122: ! 123: for (i = NROUTERS2TRAK; --i >= 0;) { ! 124: register struct routerinfo *router; ! 125: ! 126: router = &trackedrouters[(i + node) & (NROUTERS2TRAK-1)]; ! 127: if ((NODE(router) == node) && (NET_VALUE(NET(router)) == net)) { ! 128: atalk_untimeout(ddp_age_router, (caddr_t) router, router->tmo); ! 129: router->tmo = atalk_timeout(ddp_age_router, (caddr_t) router, 50*SYS_HZ); ! 130: unused = NULL; ! 131: break; ! 132: } ! 133: else if (!INUSE(router) && !unused) ! 134: unused = router; ! 135: } ! 136: if (unused) { ! 137: router_added++; ! 138: ! 139: unused->ifID = ifID; ! 140: NET_ASSIGN(NET(unused), net); ! 141: NODE(unused) = node; ! 142: unused->tmo = atalk_timeout(ddp_age_router, (caddr_t) unused, 50*SYS_HZ); ! 143: if (NET_EQUAL0(NET(ifID)) && NODE(ifID) == 0) { ! 144: NET_ASSIGN(NET(ifID), net); ! 145: NODE(ifID) = node; ! 146: ifID->ifRouterState = ROUTER_AROUND; ! 147: } ! 148: } ! 149: } ! 150: ! 151: ! 152: ! 153: void ddp_age_router(deadrouter) ! 154: register struct routerinfo *deadrouter; ! 155: { ! 156: register at_if_t *ourrouter = deadrouter->ifID; ! 157: ! 158: dPrintf(D_M_RTMP, D_L_INFO, ! 159: ("ddp_age_router called deadrouter=%d:%d\n", NODE(deadrouter), NET(deadrouter))); ! 160: ! 161: router_killed++; ! 162: ! 163: if (NODE(ourrouter) == NODE(deadrouter) && ! 164: NET_EQUAL(NET(ourrouter), NET(deadrouter))) { ! 165: register unsigned long atrandom = random(); ! 166: register struct routerinfo *newrouter; ! 167: register i; ! 168: ! 169: bzero((caddr_t) deadrouter, sizeof(struct routerinfo)); ! 170: for (i = NROUTERS2TRAK; --i >= 0;) { ! 171: newrouter = &trackedrouters[(i + atrandom) & (NROUTERS2TRAK-1)]; ! 172: if (INUSE(newrouter)) ! 173: break; ! 174: else ! 175: newrouter = NULL; ! 176: } ! 177: if (newrouter) { ! 178: NET_NET(NET(ourrouter), NET(newrouter)); ! 179: NODE(ourrouter) = NODE(newrouter); ! 180: } ! 181: else { ! 182: void gorouterless(); ! 183: gorouterless(ourrouter); ! 184: } ! 185: } else ! 186: bzero((caddr_t) deadrouter, sizeof(struct routerinfo)); ! 187: } ! 188: ! 189: ! 190: ! 191: /* ! 192: * This is the timeout function that is called after 50 seconds, ! 193: * if no router packets come in. That way we won't send extended ! 194: * frames to something that is not there. Untimeout is called if ! 195: * an RTMP packet comes in so this routine will not be called. ! 196: */ ! 197: ! 198: static void gorouterless(int_ifID) ! 199: { ! 200: register at_if_t *ifID = (at_if_t *)int_ifID; ! 201: ! 202: ATTRACE(AT_MID_DDP, AT_SID_TIMERS, AT_LV_WARNING, FALSE, ! 203: "ddp_age_router entry : ARouter = 0x%x, RouterState = 0x%x", ! 204: ATALK_VALUE(ifID->ifARouter), ifID->ifRouterState, 0); ! 205: ! 206: switch (ifID->ifRouterState) { ! 207: case ROUTER_AROUND : ! 208: ATALK_ASSIGN(ifID->ifARouter, 0, 0, 0); ! 209: dPrintf(D_M_RTMP,D_L_INFO, ! 210: ("rtmp.c Gorouterless!!!!!!!!\n")); ! 211: ifID->ifThisCableStart = 2; ! 212: ifID->ifThisCableEnd = 0xfffd; ! 213: ifID->ifRouterState = NO_ROUTER; ! 214: zip_control (ifID, ZIP_NO_ROUTER); ! 215: break; ! 216: case ROUTER_WARNING : ! 217: /* there was a router that we were ignoring... ! 218: * now, even that's gone. But we want to tackle the ! 219: * case where another router may come up after all ! 220: * of them have died... ! 221: */ ! 222: ifID->ifRouterState = NO_ROUTER; ! 223: break; ! 224: } ! 225: } ! 226: ! 227: ! 228: ! 229: void ! 230: rtmp_input (mp, ifID) ! 231: register gbuf_t *mp; ! 232: register at_if_t *ifID; ! 233: { ! 234: register at_net_al this_net; ! 235: register at_net_al range_start, range_end; ! 236: register at_ddp_t *ddp = (at_ddp_t *)gbuf_rptr(mp); ! 237: /* NOTE: there is an assumption here that the ! 238: * DATA follows the header. */ ! 239: register at_rtmp *rtmp = (at_rtmp *)ddp->data; ! 240: ! 241: if (gbuf_type(mp) != MSG_DATA) { ! 242: /* If this is a M_ERROR message, DDP is shutting down, ! 243: * nothing to do here...If it's something else, we don't ! 244: * understand what it is ! 245: */ ! 246: gbuf_freem(mp); ! 247: return; ! 248: } ! 249: ! 250: if (!ifID) { ! 251: gbuf_freem(mp); ! 252: return; ! 253: } ! 254: if (gbuf_len(mp) < (DDP_X_HDR_SIZE + sizeof(at_rtmp))) { ! 255: gbuf_freem(mp); ! 256: return; ! 257: } ! 258: this_net = NET_VALUE(ifID->ifThisNode.atalk_net); ! 259: if (rtmp->at_rtmp_id_length != 8) { ! 260: gbuf_freem(mp); ! 261: return; ! 262: } ! 263: ! 264: { ! 265: at_rtmp_tuple *tp; ! 266: tp = ((at_rtmp_tuple *)&rtmp->at_rtmp_id[1]); ! 267: range_start = NET_VALUE(tp->at_rtmp_net); ! 268: tp = ((at_rtmp_tuple *)&rtmp->at_rtmp_id[4]); ! 269: range_end = NET_VALUE(tp->at_rtmp_net); ! 270: ! 271: if (ifID->ifRouterState == ROUTER_AROUND) { ! 272: if ((ifID->ifThisCableStart == range_start) && ! 273: (ifID->ifThisCableEnd == range_end)) { ! 274: trackrouter( ! 275: ifID, ! 276: NET_VALUE(rtmp->at_rtmp_this_net), ! 277: rtmp->at_rtmp_id[0] ! 278: ); ! 279: } ! 280: } else { ! 281: /* There was no router around earlier, one ! 282: * probably just came up. ! 283: */ ! 284: if ((this_net >= DDP_STARTUP_LOW) && ! 285: (this_net <= DDP_STARTUP_HIGH)) { ! 286: /* we're operating in the startup range, ! 287: * ignore the presence of router ! 288: */ ! 289: if (ifID->ifRouterState == NO_ROUTER) { ! 290: dPrintf(D_M_RTMP, D_L_STARTUP, ! 291: ("Warning: new router came up: invalid startup net/node\n")); ! 292: trackrouter( ! 293: ifID, ! 294: NET_VALUE(rtmp->at_rtmp_this_net), ! 295: rtmp->at_rtmp_id[0] ! 296: ); ! 297: ifID->ifRouterState = ROUTER_WARNING; ! 298: } ! 299: } else { ! 300: /* our address ! 301: * is not in startup range; Is our ! 302: * address good for the cable?? ! 303: */ ! 304: if ((this_net >= range_start) && ! 305: (this_net <= range_end)) { ! 306: /* Our address is in the range ! 307: * valid for this cable... Note ! 308: * the router address and then ! 309: * get ZIP rolling to get the ! 310: * zone info. ! 311: */ ! 312: ifID->ifThisCableStart = range_start; ! 313: ifID->ifThisCableEnd = range_end; ! 314: trackrouter( ! 315: ifID, ! 316: NET_VALUE(rtmp->at_rtmp_this_net), ! 317: rtmp->at_rtmp_id[0] ! 318: ); ! 319: zip_control(ifID, ZIP_LATE_ROUTER); ! 320: } else { ! 321: /* Our address is not in the ! 322: * range valid for this cable.. ! 323: * ignore presence of the ! 324: * router ! 325: */ ! 326: if (ifID->ifRouterState == NO_ROUTER) { ! 327: dPrintf(D_M_RTMP,D_L_ERROR, ! 328: ("Warning: new router came up: invalid net/node\n")); ! 329: trackrouter( ! 330: ifID, ! 331: NET_VALUE(rtmp->at_rtmp_this_net), ! 332: rtmp->at_rtmp_id[0] ! 333: ); ! 334: ifID->ifRouterState = ! 335: ROUTER_WARNING; ! 336: } ! 337: } ! 338: } ! 339: } ! 340: } ! 341: ! 342: gbuf_freem(mp); ! 343: return; ! 344: } ! 345: ! 346: ! 347: int rtmp_init() ! 348: { ! 349: bzero((caddr_t) trackedrouters, sizeof(struct routerinfo)*NROUTERS2TRAK); ! 350: ! 351: if (!ROUTING_MODE) ! 352: return((int)rtmp_input); ! 353: ! 354: else ! 355: return ((int)rtmp_router_input); ! 356: } ! 357: ! 358:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.