/* Created with PageBuilder version 4.04 on Mon Mar  6 17:39:56 2006 */

#include "AsExtern.h"
#include <boardParams.h>
#include <sockapi.h>
#include <iam_netos.hh>
#include "iam.hh"
#include "webutil.h"
#include "session.h"
#include "webmenu.h"
#include "dnsc_api.h"
#include <narmapi.h>

#if RomPagerServer


extern rpObjectDescription Pgnetwork_config;
extern rpObjectDescription Pgreboot;

#define NETWORK_CONFIG_ID &Pgnetwork_config
#define MAX_DNS_ENTRIES         2

enum {
    dhcp_enabled, dhcp_disabled
};


// Page Cache
typedef struct {
	devBoardParamsType nvParams;
	NaIamIfAddrInfo_t addrInfo;
    rpOneOfSeveral dhcp;
	unsigned char ipv6IsEnabled;
	unsigned char ipv6PrefixLen;
    char ipAddress[ROMPAGER_IP_ARRAY_LENGTH];
    char subMask[ROMPAGER_IP_ARRAY_LENGTH];
    char gateway[ROMPAGER_IP_ARRAY_LENGTH];
    char primaryDns[ROMPAGER_IP_ARRAY_LENGTH];
    char secondaryDns[ROMPAGER_IP_ARRAY_LENGTH];
    char ipv6Address[MAX_IP_ADDR_STR_LEN];
    char ipv6Gateway[MAX_IP_ADDR_STR_LEN];

} NetworkPgCache;

NetworkPgCache *getNetworkPageCache(void *theTaskDataPtr)
{    
    SessionCache *sess = getSessionCache(theTaskDataPtr);
    if (isPageCacheEmpty(sess) || !isSessionCacheID(sess, NETWORK_CONFIG_ID))
        setPageCache(sess, malloc(sizeof(NetworkPgCache)), NETWORK_CONFIG_ID);
    return (NetworkPgCache *) getPageCache(sess, NETWORK_CONFIG_ID);
}


/* ********************************************** */
/* *    Built from "html\network_config.htm"    * */
/* ********************************************** */

extern char *network_getProductName(void *theTaskDataPtr, char *theNamePtr,
		Signed16Ptr theIndexValuesPtr);
char *network_getProductName(void *theTaskDataPtr, char *theNamePtr,
		Signed16Ptr theIndexValuesPtr) {
	char * theResult;

    theResult = html_getProductName();

	return theResult;
}

extern char *network_GetMessageText(void *theTaskDataPtr, char *theNamePtr,
		Signed16Ptr theIndexValuesPtr);
char *network_GetMessageText(void *theTaskDataPtr, char *theNamePtr,
		Signed16Ptr theIndexValuesPtr) {
	char * theResult;
    theResult = session_getMessageText(theTaskDataPtr, theNamePtr, theIndexValuesPtr);

	return theResult;
}

extern void network_repeatWhileMoreStatusMessages(void *theTaskDataPtr, Signed16Ptr theIndexPtr,
		void **theRepeatGroupValuePtr);
void network_repeatWhileMoreStatusMessages(void *theTaskDataPtr, Signed16Ptr theIndexPtr,
		void **theRepeatGroupValuePtr) {

    session_repeatWhileMoreStatusMessages(theTaskDataPtr, theIndexPtr, theRepeatGroupValuePtr);
}

extern void network_repeatWhileMoreErrorMessages(void *theTaskDataPtr, Signed16Ptr theIndexPtr,
		void **theRepeatGroupValuePtr);
void network_repeatWhileMoreErrorMessages(void *theTaskDataPtr, Signed16Ptr theIndexPtr,
		void **theRepeatGroupValuePtr) {

    session_repeatWhileMoreErrorMessages(theTaskDataPtr, theIndexPtr, theRepeatGroupValuePtr);
}


extern char *network_getMenuItemUrl(void *theTaskDataPtr, char *theNamePtr,
		Signed16Ptr theIndexValuesPtr);
char *network_getMenuItemUrl(void *theTaskDataPtr, char *theNamePtr,
		Signed16Ptr theIndexValuesPtr) {
    return webMenu_getMenuItemUrl(theTaskDataPtr, theNamePtr, theIndexValuesPtr);
}

