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

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