/* SmoothWall setup program.
 *
 * This program is distributed under the terms of the GNU General Public
 * Licence.  See the file COPYING for details.
 *
 * (c) Lawrence Manning, 2001
 * The big one: networking. 
 * 
 */
 
#include "setup.h"

#define DNS1 0
#define DNS2 1
#define DEFAULT_GATEWAY 2
#define DNSGATEWAY_TOTAL 3

extern FILE *flog;
extern char *mylog;

extern char **ctr;

extern int automode;

#define HAS_GREEN 1
#define HAS_RED (configtype == 1 || configtype == 2 || configtype == 3 || configtype == 4)
#define HAS_ORANGE (configtype == 2 || configtype == 4)
#define HAS_BLUE (configtype == 3 || configtype == 4)
#define RED_IS_NOT_ETH (configtype == 0)

extern struct nic nics[];
extern struct knic knics[];

char *configtypenames[] = {
	"GREEN + RED",
	"GREEN + RED + ORANGE",
	"GREEN + RED + BLUE",
	"GREEN + RED + ORANGE + BLUE",
	NULL };
int configtypecards[] = {
	2,	// "GREEN + RED",
	3,	// "GREEN + RED + ORANGE",
	3, 	// "GREEN + RED + BLUE",
	4	  // "GREEN + RED + ORANGE + BLUE",
};


int netaddresschange;

int oktoleave(void);
int firstmenu(void);
int configtypemenu(void);
int drivermenu(void);
int changedrivers(void);
int greenaddressmenu(void);
int addressesmenu(void);
int dnsgatewaymenu(void);

int handlenetworking(void)
{
	int done;
	int choice;
	int found;
	
	netaddresschange = 0;

	found =	scan_network_cards();
	found = init_knics();

	done = 0;
	while (!done)
	{
		choice = firstmenu();
			
		switch (choice)
		{
			case 1:
				configtypemenu();
				break;

			case 2:
				drivermenu();
				break;
							
			case 3:
				addressesmenu();
				break;
			
			case 4:
				dnsgatewaymenu();
				break;
				
			case 0:
				if (oktoleave()) done = 1;
				break;
				
			default:
				break;
		}				
	}

	if (automode == 0)
	{
		/* Restart networking! */	
		if (netaddresschange)
		{
			runcommandwithstatus("/etc/rc.d/init.d/network stop",
				ctr[TR_PUSHING_NETWORK_DOWN]);

			rename_nics();

			runcommandwithstatus("/etc/rc.d/init.d/network start",
				ctr[TR_PULLING_NETWORK_UP]);
		}
	}
	create_udev();
	return 1;
}