extern char *network_getMenuItemName(void *theTaskDataPtr, char *theNamePtr,
		Signed16Ptr theIndexValuesPtr);
char *network_getMenuItemName(void *theTaskDataPtr, char *theNamePtr,
		Signed16Ptr theIndexValuesPtr) {

    return webMenu_getMenuItemName(theTaskDataPtr, theNamePtr, theIndexValuesPtr);
}

extern void network_getMenuListWhile(void *theTaskDataPtr, Signed16Ptr theIndexPtr,
		void **theRepeatGroupValuePtr);
void network_getMenuListWhile(void *theTaskDataPtr, Signed16Ptr theIndexPtr,
		void **theRepeatGroupValuePtr) {

    webMenu_getMenuListWhile(theTaskDataPtr, theIndexPtr, theRepeatGroupValuePtr);
	
	return;
}

extern rpOneOfSeveral getDhcp(void *theTaskDataPtr, char *theNamePtr,
		Signed16Ptr theIndexValuesPtr);
rpOneOfSeveral getDhcp(void *theTaskDataPtr, char *theNamePtr,
		Signed16Ptr theIndexValuesPtr) {
	NetworkPgCache *cache = getNetworkPageCache(theTaskDataPtr);
	return cache->dhcp;
}


extern void setDhcp(void *theTaskDataPtr, rpOneOfSeveral theValue,
		char *theNamePtr, Signed16Ptr theIndexValuesPtr);
void setDhcp(void *theTaskDataPtr, rpOneOfSeveral theValue,
		char *theNamePtr, Signed16Ptr theIndexValuesPtr) {
	NetworkPgCache *cache = getNetworkPageCache(theTaskDataPtr);
	cache->dhcp = theValue;
}

extern char *getIpAddress(void *theTaskDataPtr, char *theNamePtr,
		Signed16Ptr theIndexValuesPtr);
char *getIpAddress(void *theTaskDataPtr, char *theNamePtr,
		Signed16Ptr theIndexValuesPtr) {
	NetworkPgCache *cache = getNetworkPageCache(theTaskDataPtr);
	return cache->ipAddress;
}

extern void setIPAddress(void *theTaskDataPtr, char *theValuePtr,
		char *theNamePtr, Signed16Ptr theIndexValuesPtr);
void setIPAddress(void *theTaskDataPtr, char *theValuePtr,
		char *theNamePtr, Signed16Ptr theIndexValuesPtr) {
	NetworkPgCache *cache = getNetworkPageCache(theTaskDataPtr);
	memcpy(cache->ipAddress, theValuePtr, ROMPAGER_IP_ARRAY_LENGTH);       
}


extern char *getSubMask(void *theTaskDataPtr, char *theNamePtr,
		Signed16Ptr theIndexValuesPtr);
char *getSubMask(void *theTaskDataPtr, char *theNamePtr,
		Signed16Ptr theIndexValuesPtr) {
	NetworkPgCache *cache = getNetworkPageCache(theTaskDataPtr);
	return cache->subMask;
}

extern void setSubMask(void *theTaskDataPtr, char *theValuePtr,
		char *theNamePtr, Signed16Ptr theIndexValuesPtr);
void setSubMask(void *theTaskDataPtr, char *theValuePtr,
		char *theNamePtr, Signed16Ptr theIndexValuesPtr) {
	NetworkPgCache *cache = getNetworkPageCache(theTaskDataPtr);
	memcpy(cache->subMask, theValuePtr, ROMPAGER_IP_ARRAY_LENGTH);       
}

extern char *getGateway(void *theTaskDataPtr, char *theNamePtr,
		Signed16Ptr theIndexValuesPtr);
char *getGateway(void *theTaskDataPtr, char *theNamePtr,
		Signed16Ptr theIndexValuesPtr) {
	NetworkPgCache *cache = getNetworkPageCache(theTaskDataPtr);
	return cache->gateway;
}

extern void setGateway(void *theTaskDataPtr, char *theValuePtr,
		char *theNamePtr, Signed16Ptr theIndexValuesPtr);
