Browse Source

break out all support modules into dhcp.c, static.c, wireless.c

r15142
tags/0.64
Joshua Kwan 17 years ago
parent
commit
7132d73750
9 changed files with 904 additions and 873 deletions
  1. +12
    -13
      Makefile
  2. +4
    -5
      TODO
  3. +2
    -0
      debian/changelog
  4. +175
    -0
      dhcp.c
  5. +7
    -849
      netcfg-common.c
  6. +2
    -2
      netcfg.c
  7. +20
    -4
      netcfg.h
  8. +453
    -0
      static.c
  9. +229
    -0
      wireless.c

+ 12
- 13
Makefile View File

@@ -1,10 +1,10 @@
ifndef TARGETS
TARGETS=netcfg-dhcp netcfg-static netcfg
endif
CC ?= gcc
TARGETS ?= netcfg-dhcp netcfg-static netcfg

LDOPTS=-ldebconfclient -ldebian-installer -liw
PREFIX=$(DESTDIR)/usr/
CFLAGS=-W -Wall -Os
LDOPTS = -ldebconfclient -ldebian-installer -liw
PREFIX = $(DESTDIR)/usr/
CFLAGS = -W -Wall -Os
COMMON_OBJS = netcfg-common.o mii-lite.o wireless.o

ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS)))
CFLAGS += -g
@@ -12,17 +12,16 @@ else
CFLAGS += -fomit-frame-pointer
endif

INSTALL=install
STRIPTOOL=strip
STRIP = $(STRIPTOOL) --remove-section=.note --remove-section=.comment
STRIPTOOL = strip
STRIP = $(STRIPTOOL) --remove-section=.note --remove-section=.comment

all: $(TARGETS)

netcfg-dhcp: netcfg-dhcp.o
netcfg-static: netcfg-static.o
netcfg: netcfg.o
netcfg-dhcp: netcfg-dhcp.o dhcp.o
netcfg-static: netcfg-static.o static.o
netcfg: netcfg.o dhcp.o static.o

$(TARGETS): netcfg-common.o mii-lite.o
$(TARGETS): $(COMMON_OBJS)
$(CC) $(LDOPTS) -o $@ $^
$(STRIP) $@



+ 4
- 5
TODO View File

@@ -6,10 +6,9 @@
* Make netcfg-static smarter about default values, e.g. call ifconfig and
parse.

* find a smart way to affirm that the network is functional

* allow user to abort network configuration completely (have the postinst
exit w/ a successful status though)

* allow user option to reconfigure with static IP, reconfigure wireless,
or retry DHCP without sacrificing UI usability

* rewrite the whole getif() mess without static buffers

* stop using my_debconf_input

+ 2
- 0
debian/changelog View File

@@ -15,6 +15,8 @@ netcfg (0.64) UNRELEASED; urgency=low
- Ask for a hostname at the very beginning. This will be the DHCP
hostname for netcfg and netcfg-dhcp.
- As such, rip out netcfg_get_dhcp and netcfg_get_dhcp_hostname.
- Template cleanups: netcfg/static-title, netcfg/dhcp-title,
netcfg/internal-pcmcia
- Remove a lot of calls to /sbin/this and /sbin/that in response to Joey's
rant on debian-boot.



+ 175
- 0
dhcp.c View File

@@ -0,0 +1,175 @@
#include "netcfg.h"
#include <stdlib.h>
#include <unistd.h>
#include <debian-installer.h>
#include <stdio.h>
#include <assert.h>
#include <sys/stat.h>
#include <time.h>

/* Set if DHCP client exits */
volatile int dhcp_running = 0; /* not running */
int dhcp_exit_status = -1; /* failed */

/* Signal handler for DHCP client child */
static void dhcp_client_sigchld(int sig __attribute__ ((unused)))
{
if (dhcp_running == 1) {
dhcp_running = 0;
wait(&dhcp_exit_status);
}
}

static void netcfg_write_dhcp (char* prebaseconfig, char *iface)
{
FILE *fp;

if ((fp = file_open(INTERFACES_FILE, "a"))) {
fprintf(fp,
"\n# This entry was created during the Debian installation\n");
if (!iface_is_hotpluggable(iface))
fprintf(fp, "auto %s\n", iface);
fprintf(fp, "iface %s inet dhcp\n", iface);
if (is_wireless_iface(iface))
{
fprintf(fp, "\twireless_mode %s\n",
(mode == MANAGED) ? "managed" : "adhoc");
fprintf(fp, "\twireless_essid %s\n", essid ? essid : "any");
if (wepkey != NULL)
fprintf(fp, "\twireless_key %s\n", wepkey);
}
fclose(fp);
}

if ((fp = file_open(RESOLV_FILE, "a"))) {
fclose(fp);
}
di_system_prebaseconfig_append(prebaseconfig, "cp %s %s\n", RESOLV_FILE,
"/target" RESOLV_FILE);
}

#define DHCP_SECONDS 15

int netcfg_activate_dhcp(struct debconfclient *client)
{
char buf[128];
struct stat stat_buf;
time_t start_time, now;
pid_t pid = 0;
int retry = 1;
char *ptr;
FILE *dc = NULL;

enum { PUMP, DHCLIENT, DHCLIENT3, UDHCPC } dhcp_client;

if (stat("/var/lib/dhcp3", &stat_buf) == 0)
dhcp_client = DHCLIENT3;
if (stat("/sbin/dhclient", &stat_buf) == 0)
dhcp_client = DHCLIENT;
else if (stat("/sbin/udhcpc", &stat_buf) == 0)
dhcp_client = UDHCPC;
else if (stat("/sbin/pump", &stat_buf) == 0)
dhcp_client = PUMP;
else {
debconf_input(client, "critical", "netcfg/no_dhcp_client");
debconf_go(client);
exit(1);
}

deconfigure_network();

/* setup loopback */
di_exec_shell_log("ifconfig lo 127.0.0.1");

/* load kernel module for network sockets silently */
di_exec_shell("modprobe af_packet");

/* get dhcp lease */
switch (dhcp_client) {
case PUMP:
snprintf(buf, sizeof(buf), "pump -i %s -h %s", interface, hostname);
break;

case DHCLIENT:
/* First, set up dhclient.conf */
if ((dc = file_open(DHCLIENT_CONF, "w")))
{
fprintf(dc, "send host-name %s\n", hostname);
fclose(dc);
}
snprintf(buf, sizeof(buf), "dhclient -e %s", interface);
break;

case DHCLIENT3:
/* Different place.. */
if ((dc = file_open(DHCLIENT3_CONF, "w")))
{
fprintf(dc, "send host-name %s\n", hostname);
fclose(dc);
}
snprintf(buf, sizeof(buf), "dhclient %s", interface);
break;

case UDHCPC:
snprintf(buf, sizeof(buf), "udhcpc -i %s -n -H %s", hostname, interface);
break;
}

while (retry == 1) {
/* show progress bar */
debconf_progress_start(client, 0, DHCP_SECONDS, "netcfg/dhcp_progress");
debconf_progress_info(client, "netcfg/dhcp_progress_note");
netcfg_progress_displayed = 1;

now = start_time = time(NULL);
if (! (dhcp_running || (dhcp_exit_status == 0))) {
if ((pid = fork()) == 0) {
int ret = di_exec_shell_log(buf);
((WIFEXITED(ret) && (WEXITSTATUS(ret) != 0)) || WIFSIGNALED(ret)) ?
_exit(EXIT_FAILURE) : _exit(EXIT_SUCCESS);
}
if (pid)
dhcp_running = 1;
else
return 1;
signal(SIGCHLD, &dhcp_client_sigchld);
}

/* wait 10s for a DHCP lease */
while (dhcp_running && ((now - start_time) < DHCP_SECONDS)) {
sleep(1);
debconf_progress_step(client, 1);
now = time(NULL);
}

/* stop progress bar */
debconf_progress_stop(client);
netcfg_progress_displayed = 0;

/* got a lease? */
if (!dhcp_running && (dhcp_exit_status == 0)) {
assert(hostname != NULL);

/* write configuration */
netcfg_write_common("40netcfg", ipaddress, hostname, domain);
netcfg_write_dhcp("40netcfg", interface);

return 0;
}

/* ask if user wants to retry */
if (my_debconf_input(client, "high", "netcfg/dhcp_retry", &ptr) == 30) {
if (dhcp_running) {
kill(pid, SIGTERM);
}
return 30; /* backup */
}
retry = strstr(ptr, "true") ? 1 : 0;
}

if (dhcp_running) {
kill(pid, SIGTERM);
}
return 1;
}

