|
|
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) 1988, 1989, 1993-1998 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: ! 36: /* at_elap.c: 2.0, 1.29; 10/4/93; Apple Computer, Inc. */ ! 37: ! 38: /* This is the file which implements all the streams driver ! 39: * functionality required for EtherTalk. ! 40: */ ! 41: ! 42: ! 43: ! 44: #define RESOLVE_DBG /* for debug.h global resolution */ ! 45: #include <sysglue.h> ! 46: #include <sys/malloc.h> ! 47: #include <at/appletalk.h> ! 48: #include <at/ddp.h> ! 49: #include <at/elap.h> ! 50: #include <lap.h> /* for at_statep */ ! 51: #include <routing_tables.h> /* rtmp+zip table structs */ ! 52: ! 53: #include <at/at_lap.h> ! 54: #include <at_pat.h> ! 55: #include <at_elap.h> ! 56: #include <at_aarp.h> ! 57: #include <at_ddp.h> ! 58: #include <at_zip.h> ! 59: #include <nbp.h> ! 60: #include <at_snmp.h> ! 61: #include <atlog.h> ! 62: ! 63: #ifndef NULL ! 64: #define NULL 0 ! 65: #endif ! 66: ! 67: /* globals */ ! 68: ! 69: elap_specifics_t elap_specifics[IF_TYPE_ET_MAX]; ! 70: at_state_t at_state; /* global state of AT network */ ! 71: at_state_t *at_statep = &at_state; ! 72: char *if_types[] = { IF_TYPE_1, IF_TYPE_2, IF_TYPE_3, IF_TYPE_4, IF_TYPE_5}; ! 73: gref_t *shutdown_gref = NULL; ! 74: gref_t *at_qioctl = NULL; ! 75: gbuf_t *at_mioctl = NULL; ! 76: gbuf_t *at_delay_m = NULL; ! 77: gref_t *at_delay_gref = NULL; ! 78: int (*at_delay_func)() = NULL; ! 79: int at_delay_errno = 0; ! 80: char at_delay_flag = 0; ! 81: char at_ddp_debug; ! 82: int RoutingMix= 2000; /* default for nbr of ppsec */ ! 83: snmpFlags_t snmpFlags; ! 84: ! 85: void ddp_bit_reverse(); ! 86: ! 87: /* snmp defines */ ! 88: #define MAX_BUFSIZE 8192 ! 89: #define MAX_RTMP (MAX_BUFSIZE/sizeof(RT_entry)-1) ! 90: #define MAX_NBP \ ! 91: ((MAX_BUFSIZE - SNMP_NBP_HEADER_SIZE)/sizeof(snmpNbpEntry_t)-1) ! 92: #define MAX_NBP_BYTES (MAX_NBP * sizeof(snmpNbpEntry_t)) ! 93: #define MAX_ZIP (MAX_BUFSIZE/sizeof(ZT_entry)-1) ! 94: #define MAX_RTMP_BYTES (MAX_RTMP * sizeof(RT_entry)) ! 95: #define MAX_ZIP_BYTES (MAX_ZIP * sizeof(ZT_entry)) ! 96: ! 97: /* externs */ ! 98: extern at_if_t *ifID_table[]; ! 99: extern at_if_t at_ifQueueHead; ! 100: extern int xpatcnt; ! 101: extern snmpStats_t snmpStats; ! 102: extern atlock_t ddpinp_lock; ! 103: extern atlock_t arpinp_lock; ! 104: extern short appletalk_inited; ! 105: pat_unit_t pat_units[IF_TOTAL_MAX]; ! 106: ! 107: ! 108: /* protos */ ! 109: extern snmpAarpEnt_t * getAarp(int *); ! 110: extern RT_entry *rt_getNextRoute(int); ! 111: extern ZT_entryno *zt_getNextZone(int); ! 112: extern int setLocalZones(at_nbptuple_t * , int); ! 113: extern int getRTRLocalZone(if_zone_t *); ! 114: extern at_nvestr_t *getDefZone(int); ! 115: StaticProc void getIfNames(if_name_t *); ! 116: StaticProc void get_ifs_stat(); ! 117: StaticProc void add_route(); ! 118: StaticProc int set_zones(); ! 119: StaticProc void pat_init(); ! 120: StaticProc void dodefer(); ! 121: StaticProc int domcast(); ! 122: StaticProc int elap_offline(); ! 123: StaticProc void routerShutdown(); ! 124: StaticProc void elap_hangup(); ! 125: static getSnmpCfg(); ! 126: /* temp globals, etc. */ ! 127: ! 128: #define NDEFERS 20 ! 129: /* *** static int ndefers = NDEFERS; not currently used *** */ ! 130: static int deferno = 0; ! 131: static int gotIfs = 0; ! 132: ! 133: #define ZT_BAD ZT_MAXENTRY +1 ! 134: ! 135: ! 136: ! 137: /*********************************************************************** ! 138: * lap_close() ! 139: * ! 140: **********************************************************************/ ! 141: int lap_close(gref) ! 142: gref_t *gref; ! 143: { ! 144: #ifdef CHECK_DDPR_FLAG ! 145: extern int ddprunning_flag; ! 146: #endif ! 147: int s; ! 148: ! 149: ddp_close(gref); /* for 2225395 */ ! 150: ATDISABLE(s, ddpinp_lock); ! 151: if (gref == shutdown_gref) { ! 152: #ifdef CHECK_DDPR_FLAG ! 153: while (ddprunning_flag) ! 154: ; ! 155: #endif ! 156: if (at_mioctl != NULL) { ! 157: gbuf_freem(at_mioctl); ! 158: at_mioctl = NULL; ! 159: } ! 160: shutdown_gref = NULL; ! 161: xpatcnt = 0; ! 162: at_statep->flags = 0; ! 163: } ! 164: ATENABLE(s, ddpinp_lock); ! 165: ! 166: return 0; ! 167: } ! 168: ! 169: StaticProc ! 170: validate_msg_size(m, gref, elapp) ! 171: register gbuf_t *m; ! 172: gref_t *gref; ! 173: elap_specifics_t **elapp; ! 174: ! 175: /* checks ioctl message type for minimum expected message size & ! 176: sends error back if size invalid ! 177: */ ! 178: { ! 179: register ioc_t *iocbp; ! 180: register at_elap_cfg_t *cfgp; ! 181: int i, size = 1; ! 182: int if_specific = FALSE; ! 183: ! 184: *elapp = NULL; ! 185: iocbp = (ioc_t *) gbuf_rptr(m); ! 186: ! 187: switch (iocbp->ioc_cmd) { ! 188: case LAP_IOC_ONLINE: ! 189: case LAP_IOC_OFFLINE: ! 190: case ELAP_IOC_SWITCHZONE: ! 191: case ELAP_IOC_SET_CFG: ! 192: case ELAP_IOC_SET_ZONE : ! 193: size = sizeof(at_elap_cfg_t); ! 194: if_specific = TRUE; ! 195: break; ! 196: case LAP_IOC_ADD_ROUTE: ! 197: size = sizeof(RT_entry); ! 198: break; ! 199: case LAP_IOC_ADD_ZONE: ! 200: size = sizeof(if_zone_info_t); ! 201: break; ! 202: case LAP_IOC_GET_ROUTE: ! 203: size = sizeof(RT_entry); ! 204: break; ! 205: case LAP_IOC_GET_ZONE: ! 206: size = sizeof(ZT_entryno); ! 207: break; ! 208: case LAP_IOC_GET_IFID: ! 209: size = sizeof(at_if_name_t); ! 210: break; ! 211: case LAP_IOC_SET_DBG: ! 212: size = sizeof(dbgBits_t); ! 213: break; ! 214: case LAP_IOC_SNMP_GET_CFG: ! 215: case LAP_IOC_SNMP_GET_AARP: ! 216: case LAP_IOC_SNMP_GET_ZIP: ! 217: case LAP_IOC_SNMP_GET_RTMP: ! 218: case LAP_IOC_GET_DEFAULT_ZONE: ! 219: case LAP_IOC_SNMP_GET_NBP: ! 220: size = sizeof(int); ! 221: break; ! 222: case LAP_IOC_SET_MIX: ! 223: size = sizeof(short); ! 224: break; ! 225: case LAP_IOC_GET_LOCAL_ZONE: ! 226: size = sizeof(if_zone_t); ! 227: break; ! 228: case LAP_IOC_IS_ZONE_LOCAL: ! 229: size = sizeof(at_nvestr_t); ! 230: break; ! 231: case LAP_IOC_CHECK_STATE: ! 232: size = 1; ! 233: break; ! 234: case LAP_IOC_SET_DEFAULT_ZONES: ! 235: size = sizeof(int) * IF_TOTAL_MAX; ! 236: break; ! 237: ! 238: case ELAP_IOC_GET_STATS: ! 239: case ELAP_IOC_GET_CFG: ! 240: case LAP_IOC_GET_DBG: ! 241: case LAP_IOC_GET_IFS_STAT: ! 242: case LAP_IOC_ROUTER_START: ! 243: case LAP_IOC_ROUTER_SHUTDOWN: ! 244: case LAP_IOC_ROUTER_INIT: ! 245: case LAP_IOC_DO_DEFER: ! 246: case LAP_IOC_DO_DELAY: ! 247: case LAP_IOC_SHUT_DOWN: ! 248: case LAP_IOC_SNMP_GET_DDP: ! 249: case LAP_IOC_GET_MODE: ! 250: case LAP_IOC_GET_IF_NAMES: ! 251: size = 0; ! 252: break; ! 253: /* these ioctls send variable length data */ ! 254: case LAP_IOC_SET_LOCAL_ZONES: ! 255: size = -1; ! 256: break; ! 257: default: ! 258: dPrintf(D_M_ELAP, D_L_ERROR, ("elap_wput: unknown ioctl\n")); ! 259: goto error; ! 260: } ! 261: ! 262: if (size == 0) { /* a non-data ioctl */ ! 263: return(0); ! 264: } ! 265: ! 266: /* if I/F related, validate further */ ! 267: if (if_specific) { ! 268: /* get elapp from msg */ ! 269: int lap_id; ! 270: cfgp = (at_elap_cfg_t * ) gbuf_rptr(gbuf_cont(m)); ! 271: lap_id = pat_ID(cfgp->if_name); ! 272: if (lap_id < 0 || IF_ANY_MAX <= lap_id) { ! 273: ioc_ack(EINVAL, m, gref); ! 274: dPrintf(D_M_ELAP, D_L_ERROR, ("validate_msg:bad cmd (%x) for %s\n", ! 275: iocbp->ioc_cmd, cfgp->if_name)); ! 276: return(EINVAL); ! 277: } ! 278: *elapp = &elap_specifics[lap_id]; ! 279: } ! 280: ! 281: if (gbuf_cont(m) != NULL) { ! 282: i = gbuf_len(gbuf_cont(m)); ! 283: if (size == -1) ! 284: if (i >1) ! 285: return(0); ! 286: else ! 287: goto error; ! 288: } ! 289: if (iocbp->ioc_count < size || (gbuf_cont(m) == NULL) || i < size) { ! 290: dPrintf(D_M_ELAP, D_L_ERROR, ! 291: ("ioctl msg error:s:%d c:%d bcont:%c delta:%d\n", ! 292: size, iocbp->ioc_count, ! 293: gbuf_cont(m)? 'Y' : 'N', i)); ! 294: goto error; ! 295: } ! 296: else ! 297: return(0); ! 298: error: ! 299: ioc_ack(EMSGSIZE, m, gref); ! 300: return (EMSGSIZE); ! 301: } /* validate_msg_size */ ! 302: ! 303: void ! 304: elap_input(mp, elapp, src) ! 305: register elap_specifics_t *elapp; ! 306: register gbuf_t *mp; ! 307: register char *src; ! 308: { ! 309: /* Let ddp glean link address if it wishes to */ ! 310: elapp->stats.rcv_packets++; ! 311: elapp->stats.rcv_bytes += gbuf_msgsize(mp); ! 312: ! 313: if (!MULTIPORT_MODE) ! 314: ddp_glean (mp, &elapp->elap_if, src); ! 315: gbuf_next(mp) = 0; ! 316: ddp_input(mp, &elapp->elap_if); ! 317: } /* elap_input */ ! 318: ! 319: ! 320: /*********************************************************************** ! 321: * elap_wput() ! 322: * ! 323: **********************************************************************/ ! 324: int ! 325: elap_wput(gref, m) ! 326: gref_t *gref; ! 327: register gbuf_t *m; ! 328: { ! 329: elap_specifics_t *elapp; ! 330: register ioc_t *iocbp; ! 331: register at_elap_cfg_t *cfgp; ! 332: at_elap_stats_t *statsp; ! 333: static int ifID_entry = 0; ! 334: int elap_online(); ! 335: int error; ! 336: int i; ! 337: int (*func)(); ! 338: gbuf_t *tmpm; ! 339: pat_unit_t *patp; ! 340: ! 341: ! 342: switch (gbuf_type(m)) { ! 343: case MSG_DATA: ! 344: gbuf_freem(m); ! 345: dPrintf(D_M_ELAP,D_L_ERROR, ! 346: ("Output data to control channel is ignored\n")); ! 347: break; ! 348: ! 349: case MSG_IOCTL: ! 350: iocbp = (ioc_t *) gbuf_rptr(m); ! 351: if (!xpatcnt) { ! 352: gotIfs = 0; ! 353: if (!(at_statep->flags & AT_ST_PAT_INIT)) { ! 354: bzero(elap_specifics, sizeof(elap_specifics)); ! 355: pat_init(); ! 356: at_statep->flags |= AT_ST_PAT_INIT; ! 357: at_ddp_debug = 0; ! 358: } ! 359: } ! 360: ! 361: switch (iocbp->ioc_cmd) { ! 362: case LAP_IOC_ADD_IFNAME: ! 363: /* Has this interface already been added? */ ! 364: if ((i = pat_ID(gbuf_rptr(gbuf_cont(m)))) != -1) { ! 365: ioc_ack(0, m, gref); ! 366: return 0; ! 367: } ! 368: ! 369: shutdown_gref = gref; ! 370: patp = &pat_units[xpatcnt]; ! 371: bcopy(gbuf_rptr(gbuf_cont(m)), patp->xname, sizeof(patp->xname)); ! 372: patp->xname[sizeof(patp->xname)-1] = '\0'; ! 373: patp->xunit = (char)IF_UNIT(patp->xname); ! 374: if (strncmp(IF_TYPE_1, patp->xname, 2) == 0) ! 375: patp->xtype = IFTYPE_ETHERTALK; ! 376: else if (strncmp(IF_TYPE_3, patp->xname, 2) == 0) ! 377: patp->xtype = IFTYPE_FDDITALK; ! 378: else if (strncmp(IF_TYPE_4, patp->xname, 2) == 0) ! 379: patp->xtype = IFTYPE_TOKENTALK; ! 380: else if (strncmp(IF_TYPE_5, patp->xname, 2) == 0) ! 381: patp->xtype = IFTYPE_NULLTALK; ! 382: else ! 383: patp->xtype = IFTYPE_LOCALTALK; ! 384: ioc_ack(0, m, gref); ! 385: xpatcnt++; ! 386: return 0; ! 387: ! 388: /* *** fix this later: this code may no longer be needed *** */ ! 389: case LAP_IOC_DEL_IFNAME: ! 390: if ((i = pat_ID(gbuf_rptr(gbuf_cont(m)))) != -1) { ! 391: patp = &pat_units[i]; ! 392: patp->xname[0] = '\0'; ! 393: } ! 394: ioc_ack(0, m, gref); ! 395: return 0; ! 396: } ! 397: /* *** end of code that may no longer be needed *** */ ! 398: ! 399: if (validate_msg_size(m, gref, &elapp)) ! 400: break; ! 401: ! 402: if (elapp) ! 403: cfgp = (at_elap_cfg_t*) gbuf_rptr(gbuf_cont(m)); ! 404: ! 405: if (LAP_IOC_MYIOCTL(iocbp->ioc_cmd) || ! 406: ELAP_IOC_MYIOCTL(iocbp->ioc_cmd)) { ! 407: ! 408: switch (iocbp->ioc_cmd) { ! 409: ! 410: case LAP_IOC_CHECK_STATE: ! 411: #ifdef APPLETALK_DEBUG ! 412: kprintf("LAP_IOC_CHECK_STATE\n"); ! 413: #endif ! 414: error = (shutdown_gref == NULL) ? ENOTREADY : 0; ! 415: if (error == 0) { ! 416: dPrintf(D_M_ELAP,D_L_INFO, ! 417: ("elap_wput: CHECK_STATE 1\n")); ! 418: //### LD 7/23 was 0x1000: too big for 2K cluster size ! 419: if ((tmpm = gbuf_alloc(0x512, PRI_HI)) == NULL) ! 420: ioc_ack(ENOBUFS, m, gref); ! 421: else { ! 422: *gbuf_rptr(tmpm) = *gbuf_rptr(gbuf_cont(m)); ! 423: gbuf_wset(tmpm,sizeof(int)); ! 424: gbuf_freeb(gbuf_cont(m)); ! 425: gbuf_cont(m) = tmpm; ! 426: ddp_stop(m, gref); ! 427: } ! 428: } else { ! 429: dPrintf(D_M_ELAP,D_L_INFO, ! 430: ("elap_wput: CHECK_STATE 2\n")); ! 431: ioc_ack(error, m, gref); ! 432: } ! 433: break; ! 434: ! 435: /* *** fix this later: this code may no longer be needed *** */ ! 436: case LAP_IOC_SHUT_DOWN: ! 437: #ifdef APPLETALK_DEBUG ! 438: kprintf("LAP_IOC_SHUT_DOWN\n"); ! 439: #endif ! 440: if (shutdown_gref != NULL) { ! 441: if ((tmpm = gbuf_alloc(1, PRI_HI)) == NULL) { ! 442: ioc_ack(ENOBUFS, m, gref); ! 443: break; ! 444: } ! 445: gbuf_wset(tmpm,1); ! 446: *gbuf_rptr(tmpm) = ESHUTDOWN; ! 447: gbuf_set_type(tmpm, MSG_ERROR); ! 448: atalk_putnext(shutdown_gref, tmpm); ! 449: } ! 450: ioc_ack(0, m, gref); ! 451: break; ! 452: /* *** end of code that may no longer be needed *** */ ! 453: ! 454: case LAP_IOC_DO_DEFER: ! 455: #ifdef APPLETALK_DEBUG ! 456: kprintf("LAP_IOC_DO_DEFER\n"); ! 457: #endif ! 458: if (gbuf_cont(m) == NULL) { ! 459: dodefer(); ! 460: ioc_ack(0, m, gref); ! 461: } else { ! 462: ioc_ack(EINVAL, m, gref); ! 463: } ! 464: break; ! 465: case LAP_IOC_DO_DELAY: ! 466: #ifdef APPLETALK_DEBUG ! 467: kprintf("LAP_IOC_DO_DELAY\n"); ! 468: #endif ! 469: dodefer(); ! 470: if ((func = at_delay_func) != NULL) { ! 471: at_delay_func = NULL; ! 472: error = (*func)(at_delay_flag, m, gref); ! 473: if (error != ENOTREADY) ! 474: ioc_ack(error, m, gref); ! 475: } else ! 476: ioc_ack(0, m, gref); ! 477: break; ! 478: ! 479: case LAP_IOC_ONLINE: ! 480: #ifdef APPLETALK_DEBUG ! 481: kprintf("LAP_IOC_ONLINE\n"); ! 482: #endif ! 483: if ( elapp->elap_if.ifState == LAP_ONLINE || ! 484: (elapp->elap_if.ifState == LAP_ONLINE_ZONELESS && ! 485: !(cfgp->flags & ELAP_CFG_SET_RANGE) ! 486: ) ! 487: ) { ! 488: /* This don't make much sense... ! 489: * we're already ONLINE! ! 490: */ ! 491: ioc_ack(EALREADY, m, gref); ! 492: break; ! 493: } ! 494: elapp->flags = cfgp->flags; ! 495: if (elapp->flags & ELAP_CFG_HOME) { ! 496: /* copy over the configured zone if any */ ! 497: if (cfgp->zonename.len) ! 498: bcopy((caddr_t) &cfgp->zonename, ! 499: (caddr_t) &elapp->elap_if.ifZoneName, ! 500: cfgp->zonename.len+1); ! 501: if (ifID_table[IFID_HOME]) { ! 502: /* if home flag is set, and ! 503: * there is already a home ! 504: * ifID, it better be us! ! 505: */ ! 506: if (&elapp->elap_if != ! 507: ifID_table[IFID_HOME] ) { ! 508: /* only 1 home allowed! */ ! 509: ioc_ack(EEXIST, m, gref); ! 510: break; ! 511: } ! 512: dPrintf(D_M_ELAP, D_L_STARTUP, ("elap_wput home I/F:%s\n", ! 513: cfgp->if_name)); ! 514: } ! 515: else { ! 516: /* home port designation not ! 517: * allowed unless ! 518: * i/f is off line ! 519: */ ! 520: if ( elapp->elap_if.ifState != LAP_OFFLINE) { ! 521: ioc_ack(EPERM, m, gref); ! 522: break; ! 523: } ! 524: } ! 525: } /* if CFG_HOME */ ! 526: ! 527: if (elapp->elap_if.ifState == LAP_OFFLINE) ! 528: bzero ((caddr_t) &elapp->elap_if, sizeof(at_if_t)); ! 529: ! 530: if (elapp->flags & ELAP_CFG_SET_RANGE || ! 531: elapp->flags & ELAP_CFG_SEED) { ! 532: ! 533: if ( elapp->elap_if.ifState != LAP_ONLINE_ZONELESS && ! 534: elapp->elap_if.ifState != LAP_OFFLINE ! 535: ) { /* can't change range if ONLINE */ ! 536: ioc_ack(EFAULT, m, gref); ! 537: break; ! 538: } ! 539: dPrintf(D_M_ELAP, D_L_STARTUP_INFO, ! 540: ("elap_wput: found to be seed/set range\n")); ! 541: ! 542: ! 543: ATALK_ASSIGN(elapp->cfg.initial_addr, 0, 0, 0); ! 544: elapp->elap_if.ifThisCableStart = cfgp->netStart; ! 545: elapp->elap_if.ifThisCableEnd = cfgp->netEnd; ! 546: } ! 547: else { ! 548: dPrintf(D_M_ELAP,D_L_ERROR, ! 549: ("elap_wput: we believe we're not seed\n")); ! 550: } ! 551: ! 552: at_delay_errno = 0; ! 553: error = elap_online (gref, cfgp->if_name, NULL, m); ! 554: ! 555: if (error != ENOTREADY) ! 556: ioc_ack(error, m, gref); ! 557: break; ! 558: ! 559: case LAP_IOC_OFFLINE: ! 560: #ifdef APPLETALK_DEBUG ! 561: kprintf("LAP_IOC_OFFLINE\n"); ! 562: #endif ! 563: if (!xpatcnt) { ! 564: ioc_ack(0, m, gref); ! 565: break; ! 566: } ! 567: error = elap_offline(elapp); ! 568: ioc_ack(error, m, gref); ! 569: break; ! 570: ! 571: case LAP_IOC_GET_IFS_STAT: ! 572: #ifdef APPLETALK_DEBUG ! 573: kprintf("LAP_IOC_GET_IFS_STAT\n"); ! 574: #endif ! 575: if ((gbuf_cont(m) = gbuf_alloc(sizeof(if_cfg_t), ! 576: PRI_MED)) == NULL) { ! 577: ioc_ack(ENOBUFS, m, gref); ! 578: break; ! 579: } ! 580: get_ifs_stat(gbuf_rptr(gbuf_cont(m))); ! 581: gbuf_wset(gbuf_cont(m),sizeof(if_cfg_t)); ! 582: iocbp->ioc_count = sizeof(if_cfg_t); ! 583: ioc_ack(0, m, gref); ! 584: ifID_entry = 0; ! 585: break; ! 586: ! 587: case ELAP_IOC_GET_CFG: ! 588: #ifdef APPLETALK_DEBUG ! 589: kprintf("ELAP_IOC_GET_CFG\n"); ! 590: #endif ! 591: /* an at_elap_cfg_t is passed down with this ! 592: ioctl, the elapp is obtained from it via ! 593: the if_name we then send back a copy of the ! 594: current at_elap_cfg_t by gbuf_alloc'ing a new ! 595: message ! 596: */ ! 597: gbuf_freem(gbuf_cont(m)); ! 598: gbuf_cont(m) = NULL; ! 599: if ((gbuf_cont(m) = gbuf_alloc(sizeof(at_elap_cfg_t), ! 600: PRI_MED)) == NULL) { ! 601: ioc_ack(ENOBUFS, m, gref); ! 602: break; ! 603: } ! 604: cfgp = (at_elap_cfg_t *) gbuf_rptr(gbuf_cont(m)); ! 605: if (ifID_table[IFID_HOME]) { ! 606: elapp = (elap_specifics_t *)ifID_table[IFID_HOME]->ifLapp; ! 607: if (elapp) { ! 608: *cfgp = elapp->cfg; ! 609: gbuf_wset(gbuf_cont(m),sizeof(at_elap_cfg_t)); ! 610: iocbp->ioc_count = sizeof(at_elap_cfg_t); ! 611: ioc_ack(0, m, gref); ! 612: } ! 613: else ! 614: ioc_ack(EINVAL, m, gref); ! 615: } ! 616: else ! 617: ioc_ack(EINVAL, m, gref); ! 618: break; ! 619: ! 620: case LAP_IOC_GET_IFID: ! 621: #ifdef APPLETALK_DEBUG ! 622: kprintf("LAP_IOC_GET_IFID\n"); ! 623: #endif ! 624: /* return at_if_t struct for requested interface */ ! 625: { ! 626: at_if_name_t *ifIN; ! 627: at_if_t *ifID; ! 628: int lap_id; ! 629: ! 630: ifIN = (at_if_name_t *)gbuf_rptr(gbuf_cont(m)); ! 631: lap_id = pat_ID(ifIN->if_name); ! 632: { ! 633: if (lap_id < 0 || IF_ANY_MAX <= lap_id) { ! 634: ioc_ack(EINVAL, m, gref); ! 635: break; ! 636: } ! 637: else { ! 638: ifID = &elap_specifics[lap_id].elap_if; ! 639: gbuf_freem(gbuf_cont(m)); ! 640: gbuf_cont(m) = NULL; ! 641: ! 642: if ((gbuf_cont(m) = gbuf_alloc(sizeof(at_if_name_t), ! 643: PRI_MED)) == NULL) { ! 644: ioc_ack(ENOBUFS, m, gref); ! 645: break; ! 646: } ! 647: ifID = &elap_specifics[lap_id].elap_if; ! 648: ifIN = (at_if_name_t *)gbuf_rptr(gbuf_cont(m)); ! 649: ifIN->ifID = *ifID; ! 650: gbuf_wset(gbuf_cont(m),sizeof(at_if_name_t)); ! 651: iocbp->ioc_count = sizeof(at_if_name_t); ! 652: } ! 653: } ! 654: ioc_ack(0, m, gref); ! 655: } ! 656: break; ! 657: ! 658: ! 659: case ELAP_IOC_GET_STATS: ! 660: #ifdef APPLETALK_DEBUG ! 661: kprintf("LAP_IOC_GET_STATS\n"); ! 662: #endif ! 663: if ( (gbuf_cont(m) == NULL) ! 664: || ((i = pat_ID(gbuf_rptr(gbuf_cont(m)))) == -1) ) { ! 665: ioc_ack(EINVAL, m, gref); ! 666: break; ! 667: } ! 668: gbuf_freem(gbuf_cont(m)); ! 669: if ((gbuf_cont(m) =gbuf_alloc(sizeof(at_elap_stats_t), ! 670: PRI_MED)) == NULL) { ! 671: ioc_ack(ENOBUFS, m, gref); ! 672: break; ! 673: } ! 674: statsp = ((at_elap_stats_t *)gbuf_rptr(gbuf_cont(m))); ! 675: elapp = &elap_specifics[i]; ! 676: if (elapp) { ! 677: *statsp = elapp->stats; ! 678: gbuf_wset(gbuf_cont(m),sizeof(at_elap_stats_t)); ! 679: iocbp->ioc_count = sizeof(at_elap_stats_t); ! 680: ioc_ack(0, m, gref); ! 681: } ! 682: else ! 683: ioc_ack(EINVAL, m, gref); ! 684: break; ! 685: case ELAP_IOC_SET_CFG: ! 686: #ifdef APPLETALK_DEBUG ! 687: kprintf("ELAP_IOC_SET_CFG\n"); ! 688: #endif ! 689: if (elapp->elap_if.ifState == LAP_ONLINE) { ! 690: /* Can not allow setting config after ! 691: * we're already ONLINE ! 692: */ ! 693: ioc_ack(EALREADY, m, gref); ! 694: break; ! 695: } ! 696: ATALK_ASSIGN(elapp->cfg.initial_addr, 0, 0, 0); ! 697: ! 698: bcopy ((caddr_t) cfgp->if_name, (caddr_t) elapp->cfg.if_name, AT_IF_NAME_LEN); ! 699: if (ATALK_VALUE(cfgp->initial_addr)) { ! 700: at_net_al initial_net; ! 701: at_node initial_node; ! 702: ! 703: initial_node = *(at_node *)&cfgp-> ! 704: initial_addr.atalk_node; ! 705: initial_net = NET_VALUE(cfgp-> ! 706: initial_addr.atalk_net); ! 707: /* ! 708: * The net effect of the code that was here after A/UX ! 709: * version 29 was to ignore the prior node number settings. ! 710: * As a result * Barracuda 3.0.1 machines cannot "remember" ! 711: * their AppleTalk node number from the last AppleTalk ! 712: * session. ! 713: * The following code reverts this code back to pre version ! 714: * 29 style. ! 715: * The problem that version 29 was fixing really happens because ! 716: * readxpram (and writexpram) in lap_init was returning a -1 ! 717: * instead of 0 on failure. ! 718: * Madan Valluri. May 12, 1993. ! 719: */ ! 720: if ((initial_node<0xfe) && (initial_node>0) && ! 721: !((initial_net == 0) || ! 722: ((initial_net >= DDP_STARTUP_LOW)&& ! 723: (initial_net <= DDP_STARTUP_HIGH)))) ! 724: elapp->cfg.initial_addr = ! 725: cfgp->initial_addr; ! 726: } ! 727: ioc_ack(0, m, gref); ! 728: break; ! 729: ! 730: case ELAP_IOC_SET_ZONE : ! 731: #ifdef APPLETALK_DEBUG ! 732: kprintf("ELAP_IOC_SET_ZONE\n"); ! 733: #endif ! 734: /* ioctl to set the desired zone name for the ! 735: * interface and when no router is present, to set ! 736: * multicast addr for pram zone for when router returns ! 737: */ ! 738: cfgp = (at_elap_cfg_t * ) gbuf_rptr(gbuf_cont(m)); ! 739: ! 740: if (cfgp->flags & ELAP_CFG_ZONE_MCAST) { ! 741: nbp_add_multicast(&cfgp->zonename, &elapp->elap_if); ! 742: } ! 743: else { ! 744: if (elapp->elap_if.ifState == LAP_ONLINE) { ! 745: /* Can not allow setting zonename ! 746: * after we're already ONLINE ! 747: */ ! 748: ioc_ack(EALREADY, m, gref); ! 749: break; ! 750: } ! 751: } ! 752: ! 753: if (cfgp->zonename.len) ! 754: bcopy((caddr_t) &cfgp->zonename, ! 755: (caddr_t) &elapp->cfg.zonename, ! 756: cfgp->zonename.len+1); ! 757: ioc_ack(0, m, gref); ! 758: break; ! 759: case LAP_IOC_ADD_ZONE: ! 760: #ifdef APPLETALK_DEBUG ! 761: kprintf("LAP_IOC_ADD_ZONE\n"); ! 762: #endif ! 763: i = set_zones((if_zone_info_t *)gbuf_rptr(gbuf_cont(m))); ! 764: ioc_ack(i, m, gref); ! 765: break; ! 766: ! 767: case LAP_IOC_ADD_ROUTE: ! 768: #ifdef APPLETALK_DEBUG ! 769: kprintf("LAP_IOC_ADD_ROUTE\n"); ! 770: #endif ! 771: add_route((RT_entry *)gbuf_rptr(gbuf_cont(m))); ! 772: ioc_ack(0, m, gref); ! 773: break; ! 774: ! 775: case LAP_IOC_ROUTER_INIT: /* set routing tables sizes*/ ! 776: #ifdef APPLETALK_DEBUG ! 777: kprintf("LAP_IOC_ROUTER_INIT\n"); ! 778: #endif ! 779: { ! 780: router_init_t *p = (router_init_t *)gbuf_rptr(gbuf_cont(m)); ! 781: ! 782: at_state.flags = p->flags; ! 783: if (rt_table_init(p) == ENOBUFS) { ! 784: ioc_ack(ENOBUFS, m, gref); ! 785: break; ! 786: } ! 787: ioc_ack(0, m, gref); ! 788: } ! 789: break; ! 790: case LAP_IOC_ROUTER_START: ! 791: #ifdef APPLETALK_DEBUG ! 792: kprintf("LAP_IOC_ROUTER_START\n"); ! 793: #endif ! 794: gbuf_freem(gbuf_cont(m)); ! 795: gbuf_cont(m) = NULL; ! 796: routerStart(0, m, gref); ! 797: break; ! 798: ! 799: case LAP_IOC_ROUTER_SHUTDOWN: ! 800: { ! 801: int i, lap_id; ! 802: gbuf_t *tmpm; ! 803: ! 804: #ifdef APPLETALK_DEBUG ! 805: kprintf("LAP_IOC_ROUTER_SHUTDOWN\n"); ! 806: #endif ! 807: ! 808: routerShutdown(); ! 809: ! 810: /* go through ifID_table */ ! 811: for (i = 0; i < IF_TOTAL_MAX; i++) ! 812: if (ifID_table[i] && ifID_table[i]->ifName) { ! 813: lap_id = pat_ID(ifID_table[i]->ifName); ! 814: ! 815: /* was LAP_IOC_OFFLINE processing */ ! 816: elap_offline(&elap_specifics[lap_id]); ! 817: ! 818: /* was LAP_IOC_DEL_IFNAME processing */ ! 819: pat_units[lap_id].xname[0] = '\0'; ! 820: } ! 821: ! 822: /* was LAP_IOC_SHUT_DOWN processing */ ! 823: if (shutdown_gref != NULL) { ! 824: if ((tmpm = gbuf_alloc(1, PRI_HI)) == NULL) { ! 825: ioc_ack(ENOBUFS, m, gref); ! 826: break; ! 827: } ! 828: gbuf_wset(tmpm,1); ! 829: *gbuf_rptr(tmpm) = ESHUTDOWN; ! 830: gbuf_set_type(tmpm, MSG_ERROR); ! 831: atalk_putnext(shutdown_gref, tmpm); ! 832: } ! 833: ioc_ack(0, m, gref); ! 834: } ! 835: break; ! 836: ! 837: ! 838: case LAP_IOC_SET_DBG : ! 839: #ifdef APPLETALK_DEBUG ! 840: kprintf("LAP_IOC_SET_DBG\n"); ! 841: #endif ! 842: dbgBits = *(dbgBits_t *)gbuf_rptr(gbuf_cont(m)); ! 843: ioc_ack(0, m, gref); ! 844: break; ! 845: ! 846: ! 847: case LAP_IOC_GET_DBG: ! 848: #ifdef APPLETALK_DEBUG ! 849: kprintf("LAP_IOC_GET_DBG\n"); ! 850: #endif ! 851: if ((gbuf_cont(m) = gbuf_alloc(sizeof(dbgBits_t), ! 852: PRI_MED)) == NULL) { ! 853: ioc_ack(ENOBUFS, m, gref); ! 854: break; ! 855: } ! 856: *(dbgBits_t *)gbuf_rptr(gbuf_cont(m)) = dbgBits; ! 857: gbuf_wset(gbuf_cont(m),sizeof(dbgBits_t)); ! 858: iocbp->ioc_count = sizeof(dbgBits_t); ! 859: ioc_ack(0, m, gref); ! 860: break; ! 861: ! 862: case LAP_IOC_GET_ZONE: ! 863: #ifdef APPLETALK_DEBUG ! 864: kprintf("LAP_IOC_GET_ZONE\n"); ! 865: #endif ! 866: /* return next ZT_entryno from ZT_table ! 867: a pointer to the struct ZT_entryno is passed down from ! 868: user space and the first byte is cast to a int, if ! 869: this int is non-zero, then the first ZT_entry is ! 870: returned and subsequent calls with a zero value ! 871: will return the next entry in the table. The next ! 872: read after the last valid entry will return ENOMSG ! 873: */ ! 874: { ! 875: ZT_entryno *pZTe; ! 876: ! 877: i = *(int *)gbuf_rptr(gbuf_cont(m)); ! 878: gbuf_freem(gbuf_cont(m)); ! 879: gbuf_cont(m) = NULL; ! 880: ! 881: pZTe = zt_getNextZone(i); ! 882: if (pZTe) { ! 883: if ((gbuf_cont(m) = gbuf_alloc(sizeof(ZT_entryno), PRI_MED)) == NULL) { ! 884: ioc_ack(ENOBUFS, m, gref); ! 885: break; ! 886: } ! 887: *(ZT_entryno *)gbuf_rptr(gbuf_cont(m)) = *pZTe; ! 888: gbuf_wset(gbuf_cont(m),sizeof(ZT_entryno)); ! 889: iocbp->ioc_count = sizeof(ZT_entryno); ! 890: ioc_ack(0, m, gref); ! 891: } ! 892: else ! 893: ioc_ack(ENOMSG, m, gref); ! 894: } ! 895: break; ! 896: ! 897: case LAP_IOC_GET_DEFAULT_ZONE: ! 898: #ifdef APPLETALK_DEBUG ! 899: kprintf("LAP_IOC_GET_DEFAULT_ZONE\n"); ! 900: #endif ! 901: { ! 902: at_nvestr_t *pnve; ! 903: ! 904: i = *(int *)gbuf_rptr(gbuf_cont(m)); ! 905: gbuf_freem(gbuf_cont(m)); ! 906: gbuf_cont(m) = NULL; ! 907: pnve = getDefZone(i); ! 908: if (pnve) { ! 909: if ((gbuf_cont(m) = gbuf_alloc(sizeof(*pnve), PRI_MED)) == NULL) { ! 910: ioc_ack(ENOBUFS, m, gref); ! 911: break; ! 912: } ! 913: *(at_nvestr_t *)gbuf_rptr(gbuf_cont(m)) = *pnve; ! 914: gbuf_wset(gbuf_cont(m),sizeof(*pnve)); ! 915: iocbp->ioc_count = sizeof(*pnve); ! 916: } ! 917: else ! 918: iocbp->ioc_count = 0; ! 919: } ! 920: ioc_ack(0, m, gref); ! 921: break; ! 922: case LAP_IOC_GET_LOCAL_ZONE: ! 923: #ifdef APPLETALK_DEBUG ! 924: kprintf("LAP_IOC_GET_LOCAL_ZONE\n"); ! 925: #endif ! 926: if (!(ROUTING_MODE || MULTIHOME_MODE)) { ! 927: ioc_ack(EPERM, m, gref); ! 928: break; ! 929: } ! 930: { ! 931: if_zone_t *ifz; ! 932: int zone; ! 933: ! 934: zone = ((if_zone_t *)gbuf_rptr(gbuf_cont(m)))->ifzn.zone; ! 935: gbuf_freem(gbuf_cont(m)); ! 936: gbuf_cont(m) = NULL; ! 937: if ((gbuf_cont(m) = gbuf_alloc(sizeof(if_zone_t), PRI_MED)) == NULL) { ! 938: ioc_ack(ENOBUFS, m, gref); ! 939: break; ! 940: } ! 941: ifz = (if_zone_t *)gbuf_rptr(gbuf_cont(m)); ! 942: ifz->ifzn.zone = zone; ! 943: getRTRLocalZone(ifz); ! 944: gbuf_wset(gbuf_cont(m),sizeof(*ifz)); ! 945: iocbp->ioc_count = sizeof(*ifz); ! 946: } ! 947: ioc_ack(0, m, gref); ! 948: break; ! 949: case LAP_IOC_GET_ROUTE: ! 950: #ifdef APPLETALK_DEBUG ! 951: kprintf("LAP_IOC_GET_ROUTE\n"); ! 952: #endif ! 953: /* return next RT_entry from RT_table ! 954: * a pointer to the struct RT_entry is ! 955: * passed down from user space and the first ! 956: * byte is cast to a int, if this int is ! 957: * non-zero, then the first RT_entry is ! 958: * returned and subsequent calls with a ! 959: * zero value will return the next entry in ! 960: * the table. The next read after the last ! 961: * valid entry will return ENOMSG ! 962: */ ! 963: { ! 964: RT_entry *pRT; ! 965: ! 966: i = *(int *)gbuf_rptr(gbuf_cont(m)); ! 967: gbuf_freem(gbuf_cont(m)); ! 968: gbuf_cont(m) = NULL; ! 969: ! 970: pRT = rt_getNextRoute(i); ! 971: if (pRT) { ! 972: if ((gbuf_cont(m) = gbuf_alloc(sizeof(RT_entry), PRI_MED)) == NULL) { ! 973: ioc_ack(ENOBUFS, m, gref); ! 974: break; ! 975: } ! 976: *(RT_entry *)gbuf_rptr(gbuf_cont(m)) = *pRT; ! 977: gbuf_wset(gbuf_cont(m),sizeof(RT_entry)); ! 978: iocbp->ioc_count = sizeof(RT_entry); ! 979: ioc_ack(0, m, gref); ! 980: } ! 981: else ! 982: ioc_ack(ENOMSG, m, gref); ! 983: } ! 984: break; ! 985: ! 986: case LAP_IOC_SNMP_GET_DDP: ! 987: #ifdef APPLETALK_DEBUG ! 988: kprintf("LAP_IOC_SNMP_GET_DDP\n"); ! 989: #endif ! 990: if (!shutdown_gref) { ! 991: ioc_ack(ENOTREADY, m, gref); ! 992: break; ! 993: } ! 994: if ((gbuf_cont(m) = gbuf_alloc(sizeof(snmpStats_t), ! 995: PRI_MED)) == NULL) { ! 996: ioc_ack(ENOBUFS, m, gref); ! 997: break; ! 998: } ! 999: ! 1000: *(snmpStats_t *)gbuf_rptr(gbuf_cont(m)) = snmpStats; ! 1001: gbuf_wset(gbuf_cont(m),sizeof(snmpStats)); ! 1002: iocbp->ioc_count = sizeof(snmpStats); ! 1003: ioc_ack(0, m, gref); ! 1004: break; ! 1005: case LAP_IOC_SNMP_GET_CFG: ! 1006: #ifdef APPLETALK_DEBUG ! 1007: kprintf("LAP_IOC_SNMP_GET_CFG\n"); ! 1008: #endif ! 1009: { ! 1010: int i,size; ! 1011: snmpCfg_t snmp; ! 1012: ! 1013: i = *(int *)gbuf_rptr(gbuf_cont(m)); ! 1014: gbuf_freem(gbuf_cont(m)); ! 1015: gbuf_cont(m) = NULL; ! 1016: if (!shutdown_gref) { /* if stack down */ ! 1017: iocbp->ioc_count = 0; ! 1018: ioc_ack(ENOTREADY, m, gref); ! 1019: dPrintf(D_M_ELAP_LOW, D_L_INFO, ! 1020: ("elap_wput: cfg req, stack down\n")); ! 1021: break; ! 1022: } ! 1023: if (i == UPDATE_IF_CHANGED && ! 1024: !(at_statep->flags & AT_ST_IF_CHANGED)) { ! 1025: iocbp->ioc_count = 0; ! 1026: ioc_ack(0, m, gref); ! 1027: dPrintf(D_M_ELAP_LOW, D_L_INFO, ! 1028: ("elap_wput: cfg req, unchanged\n")); ! 1029: break; ! 1030: } ! 1031: dPrintf(D_M_ELAP_LOW, D_L_INFO, ! 1032: ("elap_wput: cfg req, changed\n")); ! 1033: ! 1034: if (getSnmpCfg(&snmp)) { ! 1035: dPrintf(D_M_ELAP,D_L_ERROR, ! 1036: ("elap_wput:SNMP_GET_CFG error\n")); ! 1037: ioc_ack(ENOMSG, m, gref); ! 1038: break; ! 1039: } ! 1040: /* send up only used part of table */ ! 1041: size = sizeof(snmp) - ! 1042: sizeof(snmpIfCfg_t) * (MAX_IFS - snmp.cfg_ifCnt); ! 1043: ! 1044: if ((gbuf_cont(m) = gbuf_alloc(size, PRI_MED)) == NULL) { ! 1045: ioc_ack(ENOBUFS, m, gref); ! 1046: break; ! 1047: } ! 1048: bcopy(&snmp,gbuf_rptr(gbuf_cont(m)),size); ! 1049: gbuf_wset(gbuf_cont(m),size); ! 1050: iocbp->ioc_count = size; ! 1051: at_statep->flags &= ~AT_ST_IF_CHANGED; ! 1052: ioc_ack(0, m, gref); ! 1053: } ! 1054: break; ! 1055: ! 1056: case LAP_IOC_SNMP_GET_AARP: ! 1057: { ! 1058: snmpAarpEnt_t *snmpp; ! 1059: int bytes; ! 1060: #ifdef APPLETALK_DEBUG ! 1061: kprintf("LAP_IOC_SNMP_GET_AARP\n"); ! 1062: #endif ! 1063: i = *(int *)gbuf_rptr(gbuf_cont(m)); ! 1064: gbuf_freem(gbuf_cont(m)); ! 1065: gbuf_cont(m) = NULL; ! 1066: dPrintf(D_M_ELAP,D_L_INFO, ! 1067: ("elap_wput:calling getarp,i=%d\n", i)); ! 1068: snmpp = getAarp(&i); ! 1069: bytes = i * sizeof(snmpAarpEnt_t); ! 1070: dPrintf(D_M_ELAP,D_L_INFO, ! 1071: ("elap_wput:getarp returned, i=%d,bytes=%d\n", ! 1072: i, bytes)); ! 1073: if (snmpp) { ! 1074: if ((gbuf_cont(m) = gbuf_alloc(bytes, PRI_MED)) == NULL) { ! 1075: ioc_ack(ENOBUFS, m, gref); ! 1076: break; ! 1077: } ! 1078: bcopy(snmpp, gbuf_rptr(gbuf_cont(m)), bytes); ! 1079: gbuf_wset(gbuf_cont(m),bytes); ! 1080: iocbp->ioc_count = bytes; ! 1081: ioc_ack(0, m, gref); ! 1082: } ! 1083: else ! 1084: ioc_ack(ENOMSG, m, gref); ! 1085: } ! 1086: break; ! 1087: ! 1088: case LAP_IOC_SNMP_GET_ZIP: ! 1089: #ifdef APPLETALK_DEBUG ! 1090: kprintf("LAP_IOC_SNMP_GET_ZIP\n"); ! 1091: #endif ! 1092: { /* matching brace NOT in this case */ ! 1093: register int i,j; ! 1094: register int size, total, tabsize; ! 1095: gbuf_t *mn; /* new gbuf */ ! 1096: gbuf_t *mo; /* old gbuf */ ! 1097: gbuf_t *mt; /* temp */ ! 1098: snmpNbpTable_t *nbp; ! 1099: ! 1100: i = *(int *)gbuf_rptr(gbuf_cont(m)); ! 1101: gbuf_freem(gbuf_cont(m)); ! 1102: gbuf_cont(m) = NULL; ! 1103: if (!shutdown_gref) { ! 1104: ioc_ack(ENOTREADY, m, gref); ! 1105: break; ! 1106: } ! 1107: if (i == UPDATE_IF_CHANGED && ! 1108: !(at_statep->flags & AT_ST_ZT_CHANGED)) { ! 1109: iocbp->ioc_count = 0; ! 1110: ioc_ack(0, m, gref); ! 1111: break; ! 1112: } ! 1113: mo=(gbuf_t*)NULL; ! 1114: tabsize = getZipTableSize(); ! 1115: ! 1116: /* retrieve table into multiple gbufs */ ! 1117: for (i =0; i<tabsize; i+=j) { ! 1118: j = tabsize - i > ! 1119: MAX_ZIP ? MAX_ZIP : tabsize - i; ! 1120: size = j < MAX_ZIP ? sizeof(ZT_entry)*j : MAX_ZIP_BYTES; ! 1121: if ((mn = gbuf_alloc(size, PRI_MED)) == NULL) { ! 1122: if (gbuf_cont(m)) ! 1123: gbuf_freem(gbuf_cont(m)); ! 1124: ioc_ack(ENOBUFS, m, gref); ! 1125: break; ! 1126: } ! 1127: if (!mo) { /* if first new one */ ! 1128: mt = mn; ! 1129: total = size; ! 1130: } ! 1131: else { ! 1132: gbuf_cont(mo) = mn; ! 1133: total += size; ! 1134: } ! 1135: mo = mn; ! 1136: getZipTable((ZT_entry*)gbuf_rptr(mn),i,j); ! 1137: gbuf_wset(mn,size); ! 1138: } ! 1139: if ((gbuf_cont(m) = gbuf_alloc(sizeof(int), PRI_MED)) == NULL) { ! 1140: if (mt) ! 1141: gbuf_freem(mt); ! 1142: iocbp->ioc_count = 0; ! 1143: ioc_ack(ENOBUFS, m, gref); ! 1144: break; ! 1145: } ! 1146: if (!tabsize) { ! 1147: dPrintf(D_M_ELAP,D_L_WARNING, ! 1148: ("elap_wput:snmp: empty zip table\n")); ! 1149: total = 0; ! 1150: } ! 1151: *(int*)gbuf_rptr(gbuf_cont(m)) = total; /* return table size */ ! 1152: gbuf_wset(gbuf_cont(m),sizeof(int)); ! 1153: iocbp->ioc_count = sizeof(int); ! 1154: ioc_ack(0, m, gref); ! 1155: if (tabsize) ! 1156: atalk_putnext(gref,mt); /* send up table */ ! 1157: at_statep->flags &= ~AT_ST_ZT_CHANGED; ! 1158: break; ! 1159: ! 1160: case LAP_IOC_SNMP_GET_RTMP: ! 1161: #ifdef APPLETALK_DEBUG ! 1162: kprintf("LAP_IOC_SNMP_GET_RTMP\n"); ! 1163: #endif ! 1164: i = *(int *)gbuf_rptr(gbuf_cont(m)); ! 1165: gbuf_freem(gbuf_cont(m)); ! 1166: gbuf_cont(m) = NULL; ! 1167: if (!shutdown_gref) { ! 1168: ioc_ack(ENOTREADY, m, gref); ! 1169: break; ! 1170: } ! 1171: if (i == UPDATE_IF_CHANGED && ! 1172: !(at_statep->flags & AT_ST_RT_CHANGED)) { ! 1173: iocbp->ioc_count = 0; ! 1174: ioc_ack(0, m, gref); ! 1175: break; ! 1176: } ! 1177: ! 1178: mo=(gbuf_t*)NULL; ! 1179: tabsize = getRtmpTableSize(); ! 1180: ! 1181: /* retrieve table into multiple gbufs */ ! 1182: for (i =0; i<tabsize; i+=j) { ! 1183: j = tabsize - i > ! 1184: MAX_RTMP ? MAX_RTMP : tabsize - i; ! 1185: size = j < MAX_RTMP ? sizeof(RT_entry)*j : MAX_RTMP_BYTES; ! 1186: if ((mn = gbuf_alloc(size, PRI_MED)) == NULL) { ! 1187: if (gbuf_cont(m)) ! 1188: gbuf_freem(gbuf_cont(m)); ! 1189: ioc_ack(ENOBUFS, m, gref); ! 1190: break; ! 1191: } ! 1192: if (!mo) { /* if first new one */ ! 1193: mt = mn; ! 1194: total = size; ! 1195: } ! 1196: else { ! 1197: gbuf_cont(mo) = mn; ! 1198: total += size; ! 1199: } ! 1200: mo = mn; ! 1201: getRtmpTable((RT_entry*)gbuf_rptr(mn),i,j); ! 1202: gbuf_wset(mn,size); ! 1203: } ! 1204: if ((gbuf_cont(m) = gbuf_alloc(sizeof(int), PRI_MED)) == NULL) { ! 1205: if (mt) ! 1206: gbuf_freem(mt); ! 1207: iocbp->ioc_count = 0; ! 1208: ioc_ack(ENOBUFS, m, gref); ! 1209: break; ! 1210: } ! 1211: if (!tabsize) ! 1212: total = 0; ! 1213: *(int*)gbuf_rptr(gbuf_cont(m)) = total; /* return table size */ ! 1214: gbuf_wset(gbuf_cont(m),sizeof(int)); ! 1215: iocbp->ioc_count = sizeof(int); ! 1216: ioc_ack(0, m, gref); ! 1217: if (tabsize) ! 1218: atalk_putnext(gref,mt); /* send up table */ ! 1219: at_statep->flags &= ~AT_ST_RT_CHANGED; ! 1220: break; ! 1221: ! 1222: case LAP_IOC_SNMP_GET_NBP: ! 1223: #ifdef APPLETALK_DEBUG ! 1224: kprintf("LAP_IOC_SNMP_GET_NBP\n"); ! 1225: #endif ! 1226: i = *(int *)gbuf_rptr(gbuf_cont(m)); ! 1227: gbuf_freem(gbuf_cont(m)); ! 1228: gbuf_cont(m) = NULL; ! 1229: if (!shutdown_gref) { ! 1230: ioc_ack(ENOTREADY, m, gref); ! 1231: break; ! 1232: } ! 1233: if (i == UPDATE_IF_CHANGED && ! 1234: !(at_statep->flags & AT_ST_NBP_CHANGED)) { ! 1235: iocbp->ioc_count = 0; ! 1236: ioc_ack(0, m, gref); ! 1237: dPrintf(D_M_ELAP_LOW, D_L_INFO, ! 1238: ("elap_wput: nbp req denied, no change\n")); ! 1239: break; ! 1240: } ! 1241: ! 1242: mo=(gbuf_t*)NULL; ! 1243: tabsize = getNbpTableSize(); ! 1244: ! 1245: /* retrieve table into multiple gbufs */ ! 1246: for (i =0; i<tabsize; i+=j) { ! 1247: j = tabsize - i > ! 1248: MAX_NBP ? MAX_NBP : tabsize - i; ! 1249: size = j < MAX_NBP ? sizeof(snmpNbpEntry_t)*j : MAX_NBP_BYTES; ! 1250: if (!i) ! 1251: size += SNMP_NBP_HEADER_SIZE; ! 1252: if ((mn = gbuf_alloc(size, PRI_MED)) == NULL) { ! 1253: if (gbuf_cont(m)) ! 1254: gbuf_freem(gbuf_cont(m)); ! 1255: ioc_ack(ENOBUFS, m, gref); ! 1256: break; ! 1257: } ! 1258: if (!mo) { /* if first new one */ ! 1259: mt = mn; ! 1260: total = size; ! 1261: nbp = (snmpNbpTable_t*)gbuf_rptr(mn); ! 1262: nbp->nbpt_entries = tabsize; ! 1263: nbp->nbpt_zone = ! 1264: ifID_table[IFID_HOME]->ifZoneName; ! 1265: getNbpTable(nbp->nbpt_table,i,j); ! 1266: } ! 1267: else { ! 1268: gbuf_cont(mo) = mn; ! 1269: total += size; ! 1270: getNbpTable((snmpNbpEntry_t *)gbuf_rptr(mn),i,j); ! 1271: } ! 1272: mo = mn; ! 1273: gbuf_wset(mn,size); ! 1274: } ! 1275: if ((gbuf_cont(m) = gbuf_alloc(sizeof(int), PRI_MED)) == NULL) { ! 1276: if (mt) ! 1277: gbuf_freem(mt); ! 1278: iocbp->ioc_count = 0; ! 1279: ioc_ack(ENOBUFS, m, gref); ! 1280: break; ! 1281: } ! 1282: if (!tabsize) ! 1283: total = 0; ! 1284: *(int*)gbuf_rptr(gbuf_cont(m)) = total; /* return table size */ ! 1285: gbuf_wset(gbuf_cont(m),sizeof(int)); ! 1286: iocbp->ioc_count = sizeof(int); ! 1287: ioc_ack(0, m, gref); ! 1288: if (tabsize) ! 1289: atalk_putnext(gref,mt); /* send up table */ ! 1290: at_statep->flags &= ~AT_ST_NBP_CHANGED; ! 1291: break; ! 1292: } ! 1293: ! 1294: case LAP_IOC_SET_MIX: ! 1295: #ifdef APPLETALK_DEBUG ! 1296: kprintf("LAP_IOC_SET_MIX\n"); ! 1297: #endif ! 1298: RoutingMix = (*(short *)gbuf_rptr(gbuf_cont(m)) & 0xFFFF) * 2; ! 1299: ioc_ack(0, m, gref); ! 1300: break; ! 1301: case LAP_IOC_SET_LOCAL_ZONES: ! 1302: { int i; ! 1303: #ifdef APPLETALK_DEBUG ! 1304: kprintf("LAP_IOC_SET_LOCAL_ZONES\n"); ! 1305: #endif ! 1306: i = setLocalZones((at_nbptuple_t*)gbuf_rptr(gbuf_cont(m)), ! 1307: gbuf_len(gbuf_cont(m))); ! 1308: ioc_ack(i,m,gref); ! 1309: } ! 1310: break; ! 1311: ! 1312: case LAP_IOC_IS_ZONE_LOCAL: ! 1313: { ! 1314: at_nvestr_t *zone; ! 1315: #ifdef APPLETALK_DEBUG ! 1316: kprintf("LAP_IOC_IS_ZONE_LOCAL\n"); ! 1317: #endif ! 1318: zone = (at_nvestr_t *)gbuf_rptr(gbuf_cont(m)); ! 1319: if (isZoneLocal(zone)) ! 1320: ioc_ack(0,m,gref); ! 1321: else ! 1322: ioc_ack(ENOENT,m,gref); ! 1323: } ! 1324: break; ! 1325: case LAP_IOC_GET_MODE: ! 1326: #ifdef APPLETALK_DEBUG ! 1327: kprintf("LAP_IOC_GET_MODE\n"); ! 1328: #endif ! 1329: if ((gbuf_cont(m) = gbuf_alloc(sizeof(int), ! 1330: PRI_MED)) == NULL) { ! 1331: ioc_ack(ENOBUFS, m, gref); ! 1332: break; ! 1333: } ! 1334: if (MULTIHOME_MODE) ! 1335: *(int *)gbuf_rptr(gbuf_cont(m)) = AT_MODE_MHOME; ! 1336: else if (ROUTING_MODE) ! 1337: *(int *)gbuf_rptr(gbuf_cont(m)) = AT_MODE_ROUTER; ! 1338: else ! 1339: *(int*)gbuf_rptr(gbuf_cont(m)) = AT_MODE_SPORT; ! 1340: gbuf_wset(gbuf_cont(m),sizeof(int)); ! 1341: iocbp->ioc_count = sizeof(int); ! 1342: ioc_ack(0, m, gref); ! 1343: break; ! 1344: case LAP_IOC_GET_IF_NAMES: ! 1345: #ifdef APPLETALK_DEBUG ! 1346: kprintf("LAP_IOC_GET_IF_NAMES\n"); ! 1347: #endif ! 1348: if ((gbuf_cont(m) = gbuf_alloc(sizeof(if_name_t) * IF_ANY_MAX, ! 1349: PRI_MED)) == NULL) { ! 1350: ioc_ack(ENOBUFS, m, gref); ! 1351: break; ! 1352: } ! 1353: getIfNames((if_name_t *)gbuf_rptr(gbuf_cont(m))); ! 1354: gbuf_wset(gbuf_cont(m),sizeof(if_name_t) * IF_ANY_MAX); ! 1355: iocbp->ioc_count = sizeof(if_name_t) * IF_ANY_MAX; ! 1356: ioc_ack(0, m, gref); ! 1357: break; ! 1358: case LAP_IOC_SET_DEFAULT_ZONES: ! 1359: #ifdef APPLETALK_DEBUG ! 1360: kprintf("LAP_IOC_SET_DEFAULT_ZONES\n"); ! 1361: #endif ! 1362: setDefaultZones((int*)gbuf_rptr(gbuf_cont(m))); ! 1363: ioc_ack(0, m, gref); ! 1364: break; ! 1365: ! 1366: default: ! 1367: #ifdef APPLETALK_DEBUG ! 1368: kprintf("unknown ioctl %d\n", iocbp->ioc_cmd); ! 1369: #endif ! 1370: ioc_ack(ENOTTY, m, gref); ! 1371: dPrintf(D_M_ELAP, D_L_WARNING, ! 1372: ("elap_wput: unknown ioctl (%d)\n", iocbp->ioc_cmd)); ! 1373: ! 1374: if (elapp) ! 1375: elapp->stats.unknown_mblks++; ! 1376: break; ! 1377: } ! 1378: } ! 1379: break; ! 1380: ! 1381: default: ! 1382: gbuf_freem(m); ! 1383: break; ! 1384: } ! 1385: ! 1386: return 0; ! 1387: } /* elap_wput */ ! 1388: ! 1389: ! 1390: /* Called directly by ddp/zip. ! 1391: */ ! 1392: elap_dataput(m, elapp, addr_flag, addr) ! 1393: register gbuf_t *m; ! 1394: register elap_specifics_t *elapp; ! 1395: u_char addr_flag; ! 1396: char *addr; ! 1397: { ! 1398: register int size; ! 1399: int error; ! 1400: extern int zip_type_packet(); ! 1401: struct etalk_addr dest_addr; ! 1402: struct atalk_addr dest_at_addr; ! 1403: gbuf_t *tmp; ! 1404: extern gbuf_t *growmsg(); ! 1405: int loop = TRUE; /* flag to aarp to loopback (default) */ ! 1406: ! 1407: /* the incoming frame is of the form {flag, address, ddp...} ! 1408: * where "flag" indicates whether the address is an 802.3 ! 1409: * (link) address, or an appletalk address. If it's an ! 1410: * 802.3 address, the packet can just go out to the network ! 1411: * through PAT, if it's an appletalk address, AT->802.3 address ! 1412: * resolution needs to be done. ! 1413: * If 802.3 address is known, strip off the flag and 802.3 ! 1414: * address, and prepend 802.2 and 802.3 headers. ! 1415: */ ! 1416: ! 1417: if (addr == NULL) { ! 1418: addr_flag = *(u_char *)gbuf_rptr(m); ! 1419: gbuf_rinc(m,1); ! 1420: } ! 1421: ! 1422: switch (addr_flag) { ! 1423: case AT_ADDR_NO_LOOP : ! 1424: loop = FALSE; ! 1425: /* pass thru */ ! 1426: case AT_ADDR : ! 1427: if (addr == NULL) { ! 1428: dest_at_addr = *(struct atalk_addr *)gbuf_rptr(m); ! 1429: gbuf_rinc(m,sizeof(struct atalk_addr)); ! 1430: } else ! 1431: dest_at_addr = *(struct atalk_addr *)addr; ! 1432: break; ! 1433: case ET_ADDR : ! 1434: if (addr == NULL) { ! 1435: dest_addr = *(struct etalk_addr *)gbuf_rptr(m); ! 1436: gbuf_rinc(m,sizeof(struct etalk_addr)); ! 1437: } else ! 1438: dest_addr = *(struct etalk_addr *)addr; ! 1439: break; ! 1440: default : ! 1441: gbuf_freel(m); /* unknown address type, chuck it */ ! 1442: return(EINVAL); ! 1443: } ! 1444: ! 1445: while (gbuf_len(m) == 0) { ! 1446: tmp = m; ! 1447: m = gbuf_cont(m); ! 1448: gbuf_freeb(tmp); ! 1449: } ! 1450: ! 1451: /* At this point, rptr points to ddp header for sure */ ! 1452: ! 1453: if (elapp->elap_if.ifState == LAP_OFFLINE) { ! 1454: gbuf_freel(m); ! 1455: return(ENETDOWN); ! 1456: } ! 1457: ! 1458: if (elapp->elap_if.ifState == LAP_ONLINE_FOR_ZIP) { ! 1459: /* see if this is a ZIP packet that we need ! 1460: * to let through even though network is ! 1461: * not yet alive!! ! 1462: */ ! 1463: if (zip_type_packet(m) == 0) { ! 1464: gbuf_freel(m); ! 1465: return(ENETDOWN); ! 1466: } ! 1467: } ! 1468: ! 1469: elapp->stats.xmit_packets++; ! 1470: size = gbuf_msgsize(m); ! 1471: elapp->stats.xmit_bytes += size; ! 1472: snmpStats.dd_outLong++; ! 1473: ! 1474: switch (addr_flag) { ! 1475: case AT_ADDR_NO_LOOP : ! 1476: case AT_ADDR : ! 1477: /* ! 1478: * we don't want elap to be looking into ddp header, so ! 1479: * it doesn't know net#, consequently can't do ! 1480: * AMT_LOOKUP. That task left to aarp now. ! 1481: */ ! 1482: error = aarp_send_data(m,elapp,&dest_at_addr, loop); ! 1483: break; ! 1484: case ET_ADDR : ! 1485: error = pat_output(elapp->pat_id, m, &dest_addr, 0); ! 1486: break; ! 1487: } ! 1488: return (error); ! 1489: } /* elap_dataput */ ! 1490: ! 1491: ! 1492: /************************************************************************ ! 1493: * elap_online() ! 1494: * ! 1495: ************************************************************************/ ! 1496: ! 1497: int elap_online (gref, if_name, aerr, m) ! 1498: gref_t *gref; ! 1499: char *if_name; /* name of h/w interface (e.g. en2) */ ! 1500: int *aerr; ! 1501: gbuf_t *m; ! 1502: ! 1503: { ! 1504: register elap_specifics_t *elapp; ! 1505: int errno; ! 1506: int i,j; ! 1507: ! 1508: if (if_name == NULL) { ! 1509: elapp = (elap_specifics_t *)gref; ! 1510: gref = elapp->wait_q; ! 1511: if (aerr != NULL) ! 1512: goto AARP_sleep; ! 1513: if (elapp->elap_if.ifZipError != ZIP_RE_AARP) { ! 1514: errno = at_delay_errno ? at_delay_errno : elapp->elap_if.ifZipError; ! 1515: at_delay_errno = 0; ! 1516: ioc_ack(errno, m, gref); ! 1517: elapp->wait_p = 0; elapp->wait_q = 0; ! 1518: dPrintf(D_M_ELAP, D_L_STARTUP_INFO, ! 1519: ("elap_online: ifZipError=%d\n", ! 1520: elapp->elap_if.ifZipError)); ! 1521: } ! 1522: goto ZIP_sleep; ! 1523: } ! 1524: ! 1525: if ((i = pat_ID(if_name)) == -1) ! 1526: return(EINVAL); ! 1527: elapp = &elap_specifics[i]; ! 1528: elapp->wait_p = elap_online; elapp->wait_q = gref; elapp->wait_m = m; ! 1529: if (elapp->elap_if.ifState == LAP_ONLINE_FOR_ZIP) { ! 1530: dPrintf(D_M_ELAP, D_L_STARTUP_INFO, ! 1531: ("elap_online: goto zip_online_only\n")); ! 1532: goto zip_online_only; ! 1533: } ! 1534: if (elapp->elap_if.ifState == LAP_ONLINE_ZONELESS) { ! 1535: ATALK_ASSIGN(elapp->cfg.initial_addr, 0, 0, 0); ! 1536: dPrintf(D_M_ELAP_LOW, D_L_STARTUP_INFO, ! 1537: ("elap_online: goto re_aarp port=%d\n", elapp->elap_if.ifPort)); ! 1538: goto re_aarp; /* just reset the net range */ ! 1539: } ! 1540: ! 1541: if (!xpatcnt && !(at_statep->flags & AT_ST_PAT_INIT)) { ! 1542: pat_init(); ! 1543: at_statep->flags |= AT_ST_PAT_INIT; ! 1544: } ! 1545: ! 1546: dPrintf(D_M_ELAP, D_L_STARTUP_INFO, ("elap_online:%s elapp:0x%x\n", ! 1547: if_name[0] ? if_name : "NULL interface", (u_int) elapp)); ! 1548: ! 1549: elapp->pat_id = pat_online(if_name, &elapp->elap_if.ifType); ! 1550: if (elapp->pat_id == -1) { ! 1551: /* pat_online returned in error, interface name must be bad */ ! 1552: elapp->wait_m = 0; ! 1553: return(EINVAL); ! 1554: } ! 1555: if (elapp->elap_if.ifType == IFTYPE_TOKENTALK) ! 1556: { ! 1557: elapp->cable_multicast_addr = ttalk_multicast_addr; ! 1558: ddp_bit_reverse(&elapp->cable_multicast_addr); ! 1559: } ! 1560: else ! 1561: { ! 1562: elapp->cable_multicast_addr = etalk_multicast_addr; ! 1563: if (elapp->elap_if.ifType == IFTYPE_FDDITALK) ! 1564: ddp_bit_reverse(&elapp->cable_multicast_addr); ! 1565: } ! 1566: bcopy((caddr_t) if_name, (caddr_t) elapp->cfg.if_name, AT_IF_NAME_LEN); ! 1567: bcopy((caddr_t) if_name, (caddr_t) elapp->elap_if.ifName, AT_IF_NAME_LEN); ! 1568: elapp->elap_if.ifUnit = IF_UNIT(if_name); ! 1569: ! 1570: if (elapp->elap_if.ifState != LAP_OFFLINE) { ! 1571: /* the network must be up already or hanging ! 1572: * up! ! 1573: */ ! 1574: elapp->wait_m = 0; ! 1575: return (elapp->elap_if.ifState == LAP_HANGING_UP?EAGAIN:EALREADY); ! 1576: } ! 1577: ! 1578: bzero ((caddr_t) &elapp->stats, sizeof(at_elap_stats_t)); ! 1579: elapp->elap_if.ifFlags = AT_IFF_ETHERTALK; ! 1580: if (elapp->flags & ELAP_CFG_HOME) /* tell ddp_add_if if this is home */ ! 1581: elapp->elap_if.ifFlags |= AT_IFF_DEFAULT; ! 1582: ! 1583: elapp->elap_if.ifLapp = (void*)elapp; ! 1584: ! 1585: /* ELAP/DDP interface is not streams based anymore */ ! 1586: ! 1587: /* Get DDP started */ ! 1588: if (errno = ddp_add_if(&elapp->elap_if)) { ! 1589: elapp->wait_m = 0; ! 1590: return (errno); ! 1591: } ! 1592: ! 1593: /* set up multicast address for cable-wide broadcasts */ ! 1594: i = pat_control(elapp->pat_id, PAT_REG_MCAST, &elapp->cable_multicast_addr); ! 1595: j = pat_control(elapp->pat_id, PAT_REG_CONTEXT, (caddr_t)elapp); ! 1596: ! 1597: ! 1598: re_aarp : ! 1599: /* We now call aarp_init() to assign an apple ! 1600: * talk node addr ! 1601: */ ! 1602: ATALK_ASSIGN(elapp->cfg.node, 0, 0, 0); ! 1603: AARP_sleep : ! 1604: if (aerr != NULL) ! 1605: errno = *aerr; ! 1606: else ! 1607: errno = aarp_init(elapp, 0); ! 1608: if (errno != 0) { ! 1609: if (errno == ENOTREADY) ! 1610: return (errno); ! 1611: dPrintf(D_M_ELAP, D_L_STATE_CHG, ("elap_online aarp_init for %s\n", ! 1612: elapp->elap_if.ifName)); ! 1613: pat_control(elapp->pat_id, PAT_UNREG_MCAST, &elapp->cable_multicast_addr); ! 1614: pat_offline(elapp->pat_id); ! 1615: ddp_rem_if (&elapp->elap_if); ! 1616: elapp->elap_if.ifState = LAP_OFFLINE; ! 1617: if ((aerr != NULL) || (elapp->elap_if.ifZipError == ZIP_RE_AARP)) { ! 1618: ioc_ack(EADDRNOTAVAIL, m, gref); ! 1619: elapp->wait_p = 0; elapp->wait_q = 0; elapp->wait_m = 0; ! 1620: dPrintf(D_M_ELAP, D_L_STARTUP_INFO, ("elap_online: ack 2\n")); ! 1621: } ! 1622: return (EADDRNOTAVAIL); ! 1623: } ! 1624: else ! 1625: dPrintf(D_M_ELAP,D_L_STARTUP_INFO, ! 1626: ("elap_online: aarp_init returns zero\n")); ! 1627: ! 1628: if (ROUTING_MODE) ! 1629: { ! 1630: dPrintf(D_M_ELAP,D_L_STARTUP_INFO, ! 1631: ("elap_online: re_aarp, we know it's a router...\n")); ! 1632: ! 1633: if (elapp->flags & ELAP_CFG_SEED) { ! 1634: /* add route table entry (zones to be added later) */ ! 1635: at_if_t *ifID; ! 1636: ifID = &elapp->elap_if; ! 1637: dPrintf(D_M_ELAP, D_L_STARTUP_INFO, ! 1638: ("elap_online: rt_insert Cable %d-%d port =%d as SEED\n", ! 1639: ifID->ifThisCableStart, ifID->ifThisCableEnd, ifID->ifPort)); ! 1640: rt_insert( ifID->ifThisCableEnd, ! 1641: ifID->ifThisCableStart, ! 1642: 0,0,0, ! 1643: ifID->ifPort, ! 1644: RTE_STATE_PERMANENT | RTE_STATE_ZKNOWN | RTE_STATE_GOOD ! 1645: ); ! 1646: /* LD 081694: set the RTR_SEED_PORT flag for seed ports */ ! 1647: ifID->ifFlags |= RTR_SEED_PORT; ! 1648: } ! 1649: else ! 1650: dPrintf(D_M_ELAP,D_L_STARTUP_INFO, ! 1651: ("elap_online: it's a router, but non seed\n")); ! 1652: } ! 1653: if (elapp->flags & ELAP_CFG_ZONELESS) { ! 1654: elapp->elap_if.ifState = LAP_ONLINE_ZONELESS; ! 1655: if (aerr != NULL) { ! 1656: errno = at_delay_errno; ! 1657: at_delay_errno = 0; ! 1658: ioc_ack(errno, m, gref); ! 1659: elapp->wait_p = 0; elapp->wait_q = 0; elapp->wait_m = 0; ! 1660: dPrintf(D_M_ELAP, D_L_STARTUP_INFO, ("elap_online: ack 3\n")); ! 1661: } ! 1662: return(0); /* if not home, it's zoneless */ ! 1663: } ! 1664: ! 1665: zip_online_only: ! 1666: if (ifID_table[IFID_HOME]) { ! 1667: { ! 1668: char str[35]; ! 1669: at_nvestr_t *nve = &ifID_table[IFID_HOME]->ifZoneName; ! 1670: strncpy(str,nve->str,nve->len); ! 1671: str[nve->len] = '\0'; ! 1672: } ! 1673: } ! 1674: sethzonehash(elapp); ! 1675: ! 1676: /* Get ZIP rolling to get zone multicast address, etc. */ ! 1677: ! 1678: elapp->elap_if.ifState = LAP_ONLINE_FOR_ZIP; ! 1679: elapp->cfg.network_up = LAP_ONLINE_FOR_ZIP; ! 1680: elapp->wait_m = m; ! 1681: if ((errno = zip_control(&elapp->elap_if, ZIP_ONLINE)) != 0) { ! 1682: if (errno == ENOTREADY) ! 1683: return (ENOTREADY); ! 1684: ! 1685: ZIP_sleep: ! 1686: switch (elapp->elap_if.ifZipError) { ! 1687: case 0 : ! 1688: break; ! 1689: case ENOTREADY : ! 1690: elapp->elap_if.ifZipError = 0; ! 1691: return (ENOTREADY); ! 1692: case ZIP_RE_AARP : ! 1693: elapp->wait_m = m; ! 1694: goto re_aarp; ! 1695: case ENODEV : ! 1696: /* return ENODEV to /etc/appletalk and let the ! 1697: * network be ONLINE.... this is to tackle the ! 1698: * case where zone name resolution is not ! 1699: * complete. ! 1700: */ ! 1701: elapp->elap_if.ifState = LAP_ONLINE_FOR_ZIP; ! 1702: elapp->cfg.network_up = LAP_ONLINE_FOR_ZIP; ! 1703: return (ENODEV); ! 1704: default : ! 1705: return (elapp->elap_if.ifZipError); ! 1706: } ! 1707: } ! 1708: ! 1709: elapp->elap_if.ifState = LAP_ONLINE; ! 1710: elapp->cfg.network_up = LAP_ONLINE; ! 1711: ! 1712: return (0); ! 1713: } /* elap_online */ ! 1714: ! 1715: ! 1716: /**************************************************************************** ! 1717: * elap_offline() ! 1718: * ! 1719: ****************************************************************************/ ! 1720: ! 1721: StaticProc ! 1722: int elap_offline(elapp) ! 1723: register elap_specifics_t *elapp; ! 1724: ! 1725: { ! 1726: void zip_sched_getnetinfo(); /* forward reference */ ! 1727: int errno; ! 1728: int s; ! 1729: ! 1730: if (elapp->elap_if.ifState == LAP_OFFLINE) { ! 1731: #ifdef APPLETALK_DEBUG ! 1732: kprintf("elap_offline: network is down already.\n"); ! 1733: #endif ! 1734: /* the network must be down already! */ ! 1735: return (EALREADY); ! 1736: } ! 1737: ! 1738: elapp->elap_if.ifState = LAP_HANGING_UP; ! 1739: elap_hangup(elapp); ! 1740: ! 1741: ATDISABLE(s, ddpinp_lock); ! 1742: if (MULTIPORT_MODE) ! 1743: RT_DELETE(elapp->elap_if.ifThisCableEnd, ! 1744: elapp->elap_if.ifThisCableStart); ! 1745: ATENABLE(s, ddpinp_lock); ! 1746: ! 1747: if (errno = ddp_rem_if(&elapp->elap_if)) { ! 1748: #ifdef APPLETALK_DEBUG ! 1749: kprintf("elap_offline: ddp_rem_if ret %d\n", errno); ! 1750: #endif ! 1751: return (errno); ! 1752: } ! 1753: ! 1754: dPrintf(D_M_ELAP, D_L_SHUTDN_INFO, ("elap_offline:%s\n", elapp->cfg.if_name)); ! 1755: ! 1756: /* make sure no zip timeouts are left running */ ! 1757: atalk_untimeout (zip_sched_getnetinfo, &elapp->elap_if, ! 1758: ((at_if_t *)&elapp->elap_if)->tmo_3); ! 1759: ! 1760: /* clean up the elapp-> and elapp->cfg structures. ! 1761: * initializing with 0 is okay,(state LAP_OFFLINE == 0). ! 1762: */ ! 1763: bzero ((caddr_t) elapp, sizeof(elap_specifics_t)); ! 1764: /* Deal with deferred multicast requests */ ! 1765: dodefer(); ! 1766: ! 1767: /* *** all of the static variables (and more globals?) should ! 1768: be reinitialized. *** */ ! 1769: deferno = 0; ! 1770: gotIfs = 0; ! 1771: ! 1772: /* reset this as the last operation in the shutdown */ ! 1773: /* *** appletalk_inited cannot be reinitialized until such time as ! 1774: AppleTalk is no longer permanently linked into the kernel. ! 1775: appletalk_inited = 0; ! 1776: */ ! 1777: ! 1778: return (0); ! 1779: } /* elap_offline */ ! 1780: ! 1781: StaticProc ! 1782: void elap_hangup(elapp) ! 1783: register elap_specifics_t *elapp; ! 1784: { ! 1785: /* Since AppleTalk is going away, remove the cable ! 1786: * multicast address and turn the interface off so that all AppleTalk ! 1787: * packets are dropped in the driver itself. ! 1788: */ ! 1789: /* Get rid of the zone multicast address prior to going Offline. */ ! 1790: if (zone_multicast_addr.etalk_addr_octet[0] && ! 1791: (elapp->flags & ELAP_CFG_HOME)) { ! 1792: /* if zone is set && if this is the home port */ ! 1793: pat_control(elapp->pat_id, PAT_UNREG_MCAST, ! 1794: &zone_multicast_addr); ! 1795: bzero((caddr_t) &zone_multicast_addr, AARP_ETHER_ADDR_LEN); ! 1796: } ! 1797: else if (*(int*)&elapp->ZoneMcastAddr) ! 1798: pat_control(elapp->pat_id, PAT_REG_MCAST, &elapp->ZoneMcastAddr); ! 1799: pat_control(elapp->pat_id, PAT_UNREG_MCAST, &elapp->cable_multicast_addr); ! 1800: pat_offline(elapp->pat_id); ! 1801: ! 1802: elapp->elap_if.ifState = LAP_OFFLINE; ! 1803: return; ! 1804: } ! 1805: ! 1806: ! 1807: int elap_control (ifID, control, data) ! 1808: register at_if_t *ifID; ! 1809: int control; ! 1810: u_char *data; ! 1811: { ! 1812: register elap_specifics_t *elapp; ! 1813: ! 1814: /* extract elapp & verify */ ! 1815: dPrintf(D_M_ELAP, D_L_INFO, ("elap_control:%d\n", control)); ! 1816: if (!( elapp = (elap_specifics_t *) ifID->ifLapp)) { ! 1817: return(ENXIO); ! 1818: } ! 1819: ! 1820: switch (control) { ! 1821: case ELAP_CABLE_BROADCAST_FOR_ZONE : ! 1822: /* the cable-broadcast address is to be used as ! 1823: * zone-multicast address. ! 1824: */ ! 1825: zone_multicast_addr = elapp->cable_multicast_addr; ! 1826: pat_control(elapp->pat_id, PAT_REG_MCAST, &zone_multicast_addr); ! 1827: break; ! 1828: case ELAP_REG_ZONE_MCAST : ! 1829: bcopy((caddr_t) data, (caddr_t) &zone_multicast_addr, AARP_ETHER_ADDR_LEN); ! 1830: pat_control(elapp->pat_id, PAT_REG_MCAST, &zone_multicast_addr); ! 1831: break; ! 1832: case ELAP_UNREG_ZONE_MCAST : ! 1833: if (*(int *)&zone_multicast_addr) { ! 1834: pat_control(elapp->pat_id, PAT_UNREG_MCAST, ! 1835: &zone_multicast_addr); ! 1836: bzero((caddr_t) &zone_multicast_addr, AARP_ETHER_ADDR_LEN); ! 1837: } ! 1838: break; ! 1839: case ELAP_RESET_INITNODE : ! 1840: ATALK_ASSIGN(elapp->cfg.initial_addr, 0, 0, 0); ! 1841: break; ! 1842: case ELAP_DESIRED_ZONE : ! 1843: if (elapp->cfg.zonename.len) ! 1844: bcopy((caddr_t) &elapp->cfg.zonename, (caddr_t) data, ! 1845: elapp->cfg.zonename.len+1); ! 1846: break; ! 1847: default : ! 1848: dPrintf(D_M_ELAP, D_L_ERROR, ("elap_control:invalid control:%d\n", ! 1849: control)); ! 1850: break; ! 1851: } ! 1852: return (0); ! 1853: } ! 1854: ! 1855: StaticProc ! 1856: void get_ifs_stat(ifcfgp) ! 1857: if_cfg_t *ifcfgp; ! 1858: { ! 1859: static if_cfg_t ifcfg; ! 1860: int ifType, ifMax, i; ! 1861: char xtype, ifTypeNameBuf[4], ifName[5], *ifTypeName; ! 1862: ! 1863: bzero(&ifcfg.state[0][0], sizeof(ifcfg.state)); ! 1864: for (ifType=0; ifType<IF_TYPENO_CNT; ifType++) { ! 1865: ! 1866: /* first get reference info on this specific type then status */ ! 1867: ifTypeName = NULL; ! 1868: if (!strcmp(if_types[ifType], IF_TYPE_1)) { ! 1869: ifMax = IF_TYPE_ET_MAX; ! 1870: xtype = IFTYPE_ETHERTALK; ! 1871: } else if (!strcmp(if_types[ifType], IF_TYPE_3)) { ! 1872: ifMax = IF_TYPE_TR_MAX; ! 1873: xtype = IFTYPE_TOKENTALK; ! 1874: } else if (!strcmp(if_types[ifType], IF_TYPE_4)) { ! 1875: ifMax = IF_TYPE_FD_MAX; ! 1876: xtype = IFTYPE_FDDITALK; ! 1877: } else if (!strcmp(if_types[ifType], IF_TYPE_5)) { ! 1878: ifMax = IF_TYPE_NT_MAX; ! 1879: xtype = IFTYPE_NULLTALK; ! 1880: } else ! 1881: continue; ! 1882: ! 1883: for (i=0; i<ifMax; i++) { ! 1884: if (pat_units[i].xtype == xtype) { ! 1885: ifcfg.state[ifType][pat_units[i].xunit] = ! 1886: elap_specifics[i].elap_if.ifState; ! 1887: if (ifTypeName == NULL) { ! 1888: strcpy(ifTypeNameBuf, pat_units[i].xname); ! 1889: ifTypeName = ifTypeNameBuf; ! 1890: for (; *ifTypeName != '\0'; ifTypeName++) { ! 1891: if ( (*ifTypeName >= '0') && (*ifTypeName <= '9') ) ! 1892: break; ! 1893: } ! 1894: *ifTypeName = '\0'; ! 1895: ifTypeName = ifTypeNameBuf; ! 1896: } ! 1897: } ! 1898: } ! 1899: ! 1900: /* here we query the OS for each possible I/F type in the system ! 1901: * we only do this one time and keep the results in the static struct ! 1902: */ ! 1903: if (!gotIfs && ifTypeName) { ! 1904: for (i=0; i<ifMax; i++) { ! 1905: sprintf(ifName,"%s%d",ifTypeName,i); ! 1906: if (!strcmp(ifName, "nt0")) ! 1907: /* set corresponding bit for I/F */ ! 1908: ifcfg.avail[ifType] |= 1<<i; ! 1909: else if (ifunit(ifName)) ! 1910: /* was (pat_ifpresent(ifName) != -1) */ ! 1911: /* set corresponding bit for I/F */ ! 1912: ifcfg.avail[ifType] |= 1<<i; ! 1913: } ! 1914: } /* if !gotIfs */ ! 1915: } /* for ifType */ ! 1916: ifcfg.ver_minor = AT_VERSION_MINOR; ! 1917: ifcfg.ver_major = AT_VERSION_MAJOR; ! 1918: ifcfg.ver_date = AT_VERSION_DATE; ! 1919: bcopy(&ifcfg, ifcfgp, sizeof(if_cfg_t)); ! 1920: gotIfs = 1; ! 1921: } /* get_ifs_stat */ ! 1922: ! 1923: ! 1924: ifName2Port(name) ! 1925: char *name; ! 1926: ! 1927: /* returns DDP port number of given interface name. to get ifID, ! 1928: use port number as index in ifID_table[] ! 1929: ! 1930: returns -1 if interface has no ifID entry. ! 1931: */ ! 1932: ! 1933: { ! 1934: int i; ! 1935: ! 1936: for (i=0; i< IF_TOTAL_MAX; i++) { ! 1937: if (!ifID_table[i]) /* if we reached end of entries */ ! 1938: return(-1); ! 1939: if (!strcmp(IFID2IFNAME(ifID_table[i]), name)) ! 1940: return(i); /* got a match */ ! 1941: } ! 1942: return(-1); /* no luck, searched all entries */ ! 1943: } ! 1944: ! 1945: StaticProc int set_zones(ifz) ! 1946: if_zone_info_t *ifz; ! 1947: ! 1948: /* 1. adds zone to table ! 1949: 2. looks up each route entry from zone I/F bitmap ! 1950: 3. sets zone bit in each route entry ! 1951: ! 1952: returns 0 if successful ! 1953: -1 if error occurred ! 1954: */ ! 1955: { ! 1956: int type, iftype,i,j; ! 1957: short zno; ! 1958: RT_entry *rte; ! 1959: ! 1960: zno = zt_add_zone(ifz->zone_name.str, ifz->zone_name.len); ! 1961: ! 1962: if (zno == ZT_MAXEDOUT) { ! 1963: dPrintf(D_M_ELAP, D_L_ERROR, ("set_zones: error: table full\n")); ! 1964: return(-1); ! 1965: } ! 1966: if (!IFID_VALID(ifID_table[IFID_HOME])) { ! 1967: dPrintf(D_M_ELAP, D_L_ERROR, ("set_zones: home ifID is invalid\n")); ! 1968: return(-1); ! 1969: } ! 1970: if (ifz->zone_home) ! 1971: ifID_table[IFID_HOME]->ifZoneName = ifz->zone_name; ! 1972: ! 1973: for (iftype=0; iftype< IF_TYPENO_CNT; iftype++) { ! 1974: if (!strcmp(if_types[iftype], IF_TYPE_1)) ! 1975: type = IFTYPE_ETHERTALK; ! 1976: else if (!strcmp(if_types[iftype], IF_TYPE_3)) ! 1977: type = IFTYPE_TOKENTALK; ! 1978: else if (!strcmp(if_types[iftype], IF_TYPE_4)) ! 1979: type = IFTYPE_FDDITALK; ! 1980: else if (!strcmp(if_types[iftype], IF_TYPE_5)) ! 1981: type = IFTYPE_NULLTALK; ! 1982: else ! 1983: continue; ! 1984: for (i=0; i<IF_ANY_MAX; i++) { ! 1985: if (ifz->zone_ifs[iftype] & 1<<i) { ! 1986: for (j=0; j<IF_ANY_MAX; j++) { ! 1987: if ( (elap_specifics[j].elap_if.ifType == type) ! 1988: && (elap_specifics[j].elap_if.ifUnit == i) ) ! 1989: break; ! 1990: } ! 1991: if (j < IF_ANY_MAX) { ! 1992: rte = rt_blookup(ELAP_UNIT2NETSTOP(j)); ! 1993: if (!rte) { ! 1994: dPrintf(D_M_ELAP, D_L_ERROR, ! 1995: ("set_zones: error: can't find route\n")); ! 1996: } ! 1997: zt_set_zmap(zno, rte->ZoneBitMap); ! 1998: ! 1999: /* if first zone for this I/F, make default */ ! 2000: if (!elap_specifics[j].elap_if.ifDefZone) ! 2001: elap_specifics[j].elap_if.ifDefZone = zno; ! 2002: } ! 2003: } ! 2004: } ! 2005: } ! 2006: return(0); ! 2007: } ! 2008: ! 2009: StaticProc void add_route(rt) ! 2010: RT_entry *rt; ! 2011: ! 2012: /* support ioctl to manually add routes to table. ! 2013: this is really only for testing ! 2014: */ ! 2015: { ! 2016: rt_insert( rt->NetStop, rt->NetStart, rt->NextIRNet, ! 2017: rt->NextIRNode, rt->NetDist, rt->NetPort, ! 2018: rt->EntryState); ! 2019: dPrintf(D_M_ELAP, D_L_STARTUP_INFO, ("adding route: %ud:%ud dist:%ud\n", ! 2020: rt->NetStart, rt->NetStop,rt->NetDist)); ! 2021: } ! 2022: ! 2023: StaticProc void routerShutdown() ! 2024: { ! 2025: dPrintf(D_M_ELAP, D_L_SHUTDN, ("routerShutdown called\n")); ! 2026: ! 2027: if (ROUTING_MODE) { ! 2028: ! 2029: rtmp_shutdown(); ! 2030: ! 2031: /* free memory allocated for the rtmp/zip tables only at this point */ ! 2032: FREE(ZT_table, M_RTABLE); ! 2033: FREE(RT_table, M_RTABLE); ! 2034: } ! 2035: nbp_shutdown(); /* clear all known NVE */ ! 2036: at_state.flags = 0; /* make sure inits are done on restart */ ! 2037: } ! 2038: ! 2039: routerStart(flag, m, gref) ! 2040: int flag; ! 2041: gbuf_t *m; ! 2042: gref_t *gref; ! 2043: { ! 2044: register short i; ! 2045: register at_if_t *ifID; ! 2046: extern rtmp_router_start(); ! 2047: ! 2048: if (flag) { ! 2049: if ((m = at_delay_m) != NULL) { ! 2050: at_delay_m = NULL; ! 2051: at_delay_func = rtmp_router_start; ! 2052: at_delay_flag = 0; ! 2053: ioc_ack(ENOTREADY, m, at_delay_gref); ! 2054: } ! 2055: return (0); ! 2056: } ! 2057: ! 2058: /* ! 2059: * this will cause the ports to glean from the net the relevant ! 2060: * information before forwarding ! 2061: */ ! 2062: for (i = 0 ; i < IF_TOTAL_MAX; i++) { ! 2063: ifID = ifID_table[i]; ! 2064: if (ifID) { ! 2065: dPrintf(D_M_ELAP, D_L_STARTUP_INFO, ! 2066: ("routerStart Port %d (%s) set to activating\n", ! 2067: ifID->ifPort, ifID->ifName)); ! 2068: ifID->ifRoutingState = PORT_ACTIVATING; ! 2069: ifID->ifFlags |= RTR_XNET_PORT; ! 2070: } ! 2071: else ! 2072: break; ! 2073: } ! 2074: ! 2075: /* ! 2076: * The next step is to check the information for each port before ! 2077: * declaring the ports up and forwarding ! 2078: */ ! 2079: dPrintf(D_M_ELAP, D_L_STARTUP_INFO, ! 2080: ("router_start: waiting 20 sec before starting up\n")); ! 2081: ! 2082: at_delay_m = m; at_delay_gref = gref; ! 2083: atalk_timeout(routerStart, 1, 20 * SYS_HZ); ! 2084: return (0); ! 2085: } ! 2086: ! 2087: StaticProc ! 2088: void ZIPContinue(elapp, m) ! 2089: elap_specifics_t *elapp; ! 2090: gbuf_t *m; ! 2091: { ! 2092: if (elapp->wait_p == NULL) ! 2093: gbuf_freem(m); ! 2094: else { ! 2095: (*elapp->wait_p)((void *)elapp, NULL, NULL, m); ! 2096: } ! 2097: } ! 2098: ! 2099: void ZIPwakeup(ifID) ! 2100: at_if_t *ifID; ! 2101: { ! 2102: int s; ! 2103: gbuf_t *m; ! 2104: elap_specifics_t *elapp; ! 2105: ! 2106: ATDISABLE(s, ddpinp_lock); ! 2107: elapp = (elap_specifics_t *)ifID->ifLapp; ! 2108: if ( (elapp != NULL) && ((m = elapp->wait_m) != NULL) ) { ! 2109: elapp->wait_m = NULL; ! 2110: ATENABLE(s, ddpinp_lock); ! 2111: ZIPContinue(elapp, m); ! 2112: } else ! 2113: ATENABLE(s, ddpinp_lock); ! 2114: } ! 2115: ! 2116: StaticProc ! 2117: void AARPContinue(elapp, m) ! 2118: elap_specifics_t *elapp; ! 2119: gbuf_t *m; ! 2120: { ! 2121: int aerr; ! 2122: ! 2123: if (elapp->wait_p == NULL) ! 2124: gbuf_freem(m); ! 2125: else { ! 2126: aerr = aarp_init(elapp, 1); ! 2127: (*elapp->wait_p)((void *)elapp, NULL, &aerr, m); ! 2128: } ! 2129: } ! 2130: ! 2131: void AARPwakeup(probe_cb) ! 2132: aarp_amt_t *probe_cb; ! 2133: { ! 2134: int s; ! 2135: gbuf_t *m; ! 2136: elap_specifics_t *elapp; ! 2137: ! 2138: ATDISABLE(s, arpinp_lock); ! 2139: elapp = probe_cb->elapp; ! 2140: if ( (elapp != NULL) && ((m = elapp->wait_m) != NULL) ) { ! 2141: elapp->wait_m = NULL; ! 2142: ATENABLE(s, arpinp_lock); ! 2143: AARPContinue(elapp, m); ! 2144: } else ! 2145: ATENABLE(s, arpinp_lock); ! 2146: } ! 2147: ! 2148: IF_UNIT(if_name) ! 2149: char *if_name; ! 2150: { ! 2151: for (; *if_name != '\0'; if_name++) ! 2152: if ((*if_name >= '0') && (*if_name <= '9')) ! 2153: return strtol(if_name, (char *)NULL, 10); ! 2154: return -1; ! 2155: } ! 2156: ! 2157: ! 2158: StaticProc void getIfNames(names) ! 2159: if_name_t *names; ! 2160: { ! 2161: int i; ! 2162: at_if_t *ifID; ! 2163: bzero(names,sizeof(if_name_t) * IF_TOTAL_MAX); ! 2164: for (i=0, ifID=ifID_table[0]; ifID; ifID = ifID_table[++i], names++) ! 2165: if(ifID) ! 2166: strncpy((char *)names,ifID->ifName,sizeof(*names)); ! 2167: ! 2168: return; ! 2169: } ! 2170: ! 2171: void ddp_bit_reverse(addr) ! 2172: unsigned char *addr; ! 2173: { ! 2174: static unsigned char reverse_data[] = { ! 2175: 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, ! 2176: 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, ! 2177: 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, ! 2178: 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, ! 2179: 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, ! 2180: 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, ! 2181: 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, ! 2182: 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, ! 2183: 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, ! 2184: 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, ! 2185: 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, ! 2186: 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, ! 2187: 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, ! 2188: 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, ! 2189: 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, ! 2190: 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, ! 2191: 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, ! 2192: 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, ! 2193: 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, ! 2194: 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, ! 2195: 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, ! 2196: 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, ! 2197: 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, ! 2198: 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, ! 2199: 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, ! 2200: 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, ! 2201: 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, ! 2202: 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, ! 2203: 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, ! 2204: 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, ! 2205: 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, ! 2206: 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff ! 2207: }; ! 2208: ! 2209: unsigned char k; ! 2210: ! 2211: for (k=0; k < 6; k++) ! 2212: addr[k] = reverse_data[addr[k]]; ! 2213: } ! 2214: ! 2215: int elap_trackMcast(pat_id,func,addr) ! 2216: int pat_id; ! 2217: int func; ! 2218: caddr_t addr; ! 2219: { ! 2220: int i, loc=-1; ! 2221: u_char c; ! 2222: switch(elap_specifics[pat_id].elap_if.ifType) { ! 2223: case IFTYPE_ETHERTALK: ! 2224: case IFTYPE_FDDITALK: ! 2225: case IFTYPE_NULLTALK: ! 2226: /* set addr to point to unique part of addr */ ! 2227: c = addr[5]; ! 2228: /* first try to find match */ ! 2229: for (i=0; i< MAX_MCASTS; i++) ! 2230: if (c == pat_units[pat_id].mcast[i]) { ! 2231: loc = i; ! 2232: break; ! 2233: } ! 2234: ! 2235: switch (func) { ! 2236: case MCAST_TRACK_DELETE: ! 2237: if (loc >= 0) ! 2238: pat_units[pat_id].mcast[loc] = 0; ! 2239: ! 2240: break; ! 2241: case MCAST_TRACK_ADD: ! 2242: dPrintf(D_M_PAT_LOW, D_L_USR2, ("mctrack:add loc:%d\n", i)); ! 2243: if (loc >= 0) { ! 2244: dPrintf(D_M_PAT_LOW, D_L_USR2, ("mctrack:add, addr was there\n")); ! 2245: return(1); ! 2246: break; /* already there */ ! 2247: } ! 2248: for (i=0; i< MAX_MCASTS; i++) ! 2249: if ( pat_units[pat_id].mcast[i] == 0) { ! 2250: loc = i; ! 2251: break; ! 2252: } ! 2253: dPrintf(D_M_PAT_LOW, D_L_USR2, ("mctrack:add1 loc:%d\n", i)); ! 2254: if (loc >= 0) { ! 2255: pat_units[pat_id].mcast[loc] = c; ! 2256: dPrintf(D_M_PAT_LOW, D_L_USR2, ("mctrack:add, adding(%x)\n", ! 2257: (*(int*)addr)&0xffffff)); ! 2258: } ! 2259: else { ! 2260: /*errno = ENOMEM; */ /*LD 5/7/97 nobody is using that */ ! 2261: return(-1); ! 2262: } ! 2263: break; ! 2264: case MCAST_TRACK_CHECK: ! 2265: if (loc >= 0) { ! 2266: dPrintf(D_M_PAT_LOW, D_L_USR2, ("mctrack:check, addr was there\n")); ! 2267: return(0); ! 2268: } ! 2269: else { ! 2270: dPrintf(D_M_PAT_LOW, D_L_USR2, ("mctrack:add, addr was NOT there\n")); ! 2271: return(-1); ! 2272: } ! 2273: ! 2274: default: ! 2275: /*errno = EINVAL;*/ /*LD 5/7/97 nobody is using that */ ! 2276: return(-1); ! 2277: } ! 2278: ! 2279: case IFTYPE_TOKENTALK: ! 2280: /* we would use the lowest byte of the addr argument as a value ! 2281: to shift left a 1 to form the mcast mask for TR. We'll do this ! 2282: when the time comes ! 2283: */ ! 2284: default: ! 2285: ; ! 2286: } ! 2287: return(0); ! 2288: } ! 2289: ! 2290: ! 2291: static ! 2292: getSnmpCfg(snmp) ! 2293: snmpCfg_t *snmp; ! 2294: { ! 2295: int i; ! 2296: elap_specifics_t *elapp; ! 2297: snmpIfCfg_t *ifc; ! 2298: at_if_t *ifID; ! 2299: ! 2300: snmp->cfg_ifCnt = 0; ! 2301: ! 2302: bzero(snmp,sizeof(snmpCfg_t)); ! 2303: for (i=0, elapp=elap_specifics,ifc=snmp->cfg_ifCfg; ! 2304: i<IF_TYPE_ET_MAX; i++, elapp++, ifc++) { ! 2305: ifID = &elap_specifics[i].elap_if; ! 2306: if (ifID->ifState != LAP_OFFLINE) { ! 2307: snmp->cfg_ifCnt++; ! 2308: strncpy(ifc->ifc_name,elapp->cfg.if_name,IF_NAME_SIZE); ! 2309: ifc->ifc_aarpSize = getAarpTableSize(i); ! 2310: ifc->ifc_addrSize = getPhysAddrSize(i); ! 2311: switch (ifID->ifType) { ! 2312: case IFTYPE_ETHERTALK: ! 2313: ifc->ifc_type = SNMP_TYPE_ETHER2; ! 2314: break; ! 2315: case IFTYPE_TOKENTALK: ! 2316: ifc->ifc_type = SNMP_TYPE_TOKEN; ! 2317: break; ! 2318: case IFTYPE_LOCALTALK: ! 2319: ifc->ifc_type = SNMP_TYPE_LOCAL; ! 2320: break; ! 2321: case IFTYPE_FDDITALK: ! 2322: case IFTYPE_NULLTALK: ! 2323: default: ! 2324: ifc->ifc_type = SNMP_TYPE_OTHER; ! 2325: break; ! 2326: } ! 2327: ifc->ifc_start = ifID->ifThisCableStart; ! 2328: ifc->ifc_end = ifID->ifThisCableEnd; ! 2329: ifc->ifc_ddpAddr= ifID->ifThisNode; ! 2330: ifc->ifc_status = ifID->ifState == LAP_ONLINE ? 1 : 2; ! 2331: ifc->ifc_zoneName.len = 0; ! 2332: if (ifID->ifZoneName.len != 0) { ! 2333: ifc->ifc_zoneName = ifID->ifZoneName; ! 2334: } ! 2335: else if (ifID->ifDefZone) { ! 2336: ifc->ifc_zoneName = ZT_table[ifID->ifDefZone-1].Zone; ! 2337: } ! 2338: else /* temp, debug only */ ! 2339: ifc->ifc_zoneName = ZT_table[0].Zone; ! 2340: if (ROUTING_MODE) { ! 2341: if (ifID->ifFlags & RTR_SEED_PORT) { ! 2342: ifc->ifc_netCfg = SNMP_CFG_CONFIGURED; ! 2343: ifc->ifc_zoneCfg = SNMP_CFG_CONFIGURED; ! 2344: } ! 2345: else { ! 2346: ifc->ifc_netCfg = SNMP_CFG_GARNERED; ! 2347: ifc->ifc_zoneCfg = SNMP_CFG_GARNERED; ! 2348: } ! 2349: } ! 2350: else { /* single-port mode */ ! 2351: if (ifID->ifRouterState == ROUTER_AROUND) { ! 2352: ifc->ifc_netCfg = SNMP_CFG_GARNERED; ! 2353: } ! 2354: else { ! 2355: ifc->ifc_netCfg = SNMP_CFG_GUESSED; ! 2356: ifc->ifc_zoneCfg = SNMP_CFG_UNCONFIG; ! 2357: } ! 2358: } ! 2359: } ! 2360: } ! 2361: snmp->cfg_flags = at_statep->flags; ! 2362: ! 2363: ! 2364: return(0); ! 2365: } ! 2366: ! 2367: void ! 2368: elap_get_addr(pat_id, addr) ! 2369: int pat_id; ! 2370: unsigned char *addr; /* pointer to buffer where the address is returned */ ! 2371: { ! 2372: bcopy(pat_units[pat_id].xaddr, addr, pat_units[pat_id].xaddrlen); ! 2373: } ! 2374: ! 2375: int ! 2376: pat_ID(if_name) ! 2377: char *if_name; ! 2378: { ! 2379: int pat_id; ! 2380: ! 2381: for (pat_id=0; pat_id < xpatcnt; pat_id++) { ! 2382: if (!strcmp(pat_units[pat_id].xname, if_name)) ! 2383: return(pat_id); ! 2384: } ! 2385: ! 2386: return(-1); ! 2387: } ! 2388: ! 2389: int ! 2390: pat_control(pat_id, control, data) ! 2391: int pat_id; ! 2392: int control; ! 2393: void *data; ! 2394: { ! 2395: typedef int (*procptr)(); ! 2396: ! 2397: switch(control) { ! 2398: case PAT_REG_CONTEXT : ! 2399: pat_units[pat_id].context = data; ! 2400: break; ! 2401: case PAT_REG_AARP_UPSTREAM : ! 2402: pat_units[pat_id].aarp_func = (procptr)data; ! 2403: break; ! 2404: case PAT_REG_CHECKADDR : ! 2405: pat_units[pat_id].addr_check = (procptr)data; ! 2406: break; ! 2407: case PAT_REG_MCAST : ! 2408: if (elap_trackMcast(pat_id, MCAST_TRACK_ADD,data) == 1) ! 2409: return(0); ! 2410: return(domcast(pat_id, control, data) == 0? 0 : -1); ! 2411: case PAT_UNREG_MCAST : ! 2412: elap_trackMcast(pat_id, MCAST_TRACK_DELETE, data); ! 2413: return(domcast(pat_id, control, data) == 0? 0 : -1); ! 2414: default : ! 2415: return(-1); ! 2416: } ! 2417: ! 2418: return(0); ! 2419: } ! 2420: ! 2421: StaticProc void ! 2422: pat_init() ! 2423: { ! 2424: #ifdef CHECK_DDPR_FLAG ! 2425: extern int ddprunning_flag; ! 2426: #endif ! 2427: /* zeroing the struct is okay since PAT_OFFLINE is zero */ ! 2428: bzero(pat_units, sizeof(pat_units)); ! 2429: #ifdef CHECK_DDPR_FLAG ! 2430: ddprunning_flag = 0; ! 2431: #endif ! 2432: } ! 2433: ! 2434: /* ! 2435: * Hopefully temporary hackery to deal with the need to ! 2436: * register/deregister multicast addresses at interrupt level ! 2437: * (as a result of incoming ZIP info). ioctl routines can't ! 2438: * be called at interrupt level due to locking constraints (MP ! 2439: * and all that) ! 2440: * Unfortunately, I can't find a better way. ! 2441: */ ! 2442: ! 2443: static struct multidefer { ! 2444: int pat_id; ! 2445: int control; ! 2446: unsigned char addr[6]; ! 2447: } defer[NDEFERS]; ! 2448: ! 2449: StaticProc int ! 2450: domcast(pat_id, control, data) ! 2451: int pat_id; ! 2452: int control; ! 2453: unsigned char *data; ! 2454: { ! 2455: if (pat_units[pat_id].xtype == IFTYPE_NULLTALK) ! 2456: return 0; ! 2457: #ifdef _AIX ! 2458: if (getpid() == -1) { ! 2459: if (deferno < NDEFERS) { ! 2460: defer[deferno].pat_id = pat_id; ! 2461: defer[deferno].control = control; ! 2462: bcopy(data, defer[deferno].addr, sizeof(defer[deferno].addr)); ! 2463: deferno++; ! 2464: return 0; ! 2465: ! 2466: } ! 2467: else ! 2468: return EINVAL; ! 2469: } ! 2470: #endif ! 2471: ! 2472: dPrintf(D_M_PAT, D_L_STARTUP, ("domcast:%s multicast %08x%04x pat_id:%d\n", ! 2473: (control == PAT_REG_MCAST) ? "adding" : "deleting", ! 2474: *(unsigned*)data, (*(unsigned *)(data+2))&0x0000ffff, pat_id)); ! 2475: ! 2476: return pat_mcast(pat_id, control, data); ! 2477: } ! 2478: ! 2479: /* ! 2480: * Handle any backed-up requests to register/unregister multicasts. ! 2481: * Should not be called at interrupt level! ! 2482: */ ! 2483: StaticProc void ! 2484: dodefer() ! 2485: { ! 2486: unsigned char *data; ! 2487: while (deferno > 0) ! 2488: { --deferno; ! 2489: data = (unsigned char *)defer[deferno].addr; ! 2490: ! 2491: dPrintf(D_M_PAT, D_L_STARTUP, ! 2492: ("dodefer:%s multicast %08x%04x pat_id:%d defno:%d\n", ! 2493: (defer[deferno].control == PAT_REG_MCAST) ? "adding" : "deleting", ! 2494: *(unsigned*)data, ! 2495: (*(unsigned *)(data+2))&0x0000ffff, ! 2496: defer[deferno].pat_id, ! 2497: deferno)); ! 2498: ! 2499: domcast(defer[deferno].pat_id, defer[deferno].control, ! 2500: defer[deferno].addr); ! 2501: } ! 2502: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.