Browse Source

- add new combined dhcp and static netcfg

(udeb netcfg)
    - implement joey's dhcp idea
      (wait 10s and then ask if we should try
       longer)
    - move common code to netcfg-common.c
    - improve state machines

r6416
master
Gaudenz Steinlin 19 years ago
parent
commit
621989658a
  1. 14
      Makefile
  2. 12
      debian/changelog
  3. 14
      debian/control
  4. 37
      debian/rules
  5. 1012
      netcfg-common.c
  6. 178
      netcfg-dhcp.c
  7. 312
      netcfg-static.c
  8. 536
      netcfg.c
  9. 24
      netcfg.h

14
Makefile

@ -1,10 +1,10 @@
ifndef TARGETS
TARGETS=netcfg-dhcp netcfg-static
TARGETS=netcfg-dhcp netcfg-static netcfg
endif
LDOPTS=-ldebconfclient -ldebian-installer
PREFIX=$(DESTDIR)/usr/
CFLAGS=-W -Wall -Os
CFLAGS=-Wall -Os
ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS)))
CFLAGS += -g
@ -18,12 +18,12 @@ STRIP = $(STRIPTOOL) --remove-section=.note --remove-section=.comment
all: $(TARGETS)
netcfg-dhcp netcfg-static: netcfg-dhcp.c netcfg.o
$(CC) $(CFLAGS) $@.c -o $@ $(INCS) $(LDOPTS) netcfg.o
netcfg-dhcp netcfg-static netcfg: netcfg-dhcp.c netcfg-static.c netcfg.c netcfg-common.o
$(CC) $(CFLAGS) $@.c -o $@ $(INCS) $(LDOPTS) netcfg-common.o
$(STRIP) $@
netcfg.o: netcfg.c
$(CC) -c $(CFLAGS) netcfg.c -o $@ $(INCS)
netcfg-common.o: netcfg-common.c
$(CC) -c $(CFLAGS) netcfg-common.c -o $@ $(INCS)
clean:
rm -f netcfg-dhcp netcfg-static *.o
rm -f netcfg-dhcp netcfg-static netcfg *.o

12
debian/changelog

@ -8,8 +8,16 @@ netcfg (0.34) UNRELEASED; urgency=low
- Initial Hungarian translation
* Denis Barbier
- Unfuzzy French translation
-- Kenshi Muto <kmuto@debian.org> Wed, 10 Dec 2003 08:57:20 +0900
* Gaudenz Steinlin
- add new combined dhcp and static netcfg
(udeb netcfg)
- implement joey's dhcp idea
(wait 10s and then ask if we should try
longer)
- move common code to netcfg-common.c
- improve state machines
-- Gaudenz Steinlin <gaudenz@soziologie.ch> Thu, 11 Dec 2003 12:08:48 +0100
netcfg (0.33) unstable; urgency=low

14
debian/control

@ -6,9 +6,21 @@ Uploaders: David Kimdon <dwhedon@debian.org>, Tollef Fog Heen <tfheen@debian.org
Build-Depends: debhelper (>= 4.1.13), dpkg-dev (>= 1.9.0), libdebconfclient0-dev (>= 0.46), libdebian-installer4-dev, po-debconf (>= 0.5.0)
Standards-Version: 3.6.1.0
Package: netcfg
Architecture: i386 sparc alpha m68k arm powerpc mips mipsel hppa ia64
Depends: ${shlibs:Depends}, cdebconf-udeb, dhcp-client-udeb | pump-udeb | busybox-cvs-udeb | busybox-cvs-net-udeb, ethernet-card-detection
Provides: configured-network
XB-Installer-Menu-Item: 18
Description: Configure the network
To Install additional installer components or the Debian Base System over
the network, you need to configure the network in the installer. This
component will first try to configure your network with DHCP and ask
you for static network configuration if this fails. The configured
network settings will be copied to you newly installed system.
Package: netcfg-dhcp
Architecture: i386 sparc alpha m68k arm powerpc mips mipsel hppa ia64
Depends: ${shlibs:Depends}, cdebconf-udeb, ethernet-card-detection
Depends: ${shlibs:Depends}, cdebconf-udeb, dhcp-client-udeb | pump-udeb | busybox-cvs-udeb | busybox-cvs-net-udeb, ethernet-card-detection
Provides: configured-network
XB-Installer-Menu-Item: 18
Description: Configure the network via DHCP

37
debian/rules