+ 7
- 849
netcfg-common.c View File

@@ -20,18 +20,12 @@

*/

#define _GNU_SOURCE

#ifndef ARRAY_SIZE
# define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
#endif

#define empty_str(s) (s && *s == '\0')
#include "netcfg.h"

#include <assert.h>
#include <ctype.h>
#include <iwlib.h>
#include <sys/socket.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <string.h>
#include <stdlib.h>
@@ -42,40 +36,16 @@
#include <cdebconf/debconfclient.h>
#include <debian-installer.h>
#include <time.h>
#include "netcfg.h"


/* Set if there is currently a progress bar displayed. */
int netcfg_progress_displayed = 0;

/* Set if DCHP client exits */
volatile int dhcp_running = 0; /* not running */
volatile int dhcp_exit_status = -1; /* failed */

/* network config */
char *interface = NULL;
char *hostname = NULL;
char *domain = NULL;
struct in_addr ipaddress = { 0 };
struct in_addr old_ipaddress = { 0 };
struct in_addr nameserver_array[4] = { { 0 }, };
struct in_addr network = { 0 };
struct in_addr broadcast = { 0 };
struct in_addr netmask = { 0 };
struct in_addr gateway = { 0 };
struct in_addr pointopoint = { 0 };

/* Wireless mode */
enum { ADHOC, MANAGED } mode = MANAGED;

/* wireless config */
char* wepkey = NULL;
char* essid = NULL;

/* IW socket for global use - init in main */
int wfd = 0;

static int have_domain = 0;
int have_domain = 0;

int my_debconf_input(struct debconfclient *client, char *priority,
char *template, char **p)
@@ -88,15 +58,6 @@ int my_debconf_input(struct debconfclient *client, char *priority,
return ret;
}

/* Signal handler for DHCP client child */
static void dhcp_client_sigchld(int sig __attribute__ ((unused)))
{
if (dhcp_running == 1) {
dhcp_running = 0;
wait(&dhcp_exit_status);
}
}

int is_interface_up(char *inter)
{
struct ifreq ifr;
@@ -449,35 +410,6 @@ int netcfg_get_hostname(struct debconfclient *client, char **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;
if (have_domain == 1)
{
debconf_get(client, "netcfg/get_domain");
assert (!empty_str(client->value));
if (*domain)
free(*domain);
*domain = strdup(client->value);
return 0;
}
ret = my_debconf_input(client, "high", "netcfg/get_domain", &ptr);
if (ret)
return ret;
if (*domain)
free(*domain);
*domain = NULL;
if (ptr && ptr[0])
*domain = strdup(ptr);
return 0;
}

#define HELPFUL_COMMENT \
"# This file describes the network interfaces available on your system\n" \
"# and how to activate them. For more information, see interfaces(5).\n" \
@@ -544,247 +476,6 @@ void netcfg_write_common(const char *prebaseconfig, struct in_addr ipaddress,
}
}

int netcfg_get_ipaddress(struct debconfclient *client)
{
int ret, ok = 0;
char *ptr;

old_ipaddress = ipaddress;

while (!ok)
{
ret = my_debconf_input(client,"critical", "netcfg/get_ipaddress", &ptr);
if (ret)
return ret;

ok = inet_pton (AF_INET, ptr, &ipaddress);
if (!ok)
{
debconf_input (client, "critical", "netcfg/bad_ipaddress");
debconf_go (client);
}
}

return 0;
}

int netcfg_get_pointopoint(struct debconfclient *client)
{
int ret, ok = 0;
char *ptr;

while (!ok)
{
ret = my_debconf_input(client,"critical", "netcfg/get_pointopoint", &ptr);
if (ret)
return ret;

if (empty_str(ptr)) /* No P-P is ok */
{
memset(&pointopoint, 0, sizeof(struct in_addr));
return 0;
}
ok = inet_pton (AF_INET, ptr, &pointopoint);
if (!ok)
{
debconf_input (client, "critical", "netcfg/bad_ipaddress");
debconf_go (client);
}
}

inet_pton (AF_INET, "255.255.255.255", &netmask);
network = ipaddress;
gateway = pointopoint;

return 0;
}

int netcfg_get_netmask(struct debconfclient *client)
{
int ret, ok = 0;
char *ptr, ptr1[INET_ADDRSTRLEN];
struct in_addr old_netmask = netmask;
while (!ok)
{
ret = my_debconf_input(client,"critical", "netcfg/get_netmask", &ptr);

if (ret)
return ret;

ok = inet_pton (AF_INET, ptr, &netmask);
if (!ok)
{
debconf_input (client, "critical", "netcfg/bad_ipaddress");
debconf_go (client);
}
}

if (ipaddress.s_addr != old_ipaddress.s_addr ||
netmask.s_addr != old_netmask.s_addr)
{
network.s_addr = ipaddress.s_addr & netmask.s_addr;
broadcast.s_addr = (network.s_addr | ~netmask.s_addr);

/* Preseed gateway */
gateway.s_addr = ipaddress.s_addr & netmask.s_addr;
gateway.s_addr |= htonl(1);
}

inet_ntop (AF_INET, &gateway, ptr1, sizeof (ptr1));
debconf_set(client, "netcfg/get_gateway", ptr1);

return 0;
}

