/*
---------------------------------------------------------------------------
$Id: tsp_setup.c,v 1.29 2007/04/26 20:10:07 cnepveu Exp $
---------------------------------------------------------------------------
Copyright (c) 2001-2007 Hexago Inc. All rights reserved.
LICENSE NOTICE: You may use and modify this source code only if you
have executed a valid license agreement with Hexago Inc. granting
you the right to do so, the said license agreement governing such
use and modifications. Copyright or other intellectual property
notices are not to be removed from the source code.
---------------------------------------------------------------------------
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "platform.h"
#include "tsp_setup.h"
#include "config.h" // tConf
#include "xml_tun.h" // tTunnel
#include "log.h" // Display()
#include "hex_strings.h" // Strings for Display()
#include "lib.h" // IsAll()
// Gateway6 Client Messaging Subsystem.
#include <gw6cmessaging/gw6c_c_wrapper.h>
/* Should be defined in platform.h */
#ifndef SCRIPT_TMP_FILE
#define SCRIPT_TMP_FILE "/tmp/gw6c-tmp.log"
#endif
/* to remove a warning. This is not right,
it is already declared in tsp_client.h.
*/
extern void tspSetEnv(char *, char *, int);
extern int tspSetupInterfaceLocal(tConf *c, tTunnel *t); // Defined in tsp_local.c of each platform.
/* Execute cmd and send output to log subsystem */
int execScript(const char *cmd)
{
char buf[16384];
char *ptr,*ptr2;
int retVal, fd, n,i , used;
memset(buf, 0, sizeof(buf));
snprintf(buf,sizeof(buf),"%s > %s", cmd, SCRIPT_TMP_FILE);
retVal = system(buf);
if((fd = open(SCRIPT_TMP_FILE,O_RDONLY)) == -1) {
Display(LOG_LEVEL_3,ELError,"tspSetupInterface",HEX_STR_CANT_OPEN_TMP_FILE SCRIPT_TMP_FILE);
return -1;
}
ptr2 = buf;
used = 0;
while( (n = read(fd, ptr2, sizeof(buf) - used ) ) > 0) {
ptr=ptr2;
for(i=0;i<n;i++) {
if(ptr2[i] == '\n' ) {
ptr2[i] = 0;
Display(LOG_LEVEL_MAX,ELInfo,"Script","%s",ptr);
ptr=ptr2+i+1;
}
}
ptr2=ptr;
used = buf-ptr2;
}
close(fd);
unlink(SCRIPT_TMP_FILE);
return retVal;
}
// --------------------------------------------------------------------------
// This function will set the required environment variables that will later
// be used when invoking the template script to actually create the tunnel.
//
int tspSetupInterface(tConf *c, tTunnel *t)
{
char buf[1024];
int Err = 0;
int ret;
FILE *template = NULL;
// Specify the tunnel mode.
tspSetEnv("TSP_TUNNEL_MODE", t->type, 1);
// Specify host type {router, host}
tspSetEnv("TSP_HOST_TYPE", c->host_type, 1);
// Specify tunnel interface, for setup.
if (strcasecmp(t->type, STR_XML_TUNNELMODE_V6V4) == 0 )
{
tspSetEnv("TSP_TUNNEL_INTERFACE", c->if_tunnel_v6v4, 1);
gTunnelInfo.eTunnelType = TUNTYPE_V6V4;
}
else if (strcasecmp(t->type, STR_XML_TUNNELMODE_V6UDPV4) == 0 )
{
tspSetEnv("TSP_TUNNEL_INTERFACE", c->if_tunnel_v6udpv4, 1);
gTunnelInfo.eTunnelType = TUNTYPE_V6UDPV4;
}
#ifdef V4V6_SUPPORT
else if (strcasecmp(t->type, STR_XML_TUNNELMODE_V4V6) == 0 )
{
tspSetEnv("TSP_TUNNEL_INTERFACE", c->if_tunnel_v4v6, 1);
gTunnelInfo.eTunnelType = TUNTYPE_V4V6;
}
#endif /* V4V6_SUPPORT */
// Specify what interface will be used for routing advertizement,
// if enabled.
tspSetEnv("TSP_HOME_INTERFACE", c->if_prefix, 1);
// Specify local endpoint IPv4 address
if(IsAll(IPv4Addr, t->client_address_ipv4))
{
tspSetEnv("TSP_CLIENT_ADDRESS_IPV4", t->client_address_ipv4, 1);
gTunnelInfo.szIPV4AddrLocalEndpoint = t->client_address_ipv4;
}
else
{
Display(LOG_LEVEL_3, ELError, "tspSetupInterface", HEX_STR_BAD_CLIENT_IPV4_RECVD);
Err++;
}
// Specify local endpoint IPv6 address
if(IsAll(IPv6Addr, t->client_address_ipv6))
{
tspSetEnv("TSP_CLIENT_ADDRESS_IPV6", t->client_address_ipv6, 1);
gTunnelInfo.szIPV6AddrLocalEndpoint = t->client_address_ipv6;
}
else
{
Display(LOG_LEVEL_3, ELError, "tspSetupInterface", HEX_STR_BAD_CLIENT_IPV6_RECVD);
Err++;
}
// Specify local endpoint domain name
if(t->client_dns_name)
{
tspSetEnv("TSP_CLIENT_DNS_NAME", t->client_dns_name, 1);
gTunnelInfo.szUserDomain = t->client_dns_name;
}
// Specify remote endpoint IPv4 address.
if(IsAll(IPv4Addr, t->server_address_ipv4))
{
tspSetEnv("TSP_SERVER_ADDRESS_IPV4", t->server_address_ipv4, 1);
gTunnelInfo.szIPV4AddrRemoteEndpoint = t->server_address_ipv4;
}
else {
Display(LOG_LEVEL_3, ELError, "tspSetupInterface", HEX_STR_BAD_SERVER_IPV4_RECVD);
Err++;
}
// Specify remote endpoint IPv6 address.
if(IsAll(IPv6Addr, t->server_address_ipv6))
{
tspSetEnv("TSP_SERVER_ADDRESS_IPV6", t->server_address_ipv6, 1);
gTunnelInfo.szIPV6AddrRemoteEndpoint = t->server_address_ipv6;
}
else {
Display(LOG_LEVEL_3, ELError, "tspSetupInterface", HEX_STR_BAD_SERVER_IPV6_RECVD);
Err++;
}
// Specify prefix for tunnel endpoint.
if ((strcasecmp(t->type, STR_XML_TUNNELMODE_V6V4) == 0) ||
(strcasecmp(t->type, STR_XML_TUNNELMODE_V6UDPV4) == 0))
tspSetEnv("TSP_TUNNEL_PREFIXLEN", "128", 1);
#ifdef V4V6_SUPPORT
else
tspSetEnv("TSP_TUNNEL_PREFIXLEN", "32", 1);
#endif /* V4V6_SUPPORT */
// Free and clear delegated prefix from tunnel info.
if( gTunnelInfo.szDelegatedPrefix != NULL )
{
free( gTunnelInfo.szDelegatedPrefix );
gTunnelInfo.szDelegatedPrefix = NULL;
}
// Have we been allocated a prefix for routing advertizement..?
if(t->prefix)
{
if(IsAll(IPAddrAny, t->prefix))
{
char chPrefix[128];
int len, sep;
/* Compute the number of characters that are significant out of the prefix. */
/* This is meaningful only for IPv6 prefixes; no contraction is possible for IPv4. */
if ((strcasecmp(t->type, STR_XML_TUNNELMODE_V6V4) == 0) ||
(strcasecmp(t->type, STR_XML_TUNNELMODE_V6UDPV4) == 0))
{
len = (atoi(t->prefix_length) % 16) ? (atoi(t->prefix_length) / 16 + 1) * 4 : atoi(t->prefix_length) / 16 * 4;
sep = (atoi(t->prefix_length) % 16) ? (atoi(t->prefix_length) / 16) : (atoi(t->prefix_length) / 16) -1;
}
else
{
len = strlen( t->prefix );
sep = 0;
}
memset(chPrefix, 0, 128);
memcpy(chPrefix, t->prefix, len+sep);
// Specify delegated prefix for routing advertizement, if enabled.
tspSetEnv("TSP_PREFIX", chPrefix, 1);
gTunnelInfo.szDelegatedPrefix = (char*) malloc( strlen(chPrefix) + 10/*To append prefix_length*/ );
strcpy( gTunnelInfo.szDelegatedPrefix, chPrefix );
}
else
{
Display(LOG_LEVEL_3, ELError, "tspSetupInterface", HEX_STR_BAD_SERVER_PREFIX_RECVD);
Err++;
}
// Specify prefix length for routing advertizement, if enabled.
if(IsAll(Numeric, t->prefix_length))
{
tspSetEnv("TSP_PREFIXLEN", t->prefix_length, 1);
strcat( gTunnelInfo.szDelegatedPrefix, "/" );
strcat( gTunnelInfo.szDelegatedPrefix, t->prefix_length );
}
else
{
Display(LOG_LEVEL_3, ELError, "tspSetupInterface", HEX_STR_BAD_PREFIX_LEN_RECVD);
Err++;
}
}
// Do some platform-specific stuff before tunnel setup script is launched.
//
if( Err == 0 )
{
// Do additionnal configuration. The "tspSetupInterfaceLocal" is defined in
// tsp_local.c in every platform.
Err += tspSetupInterfaceLocal( c, t );
}
if(Err)
{
// Errors occured during verification of tunnel parameters.
Display(LOG_LEVEL_2,ELError, "tspSetupInterface", HEX_STR_ERRS_IN_SERVER_RESP);
return 1;
}
snprintf(buf, sizeof buf, "%d", LOG_LEVEL_MAX);
tspSetEnv("TSP_VERBOSE", buf, 1);
tspSetEnv("TSP_HOME_DIR", TspHomeDir, 1);
snprintf(buf, sizeof buf, "%s%c%s.%s", ScriptDir, DirSeparator, c->template, ScriptExtension);
if ((template = fopen(buf, "r")) == NULL) {
Display(LOG_LEVEL_1, ELError, "tspSetupInterface", HEX_STR_TEMPLATE_NOT_FOUND, buf);
return 1;
}
else {
fclose(template);
memset(buf, 0, sizeof buf);
}
if (ScriptInterpretor != NULL)
snprintf(buf, sizeof buf, "%s \"%s%c%s.%s\"", ScriptInterpretor, ScriptDir, DirSeparator, c->template, ScriptExtension);
else
snprintf(buf, sizeof buf, "\"%s%c%s.%s\"", ScriptDir, DirSeparator, c->template, ScriptExtension);
Display(LOG_LEVEL_2, ELInfo, "tspSetupInterface", HEX_STR_EXEC_CFG_SCRIPT, buf);
// ------------------------------------------------
// Run the template script to bring the tunnel up.
// ------------------------------------------------
if( (ret = execScript(buf)) == 0 )
{
Display(LOG_LEVEL_2, ELInfo, "tspSetupInterface", HEX_STR_SCRIPT_COMPLETED_OK);
if ((strcasecmp(t->type, STR_XML_TUNNELMODE_V6V4) == 0) ||
(strcasecmp(t->type, STR_XML_TUNNELMODE_V6UDPV4) == 0))
Display(LOG_LEVEL_1, ELInfo, "tspSetupInterface", HEX_STR_YOUR_IPV6_IP_IS, t->client_address_ipv6);
#ifdef V4V6_SUPPORT
else
Display(LOG_LEVEL_1, ELInfo, "tspSetupInterface", HEX_STR_YOUR_IPV4_IP_IS, t->client_address_ipv4);
#endif /* V4V6_SUPPORT */
if ((t->prefix != NULL) && (t->prefix_length != NULL))
{
if ((strcasecmp(t->type, STR_XML_TUNNELMODE_V6V4) == 0) ||
(strcasecmp(t->type, STR_XML_TUNNELMODE_V6UDPV4) == 0))
Display(LOG_LEVEL_1, ELInfo, "tspSetupInterface", HEX_STR_YOUR_IPV6_PREFIX_IS, t->prefix, t->prefix_length);
#ifdef V4V6_SUPPORT
else
Display(LOG_LEVEL_1, ELInfo, "tspSetupInterface", HEX_STR_YOUR_IPV4_PREFIX_IS, t->prefix, t->prefix_length);
#endif /* V4V6_SUPPORT */
}
if (t->type != NULL)
{
Display(LOG_LEVEL_2, ELInfo, "tspSetupInterface", HEX_STR_SETUP_TUNNEL_TYPE, t->type);
}
Display(LOG_LEVEL_3, ELInfo, "tspSetupInterface", HEX_STR_SETUP_PROXY, c->proxy_client == TRUE ? HEX_STR_ENABLED : HEX_STR_DISABLED);
if (c->host_type != NULL)
{
Display(LOG_LEVEL_3, ELInfo, "tspSetupInterface", HEX_STR_SETUP_HOST_TYPE, c->host_type);
}
// Set the broker used for connection.
gTunnelInfo.szBrokerName = c->server;
// Set the current time(now) for tunnel start.
gTunnelInfo.tunnelUpTime = time(NULL);
// Send the tunnel info through the messaging subsystem.
send_tunnel_info();
}
return ret;
}
syntax highlighted by Code2HTML, v. 0.9.1