]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/kern/netboot.c
xnu-1228.7.58.tar.gz
[apple/xnu.git] / bsd / kern / netboot.c
index 97ca556cfcc8a7ac0fbfc807ff375901089f46a6..3f2c11a86de83e4092e74cd27a0deeb7d3136d17 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001-2004 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2001-2006 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -45,6 +45,7 @@
 #include <sys/socket.h>
 #include <sys/socketvar.h>
 #include <sys/reboot.h>
+#include <sys/kauth.h>
 #include <net/if.h>
 #include <net/if_dl.h>
 #include <net/if_types.h>
 #include <netinet/in.h>
 #include <netinet/if_ether.h>
 #include <netinet/dhcp_options.h>
-#include <pexpert/pexpert.h>
+#include <netinet/in_dhcp.h>
 
 #include <kern/kern_types.h>
 #include <kern/kalloc.h>
 
+#include <pexpert/pexpert.h>
+
 //#include <libkern/libkern.h>
 extern struct filedesc         filedesc0;
 
-extern int     strncmp(const char *,const char *, size_t);
-extern unsigned long strtoul(const char *, char **, int);
-extern char *  strchr(const char *str, int ch);
-
 extern int     nfs_mountroot(void);    /* nfs_vfsops.c */
 extern int (*mountroot)(void);
 
@@ -90,12 +89,6 @@ extern int di_root_image(const char *path, char devname[], dev_t *dev_p);
 #define BSDP_RESPONSE  "bsdp-response"
 #define DHCP_RESPONSE  "dhcp-response"
 
-extern int 
-bootp(struct ifnet * ifp, struct in_addr * iaddr_p, int max_retry,
-      struct in_addr * netmask_p, struct in_addr * router_p,
-      struct proc * procp);
-
-
 /* forward declarations */
 int    inet_aton(char * cp, struct in_addr * pin);
 
@@ -103,7 +96,7 @@ boolean_t    netboot_iaddr(struct in_addr * iaddr_p);
 boolean_t      netboot_rootpath(struct in_addr * server_ip,
                                 char * name, int name_len, 
                                 char * path, int path_len);
-int    netboot_setup(struct proc * p);
+int    netboot_setup(void);
 int    netboot_mountroot(void);
 int    netboot_root(void);
 