int oktoleave(void)
{
	struct keyvalue *kv = initkeyvalues();
	char temp[STRING_SIZE];
	int configtype;
	int rc;
	
	if (!(readkeyvalues(kv, CONFIG_ROOT "/ethernet/settings")))
	{
		freekeyvalues(kv);
		errorbox(ctr[TR_UNABLE_TO_OPEN_SETTINGS_FILE]);
		return 0;
	}	

	strcpy(temp, "1"); findkey(kv, "CONFIG_TYPE", temp); configtype = atol(temp);
	if (configtype < 1 || configtype > 4) configtype = 1;

	if (HAS_GREEN)
	{
		strcpy(temp, ""); findkey(kv, "GREEN_DEV", temp);
		if (!(strlen(temp)))
		{
			errorbox(ctr[TR_NO_GREEN_INTERFACE]);
			freekeyvalues(kv);
			return 0;
		}
		if (!(interfacecheck(kv, "GREEN")))
		{
			errorbox(ctr[TR_MISSING_GREEN_IP]);
			freekeyvalues(kv);
			return 0;
		}
	}
	if (HAS_RED)
	{

		strcpy(temp, ""); findkey(kv, "RED_DEV", temp);
		if (!(strlen(temp)))
		{
			rc = newtWinChoice(ctr[TR_ERROR], ctr[TR_OK], ctr[TR_IGNORE], ctr[TR_NO_RED_INTERFACE]);
			if (rc == 0 || rc == 1)
			{
				freekeyvalues(kv);
				return 0;
			}
		}
		if (!(interfacecheck(kv, "RED")))
		{
			errorbox(ctr[TR_MISSING_RED_IP]);
			freekeyvalues(kv);
			return 0;
		}
	}
	if (HAS_ORANGE)
	{
		strcpy(temp, ""); findkey(kv, "ORANGE_DEV", temp);
		if (!(strlen(temp)))
		{
			errorbox(ctr[TR_NO_ORANGE_INTERFACE]);
			freekeyvalues(kv);
			return 0;
		}
		if (!(interfacecheck(kv, "ORANGE")))
		{
			errorbox(ctr[TR_MISSING_ORANGE_IP]);
			freekeyvalues(kv);
			return 0;
		}
	}
	if (HAS_BLUE)
	{
		strcpy(temp, ""); findkey(kv, "BLUE_DEV", temp);
		if (!(strlen(temp)))
		{
			errorbox(ctr[TR_NO_BLUE_INTERFACE]);
			freekeyvalues(kv);
			return 0;
		}
		if (!(interfacecheck(kv, "BLUE")))
		{
			errorbox(ctr[TR_MISSING_BLUE_IP]);
			freekeyvalues(kv);
			return 0;
		}
	}
	
	strcpy(temp, ""); findkey(kv, "RED_TYPE", temp);
	if ((configtype == 0) || (strcmp(temp, "STATIC") == 0))
	{
		strcpy(temp, ""); findkey(kv, "DNS1", temp);
		if (!(strlen(temp)))
		{
			errorbox(ctr[TR_MISSING_DNS]);
			freekeyvalues(kv);
			return 0;
		}
		strcpy(temp, ""); findkey(kv, "DEFAULT_GATEWAY", temp);
		if (!(strlen(temp)))
		{
			errorbox(ctr[TR_MISSING_DEFAULT]);
			freekeyvalues(kv);
			return 0;
		}
	}
	return 1;
}

	
/* Shows the main menu and a summary of the current settings. */
int firstmenu(void)
{
	char *sections[] = { ctr[TR_NETWORK_CONFIGURATION_TYPE],
		ctr[TR_DRIVERS_AND_CARD_ASSIGNMENTS],
		ctr[TR_ADDRESS_SETTINGS],
		ctr[TR_DNS_AND_GATEWAY_SETTINGS], NULL };
	int rc;
	static int choice = 0;
	struct keyvalue *kv = initkeyvalues();
	char message[1000];
	char temp[STRING_SIZE] = "1";
	int x;
	int result;
	char networkrestart[STRING_SIZE] = "";
	
	if (!(readkeyvalues(kv, CONFIG_ROOT "/ethernet/settings")))
	{
		freekeyvalues(kv);
		errorbox(ctr[TR_UNABLE_TO_OPEN_SETTINGS_FILE]);
		return 0;
	}	

	if (netaddresschange) 
		strcpy(networkrestart, ctr[TR_RESTART_REQUIRED]);

	strcpy(temp, ""); findkey(kv, "CONFIG_TYPE", temp); 
	x = atol(temp);
	x--;
	if (x < 0 || x > 4) x = 0;
	/* Format heading bit. */
	snprintf(message, 1000, ctr[TR_CURRENT_CONFIG], configtypenames[x],
		networkrestart);
	rc = newtWinMenu(ctr[TR_NETWORK_CONFIGURATION_MENU], message, 50, 5, 5, 6,
			sections, &choice, ctr[TR_OK], ctr[TR_DONE], NULL);

	if (rc == 0 || rc == 1)
		result = choice + 1;
	else
		result = 0;

	return result;
}

