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

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