Files
m241Neelima/components/ip_net2-6.9/ipmip4/src/ipmip4_sysext.c
T
2026-07-30 11:19:44 +05:30

591 lines
18 KiB
C

/*
******************************************************************************
* INTERPEAK SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmip4_sysext.c,v $ $Revision: 1.19 $
* $Source: /home/interpeak/CVSRoot/ipmip4/src/ipmip4_sysext.c,v $
* $Author: jhorteli $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelis@interpeak.se>
******************************************************************************
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
#include "ipmip4_config.h"
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#define IPCOM_USE_CLIB_PROTO
#include <ipcom_clib.h>
#include <ipcom_err.h>
#include <ipcom_hash.h>
#include <ipcom_inet.h>
#include <ipcom_list.h>
#include <ipcom_os.h>
#include <ipcom_sock.h>
#include <ipcom_sock2.h>
#include <ipcom_syslog.h>
#include <ipcom_sysvar.h>
#include <ipmip.h>
#include "ipmip4_h.h"
#include <private/ipmip4_sysext.h>
#include <private/ipmip4_util.h>
#include <private/ipmip4_auth.h>
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
Ipmip_sysvar_key_map_t ipmip4_sysext_spi_method[] =
{
{ IPMIP4_AUTH_METHOD_MD5_HMAC, "md5-hmac" },
{ IPMIP4_AUTH_METHOD_MD5_HMAC, "hmac-md5" },
{ IPMIP4_AUTH_METHOD_MD5_HMAC, "md5" },
{ IPMIP4_AUTH_METHOD_CHAP, "chap" },
{ IPMIP4_AUTH_METHOD_KEYGEN, "keygen" },
{ 0, 0 }
};
/*
****************************************************************************
* 9 STATIC FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* 10 GLOBAL FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipmip4_sysext_nvse_alloc
*===========================================================================
* Description: Create an NVSE extension based on vendor, subtype and data
* Parameters: vendor - Vendor ID
* subtype - Vendor NVSE subtype
* value - The vendor value
* size - The size of value
* Returns:
*
*/
IP_GLOBAL Ipmip4_msgext_uhdr_t *
ipmip4_sysext_nvse_alloc(Ip_u32 vendor,
Ip_u16 subtype,
void *data,
Ip_size_t size)
{
Ip_u8 *vse = ipcom_calloc(1, 10 + size);
if (vse)
{
vse[0] = IPMIP4_EXT_TYPE_NVSE;
vse[1] = (Ip_u8) (10 + size - 2);
IP_SET_HTONL(&vse[4], vendor);
IP_SET_HTONS(&vse[8], subtype);
ipcom_memcpy(&vse[10], data, size);
}
return (Ipmip4_msgext_uhdr_t *) vse;
}
/*
*===========================================================================
* ipmip4_sysext_cvse_alloc
*===========================================================================
* Description: Create an CVSE extension based on vendor, subtype and data
* Parameters: vendor - Vendor ID
* subtype - Vendor CVSE subtype
* value - The vendor value
* size - The size of value
* Returns:
*
*/
IP_GLOBAL Ipmip4_msgext_uhdr_t *
ipmip4_sysext_cvse_alloc(Ip_u32 vendor,
Ip_u16 subtype,
void *data,
Ip_size_t size)
{
Ip_u8 *vse = ipcom_calloc(1, 10 + size);
if (vse)
{
vse[0] = IPMIP4_EXT_TYPE_CVSE;
IP_SET_HTONS(&vse[2], (10 + size - 4));
IP_SET_HTONL(&vse[4], vendor);
IP_SET_HTONS(&vse[8], subtype);
ipcom_memcpy(&vse[10], data, size);
}
return (Ipmip4_msgext_uhdr_t *) vse;
}
/*
*===========================================================================
* ipmip4_sysext_spi_parse
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_GLOBAL Ipmip4_auth_spi_t *
ipmip4_sysext_spi_parse(struct Ipmip_proc *proc,
Ip_u32 defspi,
Ip_u32 spival,
const char *secret,
const char *delim,
const char *format,
...)
{
va_list ap;
char *spec;
va_start(ap, format);
spec = ipmip_util_vstrdup(format, ap);
va_end(ap);
if (spec)
{
Ipmip4_auth_spi_t *spi;
char *vsecret = (char *)secret;
int method;
if (spival == 0)
spival = ipmip_sysvar_ulong(defspi, "%s%sspi", spec, delim);
if (spival == 0)
{
ipcom_free(spec);
return IP_NULL;
}
/**/
method = ipmip_sysvar_key(spival == IPMIP4_AUTH_SPI_CHAP_SPI? IPMIP4_AUTH_METHOD_CHAP : IPMIP4_AUTH_METHOD_MD5_HMAC, ipmip4_sysext_spi_method, "%s%smethod", spec, delim);
/* Try read the secret */
if (vsecret == IP_NULL)
{
vsecret = ipmip_sysvar("%s%ssecret", spec, delim);
if (vsecret == IP_NULL)
vsecret = ipmip_sysvar(spec);
}
if (vsecret == IP_NULL)
{
ipcom_free(spec);
return IP_NULL;
}
/* Create the SPI */
spi = ipmip4_auth_spi_create(proc, spival, vsecret, ipcom_strlen(vsecret), method);
/* Free memory */
ipcom_free(spec);
if (vsecret != IP_NULL && vsecret != secret)
ipcom_free(vsecret);
return spi;
}
return IP_NULL;
}
/*===========================================================================
* ipmip4_sysext_foreach_spi
*===========================================================================
* Description: Parse the configured SPI's
* Parameters: proc - Current process
* name - Name of the sysvar key
* subkey - The matched subkey
* value - The SPI value
* spictx - The spi context
* Returns:
*
*/
IP_GLOBAL void
ipmip4_sysext_foreach_spi(struct Ipmip_proc *proc,
char *name,
char *subkey,
const char *value,
Ipmip4_auth_context_t *spictx)
{
/* Dont care about subkeys */
char *dot;
IPMIP_UNUSED_PARAMETER(name);
IPMIP_UNUSED_PARAMETER(proc);
if ((dot = ipcom_strchr(subkey, '.')) == IP_NULL || ipcom_strcasecmp(dot, ".secret") == 0)
{
Ip_u32 spival = ipcom_strtoul(subkey, IP_NULL, 10);
Ipmip4_auth_spi_t *spi;
if (spival < 256)
return;
/**/
spi = ipmip4_sysext_spi_parse(proc, 0, spival, value, ".", dot? ipmip_ntop_strn(proc, name, dot - name) : name);
if (spi)
ipmip4_auth_spi_add(spictx, spi);
}
}
/*===========================================================================
* ipmip4_sysext_foreach_spiroute
*===========================================================================
* Description: Parse the configured SPI lookup definitions
* Parameters: proc - Current process
* name - Name of the sysvar key
* subkey - The matched subkey
* value - The SPI value
* rtab - The route table
* Returns:
*
*/
IP_GLOBAL void
ipmip4_sysext_foreach_spiroute(struct Ipmip_proc *proc,
char *name,
char *subkey,
const char *value,
Ipmip4_auth_spi_table_t *rtab)
{
Ip_u32 addr;
Ip_u32 plen;
IPMIP_UNUSED_PARAMETER(name);
/* Dont care about subkeys */
if (ipcom_strcasecmp(subkey, "any") == 0)
{
/* Wildcard match */
addr = 0;
plen = 0;
}
else
{
if (ipmip_util_inet(subkey, &addr, &plen) == IP_FALSE)
{
IPCOM_LOG1(ERR,
"SPI key '%s' is not a valid address",
subkey);
return;
}
}
IPCOM_LOG3(DEBUG2,
"Route SPI lookup %s/%d for SPI %s",
ipmip_ntop_inet(proc, addr),
plen,
subkey);
/* Add the SPI route */
ipmip4_auth_spi_table_add(rtab, addr, plen, ipcom_strtoul(value, IP_NULL, 10));
}
/*===========================================================================
* ipmip4_sysext_foreach_spiroute
*===========================================================================
* Description: Parse the configured SPI lookup definitions
* Parameters: proc - Current process
* name - Name of the sysvar key
* subkey - The matched subkey
* value - The SPI value
* htable - The spi hash table
* Returns:
*
*/
IP_GLOBAL void
ipmip4_sysext_foreach_spihash(struct Ipmip_proc *proc,
char *name,
char *subkey,
const char *value,
Ipmip4_auth_spi_hash_t *htable)
{
IPMIP_UNUSED_PARAMETER(proc);
IPMIP_UNUSED_PARAMETER(name);
/* Add the SPI route */
IPCOM_LOG3(DEBUG2,
"NAI SPI lookup %s (%d) for SPI %d", subkey, ipcom_strlen(subkey), ipcom_strtoul(value, IP_NULL, 10));
if (!ipmip4_auth_spi_hash_add(htable, subkey, ipcom_strlen(subkey), ipcom_strtoul(value, IP_NULL, 10)))
{
IPCOM_LOG2(WARNING,
"FAILED: NAI SPI lookup %s for SPI %d", subkey, ipcom_strtoul(value, IP_NULL, 10));
}
}
/*
*===========================================================================
* ipmip4_sysext_nai_aaah
*===========================================================================
* Description: Parse and create a NAI AAAH from a sysvar
* Parameters: format - The sysvar format key.
* ... - Optional arguments
* Returns:
*
*/
IP_GLOBAL Ipmip4_msgext_shdr_t *
ipmip4_sysext_nai_aaah(const char *format,
/* args */ ...)
{
va_list ap;
char *nai;
Ipmip4_msgext_shdr_t *aaah_nai = IP_NULL;
va_start(ap, format);
nai = ipmip_vsysvar(format, ap);
va_end(ap);
if (nai != IP_NULL)
{
aaah_nai = ipmip4_sysext_nai_aaah_create((Ip_u8 *)nai, ipcom_strlen(nai));
ipcom_free(nai);
}
return aaah_nai;
}
/*
*===========================================================================
* ipmip4_sysext_nai_ha
*===========================================================================
* Description: Parse and create a NAI HA from a sysvar
* Parameters: format - The sysvar format key.
* ... - Optional arguments
* Returns:
*
*/
IP_GLOBAL Ipmip4_msgext_shdr_t *
ipmip4_sysext_nai_ha(const char *format,
/* args */ ...)
{
va_list ap;
char *nai;
Ipmip4_msgext_shdr_t *ha_nai = IP_NULL;
va_start(ap, format);
nai = ipmip_vsysvar(format, ap);
va_end(ap);
if (nai != IP_NULL)
{
Ip_size_t nai_len = ipcom_strlen(nai);
if (nai_len >= 3)
{
Ip_u8 *nai_ext = ipcom_calloc(1, nai_len + 3);
/* */
if (nai_ext != IP_NULL)
{
nai_ext[0] = IPMIP4_EXT_TYPE_NAI_AGENT;
nai_ext[1] = (Ip_u8) (nai_len + 1);
nai_ext[2] = IPMIP4_NAI_SUBTYPE_HA;
ipcom_strncpy((char *)&nai_ext[3], nai, nai_len);
/* Store the NAI */
ha_nai = (void*) nai_ext;
}
}
else if (nai_len)
{
IPCOM_LOG0(WARNING, "Too short HA NAI. Syntax is hostname@domain");
}
ipcom_free(nai);
}
return ha_nai;
}
/*
*===========================================================================
* ipmip4_sysext_nai_mn
*===========================================================================
* Description: Parse and create a NAI MN from a sysvar
* Parameters: format - The sysvar format key.
* ... - Optional arguments
* Returns:
*
*/
IP_GLOBAL Ipmip4_msgext_shdr_t *
ipmip4_sysext_nai_mn(const char *format,
/* args */ ...)
{
va_list ap;
char *nai;
Ipmip4_msgext_shdr_t *mn_nai = IP_NULL;
va_start(ap, format);
nai = ipmip_vsysvar(format, ap);
va_end(ap);
if (nai)
mn_nai = ipmip4_msgext_nai_mn(IP_NULL, nai, ipcom_strlen(nai));
if (nai != IP_NULL)
ipcom_free(nai);
return mn_nai;
}
/*
*===========================================================================
* ipmip4_sysext_tunnel_type
*===========================================================================
* Description: Interpret a tunnel protocol to its tunnel type index
* Parameters: deftype - Default type index
* format - The sysvar format string
* ... - The optional arguments
* Returns: -1 on error, deftype on none, tunnel type index otherwise
*
*/
IP_GLOBAL int
ipmip4_sysext_tunnel_type(int deftype,
const char *format,
/* args */ ...)
{
va_list ap;
char *proto;
static Ipmip_sysvar_key_map_t ttypes[] =
{
{ IPMIP_TUNNELTYPE_IPIP, "ipip" },
{ IPMIP_TUNNELTYPE_GRE, "gre" },
{ IPMIP_TUNNELTYPE_MINENC, "min" },
{ IPMIP_TUNNELTYPE_IP6IP6, "ip6ip6" },
{ IPMIP_TUNNELTYPE_GRE6, "gre6" },
{ 0, 0 }
};
va_start(ap, format);
proto = ipmip_vsysvar(format, ap);
va_end(ap);
if (proto != IP_NULL)
{
deftype = ipmip_sysvar_cmd_str_to_key(ttypes, proto);
if (deftype == -1)
{
IPCOM_LOG1(ERR, "invalid tunnel type configuration (%s)", proto);
}
ipcom_free(proto);
}
return deftype;
}
/*
*===========================================================================
* ipmip4_sysext_nai_aaah_create
*===========================================================================
* Description: Create a AAAH nai based on provided data
* Parameters: data - The data
* data_length - The length of data
* Returns: The AAAH Nai.
*
*/
IP_GLOBAL Ipmip4_msgext_shdr_t *
ipmip4_sysext_nai_aaah_create(Ip_u8 *data,
Ip_size_t data_length)
{
Ipmip4_msgext_shdr_t *aaah_nai = IP_NULL;
if (data != IP_NULL)
{
if (data_length >= 3)
{
Ip_u8 *nai_ext = ipcom_calloc(1, data_length + 4);
/* */
if (nai_ext != IP_NULL)
{
nai_ext[0] = IPMIP4_EXT_TYPE_NAI_AGENT;
nai_ext[1] = (Ip_u8) (data_length + 1);
nai_ext[2] = IPMIP4_NAI_SUBTYPE_AAAH;
ipcom_memcpy((char *)&nai_ext[3], data, data_length);
/* Store the NAI */
aaah_nai = (void*) nai_ext;
}
}
else if (data_length)
{
IPCOM_LOG0(WARNING, "Too short AAAH NAI. Syntax is hostname@domain");
}
}
return aaah_nai;
}
/*
****************************************************************************
* 11 PUBLIC FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/