original files of m241
This commit is contained in:
@@ -0,0 +1,934 @@
|
||||
/*
|
||||
******************************************************************************
|
||||
* SOURCE FILE
|
||||
*
|
||||
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp_api.c,v $ $Revision: 1.17.10.2 $
|
||||
* $Source: /home/interpeak/CVSRoot/ipl2tp/src/ipl2tp_api.c,v $
|
||||
* $Author: hxu0 $
|
||||
* $State: Exp $ $Locker: $
|
||||
*
|
||||
* INTERPEAK_COPYRIGHT_STRING
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* DESCRIPTION
|
||||
****************************************************************************
|
||||
*
|
||||
* Interpeak Layer 2 Tunneling Protocol - IPL2TP
|
||||
* ---------------------------------------------
|
||||
*
|
||||
* Compliant with the following RFCs and internet drafts:
|
||||
* RFC 2661 - L2TP
|
||||
* RFC 2233 - Interfaces MIB
|
||||
* RFC 2667 - IP Tunnel MIB
|
||||
* RFC 3371 - L2TP Management Information Base
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* CONFIGURATION
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* INCLUDE FILES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#include "ipl2tp_h.h"
|
||||
#include "ipl2tp_api.h"
|
||||
#include "ipl2tp_avp.h"
|
||||
#include "ipl2tp_trpt.h"
|
||||
#include "ipl2tp_util.h"
|
||||
#include "ipl2tp_attr_h.h"
|
||||
#include "ipl2tp_state.h"
|
||||
#include "ipl2tp_message.h"
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* DEFINES
|
||||
****************************************************************************
|
||||
*/
|
||||
#define IPL2TP_PORT_NUMBER 1701
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* TYPES
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* LOCAL DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* PUBLIC DATA
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
IP_PUBLIC int ipl2tp_occupied;
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* LOCAL FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipl2tp_api_attribute_vector_raw
|
||||
*===========================================================================
|
||||
* Description: Parse a raw vector
|
||||
* Parameters:
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_STATIC Ip_bool
|
||||
ipl2tp_api_attribute_vector_raw(Ipl2tp_attrobj *attr,
|
||||
Ipl2tp_attr_info *info,
|
||||
char *ptr,
|
||||
int len)
|
||||
{
|
||||
if (ptr == IP_NULL)
|
||||
return IP_FALSE;
|
||||
|
||||
if (ipcom_strncmp(ptr, "0x", 2) == 0)
|
||||
{
|
||||
int i;
|
||||
Ip_u8 *vec;
|
||||
char tbuf[3];
|
||||
|
||||
ptr += 2;
|
||||
len -= 2;
|
||||
|
||||
len /= 2;
|
||||
vec = ipcom_malloc(len);
|
||||
|
||||
if(vec == IP_NULL)
|
||||
{
|
||||
return IP_FALSE;
|
||||
}
|
||||
|
||||
tbuf[2] = '\0';
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
ipcom_memcpy(tbuf, ptr + i * 2, 2);
|
||||
vec[i] = (Ip_u8) ipcom_strtoul(tbuf, IP_NULL, 16);
|
||||
}
|
||||
|
||||
ipl2tp_attr_vappend(attr, info->value, vec, len);
|
||||
ipcom_free(vec);
|
||||
return IP_TRUE;
|
||||
}
|
||||
|
||||
return IP_FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* PUBLIC FUNCTIONS
|
||||
****************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipl2tp_version
|
||||
*===========================================================================
|
||||
* Description: Returns the IPL2TP version string.
|
||||
* Parameters:
|
||||
* Returns: Version string.
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC const char *
|
||||
ipl2tp_version(void)
|
||||
{
|
||||
return "@(#) IPL2TP $Name: VXWORKS_ITER40_2019102207 $ - INTERPEAK_COPYRIGHT_STRING";
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipl2tp_api_version
|
||||
*===========================================================================
|
||||
* Description: Returns the API version number. This function can be used
|
||||
* for applications to support older versions of IPL2TP.
|
||||
* Parameters:
|
||||
* Returns: The IPL2TP API version number.
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC int
|
||||
ipl2tp_api_version(void)
|
||||
{
|
||||
return IPL2TP_VERSION_API;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipl2tp_api_init
|
||||
*===========================================================================
|
||||
* Description: Initialize IPL2TP package
|
||||
* Parameters:
|
||||
* Returns: IPL2TP_STATUS_OK if success.
|
||||
* IPL2TP_STATUS_NOMEM if out of memory.
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ipl2tp_status
|
||||
ipl2tp_api_init(void)
|
||||
{
|
||||
Ipl2tp_status status;
|
||||
|
||||
/* Init data */
|
||||
status = ipl2tp_data_init();
|
||||
ipl2tp_occupied = 0;
|
||||
|
||||
ipl2tp.state = IPL2TP_STATE_INIT;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipl2tp_api_exit
|
||||
*===========================================================================
|
||||
* Description: Free resources used by the IPL2TP package.
|
||||
* Parameters:
|
||||
* Returns: IPL2TP_STATUS_OK if success.
|
||||
* IPL2TP_STATUS_STATE if wrong state.
|
||||
* IPL2TP_STATUS_BUSY if tunnels/sessions open.
|
||||
*/
|
||||
IP_PUBLIC Ipl2tp_status
|
||||
ipl2tp_api_exit(void)
|
||||
{
|
||||
Ipl2tp_status status = IPL2TP_STATUS_OK;
|
||||
|
||||
IPL2TP_OCCUPIED(return IPL2TP_STATUS_OCCUPIED);
|
||||
|
||||
if (ipl2tp.state != IPL2TP_STATE_INIT)
|
||||
{
|
||||
IPCOM_LOG1(ERR,
|
||||
"%s: IPL2TP is open or not initialized",
|
||||
ipl2tp_versions[0]);
|
||||
status = IPL2TP_STATUS_STATE;
|
||||
}
|
||||
else if (ipl2tp.open_tunnels != 0 || ipl2tp.open_sessions != 0)
|
||||
{
|
||||
IPCOM_LOG1(ERR,
|
||||
"%s: Called ipl2tp_exit() with open tunnels/sessions,",
|
||||
ipl2tp_versions[0]);
|
||||
IPCOM_LOG1(ERR,
|
||||
"%s: possibly caused by pending retransmissions",
|
||||
ipl2tp_versions[0]);
|
||||
status = IPL2TP_STATUS_BUSY;
|
||||
}
|
||||
else
|
||||
{
|
||||
ipl2tp_data_exit();
|
||||
ipl2tp.state = IPL2TP_STATE_IDLE;
|
||||
}
|
||||
|
||||
IPL2TP_AVAILABLE();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipl2tp_api_open
|
||||
*===========================================================================
|
||||
* Description: Open and configure IPL2TP with global attributes.
|
||||
* Parameters: attr - Global attributes.
|
||||
* tattr_v2 - Default V2 tunnel attributes.
|
||||
* tattr_v3 - Default V3 tunnel attributes.
|
||||
* sattr_v2 - Default V2 session attributes.
|
||||
* sattr_v3 - Default V3 session attributes.
|
||||
* Returns: IPL2TP_STATUS_OK if success.
|
||||
* IPL2TP_STATUS_STATE if wrong state.
|
||||
* IPL2TP_STATUS_BADPARAM if bad attribute object(s).
|
||||
*/
|
||||
IP_PUBLIC Ipl2tp_status
|
||||
ipl2tp_api_open(Ipl2tp_attrobj attr,
|
||||
Ipl2tp_attrobj tattr_v2,
|
||||
Ipl2tp_attrobj tattr_v3,
|
||||
Ipl2tp_attrobj sattr_v2,
|
||||
Ipl2tp_attrobj sattr_v3)
|
||||
{
|
||||
Ipl2tp_status status;
|
||||
|
||||
IPL2TP_OCCUPIED(return IPL2TP_STATUS_OCCUPIED);
|
||||
|
||||
if (ipl2tp.state != IPL2TP_STATE_INIT)
|
||||
{
|
||||
IPCOM_LOG1(ERR,
|
||||
"%s: IPL2TP is already open or not initialized",
|
||||
ipl2tp_versions[0]);
|
||||
status = IPL2TP_STATUS_STATE;
|
||||
}
|
||||
else if ((status = ipl2tp_attr_global_set(attr)) != IPL2TP_STATUS_OK)
|
||||
{
|
||||
}
|
||||
else if ((status = ipl2tp_attr_tunnel_set(IP_NULL, &ipl2tp.tunnel.v2.attr, tattr_v2)) !=
|
||||
IPL2TP_STATUS_OK)
|
||||
{
|
||||
}
|
||||
else if ((status = ipl2tp_attr_tunnel_set(IP_NULL, &ipl2tp.tunnel.v3.attr, tattr_v3)) !=
|
||||
IPL2TP_STATUS_OK)
|
||||
{
|
||||
}
|
||||
else if ((status = ipl2tp_attr_session_set(IP_NULL, &ipl2tp.session.v2.attr, sattr_v2)) !=
|
||||
IPL2TP_STATUS_OK)
|
||||
{
|
||||
}
|
||||
else if ((status = ipl2tp_attr_session_set(IP_NULL, &ipl2tp.session.v3.attr, sattr_v3)) !=
|
||||
IPL2TP_STATUS_OK)
|
||||
{
|
||||
}
|
||||
else if (ipl2tp.wcallback == IP_NULL)
|
||||
{
|
||||
IPCOM_LOG1(ERR,
|
||||
"%s: Missing attribute: IPL2TP_ATTR_SET_L2TP_WRITE_CALLBACK",
|
||||
ipl2tp_versions[0]);
|
||||
status = IPL2TP_STATUS_ERROR;
|
||||
}
|
||||
|
||||
if (status == IPL2TP_STATUS_OK)
|
||||
{
|
||||
ipl2tp.state = IPL2TP_STATE_OPEN;
|
||||
}
|
||||
|
||||
IPL2TP_AVAILABLE();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipl2tp_api_close
|
||||
*===========================================================================
|
||||
* Description: Close IPL2TP. All tunnels and sessions are closed and deleted.
|
||||
* Parameters:
|
||||
* Returns: IPL2TP_STATUS_OK if success.
|
||||
* IPL2TP_STATUS_STATE if wrong state.
|
||||
*/
|
||||
IP_PUBLIC Ipl2tp_status
|
||||
ipl2tp_api_close(void)
|
||||
{
|
||||
Ipl2tp_status status = IPL2TP_STATUS_OK;
|
||||
|
||||
IPL2TP_OCCUPIED(return IPL2TP_STATUS_OCCUPIED);
|
||||
|
||||
if (ipl2tp.state != IPL2TP_STATE_OPEN)
|
||||
{
|
||||
IPCOM_LOG1(ERR,
|
||||
"%s: IPL2TP is not opened",
|
||||
ipl2tp_versions[0]);
|
||||
status = IPL2TP_STATUS_STATE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Teardown everything */
|
||||
(void)ipl2tp_disable();
|
||||
|
||||
ipl2tp.state = IPL2TP_STATE_INIT;
|
||||
}
|
||||
|
||||
IPL2TP_AVAILABLE();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipl2tp_api_attribute_set
|
||||
*===========================================================================
|
||||
* Description: Set global IPL2TP parameters.
|
||||
* Parameters: attr - Attribute object.
|
||||
* Returns: IPL2TP_STATUS_OK if success.
|
||||
* IPL2TP_STATUS_BADPARAM if bad attribute object.
|
||||
*/
|
||||
IP_PUBLIC Ipl2tp_status
|
||||
ipl2tp_api_attribute_set(Ipl2tp_attrobj attr)
|
||||
{
|
||||
Ipl2tp_status status;
|
||||
|
||||
IPL2TP_OCCUPIED(return IPL2TP_STATUS_OCCUPIED);
|
||||
|
||||
if (ipl2tp.state != IPL2TP_STATE_OPEN)
|
||||
{
|
||||
IPCOM_LOG1(ERR,
|
||||
"%s: IPL2TP is not opened",
|
||||
ipl2tp_versions[0]);
|
||||
status = IPL2TP_STATUS_STATE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set global attributes */
|
||||
status = ipl2tp_attr_global_set(attr);
|
||||
}
|
||||
|
||||
IPL2TP_AVAILABLE();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipl2tp_api_attribute_get
|
||||
*===========================================================================
|
||||
* Description: Get global IPL2TP parameters.
|
||||
* Parameters: attr - Attribute object.
|
||||
* replies - Attribute replies.
|
||||
* Returns: IPL2TP_STATUS_OK if success.
|
||||
* IPL2TP_STATUS_BADPARAM if bad attribute object.
|
||||
*/
|
||||
IP_PUBLIC Ipl2tp_status
|
||||
ipl2tp_api_attribute_get(Ipl2tp_attrobj attr,
|
||||
Ipl2tp_attrobj *replies)
|
||||
{
|
||||
Ipl2tp_status status;
|
||||
|
||||
IPL2TP_OCCUPIED(return IPL2TP_STATUS_OCCUPIED);
|
||||
|
||||
if (ipl2tp.state != IPL2TP_STATE_OPEN)
|
||||
{
|
||||
IPCOM_LOG1(ERR,
|
||||
"%s: IPL2TP is not opened",
|
||||
ipl2tp_versions[0]);
|
||||
status = IPL2TP_STATUS_STATE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set global attributes */
|
||||
status = ipl2tp_attr_global_get(attr, replies);
|
||||
}
|
||||
|
||||
IPL2TP_AVAILABLE();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipl2tp_api_l2tp_input
|
||||
*===========================================================================
|
||||
* Description: Feed an incoming L2TP packet to the L2TP engine.
|
||||
* Parameters: buffer - Memory buffer pointer.
|
||||
* payload - Pointer to packet payload, i.e. L2TP header.
|
||||
* length - Length of payload.
|
||||
* addr - IP address of sender.
|
||||
* transport - Transport type. UDP/IP.
|
||||
* Returns: IPL2TP_STATUS_OK if success.
|
||||
* IPL2TP_STATUS_BADID if the message session ID is invalid.
|
||||
* IPL2TP_STATUS_NOTL2TP if this is a non-L2TP message.
|
||||
* IPL2TP_STATUS_MALFORMED if the message is malformed.
|
||||
* IPL2TP_STATUS_IGNORE if the message is ignored.
|
||||
* IPL2TP_STATUS_TEARDOWN if a tunnel or session teardown is required.
|
||||
* Additional error codes may be returned by the user-specified
|
||||
* data callback routine.
|
||||
*/
|
||||
IP_PUBLIC Ipl2tp_status
|
||||
ipl2tp_api_l2tp_input(void *buffer,
|
||||
void *payload,
|
||||
Ip_u16 length,
|
||||
union Ip_sockaddr_union *addr,
|
||||
int transport)
|
||||
{
|
||||
Ipl2tp_status status = IPL2TP_STATUS_OK;
|
||||
Ip_u16 *flvp = payload;
|
||||
|
||||
IPL2TP_OCCUPIED(return IPL2TP_STATUS_OCCUPIED);
|
||||
|
||||
if (ipl2tp.state != IPL2TP_STATE_OPEN)
|
||||
{
|
||||
IPCOM_LOG1(ERR,
|
||||
"%s: IPL2TP is not opened",
|
||||
ipl2tp_versions[0]);
|
||||
status = IPL2TP_STATUS_STATE;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
switch (transport)
|
||||
{
|
||||
case IPL2TP_ATTR_TRANSPORT_UDP:
|
||||
/* Basic transport for v2 and v3 */
|
||||
switch (IP_GET_NTOHS(flvp) & IPL2TP_VERSION_MASK)
|
||||
{
|
||||
case IPL2TP_VERSION_L2TPV2:
|
||||
if (ipl2tp.enable_v2 == IPL2TP_MIB_DISABLED)
|
||||
{
|
||||
if (ipl2tp.enable_v3 == IPL2TP_MIB_DISABLED)
|
||||
{
|
||||
IPCOM_LOG1(ERR,
|
||||
"%s: IPL2TPV2 is not enabled",
|
||||
ipl2tp_versions[0]);
|
||||
status = IPL2TP_STATUS_STATE;
|
||||
goto leave;
|
||||
}
|
||||
/* FALLTHROUGH TO v3 parsing */
|
||||
}
|
||||
else
|
||||
{
|
||||
status = ipl2tp_v2_l2tp_input(buffer,
|
||||
payload,
|
||||
length,
|
||||
addr);
|
||||
|
||||
if (status != IPL2TP_STATUS_NEGOTIATION)
|
||||
break;
|
||||
|
||||
/* FALLTHROUGH TO v3 parsing */
|
||||
}
|
||||
|
||||
case IPL2TP_VERSION_L2TPV3:
|
||||
if (ipl2tp.enable_v3 == IPL2TP_MIB_DISABLED)
|
||||
{
|
||||
IPCOM_LOG1(ERR,
|
||||
"%s: IPL2TPV3 is not enabled",
|
||||
ipl2tp_versions[0]);
|
||||
status = IPL2TP_STATUS_STATE;
|
||||
goto leave;
|
||||
}
|
||||
status = ipl2tp_v3_l2tp_input(buffer,
|
||||
payload,
|
||||
length,
|
||||
addr,
|
||||
transport);
|
||||
break;
|
||||
default:
|
||||
IPCOM_LOG2(INFO,
|
||||
"%s: Received non-L2TP message, Ver: %d",
|
||||
ipl2tp_versions[0],
|
||||
IP_GET_NTOHS(flvp) & IPL2TP_VERSION_MASK);
|
||||
status = IPL2TP_STATUS_NOTL2TP;
|
||||
goto leave;
|
||||
}
|
||||
break;
|
||||
case IPL2TP_ATTR_TRANSPORT_IP:
|
||||
/* Transport for v3 */
|
||||
status = ipl2tp_v3_l2tp_input(buffer,
|
||||
payload,
|
||||
length,
|
||||
addr,
|
||||
transport);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
leave:
|
||||
IPL2TP_AVAILABLE();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipl2tp_api_errname
|
||||
*===========================================================================
|
||||
* Description: Get error message.
|
||||
* Parameters: status Status code.
|
||||
* Returns: A human readable description of the error.
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC CONST char *
|
||||
ipl2tp_api_errname(Ipl2tp_status status)
|
||||
{
|
||||
static CONST char *ipl2tp_status_string[] =
|
||||
{
|
||||
"IPL2TP_STATUS_OK: Success",
|
||||
"IPL2TP_STATUS_ERROR: General error",
|
||||
"IPL2TP_STATUS_IGNORE: Message or AVP ignored",
|
||||
"IPL2TP_STATUS_TEARDOWN: Tunnel or session teardown",
|
||||
"IPL2TP_STATUS_BADAUTH: Authentication failure",
|
||||
"IPL2TP_STATUS_BADAVP: Invalid attribute",
|
||||
"IPL2TP_STATUS_BADBEARER: Bearer type not in capabilities",
|
||||
"IPL2TP_STATUS_BADFRAMING: Framing type not in capabilities",
|
||||
"IPL2TP_STATUS_BADID: An invalid ID was specified",
|
||||
"IPL2TP_STATUS_BADMTYPE: Invalid message type",
|
||||
"IPL2TP_STATUS_BADPARAM: Bad parameter",
|
||||
"IPL2TP_STATUS_BADRECWIN: Invalid receive window size",
|
||||
"IPL2TP_STATUS_BUSY: Tunnel or session open",
|
||||
"IPL2TP_STATUS_CLOSE: Tunnel or session closed",
|
||||
"IPL2TP_STATUS_DRAIN: Tunnel or session creation disabled",
|
||||
"IPL2TP_STATUS_EXISTS: Tunnel or session exists",
|
||||
"IPL2TP_STATUS_FRAMINGCAPS: No common framing capabilities",
|
||||
"IPL2TP_STATUS_GOTCDN: Received CDN",
|
||||
"IPL2TP_STATUS_GOTSTOPCCN: Received StopCCN",
|
||||
"IPL2TP_STATUS_IDZERO: A zero ID was specified",
|
||||
"IPL2TP_STATUS_MALFORMED: Malformed message",
|
||||
"IPL2TP_STATUS_NOLNS: LNS operation not supported",
|
||||
"IPL2TP_STATUS_NOMEM: Out of memory",
|
||||
"IPL2TP_STATUS_NORAND: No random vector received",
|
||||
"IPL2TP_STATUS_NOSECRET: No shared secret configured",
|
||||
"IPL2TP_STATUS_NOTINIT: Item not initialized",
|
||||
"IPL2TP_STATUS_NOTL2TP: Non-L2TP message received",
|
||||
"IPL2TP_STATUS_OCCUPIED: API already occupied",
|
||||
"IPL2TP_STATUS_PROTVERSION: Protocol version mismatch",
|
||||
"IPL2TP_STATUS_RESERVEDNZ: Reserved bits non-zero",
|
||||
"IPL2TP_STATUS_STATE: State machine error",
|
||||
"IPL2TP_STATUS_TIMEOUT: Control channel timeout",
|
||||
"IPL2TP_STATUS_VENDOR: Unsupported vendor-specific AVP",
|
||||
"IPL2TP_STATUS_BADPW: Bad pseudowire type",
|
||||
"IPL2TP_STATUS_BADL2: Unknown L2 Sublayer",
|
||||
"IPL2TP_STATUS_BADSEQUENCING: Unknown data sequencing method, or no L2 Sublayer",
|
||||
"IPL2TP_STATUS_BADVERSION: Bad version",
|
||||
"IPL2TP_STATUS_CIRCUIT_DOWN: Circuit is down",
|
||||
};
|
||||
|
||||
return (status <
|
||||
(sizeof(ipl2tp_status_string) /
|
||||
sizeof(ipl2tp_status_string[0])) ?
|
||||
ipl2tp_status_string[status] : "<invalid>");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipl2tp_api_attribute_find
|
||||
*===========================================================================
|
||||
* Description: Locate an attribute in the list based on name using strtok.
|
||||
* Parameters: info - The attribute list.
|
||||
* name - The attribute name
|
||||
* value - The pointer to where the attribute value starts.
|
||||
* Returns: The attribute information structure.
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ipl2tp_attr_info *
|
||||
ipl2tp_api_attribute_find(Ipl2tp_attr_info *info,
|
||||
char *name,
|
||||
char **value)
|
||||
{
|
||||
int i;
|
||||
char *token;
|
||||
if ((token = ipcom_strtok_r(name, " \t=,", value)) == IP_NULL)
|
||||
return IP_NULL;
|
||||
|
||||
for (i = 0; info[i].value != 0; i++)
|
||||
{
|
||||
if (ipcom_strcasecmp(info[i].name, token) == 0)
|
||||
return &info[i];
|
||||
}
|
||||
|
||||
return IP_NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipl2tp_api_attribute_parse
|
||||
*===========================================================================
|
||||
* Description: Parse an attribute value using strtok
|
||||
* Parameters: attr - The attribute to append the value to.
|
||||
* info - The attribute information object
|
||||
* value - The pointer containing the value offset
|
||||
* Returns:
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_bool
|
||||
ipl2tp_api_attribute_parse(Ipl2tp_attrobj *attr,
|
||||
Ipl2tp_attr_info *info,
|
||||
char **value)
|
||||
{
|
||||
int i;
|
||||
char *token;
|
||||
|
||||
switch (info->type)
|
||||
{
|
||||
case IPL2TP_ATTR_TYPE_STRING:
|
||||
return (ipl2tp_attr_strappend(attr, info->value, *value) == IPL2TP_STATUS_OK) ?
|
||||
IP_TRUE : IP_FALSE;
|
||||
|
||||
case IPL2TP_ATTR_TYPE_INT:
|
||||
if (info->hr)
|
||||
{
|
||||
/* first token */
|
||||
if ((token = ipcom_strtok_r(IP_NULL, " \t=,", value)) == IP_NULL)
|
||||
return IP_FALSE;
|
||||
for (i = 0; info->hr[i] != IP_NULL; i++)
|
||||
{
|
||||
if (ipcom_strlen(info->hr[i]) == 0)
|
||||
continue;
|
||||
|
||||
if (ipcom_strcasecmp(info->hr[i], token) == 0)
|
||||
{
|
||||
return (ipl2tp_attr_iappend(attr, info->value, i) == IPL2TP_STATUS_OK) ?
|
||||
IP_TRUE : IP_FALSE;
|
||||
}
|
||||
}
|
||||
return IP_FALSE;
|
||||
}
|
||||
/* Fall through */
|
||||
case IPL2TP_ATTR_TYPE_SEC:
|
||||
/* first token */
|
||||
if ((token = ipcom_strtok_r(IP_NULL, " \t=,", value)) == IP_NULL)
|
||||
return IP_FALSE;
|
||||
return (ipl2tp_attr_iappend(attr, info->value,
|
||||
(int)ipcom_strtoul(token, IP_NULL, 10)) == IPL2TP_STATUS_OK) ?
|
||||
IP_TRUE : IP_FALSE;
|
||||
|
||||
case IPL2TP_ATTR_TYPE_INT64:
|
||||
if ((token = ipcom_strtok_r(IP_NULL, " \t=,", value)) == IP_NULL)
|
||||
return IP_FALSE;
|
||||
else
|
||||
{
|
||||
Ip_u64 val;
|
||||
IP_U64_SET(val, 0, ipcom_strtoul(token, IP_NULL, 10));
|
||||
ipl2tp_attr_iappend64(attr, info->value, &val);
|
||||
}
|
||||
return IP_TRUE;
|
||||
|
||||
case IPL2TP_ATTR_TYPE_ADDRESS:
|
||||
{
|
||||
union Ip_sockaddr_union uaddr;
|
||||
/* first token */
|
||||
if ((token = ipcom_strtok_r(IP_NULL, " \t=,", value)) == IP_NULL)
|
||||
return IP_FALSE;
|
||||
if (ipl2tp_api_attribute_address_parse(token, &uaddr) == IP_FALSE)
|
||||
return IP_FALSE;
|
||||
|
||||
ipl2tp_attr_addrappend(attr, info->value, &uaddr);
|
||||
}
|
||||
return IP_TRUE;
|
||||
|
||||
case IPL2TP_ATTR_TYPE_FUNCTION:
|
||||
case IPL2TP_ATTR_TYPE_POINTER:
|
||||
if ((token = ipcom_strtok_r(IP_NULL, " \t=,", value)) == IP_NULL)
|
||||
return IP_FALSE;
|
||||
else
|
||||
{
|
||||
unsigned long data = ipcom_strtoul(token, IP_NULL, 10);
|
||||
if (ipl2tp_attr_pappend(attr, info->value, (void *)data) != IPL2TP_STATUS_OK)
|
||||
return IP_FALSE;
|
||||
}
|
||||
return IP_TRUE;
|
||||
|
||||
case IPL2TP_ATTR_TYPE_VECTOR:
|
||||
{
|
||||
int len;
|
||||
|
||||
if (*value == IP_NULL)
|
||||
{
|
||||
len = 0;
|
||||
ipl2tp_attr_vappend(attr, info->value, *value, len);
|
||||
return IP_TRUE;
|
||||
}
|
||||
|
||||
len = (int)ipcom_strlen(*value);
|
||||
|
||||
if (ipl2tp_api_attribute_vector_raw(attr,info,*value,len) == IP_FALSE)
|
||||
{
|
||||
/* Append the vector */
|
||||
ipl2tp_attr_vappend(attr, info->value, *value, len);
|
||||
}
|
||||
}
|
||||
return IP_TRUE;
|
||||
|
||||
case IPL2TP_ATTR_TYPE_VEC8:
|
||||
{
|
||||
int len;
|
||||
|
||||
if (*value == IP_NULL)
|
||||
len = 0;
|
||||
else
|
||||
len = (int)ipcom_strlen(*value);
|
||||
|
||||
if (ipl2tp_api_attribute_vector_raw(attr,info,*value,len) == IP_FALSE)
|
||||
{
|
||||
Ip_u8 *vec = ipcom_malloc(len * sizeof(Ip_u8));
|
||||
|
||||
if (vec == IP_NULL)
|
||||
return IP_FALSE;
|
||||
|
||||
i = 0;
|
||||
while ((token = ipcom_strtok_r(IP_NULL, " ,", value)) != IP_NULL)
|
||||
{
|
||||
Ip_u8 v8;
|
||||
if (info->hr)
|
||||
{
|
||||
/* first token */
|
||||
for (i = 0; info->hr[i] != IP_NULL; i++)
|
||||
{
|
||||
if (ipcom_strlen(info->hr[i]) == 0)
|
||||
continue;
|
||||
|
||||
if (ipcom_strcasecmp(info->hr[i], token) == 0)
|
||||
{
|
||||
v8 = (Ip_u8)i;
|
||||
goto set_vec8;
|
||||
}
|
||||
}
|
||||
|
||||
/* Didn't find it */
|
||||
ipcom_free(vec);
|
||||
return IP_FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
v8 = (Ip_u8)ipcom_strtoul(token, IP_NULL, 10);
|
||||
}
|
||||
set_vec8:
|
||||
vec[i++] = (Ip_u8)v8;
|
||||
}
|
||||
|
||||
ipl2tp_attr_vappend(attr, info->value, vec, i);
|
||||
ipcom_free(vec);
|
||||
}
|
||||
}
|
||||
return IP_TRUE;
|
||||
|
||||
case IPL2TP_ATTR_TYPE_VEC16:
|
||||
{
|
||||
int len;
|
||||
|
||||
if (*value == IP_NULL)
|
||||
len = 0;
|
||||
else
|
||||
len = (int)ipcom_strlen(*value);
|
||||
|
||||
if (ipl2tp_api_attribute_vector_raw(attr,info,*value,len) == IP_FALSE)
|
||||
{
|
||||
Ip_u16 *vec = ipcom_malloc(len * sizeof(Ip_u16));
|
||||
|
||||
if(vec == IP_NULL)
|
||||
{
|
||||
return IP_FALSE;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while ((token = ipcom_strtok_r(IP_NULL, " ,", value)) != IP_NULL)
|
||||
{
|
||||
Ip_u16 v16;
|
||||
|
||||
if (info->hr)
|
||||
{
|
||||
/* first token */
|
||||
for (i = 0; info->hr[i] != IP_NULL; i++)
|
||||
{
|
||||
if (ipcom_strlen(info->hr[i]) == 0)
|
||||
continue;
|
||||
|
||||
if (ipcom_strcasecmp(info->hr[i], token) == 0)
|
||||
{
|
||||
v16 = (Ip_u16)i;
|
||||
goto set_vec16;
|
||||
}
|
||||
}
|
||||
|
||||
ipcom_free(vec);
|
||||
return IP_FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
v16 = (Ip_u16)ipcom_strtoul(token, IP_NULL, 10);
|
||||
}
|
||||
set_vec16:
|
||||
vec[i++] = v16;
|
||||
}
|
||||
|
||||
ipl2tp_attr_vappend(attr, info->value, vec, i * (int)sizeof(Ip_u16));
|
||||
ipcom_free(vec);
|
||||
}
|
||||
}
|
||||
return IP_TRUE;
|
||||
|
||||
default:
|
||||
case IPL2TP_ATTR_TYPE_KEY:
|
||||
case IPL2TP_ATTR_TYPE_NONE:
|
||||
break;
|
||||
}
|
||||
|
||||
return IP_FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipl2tp_api_attribute_address_parse
|
||||
*===========================================================================
|
||||
* Description: Parse addresses. Both v4 and v6.
|
||||
* Parameters: str - The address to parse.
|
||||
* uaddr - Where to store the result.
|
||||
* Returns: IP_TRUE if parsing was successful.
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ip_bool
|
||||
ipl2tp_api_attribute_address_parse(char *str,
|
||||
union Ip_sockaddr_union *uaddr)
|
||||
{
|
||||
|
||||
ipcom_memset(uaddr, 0, sizeof(*uaddr));
|
||||
|
||||
if (ipcom_inet_pton(IP_AF_INET, str, &uaddr->sin.sin_addr) > 0)
|
||||
{
|
||||
uaddr->sin.sin_family = IP_AF_INET;
|
||||
uaddr->sin.sin_len = sizeof(struct Ip_sockaddr_in);
|
||||
uaddr->sin.sin_port = ip_htons(IPL2TP_PORT_NUMBER);
|
||||
return IP_TRUE;
|
||||
}
|
||||
#ifdef IPCOM_USE_INET6
|
||||
if (ipcom_inet_pton(IP_AF_INET6, str, &uaddr->sin6.sin6_addr) > 0)
|
||||
{
|
||||
uaddr->sin6.sin6_family = IP_AF_INET6;
|
||||
uaddr->sin6.sin6_len = sizeof(struct Ip_sockaddr_in6);
|
||||
uaddr->sin6.sin6_port = ip_htons(IPL2TP_PORT_NUMBER);
|
||||
return IP_TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* No go */
|
||||
return IP_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
*===========================================================================
|
||||
* ipl2tp_api_attribute_info
|
||||
*===========================================================================
|
||||
* Description: Map a tag to an info structure
|
||||
* Parameters: tag - The tag.
|
||||
* Returns: The attribute's information structure.
|
||||
*
|
||||
*/
|
||||
IP_PUBLIC Ipl2tp_attr_info *
|
||||
ipl2tp_api_attribute_info(int tag)
|
||||
{
|
||||
int i;
|
||||
Ipl2tp_attr_info *array;
|
||||
|
||||
if (tag < IPL2TP_ATTR_END_ENUM)
|
||||
array = ipl2tp_tags;
|
||||
else if (tag < IPL2TP_TATTR_END_ENUM)
|
||||
array = ipl2tp_tunnel_tags;
|
||||
else
|
||||
array = ipl2tp_session_tags;
|
||||
|
||||
for (i = 0; array[i].value != 0; i++)
|
||||
{
|
||||
if (array[i].value == (Ip_u32)tag)
|
||||
return &array[i];
|
||||
}
|
||||
|
||||
return IP_NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
****************************************************************************
|
||||
* END OF FILE
|
||||
****************************************************************************
|
||||
*/
|
||||
Reference in New Issue
Block a user