+++ /dev/null
-/*
- * Copyright (c) 2000-2010 Apple Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-/*
- * Copyright (c) 1988, 1989, 1993-1998 Apple Computer, Inc.
- */
-
-/* at_elap.c: 2.0, 1.29; 10/4/93; Apple Computer, Inc. */
-
-/* This is the file which implements all the streams driver
- * functionality required for EtherTalk.
- */
-
-/* revision history
-
- 03-14-94 jjs Changed all functions which assumed only one port would
- ever be used. Added validate_msg_size, changed elap_online
- to work with the h/w name only (e.g. 'et2').
-
- Modified for MP, 1996 by Tuyen Nguyen
- Modified, March 17, 1997 by Tuyen Nguyen for MacOSX.
-
-*/
-
-#define RESOLVE_DBG /* for debug.h global resolution */
-#include <sys/errno.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#include <machine/spl.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/proc.h>
-#include <sys/filedesc.h>
-#include <sys/fcntl.h>
-#include <sys/mbuf.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <net/if_dl.h>
-#include <sys/socketvar.h>
-#include <sys/malloc.h>
-#include <sys/domain.h>
-#include <sys/sockio.h>
-#include <vm/vm_kern.h> /* for kernel_map */
-
-
-#include <net/if.h>
-#include <net/if_types.h>
-
-#include <netat/sysglue.h>
-#include <netat/appletalk.h>
-#include <netat/at_pcb.h>
-#include <netat/at_var.h>
-#include <netat/ddp.h>
-#include <netat/lap.h>
-#include <netat/routing_tables.h> /* rtmp+zip table structs */
-#include <netat/zip.h>
-#include <netat/nbp.h>
-#include <netat/at_snmp.h>
-#include <netat/at_aarp.h>
-#include <netat/asp.h>
-#include <netat/atp.h>
-#include <netat/debug.h>
-#include <netat/adsp.h>
-#include <netat/adsp_internal.h>
-#include <netat/at_pat.h>
-#include <netat/rtmp.h>
-
-#include <sys/kern_event.h>
-
-/* globals */
-
-at_ifaddr_t at_interfaces[IF_TOTAL_MAX];
- /* index for at_interfaces is not important */
-at_ifaddr_t *ifID_table[IF_TOTAL_MAX];
- /* the table of ifID structures, one per interface
- (not just ethernet),
- * NOTE: for MH, entry 0 in this table is
- * now defined to be the default I/F
- */
-at_ifaddr_t *ifID_home;
- /* always ifID_table[IFID_HOME] for now, but will be used for
- dynamic "home port" assignment, later */
-
-at_state_t at_state; /* global state of AT network */
-snmpFlags_t snmpFlags;
-
-int xpatcnt = 0;
-
-/* snmp defines */
-#define MAX_BUFSIZE 8192
-#define MAX_RTMP (MAX_BUFSIZE/sizeof(RT_entry)-1)
-#define MAX_NBP \
- ((MAX_BUFSIZE - SNMP_NBP_HEADER_SIZE)/sizeof(snmpNbpEntry_t)-1)
-#define MAX_NBP_BYTES (MAX_NBP * sizeof(snmpNbpEntry_t))
-#define MAX_ZIP (MAX_BUFSIZE/sizeof(ZT_entry)-1)
-#define MAX_RTMP_BYTES (MAX_RTMP * sizeof(RT_entry))
-#define MAX_ZIP_BYTES (MAX_ZIP * sizeof(ZT_entry))
-
-/* externs */
-extern TAILQ_HEAD(name_registry, _nve_) name_registry;
-extern snmpStats_t snmpStats;
-extern short appletalk_inited;
-extern int adspInited;
-extern struct atpcb ddp_head;
-extern gref_t *atp_inputQ[];
-extern struct atp_state *atp_used_list;
-extern asp_scb_t *asp_scbQ[];
-extern asp_scb_t *scb_used_list;
-extern CCB *adsp_inputQ[];
-extern CCB *ccb_used_list;
-extern at_ddp_stats_t at_ddp_stats;
-extern lck_mtx_t * atalk_mutex;
-
-/* protos */
-int rtmp_router_start(at_kern_err_t *);
-static void add_route(RT_entry *);
-void elap_offline(at_ifaddr_t *);
-static int elap_online1(at_ifaddr_t *);
-static void elap_online2(at_ifaddr_t *);
- int elap_online3(at_ifaddr_t *);
-static int re_aarp(at_ifaddr_t *);
-static int getSnmpCfg(snmpCfg_t *);
-
-int routerStart(at_kern_err_t *);
-
-static int validate_msg_size(gbuf_t *, gref_t *, at_ifaddr_t **);
-at_ifaddr_t *find_ifID(char *);
-int lap_online( at_ifaddr_t *, at_if_cfg_t *cfgp);
-
-
-at_ifaddr_t *find_ifID(if_name)
- char *if_name;
-{
- int pat_id;
-
- if (strlen(if_name))
- for (pat_id=0; pat_id < xpatcnt; pat_id++) {
- if (!strcmp(at_interfaces[pat_id].ifName, if_name))
- return(&at_interfaces[pat_id]);
- }
-
- return((at_ifaddr_t *)NULL);
-}
-
-static int validate_msg_size(m, gref, elapp)
- register gbuf_t *m;
- gref_t *gref;
- at_ifaddr_t **elapp;
-
-/* checks ioctl message type for minimum expected message size &
- sends error back if size invalid
-*/
-{
- register ioc_t *iocbp;
- int i = 0, size = 1;
-
- *elapp = NULL;
- iocbp = (ioc_t *) gbuf_rptr(m);
-
- dPrintf(D_M_ELAP, D_L_INFO, ("validate_msg_size: ioc_cmd = %d\n",
- iocbp->ioc_cmd));
- switch (iocbp->ioc_cmd) {
- case LAP_IOC_ADD_ROUTE:
- size = sizeof(RT_entry);
- break;
- case LAP_IOC_GET_ROUTE:
- size = sizeof(RT_entry);
- break;
- case LAP_IOC_GET_ZONE:
- size = sizeof(ZT_entryno);
- break;
- case LAP_IOC_SNMP_GET_CFG:
- case LAP_IOC_SNMP_GET_AARP:
- case LAP_IOC_SNMP_GET_ZIP:
- case LAP_IOC_SNMP_GET_RTMP:
- case LAP_IOC_SNMP_GET_NBP:
- size = sizeof(int);
- break;
-
- case ELAP_IOC_GET_STATS:
- case LAP_IOC_SNMP_GET_DDP:
- size = 0;
- break;
-
- default:
- dPrintf(D_M_ELAP, D_L_ERROR, ("validate_msg_size: unknown ioctl\n"));
- goto error;
- }
-
- if (size == 0) { /* a non-data ioctl */
- return(0);
- }
-
- if (gbuf_cont(m) != NULL)
- i = gbuf_len(gbuf_cont(m));
- if (iocbp->ioc_count < size || (gbuf_cont(m) == NULL) || i < size) {
- dPrintf(D_M_ELAP, D_L_ERROR,
- ("ioctl msg error:s:%d c:%d bcont:%c delta:%d\n",
- size, iocbp->ioc_count,
- gbuf_cont(m)? 'Y' : 'N', i));
- goto error;
- }
- else
- return(0);
-error:
- ioc_ack(EMSGSIZE, m, gref);
- return (EMSGSIZE);
-} /* validate_msg_size */
-
-int lap_online(elapp, cfgp)
- at_ifaddr_t *elapp;
- at_if_cfg_t *cfgp;
-{
- int error;
-
- if (elapp->ifState != LAP_OFFLINE) {
- return(EALREADY);
- }
-
- elapp->flags = 0;
- if (cfgp->flags & ELAP_CFG_HOME) {
- if (ifID_home) {
- /* only 1 home allowed! */
- return(EEXIST);
- }
- dPrintf(D_M_ELAP, D_L_STARTUP,
- ("elap_wput home I/F:%s\n", cfgp->ifr_name));
- elapp->flags |= ELAP_CFG_HOME;
- }
-
- if (MULTIPORT_MODE) {
- elapp->flags |= ELAP_CFG_ZONELESS;
- if (ROUTING_MODE && cfgp->netStart)
- elapp->flags |= ELAP_CFG_SEED;
- }
-
- /* (VL) !? */
- if ((!DEFAULT_ZONE(&cfgp->zonename) &&
- (elapp->flags & ELAP_CFG_HOME)) || MULTIHOME_MODE) {
- elapp->startup_zone = cfgp->zonename;
- }
-
- if (elapp->flags & ELAP_CFG_SEED) {
- dPrintf(D_M_ELAP, D_L_STARTUP_INFO,
- ("elap_wput: found to be seed\n"));
- elapp->ifThisCableStart = cfgp->netStart;
- elapp->ifThisCableEnd = cfgp->netEnd;
- }
- else {
- dPrintf(D_M_ELAP,D_L_ERROR,
- ("elap_wput: we believe we're not seed\n"));
- /* from ELAP_IOC_SET_CFG */
- if (ATALK_VALUE(cfgp->node)) {
- u_short initial_net;
- u_char initial_node;
-
- initial_node = cfgp->node.s_node;
- initial_net = cfgp->node.s_net;
- if ((initial_node<0xfe) && (initial_node>0) &&
- !((initial_net == 0) ||
- ((initial_net >= DDP_STARTUP_LOW)&&
- (initial_net <= DDP_STARTUP_HIGH)))) {
-
- elapp->initial_addr = cfgp->node;
- }
- }
- }
-
- elapp->startup_error = 0;
- elapp->startup_inprogress = FALSE;
- if ((error = elap_online1(elapp)))
- ddp_rem_if(elapp);
- else
- if (!(MULTIPORT_MODE) &&
- elapp->ifZoneName.len == 1 &&
- elapp->ifZoneName.str[0] == '*' &&
- !DEFAULT_ZONE(&cfgp->zonename)) {
- nbp_add_multicast(&cfgp->zonename, elapp);
- }
- return(error);
-} /* lap_online */
-
-/***********************************************************************
- * elap_wput()
- *
- **********************************************************************/
-int elap_wput(gref, m)
- gref_t *gref;
- register gbuf_t *m;
-{
- at_ifaddr_t *elapp;
- register ioc_t *iocbp;
- register at_if_cfg_t *cfgp;
- at_elap_stats_t *statsp;
- int i,j;
- int size, totalsize = 0, tabsize;
- gbuf_t *mn; /* new gbuf */
- gbuf_t *mo; /* old gbuf */
- gbuf_t *mt = NULL; /* temp */
- snmpNbpTable_t *nbp;
-
-
- switch (gbuf_type(m)) {
- case MSG_DATA:
- gbuf_freem(m);
- dPrintf(D_M_ELAP,D_L_ERROR,
- ("Output data to control channel is ignored\n"));
- break;
-
- case MSG_IOCTL:
- iocbp = (ioc_t *) gbuf_rptr(m);
-
- if (validate_msg_size(m, gref, &elapp))
- break;
-
- if (elapp)
- cfgp = (at_if_cfg_t*) gbuf_rptr(gbuf_cont(m));
-
- if (LAP_IOC_MYIOCTL(iocbp->ioc_cmd) ||
- ELAP_IOC_MYIOCTL(iocbp->ioc_cmd)) {
-
- switch (iocbp->ioc_cmd) {
- case ELAP_IOC_GET_STATS:
-#ifdef APPLETALK_DEBUG
- kprintf("LAP_IOC_GET_STATS\n");
-#endif
- if ( (gbuf_cont(m) == NULL)
- || (elapp = find_ifID(gbuf_rptr(gbuf_cont(m)))) == NULL) {
- ioc_ack(EINVAL, m, gref);
- break;
- }
- gbuf_freem(gbuf_cont(m));
- if ((gbuf_cont(m) =gbuf_alloc(sizeof(at_elap_stats_t),
- PRI_MED)) == NULL) {
- ioc_ack(ENOBUFS, m, gref);
- break;
- }
- statsp = ((at_elap_stats_t *)gbuf_rptr(gbuf_cont(m)));
- *statsp = elapp->stats;
- gbuf_wset(gbuf_cont(m),sizeof(at_elap_stats_t));
- iocbp->ioc_count = sizeof(at_elap_stats_t);
- ioc_ack(0, m, gref);
- break;
-
- case LAP_IOC_ADD_ROUTE:
-#ifdef APPLETALK_DEBUG
- kprintf("LAP_IOC_ADD_ROUTE\n");
-#endif
- add_route((RT_entry *)gbuf_rptr(gbuf_cont(m)));
- ioc_ack(0, m, gref);
- break;
-
- case LAP_IOC_GET_ZONE:
-#ifdef APPLETALK_DEBUG
- kprintf("LAP_IOC_GET_ZONE\n");
-#endif
- /* return next ZT_entryno from ZT_table
- a pointer to the struct ZT_entryno is passed down from
- user space and the first byte is cast to a int, if
- this int is non-zero, then the first ZT_entry is
- returned and subsequent calls with a zero value
- will return the next entry in the table. The next
- read after the last valid entry will return EINVAL
- */
- {
- ZT_entryno *pZTe;
-
- i = *(int *)gbuf_rptr(gbuf_cont(m));
- gbuf_freem(gbuf_cont(m));
- gbuf_cont(m) = NULL;
-
- pZTe = zt_getNextZone(i);
- if (pZTe) {
- if ((gbuf_cont(m) = gbuf_alloc(sizeof(ZT_entryno), PRI_MED)) == NULL) {
- ioc_ack(ENOBUFS, m, gref);
- break;
- }
- *(ZT_entryno *)gbuf_rptr(gbuf_cont(m)) = *pZTe;
- gbuf_wset(gbuf_cont(m),sizeof(ZT_entryno));
- iocbp->ioc_count = sizeof(ZT_entryno);
- ioc_ack(0, m, gref);
- }
- else
- ioc_ack(EINVAL, m, gref);
- }
- break;
-
- case LAP_IOC_GET_ROUTE:
-#ifdef APPLETALK_DEBUG
- kprintf("LAP_IOC_GET_ROUTE\n");
-#endif
- /* return next RT_entry from RT_table
- * a pointer to the struct RT_entry is
- * passed down from user space and the first
- * byte is cast to a int, if this int is
- * non-zero, then the first RT_entry is
- * returned and subsequent calls with a
- * zero value will return the next entry in
- * the table. The next read after the last
- * valid entry will return EINVAL
- */
- {
- RT_entry *pRT;
-
- i = *(int *)gbuf_rptr(gbuf_cont(m));
- gbuf_freem(gbuf_cont(m));
- gbuf_cont(m) = NULL;
-
- pRT = rt_getNextRoute(i);
- if (pRT) {
- if ((gbuf_cont(m) = gbuf_alloc(sizeof(RT_entry), PRI_MED)) == NULL) {
- ioc_ack(ENOBUFS, m, gref);
- break;
- }
- *(RT_entry *)gbuf_rptr(gbuf_cont(m)) = *pRT;
- gbuf_wset(gbuf_cont(m),sizeof(RT_entry));
- iocbp->ioc_count = sizeof(RT_entry);
- ioc_ack(0, m, gref);
- }
- else
- ioc_ack(EINVAL, m, gref);
- }
- break;
-
- case LAP_IOC_SNMP_GET_DDP:
-#ifdef APPLETALK_DEBUG
- kprintf("LAP_IOC_SNMP_GET_DDP\n");
-#endif
- if (!(at_state.flags & AT_ST_STARTED)) {
- ioc_ack(ENOTREADY, m, gref);
- break;
- }
- if ((gbuf_cont(m) = gbuf_alloc(sizeof(snmpStats_t),
- PRI_MED)) == NULL) {
- ioc_ack(ENOBUFS, m, gref);
- break;
- }
-
- *(snmpStats_t *)gbuf_rptr(gbuf_cont(m)) = snmpStats;
- gbuf_wset(gbuf_cont(m),sizeof(snmpStats));
- iocbp->ioc_count = sizeof(snmpStats);
- ioc_ack(0, m, gref);
- break;
- case LAP_IOC_SNMP_GET_CFG:
-#ifdef APPLETALK_DEBUG
- kprintf("LAP_IOC_SNMP_GET_CFG\n");
-#endif
- {
- snmpCfg_t snmp;
-
- i = *(int *)gbuf_rptr(gbuf_cont(m));
- gbuf_freem(gbuf_cont(m));
- gbuf_cont(m) = NULL;
- if (!(at_state.flags & AT_ST_STARTED)) {
- /* if stack down */
- iocbp->ioc_count = 0;
- ioc_ack(ENOTREADY, m, gref);
- dPrintf(D_M_ELAP_LOW, D_L_INFO,
- ("elap_wput: cfg req, stack down\n"));
- break;
- }
- if (i == UPDATE_IF_CHANGED &&
- !(at_state.flags & AT_ST_IF_CHANGED)) {
- iocbp->ioc_count = 0;
- ioc_ack(0, m, gref);
- dPrintf(D_M_ELAP_LOW, D_L_INFO,
- ("elap_wput: cfg req, unchanged\n"));
- break;
- }
- dPrintf(D_M_ELAP_LOW, D_L_INFO,
- ("elap_wput: cfg req, changed\n"));
-
- if (getSnmpCfg(&snmp)) {
- dPrintf(D_M_ELAP,D_L_ERROR,
- ("elap_wput:SNMP_GET_CFG error\n"));
- ioc_ack(EOPNOTSUPP, m, gref);
- break;
- }
- /* send up only used part of table */
- size = sizeof(snmp) -
- sizeof(snmpIfCfg_t) * (MAX_IFS - snmp.cfg_ifCnt);
-
- if ((gbuf_cont(m) = gbuf_alloc(size, PRI_MED)) == NULL) {
- ioc_ack(ENOBUFS, m, gref);
- break;
- }
- bcopy(&snmp,gbuf_rptr(gbuf_cont(m)),size);
- gbuf_wset(gbuf_cont(m),size);
- iocbp->ioc_count = size;
- at_state.flags &= ~AT_ST_IF_CHANGED;
- ioc_ack(0, m, gref);
- }
- break;
-
- case LAP_IOC_SNMP_GET_AARP:
- {
- snmpAarpEnt_t *snmpp;
- int bytes;
-#ifdef APPLETALK_DEBUG
- kprintf("LAP_IOC_SNMP_GET_AARP\n");
-#endif
- i = *(int *)gbuf_rptr(gbuf_cont(m));
- gbuf_freem(gbuf_cont(m));
- gbuf_cont(m) = NULL;
- dPrintf(D_M_ELAP,D_L_INFO,
- ("elap_wput:calling getarp,i=%d\n", i));
- snmpp = getAarp(&i);
- bytes = i * sizeof(snmpAarpEnt_t);
- dPrintf(D_M_ELAP,D_L_INFO,
- ("elap_wput:getarp returned, i=%d,bytes=%d\n",
- i, bytes));
- if (snmpp) {
- if ((gbuf_cont(m) = gbuf_alloc(bytes, PRI_MED)) == NULL) {
- ioc_ack(ENOBUFS, m, gref);
- break;
- }
- bcopy(snmpp, gbuf_rptr(gbuf_cont(m)), bytes);
- gbuf_wset(gbuf_cont(m),bytes);
- iocbp->ioc_count = bytes;
- ioc_ack(0, m, gref);
- }
- else
- ioc_ack(EOPNOTSUPP, m, gref);
- }
- break;
-
- case LAP_IOC_SNMP_GET_ZIP:
-#ifdef APPLETALK_DEBUG
- kprintf("LAP_IOC_SNMP_GET_ZIP\n");
-#endif
- { /* matching brace NOT in this case */
-
- i = *(int *)gbuf_rptr(gbuf_cont(m));
- gbuf_freem(gbuf_cont(m));
- gbuf_cont(m) = NULL;
- if (!(at_state.flags & AT_ST_STARTED)) {
- ioc_ack(ENOTREADY, m, gref);
- break;
- }
- if (i == UPDATE_IF_CHANGED &&
- !(at_state.flags & AT_ST_ZT_CHANGED)) {
- iocbp->ioc_count = 0;
- ioc_ack(0, m, gref);
- break;
- }
- mo=(gbuf_t*)NULL;
- tabsize = getZipTableSize();
-
- /* retrieve table into multiple gbufs */
- for (i =0; i<tabsize; i+=j) {
- j = tabsize - i >
- MAX_ZIP ? MAX_ZIP : tabsize - i;
- size = j < MAX_ZIP ? sizeof(ZT_entry)*j : MAX_ZIP_BYTES;
- if ((mn = gbuf_alloc(size, PRI_MED)) == NULL) {
- if (gbuf_cont(m))
- gbuf_freem(gbuf_cont(m));
- ioc_ack(ENOBUFS, m, gref);
- break;
- }
- if (!mo) { /* if first new one */
- mt = mn;
- totalsize = size;
- }
- else {
- gbuf_cont(mo) = mn;
- totalsize += size;
- }
- mo = mn;
- getZipTable((ZT_entry*)gbuf_rptr(mn),i,j);
- gbuf_wset(mn,size);
- }
- if ((gbuf_cont(m) = gbuf_alloc(sizeof(int), PRI_MED)) == NULL) {
- if (mt)
- gbuf_freem(mt);
- iocbp->ioc_count = 0;
- ioc_ack(ENOBUFS, m, gref);
- break;
- }
- if (!tabsize) {
- dPrintf(D_M_ELAP,D_L_WARNING,
- ("elap_wput:snmp: empty zip table\n"));
- totalsize = 0;
- }
- *(int*)gbuf_rptr(gbuf_cont(m)) = totalsize; /* return table size */
- gbuf_wset(gbuf_cont(m),sizeof(int));
- iocbp->ioc_count = sizeof(int);
- ioc_ack(0, m, gref);
- if (tabsize)
- atalk_putnext(gref,mt); /* send up table */
- at_state.flags &= ~AT_ST_ZT_CHANGED;
- break;
-
- case LAP_IOC_SNMP_GET_RTMP:
-#ifdef APPLETALK_DEBUG
- kprintf("LAP_IOC_SNMP_GET_RTMP\n");
-#endif
- i = *(int *)gbuf_rptr(gbuf_cont(m));
- gbuf_freem(gbuf_cont(m));
- gbuf_cont(m) = NULL;
- if (!(at_state.flags & AT_ST_STARTED)) {
- ioc_ack(ENOTREADY, m, gref);
- break;
- }
- if (i == UPDATE_IF_CHANGED &&
- !(at_state.flags & AT_ST_RT_CHANGED)) {
- iocbp->ioc_count = 0;
- ioc_ack(0, m, gref);
- break;
- }
-
- mo=(gbuf_t*)NULL;
- tabsize = getRtmpTableSize();
-
- /* retrieve table into multiple gbufs */
- for (i =0; i<tabsize; i+=j) {
- j = tabsize - i >
- MAX_RTMP ? MAX_RTMP : tabsize - i;
- size = j < MAX_RTMP ? sizeof(RT_entry)*j : MAX_RTMP_BYTES;
- if ((mn = gbuf_alloc(size, PRI_MED)) == NULL) {
- if (gbuf_cont(m))
- gbuf_freem(gbuf_cont(m));
- ioc_ack(ENOBUFS, m, gref);
- break;
- }
- if (!mo) { /* if first new one */
- mt = mn;
- totalsize = size;
- }
- else {
- gbuf_cont(mo) = mn;
- totalsize += size;
- }
- mo = mn;
- getRtmpTable((RT_entry*)gbuf_rptr(mn),i,j);
- gbuf_wset(mn,size);
- }
- if ((gbuf_cont(m) = gbuf_alloc(sizeof(int), PRI_MED)) == NULL) {
- if (mt)
- gbuf_freem(mt);
- iocbp->ioc_count = 0;
- ioc_ack(ENOBUFS, m, gref);
- break;
- }
- if (!tabsize)
- totalsize = 0;
- *(int*)gbuf_rptr(gbuf_cont(m)) = totalsize; /* return table size */
- gbuf_wset(gbuf_cont(m),sizeof(int));
- iocbp->ioc_count = sizeof(int);
- ioc_ack(0, m, gref);
- if (tabsize)
- atalk_putnext(gref,mt); /* send up table */
- at_state.flags &= ~AT_ST_RT_CHANGED;
- break;
-
- case LAP_IOC_SNMP_GET_NBP:
-#ifdef APPLETALK_DEBUG
- kprintf("LAP_IOC_SNMP_GET_NBP\n");
-#endif
- i = *(int *)gbuf_rptr(gbuf_cont(m));
- gbuf_freem(gbuf_cont(m));
- gbuf_cont(m) = NULL;
- if (!(at_state.flags & AT_ST_STARTED)) {
- ioc_ack(ENOTREADY, m, gref);
- break;
- }
- if (i == UPDATE_IF_CHANGED &&
- !(at_state.flags & AT_ST_NBP_CHANGED)) {
- iocbp->ioc_count = 0;
- ioc_ack(0, m, gref);
- dPrintf(D_M_ELAP_LOW, D_L_INFO,
- ("elap_wput: nbp req denied, no change\n"));
- break;
- }
-
- mo=(gbuf_t*)NULL;
- tabsize = getNbpTableSize();
-
- /* retrieve table into multiple gbufs */
- for (i =0; i<tabsize; i+=j) {
- j = tabsize - i >
- MAX_NBP ? MAX_NBP : tabsize - i;
- size = j < MAX_NBP ? sizeof(snmpNbpEntry_t)*j : MAX_NBP_BYTES;
- if (!i)
- size += SNMP_NBP_HEADER_SIZE;
- if ((mn = gbuf_alloc(size, PRI_MED)) == NULL) {
- if (gbuf_cont(m))
- gbuf_freem(gbuf_cont(m));
- ioc_ack(ENOBUFS, m, gref);
- break;
- }
- if (!mo) { /* if first new one */
- mt = mn;
- totalsize = size;
- nbp = (snmpNbpTable_t*)gbuf_rptr(mn);
- nbp->nbpt_entries = tabsize;
- nbp->nbpt_zone = ifID_home->ifZoneName;
- getNbpTable(nbp->nbpt_table,i,j);
- }
- else {
- gbuf_cont(mo) = mn;
- totalsize += size;
- getNbpTable((snmpNbpEntry_t *)gbuf_rptr(mn),i,j);
- }
- mo = mn;
- gbuf_wset(mn,size);
- }
- if ((gbuf_cont(m) = gbuf_alloc(sizeof(int), PRI_MED)) == NULL) {
- if (mt)
- gbuf_freem(mt);
- iocbp->ioc_count = 0;
- ioc_ack(ENOBUFS, m, gref);
- break;
- }
- if (!tabsize)
- totalsize = 0;
- *(int*)gbuf_rptr(gbuf_cont(m)) = totalsize; /* return table size */
- gbuf_wset(gbuf_cont(m),sizeof(int));
- iocbp->ioc_count = sizeof(int);
- ioc_ack(0, m, gref);
- if (tabsize)
- atalk_putnext(gref,mt); /* send up table */
- at_state.flags &= ~AT_ST_NBP_CHANGED;
- break;
- }
-
- default:
-#ifdef APPLETALK_DEBUG
- kprintf("unknown ioctl %d\n", iocbp->ioc_cmd);
-#endif
- ioc_ack(ENOTTY, m, gref);
- dPrintf(D_M_ELAP, D_L_WARNING,
- ("elap_wput: unknown ioctl (%d)\n", iocbp->ioc_cmd));
-
- if (elapp)
- elapp->stats.unknown_mblks++;
- break;
- }
- }
- break;
-
- default:
- gbuf_freem(m);
- break;
- }
-
- return 0;
-} /* elap_wput */
-
-
-/* Called directly by ddp/zip.
- */
-int
-elap_dataput(m, elapp, addr_flag, addr)
- register gbuf_t *m;
- register at_ifaddr_t *elapp;
- u_char addr_flag;
- char *addr;
-{
- register int size;
- int error = 0;
- struct etalk_addr dest_addr;
- struct atalk_addr dest_at_addr;
- int loop = TRUE;
- /* flag to aarp to loopback (default) */
-
- /* the incoming frame is of the form {flag, address, ddp...}
- * where "flag" indicates whether the address is an 802.3
- * (link) address, or an appletalk address. If it's an
- * 802.3 address, the packet can just go out to the network
- * through PAT, if it's an appletalk address, AT->802.3 address
- * resolution needs to be done.
- * If 802.3 address is known, strip off the flag and 802.3
- * address, and prepend 802.2 and 802.3 headers.
- */
-
- if (addr == NULL) {
- addr_flag = *(u_char *)gbuf_rptr(m);
- gbuf_rinc(m,1);
- }
-
- switch (addr_flag) {
- case AT_ADDR_NO_LOOP :
- loop = FALSE;
- /* pass thru */
- case AT_ADDR :
- if (addr == NULL) {
- dest_at_addr = *(struct atalk_addr *)gbuf_rptr(m);
- gbuf_rinc(m,sizeof(struct atalk_addr));
- } else
- dest_at_addr = *(struct atalk_addr *)addr;
- break;
- case ET_ADDR :
- if (addr == NULL) {
- dest_addr = *(struct etalk_addr *)gbuf_rptr(m);
- gbuf_rinc(m,sizeof(struct etalk_addr));
- } else
- dest_addr = *(struct etalk_addr *)addr;
- break;
- default :
- gbuf_freel(m); /* unknown address type, chuck it */
- return(EINVAL);
- }
-
- m = gbuf_strip(m);
-
- /* At this point, rptr points to ddp header for sure */
- if (elapp->ifState == LAP_OFFLINE) {
- gbuf_freel(m);
- return(ENETDOWN);
- }
-
- if (elapp->ifState == LAP_ONLINE_FOR_ZIP) {
- /* see if this is a ZIP packet that we need
- * to let through even though network is
- * not yet alive!!
- */
- if (zip_type_packet(m) == 0) {
- gbuf_freel(m);
- return(ENETDOWN);
- }
- }
-
- elapp->stats.xmit_packets++;
- size = gbuf_msgsize(m);
- elapp->stats.xmit_bytes += size;
- snmpStats.dd_outLong++;
-
- switch (addr_flag) {
- case AT_ADDR_NO_LOOP :
- case AT_ADDR :
- /*
- * we don't want elap to be looking into ddp header, so
- * it doesn't know net#, consequently can't do
- * AMT_LOOKUP. That task left to aarp now.
- */
- error = aarp_send_data(m, elapp, &dest_at_addr, loop);
- break;
- case ET_ADDR :
- error = pat_output(elapp, m, (unsigned char *)&dest_addr, 0);
- break;
- }
- return (error);
-} /* elap_dataput */
-
-/************************************************************************
- * elap_online()
- *
- ************************************************************************/
-
-static int elap_online1(elapp)
- at_ifaddr_t *elapp;
-{
- int errno;
-
- dPrintf(D_M_ELAP, D_L_STARTUP_INFO, ("elap_online:%s elapp:0x%x\n",
- (elapp->ifName) ? &elapp->ifName[0] : "NULL interface", (u_int) elapp));
- if (elapp->ifState != LAP_OFFLINE || elapp->startup_inprogress == TRUE)
- return (EALREADY);
-
- at_state.flags |= AT_ST_IF_CHANGED;
-
- if (elapp->flags & ELAP_CFG_HOME) /* tell ddp_add_if if this is home */
- elapp->ifFlags |= AT_IFF_DEFAULT;
-
- /* Get DDP started */
- if ((errno = ddp_add_if(elapp)))
- return(errno);
-
- // check if we still have an interface - can be lost when
- // ddp_add_if calls malloc
- // need to make check here after ddp_add_if completes because
- // lap_online will call ddp_rem_if if we fail here
- if (elapp->aa_ifp == 0)
- return ENOENT;
-
- /* set up multicast address for cable-wide broadcasts */
- (void)at_reg_mcast(elapp, (caddr_t)&elapp->cable_multicast_addr);
-
- // need to check again if interface is present
- // can be lost in at_reg_mcast
- if (elapp->aa_ifp == 0)
- return ENOENT;
-
- elapp->startup_inprogress = TRUE;
- if (! (elapp->startup_error = re_aarp(elapp))) {
- lck_mtx_assert(atalk_mutex, LCK_MTX_ASSERT_OWNED);
- (void)msleep(&elapp->startup_inprogress, atalk_mutex, PSOCK | PCATCH,
- "elap_online1", 0);
- }
-
- /* then later, after some timeouts AARPwakeup() is called */
-
- return(elapp->startup_error);
-} /* elap_online1 */
-
-static int re_aarp(elapp)
- at_ifaddr_t *elapp;
-{
- int errno;
-
- /* We now call aarp_init() to assign an appletalk node addr */
- errno = aarp_init1(elapp);
- /* aarp_init1() returns either -1 or ENOTREADY */
- if (errno == ENOTREADY)
- return(0);
- else {
- dPrintf(D_M_ELAP, D_L_STATE_CHG,
- ("elap_online aarp_init for %s\n", elapp->ifName));
- (void)at_unreg_mcast(elapp, (caddr_t)&elapp->cable_multicast_addr);
- ddp_rem_if(elapp);
- elapp->ifState = LAP_OFFLINE;
- return(EADDRNOTAVAIL);
- }
-}
-
-/* called from AARPwakeup */
-static void elap_online2(elapp)
- at_ifaddr_t *elapp;
-{
- if (MULTIPORT_MODE) {
- dPrintf(D_M_ELAP,D_L_STARTUP_INFO,
- ("elap_online: re_aarp, we know it's a router...\n"));
-
- if (elapp->flags & ELAP_CFG_SEED) {
- /* add route table entry (zones to be added later) */
- dPrintf(D_M_ELAP, D_L_STARTUP_INFO,
- ("elap_online: rt_insert Cable %d-%d port =%d as SEED\n",
- elapp->ifThisCableStart, elapp->ifThisCableEnd, elapp->ifPort));
- rt_insert(elapp->ifThisCableEnd,
- elapp->ifThisCableStart,
- 0,0,0,
- elapp->ifPort,
- RTE_STATE_PERMANENT | RTE_STATE_ZKNOWN | RTE_STATE_GOOD
- );
- /* LD 081694: set the RTR_SEED_PORT flag for seed ports */
- elapp->ifFlags |= RTR_SEED_PORT;
- }
-#if DEBUG
- else
- dPrintf(D_M_ELAP,D_L_STARTUP_INFO,
- ("elap_online: it's a router, but non seed\n"));
-#endif
- }
-
- if (elapp->flags & ELAP_CFG_ZONELESS) {
- /* ELAP_CFG_ZONELESS tells us that it is a router or in
- multihome mode, so we don't want to do the GetNetInfo
- exchange with the router. */
-
- elapp->ifState = LAP_ONLINE_ZONELESS;
- elapp->startup_inprogress = FALSE;
- wakeup(&elapp->startup_inprogress);
- dPrintf(D_M_ELAP, D_L_STARTUP_INFO, ("elap_online: ack 3\n"));
- return;
- }
-
- /* if we don't already have a zone and a multicast address */
- if (*(int *)&elapp->ZoneMcastAddr == 0 || elapp->ifZoneName.len == 0) {
- /* hzonehash is a global containing the nbp hash for the startup_zone */
- sethzonehash(elapp);
-
- /* Get ZIP rolling to get zone multicast address, etc. */
- elapp->ifState = LAP_ONLINE_FOR_ZIP;
- (void)zip_control(elapp, ZIP_ONLINE);
- /* zip_control (w. control == ZIP_ONLINE) always returns ENOTREADY */
-
- /* later, after some timeouts ZIPwakeup() is called. */
- } else {
- /* otherwise, we have the zone and the multicast already,
- so don't bother with another ZIP GetNetInfo request */
- ZIPwakeup(elapp, 0);
- }
-} /* elap_online2 */
-
-/* called from rtmp_router_start */
-int elap_online3(elapp)
- at_ifaddr_t *elapp;
-{
- elapp->startup_inprogress = TRUE;
-
- /* just reset the net range */
- elapp->initial_addr.s_net = 0;
- elapp->initial_addr.s_node = 0;
- dPrintf(D_M_ELAP_LOW, D_L_STARTUP_INFO,
- ("elap_online: goto re_aarp port=%d\n", elapp->ifPort));
-
- if ((elapp->startup_error = re_aarp(elapp)))
- return(elapp->startup_error);
-
- /* then later, after some timeouts AARPwakeup() is called */
-
- lck_mtx_assert(atalk_mutex, LCK_MTX_ASSERT_OWNED);
- (void)msleep(&elapp->startup_inprogress, atalk_mutex, PSOCK | PCATCH,
- "elap_online3", 0);
- return(elapp->startup_error);
-} /* elap_online3 */
-
-/****************************************************************************
- * elap_offline()
- *
- ****************************************************************************/
-
-void elap_offline(elapp)
- register at_ifaddr_t *elapp;
-
-{
- dPrintf(D_M_ELAP, D_L_SHUTDN_INFO, ("elap_offline:%s\n", elapp->ifName));
- if (elapp->ifState != LAP_OFFLINE) {
-
- /* Since AppleTalk is going away, remove the cable
- * multicast address and turn the interface off so that all
- * AppleTalk packets are dropped in the driver itself.
- * Get rid of the zone multicast address prior to going Offline.
- */
- (void)at_unreg_mcast(elapp, (caddr_t)&elapp->ZoneMcastAddr);
- (void)at_unreg_mcast(elapp, (caddr_t)&elapp->cable_multicast_addr);
- elapp->ifState = LAP_OFFLINE;
-
- if (MULTIPORT_MODE)
- RT_DELETE(elapp->ifThisCableEnd,
- elapp->ifThisCableStart);
-
- /* make sure no zip timeouts are left running */
- elapp->ifGNIScheduled = 0;
- untimeout(zip_sched_getnetinfo, elapp);
- }
- ddp_rem_if(elapp);
-} /* elap_offline */
-
-
-static void add_route(rt)
-RT_entry *rt;
-
-/* support ioctl to manually add routes to table.
- this is really only for testing
-*/
-{
- rt_insert( rt->NetStop, rt->NetStart, rt->NextIRNet,
- rt->NextIRNode, rt->NetDist, rt->NetPort,
- rt->EntryState);
- dPrintf(D_M_ELAP, D_L_STARTUP_INFO, ("adding route: %ud:%ud dist:%ud\n",
- rt->NetStart, rt->NetStop,rt->NetDist));
-}
-
-/*
- * ddp_start()
- *
- * Initialization that takes place each time AppleTalk is restarted.
- *
- */
-void ddp_start()
-{
- TAILQ_INIT(&at_ifQueueHd);
- TAILQ_INIT(&name_registry);
- bzero(at_interfaces, sizeof(at_interfaces));
- bzero(ifID_table, sizeof(ifID_table));
- bzero(&at_ddp_stats, sizeof(at_ddp_stats_t));
- rtmp_init(); /* initialize trackedrouters */
-
- add_ddp_handler(RTMP_SOCKET, rtmp_input);
- ifID_home = (at_ifaddr_t *)NULL;
- xpatcnt = 0;
-}
-
-int ddp_shutdown(count_only)
- int count_only;
-{
- at_ifaddr_t *ifID;
- asp_scb_t *scb, *scb_next;
- struct atp_state *atp, *atp_next;
- CCB *sp, *sp_next;
- gref_t *gref;
- int i, active_skts = 0; /* count of active pids for non-socketized
- AppleTalk protocols */
-
- /* Network is shutting down... send error messages up on each open
- * socket.
- *** For now, for ASP, ATP and ADSP, attempt to notify open
- sockets, but return EBUSY and don't complete shutdown. ***
- */
-
- if (!count_only)
- nbp_shutdown(); /* clear all known NVE */
-
- /* ASP */
- for (scb = scb_used_list; scb; ) {
- scb_next = scb->next_scb;
- active_skts++;
- if (!count_only) {
- dPrintf(D_M_ASP, D_L_TRACE, ("asp pid=%d\n", scb->pid));
- atalk_notify(scb->gref, ESHUTDOWN);
- }
- scb = scb_next;
- }
- for (i = 0; i < 256 ; i++) {
- if ((scb = asp_scbQ[i]))
- do {
- scb_next = scb->next_scb;
- active_skts++;
- if (!count_only) {
- dPrintf(D_M_ASP, D_L_TRACE,
- ("asp pid=%d\n", scb->pid));
- atalk_notify(scb->gref, ESHUTDOWN);
- }
- scb = scb_next;
- } while (scb);
- }
-
- /* ATP */
- for (atp = atp_used_list; atp; ) {
- atp_next = atp->atp_trans_waiting;
- active_skts++;
- if (!count_only) {
- dPrintf(D_M_ATP, D_L_TRACE, ("atp pid=%d\n", atp->atp_pid));
- atalk_notify(atp->atp_gref, ESHUTDOWN);
- }
- atp = atp_next;
- }
- for (i = 0; i < 256; i++) {
- if ((gref = atp_inputQ[i]) && (gref != (gref_t *)1)) {
- atp = (struct atp_state *)gref->info;
- if (!atp->dflag) {
- active_skts++;
- if (!count_only) {
- dPrintf(D_M_ATP, D_L_TRACE,
- ("atp pid=%d\n", atp->atp_pid));
- atalk_notify(atp->atp_gref, ESHUTDOWN);
- }
- }
- }
- }
-
- /* ADSP */
- for (sp = ccb_used_list; sp ; ) {
- sp_next = sp->otccbLink;
- active_skts++;
- if (!count_only) {
- dPrintf(D_M_ADSP, D_L_TRACE, ("adsp pid=%d\n", sp->pid));
- atalk_notify(sp->gref, ESHUTDOWN);
- }
- sp = sp_next;
- }
- for (i = 0; i < 256 ; i++) {
- if ((sp = adsp_inputQ[i]))
- do {
- sp_next = sp->otccbLink;
- active_skts++;
- if (!count_only) {
- dPrintf(D_M_ADSP, D_L_TRACE,
- ("adsp pid=%d\n", sp->pid));
- atalk_notify(sp->gref, ESHUTDOWN);
- }
- sp = sp_next;
- } while (sp);
- }
-
- /* DDP */
- for (gref = ddp_head.atpcb_next; gref != &ddp_head;
- gref = gref->atpcb_next) {
- if (count_only) {
- active_skts++;
- } else {
- dPrintf(D_M_DDP,D_L_TRACE, ("ddp pid=%d\n", gref->pid));
- atalk_notify(gref, ESHUTDOWN);
- }
- }
- if (count_only)
- return(active_skts);
-
- /* if there are no interfaces in the process of going online, continue shutting down DDP */
- for (i = 0; i < IF_TOTAL_MAX; i++) {
- if (at_interfaces[i].startup_inprogress == TRUE)
- return(1);
- }
- if (MULTIPORT_MODE) {
- rtmp_shutdown();
- /* free memory allocated for the rtmp/zip tables */
- if (ZT_table) {
- FREE(ZT_table, M_RTABLE);
- ZT_table = (ZT_entry *)NULL;
- }
- if (RT_table) {
- FREE(RT_table, M_RTABLE);
- RT_table = (RT_entry *)NULL;
- }
- }
-
- at_state.flags = 0; /* make sure inits are done on restart */
-
- wakeup(&ifID_home->startup_inprogress); /* if rtmp_router_start still starting up */
-
- /* from original ddp_shutdown() */
- routershutdown();
- ddp_brt_shutdown();
-
- if (adspInited) {
- CleanupGlobals();
- adspInited = 0;
- }
-
-
- dPrintf(D_M_DDP, D_L_VERBOSE, ("DDP shutdown completed"));
-
- /*
- * make sure we don't have a probe timeout hanging around
- * it's going to try and make use of an entry in at_interfaces
- * which is going to be zero'd out by the call to ddp_start a
- * little further down
- */
- untimeout(aarp_sched_probe, 0);
-
- /* *** after an SIOCSIFADDR and before an AIOCSIFADDR,
- this is the only place to find the ifID *** */
- for (i = 0; i < IF_TOTAL_MAX; i++) {
- ifID = &at_interfaces[i];
- /* do LAP_IOC_OFFLINE processing */
- elap_offline(ifID);
- }
- ddp_start();
-
- return(0);
-} /* ddp_shutdown */
-
-int routerStart(keP)
- at_kern_err_t *keP;
-{
- register at_ifaddr_t *ifID;
- int error;
- struct timespec ts;
-
- if (! ifID_home)
- return(EINVAL);
-
- /*
- * this will cause the ports to glean from the net the relevant
- * information before forwarding
- */
- TAILQ_FOREACH(ifID, &at_ifQueueHd, aa_link) {
- dPrintf(D_M_ELAP, D_L_STARTUP_INFO,
- ("routerStart Port %d (%s) set to activating\n",
- ifID->ifPort, ifID->ifName));
- ifID->ifRoutingState = PORT_ACTIVATING;
- ifID->ifFlags |= RTR_XNET_PORT;
- }
-
- /*
- * The next step is to check the information for each port before
- * declaring the ports up and forwarding
- */
- dPrintf(D_M_ELAP, D_L_STARTUP_INFO,
- ("router_start: waiting 20 sec before starting up\n"));
-
- lck_mtx_assert(atalk_mutex, LCK_MTX_ASSERT_OWNED);
- /* sleep for 20 seconds */
-
- /* the vaue of 10n terms of hz is 100ms */
- ts.tv_sec = 20;
- ts.tv_nsec = 0;
-
- if ((error =
- /* *** eventually this will be the ifID for the interface
- being brought up in router mode *** */
- msleep(&ifID_home->startup_inprogress, atalk_mutex,
- PSOCK | PCATCH, "routerStart", &ts))
- != EWOULDBLOCK) {
-/*
- if (!error)
- panic("routerStart: spurious interrupt");
-*/
- return(error);
- }
-
- return(rtmp_router_start(keP));
- /* was timeout(rtmp_router_start, 0, 20 * SYS_HZ); */
-} /* routerStart */
-
-void ZIPwakeup(elapp, ZipError)
- at_ifaddr_t *elapp;
- int ZipError;
-{
- int error = ZipError;
-
- if ( (elapp != NULL) && elapp->startup_inprogress) {
-
- /* was ZIPContinue */
- /* was elapp_online() with jump to ZIP_sleep */
-
- /* instead of the goto ZIP_sleep ... */
- switch (ZipError) {
- case 0 : /* success */
- elapp->ifState = LAP_ONLINE;
-
- /* Send event with zone info. */
- atalk_post_msg(elapp->aa_ifp, KEV_ATALK_ZONEUPDATED, 0, &(elapp->ifZoneName));
-
- break;
- case ZIP_RE_AARP :
- /* instead of goto re_aarp; */
- /* We now call aarp_init() to assign an
- appletalk node addr */
- if ((elapp->startup_error = re_aarp(elapp))) {
- elapp->startup_inprogress = FALSE;
- wakeup(&elapp->startup_inprogress);
- dPrintf(D_M_ELAP, D_L_STARTUP_INFO,
- ("elap_online: ack 2\n"));
- }
- break;
- default :
- break;
- }
- if (ZipError != ZIP_RE_AARP) {
- elapp->startup_error = error;
- elapp->startup_inprogress = FALSE;
- wakeup(&elapp->startup_inprogress);
- dPrintf(D_M_ELAP, D_L_STARTUP_INFO,
- ("elap_online: ifZipError=%d\n", error));
- }
- }
-} /* ZIPwakeup */
-
-void AARPwakeup(probe_cb)
- aarp_amt_t *probe_cb;
-{
- int errno;
- at_ifaddr_t *elapp;
-
- elapp = probe_cb->elapp;
- if ( (elapp != NULL) && elapp->startup_inprogress && elapp->aa_ifp != 0) {
-
- /* was AARPContinue */
- errno = aarp_init2(elapp);
- /* aarp_init2() returns either -1 or 0 */
- if (errno != 0) {
- dPrintf(D_M_ELAP, D_L_STATE_CHG,
- ("elap_online aarp_init for %s\n",
- elapp->ifName));
- (void)at_unreg_mcast(elapp, (caddr_t)&elapp->ZoneMcastAddr);
- (void)at_unreg_mcast(elapp, (caddr_t)&elapp->cable_multicast_addr);
- elapp->ifState = LAP_OFFLINE;
- ddp_rem_if(elapp);
- elapp->startup_error = EADDRNOTAVAIL;
- elapp->startup_inprogress = FALSE;
- wakeup(&elapp->startup_inprogress);
- dPrintf(D_M_ELAP, D_L_STARTUP_INFO, ("elap_online: ack 2\n"));
- } else {
- dPrintf(D_M_ELAP,D_L_STARTUP_INFO,
- ("elap_online: aarp_init returns zero\n"));
- elap_online2(elapp);
- }
- }
-} /* AARPwakeup */
-
-void ddp_bit_reverse(addr)
- unsigned char *addr;
-{
-static unsigned char reverse_data[] = {
- 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
- 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
- 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
- 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
- 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
- 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
- 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
- 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
- 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
- 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
- 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
- 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
- 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
- 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
- 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
- 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
- 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
- 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
- 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
- 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
- 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
- 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
- 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
- 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
- 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
- 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
- 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
- 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
- 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
- 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
- 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
- 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
- };
-
- unsigned char k;
-
- for (k=0; k < 6; k++)
- addr[k] = reverse_data[addr[k]];
-}
-
-static int elap_trackMcast(at_ifaddr_t *, int, caddr_t);
-
-static int elap_trackMcast(patp, func, addr)
- at_ifaddr_t *patp;
- int func;
- caddr_t addr;
-{
- int i, loc=-1;
- u_char c;
- switch(patp->aa_ifp->if_type) {
- case IFT_ETHER:
- case IFT_FDDI:
- case IFT_L2VLAN:
- case IFT_IEEE8023ADLAG: /* bonded ethernet */
- /* set addr to point to unique part of addr */
- c = addr[5];
-
- /* first try to find match */
- /* *** save just one byte of the multicast address? *** */
- for (i=0; i< MAX_MCASTS; i++)
- if (c == patp->mcast[i]) {
- loc = i;
- break;
- }
-
- switch (func) {
- case MCAST_TRACK_DELETE:
- if (loc >= 0)
- patp->mcast[loc] = 0;
-
- break;
- case MCAST_TRACK_ADD:
- dPrintf(D_M_PAT_LOW, D_L_USR2, ("mctrack:add loc:%d\n", i));
- if (loc >= 0) {
- dPrintf(D_M_PAT_LOW, D_L_USR2, ("mctrack:add, addr was there\n"));
- return(1);
- break; /* already there */
- }
- for (i=0; i< MAX_MCASTS; i++)
- if (patp->mcast[i] == 0) {
- loc = i;
- break;
- }
- dPrintf(D_M_PAT_LOW, D_L_USR2, ("mctrack:add1 loc:%d\n", i));
- if (loc >= 0) {
- patp->mcast[loc] = c;
- dPrintf(D_M_PAT_LOW, D_L_USR2, ("mctrack:add, adding(%x)\n",
- (*(int*)addr)&0xffffff));
- }
- else {
- /*errno = ENOMEM; */ /*LD 5/7/97 nobody is using that */
- return(-1);
- }
- break;
- case MCAST_TRACK_CHECK:
- if (loc >= 0) {
- dPrintf(D_M_PAT_LOW, D_L_USR2, ("mctrack:check, addr was there\n"));
- return(0);
- }
- else {
- dPrintf(D_M_PAT_LOW, D_L_USR2, ("mctrack:add, addr was NOT there\n"));
- return(-1);
- }
-
- default:
- /*errno = EINVAL;*/ /*LD 5/7/97 nobody is using that */
- return(-1);
- }
-
- case IFT_ISO88025: /* token ring */
- /* we would use the lowest byte of the addr argument as a value
- to shift left a 1 to form the mcast mask for TR. We'll do this
- when the time comes
- */
- default:
- ;
- }
- return(0);
-}
-
-
-static int getSnmpCfg(snmp)
- snmpCfg_t *snmp;
-{
- int i;
- at_ifaddr_t *elapp;
- snmpIfCfg_t *ifc;
-
- snmp->cfg_ifCnt = 0;
-
- bzero(snmp,sizeof(snmpCfg_t));
- for (i=0, elapp=at_interfaces,ifc=snmp->cfg_ifCfg;
- i<IF_TOTAL_MAX; i++, elapp++, ifc++) {
- if (elapp->ifState != LAP_OFFLINE) {
- snmp->cfg_ifCnt++;
- strlcpy(ifc->ifc_name,elapp->ifName, sizeof(ifc->ifc_name));
- ifc->ifc_aarpSize = getAarpTableSize(i);
- ifc->ifc_addrSize = getPhysAddrSize(i);
- switch (elapp->aa_ifp->if_type) {
- case IFT_ETHER:
- case IFT_L2VLAN:
- case IFT_IEEE8023ADLAG: /* bonded ethernet */
- ifc->ifc_type = SNMP_TYPE_ETHER2;
- break;
- case IFT_ISO88025: /* token ring */
- ifc->ifc_type = SNMP_TYPE_TOKEN;
- break;
- case IFT_FDDI:
- default:
- ifc->ifc_type = SNMP_TYPE_OTHER;
- break;
- }
- ifc->ifc_start = elapp->ifThisCableStart;
- ifc->ifc_end = elapp->ifThisCableEnd;
- ifc->ifc_ddpAddr= elapp->ifThisNode;
- ifc->ifc_status = elapp->ifState == LAP_ONLINE ? 1 : 2;
- ifc->ifc_zoneName.len = 0;
- if (elapp->ifZoneName.len != 0) {
- ifc->ifc_zoneName = elapp->ifZoneName;
- }
- else if (elapp->ifDefZone) {
- ifc->ifc_zoneName = ZT_table[elapp->ifDefZone-1].Zone;
- }
- else /* temp, debug only */
- ifc->ifc_zoneName = ZT_table[0].Zone;
- if (ROUTING_MODE) {
- if (elapp->ifFlags & RTR_SEED_PORT) {
- ifc->ifc_netCfg = SNMP_CFG_CONFIGURED;
- ifc->ifc_zoneCfg = SNMP_CFG_CONFIGURED;
- }
- else {
- ifc->ifc_netCfg = SNMP_CFG_GARNERED;
- ifc->ifc_zoneCfg = SNMP_CFG_GARNERED;
- }
- }
- else { /* single-port mode */
- if (elapp->ifRouterState == ROUTER_AROUND) {
- ifc->ifc_netCfg = SNMP_CFG_GARNERED;
- }
- else {
- ifc->ifc_netCfg = SNMP_CFG_GUESSED;
- ifc->ifc_zoneCfg = SNMP_CFG_UNCONFIG;
- }
- }
- }
- }
- snmp->cfg_flags = at_state.flags;
-
-
- return(0);
-}
-
-int at_reg_mcast(ifID, data)
- at_ifaddr_t *ifID;
- caddr_t data;
-{
- struct ifnet *nddp = ifID->aa_ifp;
- struct sockaddr_dl sdl;
-
- if (*(int *)data) {
- if (!nddp) {
- dPrintf(D_M_PAT, D_L_STARTUP, ("pat_mcast: BAD ndpp\n"));
- return(-1);
- }
-
- if (elap_trackMcast(ifID, MCAST_TRACK_ADD, data) == 1)
- return(0);
-
- /* this is for ether_output */
- bzero(&sdl, sizeof(sdl));
- sdl.sdl_family = AF_LINK;
- sdl.sdl_alen = sizeof(struct etalk_addr);
- sdl.sdl_len = offsetof(struct sockaddr_dl, sdl_data)
- + sizeof(struct etalk_addr);
- bcopy(data, sdl.sdl_data, sizeof(struct etalk_addr));
- /* these next two lines should not really be needed XXX */
- sdl.sdl_index = nddp->if_index;
- sdl.sdl_type = IFT_ETHER;
-
- dPrintf(D_M_PAT, D_L_STARTUP,
- ("pat_mcast: adding multicast %08x%04x ifID:0x%x\n",
- *(unsigned*)data, (*(unsigned *)(data+2))&0x0000ffff,
- (unsigned)ifID));
-
- if (if_addmulti_anon(nddp, (struct sockaddr *)&sdl, NULL))
- return -1;
- }
- return 0;
-
-}
-
-int at_unreg_mcast(ifID, data)
- at_ifaddr_t *ifID;
- caddr_t data;
-{
- struct ifnet *nddp = ifID->aa_ifp;
- struct sockaddr_dl sdl;
-
- if (*(int *)data) {
- if (!nddp) {
- dPrintf(D_M_PAT, D_L_STARTUP, ("pat_mcast: BAD ndpp\n"));
- return(-1);
- }
-
- elap_trackMcast(ifID, MCAST_TRACK_DELETE, data);
-
- /* this is for ether_output */
- bzero(&sdl, sizeof(sdl));
- sdl.sdl_family = AF_LINK;
- sdl.sdl_alen = sizeof(struct etalk_addr);
- sdl.sdl_len = offsetof(struct sockaddr_dl, sdl_data)
- + sizeof(struct etalk_addr);
- bcopy(data, sdl.sdl_data, sizeof(struct etalk_addr));
- /* these next two lines should not really be needed XXX */
- sdl.sdl_index = nddp->if_index;
- sdl.sdl_type = IFT_ETHER;
-
- dPrintf(D_M_PAT, D_L_STARTUP,
- ("pat_mcast: deleting multicast %08x%04x ifID:0x%x\n",
- *(unsigned*)data, (*(unsigned *)(data+2))&0x0000ffff,
- (unsigned)ifID));
- bzero(data, sizeof(struct etalk_addr));
-
- if (if_delmulti_anon(nddp, (struct sockaddr *)&sdl))
- return -1;
- }
- return 0;
-}
-#ifdef NOT_YET
-/* *** at_reg_mcast() and at_unreg_mcast() should be replaced as soon as the
- new code to allow an AF_LINK address family multicast to be (un)registered
- using the SIOCADDMULTI / SIOCDELMULTI ioctls has been completed.
-
- The issue is that the "struct sockaddr_dl" needed for the AF_LINK does not
- fit in the "struct ifreq" that is used for these ioctls, and we do not want
- Blue/Classic, which currently uses AF_UNSPEC, to use a different address
- family multicast address than Mac OS X uses.
- *** */
-
-int at_reg_mcast(ifID, data)
- at_ifaddr_t *ifID;
- caddr_t data;
-{
- struct ifnet *nddp = ifID->aa_ifp;
- struct sockaddr_dl sdl;
-
- if (*(int *)data) {
- if (!nddp) {
- dPrintf(D_M_PAT, D_L_STARTUP, ("pat_mcast: BAD ndpp\n"));
- return(-1);
- }
- if (elap_trackMcast(ifID, MCAST_TRACK_ADD, data) == 1)
- return(0);
-
- sdl.sdl_len = sizeof(struct sockaddr_dl);
- sdl.sdl_family = AF_LINK;
- sdl.sdl_index = 0;
- sdl.sdl_type = nddp->if_type;
- sdl.sdl_alen = nddp->if_addrlen;
- sdl.sdl_slen = 0;
- sdl.sdl_nlen = sprintf(sdl.sdl_data, "%s%d",
- nddp->if_name , nddp->if_unit);
- bcopy(data, LLADDR(&sdl), sdl.sdl_alen);
-
- dPrintf(D_M_PAT, D_L_STARTUP,
- ("pat_mcast: adding multicast %08x%04x ifID:0x%x\n",
- *(unsigned*)data, (*(unsigned *)(data+2))&0x0000ffff,
- (unsigned)ifID));
-
- if (if_addmulti_anon(nddp, (struct sockaddr *)&sdl, NULL))
- return -1;
- }
-
- return 0;
-}
-
-int at_unreg_mcast(ifID, data)
- at_ifaddr_t *ifID;
- caddr_t data;
-{
- struct ifnet *nddp = ifID->aa_ifp;
- struct sockaddr_dl sdl;
-
- if (*(int *)data) {
- if (!nddp) {
- dPrintf(D_M_PAT, D_L_STARTUP, ("pat_mcast: BAD ndpp\n"));
- return(-1);
- }
-
- elap_trackMcast(ifID, MCAST_TRACK_DELETE, data);
-
- sdl.sdl_len = sizeof(struct sockaddr_dl);
- sdl.sdl_family = AF_LINK;
- sdl.sdl_index = 0;
- sdl.sdl_type = nddp->if_type;
- sdl.sdl_alen = nddp->if_addrlen;
- sdl.sdl_slen = 0;
- sdl.sdl_nlen = sprintf(sdl.sdl_data, "%s%d",
- nddp->if_name , nddp->if_unit);
-
- dPrintf(D_M_PAT, D_L_STARTUP,
- ("pat_mcast: deleting multicast %08x%04x ifID:0x%x\n",
- *(unsigned*)data, (*(unsigned *)(data+2))&0x0000ffff,
- (unsigned)ifID));
- bzero(data, ETHERNET_ADDR_LEN);
-
- if (if_delmulti_anon(nddp, (struct sockaddr *)&sdl))
- return(-1);
- }
-
- return 0;
-}
-
-#endif