linux-bk/net/ipv4/ipconfig.c
<<
>>
Prefs
   1/*
   2 *  $Id: ipconfig.c,v 1.46 2002/02/01 22:01:04 davem Exp $
   3 *
   4 *  Automatic Configuration of IP -- use DHCP, BOOTP, RARP, or
   5 *  user-supplied information to configure own IP address and routes.
   6 *
   7 *  Copyright (C) 1996-1998 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
   8 *
   9 *  Derived from network configuration code in fs/nfs/nfsroot.c,
  10 *  originally Copyright (C) 1995, 1996 Gero Kuhlmann and me.
  11 *
  12 *  BOOTP rewritten to construct and analyse packets itself instead
  13 *  of misusing the IP layer. num_bugs_causing_wrong_arp_replies--;
  14 *                                           -- MJ, December 1998
  15 *  
  16 *  Fixed ip_auto_config_setup calling at startup in the new "Linker Magic"
  17 *  initialization scheme.
  18 *      - Arnaldo Carvalho de Melo <acme@conectiva.com.br>, 08/11/1999
  19 *
  20 *  DHCP support added.  To users this looks like a whole separate
  21 *  protocol, but we know it's just a bag on the side of BOOTP.
  22 *              -- Chip Salzenberg <chip@valinux.com>, May 2000
  23 *
  24 *  Ported DHCP support from 2.2.16 to 2.4.0-test4
  25 *              -- Eric Biederman <ebiederman@lnxi.com>, 30 Aug 2000
  26 *
  27 *  Merged changes from 2.2.19 into 2.4.3
  28 *              -- Eric Biederman <ebiederman@lnxi.com>, 22 April Aug 2001
  29 *
  30 *  Multiple Nameservers in /proc/net/pnp
  31 *              --  Josef Siemes <jsiemes@web.de>, Aug 2002
  32 */
  33
  34#include <linux/config.h>
  35#include <linux/types.h>
  36#include <linux/string.h>
  37#include <linux/kernel.h>
  38#include <linux/jiffies.h>
  39#include <linux/random.h>
  40#include <linux/init.h>
  41#include <linux/utsname.h>
  42#include <linux/in.h>
  43#include <linux/if.h>
  44#include <linux/inet.h>
  45#include <linux/netdevice.h>
  46#include <linux/if_arp.h>
  47#include <linux/skbuff.h>
  48#include <linux/ip.h>
  49#include <linux/socket.h>
  50#include <linux/route.h>
  51#include <linux/udp.h>
  52#include <linux/proc_fs.h>
  53#include <linux/seq_file.h>
  54#include <linux/major.h>
  55#include <linux/root_dev.h>
  56#include <linux/delay.h>
  57#include <net/arp.h>
  58#include <net/ip.h>
  59#include <net/ipconfig.h>
  60
  61#include <asm/uaccess.h>
  62#include <net/checksum.h>
  63#include <asm/processor.h>
  64
  65/* Define this to allow debugging output */
  66#undef IPCONFIG_DEBUG
  67
  68#ifdef IPCONFIG_DEBUG
  69#define DBG(x) printk x
  70#else
  71#define DBG(x) do { } while(0)
  72#endif
  73
  74#if defined(CONFIG_IP_PNP_DHCP)
  75#define IPCONFIG_DHCP
  76#endif
  77#if defined(CONFIG_IP_PNP_BOOTP) || defined(CONFIG_IP_PNP_DHCP)
  78#define IPCONFIG_BOOTP
  79#endif
  80#if defined(CONFIG_IP_PNP_RARP)
  81#define IPCONFIG_RARP
  82#endif
  83#if defined(IPCONFIG_BOOTP) || defined(IPCONFIG_RARP)
  84#define IPCONFIG_DYNAMIC
  85#endif
  86
  87/* Define the friendly delay before and after opening net devices */
  88#define CONF_PRE_OPEN           500     /* Before opening: 1/2 second */
  89#define CONF_POST_OPEN          1       /* After opening: 1 second */
  90
  91/* Define the timeout for waiting for a DHCP/BOOTP/RARP reply */
  92#define CONF_OPEN_RETRIES       2       /* (Re)open devices twice */
  93#define CONF_SEND_RETRIES       6       /* Send six requests per open */
  94#define CONF_INTER_TIMEOUT      (HZ/2)  /* Inter-device timeout: 1/2 second */
  95#define CONF_BASE_TIMEOUT       (HZ*2)  /* Initial timeout: 2 seconds */
  96#define CONF_TIMEOUT_RANDOM     (HZ)    /* Maximum amount of randomization */
  97#define CONF_TIMEOUT_MULT       *7/4    /* Rate of timeout growth */
  98#define CONF_TIMEOUT_MAX        (HZ*30) /* Maximum allowed timeout */
  99#define CONF_NAMESERVERS_MAX   3       /* Maximum number of nameservers  
 100                                           - '3' from resolv.h */
 101
 102
 103/*
 104 * Public IP configuration
 105 */
 106
 107/* This is used by platforms which might be able to set the ipconfig
 108 * variables using firmware environment vars.  If this is set, it will
 109 * ignore such firmware variables.
 110 */
 111int ic_set_manually __initdata = 0;             /* IPconfig parameters set manually */
 112
 113static int ic_enable __initdata = 0;            /* IP config enabled? */
 114
 115/* Protocol choice */
 116int ic_proto_enabled __initdata = 0
 117#ifdef IPCONFIG_BOOTP
 118                        | IC_BOOTP
 119#endif
 120#ifdef CONFIG_IP_PNP_DHCP
 121                        | IC_USE_DHCP
 122#endif
 123#ifdef IPCONFIG_RARP
 124                        | IC_RARP
 125#endif
 126                        ;
 127
 128static int ic_host_name_set __initdata = 0;     /* Host name set by us? */
 129
 130u32 ic_myaddr = INADDR_NONE;            /* My IP address */
 131static u32 ic_netmask = INADDR_NONE;    /* Netmask for local subnet */
 132u32 ic_gateway = INADDR_NONE;   /* Gateway IP address */
 133
 134u32 ic_servaddr = INADDR_NONE;  /* Boot server IP address */
 135
 136u32 root_server_addr = INADDR_NONE;     /* Address of NFS server */
 137u8 root_server_path[256] = { 0, };      /* Path to mount as root */
 138
 139/* Persistent data: */
 140
 141static int ic_proto_used;                       /* Protocol used, if any */
 142static u32 ic_nameservers[CONF_NAMESERVERS_MAX]; /* DNS Server IP addresses */
 143static u8 ic_domain[64];                /* DNS (not NIS) domain name */
 144
 145/*
 146 * Private state.
 147 */
 148
 149/* Name of user-selected boot device */
 150static char user_dev_name[IFNAMSIZ] __initdata = { 0, };
 151
 152/* Protocols supported by available interfaces */
 153static int ic_proto_have_if __initdata = 0;
 154
 155#ifdef IPCONFIG_DYNAMIC
 156static DEFINE_SPINLOCK(ic_recv_lock);
 157static volatile int ic_got_reply __initdata = 0;    /* Proto(s) that replied */
 158#endif
 159#ifdef IPCONFIG_DHCP
 160static int ic_dhcp_msgtype __initdata = 0;      /* DHCP msg type received */
 161#endif
 162
 163
 164/*
 165 *      Network devices
 166 */
 167
 168struct ic_device {
 169        struct ic_device *next;
 170        struct net_device *dev;
 171        unsigned short flags;
 172        short able;
 173        u32 xid;
 174};
 175
 176static struct ic_device *ic_first_dev __initdata = NULL;/* List of open device */
 177static struct net_device *ic_dev __initdata = NULL;     /* Selected device */
 178
 179static int __init ic_open_devs(void)
 180{
 181        struct ic_device *d, **last;
 182        struct net_device *dev;
 183        unsigned short oflags;
 184
 185        last = &ic_first_dev;
 186        rtnl_shlock();
 187
 188        /* bring loopback device up first */
 189        if (dev_change_flags(&loopback_dev, loopback_dev.flags | IFF_UP) < 0)
 190                printk(KERN_ERR "IP-Config: Failed to open %s\n", loopback_dev.name);
 191
 192        for (dev = dev_base; dev; dev = dev->next) {
 193                if (dev == &loopback_dev)
 194                        continue;
 195                if (user_dev_name[0] ? !strcmp(dev->name, user_dev_name) :
 196                    (!(dev->flags & IFF_LOOPBACK) &&
 197                     (dev->flags & (IFF_POINTOPOINT|IFF_BROADCAST)) &&
 198                     strncmp(dev->name, "dummy", 5))) {
 199                        int able = 0;
 200                        if (dev->mtu >= 364)
 201                                able |= IC_BOOTP;
 202                        else
 203                                printk(KERN_WARNING "DHCP/BOOTP: Ignoring device %s, MTU %d too small", dev->name, dev->mtu);
 204                        if (!(dev->flags & IFF_NOARP))
 205                                able |= IC_RARP;
 206                        able &= ic_proto_enabled;
 207                        if (ic_proto_enabled && !able)
 208                                continue;
 209                        oflags = dev->flags;
 210                        if (dev_change_flags(dev, oflags | IFF_UP) < 0) {
 211                                printk(KERN_ERR "IP-Config: Failed to open %s\n", dev->name);
 212                                continue;
 213                        }
 214                        if (!(d = kmalloc(sizeof(struct ic_device), GFP_KERNEL))) {
 215                                rtnl_shunlock();
 216                                return -1;
 217                        }
 218                        d->dev = dev;
 219                        *last = d;
 220                        last = &d->next;
 221                        d->flags = oflags;
 222                        d->able = able;
 223                        if (able & IC_BOOTP)
 224                                get_random_bytes(&d->xid, sizeof(u32));
 225                        else
 226                                d->xid = 0;
 227                        ic_proto_have_if |= able;
 228                        DBG(("IP-Config: %s UP (able=%d, xid=%08x)\n",
 229                                dev->name, able, d->xid));
 230                }
 231        }
 232        rtnl_shunlock();
 233
 234        *last = NULL;
 235
 236        if (!ic_first_dev) {
 237                if (user_dev_name[0])
 238                        printk(KERN_ERR "IP-Config: Device `%s' not found.\n", user_dev_name);
 239                else
 240                        printk(KERN_ERR "IP-Config: No network devices available.\n");
 241                return -1;
 242        }
 243        return 0;
 244}
 245
 246static void __init ic_close_devs(void)
 247{
 248        struct ic_device *d, *next;
 249        struct net_device *dev;
 250
 251        rtnl_shlock();
 252        next = ic_first_dev;
 253        while ((d = next)) {
 254                next = d->next;
 255                dev = d->dev;
 256                if (dev != ic_dev) {
 257                        DBG(("IP-Config: Downing %s\n", dev->name));
 258                        dev_change_flags(dev, d->flags);
 259                }
 260                kfree(d);
 261        }
 262        rtnl_shunlock();
 263}
 264
 265/*
 266 *      Interface to various network functions.
 267 */
 268
 269static inline void
 270set_sockaddr(struct sockaddr_in *sin, u32 addr, u16 port)
 271{
 272        sin->sin_family = AF_INET;
 273        sin->sin_addr.s_addr = addr;
 274        sin->sin_port = port;
 275}
 276
 277static int __init ic_dev_ioctl(unsigned int cmd, struct ifreq *arg)
 278{
 279        int res;
 280
 281        mm_segment_t oldfs = get_fs();
 282        set_fs(get_ds());
 283        res = devinet_ioctl(cmd, (struct ifreq __user *) arg);
 284        set_fs(oldfs);
 285        return res;
 286}
 287
 288static int __init ic_route_ioctl(unsigned int cmd, struct rtentry *arg)
 289{
 290        int res;
 291
 292        mm_segment_t oldfs = get_fs();
 293        set_fs(get_ds());
 294        res = ip_rt_ioctl(cmd, (void __user *) arg);
 295        set_fs(oldfs);
 296        return res;
 297}
 298
 299/*
 300 *      Set up interface addresses and routes.
 301 */
 302
 303static int __init ic_setup_if(void)
 304{
 305        struct ifreq ir;
 306        struct sockaddr_in *sin = (void *) &ir.ifr_ifru.ifru_addr;
 307        int err;
 308
 309        memset(&ir, 0, sizeof(ir));
 310        strcpy(ir.ifr_ifrn.ifrn_name, ic_dev->name);
 311        set_sockaddr(sin, ic_myaddr, 0);
 312        if ((err = ic_dev_ioctl(SIOCSIFADDR, &ir)) < 0) {
 313                printk(KERN_ERR "IP-Config: Unable to set interface address (%d).\n", err);
 314                return -1;
 315        }
 316        set_sockaddr(sin, ic_netmask, 0);
 317        if ((err = ic_dev_ioctl(SIOCSIFNETMASK, &ir)) < 0) {
 318                printk(KERN_ERR "IP-Config: Unable to set interface netmask (%d).\n", err);
 319                return -1;
 320        }
 321        set_sockaddr(sin, ic_myaddr | ~ic_netmask, 0);
 322        if ((err = ic_dev_ioctl(SIOCSIFBRDADDR, &ir)) < 0) {
 323                printk(KERN_ERR "IP-Config: Unable to set interface broadcast address (%d).\n", err);
 324                return -1;
 325        }
 326        return 0;
 327}
 328
 329static int __init ic_setup_routes(void)
 330{
 331        /* No need to setup device routes, only the default route... */
 332
 333        if (ic_gateway != INADDR_NONE) {
 334                struct rtentry rm;
 335                int err;
 336
 337                memset(&rm, 0, sizeof(rm));
 338                if ((ic_gateway ^ ic_myaddr) & ic_netmask) {
 339                        printk(KERN_ERR "IP-Config: Gateway not on directly connected network.\n");
 340                        return -1;
 341                }
 342                set_sockaddr((struct sockaddr_in *) &rm.rt_dst, 0, 0);
 343                set_sockaddr((struct sockaddr_in *) &rm.rt_genmask, 0, 0);
 344                set_sockaddr((struct sockaddr_in *) &rm.rt_gateway, ic_gateway, 0);
 345                rm.rt_flags = RTF_UP | RTF_GATEWAY;
 346                if ((err = ic_route_ioctl(SIOCADDRT, &rm)) < 0) {
 347                        printk(KERN_ERR "IP-Config: Cannot add default route (%d).\n", err);
 348                        return -1;
 349                }
 350        }
 351
 352        return 0;
 353}
 354
 355/*
 356 *      Fill in default values for all missing parameters.
 357 */
 358
 359static int __init ic_defaults(void)
 360{
 361        /*
 362         *      At this point we have no userspace running so need not
 363         *      claim locks on system_utsname
 364         */
 365         
 366        if (!ic_host_name_set)
 367                sprintf(system_utsname.nodename, "%u.%u.%u.%u", NIPQUAD(ic_myaddr));
 368
 369        if (root_server_addr == INADDR_NONE)
 370                root_server_addr = ic_servaddr;
 371
 372        if (ic_netmask == INADDR_NONE) {
 373                if (IN_CLASSA(ntohl(ic_myaddr)))
 374                        ic_netmask = htonl(IN_CLASSA_NET);
 375                else if (IN_CLASSB(ntohl(ic_myaddr)))
 376                        ic_netmask = htonl(IN_CLASSB_NET);
 377                else if (IN_CLASSC(ntohl(ic_myaddr)))
 378                        ic_netmask = htonl(IN_CLASSC_NET);
 379                else {
 380                        printk(KERN_ERR "IP-Config: Unable to guess netmask for address %u.%u.%u.%u\n",
 381                                NIPQUAD(ic_myaddr));
 382                        return -1;
 383                }
 384                printk("IP-Config: Guessing netmask %u.%u.%u.%u\n", NIPQUAD(ic_netmask));
 385        }
 386
 387        return 0;
 388}
 389
 390/*
 391 *      RARP support.
 392 */
 393
 394#ifdef IPCONFIG_RARP
 395
 396static int ic_rarp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt);
 397
 398static struct packet_type rarp_packet_type __initdata = {
 399        .type = __constant_htons(ETH_P_RARP),
 400        .func = ic_rarp_recv,
 401};
 402
 403static inline void ic_rarp_init(void)
 404{
 405        dev_add_pack(&rarp_packet_type);
 406}
 407
 408static inline void ic_rarp_cleanup(void)
 409{
 410        dev_remove_pack(&rarp_packet_type);
 411}
 412
 413/*
 414 *  Process received RARP packet.
 415 */
 416static int __init
 417ic_rarp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
 418{
 419        struct arphdr *rarp;
 420        unsigned char *rarp_ptr;
 421        unsigned long sip, tip;
 422        unsigned char *sha, *tha;               /* s for "source", t for "target" */
 423        struct ic_device *d;
 424
 425        if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
 426                return NET_RX_DROP;
 427
 428        if (!pskb_may_pull(skb, sizeof(struct arphdr)))
 429                goto drop;
 430
 431        /* Basic sanity checks can be done without the lock.  */
 432        rarp = (struct arphdr *)skb->h.raw;
 433
 434        /* If this test doesn't pass, it's not IP, or we should
 435         * ignore it anyway.
 436         */
 437        if (rarp->ar_hln != dev->addr_len || dev->type != ntohs(rarp->ar_hrd))
 438                goto drop;
 439
 440        /* If it's not a RARP reply, delete it. */
 441        if (rarp->ar_op != htons(ARPOP_RREPLY))
 442                goto drop;
 443
 444        /* If it's not Ethernet, delete it. */
 445        if (rarp->ar_pro != htons(ETH_P_IP))
 446                goto drop;
 447
 448        if (!pskb_may_pull(skb,
 449                           sizeof(struct arphdr) +
 450                           (2 * dev->addr_len) +
 451                           (2 * 4)))
 452                goto drop;
 453
 454        /* OK, it is all there and looks valid, process... */
 455        rarp = (struct arphdr *)skb->h.raw;
 456        rarp_ptr = (unsigned char *) (rarp + 1);
 457
 458        /* One reply at a time, please. */
 459        spin_lock(&ic_recv_lock);
 460
 461        /* If we already have a reply, just drop the packet */
 462        if (ic_got_reply)
 463                goto drop_unlock;
 464
 465        /* Find the ic_device that the packet arrived on */
 466        d = ic_first_dev;
 467        while (d && d->dev != dev)
 468                d = d->next;
 469        if (!d)
 470                goto drop_unlock;       /* should never happen */
 471
 472        /* Extract variable-width fields */
 473        sha = rarp_ptr;
 474        rarp_ptr += dev->addr_len;
 475        memcpy(&sip, rarp_ptr, 4);
 476        rarp_ptr += 4;
 477        tha = rarp_ptr;
 478        rarp_ptr += dev->addr_len;
 479        memcpy(&tip, rarp_ptr, 4);
 480
 481        /* Discard packets which are not meant for us. */
 482        if (memcmp(tha, dev->dev_addr, dev->addr_len))
 483                goto drop_unlock;
 484
 485        /* Discard packets which are not from specified server. */
 486        if (ic_servaddr != INADDR_NONE && ic_servaddr != sip)
 487                goto drop_unlock;
 488
 489        /* We have a winner! */
 490        ic_dev = dev;
 491        if (ic_myaddr == INADDR_NONE)
 492                ic_myaddr = tip;
 493        ic_servaddr = sip;
 494        ic_got_reply = IC_RARP;
 495
 496drop_unlock:
 497        /* Show's over.  Nothing to see here.  */
 498        spin_unlock(&ic_recv_lock);
 499
 500drop:
 501        /* Throw the packet out. */
 502        kfree_skb(skb);
 503        return 0;
 504}
 505
 506
 507/*
 508 *  Send RARP request packet over a single interface.
 509 */
 510static void __init ic_rarp_send_if(struct ic_device *d)
 511{
 512        struct net_device *dev = d->dev;
 513        arp_send(ARPOP_RREQUEST, ETH_P_RARP, 0, dev, 0, NULL,
 514                 dev->dev_addr, dev->dev_addr);
 515}
 516#endif
 517
 518/*
 519 *      DHCP/BOOTP support.
 520 */
 521
 522#ifdef IPCONFIG_BOOTP
 523
 524struct bootp_pkt {              /* BOOTP packet format */
 525        struct iphdr iph;       /* IP header */
 526        struct udphdr udph;     /* UDP header */
 527        u8 op;                  /* 1=request, 2=reply */
 528        u8 htype;               /* HW address type */
 529        u8 hlen;                /* HW address length */
 530        u8 hops;                /* Used only by gateways */
 531        u32 xid;                /* Transaction ID */
 532        u16 secs;               /* Seconds since we started */
 533        u16 flags;              /* Just what it says */
 534        u32 client_ip;          /* Client's IP address if known */
 535        u32 your_ip;            /* Assigned IP address */
 536        u32 server_ip;          /* (Next, e.g. NFS) Server's IP address */
 537        u32 relay_ip;           /* IP address of BOOTP relay */
 538        u8 hw_addr[16];         /* Client's HW address */
 539        u8 serv_name[64];       /* Server host name */
 540        u8 boot_file[128];      /* Name of boot file */
 541        u8 exten[312];          /* DHCP options / BOOTP vendor extensions */
 542};
 543
 544/* packet ops */
 545#define BOOTP_REQUEST   1
 546#define BOOTP_REPLY     2
 547
 548/* DHCP message types */
 549#define DHCPDISCOVER    1
 550#define DHCPOFFER       2
 551#define DHCPREQUEST     3
 552#define DHCPDECLINE     4
 553#define DHCPACK         5
 554#define DHCPNAK         6
 555#define DHCPRELEASE     7
 556#define DHCPINFORM      8
 557
 558static int ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt);
 559
 560static struct packet_type bootp_packet_type __initdata = {
 561        .type = __constant_htons(ETH_P_IP),
 562        .func = ic_bootp_recv,
 563};
 564
 565
 566/*
 567 *  Initialize DHCP/BOOTP extension fields in the request.
 568 */
 569
 570static const u8 ic_bootp_cookie[4] = { 99, 130, 83, 99 };
 571
 572#ifdef IPCONFIG_DHCP
 573
 574static void __init
 575ic_dhcp_init_options(u8 *options)
 576{
 577        u8 mt = ((ic_servaddr == INADDR_NONE)
 578                 ? DHCPDISCOVER : DHCPREQUEST);
 579        u8 *e = options;
 580
 581#ifdef IPCONFIG_DEBUG
 582        printk("DHCP: Sending message type %d\n", mt);
 583#endif
 584
 585        memcpy(e, ic_bootp_cookie, 4);  /* RFC1048 Magic Cookie */
 586        e += 4;
 587
 588        *e++ = 53;              /* DHCP message type */
 589        *e++ = 1;
 590        *e++ = mt;
 591
 592        if (mt == DHCPREQUEST) {
 593                *e++ = 54;      /* Server ID (IP address) */
 594                *e++ = 4;
 595                memcpy(e, &ic_servaddr, 4);
 596                e += 4;
 597
 598                *e++ = 50;      /* Requested IP address */
 599                *e++ = 4;
 600                memcpy(e, &ic_myaddr, 4);
 601                e += 4;
 602        }
 603
 604        /* always? */
 605        {
 606                static const u8 ic_req_params[] = {
 607                        1,      /* Subnet mask */
 608                        3,      /* Default gateway */
 609                        6,      /* DNS server */
 610                        12,     /* Host name */
 611                        15,     /* Domain name */
 612                        17,     /* Boot path */
 613                        40,     /* NIS domain name */
 614                };
 615
 616                *e++ = 55;      /* Parameter request list */
 617                *e++ = sizeof(ic_req_params);
 618                memcpy(e, ic_req_params, sizeof(ic_req_params));
 619                e += sizeof(ic_req_params);
 620        }
 621
 622        *e++ = 255;     /* End of the list */
 623}
 624
 625#endif /* IPCONFIG_DHCP */
 626
 627static void __init ic_bootp_init_ext(u8 *e)
 628{
 629        memcpy(e, ic_bootp_cookie, 4);  /* RFC1048 Magic Cookie */
 630        e += 4;
 631        *e++ = 1;               /* Subnet mask request */
 632        *e++ = 4;
 633        e += 4;
 634        *e++ = 3;               /* Default gateway request */
 635        *e++ = 4;
 636        e += 4;
 637        *e++ = 5;               /* Name server request */
 638        *e++ = 8;
 639        e += 8;
 640        *e++ = 12;              /* Host name request */
 641        *e++ = 32;
 642        e += 32;
 643        *e++ = 40;              /* NIS Domain name request */
 644        *e++ = 32;
 645        e += 32;
 646        *e++ = 17;              /* Boot path */
 647        *e++ = 40;
 648        e += 40;
 649
 650        *e++ = 57;              /* set extension buffer size for reply */ 
 651        *e++ = 2;
 652        *e++ = 1;               /* 128+236+8+20+14, see dhcpd sources */ 
 653        *e++ = 150;
 654
 655        *e++ = 255;             /* End of the list */
 656}
 657
 658
 659/*
 660 *  Initialize the DHCP/BOOTP mechanism.
 661 */
 662static inline void ic_bootp_init(void)
 663{
 664        int i;
 665
 666        for (i = 0; i < CONF_NAMESERVERS_MAX; i++)
 667                ic_nameservers[i] = INADDR_NONE;
 668
 669        dev_add_pack(&bootp_packet_type);
 670}
 671
 672
 673/*
 674 *  DHCP/BOOTP cleanup.
 675 */
 676static inline void ic_bootp_cleanup(void)
 677{
 678        dev_remove_pack(&bootp_packet_type);
 679}
 680
 681
 682/*
 683 *  Send DHCP/BOOTP request to single interface.
 684 */
 685static void __init ic_bootp_send_if(struct ic_device *d, unsigned long jiffies_diff)
 686{
 687        struct net_device *dev = d->dev;
 688        struct sk_buff *skb;
 689        struct bootp_pkt *b;
 690        int hh_len = LL_RESERVED_SPACE(dev);
 691        struct iphdr *h;
 692
 693        /* Allocate packet */
 694        skb = alloc_skb(sizeof(struct bootp_pkt) + hh_len + 15, GFP_KERNEL);
 695        if (!skb)
 696                return;
 697        skb_reserve(skb, hh_len);
 698        b = (struct bootp_pkt *) skb_put(skb, sizeof(struct bootp_pkt));
 699        memset(b, 0, sizeof(struct bootp_pkt));
 700
 701        /* Construct IP header */
 702        skb->nh.iph = h = &b->iph;
 703        h->version = 4;
 704        h->ihl = 5;
 705        h->tot_len = htons(sizeof(struct bootp_pkt));
 706        h->frag_off = htons(IP_DF);
 707        h->ttl = 64;
 708        h->protocol = IPPROTO_UDP;
 709        h->daddr = INADDR_BROADCAST;
 710        h->check = ip_fast_csum((unsigned char *) h, h->ihl);
 711
 712        /* Construct UDP header */
 713        b->udph.source = htons(68);
 714        b->udph.dest = htons(67);
 715        b->udph.len = htons(sizeof(struct bootp_pkt) - sizeof(struct iphdr));
 716        /* UDP checksum not calculated -- explicitly allowed in BOOTP RFC */
 717
 718        /* Construct DHCP/BOOTP header */
 719        b->op = BOOTP_REQUEST;
 720        if (dev->type < 256) /* check for false types */
 721                b->htype = dev->type;
 722        else if (dev->type == ARPHRD_IEEE802_TR) /* fix for token ring */
 723                b->htype = ARPHRD_IEEE802;
 724        else if (dev->type == ARPHRD_FDDI)
 725                b->htype = ARPHRD_ETHER;
 726        else {
 727                printk("Unknown ARP type 0x%04x for device %s\n", dev->type, dev->name);
 728                b->htype = dev->type; /* can cause undefined behavior */
 729        }
 730        b->hlen = dev->addr_len;
 731        b->your_ip = INADDR_NONE;
 732        b->server_ip = INADDR_NONE;
 733        memcpy(b->hw_addr, dev->dev_addr, dev->addr_len);
 734        b->secs = htons(jiffies_diff / HZ);
 735        b->xid = d->xid;
 736
 737        /* add DHCP options or BOOTP extensions */
 738#ifdef IPCONFIG_DHCP
 739        if (ic_proto_enabled & IC_USE_DHCP)
 740                ic_dhcp_init_options(b->exten);
 741        else
 742#endif
 743                ic_bootp_init_ext(b->exten);
 744
 745        /* Chain packet down the line... */
 746        skb->dev = dev;
 747        skb->protocol = htons(ETH_P_IP);
 748        if ((dev->hard_header &&
 749             dev->hard_header(skb, dev, ntohs(skb->protocol), dev->broadcast, dev->dev_addr, skb->len) < 0) ||
 750            dev_queue_xmit(skb) < 0)
 751                printk("E");
 752}
 753
 754
 755/*
 756 *  Copy BOOTP-supplied string if not already set.
 757 */
 758static int __init ic_bootp_string(char *dest, char *src, int len, int max)
 759{
 760        if (!len)
 761                return 0;
 762        if (len > max-1)
 763                len = max-1;
 764        memcpy(dest, src, len);
 765        dest[len] = '\0';
 766        return 1;
 767}
 768
 769
 770/*
 771 *  Process BOOTP extensions.
 772 */
 773static void __init ic_do_bootp_ext(u8 *ext)
 774{
 775       u8 servers;
 776       int i;
 777
 778#ifdef IPCONFIG_DEBUG
 779        u8 *c;
 780
 781        printk("DHCP/BOOTP: Got extension %d:",*ext);
 782        for(c=ext+2; c<ext+2+ext[1]; c++)
 783                printk(" %02x", *c);
 784        printk("\n");
 785#endif
 786
 787        switch (*ext++) {
 788                case 1:         /* Subnet mask */
 789                        if (ic_netmask == INADDR_NONE)
 790                                memcpy(&ic_netmask, ext+1, 4);
 791                        break;
 792                case 3:         /* Default gateway */
 793                        if (ic_gateway == INADDR_NONE)
 794                                memcpy(&ic_gateway, ext+1, 4);
 795                        break;
 796                case 6:         /* DNS server */
 797                        servers= *ext/4;
 798                        if (servers > CONF_NAMESERVERS_MAX)
 799                                servers = CONF_NAMESERVERS_MAX;
 800                        for (i = 0; i < servers; i++) {
 801                                if (ic_nameservers[i] == INADDR_NONE)
 802                                        memcpy(&ic_nameservers[i], ext+1+4*i, 4);
 803                        }
 804                        break;
 805                case 12:        /* Host name */
 806                        ic_bootp_string(system_utsname.nodename, ext+1, *ext, __NEW_UTS_LEN);
 807                        ic_host_name_set = 1;
 808                        break;
 809                case 15:        /* Domain name (DNS) */
 810                        ic_bootp_string(ic_domain, ext+1, *ext, sizeof(ic_domain));
 811                        break;
 812                case 17:        /* Root path */
 813                        if (!root_server_path[0])
 814                                ic_bootp_string(root_server_path, ext+1, *ext, sizeof(root_server_path));
 815                        break;
 816                case 40:        /* NIS Domain name (_not_ DNS) */
 817                        ic_bootp_string(system_utsname.domainname, ext+1, *ext, __NEW_UTS_LEN);
 818                        break;
 819        }
 820}
 821
 822
 823/*
 824 *  Receive BOOTP reply.
 825 */
 826static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
 827{
 828        struct bootp_pkt *b;
 829        struct iphdr *h;
 830        struct ic_device *d;
 831        int len, ext_len;
 832
 833        /* Perform verifications before taking the lock.  */
 834        if (skb->pkt_type == PACKET_OTHERHOST)
 835                goto drop;
 836
 837        if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
 838                return NET_RX_DROP;
 839
 840        if (!pskb_may_pull(skb,
 841                           sizeof(struct iphdr) +
 842                           sizeof(struct udphdr)))
 843                goto drop;
 844
 845        b = (struct bootp_pkt *) skb->nh.iph;
 846        h = &b->iph;
 847
 848        if (h->ihl != 5 || h->version != 4 || h->protocol != IPPROTO_UDP)
 849                goto drop;
 850
 851        /* Fragments are not supported */
 852        if (h->frag_off & htons(IP_OFFSET | IP_MF)) {
 853                if (net_ratelimit())
 854                        printk(KERN_ERR "DHCP/BOOTP: Ignoring fragmented "
 855                               "reply.\n");
 856                goto drop;
 857        }
 858
 859        if (skb->len < ntohs(h->tot_len))
 860                goto drop;
 861
 862        if (ip_fast_csum((char *) h, h->ihl))
 863                goto drop;
 864
 865        if (b->udph.source != htons(67) || b->udph.dest != htons(68))
 866                goto drop;
 867
 868        if (ntohs(h->tot_len) < ntohs(b->udph.len) + sizeof(struct iphdr))
 869                goto drop;
 870
 871        len = ntohs(b->udph.len) - sizeof(struct udphdr);
 872        ext_len = len - (sizeof(*b) -
 873                         sizeof(struct iphdr) -
 874                         sizeof(struct udphdr) -
 875                         sizeof(b->exten));
 876        if (ext_len < 0)
 877                goto drop;
 878
 879        /* Ok the front looks good, make sure we can get at the rest.  */
 880        if (!pskb_may_pull(skb, skb->len))
 881                goto drop;
 882
 883        b = (struct bootp_pkt *) skb->nh.iph;
 884        h = &b->iph;
 885
 886        /* One reply at a time, please. */
 887        spin_lock(&ic_recv_lock);
 888
 889        /* If we already have a reply, just drop the packet */
 890        if (ic_got_reply)
 891                goto drop_unlock;
 892
 893        /* Find the ic_device that the packet arrived on */
 894        d = ic_first_dev;
 895        while (d && d->dev != dev)
 896                d = d->next;
 897        if (!d)
 898                goto drop_unlock;  /* should never happen */
 899
 900        /* Is it a reply to our BOOTP request? */
 901        if (b->op != BOOTP_REPLY ||
 902            b->xid != d->xid) {
 903                if (net_ratelimit())
 904                        printk(KERN_ERR "DHCP/BOOTP: Reply not for us, "
 905                               "op[%x] xid[%x]\n",
 906                               b->op, b->xid);
 907                goto drop_unlock;
 908        }
 909
 910        /* Parse extensions */
 911        if (ext_len >= 4 &&
 912            !memcmp(b->exten, ic_bootp_cookie, 4)) { /* Check magic cookie */
 913                u8 *end = (u8 *) b + ntohs(b->iph.tot_len);
 914                u8 *ext;
 915
 916#ifdef IPCONFIG_DHCP
 917                if (ic_proto_enabled & IC_USE_DHCP) {
 918                        u32 server_id = INADDR_NONE;
 919                        int mt = 0;
 920
 921                        ext = &b->exten[4];
 922                        while (ext < end && *ext != 0xff) {
 923                                u8 *opt = ext++;
 924                                if (*opt == 0)  /* Padding */
 925                                        continue;
 926                                ext += *ext + 1;
 927                                if (ext >= end)
 928                                        break;
 929                                switch (*opt) {
 930                                case 53:        /* Message type */
 931                                        if (opt[1])
 932                                                mt = opt[2];
 933                                        break;
 934                                case 54:        /* Server ID (IP address) */
 935                                        if (opt[1] >= 4)
 936                                                memcpy(&server_id, opt + 2, 4);
 937                                        break;
 938                                };
 939                        }
 940
 941#ifdef IPCONFIG_DEBUG
 942                        printk("DHCP: Got message type %d\n", mt);
 943#endif
 944
 945                        switch (mt) {
 946                        case DHCPOFFER:
 947                                /* While in the process of accepting one offer,
 948                                 * ignore all others.
 949                                 */
 950                                if (ic_myaddr != INADDR_NONE)
 951                                        goto drop_unlock;
 952
 953                                /* Let's accept that offer. */
 954                                ic_myaddr = b->your_ip;
 955                                ic_servaddr = server_id;
 956#ifdef IPCONFIG_DEBUG
 957                                printk("DHCP: Offered address %u.%u.%u.%u",
 958                                       NIPQUAD(ic_myaddr));
 959                                printk(" by server %u.%u.%u.%u\n",
 960                                       NIPQUAD(ic_servaddr));
 961#endif
 962                                /* The DHCP indicated server address takes
 963                                 * precedence over the bootp header one if
 964                                 * they are different.
 965                                 */
 966                                if ((server_id != INADDR_NONE) &&
 967                                    (b->server_ip != server_id))
 968                                        b->server_ip = ic_servaddr;
 969                                break;
 970
 971                        case DHCPACK:
 972                                if (memcmp(dev->dev_addr, b->hw_addr, dev->addr_len) != 0)
 973                                        goto drop_unlock;
 974
 975                                /* Yeah! */
 976                                break;
 977
 978                        default:
 979                                /* Urque.  Forget it*/
 980                                ic_myaddr = INADDR_NONE;
 981                                ic_servaddr = INADDR_NONE;
 982                                goto drop_unlock;
 983                        };
 984
 985                        ic_dhcp_msgtype = mt;
 986
 987                }
 988#endif /* IPCONFIG_DHCP */
 989
 990                ext = &b->exten[4];
 991                while (ext < end && *ext != 0xff) {
 992                        u8 *opt = ext++;
 993                        if (*opt == 0)  /* Padding */
 994                                continue;
 995                        ext += *ext + 1;
 996                        if (ext < end)
 997                                ic_do_bootp_ext(opt);
 998                }
 999        }
1000
1001        /* We have a winner! */
1002        ic_dev = dev;
1003        ic_myaddr = b->your_ip;
1004        ic_servaddr = b->server_ip;
1005        if (ic_gateway == INADDR_NONE && b->relay_ip)
1006                ic_gateway = b->relay_ip;
1007        if (ic_nameservers[0] == INADDR_NONE)
1008                ic_nameservers[0] = ic_servaddr;
1009        ic_got_reply = IC_BOOTP;
1010
1011drop_unlock:
1012        /* Show's over.  Nothing to see here.  */
1013        spin_unlock(&ic_recv_lock);
1014
1015drop:
1016        /* Throw the packet out. */
1017        kfree_skb(skb);
1018
1019        return 0;
1020}       
1021
1022
1023#endif
1024
1025
1026/*
1027 *      Dynamic IP configuration -- DHCP, BOOTP, RARP.
1028 */
1029
1030#ifdef IPCONFIG_DYNAMIC
1031
1032static int __init ic_dynamic(void)
1033{
1034        int retries;
1035        struct ic_device *d;
1036        unsigned long start_jiffies, timeout, jiff;
1037        int do_bootp = ic_proto_have_if & IC_BOOTP;
1038        int do_rarp = ic_proto_have_if & IC_RARP;
1039
1040        /*
1041         * If none of DHCP/BOOTP/RARP was selected, return with an error.
1042         * This routine gets only called when some pieces of information
1043         * are missing, and without DHCP/BOOTP/RARP we are unable to get it.
1044         */
1045        if (!ic_proto_enabled) {
1046                printk(KERN_ERR "IP-Config: Incomplete network configuration information.\n");
1047                return -1;
1048        }
1049
1050#ifdef IPCONFIG_BOOTP
1051        if ((ic_proto_enabled ^ ic_proto_have_if) & IC_BOOTP)
1052                printk(KERN_ERR "DHCP/BOOTP: No suitable device found.\n");
1053#endif
1054#ifdef IPCONFIG_RARP
1055        if ((ic_proto_enabled ^ ic_proto_have_if) & IC_RARP)
1056                printk(KERN_ERR "RARP: No suitable device found.\n");
1057#endif
1058
1059        if (!ic_proto_have_if)
1060                /* Error message already printed */
1061                return -1;
1062
1063        /*
1064         * Setup protocols
1065         */
1066#ifdef IPCONFIG_BOOTP
1067        if (do_bootp)
1068                ic_bootp_init();
1069#endif
1070#ifdef IPCONFIG_RARP
1071        if (do_rarp)
1072                ic_rarp_init();
1073#endif
1074
1075        /*
1076         * Send requests and wait, until we get an answer. This loop
1077         * seems to be a terrible waste of CPU time, but actually there is
1078         * only one process running at all, so we don't need to use any
1079         * scheduler functions.
1080         * [Actually we could now, but the nothing else running note still 
1081         *  applies.. - AC]
1082         */
1083        printk(KERN_NOTICE "Sending %s%s%s requests .",
1084               do_bootp
1085                ? ((ic_proto_enabled & IC_USE_DHCP) ? "DHCP" : "BOOTP") : "",
1086               (do_bootp && do_rarp) ? " and " : "",
1087               do_rarp ? "RARP" : "");
1088
1089        start_jiffies = jiffies;
1090        d = ic_first_dev;
1091        retries = CONF_SEND_RETRIES;
1092        get_random_bytes(&timeout, sizeof(timeout));
1093        timeout = CONF_BASE_TIMEOUT + (timeout % (unsigned) CONF_TIMEOUT_RANDOM);
1094        for(;;) {
1095#ifdef IPCONFIG_BOOTP
1096                if (do_bootp && (d->able & IC_BOOTP))
1097                        ic_bootp_send_if(d, jiffies - start_jiffies);
1098#endif
1099#ifdef IPCONFIG_RARP
1100                if (do_rarp && (d->able & IC_RARP))
1101                        ic_rarp_send_if(d);
1102#endif
1103
1104                jiff = jiffies + (d->next ? CONF_INTER_TIMEOUT : timeout);
1105                while (time_before(jiffies, jiff) && !ic_got_reply) {
1106                        set_current_state(TASK_UNINTERRUPTIBLE);
1107                        schedule_timeout(1);
1108                }
1109#ifdef IPCONFIG_DHCP
1110                /* DHCP isn't done until we get a DHCPACK. */
1111                if ((ic_got_reply & IC_BOOTP)
1112                    && (ic_proto_enabled & IC_USE_DHCP)
1113                    && ic_dhcp_msgtype != DHCPACK)
1114                {
1115                        ic_got_reply = 0;
1116                        printk(",");
1117                        continue;
1118                }
1119#endif /* IPCONFIG_DHCP */
1120
1121                if (ic_got_reply) {
1122                        printk(" OK\n");
1123                        break;
1124                }
1125
1126                if ((d = d->next))
1127                        continue;
1128
1129                if (! --retries) {
1130                        printk(" timed out!\n");
1131                        break;
1132                }
1133
1134                d = ic_first_dev;
1135
1136                timeout = timeout CONF_TIMEOUT_MULT;
1137                if (timeout > CONF_TIMEOUT_MAX)
1138                        timeout = CONF_TIMEOUT_MAX;
1139
1140                printk(".");
1141        }
1142
1143#ifdef IPCONFIG_BOOTP
1144        if (do_bootp)
1145                ic_bootp_cleanup();
1146#endif
1147#ifdef IPCONFIG_RARP
1148        if (do_rarp)
1149                ic_rarp_cleanup();
1150#endif
1151
1152        if (!ic_got_reply)
1153                return -1;
1154
1155        printk("IP-Config: Got %s answer from %u.%u.%u.%u, ",
1156                ((ic_got_reply & IC_RARP) ? "RARP" 
1157                 : (ic_proto_enabled & IC_USE_DHCP) ? "DHCP" : "BOOTP"),
1158                NIPQUAD(ic_servaddr));
1159        printk("my address is %u.%u.%u.%u\n", NIPQUAD(ic_myaddr));
1160
1161        return 0;
1162}
1163
1164#endif /* IPCONFIG_DYNAMIC */
1165
1166#ifdef CONFIG_PROC_FS
1167
1168static int pnp_seq_show(struct seq_file *seq, void *v)
1169{
1170        int i;
1171
1172        if (ic_proto_used & IC_PROTO)
1173                seq_printf(seq, "#PROTO: %s\n",
1174                           (ic_proto_used & IC_RARP) ? "RARP"
1175                           : (ic_proto_used & IC_USE_DHCP) ? "DHCP" : "BOOTP");
1176        else
1177                seq_puts(seq, "#MANUAL\n");
1178
1179        if (ic_domain[0])
1180                seq_printf(seq,
1181                           "domain %s\n", ic_domain);
1182        for (i = 0; i < CONF_NAMESERVERS_MAX; i++) {
1183                if (ic_nameservers[i] != INADDR_NONE)
1184                        seq_printf(seq,
1185                                   "nameserver %u.%u.%u.%u\n",
1186                                   NIPQUAD(ic_nameservers[i]));
1187        }
1188        if (ic_servaddr != INADDR_NONE)
1189                seq_printf(seq,
1190                           "bootserver %u.%u.%u.%u\n",
1191                           NIPQUAD(ic_servaddr));
1192        return 0;
1193}
1194
1195static int pnp_seq_open(struct inode *indoe, struct file *file)
1196{
1197        return single_open(file, pnp_seq_show, NULL);
1198}
1199
1200static struct file_operations pnp_seq_fops = {
1201        .owner          = THIS_MODULE,
1202        .open           = pnp_seq_open,
1203        .read           = seq_read,
1204        .llseek         = seq_lseek,
1205        .release        = single_release,
1206};
1207#endif /* CONFIG_PROC_FS */
1208
1209/*
1210 *  Extract IP address from the parameter string if needed. Note that we
1211 *  need to have root_server_addr set _before_ IPConfig gets called as it
1212 *  can override it.
1213 */
1214u32 __init root_nfs_parse_addr(char *name)
1215{
1216        u32 addr;
1217        int octets = 0;
1218        char *cp, *cq;
1219
1220        cp = cq = name;
1221        while (octets < 4) {
1222                while (*cp >= '0' && *cp <= '9')
1223                        cp++;
1224                if (cp == cq || cp - cq > 3)
1225                        break;
1226                if (*cp == '.' || octets == 3)
1227                        octets++;
1228                if (octets < 4)
1229                        cp++;
1230                cq = cp;
1231        }
1232        if (octets == 4 && (*cp == ':' || *cp == '\0')) {
1233                if (*cp == ':')
1234                        *cp++ = '\0';
1235                addr = in_aton(name);
1236                memmove(name, cp, strlen(cp) + 1);
1237        } else
1238                addr = INADDR_NONE;
1239
1240        return addr;
1241}
1242
1243/*
1244 *      IP Autoconfig dispatcher.
1245 */
1246
1247static int __init ip_auto_config(void)
1248{
1249        u32 addr;
1250
1251#ifdef CONFIG_PROC_FS
1252        proc_net_fops_create("pnp", S_IRUGO, &pnp_seq_fops);
1253#endif /* CONFIG_PROC_FS */
1254
1255        if (!ic_enable)
1256                return 0;
1257
1258        DBG(("IP-Config: Entered.\n"));
1259#ifdef IPCONFIG_DYNAMIC
1260 try_try_again:
1261#endif
1262        /* Give hardware a chance to settle */
1263        msleep(CONF_PRE_OPEN);
1264
1265        /* Setup all network devices */
1266        if (ic_open_devs() < 0)
1267                return -1;
1268
1269        /* Give drivers a chance to settle */
1270        ssleep(CONF_POST_OPEN);
1271
1272        /*
1273         * If the config information is insufficient (e.g., our IP address or
1274         * IP address of the boot server is missing or we have multiple network
1275         * interfaces and no default was set), use BOOTP or RARP to get the
1276         * missing values.
1277         */
1278        if (ic_myaddr == INADDR_NONE ||
1279#ifdef CONFIG_ROOT_NFS
1280            (MAJOR(ROOT_DEV) == UNNAMED_MAJOR
1281             && root_server_addr == INADDR_NONE
1282             && ic_servaddr == INADDR_NONE) ||
1283#endif
1284            ic_first_dev->next) {
1285#ifdef IPCONFIG_DYNAMIC
1286        
1287                int retries = CONF_OPEN_RETRIES;
1288
1289                if (ic_dynamic() < 0) {
1290                        ic_close_devs();
1291
1292                        /*
1293                         * I don't know why, but sometimes the
1294                         * eepro100 driver (at least) gets upset and
1295                         * doesn't work the first time it's opened.
1296                         * But then if you close it and reopen it, it
1297                         * works just fine.  So we need to try that at
1298                         * least once before giving up.
1299                         *
1300                         * Also, if the root will be NFS-mounted, we
1301                         * have nowhere to go if DHCP fails.  So we
1302                         * just have to keep trying forever.
1303                         *
1304                         *                              -- Chip
1305                         */
1306#ifdef CONFIG_ROOT_NFS
1307                        if (ROOT_DEV ==  Root_NFS) {
1308                                printk(KERN_ERR 
1309                                        "IP-Config: Retrying forever (NFS root)...\n");
1310                                goto try_try_again;
1311                        }
1312#endif
1313
1314                        if (--retries) {
1315                                printk(KERN_ERR 
1316                                       "IP-Config: Reopening network devices...\n");
1317                                goto try_try_again;
1318                        }
1319
1320                        /* Oh, well.  At least we tried. */
1321                        printk(KERN_ERR "IP-Config: Auto-configuration of network failed.\n");
1322                        return -1;
1323                }
1324#else /* !DYNAMIC */
1325                printk(KERN_ERR "IP-Config: Incomplete network configuration information.\n");
1326                ic_close_devs();
1327                return -1;
1328#endif /* IPCONFIG_DYNAMIC */
1329        } else {
1330                /* Device selected manually or only one device -> use it */
1331                ic_dev = ic_first_dev->dev;
1332        }
1333
1334        addr = root_nfs_parse_addr(root_server_path);
1335        if (root_server_addr == INADDR_NONE)
1336                root_server_addr = addr;
1337
1338        /*
1339         * Use defaults whereever applicable.
1340         */
1341        if (ic_defaults() < 0)
1342                return -1;
1343
1344        /*
1345         * Close all network devices except the device we've
1346         * autoconfigured and set up routes.
1347         */
1348        ic_close_devs();
1349        if (ic_setup_if() < 0 || ic_setup_routes() < 0)
1350                return -1;
1351
1352        /*
1353         * Record which protocol was actually used.
1354         */
1355#ifdef IPCONFIG_DYNAMIC
1356        ic_proto_used = ic_got_reply | (ic_proto_enabled & IC_USE_DHCP);
1357#endif
1358
1359#ifndef IPCONFIG_SILENT
1360        /*
1361         * Clue in the operator.
1362         */
1363        printk("IP-Config: Complete:");
1364        printk("\n      device=%s", ic_dev->name);
1365        printk(", addr=%u.%u.%u.%u", NIPQUAD(ic_myaddr));
1366        printk(", mask=%u.%u.%u.%u", NIPQUAD(ic_netmask));
1367        printk(", gw=%u.%u.%u.%u", NIPQUAD(ic_gateway));
1368        printk(",\n     host=%s, domain=%s, nis-domain=%s",
1369               system_utsname.nodename, ic_domain, system_utsname.domainname);
1370        printk(",\n     bootserver=%u.%u.%u.%u", NIPQUAD(ic_servaddr));
1371        printk(", rootserver=%u.%u.%u.%u", NIPQUAD(root_server_addr));
1372        printk(", rootpath=%s", root_server_path);
1373        printk("\n");
1374#endif /* !SILENT */
1375
1376        return 0;
1377}
1378
1379late_initcall(ip_auto_config);
1380
1381
1382/*
1383 *  Decode any IP configuration options in the "ip=" or "nfsaddrs=" kernel
1384 *  command line parameter. It consists of option fields separated by colons in
1385 *  the following order:
1386 *
1387 *  <client-ip>:<server-ip>:<gw-ip>:<netmask>:<host name>:<device>:<PROTO>
1388 *
1389 *  Any of the fields can be empty which means to use a default value:
1390 *      <client-ip>     - address given by BOOTP or RARP
1391 *      <server-ip>     - address of host returning BOOTP or RARP packet
1392 *      <gw-ip>         - none, or the address returned by BOOTP
1393 *      <netmask>       - automatically determined from <client-ip>, or the
1394 *                        one returned by BOOTP
1395 *      <host name>     - <client-ip> in ASCII notation, or the name returned
1396 *                        by BOOTP
1397 *      <device>        - use all available devices
1398 *      <PROTO>:
1399 *         off|none         - don't do autoconfig at all (DEFAULT)
1400 *         on|any           - use any configured protocol
1401 *         dhcp|bootp|rarp  - use only the specified protocol
1402 *         both             - use both BOOTP and RARP (not DHCP)
1403 */
1404static int __init ic_proto_name(char *name)
1405{
1406        if (!strcmp(name, "on") || !strcmp(name, "any")) {
1407                return 1;
1408        }
1409#ifdef CONFIG_IP_PNP_DHCP
1410        else if (!strcmp(name, "dhcp")) {
1411                ic_proto_enabled &= ~IC_RARP;
1412                return 1;
1413        }
1414#endif
1415#ifdef CONFIG_IP_PNP_BOOTP
1416        else if (!strcmp(name, "bootp")) {
1417                ic_proto_enabled &= ~(IC_RARP | IC_USE_DHCP);
1418                return 1;
1419        }
1420#endif
1421#ifdef CONFIG_IP_PNP_RARP
1422        else if (!strcmp(name, "rarp")) {
1423                ic_proto_enabled &= ~(IC_BOOTP | IC_USE_DHCP);
1424                return 1;
1425        }
1426#endif
1427#ifdef IPCONFIG_DYNAMIC
1428        else if (!strcmp(name, "both")) {
1429                ic_proto_enabled &= ~IC_USE_DHCP; /* backward compat :-( */
1430                return 1;
1431        }
1432#endif
1433        return 0;
1434}
1435
1436static int __init ip_auto_config_setup(char *addrs)
1437{
1438        char *cp, *ip, *dp;
1439        int num = 0;
1440
1441        ic_set_manually = 1;
1442
1443        ic_enable = (*addrs && 
1444                (strcmp(addrs, "off") != 0) && 
1445                (strcmp(addrs, "none") != 0));
1446        if (!ic_enable)
1447                return 1;
1448
1449        if (ic_proto_name(addrs))
1450                return 1;
1451
1452        /* Parse the whole string */
1453        ip = addrs;
1454        while (ip && *ip) {
1455                if ((cp = strchr(ip, ':')))
1456                        *cp++ = '\0';
1457                if (strlen(ip) > 0) {
1458                        DBG(("IP-Config: Parameter #%d: `%s'\n", num, ip));
1459                        switch (num) {
1460                        case 0:
1461                                if ((ic_myaddr = in_aton(ip)) == INADDR_ANY)
1462                                        ic_myaddr = INADDR_NONE;
1463                                break;
1464                        case 1:
1465                                if ((ic_servaddr = in_aton(ip)) == INADDR_ANY)
1466                                        ic_servaddr = INADDR_NONE;
1467                                break;
1468                        case 2:
1469                                if ((ic_gateway = in_aton(ip)) == INADDR_ANY)
1470                                        ic_gateway = INADDR_NONE;
1471                                break;
1472                        case 3:
1473                                if ((ic_netmask = in_aton(ip)) == INADDR_ANY)
1474                                        ic_netmask = INADDR_NONE;
1475                                break;
1476                        case 4:
1477                                if ((dp = strchr(ip, '.'))) {
1478                                        *dp++ = '\0';
1479                                        strlcpy(system_utsname.domainname, dp,
1480                                                sizeof(system_utsname.domainname));
1481                                }
1482                                strlcpy(system_utsname.nodename, ip,
1483                                        sizeof(system_utsname.nodename));
1484                                ic_host_name_set = 1;
1485                                break;
1486                        case 5:
1487                                strlcpy(user_dev_name, ip, sizeof(user_dev_name));
1488                                break;
1489                        case 6:
1490                                ic_proto_name(ip);
1491                                break;
1492                        }
1493                }
1494                ip = cp;
1495                num++;
1496        }
1497
1498        return 1;
1499}
1500
1501static int __init nfsaddrs_config_setup(char *addrs)
1502{
1503        return ip_auto_config_setup(addrs);
1504}
1505
1506__setup("ip=", ip_auto_config_setup);
1507__setup("nfsaddrs=", nfsaddrs_config_setup);
1508
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.