|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * The contents of this file constitute Original Code as defined in and ! 7: * are subject to the Apple Public Source License Version 1.1 (the ! 8: * "License"). You may not use this file except in compliance with the ! 9: * License. Please obtain a copy of the License at ! 10: * http://www.apple.com/publicsource and read it before using this file. ! 11: * ! 12: * This Original Code and all software distributed under the License are ! 13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: * License for the specific language governing rights and limitations ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: /* ! 23: * Copyright (c) 1993-1998 Apple Computer, Inc. ! 24: * All Rights Reserved. ! 25: */ ! 26: ! 27: /* ! 28: * Modified, March 17, 1997 by Tuyen Nguyen for MacOSX. ! 29: */ ! 30: ! 31: #include <sys/errno.h> ! 32: #include <sys/types.h> ! 33: #include <sys/param.h> ! 34: #include <machine/spl.h> ! 35: #include <sys/systm.h> ! 36: #include <sys/kernel.h> ! 37: #include <sys/proc.h> ! 38: #include <sys/filedesc.h> ! 39: #include <sys/fcntl.h> ! 40: #include <sys/mbuf.h> ! 41: #include <sys/ioctl.h> ! 42: #include <sys/malloc.h> ! 43: #include <sys/socket.h> ! 44: #include <sys/socketvar.h> ! 45: ! 46: #include <net/if.h> ! 47: ! 48: #include <netat/sysglue.h> ! 49: #include <netat/appletalk.h> ! 50: #include <netat/at_var.h> ! 51: #include <netat/ddp.h> ! 52: #include <netat/rtmp.h> ! 53: #include <netat/lap.h> ! 54: #include <netat/zip.h> ! 55: #include <netat/routing_tables.h> ! 56: #include <netat/debug.h> ! 57: #include <netat/at_pcb.h> ! 58: ! 59: extern void rtmp_router_input(); ! 60: ! 61: /****************************************************************/ ! 62: /* */ ! 63: /* */ ! 64: /* RTMP Protocol */ ! 65: /* */ ! 66: /* */ ! 67: /****************************************************************/ ! 68: ! 69: ! 70: /* rtmp.c: , 1.6; 2/26/93; Apple Computer, Inc." */ ! 71: ! 72: ! 73: #define NROUTERS2TRAK 8 ! 74: #define FIFTYSECS 10 ! 75: #define NODE(r) ((r)->ifARouter.s_node) ! 76: #define NET(r) ((r)->ifARouter.s_net) ! 77: #define INUSE(r) (NODE(r)) ! 78: ! 79: void ddp_age_router(); ! 80: ! 81: static struct routerinfo { ! 82: struct at_addr ifARouter; ! 83: at_ifaddr_t *ifID; ! 84: void *tmo; ! 85: } trackedrouters[NROUTERS2TRAK]; ! 86: ! 87: void trackrouter_rem_if(ifID) ! 88: register at_ifaddr_t *ifID; ! 89: { ! 90: register i; ! 91: register struct routerinfo *router; ! 92: ! 93: for (i = NROUTERS2TRAK; --i >= 0;) { ! 94: router = &trackedrouters[i]; ! 95: if (trackedrouters[i].ifID == ifID) { ! 96: untimeout(ddp_age_router, (caddr_t)router); ! 97: break; ! 98: } ! 99: } ! 100: } ! 101: ! 102: ! 103: void routershutdown() ! 104: { ! 105: register i; ! 106: ! 107: for (i = NROUTERS2TRAK; --i >= 0;) { ! 108: register struct routerinfo *router; ! 109: ! 110: router = &trackedrouters[i]; ! 111: if (INUSE(router)) { ! 112: untimeout(ddp_age_router, (caddr_t) router); ! 113: bzero((caddr_t) router, sizeof(struct routerinfo)); ! 114: } ! 115: } ! 116: } ! 117: ! 118: int router_added = 0; ! 119: int router_killed = 0; ! 120: ! 121: ! 122: ! 123: void trackrouter(ifID, net, node) ! 124: register at_ifaddr_t *ifID; ! 125: register unsigned short net; ! 126: register unsigned char node; ! 127: { ! 128: register struct routerinfo *unused = NULL; ! 129: register i; ! 130: ! 131: for (i = NROUTERS2TRAK; --i >= 0;) { ! 132: register struct routerinfo *router; ! 133: ! 134: router = &trackedrouters[(i + node) & (NROUTERS2TRAK-1)]; ! 135: if ((NODE(router) == node) && (NET(router) == net)) { ! 136: untimeout(ddp_age_router, (caddr_t) router); ! 137: timeout(ddp_age_router, (caddr_t) router, 50*SYS_HZ); ! 138: unused = NULL; ! 139: break; ! 140: } ! 141: else if (!INUSE(router) && !unused) ! 142: unused = router; ! 143: } ! 144: if (unused) { ! 145: router_added++; ! 146: ! 147: unused->ifID = ifID; ! 148: NET(unused) = net; ! 149: NODE(unused) = node; ! 150: timeout(ddp_age_router, (caddr_t) unused, 50*SYS_HZ); ! 151: if (NET(ifID) == 0 && NODE(ifID) == 0) { ! 152: NET(ifID) = net; ! 153: NODE(ifID) = node; ! 154: ifID->ifRouterState = ROUTER_AROUND; ! 155: } ! 156: } ! 157: } ! 158: ! 159: /* ! 160: * This is the timeout function that is called after 50 seconds, ! 161: * if no router packets come in. That way we won't send extended ! 162: * frames to something that is not there. Untimeout is called if ! 163: * an RTMP packet comes in so this routine will not be called. ! 164: */ ! 165: void ddp_age_router(deadrouter) ! 166: register struct routerinfo *deadrouter; ! 167: { ! 168: register at_ifaddr_t *ourrouter = deadrouter->ifID; ! 169: ! 170: dPrintf(D_M_RTMP, D_L_INFO, ! 171: ("ddp_age_router called deadrouter=%d:%d\n", NODE(deadrouter), NET(deadrouter))); ! 172: ! 173: router_killed++; ! 174: ! 175: if (NODE(ourrouter) == NODE(deadrouter) && ! 176: NET(ourrouter) == NET(deadrouter)) { ! 177: register unsigned long atrandom = random(); ! 178: register struct routerinfo *newrouter; ! 179: register i; ! 180: ! 181: bzero((caddr_t) deadrouter, sizeof(struct routerinfo)); ! 182: for (i = NROUTERS2TRAK; --i >= 0;) { ! 183: newrouter = &trackedrouters[(i + atrandom) & (NROUTERS2TRAK-1)]; ! 184: if (INUSE(newrouter)) ! 185: break; ! 186: else ! 187: newrouter = NULL; ! 188: } ! 189: if (newrouter) { ! 190: NET(ourrouter) = NET(newrouter); ! 191: NODE(ourrouter) = NODE(newrouter); ! 192: } ! 193: else { ! 194: /* from gorouterless() */ ! 195: ATTRACE(AT_MID_DDP, AT_SID_TIMERS, AT_LV_WARNING, FALSE, ! 196: "ddp_age_router entry : ARouter = 0x%x, RouterState = 0x%x", ! 197: ATALK_VALUE(ourrouter->ifARouter), ourrouter->ifRouterState, 0); ! 198: ! 199: switch (ourrouter->ifRouterState) { ! 200: case ROUTER_AROUND : ! 201: ourrouter->ifARouter.s_net = 0; ! 202: ourrouter->ifARouter.s_node = 0; ! 203: dPrintf(D_M_RTMP,D_L_INFO, ! 204: ("rtmp.c Gorouterless!!!!!!!!\n")); ! 205: ourrouter->ifThisCableStart = DDP_MIN_NETWORK; ! 206: ourrouter->ifThisCableEnd = DDP_MAX_NETWORK; ! 207: ourrouter->ifRouterState = NO_ROUTER; ! 208: zip_control(ourrouter, ZIP_NO_ROUTER); ! 209: break; ! 210: case ROUTER_WARNING : ! 211: /* there was a router that we were ignoring... ! 212: * now, even that's gone. But we want to tackle the ! 213: * case where another router may come up after all ! 214: * of them have died... ! 215: */ ! 216: ourrouter->ifRouterState = NO_ROUTER; ! 217: break; ! 218: } ! 219: } ! 220: } else ! 221: bzero((caddr_t) deadrouter, sizeof(struct routerinfo)); ! 222: } /* ddp_age_router */ ! 223: ! 224: void rtmp_input (mp, ifID) ! 225: register gbuf_t *mp; ! 226: register at_ifaddr_t *ifID; ! 227: { ! 228: register at_net_al this_net; ! 229: register at_net_al range_start, range_end; ! 230: register at_ddp_t *ddp = (at_ddp_t *)gbuf_rptr(mp); ! 231: /* NOTE: there is an assumption here that the ! 232: * DATA follows the header. */ ! 233: register at_rtmp *rtmp = (at_rtmp *)ddp->data; ! 234: ! 235: if (gbuf_type(mp) != MSG_DATA) { ! 236: /* If this is a M_ERROR message, DDP is shutting down, ! 237: * nothing to do here...If it's something else, we don't ! 238: * understand what it is ! 239: */ ! 240: gbuf_freem(mp); ! 241: return; ! 242: } ! 243: ! 244: if (!ifID) { ! 245: gbuf_freem(mp); ! 246: return; ! 247: } ! 248: if (gbuf_len(mp) < (DDP_X_HDR_SIZE + sizeof(at_rtmp))) { ! 249: gbuf_freem(mp); ! 250: return; ! 251: } ! 252: this_net = ifID->ifThisNode.s_net; ! 253: if (rtmp->at_rtmp_id_length != 8) { ! 254: gbuf_freem(mp); ! 255: return; ! 256: } ! 257: ! 258: { ! 259: at_rtmp_tuple *tp; ! 260: tp = ((at_rtmp_tuple *)&rtmp->at_rtmp_id[1]); ! 261: range_start = NET_VALUE(tp->at_rtmp_net); ! 262: tp = ((at_rtmp_tuple *)&rtmp->at_rtmp_id[4]); ! 263: range_end = NET_VALUE(tp->at_rtmp_net); ! 264: ! 265: if (ifID->ifRouterState == ROUTER_AROUND) { ! 266: if ((ifID->ifThisCableStart == range_start) && ! 267: (ifID->ifThisCableEnd == range_end)) { ! 268: trackrouter(ifID, ! 269: NET_VALUE(rtmp->at_rtmp_this_net), ! 270: rtmp->at_rtmp_id[0] ! 271: ); ! 272: } ! 273: } else { ! 274: /* There was no router around earlier, one ! 275: * probably just came up. ! 276: */ ! 277: if ((this_net >= DDP_STARTUP_LOW) && ! 278: (this_net <= DDP_STARTUP_HIGH)) { ! 279: /* we're operating in the startup range, ! 280: * ignore the presence of router ! 281: */ ! 282: if (ifID->ifRouterState == NO_ROUTER) { ! 283: dPrintf(D_M_RTMP, D_L_STARTUP, ! 284: ("Warning: new router came up: invalid startup net/node\n")); ! 285: trackrouter(ifID, ! 286: NET_VALUE(rtmp->at_rtmp_this_net), ! 287: rtmp->at_rtmp_id[0] ! 288: ); ! 289: ifID->ifRouterState = ROUTER_WARNING; ! 290: } ! 291: } else { ! 292: /* our address ! 293: * is not in startup range; Is our ! 294: * address good for the cable?? ! 295: */ ! 296: if ((this_net >= range_start) && ! 297: (this_net <= range_end)) { ! 298: /* Our address is in the range ! 299: * valid for this cable... Note ! 300: * the router address and then ! 301: * get ZIP rolling to get the ! 302: * zone info. ! 303: */ ! 304: ifID->ifThisCableStart = range_start; ! 305: ifID->ifThisCableEnd = range_end; ! 306: trackrouter(ifID, ! 307: NET_VALUE(rtmp->at_rtmp_this_net), ! 308: rtmp->at_rtmp_id[0] ! 309: ); ! 310: zip_control(ifID, ZIP_LATE_ROUTER); ! 311: } else { ! 312: /* Our address is not in the ! 313: * range valid for this cable.. ! 314: * ignore presence of the ! 315: * router ! 316: */ ! 317: if (ifID->ifRouterState == NO_ROUTER) { ! 318: dPrintf(D_M_RTMP,D_L_ERROR, ! 319: ("Warning: new router came up: invalid net/node\n")); ! 320: trackrouter(ifID, ! 321: NET_VALUE(rtmp->at_rtmp_this_net), ! 322: rtmp->at_rtmp_id[0] ! 323: ); ! 324: ifID->ifRouterState = ROUTER_WARNING; ! 325: } ! 326: } ! 327: } ! 328: } ! 329: } ! 330: ! 331: gbuf_freem(mp); ! 332: return; ! 333: } ! 334: ! 335: ! 336: void rtmp_init() ! 337: { ! 338: bzero((caddr_t)trackedrouters, sizeof(struct routerinfo)*NROUTERS2TRAK); ! 339: } ! 340: ! 341:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.