X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/ff6e181ae92fc6f1e89841290f461d1f2f9badd9..2d21ac55c334faf3a56e5634905ed6987fc787d4:/bsd/netat/at.c diff --git a/bsd/netat/at.c b/bsd/netat/at.c index e4b70e4a2..572b7f58b 100644 --- a/bsd/netat/at.c +++ b/bsd/netat/at.c @@ -1,14 +1,19 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved. * - * @APPLE_LICENSE_HEADER_START@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * * 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. + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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 @@ -18,7 +23,7 @@ * Please see the License for the specific language governing rights and * limitations under the License. * - * @APPLE_LICENSE_HEADER_END@ + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ /* * Copyright (c) 1998 Apple Computer, Inc. @@ -42,8 +47,8 @@ #include #include -#include #include +#include #include #include #include @@ -52,13 +57,13 @@ #include #include +#include + +int lap_online( at_ifaddr_t *, at_if_cfg_t *cfgp); -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 *); -extern at_nvestr_t *getRTRLocalZone(zone_usage_t *); -extern int setLocalZones(at_nvestr_t *, int); extern int xpatcnt; extern at_ifaddr_t at_interfaces[]; @@ -72,8 +77,7 @@ struct etalk_addr ttalk_multicast_addr = { {0xC0, 0x00, 0x40, 0x00, 0x00, 0x00}}; /* called only in router mode */ -static int set_zones(ifz) - zone_usage_t *ifz; +static int set_zones(zone_usage_t *ifz) /* 1. adds zone to table 2. looks up each route entry from zone list @@ -88,7 +92,10 @@ static int set_zones(ifz) short zno; RT_entry *rte; - zno = zt_add_zone(ifz->zone_name.str, ifz->zone_name.len); + if (ifz->zone_name.len <= 0 || ifz->zone_name.len > NBP_NVE_STR_SIZE) + return(ENOSPC); + + zno = zt_add_zone((char *)ifz->zone_name.str, ifz->zone_name.len); if (zno == ZT_MAXEDOUT) { dPrintf(D_M_ELAP, D_L_ERROR, ("set_zones: error: table full\n")); @@ -135,14 +142,12 @@ at_control(so, cmd, data, ifp) { struct ifreq *ifr = (struct ifreq *)data; int pat_id = 0, error = 0; - struct proc *p = current_proc(); at_ifaddr_t *ifID = 0; struct ifaddr *ifa; struct sockaddr_dl *sdl; if ((cmd & 0xffff) == 0xff99) { u_long fixed_command; - char ioctl_buffer[32]; /* *** this is a temporary hack to get at_send_to_dev() to work with BSD-style sockets instead of the special purpose system calls, ATsocket() and ATioctl(). @@ -196,8 +201,8 @@ at_control(so, cmd, data, ifp) } } else { ifID = ifID_home; - strncpy(cfgp->ifr_name, ifID->ifName, - sizeof(ifID->ifName)); + strlcpy(cfgp->ifr_name, ifID->ifName, + sizeof(cfgp->ifr_name)); } if (ifID && ifID->ifState != LAP_OFFLINE) { cfgp->flags = ifID->ifFlags; @@ -222,7 +227,7 @@ at_control(so, cmd, data, ifp) at_def_zone_t *defzonep = (at_def_zone_t *)data; /* check for root access */ - if (error = suser(kauth_cred_get(), 0)) + if ((error = suser(kauth_cred_get(), 0))) return(EACCES); ifID = 0; @@ -235,8 +240,8 @@ at_control(so, cmd, data, ifp) } } else { ifID = ifID_home; - strncpy(defzonep->ifr_name, ifID->ifName, - sizeof(ifID->ifName)); + strlcpy(defzonep->ifr_name, ifID->ifName, + sizeof(defzonep->ifr_name)); } /* In routing mode the default zone is only set for the @@ -387,13 +392,11 @@ at_control(so, cmd, data, ifp) /* Normal case; no tuple found for this name, so insert * this tuple in the registry and return ok response. */ - ATDISABLE(nve_lock, NVE_LOCK); if ((error2 = nbp_new_nve_entry(&nve, ifID)) == 0) { nbpP->addr.net = ifID->ifThisNode.s_net; nbpP->addr.node = ifID->ifThisNode.s_node; nbpP->unique_nbp_id = nve.unique_nbp_id; } - ATENABLE(nve_lock, NVE_LOCK); return(error2); break; @@ -409,16 +412,13 @@ at_control(so, cmd, data, ifp) /* delete by id */ if (nbpP->unique_nbp_id) { - ATDISABLE(nve_lock, NVE_LOCK); TAILQ_FOREACH(nve_entry, &name_registry, nve_link) { if (nve_entry->unique_nbp_id == nbpP->unique_nbp_id) { /* Found a match! */ nbp_delete_entry(nve_entry); - ATENABLE(nve_lock, NVE_LOCK); return(0); } } - ATENABLE(nve_lock, NVE_LOCK); return(EADDRNOTAVAIL); } @@ -438,9 +438,7 @@ at_control(so, cmd, data, ifp) if ((nve_entry = nbp_find_nve(&nve)) == NULL) continue; - ATDISABLE(nve_lock, NVE_LOCK); nbp_delete_entry(nve_entry); - ATENABLE(nve_lock, NVE_LOCK); found = TRUE; } if (found) @@ -456,9 +454,7 @@ at_control(so, cmd, data, ifp) /* Normal case; tuple found for this name, so delete * the entry from the registry and return ok response. */ - ATDISABLE(nve_lock, NVE_LOCK); nbp_delete_entry(nve_entry); - ATENABLE(nve_lock, NVE_LOCK); return(0); break; @@ -469,7 +465,7 @@ at_control(so, cmd, data, ifp) at_router_params_t *rt = (at_router_params_t *)data; /* check for root access */ - if (error = suser(kauth_cred_get(), 0)) + if ((error = suser(kauth_cred_get(), 0))) return(EACCES); /* when in routing/multihome mode the AIOCSETROUTER IOCTL @@ -540,7 +536,7 @@ at_control(so, cmd, data, ifp) ret; /* check for root access */ - if (error = suser(kauth_cred_get(), 0)) + if ((error = suser(kauth_cred_get(), 0))) return(EACCES); ret = ddp_shutdown(*count_only); @@ -567,12 +563,11 @@ at_control(so, cmd, data, ifp) case SIOCSIFADDR: /* check for root access */ - if (error = suser(kauth_cred_get(), 0)) + if ((error = suser(kauth_cred_get(), 0))) error = EACCES; else if (ifID) error = EEXIST; else { - int s; if (xpatcnt == 0) { at_state.flags |= AT_ST_STARTING; ddp_brt_init(); @@ -581,10 +576,21 @@ at_control(so, cmd, data, ifp) /* *** find an empty entry *** */ ifID = &at_interfaces[xpatcnt]; bzero((caddr_t)ifID, sizeof(at_ifaddr_t)); - strncpy(ifID->ifName, ifr->ifr_name, sizeof(ifID->ifName)); + strlcpy(ifID->ifName, ifr->ifr_name, sizeof(ifID->ifName)); ifID->aa_ifp = ifp; ifa = &ifID->aa_ifa; + error = proto_plumb(PF_APPLETALK, ifp); + if (error == EEXIST) { + ifID->at_was_attached = 1; + error = 0; + } + if (error != 0) { + break; + } + /* XXX ethernet-specific */ + ifID->cable_multicast_addr = etalk_multicast_addr; + xpatcnt++; ifnet_lock_exclusive(ifp); TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) && @@ -608,31 +614,6 @@ at_control(so, cmd, data, ifp) is set */ if_attach_ifa(ifp, ifa); ifnet_lock_done(ifp); - - switch (ifp->if_type) { - case IFT_ETHER: - case IFT_L2VLAN: - case IFT_IEEE8023ADLAG: /* bonded ethernet */ - ether_attach_at(ifp); - error = 0; - ifID->cable_multicast_addr = etalk_multicast_addr; - - xpatcnt++; - break; - case IFT_FDDI: - ifID->cable_multicast_addr = etalk_multicast_addr; - ddp_bit_reverse(&ifID->cable_multicast_addr); - xpatcnt++; - break; - case IFT_ISO88025: /* token ring */ - ifID->cable_multicast_addr = ttalk_multicast_addr; - ddp_bit_reverse(&ifID->cable_multicast_addr); - - xpatcnt++; - break; - default: - error = EINVAL; - } } break; @@ -666,21 +647,17 @@ at_control(so, cmd, data, ifp) #endif case SIOCSETOT: { - int s; struct atpcb *at_pcb, *clonedat_pcb; int cloned_fd = *(int *)data; - s = splnet(); /* XXX */ at_pcb = sotoatpcb(so); /* let's make sure it's either -1 or a valid file descriptor */ if (cloned_fd != -1) { struct socket *cloned_so; error = file_socket(cloned_fd, &cloned_so); - if (error){ - splx(s); /* XXX */ + if (error) break; - } clonedat_pcb = sotoatpcb(cloned_so); } else { clonedat_pcb = NULL; @@ -691,15 +668,40 @@ at_control(so, cmd, data, ifp) } else { at_pcb->ddp_flags = clonedat_pcb->ddp_flags; } - splx(s); /* XXX */ file_drop(cloned_fd); break; } + case SIOCPROTOATTACH: + /* check for root access */ + if (suser(kauth_cred_get(), 0) != 0) { + error = EACCES; + break; + } + error = proto_plumb(PF_APPLETALK, ifp); + if (ifID != NULL + && (error == 0 || error == EEXIST)) { + ifID->at_was_attached = 1; + } + break; + + case SIOCPROTODETACH: + /* check for root access */ + if (suser(kauth_cred_get(), 0) != 0) { + error = EACCES; + break; + } + if (ifID != NULL) { + error = EBUSY; + break; + } + error = proto_unplumb(PF_APPLETALK, ifp); + break; + default: if (ifp == 0 || ifp->if_ioctl == 0) return (EOPNOTSUPP); - return dlil_ioctl(0, ifp, cmd, (caddr_t) data); + return ifnet_ioctl(ifp, 0, cmd, data); } return(error); @@ -719,7 +721,7 @@ void atalk_post_msg(struct ifnet *ifp, u_long event_code, struct at_addr *addres 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); + strlcpy(&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; }