- if (ifp == NULL)
- panic("nfs_boot: no suitable interface");
- sprintf(ireq.ifr_name, "%s%d", ifp->if_name, ifp->if_unit);
- printf("nfs_boot: using network interface '%s'\n", ireq.ifr_name);
-
- /*
- * Bring up the interface.
- */
- if ((error = socreate(AF_INET, &so, SOCK_DGRAM, 0)) != 0)
- panic("nfs_boot: socreate, error=%d", error);
- ireq.ifr_flags = ifp->if_flags | IFF_UP;
- error = ifioctl(so, SIOCSIFFLAGS, (caddr_t)&ireq, procp);
- if (error)
- panic("nfs_boot: SIFFLAGS, error=%d", error);
-
-#define DO_BOOTP
-#ifdef DO_BOOTP
- { /* use BOOTP to retrieve IP address, netmask and router */
- struct sockaddr_in sockin;
- struct in_addr router;
- struct in_addr netmask;
-
- my_ip.s_addr = 0;
- netmask.s_addr = 0;
- router.s_addr = 0;
- sockin.sin_family = AF_INET;
- sockin.sin_len = sizeof(sockin);
- sockin.sin_addr.s_addr = 0;
-#define RETRY_COUNT 32
- while ((error = bootp(ifp, &my_ip, RETRY_COUNT,
- &netmask, &router, procp))) {
- if (error == ETIMEDOUT)
- printf("nfs_boot: BOOTP timed out, retrying...\n");
-
- else {
- printf("nfs_boot: bootp() failed, error = %d\n", error);
- panic("nfs_boot");
- }
- }
- /* clear the netmask */
- ((struct sockaddr_in *)&ireq.ifr_addr)->sin_addr.s_addr = 0;
- error = ifioctl(so, SIOCSIFNETMASK, (caddr_t)&ireq, procp);
- if (error)
- printf("nfs_boot: SIOCSIFNETMASK failed: %d\n", error);
-
- if (netmask.s_addr) {
- /* set our new subnet mask */
- sockin.sin_addr = netmask;
- *((struct sockaddr_in *)&ireq.ifr_addr) = sockin;
- error = ifioctl(so, SIOCSIFNETMASK, (caddr_t)&ireq, procp);
- if (error)
- printf("nfs_boot: SIOCSIFNETMASK failed: %d\n", error);
- }
-
- /* set our address */
- sockin.sin_addr = my_ip;
- *((struct sockaddr_in *)&ireq.ifr_addr) = sockin;
- error = ifioctl(so, SIOCSIFADDR, (caddr_t)&ireq, procp);
- if (error) {
- printf("SIOCSIFADDR failed: %d\n", error);
- panic("nfs_boot.c");
- }
- printf("nfs_boot: IP address " IP_FORMAT, IP_LIST(&my_ip));
- if (netmask.s_addr)
- printf(" netmask " IP_FORMAT, IP_LIST(&netmask));
- if (router.s_addr) {
- gw_ip = router;
- printf(" router " IP_FORMAT, IP_LIST(&router));
- }
- printf("\n");
- }
-#else
- /*
- * Do RARP for the interface address.
- */
- if ((error = revarpwhoami(&my_ip, ifp)) != 0)
- panic("revarp failed, error=%d", error);
- printf("nfs_boot: client_addr=0x%x\n", ntohl(my_ip.s_addr));
-
- /*
- * Do enough of ifconfig(8) so that the chosen interface
- * can talk to the servers. (just set the address)
- */
- sin = (struct sockaddr_in *)&ireq.ifr_addr;
- bzero((caddr_t)sin, sizeof(*sin));
- sin->sin_len = sizeof(*sin);
- sin->sin_family = AF_INET;
- sin->sin_addr.s_addr = my_ip.s_addr;
- error = ifioctl(so, SIOCSIFADDR, (caddr_t)&ireq, procp);
- if (error)
- panic("nfs_boot: set if addr, error=%d", error);
-#endif DO_BOOTP
-
- /* need netmask to determine whether NFS server local */
- sin = (struct sockaddr_in *)&ireq.ifr_addr;
- bzero((caddr_t)sin, sizeof(*sin));
- sin->sin_len = sizeof(*sin);
- sin->sin_family = AF_INET;
- error = ifioctl(so, SIOCGIFNETMASK, (caddr_t)&ireq, procp);
- if (error)
- panic("nfs_boot: SIOCGIFNETMASK error=%d", error);
- my_netmask = sin->sin_addr;
-
- soclose(so);
-
- /* check for a booter-specified path */
- if (booter_path[0]) {
- nd->nd_root.ndm_saddr.sin_addr.s_addr = 0;
- nd->nd_private.ndm_saddr.sin_addr.s_addr = 0;
- if (path_getfile(booter_path, &nd->nd_root.ndm_saddr,
- nd->nd_root.ndm_host, root_path)) {
- do_bpgetfile = FALSE;
- printf("nfs_boot: using booter-supplied path '%s'\n",
- booter_path);
- if (same_subnet(nd->nd_root.ndm_saddr.sin_addr,
- my_ip, my_netmask)
- || gw_ip.s_addr) {
- do_bpwhoami = FALSE;
- }
- else {
- /* do bpwhoami to attempt to get the router */
- }
- }
- else {
- printf("nfs_boot: ignoring badly formed bootpath '%s'\n",
- booter_path);
- }