/* Here they choose general network config, number of nics etc. */
int configtypemenu(void)
{
	struct keyvalue *kv = initkeyvalues();
	char temp[STRING_SIZE] = "1";
	char message[1000];
	int choise, found;
	int rc, configtype;

	if (!(readkeyvalues(kv, CONFIG_ROOT "/ethernet/settings")))
	{
		freekeyvalues(kv);
		errorbox(ctr[TR_UNABLE_TO_OPEN_SETTINGS_FILE]);
		return 0;
	}

	found = scan_network_cards();
	
	findkey(kv, "CONFIG_TYPE", temp); choise = atol(temp);
	choise--;

		sprintf(message, ctr[TR_NETWORK_CONFIGURATION_TYPE_LONG], NAME);
		rc = newtWinMenu(ctr[TR_NETWORK_CONFIGURATION_TYPE], message, 50, 5, 5,
			6, configtypenames, &choise, ctr[TR_OK], ctr[TR_CANCEL], NULL);
		if ( configtypecards[choise] > found ) {
			sprintf(message, ctr[TR_NOT_ENOUGH_INTERFACES] , configtypecards[choise], found);
			errorbox(message);
		}

	if (rc == 0 || rc == 1)
	{
		choise++;
		sprintf(temp, "%d", choise);
		replacekeyvalue(kv, "CONFIG_TYPE", temp);
		configtype = atol(temp);
		if (!HAS_RED)
			clear_card_entry(_RED_CARD_);
		if (!HAS_ORANGE)
			clear_card_entry(_ORANGE_CARD_);
		if (!HAS_BLUE)
			clear_card_entry(_BLUE_CARD_);

		writekeyvalues(kv, CONFIG_ROOT "/ethernet/settings");
		netaddresschange = 1;
	}
	freekeyvalues(kv);
	
	return 0;
}

/* Driver menu.  Choose drivers.. */
int drivermenu(void)
{
	struct keyvalue *kv = initkeyvalues();
	char message[STRING_SIZE];
	char temp[STRING_SIZE] = "1";

	int configtype;
	int i, rc, kcount = 0, neednics;

	if (!(readkeyvalues(kv, CONFIG_ROOT "/ethernet/settings")))
	{
		freekeyvalues(kv);
		errorbox(ctr[TR_UNABLE_TO_OPEN_SETTINGS_FILE]);
		return 0;
	}

	if (findkey(kv, "CONFIG_TYPE", temp))
		configtype = atol(temp);
	else {
		fprintf(flog,"setting CONFIG_TYPE = %s\n",temp);
		configtype = atol(temp);
		replacekeyvalue(kv, "CONFIG_TYPE", temp);
		writekeyvalues(kv, CONFIG_ROOT "/ethernet/settings");
	}

	strcpy(message, ctr[TR_CONFIGURE_NETWORK_DRIVERS]);

	kcount = 0;
	neednics = 0;
	if (HAS_GREEN) {
		sprintf(temp, "GREEN:  %s\n", knics[_GREEN_CARD_].description);
		strcat(message, temp);
		if (strlen(knics[_GREEN_CARD_].macaddr) ) {
			sprintf(temp, "GREEN:  (%s) %s green0\n", knics[_GREEN_CARD_].macaddr, ctr[TR_AS]);
			strcat(message, temp);
		}
		neednics++;
	}
	if (HAS_RED) {
		sprintf(temp, "RED:    %s\n", knics[_RED_CARD_].description);
		strcat(message, temp);
		if (strlen(knics[_RED_CARD_].macaddr) ) {
			sprintf(temp, "RED:    (%s) %s red0\n", knics[_RED_CARD_].macaddr, ctr[TR_AS]);
			strcat(message, temp);
		}
		neednics++;
	}
	if (HAS_ORANGE) {
		sprintf(temp, "ORANGE: %s\n", knics[_ORANGE_CARD_].description);
		strcat(message, temp);
		if ( strlen(knics[_ORANGE_CARD_].macaddr) ) {
			sprintf(temp, "ORANGE: (%s) %s orange0\n", knics[_ORANGE_CARD_].macaddr, ctr[TR_AS]);
			strcat(message, temp);
		}
		neednics++;
	}
	if (HAS_BLUE) {
		sprintf(temp, "BLUE:   %s\n", knics[_BLUE_CARD_].description);
		strcat(message, temp);
		if (strlen(knics[_BLUE_CARD_].macaddr)) {
			sprintf(temp, "BLUE:   (%s) %s blue0\n", knics[_BLUE_CARD_].macaddr, ctr[TR_AS]);
			strcat(message, temp);
		}
		neednics++;
	}

	for ( i=0 ; i<4; i++)
		if (strcmp(knics[i].macaddr, ""))
			kcount++;

	if (neednics = kcount)
	{
		strcat(message, ctr[TR_DO_YOU_WISH_TO_CHANGE_THESE_SETTINGS]);
		rc = newtWinChoice(ctr[TR_DRIVERS_AND_CARD_ASSIGNMENTS], ctr[TR_OK],
		ctr[TR_CANCEL], message);
		if (rc == 0 || rc == 1)
		{
			changedrivers();
		}
	} else {
		changedrivers();
	}
	freekeyvalues(kv);

	return 1;
}

