#include <linux/seq_file.h>
#include <linux/major.h>
#include <linux/root_dev.h>
+#include <linux/delay.h>
#include <net/arp.h>
#include <net/ip.h>
#include <net/ipconfig.h>
#endif
/* Define the friendly delay before and after opening net devices */
-#define CONF_PRE_OPEN (HZ/2) /* Before opening: 1/2 second */
-#define CONF_POST_OPEN (1*HZ) /* After opening: 1 second */
+#define CONF_PRE_OPEN 500 /* Before opening: 1/2 second */
+#define CONF_POST_OPEN 1 /* After opening: 1 second */
/* Define the timeout for waiting for a DHCP/BOOTP/RARP reply */
#define CONF_OPEN_RETRIES 2 /* (Re)open devices twice */
*/
int ic_set_manually __initdata = 0; /* IPconfig parameters set manually */
-int ic_enable __initdata = 0; /* IP config enabled? */
+static int ic_enable __initdata = 0; /* IP config enabled? */
/* Protocol choice */
int ic_proto_enabled __initdata = 0
#endif
;
-int ic_host_name_set __initdata = 0; /* Host name set by us? */
+static int ic_host_name_set __initdata = 0; /* Host name set by us? */
u32 ic_myaddr = INADDR_NONE; /* My IP address */
-u32 ic_netmask = INADDR_NONE; /* Netmask for local subnet */
+static u32 ic_netmask = INADDR_NONE; /* Netmask for local subnet */
u32 ic_gateway = INADDR_NONE; /* Gateway IP address */
u32 ic_servaddr = INADDR_NONE; /* Boot server IP address */
/* Persistent data: */
-int ic_proto_used; /* Protocol used, if any */
-u32 ic_nameservers[CONF_NAMESERVERS_MAX]; /* DNS Server IP addresses */
-u8 ic_domain[64]; /* DNS (not NIS) domain name */
+static int ic_proto_used; /* Protocol used, if any */
+static u32 ic_nameservers[CONF_NAMESERVERS_MAX]; /* DNS Server IP addresses */
+static u8 ic_domain[64]; /* DNS (not NIS) domain name */
/*
* Private state.
static int ic_proto_have_if __initdata = 0;
#ifdef IPCONFIG_DYNAMIC
-static spinlock_t ic_recv_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(ic_recv_lock);
static volatile int ic_got_reply __initdata = 0; /* Proto(s) that replied */
#endif
#ifdef IPCONFIG_DHCP
last = &ic_first_dev;
rtnl_shlock();
+
+ /* bring loopback device up first */
+ if (dev_change_flags(&loopback_dev, loopback_dev.flags | IFF_UP) < 0)
+ printk(KERN_ERR "IP-Config: Failed to open %s\n", loopback_dev.name);
+
for (dev = dev_base; dev; dev = dev->next) {
+ if (dev == &loopback_dev)
+ continue;
if (user_dev_name[0] ? !strcmp(dev->name, user_dev_name) :
(!(dev->flags & IFF_LOOPBACK) &&
(dev->flags & (IFF_POINTOPOINT|IFF_BROADCAST)) &&
mm_segment_t oldfs = get_fs();
set_fs(get_ds());
- res = devinet_ioctl(cmd, arg);
+ res = devinet_ioctl(cmd, (struct ifreq __user *) arg);
set_fs(oldfs);
return res;
}
mm_segment_t oldfs = get_fs();
set_fs(get_ds());
- res = ip_rt_ioctl(cmd, arg);
+ res = ip_rt_ioctl(cmd, (void __user *) arg);
set_fs(oldfs);
return res;
}
b->htype = dev->type;
else if (dev->type == ARPHRD_IEEE802_TR) /* fix for token ring */
b->htype = ARPHRD_IEEE802;
+ else if (dev->type == ARPHRD_FDDI)
+ b->htype = ARPHRD_ETHER;
else {
printk("Unknown ARP type 0x%04x for device %s\n", dev->type, dev->name);
b->htype = dev->type; /* can cause undefined behavior */
struct bootp_pkt *b;
struct iphdr *h;
struct ic_device *d;
- int len;
+ int len, ext_len;
/* Perform verifications before taking the lock. */
if (skb->pkt_type == PACKET_OTHERHOST)
goto drop;
len = ntohs(b->udph.len) - sizeof(struct udphdr);
- if (len < 300)
+ ext_len = len - (sizeof(*b) -
+ sizeof(struct iphdr) -
+ sizeof(struct udphdr) -
+ sizeof(b->exten));
+ if (ext_len < 0)
goto drop;
/* Ok the front looks good, make sure we can get at the rest. */
}
/* Parse extensions */
- if (!memcmp(b->exten, ic_bootp_cookie, 4)) { /* Check magic cookie */
+ if (ext_len >= 4 &&
+ !memcmp(b->exten, ic_bootp_cookie, 4)) { /* Check magic cookie */
u8 *end = (u8 *) b + ntohs(b->iph.tot_len);
u8 *ext;
break;
case DHCPACK:
+ if (memcmp(dev->dev_addr, b->hw_addr, dev->addr_len) != 0)
+ goto drop_unlock;
+
/* Yeah! */
break;
jiff = jiffies + (d->next ? CONF_INTER_TIMEOUT : timeout);
while (time_before(jiffies, jiff) && !ic_got_reply) {
- barrier();
- cpu_relax();
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(1);
}
#ifdef IPCONFIG_DHCP
/* DHCP isn't done until we get a DHCPACK. */
if (*cp == ':')
*cp++ = '\0';
addr = in_aton(name);
- strcpy(name, cp);
+ memmove(name, cp, strlen(cp) + 1);
} else
addr = INADDR_NONE;
static int __init ip_auto_config(void)
{
- unsigned long jiff;
u32 addr;
#ifdef CONFIG_PROC_FS
try_try_again:
#endif
/* Give hardware a chance to settle */
- jiff = jiffies + CONF_PRE_OPEN;
- while (time_before(jiffies, jiff))
- cpu_relax();
+ msleep(CONF_PRE_OPEN);
/* Setup all network devices */
if (ic_open_devs() < 0)
return -1;
/* Give drivers a chance to settle */
- jiff = jiffies + CONF_POST_OPEN;
- while (time_before(jiffies, jiff))
- cpu_relax();
+ ssleep(CONF_POST_OPEN);
/*
* If the config information is insufficient (e.g., our IP address or