int netcfg_get_gateway(struct debconfclient *client)
{
int ret, ok = 0;
char *ptr;

while (!ok)
{
ret = my_debconf_input(client, "critical", "netcfg/get_gateway", &ptr);
if (ret)
return ret;

if (empty_str(ptr)) /* No gateway, that's fine */
{
/* clear existing gateway setting */
memset(&gateway, 0, sizeof(struct in_addr));
return 0;
}

ok = inet_pton (AF_INET, ptr, &gateway);
if (!ok)
{
debconf_input (client, "critical", "netcfg/bad_ipaddress");
debconf_go (client);
}
}

return 0;
}


int netcfg_get_nameservers (struct debconfclient *client, char **nameservers)
{
char *ptr, ptr1[INET_ADDRSTRLEN];
int ret;
if (*nameservers)
ptr = *nameservers;
else if (gateway.s_addr)
{
inet_ntop (AF_INET, &gateway, ptr1, sizeof (ptr1));
ptr = ptr1;
}
else
ptr = "";
debconf_set(client, "netcfg/get_nameservers", ptr);
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, struct in_addr array[])
{
char *save, *ptr, *ns;
int i;

if (nameservers) {
save = ptr = strdup(nameservers);

for (i = 0; i < 3; i++)
{
ns = strtok_r(ptr, " \n\t", &ptr);
if (ns)
inet_pton (AF_INET, ns, &array[i]);
else
array[i].s_addr = 0;
}

array[3].s_addr = 0;
free(save);
} else
array[0].s_addr = 0;
}

static int netcfg_write_static(char *prebaseconfig, char *domain,
struct in_addr nameservers[])
{
char ptr1[INET_ADDRSTRLEN];
FILE *fp;

if ((fp = file_open(NETWORKS_FILE, "w"))) {
fprintf(fp, "localnet %s\n", inet_ntop (AF_INET, &network, ptr1, sizeof (ptr1)));
fclose(fp);
di_system_prebaseconfig_append(prebaseconfig, "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");
if (!iface_is_hotpluggable(interface))
fprintf(fp, "auto %s\n", interface);
fprintf(fp, "iface %s inet static\n", interface);
fprintf(fp, "\taddress %s\n", inet_ntop (AF_INET, &ipaddress, ptr1, sizeof (ptr1)));
fprintf(fp, "\tnetmask %s\n", inet_ntop (AF_INET, &netmask, ptr1, sizeof (ptr1)));
fprintf(fp, "\tnetwork %s\n", inet_ntop (AF_INET, &network, ptr1, sizeof (ptr1)));
fprintf(fp, "\tbroadcast %s\n", inet_ntop (AF_INET, &broadcast, ptr1, sizeof (ptr1)));
if (gateway.s_addr)
fprintf(fp, "\tgateway %s\n", inet_ntop (AF_INET, &gateway, ptr1, sizeof (ptr1)));
if (pointopoint.s_addr)
fprintf(fp, "\tpointopoint %s\n", inet_ntop (AF_INET, &pointopoint, ptr1, sizeof (ptr1)));
if (is_wireless_iface(interface))
{
fprintf(fp, "\twireless_mode %s\n",
(mode == MANAGED) ? "managed" : "ad-hoc");
fprintf(fp, "\twireless_essid %s\n", essid ? essid : "any");

if (wepkey != NULL)
fprintf(fp, "\twireless_key %s\n", wepkey);
}
fclose(fp);
} else
goto error;

if ((fp = file_open(RESOLV_FILE, "w"))) {
int i = 0;
if (domain && !empty_str(domain))
fprintf(fp, "search %s\n", domain);

while (nameservers[i].s_addr)
fprintf(fp, "nameserver %s\n",
inet_ntop (AF_INET, &nameservers[i++], ptr1, sizeof (ptr1)));

fclose(fp);
} else
goto error;

di_system_prebaseconfig_append(prebaseconfig, "cp %s %s\n", RESOLV_FILE,
"/target" RESOLV_FILE);

return 0;
error:
return -1;
}

