Dirk von Suchodoletz
2004-May-28 07:44 UTC
[klibc] ipconfig related question (do not get static IP setting)
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) into kernel command line ... I checked the mailing list archive, but did not find additional information on the tools usage (checked the README from Russell King (2002/10/22) / Bryan O'Sullivan) :-( ipconfig -c dhcp -d eth0" or "ipconfig -c any eth0" work pretty well. It gets a dhcp reply and configures the interface correctly. But unfortunately our dhcp setup is more sophisticated. We run more than one dhcp server in a subnet - both linux and windows (completely independent). We distinguish clients and servers by vendor code identifiers and not simply by MAC. The clients could boot windows or linux alternatively ... Thatswhy I would like to use the fixed IP address assignment (via PXE or Etherboot), but ipconfig 10.8.4.204:10.8.4.254:10.8.4.254:255.255.255.0 or ipconfig 10.8.4.204:10.8.4.254:10.8.4.254:255.255.255.0:: or ipconfig -c none eth0 10.8.4.204:10.8.4.254:10.8.4.254:255.255.255.0 ipconfig -c none eth0 10.8.4.204:10.8.4.254:10.8.4.254:255.255.255.0:eth0:none ipconfig eth0 10.8.4.204::::: or similar tests and tries does not succeed :-( If you could give me a hint whats wrong with my commandlines!? Thank you very much!! Dirk
Olaf Hering
2004-May-31 00:46 UTC
[klibc] ipconfig related question (do not get static IP setting)
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