@@ -138,7 +131,7 @@ struct netboot_info {
 int
 inet_aton(char * cp, struct in_addr * pin)
 {
-    u_char * b = (char *)pin;
+    u_char * b = (u_char *)pin;
     int           i;
     char * p;
 
@@ -168,7 +161,7 @@ inet_aton(char * cp, struct in_addr * pin)
  *   "17.202.16.17:seaport:/release/.images/Image9/CurrentHera"
  */
 static __inline__ boolean_t
-parse_booter_path(char * path, struct in_addr * iaddr_p, char * * host,
+parse_booter_path(char * path, struct in_addr * iaddr_p, char const * * host,
                  char * * mount_dir, char * * image_path)
 {
     char *     start;
@@ -255,7 +248,7 @@ find_colon(char * str)
  * nfs:17.202.42.112:/Volumes/Foo\:/Library/NetBoot/NetBootSP0:Jaguar/Jaguar.dmg
  */
 static __inline__ boolean_t
-parse_netboot_path(char * path, struct in_addr * iaddr_p, char * * host,
+parse_netboot_path(char * path, struct in_addr * iaddr_p, char const * * host,
                   char * * mount_dir, char * * image_path)
 {
        static char     tmp[MAX_IPv4_STR_LEN];  /* Danger - not thread safe */
@@ -297,7 +290,7 @@ parse_netboot_path(char * path, struct in_addr * iaddr_p, char * * host,
 }
 
 static boolean_t
-parse_image_path(char * path, struct in_addr * iaddr_p, char * * host,
+parse_image_path(char * path, struct in_addr * iaddr_p, char const * * host,
                 char * * mount_dir, char * * image_path)
 {
     if (path[0] >= '0' && path[0] <= '9') {
@@ -334,16 +327,16 @@ get_root_path(char * root_path)
     if (pkt != NULL) {
        int                     len;
        dhcpol_t                options;
-       char *                  path;
-       struct dhcp *           reply;
+       const char *            path;
+       const struct dhcp *     reply;
 
-       reply = (struct dhcp *)pkt;
-       (void)dhcpol_parse_packet(&options, reply, pkt_len, NULL);
+       reply = (const struct dhcp *)pkt;
+       (void)dhcpol_parse_packet(&options, reply, pkt_len);
 
-       path = (char *)dhcpol_find(&options, 
-                                  dhcptag_root_path_e, &len, NULL);
+       path = (const char *)dhcpol_find(&options, 
+                                        dhcptag_root_path_e, &len, NULL);
        if (path) {
-           bcopy(path, root_path, len);
+           memcpy(root_path, path, len);
            root_path[len] = '\0';
            found = TRUE;
        }
@@ -364,7 +357,7 @@ netboot_info_init(struct in_addr iaddr)
     MALLOC_ZONE(vndevice, caddr_t, MAXPATHLEN, M_NAMEI, M_WAITOK);
     if (vndevice == NULL)
        panic("netboot_info_init: M_NAMEI zone exhausted");
-    if (PE_parse_boot_arg("vndevice", vndevice) == TRUE) {
+    if (PE_parse_boot_argn("vndevice", vndevice, MAXPATHLEN) == TRUE) {
        use_hdix = FALSE;
     }
     FREE_ZONE(vndevice, MAXPATHLEN, M_NAMEI);
@@ -379,10 +372,10 @@ netboot_info_init(struct in_addr iaddr)
     MALLOC_ZONE(root_path, caddr_t, MAXPATHLEN, M_NAMEI, M_WAITOK);
     if (root_path  == NULL)
        panic("netboot_info_init: M_NAMEI zone exhausted");
-    if (PE_parse_boot_arg("rp", root_path) == TRUE
-       || PE_parse_boot_arg("rootpath", root_path) == TRUE
+    if (PE_parse_boot_argn("rp", root_path, MAXPATHLEN) == TRUE
+       || PE_parse_boot_argn("rootpath", root_path, MAXPATHLEN) == TRUE
        || get_root_path(root_path) == TRUE) {
-       char * server_name = NULL;
+       const char * server_name = NULL;
        char * mount_point = NULL;
        char * image_path = NULL;
        struct in_addr  server_ip;
@@ -395,8 +388,8 @@ netboot_info_init(struct in_addr iaddr)
            info->server_name = (char *)kalloc(info->server_name_length);
            info->mount_point_length = strlen(mount_point) + 1;
            info->mount_point = (char *)kalloc(info->mount_point_length);
-           strcpy(info->server_name, server_name);
-           strcpy(info->mount_point, mount_point);
+           strlcpy(info->server_name, server_name, info->server_name_length);
+           strlcpy(info->mount_point, mount_point, info->mount_point_length);
            
            printf("Server %s Mount %s", 
                   server_name, info->mount_point);
@@ -410,11 +403,12 @@ netboot_info_init(struct in_addr iaddr)
                }
                info->image_path = (char *)kalloc(info->image_path_length);
                if (needs_slash) {
-                   info->image_path[0] = '/';
-                   strcpy(info->image_path + 1, image_path);
-               }
-               else {
-                   strcpy(info->image_path, image_path);
+                       info->image_path[0] = '/';
+                       strlcpy(info->image_path + 1, image_path,
+                                       info->image_path_length - 1);
+               } else {
+                       strlcpy(info->image_path, image_path,
+                                       info->image_path_length);
                }
                printf(" Image %s", info->image_path);
            }
@@ -427,7 +421,7 @@ netboot_info_init(struct in_addr iaddr)
            info->use_hdix = TRUE;
            info->image_path_length = strlen(root_path) + 1;
            info->image_path = (char *)kalloc(info->image_path_length);
-           strcpy(info->image_path, root_path);
+           strlcpy(info->image_path, root_path, info->image_path_length);
        }           
        else {
            printf("netboot: root path uses unrecognized format\n");
@@ -487,8 +481,8 @@ netboot_rootpath(struct in_addr * server_ip,
               path_len, S_netboot_info_p->mount_point_length);
        return (FALSE);
     }
-    strcpy(path, S_netboot_info_p->mount_point);
-    strncpy(name, S_netboot_info_p->server_name, name_len);
+    strlcpy(path, S_netboot_info_p->mount_point, path_len);
+    strlcpy(name, S_netboot_info_p->server_name, name_len);
     *server_ip = S_netboot_info_p->server_ip;
     return (TRUE);
 }
@@ -518,21 +512,21 @@ get_ip_parameters(struct in_addr * iaddr_p, struct in_addr * netmask_p,
        }
     }
     if (pkt != NULL) {
-       struct in_addr *        ip;
+       const struct in_addr *  ip;
        int                     len;
        dhcpol_t                options;
-       struct dhcp *           reply;
+       const struct dhcp *     reply;
 
-       reply = (struct dhcp *)pkt;
-       (void)dhcpol_parse_packet(&options, reply, pkt_len, NULL);
+       reply = (const struct dhcp *)pkt;
+       (void)dhcpol_parse_packet(&options, reply, pkt_len);
        *iaddr_p = reply->dp_yiaddr;
-       ip = (struct in_addr *)
+       ip = (const struct in_addr *)
            dhcpol_find(&options, 
                        dhcptag_subnet_mask_e, &len, NULL);
        if (ip) {
            *netmask_p = *ip;
        }
-       ip = (struct in_addr *)
+       ip = (const struct in_addr *)
            dhcpol_find(&options, dhcptag_router_e, &len, NULL);
        if (ip) {
            *router_p = *ip;
@@ -542,35 +536,6 @@ get_ip_parameters(struct in_addr * iaddr_p, struct in_addr * netmask_p,
     return (pkt != NULL);
 }
 
-static int
-inet_aifaddr(struct socket * so, char * name, const struct in_addr * addr, 
-            const struct in_addr * mask,
-            const struct in_addr * broadcast)
-{
-    struct sockaddr    blank_sin;
-    struct ifaliasreq  ifra;
-
-    bzero(&blank_sin, sizeof(blank_sin));
-    blank_sin.sa_len = sizeof(blank_sin);
-    blank_sin.sa_family = AF_INET;
-
-    bzero(&ifra, sizeof(ifra));
-    strncpy(ifra.ifra_name, name, sizeof(ifra.ifra_name));
-    if (addr) {
-       ifra.ifra_addr = blank_sin;
-       ((struct sockaddr_in *)&ifra.ifra_addr)->sin_addr = *addr;
-    }
-    if (mask) {
-       ifra.ifra_mask = blank_sin;
-       ((struct sockaddr_in *)&ifra.ifra_mask)->sin_addr = *mask;
-    }
-    if (broadcast) {
-       ifra.ifra_broadaddr = blank_sin;
-       ((struct sockaddr_in *)&ifra.ifra_broadaddr)->sin_addr = *broadcast;
-    }
-    return (ifioctl(so, SIOCAIFADDR, (caddr_t)&ifra, current_proc()));
-}
-
 static int
 route_cmd(int cmd, struct in_addr d, struct in_addr g, 
          struct in_addr m, u_long more_flags)
@@ -630,7 +595,7 @@ find_interface(void)
     struct ifnet *             ifp = NULL;
 
     if (rootdevice[0]) {
-               ifp = ifunit(rootdevice);
+               ifp = ifunit((char *)rootdevice);
     }
     if (ifp == NULL) {
                ifnet_head_lock_shared();
@@ -650,14 +615,13 @@ netboot_mountroot(void)
     struct ifreq               ifr;
     struct ifnet *             ifp;
     struct in_addr             netmask = { 0 };
-    struct proc *              procp = current_proc();
+    proc_t                     procp = current_proc();
     struct in_addr             router = { 0 };
     struct socket *            so = NULL;
     unsigned int               try;
 
     bzero(&ifr, sizeof(ifr));
 
-
     /* find the interface */
     ifp = find_interface();
     if (ifp == NULL) {
@@ -665,7 +629,8 @@ netboot_mountroot(void)
        error = ENXIO;
        goto failed;
     }
-    sprintf(ifr.ifr_name, "%s%d", ifp->if_name, ifp->if_unit);
+    snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s%d", ifp->if_name,
+            ifp->if_unit);
     printf("netboot: using network interface '%s'\n", ifr.ifr_name);
 
     /* bring it up */
@@ -682,10 +647,10 @@ netboot_mountroot(void)
 
     /* grab information from the registry */
     if (get_ip_parameters(&iaddr, &netmask, &router) == FALSE) {
-       /* use BOOTP to retrieve IP address, netmask and router */
-       error = bootp(ifp, &iaddr, 32, &netmask, &router, procp);
+       /* use DHCP to retrieve IP address, netmask and router */
+       error = dhcp(ifp, &iaddr, 64, &netmask, &router, procp);
        if (error) {
-           printf("netboot: BOOTP failed %d\n", error);
+           printf("netboot: DHCP failed %d\n", error);
            goto failed;
        }
     }
@@ -758,7 +723,7 @@ netboot_mountroot(void)
        }
        break;
     case kNetBootImageTypeHTTP:
-       error = netboot_setup(procp);
+       error = netboot_setup();
        break;
     }
     if (error == 0) {
@@ -776,7 +741,7 @@ failed:
 }
 
 int
-netboot_setup(struct proc * p)
+netboot_setup()
 {
     dev_t      dev;
     int        error = 0;
@@ -788,7 +753,7 @@ netboot_setup(struct proc * p)
     if (S_netboot_info_p->use_hdix) {
        printf("netboot_setup: calling di_root_image\n");
        error = di_root_image(S_netboot_info_p->image_path, 
-                             rootdevice, &dev);
+                             (char *)rootdevice, &dev);
        if (error) {
            printf("netboot_setup: di_root_image: failed %d\n", error);
            goto done;
@@ -797,7 +762,7 @@ netboot_setup(struct proc * p)
     else {
        printf("netboot_setup: calling vndevice_root_image\n");
        error = vndevice_root_image(S_netboot_info_p->image_path, 
-                                   rootdevice, &dev);
+                                   (char *)rootdevice, &dev);
        if (error) {
            printf("netboot_setup: vndevice_root_image: failed %d\n", error);
            goto done;
@@ -810,13 +775,9 @@ netboot_setup(struct proc * p)
     if (error == 0 && rootvnode != NULL) {
         struct vnode *tvp;
         struct vnode *newdp;
-       struct vfs_context context;
-
-       context.vc_proc = p;
-       context.vc_ucred = proc_ucred(p);       /* XXX kauth_cred_get() ??? proxy */
 
        /* Get the vnode for '/'.  Set fdp->fd_fd.fd_cdir to reference it. */
-       if (VFS_ROOT(mountlist.tqh_last, &newdp, &context))
+       if (VFS_ROOT(TAILQ_LAST(&mountlist,mntlist), &newdp, vfs_context_kernel()))
                panic("netboot_setup: cannot find root vnode");
        vnode_ref(newdp);
        vnode_put(newdp);