@ -10,6 +10,7 @@ PACKAGES=$(shell dh_listpackages)
VERSION=$(shell dpkg-parsechangelog | grep ^Version: | cut -d ' ' -f 2)
ARCH=$(shell dpkg --print-architecture)
DHCP_PACKAGES=netcfg netcfg-dhcp
# This is the debhelper compatability version to use.
export DH_COMPAT=2
@ -37,7 +38,8 @@ clean:
dh_testdir
dh_testroot
rm -f build-stamp configure-stamp
rm -f debian/netcfg-dhcp.postinst debian/netcfg-static.postinst
rm -f debian/netcfg-dhcp.postinst debian/netcfg-static.postinst \
debian/netcfg.postinst
# Add here commands to clean up after the build process.
-$(MAKE) clean
@ -48,19 +50,20 @@ install: build
dh_testdir
dh_testroot
dh_clean -k
cp netcfg-dhcp debian/netcfg-dhcp.postinst
cp netcfg-static debian/netcfg-static.postinst
mkdir -p debian/netcfg-dhcp/usr/share/udhcpc
install -m755 udhcpc.default.script debian/netcfg-dhcp/usr/share/udhcpc/default.script
mkdir -p debian/netcfg-dhcp/etc/dhcp debian/netcfg-dhcp/var/dhcp
mkdir -p debian/netcfg-static/etc/network
mkdir -p debian/netcfg-dhcp/etc/network
mkdir -p debian/netcfg-dhcp/usr/lib/prebaseconfig.d
install -m 755 prebaseconfig \
debian/netcfg-dhcp/usr/lib/prebaseconfig.d/40netcfg-dhcp
mkdir -p debian/netcfg-static/usr/lib/prebaseconfig.d
install -m 755 prebaseconfig \
debian/netcfg-static/usr/lib/prebaseconfig.d/40netcfg-static
# Install files that are the same in all packages
$(foreach PACKAGE, $(PACKAGES), \
cp $(PACKAGE) debian/$(PACKAGE).postinst ; \
mkdir -p debian/$(PACKAGE)/etc/network ; \
mkdir -p debian/$(PACKAGE)/usr/lib/prebaseconfig.d ; \
install -m 755 prebaseconfig \
debian/$(PACKAGE)/usr/lib/prebaseconfig.d/40$(PACKAGE) ; )
# Install files that are in all DHCP packages
$(foreach PACKAGE, $(DHCP_PACKAGES), \
mkdir -p debian/$(PACKAGE)/usr/share/udhcpc ; \
install -m755 udhcpc.default.script debian/$(PACKAGE)/usr/share/udhcpc/default.script ; \
mkdir -p debian/$(PACKAGE)/etc/dhcp ; \
mkdir -p debian/$(PACKAGE)/var/dhcp ; )
# Build architecture-independent files here.
binary-indep: build install
@ -77,6 +80,12 @@ binary-arch: build install
>> debian/netcfg-static/DEBIAN/templates
(echo ; po2debconf debian/netcfg-common.templates )\
>> debian/netcfg-dhcp/DEBIAN/templates
(echo ; po2debconf debian/netcfg-common.templates )\
>> debian/netcfg/DEBIAN/templates
(echo ; po2debconf debian/netcfg-dhcp.templates )\
>> debian/netcfg/DEBIAN/templates
(echo ; po2debconf debian/netcfg-static.templates )\
>> debian/netcfg/DEBIAN/templates
dh_strip
dh_compress
dh_fixperms

1012
netcfg-common.c

File diff suppressed because it is too large

178
netcfg-dhcp.c

