[klibc] ipconfig related question (do not get static IP setting)

Olaf Hering olh at suse.de
Mon May 31 00:14:18 PDT 2004


 On Fri, May 28, Dirk von Suchodoletz wrote:

> 
> Hi!! I found your ipconfig stuff in the udev rpm in SuSE 9.1. I'm about to 
> setup a initramfs (pretty cool - much better than initrd) to boot linux 
> diskless clients over the net. All the tools I would need, seem to be 
> there with ipconfig/nfsmount ...
> 
> I like to use the information I get from PXE/syslinux or Etherboot 
> writing something like:
> ip=10.8.4.204:10.8.4.254:10.8.4.254:255.255.255.0:machine01 (etherboot)
> ip=10.8.4.204:10.8.4.254:10.8.4.254:255.255.255.0 (pxe/syslinux)

2.6 has a broken SIOCGIFCONF ioctl, it does only return interfaces in UP
state. So the eth0 is not seen by ipconfig, and your ip= line contains
no interface. As a result, no config happens if the interface data are
specified manually.

this simple patch uses sysfs to find the available interfaces, it adds
only ethernet links.



diff -p -purN klibc-0.116/ipconfig/README klibc-0.116.ipconfig/ipconfig/README
--- klibc-0.116/ipconfig/README	2003-05-01 21:10:35.000000000 +0200
+++ klibc-0.116.ipconfig/ipconfig/README	2004-05-30 18:44:56.000000000 +0200
@@ -32,12 +32,13 @@ An interface spec can be either short fo
 an interface (eth0 or whatever), or long form.  The long form consists
 of up to six elements, separated by colons:
 
-addr:server:gateway:netmask:interface:proto
+addr:server:gateway:netmask:hostname:interface:proto
 
 addr		the local IP address
 server		the server's IP address (doubles as DNS server)
 gateway		default gateway
 netmask		netmask
+hostname	hostname of the client
 interface	name of the interface (empty string is synonym for "all")
 proto		the autoconfig protocol to use, as outlined above
 
diff -p -purN klibc-0.116/ipconfig/main.c klibc-0.116.ipconfig/ipconfig/main.c
--- klibc-0.116/ipconfig/main.c	2003-05-06 00:15:09.000000000 +0200
+++ klibc-0.116.ipconfig/ipconfig/main.c	2004-05-25 03:03:02.000000000 +0200
@@ -9,6 +9,11 @@
 #include <stdlib.h>
 #include <time.h>
 #include <arpa/inet.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <fcntl.h>
+
+#include <linux/if_arp.h>
 
 #include "ipconfig.h"
 #include "netdev.h"
@@ -17,6 +22,7 @@
 #include "dhcp_proto.h"
 #include "packet.h"
 
+static const char sysfs_class_net[] = "/sys/class/net";
 static const char *progname;
 static char do_not_config;
 static unsigned int default_caps = CAP_DHCP | CAP_BOOTP | CAP_RARP;
@@ -427,62 +433,7 @@ static unsigned int parse_proto(const ch
 	return caps;
 }
 