void setGateway(void *theTaskDataPtr, char *theValuePtr,
		char *theNamePtr, Signed16Ptr theIndexValuesPtr) {
	NetworkPgCache *cache = getNetworkPageCache(theTaskDataPtr);
	memcpy(cache->gateway, theValuePtr, ROMPAGER_IP_ARRAY_LENGTH);       
}

extern char *getPrimaryDNS(void *theTaskDataPtr, char *theNamePtr,
		Signed16Ptr theIndexValuesPtr);
char *getPrimaryDNS(void *theTaskDataPtr, char *theNamePtr,
		Signed16Ptr theIndexValuesPtr) {
	NetworkPgCache *cache = getNetworkPageCache(theTaskDataPtr);
	return cache->primaryDns;
}

extern void setPrimaryDNS(void *theTaskDataPtr, char *theValuePtr,
		char *theNamePtr, Signed16Ptr theIndexValuesPtr);
void setPrimaryDNS(void *theTaskDataPtr, char *theValuePtr,
		char *theNamePtr, Signed16Ptr theIndexValuesPtr) {

	NetworkPgCache *cache = getNetworkPageCache(theTaskDataPtr);
	memcpy(cache->primaryDns, theValuePtr, ROMPAGER_IP_ARRAY_LENGTH);       
}

extern char *getSecondaryDNS(void *theTaskDataPtr, char *theNamePtr,
		Signed16Ptr theIndexValuesPtr);
char *getSecondaryDNS(void *theTaskDataPtr, char *theNamePtr,
		Signed16Ptr theIndexValuesPtr) {
	NetworkPgCache *cache = getNetworkPageCache(theTaskDataPtr);
	return cache->secondaryDns;
}

extern void setSecondaryDNS(void *theTaskDataPtr, char *theValuePtr,
		char *theNamePtr, Signed16Ptr theIndexValuesPtr);
void setSecondaryDNS(void *theTaskDataPtr, char *theValuePtr,
		char *theNamePtr, Signed16Ptr theIndexValuesPtr) {

	NetworkPgCache *cache = getNetworkPageCache(theTaskDataPtr);
	memcpy(cache->secondaryDns, theValuePtr, ROMPAGER_IP_ARRAY_LENGTH);       
}

extern Boolean getIpv6Dhcp(void *theTaskDataPtr, char *theNamePtr,
		Signed16Ptr theIndexValuesPtr);
Boolean getIpv6Dhcp(void *theTaskDataPtr, char *theNamePtr,
		Signed16Ptr theIndexValuesPtr) {

	NetworkPgCache *cache = getNetworkPageCache(theTaskDataPtr);
	return (cache->ipv6IsEnabled & NA_IAM_DHCPV6_ENABLED);
}

extern void setIpv6Dhcp(void *theTaskDataPtr, Boolean theValue,
		char *theNamePtr, Signed16Ptr theIndexValuesPtr);
void setIpv6Dhcp(void *theTaskDataPtr, Boolean theValue,
		char *theNamePtr, Signed16Ptr theIndexValuesPtr) {

	NetworkPgCache *cache = getNetworkPageCache(theTaskDataPtr);

    if (theValue == True)
    {  /* Enable DHCP v6 */
        cache->ipv6IsEnabled |= NA_IAM_DHCPV6_ENABLED;
    }
    else
    {  /* Disable DHCP v6 */
        cache->ipv6IsEnabled &= ~NA_IAM_DHCPV6_ENABLED;
    }
	return;
}

extern Boolean getIpv6Static(void *theTaskDataPtr, char *theNamePtr,
		Signed16Ptr theIndexValuesPtr);
Boolean getIpv6Static(void *theTaskDataPtr, char *theNamePtr,
		Signed16Ptr theIndexValuesPtr) {

	NetworkPgCache *cache = getNetworkPageCache(theTaskDataPtr);
	return (cache->ipv6IsEnabled & NA_IAM_STATICV6_ENABLED);
}

extern void setIpv6Static(void *theTaskDataPtr, Boolean theValue,
		char *theNamePtr, Signed16Ptr theIndexValuesPtr);
