|
|
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.