@ -34,151 +34,45 @@
#include <debian-installer.h>
#include "netcfg.h"
static u_int32_t ipaddress = 0;
static u_int32_t nameserver_array[4] = { 0 };
static struct debconfclient *client;
enum {
PUMP,
DHCLIENT,
UDHCPC
} dhcp_client = PUMP;
static char *none;
static int netcfg_get_dhcp_hostname(struct debconfclient *client, char **dhcp_hostname)
{
int ret;
debconf_input(client, "low", "netcfg/dhcp_hostname");
ret = debconf_go(client);
if (ret == 30)
return ret;
if (*dhcp_hostname) {
free(*dhcp_hostname);
*dhcp_hostname = NULL;
}
debconf_get(client, "netcfg/dhcp_hostname");
if (strcmp (client->value, "") != 0)
*dhcp_hostname = strdup(client->value);
return 0;
}
static void netcfg_write_dhcp(char *interface, char *dhcp_hostname)
{
FILE *fp;
if ((fp = file_open(INTERFACES_FILE, "a"))) {
fprintf(fp,
"\n# This entry was created during the Debian installation\n");
fprintf(fp, "auto %s\n", interface);
fprintf(fp, "iface %s inet dhcp\n", interface);
if (dhcp_hostname)
fprintf(fp, "\thostname %s\n", dhcp_hostname);
fclose(fp);
}
}
static void netcfg_activate_dhcp(struct debconfclient *client,
char *interface, char *dhcp_hostname)
{
char buf[128];
di_exec_shell_log("/sbin/ifconfig lo 127.0.0.1");
di_exec_shell_log("/sbin/modprobe af_packet");
switch (dhcp_client) {
case PUMP:
snprintf(buf, sizeof(buf), "/sbin/pump -i %s", interface);
if (dhcp_hostname)
di_snprintfcat(buf, sizeof(buf), " -h %s",
dhcp_hostname);
break;
case DHCLIENT:
snprintf(buf, sizeof(buf), "/sbin/dhclient -e %s", interface);
break;
case UDHCPC:
snprintf(buf, sizeof(buf), "/sbin/udhcpc -i %s -n",
interface);
if (dhcp_hostname)
di_snprintfcat(buf, sizeof(buf), " -H %s",
dhcp_hostname);
break;
}
if (di_exec_shell_log(buf))
netcfg_die(client);
}
int main(int argc, char *argv[])
{
char *ptr;
struct stat buf;
int num_interfaces;
char *interface = NULL, *hostname = NULL,*domain = NULL, *dhcp_hostname = NULL;
enum { BACKUP, GET_INTERFACE, GET_HOSTNAME, GET_DHCP_HOSTNAME,
QUIT } state = GET_INTERFACE;
client = debconfclient_new();
debconf_capb(client,"backup");
debconf_metaget(client, "netcfg/internal-none", "description");
none = client->value ? strdup(client->value) : strdup("<none>");
if (stat("/sbin/dhclient", &buf) == 0)
dhcp_client = DHCLIENT;
else if (stat("/sbin/pump", &buf) == 0)
dhcp_client = PUMP;
else if (stat("/sbin/udhcpc", &buf) == 0)
dhcp_client = UDHCPC;
else {
debconf_input(client, "critical", "netcfg/no_dhcp_client");
debconf_go(client);
exit(1);
}
while (state != QUIT) {
switch (state) {
case BACKUP:
exit (10); // Back the whole way out
break;
case GET_INTERFACE:
state = netcfg_get_interface(client, &interface, &num_interfaces) ?
BACKUP : GET_HOSTNAME;
break;
case GET_HOSTNAME:
if (netcfg_get_hostname(client, &hostname))
// if num_interfaces ==1 , interface question won't be asked. Go further back
state = (num_interfaces == 1) ? BACKUP : GET_INTERFACE;
else
state = GET_DHCP_HOSTNAME;
break;
case GET_DHCP_HOSTNAME:
state = netcfg_get_dhcp_hostname(client, &dhcp_hostname) ?
GET_HOSTNAME : QUIT;
break;
case QUIT:
break;
}
int num_interfaces;
static struct debconfclient *client;
enum { BACKUP, GET_INTERFACE, GET_DHCP,
QUIT } state = GET_INTERFACE;
/* initialize libd-i */
di_system_init("netcfg-dhcp");
/* initialize debconf */
client = debconfclient_new();
debconf_capb(client,"backup");
while (state != QUIT) {
switch(state) {
case BACKUP:
exit(10);
break;
case GET_INTERFACE:
state = netcfg_get_interface(client, &interface, &num_interfaces) ?
BACKUP : GET_DHCP;
break;
case GET_DHCP:
if (netcfg_get_dhcp(client))
state = (num_interfaces == 1) ? BACKUP : GET_INTERFACE;
else
state = QUIT;
break;
case QUIT:
break;
}
}
netcfg_write_common("40netcfg-dhcp", ipaddress, domain, hostname,
nameserver_array);
netcfg_write_dhcp(interface, dhcp_hostname);
debconf_progress_start(client, 0, 1, "netcfg/dhcp_progress");
netcfg_progress_displayed = 1;
debconf_progress_info(client, "netcfg/dhcp_progress_note");
my_debconf_input(client, "medium", "netcfg/do_dhcp", &ptr);
netcfg_activate_dhcp(client, interface, dhcp_hostname);
debconf_progress_step(client, 1);
debconf_progress_stop(client);
netcfg_progress_displayed = 0;
return 0;
if (netcfg_activate_dhcp(client) != 0)
exit(1);
return 0;
}

312
netcfg-static.c

@ -32,288 +32,44 @@
#include <debian-installer.h>
#include "netcfg.h"
static char *interface = NULL;
static char *hostname = NULL;
static char *domain = NULL;
static u_int32_t ipaddress = 0;
static u_int32_t nameserver_array[4] = { 0 };
static u_int32_t network = 0;
static u_int32_t broadcast = 0;
static u_int32_t netmask = 0;
static u_int32_t gateway = 0;
static u_int32_t pointopoint = 0;
static struct debconfclient *client;
static char *none;
int netcfg_get_ipaddress(struct debconfclient *client)
{
int ret;
char *ptr;
ret = my_debconf_input(client,"critical", "netcfg/get_ipaddress", &ptr);
if (ret)
return ret;
dot2num(&ipaddress, ptr);
return 0;
}
int netcfg_get_pointopoint(struct debconfclient *client)
{
int ret;
char *ptr;
ret = my_debconf_input(client,"critical", "netcfg/get_pointopoint", &ptr);
if (ret)
return ret;
dot2num(&pointopoint, ptr);
dot2num(&netmask, "255.255.255.255");
network = ipaddress;
gateway = pointopoint;
return 0;
}
int netcfg_get_netmask(struct debconfclient *client)
{
int ret;
char *ptr;
ret = my_debconf_input(client,"critical", "netcfg/get_netmask", &ptr);
if (ret)
return ret;
dot2num(&netmask, ptr);
network = ipaddress & netmask;
broadcast = (network | ~netmask);
/* Preseed gateway */
gateway = ipaddress & netmask;
debconf_set(client, "netcfg/get_gateway", num2dot(gateway+1));
return 0;
}
int netcfg_get_gateway(struct debconfclient *client)
{
int ret;
char *ptr;
ret = my_debconf_input(client, "critical", "netcfg/get_gateway", &ptr);
if (ret)
return ret;
dot2num(&gateway, ptr);
return 0;
}
static int netcfg_write_static()
{
FILE *fp;
if ((fp = file_open(NETWORKS_FILE, "w"))) {
fprintf(fp, "localnet %s\n", num2dot(network));
fclose(fp);
di_system_prebaseconfig_append("40netcfg-static", "cp %s %s\n",
NETWORKS_FILE,
"/target" NETWORKS_FILE);
} else
goto error;
if ((fp = file_open(INTERFACES_FILE, "a"))) {
fprintf(fp,
"\n# This entry was created during the Debian installation\n");
fprintf(fp,
"# (network, broadcast and gateway are optional)\n");
fprintf(fp, "auto %s\n", interface);
fprintf(fp, "iface %s inet static\n", interface);
fprintf(fp, "\taddress %s\n", num2dot(ipaddress));
fprintf(fp, "\tnetmask %s\n", num2dot(netmask));
fprintf(fp, "\tnetwork %s\n", num2dot(network));
fprintf(fp, "\tbroadcast %s\n", num2dot(broadcast));
if (gateway)
fprintf(fp, "\tgateway %s\n", num2dot(gateway));
if (pointopoint)
fprintf(fp, "\tpointopoint %s\n",
num2dot(pointopoint));
fclose(fp);
} else
goto error;
return 0;
error:
return -1;
}
static int netcfg_activate_static()
{
int rv = 0;
char buf[256];
#ifdef __GNU__
/* I had to do something like this ? */
/* di_exec_shell_log ("settrans /servers/socket/2 -fg"); */
di_exec_shell_log("settrans /servers/socket/2 --goaway");
snprintf(buf, sizeof(buf),
"settrans -fg /servers/socket/2 /hurd/pfinet --interface=%s --address=%s",
interface, num2dot(ipaddress));
di_snprintfcat(buf, sizeof(buf), " --netmask=%s",
num2dot(netmask));
buf[sizeof(buf) - 1] = '\0';
if (gateway)
snprintf(buf, sizeof(buf), " --gateway=%s",
num2dot(gateway));
rv |= di_exec_shell_log(buf);
#else
di_exec_shell_log("/sbin/ifconfig lo 127.0.0.1");
snprintf(buf, sizeof(buf), "/sbin/ifconfig %s %s",
interface, num2dot(ipaddress));
di_snprintfcat(buf, sizeof(buf), " netmask %s", num2dot(netmask));
di_snprintfcat(buf, sizeof(buf), " broadcast %s",
num2dot(broadcast));
buf[sizeof(buf) - 1] = '\0';
if (pointopoint)
di_snprintfcat(buf, sizeof(buf), " pointopoint %s",
num2dot(pointopoint));
rv |= di_exec_shell_log(buf);
if (gateway) {
snprintf(buf, sizeof(buf),
"/sbin/route add default gateway %s",
num2dot(gateway));
rv |= di_exec_shell_log(buf);
}
#endif
if (rv != 0) {
debconf_input(client, "critical", "netcfg/error_cfg");
debconf_go(client);
}
return 0;
}
int main(int argc, char *argv[])
{
int num_interfaces =0;
char *ptr;
char *nameservers = NULL;
ipaddress = network = broadcast = netmask = gateway = pointopoint =
0;
enum { BACKUP, GET_INTERFACE, GET_HOSTNAME, GET_DOMAIN, GET_NAMESERVERS,
GET_IPADDRESS, GET_POINTTOPOINT, GET_NETMASK, GET_GATEWAY,
GATEWAY_UNREACHABLE, CONFIRM, QUIT} state = GET_INTERFACE;
client = debconfclient_new();
debconf_capb(client, "backup");
debconf_metaget(client, "netcfg/internal-none", "description");
none = client->value ? strdup(client->value) : strdup("<none>");
while (state != QUIT) {
switch (state) {
case BACKUP:
exit (10); // Back the whole way out
break;
case GET_INTERFACE:
state = (netcfg_get_interface (client, &interface, &num_interfaces)) ?
BACKUP : GET_IPADDRESS;
break;
case GET_IPADDRESS:
if (netcfg_get_ipaddress (client)) {
// if num_interfaces ==1 , interface question won't be asked. Go further back
state = (num_interfaces == 1) ? BACKUP : GET_INTERFACE;
} else {
if (strncmp(interface, "plip", 4) == 0
|| strncmp(interface, "slip", 4) == 0
|| strncmp(interface, "ctc", 3) == 0
|| strncmp(interface, "escon", 5) == 0)
state = GET_POINTTOPOINT;
else
state = GET_NETMASK;
}
break;
int num_interfaces =0;
static struct debconfclient *client;
case GET_POINTTOPOINT:
state = netcfg_get_pointopoint(client) ?
GET_IPADDRESS : GET_NAMESERVERS;
break;
case GET_NETMASK:
state = netcfg_get_netmask(client) ?
GET_IPADDRESS : GET_GATEWAY;
break;
case GET_GATEWAY:
if (netcfg_get_gateway(client))
state = GET_NETMASK;
else
if (gateway && ((gateway & netmask) != network))
state = GATEWAY_UNREACHABLE;
else
state = GET_NAMESERVERS;
break;
case GATEWAY_UNREACHABLE:
debconf_capb(client); // Turn off backup
debconf_input(client, "high", "netcfg/gateway_unreachable");
debconf_go(client);
state = GET_GATEWAY;
debconf_capb(client, "backup");
break;
case GET_NAMESERVERS:
state = (netcfg_get_nameservers (client, &nameservers)) ?
GET_GATEWAY : GET_HOSTNAME;
break;
case GET_HOSTNAME:
state = (netcfg_get_hostname(client, &hostname)) ?
GET_NAMESERVERS : GET_DOMAIN;
break;
case GET_DOMAIN:
state = (netcfg_get_domain (client, &domain)) ?
GET_HOSTNAME : CONFIRM;
break;
case CONFIRM:
debconf_subst(client, "netcfg/confirm_static", "interface", interface);
debconf_subst(client, "netcfg/confirm_static", "ipaddress",
(ipaddress ? num2dot(ipaddress) : none));
debconf_subst(client, "netcfg/confirm_static", "pointopoint",
(pointopoint ? num2dot(pointopoint) : none));
debconf_subst(client, "netcfg/confirm_static", "netmask",
(netmask ? num2dot(netmask) : none));
debconf_subst(client, "netcfg/confirm_static", "gateway",
(gateway ? num2dot(gateway) : none));
debconf_subst(client, "netcfg/confirm_static", "hostname", hostname);
debconf_subst(client, "netcfg/confirm_static", "domain",
(domain ? domain : none));
debconf_subst(client, "netcfg/confirm_static", "nameservers",
(nameservers ? nameservers : none));
netcfg_nameservers_to_array(nameservers, nameserver_array);
debconf_capb(client); // Turn off backup for yes/no confirmation
my_debconf_input(client, "medium", "netcfg/confirm_static", &ptr);
state = strstr(ptr, "true") ? QUIT : GET_INTERFACE;
debconf_capb(client, "backup");
break;
case QUIT:
break;
}
enum { BACKUP, GET_INTERFACE, GET_STATIC, QUIT} state = GET_INTERFACE;
/* initialize libd-i */
di_system_init("netcfg-static");
/* initialize debconf */
client = debconfclient_new();
debconf_capb(client, "backup");
while (state != QUIT) {
switch(state) {
case BACKUP:
exit(10);
break;
case GET_INTERFACE:
state = netcfg_get_interface(client, &interface, &num_interfaces) ?
BACKUP : GET_STATIC;
break;
case GET_STATIC:
if (netcfg_get_static(client))
state = (num_interfaces == 1) ? BACKUP : GET_INTERFACE;
else
state = QUIT;
break;
case QUIT:
break;
}
}
netcfg_write_common("40netcfg-static", ipaddress, domain, hostname,
nameserver_array);
netcfg_write_static();
netcfg_activate_static();
if (netcfg_activate_static(client) != 0)
exit(1);
return 0;
return 0;
}

536
netcfg.c

@ -1,6 +1,6 @@
/*
netcfg.c - Shared functions used to configure the network for
the debian-installer.
netcfg.c - Configure a network via DHCP or manual configuration
for debian-installer
Copyright (C) 2000-2002 David Kimdon <dwhedon@debian.org>
@ -34,456 +34,90 @@
#include <debian-installer.h>
#include "netcfg.h"
/* Set if there is currently a progress bar displayed. */
int netcfg_progress_displayed = 0;
int my_debconf_input(struct debconfclient *client, char *priority,
char *template, char **p)
{
int ret = 0;
debconf_fset(client, template, "seen", "false");
debconf_input(client, priority, template);
ret = debconf_go(client);
debconf_get(client, template);
*p = client->value;
return ret;
}
int is_interface_up(char *inter)
{
struct ifreq ifr;
int sfd = -1, ret = -1;
if ((sfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
goto int_up_done;
strncpy(ifr.ifr_name, inter, sizeof(ifr.ifr_name));
if (ioctl(sfd, SIOCGIFFLAGS, &ifr) < 0)
goto int_up_done;
ret = (ifr.ifr_flags & IFF_UP) ? 1 : 0;
int_up_done:
if (sfd != -1)
close(sfd);
return ret;
}
void get_name(char *name, char *p)
{
while (isspace(*p))
p++;
while (*p) {
if (isspace(*p))
break;
if (*p == ':') { /* could be an alias */
char *dot = p, *dotname = name;
*name++ = *p++;
while (isdigit(*p))
*name++ = *p++;
if (*p != ':') { /* it wasn't, backup */
p = dot;
name = dotname;
}
if (*p == '\0')
return;
p++;
break;
}
*name++ = *p++;
}
*name++ = '\0';
return;
}
static FILE *ifs = NULL;
static char ibuf[512];
void getif_start()
{
if (ifs != NULL) {
fclose(ifs);
ifs = NULL;
}
if ((ifs = fopen("/proc/net/dev", "r")) != NULL) {
fgets(ibuf, sizeof(ibuf), ifs); /* eat header */
fgets(ibuf, sizeof(ibuf), ifs); /* ditto */
}
return;
}
char *getif(int all)
{
char rbuf[512];
if (ifs == NULL)
return NULL;
if (fgets(rbuf, sizeof(rbuf), ifs) != NULL) {
get_name(ibuf, rbuf);
if (!strcmp(ibuf, "lo")) /* ignore the loopback */
return getif(all); /* seriously doubt there is an infinite number of lo devices */
if (all || is_interface_up(ibuf) == 1)
return ibuf;
}
return NULL;
}
void getif_end()
{
if (ifs != NULL) {
fclose(ifs);
ifs = NULL;
}
return;
}
char *get_ifdsc(struct debconfclient *client, const char *ifp)
{
char template[256];
if (strlen(ifp) < 100) {
/* strip away the number from the interface (eth0 -> eth) */
char *new_ifp = strdup(ifp), *ptr = new_ifp;
while ((*ptr < '0' || *ptr > '9') && *ptr != '\0')
ptr++;
*ptr = '\0';
sprintf(template, "netcfg/internal-%s", new_ifp);
free(new_ifp);
debconf_metaget(client, template, "description");
if (client->value != NULL)
return strdup(client->value);
}
debconf_metaget(client, "netcfg/internal-unknown-iface", "description");
if (client->value != NULL)
return strdup(client->value);
else
return strdup("Unknown interface");
}
FILE *file_open(char *path, const char *opentype)
{
FILE *fp;
if ((fp = fopen(path, opentype)))
return fp;
else {
fprintf(stderr, "%s\n", path);
perror("fopen");
return NULL;
}
}
void dot2num(u_int32_t * num, char *dot)
{
char *p = dot - 1;
char *e;
int ix;
unsigned long val;
if (!dot)
goto exit;
*num = 0;
for (ix = 0; ix < 4; ix++) {
*num <<= 8;
p++;
val = strtoul(p, &e, 10);
if (e == p)
val = 0;
else if (val > 255)
goto exit;
*num += val;
/*printf("%#8x, %#2x\n", *num, val); */
if (ix < 3 && *e != '.')
goto exit;
p = e;
}
return;
exit:
*num = 0;
}
static char num2dot_buf[16];
char *num2dot(u_int32_t num)
{
int byte[4];
int ix;
char *dot = num2dot_buf;
for (ix = 3; ix >= 0; ix--) {
byte[ix] = num & 0xff;
num >>= 8;
}
sprintf(dot, "%d.%d.%d.%d", byte[0], byte[1], byte[2], byte[3]);
return dot;
}
void netcfg_die(struct debconfclient *client)
{
if (netcfg_progress_displayed)
debconf_progress_stop(client);
debconf_capb(client);
debconf_input(client, "high", "netcfg/error");
debconf_go(client);
exit(1);
}
/**
* @brief Ask which interface to configure
* @param client - client
* @param interface - set to the answer
* @param numif - number of interfaces found.
*/
int
netcfg_get_interface(struct debconfclient *client, char **interface,
int *numif)
{
char *inter;
int len, ret;
int num_interfaces = 0;
int newchars;
char *ptr;
char *ifdsc;
if (*interface) {
free(*interface);
*interface = NULL;
}
if (!(ptr = malloc(128)))
netcfg_die(client);
len = 128;
*ptr = '\0';
getif_start();
while ((inter = getif(1)) != NULL) {
ifdsc = get_ifdsc(client, inter);
newchars = strlen(inter) + strlen(ifdsc) + 5;
if (len < (strlen(ptr) + newchars)) {
if (!(ptr = realloc(ptr, len + newchars + 128)))
goto error;
len += newchars + 128;
}
di_snprintfcat(ptr, len, "%s: %s, ", inter, ifdsc);
num_interfaces++;
free(ifdsc);
}
getif_end();
if (num_interfaces == 0) {
debconf_input(client, "high", "netcfg/no_interfaces");
debconf_go(client);
free(ptr);
exit(1);
} else if (num_interfaces > 1) {
*numif = num_interfaces;
/* remove the trailing ", ", which confuses cdebconf */
ptr[strlen(ptr) - 2] = '\0';
debconf_subst(client, "netcfg/choose_interface", "ifchoices", ptr);
free(ptr);
ret = my_debconf_input(client, "high",
"netcfg/choose_interface", &inter);
if (ret)
return ret;
if (!inter)
netcfg_die(client);
} else if (num_interfaces == 1) {
inter = ptr;
*numif = 1;
static enum {DHCP, STATIC} netcfg_method = DHCP;
int netcfg_get_method(struct debconfclient *client)
{
char *method;
int ret;
ret = my_debconf_input(client, "medium", "netcfg/get_method", &method);
if (strcmp(method, "configure network with DHCP") == 0)
netcfg_method = DHCP;
else
netcfg_method = STATIC;
return ret;
}
int main(int argc, char *argv[])
{
int num_interfaces =0;
enum { BACKUP, GET_INTERFACE, GET_METHOD, GET_DHCP, GET_STATIC, QUIT} state = GET_INTERFACE;
static struct debconfclient *client;
static char *none;
/* initialize libd-i */
di_system_init("netcfg");
/* initialize debconf */
client = debconfclient_new();
debconf_capb(client, "backup");
debconf_metaget(client, "netcfg/internal-none", "description");
none = client->value ? strdup(client->value) : strdup("<none>");
while (state != QUIT) {
switch(state) {
case BACKUP:
exit(10);
break;
case GET_INTERFACE:
state = netcfg_get_interface(client, &interface, &num_interfaces) ?
BACKUP : GET_METHOD;
break;
case GET_METHOD:
if (netcfg_get_method(client))
state = (num_interfaces == 1) ? BACKUP : GET_INTERFACE;
else
if (netcfg_method == DHCP)
state = GET_DHCP;
else
state = GET_STATIC;
break;
case GET_DHCP:
if (netcfg_get_dhcp(client))
state = GET_METHOD;
else {
if (netcfg_activate_dhcp(client))
state = GET_STATIC;
else
state = QUIT;
}
break;
case GET_STATIC:
if (netcfg_get_static(client))
state = GET_METHOD;
else {
if (netcfg_activate_static(client))
exit(1);
else
state = QUIT;
}
break;
case QUIT:
break;
}
}
/* grab just the interface name, not the description too */
*interface = inter;
ptr = strchr(inter, ':');
if (ptr == NULL)
goto error;
*ptr = '\0';
*interface = strdup(*interface);
return 0;
error:
if (ptr)
free(ptr);
netcfg_die(client);
return 10; /* unreachable */
}
/*
* Set the hostname.
* @return 0 on success, 30 on BACKUP being selected.
*/
int
netcfg_get_hostname(struct debconfclient *client, char **hostname)
{
static const char *valid_chars =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-";
size_t len;
int ret;
char *p;
do {
ret = my_debconf_input(client, "medium", "netcfg/get_hostname", &p);
if (ret == 30) // backup
return ret;
free(*hostname);
*hostname = strdup(p);
len = strlen(*hostname);
/* Check the hostname for RFC 1123 compliance. */
if ((len < 2) ||
(len > 63) ||
(strspn(*hostname, valid_chars) != len) ||
((*hostname)[len - 1] == '-') ||
((*hostname)[0] == '-')) {
debconf_subst(client, "netcfg/invalid_hostname",
"hostname", *hostname);
debconf_input(client, "high", "netcfg/invalid_hostname");
debconf_go(client);
free(*hostname);
*hostname = NULL;
debconf_set(client, "netcfg/get_hostname", "debian");
}
} while (!*hostname);
return 0;
}
/* @brief Get the domainname.
* @return 0 for success, with *domain = domain, 30 for 'goback',
*/
int netcfg_get_domain(struct debconfclient *client, char **domain)
{
int ret;
char *ptr;
ret = my_debconf_input(client, "medium", "netcfg/get_domain", &ptr);
if (ret)
return ret;
if (*domain)
free(*domain);
*domain = NULL;
if (ptr)
*domain = strdup(ptr);
return 0;
}
int
netcfg_get_nameservers (struct debconfclient *client, char **nameservers)
{
char *ptr;
int ret;
ret = my_debconf_input(client, "high", "netcfg/get_nameservers", &ptr);
if (*nameservers)
free(*nameservers);
*nameservers = NULL;
if (ptr)
*nameservers = strdup(ptr);
return ret;
}
void netcfg_nameservers_to_array(char *nameservers, u_int32_t array[])
{
char *save, *ptr, *ns;
if (nameservers) {
save = ptr = strdup(nameservers);
ns = strtok_r(ptr, " \n\t", &ptr);
dot2num(&array[0], ns);
ns = strtok_r(NULL, " \n\t", &ptr);
dot2num(&array[1], ns);
ns = strtok_r(NULL, " \n\t", &ptr);
dot2num(&array[2], ns);
array[3] = 0;
free(save);
} else
array[0] = 0;
}
void
netcfg_write_common(const char *prebaseconfig, u_int32_t ipaddress,
char *domain, char *hostname, u_int32_t nameservers[])
{
FILE *fp;
if ((fp = file_open(INTERFACES_FILE, "w"))) {
fprintf(fp, "auto lo\n");
fprintf(fp, "iface lo inet loopback\n");
fclose(fp);
di_system_prebaseconfig_append(prebaseconfig, "cp %s %s\n",
INTERFACES_FILE,
"/target" INTERFACES_FILE);
}
if ((fp = file_open(HOSTS_FILE, "w"))) {
if (ipaddress) {
fprintf(fp, "127.0.0.1\tlocalhost\n");
if (domain)
fprintf(fp, "%s\t%s.%s\t%s\n",
num2dot(ipaddress), hostname,
domain, hostname);
else
fprintf(fp, "%s\t%s\n", num2dot(ipaddress),
hostname);
} else {
fprintf(fp, "127.0.0.1\t%s\tlocalhost\n", hostname);
}
fclose(fp);
di_system_prebaseconfig_append(prebaseconfig, "cp %s %s\n",
HOSTS_FILE, "/target" HOSTS_FILE);
}
if ((fp = file_open(RESOLV_FILE, "w"))) {
int i = 0;
if (domain)
fprintf(fp, "search %s\n", domain);
while (nameservers[i])
fprintf(fp, "nameserver %s\n",
num2dot(nameservers[i++]));
fclose(fp);
di_system_prebaseconfig_append(prebaseconfig, "cp %s %s\n",
RESOLV_FILE, "/target" RESOLV_FILE);
}
return 0;
}

24
netcfg.h

@ -14,8 +14,24 @@
#define DHCPCD_FILE "/etc/dhcpc/config"
#define DHCLIENT_DIR "/var/dhcp"
#define _GNU_SOURCE
extern int netcfg_progress_displayed;
/* network config */
extern char *interface;
extern char *hostname;
extern char *dhcp_hostname;
extern char *domain;
extern u_int32_t ipaddress;
extern u_int32_t nameserver_array[4];
extern u_int32_t network;
extern u_int32_t broadcast;
extern u_int32_t netmask;
extern u_int32_t gateway;
extern u_int32_t pointopoint;
/* common functions */
extern int netcfg_mkdir (char *path);
extern int is_interface_up (char *inter);
@ -44,6 +60,14 @@ extern int netcfg_get_nameservers (struct debconfclient *client, char **nameserv
extern int netcfg_get_domain(struct debconfclient *client, char **domain);
extern int netcfg_get_dhcp(struct debconfclient *client);
extern int netcfg_get_static(struct debconfclient *client);
extern int netcfg_activate_dhcp(struct debconfclient *client);
extern int netcfg_activate_static(struct debconfclient *client);
extern int my_debconf_input(struct debconfclient *client, char *priority, char *template, char **result);
extern void netcfg_write_common (const char *prebaseconfig,

Loading…
Cancel
Save