int set_menu_entry_for(int *nr, int *card)
{

}

int changedrivers(void)
{
	struct keyvalue *kv = initkeyvalues();
	char temp[STRING_SIZE], message[STRING_SIZE];
	int configtype;
	int green = 0, red = 0, blue = 0, orange = 0;
	char MenuInhalt[10][180];
	char *pMenuInhalt[10];
	int count = 0, choise = 0, rc;
	int NicEntry[10];

	if (!(readkeyvalues(kv, CONFIG_ROOT "/ethernet/settings")))
	{
		freekeyvalues(kv);
		errorbox(ctr[TR_UNABLE_TO_OPEN_SETTINGS_FILE]);
		return 0;
	}
	if (automode == 0)
		runcommandwithstatus("/etc/rc.d/init.d/network stop red blue orange",
			ctr[TR_PUSHING_NON_LOCAL_NETWORK_DOWN]);

	findkey(kv, "CONFIG_TYPE", temp); configtype = atol(temp);
	if (configtype == 1)
		{ green = 1; red = 1; }
	else if (configtype == 2)
		{ green = 1; red = 1; orange = 1; }
	else if (configtype == 3)
		{ green = 1; red = 1; blue = 1; }
	else if (configtype == 4)
		{ green = 1; red=1; orange=1; blue = 1; }
	else if (configtype == "")
	  { green = 1; red = 1; }

	do
	{
		count = 0;
		strcpy(message, ctr[TR_INTERFACE_CHANGE]);

		if (green) {
			strcpy(MenuInhalt[count], "GREEN");
			pMenuInhalt[count] = MenuInhalt[count];
			NicEntry[_GREEN_CARD_] = count;
			sprintf(temp, "GREEN:  %s\n", knics[_GREEN_CARD_].description);
			strcat(message, temp);
			if ( strlen(knics[_GREEN_CARD_].macaddr) ) {
				sprintf(temp, "GREEN:  (%s) %s green0\n", knics[_GREEN_CARD_].macaddr, ctr[TR_AS]);
				strcat(message, temp);
			}
			count++;
		}

		if (red) {
			strcpy(MenuInhalt[count], "RED");
			pMenuInhalt[count] = MenuInhalt[count];
			NicEntry[_RED_CARD_] = count;
			sprintf(temp, "RED:    %s\n", knics[_RED_CARD_].description);
			strcat(message, temp);
			if ( strlen(knics[_RED_CARD_].macaddr) ) {
				sprintf(temp, "RED:    (%s) %s red0\n", knics[_RED_CARD_].macaddr, ctr[TR_AS]);
				strcat(message, temp);
			}
			count++;
		}

		if (orange) {
			strcpy(MenuInhalt[count], "ORANGE");
			pMenuInhalt[count] = MenuInhalt[count];
			NicEntry[_ORANGE_CARD_] = count;
			sprintf(temp, "ORANGE: %s\n", knics[_ORANGE_CARD_].description);
			strcat(message, temp);
			if ( strlen(knics[_ORANGE_CARD_].macaddr) ) {
				sprintf(temp, "ORANGE: (%s) %s orange0\n", knics[_ORANGE_CARD_].macaddr, ctr[TR_AS]);
				strcat(message, temp);
			}
			count++;
		}

		if (blue) {
			strcpy(MenuInhalt[count], "BLUE");
			pMenuInhalt[count] = MenuInhalt[count];
			NicEntry[_BLUE_CARD_] = count;
			sprintf(temp, "BLUE:   %s\n", knics[_BLUE_CARD_].description);
			strcat(message, temp);
			if ( strlen(knics[_BLUE_CARD_].macaddr) ) {
				sprintf(temp, "BLUE:   (%s) %s blue0\n", knics[_BLUE_CARD_].macaddr, ctr[TR_AS]);
				strcat(message, temp);
			}
			count++;
		}
		pMenuInhalt[count] = NULL;

		rc = newtWinMenu( ctr[TR_NETCARD_COLOR], message, 70, 5, 5, 6, pMenuInhalt, &choise, ctr[TR_SELECT], ctr[TR_REMOVE], ctr[TR_DONE], NULL);
			
		if ( rc == 0 || rc == 1) {
			if ((green) && ( choise == NicEntry[0])) nicmenu(_GREEN_CARD_);
			if ((red) && ( choise == NicEntry[1])) nicmenu(_RED_CARD_);
			if ((orange) && ( choise == NicEntry[2])) nicmenu(_ORANGE_CARD_);
			if ((blue) && ( choise == NicEntry[3])) nicmenu(_BLUE_CARD_);
			netaddresschange = 1;
		} else if (rc == 2) {
			if ((green) && ( choise == NicEntry[0])) ask_clear_card_entry(_GREEN_CARD_);
			if ((red) && ( choise == NicEntry[1])) ask_clear_card_entry(_RED_CARD_);
			if ((orange) && ( choise == NicEntry[2])) ask_clear_card_entry(_ORANGE_CARD_);
			if ((blue) && ( choise == NicEntry[3])) ask_clear_card_entry(_BLUE_CARD_);
			netaddresschange = 1;
		}
	}
	while ( rc <= 2);

	freekeyvalues(kv);
	return 1;
}