void setIpv6Static(void *theTaskDataPtr, Boolean theValue,
		char *theNamePtr, Signed16Ptr theIndexValuesPtr) {

	NetworkPgCache *cache = getNetworkPageCache(theTaskDataPtr);

    if (theValue == True)
    {  /* Enable StaticV6 */
        cache->ipv6IsEnabled |= NA_IAM_STATICV6_ENABLED;
    }
    else
    {  /* Disable StaticV6 */
        cache->ipv6IsEnabled &= ~NA_IAM_STATICV6_ENABLED;
    }
	return;
}

extern char *getIpv6Address(void *theTaskDataPtr, char *theNamePtr,
		Signed16Ptr theIndexValuesPtr);
char *getIpv6Address(void *theTaskDataPtr, char *theNamePtr,
		Signed16Ptr theIndexValuesPtr) {

	NetworkPgCache *cache = getNetworkPageCache(theTaskDataPtr);

	return cache->ipv6Address;
}

extern void setIPv6Address(void *theTaskDataPtr, char *theValuePtr,
		char *theNamePtr, Signed16Ptr theIndexValuesPtr);
void setIPv6Address(void *theTaskDataPtr, char *theValuePtr,
		char *theNamePtr, Signed16Ptr theIndexValuesPtr) {

	NetworkPgCache *cache = getNetworkPageCache(theTaskDataPtr);
	strcpy(cache->ipv6Address, theValuePtr);
}

extern char *getIpv6Gateway(void *theTaskDataPtr, char *theNamePtr,
		Signed16Ptr theIndexValuesPtr);
char *getIpv6Gateway(void *theTaskDataPtr, char *theNamePtr,
		Signed16Ptr theIndexValuesPtr) {

	NetworkPgCache *cache = getNetworkPageCache(theTaskDataPtr);
	return cache->ipv6Gateway;
}

extern void setIPv6Gateway(void *theTaskDataPtr, char *theValuePtr,
		char *theNamePtr, Signed16Ptr theIndexValuesPtr);
void setIPv6Gateway(void *theTaskDataPtr, char *theValuePtr,
		char *theNamePtr, Signed16Ptr theIndexValuesPtr) {

	NetworkPgCache *cache = getNetworkPageCache(theTaskDataPtr);
	strcpy(cache->ipv6Gateway, theValuePtr);
}

extern Unsigned8 getPrefixLength(void *theTaskDataPtr, char *theNamePtr,
		Signed16Ptr theIndexValuesPtr);
Unsigned8 getPrefixLength(void *theTaskDataPtr, char *theNamePtr,
		Signed16Ptr theIndexValuesPtr) {

	NetworkPgCache *cache = getNetworkPageCache(theTaskDataPtr);

	return cache->ipv6PrefixLen;
}

extern void setPrefixLength(void *theTaskDataPtr, Unsigned8 theValue,
		char *theNamePtr, Signed16Ptr theIndexValuesPtr);
void setPrefixLength(void *theTaskDataPtr, Unsigned8 theValue,
		char *theNamePtr, Signed16Ptr theIndexValuesPtr) {

	NetworkPgCache *cache = getNetworkPageCache(theTaskDataPtr);

	cache->ipv6PrefixLen = theValue;
	return;
}