int kill_dhcp_client(void) {
FILE *ps;
@@ -839,539 +530,6 @@ int deconfigure_network(void) {
return 0;
}

int netcfg_activate_static(struct debconfclient *client)
{
int rv = 0;
char buf[256], ptr1[INET_ADDRSTRLEN];

#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, inet_ntop (AF_INET, &ipaddress));
di_snprintfcat(buf, sizeof(buf), " --netmask=%s",
inet_ntop (AF_INET, &netmask, ptr1, sizeof (ptr1)));
buf[sizeof(buf) - 1] = '\0';

if (gateway)
snprintf(buf, sizeof(buf), " --gateway=%s",
inet_ntop (AF_INET, &gateway, ptr1, sizeof (ptr1)));

rv |= di_exec_shell_log(buf);

#else
deconfigure_network();

/* configure loopback */
di_exec_shell_log("ifconfig lo 127.0.0.1");

snprintf(buf, sizeof(buf), "ifconfig %s %s",
interface, inet_ntop (AF_INET, &ipaddress, ptr1, sizeof (ptr1)));
di_snprintfcat(buf, sizeof(buf), " netmask %s", inet_ntop (AF_INET, &netmask, ptr1, sizeof (ptr1)));
di_snprintfcat(buf, sizeof(buf), " broadcast %s",
inet_ntop (AF_INET, &broadcast, ptr1, sizeof (ptr1)));
buf[sizeof(buf) - 1] = '\0';

if (pointopoint.s_addr)
di_snprintfcat(buf, sizeof(buf), " pointopoint %s",
inet_ntop (AF_INET, &pointopoint, ptr1, sizeof (ptr1)));

rv |= di_exec_shell_log(buf);

if (gateway.s_addr) {
snprintf(buf, sizeof(buf),
"route add default gateway %s",
inet_ntop (AF_INET, &gateway, ptr1, sizeof (ptr1)));
rv |= di_exec_shell_log(buf);
printf("rv = %i, buf = %s\n", rv, buf);
}
#endif

if (rv != 0) {
debconf_capb(client);
debconf_input(client, "high", "netcfg/error");
debconf_go(client);
debconf_capb(client, "backup");
return -1;
}

/* write configuration */

netcfg_write_common("40netcfg", ipaddress, hostname, domain);
netcfg_write_static("40netcfg", domain, nameserver_array);

return 0;
}

int netcfg_get_static(struct debconfclient *client)
{
char *nameservers = NULL;
char *ptr, ptr1[INET_ADDRSTRLEN];
char *none;

enum { BACKUP, GET_IPADDRESS, GET_POINTOPOINT, GET_NETMASK, GET_GATEWAY,
GATEWAY_UNREACHABLE, GET_NAMESERVERS, CONFIRM, GET_DOMAIN, QUIT } state = GET_IPADDRESS;

kill_dhcp_client();
ipaddress.s_addr = network.s_addr = broadcast.s_addr = netmask.s_addr = gateway.s_addr = pointopoint.s_addr =
0;

debconf_metaget(client, "netcfg/internal-none", "description");
none = client->value ? strdup(client->value) : strdup("<none>");

while (state != QUIT) {
switch (state) {
case BACKUP:
return 10; /* Back to main */
break;
case GET_IPADDRESS:
if (netcfg_get_ipaddress (client)) {
state = BACKUP;
} else {
if (strncmp(interface, "plip", 4) == 0
|| strncmp(interface, "slip", 4) == 0
|| strncmp(interface, "ctc", 3) == 0
|| strncmp(interface, "escon", 5) == 0)
state = GET_POINTOPOINT;
else
state = GET_NETMASK;
}
break;
case GET_POINTOPOINT:
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.s_addr && ((gateway.s_addr & netmask.s_addr) != network.s_addr))
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_DOMAIN;
break;
case GET_DOMAIN:
state = (netcfg_get_domain (client, &domain)) ?
GET_NAMESERVERS : CONFIRM;
break;
case CONFIRM:
debconf_subst(client, "netcfg/confirm_static", "interface", interface);
debconf_subst(client, "netcfg/confirm_static", "ipaddress",
(ipaddress.s_addr ? inet_ntop (AF_INET, &ipaddress, ptr1, sizeof (ptr1)) : none));
debconf_subst(client, "netcfg/confirm_static", "pointopoint",
(pointopoint.s_addr ? inet_ntop (AF_INET, &pointopoint, ptr1, sizeof (ptr1)) : none));
debconf_subst(client, "netcfg/confirm_static", "netmask",
(netmask.s_addr ? inet_ntop (AF_INET, &netmask, ptr1, sizeof (ptr1)) : none));
debconf_subst(client, "netcfg/confirm_static", "gateway",
(gateway.s_addr ? inet_ntop (AF_INET, &gateway, ptr1, sizeof (ptr1)) : 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_IPADDRESS;
debconf_capb(client, "backup");
break;
case QUIT:
return 0;
break;
}
}
return 0;
}


static void netcfg_write_dhcp (char* prebaseconfig, char *iface)
{
FILE *fp;

if ((fp = file_open(INTERFACES_FILE, "a"))) {
fprintf(fp,
"\n# This entry was created during the Debian installation\n");
if (!iface_is_hotpluggable(iface))
fprintf(fp, "auto %s\n", iface);
fprintf(fp, "iface %s inet dhcp\n", iface);
if (is_wireless_iface(iface))
{
fprintf(fp, "\twireless_mode %s\n",
(mode == MANAGED) ? "managed" : "adhoc");
fprintf(fp, "\twireless_essid %s\n", essid ? essid : "any");
if (wepkey != NULL)
fprintf(fp, "\twireless_key %s\n", wepkey);
}
fclose(fp);
}

if ((fp = file_open(RESOLV_FILE, "a"))) {
fclose(fp);
}
di_system_prebaseconfig_append(prebaseconfig, "cp %s %s\n", RESOLV_FILE,
"/target" RESOLV_FILE);
}

#define DHCP_SECONDS 15

int netcfg_activate_dhcp(struct debconfclient *client)
{
char buf[128];
struct stat stat_buf;
time_t start_time, now;
pid_t pid = 0;
int retry = 1;
char *ptr;
FILE *dc = NULL;

enum { PUMP, DHCLIENT, DHCLIENT3, UDHCPC } dhcp_client;

if (stat("/var/lib/dhcp3", &stat_buf) == 0)
dhcp_client = DHCLIENT3;
if (stat("/sbin/dhclient", &stat_buf) == 0)
dhcp_client = DHCLIENT;
else if (stat("/sbin/udhcpc", &stat_buf) == 0)
dhcp_client = UDHCPC;
else if (stat("/sbin/pump", &stat_buf) == 0)
dhcp_client = PUMP;
else {
debconf_input(client, "critical", "netcfg/no_dhcp_client");
debconf_go(client);
exit(1);
}

deconfigure_network();

/* setup loopback */
di_exec_shell_log("ifconfig lo 127.0.0.1");

/* load kernel module for network sockets silently */
di_exec_shell("modprobe af_packet");

/* get dhcp lease */
switch (dhcp_client) {
case PUMP:
snprintf(buf, sizeof(buf), "pump -i %s -h %s", interface, hostname);
break;

case DHCLIENT:
/* First, set up dhclient.conf */
if ((dc = file_open(DHCLIENT_CONF, "w")))
{
fprintf(dc, "send host-name %s\n", hostname);
fclose(dc);
}
snprintf(buf, sizeof(buf), "dhclient -e %s", interface);
break;

case DHCLIENT3:
/* Different place.. */
if ((dc = file_open(DHCLIENT3_CONF, "w")))
{
fprintf(dc, "send host-name %s\n", hostname);
fclose(dc);
}
snprintf(buf, sizeof(buf), "dhclient %s", interface);
break;

case UDHCPC:
snprintf(buf, sizeof(buf), "udhcpc -i %s -n -H %s", hostname, interface);
break;
}

while (retry == 1) {
/* show progress bar */
debconf_progress_start(client, 0, DHCP_SECONDS, "netcfg/dhcp_progress");
debconf_progress_info(client, "netcfg/dhcp_progress_note");
netcfg_progress_displayed = 1;

now = start_time = time(NULL);
if (! (dhcp_running || (dhcp_exit_status == 0))) {
if ((pid = fork()) == 0) {
int ret = di_exec_shell_log(buf);
((WIFEXITED(ret) && (WEXITSTATUS(ret) != 0)) || WIFSIGNALED(ret)) ?
_exit(EXIT_FAILURE) : _exit(EXIT_SUCCESS);
}
if (pid)
dhcp_running = 1;
else
return 1;
signal(SIGCHLD, &dhcp_client_sigchld);
}

/* wait 10s for a DHCP lease */
while (dhcp_running && ((now - start_time) < DHCP_SECONDS)) {
sleep(1);
debconf_progress_step(client, 1);
now = time(NULL);
}

/* stop progress bar */
debconf_progress_stop(client);
netcfg_progress_displayed = 0;

/* got a lease? */
if (!dhcp_running && (dhcp_exit_status == 0)) {
assert(hostname != NULL);

/* write configuration */
netcfg_write_common("40netcfg", ipaddress, hostname, domain);
netcfg_write_dhcp("40netcfg", interface);

return 0;
}

/* ask if user wants to retry */
if (my_debconf_input(client, "high", "netcfg/dhcp_retry", &ptr) == 30) {
if (dhcp_running) {
kill(pid, SIGTERM);
}
return 30; /* backup */
}
retry = strstr(ptr, "true") ? 1 : 0;
}

if (dhcp_running) {
kill(pid, SIGTERM);
}
return 1;
}

int is_wireless_iface (const char* iface)
{
wireless_config wc;

if (wfd == 0)
wfd = iw_sockets_open();
return (iw_get_basic_config (wfd, (char*)iface, &wc) == 0);
}

int netcfg_wireless_set_essid (struct debconfclient * client, char *iface)
{
int ret, couldnt_associate = 0;
wireless_config wconf;
char* tf = NULL, *user_essid = NULL, *ptr = wconf.essid;

if (wfd == 0) /* shouldn't happen */
wfd = iw_sockets_open();

iw_get_basic_config (wfd, iface, &wconf);

debconf_subst(client, "netcfg/wireless_essid", "iface", iface);
debconf_subst(client, "netcfg/wireless_adhoc_managed", "iface", iface);

debconf_input(client, "low", "netcfg/wireless_adhoc_managed");

if (debconf_go(client) == 30)
return GO_BACK;

debconf_get(client, "netcfg/wireless_adhoc_managed");

if (!strcmp(client->value, "Ad-hoc network (Peer to peer)"))
mode = ADHOC;

wconf.has_mode = 1;
wconf.mode = (mode == ADHOC) ? 1 : 2;

debconf_input(client, "low", "netcfg/wireless_essid");

if (debconf_go(client) == 30)
return GO_BACK;

debconf_get(client, "netcfg/wireless_essid");
tf = strdup(client->value);

automatic:
/* question not asked or user doesn't care or we're successfully associated */
if (!empty_str(wconf.essid) || empty_str(client->value))
{
int i, success = 0;

/* Default to any AP */
wconf.essid[0] = '\0';
wconf.essid_on = 0;

iw_set_basic_config (wfd, iface, &wconf);

/* Wait for association.. (MAX_SECS seconds)*/
#define MAX_SECS 3

debconf_progress_start(client, 0, MAX_SECS, "netcfg/wifi_progress_title");
debconf_progress_info(client, "netcfg/wifi_progress_info");

for (i = 0; i <= MAX_SECS; i++)
{
ifconfig_up(iface);
sleep (1);
iw_get_basic_config (wfd, iface, &wconf);

if (!empty_str(wconf.essid))
{
/* Save for later */
debconf_set(client, "netcfg/wireless_essid", wconf.essid);
debconf_progress_set(client, MAX_SECS);
success = 1;
break;
}

debconf_progress_step(client, 1);
ifconfig_down(iface);
}

debconf_progress_stop(client);

if (success)
return 0;

couldnt_associate = 1;
}
/* yes, wants to set an essid by himself */

if (strlen(tf) <= IW_ESSID_MAX_SIZE) /* looks ok, let's use it */
user_essid = tf;

while (!user_essid || empty_str(user_essid) ||
strlen(user_essid) > IW_ESSID_MAX_SIZE)
{
/* Misnomer of a check. Basically, if we went through autodetection,
* we want to enter this loop, but we want to suppress anything that
* relied on the checking of tf/user_essid (i.e. "", in most cases.) */
if (!couldnt_associate)
{
debconf_subst(client, "netcfg/invalid_essid", "essid", user_essid);
debconf_input(client, "high", "netcfg/invalid_essid");
debconf_go(client);
}

ret = debconf_input(client,
couldnt_associate ? "critical" : "low",
"netcfg/wireless_essid");
/* But now we'd not like to suppress any MORE errors */
couldnt_associate = 0;
/* we asked the question once, why can't we ask it again? */
assert (ret != 30);

if (debconf_go(client) == 30) /* well, we did, but he wants to go back */
return GO_BACK;

debconf_get(client, "netcfg/wireless_essid");

if (empty_str(client->value))
goto automatic;

free(user_essid);
user_essid = strdup(client->value);
}

essid = user_essid;

memset(ptr, 0, IW_ESSID_MAX_SIZE + 1);
snprintf(wconf.essid, IW_ESSID_MAX_SIZE + 1, "%s", essid);
wconf.has_essid = 1;
wconf.essid_on = 1;

iw_set_basic_config (wfd, iface, &wconf);

return 0;
}

void unset_wep_key (char* iface)
{
wireless_config wconf;
int ret;

if (!wfd)
wfd = iw_sockets_open();

iw_get_basic_config(wfd, iface, &wconf);

wconf.has_key = 1;
wconf.key[0] = '\0';
wconf.key_flags = IW_ENCODE_DISABLED | IW_ENCODE_NOKEY;
wconf.key_size = 0;

ret = iw_set_basic_config (wfd, iface, &wconf);

fprintf (stderr, "iw_set_basic_config for uncode returned %d",
ret);
}

int netcfg_wireless_set_wep (struct debconfclient * client, char* iface)
{
wireless_config wconf;
char* rv = NULL;
int ret, keylen;
unsigned char buf [IW_ENCODING_TOKEN_MAX];
iw_get_basic_config (wfd, iface, &wconf);

debconf_subst(client, "netcfg/wireless_wep", "iface", iface);
ret = my_debconf_input (client, "high", "netcfg/wireless_wep", &rv);

if (ret == 30)
return GO_BACK;

if (empty_str(rv))
{
unset_wep_key (iface);

if (wepkey != NULL)
{
free(wepkey);
wepkey = NULL;
}
return 0;
}

while ((keylen = iw_in_key (rv, buf)) == -1)
{
debconf_subst(client, "netcfg/invalid_wep", "wepkey", rv);
debconf_input(client, "high", "netcfg/invalid_wep");
debconf_go(client);
ret = my_debconf_input (client, "high", "netcfg/wireless_wep", &rv);
}

wconf.has_key = 1;
wconf.key_size = keylen;
wconf.key_flags = IW_ENCODE_ENABLED | IW_ENCODE_OPEN;
strncpy (wconf.key, buf, keylen);

wepkey = strdup(rv);

iw_set_basic_config (wfd, iface, &wconf);

return 0;
}

/* Utility functions. */
int ifconfig_up (char* iface)
{
@@ -1380,7 +538,7 @@ int ifconfig_up (char* iface)
int ret;

if (!(cmd = malloc(len)))
return 1;
return 1;

snprintf(cmd, len, "ifconfig %s up", iface);

@@ -1388,7 +546,7 @@ int ifconfig_up (char* iface)

free(cmd);

return ret;
return ret;
}

int ifconfig_down (char* iface)
@@ -1398,7 +556,7 @@ int ifconfig_down (char* iface)
int ret;

if (!(cmd = malloc(len)))
return 1;
return 1;

snprintf(cmd, len, "ifconfig %s down", iface);

@@ -1406,5 +564,5 @@ int ifconfig_down (char* iface)

free(cmd);

return ret;
return ret;
}

+ 2
- 2
netcfg.c View File

@@ -43,10 +43,10 @@ response_t netcfg_get_method(struct debconfclient *client)
iret = debconf_input(client, "medium", "netcfg/use_dhcp");
ret = debconf_go(client);

debconf_get(client, "netcfg/use_dhcp");

if (ret == 30)
return GO_BACK;
debconf_get(client, "netcfg/use_dhcp");

if (strcmp(client->value, "true") == 0)
netcfg_method = DHCP;


+ 20
- 4
netcfg.h View File

@@ -1,9 +1,5 @@
#ifndef _NETCFG_H_
#define _NETCFG_H_
#include <sys/types.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <cdebconf/debconfclient.h>

#define INTERFACES_FILE "/etc/network/interfaces"
#define HOSTS_FILE "/etc/hosts"
@@ -15,12 +11,25 @@

#define _GNU_SOURCE

#include <sys/types.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <cdebconf/debconfclient.h>

#ifndef ARRAY_SIZE
# define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
#endif

#define empty_str(s) (s && *s == '\0')

typedef enum { NOT_ASKED = 30, GO_BACK } response_t;
typedef enum { DHCP, STATIC, DUNNO } method_t;
typedef enum { ADHOC = 1, MANAGED = 2 } wifimode_t;

extern int netcfg_progress_displayed;
extern int wfd;
extern int input_result;
extern int have_domain;

/* network config */
extern char *interface;
@@ -35,6 +44,10 @@ extern struct in_addr netmask;
extern struct in_addr gateway;
extern struct in_addr pointopoint;

/* wireless */
extern char *essid, *wepkey;
extern wifimode_t mode;

/* common functions */
extern int is_interface_up (char *inter);

@@ -79,6 +92,9 @@ extern int is_wireless_iface (const char* iface);
extern int netcfg_wireless_set_essid (struct debconfclient *client, char* iface);
extern int netcfg_wireless_set_wep (struct debconfclient *client, char* iface);

extern int iface_is_hotpluggable(const char *iface);
extern int deconfigure_network(void);

extern method_t mii_diag_status_lite (char *ifname);

extern int ifconfig_up (char*);


+ 453
- 0
static.c View File

@@ -0,0 +1,453 @@
/* Static network configurator module for netcfg.
*
* Licensed under the terms of the GNU General Public License
*/

#include "netcfg.h"
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <debian-installer.h>
#include <assert.h>

struct in_addr old_ipaddress = { 0 };
struct in_addr nameserver_array[4] = { { 0 }, };
struct in_addr network = { 0 };
struct in_addr broadcast = { 0 };
struct in_addr netmask = { 0 };
struct in_addr gateway = { 0 };
struct in_addr pointopoint = { 0 };

int netcfg_get_ipaddress(struct debconfclient *client)
{
int ret, ok = 0;
char *ptr;

old_ipaddress = ipaddress;

while (!ok)
{
ret = my_debconf_input(client,"critical", "netcfg/get_ipaddress", &ptr);
if (ret)
return ret;

ok = inet_pton (AF_INET, ptr, &ipaddress);
if (!ok)
{
debconf_input (client, "critical", "netcfg/bad_ipaddress");
debconf_go (client);
}
}

return 0;
}

int netcfg_get_pointopoint(struct debconfclient *client)
{
int ret, ok = 0;
char *ptr;

while (!ok)
{
ret = my_debconf_input(client,"critical", "netcfg/get_pointopoint", &ptr);
if (ret)
return ret;

if (empty_str(ptr)) /* No P-P is ok */
{
memset(&pointopoint, 0, sizeof(struct in_addr));
return 0;
}
ok = inet_pton (AF_INET, ptr, &pointopoint);
if (!ok)
{
debconf_input (client, "critical", "netcfg/bad_ipaddress");
debconf_go (client);
}
}

inet_pton (AF_INET, "255.255.255.255", &netmask);
network = ipaddress;
gateway = pointopoint;

return 0;
}

int netcfg_get_netmask(struct debconfclient *client)
{
int ret, ok = 0;
char *ptr, ptr1[INET_ADDRSTRLEN];
struct in_addr old_netmask = netmask;
while (!ok)
{
ret = my_debconf_input(client,"critical", "netcfg/get_netmask", &ptr);

if (ret)
return ret;

ok = inet_pton (AF_INET, ptr, &netmask);
if (!ok)
{
debconf_input (client, "critical", "netcfg/bad_ipaddress");
debconf_go (client);
}
}

if (ipaddress.s_addr != old_ipaddress.s_addr ||
netmask.s_addr != old_netmask.s_addr)
{
network.s_addr = ipaddress.s_addr & netmask.s_addr;
broadcast.s_addr = (network.s_addr | ~netmask.s_addr);

/* Preseed gateway */
gateway.s_addr = ipaddress.s_addr & netmask.s_addr;
gateway.s_addr |= htonl(1);
}

inet_ntop (AF_INET, &gateway, ptr1, sizeof (ptr1));
debconf_set(client, "netcfg/get_gateway", ptr1);

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;
if (have_domain == 1)
{
debconf_get(client, "netcfg/get_domain");
assert (!empty_str(client->value));
if (*domain)
free(*domain);
*domain = strdup(client->value);
return 0;
}
ret = my_debconf_input(client, "high", "netcfg/get_domain", &ptr);
if (ret)
return ret;
if (*domain)
free(*domain);
*domain = NULL;
if (ptr && ptr[0])
*domain = strdup(ptr);
return 0;
}

int netcfg_get_gateway(struct debconfclient *client)
{
int ret, ok = 0;
char *ptr;

while (!ok)
{
ret = my_debconf_input(client, "critical", "netcfg/get_gateway", &ptr);
if (ret)
return ret;

if (empty_str(ptr)) /* No gateway, that's fine */
{
/* clear existing gateway setting */
memset(&gateway, 0, sizeof(struct in_addr));
return 0;
}

ok = inet_pton (AF_INET, ptr, &gateway);
if (!ok)
{
debconf_input (client, "critical", "netcfg/bad_ipaddress");
debconf_go (client);
}
}

return 0;
}

int netcfg_get_nameservers (struct debconfclient *client, char **nameservers)
{
char *ptr, ptr1[INET_ADDRSTRLEN];
int ret;
if (*nameservers)
ptr = *nameservers;
else if (gateway.s_addr)
{
inet_ntop (AF_INET, &gateway, ptr1, sizeof (ptr1));
ptr = ptr1;
}
else
ptr = "";
debconf_set(client, "netcfg/get_nameservers", ptr);
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, struct in_addr array[])
{
char *save, *ptr, *ns;
int i;

if (nameservers) {
save = ptr = strdup(nameservers);

for (i = 0; i < 3; i++)
{
ns = strtok_r(ptr, " \n\t", &ptr);
if (ns)
inet_pton (AF_INET, ns, &array[i]);
else
array[i].s_addr = 0;
}

array[3].s_addr = 0;
free(save);
} else
array[0].s_addr = 0;
}

static int netcfg_write_static(char *prebaseconfig, char *domain,
struct in_addr nameservers[])
{
char ptr1[INET_ADDRSTRLEN];
FILE *fp;

if ((fp = file_open(NETWORKS_FILE, "w"))) {
fprintf(fp, "localnet %s\n", inet_ntop (AF_INET, &network, ptr1, sizeof (ptr1)));
fclose(fp);
di_system_prebaseconfig_append(prebaseconfig, "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");
if (!iface_is_hotpluggable(interface))
fprintf(fp, "auto %s\n", interface);
fprintf(fp, "iface %s inet static\n", interface);
fprintf(fp, "\taddress %s\n", inet_ntop (AF_INET, &ipaddress, ptr1, sizeof (ptr1)));
fprintf(fp, "\tnetmask %s\n", inet_ntop (AF_INET, &netmask, ptr1, sizeof (ptr1)));
fprintf(fp, "\tnetwork %s\n", inet_ntop (AF_INET, &network, ptr1, sizeof (ptr1)));
fprintf(fp, "\tbroadcast %s\n", inet_ntop (AF_INET, &broadcast, ptr1, sizeof (ptr1)));
if (gateway.s_addr)
fprintf(fp, "\tgateway %s\n", inet_ntop (AF_INET, &gateway, ptr1, sizeof (ptr1)));
if (pointopoint.s_addr)
fprintf(fp, "\tpointopoint %s\n", inet_ntop (AF_INET, &pointopoint, ptr1, sizeof (ptr1)));
if (is_wireless_iface(interface))
{
fprintf(fp, "\twireless_mode %s\n",
(mode == MANAGED) ? "managed" : "ad-hoc");
fprintf(fp, "\twireless_essid %s\n", essid ? essid : "any");

if (wepkey != NULL)
fprintf(fp, "\twireless_key %s\n", wepkey);
}
fclose(fp);
} else
goto error;

if ((fp = file_open(RESOLV_FILE, "w"))) {
int i = 0;
if (domain && !empty_str(domain))
fprintf(fp, "search %s\n", domain);

while (nameservers[i].s_addr)
fprintf(fp, "nameserver %s\n",
inet_ntop (AF_INET, &nameservers[i++], ptr1, sizeof (ptr1)));

fclose(fp);
} else
goto error;

di_system_prebaseconfig_append(prebaseconfig, "cp %s %s\n", RESOLV_FILE,
"/target" RESOLV_FILE);

return 0;
error:
return -1;
}

int netcfg_activate_static(struct debconfclient *client)
{
int rv = 0;
char buf[256], ptr1[INET_ADDRSTRLEN];

#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, inet_ntop (AF_INET, &ipaddress));
di_snprintfcat(buf, sizeof(buf), " --netmask=%s",
inet_ntop (AF_INET, &netmask, ptr1, sizeof (ptr1)));
buf[sizeof(buf) - 1] = '\0';

if (gateway)
snprintf(buf, sizeof(buf), " --gateway=%s",
inet_ntop (AF_INET, &gateway, ptr1, sizeof (ptr1)));

rv |= di_exec_shell_log(buf);

#else
deconfigure_network();

/* configure loopback */
di_exec_shell_log("ifconfig lo 127.0.0.1");

snprintf(buf, sizeof(buf), "ifconfig %s %s",
interface, inet_ntop (AF_INET, &ipaddress, ptr1, sizeof (ptr1)));
di_snprintfcat(buf, sizeof(buf), " netmask %s", inet_ntop (AF_INET, &netmask, ptr1, sizeof (ptr1)));
di_snprintfcat(buf, sizeof(buf), " broadcast %s",
inet_ntop (AF_INET, &broadcast, ptr1, sizeof (ptr1)));
buf[sizeof(buf) - 1] = '\0';

if (pointopoint.s_addr)
di_snprintfcat(buf, sizeof(buf), " pointopoint %s",
inet_ntop (AF_INET, &pointopoint, ptr1, sizeof (ptr1)));

rv |= di_exec_shell_log(buf);

if (gateway.s_addr) {
snprintf(buf, sizeof(buf),
"route add default gateway %s",
inet_ntop (AF_INET, &gateway, ptr1, sizeof (ptr1)));
rv |= di_exec_shell_log(buf);
printf("rv = %i, buf = %s\n", rv, buf);
}
#endif

if (rv != 0) {
debconf_capb(client);
debconf_input(client, "high", "netcfg/error");
debconf_go(client);
debconf_capb(client, "backup");
return -1;
}

/* write configuration */

netcfg_write_common("40netcfg", ipaddress, hostname, domain);
netcfg_write_static("40netcfg", domain, nameserver_array);

return 0;
}

int netcfg_get_static(struct debconfclient *client)
{
char *nameservers = NULL;
char *ptr, ptr1[INET_ADDRSTRLEN];
char *none;

enum { BACKUP, GET_IPADDRESS, GET_POINTOPOINT, GET_NETMASK, GET_GATEWAY,
GATEWAY_UNREACHABLE, GET_NAMESERVERS, CONFIRM, GET_DOMAIN, QUIT } state = GET_IPADDRESS;

ipaddress.s_addr = network.s_addr = broadcast.s_addr = netmask.s_addr = gateway.s_addr = pointopoint.s_addr =
0;

debconf_metaget(client, "netcfg/internal-none", "description");
none = client->value ? strdup(client->value) : strdup("<none>");

while (state != QUIT) {
switch (state) {
case BACKUP:
return 10; /* Back to main */
break;
case GET_IPADDRESS:
if (netcfg_get_ipaddress (client)) {
state = BACKUP;
} else {
if (strncmp(interface, "plip", 4) == 0
|| strncmp(interface, "slip", 4) == 0
|| strncmp(interface, "ctc", 3) == 0
|| strncmp(interface, "escon", 5) == 0)
state = GET_POINTOPOINT;
else
state = GET_NETMASK;
}
break;
case GET_POINTOPOINT:
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.s_addr && ((gateway.s_addr & netmask.s_addr) != network.s_addr))
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_DOMAIN;
break;
case GET_DOMAIN:
state = (netcfg_get_domain (client, &domain)) ?
GET_NAMESERVERS : CONFIRM;
break;
case CONFIRM:
debconf_subst(client, "netcfg/confirm_static", "interface", interface);
debconf_subst(client, "netcfg/confirm_static", "ipaddress",
(ipaddress.s_addr ? inet_ntop (AF_INET, &ipaddress, ptr1, sizeof (ptr1)) : none));
debconf_subst(client, "netcfg/confirm_static", "pointopoint",
(pointopoint.s_addr ? inet_ntop (AF_INET, &pointopoint, ptr1, sizeof (ptr1)) : none));
debconf_subst(client, "netcfg/confirm_static", "netmask",
(netmask.s_addr ? inet_ntop (AF_INET, &netmask, ptr1, sizeof (ptr1)) : none));
debconf_subst(client, "netcfg/confirm_static", "gateway",
(gateway.s_addr ? inet_ntop (AF_INET, &gateway, ptr1, sizeof (ptr1)) : 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_IPADDRESS;
debconf_capb(client, "backup");
break;
case QUIT:
return 0;
break;
}
}
return 0;
}


+ 229
- 0
wireless.c View File

@@ -0,0 +1,229 @@
/* Wireless support using iwlib for netcfg.
* (C) 2004 Joshua Kwan, Bastian Blank
*
* Licensed under the GNU General Public License
*/

#include "netcfg.h"
#include <iwlib.h>
#include <sys/types.h>
#include <assert.h>

/* Wireless mode */
wifimode_t mode = MANAGED;

/* wireless config */
char* wepkey = NULL;
char* essid = NULL;

/* IW socket for global use - init in main */
int wfd = 0;

int is_wireless_iface (const char* iface)
{
wireless_config wc;

if (wfd == 0)
wfd = iw_sockets_open();
return (iw_get_basic_config (wfd, (char*)iface, &wc) == 0);
}

int netcfg_wireless_set_essid (struct debconfclient * client, char *iface)
{
int ret, couldnt_associate = 0;
wireless_config wconf;
char* tf = NULL, *user_essid = NULL, *ptr = wconf.essid;

if (wfd == 0) /* shouldn't happen */
wfd = iw_sockets_open();

iw_get_basic_config (wfd, iface, &wconf);

debconf_subst(client, "netcfg/wireless_essid", "iface", iface);
debconf_subst(client, "netcfg/wireless_adhoc_managed", "iface", iface);

debconf_input(client, "low", "netcfg/wireless_adhoc_managed");

if (debconf_go(client) == 30)
return GO_BACK;

debconf_get(client, "netcfg/wireless_adhoc_managed");

if (!strcmp(client->value, "Ad-hoc network (Peer to peer)"))
mode = ADHOC;

wconf.has_mode = 1;
wconf.mode = mode;

debconf_input(client, "low", "netcfg/wireless_essid");

if (debconf_go(client) == 30)
return GO_BACK;

debconf_get(client, "netcfg/wireless_essid");
tf = strdup(client->value);

automatic:
/* question not asked or user doesn't care or we're successfully associated */
if (!empty_str(wconf.essid) || empty_str(client->value))
{
int i, success = 0;

/* Default to any AP */
wconf.essid[0] = '\0';
wconf.essid_on = 0;

iw_set_basic_config (wfd, iface, &wconf);

/* Wait for association.. (MAX_SECS seconds)*/
#define MAX_SECS 3

debconf_progress_start(client, 0, MAX_SECS, "netcfg/wifi_progress_title");
debconf_progress_info(client, "netcfg/wifi_progress_info");

for (i = 0; i <= MAX_SECS; i++)
{
ifconfig_up(iface);
sleep (1);
iw_get_basic_config (wfd, iface, &wconf);

if (!empty_str(wconf.essid))
{
/* Save for later */
debconf_set(client, "netcfg/wireless_essid", wconf.essid);
debconf_progress_set(client, MAX_SECS);
success = 1;
break;
}

debconf_progress_step(client, 1);
ifconfig_down(iface);
}

debconf_progress_stop(client);

if (success)
return 0;

couldnt_associate = 1;
}
/* yes, wants to set an essid by himself */

if (strlen(tf) <= IW_ESSID_MAX_SIZE) /* looks ok, let's use it */
user_essid = tf;

while (!user_essid || empty_str(user_essid) ||
strlen(user_essid) > IW_ESSID_MAX_SIZE)
{
/* Misnomer of a check. Basically, if we went through autodetection,
* we want to enter this loop, but we want to suppress anything that
* relied on the checking of tf/user_essid (i.e. "", in most cases.) */
if (!couldnt_associate)
{
debconf_subst(client, "netcfg/invalid_essid", "essid", user_essid);
debconf_input(client, "high", "netcfg/invalid_essid");
debconf_go(client);
}

ret = debconf_input(client,
couldnt_associate ? "critical" : "low",
"netcfg/wireless_essid");
/* But now we'd not like to suppress any MORE errors */
couldnt_associate = 0;
/* we asked the question once, why can't we ask it again? */
assert (ret != 30);

if (debconf_go(client) == 30) /* well, we did, but he wants to go back */
return GO_BACK;

debconf_get(client, "netcfg/wireless_essid");

if (empty_str(client->value))
goto automatic;

free(user_essid);
user_essid = strdup(client->value);
}

essid = user_essid;

memset(ptr, 0, IW_ESSID_MAX_SIZE + 1);
snprintf(wconf.essid, IW_ESSID_MAX_SIZE + 1, "%s", essid);
wconf.has_essid = 1;
wconf.essid_on = 1;

iw_set_basic_config (wfd, iface, &wconf);

return 0;
}

void unset_wep_key (char* iface)
{
wireless_config wconf;
int ret;

if (!wfd)
wfd = iw_sockets_open();

iw_get_basic_config(wfd, iface, &wconf);

wconf.has_key = 1;
wconf.key[0] = '\0';
wconf.key_flags = IW_ENCODE_DISABLED | IW_ENCODE_NOKEY;
wconf.key_size = 0;

ret = iw_set_basic_config (wfd, iface, &wconf);
}

int netcfg_wireless_set_wep (struct debconfclient * client, char* iface)
{
wireless_config wconf;
char* rv = NULL;
int ret, keylen;
unsigned char buf [IW_ENCODING_TOKEN_MAX];
iw_get_basic_config (wfd, iface, &wconf);

debconf_subst(client, "netcfg/wireless_wep", "iface", iface);
ret = my_debconf_input (client, "high", "netcfg/wireless_wep", &rv);

if (ret == 30)
return GO_BACK;

if (empty_str(rv))
{
unset_wep_key (iface);

if (wepkey != NULL)
{
free(wepkey);
wepkey = NULL;
}
return 0;
}

while ((keylen = iw_in_key (rv, buf)) == -1)
{
debconf_subst(client, "netcfg/invalid_wep", "wepkey", rv);
debconf_input(client, "high", "netcfg/invalid_wep");
debconf_go(client);
ret = my_debconf_input (client, "high", "netcfg/wireless_wep", &rv);
}

wconf.has_key = 1;
wconf.key_size = keylen;
wconf.key_flags = IW_ENCODE_ENABLED | IW_ENCODE_OPEN;
strncpy (wconf.key, buf, keylen);

wepkey = strdup(rv);

iw_set_basic_config (wfd, iface, &wconf);

return 0;
}

Loading…
Cancel
Save