2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
26 * Copyright (c) 1988, 1989, 1993-1998 Apple Computer, Inc.
29 /* at_elap.c: 2.0, 1.29; 10/4/93; Apple Computer, Inc. */
31 /* This is the file which implements all the streams driver
32 * functionality required for EtherTalk.
37 03-14-94 jjs Changed all functions which assumed only one port would
38 ever be used. Added validate_msg_size, changed elap_online
39 to work with the h/w name only (e.g. 'et2').
41 Modified for MP, 1996 by Tuyen Nguyen
42 Modified, March 17, 1997 by Tuyen Nguyen for MacOSX.
46 #define RESOLVE_DBG /* for debug.h global resolution */
47 #include <sys/errno.h>
48 #include <sys/types.h>
49 #include <sys/param.h>
50 #include <machine/spl.h>
51 #include <sys/systm.h>
52 #include <sys/kernel.h>
54 #include <sys/filedesc.h>
55 #include <sys/fcntl.h>
57 #include <sys/ioctl.h>
58 #include <sys/socket.h>
59 #include <sys/socketvar.h>
60 #include <sys/malloc.h>
61 #include <sys/sockio.h>
62 #include <vm/vm_kern.h> /* for kernel_map */
66 #include <net/if_types.h>
68 #include <netat/sysglue.h>
69 #include <netat/appletalk.h>
70 #include <netat/at_var.h>
71 #include <netat/ddp.h>
72 #include <netat/lap.h>
73 #include <netat/routing_tables.h> /* rtmp+zip table structs */
74 #include <netat/zip.h>
75 #include <netat/nbp.h>
76 #include <netat/at_snmp.h>
77 #include <netat/at_pcb.h>
78 #include <netat/at_aarp.h>
79 #include <netat/asp.h>
80 #include <netat/atp.h>
81 #include <netat/debug.h>
82 #include <netat/adsp.h>
83 #include <netat/adsp_internal.h>
85 #include <sys/kern_event.h>
89 at_ifaddr_t at_interfaces
[IF_TOTAL_MAX
];
90 /* index for at_interfaces is not important */
91 at_ifaddr_t
*ifID_table
[IF_TOTAL_MAX
];
92 /* the table of ifID structures, one per interface
94 * NOTE: for MH, entry 0 in this table is
95 * now defined to be the default I/F
97 at_ifaddr_t
*ifID_home
;
98 /* always ifID_table[IFID_HOME] for now, but will be used for
99 dynamic "home port" assignment, later */
101 at_state_t at_state
; /* global state of AT network */
102 snmpFlags_t snmpFlags
;
107 #define MAX_BUFSIZE 8192
108 #define MAX_RTMP (MAX_BUFSIZE/sizeof(RT_entry)-1)
110 ((MAX_BUFSIZE - SNMP_NBP_HEADER_SIZE)/sizeof(snmpNbpEntry_t)-1)
111 #define MAX_NBP_BYTES (MAX_NBP * sizeof(snmpNbpEntry_t))
112 #define MAX_ZIP (MAX_BUFSIZE/sizeof(ZT_entry)-1)
113 #define MAX_RTMP_BYTES (MAX_RTMP * sizeof(RT_entry))
114 #define MAX_ZIP_BYTES (MAX_ZIP * sizeof(ZT_entry))
117 extern TAILQ_HEAD(name_registry
, _nve_
) name_registry
;
118 extern snmpStats_t snmpStats
;
119 extern atlock_t ddpinp_lock
;
120 extern atlock_t arpinp_lock
;
121 extern short appletalk_inited
;
122 extern int adspInited
;
123 extern struct atpcb ddp_head
;
124 extern gref_t
*atp_inputQ
[];
125 extern struct atp_state
*atp_used_list
;
126 extern asp_scb_t
*asp_scbQ
[];
127 extern asp_scb_t
*scb_used_list
;
128 extern CCB
*adsp_inputQ
[];
129 extern CCB
*ccb_used_list
;
130 extern at_ddp_stats_t at_ddp_stats
;
133 extern snmpAarpEnt_t
* getAarp(int *);
134 extern void nbp_shutdown(), routershutdown(), ddp_brt_shutdown();
135 extern void ddp_brt_init(), rtmp_init(), rtmp_input();
136 extern rtmp_router_start(at_kern_err_t
*);
137 static void getIfNames(at_ifnames_t
*);
138 static void add_route();
139 static int set_zones();
141 static int elap_online1(), re_aarp();
142 int at_reg_mcast(), at_unreg_mcast();
143 void AARPwakeup(), ZIPwakeup();
144 static void elap_hangup();
147 at_ifaddr_t
*find_ifID(if_name
)
153 for (pat_id
=0; pat_id
< xpatcnt
; pat_id
++) {
154 if (!strcmp(at_interfaces
[pat_id
].ifName
, if_name
))
155 return(&at_interfaces
[pat_id
]);
158 return((at_ifaddr_t
*)NULL
);
161 static int validate_msg_size(m
, gref
, elapp
)
166 /* checks ioctl message type for minimum expected message size &
167 sends error back if size invalid
170 register ioc_t
*iocbp
;
171 register at_if_cfg_t
*cfgp
;
175 iocbp
= (ioc_t
*) gbuf_rptr(m
);
177 dPrintf(D_M_ELAP
, D_L_INFO
, ("validate_msg_size: ioc_cmd = %d\n",
179 switch (iocbp
->ioc_cmd
) {
180 case LAP_IOC_ADD_ROUTE
:
181 size
= sizeof(RT_entry
);
183 case LAP_IOC_GET_ROUTE
:
184 size
= sizeof(RT_entry
);
186 case LAP_IOC_GET_ZONE
:
187 size
= sizeof(ZT_entryno
);
189 case LAP_IOC_SNMP_GET_CFG
:
190 case LAP_IOC_SNMP_GET_AARP
:
191 case LAP_IOC_SNMP_GET_ZIP
:
192 case LAP_IOC_SNMP_GET_RTMP
:
193 case LAP_IOC_SNMP_GET_NBP
:
197 case ELAP_IOC_GET_STATS
:
198 case LAP_IOC_SNMP_GET_DDP
:
203 dPrintf(D_M_ELAP
, D_L_ERROR
, ("validate_msg_size: unknown ioctl\n"));
207 if (size
== 0) { /* a non-data ioctl */
211 if (gbuf_cont(m
) != NULL
)
212 i
= gbuf_len(gbuf_cont(m
));
213 if (iocbp
->ioc_count
< size
|| (gbuf_cont(m
) == NULL
) || i
< size
) {
214 dPrintf(D_M_ELAP
, D_L_ERROR
,
215 ("ioctl msg error:s:%d c:%d bcont:%c delta:%d\n",
216 size
, iocbp
->ioc_count
,
217 gbuf_cont(m
)? 'Y' : 'N', i
));
223 ioc_ack(EMSGSIZE
, m
, gref
);
225 } /* validate_msg_size */
227 int lap_online(elapp
, cfgp
)
233 if (elapp
->ifState
!= LAP_OFFLINE
) {
238 if (cfgp
->flags
& ELAP_CFG_HOME
) {
240 /* only 1 home allowed! */
243 dPrintf(D_M_ELAP
, D_L_STARTUP
,
244 ("elap_wput home I/F:%s\n", cfgp
->ifr_name
));
245 elapp
->flags
|= ELAP_CFG_HOME
;
248 if (MULTIPORT_MODE
) {
249 elapp
->flags
|= ELAP_CFG_ZONELESS
;
250 if (ROUTING_MODE
&& cfgp
->netStart
)
251 elapp
->flags
|= ELAP_CFG_SEED
;
254 if (!DEFAULT_ZONE(&cfgp
->zonename
) &&
255 (elapp
->flags
& ELAP_CFG_HOME
) || MULTIHOME_MODE
) {
256 elapp
->startup_zone
= cfgp
->zonename
;
259 if (elapp
->flags
& ELAP_CFG_SEED
) {
260 dPrintf(D_M_ELAP
, D_L_STARTUP_INFO
,
261 ("elap_wput: found to be seed\n"));
262 elapp
->ifThisCableStart
= cfgp
->netStart
;
263 elapp
->ifThisCableEnd
= cfgp
->netEnd
;
266 dPrintf(D_M_ELAP
,D_L_ERROR
,
267 ("elap_wput: we believe we're not seed\n"));
268 /* from ELAP_IOC_SET_CFG */
269 if (ATALK_VALUE(cfgp
->node
)) {
273 initial_node
= cfgp
->node
.s_node
;
274 initial_net
= cfgp
->node
.s_net
;
275 if ((initial_node
<0xfe) && (initial_node
>0) &&
276 !((initial_net
== 0) ||
277 ((initial_net
>= DDP_STARTUP_LOW
)&&
278 (initial_net
<= DDP_STARTUP_HIGH
)))) {
280 elapp
->initial_addr
= cfgp
->node
;
285 elapp
->startup_error
= 0;
286 elapp
->startup_inprogress
= FALSE
;
287 if ((error
= elap_online1(elapp
)))
290 if (!(MULTIPORT_MODE
) &&
291 elapp
->ifZoneName
.len
== 1 &&
292 elapp
->ifZoneName
.str
[0] == '*' &&
293 !DEFAULT_ZONE(&cfgp
->zonename
)) {
294 nbp_add_multicast(&cfgp
->zonename
, elapp
);
299 /***********************************************************************
302 **********************************************************************/
303 int elap_wput(gref
, m
)
308 register ioc_t
*iocbp
;
309 register at_if_cfg_t
*cfgp
;
310 at_elap_stats_t
*statsp
;
317 switch (gbuf_type(m
)) {
320 dPrintf(D_M_ELAP
,D_L_ERROR
,
321 ("Output data to control channel is ignored\n"));
325 iocbp
= (ioc_t
*) gbuf_rptr(m
);
327 if (validate_msg_size(m
, gref
, &elapp
))
331 cfgp
= (at_if_cfg_t
*) gbuf_rptr(gbuf_cont(m
));
333 if (LAP_IOC_MYIOCTL(iocbp
->ioc_cmd
) ||
334 ELAP_IOC_MYIOCTL(iocbp
->ioc_cmd
)) {
336 switch (iocbp
->ioc_cmd
) {
337 case ELAP_IOC_GET_STATS
:
338 #ifdef APPLETALK_DEBUG
339 kprintf("LAP_IOC_GET_STATS\n");
341 if ( (gbuf_cont(m
) == NULL
)
342 || (elapp
= find_ifID(gbuf_rptr(gbuf_cont(m
)))) == NULL
) {
343 ioc_ack(EINVAL
, m
, gref
);
346 gbuf_freem(gbuf_cont(m
));
347 if ((gbuf_cont(m
) =gbuf_alloc(sizeof(at_elap_stats_t
),
349 ioc_ack(ENOBUFS
, m
, gref
);
352 statsp
= ((at_elap_stats_t
*)gbuf_rptr(gbuf_cont(m
)));
353 *statsp
= elapp
->stats
;
354 gbuf_wset(gbuf_cont(m
),sizeof(at_elap_stats_t
));
355 iocbp
->ioc_count
= sizeof(at_elap_stats_t
);
359 case LAP_IOC_ADD_ROUTE
:
360 #ifdef APPLETALK_DEBUG
361 kprintf("LAP_IOC_ADD_ROUTE\n");
363 add_route((RT_entry
*)gbuf_rptr(gbuf_cont(m
)));
367 case LAP_IOC_GET_ZONE
:
368 #ifdef APPLETALK_DEBUG
369 kprintf("LAP_IOC_GET_ZONE\n");
371 /* return next ZT_entryno from ZT_table
372 a pointer to the struct ZT_entryno is passed down from
373 user space and the first byte is cast to a int, if
374 this int is non-zero, then the first ZT_entry is
375 returned and subsequent calls with a zero value
376 will return the next entry in the table. The next
377 read after the last valid entry will return EINVAL
382 i
= *(int *)gbuf_rptr(gbuf_cont(m
));
383 gbuf_freem(gbuf_cont(m
));
386 pZTe
= zt_getNextZone(i
);
388 if ((gbuf_cont(m
) = gbuf_alloc(sizeof(ZT_entryno
), PRI_MED
)) == NULL
) {
389 ioc_ack(ENOBUFS
, m
, gref
);
392 *(ZT_entryno
*)gbuf_rptr(gbuf_cont(m
)) = *pZTe
;
393 gbuf_wset(gbuf_cont(m
),sizeof(ZT_entryno
));
394 iocbp
->ioc_count
= sizeof(ZT_entryno
);
398 ioc_ack(EINVAL
, m
, gref
);
402 case LAP_IOC_GET_ROUTE
:
403 #ifdef APPLETALK_DEBUG
404 kprintf("LAP_IOC_GET_ROUTE\n");
406 /* return next RT_entry from RT_table
407 * a pointer to the struct RT_entry is
408 * passed down from user space and the first
409 * byte is cast to a int, if this int is
410 * non-zero, then the first RT_entry is
411 * returned and subsequent calls with a
412 * zero value will return the next entry in
413 * the table. The next read after the last
414 * valid entry will return EINVAL
419 i
= *(int *)gbuf_rptr(gbuf_cont(m
));
420 gbuf_freem(gbuf_cont(m
));
423 pRT
= rt_getNextRoute(i
);
425 if ((gbuf_cont(m
) = gbuf_alloc(sizeof(RT_entry
), PRI_MED
)) == NULL
) {
426 ioc_ack(ENOBUFS
, m
, gref
);
429 *(RT_entry
*)gbuf_rptr(gbuf_cont(m
)) = *pRT
;
430 gbuf_wset(gbuf_cont(m
),sizeof(RT_entry
));
431 iocbp
->ioc_count
= sizeof(RT_entry
);
435 ioc_ack(EINVAL
, m
, gref
);
439 case LAP_IOC_SNMP_GET_DDP
:
440 #ifdef APPLETALK_DEBUG
441 kprintf("LAP_IOC_SNMP_GET_DDP\n");
443 if (!(at_state
.flags
& AT_ST_STARTED
)) {
444 ioc_ack(ENOTREADY
, m
, gref
);
447 if ((gbuf_cont(m
) = gbuf_alloc(sizeof(snmpStats_t
),
449 ioc_ack(ENOBUFS
, m
, gref
);
453 *(snmpStats_t
*)gbuf_rptr(gbuf_cont(m
)) = snmpStats
;
454 gbuf_wset(gbuf_cont(m
),sizeof(snmpStats
));
455 iocbp
->ioc_count
= sizeof(snmpStats
);
458 case LAP_IOC_SNMP_GET_CFG
:
459 #ifdef APPLETALK_DEBUG
460 kprintf("LAP_IOC_SNMP_GET_CFG\n");
466 i
= *(int *)gbuf_rptr(gbuf_cont(m
));
467 gbuf_freem(gbuf_cont(m
));
469 if (!(at_state
.flags
& AT_ST_STARTED
)) {
471 iocbp
->ioc_count
= 0;
472 ioc_ack(ENOTREADY
, m
, gref
);
473 dPrintf(D_M_ELAP_LOW
, D_L_INFO
,
474 ("elap_wput: cfg req, stack down\n"));
477 if (i
== UPDATE_IF_CHANGED
&&
478 !(at_state
.flags
& AT_ST_IF_CHANGED
)) {
479 iocbp
->ioc_count
= 0;
481 dPrintf(D_M_ELAP_LOW
, D_L_INFO
,
482 ("elap_wput: cfg req, unchanged\n"));
485 dPrintf(D_M_ELAP_LOW
, D_L_INFO
,
486 ("elap_wput: cfg req, changed\n"));
488 if (getSnmpCfg(&snmp
)) {
489 dPrintf(D_M_ELAP
,D_L_ERROR
,
490 ("elap_wput:SNMP_GET_CFG error\n"));
491 ioc_ack(EOPNOTSUPP
, m
, gref
);
494 /* send up only used part of table */
495 size
= sizeof(snmp
) -
496 sizeof(snmpIfCfg_t
) * (MAX_IFS
- snmp
.cfg_ifCnt
);
498 if ((gbuf_cont(m
) = gbuf_alloc(size
, PRI_MED
)) == NULL
) {
499 ioc_ack(ENOBUFS
, m
, gref
);
502 bcopy(&snmp
,gbuf_rptr(gbuf_cont(m
)),size
);
503 gbuf_wset(gbuf_cont(m
),size
);
504 iocbp
->ioc_count
= size
;
505 at_state
.flags
&= ~AT_ST_IF_CHANGED
;
510 case LAP_IOC_SNMP_GET_AARP
:
512 snmpAarpEnt_t
*snmpp
;
514 #ifdef APPLETALK_DEBUG
515 kprintf("LAP_IOC_SNMP_GET_AARP\n");
517 i
= *(int *)gbuf_rptr(gbuf_cont(m
));
518 gbuf_freem(gbuf_cont(m
));
520 dPrintf(D_M_ELAP
,D_L_INFO
,
521 ("elap_wput:calling getarp,i=%d\n", i
));
523 bytes
= i
* sizeof(snmpAarpEnt_t
);
524 dPrintf(D_M_ELAP
,D_L_INFO
,
525 ("elap_wput:getarp returned, i=%d,bytes=%d\n",
528 if ((gbuf_cont(m
) = gbuf_alloc(bytes
, PRI_MED
)) == NULL
) {
529 ioc_ack(ENOBUFS
, m
, gref
);
532 bcopy(snmpp
, gbuf_rptr(gbuf_cont(m
)), bytes
);
533 gbuf_wset(gbuf_cont(m
),bytes
);
534 iocbp
->ioc_count
= bytes
;
538 ioc_ack(EOPNOTSUPP
, m
, gref
);
542 case LAP_IOC_SNMP_GET_ZIP
:
543 #ifdef APPLETALK_DEBUG
544 kprintf("LAP_IOC_SNMP_GET_ZIP\n");
546 { /* matching brace NOT in this case */
548 register int size
, total
, tabsize
;
549 gbuf_t
*mn
; /* new gbuf */
550 gbuf_t
*mo
; /* old gbuf */
551 gbuf_t
*mt
; /* temp */
554 i
= *(int *)gbuf_rptr(gbuf_cont(m
));
555 gbuf_freem(gbuf_cont(m
));
557 if (!(at_state
.flags
& AT_ST_STARTED
)) {
558 ioc_ack(ENOTREADY
, m
, gref
);
561 if (i
== UPDATE_IF_CHANGED
&&
562 !(at_state
.flags
& AT_ST_ZT_CHANGED
)) {
563 iocbp
->ioc_count
= 0;
568 tabsize
= getZipTableSize();
570 /* retrieve table into multiple gbufs */
571 for (i
=0; i
<tabsize
; i
+=j
) {
573 MAX_ZIP
? MAX_ZIP
: tabsize
- i
;
574 size
= j
< MAX_ZIP
? sizeof(ZT_entry
)*j
: MAX_ZIP_BYTES
;
575 if ((mn
= gbuf_alloc(size
, PRI_MED
)) == NULL
) {
577 gbuf_freem(gbuf_cont(m
));
578 ioc_ack(ENOBUFS
, m
, gref
);
581 if (!mo
) { /* if first new one */
590 getZipTable((ZT_entry
*)gbuf_rptr(mn
),i
,j
);
593 if ((gbuf_cont(m
) = gbuf_alloc(sizeof(int), PRI_MED
)) == NULL
) {
596 iocbp
->ioc_count
= 0;
597 ioc_ack(ENOBUFS
, m
, gref
);
601 dPrintf(D_M_ELAP
,D_L_WARNING
,
602 ("elap_wput:snmp: empty zip table\n"));
605 *(int*)gbuf_rptr(gbuf_cont(m
)) = total
; /* return table size */
606 gbuf_wset(gbuf_cont(m
),sizeof(int));
607 iocbp
->ioc_count
= sizeof(int);
610 atalk_putnext(gref
,mt
); /* send up table */
611 at_state
.flags
&= ~AT_ST_ZT_CHANGED
;
614 case LAP_IOC_SNMP_GET_RTMP
:
615 #ifdef APPLETALK_DEBUG
616 kprintf("LAP_IOC_SNMP_GET_RTMP\n");
618 i
= *(int *)gbuf_rptr(gbuf_cont(m
));
619 gbuf_freem(gbuf_cont(m
));
621 if (!(at_state
.flags
& AT_ST_STARTED
)) {
622 ioc_ack(ENOTREADY
, m
, gref
);
625 if (i
== UPDATE_IF_CHANGED
&&
626 !(at_state
.flags
& AT_ST_RT_CHANGED
)) {
627 iocbp
->ioc_count
= 0;
633 tabsize
= getRtmpTableSize();
635 /* retrieve table into multiple gbufs */
636 for (i
=0; i
<tabsize
; i
+=j
) {
638 MAX_RTMP
? MAX_RTMP
: tabsize
- i
;
639 size
= j
< MAX_RTMP
? sizeof(RT_entry
)*j
: MAX_RTMP_BYTES
;
640 if ((mn
= gbuf_alloc(size
, PRI_MED
)) == NULL
) {
642 gbuf_freem(gbuf_cont(m
));
643 ioc_ack(ENOBUFS
, m
, gref
);
646 if (!mo
) { /* if first new one */
655 getRtmpTable((RT_entry
*)gbuf_rptr(mn
),i
,j
);
658 if ((gbuf_cont(m
) = gbuf_alloc(sizeof(int), PRI_MED
)) == NULL
) {
661 iocbp
->ioc_count
= 0;
662 ioc_ack(ENOBUFS
, m
, gref
);
667 *(int*)gbuf_rptr(gbuf_cont(m
)) = total
; /* return table size */
668 gbuf_wset(gbuf_cont(m
),sizeof(int));
669 iocbp
->ioc_count
= sizeof(int);
672 atalk_putnext(gref
,mt
); /* send up table */
673 at_state
.flags
&= ~AT_ST_RT_CHANGED
;
676 case LAP_IOC_SNMP_GET_NBP
:
677 #ifdef APPLETALK_DEBUG
678 kprintf("LAP_IOC_SNMP_GET_NBP\n");
680 i
= *(int *)gbuf_rptr(gbuf_cont(m
));
681 gbuf_freem(gbuf_cont(m
));
683 if (!(at_state
.flags
& AT_ST_STARTED
)) {
684 ioc_ack(ENOTREADY
, m
, gref
);
687 if (i
== UPDATE_IF_CHANGED
&&
688 !(at_state
.flags
& AT_ST_NBP_CHANGED
)) {
689 iocbp
->ioc_count
= 0;
691 dPrintf(D_M_ELAP_LOW
, D_L_INFO
,
692 ("elap_wput: nbp req denied, no change\n"));
697 tabsize
= getNbpTableSize();
699 /* retrieve table into multiple gbufs */
700 for (i
=0; i
<tabsize
; i
+=j
) {
702 MAX_NBP
? MAX_NBP
: tabsize
- i
;
703 size
= j
< MAX_NBP
? sizeof(snmpNbpEntry_t
)*j
: MAX_NBP_BYTES
;
705 size
+= SNMP_NBP_HEADER_SIZE
;
706 if ((mn
= gbuf_alloc(size
, PRI_MED
)) == NULL
) {
708 gbuf_freem(gbuf_cont(m
));
709 ioc_ack(ENOBUFS
, m
, gref
);
712 if (!mo
) { /* if first new one */
715 nbp
= (snmpNbpTable_t
*)gbuf_rptr(mn
);
716 nbp
->nbpt_entries
= tabsize
;
717 nbp
->nbpt_zone
= ifID_home
->ifZoneName
;
718 getNbpTable(nbp
->nbpt_table
,i
,j
);
723 getNbpTable((snmpNbpEntry_t
*)gbuf_rptr(mn
),i
,j
);
728 if ((gbuf_cont(m
) = gbuf_alloc(sizeof(int), PRI_MED
)) == NULL
) {
731 iocbp
->ioc_count
= 0;
732 ioc_ack(ENOBUFS
, m
, gref
);
737 *(int*)gbuf_rptr(gbuf_cont(m
)) = total
; /* return table size */
738 gbuf_wset(gbuf_cont(m
),sizeof(int));
739 iocbp
->ioc_count
= sizeof(int);
742 atalk_putnext(gref
,mt
); /* send up table */
743 at_state
.flags
&= ~AT_ST_NBP_CHANGED
;
748 #ifdef APPLETALK_DEBUG
749 kprintf("unknown ioctl %d\n", iocbp
->ioc_cmd
);
751 ioc_ack(ENOTTY
, m
, gref
);
752 dPrintf(D_M_ELAP
, D_L_WARNING
,
753 ("elap_wput: unknown ioctl (%d)\n", iocbp
->ioc_cmd
));
756 elapp
->stats
.unknown_mblks
++;
771 /* Called directly by ddp/zip.
773 elap_dataput(m
, elapp
, addr_flag
, addr
)
775 register at_ifaddr_t
*elapp
;
781 extern int zip_type_packet();
782 struct etalk_addr dest_addr
;
783 struct atalk_addr dest_at_addr
;
784 extern gbuf_t
*growmsg();
786 /* flag to aarp to loopback (default) */
788 /* the incoming frame is of the form {flag, address, ddp...}
789 * where "flag" indicates whether the address is an 802.3
790 * (link) address, or an appletalk address. If it's an
791 * 802.3 address, the packet can just go out to the network
792 * through PAT, if it's an appletalk address, AT->802.3 address
793 * resolution needs to be done.
794 * If 802.3 address is known, strip off the flag and 802.3
795 * address, and prepend 802.2 and 802.3 headers.
799 addr_flag
= *(u_char
*)gbuf_rptr(m
);
804 case AT_ADDR_NO_LOOP
:
809 dest_at_addr
= *(struct atalk_addr
*)gbuf_rptr(m
);
810 gbuf_rinc(m
,sizeof(struct atalk_addr
));
812 dest_at_addr
= *(struct atalk_addr
*)addr
;
816 dest_addr
= *(struct etalk_addr
*)gbuf_rptr(m
);
817 gbuf_rinc(m
,sizeof(struct etalk_addr
));
819 dest_addr
= *(struct etalk_addr
*)addr
;
822 gbuf_freel(m
); /* unknown address type, chuck it */
828 /* At this point, rptr points to ddp header for sure */
829 if (elapp
->ifState
== LAP_OFFLINE
) {
834 if (elapp
->ifState
== LAP_ONLINE_FOR_ZIP
) {
835 /* see if this is a ZIP packet that we need
836 * to let through even though network is
839 if (zip_type_packet(m
) == 0) {
845 elapp
->stats
.xmit_packets
++;
846 size
= gbuf_msgsize(m
);
847 elapp
->stats
.xmit_bytes
+= size
;
848 snmpStats
.dd_outLong
++;
851 case AT_ADDR_NO_LOOP
:
854 * we don't want elap to be looking into ddp header, so
855 * it doesn't know net#, consequently can't do
856 * AMT_LOOKUP. That task left to aarp now.
858 error
= aarp_send_data(m
,elapp
,&dest_at_addr
, loop
);
861 error
= pat_output(elapp
, m
, &dest_addr
, 0);
867 /************************************************************************
870 ************************************************************************/
872 static int elap_online1(elapp
)
877 dPrintf(D_M_ELAP
, D_L_STARTUP_INFO
, ("elap_online:%s elapp:0x%x\n",
878 (elapp
->ifName
) ? &elapp
->ifName
[0] : "NULL interface", (u_int
) elapp
));
879 if (elapp
->ifState
!= LAP_OFFLINE
|| elapp
->startup_inprogress
== TRUE
)
882 at_state
.flags
|= AT_ST_IF_CHANGED
;
884 if (elapp
->flags
& ELAP_CFG_HOME
) /* tell ddp_add_if if this is home */
885 elapp
->ifFlags
|= AT_IFF_DEFAULT
;
887 /* Get DDP started */
888 if ((errno
= ddp_add_if(elapp
)))
891 /* set up multicast address for cable-wide broadcasts */
892 (void)at_reg_mcast(elapp
, (caddr_t
)&elapp
->cable_multicast_addr
);
894 elapp
->startup_inprogress
= TRUE
;
895 if (! (elapp
->startup_error
= re_aarp(elapp
)))
896 (void)tsleep(&elapp
->startup_inprogress
, PSOCK
| PCATCH
,
899 /* then later, after some timeouts AARPwakeup() is called */
901 return(elapp
->startup_error
);
904 static int re_aarp(elapp
)
909 /* We now call aarp_init() to assign an appletalk node addr */
910 errno
= aarp_init1(elapp
);
911 /* aarp_init1() returns either -1 or ENOTREADY */
912 if (errno
== ENOTREADY
)
915 dPrintf(D_M_ELAP
, D_L_STATE_CHG
,
916 ("elap_online aarp_init for %s\n", elapp
->ifName
));
917 (void)at_unreg_mcast(elapp
, (caddr_t
)&elapp
->cable_multicast_addr
);
919 elapp
->ifState
= LAP_OFFLINE
;
920 return(EADDRNOTAVAIL
);
924 /* called from AARPwakeup */
925 static void elap_online2(elapp
)
928 if (MULTIPORT_MODE
) {
929 dPrintf(D_M_ELAP
,D_L_STARTUP_INFO
,
930 ("elap_online: re_aarp, we know it's a router...\n"));
932 if (elapp
->flags
& ELAP_CFG_SEED
) {
933 /* add route table entry (zones to be added later) */
934 dPrintf(D_M_ELAP
, D_L_STARTUP_INFO
,
935 ("elap_online: rt_insert Cable %d-%d port =%d as SEED\n",
936 elapp
->ifThisCableStart
, elapp
->ifThisCableEnd
, elapp
->ifPort
));
937 rt_insert(elapp
->ifThisCableEnd
,
938 elapp
->ifThisCableStart
,
941 RTE_STATE_PERMANENT
| RTE_STATE_ZKNOWN
| RTE_STATE_GOOD
943 /* LD 081694: set the RTR_SEED_PORT flag for seed ports */
944 elapp
->ifFlags
|= RTR_SEED_PORT
;
947 dPrintf(D_M_ELAP
,D_L_STARTUP_INFO
,
948 ("elap_online: it's a router, but non seed\n"));
951 if (elapp
->flags
& ELAP_CFG_ZONELESS
) {
952 /* ELAP_CFG_ZONELESS tells us that it is a router or in
953 multihome mode, so we don't want to do the GetNetInfo
954 exchange with the router. */
956 elapp
->ifState
= LAP_ONLINE_ZONELESS
;
957 elapp
->startup_inprogress
= FALSE
;
958 wakeup(&elapp
->startup_inprogress
);
959 dPrintf(D_M_ELAP
, D_L_STARTUP_INFO
, ("elap_online: ack 3\n"));
963 /* if we don't already have a zone and a multicast address */
964 if (*(int *)&elapp
->ZoneMcastAddr
== 0 || elapp
->ifZoneName
.len
== 0) {
965 /* hzonehash is a global containing the nbp hash for the startup_zone */
968 /* Get ZIP rolling to get zone multicast address, etc. */
969 elapp
->ifState
= LAP_ONLINE_FOR_ZIP
;
970 (void)zip_control(elapp
, ZIP_ONLINE
);
971 /* zip_control (w. control == ZIP_ONLINE) always returns ENOTREADY */
973 /* later, after some timeouts ZIPwakeup() is called. */
975 /* otherwise, we have the zone and the multicast already,
976 so don't bother with another ZIP GetNetInfo request */
981 /* called from rtmp_router_start */
982 int elap_online3(elapp
)
985 elapp
->startup_inprogress
= TRUE
;
987 /* just reset the net range */
988 elapp
->initial_addr
.s_net
= 0;
989 elapp
->initial_addr
.s_node
= 0;
990 dPrintf(D_M_ELAP_LOW
, D_L_STARTUP_INFO
,
991 ("elap_online: goto re_aarp port=%d\n", elapp
->ifPort
));
993 if ((elapp
->startup_error
= re_aarp(elapp
)))
994 return(elapp
->startup_error
);
996 /* then later, after some timeouts AARPwakeup() is called */
998 (void)tsleep(&elapp
->startup_inprogress
, PSOCK
| PCATCH
,
1000 return(elapp
->startup_error
);
1001 } /* elap_online3 */
1003 /****************************************************************************
1006 ****************************************************************************/
1008 void elap_offline(elapp
)
1009 register at_ifaddr_t
*elapp
;
1012 void zip_sched_getnetinfo(); /* forward reference */
1016 dPrintf(D_M_ELAP
, D_L_SHUTDN_INFO
, ("elap_offline:%s\n", elapp
->ifName
));
1017 if (elapp
->ifState
!= LAP_OFFLINE
) {
1019 /* Since AppleTalk is going away, remove the cable
1020 * multicast address and turn the interface off so that all
1021 * AppleTalk packets are dropped in the driver itself.
1022 * Get rid of the zone multicast address prior to going Offline.
1024 (void)at_unreg_mcast(elapp
, (caddr_t
)&elapp
->ZoneMcastAddr
);
1025 (void)at_unreg_mcast(elapp
, (caddr_t
)&elapp
->cable_multicast_addr
);
1026 elapp
->ifState
= LAP_OFFLINE
;
1028 ATDISABLE(s
, ddpinp_lock
);
1030 RT_DELETE(elapp
->ifThisCableEnd
,
1031 elapp
->ifThisCableStart
);
1032 ATENABLE(s
, ddpinp_lock
);
1034 /* make sure no zip timeouts are left running */
1035 untimeout(zip_sched_getnetinfo
, elapp
);
1038 } /* elap_offline */
1041 static void add_route(rt
)
1044 /* support ioctl to manually add routes to table.
1045 this is really only for testing
1048 rt_insert( rt
->NetStop
, rt
->NetStart
, rt
->NextIRNet
,
1049 rt
->NextIRNode
, rt
->NetDist
, rt
->NetPort
,
1051 dPrintf(D_M_ELAP
, D_L_STARTUP_INFO
, ("adding route: %ud:%ud dist:%ud\n",
1052 rt
->NetStart
, rt
->NetStop
,rt
->NetDist
));
1058 * Initialization that takes place each time AppleTalk is restarted.
1063 TAILQ_INIT(&at_ifQueueHd
);
1064 TAILQ_INIT(&name_registry
);
1065 bzero(at_interfaces
, sizeof(at_interfaces
));
1066 bzero(ifID_table
, sizeof(ifID_table
));
1067 bzero(&at_ddp_stats
, sizeof(at_ddp_stats_t
));
1068 rtmp_init(); /* initialize trackedrouters */
1070 add_ddp_handler(RTMP_SOCKET
, rtmp_input
);
1071 ifID_home
= (at_ifaddr_t
*)NULL
;
1075 int ddp_shutdown(count_only
)
1079 asp_scb_t
*scb
, *scb_next
;
1080 struct atp_state
*atp
, *atp_next
;
1083 vm_offset_t temp_rcb_data
, temp_state_data
;
1084 int i
, s
, active_skts
= 0; /* count of active pids for non-socketized
1085 AppleTalk protocols */
1086 extern int aarp_sched_probe();
1089 /* Network is shutting down... send error messages up on each open
1091 *** For now, for ASP, ATP and ADSP, attempt to notify open
1092 sockets, but return EBUSY and don't complete shutdown. ***
1095 s
= splimp(); /* *** previously contained mismatched locking
1096 that was ifdef'ed to splimp() *** */
1098 nbp_shutdown(); /* clear all known NVE */
1101 for (scb
= scb_used_list
; scb
; ) {
1102 scb_next
= scb
->next_scb
;
1105 dPrintf(D_M_ASP
, D_L_TRACE
, ("asp pid=%d\n", scb
->pid
));
1106 atalk_notify(scb
->gref
, ESHUTDOWN
);
1110 for (i
= 0; i
< 256 ; i
++) {
1111 if ((scb
= asp_scbQ
[i
]))
1113 scb_next
= scb
->next_scb
;
1116 dPrintf(D_M_ASP
, D_L_TRACE
,
1117 ("asp pid=%d\n", scb
->pid
));
1118 atalk_notify(scb
->gref
, ESHUTDOWN
);
1125 for (atp
= atp_used_list
; atp
; ) {
1126 atp_next
= atp
->atp_trans_waiting
;
1129 dPrintf(D_M_ATP
, D_L_TRACE
, ("atp pid=%d\n", atp
->atp_pid
));
1130 atalk_notify(atp
->atp_gref
, ESHUTDOWN
);
1134 for (i
= 0; i
< 256; i
++) {
1135 if ((gref
= atp_inputQ
[i
]) && (gref
!= (gref_t
*)1)) {
1136 atp
= (struct atp_state
*)gref
->info
;
1140 dPrintf(D_M_ATP
, D_L_TRACE
,
1141 ("atp pid=%d\n", atp
->atp_pid
));
1142 atalk_notify(atp
->atp_gref
, ESHUTDOWN
);
1149 for (sp
= ccb_used_list
; sp
; ) {
1150 sp_next
= sp
->otccbLink
;
1153 dPrintf(D_M_ADSP
, D_L_TRACE
, ("adsp pid=%d\n", sp
->pid
));
1154 atalk_notify(sp
->gref
, ESHUTDOWN
);
1158 for (i
= 0; i
< 256 ; i
++) {
1159 if ((sp
= adsp_inputQ
[i
]))
1161 sp_next
= sp
->otccbLink
;
1164 dPrintf(D_M_ADSP
, D_L_TRACE
,
1165 ("adsp pid=%d\n", sp
->pid
));
1166 atalk_notify(sp
->gref
, ESHUTDOWN
);
1173 for (gref
= ddp_head
.atpcb_next
; gref
!= &ddp_head
;
1174 gref
= gref
->atpcb_next
) {
1178 dPrintf(D_M_DDP
,D_L_TRACE
, ("ddp pid=%d\n", gref
->pid
));
1179 atalk_notify(gref
, ESHUTDOWN
);
1182 if (count_only
|| active_skts
) {
1184 return(active_skts
);
1187 /* if there are no interfaces in the process of going online, continue shutting down DDP */
1188 for (i
= 0; i
< IF_TOTAL_MAX
; i
++) {
1189 if (at_interfaces
[i
].startup_inprogress
== TRUE
)
1192 if (MULTIPORT_MODE
) {
1194 /* free memory allocated for the rtmp/zip tables */
1196 FREE(ZT_table
, M_RTABLE
);
1197 ZT_table
= (ZT_entry
*)NULL
;
1200 FREE(RT_table
, M_RTABLE
);
1201 RT_table
= (RT_entry
*)NULL
;
1205 at_state
.flags
= 0; /* make sure inits are done on restart */
1207 wakeup(&ifID_home
->startup_inprogress
); /* if rtmp_router_start still starting up */
1209 /* from original ddp_shutdown() */
1219 dPrintf(D_M_DDP
, D_L_VERBOSE
, ("DDP shutdown completed"));
1222 * make sure we don't have a probe timeout hanging around
1223 * it's going to try and make use of an entry in at_interfaces
1224 * which is going to be zero'd out by the call to ddp_start a
1225 * little further down
1227 untimeout(aarp_sched_probe
, 0);
1229 /* *** after an SIOCSIFADDR and before an AIOCSIFADDR,
1230 this is the only place to find the ifID *** */
1231 for (i
= 0; i
< IF_TOTAL_MAX
; i
++) {
1232 ifID
= &at_interfaces
[i
];
1233 /* do LAP_IOC_OFFLINE processing */
1238 /* free buffers for large arrays used by atp.
1239 * to prevent a race condition if the funnel is dropped
1240 * while calling kmem_free, the fields are grabbed and
1243 if (atp_rcb_data
!= NULL
) {
1244 temp_rcb_data
= (vm_offset_t
)atp_rcb_data
;
1245 atp_rcb_data
= NULL
;
1246 atp_rcb_free_list
= NULL
;
1248 temp_rcb_data
= NULL
;
1249 if (atp_state_data
!= NULL
) {
1250 temp_state_data
= (vm_offset_t
)atp_state_data
;
1251 atp_state_data
= NULL
;
1252 atp_free_list
= NULL
;
1254 temp_state_data
= NULL
;
1257 kmem_free(kernel_map
, temp_rcb_data
, sizeof(struct atp_rcb
) * NATP_RCB
);
1258 if (temp_state_data
)
1259 kmem_free(kernel_map
, temp_state_data
, sizeof(struct atp_state
) * NATP_STATE
);
1263 } /* ddp_shutdown */
1265 int routerStart(keP
)
1268 register at_ifaddr_t
*ifID
;
1275 * this will cause the ports to glean from the net the relevant
1276 * information before forwarding
1278 TAILQ_FOREACH(ifID
, &at_ifQueueHd
, aa_link
) {
1279 dPrintf(D_M_ELAP
, D_L_STARTUP_INFO
,
1280 ("routerStart Port %d (%s) set to activating\n",
1281 ifID
->ifPort
, ifID
->ifName
));
1282 ifID
->ifRoutingState
= PORT_ACTIVATING
;
1283 ifID
->ifFlags
|= RTR_XNET_PORT
;
1287 * The next step is to check the information for each port before
1288 * declaring the ports up and forwarding
1290 dPrintf(D_M_ELAP
, D_L_STARTUP_INFO
,
1291 ("router_start: waiting 20 sec before starting up\n"));
1293 /* sleep for 20 seconds */
1295 /* *** eventually this will be the ifID for the interface
1296 being brought up in router mode *** */
1297 tsleep(&ifID_home
->startup_inprogress
,
1298 PSOCK
| PCATCH
, "routerStart", 20 * SYS_HZ
))
1302 panic("routerStart: spurious interrupt");
1307 return(rtmp_router_start(keP
));
1308 /* was timeout(rtmp_router_start, 0, 20 * SYS_HZ); */
1311 void ZIPwakeup(elapp
, ZipError
)
1315 int s
, error
= ZipError
;
1317 ATDISABLE(s
, ddpinp_lock
);
1318 if ( (elapp
!= NULL
) && elapp
->startup_inprogress
) {
1319 ATENABLE(s
, ddpinp_lock
);
1321 /* was ZIPContinue */
1322 /* was elapp_online() with jump to ZIP_sleep */
1324 /* instead of the goto ZIP_sleep ... */
1326 case 0 : /* success */
1327 elapp
->ifState
= LAP_ONLINE
;
1329 /* Send event with zone info. */
1330 atalk_post_msg(elapp
->aa_ifp
, KEV_ATALK_ZONEUPDATED
, 0, &(elapp
->ifZoneName
));
1334 /* instead of goto re_aarp; */
1335 /* We now call aarp_init() to assign an
1336 appletalk node addr */
1337 if ((elapp
->startup_error
= re_aarp(elapp
))) {
1338 elapp
->startup_inprogress
= FALSE
;
1339 wakeup(&elapp
->startup_inprogress
);
1340 dPrintf(D_M_ELAP
, D_L_STARTUP_INFO
,
1341 ("elap_online: ack 2\n"));
1347 if (ZipError
!= ZIP_RE_AARP
) {
1348 elapp
->startup_error
= error
;
1349 elapp
->startup_inprogress
= FALSE
;
1350 wakeup(&elapp
->startup_inprogress
);
1351 dPrintf(D_M_ELAP
, D_L_STARTUP_INFO
,
1352 ("elap_online: ifZipError=%d\n", error
));
1355 ATENABLE(s
, ddpinp_lock
);
1358 void AARPwakeup(probe_cb
)
1359 aarp_amt_t
*probe_cb
;
1365 ATDISABLE(s
, arpinp_lock
);
1366 elapp
= probe_cb
->elapp
;
1367 if ( (elapp
!= NULL
) && elapp
->startup_inprogress
) {
1368 ATENABLE(s
, arpinp_lock
);
1370 /* was AARPContinue */
1371 errno
= aarp_init2(elapp
);
1372 /* aarp_init2() returns either -1 or 0 */
1374 dPrintf(D_M_ELAP
, D_L_STATE_CHG
,
1375 ("elap_online aarp_init for %s\n",
1377 (void)at_unreg_mcast(elapp
, (caddr_t
)&elapp
->ZoneMcastAddr
);
1378 (void)at_unreg_mcast(elapp
, (caddr_t
)&elapp
->cable_multicast_addr
);
1379 elapp
->ifState
= LAP_OFFLINE
;
1381 elapp
->startup_error
= EADDRNOTAVAIL
;
1382 elapp
->startup_inprogress
= FALSE
;
1383 wakeup(&elapp
->startup_inprogress
);
1384 dPrintf(D_M_ELAP
, D_L_STARTUP_INFO
, ("elap_online: ack 2\n"));
1386 dPrintf(D_M_ELAP
,D_L_STARTUP_INFO
,
1387 ("elap_online: aarp_init returns zero\n"));
1388 elap_online2(elapp
);
1391 ATENABLE(s
, arpinp_lock
);
1394 void ddp_bit_reverse(addr
)
1395 unsigned char *addr
;
1397 static unsigned char reverse_data
[] = {
1398 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
1399 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
1400 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
1401 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
1402 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
1403 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
1404 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
1405 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
1406 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
1407 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
1408 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
1409 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
1410 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
1411 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
1412 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
1413 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
1414 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
1415 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
1416 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
1417 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
1418 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
1419 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
1420 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
1421 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
1422 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
1423 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
1424 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
1425 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
1426 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
1427 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
1428 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
1429 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
1434 for (k
=0; k
< 6; k
++)
1435 addr
[k
] = reverse_data
[addr
[k
]];
1438 static int elap_trackMcast(patp
, func
, addr
)
1445 switch(patp
->aa_ifp
->if_type
) {
1448 /* set addr to point to unique part of addr */
1451 /* first try to find match */
1452 /* *** save just one byte of the multicast address? *** */
1453 for (i
=0; i
< MAX_MCASTS
; i
++)
1454 if (c
== patp
->mcast
[i
]) {
1460 case MCAST_TRACK_DELETE
:
1462 patp
->mcast
[loc
] = 0;
1465 case MCAST_TRACK_ADD
:
1466 dPrintf(D_M_PAT_LOW
, D_L_USR2
, ("mctrack:add loc:%d\n", i
));
1468 dPrintf(D_M_PAT_LOW
, D_L_USR2
, ("mctrack:add, addr was there\n"));
1470 break; /* already there */
1472 for (i
=0; i
< MAX_MCASTS
; i
++)
1473 if (patp
->mcast
[i
] == 0) {
1477 dPrintf(D_M_PAT_LOW
, D_L_USR2
, ("mctrack:add1 loc:%d\n", i
));
1479 patp
->mcast
[loc
] = c
;
1480 dPrintf(D_M_PAT_LOW
, D_L_USR2
, ("mctrack:add, adding(%x)\n",
1481 (*(int*)addr
)&0xffffff));
1484 /*errno = ENOMEM; */ /*LD 5/7/97 nobody is using that */
1488 case MCAST_TRACK_CHECK
:
1490 dPrintf(D_M_PAT_LOW
, D_L_USR2
, ("mctrack:check, addr was there\n"));
1494 dPrintf(D_M_PAT_LOW
, D_L_USR2
, ("mctrack:add, addr was NOT there\n"));
1499 /*errno = EINVAL;*/ /*LD 5/7/97 nobody is using that */
1503 case IFT_ISO88025
: /* token ring */
1504 /* we would use the lowest byte of the addr argument as a value
1505 to shift left a 1 to form the mcast mask for TR. We'll do this
1515 static getSnmpCfg(snmp
)
1522 snmp
->cfg_ifCnt
= 0;
1524 bzero(snmp
,sizeof(snmpCfg_t
));
1525 for (i
=0, elapp
=at_interfaces
,ifc
=snmp
->cfg_ifCfg
;
1526 i
<IF_TOTAL_MAX
; i
++, elapp
++, ifc
++) {
1527 if (elapp
->ifState
!= LAP_OFFLINE
) {
1529 strncpy(ifc
->ifc_name
,elapp
->ifName
, sizeof(ifc
->ifc_name
));
1530 ifc
->ifc_aarpSize
= getAarpTableSize(i
);
1531 ifc
->ifc_addrSize
= getPhysAddrSize(i
);
1532 switch (elapp
->aa_ifp
->if_type
) {
1534 ifc
->ifc_type
= SNMP_TYPE_ETHER2
;
1536 case IFT_ISO88025
: /* token ring */
1537 ifc
->ifc_type
= SNMP_TYPE_TOKEN
;
1541 ifc
->ifc_type
= SNMP_TYPE_OTHER
;
1544 ifc
->ifc_start
= elapp
->ifThisCableStart
;
1545 ifc
->ifc_end
= elapp
->ifThisCableEnd
;
1546 ifc
->ifc_ddpAddr
= elapp
->ifThisNode
;
1547 ifc
->ifc_status
= elapp
->ifState
== LAP_ONLINE
? 1 : 2;
1548 ifc
->ifc_zoneName
.len
= 0;
1549 if (elapp
->ifZoneName
.len
!= 0) {
1550 ifc
->ifc_zoneName
= elapp
->ifZoneName
;
1552 else if (elapp
->ifDefZone
) {
1553 ifc
->ifc_zoneName
= ZT_table
[elapp
->ifDefZone
-1].Zone
;
1555 else /* temp, debug only */
1556 ifc
->ifc_zoneName
= ZT_table
[0].Zone
;
1558 if (elapp
->ifFlags
& RTR_SEED_PORT
) {
1559 ifc
->ifc_netCfg
= SNMP_CFG_CONFIGURED
;
1560 ifc
->ifc_zoneCfg
= SNMP_CFG_CONFIGURED
;
1563 ifc
->ifc_netCfg
= SNMP_CFG_GARNERED
;
1564 ifc
->ifc_zoneCfg
= SNMP_CFG_GARNERED
;
1567 else { /* single-port mode */
1568 if (elapp
->ifRouterState
== ROUTER_AROUND
) {
1569 ifc
->ifc_netCfg
= SNMP_CFG_GARNERED
;
1572 ifc
->ifc_netCfg
= SNMP_CFG_GUESSED
;
1573 ifc
->ifc_zoneCfg
= SNMP_CFG_UNCONFIG
;
1578 snmp
->cfg_flags
= at_state
.flags
;
1584 int at_reg_mcast(ifID
, data
)
1588 struct ifnet
*nddp
= ifID
->aa_ifp
;
1593 dPrintf(D_M_PAT
, D_L_STARTUP
, ("pat_mcast: BAD ndpp\n"));
1597 if (elap_trackMcast(ifID
, MCAST_TRACK_ADD
, data
) == 1)
1600 /* this is for ether_output */
1601 sa
.sa_family
= AF_UNSPEC
;
1602 sa
.sa_len
= 2 + sizeof(struct etalk_addr
);
1603 bcopy (data
, &sa
.sa_data
[0], sizeof(struct etalk_addr
));
1605 dPrintf(D_M_PAT
, D_L_STARTUP
,
1606 ("pat_mcast: adding multicast %08x%04x ifID:0x%x\n",
1607 *(unsigned*)data
, (*(unsigned *)(data
+2))&0x0000ffff,
1610 if (if_addmulti(nddp
, &sa
, 0))
1617 int at_unreg_mcast(ifID
, data
)
1621 struct ifnet
*nddp
= ifID
->aa_ifp
;
1626 dPrintf(D_M_PAT
, D_L_STARTUP
, ("pat_mcast: BAD ndpp\n"));
1630 elap_trackMcast(ifID
, MCAST_TRACK_DELETE
, data
);
1632 /* this is for ether_output */
1633 sa
.sa_family
= AF_UNSPEC
;
1634 sa
.sa_len
= 2 + sizeof(struct etalk_addr
);
1635 bcopy (data
, &sa
.sa_data
[0], sizeof(struct etalk_addr
));
1637 dPrintf(D_M_PAT
, D_L_STARTUP
,
1638 ("pat_mcast: deleting multicast %08x%04x ifID:0x%x\n",
1639 *(unsigned*)data
, (*(unsigned *)(data
+2))&0x0000ffff,
1641 bzero(data
, sizeof(struct etalk_addr
));
1643 if (if_delmulti(nddp
, &sa
))
1649 /* *** at_reg_mcast() and at_unreg_mcast() should be replaced as soon as the
1650 new code to allow an AF_LINK address family multicast to be (un)registered
1651 using the SIOCADDMULTI / SIOCDELMULTI ioctls has been completed.
1653 The issue is that the "struct sockaddr_dl" needed for the AF_LINK does not
1654 fit in the "struct ifreq" that is used for these ioctls, and we do not want
1655 Blue/Classic, which currently uses AF_UNSPEC, to use a different address
1656 family multicast address than Mac OS X uses.
1659 int at_reg_mcast(ifID
, data
)
1663 struct ifnet
*nddp
= ifID
->aa_ifp
;
1664 struct sockaddr_dl sdl
;
1668 dPrintf(D_M_PAT
, D_L_STARTUP
, ("pat_mcast: BAD ndpp\n"));
1671 if (elap_trackMcast(ifID
, MCAST_TRACK_ADD
, data
) == 1)
1674 sdl
.sdl_len
= sizeof(struct sockaddr_dl
);
1675 sdl
.sdl_family
= AF_LINK
;
1677 sdl
.sdl_type
= nddp
->if_type
;
1678 sdl
.sdl_alen
= nddp
->if_addrlen
;
1680 sdl
.sdl_nlen
= sprintf(sdl
.sdl_data
, "%s%d",
1681 nddp
->if_name
, nddp
->if_unit
);
1682 bcopy(data
, LLADDR(&sdl
), sdl
.sdl_alen
);
1684 dPrintf(D_M_PAT
, D_L_STARTUP
,
1685 ("pat_mcast: adding multicast %08x%04x ifID:0x%x\n",
1686 *(unsigned*)data
, (*(unsigned *)(data
+2))&0x0000ffff,
1689 if (if_addmulti(nddp
, (struct sockaddr
*)&sdl
, 0))
1696 int at_unreg_mcast(ifID
, data
)
1700 struct ifnet
*nddp
= ifID
->aa_ifp
;
1701 struct sockaddr_dl sdl
;
1705 dPrintf(D_M_PAT
, D_L_STARTUP
, ("pat_mcast: BAD ndpp\n"));
1709 elap_trackMcast(ifID
, MCAST_TRACK_DELETE
, data
);
1711 sdl
.sdl_len
= sizeof(struct sockaddr_dl
);
1712 sdl
.sdl_family
= AF_LINK
;
1714 sdl
.sdl_type
= nddp
->if_type
;
1715 sdl
.sdl_alen
= nddp
->if_addrlen
;
1717 sdl
.sdl_nlen
= sprintf(sdl
.sdl_data
, "%s%d",
1718 nddp
->if_name
, nddp
->if_unit
);
1720 dPrintf(D_M_PAT
, D_L_STARTUP
,
1721 ("pat_mcast: deleting multicast %08x%04x ifID:0x%x\n",
1722 *(unsigned*)data
, (*(unsigned *)(data
+2))&0x0000ffff,
1724 bzero(data
, ETHERNET_ADDR_LEN
);
1726 if (if_delmulti(nddp
, (struct sockaddr
*)&sdl
))