[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