// Let user change GREEN address.
int greenaddressmenu(void)
{
	struct keyvalue *kv = initkeyvalues();
	char message[1000];
	int rc;
	
	if (!(readkeyvalues(kv, CONFIG_ROOT "/ethernet/settings")))
	{
		freekeyvalues(kv);
		errorbox(ctr[TR_UNABLE_TO_OPEN_SETTINGS_FILE]);
		return 0;
	}

	sprintf(message, ctr[TR_WARNING_LONG], NAME);
	rc = newtWinChoice(ctr[TR_WARNING], ctr[TR_OK], ctr[TR_CANCEL], message);
	
	if (rc == 0 || rc == 1)
	{
		if (changeaddress(kv, "GREEN", 0, ""))
		{
			netaddresschange = 1;
			writekeyvalues(kv, CONFIG_ROOT "/ethernet/settings");			
			writehostsfiles();			
		}
	}
	
	freekeyvalues(kv);

	return 0;
}

// They can change BLUE, ORANGE and GREEN too :)
int addressesmenu(void)
{
	struct keyvalue *kv = initkeyvalues();
	struct keyvalue *mainkv = initkeyvalues();
	int rc = 0;
	char *sections[5];
	char *green = "GREEN";
	char *orange = "ORANGE";
	char *blue = "BLUE";
	char *red = "RED";
	int c = 0;
	char greenaddress[STRING_SIZE];
	char oldgreenaddress[STRING_SIZE];
	char temp[STRING_SIZE];
	char temp2[STRING_SIZE];
	char message[1000];
	int configtype;
	int done;
	int choice;
	char hostname[STRING_SIZE];
	
	if (!(readkeyvalues(kv, CONFIG_ROOT "/ethernet/settings")))
	{
		freekeyvalues(kv);
		freekeyvalues(mainkv);
		errorbox(ctr[TR_UNABLE_TO_OPEN_SETTINGS_FILE]);
		return 0;
	}
	if (!(readkeyvalues(mainkv, CONFIG_ROOT "/main/settings")))
	{
		freekeyvalues(kv);
		freekeyvalues(mainkv);
		errorbox(ctr[TR_UNABLE_TO_OPEN_SETTINGS_FILE]);
		return 0;
	}

	strcpy(temp, "0"); findkey(kv, "CONFIG_TYPE", temp);
	configtype = atol(temp);
	
	sections[c] = green;
	c++;
	if (HAS_BLUE)
	{
		sections[c] = blue;
		c++;
	}
	if (HAS_ORANGE)
	{
		sections[c] = orange;
		c++;
	}
	if (HAS_RED)
	{
		sections[c] = red;
		c++;
	}
	sections[c] = NULL;

	choice = 0;	
	done = 0;	
	while (!done)
	{
		rc = newtWinMenu(ctr[TR_ADDRESS_SETTINGS],
			ctr[TR_SELECT_THE_INTERFACE_YOU_WISH_TO_RECONFIGURE], 50, 5,
			5, 6, sections, &choice, ctr[TR_OK], ctr[TR_DONE], NULL);	

		if (rc == 0 || rc == 1)
		{
			if (strcmp(sections[choice], "GREEN") == 0)
			{
				findkey(kv, "GREEN_ADDRESS", oldgreenaddress);
				sprintf(message, ctr[TR_WARNING_LONG], NAME);
				rc = newtWinChoice(ctr[TR_WARNING], ctr[TR_OK], ctr[TR_CANCEL],
					message);
				if (rc == 0 || rc == 1)
				{
					if (changeaddress(kv, "GREEN", 0, ""))
					{
						netaddresschange = 1;
						writekeyvalues(kv, CONFIG_ROOT "/ethernet/settings");
						writehostsfiles();
						findkey(kv, "GREEN_ADDRESS", greenaddress);
						snprintf(temp, STRING_SIZE-1, "option routers %s", oldgreenaddress);
						snprintf(temp2, STRING_SIZE-1, "option routers %s", greenaddress);
						replace (CONFIG_ROOT "/dhcp/dhcpd.conf", temp, temp2);
						chown  (CONFIG_ROOT "/dhcp/dhcpd.conf", 99, 99);
					}
				}
			}
			if (strcmp(sections[choice], "BLUE") == 0)
			{
				if (changeaddress(kv, "BLUE", 0, ""))
					netaddresschange = 1;
			}
			if (strcmp(sections[choice], "ORANGE") == 0)
			{
				if (changeaddress(kv, "ORANGE", 0, ""))
					netaddresschange = 1;
			}
			if (strcmp(sections[choice], "RED") == 0)
			{
				strcpy(hostname, "");
				findkey(mainkv, "HOSTNAME", hostname);
				if (changeaddress(kv, "RED", 1, hostname))
					netaddresschange = 1;
			}
		}
		else
			done = 1;
	}
	
	writekeyvalues(kv, CONFIG_ROOT "/ethernet/settings");
	freekeyvalues(kv);
	freekeyvalues(mainkv);
	
	return 0;
}

