|
|
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) 1988, 1989, 1993-1998 Apple Computer, Inc. ! 24: */ ! 25: ! 26: /* at_elap.c: 2.0, 1.29; 10/4/93; Apple Computer, Inc. */ ! 27: ! 28: /* This is the file which implements all the streams driver ! 29: * functionality required for EtherTalk. ! 30: */ ! 31: ! 32: /* revision history ! 33: ! 34: 03-14-94 jjs Changed all functions which assumed only one port would ! 35: ever be used. Added validate_msg_size, changed elap_online ! 36: to work with the h/w name only (e.g. 'et2'). ! 37: ! 38: Modified for MP, 1996 by Tuyen Nguyen ! 39: Modified, March 17, 1997 by Tuyen Nguyen for MacOSX. ! 40: ! 41: */ ! 42: ! 43: #define RESOLVE_DBG /* for debug.h global resolution */ ! 44: #include <sys/errno.h> ! 45: #include <sys/types.h> ! 46: #include <sys/param.h> ! 47: #include <machine/spl.h> ! 48: #include <sys/systm.h> ! 49: #include <sys/kernel.h> ! 50: #include <sys/proc.h> ! 51: #include <sys/filedesc.h> ! 52: #include <sys/fcntl.h> ! 53: #include <sys/mbuf.h> ! 54: #include <sys/ioctl.h> ! 55: #include <sys/socket.h> ! 56: #include <sys/socketvar.h> ! 57: #include <sys/malloc.h> ! 58: #include <sys/sockio.h> ! 59: ! 60: #include <net/if.h> ! 61: #include <net/if_types.h> ! 62: ! 63: #include <netat/sysglue.h> ! 64: #include <netat/appletalk.h> ! 65: #include <netat/at_var.h> ! 66: #include <netat/ddp.h> ! 67: #include <netat/lap.h> ! 68: #include <netat/routing_tables.h> /* rtmp+zip table structs */ ! 69: #include <netat/zip.h> ! 70: #include <netat/nbp.h> ! 71: #include <netat/at_snmp.h> ! 72: #include <netat/at_pcb.h> ! 73: #include <netat/at_aarp.h> ! 74: #include <netat/debug.h> ! 75: #include <netat/at_config.h> ! 76: ! 77: /* globals */ ! 78: ! 79: at_ifaddr_t at_interfaces[IF_TOTAL_MAX]; ! 80: /* index for at_interfaces is not important */ ! 81: at_ifaddr_t *ifID_table[IF_TOTAL_MAX]; ! 82: /* the table of ifID structures, one per interface ! 83: (not just ethernet), indexed by DDP port ! 84: * NOTE: for MH, entry 0 in this table is ! 85: * now defined to be the default I/F ! 86: */ ! 87: at_ifaddr_t *ifID_home; ! 88: /* always ifID_table[IFID_HOME] for now, but will be used for ! 89: dynamic "home port" assignment, later */ ! 90: ! 91: at_state_t at_state; /* global state of AT network */ ! 92: if_types_t if_types[IF_TYPENO_CNT] = {{ IFT_ETHER, IF_TOTAL_MAX }}; ! 93: ! 94: snmpFlags_t snmpFlags; ! 95: ! 96: int xpatcnt = 0; ! 97: ! 98: /* snmp defines */ ! 99: #define MAX_BUFSIZE 8192 ! 100: #define MAX_RTMP (MAX_BUFSIZE/sizeof(RT_entry)-1) ! 101: #define MAX_NBP \ ! 102: ((MAX_BUFSIZE - SNMP_NBP_HEADER_SIZE)/sizeof(snmpNbpEntry_t)-1) ! 103: #define MAX_NBP_BYTES (MAX_NBP * sizeof(snmpNbpEntry_t)) ! 104: #define MAX_ZIP (MAX_BUFSIZE/sizeof(ZT_entry)-1) ! 105: #define MAX_RTMP_BYTES (MAX_RTMP * sizeof(RT_entry)) ! 106: #define MAX_ZIP_BYTES (MAX_ZIP * sizeof(ZT_entry)) ! 107: ! 108: /* externs */ ! 109: extern TAILQ_HEAD(name_registry, _nve_) name_registry; ! 110: extern snmpStats_t snmpStats; ! 111: extern atlock_t ddpinp_lock; ! 112: extern atlock_t arpinp_lock; ! 113: extern short appletalk_inited; ! 114: extern int adspInited; ! 115: extern struct atpcb ddp_head; ! 116: extern at_ddp_stats_t at_ddp_stats; ! 117: ! 118: /* protos */ ! 119: extern snmpAarpEnt_t * getAarp(int *); ! 120: extern int setLocalZones(at_nbptuple_t * , int); ! 121: extern int getRTRLocalZone(if_zone_t *); ! 122: extern void nbp_shutdown(), routershutdown(), ddp_brt_shutdown(); ! 123: extern void ddp_brt_init(), rtmp_init(), rtmp_input(); ! 124: extern rtmp_router_start(at_kern_err_t *); ! 125: static void getIfNames(if_name_t *); ! 126: static void add_route(); ! 127: static int set_zones(); ! 128: void elap_offline(); ! 129: static int elap_online1(), re_aarp(); ! 130: int at_reg_mcast(), at_unreg_mcast(); ! 131: void AARPwakeup(), ZIPwakeup(); ! 132: void ddp_bit_reverse(), ddp_shutdown(); ! 133: static void elap_hangup(); ! 134: static getSnmpCfg(); ! 135: ! 136: at_ifaddr_t *find_ifID(if_name) ! 137: char *if_name; ! 138: { ! 139: int pat_id; ! 140: ! 141: if (strlen(if_name)) ! 142: for (pat_id=0; pat_id < xpatcnt; pat_id++) { ! 143: if (!strcmp(at_interfaces[pat_id].ifName, if_name)) ! 144: return(&at_interfaces[pat_id]); ! 145: } ! 146: ! 147: return((at_ifaddr_t *)NULL); ! 148: } ! 149: ! 150: static int validate_msg_size(m, gref, elapp) ! 151: register gbuf_t *m; ! 152: gref_t *gref; ! 153: at_ifaddr_t **elapp; ! 154: ! 155: /* checks ioctl message type for minimum expected message size & ! 156: sends error back if size invalid ! 157: */ ! 158: { ! 159: register ioc_t *iocbp; ! 160: register at_if_cfg_t *cfgp; ! 161: int i, size = 1; ! 162: ! 163: *elapp = NULL; ! 164: iocbp = (ioc_t *) gbuf_rptr(m); ! 165: ! 166: dPrintf(D_M_ELAP, D_L_INFO, ("validate_msg_size: ioc_cmd = %d\n", ! 167: iocbp->ioc_cmd)); ! 168: switch (iocbp->ioc_cmd) { ! 169: case LAP_IOC_ADD_ROUTE: ! 170: size = sizeof(RT_entry); ! 171: break; ! 172: case LAP_IOC_ADD_ZONE: ! 173: size = sizeof(if_zone_info_t); ! 174: break; ! 175: case LAP_IOC_GET_ROUTE: ! 176: size = sizeof(RT_entry); ! 177: break; ! 178: case LAP_IOC_GET_ZONE: ! 179: size = sizeof(ZT_entryno); ! 180: break; ! 181: case LAP_IOC_SNMP_GET_CFG: ! 182: case LAP_IOC_SNMP_GET_AARP: ! 183: case LAP_IOC_SNMP_GET_ZIP: ! 184: case LAP_IOC_SNMP_GET_RTMP: ! 185: case LAP_IOC_SNMP_GET_NBP: ! 186: size = sizeof(int); ! 187: break; ! 188: case LAP_IOC_GET_LOCAL_ZONE: ! 189: size = sizeof(if_zone_t); ! 190: break; ! 191: case LAP_IOC_CHECK_STATE: ! 192: size = 1; ! 193: break; ! 194: ! 195: case ELAP_IOC_GET_STATS: ! 196: case LAP_IOC_SNMP_GET_DDP: ! 197: case LAP_IOC_GET_IF_NAMES: ! 198: size = 0; ! 199: break; ! 200: ! 201: /* these ioctls send variable length data */ ! 202: case LAP_IOC_SET_LOCAL_ZONES: ! 203: size = -1; ! 204: break; ! 205: default: ! 206: dPrintf(D_M_ELAP, D_L_ERROR, ("validate_msg_size: unknown ioctl\n")); ! 207: goto error; ! 208: } ! 209: ! 210: if (size == 0) { /* a non-data ioctl */ ! 211: return(0); ! 212: } ! 213: ! 214: if (gbuf_cont(m) != NULL) { ! 215: i = gbuf_len(gbuf_cont(m)); ! 216: if (size == -1) ! 217: if (i >1) ! 218: return(0); ! 219: else ! 220: goto error; ! 221: } ! 222: if (iocbp->ioc_count < size || (gbuf_cont(m) == NULL) || i < size) { ! 223: dPrintf(D_M_ELAP, D_L_ERROR, ! 224: ("ioctl msg error:s:%d c:%d bcont:%c delta:%d\n", ! 225: size, iocbp->ioc_count, ! 226: gbuf_cont(m)? 'Y' : 'N', i)); ! 227: goto error; ! 228: } ! 229: else ! 230: return(0); ! 231: error: ! 232: ioc_ack(EMSGSIZE, m, gref); ! 233: return (EMSGSIZE); ! 234: } /* validate_msg_size */ ! 235: ! 236: int lap_online(elapp, cfgp) ! 237: at_ifaddr_t *elapp; ! 238: at_if_cfg_t *cfgp; ! 239: { ! 240: int error; ! 241: ! 242: if (elapp->ifState != LAP_OFFLINE) { ! 243: return(EALREADY); ! 244: } ! 245: ! 246: elapp->flags = 0; ! 247: if (cfgp->flags & ELAP_CFG_HOME) { ! 248: if (ifID_home) { ! 249: /* only 1 home allowed! */ ! 250: return(EEXIST); ! 251: } ! 252: dPrintf(D_M_ELAP, D_L_STARTUP, ! 253: ("elap_wput home I/F:%s\n", cfgp->ifr_name)); ! 254: elapp->flags |= ELAP_CFG_HOME; ! 255: } ! 256: ! 257: if (MULTIPORT_MODE) { ! 258: elapp->flags |= ELAP_CFG_ZONELESS; ! 259: if (ROUTING_MODE && cfgp->netStart) ! 260: elapp->flags |= ELAP_CFG_SEED; ! 261: } ! 262: ! 263: if (!DEFAULT_ZONE(&cfgp->zonename) && ! 264: (elapp->flags & ELAP_CFG_HOME) || MULTIHOME_MODE) { ! 265: elapp->startup_zone = cfgp->zonename; ! 266: } ! 267: ! 268: if (elapp->flags & ELAP_CFG_SEED) { ! 269: dPrintf(D_M_ELAP, D_L_STARTUP_INFO, ! 270: ("elap_wput: found to be seed\n")); ! 271: elapp->ifThisCableStart = cfgp->netStart; ! 272: elapp->ifThisCableEnd = cfgp->netEnd; ! 273: } ! 274: else { ! 275: dPrintf(D_M_ELAP,D_L_ERROR, ! 276: ("elap_wput: we believe we're not seed\n")); ! 277: /* from ELAP_IOC_SET_CFG */ ! 278: if (ATALK_VALUE(cfgp->node)) { ! 279: u_short initial_net; ! 280: u_char initial_node; ! 281: ! 282: initial_node = cfgp->node.s_node; ! 283: initial_net = cfgp->node.s_net; ! 284: if ((initial_node<0xfe) && (initial_node>0) && ! 285: !((initial_net == 0) || ! 286: ((initial_net >= DDP_STARTUP_LOW)&& ! 287: (initial_net <= DDP_STARTUP_HIGH)))) { ! 288: ! 289: elapp->initial_addr = cfgp->node; ! 290: } ! 291: } ! 292: } ! 293: ! 294: elapp->startup_error = 0; ! 295: elapp->startup_inprogress = FALSE; ! 296: if ((error = elap_online1(elapp))) ! 297: ddp_rem_if(elapp); ! 298: else ! 299: if (!(MULTIPORT_MODE) && ! 300: elapp->ifZoneName.len == 1 && ! 301: elapp->ifZoneName.str[0] == '*' && ! 302: !DEFAULT_ZONE(&cfgp->zonename)) { ! 303: nbp_add_multicast(&cfgp->zonename, elapp); ! 304: } ! 305: return(error); ! 306: } /* lap_online */ ! 307: ! 308: /*********************************************************************** ! 309: * elap_wput() ! 310: * ! 311: **********************************************************************/ ! 312: int elap_wput(gref, m) ! 313: gref_t *gref; ! 314: register gbuf_t *m; ! 315: { ! 316: at_ifaddr_t *elapp; ! 317: register ioc_t *iocbp; ! 318: register at_if_cfg_t *cfgp; ! 319: at_elap_stats_t *statsp; ! 320: int error, i; ! 321: int (*func)(); ! 322: gbuf_t *tmpm; ! 323: at_ifaddr_t *patp; ! 324: ! 325: ! 326: switch (gbuf_type(m)) { ! 327: case MSG_DATA: ! 328: gbuf_freem(m); ! 329: dPrintf(D_M_ELAP,D_L_ERROR, ! 330: ("Output data to control channel is ignored\n")); ! 331: break; ! 332: ! 333: case MSG_IOCTL: ! 334: iocbp = (ioc_t *) gbuf_rptr(m); ! 335: ! 336: if (validate_msg_size(m, gref, &elapp)) ! 337: break; ! 338: ! 339: if (elapp) ! 340: cfgp = (at_if_cfg_t*) gbuf_rptr(gbuf_cont(m)); ! 341: ! 342: if (LAP_IOC_MYIOCTL(iocbp->ioc_cmd) || ! 343: ELAP_IOC_MYIOCTL(iocbp->ioc_cmd)) { ! 344: ! 345: switch (iocbp->ioc_cmd) { ! 346: ! 347: case LAP_IOC_CHECK_STATE: ! 348: #ifdef APPLETALK_DEBUG ! 349: kprintf("LAP_IOC_CHECK_STATE\n"); ! 350: #endif ! 351: error = (!(at_state.flags & AT_ST_STARTED))? ! 352: ENOTREADY : 0; ! 353: if (error == 0) { ! 354: int size; ! 355: dPrintf(D_M_ELAP,D_L_INFO, ! 356: ("elap_wput: CHECK_STATE 1\n")); ! 357: ! 358: /* re-use gbuf */ ! 359: tmpm = gbuf_cont(m); ! 360: gbuf_wset(tmpm, 0); ! 361: ! 362: size = list_pids((int *)gbuf_rptr(tmpm), ! 363: 10); /* *** 10 just for now *** */ ! 364: gbuf_wset(tmpm, (size * sizeof(int))); ! 365: gbuf_set_type(tmpm, MSG_DATA); ! 366: ((ioc_t *)gbuf_rptr(m))->ioc_count = gbuf_msgsize(tmpm); ! 367: ioc_ack(0, m, gref); ! 368: } else { ! 369: dPrintf(D_M_ELAP,D_L_INFO, ! 370: ("elap_wput: CHECK_STATE 2\n")); ! 371: ioc_ack(error, m, gref); ! 372: } ! 373: break; ! 374: ! 375: case ELAP_IOC_GET_STATS: ! 376: #ifdef APPLETALK_DEBUG ! 377: kprintf("LAP_IOC_GET_STATS\n"); ! 378: #endif ! 379: if ( (gbuf_cont(m) == NULL) ! 380: || (elapp = find_ifID(gbuf_rptr(gbuf_cont(m)))) == NULL) { ! 381: ioc_ack(EINVAL, m, gref); ! 382: break; ! 383: } ! 384: gbuf_freem(gbuf_cont(m)); ! 385: if ((gbuf_cont(m) =gbuf_alloc(sizeof(at_elap_stats_t), ! 386: PRI_MED)) == NULL) { ! 387: ioc_ack(ENOBUFS, m, gref); ! 388: break; ! 389: } ! 390: statsp = ((at_elap_stats_t *)gbuf_rptr(gbuf_cont(m))); ! 391: *statsp = elapp->stats; ! 392: gbuf_wset(gbuf_cont(m),sizeof(at_elap_stats_t)); ! 393: iocbp->ioc_count = sizeof(at_elap_stats_t); ! 394: ioc_ack(0, m, gref); ! 395: break; ! 396: ! 397: case LAP_IOC_ADD_ZONE: ! 398: #ifdef APPLETALK_DEBUG ! 399: kprintf("LAP_IOC_ADD_ZONE\n"); ! 400: #endif ! 401: i = set_zones((if_zone_info_t *)gbuf_rptr(gbuf_cont(m))); ! 402: ioc_ack(i, m, gref); ! 403: break; ! 404: ! 405: case LAP_IOC_ADD_ROUTE: ! 406: #ifdef APPLETALK_DEBUG ! 407: kprintf("LAP_IOC_ADD_ROUTE\n"); ! 408: #endif ! 409: add_route((RT_entry *)gbuf_rptr(gbuf_cont(m))); ! 410: ioc_ack(0, m, gref); ! 411: break; ! 412: ! 413: case LAP_IOC_GET_ZONE: ! 414: #ifdef APPLETALK_DEBUG ! 415: kprintf("LAP_IOC_GET_ZONE\n"); ! 416: #endif ! 417: /* return next ZT_entryno from ZT_table ! 418: a pointer to the struct ZT_entryno is passed down from ! 419: user space and the first byte is cast to a int, if ! 420: this int is non-zero, then the first ZT_entry is ! 421: returned and subsequent calls with a zero value ! 422: will return the next entry in the table. The next ! 423: read after the last valid entry will return EINVAL ! 424: */ ! 425: { ! 426: ZT_entryno *pZTe; ! 427: ! 428: i = *(int *)gbuf_rptr(gbuf_cont(m)); ! 429: gbuf_freem(gbuf_cont(m)); ! 430: gbuf_cont(m) = NULL; ! 431: ! 432: pZTe = zt_getNextZone(i); ! 433: if (pZTe) { ! 434: if ((gbuf_cont(m) = gbuf_alloc(sizeof(ZT_entryno), PRI_MED)) == NULL) { ! 435: ioc_ack(ENOBUFS, m, gref); ! 436: break; ! 437: } ! 438: *(ZT_entryno *)gbuf_rptr(gbuf_cont(m)) = *pZTe; ! 439: gbuf_wset(gbuf_cont(m),sizeof(ZT_entryno)); ! 440: iocbp->ioc_count = sizeof(ZT_entryno); ! 441: ioc_ack(0, m, gref); ! 442: } ! 443: else ! 444: ioc_ack(EINVAL, m, gref); ! 445: } ! 446: break; ! 447: case LAP_IOC_GET_LOCAL_ZONE: ! 448: #ifdef APPLETALK_DEBUG ! 449: kprintf("LAP_IOC_GET_LOCAL_ZONE\n"); ! 450: #endif ! 451: if (!MULTIPORT_MODE) { ! 452: ioc_ack(EPERM, m, gref); ! 453: break; ! 454: } ! 455: { ! 456: if_zone_t *ifz; ! 457: int zone; ! 458: ! 459: zone = ((if_zone_t *)gbuf_rptr(gbuf_cont(m)))->ifzn.zone; ! 460: gbuf_freem(gbuf_cont(m)); ! 461: gbuf_cont(m) = NULL; ! 462: if ((gbuf_cont(m) = gbuf_alloc(sizeof(if_zone_t), PRI_MED)) == NULL) { ! 463: ioc_ack(ENOBUFS, m, gref); ! 464: break; ! 465: } ! 466: ifz = (if_zone_t *)gbuf_rptr(gbuf_cont(m)); ! 467: ifz->ifzn.zone = zone; ! 468: getRTRLocalZone(ifz); ! 469: gbuf_wset(gbuf_cont(m),sizeof(*ifz)); ! 470: iocbp->ioc_count = sizeof(*ifz); ! 471: } ! 472: ioc_ack(0, m, gref); ! 473: break; ! 474: case LAP_IOC_GET_ROUTE: ! 475: #ifdef APPLETALK_DEBUG ! 476: kprintf("LAP_IOC_GET_ROUTE\n"); ! 477: #endif ! 478: /* return next RT_entry from RT_table ! 479: * a pointer to the struct RT_entry is ! 480: * passed down from user space and the first ! 481: * byte is cast to a int, if this int is ! 482: * non-zero, then the first RT_entry is ! 483: * returned and subsequent calls with a ! 484: * zero value will return the next entry in ! 485: * the table. The next read after the last ! 486: * valid entry will return EINVAL ! 487: */ ! 488: { ! 489: RT_entry *pRT; ! 490: ! 491: i = *(int *)gbuf_rptr(gbuf_cont(m)); ! 492: gbuf_freem(gbuf_cont(m)); ! 493: gbuf_cont(m) = NULL; ! 494: ! 495: pRT = rt_getNextRoute(i); ! 496: if (pRT) { ! 497: if ((gbuf_cont(m) = gbuf_alloc(sizeof(RT_entry), PRI_MED)) == NULL) { ! 498: ioc_ack(ENOBUFS, m, gref); ! 499: break; ! 500: } ! 501: *(RT_entry *)gbuf_rptr(gbuf_cont(m)) = *pRT; ! 502: gbuf_wset(gbuf_cont(m),sizeof(RT_entry)); ! 503: iocbp->ioc_count = sizeof(RT_entry); ! 504: ioc_ack(0, m, gref); ! 505: } ! 506: else ! 507: ioc_ack(EINVAL, m, gref); ! 508: } ! 509: break; ! 510: ! 511: case LAP_IOC_SNMP_GET_DDP: ! 512: #ifdef APPLETALK_DEBUG ! 513: kprintf("LAP_IOC_SNMP_GET_DDP\n"); ! 514: #endif ! 515: if (!(at_state.flags & AT_ST_STARTED)) { ! 516: ioc_ack(ENOTREADY, m, gref); ! 517: break; ! 518: } ! 519: if ((gbuf_cont(m) = gbuf_alloc(sizeof(snmpStats_t), ! 520: PRI_MED)) == NULL) { ! 521: ioc_ack(ENOBUFS, m, gref); ! 522: break; ! 523: } ! 524: ! 525: *(snmpStats_t *)gbuf_rptr(gbuf_cont(m)) = snmpStats; ! 526: gbuf_wset(gbuf_cont(m),sizeof(snmpStats)); ! 527: iocbp->ioc_count = sizeof(snmpStats); ! 528: ioc_ack(0, m, gref); ! 529: break; ! 530: case LAP_IOC_SNMP_GET_CFG: ! 531: #ifdef APPLETALK_DEBUG ! 532: kprintf("LAP_IOC_SNMP_GET_CFG\n"); ! 533: #endif ! 534: { ! 535: int i,size; ! 536: snmpCfg_t snmp; ! 537: ! 538: i = *(int *)gbuf_rptr(gbuf_cont(m)); ! 539: gbuf_freem(gbuf_cont(m)); ! 540: gbuf_cont(m) = NULL; ! 541: if (!(at_state.flags & AT_ST_STARTED)) { ! 542: /* if stack down */ ! 543: iocbp->ioc_count = 0; ! 544: ioc_ack(ENOTREADY, m, gref); ! 545: dPrintf(D_M_ELAP_LOW, D_L_INFO, ! 546: ("elap_wput: cfg req, stack down\n")); ! 547: break; ! 548: } ! 549: if (i == UPDATE_IF_CHANGED && ! 550: !(at_state.flags & AT_ST_IF_CHANGED)) { ! 551: iocbp->ioc_count = 0; ! 552: ioc_ack(0, m, gref); ! 553: dPrintf(D_M_ELAP_LOW, D_L_INFO, ! 554: ("elap_wput: cfg req, unchanged\n")); ! 555: break; ! 556: } ! 557: dPrintf(D_M_ELAP_LOW, D_L_INFO, ! 558: ("elap_wput: cfg req, changed\n")); ! 559: ! 560: if (getSnmpCfg(&snmp)) { ! 561: dPrintf(D_M_ELAP,D_L_ERROR, ! 562: ("elap_wput:SNMP_GET_CFG error\n")); ! 563: ioc_ack(EOPNOTSUPP, m, gref); ! 564: break; ! 565: } ! 566: /* send up only used part of table */ ! 567: size = sizeof(snmp) - ! 568: sizeof(snmpIfCfg_t) * (MAX_IFS - snmp.cfg_ifCnt); ! 569: ! 570: if ((gbuf_cont(m) = gbuf_alloc(size, PRI_MED)) == NULL) { ! 571: ioc_ack(ENOBUFS, m, gref); ! 572: break; ! 573: } ! 574: bcopy(&snmp,gbuf_rptr(gbuf_cont(m)),size); ! 575: gbuf_wset(gbuf_cont(m),size); ! 576: iocbp->ioc_count = size; ! 577: at_state.flags &= ~AT_ST_IF_CHANGED; ! 578: ioc_ack(0, m, gref); ! 579: } ! 580: break; ! 581: ! 582: case LAP_IOC_SNMP_GET_AARP: ! 583: { ! 584: snmpAarpEnt_t *snmpp; ! 585: int bytes; ! 586: #ifdef APPLETALK_DEBUG ! 587: kprintf("LAP_IOC_SNMP_GET_AARP\n"); ! 588: #endif ! 589: i = *(int *)gbuf_rptr(gbuf_cont(m)); ! 590: gbuf_freem(gbuf_cont(m)); ! 591: gbuf_cont(m) = NULL; ! 592: dPrintf(D_M_ELAP,D_L_INFO, ! 593: ("elap_wput:calling getarp,i=%d\n", i)); ! 594: snmpp = getAarp(&i); ! 595: bytes = i * sizeof(snmpAarpEnt_t); ! 596: dPrintf(D_M_ELAP,D_L_INFO, ! 597: ("elap_wput:getarp returned, i=%d,bytes=%d\n", ! 598: i, bytes)); ! 599: if (snmpp) { ! 600: if ((gbuf_cont(m) = gbuf_alloc(bytes, PRI_MED)) == NULL) { ! 601: ioc_ack(ENOBUFS, m, gref); ! 602: break; ! 603: } ! 604: bcopy(snmpp, gbuf_rptr(gbuf_cont(m)), bytes); ! 605: gbuf_wset(gbuf_cont(m),bytes); ! 606: iocbp->ioc_count = bytes; ! 607: ioc_ack(0, m, gref); ! 608: } ! 609: else ! 610: ioc_ack(EOPNOTSUPP, m, gref); ! 611: } ! 612: break; ! 613: ! 614: case LAP_IOC_SNMP_GET_ZIP: ! 615: #ifdef APPLETALK_DEBUG ! 616: kprintf("LAP_IOC_SNMP_GET_ZIP\n"); ! 617: #endif ! 618: { /* matching brace NOT in this case */ ! 619: register int i,j; ! 620: register int size, total, tabsize; ! 621: gbuf_t *mn; /* new gbuf */ ! 622: gbuf_t *mo; /* old gbuf */ ! 623: gbuf_t *mt; /* temp */ ! 624: snmpNbpTable_t *nbp; ! 625: ! 626: i = *(int *)gbuf_rptr(gbuf_cont(m)); ! 627: gbuf_freem(gbuf_cont(m)); ! 628: gbuf_cont(m) = NULL; ! 629: if (!(at_state.flags & AT_ST_STARTED)) { ! 630: ioc_ack(ENOTREADY, m, gref); ! 631: break; ! 632: } ! 633: if (i == UPDATE_IF_CHANGED && ! 634: !(at_state.flags & AT_ST_ZT_CHANGED)) { ! 635: iocbp->ioc_count = 0; ! 636: ioc_ack(0, m, gref); ! 637: break; ! 638: } ! 639: mo=(gbuf_t*)NULL; ! 640: tabsize = getZipTableSize(); ! 641: ! 642: /* retrieve table into multiple gbufs */ ! 643: for (i =0; i<tabsize; i+=j) { ! 644: j = tabsize - i > ! 645: MAX_ZIP ? MAX_ZIP : tabsize - i; ! 646: size = j < MAX_ZIP ? sizeof(ZT_entry)*j : MAX_ZIP_BYTES; ! 647: if ((mn = gbuf_alloc(size, PRI_MED)) == NULL) { ! 648: if (gbuf_cont(m)) ! 649: gbuf_freem(gbuf_cont(m)); ! 650: ioc_ack(ENOBUFS, m, gref); ! 651: break; ! 652: } ! 653: if (!mo) { /* if first new one */ ! 654: mt = mn; ! 655: total = size; ! 656: } ! 657: else { ! 658: gbuf_cont(mo) = mn; ! 659: total += size; ! 660: } ! 661: mo = mn; ! 662: getZipTable((ZT_entry*)gbuf_rptr(mn),i,j); ! 663: gbuf_wset(mn,size); ! 664: } ! 665: if ((gbuf_cont(m) = gbuf_alloc(sizeof(int), PRI_MED)) == NULL) { ! 666: if (mt) ! 667: gbuf_freem(mt); ! 668: iocbp->ioc_count = 0; ! 669: ioc_ack(ENOBUFS, m, gref); ! 670: break; ! 671: } ! 672: if (!tabsize) { ! 673: dPrintf(D_M_ELAP,D_L_WARNING, ! 674: ("elap_wput:snmp: empty zip table\n")); ! 675: total = 0; ! 676: } ! 677: *(int*)gbuf_rptr(gbuf_cont(m)) = total; /* return table size */ ! 678: gbuf_wset(gbuf_cont(m),sizeof(int)); ! 679: iocbp->ioc_count = sizeof(int); ! 680: ioc_ack(0, m, gref); ! 681: if (tabsize) ! 682: atalk_putnext(gref,mt); /* send up table */ ! 683: at_state.flags &= ~AT_ST_ZT_CHANGED; ! 684: break; ! 685: ! 686: case LAP_IOC_SNMP_GET_RTMP: ! 687: #ifdef APPLETALK_DEBUG ! 688: kprintf("LAP_IOC_SNMP_GET_RTMP\n"); ! 689: #endif ! 690: i = *(int *)gbuf_rptr(gbuf_cont(m)); ! 691: gbuf_freem(gbuf_cont(m)); ! 692: gbuf_cont(m) = NULL; ! 693: if (!(at_state.flags & AT_ST_STARTED)) { ! 694: ioc_ack(ENOTREADY, m, gref); ! 695: break; ! 696: } ! 697: if (i == UPDATE_IF_CHANGED && ! 698: !(at_state.flags & AT_ST_RT_CHANGED)) { ! 699: iocbp->ioc_count = 0; ! 700: ioc_ack(0, m, gref); ! 701: break; ! 702: } ! 703: ! 704: mo=(gbuf_t*)NULL; ! 705: tabsize = getRtmpTableSize(); ! 706: ! 707: /* retrieve table into multiple gbufs */ ! 708: for (i =0; i<tabsize; i+=j) { ! 709: j = tabsize - i > ! 710: MAX_RTMP ? MAX_RTMP : tabsize - i; ! 711: size = j < MAX_RTMP ? sizeof(RT_entry)*j : MAX_RTMP_BYTES; ! 712: if ((mn = gbuf_alloc(size, PRI_MED)) == NULL) { ! 713: if (gbuf_cont(m)) ! 714: gbuf_freem(gbuf_cont(m)); ! 715: ioc_ack(ENOBUFS, m, gref); ! 716: break; ! 717: } ! 718: if (!mo) { /* if first new one */ ! 719: mt = mn; ! 720: total = size; ! 721: } ! 722: else { ! 723: gbuf_cont(mo) = mn; ! 724: total += size; ! 725: } ! 726: mo = mn; ! 727: getRtmpTable((RT_entry*)gbuf_rptr(mn),i,j); ! 728: gbuf_wset(mn,size); ! 729: } ! 730: if ((gbuf_cont(m) = gbuf_alloc(sizeof(int), PRI_MED)) == NULL) { ! 731: if (mt) ! 732: gbuf_freem(mt); ! 733: iocbp->ioc_count = 0; ! 734: ioc_ack(ENOBUFS, m, gref); ! 735: break; ! 736: } ! 737: if (!tabsize) ! 738: total = 0; ! 739: *(int*)gbuf_rptr(gbuf_cont(m)) = total; /* return table size */ ! 740: gbuf_wset(gbuf_cont(m),sizeof(int)); ! 741: iocbp->ioc_count = sizeof(int); ! 742: ioc_ack(0, m, gref); ! 743: if (tabsize) ! 744: atalk_putnext(gref,mt); /* send up table */ ! 745: at_state.flags &= ~AT_ST_RT_CHANGED; ! 746: break; ! 747: ! 748: case LAP_IOC_SNMP_GET_NBP: ! 749: #ifdef APPLETALK_DEBUG ! 750: kprintf("LAP_IOC_SNMP_GET_NBP\n"); ! 751: #endif ! 752: i = *(int *)gbuf_rptr(gbuf_cont(m)); ! 753: gbuf_freem(gbuf_cont(m)); ! 754: gbuf_cont(m) = NULL; ! 755: if (!(at_state.flags & AT_ST_STARTED)) { ! 756: ioc_ack(ENOTREADY, m, gref); ! 757: break; ! 758: } ! 759: if (i == UPDATE_IF_CHANGED && ! 760: !(at_state.flags & AT_ST_NBP_CHANGED)) { ! 761: iocbp->ioc_count = 0; ! 762: ioc_ack(0, m, gref); ! 763: dPrintf(D_M_ELAP_LOW, D_L_INFO, ! 764: ("elap_wput: nbp req denied, no change\n")); ! 765: break; ! 766: } ! 767: ! 768: mo=(gbuf_t*)NULL; ! 769: tabsize = getNbpTableSize(); ! 770: ! 771: /* retrieve table into multiple gbufs */ ! 772: for (i =0; i<tabsize; i+=j) { ! 773: j = tabsize - i > ! 774: MAX_NBP ? MAX_NBP : tabsize - i; ! 775: size = j < MAX_NBP ? sizeof(snmpNbpEntry_t)*j : MAX_NBP_BYTES; ! 776: if (!i) ! 777: size += SNMP_NBP_HEADER_SIZE; ! 778: if ((mn = gbuf_alloc(size, PRI_MED)) == NULL) { ! 779: if (gbuf_cont(m)) ! 780: gbuf_freem(gbuf_cont(m)); ! 781: ioc_ack(ENOBUFS, m, gref); ! 782: break; ! 783: } ! 784: if (!mo) { /* if first new one */ ! 785: mt = mn; ! 786: total = size; ! 787: nbp = (snmpNbpTable_t*)gbuf_rptr(mn); ! 788: nbp->nbpt_entries = tabsize; ! 789: nbp->nbpt_zone = ifID_home->ifZoneName; ! 790: getNbpTable(nbp->nbpt_table,i,j); ! 791: } ! 792: else { ! 793: gbuf_cont(mo) = mn; ! 794: total += size; ! 795: getNbpTable((snmpNbpEntry_t *)gbuf_rptr(mn),i,j); ! 796: } ! 797: mo = mn; ! 798: gbuf_wset(mn,size); ! 799: } ! 800: if ((gbuf_cont(m) = gbuf_alloc(sizeof(int), PRI_MED)) == NULL) { ! 801: if (mt) ! 802: gbuf_freem(mt); ! 803: iocbp->ioc_count = 0; ! 804: ioc_ack(ENOBUFS, m, gref); ! 805: break; ! 806: } ! 807: if (!tabsize) ! 808: total = 0; ! 809: *(int*)gbuf_rptr(gbuf_cont(m)) = total; /* return table size */ ! 810: gbuf_wset(gbuf_cont(m),sizeof(int)); ! 811: iocbp->ioc_count = sizeof(int); ! 812: ioc_ack(0, m, gref); ! 813: if (tabsize) ! 814: atalk_putnext(gref,mt); /* send up table */ ! 815: at_state.flags &= ~AT_ST_NBP_CHANGED; ! 816: break; ! 817: } ! 818: ! 819: case LAP_IOC_SET_LOCAL_ZONES: ! 820: { ! 821: int i; ! 822: #ifdef APPLETALK_DEBUG ! 823: kprintf("LAP_IOC_SET_LOCAL_ZONES\n"); ! 824: #endif ! 825: i = setLocalZones((at_nbptuple_t*)gbuf_rptr(gbuf_cont(m)), ! 826: gbuf_len(gbuf_cont(m))); ! 827: ioc_ack(i,m,gref); ! 828: } ! 829: break; ! 830: case LAP_IOC_GET_IF_NAMES: ! 831: #ifdef APPLETALK_DEBUG ! 832: kprintf("LAP_IOC_GET_IF_NAMES\n"); ! 833: #endif ! 834: if ((gbuf_cont(m) = gbuf_alloc(sizeof(if_name_t) * IF_TOTAL_MAX, ! 835: PRI_MED)) == NULL) { ! 836: ioc_ack(ENOBUFS, m, gref); ! 837: break; ! 838: } ! 839: getIfNames((if_name_t *)gbuf_rptr(gbuf_cont(m))); ! 840: gbuf_wset(gbuf_cont(m),sizeof(if_name_t) * IF_TOTAL_MAX); ! 841: iocbp->ioc_count = sizeof(if_name_t) * IF_TOTAL_MAX; ! 842: ioc_ack(0, m, gref); ! 843: break; ! 844: default: ! 845: #ifdef APPLETALK_DEBUG ! 846: kprintf("unknown ioctl %d\n", iocbp->ioc_cmd); ! 847: #endif ! 848: ioc_ack(ENOTTY, m, gref); ! 849: dPrintf(D_M_ELAP, D_L_WARNING, ! 850: ("elap_wput: unknown ioctl (%d)\n", iocbp->ioc_cmd)); ! 851: ! 852: if (elapp) ! 853: elapp->stats.unknown_mblks++; ! 854: break; ! 855: } ! 856: } ! 857: break; ! 858: ! 859: default: ! 860: gbuf_freem(m); ! 861: break; ! 862: } ! 863: ! 864: return 0; ! 865: } /* elap_wput */ ! 866: ! 867: ! 868: /* Called directly by ddp/zip. ! 869: */ ! 870: elap_dataput(m, elapp, addr_flag, addr) ! 871: register gbuf_t *m; ! 872: register at_ifaddr_t *elapp; ! 873: u_char addr_flag; ! 874: char *addr; ! 875: { ! 876: register int size; ! 877: int error; ! 878: extern int zip_type_packet(); ! 879: struct etalk_addr dest_addr; ! 880: struct atalk_addr dest_at_addr; ! 881: extern gbuf_t *growmsg(); ! 882: int loop = TRUE; ! 883: /* flag to aarp to loopback (default) */ ! 884: ! 885: /* the incoming frame is of the form {flag, address, ddp...} ! 886: * where "flag" indicates whether the address is an 802.3 ! 887: * (link) address, or an appletalk address. If it's an ! 888: * 802.3 address, the packet can just go out to the network ! 889: * through PAT, if it's an appletalk address, AT->802.3 address ! 890: * resolution needs to be done. ! 891: * If 802.3 address is known, strip off the flag and 802.3 ! 892: * address, and prepend 802.2 and 802.3 headers. ! 893: */ ! 894: ! 895: if (addr == NULL) { ! 896: addr_flag = *(u_char *)gbuf_rptr(m); ! 897: gbuf_rinc(m,1); ! 898: } ! 899: ! 900: switch (addr_flag) { ! 901: case AT_ADDR_NO_LOOP : ! 902: loop = FALSE; ! 903: /* pass thru */ ! 904: case AT_ADDR : ! 905: if (addr == NULL) { ! 906: dest_at_addr = *(struct atalk_addr *)gbuf_rptr(m); ! 907: gbuf_rinc(m,sizeof(struct atalk_addr)); ! 908: } else ! 909: dest_at_addr = *(struct atalk_addr *)addr; ! 910: break; ! 911: case ET_ADDR : ! 912: if (addr == NULL) { ! 913: dest_addr = *(struct etalk_addr *)gbuf_rptr(m); ! 914: gbuf_rinc(m,sizeof(struct etalk_addr)); ! 915: } else ! 916: dest_addr = *(struct etalk_addr *)addr; ! 917: break; ! 918: default : ! 919: gbuf_freel(m); /* unknown address type, chuck it */ ! 920: return(EINVAL); ! 921: } ! 922: ! 923: m = gbuf_strip(m); ! 924: ! 925: /* At this point, rptr points to ddp header for sure */ ! 926: if (elapp->ifState == LAP_OFFLINE) { ! 927: gbuf_freel(m); ! 928: return(ENETDOWN); ! 929: } ! 930: ! 931: if (elapp->ifState == LAP_ONLINE_FOR_ZIP) { ! 932: /* see if this is a ZIP packet that we need ! 933: * to let through even though network is ! 934: * not yet alive!! ! 935: */ ! 936: if (zip_type_packet(m) == 0) { ! 937: gbuf_freel(m); ! 938: return(ENETDOWN); ! 939: } ! 940: } ! 941: ! 942: elapp->stats.xmit_packets++; ! 943: size = gbuf_msgsize(m); ! 944: elapp->stats.xmit_bytes += size; ! 945: snmpStats.dd_outLong++; ! 946: ! 947: switch (addr_flag) { ! 948: case AT_ADDR_NO_LOOP : ! 949: case AT_ADDR : ! 950: /* ! 951: * we don't want elap to be looking into ddp header, so ! 952: * it doesn't know net#, consequently can't do ! 953: * AMT_LOOKUP. That task left to aarp now. ! 954: */ ! 955: error = aarp_send_data(m,elapp,&dest_at_addr, loop); ! 956: break; ! 957: case ET_ADDR : ! 958: error = pat_output(elapp, m, &dest_addr, 0); ! 959: break; ! 960: } ! 961: return (error); ! 962: } /* elap_dataput */ ! 963: ! 964: /************************************************************************ ! 965: * elap_online() ! 966: * ! 967: ************************************************************************/ ! 968: ! 969: static int elap_online1(elapp) ! 970: at_ifaddr_t *elapp; ! 971: { ! 972: int errno; ! 973: ! 974: dPrintf(D_M_ELAP, D_L_STARTUP_INFO, ("elap_online:%s elapp:0x%x\n", ! 975: (elapp->ifName) ? &elapp->ifName[0] : "NULL interface", (u_int) elapp)); ! 976: if (elapp->ifState != LAP_OFFLINE) ! 977: return (EALREADY); ! 978: ! 979: at_state.flags |= AT_ST_IF_CHANGED; ! 980: ! 981: if (elapp->flags & ELAP_CFG_HOME) /* tell ddp_add_if if this is home */ ! 982: elapp->ifFlags |= AT_IFF_DEFAULT; ! 983: ! 984: /* Get DDP started */ ! 985: if ((errno = ddp_add_if(elapp))) ! 986: return(errno); ! 987: ! 988: /* set up multicast address for cable-wide broadcasts */ ! 989: (void)at_reg_mcast(elapp, (caddr_t)&elapp->cable_multicast_addr); ! 990: ! 991: elapp->startup_inprogress = TRUE; ! 992: if (! (elapp->startup_error = re_aarp(elapp))) ! 993: (void)tsleep(&elapp->startup_inprogress, PSOCK | PCATCH, ! 994: "elap_online1", 0); ! 995: ! 996: /* then later, after some timeouts AARPwakeup() is called */ ! 997: ! 998: return(elapp->startup_error); ! 999: } /* elap_online1 */ ! 1000: ! 1001: static int re_aarp(elapp) ! 1002: at_ifaddr_t *elapp; ! 1003: { ! 1004: int errno; ! 1005: ! 1006: /* We now call aarp_init() to assign an appletalk node addr */ ! 1007: errno = aarp_init1(elapp); ! 1008: /* aarp_init1() returns either -1 or ENOTREADY */ ! 1009: if (errno == ENOTREADY) ! 1010: return(0); ! 1011: else { ! 1012: dPrintf(D_M_ELAP, D_L_STATE_CHG, ! 1013: ("elap_online aarp_init for %s\n", elapp->ifName)); ! 1014: (void)at_unreg_mcast(elapp, (caddr_t)&elapp->cable_multicast_addr); ! 1015: ddp_rem_if(elapp); ! 1016: elapp->ifState = LAP_OFFLINE; ! 1017: return(EADDRNOTAVAIL); ! 1018: } ! 1019: } ! 1020: ! 1021: /* called from AARPwakeup */ ! 1022: static void elap_online2(elapp) ! 1023: at_ifaddr_t *elapp; ! 1024: { ! 1025: if (MULTIPORT_MODE) { ! 1026: dPrintf(D_M_ELAP,D_L_STARTUP_INFO, ! 1027: ("elap_online: re_aarp, we know it's a router...\n")); ! 1028: ! 1029: if (elapp->flags & ELAP_CFG_SEED) { ! 1030: /* add route table entry (zones to be added later) */ ! 1031: dPrintf(D_M_ELAP, D_L_STARTUP_INFO, ! 1032: ("elap_online: rt_insert Cable %d-%d port =%d as SEED\n", ! 1033: elapp->ifThisCableStart, elapp->ifThisCableEnd, elapp->ifPort)); ! 1034: rt_insert(elapp->ifThisCableEnd, ! 1035: elapp->ifThisCableStart, ! 1036: 0,0,0, ! 1037: elapp->ifPort, ! 1038: RTE_STATE_PERMANENT | RTE_STATE_ZKNOWN | RTE_STATE_GOOD ! 1039: ); ! 1040: /* LD 081694: set the RTR_SEED_PORT flag for seed ports */ ! 1041: elapp->ifFlags |= RTR_SEED_PORT; ! 1042: } ! 1043: else ! 1044: dPrintf(D_M_ELAP,D_L_STARTUP_INFO, ! 1045: ("elap_online: it's a router, but non seed\n")); ! 1046: } ! 1047: ! 1048: if (elapp->flags & ELAP_CFG_ZONELESS) { ! 1049: /* ELAP_CFG_ZONELESS tells us that it is a router or in ! 1050: multihome mode, so we don't want to do the GetNetInfo ! 1051: exchange with the router. */ ! 1052: ! 1053: elapp->ifState = LAP_ONLINE_ZONELESS; ! 1054: elapp->startup_inprogress = FALSE; ! 1055: thread_wakeup(&elapp->startup_inprogress); ! 1056: dPrintf(D_M_ELAP, D_L_STARTUP_INFO, ("elap_online: ack 3\n")); ! 1057: return; ! 1058: } ! 1059: ! 1060: /* if we don't already have a zone and a multicast address */ ! 1061: if (*(int *)&elapp->ZoneMcastAddr == 0 || elapp->ifZoneName.len == 0) { ! 1062: /* hzonehash is a global containing the nbp hash for the startup_zone */ ! 1063: sethzonehash(elapp); ! 1064: ! 1065: /* Get ZIP rolling to get zone multicast address, etc. */ ! 1066: elapp->ifState = LAP_ONLINE_FOR_ZIP; ! 1067: (void)zip_control(elapp, ZIP_ONLINE); ! 1068: /* zip_control (w. control == ZIP_ONLINE) always returns ENOTREADY */ ! 1069: ! 1070: /* later, after some timeouts ZIPwakeup() is called. */ ! 1071: } else { ! 1072: /* otherwise, we have the zone and the multicast already, ! 1073: so don't bother with another ZIP GetNetInfo request */ ! 1074: ZIPwakeup(elapp, 0); ! 1075: } ! 1076: } /* elap_online2 */ ! 1077: ! 1078: /* called from rtmp_router_start */ ! 1079: int elap_online3(elapp) ! 1080: at_ifaddr_t *elapp; ! 1081: { ! 1082: elapp->startup_inprogress = TRUE; ! 1083: ! 1084: /* just reset the net range */ ! 1085: elapp->initial_addr.s_net = 0; ! 1086: elapp->initial_addr.s_node = 0; ! 1087: dPrintf(D_M_ELAP_LOW, D_L_STARTUP_INFO, ! 1088: ("elap_online: goto re_aarp port=%d\n", elapp->ifPort)); ! 1089: ! 1090: if ((elapp->startup_error = re_aarp(elapp))) ! 1091: return(elapp->startup_error); ! 1092: ! 1093: /* then later, after some timeouts AARPwakeup() is called */ ! 1094: ! 1095: (void)tsleep(&elapp->startup_inprogress, PSOCK | PCATCH, ! 1096: "elap_online3", 0); ! 1097: return(elapp->startup_error); ! 1098: } /* elap_online3 */ ! 1099: ! 1100: /**************************************************************************** ! 1101: * elap_offline() ! 1102: * ! 1103: ****************************************************************************/ ! 1104: ! 1105: void elap_offline(elapp) ! 1106: register at_ifaddr_t *elapp; ! 1107: ! 1108: { ! 1109: void zip_sched_getnetinfo(); /* forward reference */ ! 1110: int errno; ! 1111: int s; ! 1112: ! 1113: dPrintf(D_M_ELAP, D_L_SHUTDN_INFO, ("elap_offline:%s\n", elapp->ifName)); ! 1114: if (elapp->ifState != LAP_OFFLINE) { ! 1115: ! 1116: /* Since AppleTalk is going away, remove the cable ! 1117: * multicast address and turn the interface off so that all ! 1118: * AppleTalk packets are dropped in the driver itself. ! 1119: * Get rid of the zone multicast address prior to going Offline. ! 1120: */ ! 1121: (void)at_unreg_mcast(elapp, (caddr_t)&elapp->ZoneMcastAddr); ! 1122: (void)at_unreg_mcast(elapp, (caddr_t)&elapp->cable_multicast_addr); ! 1123: elapp->ifState = LAP_OFFLINE; ! 1124: ! 1125: ATDISABLE(s, ddpinp_lock); ! 1126: if (MULTIPORT_MODE) ! 1127: RT_DELETE(elapp->ifThisCableEnd, ! 1128: elapp->ifThisCableStart); ! 1129: ATENABLE(s, ddpinp_lock); ! 1130: ! 1131: /* make sure no zip timeouts are left running */ ! 1132: untimeout(zip_sched_getnetinfo, elapp); ! 1133: } ! 1134: ddp_rem_if(elapp); ! 1135: } /* elap_offline */ ! 1136: ! 1137: /* called only in router mode */ ! 1138: static int set_zones(ifz) ! 1139: if_zone_info_t *ifz; ! 1140: ! 1141: /* 1. adds zone to table ! 1142: 2. looks up each route entry from zone I/F bitmap ! 1143: 3. sets zone bit in each route entry ! 1144: ! 1145: returns 0 if successful ! 1146: -1 if error occurred ! 1147: */ ! 1148: { ! 1149: int type, iftype, i; ! 1150: at_ifaddr_t *ifID; ! 1151: short zno; ! 1152: RT_entry *rte; ! 1153: ! 1154: zno = zt_add_zone(ifz->zone_name.str, ifz->zone_name.len); ! 1155: ! 1156: if (zno == ZT_MAXEDOUT) { ! 1157: dPrintf(D_M_ELAP, D_L_ERROR, ("set_zones: error: table full\n")); ! 1158: return(-1); ! 1159: } ! 1160: if (ifz->zone_home) { ! 1161: ifID_home->ifZoneName = ifz->zone_name; ! 1162: ifID_home->ifDefZone = zno; ! 1163: } ! 1164: ! 1165: for (iftype=0; iftype< IF_TYPENO_CNT; iftype++) { ! 1166: type = if_types[iftype].iftype; ! 1167: for (i=0; i<IF_TOTAL_MAX; i++) { ! 1168: if (ifz->zone_ifs[iftype] & 1<<i) { ! 1169: TAILQ_FOREACH(ifID, &at_ifQueueHd, aa_link) { ! 1170: if (ifID->aa_ifp && ! 1171: ((ifID->aa_ifp)->if_type == type) && ! 1172: ((ifID->aa_ifp)->if_unit == i)) ! 1173: break; ! 1174: } ! 1175: if (ifID) { ! 1176: rte = rt_blookup(ifID->ifThisCableEnd); ! 1177: if (!rte) { ! 1178: dPrintf(D_M_ELAP, D_L_ERROR, ! 1179: ("set_zones: error: can't find route\n")); ! 1180: } ! 1181: zt_set_zmap(zno, rte->ZoneBitMap); ! 1182: ! 1183: /* if first zone for this I/F, make default */ ! 1184: if (!ifID->ifDefZone) ! 1185: ifID->ifDefZone = zno; ! 1186: } ! 1187: } ! 1188: } ! 1189: } ! 1190: return(0); ! 1191: } ! 1192: ! 1193: static void add_route(rt) ! 1194: RT_entry *rt; ! 1195: ! 1196: /* support ioctl to manually add routes to table. ! 1197: this is really only for testing ! 1198: */ ! 1199: { ! 1200: rt_insert( rt->NetStop, rt->NetStart, rt->NextIRNet, ! 1201: rt->NextIRNode, rt->NetDist, rt->NetPort, ! 1202: rt->EntryState); ! 1203: dPrintf(D_M_ELAP, D_L_STARTUP_INFO, ("adding route: %ud:%ud dist:%ud\n", ! 1204: rt->NetStart, rt->NetStop,rt->NetDist)); ! 1205: } ! 1206: ! 1207: /* ! 1208: * ddp_start() ! 1209: * ! 1210: * Initialization that takes place each time AppleTalk is restarted. ! 1211: * ! 1212: */ ! 1213: void ddp_start() ! 1214: { ! 1215: TAILQ_INIT(&at_ifQueueHd); ! 1216: TAILQ_INIT(&name_registry); ! 1217: bzero(at_interfaces, sizeof(at_interfaces)); ! 1218: bzero(ifID_table, sizeof(ifID_table)); ! 1219: bzero(&at_ddp_stats, sizeof(at_ddp_stats_t)); ! 1220: rtmp_init(); /* initialize trackedrouters */ ! 1221: ! 1222: add_ddp_handler(RTMP_SOCKET, rtmp_input); ! 1223: ifID_home = (at_ifaddr_t *)NULL; ! 1224: xpatcnt = 0; ! 1225: } ! 1226: ! 1227: void ddp_shutdown() ! 1228: { ! 1229: at_ifaddr_t *ifID; ! 1230: gref_t *gref; ! 1231: int i; ! 1232: ! 1233: if (MULTIPORT_MODE) { ! 1234: rtmp_shutdown(); ! 1235: /* free memory allocated for the rtmp/zip tables */ ! 1236: if (ZT_table) { ! 1237: FREE(ZT_table, M_RTABLE); ! 1238: ZT_table = (ZT_entry *)NULL; ! 1239: } ! 1240: if (RT_table) { ! 1241: FREE(RT_table, M_RTABLE); ! 1242: RT_table = (RT_entry *)NULL; ! 1243: } ! 1244: } ! 1245: ! 1246: at_state.flags = 0; /* make sure inits are done on restart */ ! 1247: ! 1248: /* from original ddp_shutdown() */ ! 1249: nbp_shutdown(); /* clear all known NVE */ ! 1250: routershutdown(); ! 1251: ddp_brt_shutdown(); ! 1252: ! 1253: /* Network is shutting down... send error messages up on each open ! 1254: * socket. From ddps_shutdown(). ! 1255: */ ! 1256: for (gref = ddp_head.atpcb_next; gref != &ddp_head; gref = gref->atpcb_next) ! 1257: atalk_notify(gref, ESHUTDOWN); ! 1258: ! 1259: if (adspInited) { ! 1260: CleanupGlobals(); ! 1261: adspInited = 0; ! 1262: } ! 1263: dPrintf(D_M_DDP, D_L_VERBOSE, ("DDP shutdown completed")); ! 1264: ! 1265: /* *** after an SIOCSIFADDR and before an AIOCSIFADDR, ! 1266: this is the only place to find the ifID *** */ ! 1267: for (i = 0; i < IF_TOTAL_MAX; i++) { ! 1268: ifID = &at_interfaces[i]; ! 1269: /* do LAP_IOC_OFFLINE processing */ ! 1270: elap_offline(ifID); ! 1271: } ! 1272: ddp_start(); ! 1273: } /* ddp_shutdown */ ! 1274: ! 1275: int routerStart(keP) ! 1276: at_kern_err_t *keP; ! 1277: { ! 1278: register at_ifaddr_t *ifID; ! 1279: int error; ! 1280: ! 1281: if (! ifID_home) ! 1282: return(EINVAL); ! 1283: ! 1284: /* ! 1285: * this will cause the ports to glean from the net the relevant ! 1286: * information before forwarding ! 1287: */ ! 1288: TAILQ_FOREACH(ifID, &at_ifQueueHd, aa_link) { ! 1289: dPrintf(D_M_ELAP, D_L_STARTUP_INFO, ! 1290: ("routerStart Port %d (%s) set to activating\n", ! 1291: ifID->ifPort, ifID->ifName)); ! 1292: ifID->ifRoutingState = PORT_ACTIVATING; ! 1293: ifID->ifFlags |= RTR_XNET_PORT; ! 1294: } ! 1295: ! 1296: /* ! 1297: * The next step is to check the information for each port before ! 1298: * declaring the ports up and forwarding ! 1299: */ ! 1300: dPrintf(D_M_ELAP, D_L_STARTUP_INFO, ! 1301: ("router_start: waiting 20 sec before starting up\n")); ! 1302: ! 1303: /* sleep for 20 seconds */ ! 1304: if ((error = ! 1305: /* *** eventually this will be the ifID for the interface ! 1306: being brought up in router mode *** */ ! 1307: tsleep(&ifID_home->startup_inprogress, ! 1308: PSOCK | PCATCH, "routerStart", 20 * SYS_HZ)) ! 1309: != EWOULDBLOCK) { ! 1310: /* ! 1311: if (!error) ! 1312: panic("routerStart: spurious interrupt"); ! 1313: */ ! 1314: return(error); ! 1315: } ! 1316: ! 1317: return(rtmp_router_start(keP)); ! 1318: /* was timeout(rtmp_router_start, 0, 20 * SYS_HZ); */ ! 1319: } /* routerStart */ ! 1320: ! 1321: void ZIPwakeup(elapp, ZipError) ! 1322: at_ifaddr_t *elapp; ! 1323: int ZipError; ! 1324: { ! 1325: int s, error = ZipError; ! 1326: ! 1327: ATDISABLE(s, ddpinp_lock); ! 1328: if ( (elapp != NULL) && elapp->startup_inprogress) { ! 1329: ATENABLE(s, ddpinp_lock); ! 1330: ! 1331: /* was ZIPContinue */ ! 1332: /* was elapp_online() with jump to ZIP_sleep */ ! 1333: ! 1334: /* instead of the goto ZIP_sleep ... */ ! 1335: switch (ZipError) { ! 1336: case 0 : /* success */ ! 1337: elapp->ifState = LAP_ONLINE; ! 1338: break; ! 1339: case ZIP_RE_AARP : ! 1340: /* instead of goto re_aarp; */ ! 1341: /* We now call aarp_init() to assign an ! 1342: appletalk node addr */ ! 1343: if ((elapp->startup_error = re_aarp(elapp))) { ! 1344: elapp->startup_inprogress = FALSE; ! 1345: thread_wakeup(&elapp->startup_inprogress); ! 1346: dPrintf(D_M_ELAP, D_L_STARTUP_INFO, ! 1347: ("elap_online: ack 2\n")); ! 1348: } ! 1349: break; ! 1350: default : ! 1351: break; ! 1352: } ! 1353: if (ZipError != ZIP_RE_AARP) { ! 1354: elapp->startup_error = error; ! 1355: elapp->startup_inprogress = FALSE; ! 1356: thread_wakeup(&elapp->startup_inprogress); ! 1357: dPrintf(D_M_ELAP, D_L_STARTUP_INFO, ! 1358: ("elap_online: ifZipError=%d\n", error)); ! 1359: } ! 1360: } else ! 1361: ATENABLE(s, ddpinp_lock); ! 1362: } /* ZIPwakeup */ ! 1363: ! 1364: void AARPwakeup(probe_cb) ! 1365: aarp_amt_t *probe_cb; ! 1366: { ! 1367: int s; ! 1368: int errno; ! 1369: at_ifaddr_t *elapp; ! 1370: ! 1371: ATDISABLE(s, arpinp_lock); ! 1372: elapp = probe_cb->elapp; ! 1373: if ( (elapp != NULL) && elapp->startup_inprogress ) { ! 1374: ATENABLE(s, arpinp_lock); ! 1375: ! 1376: /* was AARPContinue */ ! 1377: errno = aarp_init2(elapp); ! 1378: /* aarp_init2() returns either -1 or 0 */ ! 1379: if (errno != 0) { ! 1380: dPrintf(D_M_ELAP, D_L_STATE_CHG, ! 1381: ("elap_online aarp_init for %s\n", ! 1382: elapp->ifName)); ! 1383: (void)at_unreg_mcast(elapp, (caddr_t)&elapp->ZoneMcastAddr); ! 1384: (void)at_unreg_mcast(elapp, (caddr_t)&elapp->cable_multicast_addr); ! 1385: elapp->ifState = LAP_OFFLINE; ! 1386: ddp_rem_if(elapp); ! 1387: elapp->startup_error = EADDRNOTAVAIL; ! 1388: elapp->startup_inprogress = FALSE; ! 1389: thread_wakeup(&elapp->startup_inprogress); ! 1390: dPrintf(D_M_ELAP, D_L_STARTUP_INFO, ("elap_online: ack 2\n")); ! 1391: } else { ! 1392: dPrintf(D_M_ELAP,D_L_STARTUP_INFO, ! 1393: ("elap_online: aarp_init returns zero\n")); ! 1394: elap_online2(elapp); ! 1395: } ! 1396: } else ! 1397: ATENABLE(s, arpinp_lock); ! 1398: } /* AARPwakeup */ ! 1399: ! 1400: static void getIfNames(names) ! 1401: if_name_t *names; ! 1402: { ! 1403: int i; ! 1404: at_ifaddr_t *ifID; ! 1405: bzero(names,sizeof(if_name_t) * IF_TOTAL_MAX); ! 1406: for (i=0, ifID=ifID_table[0]; ifID; ifID = ifID_table[++i], names++) ! 1407: if(ifID) ! 1408: strncpy((char *)names,ifID->ifName,sizeof(*names)); ! 1409: ! 1410: return; ! 1411: } ! 1412: ! 1413: void ddp_bit_reverse(addr) ! 1414: unsigned char *addr; ! 1415: { ! 1416: static unsigned char reverse_data[] = { ! 1417: 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, ! 1418: 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, ! 1419: 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, ! 1420: 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, ! 1421: 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, ! 1422: 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, ! 1423: 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, ! 1424: 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, ! 1425: 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, ! 1426: 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, ! 1427: 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, ! 1428: 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, ! 1429: 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, ! 1430: 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, ! 1431: 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, ! 1432: 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, ! 1433: 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, ! 1434: 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, ! 1435: 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, ! 1436: 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, ! 1437: 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, ! 1438: 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, ! 1439: 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, ! 1440: 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, ! 1441: 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, ! 1442: 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, ! 1443: 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, ! 1444: 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, ! 1445: 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, ! 1446: 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, ! 1447: 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, ! 1448: 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff ! 1449: }; ! 1450: ! 1451: unsigned char k; ! 1452: ! 1453: for (k=0; k < 6; k++) ! 1454: addr[k] = reverse_data[addr[k]]; ! 1455: } ! 1456: ! 1457: static int elap_trackMcast(patp, func, addr) ! 1458: at_ifaddr_t *patp; ! 1459: int func; ! 1460: caddr_t addr; ! 1461: { ! 1462: int i, loc=-1; ! 1463: u_char c; ! 1464: switch(patp->aa_ifp->if_type) { ! 1465: case IFT_ETHER: ! 1466: case IFT_FDDI: ! 1467: /* set addr to point to unique part of addr */ ! 1468: c = addr[5]; ! 1469: ! 1470: /* first try to find match */ ! 1471: /* *** save just one byte of the multicast address? *** */ ! 1472: for (i=0; i< MAX_MCASTS; i++) ! 1473: if (c == patp->mcast[i]) { ! 1474: loc = i; ! 1475: break; ! 1476: } ! 1477: ! 1478: switch (func) { ! 1479: case MCAST_TRACK_DELETE: ! 1480: if (loc >= 0) ! 1481: patp->mcast[loc] = 0; ! 1482: ! 1483: break; ! 1484: case MCAST_TRACK_ADD: ! 1485: dPrintf(D_M_PAT_LOW, D_L_USR2, ("mctrack:add loc:%d\n", i)); ! 1486: if (loc >= 0) { ! 1487: dPrintf(D_M_PAT_LOW, D_L_USR2, ("mctrack:add, addr was there\n")); ! 1488: return(1); ! 1489: break; /* already there */ ! 1490: } ! 1491: for (i=0; i< MAX_MCASTS; i++) ! 1492: if (patp->mcast[i] == 0) { ! 1493: loc = i; ! 1494: break; ! 1495: } ! 1496: dPrintf(D_M_PAT_LOW, D_L_USR2, ("mctrack:add1 loc:%d\n", i)); ! 1497: if (loc >= 0) { ! 1498: patp->mcast[loc] = c; ! 1499: dPrintf(D_M_PAT_LOW, D_L_USR2, ("mctrack:add, adding(%x)\n", ! 1500: (*(int*)addr)&0xffffff)); ! 1501: } ! 1502: else { ! 1503: /*errno = ENOMEM; */ /*LD 5/7/97 nobody is using that */ ! 1504: return(-1); ! 1505: } ! 1506: break; ! 1507: case MCAST_TRACK_CHECK: ! 1508: if (loc >= 0) { ! 1509: dPrintf(D_M_PAT_LOW, D_L_USR2, ("mctrack:check, addr was there\n")); ! 1510: return(0); ! 1511: } ! 1512: else { ! 1513: dPrintf(D_M_PAT_LOW, D_L_USR2, ("mctrack:add, addr was NOT there\n")); ! 1514: return(-1); ! 1515: } ! 1516: ! 1517: default: ! 1518: /*errno = EINVAL;*/ /*LD 5/7/97 nobody is using that */ ! 1519: return(-1); ! 1520: } ! 1521: ! 1522: case IFT_ISO88025: /* token ring */ ! 1523: /* we would use the lowest byte of the addr argument as a value ! 1524: to shift left a 1 to form the mcast mask for TR. We'll do this ! 1525: when the time comes ! 1526: */ ! 1527: default: ! 1528: ; ! 1529: } ! 1530: return(0); ! 1531: } ! 1532: ! 1533: ! 1534: static getSnmpCfg(snmp) ! 1535: snmpCfg_t *snmp; ! 1536: { ! 1537: int i; ! 1538: at_ifaddr_t *elapp; ! 1539: snmpIfCfg_t *ifc; ! 1540: ! 1541: snmp->cfg_ifCnt = 0; ! 1542: ! 1543: bzero(snmp,sizeof(snmpCfg_t)); ! 1544: for (i=0, elapp=at_interfaces,ifc=snmp->cfg_ifCfg; ! 1545: i<IF_TOTAL_MAX; i++, elapp++, ifc++) { ! 1546: if (elapp->ifState != LAP_OFFLINE) { ! 1547: snmp->cfg_ifCnt++; ! 1548: strncpy(ifc->ifc_name,elapp->ifName, sizeof(ifc->ifc_name)); ! 1549: ifc->ifc_aarpSize = getAarpTableSize(i); ! 1550: ifc->ifc_addrSize = getPhysAddrSize(i); ! 1551: switch (elapp->aa_ifp->if_type) { ! 1552: case IFT_ETHER: ! 1553: ifc->ifc_type = SNMP_TYPE_ETHER2; ! 1554: break; ! 1555: case IFT_ISO88025: /* token ring */ ! 1556: ifc->ifc_type = SNMP_TYPE_TOKEN; ! 1557: break; ! 1558: case IFT_FDDI: ! 1559: default: ! 1560: ifc->ifc_type = SNMP_TYPE_OTHER; ! 1561: break; ! 1562: } ! 1563: ifc->ifc_start = elapp->ifThisCableStart; ! 1564: ifc->ifc_end = elapp->ifThisCableEnd; ! 1565: ifc->ifc_ddpAddr= elapp->ifThisNode; ! 1566: ifc->ifc_status = elapp->ifState == LAP_ONLINE ? 1 : 2; ! 1567: ifc->ifc_zoneName.len = 0; ! 1568: if (elapp->ifZoneName.len != 0) { ! 1569: ifc->ifc_zoneName = elapp->ifZoneName; ! 1570: } ! 1571: else if (elapp->ifDefZone) { ! 1572: ifc->ifc_zoneName = ZT_table[elapp->ifDefZone-1].Zone; ! 1573: } ! 1574: else /* temp, debug only */ ! 1575: ifc->ifc_zoneName = ZT_table[0].Zone; ! 1576: if (ROUTING_MODE) { ! 1577: if (elapp->ifFlags & RTR_SEED_PORT) { ! 1578: ifc->ifc_netCfg = SNMP_CFG_CONFIGURED; ! 1579: ifc->ifc_zoneCfg = SNMP_CFG_CONFIGURED; ! 1580: } ! 1581: else { ! 1582: ifc->ifc_netCfg = SNMP_CFG_GARNERED; ! 1583: ifc->ifc_zoneCfg = SNMP_CFG_GARNERED; ! 1584: } ! 1585: } ! 1586: else { /* single-port mode */ ! 1587: if (elapp->ifRouterState == ROUTER_AROUND) { ! 1588: ifc->ifc_netCfg = SNMP_CFG_GARNERED; ! 1589: } ! 1590: else { ! 1591: ifc->ifc_netCfg = SNMP_CFG_GUESSED; ! 1592: ifc->ifc_zoneCfg = SNMP_CFG_UNCONFIG; ! 1593: } ! 1594: } ! 1595: } ! 1596: } ! 1597: snmp->cfg_flags = at_state.flags; ! 1598: ! 1599: ! 1600: return(0); ! 1601: } ! 1602: ! 1603: int at_reg_mcast(ifID, data) ! 1604: at_ifaddr_t *ifID; ! 1605: caddr_t data; ! 1606: { ! 1607: struct ifnet *nddp = ifID->aa_ifp; ! 1608: struct ifreq request; ! 1609: ! 1610: if (!nddp) { ! 1611: dPrintf(D_M_PAT, D_L_STARTUP, ("pat_mcast: BAD ndpp\n")); ! 1612: return(-1); ! 1613: } ! 1614: if (elap_trackMcast(ifID, MCAST_TRACK_ADD, data) == 1) ! 1615: return(0); ! 1616: ! 1617: /* this is for ether_output */ ! 1618: request.ifr_addr.sa_family = AF_UNSPEC; ! 1619: request.ifr_addr.sa_len = 2 + sizeof(struct etalk_addr); ! 1620: bcopy (data, &request.ifr_addr.sa_data[0], sizeof(struct etalk_addr)); ! 1621: ! 1622: /*### LD Direct access to the ifp->if_ioctl function */ ! 1623: ! 1624: dPrintf(D_M_PAT, D_L_STARTUP, ! 1625: ("pat_mcast: adding multicast %08x%04x ifID:0x%x\n", ! 1626: *(unsigned*)data, (*(unsigned *)(data+2))&0x0000ffff, ! 1627: (unsigned)ifID)); ! 1628: ! 1629: /* ! 1630: if ((*nddp->if_ioctl)(nddp, SIOCADDMULTI, (caddr_t)&request)) ! 1631: return(-1); ! 1632: */ ! 1633: if (if_addmulti(nddp, &request.ifr_addr, 0)) ! 1634: return -1; ! 1635: else ! 1636: return 0; ! 1637: ! 1638: } ! 1639: ! 1640: int at_unreg_mcast(ifID, data) ! 1641: at_ifaddr_t *ifID; ! 1642: caddr_t data; ! 1643: { ! 1644: struct ifnet *nddp = ifID->aa_ifp; ! 1645: struct ifreq request; ! 1646: ! 1647: ! 1648: if (*(int *)data) { ! 1649: if (!nddp) { ! 1650: dPrintf(D_M_PAT, D_L_STARTUP, ("pat_mcast: BAD ndpp\n")); ! 1651: return(-1); ! 1652: } ! 1653: ! 1654: elap_trackMcast(ifID, MCAST_TRACK_DELETE, data); ! 1655: ! 1656: /* this is for ether_output */ ! 1657: request.ifr_addr.sa_family = AF_UNSPEC; ! 1658: request.ifr_addr.sa_len = 2 + sizeof(struct etalk_addr); ! 1659: bcopy (data, &request.ifr_addr.sa_data[0], sizeof(struct etalk_addr)); ! 1660: ! 1661: /*### LD Direct access to the ifp->if_ioctl function */ ! 1662: dPrintf(D_M_PAT, D_L_STARTUP, ! 1663: ("pat_mcast: deleting multicast %08x%04x ifID:0x%x\n", ! 1664: *(unsigned*)data, (*(unsigned *)(data+2))&0x0000ffff, ! 1665: (unsigned)ifID)); ! 1666: /* ! 1667: if ((*nddp->if_ioctl)(nddp, SIOCDELMULTI, (caddr_t)&request)) ! 1668: return(-1); ! 1669: */ ! 1670: bzero(data, sizeof(struct etalk_addr)); ! 1671: } ! 1672: ! 1673: if (if_delmulti(nddp, &request.ifr_addr)) ! 1674: return -1; ! 1675: else ! 1676: return 0; ! 1677: } ! 1678: #ifdef NOT_YET ! 1679: /* *** at_reg_mcast() and at_unreg_mcast() should be replaced as soon as the ! 1680: new code to allow an AF_LINK address family multicast to be (un)registered ! 1681: using the SIOCADDMULTI / SIOCDELMULTI ioctls has been completed. ! 1682: ! 1683: The issue is that the "struct sockaddr_dl" needed for the AF_LINK does not ! 1684: fit in the "struct ifreq" that is used for these ioctls, and we do not want ! 1685: Blue/Classic, which currently uses AF_UNSPEC, to use a different address ! 1686: family multicast address than Mac OS X uses. ! 1687: *** */ ! 1688: ! 1689: int at_reg_mcast(ifID, data) ! 1690: at_ifaddr_t *ifID; ! 1691: caddr_t data; ! 1692: { ! 1693: struct ifnet *nddp = ifID->aa_ifp; ! 1694: struct sockaddr_dl sdl; ! 1695: ! 1696: if (*(int *)data) { ! 1697: if (!nddp) { ! 1698: dPrintf(D_M_PAT, D_L_STARTUP, ("pat_mcast: BAD ndpp\n")); ! 1699: return(-1); ! 1700: } ! 1701: if (elap_trackMcast(ifID, MCAST_TRACK_ADD, data) == 1) ! 1702: return(0); ! 1703: ! 1704: sdl.sdl_len = sizeof(struct sockaddr_dl); ! 1705: sdl.sdl_family = AF_LINK; ! 1706: sdl.sdl_index = 0; ! 1707: sdl.sdl_type = nddp->if_type; ! 1708: sdl.sdl_alen = nddp->if_addrlen; ! 1709: sdl.sdl_slen = 0; ! 1710: sdl.sdl_nlen = sprintf(sdl.sdl_data, "%s%d", ! 1711: nddp->if_name , nddp->if_unit); ! 1712: bcopy(data, LLADDR(&sdl), sdl.sdl_alen); ! 1713: ! 1714: dPrintf(D_M_PAT, D_L_STARTUP, ! 1715: ("pat_mcast: adding multicast %08x%04x ifID:0x%x\n", ! 1716: *(unsigned*)data, (*(unsigned *)(data+2))&0x0000ffff, ! 1717: (unsigned)ifID)); ! 1718: ! 1719: if (if_addmulti(nddp, (struct sockaddr *)&sdl, 0)) ! 1720: return -1; ! 1721: } ! 1722: ! 1723: return 0; ! 1724: } ! 1725: ! 1726: int at_unreg_mcast(ifID, data) ! 1727: at_ifaddr_t *ifID; ! 1728: caddr_t data; ! 1729: { ! 1730: struct ifnet *nddp = ifID->aa_ifp; ! 1731: struct sockaddr_dl sdl; ! 1732: ! 1733: if (*(int *)data) { ! 1734: if (!nddp) { ! 1735: dPrintf(D_M_PAT, D_L_STARTUP, ("pat_mcast: BAD ndpp\n")); ! 1736: return(-1); ! 1737: } ! 1738: ! 1739: elap_trackMcast(ifID, MCAST_TRACK_DELETE, data); ! 1740: ! 1741: sdl.sdl_len = sizeof(struct sockaddr_dl); ! 1742: sdl.sdl_family = AF_LINK; ! 1743: sdl.sdl_index = 0; ! 1744: sdl.sdl_type = nddp->if_type; ! 1745: sdl.sdl_alen = nddp->if_addrlen; ! 1746: sdl.sdl_slen = 0; ! 1747: sdl.sdl_nlen = sprintf(sdl.sdl_data, "%s%d", ! 1748: nddp->if_name , nddp->if_unit); ! 1749: ! 1750: dPrintf(D_M_PAT, D_L_STARTUP, ! 1751: ("pat_mcast: deleting multicast %08x%04x ifID:0x%x\n", ! 1752: *(unsigned*)data, (*(unsigned *)(data+2))&0x0000ffff, ! 1753: (unsigned)ifID)); ! 1754: bzero(data, ETHERNET_ADDR_LEN); ! 1755: ! 1756: if (if_delmulti(nddp, (struct sockaddr *)&sdl)) ! 1757: return(-1); ! 1758: } ! 1759: ! 1760: return 0; ! 1761: } ! 1762: ! 1763: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.