linux-old/net/ipv4/ipconfig.c
<<
>>
Prefs
   1/*
   2 *  $Id: ipconfig.c,v 1.20 1999/03/28 10:18:28 davem Exp $
   3 *
   4 *  Automatic Configuration of IP -- use BOOTP or RARP or user-supplied
   5 *  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
  17#include <linux/config.h>
  18#include <linux/types.h>
  19#include <linux/string.h>
  20#include <linux/kernel.h>
  21#include <linux/sched.h>
  22#include <linux/random.h>
  23#include <linux/init.h>
  24#include <linux/utsname.h>
  25#include <linux/in.h>
  26#include <linux/if.h>
  27#include <linux/inet.h>
  28#include <linux/netdevice.h>
  29#include <linux/if_arp.h>
  30#include <linux/skbuff.h>
  31#include <linux/ip.h>
  32#include <linux/socket.h>
  33#include <linux/route.h>
  34#include <linux/udp.h>
  35#include <net/arp.h>
  36#include <net/ip.h>
  37#include <net/ipconfig.h>
  38
  39#include <asm/segment.h>
  40#include <asm/uaccess.h>
  41#include <asm/checksum.h>
  42
  43/* Define this to allow debugging output */
  44#undef IPCONFIG_DEBUG
  45
  46#ifdef IPCONFIG_DEBUG
  47#define DBG(x) printk x
  48#else
  49#define DBG(x) do { } while(0)
  50#endif
  51
  52/* Define the timeout for waiting for a RARP/BOOTP reply */
  53#define CONF_BASE_TIMEOUT       (HZ*5)  /* Initial timeout: 5 seconds */
  54#define CONF_RETRIES            10      /* 10 retries */
  55#define CONF_TIMEOUT_RANDOM     (HZ)    /* Maximum amount of randomization */
  56#define CONF_TIMEOUT_MULT       *5/4    /* Rate of timeout growth */
  57#define CONF_TIMEOUT_MAX        (HZ*30) /* Maximum allowed timeout */
  58
  59/* IP configuration */
  60static char user_dev_name[IFNAMSIZ] __initdata = { 0, };/* Name of user-selected boot device */
  61u32 ic_myaddr __initdata = INADDR_NONE;         /* My IP address */
  62u32 ic_servaddr __initdata = INADDR_NONE;       /* Server IP address */
  63u32 ic_gateway __initdata = INADDR_NONE;        /* Gateway IP address */
  64u32 ic_netmask __initdata = INADDR_NONE;        /* Netmask for local subnet */
  65int ic_enable __initdata = 1;                   /* Automatic IP configuration enabled */
  66int ic_host_name_set __initdata = 0;            /* Host name configured manually */
  67int ic_set_manually __initdata = 0;             /* IPconfig parameters set manually */
  68
  69u32 root_server_addr __initdata = INADDR_NONE;          /* Address of boot server */
  70u8 root_server_path[256] __initdata = { 0, };           /* Path to mount as root */
  71
  72#if defined(CONFIG_IP_PNP_BOOTP) || defined(CONFIG_IP_PNP_RARP)
  73
  74#define CONFIG_IP_PNP_DYNAMIC
  75
  76static int ic_proto_enabled __initdata = 0                      /* Protocols enabled */
  77#ifdef CONFIG_IP_PNP_BOOTP
  78                        | IC_BOOTP
  79#endif
  80#ifdef CONFIG_IP_PNP_RARP
  81                        | IC_RARP
  82#endif
  83                        ;
  84static int ic_got_reply __initdata = 0;                         /* Protocol(s) we got reply from */
  85
  86#else
  87
  88static int ic_proto_enabled __initdata = 0;
  89
  90#endif
  91
  92static int ic_proto_have_if __initdata = 0;
  93
  94/*
  95 *      Network devices
  96 */
  97
  98struct ic_device {
  99        struct ic_device *next;
 100        struct device *dev;
 101        unsigned short flags;
 102        int able;
 103};
 104
 105static struct ic_device *ic_first_dev __initdata = NULL;/* List of open device */
 106static struct device *ic_dev __initdata = NULL;         /* Selected device */
 107
 108static int __init ic_open_devs(void)
 109{
 110        struct ic_device *d, **last;
 111        struct device *dev;
 112        unsigned short oflags;
 113
 114        last = &ic_first_dev;
 115        for (dev = dev_base; dev; dev = dev->next)
 116                if (user_dev_name[0] ? !strcmp(dev->name, user_dev_name) :
 117                    (!(dev->flags & IFF_LOOPBACK) &&
 118                     (dev->flags & (IFF_POINTOPOINT|IFF_BROADCAST)) &&
 119                     strncmp(dev->name, "dummy", 5))) {
 120                        int able = 0;
 121                        if (dev->mtu >= 364)
 122                                able |= IC_BOOTP;
 123                        else
 124                                printk(KERN_WARNING "BOOTP: Ignoring device %s, MTU %d too small", dev->name, dev->mtu);
 125                        if (!(dev->flags & IFF_NOARP))
 126                                able |= IC_RARP;
 127                        able &= ic_proto_enabled;
 128                        if (ic_proto_enabled && !able)
 129                                continue;
 130                        oflags = dev->flags;
 131                        if (dev_change_flags(dev, oflags | IFF_UP) < 0) {
 132                                printk(KERN_ERR "IP-Config: Failed to open %s\n", dev->name);
 133                                continue;
 134                        }
 135                        if (!(d = kmalloc(sizeof(struct ic_device), GFP_KERNEL)))
 136                                return -1;
 137                        d->dev = dev;
 138                        *last = d;
 139                        last = &d->next;
 140                        d->flags = oflags;
 141                        d->able = able;
 142                        ic_proto_have_if |= able;
 143                        DBG(("IP-Config: Opened %s (able=%d)\n", dev->name, able));
 144                }
 145        *last = NULL;
 146
 147        if (!ic_first_dev) {
 148                if (user_dev_name[0])
 149                        printk(KERN_ERR "IP-Config: Device `%s' not found.\n", user_dev_name);
 150                else
 151                        printk(KERN_ERR "IP-Config: No network devices available.\n");
 152                return -1;
 153        }
 154        return 0;
 155}
 156
 157static void __init ic_close_devs(void)
 158{
 159        struct ic_device *d, *next;
 160        struct device *dev;
 161
 162        next = ic_first_dev;
 163        while ((d = next)) {
 164                next = d->next;
 165                dev = d->dev;
 166                if (dev != ic_dev) {
 167                        DBG(("IP-Config: Downing %s\n", dev->name));
 168                        dev_change_flags(dev, d->flags);
 169                }
 170                kfree_s(d, sizeof(struct ic_device));
 171        }
 172}
 173
 174/*
 175 *      Interface to various network functions.
 176 */
 177
 178static inline void
 179set_sockaddr(struct sockaddr_in *sin, u32 addr, u16 port)
 180{
 181        sin->sin_family = AF_INET;
 182        sin->sin_addr.s_addr = addr;
 183        sin->sin_port = port;
 184}
 185
 186static int __init ic_dev_ioctl(unsigned int cmd, struct ifreq *arg)
 187{
 188        int res;
 189
 190        mm_segment_t oldfs = get_fs();
 191        set_fs(get_ds());
 192        res = devinet_ioctl(cmd, arg);
 193        set_fs(oldfs);
 194        return res;
 195}
 196
 197static int __init ic_route_ioctl(unsigned int cmd, struct rtentry *arg)
 198{
 199        int res;
 200
 201        mm_segment_t oldfs = get_fs();
 202        set_fs(get_ds());
 203        res = ip_rt_ioctl(cmd, arg);
 204        set_fs(oldfs);
 205        return res;
 206}
 207
 208/*
 209 *      Set up interface addresses and routes.
 210 */
 211
 212static int __init ic_setup_if(void)
 213{
 214        struct ifreq ir;
 215        struct sockaddr_in *sin = (void *) &ir.ifr_ifru.ifru_addr;
 216        int err;
 217
 218        memset(&ir, 0, sizeof(ir));
 219        strcpy(ir.ifr_ifrn.ifrn_name, ic_dev->name);
 220        set_sockaddr(sin, ic_myaddr, 0);
 221        if ((err = ic_dev_ioctl(SIOCSIFADDR, &ir)) < 0) {
 222                printk(KERN_ERR "IP-Config: Unable to set interface address (%d).\n", err);
 223                return -1;
 224        }
 225        set_sockaddr(sin, ic_netmask, 0);
 226        if ((err = ic_dev_ioctl(SIOCSIFNETMASK, &ir)) < 0) {
 227                printk(KERN_ERR "IP-Config: Unable to set interface netmask (%d).\n", err);
 228                return -1;
 229        }
 230        set_sockaddr(sin, ic_myaddr | ~ic_netmask, 0);
 231        if ((err = ic_dev_ioctl(SIOCSIFBRDADDR, &ir)) < 0) {
 232                printk(KERN_ERR "IP-Config: Unable to set interface broadcast address (%d).\n", err);
 233                return -1;
 234        }
 235        return 0;
 236}
 237
 238static int __init ic_setup_routes(void)
 239{
 240        /* No need to setup device routes, only the default route... */
 241
 242        if (ic_gateway != INADDR_NONE) {
 243                struct rtentry rm;
 244                int err;
 245
 246                memset(&rm, 0, sizeof(rm));
 247                if ((ic_gateway ^ ic_myaddr) & ic_netmask) {
 248                        printk(KERN_ERR "IP-Config: Gateway not on directly connected network.\n");
 249                        return -1;
 250                }
 251                set_sockaddr((struct sockaddr_in *) &rm.rt_dst, 0, 0);
 252                set_sockaddr((struct sockaddr_in *) &rm.rt_genmask, 0, 0);
 253                set_sockaddr((struct sockaddr_in *) &rm.rt_gateway, ic_gateway, 0);
 254                rm.rt_flags = RTF_UP | RTF_GATEWAY;
 255                if ((err = ic_route_ioctl(SIOCADDRT, &rm)) < 0) {
 256                        printk(KERN_ERR "IP-Config: Cannot add default route (%d).\n", err);
 257                        return -1;
 258                }
 259        }
 260
 261        return 0;
 262}
 263
 264/*
 265 *      Fill in default values for all missing parameters.
 266 */
 267
 268static int __init ic_defaults(void)
 269{
 270        /*
 271         *      At this point we have no userspace running so need not
 272         *      claim locks on system_utsname
 273         */
 274         
 275        if (!ic_host_name_set)
 276                strcpy(system_utsname.nodename, in_ntoa(ic_myaddr));
 277
 278        if (root_server_addr == INADDR_NONE)
 279                root_server_addr = ic_servaddr;
 280
 281        if (ic_netmask == INADDR_NONE) {
 282                if (IN_CLASSA(ntohl(ic_myaddr)))
 283                        ic_netmask = htonl(IN_CLASSA_NET);
 284                else if (IN_CLASSB(ntohl(ic_myaddr)))
 285                        ic_netmask = htonl(IN_CLASSB_NET);
 286                else if (IN_CLASSC(ntohl(ic_myaddr)))
 287                        ic_netmask = htonl(IN_CLASSC_NET);
 288                else {
 289                        printk(KERN_ERR "IP-Config: Unable to guess netmask for address %08x\n", ic_myaddr);
 290                        return -1;
 291                }
 292                printk("IP-Config: Guessing netmask %s\n", in_ntoa(ic_netmask));
 293        }
 294
 295        return 0;
 296}
 297
 298/*
 299 *      RARP support.
 300 */
 301
 302#ifdef CONFIG_IP_PNP_RARP
 303
 304static int ic_rarp_recv(struct sk_buff *skb, struct device *dev, struct packet_type *pt);
 305
 306static struct packet_type rarp_packet_type __initdata = {
 307        __constant_htons(ETH_P_RARP),
 308        NULL,                   /* Listen to all devices */
 309        ic_rarp_recv,
 310        NULL,
 311        NULL
 312};
 313
 314static inline void ic_rarp_init(void)
 315{
 316        dev_add_pack(&rarp_packet_type);
 317}
 318
 319static inline void ic_rarp_cleanup(void)
 320{
 321        dev_remove_pack(&rarp_packet_type);
 322}
 323
 324/*
 325 *  Process received RARP packet.
 326 */
 327static int __init
 328ic_rarp_recv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
 329{
 330        struct arphdr *rarp = (struct arphdr *)skb->h.raw;
 331        unsigned char *rarp_ptr = (unsigned char *) (rarp + 1);
 332        unsigned long sip, tip;
 333        unsigned char *sha, *tha;               /* s for "source", t for "target" */
 334
 335        /* If we already have a reply, just drop the packet */
 336        if (ic_got_reply)
 337                goto drop;
 338
 339        /* If this test doesn't pass, it's not IP, or we should ignore it anyway */
 340        if (rarp->ar_hln != dev->addr_len || dev->type != ntohs(rarp->ar_hrd))
 341                goto drop;
 342
 343        /* If it's not a RARP reply, delete it. */
 344        if (rarp->ar_op != htons(ARPOP_RREPLY))
 345                goto drop;
 346
 347        /* If it's not Ethernet, delete it. */
 348        if (rarp->ar_pro != htons(ETH_P_IP))
 349                goto drop;
 350
 351        /* Extract variable-width fields */
 352        sha = rarp_ptr;
 353        rarp_ptr += dev->addr_len;
 354        memcpy(&sip, rarp_ptr, 4);
 355        rarp_ptr += 4;
 356        tha = rarp_ptr;
 357        rarp_ptr += dev->addr_len;
 358        memcpy(&tip, rarp_ptr, 4);
 359
 360        /* Discard packets which are not meant for us. */
 361        if (memcmp(tha, dev->dev_addr, dev->addr_len))
 362                goto drop;
 363
 364        /* Discard packets which are not from specified server. */
 365        if (ic_servaddr != INADDR_NONE && ic_servaddr != sip)
 366                goto drop;
 367
 368        /* Victory! The packet is what we were looking for! */
 369        if (!ic_got_reply) {
 370                ic_got_reply = IC_RARP;
 371                ic_dev = dev;
 372                if (ic_myaddr == INADDR_NONE)
 373                        ic_myaddr = tip;
 374                ic_servaddr = sip;
 375        }
 376
 377        /* And throw the packet out... */
 378drop:
 379        kfree_skb(skb);
 380        return 0;
 381}
 382
 383
 384/*
 385 *  Send RARP request packet over all devices which allow RARP.
 386 */
 387static void __init ic_rarp_send(void)
 388{
 389        struct ic_device *d;
 390
 391        for (d=ic_first_dev; d; d=d->next)
 392                if (d->able & IC_RARP) {
 393                        struct device *dev = d->dev;
 394                        arp_send(ARPOP_RREQUEST, ETH_P_RARP, 0, dev, 0, NULL,
 395                                 dev->dev_addr, dev->dev_addr);
 396                }
 397}
 398
 399#endif
 400
 401/*
 402 *      BOOTP support.
 403 */
 404
 405#ifdef CONFIG_IP_PNP_BOOTP
 406
 407struct bootp_pkt {              /* BOOTP packet format */
 408        struct iphdr iph;       /* IP header */
 409        struct udphdr udph;     /* UDP header */
 410        u8 op;                  /* 1=request, 2=reply */
 411        u8 htype;               /* HW address type */
 412        u8 hlen;                /* HW address length */
 413        u8 hops;                /* Used only by gateways */
 414        u32 xid;                /* Transaction ID */
 415        u16 secs;               /* Seconds since we started */
 416        u16 flags;              /* Just what it says */
 417        u32 client_ip;          /* Client's IP address if known */
 418        u32 your_ip;            /* Assigned IP address */
 419        u32 server_ip;          /* Server's IP address */
 420        u32 relay_ip;           /* IP address of BOOTP relay */
 421        u8 hw_addr[16];         /* Client's HW address */
 422        u8 serv_name[64];       /* Server host name */
 423        u8 boot_file[128];      /* Name of boot file */
 424        u8 vendor_area[128];    /* Area for extensions */
 425};
 426
 427#define BOOTP_REQUEST 1
 428#define BOOTP_REPLY 2
 429
 430static u32 ic_bootp_xid;
 431
 432static int ic_bootp_recv(struct sk_buff *skb, struct device *dev, struct packet_type *pt);
 433
 434static struct packet_type bootp_packet_type __initdata = {
 435        __constant_htons(ETH_P_IP),
 436        NULL,                   /* Listen to all devices */
 437        ic_bootp_recv,
 438        NULL,
 439        NULL
 440};
 441
 442
 443/*
 444 *  Initialize BOOTP extension fields in the request.
 445 */
 446static void __init ic_bootp_init_ext(u8 *e)
 447{
 448        *e++ = 99;              /* RFC1048 Magic Cookie */
 449        *e++ = 130;
 450        *e++ = 83;
 451        *e++ = 99;
 452        *e++ = 1;               /* Subnet mask request */
 453        *e++ = 4;
 454        e += 4;
 455        *e++ = 3;               /* Default gateway request */
 456        *e++ = 4;
 457        e += 4;
 458        *e++ = 12;              /* Host name request */
 459        *e++ = 32;
 460        e += 32;
 461        *e++ = 40;              /* NIS Domain name request */
 462        *e++ = 32;
 463        e += 32;
 464        *e++ = 17;              /* Boot path */
 465        *e++ = 32;
 466        e += 32;
 467        *e = 255;               /* End of the list */
 468}
 469
 470
 471/*
 472 *  Initialize the BOOTP mechanism.
 473 */
 474static inline void ic_bootp_init(void)
 475{
 476        get_random_bytes(&ic_bootp_xid, sizeof(u32));
 477        DBG(("BOOTP: XID=%08x\n", ic_bootp_xid));
 478        dev_add_pack(&bootp_packet_type);
 479}
 480
 481
 482/*
 483 *  BOOTP cleanup.
 484 */
 485static inline void ic_bootp_cleanup(void)
 486{
 487        dev_remove_pack(&bootp_packet_type);
 488}
 489
 490
 491/*
 492 *  Send BOOTP request to single interface.
 493 */
 494static void __init ic_bootp_send_if(struct ic_device *d, u32 jiffies)
 495{
 496        struct device *dev = d->dev;
 497        struct sk_buff *skb;
 498        struct bootp_pkt *b;
 499        int hh_len = (dev->hard_header_len + 15) & ~15;
 500        struct iphdr *h;
 501
 502        /* Allocate packet */
 503        skb = alloc_skb(sizeof(struct bootp_pkt) + hh_len + 15, GFP_KERNEL);
 504        if (!skb)
 505                return;
 506        skb_reserve(skb, hh_len);
 507        b = (struct bootp_pkt *) skb_put(skb, sizeof(struct bootp_pkt));
 508        memset(b, 0, sizeof(struct bootp_pkt));
 509
 510        /* Construct IP header */
 511        skb->nh.iph = h = &b->iph;
 512        h->version = 4;
 513        h->ihl = 5;
 514        h->tot_len = htons(sizeof(struct bootp_pkt));
 515        h->frag_off = htons(IP_DF);
 516        h->ttl = 64;
 517        h->protocol = IPPROTO_UDP;
 518        h->daddr = INADDR_BROADCAST;
 519        h->check = ip_fast_csum((unsigned char *) h, h->ihl);
 520
 521        /* Construct UDP header */
 522        b->udph.source = htons(68);
 523        b->udph.dest = htons(67);
 524        b->udph.len = htons(sizeof(struct bootp_pkt) - sizeof(struct iphdr));
 525        /* UDP checksum not calculated -- explicitly allowed in BOOTP RFC */
 526
 527        /* Construct BOOTP header */
 528        b->op = BOOTP_REQUEST;
 529        b->htype = dev->type;
 530        b->hlen = dev->addr_len;
 531        memcpy(b->hw_addr, dev->dev_addr, dev->addr_len);
 532        b->secs = htons(jiffies / HZ);
 533        b->xid = ic_bootp_xid;
 534        ic_bootp_init_ext(b->vendor_area);
 535
 536        /* Chain packet down the line... */
 537        skb->dev = dev;
 538        skb->protocol = __constant_htons(ETH_P_IP);
 539        if ((dev->hard_header &&
 540             dev->hard_header(skb, dev, ntohs(skb->protocol), dev->broadcast, dev->dev_addr, skb->len) < 0) ||
 541            dev_queue_xmit(skb) < 0)
 542                printk("E");
 543}
 544
 545
 546/*
 547 *  Send BOOTP requests to all interfaces.
 548 */
 549static void __init ic_bootp_send(u32 jiffies)
 550{
 551        struct ic_device *d;
 552
 553        for(d=ic_first_dev; d; d=d->next)
 554                if (d->able & IC_BOOTP)
 555                        ic_bootp_send_if(d, jiffies);
 556}
 557
 558
 559/*
 560 *  Copy BOOTP-supplied string if not already set.
 561 */
 562static int __init ic_bootp_string(char *dest, char *src, int len, int max)
 563{
 564        if (!len)
 565                return 0;
 566        if (len > max-1)
 567                len = max-1;
 568        strncpy(dest, src, len);
 569        dest[len] = '\0';
 570        return 1;
 571}
 572
 573
 574/*
 575 *  Process BOOTP extension.
 576 */
 577static void __init ic_do_bootp_ext(u8 *ext)
 578{
 579#ifdef IPCONFIG_DEBUG
 580        u8 *c;
 581
 582        printk("BOOTP: Got extension %02x",*ext);
 583        for(c=ext+2; c<ext+2+ext[1]; c++)
 584                printk(" %02x", *c);
 585        printk("\n");
 586#endif
 587
 588        switch (*ext++) {
 589                case 1:         /* Subnet mask */
 590                        if (ic_netmask == INADDR_NONE)
 591                                memcpy(&ic_netmask, ext+1, 4);
 592                        break;
 593                case 3:         /* Default gateway */
 594                        if (ic_gateway == INADDR_NONE)
 595                                memcpy(&ic_gateway, ext+1, 4);
 596                        break;
 597                case 12:        /* Host name */
 598                        ic_bootp_string(system_utsname.nodename, ext+1, *ext, __NEW_UTS_LEN);
 599                        ic_host_name_set = 1;
 600                        break;
 601                case 40:        /* NIS Domain name */
 602                        ic_bootp_string(system_utsname.domainname, ext+1, *ext, __NEW_UTS_LEN);
 603                        break;
 604                case 17:        /* Root path */
 605                        if (!root_server_path[0])
 606                                ic_bootp_string(root_server_path, ext+1, *ext, sizeof(root_server_path));
 607                        break;
 608        }
 609}
 610
 611
 612/*
 613 *  Receive BOOTP reply.
 614 */
 615static int __init ic_bootp_recv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
 616{
 617        struct bootp_pkt *b = (struct bootp_pkt *) skb->nh.iph;
 618        struct iphdr *h = &b->iph;
 619        int len;
 620
 621        /* If we already have a reply, just drop the packet */
 622        if (ic_got_reply)
 623                goto drop;
 624
 625        /* Check whether it's a BOOTP packet */
 626        if (skb->pkt_type == PACKET_OTHERHOST ||
 627            skb->len < sizeof(struct udphdr) + sizeof(struct iphdr) ||
 628            h->ihl != 5 ||
 629            h->version != 4 ||
 630            ip_fast_csum((char *) h, h->ihl) != 0 ||
 631            skb->len < ntohs(h->tot_len) ||
 632            h->protocol != IPPROTO_UDP ||
 633            b->udph.source != htons(67) ||
 634            b->udph.dest != htons(68) ||
 635            ntohs(h->tot_len) < ntohs(b->udph.len) + sizeof(struct iphdr))
 636                goto drop;
 637
 638        /* Fragments are not supported */
 639        if (h->frag_off & htons(IP_OFFSET|IP_MF)) {
 640                printk(KERN_ERR "BOOTP: Ignoring fragmented reply.\n");
 641                goto drop;
 642        }
 643
 644        /* Is it a reply to our BOOTP request? */
 645        len = ntohs(b->udph.len) - sizeof(struct udphdr);
 646        if (len < 300 ||                                    /* See RFC 951:2.1 */
 647            b->op != BOOTP_REPLY ||
 648            b->xid != ic_bootp_xid) {
 649                printk("?");
 650                goto drop;
 651        }
 652
 653        /* Extract basic fields */
 654        ic_myaddr = b->your_ip;
 655        ic_servaddr = b->server_ip;
 656        ic_got_reply = IC_BOOTP;
 657        ic_dev = dev;
 658
 659        /* Parse extensions */
 660        if (b->vendor_area[0] == 99 &&  /* Check magic cookie */
 661            b->vendor_area[1] == 130 &&
 662            b->vendor_area[2] == 83 &&
 663            b->vendor_area[3] == 99) {
 664                u8 *ext = &b->vendor_area[4];
 665                u8 *end = (u8 *) b + len;
 666                while (ext < end && *ext != 0xff) {
 667                        if (*ext == 0)          /* Padding */
 668                                ext++;
 669                        else {
 670                                u8 *opt = ext;
 671                                ext += ext[1] + 2;
 672                                if (ext <= end)
 673                                        ic_do_bootp_ext(opt);
 674                        }
 675                }
 676        }
 677
 678        if (ic_gateway == INADDR_NONE && b->relay_ip)
 679                ic_gateway = b->relay_ip;
 680
 681drop:
 682        kfree_skb(skb);
 683        return 0;
 684}       
 685
 686
 687#endif
 688
 689
 690/*
 691 *      Dynamic IP configuration -- BOOTP and RARP.
 692 */
 693
 694#ifdef CONFIG_IP_PNP_DYNAMIC
 695
 696static int __init ic_dynamic(void)
 697{
 698        int retries;
 699        unsigned long timeout, jiff;
 700        unsigned long start_jiffies;
 701        int do_rarp = ic_proto_have_if & IC_RARP;
 702        int do_bootp = ic_proto_have_if & IC_BOOTP;
 703
 704        /*
 705         * If neither BOOTP nor RARP was selected, return with an error. This
 706         * routine gets only called when some pieces of information are mis-
 707         * sing, and without BOOTP and RARP we are not able to get that in-
 708         * formation.
 709         */
 710        if (!ic_proto_enabled) {
 711                printk(KERN_ERR "IP-Config: Incomplete network configuration information.\n");
 712                return -1;
 713        }
 714
 715#ifdef CONFIG_IP_PNP_BOOTP
 716        if ((ic_proto_enabled ^ ic_proto_have_if) & IC_BOOTP)
 717                printk(KERN_ERR "BOOTP: No suitable device found.\n");
 718#endif
 719
 720#ifdef CONFIG_IP_PNP_RARP
 721        if ((ic_proto_enabled ^ ic_proto_have_if) & IC_RARP)
 722                printk(KERN_ERR "RARP: No suitable device found.\n");
 723#endif
 724
 725        if (!ic_proto_have_if)
 726                /* Error message already printed */
 727                return -1;
 728
 729        /*
 730         * Setup RARP and BOOTP protocols
 731         */
 732#ifdef CONFIG_IP_PNP_RARP
 733        if (do_rarp)
 734                ic_rarp_init();
 735#endif
 736#ifdef CONFIG_IP_PNP_BOOTP
 737        if (do_bootp)
 738                ic_bootp_init();
 739#endif
 740
 741        /*
 742         * Send requests and wait, until we get an answer. This loop
 743         * seems to be a terrible waste of CPU time, but actually there is
 744         * only one process running at all, so we don't need to use any
 745         * scheduler functions.
 746         * [Actually we could now, but the nothing else running note still 
 747         *  applies.. - AC]
 748         */
 749        printk(KERN_NOTICE "Sending %s%s%s requests...",
 750                do_bootp ? "BOOTP" : "",
 751                do_bootp && do_rarp ? " and " : "",
 752                do_rarp ? "RARP" : "");
 753        start_jiffies = jiffies;
 754        retries = CONF_RETRIES;
 755        get_random_bytes(&timeout, sizeof(timeout));
 756        timeout = CONF_BASE_TIMEOUT + (timeout % (unsigned) CONF_TIMEOUT_RANDOM);
 757        for(;;) {
 758#ifdef CONFIG_IP_PNP_BOOTP
 759                if (do_bootp)
 760                        ic_bootp_send(jiffies - start_jiffies);
 761#endif
 762#ifdef CONFIG_IP_PNP_RARP
 763                if (do_rarp)
 764                        ic_rarp_send();
 765#endif
 766                printk(".");
 767                jiff = jiffies + timeout;
 768                while (jiffies < jiff && !ic_got_reply)
 769                        ;
 770                if (ic_got_reply) {
 771                        printk(" OK\n");
 772                        break;
 773                }
 774                if (! --retries) {
 775                        printk(" timed out!\n");
 776                        break;
 777                }
 778                timeout = timeout CONF_TIMEOUT_MULT;
 779                if (timeout > CONF_TIMEOUT_MAX)
 780                        timeout = CONF_TIMEOUT_MAX;
 781        }
 782
 783#ifdef CONFIG_IP_PNP_RARP
 784        if (do_rarp)
 785                ic_rarp_cleanup();
 786#endif
 787#ifdef CONFIG_IP_PNP_BOOTP
 788        if (do_bootp)
 789                ic_bootp_cleanup();
 790#endif
 791
 792        if (!ic_got_reply)
 793                return -1;
 794
 795        printk("IP-Config: Got %s answer from %s, ",
 796                (ic_got_reply & IC_BOOTP) ? "BOOTP" : "RARP",
 797                in_ntoa(ic_servaddr));
 798        printk("my address is %s\n", in_ntoa(ic_myaddr));
 799
 800        return 0;
 801}
 802
 803#endif
 804
 805/*
 806 *      IP Autoconfig dispatcher.
 807 */
 808
 809int __init ip_auto_config(void)
 810{
 811        if (!ic_enable)
 812                return 0;
 813
 814        DBG(("IP-Config: Entered.\n"));
 815
 816        /* Setup all network devices */
 817        if (ic_open_devs() < 0)
 818                return -1;
 819
 820        /*
 821         * If the config information is insufficient (e.g., our IP address or
 822         * IP address of the boot server is missing or we have multiple network
 823         * interfaces and no default was set), use BOOTP or RARP to get the
 824         * missing values.
 825         */
 826        if (ic_myaddr == INADDR_NONE ||
 827#ifdef CONFIG_ROOT_NFS
 828            (root_server_addr == INADDR_NONE && ic_servaddr == INADDR_NONE) ||
 829#endif
 830            ic_first_dev->next) {
 831#ifdef CONFIG_IP_PNP_DYNAMIC
 832                if (ic_dynamic() < 0) {
 833                        printk(KERN_ERR "IP-Config: Auto-configuration of network failed.\n");
 834                        ic_close_devs();
 835                        return -1;
 836                }
 837#else
 838                printk(KERN_ERR "IP-Config: Incomplete network configuration information.\n");
 839                ic_close_devs();
 840                return -1;
 841#endif
 842        } else {
 843                ic_dev = ic_first_dev->dev;     /* Device selected manually or only one device -> use it */
 844        }
 845
 846        /*
 847         * Use defaults whereever applicable.
 848         */
 849        if (ic_defaults() < 0)
 850                return -1;
 851
 852        /*
 853         * Close all network devices except the device we've
 854         * autoconfigured and set up routes.
 855         */
 856        ic_close_devs();
 857        if (ic_setup_if() < 0 || ic_setup_routes() < 0)
 858                return -1;
 859
 860        DBG(("IP-Config: device=%s, local=%08x, server=%08x, boot=%08x, gw=%08x, mask=%08x\n",
 861            ic_dev->name, ic_myaddr, ic_servaddr, root_server_addr, ic_gateway, ic_netmask));
 862        DBG(("IP-Config: host=%s, domain=%s, path=`%s'\n", system_utsname.nodename,
 863            system_utsname.domainname, root_server_path));
 864        return 0;
 865}
 866
 867/*
 868 *  Decode any IP configuration options in the "ip=" or "nfsaddrs=" kernel
 869 *  command line parameter. It consists of option fields separated by colons in
 870 *  the following order:
 871 *
 872 *  <client-ip>:<server-ip>:<gw-ip>:<netmask>:<host name>:<device>:<bootp|rarp>
 873 *
 874 *  Any of the fields can be empty which means to use a default value:
 875 *      <client-ip>     - address given by BOOTP or RARP
 876 *      <server-ip>     - address of host returning BOOTP or RARP packet
 877 *      <gw-ip>         - none, or the address returned by BOOTP
 878 *      <netmask>       - automatically determined from <client-ip>, or the
 879 *                        one returned by BOOTP
 880 *      <host name>     - <client-ip> in ASCII notation, or the name returned
 881 *                        by BOOTP
 882 *      <device>        - use all available devices
 883 *      <bootp|rarp|both|off> - use both protocols to determine my own address
 884 */
 885static int __init ic_proto_name(char *name)
 886{
 887        if (!strcmp(name, "off")) {
 888                ic_proto_enabled = 0;
 889                return 1;
 890        }
 891#ifdef CONFIG_IP_PNP_BOOTP
 892        else if (!strcmp(name, "bootp")) {
 893                ic_proto_enabled &= ~IC_RARP;
 894                return 1;
 895        }
 896#endif
 897#ifdef CONFIG_IP_PNP_RARP
 898        else if (!strcmp(name, "rarp")) {
 899                ic_proto_enabled &= ~IC_BOOTP;
 900                return 1;
 901        }
 902#endif
 903#ifdef CONFIG_IP_PNP_DYNAMIC
 904        else if (!strcmp(name, "both")) {
 905                return 1;
 906        }
 907#endif
 908        return 0;
 909}
 910
 911void __init ip_auto_config_setup(char *addrs, int *ints)
 912{
 913        char *cp, *ip, *dp;
 914        int num = 0;
 915
 916        ic_set_manually = 1;
 917        if (!strcmp(addrs, "off")) {
 918                ic_enable = 0;
 919                return;
 920        }
 921        if (ic_proto_name(addrs))
 922                return;
 923
 924        /* Parse the whole string */
 925        ip = addrs;
 926        while (ip && *ip) {
 927                if ((cp = strchr(ip, ':')))
 928                        *cp++ = '\0';
 929                if (strlen(ip) > 0) {
 930                        DBG(("IP-Config: Parameter #%d: `%s'\n", num, ip));
 931                        switch (num) {
 932                        case 0:
 933                                if ((ic_myaddr = in_aton(ip)) == INADDR_ANY)
 934                                        ic_myaddr = INADDR_NONE;
 935                                break;
 936                        case 1:
 937                                if ((ic_servaddr = in_aton(ip)) == INADDR_ANY)
 938                                        ic_servaddr = INADDR_NONE;
 939                                break;
 940                        case 2:
 941                                if ((ic_gateway = in_aton(ip)) == INADDR_ANY)
 942                                        ic_gateway = INADDR_NONE;
 943                                break;
 944                        case 3:
 945                                if ((ic_netmask = in_aton(ip)) == INADDR_ANY)
 946                                        ic_netmask = INADDR_NONE;
 947                                break;
 948                        case 4:
 949                                if ((dp = strchr(ip, '.'))) {
 950                                        *dp++ = '\0';
 951                                        strncpy(system_utsname.domainname, dp, __NEW_UTS_LEN);
 952                                        system_utsname.domainname[__NEW_UTS_LEN] = '\0';
 953                                }
 954                                strncpy(system_utsname.nodename, ip, __NEW_UTS_LEN);
 955                                system_utsname.nodename[__NEW_UTS_LEN] = '\0';
 956                                ic_host_name_set = 1;
 957                                break;
 958                        case 5:
 959                                strncpy(user_dev_name, ip, IFNAMSIZ);
 960                                user_dev_name[IFNAMSIZ-1] = '\0';
 961                                break;
 962                        case 6:
 963                                ic_proto_name(ip);
 964                                break;
 965                        }
 966                }
 967                ip = cp;
 968                num++;
 969        }
 970}
 971
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.