X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/1c79356b52d46aa6b508fb032f5ae709b1f2897b..43866e378188c25dd1e2208016ab3cbeb086ae6c:/bsd/netat/at.c?ds=sidebyside diff --git a/bsd/netat/at.c b/bsd/netat/at.c index f1a750bbf..c333d15bc 100644 --- a/bsd/netat/at.c +++ b/bsd/netat/at.c @@ -3,19 +3,22 @@ * * @APPLE_LICENSE_HEADER_START@ * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ @@ -38,8 +41,6 @@ #include #include #include -#include -#include #include #include @@ -51,7 +52,9 @@ #include #include -extern int at_ioctl(struct atpcb *, u_long, caddr_t); +#include + +extern int at_ioctl(struct atpcb *, u_long, caddr_t, int fromKernel); extern int routerStart(at_kern_err_t *); extern void elap_offline(at_ifaddr_t *); extern at_ifaddr_t *find_ifID(char *); @@ -142,10 +145,10 @@ int at_control(so, cmd, data, ifp) work with BSD-style sockets instead of the special purpose system calls, ATsocket() and ATioctl(). *** */ - if ((error = at_ioctl((struct atpcb *)so->so_pcb, cmd, data))) { + if ((error = at_ioctl((struct atpcb *)so->so_pcb, cmd, data, 0))) { if (((struct atpcb *)so->so_pcb)->proto != ATPROTO_LAP) { ((struct atpcb *)so->so_pcb)->proto = ATPROTO_LAP; - error = at_ioctl((struct atpcb *)so->so_pcb, cmd, data); + error = at_ioctl((struct atpcb *)so->so_pcb, cmd, data, 0); } } return(error); @@ -246,13 +249,13 @@ int at_control(so, cmd, data, ifp) /* check the zone name */ if (MULTIPORT_MODE) { short zno; - char ifs_in_zone[IF_TOTAL_MAX]; + at_ifnames_t ifs_in_zone; if (!(zno = zt_find_zname(&defzonep->zonename))) return(EINVAL); - getIfUsage(zno-1, ifs_in_zone); - if (!ifs_in_zone[ifID->ifPort]) + getIfUsage(zno-1, &ifs_in_zone); + if (!ifs_in_zone.at_if[ifID->ifPort]) return(EINVAL); ifID->ifDefZone = zno+1; } else { @@ -271,6 +274,10 @@ int at_control(so, cmd, data, ifp) } ifID->ifZoneName = defzonep->zonename; (void)regDefaultZone(ifID); + + /* AppleTalk zone was changed. Send event with zone info. */ + atalk_post_msg(ifID->aa_ifp, KEV_ATALK_ZONEUPDATED, 0, &(ifID->ifZoneName)); + return(0); } } else @@ -346,18 +353,20 @@ int at_control(so, cmd, data, ifp) this zone */ int finished = FALSE; int zno; - char ifs_in_zone[IF_TOTAL_MAX]; + at_ifnames_t ifs_in_zone; if (!(zno = zt_find_zname(&nve.zone))) { return(EINVAL); } - getIfUsage(zno-1, ifs_in_zone); + getIfUsage(zno-1, &ifs_in_zone); TAILQ_FOREACH(ifID, &at_ifQueueHd, aa_link) { - if (!ifs_in_zone[ifID->ifPort]) + if (!ifs_in_zone.at_if[ifID->ifPort]) /* zone doesn't match */ continue; - else + else { finished = TRUE; + break; + } } if (!finished) return(EINVAL); @@ -523,8 +532,8 @@ int at_control(so, cmd, data, ifp) break; } case AIOCSTOPATALK: - { - int *count_only = (int *)data, + { + int *count_only = (int *)data, ret; /* check for root access */ @@ -532,13 +541,26 @@ int at_control(so, cmd, data, ifp) return(EACCES); ret = ddp_shutdown(*count_only); - if (*count_only) { + + if (*count_only != 0) + { *count_only = ret; return(0); - } else - return((ret == 0)? 0 : EBUSY); + } + else + { + if (ret == 0) + { + /* AppleTalk was successfully shut down. Send event. */ + atalk_post_msg(0, KEV_ATALK_DISABLED, 0, 0); + return 0; + } + else + return EBUSY; + } + break; - } + } case SIOCSIFADDR: /* check for root access */ @@ -549,7 +571,7 @@ int at_control(so, cmd, data, ifp) else { int s; if (xpatcnt == 0) { - at_state.flags |= AT_ST_STARTED; + at_state.flags |= AT_ST_STARTING; ddp_brt_init(); } @@ -612,18 +634,18 @@ int at_control(so, cmd, data, ifp) /* complete the initialization started in SIOCSIFADDR */ case AIOCSIFADDR: - { + { at_if_cfg_t *cfgp = (at_if_cfg_t *)data; - if (!(at_state.flags & AT_ST_STARTED)) + if (!(at_state.flags & AT_ST_STARTING)) return(ENOTREADY); if (!(ifID = find_ifID(cfgp->ifr_name))) return(EINVAL); - + return(lap_online(ifID, cfgp)); break; - } + } #ifdef NOT_YET /* *** this can't be added until AT can handle dynamic addition and @@ -679,3 +701,36 @@ int at_control(so, cmd, data, ifp) return(error); } + +/* From dlil_post_msg() */ +void atalk_post_msg(struct ifnet *ifp, u_long event_code, struct at_addr *address, at_nvestr_t *zone) +{ + struct kev_atalk_data at_event_data; + struct kev_msg ev_msg; + + ev_msg.vendor_code = KEV_VENDOR_APPLE; + ev_msg.kev_class = KEV_NETWORK_CLASS; + ev_msg.kev_subclass = KEV_ATALK_SUBCLASS; + ev_msg.event_code = event_code; + + bzero(&at_event_data, sizeof(struct kev_atalk_data)); + + if (ifp != 0) { + strncpy(&at_event_data.link_data.if_name[0], ifp->if_name, IFNAMSIZ); + at_event_data.link_data.if_family = ifp->if_family; + at_event_data.link_data.if_unit = (unsigned long) ifp->if_unit; + } + + if (address != 0) { + at_event_data.node_data.address = *address; + } + else if (zone != 0) { + at_event_data.node_data.zone = *zone; + } + + ev_msg.dv[0].data_length = sizeof(struct kev_atalk_data); + ev_msg.dv[0].data_ptr = &at_event_data; + ev_msg.dv[1].data_length = 0; + + kev_post_msg(&ev_msg); +}