00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
#include <linux/config.h>
00035
#include <linux/types.h>
00036
#include <linux/string.h>
00037
#include <linux/kernel.h>
00038
#include <linux/sched.h>
00039
#include <linux/random.h>
00040
#include <linux/init.h>
00041
#include <linux/utsname.h>
00042
#include <linux/in.h>
00043
#include <linux/if.h>
00044
#include <linux/inet.h>
00045
#include <linux/netdevice.h>
00046
#include <linux/if_arp.h>
00047
#include <linux/skbuff.h>
00048
#include <linux/ip.h>
00049
#include <linux/socket.h>
00050
#include <linux/route.h>
00051
#include <linux/udp.h>
00052
#include <linux/proc_fs.h>
00053
#include <linux/major.h>
00054
#include <net/arp.h>
00055
#include <net/ip.h>
00056
#include <net/ipconfig.h>
00057
00058
#include <asm/uaccess.h>
00059
#include <asm/checksum.h>
00060
#include <asm/processor.h>
00061
00062
00063
#undef IPCONFIG_DEBUG
00064
00065
#ifdef IPCONFIG_DEBUG
00066
#define DBG(x) printk x
00067
#else
00068 #define DBG(x) do { } while(0)
00069
#endif
00070
00071
#if defined(CONFIG_IP_PNP_DHCP)
00072
#define IPCONFIG_DHCP
00073
#endif
00074
#if defined(CONFIG_IP_PNP_BOOTP) || defined(CONFIG_IP_PNP_DHCP)
00075
#define IPCONFIG_BOOTP
00076
#endif
00077
#if defined(CONFIG_IP_PNP_RARP)
00078
#define IPCONFIG_RARP
00079
#endif
00080
#if defined(IPCONFIG_BOOTP) || defined(IPCONFIG_RARP)
00081
#define IPCONFIG_DYNAMIC
00082
#endif
00083
00084
00085 #define CONF_PRE_OPEN (HZ/2)
00086 #define CONF_POST_OPEN (1*HZ)
00087
00088
00089 #define CONF_OPEN_RETRIES 2
00090 #define CONF_SEND_RETRIES 6
00091 #define CONF_INTER_TIMEOUT (HZ/2)
00092 #define CONF_BASE_TIMEOUT (HZ*2)
00093 #define CONF_TIMEOUT_RANDOM (HZ)
00094 #define CONF_TIMEOUT_MULT *7/4
00095 #define CONF_TIMEOUT_MAX (HZ*30)
00096 #define CONF_NAMESERVERS_MAX 3
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
int ic_set_manually __initdata = 0;
00109
00110
int ic_enable __initdata = 0;
00111
00112
00113
int ic_proto_enabled __initdata = 0
00114
#ifdef IPCONFIG_BOOTP
00115
|
IC_BOOTP
00116
#endif
00117
#ifdef CONFIG_IP_PNP_DHCP
00118
|
IC_USE_DHCP
00119
#endif
00120
#ifdef IPCONFIG_RARP
00121
|
IC_RARP
00122
#endif
00123
;
00124
00125
int ic_host_name_set __initdata = 0;
00126
00127 u32
ic_myaddr =
INADDR_NONE;
00128 u32
ic_netmask =
INADDR_NONE;
00129 u32
ic_gateway =
INADDR_NONE;
00130
00131 u32
ic_servaddr =
INADDR_NONE;
00132
00133 u32
root_server_addr =
INADDR_NONE;
00134 u8
root_server_path[256] = { 0, };
00135
00136
00137
00138 int ic_proto_used;
00139 u32
ic_nameservers[
CONF_NAMESERVERS_MAX];
00140 u8
ic_domain[64];
00141
00142
00143
00144
00145
00146
00147
static char user_dev_name[IFNAMSIZ]
__initdata = { 0, };
00148
00149
00150
static int ic_proto_have_if
__initdata = 0;
00151
00152
#ifdef IPCONFIG_DYNAMIC
00153
static spinlock_t ic_recv_lock = SPIN_LOCK_UNLOCKED;
00154
static volatile int ic_got_reply
__initdata = 0;
00155
#endif
00156
#ifdef IPCONFIG_DHCP
00157
static int ic_dhcp_msgtype
__initdata = 0;
00158
#endif
00159
00160
00161
00162
00163
00164
00165 struct ic_device {
00166 struct ic_device *
next;
00167 struct net_device *
dev;
00168 unsigned short flags;
00169 short able;
00170 u32
xid;
00171 };
00172
00173
static struct ic_device *ic_first_dev
__initdata = NULL;
00174 static struct net_device *ic_dev
__initdata = NULL;
00175
00176 static int __init
ic_open_devs(
void)
00177 {
00178
struct ic_device *d, **last;
00179
struct net_device *dev;
00180
unsigned short oflags;
00181
00182 last = &ic_first_dev;
00183 rtnl_shlock();
00184
for (dev =
dev_base; dev; dev = dev->
next) {
00185
if (user_dev_name[0] ? !strcmp(dev->name, user_dev_name) :
00186 (!(dev->flags & IFF_LOOPBACK) &&
00187 (dev->flags & (IFF_POINTOPOINT|IFF_BROADCAST)) &&
00188 strncmp(dev->name,
"dummy", 5))) {
00189
int able = 0;
00190
if (dev->mtu >= 364)
00191 able |=
IC_BOOTP;
00192
else
00193 printk(KERN_WARNING
"DHCP/BOOTP: Ignoring device %s, MTU %d too small", dev->name, dev->mtu);
00194
if (!(dev->flags & IFF_NOARP))
00195 able |=
IC_RARP;
00196 able &=
ic_proto_enabled;
00197
if (
ic_proto_enabled && !able)
00198
continue;
00199 oflags = dev->flags;
00200
if (
dev_change_flags(dev, oflags | IFF_UP) < 0) {
00201 printk(KERN_ERR
"IP-Config: Failed to open %s\n", dev->name);
00202
continue;
00203 }
00204
if (!(d = kmalloc(
sizeof(
struct ic_device), GFP_KERNEL))) {
00205 rtnl_shunlock();
00206
return -1;
00207 }
00208 d->dev = dev;
00209 *last = d;
00210 last = &d->next;
00211 d->flags = oflags;
00212 d->able = able;
00213
if (able &
IC_BOOTP)
00214 get_random_bytes(&d->xid,
sizeof(u32));
00215
else
00216 d->xid = 0;
00217 ic_proto_have_if |= able;
00218
DBG((
"IP-Config: %s UP (able=%d, xid=%08x)\n",
00219 dev->name, able, d->xid));
00220 }
00221 }
00222 rtnl_shunlock();
00223
00224 *last = NULL;
00225
00226
if (!ic_first_dev) {
00227
if (user_dev_name[0])
00228 printk(KERN_ERR
"IP-Config: Device `%s' not found.\n", user_dev_name);
00229
else
00230 printk(KERN_ERR
"IP-Config: No network devices available.\n");
00231
return -1;
00232 }
00233
return 0;
00234 }
00235
00236 static void __init
ic_close_devs(
void)
00237 {
00238
struct ic_device *d, *next;
00239
struct net_device *dev;
00240
00241 rtnl_shlock();
00242 next = ic_first_dev;
00243
while ((d = next)) {
00244 next = d->next;
00245 dev = d->dev;
00246
if (dev != ic_dev) {
00247
DBG((
"IP-Config: Downing %s\n", dev->name));
00248
dev_change_flags(dev, d->flags);
00249 }
00250 kfree(d);
00251 }
00252 rtnl_shunlock();
00253 }
00254
00255
00256
00257
00258
00259
static inline void
00260 set_sockaddr(
struct sockaddr_in *sin, u32 addr, u16 port)
00261 {
00262 sin->
sin_family = AF_INET;
00263 sin->
sin_addr.
s_addr = addr;
00264 sin->
sin_port = port;
00265 }
00266
00267 static int __init
ic_dev_ioctl(
unsigned int cmd,
struct ifreq *arg)
00268 {
00269
int res;
00270
00271 mm_segment_t oldfs = get_fs();
00272 set_fs(get_ds());
00273 res =
devinet_ioctl(cmd, arg);
00274 set_fs(oldfs);
00275
return res;
00276 }
00277
00278 static int __init
ic_route_ioctl(
unsigned int cmd,
struct rtentry *arg)
00279 {
00280
int res;
00281
00282 mm_segment_t oldfs = get_fs();
00283 set_fs(get_ds());
00284 res =
ip_rt_ioctl(cmd, arg);
00285 set_fs(oldfs);
00286
return res;
00287 }
00288
00289
00290
00291
00292
00293 static int __init
ic_setup_if(
void)
00294 {
00295
struct ifreq ir;
00296
struct sockaddr_in *sin = (
void *) &ir.ifr_ifru.ifru_addr;
00297
int err;
00298
00299 memset(&ir, 0,
sizeof(ir));
00300 strcpy(ir.ifr_ifrn.ifrn_name, ic_dev->name);
00301
set_sockaddr(sin,
ic_myaddr, 0);
00302
if ((err =
ic_dev_ioctl(SIOCSIFADDR, &ir)) < 0) {
00303 printk(KERN_ERR
"IP-Config: Unable to set interface address (%d).\n", err);
00304
return -1;
00305 }
00306
set_sockaddr(sin,
ic_netmask, 0);
00307
if ((err =
ic_dev_ioctl(SIOCSIFNETMASK, &ir)) < 0) {
00308 printk(KERN_ERR
"IP-Config: Unable to set interface netmask (%d).\n", err);
00309
return -1;
00310 }
00311
set_sockaddr(sin,
ic_myaddr | ~
ic_netmask, 0);
00312
if ((err =
ic_dev_ioctl(SIOCSIFBRDADDR, &ir)) < 0) {
00313 printk(KERN_ERR
"IP-Config: Unable to set interface broadcast address (%d).\n", err);
00314
return -1;
00315 }
00316
return 0;
00317 }
00318
00319 static int __init
ic_setup_routes(
void)
00320 {
00321
00322
00323
if (
ic_gateway !=
INADDR_NONE) {
00324
struct rtentry rm;
00325
int err;
00326
00327 memset(&rm, 0,
sizeof(rm));
00328
if ((
ic_gateway ^
ic_myaddr) &
ic_netmask) {
00329 printk(KERN_ERR
"IP-Config: Gateway not on directly connected network.\n");
00330
return -1;
00331 }
00332
set_sockaddr((
struct sockaddr_in *) &rm.rt_dst, 0, 0);
00333
set_sockaddr((
struct sockaddr_in *) &rm.rt_genmask, 0, 0);
00334
set_sockaddr((
struct sockaddr_in *) &rm.rt_gateway,
ic_gateway, 0);
00335 rm.rt_flags = RTF_UP | RTF_GATEWAY;
00336
if ((err =
ic_route_ioctl(SIOCADDRT, &rm)) < 0) {
00337 printk(KERN_ERR
"IP-Config: Cannot add default route (%d).\n", err);
00338
return -1;
00339 }
00340 }
00341
00342
return 0;
00343 }
00344
00345
00346
00347
00348
00349 static int __init
ic_defaults(
void)
00350 {
00351
00352
00353
00354
00355
00356
if (!
ic_host_name_set)
00357 sprintf(system_utsname.nodename,
"%u.%u.%u.%u", NIPQUAD(
ic_myaddr));
00358
00359
if (
root_server_addr ==
INADDR_NONE)
00360
root_server_addr =
ic_servaddr;
00361
00362
if (
ic_netmask ==
INADDR_NONE) {
00363
if (
IN_CLASSA(ntohl(
ic_myaddr)))
00364
ic_netmask = htonl(
IN_CLASSA_NET);
00365
else if (
IN_CLASSB(ntohl(
ic_myaddr)))
00366
ic_netmask = htonl(
IN_CLASSB_NET);
00367
else if (
IN_CLASSC(ntohl(
ic_myaddr)))
00368
ic_netmask = htonl(
IN_CLASSC_NET);
00369
else {
00370 printk(KERN_ERR
"IP-Config: Unable to guess netmask for address %u.%u.%u.%u\n",
00371 NIPQUAD(
ic_myaddr));
00372
return -1;
00373 }
00374 printk(
"IP-Config: Guessing netmask %u.%u.%u.%u\n", NIPQUAD(
ic_netmask));
00375 }
00376
00377
return 0;
00378 }
00379
00380
00381
00382
00383
00384
#ifdef IPCONFIG_RARP
00385
00386
static int ic_rarp_recv(
struct sk_buff *skb,
struct net_device *dev,
struct packet_type *pt);
00387
00388
static struct packet_type rarp_packet_type
__initdata = {
00389 type: __constant_htons(ETH_P_RARP),
00390 func: ic_rarp_recv,
00391 };
00392
00393
static inline void ic_rarp_init(
void)
00394 {
00395
dev_add_pack(&rarp_packet_type);
00396 }
00397
00398
static inline void ic_rarp_cleanup(
void)
00399 {
00400
dev_remove_pack(&rarp_packet_type);
00401 }
00402
00403
00404
00405
00406
static int __init
00407 ic_rarp_recv(
struct sk_buff *skb,
struct net_device *dev,
struct packet_type *pt)
00408 {
00409
struct arphdr *rarp = (
struct arphdr *)skb->
h.raw;
00410
unsigned char *rarp_ptr = (
unsigned char *) (rarp + 1);
00411
unsigned long sip, tip;
00412
unsigned char *sha, *tha;
00413
struct ic_device *d;
00414
00415
00416 spin_lock(&ic_recv_lock);
00417
00418
00419
if (ic_got_reply)
00420
goto drop;
00421
00422
00423 d = ic_first_dev;
00424
while (d && d->dev != dev)
00425 d = d->next;
00426
if (!d)
00427
goto drop;
00428
00429
00430
if (rarp->ar_hln != dev->
addr_len || dev->
type != ntohs(rarp->ar_hrd))
00431
goto drop;
00432
00433
00434
if (rarp->ar_op != htons(ARPOP_RREPLY))
00435
goto drop;
00436
00437
00438
if (rarp->ar_pro != htons(ETH_P_IP))
00439
goto drop;
00440
00441
00442 sha = rarp_ptr;
00443 rarp_ptr += dev->
addr_len;
00444 memcpy(&sip, rarp_ptr, 4);
00445 rarp_ptr += 4;
00446 tha = rarp_ptr;
00447 rarp_ptr += dev->
addr_len;
00448 memcpy(&tip, rarp_ptr, 4);
00449
00450
00451
if (memcmp(tha, dev->
dev_addr, dev->
addr_len))
00452
goto drop;
00453
00454
00455
if (
ic_servaddr !=
INADDR_NONE &&
ic_servaddr != sip)
00456
goto drop;
00457
00458
00459 ic_dev = dev;
00460
if (
ic_myaddr ==
INADDR_NONE)
00461
ic_myaddr = tip;
00462
ic_servaddr = sip;
00463 ic_got_reply =
IC_RARP;
00464
00465 drop:
00466
00467 spin_unlock(&ic_recv_lock);
00468
00469
00470
kfree_skb(skb);
00471
return 0;
00472 }
00473
00474
00475
00476
00477
00478
static void __init ic_rarp_send_if(
struct ic_device *d)
00479 {
00480
struct net_device *dev = d->
dev;
00481
arp_send(ARPOP_RREQUEST, ETH_P_RARP, 0, dev, 0, NULL,
00482 dev->dev_addr, dev->dev_addr);
00483 }
00484
#endif
00485
00486
00487
00488
00489
00490
#ifdef IPCONFIG_BOOTP
00491
00492
struct bootp_pkt {
00493
struct iphdr iph;
00494
struct udphdr udph;
00495 u8 op;
00496 u8 htype;
00497 u8 hlen;
00498 u8 hops;
00499 u32 xid;
00500 u16 secs;
00501 u16 flags;
00502 u32 client_ip;
00503 u32 your_ip;
00504 u32 server_ip;
00505 u32 relay_ip;
00506 u8 hw_addr[16];
00507 u8 serv_name[64];
00508 u8 boot_file[128];
00509 u8 exten[312];
00510 };
00511
00512
00513
#define BOOTP_REQUEST 1
00514
#define BOOTP_REPLY 2
00515
00516
00517
#define DHCPDISCOVER 1
00518
#define DHCPOFFER 2
00519
#define DHCPREQUEST 3
00520
#define DHCPDECLINE 4
00521
#define DHCPACK 5
00522
#define DHCPNAK 6
00523
#define DHCPRELEASE 7
00524
#define DHCPINFORM 8
00525
00526
static int ic_bootp_recv(
struct sk_buff *skb,
struct net_device *dev,
struct packet_type *pt);
00527
00528
static struct packet_type bootp_packet_type
__initdata = {
00529 type: __constant_htons(ETH_P_IP),
00530 func: ic_bootp_recv,
00531 };
00532
00533
00534
00535
00536
00537
00538
static const u8 ic_bootp_cookie[4] = { 99, 130, 83, 99 };
00539
00540
#ifdef IPCONFIG_DHCP
00541
00542
static void __init
00543 ic_dhcp_init_options(u8 *options)
00544 {
00545 u8 mt = ((
ic_servaddr ==
INADDR_NONE)
00546 ? DHCPDISCOVER : DHCPREQUEST);
00547 u8 *e = options;
00548
00549
#ifdef IPCONFIG_DEBUG
00550
printk(
"DHCP: Sending message type %d\n", mt);
00551
#endif
00552
00553 memcpy(e, ic_bootp_cookie, 4);
00554 e += 4;
00555
00556 *e++ = 53;
00557 *e++ = 1;
00558 *e++ = mt;
00559
00560
if (mt == DHCPREQUEST) {
00561 *e++ = 54;
00562 *e++ = 4;
00563 memcpy(e, &ic_servaddr, 4);
00564 e += 4;
00565
00566 *e++ = 50;
00567 *e++ = 4;
00568 memcpy(e, &ic_myaddr, 4);
00569 e += 4;
00570 }
00571
00572
00573 {
00574
static const u8 ic_req_params[] = {
00575 1,
00576 3,
00577 6,
00578 12,
00579 15,
00580 17,
00581 40,
00582 };
00583
00584 *e++ = 55;
00585 *e++ =
sizeof(ic_req_params);
00586 memcpy(e, ic_req_params,
sizeof(ic_req_params));
00587 e +=
sizeof(ic_req_params);
00588 }
00589
00590 *e++ = 255;
00591 }
00592
00593
#endif
00594
00595
static void __init ic_bootp_init_ext(u8 *e)
00596 {
00597 memcpy(e, ic_bootp_cookie, 4);
00598 e += 4;
00599 *e++ = 1;
00600 *e++ = 4;
00601 e += 4;
00602 *e++ = 3;
00603 *e++ = 4;
00604 e += 4;
00605 *e++ = 5;
00606 *e++ = 8;
00607 e += 8;
00608 *e++ = 12;
00609 *e++ = 32;
00610 e += 32;
00611 *e++ = 40;
00612 *e++ = 32;
00613 e += 32;
00614 *e++ = 17;
00615 *e++ = 40;
00616 e += 40;
00617
00618 *e++ = 57;
00619 *e++ = 2;
00620 *e++ = 1;
00621 *e++ = 150;
00622
00623 *e++ = 255;
00624 }
00625
00626
00627
00628
00629
00630
static inline void ic_bootp_init(
void)
00631 {
00632
int i;
00633
00634
for (i = 0; i <
CONF_NAMESERVERS_MAX; i++)
00635
ic_nameservers[i] =
INADDR_NONE;
00636
00637
dev_add_pack(&bootp_packet_type);
00638 }
00639
00640
00641
00642
00643
00644
static inline void ic_bootp_cleanup(
void)
00645 {
00646
dev_remove_pack(&bootp_packet_type);
00647 }
00648
00649
00650
00651
00652
00653
static void __init ic_bootp_send_if(
struct ic_device *d,
unsigned long jiffies_diff)
00654 {
00655
struct net_device *dev = d->
dev;
00656
struct sk_buff *skb;
00657
struct bootp_pkt *b;
00658
int hh_len = (dev->hard_header_len + 15) & ~15;
00659
struct iphdr *h;
00660
00661
00662 skb =
alloc_skb(
sizeof(
struct bootp_pkt) + hh_len + 15, GFP_KERNEL);
00663
if (!skb)
00664
return;
00665
skb_reserve(skb, hh_len);
00666 b = (
struct bootp_pkt *)
skb_put(skb,
sizeof(
struct bootp_pkt));
00667 memset(b, 0,
sizeof(
struct bootp_pkt));
00668
00669
00670 skb->nh.iph = h = &b->iph;
00671 h->version = 4;
00672 h->ihl = 5;
00673 h->tot_len = htons(
sizeof(
struct bootp_pkt));
00674 h->frag_off = htons(IP_DF);
00675 h->ttl = 64;
00676 h->protocol =
IPPROTO_UDP;
00677 h->daddr =
INADDR_BROADCAST;
00678 h->check =
ip_fast_csum((
unsigned char *) h, h->ihl);
00679
00680
00681 b->udph.source = htons(68);
00682 b->udph.dest = htons(67);
00683 b->udph.len = htons(
sizeof(
struct bootp_pkt) -
sizeof(
struct iphdr));
00684
00685
00686
00687 b->op = BOOTP_REQUEST;
00688
if (dev->type < 256)
00689 b->htype = dev->type;
00690
else if (dev->type == ARPHRD_IEEE802_TR)
00691 b->htype = ARPHRD_IEEE802;
00692
else {
00693 printk(
"Unknown ARP type 0x%04x for device %s\n", dev->type, dev->name);
00694 b->htype = dev->type;
00695 }
00696 b->hlen = dev->addr_len;
00697 b->your_ip =
INADDR_NONE;
00698 b->server_ip =
INADDR_NONE;
00699 memcpy(b->hw_addr, dev->dev_addr, dev->addr_len);
00700 b->secs = htons(jiffies_diff / HZ);
00701 b->xid = d->
xid;
00702
00703
00704
#ifdef IPCONFIG_DHCP
00705
if (
ic_proto_enabled &
IC_USE_DHCP)
00706 ic_dhcp_init_options(b->exten);
00707
else
00708
#endif
00709
ic_bootp_init_ext(b->exten);
00710
00711
00712 skb->dev = dev;
00713 skb->protocol = htons(ETH_P_IP);
00714
if ((dev->hard_header &&
00715 dev->hard_header(skb, dev, ntohs(skb->protocol), dev->broadcast, dev->dev_addr, skb->len) < 0) ||
00716
dev_queue_xmit(skb) < 0)
00717 printk(
"E");
00718 }
00719
00720
00721
00722
00723
00724
static int __init ic_bootp_string(
char *dest,
char *src,
int len,
int max)
00725 {
00726
if (!len)
00727
return 0;
00728
if (len > max-1)
00729 len = max-1;
00730 memcpy(dest, src, len);
00731 dest[len] =
'\0';
00732
return 1;
00733 }
00734
00735
00736
00737
00738
00739
static void __init ic_do_bootp_ext(u8 *ext)
00740 {
00741 u8 servers;
00742
int i;
00743
00744
#ifdef IPCONFIG_DEBUG
00745
u8 *c;
00746
00747 printk(
"DHCP/BOOTP: Got extension %d:",*ext);
00748
for(c=ext+2; c<ext+2+ext[1]; c++)
00749 printk(
" %02x", *c);
00750 printk(
"\n");
00751
#endif
00752
00753
switch (*ext++) {
00754
case 1:
00755
if (
ic_netmask ==
INADDR_NONE)
00756 memcpy(&ic_netmask, ext+1, 4);
00757
break;
00758
case 3:
00759
if (
ic_gateway ==
INADDR_NONE)
00760 memcpy(&ic_gateway, ext+1, 4);
00761
break;
00762
case 6:
00763 servers= *ext/4;
00764
if (servers >
CONF_NAMESERVERS_MAX)
00765 servers =
CONF_NAMESERVERS_MAX;
00766
for (i = 0; i < servers; i++) {
00767
if (
ic_nameservers[i] ==
INADDR_NONE)
00768 memcpy(&ic_nameservers[i], ext+1+4*i, 4);
00769 }
00770
break;
00771
case 12:
00772 ic_bootp_string(system_utsname.nodename, ext+1, *ext, __NEW_UTS_LEN);
00773
ic_host_name_set = 1;
00774
break;
00775
case 15:
00776 ic_bootp_string(ic_domain, ext+1, *ext,
sizeof(ic_domain));
00777
break;
00778
case 17:
00779
if (!
root_server_path[0])
00780 ic_bootp_string(root_server_path, ext+1, *ext,
sizeof(root_server_path));
00781
break;
00782
case 40:
00783 ic_bootp_string(system_utsname.domainname, ext+1, *ext, __NEW_UTS_LEN);
00784
break;
00785 }
00786 }
00787
00788
00789
00790
00791
00792
static int __init ic_bootp_recv(
struct sk_buff *skb,
struct net_device *dev,
struct packet_type *pt)
00793 {
00794
struct bootp_pkt *b = (
struct bootp_pkt *) skb->
nh.iph;
00795
struct iphdr *h = &b->iph;
00796
struct ic_device *d;
00797
int len;
00798
00799
00800 spin_lock(&ic_recv_lock);
00801
00802
00803
if (ic_got_reply)
00804
goto drop;
00805
00806
00807 d = ic_first_dev;
00808
while (d && d->
dev != dev)
00809 d = d->
next;
00810
if (!d)
00811
goto drop;
00812
00813
00814
if (skb->
pkt_type == PACKET_OTHERHOST ||
00815 skb->
len <
sizeof(
struct udphdr) + sizeof(struct iphdr) ||
00816 h->ihl != 5 ||
00817 h->version != 4 ||
00818
ip_fast_csum((
char *) h, h->ihl) != 0 ||
00819 skb->
len < ntohs(h->tot_len) ||
00820 h->protocol !=
IPPROTO_UDP ||
00821 b->udph.source != htons(67) ||
00822 b->udph.dest != htons(68) ||
00823 ntohs(h->tot_len) < ntohs(b->udph.len) +
sizeof(
struct iphdr))
00824 goto drop;
00825
00826
00827
if (h->frag_off & htons(IP_OFFSET | IP_MF)) {
00828 printk(KERN_ERR
"DHCP/BOOTP: Ignoring fragmented reply.\n");
00829
goto drop;
00830 }
00831
00832
00833 len = ntohs(b->udph.len) -
sizeof(
struct udphdr);
00834
if (len < 300 ||
00835 b->op != BOOTP_REPLY ||
00836 b->xid != d->
xid) {
00837 printk(
"?");
00838
goto drop;
00839 }
00840
00841
00842
if (!memcmp(b->exten, ic_bootp_cookie, 4)) {
00843 u8 *end = (u8 *) b + ntohs(b->iph.tot_len);
00844 u8 *ext;
00845
00846
#ifdef IPCONFIG_DHCP
00847
if (
ic_proto_enabled &
IC_USE_DHCP) {
00848 u32 server_id =
INADDR_NONE;
00849
int mt = 0;
00850
00851 ext = &b->exten[4];
00852
while (ext < end && *ext != 0xff) {
00853 u8 *opt = ext++;
00854
if (*opt == 0)
00855
continue;
00856 ext += *ext + 1;
00857
if (ext >= end)
00858
break;
00859
switch (*opt) {
00860
case 53:
00861
if (opt[1])
00862 mt = opt[2];
00863
break;
00864
case 54:
00865
if (opt[1] >= 4)
00866 memcpy(&server_id, opt + 2, 4);
00867
break;
00868 };
00869 }
00870
00871
#ifdef IPCONFIG_DEBUG
00872
printk(
"DHCP: Got message type %d\n", mt);
00873
#endif
00874
00875
switch (mt) {
00876
case DHCPOFFER:
00877
00878
00879
00880
if (
ic_myaddr !=
INADDR_NONE)
00881
goto drop;
00882
00883
00884
ic_myaddr = b->your_ip;
00885
ic_servaddr = server_id;
00886
#ifdef IPCONFIG_DEBUG
00887
printk(
"DHCP: Offered address %u.%u.%u.%u",
00888 NIPQUAD(ic_myaddr));
00889 printk(
" by server %u.%u.%u.%u\n",
00890 NIPQUAD(ic_servaddr));
00891
#endif
00892
00893
00894
00895
00896
if ((server_id !=
INADDR_NONE) &&
00897 (b->server_ip != server_id))
00898 b->server_ip =
ic_servaddr;
00899
break;
00900
00901
case DHCPACK:
00902
00903
break;
00904
00905
default:
00906
00907
ic_myaddr =
INADDR_NONE;
00908
ic_servaddr =
INADDR_NONE;
00909
goto drop;
00910 };
00911
00912 ic_dhcp_msgtype = mt;
00913
00914 }
00915
#endif
00916
00917 ext = &b->exten[4];
00918
while (ext < end && *ext != 0xff) {
00919 u8 *opt = ext++;
00920
if (*opt == 0)
00921
continue;
00922 ext += *ext + 1;
00923
if (ext < end)
00924 ic_do_bootp_ext(opt);
00925 }
00926 }
00927
00928
00929 ic_dev = dev;
00930
ic_myaddr = b->your_ip;
00931
ic_servaddr = b->server_ip;
00932
if (
ic_gateway ==
INADDR_NONE && b->relay_ip)
00933
ic_gateway = b->relay_ip;
00934
if (
ic_nameservers[0] ==
INADDR_NONE)
00935
ic_nameservers[0] =
ic_servaddr;
00936 ic_got_reply =
IC_BOOTP;
00937
00938 drop:
00939
00940 spin_unlock(&ic_recv_lock);
00941
00942
00943
kfree_skb(skb);
00944
00945
return 0;
00946 }
00947
00948
00949
#endif
00950
00951
00952
00953
00954
00955
00956
#ifdef IPCONFIG_DYNAMIC
00957
00958
static int __init ic_dynamic(
void)
00959 {
00960
int retries;
00961
struct ic_device *d;
00962
unsigned long start_jiffies, timeout, jiff;
00963
int do_bootp = ic_proto_have_if &
IC_BOOTP;
00964
int do_rarp = ic_proto_have_if &
IC_RARP;
00965
00966
00967
00968
00969
00970
00971
if (!
ic_proto_enabled) {
00972 printk(KERN_ERR
"IP-Config: Incomplete network configuration information.\n");
00973
return -1;
00974 }
00975
00976
#ifdef IPCONFIG_BOOTP
00977
if ((
ic_proto_enabled ^ ic_proto_have_if) &
IC_BOOTP)
00978 printk(KERN_ERR
"DHCP/BOOTP: No suitable device found.\n");
00979
#endif
00980
#ifdef IPCONFIG_RARP
00981
if ((
ic_proto_enabled ^ ic_proto_have_if) &
IC_RARP)
00982 printk(KERN_ERR
"RARP: No suitable device found.\n");
00983
#endif
00984
00985
if (!ic_proto_have_if)
00986
00987
return -1;
00988
00989
00990
00991
00992
#ifdef IPCONFIG_BOOTP
00993
if (do_bootp)
00994 ic_bootp_init();
00995
#endif
00996
#ifdef IPCONFIG_RARP
00997
if (do_rarp)
00998 ic_rarp_init();
00999
#endif
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009 printk(KERN_NOTICE
"Sending %s%s%s requests .",
01010 do_bootp
01011 ? ((ic_proto_enabled & IC_USE_DHCP) ?
"DHCP" :
"BOOTP") :
"",
01012 (do_bootp && do_rarp) ?
" and " :
"",
01013 do_rarp ?
"RARP" :
"");
01014
01015 start_jiffies = jiffies;
01016 d = ic_first_dev;
01017 retries =
CONF_SEND_RETRIES;
01018 get_random_bytes(&timeout,
sizeof(timeout));
01019 timeout =
CONF_BASE_TIMEOUT + (timeout % (
unsigned)
CONF_TIMEOUT_RANDOM);
01020
for(;;) {
01021
#ifdef IPCONFIG_BOOTP
01022
if (do_bootp && (d->
able &
IC_BOOTP))
01023 ic_bootp_send_if(d, jiffies - start_jiffies);
01024
#endif
01025
#ifdef IPCONFIG_RARP
01026
if (do_rarp && (d->
able &
IC_RARP))
01027 ic_rarp_send_if(d);
01028
#endif
01029
01030 jiff = jiffies + (d->
next ?
CONF_INTER_TIMEOUT : timeout);
01031
while (time_before(jiffies, jiff) && !ic_got_reply) {
01032 barrier();
01033 cpu_relax();
01034 }
01035
#ifdef IPCONFIG_DHCP
01036
01037
if ((ic_got_reply &
IC_BOOTP)
01038 && (
ic_proto_enabled &
IC_USE_DHCP)
01039 && ic_dhcp_msgtype != DHCPACK)
01040 {
01041 ic_got_reply = 0;
01042 printk(
",");
01043
continue;
01044 }
01045
#endif
01046
01047
if (ic_got_reply) {
01048 printk(
" OK\n");
01049
break;
01050 }
01051
01052
if ((d = d->
next))
01053
continue;
01054
01055
if (! --retries) {
01056 printk(
" timed out!\n");
01057
break;
01058 }
01059
01060 d = ic_first_dev;
01061
01062 timeout = timeout
CONF_TIMEOUT_MULT;
01063
if (timeout >
CONF_TIMEOUT_MAX)
01064 timeout =
CONF_TIMEOUT_MAX;
01065
01066 printk(
".");
01067 }
01068
01069
#ifdef IPCONFIG_BOOTP
01070
if (do_bootp)
01071 ic_bootp_cleanup();
01072
#endif
01073
#ifdef IPCONFIG_RARP
01074
if (do_rarp)
01075 ic_rarp_cleanup();
01076
#endif
01077
01078
if (!ic_got_reply)
01079
return -1;
01080
01081 printk(
"IP-Config: Got %s answer from %u.%u.%u.%u, ",
01082 ((ic_got_reply & IC_RARP) ?
"RARP"
01083 : (ic_proto_enabled & IC_USE_DHCP) ?
"DHCP" :
"BOOTP"),
01084 NIPQUAD(ic_servaddr));
01085 printk(
"my address is %u.%u.%u.%u\n", NIPQUAD(ic_myaddr));
01086
01087
return 0;
01088 }
01089
01090
#endif
01091
01092
#ifdef CONFIG_PROC_FS
01093
01094
static int pnp_get_info(
char *buffer,
char **start,
01095 off_t offset,
int length)
01096 {
01097
int len;
01098
int i;
01099
01100
if (
ic_proto_used &
IC_PROTO)
01101 sprintf(buffer,
"#PROTO: %s\n",
01102 (ic_proto_used & IC_RARP) ?
"RARP"
01103 : (ic_proto_used & IC_USE_DHCP) ?
"DHCP" :
"BOOTP");
01104
else
01105 strcpy(buffer,
"#MANUAL\n");
01106 len = strlen(buffer);
01107
01108
if (
ic_domain[0])
01109 len += sprintf(buffer + len,
01110
"domain %s\n", ic_domain);
01111
for (i = 0; i <
CONF_NAMESERVERS_MAX; i++) {
01112
if (
ic_nameservers[i] !=
INADDR_NONE)
01113 len += sprintf(buffer + len,
01114
"nameserver %u.%u.%u.%u\n",
01115 NIPQUAD(ic_nameservers[i]));
01116 }
01117
if (
ic_servaddr !=
INADDR_NONE)
01118 len += sprintf(buffer + len,
01119
"bootserver %u.%u.%u.%u\n",
01120 NIPQUAD(ic_servaddr));
01121
01122
if (offset > len)
01123 offset = len;
01124 *start = buffer + offset;
01125
01126
if (offset + length > len)
01127 length = len - offset;
01128
return length;
01129 }
01130
01131
#endif
01132
01133
01134
01135
01136
01137
01138 u32 __init
root_nfs_parse_addr(
char *name)
01139 {
01140 u32 addr;
01141
int octets = 0;
01142
char *cp, *cq;
01143
01144 cp = cq = name;
01145
while (octets < 4) {
01146
while (*cp >=
'0' && *cp <=
'9')
01147 cp++;
01148
if (cp == cq || cp - cq > 3)
01149
break;
01150
if (*cp ==
'.' || octets == 3)
01151 octets++;
01152
if (octets < 4)
01153 cp++;
01154 cq = cp;
01155 }
01156
if (octets == 4 && (*cp ==
':' || *cp ==
'\0')) {
01157
if (*cp ==
':')
01158 *cp++ =
'\0';
01159 addr =
in_aton(name);
01160 strcpy(name, cp);
01161 }
else
01162 addr =
INADDR_NONE;
01163
01164
return addr;
01165 }
01166
01167
01168
01169
01170
01171 static int __init
ip_auto_config(
void)
01172 {
01173
unsigned long jiff;
01174 u32 addr;
01175
01176
#ifdef CONFIG_PROC_FS
01177
proc_net_create(
"pnp", 0, pnp_get_info);
01178
#endif
01179
01180
if (!
ic_enable)
01181
return 0;
01182
01183
DBG((
"IP-Config: Entered.\n"));
01184
01185
#ifdef IPCONFIG_DYNAMIC
01186
try_try_again:
01187
#endif
01188
01189 jiff = jiffies +
CONF_PRE_OPEN;
01190
while (time_before(jiffies, jiff))
01191 ;
01192
01193
01194
if (
ic_open_devs() < 0)
01195
return -1;
01196
01197
01198 jiff = jiffies +
CONF_POST_OPEN;
01199
while (time_before(jiffies, jiff))
01200 ;
01201
01202
01203
01204
01205
01206
01207
01208
if (
ic_myaddr ==
INADDR_NONE ||
01209
#ifdef CONFIG_ROOT_NFS
01210
(MAJOR(ROOT_DEV) == UNNAMED_MAJOR
01211 &&
root_server_addr ==
INADDR_NONE
01212 &&
ic_servaddr ==
INADDR_NONE) ||
01213
#endif
01214
ic_first_dev->next) {
01215
#ifdef IPCONFIG_DYNAMIC
01216
01217
int retries =
CONF_OPEN_RETRIES;
01218
01219
if (ic_dynamic() < 0) {
01220
ic_close_devs();
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
#ifdef CONFIG_ROOT_NFS
01237
if (ROOT_DEV == MKDEV(NFS_MAJOR, NFS_MINOR)) {
01238 printk(KERN_ERR
01239
"IP-Config: Retrying forever (NFS root)...\n");
01240
goto try_try_again;
01241 }
01242
#endif
01243
01244
if (--retries) {
01245 printk(KERN_ERR
01246
"IP-Config: Reopening network devices...\n");
01247
goto try_try_again;
01248 }
01249
01250
01251 printk(KERN_ERR
"IP-Config: Auto-configuration of network failed.\n");
01252
return -1;
01253 }
01254
#else
01255 printk(KERN_ERR
"IP-Config: Incomplete network configuration information.\n");
01256
ic_close_devs();
01257
return -1;
01258
#endif
01259 }
else {
01260
01261 ic_dev = ic_first_dev->dev;
01262 }
01263
01264 addr =
root_nfs_parse_addr(
root_server_path);
01265
if (
root_server_addr ==
INADDR_NONE)
01266
root_server_addr = addr;
01267
01268
01269
01270
01271
if (
ic_defaults() < 0)
01272
return -1;
01273
01274
01275
01276
01277
01278
ic_close_devs();
01279
if (
ic_setup_if() < 0 ||
ic_setup_routes() < 0)
01280
return -1;
01281
01282
01283
01284
01285
#ifdef IPCONFIG_DYNAMIC
01286
ic_proto_used = ic_got_reply | (
ic_proto_enabled &
IC_USE_DHCP);
01287
#endif
01288
01289
#ifndef IPCONFIG_SILENT
01290
01291
01292
01293 printk(
"IP-Config: Complete:");
01294 printk(
"\n device=%s", ic_dev->name);
01295 printk(
", addr=%u.%u.%u.%u", NIPQUAD(
ic_myaddr));
01296 printk(
", mask=%u.%u.%u.%u", NIPQUAD(
ic_netmask));
01297 printk(
", gw=%u.%u.%u.%u", NIPQUAD(
ic_gateway));
01298 printk(
",\n host=%s, domain=%s, nis-domain=%s",
01299 system_utsname.nodename,
ic_domain, system_utsname.domainname);
01300 printk(
",\n bootserver=%u.%u.%u.%u", NIPQUAD(
ic_servaddr));
01301 printk(
", rootserver=%u.%u.%u.%u", NIPQUAD(
root_server_addr));
01302 printk(
", rootpath=%s",
root_server_path);
01303 printk(
"\n");
01304
#endif
01305
01306
return 0;
01307 }
01308
01309
module_init(ip_auto_config);
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334 static int __init
ic_proto_name(
char *name)
01335 {
01336
if (!strcmp(name,
"on") || !strcmp(name,
"any")) {
01337
return 1;
01338 }
01339
#ifdef CONFIG_IP_PNP_DHCP
01340
else if (!strcmp(name,
"dhcp")) {
01341
ic_proto_enabled &= ~
IC_RARP;
01342
return 1;
01343 }
01344
#endif
01345
#ifdef CONFIG_IP_PNP_BOOTP
01346
else if (!strcmp(name,
"bootp")) {
01347
ic_proto_enabled &= ~(
IC_RARP |
IC_USE_DHCP);
01348
return 1;
01349 }
01350
#endif
01351
#ifdef CONFIG_IP_PNP_RARP
01352
else if (!strcmp(name,
"rarp")) {
01353
ic_proto_enabled &= ~(
IC_BOOTP |
IC_USE_DHCP);
01354
return 1;
01355 }
01356
#endif
01357
#ifdef IPCONFIG_DYNAMIC
01358
else if (!strcmp(name,
"both")) {
01359
ic_proto_enabled &= ~
IC_USE_DHCP;
01360
return 1;
01361 }
01362
#endif
01363
return 0;
01364 }
01365
01366 static int __init
ip_auto_config_setup(
char *addrs)
01367 {
01368
char *cp, *ip, *dp;
01369
int num = 0;
01370
01371
ic_set_manually = 1;
01372
01373
ic_enable = (*addrs &&
01374 (strcmp(addrs,
"off") != 0) &&
01375 (strcmp(addrs,
"none") != 0));
01376
if (!
ic_enable)
01377
return 1;
01378
01379
if (
ic_proto_name(addrs))
01380
return 1;
01381
01382
01383 ip = addrs;
01384
while (ip && *ip) {
01385
if ((cp = strchr(ip,
':')))
01386 *cp++ =
'\0';
01387
if (strlen(ip) > 0) {
01388
DBG((
"IP-Config: Parameter #%d: `%s'\n", num, ip));
01389
switch (num) {
01390
case 0:
01391
if ((
ic_myaddr =
in_aton(ip)) ==
INADDR_ANY)
01392
ic_myaddr =
INADDR_NONE;
01393
break;
01394
case 1:
01395
if ((
ic_servaddr =
in_aton(ip)) ==
INADDR_ANY)
01396
ic_servaddr =
INADDR_NONE;
01397
break;
01398
case 2:
01399
if ((
ic_gateway =
in_aton(ip)) ==
INADDR_ANY)
01400
ic_gateway =
INADDR_NONE;
01401
break;
01402
case 3:
01403
if ((
ic_netmask =
in_aton(ip)) ==
INADDR_ANY)
01404
ic_netmask =
INADDR_NONE;
01405
break;
01406
case 4:
01407
if ((dp = strchr(ip,
'.'))) {
01408 *dp++ =
'\0';
01409 strncpy(system_utsname.domainname, dp, __NEW_UTS_LEN);
01410 system_utsname.domainname[__NEW_UTS_LEN] =
'\0';
01411 }
01412 strncpy(system_utsname.nodename, ip, __NEW_UTS_LEN);
01413 system_utsname.nodename[__NEW_UTS_LEN] =
'\0';
01414
ic_host_name_set = 1;
01415
break;
01416
case 5:
01417 strncpy(user_dev_name, ip, IFNAMSIZ);
01418 user_dev_name[IFNAMSIZ-1] =
'\0';
01419
break;
01420
case 6:
01421
ic_proto_name(ip);
01422
break;
01423 }
01424 }
01425 ip = cp;
01426 num++;
01427 }
01428
01429
return 1;
01430 }
01431
01432 static int __init
nfsaddrs_config_setup(
char *addrs)
01433 {
01434
return ip_auto_config_setup(addrs);
01435 }
01436
01437
__setup(
"ip=", ip_auto_config_setup);
01438
__setup(
"nfsaddrs=", nfsaddrs_config_setup);