]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/netat/at.c
xnu-1228.15.4.tar.gz
[apple/xnu.git] / bsd / netat / at.c
index 786b779a8b6bac42db9c806a0db98bc621ff642f..572b7f58bafea647a6ea38296a3bbd8397efa3a0 100644 (file)
@@ -1,31 +1,29 @@
 /*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved.
  *
- * @APPLE_LICENSE_OSREFERENCE_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.  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 
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
- * Please see the License for the specific language governing rights and 
+ * 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. 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
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * 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_OSREFERENCE_HEADER_END@
+ * 
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 /*
  *     Copyright (c) 1998 Apple Computer, Inc. 
@@ -49,8 +47,8 @@
 #include <net/if_types.h>
 #include <net/dlil.h>
 
-#include <netat/appletalk.h>
 #include <netat/sysglue.h>
+#include <netat/appletalk.h>
 #include <netat/at_pcb.h>
 #include <netat/at_var.h>
 #include <netat/ddp.h>
 #include <netat/debug.h>
 
 #include <sys/kern_event.h>
+#include <net/kpi_protocol.h>
+
+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[];
@@ -94,7 +92,10 @@ static int set_zones(zone_usage_t *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"));
@@ -141,7 +142,6 @@ 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;
@@ -201,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;
@@ -227,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;
@@ -240,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 
@@ -465,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 
@@ -536,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);
@@ -563,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();
@@ -577,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) &&
@@ -604,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;
 
@@ -687,10 +672,36 @@ at_control(so, cmd, data, ifp)
         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);
@@ -710,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;
        }