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>
61 #include <net/if_types.h>
63 #include <netat/sysglue.h>
64 #include <netat/appletalk.h>
65 #include <netat/at_var.h>
66 #include <netat/ddp.h>
67 #include <netat/lap.h>
68 #include <netat/routing_tables.h> /* rtmp+zip table structs */
69 #include <netat/zip.h>
70 #include <netat/nbp.h>
71 #include <netat/at_snmp.h>
72 #include <netat/at_pcb.h>
73 #include <netat/at_aarp.h>
74 #include <netat/asp.h>
75 #include <netat/atp.h>
76 #include <netat/debug.h>
77 #include <netat/adsp.h>
78 #include <netat/adsp_internal.h>
82 at_ifaddr_t at_interfaces
[IF_TOTAL_MAX
];
83 /* index for at_interfaces is not important */
84 at_ifaddr_t
*ifID_table
[IF_TOTAL_MAX
];
85 /* the table of ifID structures, one per interface
87 * NOTE: for MH, entry 0 in this table is
88 * now defined to be the default I/F
90 at_ifaddr_t
*ifID_home
;
91 /* always ifID_table[IFID_HOME] for now, but will be used for
92 dynamic "home port" assignment, later */
94 at_state_t at_state
; /* global state of AT network */
95 snmpFlags_t snmpFlags
;
100 #define MAX_BUFSIZE 8192
101 #define MAX_RTMP (MAX_BUFSIZE/sizeof(RT_entry)-1)
103 ((MAX_BUFSIZE - SNMP_NBP_HEADER_SIZE)/sizeof(snmpNbpEntry_t)-1)
104 #define MAX_NBP_BYTES (MAX_NBP * sizeof(snmpNbpEntry_t))
105 #define MAX_ZIP (MAX_BUFSIZE/sizeof(ZT_entry)-1)
106 #define MAX_RTMP_BYTES (MAX_RTMP * sizeof(RT_entry))
107 #define MAX_ZIP_BYTES (MAX_ZIP * sizeof(ZT_entry))
110 extern TAILQ_HEAD(name_registry
, _nve_
) name_registry
;
111 extern snmpStats_t snmpStats
;
112 extern atlock_t ddpinp_lock
;
113 extern atlock_t arpinp_lock
;
114 extern short appletalk_inited
;
115 extern int adspInited
;
116 extern struct atpcb ddp_head
;
117 extern gref_t
*atp_inputQ
[];
118 extern struct atp_state
*atp_used_list
;
119 extern asp_scb_t
*asp_scbQ
[];
120 extern asp_scb_t
*scb_used_list
;
121 extern CCB
*adsp_inputQ
[];
122 extern CCB
*ccb_used_list
;
123 extern at_ddp_stats_t at_ddp_stats
;
126 extern snmpAarpEnt_t
* getAarp(int *);
127 extern void nbp_shutdown(), routershutdown(), ddp_brt_shutdown();
128 extern void ddp_brt_init(), rtmp_init(), rtmp_input();
129 extern rtmp_router_start(at_kern_err_t
*);
130 static void getIfNames(at_ifnames_t
*);
131 static void add_route();
132 static int set_zones();
134 static int elap_online1(), re_aarp();
135 int at_reg_mcast(), at_unreg_mcast();
136 void AARPwakeup(), ZIPwakeup();
137 static void elap_hangup();
140 at_ifaddr_t
*find_ifID(if_name
)
146 for (pat_id
=0; pat_id
< xpatcnt
; pat_id
++) {
147 if (!strcmp(at_interfaces
[pat_id
].ifName
, if_name
))
148 return(&at_interfaces
[pat_id
]);
151 return((at_ifaddr_t
*)NULL
);
154 static int validate_msg_size(m
, gref
, elapp
)
159 /* checks ioctl message type for minimum expected message size &
160 sends error back if size invalid
163 register ioc_t
*iocbp
;
164 register at_if_cfg_t
*cfgp
;
168 iocbp
= (ioc_t
*) gbuf_rptr(m
);
170 dPrintf(D_M_ELAP
, D_L_INFO
, ("validate_msg_size: ioc_cmd = %d\n",
172 switch (iocbp
->ioc_cmd
) {
173 case LAP_IOC_ADD_ROUTE
:
174 size
= sizeof(RT_entry
);
176 case LAP_IOC_GET_ROUTE
:
177 size
= sizeof(RT_entry
);
179 case LAP_IOC_GET_ZONE
:
180 size
= sizeof(ZT_entryno
);
182 case LAP_IOC_SNMP_GET_CFG
:
183 case LAP_IOC_SNMP_GET_AARP
:
184 case LAP_IOC_SNMP_GET_ZIP
:
185 case LAP_IOC_SNMP_GET_RTMP
:
186 case LAP_IOC_SNMP_GET_NBP
:
190 case ELAP_IOC_GET_STATS
:
191 case LAP_IOC_SNMP_GET_DDP
:
196 dPrintf(D_M_ELAP
, D_L_ERROR
, ("validate_msg_size: unknown ioctl\n"));
200 if (size
== 0) { /* a non-data ioctl */
204 if (gbuf_cont(m
) != NULL
)
205 i
= gbuf_len(gbuf_cont(m
));
206 if (iocbp
->ioc_count
< size
|| (gbuf_cont(m
) == NULL
) || i
< size
) {
207 dPrintf(D_M_ELAP
, D_L_ERROR
,
208 ("ioctl msg error:s:%d c:%d bcont:%c delta:%d\n",
209 size
, iocbp
->ioc_count
,
210 gbuf_cont(m
)? 'Y' : 'N', i
));
216 ioc_ack(EMSGSIZE
, m
, gref
);
218 } /* validate_msg_size */
220 int lap_online(elapp
, cfgp
)
226 if (elapp
->ifState
!= LAP_OFFLINE
) {
231 if (cfgp
->flags
& ELAP_CFG_HOME
) {
233 /* only 1 home allowed! */
236 dPrintf(D_M_ELAP
, D_L_STARTUP
,
237 ("elap_wput home I/F:%s\n", cfgp
->ifr_name
));
238 elapp
->flags
|= ELAP_CFG_HOME
;
241 if (MULTIPORT_MODE
) {
242 elapp
->flags
|= ELAP_CFG_ZONELESS
;
243 if (ROUTING_MODE
&& cfgp
->netStart
)
244 elapp
->flags
|= ELAP_CFG_SEED
;
247 if (!DEFAULT_ZONE(&cfgp
->zonename
) &&
248 (elapp
->flags
& ELAP_CFG_HOME
) || MULTIHOME_MODE
) {
249 elapp
->startup_zone
= cfgp
->zonename
;
252 if (elapp
->flags
& ELAP_CFG_SEED
) {
253 dPrintf(D_M_ELAP
, D_L_STARTUP_INFO
,
254 ("elap_wput: found to be seed\n"));
255 elapp
->ifThisCableStart
= cfgp
->netStart
;
256 elapp
->ifThisCableEnd
= cfgp
->netEnd
;
259 dPrintf(D_M_ELAP
,D_L_ERROR
,
260 ("elap_wput: we believe we're not seed\n"));
261 /* from ELAP_IOC_SET_CFG */
262 if (ATALK_VALUE(cfgp
->node
)) {
266 initial_node
= cfgp
->node
.s_node
;
267 initial_net
= cfgp
->node
.s_net
;
268 if ((initial_node
<0xfe) && (initial_node
>0) &&
269 !((initial_net
== 0) ||
270 ((initial_net
>= DDP_STARTUP_LOW
)&&
271 (initial_net
<= DDP_STARTUP_HIGH
)))) {
273 elapp
->initial_addr
= cfgp
->node
;
278 elapp
->startup_error
= 0;
279 elapp
->startup_inprogress
= FALSE
;
280 if ((error
= elap_online1(elapp
)))
283 if (!(MULTIPORT_MODE
) &&
284 elapp
->ifZoneName
.len
== 1 &&
285 elapp
->ifZoneName
.str
[0] == '*' &&
286 !DEFAULT_ZONE(&cfgp
->zonename
)) {
287 nbp_add_multicast(&cfgp
->zonename
, elapp
);
292 /***********************************************************************
295 **********************************************************************/
296 int elap_wput(gref
, m
)
301 register ioc_t
*iocbp
;
302 register at_if_cfg_t
*cfgp
;
303 at_elap_stats_t
*statsp
;
310 switch (gbuf_type(m
)) {
313 dPrintf(D_M_ELAP
,D_L_ERROR
,
314 ("Output data to control channel is ignored\n"));
318 iocbp
= (ioc_t
*) gbuf_rptr(m
);
320 if (validate_msg_size(m
, gref
, &elapp
))
324 cfgp
= (at_if_cfg_t
*) gbuf_rptr(gbuf_cont(m
));
326 if (LAP_IOC_MYIOCTL(iocbp
->ioc_cmd
) ||
327 ELAP_IOC_MYIOCTL(iocbp
->ioc_cmd
)) {
329 switch (iocbp
->ioc_cmd
) {
330 case ELAP_IOC_GET_STATS
:
331 #ifdef APPLETALK_DEBUG
332 kprintf("LAP_IOC_GET_STATS\n");
334 if ( (gbuf_cont(m
) == NULL
)
335 || (elapp
= find_ifID(gbuf_rptr(gbuf_cont(m
)))) == NULL
) {
336 ioc_ack(EINVAL
, m
, gref
);
339 gbuf_freem(gbuf_cont(m
));
340 if ((gbuf_cont(m
) =gbuf_alloc(sizeof(at_elap_stats_t
),
342 ioc_ack(ENOBUFS
, m
, gref
);
345 statsp
= ((at_elap_stats_t
*)gbuf_rptr(gbuf_cont(m
)));
346 *statsp
= elapp
->stats
;
347 gbuf_wset(gbuf_cont(m
),sizeof(at_elap_stats_t
));
348 iocbp
->ioc_count
= sizeof(at_elap_stats_t
);
352 case LAP_IOC_ADD_ROUTE
:
353 #ifdef APPLETALK_DEBUG
354 kprintf("LAP_IOC_ADD_ROUTE\n");
356 add_route((RT_entry
*)gbuf_rptr(gbuf_cont(m
)));
360 case LAP_IOC_GET_ZONE
:
361 #ifdef APPLETALK_DEBUG
362 kprintf("LAP_IOC_GET_ZONE\n");
364 /* return next ZT_entryno from ZT_table
365 a pointer to the struct ZT_entryno is passed down from
366 user space and the first byte is cast to a int, if
367 this int is non-zero, then the first ZT_entry is
368 returned and subsequent calls with a zero value
369 will return the next entry in the table. The next
370 read after the last valid entry will return EINVAL
375 i
= *(int *)gbuf_rptr(gbuf_cont(m
));
376 gbuf_freem(gbuf_cont(m
));
379 pZTe
= zt_getNextZone(i
);
381 if ((gbuf_cont(m
) = gbuf_alloc(sizeof(ZT_entryno
), PRI_MED
)) == NULL
) {
382 ioc_ack(ENOBUFS
, m
, gref
);
385 *(ZT_entryno
*)gbuf_rptr(gbuf_cont(m
)) = *pZTe
;
386 gbuf_wset(gbuf_cont(m
),sizeof(ZT_entryno
));
387 iocbp
->ioc_count
= sizeof(ZT_entryno
);
391 ioc_ack(EINVAL
, m
, gref
);
395 case LAP_IOC_GET_ROUTE
:
396 #ifdef APPLETALK_DEBUG
397 kprintf("LAP_IOC_GET_ROUTE\n");
399 /* return next RT_entry from RT_table
400 * a pointer to the struct RT_entry is
401 * passed down from user space and the first
402 * byte is cast to a int, if this int is
403 * non-zero, then the first RT_entry is
404 * returned and subsequent calls with a
405 * zero value will return the next entry in
406 * the table. The next read after the last
407 * valid entry will return EINVAL
412 i
= *(int *)gbuf_rptr(gbuf_cont(m
));
413 gbuf_freem(gbuf_cont(m
));
416 pRT
= rt_getNextRoute(i
);
418 if ((gbuf_cont(m
) = gbuf_alloc(sizeof(RT_entry
), PRI_MED
)) == NULL
) {
419 ioc_ack(ENOBUFS
, m
, gref
);
422 *(RT_entry
*)gbuf_rptr(gbuf_cont(m
)) = *pRT
;
423 gbuf_wset(gbuf_cont(m
),sizeof(RT_entry
));
424 iocbp
->ioc_count
= sizeof(RT_entry
);
428 ioc_ack(EINVAL
, m
, gref
);
432 case LAP_IOC_SNMP_GET_DDP
:
433 #ifdef APPLETALK_DEBUG
434 kprintf("LAP_IOC_SNMP_GET_DDP\n");
436 if (!(at_state
.flags
& AT_ST_STARTED
)) {
437 ioc_ack(ENOTREADY
, m
, gref
);
440 if ((gbuf_cont(m
) = gbuf_alloc(sizeof(snmpStats_t
),
442 ioc_ack(ENOBUFS
, m
, gref
);
446 *(snmpStats_t
*)gbuf_rptr(gbuf_cont(m
)) = snmpStats
;
447 gbuf_wset(gbuf_cont(m
),sizeof(snmpStats
));
448 iocbp
->ioc_count
= sizeof(snmpStats
);
451 case LAP_IOC_SNMP_GET_CFG
:
452 #ifdef APPLETALK_DEBUG
453 kprintf("LAP_IOC_SNMP_GET_CFG\n");
459 i
= *(int *)gbuf_rptr(gbuf_cont(m
));
460 gbuf_freem(gbuf_cont(m
));
462 if (!(at_state
.flags
& AT_ST_STARTED
)) {
464 iocbp
->ioc_count
= 0;
465 ioc_ack(ENOTREADY
, m
, gref
);
466 dPrintf(D_M_ELAP_LOW
, D_L_INFO
,
467 ("elap_wput: cfg req, stack down\n"));
470 if (i
== UPDATE_IF_CHANGED
&&
471 !(at_state
.flags
& AT_ST_IF_CHANGED
)) {
472 iocbp
->ioc_count
= 0;
474 dPrintf(D_M_ELAP_LOW
, D_L_INFO
,
475 ("elap_wput: cfg req, unchanged\n"));
478 dPrintf(D_M_ELAP_LOW
, D_L_INFO
,
479 ("elap_wput: cfg req, changed\n"));
481 if (getSnmpCfg(&snmp
)) {
482 dPrintf(D_M_ELAP
,D_L_ERROR
,
483 ("elap_wput:SNMP_GET_CFG error\n"));
484 ioc_ack(EOPNOTSUPP
, m
, gref
);
487 /* send up only used part of table */
488 size
= sizeof(snmp
) -
489 sizeof(snmpIfCfg_t
) * (MAX_IFS
- snmp
.cfg_ifCnt
);
491 if ((gbuf_cont(m
) = gbuf_alloc(size
, PRI_MED
)) == NULL
) {
492 ioc_ack(ENOBUFS
, m
, gref
);
495 bcopy(&snmp
,gbuf_rptr(gbuf_cont(m
)),size
);
496 gbuf_wset(gbuf_cont(m
),size
);
497 iocbp
->ioc_count
= size
;
498 at_state
.flags
&= ~AT_ST_IF_CHANGED
;
503 case LAP_IOC_SNMP_GET_AARP
:
505 snmpAarpEnt_t
*snmpp
;
507 #ifdef APPLETALK_DEBUG
508 kprintf("LAP_IOC_SNMP_GET_AARP\n");
510 i
= *(int *)gbuf_rptr(gbuf_cont(m
));
511 gbuf_freem(gbuf_cont(m
));
513 dPrintf(D_M_ELAP
,D_L_INFO
,
514 ("elap_wput:calling getarp,i=%d\n", i
));
516 bytes
= i
* sizeof(snmpAarpEnt_t
);
517 dPrintf(D_M_ELAP
,D_L_INFO
,
518 ("elap_wput:getarp returned, i=%d,bytes=%d\n",
521 if ((gbuf_cont(m
) = gbuf_alloc(bytes
, PRI_MED
)) == NULL
) {
522 ioc_ack(ENOBUFS
, m
, gref
);
525 bcopy(snmpp
, gbuf_rptr(gbuf_cont(m
)), bytes
);
526 gbuf_wset(gbuf_cont(m
),bytes
);
527 iocbp
->ioc_count
= bytes
;
531 ioc_ack(EOPNOTSUPP
, m
, gref
);
535 case LAP_IOC_SNMP_GET_ZIP
:
536 #ifdef APPLETALK_DEBUG
537 kprintf("LAP_IOC_SNMP_GET_ZIP\n");
539 { /* matching brace NOT in this case */
541 register int size
, total
, tabsize
;
542 gbuf_t
*mn
; /* new gbuf */
543 gbuf_t
*mo
; /* old gbuf */
544 gbuf_t
*mt
; /* temp */
547 i
= *(int *)gbuf_rptr(gbuf_cont(m
));
548 gbuf_freem(gbuf_cont(m
));
550 if (!(at_state
.flags
& AT_ST_STARTED
)) {
551 ioc_ack(ENOTREADY
, m
, gref
);
554 if (i
== UPDATE_IF_CHANGED
&&
555 !(at_state
.flags
& AT_ST_ZT_CHANGED
)) {
556 iocbp
->ioc_count
= 0;
561 tabsize
= getZipTableSize();
563 /* retrieve table into multiple gbufs */
564 for (i
=0; i
<tabsize
; i
+=j
) {
566 MAX_ZIP
? MAX_ZIP
: tabsize
- i
;
567 size
= j
< MAX_ZIP
? sizeof(ZT_entry
)*j
: MAX_ZIP_BYTES
;
568 if ((mn
= gbuf_alloc(size
, PRI_MED
)) == NULL
) {
570 gbuf_freem(gbuf_cont(m
));
571 ioc_ack(ENOBUFS
, m
, gref
);
574 if (!mo
) { /* if first new one */
583 getZipTable((ZT_entry
*)gbuf_rptr(mn
),i
,j
);
586 if ((gbuf_cont(m
) = gbuf_alloc(sizeof(int), PRI_MED
)) == NULL
) {
589 iocbp
->ioc_count
= 0;
590 ioc_ack(ENOBUFS
, m
, gref
);
594 dPrintf(D_M_ELAP
,D_L_WARNING
,
595 ("elap_wput:snmp: empty zip table\n"));
598 *(int*)gbuf_rptr(gbuf_cont(m
)) = total
; /* return table size */
599 gbuf_wset(gbuf_cont(m
),sizeof(int));
600 iocbp
->ioc_count
= sizeof(int);
603 atalk_putnext(gref
,mt
); /* send up table */
604 at_state
.flags
&= ~AT_ST_ZT_CHANGED
;
607 case LAP_IOC_SNMP_GET_RTMP
:
608 #ifdef APPLETALK_DEBUG
609 kprintf("LAP_IOC_SNMP_GET_RTMP\n");
611 i
= *(int *)gbuf_rptr(gbuf_cont(m
));
612 gbuf_freem(gbuf_cont(m
));
614 if (!(at_state
.flags
& AT_ST_STARTED
)) {
615 ioc_ack(ENOTREADY
, m
, gref
);
618 if (i
== UPDATE_IF_CHANGED
&&
619 !(at_state
.flags
& AT_ST_RT_CHANGED
)) {
620 iocbp
->ioc_count
= 0;
626 tabsize
= getRtmpTableSize();
628 /* retrieve table into multiple gbufs */
629 for (i
=0; i
<tabsize
; i
+=j
) {
631 MAX_RTMP
? MAX_RTMP
: tabsize
- i
;
632 size
= j
< MAX_RTMP
? sizeof(RT_entry
)*j
: MAX_RTMP_BYTES
;
633 if ((mn
= gbuf_alloc(size
, PRI_MED
)) == NULL
) {
635 gbuf_freem(gbuf_cont(m
));
636 ioc_ack(ENOBUFS
, m
, gref
);
639 if (!mo
) { /* if first new one */
648 getRtmpTable((RT_entry
*)gbuf_rptr(mn
),i
,j
);
651 if ((gbuf_cont(m
) = gbuf_alloc(sizeof(int), PRI_MED
)) == NULL
) {
654 iocbp
->ioc_count
= 0;
655 ioc_ack(ENOBUFS
, m
, gref
);
660 *(int*)gbuf_rptr(gbuf_cont(m
)) = total
; /* return table size */
661 gbuf_wset(gbuf_cont(m
),sizeof(int));
662 iocbp
->ioc_count
= sizeof(int);
665 atalk_putnext(gref
,mt
); /* send up table */
666 at_state
.flags
&= ~AT_ST_RT_CHANGED
;
669 case LAP_IOC_SNMP_GET_NBP
:
670 #ifdef APPLETALK_DEBUG
671 kprintf("LAP_IOC_SNMP_GET_NBP\n");
673 i
= *(int *)gbuf_rptr(gbuf_cont(m
));
674 gbuf_freem(gbuf_cont(m
));
676 if (!(at_state
.flags
& AT_ST_STARTED
)) {
677 ioc_ack(ENOTREADY
, m
, gref
);
680 if (i
== UPDATE_IF_CHANGED
&&
681 !(at_state
.flags
& AT_ST_NBP_CHANGED
)) {
682 iocbp
->ioc_count
= 0;
684 dPrintf(D_M_ELAP_LOW
, D_L_INFO
,
685 ("elap_wput: nbp req denied, no change\n"));
690 tabsize
= getNbpTableSize();
692 /* retrieve table into multiple gbufs */
693 for (i
=0; i
<tabsize
; i
+=j
) {
695 MAX_NBP
? MAX_NBP
: tabsize
- i
;
696 size
= j
< MAX_NBP
? sizeof(snmpNbpEntry_t
)*j
: MAX_NBP_BYTES
;
698 size
+= SNMP_NBP_HEADER_SIZE
;
699 if ((mn
= gbuf_alloc(size
, PRI_MED
)) == NULL
) {
701 gbuf_freem(gbuf_cont(m
));
702 ioc_ack(ENOBUFS
, m
, gref
);
705 if (!mo
) { /* if first new one */
708 nbp
= (snmpNbpTable_t
*)gbuf_rptr(mn
);
709 nbp
->nbpt_entries
= tabsize
;
710 nbp
->nbpt_zone
= ifID_home
->ifZoneName
;
711 getNbpTable(nbp
->nbpt_table
,i
,j
);
716 getNbpTable((snmpNbpEntry_t
*)gbuf_rptr(mn
),i
,j
);
721 if ((gbuf_cont(m
) = gbuf_alloc(sizeof(int), PRI_MED
)) == NULL
) {
724 iocbp
->ioc_count
= 0;
725 ioc_ack(ENOBUFS
, m
, gref
);
730 *(int*)gbuf_rptr(gbuf_cont(m
)) = total
; /* return table size */
731 gbuf_wset(gbuf_cont(m
),sizeof(int));
732 iocbp
->ioc_count
= sizeof(int);
735 atalk_putnext(gref
,mt
); /* send up table */
736 at_state
.flags
&= ~AT_ST_NBP_CHANGED
;
741 #ifdef APPLETALK_DEBUG
742 kprintf("unknown ioctl %d\n", iocbp
->ioc_cmd
);
744 ioc_ack(ENOTTY
, m
, gref
);
745 dPrintf(D_M_ELAP
, D_L_WARNING
,
746 ("elap_wput: unknown ioctl (%d)\n", iocbp
->ioc_cmd
));
749 elapp
->stats
.unknown_mblks
++;
764 /* Called directly by ddp/zip.
766 elap_dataput(m
, elapp
, addr_flag
, addr
)
768 register at_ifaddr_t
*elapp
;
774 extern int zip_type_packet();
775 struct etalk_addr dest_addr
;
776 struct atalk_addr dest_at_addr
;
777 extern gbuf_t
*growmsg();
779 /* flag to aarp to loopback (default) */
781 /* the incoming frame is of the form {flag, address, ddp...}
782 * where "flag" indicates whether the address is an 802.3
783 * (link) address, or an appletalk address. If it's an
784 * 802.3 address, the packet can just go out to the network
785 * through PAT, if it's an appletalk address, AT->802.3 address
786 * resolution needs to be done.
787 * If 802.3 address is known, strip off the flag and 802.3
788 * address, and prepend 802.2 and 802.3 headers.
792 addr_flag
= *(u_char
*)gbuf_rptr(m
);
797 case AT_ADDR_NO_LOOP
:
802 dest_at_addr
= *(struct atalk_addr
*)gbuf_rptr(m
);
803 gbuf_rinc(m
,sizeof(struct atalk_addr
));
805 dest_at_addr
= *(struct atalk_addr
*)addr
;
809 dest_addr
= *(struct etalk_addr
*)gbuf_rptr(m
);
810 gbuf_rinc(m
,sizeof(struct etalk_addr
));
812 dest_addr
= *(struct etalk_addr
*)addr
;
815 gbuf_freel(m
); /* unknown address type, chuck it */
821 /* At this point, rptr points to ddp header for sure */
822 if (elapp
->ifState
== LAP_OFFLINE
) {
827 if (elapp
->ifState
== LAP_ONLINE_FOR_ZIP
) {
828 /* see if this is a ZIP packet that we need
829 * to let through even though network is
832 if (zip_type_packet(m
) == 0) {
838 elapp
->stats
.xmit_packets
++;
839 size
= gbuf_msgsize(m
);
840 elapp
->stats
.xmit_bytes
+= size
;
841 snmpStats
.dd_outLong
++;
844 case AT_ADDR_NO_LOOP
:
847 * we don't want elap to be looking into ddp header, so
848 * it doesn't know net#, consequently can't do
849 * AMT_LOOKUP. That task left to aarp now.
851 error
= aarp_send_data(m
,elapp
,&dest_at_addr
, loop
);
854 error
= pat_output(elapp
, m
, &dest_addr
, 0);
860 /************************************************************************
863 ************************************************************************/
865 static int elap_online1(elapp
)
870 dPrintf(D_M_ELAP
, D_L_STARTUP_INFO
, ("elap_online:%s elapp:0x%x\n",
871 (elapp
->ifName
) ? &elapp
->ifName
[0] : "NULL interface", (u_int
) elapp
));
872 if (elapp
->ifState
!= LAP_OFFLINE
|| elapp
->startup_inprogress
== TRUE
)
875 at_state
.flags
|= AT_ST_IF_CHANGED
;
877 if (elapp
->flags
& ELAP_CFG_HOME
) /* tell ddp_add_if if this is home */
878 elapp
->ifFlags
|= AT_IFF_DEFAULT
;
880 /* Get DDP started */
881 if ((errno
= ddp_add_if(elapp
)))
884 /* set up multicast address for cable-wide broadcasts */
885 (void)at_reg_mcast(elapp
, (caddr_t
)&elapp
->cable_multicast_addr
);
887 elapp
->startup_inprogress
= TRUE
;
888 if (! (elapp
->startup_error
= re_aarp(elapp
)))
889 (void)tsleep(&elapp
->startup_inprogress
, PSOCK
| PCATCH
,
892 /* then later, after some timeouts AARPwakeup() is called */
894 return(elapp
->startup_error
);
897 static int re_aarp(elapp
)
902 /* We now call aarp_init() to assign an appletalk node addr */
903 errno
= aarp_init1(elapp
);
904 /* aarp_init1() returns either -1 or ENOTREADY */
905 if (errno
== ENOTREADY
)
908 dPrintf(D_M_ELAP
, D_L_STATE_CHG
,
909 ("elap_online aarp_init for %s\n", elapp
->ifName
));
910 (void)at_unreg_mcast(elapp
, (caddr_t
)&elapp
->cable_multicast_addr
);
912 elapp
->ifState
= LAP_OFFLINE
;
913 return(EADDRNOTAVAIL
);
917 /* called from AARPwakeup */
918 static void elap_online2(elapp
)
921 if (MULTIPORT_MODE
) {
922 dPrintf(D_M_ELAP
,D_L_STARTUP_INFO
,
923 ("elap_online: re_aarp, we know it's a router...\n"));
925 if (elapp
->flags
& ELAP_CFG_SEED
) {
926 /* add route table entry (zones to be added later) */
927 dPrintf(D_M_ELAP
, D_L_STARTUP_INFO
,
928 ("elap_online: rt_insert Cable %d-%d port =%d as SEED\n",
929 elapp
->ifThisCableStart
, elapp
->ifThisCableEnd
, elapp
->ifPort
));
930 rt_insert(elapp
->ifThisCableEnd
,
931 elapp
->ifThisCableStart
,
934 RTE_STATE_PERMANENT
| RTE_STATE_ZKNOWN
| RTE_STATE_GOOD
936 /* LD 081694: set the RTR_SEED_PORT flag for seed ports */
937 elapp
->ifFlags
|= RTR_SEED_PORT
;
940 dPrintf(D_M_ELAP
,D_L_STARTUP_INFO
,
941 ("elap_online: it's a router, but non seed\n"));
944 if (elapp
->flags
& ELAP_CFG_ZONELESS
) {
945 /* ELAP_CFG_ZONELESS tells us that it is a router or in
946 multihome mode, so we don't want to do the GetNetInfo
947 exchange with the router. */
949 elapp
->ifState
= LAP_ONLINE_ZONELESS
;
950 elapp
->startup_inprogress
= FALSE
;
951 thread_wakeup(&elapp
->startup_inprogress
);
952 dPrintf(D_M_ELAP
, D_L_STARTUP_INFO
, ("elap_online: ack 3\n"));
956 /* if we don't already have a zone and a multicast address */
957 if (*(int *)&elapp
->ZoneMcastAddr
== 0 || elapp
->ifZoneName
.len
== 0) {
958 /* hzonehash is a global containing the nbp hash for the startup_zone */
961 /* Get ZIP rolling to get zone multicast address, etc. */
962 elapp
->ifState
= LAP_ONLINE_FOR_ZIP
;
963 (void)zip_control(elapp
, ZIP_ONLINE
);
964 /* zip_control (w. control == ZIP_ONLINE) always returns ENOTREADY */
966 /* later, after some timeouts ZIPwakeup() is called. */
968 /* otherwise, we have the zone and the multicast already,
969 so don't bother with another ZIP GetNetInfo request */
974 /* called from rtmp_router_start */
975 int elap_online3(elapp
)
978 elapp
->startup_inprogress
= TRUE
;
980 /* just reset the net range */
981 elapp
->initial_addr
.s_net
= 0;
982 elapp
->initial_addr
.s_node
= 0;
983 dPrintf(D_M_ELAP_LOW
, D_L_STARTUP_INFO
,
984 ("elap_online: goto re_aarp port=%d\n", elapp
->ifPort
));
986 if ((elapp
->startup_error
= re_aarp(elapp
)))
987 return(elapp
->startup_error
);
989 /* then later, after some timeouts AARPwakeup() is called */
991 (void)tsleep(&elapp
->startup_inprogress
, PSOCK
| PCATCH
,
993 return(elapp
->startup_error
);
996 /****************************************************************************
999 ****************************************************************************/
1001 void elap_offline(elapp
)
1002 register at_ifaddr_t
*elapp
;
1005 void zip_sched_getnetinfo(); /* forward reference */
1009 dPrintf(D_M_ELAP
, D_L_SHUTDN_INFO
, ("elap_offline:%s\n", elapp
->ifName
));
1010 if (elapp
->ifState
!= LAP_OFFLINE
) {
1012 /* Since AppleTalk is going away, remove the cable
1013 * multicast address and turn the interface off so that all
1014 * AppleTalk packets are dropped in the driver itself.
1015 * Get rid of the zone multicast address prior to going Offline.
1017 (void)at_unreg_mcast(elapp
, (caddr_t
)&elapp
->ZoneMcastAddr
);
1018 (void)at_unreg_mcast(elapp
, (caddr_t
)&elapp
->cable_multicast_addr
);
1019 elapp
->ifState
= LAP_OFFLINE
;
1021 ATDISABLE(s
, ddpinp_lock
);
1023 RT_DELETE(elapp
->ifThisCableEnd
,
1024 elapp
->ifThisCableStart
);
1025 ATENABLE(s
, ddpinp_lock
);
1027 /* make sure no zip timeouts are left running */
1028 untimeout(zip_sched_getnetinfo
, elapp
);
1031 } /* elap_offline */
1034 static void add_route(rt
)
1037 /* support ioctl to manually add routes to table.
1038 this is really only for testing
1041 rt_insert( rt
->NetStop
, rt
->NetStart
, rt
->NextIRNet
,
1042 rt
->NextIRNode
, rt
->NetDist
, rt
->NetPort
,
1044 dPrintf(D_M_ELAP
, D_L_STARTUP_INFO
, ("adding route: %ud:%ud dist:%ud\n",
1045 rt
->NetStart
, rt
->NetStop
,rt
->NetDist
));
1051 * Initialization that takes place each time AppleTalk is restarted.
1056 TAILQ_INIT(&at_ifQueueHd
);
1057 TAILQ_INIT(&name_registry
);
1058 bzero(at_interfaces
, sizeof(at_interfaces
));
1059 bzero(ifID_table
, sizeof(ifID_table
));
1060 bzero(&at_ddp_stats
, sizeof(at_ddp_stats_t
));
1061 rtmp_init(); /* initialize trackedrouters */
1063 add_ddp_handler(RTMP_SOCKET
, rtmp_input
);
1064 ifID_home
= (at_ifaddr_t
*)NULL
;
1068 int ddp_shutdown(count_only
)
1072 asp_scb_t
*scb
, *scb_next
;
1073 struct atp_state
*atp
, *atp_next
;
1077 active_skts
= 0; /* count of active pids for non-socketized
1078 AppleTalk protocols */
1079 extern int aarp_sched_probe();
1082 /* Network is shutting down... send error messages up on each open
1084 *** For now, for ASP, ATP and ADSP, attempt to notify open
1085 sockets, but return EBUSY and don't complete shutdown. ***
1088 s
= splimp(); /* *** previously contained mismatched locking
1089 that was ifdef'ed to splimp() *** */
1091 nbp_shutdown(); /* clear all known NVE */
1094 for (scb
= scb_used_list
; scb
; ) {
1095 scb_next
= scb
->next_scb
;
1098 dPrintf(D_M_ASP
, D_L_TRACE
, ("asp pid=%d\n", scb
->pid
));
1099 atalk_notify(scb
->gref
, ESHUTDOWN
);
1103 for (i
= 0; i
< 256 ; i
++) {
1104 if ((scb
= asp_scbQ
[i
]))
1106 scb_next
= scb
->next_scb
;
1109 dPrintf(D_M_ASP
, D_L_TRACE
,
1110 ("asp pid=%d\n", scb
->pid
));
1111 atalk_notify(scb
->gref
, ESHUTDOWN
);
1118 for (atp
= atp_used_list
; atp
; ) {
1119 atp_next
= atp
->atp_trans_waiting
;
1122 dPrintf(D_M_ATP
, D_L_TRACE
, ("atp pid=%d\n", atp
->atp_pid
));
1123 atalk_notify(atp
->atp_gref
, ESHUTDOWN
);
1127 for (i
= 0; i
< 256; i
++) {
1128 if ((gref
= atp_inputQ
[i
]) && (gref
!= (gref_t
*)1)) {
1129 atp
= (struct atp_state
*)gref
->info
;
1133 dPrintf(D_M_ATP
, D_L_TRACE
,
1134 ("atp pid=%d\n", atp
->atp_pid
));
1135 atalk_notify(atp
->atp_gref
, ESHUTDOWN
);
1142 for (sp
= ccb_used_list
; sp
; ) {
1143 sp_next
= sp
->otccbLink
;
1146 dPrintf(D_M_ADSP
, D_L_TRACE
, ("adsp pid=%d\n", sp
->pid
));
1147 atalk_notify(sp
->gref
, ESHUTDOWN
);
1151 for (i
= 0; i
< 256 ; i
++) {
1152 if ((sp
= adsp_inputQ
[i
]))
1154 sp_next
= sp
->otccbLink
;
1157 dPrintf(D_M_ADSP
, D_L_TRACE
,
1158 ("adsp pid=%d\n", sp
->pid
));
1159 atalk_notify(sp
->gref
, ESHUTDOWN
);
1166 for (gref
= ddp_head
.atpcb_next
; gref
!= &ddp_head
;
1167 gref
= gref
->atpcb_next
) {
1171 dPrintf(D_M_DDP
,D_L_TRACE
, ("ddp pid=%d\n", gref
->pid
));
1172 atalk_notify(gref
, ESHUTDOWN
);
1175 if (count_only
|| active_skts
) {
1177 return(active_skts
);
1180 /* if there are no interfaces in the process of going online, continue shutting down DDP */
1181 for (i
= 0; i
< IF_TOTAL_MAX
; i
++) {
1182 if (at_interfaces
[i
].startup_inprogress
== TRUE
)
1185 if (MULTIPORT_MODE
) {
1187 /* free memory allocated for the rtmp/zip tables */
1189 FREE(ZT_table
, M_RTABLE
);
1190 ZT_table
= (ZT_entry
*)NULL
;
1193 FREE(RT_table
, M_RTABLE
);
1194 RT_table
= (RT_entry
*)NULL
;
1198 at_state
.flags
= 0; /* make sure inits are done on restart */
1200 /* from original ddp_shutdown() */
1208 dPrintf(D_M_DDP
, D_L_VERBOSE
, ("DDP shutdown completed"));
1211 * make sure we don't have a probe timeout hanging around
1212 * it's going to try and make use of an entry in at_interfaces
1213 * which is going to be zero'd out by the call to ddp_start a
1214 * little further down
1216 untimeout(aarp_sched_probe
, 0);
1218 /* *** after an SIOCSIFADDR and before an AIOCSIFADDR,
1219 this is the only place to find the ifID *** */
1220 for (i
= 0; i
< IF_TOTAL_MAX
; i
++) {
1221 ifID
= &at_interfaces
[i
];
1222 /* do LAP_IOC_OFFLINE processing */
1229 } /* ddp_shutdown */
1231 int routerStart(keP
)
1234 register at_ifaddr_t
*ifID
;
1241 * this will cause the ports to glean from the net the relevant
1242 * information before forwarding
1244 TAILQ_FOREACH(ifID
, &at_ifQueueHd
, aa_link
) {
1245 dPrintf(D_M_ELAP
, D_L_STARTUP_INFO
,
1246 ("routerStart Port %d (%s) set to activating\n",
1247 ifID
->ifPort
, ifID
->ifName
));
1248 ifID
->ifRoutingState
= PORT_ACTIVATING
;
1249 ifID
->ifFlags
|= RTR_XNET_PORT
;
1253 * The next step is to check the information for each port before
1254 * declaring the ports up and forwarding
1256 dPrintf(D_M_ELAP
, D_L_STARTUP_INFO
,
1257 ("router_start: waiting 20 sec before starting up\n"));
1259 /* sleep for 20 seconds */
1261 /* *** eventually this will be the ifID for the interface
1262 being brought up in router mode *** */
1263 tsleep(&ifID_home
->startup_inprogress
,
1264 PSOCK
| PCATCH
, "routerStart", 20 * SYS_HZ
))
1268 panic("routerStart: spurious interrupt");
1273 return(rtmp_router_start(keP
));
1274 /* was timeout(rtmp_router_start, 0, 20 * SYS_HZ); */
1277 void ZIPwakeup(elapp
, ZipError
)
1281 int s
, error
= ZipError
;
1283 ATDISABLE(s
, ddpinp_lock
);
1284 if ( (elapp
!= NULL
) && elapp
->startup_inprogress
) {
1285 ATENABLE(s
, ddpinp_lock
);
1287 /* was ZIPContinue */
1288 /* was elapp_online() with jump to ZIP_sleep */
1290 /* instead of the goto ZIP_sleep ... */
1292 case 0 : /* success */
1293 elapp
->ifState
= LAP_ONLINE
;
1296 /* instead of goto re_aarp; */
1297 /* We now call aarp_init() to assign an
1298 appletalk node addr */
1299 if ((elapp
->startup_error
= re_aarp(elapp
))) {
1300 elapp
->startup_inprogress
= FALSE
;
1301 thread_wakeup(&elapp
->startup_inprogress
);
1302 dPrintf(D_M_ELAP
, D_L_STARTUP_INFO
,
1303 ("elap_online: ack 2\n"));
1309 if (ZipError
!= ZIP_RE_AARP
) {
1310 elapp
->startup_error
= error
;
1311 elapp
->startup_inprogress
= FALSE
;
1312 thread_wakeup(&elapp
->startup_inprogress
);
1313 dPrintf(D_M_ELAP
, D_L_STARTUP_INFO
,
1314 ("elap_online: ifZipError=%d\n", error
));
1317 ATENABLE(s
, ddpinp_lock
);
1320 void AARPwakeup(probe_cb
)
1321 aarp_amt_t
*probe_cb
;
1327 ATDISABLE(s
, arpinp_lock
);
1328 elapp
= probe_cb
->elapp
;
1329 if ( (elapp
!= NULL
) && elapp
->startup_inprogress
) {
1330 ATENABLE(s
, arpinp_lock
);
1332 /* was AARPContinue */
1333 errno
= aarp_init2(elapp
);
1334 /* aarp_init2() returns either -1 or 0 */
1336 dPrintf(D_M_ELAP
, D_L_STATE_CHG
,
1337 ("elap_online aarp_init for %s\n",
1339 (void)at_unreg_mcast(elapp
, (caddr_t
)&elapp
->ZoneMcastAddr
);
1340 (void)at_unreg_mcast(elapp
, (caddr_t
)&elapp
->cable_multicast_addr
);
1341 elapp
->ifState
= LAP_OFFLINE
;
1343 elapp
->startup_error
= EADDRNOTAVAIL
;
1344 elapp
->startup_inprogress
= FALSE
;
1345 thread_wakeup(&elapp
->startup_inprogress
);
1346 dPrintf(D_M_ELAP
, D_L_STARTUP_INFO
, ("elap_online: ack 2\n"));
1348 dPrintf(D_M_ELAP
,D_L_STARTUP_INFO
,
1349 ("elap_online: aarp_init returns zero\n"));
1350 elap_online2(elapp
);
1353 ATENABLE(s
, arpinp_lock
);
1356 void ddp_bit_reverse(addr
)
1357 unsigned char *addr
;
1359 static unsigned char reverse_data
[] = {
1360 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
1361 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
1362 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
1363 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
1364 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
1365 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
1366 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
1367 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
1368 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
1369 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
1370 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
1371 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
1372 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
1373 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
1374 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
1375 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
1376 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
1377 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
1378 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
1379 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
1380 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
1381 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
1382 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
1383 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
1384 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
1385 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
1386 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
1387 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
1388 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
1389 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
1390 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
1391 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
1396 for (k
=0; k
< 6; k
++)
1397 addr
[k
] = reverse_data
[addr
[k
]];
1400 static int elap_trackMcast(patp
, func
, addr
)
1407 switch(patp
->aa_ifp
->if_type
) {
1410 /* set addr to point to unique part of addr */
1413 /* first try to find match */
1414 /* *** save just one byte of the multicast address? *** */
1415 for (i
=0; i
< MAX_MCASTS
; i
++)
1416 if (c
== patp
->mcast
[i
]) {
1422 case MCAST_TRACK_DELETE
:
1424 patp
->mcast
[loc
] = 0;
1427 case MCAST_TRACK_ADD
:
1428 dPrintf(D_M_PAT_LOW
, D_L_USR2
, ("mctrack:add loc:%d\n", i
));
1430 dPrintf(D_M_PAT_LOW
, D_L_USR2
, ("mctrack:add, addr was there\n"));
1432 break; /* already there */
1434 for (i
=0; i
< MAX_MCASTS
; i
++)
1435 if (patp
->mcast
[i
] == 0) {
1439 dPrintf(D_M_PAT_LOW
, D_L_USR2
, ("mctrack:add1 loc:%d\n", i
));
1441 patp
->mcast
[loc
] = c
;
1442 dPrintf(D_M_PAT_LOW
, D_L_USR2
, ("mctrack:add, adding(%x)\n",
1443 (*(int*)addr
)&0xffffff));
1446 /*errno = ENOMEM; */ /*LD 5/7/97 nobody is using that */
1450 case MCAST_TRACK_CHECK
:
1452 dPrintf(D_M_PAT_LOW
, D_L_USR2
, ("mctrack:check, addr was there\n"));
1456 dPrintf(D_M_PAT_LOW
, D_L_USR2
, ("mctrack:add, addr was NOT there\n"));
1461 /*errno = EINVAL;*/ /*LD 5/7/97 nobody is using that */
1465 case IFT_ISO88025
: /* token ring */
1466 /* we would use the lowest byte of the addr argument as a value
1467 to shift left a 1 to form the mcast mask for TR. We'll do this
1477 static getSnmpCfg(snmp
)
1484 snmp
->cfg_ifCnt
= 0;
1486 bzero(snmp
,sizeof(snmpCfg_t
));
1487 for (i
=0, elapp
=at_interfaces
,ifc
=snmp
->cfg_ifCfg
;
1488 i
<IF_TOTAL_MAX
; i
++, elapp
++, ifc
++) {
1489 if (elapp
->ifState
!= LAP_OFFLINE
) {
1491 strncpy(ifc
->ifc_name
,elapp
->ifName
, sizeof(ifc
->ifc_name
));
1492 ifc
->ifc_aarpSize
= getAarpTableSize(i
);
1493 ifc
->ifc_addrSize
= getPhysAddrSize(i
);
1494 switch (elapp
->aa_ifp
->if_type
) {
1496 ifc
->ifc_type
= SNMP_TYPE_ETHER2
;
1498 case IFT_ISO88025
: /* token ring */
1499 ifc
->ifc_type
= SNMP_TYPE_TOKEN
;
1503 ifc
->ifc_type
= SNMP_TYPE_OTHER
;
1506 ifc
->ifc_start
= elapp
->ifThisCableStart
;
1507 ifc
->ifc_end
= elapp
->ifThisCableEnd
;
1508 ifc
->ifc_ddpAddr
= elapp
->ifThisNode
;
1509 ifc
->ifc_status
= elapp
->ifState
== LAP_ONLINE
? 1 : 2;
1510 ifc
->ifc_zoneName
.len
= 0;
1511 if (elapp
->ifZoneName
.len
!= 0) {
1512 ifc
->ifc_zoneName
= elapp
->ifZoneName
;
1514 else if (elapp
->ifDefZone
) {
1515 ifc
->ifc_zoneName
= ZT_table
[elapp
->ifDefZone
-1].Zone
;
1517 else /* temp, debug only */
1518 ifc
->ifc_zoneName
= ZT_table
[0].Zone
;
1520 if (elapp
->ifFlags
& RTR_SEED_PORT
) {
1521 ifc
->ifc_netCfg
= SNMP_CFG_CONFIGURED
;
1522 ifc
->ifc_zoneCfg
= SNMP_CFG_CONFIGURED
;
1525 ifc
->ifc_netCfg
= SNMP_CFG_GARNERED
;
1526 ifc
->ifc_zoneCfg
= SNMP_CFG_GARNERED
;
1529 else { /* single-port mode */
1530 if (elapp
->ifRouterState
== ROUTER_AROUND
) {
1531 ifc
->ifc_netCfg
= SNMP_CFG_GARNERED
;
1534 ifc
->ifc_netCfg
= SNMP_CFG_GUESSED
;
1535 ifc
->ifc_zoneCfg
= SNMP_CFG_UNCONFIG
;
1540 snmp
->cfg_flags
= at_state
.flags
;
1546 int at_reg_mcast(ifID
, data
)
1550 struct ifnet
*nddp
= ifID
->aa_ifp
;
1555 dPrintf(D_M_PAT
, D_L_STARTUP
, ("pat_mcast: BAD ndpp\n"));
1559 if (elap_trackMcast(ifID
, MCAST_TRACK_ADD
, data
) == 1)
1562 /* this is for ether_output */
1563 sa
.sa_family
= AF_UNSPEC
;
1564 sa
.sa_len
= 2 + sizeof(struct etalk_addr
);
1565 bcopy (data
, &sa
.sa_data
[0], sizeof(struct etalk_addr
));
1567 dPrintf(D_M_PAT
, D_L_STARTUP
,
1568 ("pat_mcast: adding multicast %08x%04x ifID:0x%x\n",
1569 *(unsigned*)data
, (*(unsigned *)(data
+2))&0x0000ffff,
1572 if (if_addmulti(nddp
, &sa
, 0))
1579 int at_unreg_mcast(ifID
, data
)
1583 struct ifnet
*nddp
= ifID
->aa_ifp
;
1588 dPrintf(D_M_PAT
, D_L_STARTUP
, ("pat_mcast: BAD ndpp\n"));
1592 elap_trackMcast(ifID
, MCAST_TRACK_DELETE
, data
);
1594 /* this is for ether_output */
1595 sa
.sa_family
= AF_UNSPEC
;
1596 sa
.sa_len
= 2 + sizeof(struct etalk_addr
);
1597 bcopy (data
, &sa
.sa_data
[0], sizeof(struct etalk_addr
));
1599 dPrintf(D_M_PAT
, D_L_STARTUP
,
1600 ("pat_mcast: deleting multicast %08x%04x ifID:0x%x\n",
1601 *(unsigned*)data
, (*(unsigned *)(data
+2))&0x0000ffff,
1603 bzero(data
, sizeof(struct etalk_addr
));
1605 if (if_delmulti(nddp
, &sa
))
1611 /* *** at_reg_mcast() and at_unreg_mcast() should be replaced as soon as the
1612 new code to allow an AF_LINK address family multicast to be (un)registered
1613 using the SIOCADDMULTI / SIOCDELMULTI ioctls has been completed.
1615 The issue is that the "struct sockaddr_dl" needed for the AF_LINK does not
1616 fit in the "struct ifreq" that is used for these ioctls, and we do not want
1617 Blue/Classic, which currently uses AF_UNSPEC, to use a different address
1618 family multicast address than Mac OS X uses.
1621 int at_reg_mcast(ifID
, data
)
1625 struct ifnet
*nddp
= ifID
->aa_ifp
;
1626 struct sockaddr_dl sdl
;
1630 dPrintf(D_M_PAT
, D_L_STARTUP
, ("pat_mcast: BAD ndpp\n"));
1633 if (elap_trackMcast(ifID
, MCAST_TRACK_ADD
, data
) == 1)
1636 sdl
.sdl_len
= sizeof(struct sockaddr_dl
);
1637 sdl
.sdl_family
= AF_LINK
;
1639 sdl
.sdl_type
= nddp
->if_type
;
1640 sdl
.sdl_alen
= nddp
->if_addrlen
;
1642 sdl
.sdl_nlen
= sprintf(sdl
.sdl_data
, "%s%d",
1643 nddp
->if_name
, nddp
->if_unit
);
1644 bcopy(data
, LLADDR(&sdl
), sdl
.sdl_alen
);
1646 dPrintf(D_M_PAT
, D_L_STARTUP
,
1647 ("pat_mcast: adding multicast %08x%04x ifID:0x%x\n",
1648 *(unsigned*)data
, (*(unsigned *)(data
+2))&0x0000ffff,
1651 if (if_addmulti(nddp
, (struct sockaddr
*)&sdl
, 0))
1658 int at_unreg_mcast(ifID
, data
)
1662 struct ifnet
*nddp
= ifID
->aa_ifp
;
1663 struct sockaddr_dl sdl
;
1667 dPrintf(D_M_PAT
, D_L_STARTUP
, ("pat_mcast: BAD ndpp\n"));
1671 elap_trackMcast(ifID
, MCAST_TRACK_DELETE
, data
);
1673 sdl
.sdl_len
= sizeof(struct sockaddr_dl
);
1674 sdl
.sdl_family
= AF_LINK
;
1676 sdl
.sdl_type
= nddp
->if_type
;
1677 sdl
.sdl_alen
= nddp
->if_addrlen
;
1679 sdl
.sdl_nlen
= sprintf(sdl
.sdl_data
, "%s%d",
1680 nddp
->if_name
, nddp
->if_unit
);
1682 dPrintf(D_M_PAT
, D_L_STARTUP
,
1683 ("pat_mcast: deleting multicast %08x%04x ifID:0x%x\n",
1684 *(unsigned*)data
, (*(unsigned *)(data
+2))&0x0000ffff,
1686 bzero(data
, ETHERNET_ADDR_LEN
);
1688 if (if_delmulti(nddp
, (struct sockaddr
*)&sdl
))