-static void bringup_device(struct netdev *dev)
-{
-	if (netdev_up(dev) == 0) {
-		if (dev->caps) {
-			add_one_dev(dev);
-		} else {
-			complete_device(dev);
-		}
-	}
-}
-
-static struct netdev *add_device(const char *info);
-
-static void add_all_devices(struct netdev *template)
-{
-#define MAX_IFS 128
-	struct ifreq ifr[MAX_IFS];
-	struct ifconf ifc;
-	int fd, nif, i;
-
-	fd = packet_open();
-
-	ifc.ifc_len = sizeof(ifr);
-	ifc.ifc_req = ifr;
-
-	if (ioctl(fd, SIOCGIFCONF, &ifc) == -1) {
-		perror("SIOCGIFCONF");
-		exit(1);
-	}
-	nif = ifc.ifc_len / sizeof(ifr[0]);
-
-	for (i = 0; i < nif; i++) {
-		struct netdev *dev;
-
-		if (strcmp(ifr[i].ifr_name, "lo") == 0)
-			continue;
-		if ((dev = add_device(ifr[i].ifr_name)) == NULL)
-			continue;
-
-		if (template->ip_addr != INADDR_NONE)
-			dev->ip_addr = template->ip_addr;
-		if (template->ip_server != INADDR_NONE)
-			dev->ip_server = template->ip_server;
-		if (template->ip_gateway != INADDR_NONE)
-			dev->ip_gateway = template->ip_gateway;
-		if (template->ip_nameserver[0] != INADDR_NONE)
-			dev->ip_nameserver[0] = template->ip_nameserver[0];
-		if (template->ip_nameserver[1] != INADDR_NONE)
-			dev->ip_nameserver[1] = template->ip_nameserver[1];
-		if (template->hostname[0] != '\0')
-			strcpy(dev->hostname, template->hostname);
-		dev->caps &= template->caps;
-
-		bringup_device(dev);
-	}
-}
+static void add_all_devices(struct netdev *template);
 
 static int parse_device(struct netdev *dev, const char *ip)
 {
@@ -549,6 +500,36 @@ static int parse_device(struct netdev *d
 	return 1;
 }
 
+static void bringup_device(struct netdev *dev)
+{
+	if (netdev_up(dev) == 0) {
+		if (dev->caps) {
+			add_one_dev(dev);
+		} else {
+			complete_device(dev);
+		}
+	}
+}
+
+static void bringup_one_dev(struct netdev *template, struct netdev *dev)
+{
+		if (template->ip_addr != INADDR_NONE)
+			dev->ip_addr = template->ip_addr;
+		if (template->ip_server != INADDR_NONE)
+			dev->ip_server = template->ip_server;
+		if (template->ip_gateway != INADDR_NONE)
+			dev->ip_gateway = template->ip_gateway;
+		if (template->ip_nameserver[0] != INADDR_NONE)
+			dev->ip_nameserver[0] = template->ip_nameserver[0];
+		if (template->ip_nameserver[1] != INADDR_NONE)
+			dev->ip_nameserver[1] = template->ip_nameserver[1];
+		if (template->hostname[0] != '\0')
+			strcpy(dev->hostname, template->hostname);
+		dev->caps &= template->caps;
+
+		bringup_device(dev);
+}
+
 static struct netdev *add_device(const char *info)
 {
 	struct netdev *dev;
@@ -585,6 +566,81 @@ static struct netdev *add_device(const c
 	return NULL;
 }
 
+static int add_all_sysfs_net_devices(struct netdev *template)
+{
+	DIR *d;
+	struct dirent *de;
+	struct netdev *dev;
+	char t[PATH_MAX], p[255];
+	int i, fd;
+	unsigned long type;
+
+	d = opendir(sysfs_class_net);
+	if (!d)
+		return 0;
+
+	while((de = readdir(d)) != NULL ) {
+		if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
+			continue;
+		i = snprintf(t, PATH_MAX-1, "%s/%s/type", sysfs_class_net, de->d_name);
+		if (i < 0 || i >= PATH_MAX-1)
+			continue;
+		t[i] = '\0';
+		fd = open(t, O_RDONLY);
+		if (fd < 0) {
+			perror(t);
+			continue;
+		}
+		i = read(fd, &p, sizeof(p) - 1);
+		close(fd);
+		if (i == -1) {
+			perror(t);
+			continue;
+		}
+		p[i] = '\0';
+		type = strtoul(p, NULL, 10);
+		if (type != ARPHRD_ETHER)
+			continue;
+		if ((dev = add_device(de->d_name)) == NULL)
+			continue;
+		bringup_one_dev(template, dev);
+	}
+	closedir(d);
+	return 1;
+}
+
+static void add_all_devices(struct netdev *template)
+{
+#define MAX_IFS 128
+	struct ifreq ifr[MAX_IFS];
+	struct ifconf ifc;
+	int fd, nif, i;
+
+	if (add_all_sysfs_net_devices(template))
+		return;
+
+	fd = packet_open();
+
+	ifc.ifc_len = sizeof(ifr);
+	ifc.ifc_req = ifr;
+
+	if (ioctl(fd, SIOCGIFCONF, &ifc) == -1) {
+		perror("SIOCGIFCONF");
+		exit(1);
+	}
+	nif = ifc.ifc_len / sizeof(ifr[0]);
+
+	for (i = 0; i < nif; i++) {
+		struct netdev *dev;
+
+		if (strcmp(ifr[i].ifr_name, "lo") == 0)
+			continue;
+		if ((dev = add_device(ifr[i].ifr_name)) == NULL)
+			continue;
+		bringup_one_dev(template, dev);
+	}
+}
+
 static int check_autoconfig(void)
 {
 	int ndev = 0, nauto = 0;
-- 
USB is for mice, FireWire is for men!

sUse lINUX ag, nÜRNBERG



More information about the klibc mailing list