root/fs/nfs/nfsroot.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. root_dev_open
  2. root_dev_close
  3. root_rarp_open
  4. root_rarp_close
  5. root_rarp_recv
  6. root_rarp_send
  7. root_free_bootp
  8. root_alloc_bootp
  9. root_add_bootp_route
  10. root_del_bootp_route
  11. root_open_udp_sock
  12. root_connect_udp_sock
  13. root_bind_udp_sock
  14. root_send_udp
  15. root_recv_udp
  16. root_bootp_init_ext
  17. root_bootp_close
  18. root_bootp_open
  19. root_bootp_send
  20. root_bootp_string
  21. root_do_bootp_ext
  22. root_bootp_recv
  23. root_auto_config
  24. root_nfs_parse
  25. root_nfs_print
  26. root_nfs_ip_config
  27. root_nfs_setup
  28. nfs_root_init
  29. root_nfs_open
  30. root_nfs_close
  31. root_nfs_bind
  32. root_nfs_call
  33. root_nfs_header
  34. root_nfs_get_port
  35. root_nfs_ports
  36. root_nfs_get_handle
  37. root_nfs_do_mount
  38. nfs_root_mount

   1 /*
   2  *  linux/fs/nfs/nfsroot.c -- version 2.1
   3  *
   4  *  Copyright (C) 1995  Gero Kuhlmann <gero@gkminix.han.de>
   5  *  Copyright (C) 1996  Martin Mares <mj@k332.feld.cvut.cz>
   6  *
   7  *  Allow an NFS filesystem to be mounted as root. The way this works is:
   8  *     (1) Determine the local IP address via RARP or BOOTP or from the
   9  *         kernel command line.
  10  *     (2) Handle RPC negotiation with the system which replied to RARP or
  11  *         was reported as a boot server by BOOTP or manually.
  12  *     (3) The actual mounting is done later, when init() is running.
  13  *
  14  *
  15  *      Changes:
  16  *
  17  *      Alan Cox        :       Removed get_address name clash with FPU.
  18  *      Alan Cox        :       Reformatted a bit.
  19  *      Michael Rausch  :       Fixed recognition of an incoming RARP answer.
  20  *      Martin Mares    : (2.0) Auto-configuration via BOOTP supported.
  21  *      Martin Mares    :       Manual selection of interface & BOOTP/RARP.
  22  *      Martin Mares    :       Using network routes instead of host routes,
  23  *                              allowing the default configuration to be used
  24  *                              for normal operation of the host.
  25  *      Martin Mares    :       Randomized timer with exponential backoff
  26  *                              installed to minimize network congestion.
  27  *      Martin Mares    :       Code cleanup.
  28  *      Martin Mares    : (2.1) BOOTP and RARP made configuration options.
  29  *      Martin Mares    :       Server hostname generation fixed.
  30  *      Gerd Knorr      :       Fixed wired inode handling
  31  *      Martin Mares    : (2.2) "0.0.0.0" addresses from command line ignored.
  32  *      Martin Mares    :       RARP replies not tested for server address.
  33  *
  34  *
  35  *      Known bugs and caveats:
  36  *
  37  *      - BOOTP code doesn't handle multiple network interfaces properly.
  38  *        For now, it uses the first one, trying to prefer ethernet-like
  39  *        devices. Not critical as diskless stations are usually single-homed.
  40  *
  41  */
  42 
  43 
  44 /* Define this to allow debugging output */
  45 #undef NFSROOT_DEBUG
  46 #undef NFSROOT_MORE_DEBUG
  47 
  48 /* Define the timeout for waiting for a RARP/BOOTP reply */
  49 #define CONF_BASE_TIMEOUT       (HZ*5)  /* Initial timeout: 5 seconds */
  50 #define CONF_RETRIES            10      /* 10 retries */
  51 #define CONF_TIMEOUT_RANDOM     (HZ)    /* Maximum amount of randomization */
  52 #define CONF_TIMEOUT_MULT       *5/4    /* Speed of timeout growth */
  53 #define CONF_TIMEOUT_MAX        (HZ*30) /* Maximum allowed timeout */
  54 
  55 #include <linux/config.h>
  56 #include <linux/types.h>
  57 #include <linux/string.h>
  58 #include <linux/kernel.h>
  59 #include <linux/sched.h>
  60 #include <linux/fs.h>
  61 
  62 #include <asm/param.h>
  63 #include <linux/utsname.h>
  64 #include <linux/in.h>
  65 #include <linux/if.h>
  66 #include <linux/inet.h>
  67 #include <linux/net.h>
  68 #include <linux/if_arp.h>
  69 #include <linux/netdevice.h>
  70 #ifdef CONFIG_AX25
  71 #include <net/ax25.h>   /* For AX25_P_IP */
  72 #endif
  73 #include <linux/skbuff.h>
  74 #include <linux/socket.h>
  75 #include <linux/route.h>
  76 #include <linux/nfs.h>
  77 #include <linux/nfs_fs.h>
  78 #include <linux/nfs_mount.h>
  79 #include <linux/in.h>
  80 #include <net/route.h>
  81 #include <net/sock.h>
  82 #include <linux/random.h>
  83 #include <linux/fcntl.h>
  84 
  85 
  86 /* Range of privileged ports */
  87 #define STARTPORT       600
  88 #define ENDPORT         1023
  89 #define NPORTS          (ENDPORT - STARTPORT + 1)
  90 
  91 
  92 /* List of open devices */
  93 struct open_dev {
  94         struct device *dev;
  95         unsigned short old_flags;
  96         struct open_dev *next;
  97 };
  98 
  99 static struct open_dev *open_base = NULL;
 100 
 101 /* IP configuration */
 102 static struct device *root_dev = NULL;  /* Device selected for booting */
 103 static char user_dev_name[IFNAMSIZ];    /* Name of user-selected boot device */
 104 static struct sockaddr_in myaddr;       /* My IP address */
 105 static struct sockaddr_in server;       /* Server IP address */
 106 static struct sockaddr_in gateway;      /* Gateway IP address */
 107 static struct sockaddr_in netmask;      /* Netmask for local subnet */
 108 
 109 /* BOOTP/RARP variables */
 110 
 111 static int bootp_flag;                  /* User said: Use BOOTP! */
 112 static int rarp_flag;                   /* User said: Use RARP! */
 113 static int bootp_dev_count = 0;         /* Number of devices allowing BOOTP */
 114 static int rarp_dev_count = 0;          /* Number of devices allowing RARP */
 115 
 116 #if defined(CONFIG_RNFS_BOOTP) || defined(CONFIG_RNFS_RARP)
 117 #define CONFIG_RNFS_DYNAMIC             /* Enable dynamic IP config */
 118 volatile static int pkt_arrived;        /* BOOTP/RARP packet detected */
 119 
 120 #define ARRIVED_BOOTP 1
 121 #define ARRIVED_RARP 2
 122 #endif
 123 
 124 /* NFS-related data */
 125 static struct nfs_mount_data nfs_data;  /* NFS mount info */
 126 static char nfs_path[NFS_MAXPATHLEN];   /* Name of directory to mount */
 127 static int nfs_port;                    /* Port to connect to for NFS service */
 128 
 129 /* Macro for formatting of addresses in debug dumps */
 130 #define IN_NTOA(x) (((x) == INADDR_NONE) ? "none" : in_ntoa(x))
 131 
 132 /* Yes, we use sys_socket, but there's no include file for it */
 133 extern asmlinkage int sys_socket(int family, int type, int protocol);
 134      
 135 
 136 /***************************************************************************
 137 
 138                         Device Handling Subroutines
 139 
 140  ***************************************************************************/
 141 
 142 /*
 143  * Setup and initialize all network devices. If there is a user-prefered
 144  * interface, ignore all other interfaces.
 145  */
 146 static int root_dev_open(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 147 {
 148         struct open_dev *openp, **last;
 149         struct device *dev;
 150         unsigned short old_flags;
 151 
 152         last = &open_base;
 153         for (dev = dev_base; dev != NULL; dev = dev->next) {
 154                 if (dev->type < ARPHRD_SLIP &&
 155                     dev->family == AF_INET &&
 156                     !(dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) &&
 157                     (!user_dev_name[0] || !strcmp(dev->name, user_dev_name))) {
 158                         /* First up the interface */
 159                         old_flags = dev->flags;
 160                         dev->flags = IFF_UP | IFF_BROADCAST | IFF_RUNNING;
 161                         if (!(old_flags & IFF_UP) && dev_open(dev)) {
 162                                 dev->flags = old_flags;
 163                                 continue;
 164                         }
 165                         openp = (struct open_dev *) kmalloc(sizeof(struct open_dev),
 166                                                 GFP_ATOMIC);
 167                         if (openp == NULL)
 168                                 continue;
 169                         openp->dev = dev;
 170                         openp->old_flags = old_flags;
 171                         *last = openp;
 172                         last = &openp->next;
 173                         bootp_dev_count++;
 174                         if (!(dev->flags & IFF_NOARP))
 175                                 rarp_dev_count++;
 176 #ifdef NFSROOT_DEBUG
 177         printk(KERN_NOTICE "Root-NFS: Opened %s\n", dev->name);
 178 #endif
 179                 }
 180         }
 181         *last = NULL;
 182 
 183         if (!bootp_dev_count && !rarp_dev_count) {
 184                 printk(KERN_ERR "Root-NFS: Unable to open at least one network device\n");
 185                 return -1;
 186         }
 187         return 0;
 188 }
 189 
 190 
 191 /*
 192  *  Restore the state of all devices. However, keep the root device open
 193  *  for the upcoming mount.
 194  */
 195 static void root_dev_close(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 196 {
 197         struct open_dev *openp;
 198         struct open_dev *nextp;
 199 
 200         openp = open_base;
 201         while (openp != NULL) {
 202                 nextp = openp->next;
 203                 openp->next = NULL;
 204                 if (openp->dev != root_dev) {
 205                         if (!(openp->old_flags & IFF_UP))
 206                                 dev_close(openp->dev);
 207                         openp->dev->flags = openp->old_flags;
 208                 }
 209                 kfree_s(openp, sizeof(struct open_dev));
 210                 openp = nextp;
 211         }
 212 }
 213 
 214 
 215 /***************************************************************************
 216 
 217                               RARP Subroutines
 218 
 219  ***************************************************************************/
 220 
 221 #ifdef CONFIG_RNFS_RARP
 222 
 223 extern void arp_send(int type, int ptype, unsigned long target_ip,
 224                      struct device *dev, unsigned long src_ip,
 225                      unsigned char *dest_hw, unsigned char *src_hw,
 226                      unsigned char *target_hw);
 227 
 228 static int root_rarp_recv(struct sk_buff *skb, struct device *dev,
 229                           struct packet_type *pt);
 230 
 231 
 232 static struct packet_type rarp_packet_type = {
 233         0,                      /* Should be: __constant_htons(ETH_P_RARP)
 234                                  * - but this _doesn't_ come out constant! */
 235         NULL,                   /* Listen to all devices */
 236         root_rarp_recv,
 237         NULL,
 238         NULL
 239 };
 240 
 241 
 242 /*
 243  *  Register the packet type for RARP
 244  */
 245 static void root_rarp_open(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 246 {
 247         rarp_packet_type.type = htons(ETH_P_RARP);
 248         dev_add_pack(&rarp_packet_type);
 249 }
 250 
 251 
 252 /*
 253  *  Deregister the RARP packet type
 254  */
 255 static void root_rarp_close(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 256 {
 257         rarp_packet_type.type = htons(ETH_P_RARP);
 258         dev_remove_pack(&rarp_packet_type);
 259 }
 260 
 261 
 262 /*
 263  *  Receive RARP packets.
 264  */
 265 static int root_rarp_recv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
     /* [previous][next][first][last][top][bottom][index][help] */
 266 {
 267         struct arphdr *rarp = (struct arphdr *)skb->h.raw;
 268         unsigned char *rarp_ptr = (unsigned char *) (rarp + 1);
 269         unsigned long sip, tip;
 270         unsigned char *sha, *tha;               /* s for "source", t for "target" */
 271 
 272         /* If this test doesn't pass, its not IP, or we should ignore it anyway */
 273         if (rarp->ar_hln != dev->addr_len || dev->type != ntohs(rarp->ar_hrd)) {
 274                 kfree_skb(skb, FREE_READ);
 275                 return 0;
 276         }
 277 
 278         /* If it's not a RARP reply, delete it. */
 279         if (rarp->ar_op != htons(ARPOP_RREPLY)) {
 280                 kfree_skb(skb, FREE_READ);
 281                 return 0;
 282         }
 283 
 284         /* If it's not ethernet or AX25, delete it. */
 285         if ((rarp->ar_pro != htons(ETH_P_IP) && dev->type != ARPHRD_AX25) ||
 286 #ifdef CONFIG_AX25
 287            (rarp->ar_pro != htons(AX25_P_IP) && dev->type == ARPHRD_AX25) ||
 288 #endif
 289             rarp->ar_pln != 4) {
 290                 kfree_skb(skb, FREE_READ);
 291                 return 0;
 292         }
 293 
 294         /* Extract variable width fields */
 295         sha = rarp_ptr;
 296         rarp_ptr += dev->addr_len;
 297         memcpy(&sip, rarp_ptr, 4);
 298         rarp_ptr += 4;
 299         tha = rarp_ptr;
 300         rarp_ptr += dev->addr_len;
 301         memcpy(&tip, rarp_ptr, 4);
 302 
 303         /* Discard packets which are not meant for us. */
 304         if (memcmp(tha, dev->dev_addr, dev->addr_len)) {
 305                 kfree_skb(skb, FREE_READ);
 306                 return 0;
 307         }
 308 
 309         /*
 310          * The packet is what we were looking for. Setup the global
 311          * variables.
 312          */
 313         cli();
 314         if (pkt_arrived) {
 315                 sti();
 316                 kfree_skb(skb, FREE_READ);
 317                 return 0;
 318         }
 319         pkt_arrived = ARRIVED_RARP;
 320         sti();
 321         root_dev = dev;
 322 
 323         if (myaddr.sin_addr.s_addr == INADDR_NONE) {
 324                 myaddr.sin_family = dev->family;
 325                 myaddr.sin_addr.s_addr = tip;
 326         }
 327         if (server.sin_addr.s_addr == INADDR_NONE) {
 328                 server.sin_family = dev->family;
 329                 server.sin_addr.s_addr = sip;
 330         }
 331         kfree_skb(skb, FREE_READ);
 332         return 0;
 333 }
 334 
 335 
 336 /*
 337  *  Send RARP request packet over all devices which allow RARP.
 338  */
 339 static void root_rarp_send(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 340 {
 341         struct open_dev *openp;
 342         struct device *dev;
 343         int num = 0;
 344 
 345         for (openp = open_base; openp != NULL; openp = openp->next) {
 346                 dev = openp->dev;
 347                 if (!(dev->flags & IFF_NOARP)) {
 348                         arp_send(ARPOP_RREQUEST, ETH_P_RARP, 0, dev, 0, NULL,
 349                                  dev->dev_addr, dev->dev_addr);
 350                         num++;
 351                 }
 352         }
 353 }
 354 
 355 #endif
 356 
 357 /***************************************************************************
 358 
 359                              BOOTP Subroutines
 360 
 361  ***************************************************************************/
 362 
 363 #ifdef CONFIG_RNFS_BOOTP
 364 
 365 static struct device *bootp_dev = NULL; /* Device selected as best BOOTP target */
 366 
 367 static int bootp_xmit_fd = -1;          /* Socket descriptor for transmit */
 368 static struct socket *bootp_xmit_sock;  /* The socket itself */
 369 static int bootp_recv_fd = -1;          /* Socket descriptor for receive */
 370 static struct socket *bootp_recv_sock;  /* The socket itself */
 371 
 372 struct bootp_pkt {              /* BOOTP packet format */
 373         u8 op;                  /* 1=request, 2=reply */
 374         u8 htype;               /* HW address type */
 375         u8 hlen;                /* HW address length */
 376         u8 hops;                /* Used only by gateways */
 377         u32 xid;                /* Transaction ID */
 378         u16 secs;               /* Seconds since we started */
 379         u16 flags;              /* Just what is says */
 380         u32 client_ip;          /* Client's IP address if known */
 381         u32 your_ip;            /* Assigned IP address */
 382         u32 server_ip;          /* Server's IP address */
 383         u32 relay_ip;           /* IP address of BOOTP relay */
 384         u8 hw_addr[16];         /* Client's HW address */
 385         u8 serv_name[64];       /* Server host name */
 386         u8 boot_file[128];      /* Name of boot file */
 387         u8 vendor_area[128];    /* Area for extensions */
 388 };
 389 
 390 #define BOOTP_REQUEST 1
 391 #define BOOTP_REPLY 2
 392 
 393 static struct bootp_pkt *xmit_bootp;    /* Packet being transmitted */
 394 static struct bootp_pkt *recv_bootp;    /* Packet being received */
 395 
 396 static int bootp_have_route = 0;        /* BOOTP route installed */
 397 
 398 /*
 399  *  Free BOOTP packet buffers
 400  */
 401 static void root_free_bootp(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 402 {
 403         if (xmit_bootp) {
 404                 kfree_s(xmit_bootp, sizeof(struct bootp_pkt));
 405                 xmit_bootp = NULL;
 406         }
 407         if (recv_bootp) {
 408                 kfree_s(recv_bootp, sizeof(struct bootp_pkt));
 409                 recv_bootp = NULL;
 410         }
 411 }
 412 
 413 
 414 /*
 415  *  Allocate memory for BOOTP packet buffers
 416  */
 417 static inline int root_alloc_bootp(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 418 {
 419         if (!(xmit_bootp = kmalloc(sizeof(struct bootp_pkt), GFP_KERNEL)) ||
 420             !(recv_bootp = kmalloc(sizeof(struct bootp_pkt), GFP_KERNEL))) {
 421                 printk("BOOTP: Out of memory!");
 422                 return -1;
 423         }
 424         return 0;
 425 }
 426 
 427 
 428 /*
 429  *  Create default route for BOOTP sending
 430  */
 431 static int root_add_bootp_route(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 432 {
 433         struct rtentry route;
 434 
 435         memset(&route, 0, sizeof(route));
 436         route.rt_dev = bootp_dev->name;
 437         route.rt_mss = bootp_dev->mtu;
 438         route.rt_flags = RTF_UP;
 439         ((struct sockaddr_in *) &(route.rt_dst)) -> sin_addr.s_addr = 0;
 440         ((struct sockaddr_in *) &(route.rt_dst)) -> sin_family = AF_INET;
 441         ((struct sockaddr_in *) &(route.rt_genmask)) -> sin_addr.s_addr = 0;
 442         ((struct sockaddr_in *) &(route.rt_genmask)) -> sin_family = AF_INET;
 443         if (ip_rt_new(&route)) {
 444                 printk(KERN_ERR "BOOTP: Adding of route failed!\n");
 445                 return -1;
 446         }
 447         bootp_have_route = 1;
 448         return 0;
 449 }
 450 
 451 
 452 /*
 453  *  Delete default route for BOOTP sending
 454  */
 455 static int root_del_bootp_route(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 456 {
 457         struct rtentry route;
 458 
 459         if (!bootp_have_route)
 460                 return 0;
 461         memset(&route, 0, sizeof(route));
 462         ((struct sockaddr_in *) &(route.rt_dst)) -> sin_addr.s_addr = 0;
 463         ((struct sockaddr_in *) &(route.rt_genmask)) -> sin_addr.s_addr = 0;
 464         if (ip_rt_kill(&route)) {
 465                 printk(KERN_ERR "BOOTP: Deleting of route failed!\n");
 466                 return -1;
 467         }
 468         bootp_have_route = 0;
 469         return 0;
 470 }
 471 
 472 
 473 /*
 474  *  Open UDP socket.
 475  */
 476 static int root_open_udp_sock(int *fd, struct socket **sock)
     /* [previous][next][first][last][top][bottom][index][help] */
 477 {
 478         struct file *file;
 479         struct inode *inode;
 480 
 481         *fd = sys_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
 482         if (*fd >= 0) {
 483                 file = current->files->fd[*fd];
 484                 inode = file->f_inode;
 485                 *sock = &inode->u.socket_i;
 486                 return 0;
 487         }
 488 
 489         printk(KERN_ERR "BOOTP: Cannot open UDP socket!\n");
 490         return -1;
 491 }
 492 
 493 
 494 /*
 495  *  Connect UDP socket.
 496  */
 497 static int root_connect_udp_sock(struct socket *sock, u32 addr, u16 port)
     /* [previous][next][first][last][top][bottom][index][help] */
 498 {
 499         struct sockaddr_in sa;
 500         int result;
 501 
 502         sa.sin_family = AF_INET;
 503         sa.sin_addr.s_addr = htonl(addr);
 504         sa.sin_port = htons(port);
 505         result = sock->ops->connect(sock, (struct sockaddr *) &sa, sizeof(sa), 0);
 506         if (result < 0) {
 507                 printk(KERN_ERR "BOOTP: connect() failed\n");
 508                 return -1;
 509         }
 510         return 0;
 511 }
 512 
 513 
 514 /*
 515  *  Bind UDP socket.
 516  */
 517 static int root_bind_udp_sock(struct socket *sock, u32 addr, u16 port)
     /* [previous][next][first][last][top][bottom][index][help] */
 518 {
 519         struct sockaddr_in sa;
 520         int result;
 521 
 522         sa.sin_family = AF_INET;
 523         sa.sin_addr.s_addr = htonl(addr);
 524         sa.sin_port = htons(port);
 525         result = sock->ops->bind(sock, (struct sockaddr *) &sa, sizeof(sa));
 526         if (result < 0) {
 527                 printk(KERN_ERR "BOOTP: bind() failed\n");
 528                 return -1;
 529         }
 530         return 0;
 531 }
 532 
 533 
 534 /*
 535  *  Send UDP packet.
 536  */
 537 static inline int root_send_udp(struct socket *sock, void *buf, int size)
     /* [previous][next][first][last][top][bottom][index][help] */
 538 {
 539         u32 oldfs;
 540         int result;
 541         struct msghdr msg;
 542         struct iovec iov;
 543 
 544         oldfs = get_fs();
 545         set_fs(get_ds());
 546         iov.iov_base = buf;
 547         iov.iov_len = size;
 548         msg.msg_name = NULL;
 549         msg.msg_iov = &iov;
 550         msg.msg_iovlen = 1;
 551         msg.msg_accrights = NULL;
 552         result = sock->ops->sendmsg(sock, &msg, size, 0, 0);
 553         set_fs(oldfs);
 554         return (result != size);
 555 }
 556 
 557 
 558 /*
 559  *  Try to receive UDP packet.
 560  */
 561 static inline int root_recv_udp(struct socket *sock, void *buf, int size)
     /* [previous][next][first][last][top][bottom][index][help] */
 562 {
 563         u32 oldfs;
 564         int result;
 565         struct msghdr msg;
 566         struct iovec iov;
 567 
 568         oldfs = get_fs();
 569         set_fs(get_ds());
 570         iov.iov_base = buf;
 571         iov.iov_len = size;
 572         msg.msg_name = NULL;
 573         msg.msg_iov = &iov;
 574         msg.msg_iovlen = 1;
 575         msg.msg_accrights = NULL;
 576         msg.msg_namelen = 0;
 577         result = sock->ops->recvmsg(sock, &msg, size, O_NONBLOCK, 0, &msg.msg_namelen);
 578         set_fs(oldfs);
 579         return result;
 580 }
 581 
 582 
 583 /*
 584  *  Initialize BOOTP extension fields in the request.
 585  */
 586 static void root_bootp_init_ext(u8 *e)
     /* [previous][next][first][last][top][bottom][index][help] */
 587 {
 588         *e++ = 99;              /* RFC1048 Magic Cookie */
 589         *e++ = 130;
 590         *e++ = 83;
 591         *e++ = 99;
 592         *e++ = 1;               /* Subnet mask request */
 593         *e++ = 4;
 594         e += 4;
 595         *e++ = 3;               /* Default gateway request */
 596         *e++ = 4;
 597         e += 4;
 598         *e++ = 12;              /* Host name request */
 599         *e++ = 32;
 600         e += 32;
 601         *e++ = 15;              /* Domain name request */
 602         *e++ = 32;
 603         e += 32;
 604         *e++ = 17;              /* Boot path */
 605         *e++ = 32;
 606         e += 32;
 607         *e = 255;               /* End of the list */
 608 }
 609 
 610 
 611 /*
 612  *  Deinitialize the BOOTP mechanism.
 613  */
 614 static void root_bootp_close(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 615 {
 616         if (bootp_xmit_fd != -1)
 617                 sys_close(bootp_xmit_fd);
 618         if (bootp_recv_fd != -1)
 619                 sys_close(bootp_recv_fd);
 620         root_del_bootp_route();
 621         root_free_bootp();
 622 }
 623 
 624 
 625 /*
 626  *  Initialize the BOOTP mechanism.
 627  */
 628 static int root_bootp_open(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 629 {
 630         struct open_dev *openp;
 631         struct device *dev, *best_dev;
 632 
 633         /*
 634          * Select the best interface for BOOTP. We try to select a first
 635          * Ethernet-like interface. It's shame I know no simple way how to send
 636          * BOOTP's to all interfaces, but it doesn't apply to usual diskless
 637          * stations as they don't have multiple interfaces.
 638          */
 639 
 640         best_dev = NULL;
 641         for (openp = open_base; openp != NULL; openp = openp->next) {
 642                 dev = openp->dev;
 643                 if (dev->flags & IFF_BROADCAST) {
 644                         if (!best_dev ||
 645                            ((best_dev->flags & IFF_NOARP) && !(dev->flags & IFF_NOARP)))
 646                                 best_dev = dev;
 647                         }
 648                 }
 649 
 650         if (!best_dev) {
 651                 printk(KERN_ERR "BOOTP: This cannot happen!\n");
 652                 return -1;
 653         }
 654         bootp_dev = best_dev;
 655 
 656         /* Allocate memory for BOOTP packets */
 657         if (root_alloc_bootp())
 658                 return -1;
 659 
 660         /* Construct BOOTP request */
 661         memset(xmit_bootp, 0, sizeof(struct bootp_pkt));
 662         xmit_bootp->op = BOOTP_REQUEST;
 663         get_random_bytes(&xmit_bootp->xid, sizeof(xmit_bootp->xid));
 664         xmit_bootp->htype = best_dev->type;
 665         xmit_bootp->hlen = best_dev->addr_len;
 666         memcpy(xmit_bootp->hw_addr, best_dev->dev_addr, best_dev->addr_len);
 667         root_bootp_init_ext(xmit_bootp->vendor_area);
 668 #ifdef NFSROOT_DEBUG
 669         {
 670                 int x;
 671                 printk(KERN_NOTICE "BOOTP: XID=%08x, DE=%s, HT=%02x, HL=%02x, HA=",
 672                         xmit_bootp->xid,
 673                         best_dev->name,
 674                         xmit_bootp->htype,
 675                         xmit_bootp->hlen);
 676                 for(x=0; x<xmit_bootp->hlen; x++)
 677                         printk("%02x", xmit_bootp->hw_addr[x]);
 678                 printk("\n");
 679         }
 680 #endif
 681 
 682         /* Create default route to that interface */
 683         if (root_add_bootp_route())
 684                 return -1;
 685 
 686         /* Open the sockets */
 687         if (root_open_udp_sock(&bootp_xmit_fd, &bootp_xmit_sock) ||
 688             root_open_udp_sock(&bootp_recv_fd, &bootp_recv_sock))
 689                 return -1;
 690 
 691         /* Bind/connect the sockets */
 692         ((struct sock *) bootp_xmit_sock->data) -> broadcast = 1;
 693         ((struct sock *) bootp_xmit_sock->data) -> reuse = 1;
 694         ((struct sock *) bootp_recv_sock->data) -> reuse = 1;
 695         if (root_bind_udp_sock(bootp_recv_sock, INADDR_ANY, 68) ||
 696             root_bind_udp_sock(bootp_xmit_sock, INADDR_ANY, 68) ||
 697             root_connect_udp_sock(bootp_xmit_sock, INADDR_BROADCAST, 67))
 698                 return -1;
 699 
 700         return 0;
 701 }
 702 
 703 
 704 /*
 705  *  Send BOOTP request.
 706  */
 707 static int root_bootp_send(u32 jiffies)
     /* [previous][next][first][last][top][bottom][index][help] */
 708 {
 709         xmit_bootp->secs = htons(jiffies / HZ);
 710         return root_send_udp(bootp_xmit_sock, xmit_bootp, sizeof(struct bootp_pkt));
 711 }
 712 
 713 
 714 /*
 715  *  Copy BOOTP-supplied string if not already set.
 716  */
 717 static int root_bootp_string(char *dest, char *src, int len, int max)
     /* [previous][next][first][last][top][bottom][index][help] */
 718 {
 719         if (*dest || !len)
 720                 return 0;
 721         if (len > max-1)
 722                 len = max-1;
 723         strncpy(dest, src, len);
 724         dest[len] = '\0';
 725         return 1;
 726 }
 727 
 728 
 729 /*
 730  *  Process BOOTP extension.
 731  */
 732 static void root_do_bootp_ext(u8 *ext)
     /* [previous][next][first][last][top][bottom][index][help] */
 733 {
 734         u8 *c;
 735         static int got_bootp_domain = 0;
 736 
 737 #ifdef NFSROOT_MORE_DEBUG
 738         printk("BOOTP: Got extension %02x",*ext);
 739         for(c=ext+2; c<ext+2+ext[1]; c++)
 740                 printk(" %02x", *c);
 741         printk("\n");
 742 #endif
 743 
 744         switch (*ext++) {
 745                 case 1:         /* Subnet mask */
 746                         if (netmask.sin_addr.s_addr == INADDR_NONE)
 747                                 memcpy(&netmask.sin_addr.s_addr, ext+1, 4);
 748                         break;
 749                 case 3:         /* Default gateway */
 750                         if (gateway.sin_addr.s_addr == INADDR_NONE)
 751                                 memcpy(&gateway.sin_addr.s_addr, ext+1, 4);
 752                         break;
 753                 case 12:        /* Host name */
 754                         if (root_bootp_string(system_utsname.nodename, ext+1, *ext, __NEW_UTS_LEN)) {
 755                                 c = strchr(system_utsname.nodename, '.');
 756                                 if (c) {
 757                                         *c++ = 0;
 758                                         if (!system_utsname.domainname[0]) {
 759                                                 strcpy(system_utsname.domainname, c);
 760                                                 got_bootp_domain = 1;
 761                                         }
 762                                 }
 763                         }
 764                         break;
 765                 case 15:        /* Domain name */
 766                         if (got_bootp_domain && *ext && ext[1])
 767                                 system_utsname.domainname[0] = '\0';
 768                         root_bootp_string(system_utsname.domainname, ext+1, *ext, __NEW_UTS_LEN);
 769                         break;
 770                 case 17:        /* Root path */
 771                         root_bootp_string(nfs_path, ext+1, *ext, NFS_MAXPATHLEN);
 772                         break;
 773         }
 774 }
 775 
 776 
 777 /*
 778  *  Receive BOOTP request.
 779  */
 780 static void root_bootp_recv(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 781 {
 782         int len;
 783         u8 *ext, *end, *opt;
 784 
 785         len = root_recv_udp(bootp_recv_sock, recv_bootp, sizeof(struct bootp_pkt));
 786         if (len < 0)
 787                 return;
 788 
 789         /* Check consistency of incoming packet */
 790         if (len < 300 ||                        /* See RFC 1542:2.1 */
 791             recv_bootp->op != BOOTP_REPLY ||
 792             recv_bootp->htype != xmit_bootp->htype ||
 793             recv_bootp->hlen != xmit_bootp->hlen ||
 794             recv_bootp->xid != xmit_bootp->xid) {
 795 #ifdef NFSROOT_DEBUG
 796                 printk("?");
 797 #endif
 798                 return;
 799                 }
 800 
 801         /* Record BOOTP packet arrival in the global variables */
 802         cli();
 803         if (pkt_arrived) {
 804                 sti();
 805                 return;
 806         }
 807         pkt_arrived = ARRIVED_BOOTP;
 808         sti();
 809         root_dev = bootp_dev;
 810 
 811         /* Extract basic fields */
 812         myaddr.sin_addr.s_addr = recv_bootp->your_ip;
 813         server.sin_addr.s_addr = recv_bootp->server_ip;
 814 
 815         /* Parse extensions */
 816         if (recv_bootp->vendor_area[0] == 99 && /* Check magic cookie */
 817             recv_bootp->vendor_area[1] == 130 &&
 818             recv_bootp->vendor_area[2] == 83 &&
 819             recv_bootp->vendor_area[3] == 99) {
 820                 ext = &recv_bootp->vendor_area[4];
 821                 end = (u8 *) recv_bootp + len;
 822                 while (ext < end && *ext != 255) {
 823                         if (*ext == 0)          /* Padding */
 824                                 ext++;
 825                         else {
 826                                 opt = ext;
 827                                 ext += ext[1] + 2;
 828                                 if (ext <= end)
 829                                         root_do_bootp_ext(opt);
 830                         }
 831                 }
 832         }
 833 }
 834 
 835 #endif
 836 
 837 /***************************************************************************
 838 
 839                         Dynamic configuration of IP.
 840 
 841  ***************************************************************************/
 842 
 843 #ifdef CONFIG_RNFS_DYNAMIC
 844 
 845 /*
 846  *  Determine client and server IP numbers and appropriate device by using
 847  *  the RARP and BOOTP protocols.
 848  */
 849 static int root_auto_config(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 850 {
 851         int retries;
 852         u32 timeout, jiff;
 853         u32 start_jiffies;
 854         int selected = 0;
 855 
 856         /* Check devices */
 857 
 858 #ifdef CONFIG_RNFS_BOOTP
 859         if (bootp_flag) {
 860                 if (bootp_dev_count)
 861                         selected = 1;
 862                 else {
 863                         printk(KERN_ERR "BOOTP: No suitable device found.\n");
 864                         bootp_flag = 0;
 865                 }
 866         }
 867 #else
 868         bootp_flag = 0;
 869 #endif
 870 
 871 #ifdef CONFIG_RNFS_RARP
 872         if (rarp_flag) {
 873                 if (rarp_dev_count)
 874                         selected = 1;
 875                 else {
 876                         printk(KERN_ERR "RARP: No suitable device found.\n");
 877                         rarp_flag = 0;
 878                 }
 879         }
 880 #else
 881         rarp_flag = 0;
 882 #endif
 883 
 884         /* If neither BOOTP nor RARP was selected manually, use both of them */
 885         if (!selected) {
 886 #ifdef CONFIG_RNFS_BOOTP
 887                 if (bootp_dev_count)
 888                         bootp_flag = 1;
 889 #endif
 890 #ifdef CONFIG_RNFS_RARP
 891                 if (rarp_dev_count)
 892                         rarp_flag = 1;
 893 #endif
 894                 if (!bootp_flag && !rarp_flag)
 895                         return -1;
 896         }
 897 
 898         /* Setup RARP and BOOTP protocols */
 899 #ifdef CONFIG_RNFS_RARP
 900         if (rarp_flag)
 901                 root_rarp_open();
 902 #endif
 903 #ifdef CONFIG_RNFS_BOOTP
 904         if (bootp_flag && root_bootp_open()) {
 905                 root_bootp_close();
 906                 return -1;
 907         }
 908 #endif
 909 
 910         /*
 911          * Send requests and wait, until we get an answer. This loop
 912          * seems to be a terrible waste of CPU time, but actually there is
 913          * only one process running at all, so we don't need to use any
 914          * scheduler functions.
 915          * [Actually we could now, but the nothing else running note still 
 916          *  applies.. - AC]
 917          */
 918         printk(KERN_NOTICE "Sending %s%s%s requests...",
 919                 bootp_flag ? "BOOTP" : "",
 920                 bootp_flag && rarp_flag ? " and " : "",
 921                 rarp_flag ? "RARP" : "");
 922         start_jiffies = jiffies;
 923         retries = CONF_RETRIES;
 924         get_random_bytes(&timeout, sizeof(timeout));
 925         timeout = CONF_BASE_TIMEOUT + (timeout % (unsigned) CONF_TIMEOUT_RANDOM);
 926         for(;;) {
 927 #ifdef CONFIG_RNFS_BOOTP
 928                 if (bootp_flag && root_bootp_send(jiffies - start_jiffies)) {
 929                         printk("...BOOTP failed!\n");
 930                         root_bootp_close();
 931                         bootp_flag = 0;
 932                         if (!rarp_flag)
 933                                 break;
 934                 }
 935 #endif
 936 #ifdef CONFIG_RNFS_RARP
 937                 if (rarp_flag)
 938                         root_rarp_send();
 939 #endif
 940                 printk(".");
 941                 jiff = jiffies + timeout;
 942                 while (jiffies < jiff && !pkt_arrived)
 943 #ifdef CONFIG_RNFS_BOOTP
 944                         root_bootp_recv();
 945 #else
 946                         ;
 947 #endif
 948                 if (pkt_arrived)
 949                         break;
 950                 if (! --retries) {
 951                         printk("timed out!\n");
 952                         break;
 953                 }
 954                 timeout = timeout CONF_TIMEOUT_MULT;
 955                 if (timeout > CONF_TIMEOUT_MAX)
 956                         timeout = CONF_TIMEOUT_MAX;
 957         }
 958 
 959 #ifdef CONFIG_RNFS_RARP
 960         if (rarp_flag)
 961                 root_rarp_close();
 962 #endif
 963 #ifdef CONFIG_RNFS_BOOTP
 964         if (bootp_flag)
 965                 root_bootp_close();
 966 #endif
 967 
 968         if (!pkt_arrived)
 969                 return -1;
 970 
 971         printk("OK\n");
 972         printk(KERN_NOTICE "Root-NFS: Got %s answer from %s, ",
 973                 (pkt_arrived == ARRIVED_BOOTP) ? "BOOTP" : "RARP",
 974                 in_ntoa(server.sin_addr.s_addr));
 975         printk("my address is %s\n", in_ntoa(myaddr.sin_addr.s_addr));
 976 
 977         return 0;
 978 }
 979 
 980 #endif
 981 
 982 /***************************************************************************
 983 
 984                              Parsing of options
 985 
 986  ***************************************************************************/
 987 
 988 
 989 /*
 990  *  The following integer options are recognized
 991  */
 992 static struct nfs_int_opts {
 993         char *name;
 994         int  *val;
 995 } root_int_opts[] = {
 996         { "port",       &nfs_port },
 997         { "rsize",      &nfs_data.rsize },
 998         { "wsize",      &nfs_data.wsize },
 999         { "timeo",      &nfs_data.timeo },
1000         { "retrans",    &nfs_data.retrans },
1001         { "acregmin",   &nfs_data.acregmin },
1002         { "acregmax",   &nfs_data.acregmax },
1003         { "acdirmin",   &nfs_data.acdirmin },
1004         { "acdirmax",   &nfs_data.acdirmax },
1005         { NULL,         NULL }
1006 };
1007 
1008 
1009 /*
1010  *  And now the flag options
1011  */
1012 static struct nfs_bool_opts {
1013         char *name;
1014         int  and_mask;
1015         int  or_mask;
1016 } root_bool_opts[] = {
1017         { "soft",       ~NFS_MOUNT_SOFT,        NFS_MOUNT_SOFT },
1018         { "hard",       ~NFS_MOUNT_SOFT,        0 },
1019         { "intr",       ~NFS_MOUNT_INTR,        NFS_MOUNT_INTR },
1020         { "nointr",     ~NFS_MOUNT_INTR,        0 },
1021         { "posix",      ~NFS_MOUNT_POSIX,       NFS_MOUNT_POSIX },
1022         { "noposix",    ~NFS_MOUNT_POSIX,       0 },
1023         { "cto",        ~NFS_MOUNT_NOCTO,       0 },
1024         { "nocto",      ~NFS_MOUNT_NOCTO,       NFS_MOUNT_NOCTO },
1025         { "ac",         ~NFS_MOUNT_NOAC,        0 },
1026         { "noac",       ~NFS_MOUNT_NOAC,        NFS_MOUNT_NOAC },
1027         { NULL,         0,                      0 }
1028 };
1029 
1030 
1031 /*
1032  *  Prepare the NFS data structure and parse any options
1033  */
1034 static int root_nfs_parse(char *name)
     /* [previous][next][first][last][top][bottom][index][help] */
1035 {
1036         char buf[NFS_MAXPATHLEN];
1037         char *cp, *options, *val;
1038 
1039         /* It is possible to override the server IP number here */
1040         if (*name >= '0' && *name <= '9' && (cp = strchr(name, ':')) != NULL) {
1041                 *cp++ = '\0';
1042                 server.sin_addr.s_addr = in_aton(name);
1043                 name = cp;
1044         }
1045 
1046         /* Set the name of the directory to mount */
1047         cp = in_ntoa(myaddr.sin_addr.s_addr);
1048         strncpy(buf, name, 255);
1049         if ((options = strchr(buf, ',')))
1050                 *options++ = '\0';
1051         if (strlen(buf) + strlen(cp) > NFS_MAXPATHLEN) {
1052                 printk(KERN_ERR "Root-NFS: Pathname for remote directory too long\n");
1053                 return -1;
1054         }
1055         sprintf(nfs_path, buf, cp);
1056 
1057         /* Set some default values */
1058         nfs_port          = -1;
1059         nfs_data.version  = NFS_MOUNT_VERSION;
1060         nfs_data.flags    = 0;
1061         nfs_data.rsize    = NFS_DEF_FILE_IO_BUFFER_SIZE;
1062         nfs_data.wsize    = NFS_DEF_FILE_IO_BUFFER_SIZE;
1063         nfs_data.timeo    = 7;
1064         nfs_data.retrans  = 3;
1065         nfs_data.acregmin = 3;
1066         nfs_data.acregmax = 60;
1067         nfs_data.acdirmin = 30;
1068         nfs_data.acdirmax = 60;
1069 
1070         /* Process any options */
1071         if (options) {
1072                 cp = strtok(options, ",");
1073                 while (cp) {
1074                         if ((val = strchr(cp, '='))) {
1075                                 struct nfs_int_opts *opts = root_int_opts;
1076                                 *val++ = '\0';
1077                                 while (opts->name && strcmp(opts->name, cp))
1078                                         opts++;
1079                                 if (opts->name)
1080                                         *(opts->val) = (int) simple_strtoul(val, NULL, 10);
1081                         } else {
1082                                 struct nfs_bool_opts *opts = root_bool_opts;
1083                                 while (opts->name && strcmp(opts->name, cp))
1084                                         opts++;
1085                                 if (opts->name) {
1086                                         nfs_data.flags &= opts->and_mask;
1087                                         nfs_data.flags |= opts->or_mask;
1088                                 }
1089                         }
1090                         cp = strtok(NULL, ",");
1091                 }
1092         }
1093         return 0;
1094 }
1095 
1096 
1097 /*
1098  *  Tell the user what's going on.
1099  */
1100 #ifdef NFSROOT_DEBUG
1101 static void root_nfs_print(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1102 {
1103         printk(KERN_NOTICE "Root-NFS: IP config: dev=%s, ",
1104                 root_dev ? root_dev->name : "none");
1105         printk("local=%s, ", IN_NTOA(myaddr.sin_addr.s_addr));
1106         printk("server=%s, ", IN_NTOA(server.sin_addr.s_addr));
1107         printk("gw=%s, ", IN_NTOA(gateway.sin_addr.s_addr));
1108         printk("mask=%s, ", IN_NTOA(netmask.sin_addr.s_addr));
1109         printk("host=%s, domain=%s\n",
1110                 system_utsname.nodename[0] ? system_utsname.nodename : "none",
1111                 system_utsname.domainname[0] ? system_utsname.domainname : "none");
1112         printk(KERN_NOTICE "Root-NFS: Mounting %s on server %s as root\n",
1113                 nfs_path, nfs_data.hostname);
1114         printk(KERN_NOTICE "Root-NFS:     rsize = %d, wsize = %d, timeo = %d, retrans = %d\n",
1115                 nfs_data.rsize, nfs_data.wsize, nfs_data.timeo, nfs_data.retrans);
1116         printk(KERN_NOTICE "Root-NFS:     acreg (min,max) = (%d,%d), acdir (min,max) = (%d,%d)\n",
1117                 nfs_data.acregmin, nfs_data.acregmax,
1118                 nfs_data.acdirmin, nfs_data.acdirmax);
1119         printk(KERN_NOTICE "Root-NFS:     port = %d, flags = %08x\n",
1120                 nfs_port, nfs_data.flags);
1121 }
1122 #endif
1123 
1124 
1125 /*
1126  *  Parse any IP configuration options (the "nfsaddrs" parameter).
1127  *  The parameter consists of option fields separated by colons. It can start
1128  *  with device name and possibly with auto-config type ("bootp" or "rarp")
1129  *  followed by own IP address, IP address of the server, IP address of
1130  *  default gateway, local netmask and a host name. Any of the addresses can
1131  *  be blank to indicate that default value should be used.
1132  */
1133 static void root_nfs_ip_config(char *addrs)
     /* [previous][next][first][last][top][bottom][index][help] */
1134 {
1135         char *cp, *ip, *dp;
1136         int num = 0;
1137 
1138         /* Clear all addresses and strings */
1139         myaddr.sin_family = server.sin_family =
1140             gateway.sin_family = netmask.sin_family = AF_INET;
1141         myaddr.sin_addr.s_addr = server.sin_addr.s_addr =
1142             gateway.sin_addr.s_addr = netmask.sin_addr.s_addr = INADDR_NONE;
1143         system_utsname.nodename[0] = '\0';
1144         system_utsname.domainname[0] = '\0';
1145         user_dev_name[0] = '\0';
1146         bootp_flag = rarp_flag = 0;
1147 
1148         /* Check for device name and BOOTP/RARP flags */
1149         ip = addrs;
1150         while (ip && *ip && (*ip < '0' || *ip > '9')) {
1151                 if ((cp = strchr(ip, ':')))
1152                         *cp++ = '\0';
1153                 if (*ip) {
1154                         if (!strcmp(ip, "rarp"))
1155                                 rarp_flag = 1;
1156                         else if (!strcmp(ip, "bootp"))
1157                                 bootp_flag = 1;
1158                         else if (!user_dev_name[0]) {
1159                                 strncpy(user_dev_name, ip, IFNAMSIZ);
1160                                 user_dev_name[IFNAMSIZ-1] = '\0';
1161                         }
1162                 }
1163                 ip = cp;
1164         }
1165 
1166         /* Parse the IP addresses */
1167         while (ip && *ip) {
1168                 if ((cp = strchr(ip, ':')))
1169                         *cp++ = '\0';
1170                 if (strlen(ip) > 0 && strcmp(ip, "0.0.0.0")) {
1171                         switch (num) {
1172                         case 0:
1173                                 myaddr.sin_addr.s_addr = in_aton(ip);
1174                                 break;
1175                         case 1:
1176                                 server.sin_addr.s_addr = in_aton(ip);
1177                                 break;
1178                         case 2:
1179                                 gateway.sin_addr.s_addr = in_aton(ip);
1180                                 break;
1181                         case 3:
1182                                 netmask.sin_addr.s_addr = in_aton(ip);
1183                                 break;
1184                         case 4:
1185                                 if ((dp = strchr(ip, '.'))) {
1186                                         *dp++ = '\0';
1187                                         strncpy(system_utsname.domainname, dp, __NEW_UTS_LEN);
1188                                         system_utsname.domainname[__NEW_UTS_LEN] = '\0';
1189                                 }
1190                                 strncpy(system_utsname.nodename, ip, __NEW_UTS_LEN);
1191                                 system_utsname.nodename[__NEW_UTS_LEN] = '\0';
1192                                 break;
1193                         default:
1194                                 break;
1195                         }
1196                 }
1197                 ip = cp;
1198                 num++;
1199         }
1200 #ifdef NFSROOT_DEBUG
1201         printk(KERN_NOTICE "Root-NFS: IP options: dev=%s, RARP=%d, BOOTP=%d, ",
1202                 user_dev_name[0] ? user_dev_name : "none",
1203                 rarp_flag,
1204                 bootp_flag);
1205         printk("local=%s, ", IN_NTOA(myaddr.sin_addr.s_addr));
1206         printk("server=%s, ", IN_NTOA(server.sin_addr.s_addr));
1207         printk("gw=%s, ", IN_NTOA(gateway.sin_addr.s_addr));
1208         printk("mask=%s, ", IN_NTOA(netmask.sin_addr.s_addr));
1209         printk("host=%s, domain=%s\n",
1210                 system_utsname.nodename[0] ? system_utsname.nodename : "none",
1211                 system_utsname.domainname[0] ? system_utsname.domainname : "none");
1212 #endif
1213 }
1214 
1215 
1216 /*
1217  *  Set the interface address and configure a route to the server.
1218  */
1219 static int root_nfs_setup(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1220 {
1221         struct rtentry route;
1222 
1223         /* Set the default system name in case none was previously found */
1224         if (!system_utsname.nodename[0]) {
1225                 strncpy(system_utsname.nodename, in_ntoa(myaddr.sin_addr.s_addr), __NEW_UTS_LEN);
1226                 system_utsname.nodename[__NEW_UTS_LEN] = '\0';
1227         }
1228 
1229         /* Setup the server hostname */
1230         strncpy(nfs_data.hostname, in_ntoa(server.sin_addr.s_addr), 255);
1231 
1232         /* Set the correct netmask */
1233         if (netmask.sin_addr.s_addr == INADDR_NONE)
1234                 netmask.sin_addr.s_addr = ip_get_mask(myaddr.sin_addr.s_addr);
1235 
1236         /* Setup the device correctly */
1237         root_dev->family     = myaddr.sin_family;
1238         root_dev->pa_addr    = myaddr.sin_addr.s_addr;
1239         root_dev->pa_mask    = netmask.sin_addr.s_addr;
1240         root_dev->pa_brdaddr = root_dev->pa_addr | ~root_dev->pa_mask;
1241         root_dev->pa_dstaddr = 0;
1242 
1243         /*
1244          * Now add a route to the server. If there is no gateway given,
1245          * the server is on the same subnet, so we establish only a route to
1246          * the local network. Otherwise we create a route to the gateway (the
1247          * same local network router as in the former case) and then setup a
1248          * gatewayed default route. Note that this gives sufficient network
1249          * setup even for full system operation in all common cases.
1250          */
1251         memset(&route, 0, sizeof(route));       /* Local subnet route */
1252         route.rt_dev = root_dev->name;
1253         route.rt_mss = root_dev->mtu;
1254         route.rt_flags = RTF_UP;
1255         *((struct sockaddr_in *) &(route.rt_dst)) = myaddr;
1256         (((struct sockaddr_in *) &(route.rt_dst))) -> sin_addr.s_addr &= netmask.sin_addr.s_addr;
1257         *((struct sockaddr_in *) &(route.rt_genmask)) = netmask;
1258         if (ip_rt_new(&route)) {
1259                 printk(KERN_ERR "Root-NFS: Adding of local route failed!\n");
1260                 return -1;
1261         }
1262 
1263         if (gateway.sin_addr.s_addr != INADDR_NONE) {   /* Default route */
1264                 (((struct sockaddr_in *) &(route.rt_dst))) -> sin_addr.s_addr = 0;
1265                 (((struct sockaddr_in *) &(route.rt_genmask))) -> sin_addr.s_addr = 0;
1266                 *((struct sockaddr_in *) &(route.rt_gateway)) = gateway;
1267                 route.rt_flags |= RTF_GATEWAY;
1268                 if ((gateway.sin_addr.s_addr ^ myaddr.sin_addr.s_addr) & netmask.sin_addr.s_addr) {
1269                         printk(KERN_ERR "Root-NFS: Gateway not on local network!\n");
1270                         return -1;
1271                 }
1272                 if (ip_rt_new(&route)) {
1273                         printk(KERN_ERR "Root-NFS: Adding of default route failed!\n");
1274                         return -1;
1275                 }
1276         } else if ((server.sin_addr.s_addr ^ myaddr.sin_addr.s_addr) & netmask.sin_addr.s_addr) {
1277                 printk(KERN_ERR "Root-NFS: Boot server not on local network and no default gateway configured!\n");
1278                 return -1;
1279         }
1280 
1281         return 0;
1282 }
1283 
1284 
1285 /*
1286  *  Get the necessary IP addresses and prepare for mounting the required
1287  *  NFS filesystem.
1288  */
1289 int nfs_root_init(char *nfsname, char *nfsaddrs)
     /* [previous][next][first][last][top][bottom][index][help] */
1290 {
1291         /*
1292          * Get local and server IP address. First check for network config
1293          * parameters in the command line parameter.
1294          */
1295         root_nfs_ip_config(nfsaddrs);
1296 
1297         /* Parse NFS options */
1298         if (root_nfs_parse(nfsname))
1299                 return -1;
1300 
1301         /* Setup all network devices */
1302         if (root_dev_open() < 0)
1303                 return -1;
1304 
1305         /*
1306          * If the config information is insufficient (e.g., our IP address or
1307          * IP address of the boot server is missing or we have multiple network
1308          * interfaces and no default was set), use BOOTP or RARP to get the
1309          * missing values.
1310          *
1311          * Note that we don't try to set up correct routes for multiple
1312          * interfaces (could be solved by trying icmp echo requests), because
1313          * it's only necessary in the rare case of multiple ethernet devices
1314          * in the (diskless) system and if the server is on another subnet.
1315          * If only one interface is installed, the routing is obvious.
1316          */
1317         if ((myaddr.sin_addr.s_addr == INADDR_NONE ||
1318              server.sin_addr.s_addr == INADDR_NONE ||
1319              (open_base != NULL && open_base->next != NULL))
1320 #ifdef CONFIG_RNFS_DYNAMIC
1321                 && root_auto_config() < 0
1322 #endif
1323            ) {
1324                 root_dev_close();
1325                 return -1;
1326         }
1327         if (root_dev == NULL) {
1328                 if (open_base != NULL && open_base->next == NULL) {
1329                         root_dev = open_base->dev;
1330                 } else {
1331                         /* I hope this cannot happen */
1332                         printk(KERN_ERR "Root-NFS: 1 == 0!\n");
1333                         root_dev_close();
1334                         return -1;
1335                 }
1336         }
1337         /*
1338          * Close all network devices except the device which connects to
1339          * server
1340          */
1341         root_dev_close();
1342 
1343         /* Setup devices and routes */
1344         if (root_nfs_setup())
1345                 return -1;
1346 
1347 #ifdef NFSROOT_DEBUG
1348         root_nfs_print();
1349 #endif
1350 
1351         return 0;
1352 }
1353 
1354 
1355 /***************************************************************************
1356 
1357                Routines to actually mount the root directory
1358 
1359  ***************************************************************************/
1360 
1361 static struct file  *nfs_file;
1362 static struct inode *nfs_sock_inode;    /* Inode containing socket */
1363 static int *rpc_packet = NULL;          /* RPC packet */
1364 
1365 
1366 /*
1367  *  Open a UDP socket.
1368  */
1369 static int root_nfs_open(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1370 {
1371         /* Open the socket */
1372         if ((nfs_data.fd = sys_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
1373                 printk(KERN_ERR "Root-NFS: Cannot open UDP socket!\n");
1374                 return -1;
1375         }
1376         nfs_file = current->files->fd[nfs_data.fd];
1377         nfs_sock_inode = nfs_file->f_inode;
1378 
1379         /* keep socket open. Do we need really this ? */
1380         /* nfs_file->f_count++; */                   
1381         return 0;
1382 }
1383 
1384 
1385 /*
1386  *  Close the UDP file descriptor. If nfs_read_super is successful, it
1387  *  increases the reference count, so we can simply close the file, and
1388  *  the socket keeps open.
1389  */
1390 static void root_nfs_close(int close_all)
     /* [previous][next][first][last][top][bottom][index][help] */
1391 {
1392         sys_close(nfs_data.fd);
1393 }
1394 
1395 
1396 /*
1397  *  Find a suitable listening port and bind to it
1398  */
1399 static int root_nfs_bind(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1400 {
1401         int res = -1;
1402         short port = STARTPORT;
1403         struct sockaddr_in *sin = &myaddr;
1404         int i;
1405 
1406         if (nfs_sock_inode->u.socket_i.ops->bind) {
1407                 for (i = 0; i < NPORTS && res < 0; i++) {
1408                         sin->sin_port = htons(port++);
1409                         if (port > ENDPORT) {
1410                                 port = STARTPORT;
1411                         }
1412                         res = nfs_sock_inode->u.socket_i.ops->bind
1413                                 (&nfs_sock_inode->u.socket_i,
1414                                  (struct sockaddr *)sin, sizeof(struct sockaddr_in));
1415                 }
1416         }
1417         if (res < 0) {
1418                 printk(KERN_ERR "Root-NFS: Cannot find a suitable listening port\n");
1419                 root_nfs_close(1);
1420                 return -1;
1421         }
1422 #ifdef NFSROOT_DEBUG
1423         printk(KERN_NOTICE "Root-NFS: Binding to listening port %d\n", port);
1424 #endif
1425         return 0;
1426 }
1427 
1428 
1429 /*
1430  *  Send an RPC request and wait for the answer
1431  */
1432 static int *root_nfs_call(int *end)
     /* [previous][next][first][last][top][bottom][index][help] */
1433 {
1434         struct socket *sock;
1435         int dummylen;
1436         static struct nfs_server s = {
1437                 0,                      /* struct file *         */
1438                 0,                      /* struct rsock *        */
1439                 {
1440                     0, "",
1441                 },                      /* toaddr                */
1442                 0,                      /* lock                  */
1443                 NULL,                   /* wait queue            */
1444                 NFS_MOUNT_SOFT,         /* flags                 */
1445                 0, 0,                   /* rsize, wsize          */
1446                 0,                      /* timeo                 */
1447                 0,                      /* retrans               */
1448                 3 * HZ, 60 * HZ, 30 * HZ, 60 * HZ, "\0"
1449         };
1450 
1451         s.file = nfs_file;
1452         sock = &((nfs_file->f_inode)->u.socket_i);
1453 
1454         /* extract the other end of the socket into s->toaddr */
1455         sock->ops->getname(sock, &(s.toaddr), &dummylen, 1);
1456         ((struct sockaddr_in *) &s.toaddr)->sin_port   = server.sin_port;
1457         ((struct sockaddr_in *) &s.toaddr)->sin_family = server.sin_family;
1458         ((struct sockaddr_in *) &s.toaddr)->sin_addr.s_addr = server.sin_addr.s_addr;
1459 
1460         s.rsock = rpc_makesock(nfs_file);
1461         s.flags = nfs_data.flags;
1462         s.rsize = nfs_data.rsize;
1463         s.wsize = nfs_data.wsize;
1464         s.timeo = nfs_data.timeo * HZ / 10;
1465         s.retrans = nfs_data.retrans;
1466         strcpy(s.hostname, nfs_data.hostname);
1467 
1468         /*
1469          * First connect the UDP socket to a server port, then send the
1470          * packet out, and finally check wether the answer is OK.
1471          */
1472         if (nfs_sock_inode->u.socket_i.ops->connect &&
1473             nfs_sock_inode->u.socket_i.ops->connect
1474             (&nfs_sock_inode->u.socket_i,
1475              (struct sockaddr *) &server,
1476              sizeof(struct sockaddr_in),
1477              nfs_file->f_flags) < 0)
1478                 return NULL;
1479         if (nfs_rpc_call(&s, rpc_packet, end, nfs_data.wsize) < 0)
1480                 return NULL;
1481         return rpc_verify(rpc_packet);
1482 }
1483 
1484 
1485 /*
1486  *  Create an RPC packet header
1487  */
1488 static int *root_nfs_header(int proc, int program, int version)
     /* [previous][next][first][last][top][bottom][index][help] */
1489 {
1490         int groups[] = { 0, NOGROUP };
1491 
1492         if (rpc_packet == NULL) {
1493                 if (!(rpc_packet = kmalloc(nfs_data.wsize + 1024, GFP_NFS))) {
1494                         printk(KERN_ERR "Root-NFS: Cannot allocate UDP buffer\n");
1495                         return NULL;
1496                 }
1497         }
1498         return rpc_header(rpc_packet, proc, program, version, 0, 0, groups);
1499 }
1500 
1501 
1502 /*
1503  *  Query server portmapper for the port of a daemon program
1504  */
1505 static int root_nfs_get_port(int program, int version)
     /* [previous][next][first][last][top][bottom][index][help] */
1506 {
1507         int *p;
1508 
1509         /* Prepare header for portmap request */
1510         server.sin_port = htons(NFS_PMAP_PORT);
1511         p = root_nfs_header(NFS_PMAP_PROC, NFS_PMAP_PROGRAM, NFS_PMAP_VERSION);
1512         if (!p)
1513                 return -1;
1514 
1515         /* Set arguments for portmapper */
1516         *p++ = htonl(program);
1517         *p++ = htonl(version);
1518         *p++ = htonl(IPPROTO_UDP);
1519         *p++ = 0;
1520 
1521         /* Send request to server portmapper */
1522         if ((p = root_nfs_call(p)) == NULL)
1523                 return -1;
1524 
1525         return ntohl(*p);
1526 }
1527 
1528 
1529 /*
1530  *  Get portnumbers for mountd and nfsd from server
1531  */
1532 static int root_nfs_ports(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1533 {
1534         int port;
1535 
1536         if (nfs_port < 0) {
1537                 if ((port = root_nfs_get_port(NFS_NFS_PROGRAM, NFS_NFS_VERSION)) < 0) {
1538                         printk(KERN_ERR "Root-NFS: Unable to get nfsd port number from server, using default\n");
1539                         port = NFS_NFS_PORT;
1540                 }
1541                 nfs_port = port;
1542 #ifdef NFSROOT_DEBUG
1543                 printk(KERN_NOTICE "Root-NFS: Portmapper on server returned %d as nfsd port\n", port);
1544 #endif
1545         }
1546         if ((port = root_nfs_get_port(NFS_MOUNT_PROGRAM, NFS_MOUNT_VERSION)) < 0) {
1547                 printk(KERN_ERR "Root-NFS: Unable to get mountd port number from server, using default\n");
1548                 port = NFS_MOUNT_PORT;
1549         }
1550         server.sin_port = htons(port);
1551 #ifdef NFSROOT_DEBUG
1552         printk(KERN_NOTICE "Root-NFS: Portmapper on server returned %d as mountd port\n", port);
1553 #endif
1554 
1555         return 0;
1556 }
1557 
1558 
1559 /*
1560  *  Get a file handle from the server for the directory which is to be
1561  *  mounted
1562  */
1563 static int root_nfs_get_handle(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1564 {
1565         int len, status, *p;
1566 
1567         /* Prepare header for mountd request */
1568         p = root_nfs_header(NFS_MOUNT_PROC, NFS_MOUNT_PROGRAM, NFS_MOUNT_VERSION);
1569         if (!p) {
1570                 root_nfs_close(1);
1571                 return -1;
1572         }
1573         /* Set arguments for mountd */
1574         len = strlen(nfs_path);
1575         *p++ = htonl(len);
1576         memcpy(p, nfs_path, len);
1577         len = (len + 3) >> 2;
1578         p[len] = 0;
1579         p += len;
1580 
1581         /* Send request to server mountd */
1582         if ((p = root_nfs_call(p)) == NULL) {
1583                 root_nfs_close(1);
1584                 return -1;
1585         }
1586         status = ntohl(*p++);
1587         if (status == 0) {
1588                 nfs_data.root = *((struct nfs_fh *) p);
1589                 printk(KERN_NOTICE "Root-NFS: Got file handle for %s via RPC\n", nfs_path);
1590         } else {
1591                 printk(KERN_ERR "Root-NFS: Server returned error %d while mounting %s\n",
1592                         status, nfs_path);
1593                 root_nfs_close(1);
1594                 return -1;
1595         }
1596 
1597         return 0;
1598 }
1599 
1600 
1601 /*
1602  *  Now actually mount the given directory
1603  */
1604 static int root_nfs_do_mount(struct super_block *sb)
     /* [previous][next][first][last][top][bottom][index][help] */
1605 {
1606         /* First connect to the nfsd port on the server */
1607         server.sin_port = htons(nfs_port);
1608         nfs_data.addr = server;
1609         if (nfs_sock_inode->u.socket_i.ops->connect &&
1610             nfs_sock_inode->u.socket_i.ops->connect
1611             (&nfs_sock_inode->u.socket_i,
1612              (struct sockaddr *) &server,
1613              sizeof(struct sockaddr_in),
1614              nfs_file->f_flags) < 0) {
1615                 root_nfs_close(1);
1616                 return -1;
1617         }
1618         /* Now (finally ;-)) read the super block for mounting */
1619         if (nfs_read_super(sb, &nfs_data, 1) == NULL) {
1620                 root_nfs_close(1);
1621                 return -1;
1622         }
1623         return 0;
1624 }
1625 
1626 
1627 /*
1628  *  Get the NFS port numbers and file handle, and then read the super-
1629  *  block for mounting.
1630  */
1631 int nfs_root_mount(struct super_block *sb)
     /* [previous][next][first][last][top][bottom][index][help] */
1632 {
1633         if (root_nfs_open() < 0)
1634                 return -1;
1635         if (root_nfs_bind() < 0)
1636                 return -1;
1637         if (root_nfs_ports() < 0)
1638                 return -1;
1639         if (root_nfs_get_handle() < 0)
1640                 return -1;
1641         if (root_nfs_do_mount(sb) < 0)
1642                 return -1;
1643         root_nfs_close(0);
1644         return 0;
1645 }

/* [previous][next][first][last][top][bottom][index][help] */