2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 * Copyright (c) 1988, 1989, 1993-1998 Apple Computer, Inc.
26 /* at_elap.c: 2.0, 1.29; 10/4/93; Apple Computer, Inc. */
28 /* This is the file which implements all the streams driver
29 * functionality required for EtherTalk.
34 03-14-94 jjs Changed all functions which assumed only one port would
35 ever be used. Added validate_msg_size, changed elap_online
36 to work with the h/w name only (e.g. 'et2').
38 Modified for MP, 1996 by Tuyen Nguyen
39 Modified, March 17, 1997 by Tuyen Nguyen for MacOSX.
43 #define RESOLVE_DBG /* for debug.h global resolution */
44 #include <sys/errno.h>
45 #include <sys/types.h>
46 #include <sys/param.h>
47 #include <machine/spl.h>
48 #include <sys/systm.h>
49 #include <sys/kernel.h>
51 #include <sys/filedesc.h>
52 #include <sys/fcntl.h>
54 #include <sys/ioctl.h>
55 #include <sys/socket.h>
56 #include <sys/socketvar.h>
57 #include <sys/malloc.h>
58 #include <sys/sockio.h>
59 #include <vm/vm_kern.h> /* for kernel_map */
63 #include <net/if_types.h>
65 #include <netat/sysglue.h>
66 #include <netat/appletalk.h>
67 #include <netat/at_var.h>
68 #include <netat/ddp.h>
69 #include <netat/lap.h>
70 #include <netat/routing_tables.h> /* rtmp+zip table structs */
71 #include <netat/zip.h>
72 #include <netat/nbp.h>
73 #include <netat/at_snmp.h>
74 #include <netat/at_pcb.h>
75 #include <netat/at_aarp.h>
76 #include <netat/asp.h>
77 #include <netat/atp.h>
78 #include <netat/debug.h>
79 #include <netat/adsp.h>
80 #include <netat/adsp_internal.h>
82 #include <sys/kern_event.h>
86 at_ifaddr_t at_interfaces
[IF_TOTAL_MAX
];
87 /* index for at_interfaces is not important */
88 at_ifaddr_t
*ifID_table
[IF_TOTAL_MAX
];
89 /* the table of ifID structures, one per interface
91 * NOTE: for MH, entry 0 in this table is
92 * now defined to be the default I/F
94 at_ifaddr_t
*ifID_home
;
95 /* always ifID_table[IFID_HOME] for now, but will be used for
96 dynamic "home port" assignment, later */
98 at_state_t at_state
; /* global state of AT network */
99 snmpFlags_t snmpFlags
;
104 #define MAX_BUFSIZE 8192
105 #define MAX_RTMP (MAX_BUFSIZE/sizeof(RT_entry)-1)
107 ((MAX_BUFSIZE - SNMP_NBP_HEADER_SIZE)/sizeof(snmpNbpEntry_t)-1)
108 #define MAX_NBP_BYTES (MAX_NBP * sizeof(snmpNbpEntry_t))
109 #define MAX_ZIP (MAX_BUFSIZE/sizeof(ZT_entry)-1)
110 #define MAX_RTMP_BYTES (MAX_RTMP * sizeof(RT_entry))
111 #define MAX_ZIP_BYTES (MAX_ZIP * sizeof(ZT_entry))
114 extern TAILQ_HEAD(name_registry
, _nve_
) name_registry
;
115 extern snmpStats_t snmpStats
;
116 extern atlock_t ddpinp_lock
;
117 extern atlock_t arpinp_lock
;
118 extern short appletalk_inited
;
119 extern int adspInited
;
120 extern struct atpcb ddp_head
;
121 extern gref_t
*atp_inputQ
[];
122 extern struct atp_state
*atp_used_list
;
123 extern asp_scb_t
*asp_scbQ
[];
124 extern asp_scb_t
*scb_used_list
;
125 extern CCB
*adsp_inputQ
[];
126 extern CCB
*ccb_used_list
;
127 extern at_ddp_stats_t at_ddp_stats
;
130 extern snmpAarpEnt_t
* getAarp(int *);
131 extern void nbp_shutdown(), routershutdown(), ddp_brt_shutdown();
132 extern void ddp_brt_init(), rtmp_init(), rtmp_input();
133 extern rtmp_router_start(at_kern_err_t
*);
134 static void getIfNames(at_ifnames_t
*);
135 static void add_route();
136 static int set_zones();
138 static int elap_online1(), re_aarp();
139 int at_reg_mcast(), at_unreg_mcast();
140 void AARPwakeup(), ZIPwakeup();
141 static void elap_hangup();
144 at_ifaddr_t
*find_ifID(if_name
)
150 for (pat_id
=0; pat_id
< xpatcnt
; pat_id
++) {
151 if (!strcmp(at_interfaces
[pat_id
].ifName
, if_name
))
152 return(&at_interfaces
[pat_id
]);
155 return((at_ifaddr_t
*)NULL
);
158 static int validate_msg_size(m
, gref
, elapp
)
163 /* checks ioctl message type for minimum expected message size &
164 sends error back if size invalid
167 register ioc_t
*iocbp
;
168 register at_if_cfg_t
*cfgp
;
172 iocbp
= (ioc_t
*) gbuf_rptr(m
);
174 dPrintf(D_M_ELAP
, D_L_INFO
, ("validate_msg_size: ioc_cmd = %d\n",
176 switch (iocbp
->ioc_cmd
) {
177 case LAP_IOC_ADD_ROUTE
:
178 size
= sizeof(RT_entry
);
180 case LAP_IOC_GET_ROUTE
:
181 size
= sizeof(RT_entry
);
183 case LAP_IOC_GET_ZONE
:
184 size
= sizeof(ZT_entryno
);
186 case LAP_IOC_SNMP_GET_CFG
:
187 case LAP_IOC_SNMP_GET_AARP
:
188 case LAP_IOC_SNMP_GET_ZIP
:
189 case LAP_IOC_SNMP_GET_RTMP
:
190 case LAP_IOC_SNMP_GET_NBP
:
194 case ELAP_IOC_GET_STATS
:
195 case LAP_IOC_SNMP_GET_DDP
:
200 dPrintf(D_M_ELAP
, D_L_ERROR
, ("validate_msg_size: unknown ioctl\n"));
204 if (size
== 0) { /* a non-data ioctl */
208 if (gbuf_cont(m
) != NULL
)
209 i
= gbuf_len(gbuf_cont(m
));
210 if (iocbp
->ioc_count
< size
|| (gbuf_cont(m
) == NULL
) || i
< size
) {
211 dPrintf(D_M_ELAP
, D_L_ERROR
,
212 ("ioctl msg error:s:%d c:%d bcont:%c delta:%d\n",
213 size
, iocbp
->ioc_count
,
214 gbuf_cont(m
)? 'Y' : 'N', i
));
220 ioc_ack(EMSGSIZE
, m
, gref
);
222 } /* validate_msg_size */
224 int lap_online(elapp
, cfgp
)
230 if (elapp
->ifState
!= LAP_OFFLINE
) {
235 if (cfgp
->flags
& ELAP_CFG_HOME
) {
237 /* only 1 home allowed! */
240 dPrintf(D_M_ELAP
, D_L_STARTUP
,
241 ("elap_wput home I/F:%s\n", cfgp
->ifr_name
));
242 elapp
->flags
|= ELAP_CFG_HOME
;
245 if (MULTIPORT_MODE
) {
246 elapp
->flags
|= ELAP_CFG_ZONELESS
;
247 if (ROUTING_MODE
&& cfgp
->netStart
)
248 elapp
->flags
|= ELAP_CFG_SEED
;
251 if (!DEFAULT_ZONE(&cfgp
->zonename
) &&
252 (elapp
->flags
& ELAP_CFG_HOME
) || MULTIHOME_MODE
) {
253 elapp
->startup_zone
= cfgp
->zonename
;
256 if (elapp
->flags
& ELAP_CFG_SEED
) {
257 dPrintf(D_M_ELAP
, D_L_STARTUP_INFO
,
258 ("elap_wput: found to be seed\n"));
259 elapp
->ifThisCableStart
= cfgp
->netStart
;
260 elapp
->ifThisCableEnd
= cfgp
->netEnd
;
263 dPrintf(D_M_ELAP
,D_L_ERROR
,
264 ("elap_wput: we believe we're not seed\n"));
265 /* from ELAP_IOC_SET_CFG */
266 if (ATALK_VALUE(cfgp
->node
)) {
270 initial_node
= cfgp
->node
.s_node
;
271 initial_net
= cfgp
->node
.s_net
;
272 if ((initial_node
<0xfe) && (initial_node
>0) &&
273 !((initial_net
== 0) ||
274 ((initial_net
>= DDP_STARTUP_LOW
)&&
275 (initial_net
<= DDP_STARTUP_HIGH
)))) {
277 elapp
->initial_addr
= cfgp
->node
;
282 elapp
->startup_error
= 0;
283 elapp
->startup_inprogress
= FALSE
;
284 if ((error
= elap_online1(elapp
)))
287 if (!(MULTIPORT_MODE
) &&
288 elapp
->ifZoneName
.len
== 1 &&
289 elapp
->ifZoneName
.str
[0] == '*' &&
290 !DEFAULT_ZONE(&cfgp
->zonename
)) {
291 nbp_add_multicast(&cfgp
->zonename
, elapp
);
296 /***********************************************************************
299 **********************************************************************/
300 int elap_wput(gref
, m
)
305 register ioc_t
*iocbp
;
306 register at_if_cfg_t
*cfgp
;
307 at_elap_stats_t
*statsp
;
314 switch (gbuf_type(m
)) {
317 dPrintf(D_M_ELAP
,D_L_ERROR
,
318 ("Output data to control channel is ignored\n"));
322 iocbp
= (ioc_t
*) gbuf_rptr(m
);
324 if (validate_msg_size(m
, gref
, &elapp
))
328 cfgp
= (at_if_cfg_t
*) gbuf_rptr(gbuf_cont(m
));
330 if (LAP_IOC_MYIOCTL(iocbp
->ioc_cmd
) ||
331 ELAP_IOC_MYIOCTL(iocbp
->ioc_cmd
)) {
333 switch (iocbp
->ioc_cmd
) {
334 case ELAP_IOC_GET_STATS
:
335 #ifdef APPLETALK_DEBUG
336 kprintf("LAP_IOC_GET_STATS\n");
338 if ( (gbuf_cont(m
) == NULL
)
339 || (elapp
= find_ifID(gbuf_rptr(gbuf_cont(m
)))) == NULL
) {
340 ioc_ack(EINVAL
, m
, gref
);
343 gbuf_freem(gbuf_cont(m
));
344 if ((gbuf_cont(m
) =gbuf_alloc(sizeof(at_elap_stats_t
),
346 ioc_ack(ENOBUFS
, m
, gref
);
349 statsp
= ((at_elap_stats_t
*)gbuf_rptr(gbuf_cont(m
)));
350 *statsp
= elapp
->stats
;
351 gbuf_wset(gbuf_cont(m
),sizeof(at_elap_stats_t
));
352 iocbp
->ioc_count
= sizeof(at_elap_stats_t
);
356 case LAP_IOC_ADD_ROUTE
:
357 #ifdef APPLETALK_DEBUG
358 kprintf("LAP_IOC_ADD_ROUTE\n");
360 add_route((RT_entry
*)gbuf_rptr(gbuf_cont(m
)));
364 case LAP_IOC_GET_ZONE
:
365 #ifdef APPLETALK_DEBUG
366 kprintf("LAP_IOC_GET_ZONE\n");
368 /* return next ZT_entryno from ZT_table
369 a pointer to the struct ZT_entryno is passed down from
370 user space and the first byte is cast to a int, if
371 this int is non-zero, then the first ZT_entry is
372 returned and subsequent calls with a zero value
373 will return the next entry in the table. The next
374 read after the last valid entry will return EINVAL
379 i
= *(int *)gbuf_rptr(gbuf_cont(m
));
380 gbuf_freem(gbuf_cont(m
));
383 pZTe
= zt_getNextZone(i
);
385 if ((gbuf_cont(m
) = gbuf_alloc(sizeof(ZT_entryno
), PRI_MED
)) == NULL
) {
386 ioc_ack(ENOBUFS
, m
, gref
);
389 *(ZT_entryno
*)gbuf_rptr(gbuf_cont(m
)) = *pZTe
;
390 gbuf_wset(gbuf_cont(m
),sizeof(ZT_entryno
));
391 iocbp
->ioc_count
= sizeof(ZT_entryno
);
395 ioc_ack(EINVAL
, m
, gref
);
399 case LAP_IOC_GET_ROUTE
:
400 #ifdef APPLETALK_DEBUG
401 kprintf("LAP_IOC_GET_ROUTE\n");
403 /* return next RT_entry from RT_table
404 * a pointer to the struct RT_entry is
405 * passed down from user space and the first
406 * byte is cast to a int, if this int is
407 * non-zero, then the first RT_entry is
408 * returned and subsequent calls with a
409 * zero value will return the next entry in
410 * the table. The next read after the last
411 * valid entry will return EINVAL
416 i
= *(int *)gbuf_rptr(gbuf_cont(m
));
417 gbuf_freem(gbuf_cont(m
));
420 pRT
= rt_getNextRoute(i
);
422 if ((gbuf_cont(m
) = gbuf_alloc(sizeof(RT_entry
), PRI_MED
)) == NULL
) {
423 ioc_ack(ENOBUFS
, m
, gref
);
426 *(RT_entry
*)gbuf_rptr(gbuf_cont(m
)) = *pRT
;
427 gbuf_wset(gbuf_cont(m
),sizeof(RT_entry
));
428 iocbp
->ioc_count
= sizeof(RT_entry
);
432 ioc_ack(EINVAL
, m
, gref
);
436 case LAP_IOC_SNMP_GET_DDP
:
437 #ifdef APPLETALK_DEBUG
438 kprintf("LAP_IOC_SNMP_GET_DDP\n");
440 if (!(at_state
.flags
& AT_ST_STARTED
)) {
441 ioc_ack(ENOTREADY
, m
, gref
);
444 if ((gbuf_cont(m
) = gbuf_alloc(sizeof(snmpStats_t
),
446 ioc_ack(ENOBUFS
, m
, gref
);
450 *(snmpStats_t
*)gbuf_rptr(gbuf_cont(m
)) = snmpStats
;
451 gbuf_wset(gbuf_cont(m
),sizeof(snmpStats
));
452 iocbp
->ioc_count
= sizeof(snmpStats
);
455 case LAP_IOC_SNMP_GET_CFG
:
456 #ifdef APPLETALK_DEBUG
457 kprintf("LAP_IOC_SNMP_GET_CFG\n");
463 i
= *(int *)gbuf_rptr(gbuf_cont(m
));
464 gbuf_freem(gbuf_cont(m
));
466 if (!(at_state
.flags
& AT_ST_STARTED
)) {
468 iocbp
->ioc_count
= 0;
469 ioc_ack(ENOTREADY
, m
, gref
);
470 dPrintf(D_M_ELAP_LOW
, D_L_INFO
,
471 ("elap_wput: cfg req, stack down\n"));
474 if (i
== UPDATE_IF_CHANGED
&&
475 !(at_state
.flags
& AT_ST_IF_CHANGED
)) {
476 iocbp
->ioc_count
= 0;
478 dPrintf(D_M_ELAP_LOW
, D_L_INFO
,
479 ("elap_wput: cfg req, unchanged\n"));
482 dPrintf(D_M_ELAP_LOW
, D_L_INFO
,
483 ("elap_wput: cfg req, changed\n"));
485 if (getSnmpCfg(&snmp
)) {
486 dPrintf(D_M_ELAP
,D_L_ERROR
,
487 ("elap_wput:SNMP_GET_CFG error\n"));
488 ioc_ack(EOPNOTSUPP
, m
, gref
);
491 /* send up only used part of table */
492 size
= sizeof(snmp
) -
493 sizeof(snmpIfCfg_t
) * (MAX_IFS
- snmp
.cfg_ifCnt
);
495 if ((gbuf_cont(m
) = gbuf_alloc(size
, PRI_MED
)) == NULL
) {
496 ioc_ack(ENOBUFS
, m
, gref
);
499 bcopy(&snmp
,gbuf_rptr(gbuf_cont(m
)),size
);
500 gbuf_wset(gbuf_cont(m
),size
);
501 iocbp
->ioc_count
= size
;
502 at_state
.flags
&= ~AT_ST_IF_CHANGED
;
507 case LAP_IOC_SNMP_GET_AARP
:
509 snmpAarpEnt_t
*snmpp
;
511 #ifdef APPLETALK_DEBUG
512 kprintf("LAP_IOC_SNMP_GET_AARP\n");
514 i
= *(int *)gbuf_rptr(gbuf_cont(m
));
515 gbuf_freem(gbuf_cont(m
));
517 dPrintf(D_M_ELAP
,D_L_INFO
,
518 ("elap_wput:calling getarp,i=%d\n", i
));
520 bytes
= i
* sizeof(snmpAarpEnt_t
);
521 dPrintf(D_M_ELAP
,D_L_INFO
,
522 ("elap_wput:getarp returned, i=%d,bytes=%d\n",
525 if ((gbuf_cont(m
) = gbuf_alloc(bytes
, PRI_MED
)) == NULL
) {
526 ioc_ack(ENOBUFS
, m
, gref
);
529 bcopy(snmpp
, gbuf_rptr(gbuf_cont(m
)), bytes
);
530 gbuf_wset(gbuf_cont(m
),bytes
);
531 iocbp
->ioc_count
= bytes
;
535 ioc_ack(EOPNOTSUPP
, m
, gref
);
539 case LAP_IOC_SNMP_GET_ZIP
:
540 #ifdef APPLETALK_DEBUG
541 kprintf("LAP_IOC_SNMP_GET_ZIP\n");
543 { /* matching brace NOT in this case */
545 register int size
, total
, tabsize
;
546 gbuf_t
*mn
; /* new gbuf */
547 gbuf_t
*mo
; /* old gbuf */
548 gbuf_t
*mt
; /* temp */
551 i
= *(int *)gbuf_rptr(gbuf_cont(m
));
552 gbuf_freem(gbuf_cont(m
));
554 if (!(at_state
.flags
& AT_ST_STARTED
)) {
555 ioc_ack(ENOTREADY
, m
, gref
);
558 if (i
== UPDATE_IF_CHANGED
&&
559 !(at_state
.flags
& AT_ST_ZT_CHANGED
)) {
560 iocbp
->ioc_count
= 0;
565 tabsize
= getZipTableSize();
567 /* retrieve table into multiple gbufs */
568 for (i
=0; i
<tabsize
; i
+=j
) {
570 MAX_ZIP
? MAX_ZIP
: tabsize
- i
;
571 size
= j
< MAX_ZIP
? sizeof(ZT_entry
)*j
: MAX_ZIP_BYTES
;
572 if ((mn
= gbuf_alloc(size
, PRI_MED
)) == NULL
) {
574 gbuf_freem(gbuf_cont(m
));
575 ioc_ack(ENOBUFS
, m
, gref
);
578 if (!mo
) { /* if first new one */
587 getZipTable((ZT_entry
*)gbuf_rptr(mn
),i
,j
);
590 if ((gbuf_cont(m
) = gbuf_alloc(sizeof(int), PRI_MED
)) == NULL
) {
593 iocbp
->ioc_count
= 0;
594 ioc_ack(ENOBUFS
, m
, gref
);
598 dPrintf(D_M_ELAP
,D_L_WARNING
,
599 ("elap_wput:snmp: empty zip table\n"));
602 *(int*)gbuf_rptr(gbuf_cont(m
)) = total
; /* return table size */
603 gbuf_wset(gbuf_cont(m
),sizeof(int));
604 iocbp
->ioc_count
= sizeof(int);
607 atalk_putnext(gref
,mt
); /* send up table */
608 at_state
.flags
&= ~AT_ST_ZT_CHANGED
;
611 case LAP_IOC_SNMP_GET_RTMP
:
612 #ifdef APPLETALK_DEBUG
613 kprintf("LAP_IOC_SNMP_GET_RTMP\n");
615 i
= *(int *)gbuf_rptr(gbuf_cont(m
));
616 gbuf_freem(gbuf_cont(m
));
618 if (!(at_state
.flags
& AT_ST_STARTED
)) {
619 ioc_ack(ENOTREADY
, m
, gref
);
622 if (i
== UPDATE_IF_CHANGED
&&
623 !(at_state
.flags
& AT_ST_RT_CHANGED
)) {
624 iocbp
->ioc_count
= 0;
630 tabsize
= getRtmpTableSize();
632 /* retrieve table into multiple gbufs */
633 for (i
=0; i
<tabsize
; i
+=j
) {
635 MAX_RTMP
? MAX_RTMP
: tabsize
- i
;
636 size
= j
< MAX_RTMP
? sizeof(RT_entry
)*j
: MAX_RTMP_BYTES
;
637 if ((mn
= gbuf_alloc(size
, PRI_MED
)) == NULL
) {
639 gbuf_freem(gbuf_cont(m
));
640 ioc_ack(ENOBUFS
, m
, gref
);
643 if (!mo
) { /* if first new one */
652 getRtmpTable((RT_entry
*)gbuf_rptr(mn
),i
,j
);
655 if ((gbuf_cont(m
) = gbuf_alloc(sizeof(int), PRI_MED
)) == NULL
) {
658 iocbp
->ioc_count
= 0;
659 ioc_ack(ENOBUFS
, m
, gref
);
664 *(int*)gbuf_rptr(gbuf_cont(m
)) = total
; /* return table size */
665 gbuf_wset(gbuf_cont(m
),sizeof(int));
666 iocbp
->ioc_count
= sizeof(int);
669 atalk_putnext(gref
,mt
); /* send up table */
670 at_state
.flags
&= ~AT_ST_RT_CHANGED
;
673 case LAP_IOC_SNMP_GET_NBP
:
674 #ifdef APPLETALK_DEBUG
675 kprintf("LAP_IOC_SNMP_GET_NBP\n");
677 i
= *(int *)gbuf_rptr(gbuf_cont(m
));
678 gbuf_freem(gbuf_cont(m
));
680 if (!(at_state
.flags
& AT_ST_STARTED
)) {
681 ioc_ack(ENOTREADY
, m
, gref
);
684 if (i
== UPDATE_IF_CHANGED
&&
685 !(at_state
.flags
& AT_ST_NBP_CHANGED
)) {
686 iocbp
->ioc_count
= 0;
688 dPrintf(D_M_ELAP_LOW
, D_L_INFO
,
689 ("elap_wput: nbp req denied, no change\n"));
694 tabsize
= getNbpTableSize();
696 /* retrieve table into multiple gbufs */
697 for (i
=0; i
<tabsize
; i
+=j
) {
699 MAX_NBP
? MAX_NBP
: tabsize
- i
;
700 size
= j
< MAX_NBP
? sizeof(snmpNbpEntry_t
)*j
: MAX_NBP_BYTES
;
702 size
+= SNMP_NBP_HEADER_SIZE
;
703 if ((mn
= gbuf_alloc(size
, PRI_MED
)) == NULL
) {
705 gbuf_freem(gbuf_cont(m
));
706 ioc_ack(ENOBUFS
, m
, gref
);
709 if (!mo
) { /* if first new one */
712 nbp
= (snmpNbpTable_t
*)gbuf_rptr(mn
);
713 nbp
->nbpt_entries
= tabsize
;
714 nbp
->nbpt_zone
= ifID_home
->ifZoneName
;
715 getNbpTable(nbp
->nbpt_table
,i
,j
);
720 getNbpTable((snmpNbpEntry_t
*)gbuf_rptr(mn
),i
,j
);
725 if ((gbuf_cont(m
) = gbuf_alloc(sizeof(int), PRI_MED
)) == NULL
) {
728 iocbp
->ioc_count
= 0;
729 ioc_ack(ENOBUFS
, m
, gref
);
734 *(int*)gbuf_rptr(gbuf_cont(m
)) = total
; /* return table size */
735 gbuf_wset(gbuf_cont(m
),sizeof(int));
736 iocbp
->ioc_count
= sizeof(int);
739 atalk_putnext(gref
,mt
); /* send up table */
740 at_state
.flags
&= ~AT_ST_NBP_CHANGED
;
745 #ifdef APPLETALK_DEBUG
746 kprintf("unknown ioctl %d\n", iocbp
->ioc_cmd
);
748 ioc_ack(ENOTTY
, m
, gref
);
749 dPrintf(D_M_ELAP
, D_L_WARNING
,
750 ("elap_wput: unknown ioctl (%d)\n", iocbp
->ioc_cmd
));
753 elapp
->stats
.unknown_mblks
++;
768 /* Called directly by ddp/zip.
770 elap_dataput(m
, elapp
, addr_flag
, addr
)
772 register at_ifaddr_t
*elapp
;
778 extern int zip_type_packet();
779 struct etalk_addr dest_addr
;
780 struct atalk_addr dest_at_addr
;
781 extern gbuf_t
*growmsg();
783 /* flag to aarp to loopback (default) */
785 /* the incoming frame is of the form {flag, address, ddp...}
786 * where "flag" indicates whether the address is an 802.3
787 * (link) address, or an appletalk address. If it's an
788 * 802.3 address, the packet can just go out to the network
789 * through PAT, if it's an appletalk address, AT->802.3 address
790 * resolution needs to be done.
791 * If 802.3 address is known, strip off the flag and 802.3
792 * address, and prepend 802.2 and 802.3 headers.
796 addr_flag
= *(u_char
*)gbuf_rptr(m
);
801 case AT_ADDR_NO_LOOP
:
806 dest_at_addr
= *(struct atalk_addr
*)gbuf_rptr(m
);
807 gbuf_rinc(m
,sizeof(struct atalk_addr
));
809 dest_at_addr
= *(struct atalk_addr
*)addr
;
813 dest_addr
= *(struct etalk_addr
*)gbuf_rptr(m
);
814 gbuf_rinc(m
,sizeof(struct etalk_addr
));
816 dest_addr
= *(struct etalk_addr
*)addr
;
819 gbuf_freel(m
); /* unknown address type, chuck it */
825 /* At this point, rptr points to ddp header for sure */
826 if (elapp
->ifState
== LAP_OFFLINE
) {
831 if (elapp
->ifState
== LAP_ONLINE_FOR_ZIP
) {
832 /* see if this is a ZIP packet that we need
833 * to let through even though network is
836 if (zip_type_packet(m
) == 0) {
842 elapp
->stats
.xmit_packets
++;
843 size
= gbuf_msgsize(m
);
844 elapp
->stats
.xmit_bytes
+= size
;
845 snmpStats
.dd_outLong
++;
848 case AT_ADDR_NO_LOOP
:
851 * we don't want elap to be looking into ddp header, so
852 * it doesn't know net#, consequently can't do
853 * AMT_LOOKUP. That task left to aarp now.
855 error
= aarp_send_data(m
,elapp
,&dest_at_addr
, loop
);
858 error
= pat_output(elapp
, m
, &dest_addr
, 0);
864 /************************************************************************
867 ************************************************************************/
869 static int elap_online1(elapp
)
874 dPrintf(D_M_ELAP
, D_L_STARTUP_INFO
, ("elap_online:%s elapp:0x%x\n",
875 (elapp
->ifName
) ? &elapp
->ifName
[0] : "NULL interface", (u_int
) elapp
));
876 if (elapp
->ifState
!= LAP_OFFLINE
|| elapp
->startup_inprogress
== TRUE
)
879 at_state
.flags
|= AT_ST_IF_CHANGED
;
881 if (elapp
->flags
& ELAP_CFG_HOME
) /* tell ddp_add_if if this is home */
882 elapp
->ifFlags
|= AT_IFF_DEFAULT
;
884 /* Get DDP started */
885 if ((errno
= ddp_add_if(elapp
)))
888 // check if we still have an interface - can be lost when
889 // ddp_add_if calls malloc
890 // need to make check here after ddp_add_if completes because
891 // lap_online will call ddp_rem_if if we fail here
892 if (elapp
->aa_ifp
== 0)
895 /* set up multicast address for cable-wide broadcasts */
896 (void)at_reg_mcast(elapp
, (caddr_t
)&elapp
->cable_multicast_addr
);
898 // need to check again if interface is present
899 // can be lost in at_reg_mcast
900 if (elapp
->aa_ifp
== 0)
903 elapp
->startup_inprogress
= TRUE
;
904 if (! (elapp
->startup_error
= re_aarp(elapp
)))
905 (void)tsleep(&elapp
->startup_inprogress
, PSOCK
| PCATCH
,
908 /* then later, after some timeouts AARPwakeup() is called */
910 return(elapp
->startup_error
);
913 static int re_aarp(elapp
)
918 /* We now call aarp_init() to assign an appletalk node addr */
919 errno
= aarp_init1(elapp
);
920 /* aarp_init1() returns either -1 or ENOTREADY */
921 if (errno
== ENOTREADY
)
924 dPrintf(D_M_ELAP
, D_L_STATE_CHG
,
925 ("elap_online aarp_init for %s\n", elapp
->ifName
));
926 (void)at_unreg_mcast(elapp
, (caddr_t
)&elapp
->cable_multicast_addr
);
928 elapp
->ifState
= LAP_OFFLINE
;
929 return(EADDRNOTAVAIL
);
933 /* called from AARPwakeup */
934 static void elap_online2(elapp
)
937 if (MULTIPORT_MODE
) {
938 dPrintf(D_M_ELAP
,D_L_STARTUP_INFO
,
939 ("elap_online: re_aarp, we know it's a router...\n"));
941 if (elapp
->flags
& ELAP_CFG_SEED
) {
942 /* add route table entry (zones to be added later) */
943 dPrintf(D_M_ELAP
, D_L_STARTUP_INFO
,
944 ("elap_online: rt_insert Cable %d-%d port =%d as SEED\n",
945 elapp
->ifThisCableStart
, elapp
->ifThisCableEnd
, elapp
->ifPort
));
946 rt_insert(elapp
->ifThisCableEnd
,
947 elapp
->ifThisCableStart
,
950 RTE_STATE_PERMANENT
| RTE_STATE_ZKNOWN
| RTE_STATE_GOOD
952 /* LD 081694: set the RTR_SEED_PORT flag for seed ports */
953 elapp
->ifFlags
|= RTR_SEED_PORT
;
956 dPrintf(D_M_ELAP
,D_L_STARTUP_INFO
,
957 ("elap_online: it's a router, but non seed\n"));
960 if (elapp
->flags
& ELAP_CFG_ZONELESS
) {
961 /* ELAP_CFG_ZONELESS tells us that it is a router or in
962 multihome mode, so we don't want to do the GetNetInfo
963 exchange with the router. */
965 elapp
->ifState
= LAP_ONLINE_ZONELESS
;
966 elapp
->startup_inprogress
= FALSE
;
967 wakeup(&elapp
->startup_inprogress
);
968 dPrintf(D_M_ELAP
, D_L_STARTUP_INFO
, ("elap_online: ack 3\n"));
972 /* if we don't already have a zone and a multicast address */
973 if (*(int *)&elapp
->ZoneMcastAddr
== 0 || elapp
->ifZoneName
.len
== 0) {
974 /* hzonehash is a global containing the nbp hash for the startup_zone */
977 /* Get ZIP rolling to get zone multicast address, etc. */
978 elapp
->ifState
= LAP_ONLINE_FOR_ZIP
;
979 (void)zip_control(elapp
, ZIP_ONLINE
);
980 /* zip_control (w. control == ZIP_ONLINE) always returns ENOTREADY */
982 /* later, after some timeouts ZIPwakeup() is called. */
984 /* otherwise, we have the zone and the multicast already,
985 so don't bother with another ZIP GetNetInfo request */
990 /* called from rtmp_router_start */
991 int elap_online3(elapp
)
994 elapp
->startup_inprogress
= TRUE
;
996 /* just reset the net range */
997 elapp
->initial_addr
.s_net
= 0;
998 elapp
->initial_addr
.s_node
= 0;
999 dPrintf(D_M_ELAP_LOW
, D_L_STARTUP_INFO
,
1000 ("elap_online: goto re_aarp port=%d\n", elapp
->ifPort
));
1002 if ((elapp
->startup_error
= re_aarp(elapp
)))
1003 return(elapp
->startup_error
);
1005 /* then later, after some timeouts AARPwakeup() is called */
1007 (void)tsleep(&elapp
->startup_inprogress
, PSOCK
| PCATCH
,
1009 return(elapp
->startup_error
);
1010 } /* elap_online3 */
1012 /****************************************************************************
1015 ****************************************************************************/
1017 void elap_offline(elapp
)
1018 register at_ifaddr_t
*elapp
;
1021 void zip_sched_getnetinfo(); /* forward reference */
1025 dPrintf(D_M_ELAP
, D_L_SHUTDN_INFO
, ("elap_offline:%s\n", elapp
->ifName
));
1026 if (elapp
->ifState
!= LAP_OFFLINE
) {
1028 /* Since AppleTalk is going away, remove the cable
1029 * multicast address and turn the interface off so that all
1030 * AppleTalk packets are dropped in the driver itself.
1031 * Get rid of the zone multicast address prior to going Offline.
1033 (void)at_unreg_mcast(elapp
, (caddr_t
)&elapp
->ZoneMcastAddr
);
1034 (void)at_unreg_mcast(elapp
, (caddr_t
)&elapp
->cable_multicast_addr
);
1035 elapp
->ifState
= LAP_OFFLINE
;
1037 ATDISABLE(s
, ddpinp_lock
);
1039 RT_DELETE(elapp
->ifThisCableEnd
,
1040 elapp
->ifThisCableStart
);
1041 ATENABLE(s
, ddpinp_lock
);
1043 /* make sure no zip timeouts are left running */
1044 untimeout(zip_sched_getnetinfo
, elapp
);
1047 } /* elap_offline */
1050 static void add_route(rt
)
1053 /* support ioctl to manually add routes to table.
1054 this is really only for testing
1057 rt_insert( rt
->NetStop
, rt
->NetStart
, rt
->NextIRNet
,
1058 rt
->NextIRNode
, rt
->NetDist
, rt
->NetPort
,
1060 dPrintf(D_M_ELAP
, D_L_STARTUP_INFO
, ("adding route: %ud:%ud dist:%ud\n",
1061 rt
->NetStart
, rt
->NetStop
,rt
->NetDist
));
1067 * Initialization that takes place each time AppleTalk is restarted.
1072 TAILQ_INIT(&at_ifQueueHd
);
1073 TAILQ_INIT(&name_registry
);
1074 bzero(at_interfaces
, sizeof(at_interfaces
));
1075 bzero(ifID_table
, sizeof(ifID_table
));
1076 bzero(&at_ddp_stats
, sizeof(at_ddp_stats_t
));
1077 rtmp_init(); /* initialize trackedrouters */
1079 add_ddp_handler(RTMP_SOCKET
, rtmp_input
);
1080 ifID_home
= (at_ifaddr_t
*)NULL
;
1084 int ddp_shutdown(count_only
)
1088 asp_scb_t
*scb
, *scb_next
;
1089 struct atp_state
*atp
, *atp_next
;
1092 vm_offset_t temp_rcb_data
, temp_state_data
;
1093 int i
, s
, active_skts
= 0; /* count of active pids for non-socketized
1094 AppleTalk protocols */
1096 /* Network is shutting down... send error messages up on each open
1098 *** For now, for ASP, ATP and ADSP, attempt to notify open
1099 sockets, but return EBUSY and don't complete shutdown. ***
1102 s
= splimp(); /* *** previously contained mismatched locking
1103 that was ifdef'ed to splimp() *** */
1105 nbp_shutdown(); /* clear all known NVE */
1108 for (scb
= scb_used_list
; scb
; ) {
1109 scb_next
= scb
->next_scb
;
1112 dPrintf(D_M_ASP
, D_L_TRACE
, ("asp pid=%d\n", scb
->pid
));
1113 atalk_notify(scb
->gref
, ESHUTDOWN
);
1117 for (i
= 0; i
< 256 ; i
++) {
1118 if ((scb
= asp_scbQ
[i
]))
1120 scb_next
= scb
->next_scb
;
1123 dPrintf(D_M_ASP
, D_L_TRACE
,
1124 ("asp pid=%d\n", scb
->pid
));
1125 atalk_notify(scb
->gref
, ESHUTDOWN
);
1132 for (atp
= atp_used_list
; atp
; ) {
1133 atp_next
= atp
->atp_trans_waiting
;
1136 dPrintf(D_M_ATP
, D_L_TRACE
, ("atp pid=%d\n", atp
->atp_pid
));
1137 atalk_notify(atp
->atp_gref
, ESHUTDOWN
);
1141 for (i
= 0; i
< 256; i
++) {
1142 if ((gref
= atp_inputQ
[i
]) && (gref
!= (gref_t
*)1)) {
1143 atp
= (struct atp_state
*)gref
->info
;
1147 dPrintf(D_M_ATP
, D_L_TRACE
,
1148 ("atp pid=%d\n", atp
->atp_pid
));
1149 atalk_notify(atp
->atp_gref
, ESHUTDOWN
);
1156 for (sp
= ccb_used_list
; sp
; ) {
1157 sp_next
= sp
->otccbLink
;
1160 dPrintf(D_M_ADSP
, D_L_TRACE
, ("adsp pid=%d\n", sp
->pid
));
1161 atalk_notify(sp
->gref
, ESHUTDOWN
);
1165 for (i
= 0; i
< 256 ; i
++) {
1166 if ((sp
= adsp_inputQ
[i
]))
1168 sp_next
= sp
->otccbLink
;
1171 dPrintf(D_M_ADSP
, D_L_TRACE
,
1172 ("adsp pid=%d\n", sp
->pid
));
1173 atalk_notify(sp
->gref
, ESHUTDOWN
);
1180 for (gref
= ddp_head
.atpcb_next
; gref
!= &ddp_head
;
1181 gref
= gref
->atpcb_next
) {
1185 dPrintf(D_M_DDP
,D_L_TRACE
, ("ddp pid=%d\n", gref
->pid
));
1186 atalk_notify(gref
, ESHUTDOWN
);
1189 if (count_only
|| active_skts
) {
1191 return(active_skts
);
1194 /* if there are no interfaces in the process of going online, continue shutting down DDP */
1195 for (i
= 0; i
< IF_TOTAL_MAX
; i
++) {
1196 if (at_interfaces
[i
].startup_inprogress
== TRUE
)
1199 if (MULTIPORT_MODE
) {
1201 /* free memory allocated for the rtmp/zip tables */
1203 FREE(ZT_table
, M_RTABLE
);
1204 ZT_table
= (ZT_entry
*)NULL
;
1207 FREE(RT_table
, M_RTABLE
);
1208 RT_table
= (RT_entry
*)NULL
;
1212 at_state
.flags
= 0; /* make sure inits are done on restart */
1214 wakeup(&ifID_home
->startup_inprogress
); /* if rtmp_router_start still starting up */
1216 /* from original ddp_shutdown() */
1226 dPrintf(D_M_DDP
, D_L_VERBOSE
, ("DDP shutdown completed"));
1229 * make sure we don't have a probe timeout hanging around
1230 * it's going to try and make use of an entry in at_interfaces
1231 * which is going to be zero'd out by the call to ddp_start a
1232 * little further down
1234 untimeout(aarp_sched_probe
, 0);
1236 /* *** after an SIOCSIFADDR and before an AIOCSIFADDR,
1237 this is the only place to find the ifID *** */
1238 for (i
= 0; i
< IF_TOTAL_MAX
; i
++) {
1239 ifID
= &at_interfaces
[i
];
1240 /* do LAP_IOC_OFFLINE processing */
1247 } /* ddp_shutdown */
1249 int routerStart(keP
)
1252 register at_ifaddr_t
*ifID
;
1259 * this will cause the ports to glean from the net the relevant
1260 * information before forwarding
1262 TAILQ_FOREACH(ifID
, &at_ifQueueHd
, aa_link
) {
1263 dPrintf(D_M_ELAP
, D_L_STARTUP_INFO
,
1264 ("routerStart Port %d (%s) set to activating\n",
1265 ifID
->ifPort
, ifID
->ifName
));
1266 ifID
->ifRoutingState
= PORT_ACTIVATING
;
1267 ifID
->ifFlags
|= RTR_XNET_PORT
;
1271 * The next step is to check the information for each port before
1272 * declaring the ports up and forwarding
1274 dPrintf(D_M_ELAP
, D_L_STARTUP_INFO
,
1275 ("router_start: waiting 20 sec before starting up\n"));
1277 /* sleep for 20 seconds */
1279 /* *** eventually this will be the ifID for the interface
1280 being brought up in router mode *** */
1281 tsleep(&ifID_home
->startup_inprogress
,
1282 PSOCK
| PCATCH
, "routerStart", 20 * SYS_HZ
))
1286 panic("routerStart: spurious interrupt");
1291 return(rtmp_router_start(keP
));
1292 /* was timeout(rtmp_router_start, 0, 20 * SYS_HZ); */
1295 void ZIPwakeup(elapp
, ZipError
)
1299 int s
, error
= ZipError
;
1301 ATDISABLE(s
, ddpinp_lock
);
1302 if ( (elapp
!= NULL
) && elapp
->startup_inprogress
) {
1303 ATENABLE(s
, ddpinp_lock
);
1305 /* was ZIPContinue */
1306 /* was elapp_online() with jump to ZIP_sleep */
1308 /* instead of the goto ZIP_sleep ... */
1310 case 0 : /* success */
1311 elapp
->ifState
= LAP_ONLINE
;
1313 /* Send event with zone info. */
1314 atalk_post_msg(elapp
->aa_ifp
, KEV_ATALK_ZONEUPDATED
, 0, &(elapp
->ifZoneName
));
1318 /* instead of goto re_aarp; */
1319 /* We now call aarp_init() to assign an
1320 appletalk node addr */
1321 if ((elapp
->startup_error
= re_aarp(elapp
))) {
1322 elapp
->startup_inprogress
= FALSE
;
1323 wakeup(&elapp
->startup_inprogress
);
1324 dPrintf(D_M_ELAP
, D_L_STARTUP_INFO
,
1325 ("elap_online: ack 2\n"));
1331 if (ZipError
!= ZIP_RE_AARP
) {
1332 elapp
->startup_error
= error
;
1333 elapp
->startup_inprogress
= FALSE
;
1334 wakeup(&elapp
->startup_inprogress
);
1335 dPrintf(D_M_ELAP
, D_L_STARTUP_INFO
,
1336 ("elap_online: ifZipError=%d\n", error
));
1339 ATENABLE(s
, ddpinp_lock
);
1342 void AARPwakeup(probe_cb
)
1343 aarp_amt_t
*probe_cb
;
1349 ATDISABLE(s
, arpinp_lock
);
1350 elapp
= probe_cb
->elapp
;
1351 if ( (elapp
!= NULL
) && elapp
->startup_inprogress
&& elapp
->aa_ifp
!= 0) {
1352 ATENABLE(s
, arpinp_lock
);
1354 /* was AARPContinue */
1355 errno
= aarp_init2(elapp
);
1356 /* aarp_init2() returns either -1 or 0 */
1358 dPrintf(D_M_ELAP
, D_L_STATE_CHG
,
1359 ("elap_online aarp_init for %s\n",
1361 (void)at_unreg_mcast(elapp
, (caddr_t
)&elapp
->ZoneMcastAddr
);
1362 (void)at_unreg_mcast(elapp
, (caddr_t
)&elapp
->cable_multicast_addr
);
1363 elapp
->ifState
= LAP_OFFLINE
;
1365 elapp
->startup_error
= EADDRNOTAVAIL
;
1366 elapp
->startup_inprogress
= FALSE
;
1367 wakeup(&elapp
->startup_inprogress
);
1368 dPrintf(D_M_ELAP
, D_L_STARTUP_INFO
, ("elap_online: ack 2\n"));
1370 dPrintf(D_M_ELAP
,D_L_STARTUP_INFO
,
1371 ("elap_online: aarp_init returns zero\n"));
1372 elap_online2(elapp
);
1375 ATENABLE(s
, arpinp_lock
);
1378 void ddp_bit_reverse(addr
)
1379 unsigned char *addr
;
1381 static unsigned char reverse_data
[] = {
1382 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
1383 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
1384 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
1385 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
1386 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
1387 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
1388 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
1389 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
1390 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
1391 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
1392 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
1393 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
1394 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
1395 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
1396 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
1397 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
1398 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
1399 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
1400 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
1401 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
1402 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
1403 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
1404 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
1405 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
1406 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
1407 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
1408 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
1409 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
1410 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
1411 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
1412 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
1413 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
1418 for (k
=0; k
< 6; k
++)
1419 addr
[k
] = reverse_data
[addr
[k
]];
1422 static int elap_trackMcast(patp
, func
, addr
)
1429 switch(patp
->aa_ifp
->if_type
) {
1432 /* set addr to point to unique part of addr */
1435 /* first try to find match */
1436 /* *** save just one byte of the multicast address? *** */
1437 for (i
=0; i
< MAX_MCASTS
; i
++)
1438 if (c
== patp
->mcast
[i
]) {
1444 case MCAST_TRACK_DELETE
:
1446 patp
->mcast
[loc
] = 0;
1449 case MCAST_TRACK_ADD
:
1450 dPrintf(D_M_PAT_LOW
, D_L_USR2
, ("mctrack:add loc:%d\n", i
));
1452 dPrintf(D_M_PAT_LOW
, D_L_USR2
, ("mctrack:add, addr was there\n"));
1454 break; /* already there */
1456 for (i
=0; i
< MAX_MCASTS
; i
++)
1457 if (patp
->mcast
[i
] == 0) {
1461 dPrintf(D_M_PAT_LOW
, D_L_USR2
, ("mctrack:add1 loc:%d\n", i
));
1463 patp
->mcast
[loc
] = c
;
1464 dPrintf(D_M_PAT_LOW
, D_L_USR2
, ("mctrack:add, adding(%x)\n",
1465 (*(int*)addr
)&0xffffff));
1468 /*errno = ENOMEM; */ /*LD 5/7/97 nobody is using that */
1472 case MCAST_TRACK_CHECK
:
1474 dPrintf(D_M_PAT_LOW
, D_L_USR2
, ("mctrack:check, addr was there\n"));
1478 dPrintf(D_M_PAT_LOW
, D_L_USR2
, ("mctrack:add, addr was NOT there\n"));
1483 /*errno = EINVAL;*/ /*LD 5/7/97 nobody is using that */
1487 case IFT_ISO88025
: /* token ring */
1488 /* we would use the lowest byte of the addr argument as a value
1489 to shift left a 1 to form the mcast mask for TR. We'll do this
1499 static getSnmpCfg(snmp
)
1506 snmp
->cfg_ifCnt
= 0;
1508 bzero(snmp
,sizeof(snmpCfg_t
));
1509 for (i
=0, elapp
=at_interfaces
,ifc
=snmp
->cfg_ifCfg
;
1510 i
<IF_TOTAL_MAX
; i
++, elapp
++, ifc
++) {
1511 if (elapp
->ifState
!= LAP_OFFLINE
) {
1513 strncpy(ifc
->ifc_name
,elapp
->ifName
, sizeof(ifc
->ifc_name
));
1514 ifc
->ifc_aarpSize
= getAarpTableSize(i
);
1515 ifc
->ifc_addrSize
= getPhysAddrSize(i
);
1516 switch (elapp
->aa_ifp
->if_type
) {
1518 ifc
->ifc_type
= SNMP_TYPE_ETHER2
;
1520 case IFT_ISO88025
: /* token ring */
1521 ifc
->ifc_type
= SNMP_TYPE_TOKEN
;
1525 ifc
->ifc_type
= SNMP_TYPE_OTHER
;
1528 ifc
->ifc_start
= elapp
->ifThisCableStart
;
1529 ifc
->ifc_end
= elapp
->ifThisCableEnd
;
1530 ifc
->ifc_ddpAddr
= elapp
->ifThisNode
;
1531 ifc
->ifc_status
= elapp
->ifState
== LAP_ONLINE
? 1 : 2;
1532 ifc
->ifc_zoneName
.len
= 0;
1533 if (elapp
->ifZoneName
.len
!= 0) {
1534 ifc
->ifc_zoneName
= elapp
->ifZoneName
;
1536 else if (elapp
->ifDefZone
) {
1537 ifc
->ifc_zoneName
= ZT_table
[elapp
->ifDefZone
-1].Zone
;
1539 else /* temp, debug only */
1540 ifc
->ifc_zoneName
= ZT_table
[0].Zone
;
1542 if (elapp
->ifFlags
& RTR_SEED_PORT
) {
1543 ifc
->ifc_netCfg
= SNMP_CFG_CONFIGURED
;
1544 ifc
->ifc_zoneCfg
= SNMP_CFG_CONFIGURED
;
1547 ifc
->ifc_netCfg
= SNMP_CFG_GARNERED
;
1548 ifc
->ifc_zoneCfg
= SNMP_CFG_GARNERED
;
1551 else { /* single-port mode */
1552 if (elapp
->ifRouterState
== ROUTER_AROUND
) {
1553 ifc
->ifc_netCfg
= SNMP_CFG_GARNERED
;
1556 ifc
->ifc_netCfg
= SNMP_CFG_GUESSED
;
1557 ifc
->ifc_zoneCfg
= SNMP_CFG_UNCONFIG
;
1562 snmp
->cfg_flags
= at_state
.flags
;
1568 int at_reg_mcast(ifID
, data
)
1572 struct ifnet
*nddp
= ifID
->aa_ifp
;
1577 dPrintf(D_M_PAT
, D_L_STARTUP
, ("pat_mcast: BAD ndpp\n"));
1581 if (elap_trackMcast(ifID
, MCAST_TRACK_ADD
, data
) == 1)
1584 /* this is for ether_output */
1585 sa
.sa_family
= AF_UNSPEC
;
1586 sa
.sa_len
= 2 + sizeof(struct etalk_addr
);
1587 bcopy (data
, &sa
.sa_data
[0], sizeof(struct etalk_addr
));
1589 dPrintf(D_M_PAT
, D_L_STARTUP
,
1590 ("pat_mcast: adding multicast %08x%04x ifID:0x%x\n",
1591 *(unsigned*)data
, (*(unsigned *)(data
+2))&0x0000ffff,
1594 if (if_addmulti(nddp
, &sa
, 0))
1601 int at_unreg_mcast(ifID
, data
)
1605 struct ifnet
*nddp
= ifID
->aa_ifp
;
1610 dPrintf(D_M_PAT
, D_L_STARTUP
, ("pat_mcast: BAD ndpp\n"));
1614 elap_trackMcast(ifID
, MCAST_TRACK_DELETE
, data
);
1616 /* this is for ether_output */
1617 sa
.sa_family
= AF_UNSPEC
;
1618 sa
.sa_len
= 2 + sizeof(struct etalk_addr
);
1619 bcopy (data
, &sa
.sa_data
[0], sizeof(struct etalk_addr
));
1621 dPrintf(D_M_PAT
, D_L_STARTUP
,
1622 ("pat_mcast: deleting multicast %08x%04x ifID:0x%x\n",
1623 *(unsigned*)data
, (*(unsigned *)(data
+2))&0x0000ffff,
1625 bzero(data
, sizeof(struct etalk_addr
));
1627 if (if_delmulti(nddp
, &sa
))
1633 /* *** at_reg_mcast() and at_unreg_mcast() should be replaced as soon as the
1634 new code to allow an AF_LINK address family multicast to be (un)registered
1635 using the SIOCADDMULTI / SIOCDELMULTI ioctls has been completed.
1637 The issue is that the "struct sockaddr_dl" needed for the AF_LINK does not
1638 fit in the "struct ifreq" that is used for these ioctls, and we do not want
1639 Blue/Classic, which currently uses AF_UNSPEC, to use a different address
1640 family multicast address than Mac OS X uses.
1643 int at_reg_mcast(ifID
, data
)
1647 struct ifnet
*nddp
= ifID
->aa_ifp
;
1648 struct sockaddr_dl sdl
;
1652 dPrintf(D_M_PAT
, D_L_STARTUP
, ("pat_mcast: BAD ndpp\n"));
1655 if (elap_trackMcast(ifID
, MCAST_TRACK_ADD
, data
) == 1)
1658 sdl
.sdl_len
= sizeof(struct sockaddr_dl
);
1659 sdl
.sdl_family
= AF_LINK
;
1661 sdl
.sdl_type
= nddp
->if_type
;
1662 sdl
.sdl_alen
= nddp
->if_addrlen
;
1664 sdl
.sdl_nlen
= sprintf(sdl
.sdl_data
, "%s%d",
1665 nddp
->if_name
, nddp
->if_unit
);
1666 bcopy(data
, LLADDR(&sdl
), sdl
.sdl_alen
);
1668 dPrintf(D_M_PAT
, D_L_STARTUP
,
1669 ("pat_mcast: adding multicast %08x%04x ifID:0x%x\n",
1670 *(unsigned*)data
, (*(unsigned *)(data
+2))&0x0000ffff,
1673 if (if_addmulti(nddp
, (struct sockaddr
*)&sdl
, 0))
1680 int at_unreg_mcast(ifID
, data
)
1684 struct ifnet
*nddp
= ifID
->aa_ifp
;
1685 struct sockaddr_dl sdl
;
1689 dPrintf(D_M_PAT
, D_L_STARTUP
, ("pat_mcast: BAD ndpp\n"));
1693 elap_trackMcast(ifID
, MCAST_TRACK_DELETE
, data
);
1695 sdl
.sdl_len
= sizeof(struct sockaddr_dl
);
1696 sdl
.sdl_family
= AF_LINK
;
1698 sdl
.sdl_type
= nddp
->if_type
;
1699 sdl
.sdl_alen
= nddp
->if_addrlen
;
1701 sdl
.sdl_nlen
= sprintf(sdl
.sdl_data
, "%s%d",
1702 nddp
->if_name
, nddp
->if_unit
);
1704 dPrintf(D_M_PAT
, D_L_STARTUP
,
1705 ("pat_mcast: deleting multicast %08x%04x ifID:0x%x\n",
1706 *(unsigned*)data
, (*(unsigned *)(data
+2))&0x0000ffff,
1708 bzero(data
, ETHERNET_ADDR_LEN
);
1710 if (if_delmulti(nddp
, (struct sockaddr
*)&sdl
))