extern void networkSubmit(void *theTaskDataPtr, Signed16Ptr theIndexValuesPtr);
void networkSubmit(void *theTaskDataPtr, Signed16Ptr theIndexValuesPtr) {
	SessionCache *sess = getSessionCache(theTaskDataPtr);
	NetworkPgCache *cache = getNetworkPageCache(theTaskDataPtr);
	struct sockaddr_storage ipv6addr;
    struct sockaddr_storage ipv6gateway;

	int status;
	NaIamParams_t *interface;
  
	interface = customizeIamFindInterfaceConfig(BP_ETH_INTERFACE, &cache->nvParams.iamParamsInfo);

	if (cache->dhcp == dhcp_enabled) {
 	    // Disable the static configuration to make ACE get an address from the network.
        interface->staticParams.isEnabled = FALSE;
        interface->dhcpParams.isEnabled = TRUE;
    } else {
		interface->staticParams.IPV4_ADDR(ipAddress) = rompager_to_ipaddr(cache->ipAddress);        
		interface->staticParams.subnetMask = rompager_to_ipaddr(cache->subMask);        
		interface->staticParams.IPV4_ADDR(gateway) = rompager_to_ipaddr(cache->gateway);  
						  
        interface->staticParams.IPV4_ADDR(primaryDns) = rompager_to_ipaddr(cache->primaryDns);
        interface->staticParams.IPV4_ADDR(secondaryDns) = rompager_to_ipaddr(cache->secondaryDns);
        
        //Enabling the static configuration will cause DHCP, BOOTP, etc. to be
        // ignored on this interface.
        interface->staticParams.isEnabled = TRUE;
        interface->dhcpParams.isEnabled = FALSE;
    }
	interface->staticParams.ipv6IsEnabled = cache->ipv6IsEnabled;
	if (cache->ipv6IsEnabled & NA_IAM_STATICV6_ENABLED)
	{
        struct sockaddr_storage * ipv6GatewayPtr = customizeIamFindIpv6GatewayConfig(BP_ETH_INTERFACE, &cache->nvParams);

		if ((inet_pton(AF_INET6, cache->ipv6Address, &ipv6addr.addr.ipv6.sin6_addr) == 1) && 
            (inet_pton(AF_INET6, cache->ipv6Gateway, &ipv6gateway.addr.ipv6.sin6_addr) == 1))
		{
			ipv6addr.ss_family = AF_INET6;
			ipv6addr.ss_len = sizeof(struct sockaddr_in6);
            ipv6gateway.ss_family = AF_INET6;
			ipv6gateway.ss_len = sizeof(struct sockaddr_in6);

            if (naValidateIpv6AddrGateway(&ipv6addr, cache->ipv6PrefixLen, &ipv6gateway) == 0)
			{
				interface->staticParams.ipv6Address = ipv6addr;
				interface->staticParams.ipv6PrefixLen = cache->ipv6PrefixLen;
                if (ipv6GatewayPtr)
                    *ipv6GatewayPtr = ipv6gateway;
			}
			else
			if (naValidateIpv6AddrGateway(&ipv6addr, 64, &ipv6gateway) == 0)
			{
				interface->staticParams.ipv6Address = ipv6addr;
				interface->staticParams.ipv6PrefixLen = 64;
                if (ipv6GatewayPtr)
                    *ipv6GatewayPtr = ipv6gateway;
			}
			else
				interface->staticParams.ipv6IsEnabled &= ~NA_IAM_STATICV6_ENABLED;
		}
		else if (naValidateIpv6AddrGateway(&interface->staticParams.ipv6Address, interface->staticParams.ipv6PrefixLen, ipv6GatewayPtr))
			interface->staticParams.ipv6IsEnabled &= ~NA_IAM_STATICV6_ENABLED;
	}

	status = customizeWriteDevBoardParams(&cache->nvParams);

	if (status != BP_SUCCESS) {
		setCacheValid(sess); // Leave user entered data in form
		addSessionMsg(sess, WEBUI_ERROR_MSG, "Critical error saving network settings!");
	} else {
		setCacheInvalid(sess);
		addSessionMsg(sess, WEBUI_STATUS_MSG, "Settings have been saved. You must reboot for changes to take effect.");
	}

	return;
}