/* DNS and default gateway.... */
int dnsgatewaymenu(void)
{
	struct keyvalue *kv = initkeyvalues();
	char message[1000];
	char temp[STRING_SIZE] = "0";
	struct newtWinEntry entries[DNSGATEWAY_TOTAL+1];
	char *values[DNSGATEWAY_TOTAL];         /* pointers for the values. */
	int error;
	int configtype;
	int rc;

	if (!(readkeyvalues(kv, CONFIG_ROOT "/ethernet/settings")))
	{
		freekeyvalues(kv);
		errorbox(ctr[TR_UNABLE_TO_OPEN_SETTINGS_FILE]);
		return 0;
	}

	entries[DNS1].text = ctr[TR_PRIMARY_DNS];
	strcpy(temp, ""); findkey(kv, "DNS1", temp);
	values[DNS1] = strdup(temp);
	entries[DNS1].value = &values[DNS1];
	entries[DNS1].flags = 0;
	
	entries[DNS2].text = ctr[TR_SECONDARY_DNS];
	strcpy(temp, ""); findkey(kv, "DNS2", temp);
	values[DNS2] = strdup(temp);
	entries[DNS2].value = &values[DNS2];
	entries[DNS2].flags = 0;
	
	entries[DEFAULT_GATEWAY].text = ctr[TR_DEFAULT_GATEWAY];
	strcpy(temp, ""); findkey(kv, "DEFAULT_GATEWAY", temp);
	values[DEFAULT_GATEWAY] = strdup(temp);
	entries[DEFAULT_GATEWAY].value = &values[DEFAULT_GATEWAY];
	entries[DEFAULT_GATEWAY].flags = 0;
	
	entries[DNSGATEWAY_TOTAL].text = NULL;
	entries[DNSGATEWAY_TOTAL].value = NULL;
	entries[DNSGATEWAY_TOTAL].flags = 0;
	
	do
	{
		error = 0;
		
		rc = newtWinEntries(ctr[TR_DNS_AND_GATEWAY_SETTINGS], 
			ctr[TR_DNS_AND_GATEWAY_SETTINGS_LONG], 50, 5, 5, 18, entries,
			ctr[TR_OK], ctr[TR_CANCEL], NULL);
		if (rc == 0 || rc == 1)
		{
			strcpy(message, ctr[TR_INVALID_FIELDS]);
			if (strlen(values[DNS1]))
			{
				if (inet_addr(values[DNS1]) == INADDR_NONE)
				{
					strcat(message, ctr[TR_PRIMARY_DNS_CR]);
					error = 1;
				}
			}
			if (strlen(values[DNS2]))
			{
				if (inet_addr(values[DNS2]) == INADDR_NONE)
				{
					strcat(message, ctr[TR_SECONDARY_DNS_CR]);
					error = 1;
				}
			}
			if (strlen(values[DEFAULT_GATEWAY]))
			{
				if (inet_addr(values[DEFAULT_GATEWAY]) == INADDR_NONE)
				{
					strcat(message, ctr[TR_DEFAULT_GATEWAY_CR]);
					error = 1;
				}
			}
			if (!strlen(values[DNS1]) && strlen(values[DNS2]))
			{
				strcpy(message, ctr[TR_SECONDARY_WITHOUT_PRIMARY_DNS]);
				error = 1;
			}

			if (error)
				errorbox(message);
			else
			{
				replacekeyvalue(kv, "DNS1", values[DNS1]);
				replacekeyvalue(kv, "DNS2", values[DNS2]);
				replacekeyvalue(kv, "DEFAULT_GATEWAY", values[DEFAULT_GATEWAY]);
				netaddresschange = 1;
				free(values[DNS1]);
				free(values[DNS2]);
				free(values[DEFAULT_GATEWAY]);
				writekeyvalues(kv, CONFIG_ROOT "/ethernet/settings");
			}
		}
	}
	while (error);
	
	freekeyvalues(kv);
	
	return 1;
}			
