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