extern void networkConfigPagePreProc(void *theTaskDataPtr, Signed16Ptr theIndexValuesPtr);
void networkConfigPagePreProc(void *theTaskDataPtr, Signed16Ptr theIndexValuesPtr) {
	SessionCache *sess = getSessionCache(theTaskDataPtr);
	NetworkPgCache *cache = getNetworkPageCache(theTaskDataPtr);
    struct sockaddr_storage * ipv6GatewayPtr = NULL;
	NaIamParams_t *interface;
	char * ipv6_addr;
    char * ipv6_gateway;

	if (!isPageCacheValid(sess, NETWORK_CONFIG_ID)) {
		// Set defaults.
		cache->dhcp = dhcp_enabled;
		memset(cache->ipAddress, 0, sizeof(cache->ipAddress));
		memset(cache->subMask, 0, sizeof(cache->subMask));
		memset(cache->gateway, 0, sizeof(cache->gateway));
		memset(cache->primaryDns, 0, sizeof(cache->primaryDns));
		memset(cache->secondaryDns, 0, sizeof(cache->secondaryDns));
		memset(cache->ipv6Address, 0, sizeof(cache->ipv6Address));
        memset(cache->ipv6Gateway, 0, sizeof(cache->ipv6Gateway));

		cache->ipv6IsEnabled = 0;
		cache->ipv6PrefixLen = 64;
	
		// Read current settings.
		customizeReadDevBoardParams(&cache->nvParams);
        ipv6GatewayPtr = customizeIamFindIpv6GatewayConfig(BP_ETH_INTERFACE, &cache->nvParams);
	
		// Extract the configuration structure from the NVRAM structure.  There should be a configuration
		// settings for the eth0 interface.  If not, then reinitialize the structure.
		interface = customizeIamFindInterfaceConfig(BP_ETH_INTERFACE, &cache->nvParams.iamParamsInfo);
		if (interface == NULL) {
 			customizeIamGetDefaultConfig(&cache->nvParams.iamParamsInfo);
			interface = customizeIamFindInterfaceConfig(BP_ETH_INTERFACE, &cache->nvParams.iamParamsInfo);
            if (ipv6GatewayPtr != NULL)
                *ipv6GatewayPtr = customizeIamGetDefaultIpv6GatewayConfig(BP_ETH_INTERFACE);
		}

	    // Static configuration?
	    if (interface->staticParams.isEnabled) {
	    	cache->dhcp = dhcp_disabled;
	    	ipaddr_to_rompager(cache->ipAddress, interface->staticParams.IPV4_ADDR(ipAddress));
	    	ipaddr_to_rompager(cache->subMask, interface->staticParams.subnetMask);
	    	ipaddr_to_rompager(cache->gateway, interface->staticParams.IPV4_ADDR(gateway));
	    	ipaddr_to_rompager(cache->primaryDns, interface->staticParams.IPV4_ADDR(primaryDns));
	    	ipaddr_to_rompager(cache->secondaryDns, interface->staticParams.IPV4_ADDR(secondaryDns));
    	
	    } else {
	    	customizeIamGetIfAddrInfo(BP_ETH_INTERFACE, &cache->addrInfo);
	    	
			cache->dhcp = dhcp_enabled;
			ipaddr_to_rompager(cache->ipAddress, IPV4_ADDR(cache->addrInfo.v4Info.ipAddress));
			ipaddr_to_rompager(cache->subMask, cache->addrInfo.v4Info.subnetMask);
			ipaddr_to_rompager(cache->gateway, IPV4_ADDR(cache->addrInfo.v4Info.defaultGateway));
#if IPV6_ENABLED			
			ipaddr_to_rompager(cache->primaryDns, cache->addrInfo.primaryDnsServer.addr.ipv6.sin6_addr.ip6Addr.ip6U32[3]);
			ipaddr_to_rompager(cache->secondaryDns, cache->addrInfo.secondaryDnsServer.addr.ipv6.sin6_addr.ip6Addr.ip6U32[3]);
#else			
			ipaddr_to_rompager(cache->primaryDns, IPV4_ADDR(cache->addrInfo.primaryDnsServer));
			ipaddr_to_rompager(cache->secondaryDns, IPV4_ADDR(cache->addrInfo.secondaryDnsServer));
#endif		
		
	    }

		cache->ipv6IsEnabled = interface->staticParams.ipv6IsEnabled;
		ipv6_addr = (char *)&interface->staticParams.ipv6Address.addr.ipv6.sin6_addr;
		cache->ipv6PrefixLen = interface->staticParams.ipv6PrefixLen;
	    	
	    /* Convert v6 address to ASCII. */
	    if (!inet_ntop(AF_INET6, ipv6_addr, cache->ipv6Address, MAX_IP_ADDR_STR_LEN))
			cache->ipv6Address[0] = '\0';

        if (ipv6GatewayPtr != NULL)
        {
            ipv6_gateway = (char *)&ipv6GatewayPtr->addr.ipv6.sin6_addr;
            if (!inet_ntop(AF_INET6, ipv6_gateway, cache->ipv6Gateway, MAX_IP_ADDR_STR_LEN))
			    cache->ipv6Gateway[0] = '\0';
        }
        else
 			cache->ipv6Gateway[0] = '\0';
	}

	setCacheInvalid(sess);
}


#endif	/* RomPagerServer */
