original files of m241

This commit is contained in:
neelimap
2026-07-30 11:19:44 +05:30
parent 170c2b3f3a
commit afc7070c1f
12254 changed files with 7655111 additions and 0 deletions
@@ -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
****************************************************************************
*/
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,841 @@
/*
******************************************************************************
* INTERPEAK SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp_api_tunnel.c,v $ $Revision: 1.4 $
* $Source: /home/interpeak/CVSRoot/ipl2tp/src/ipl2tp_api_tunnel.c,v $
* $Author: tneale $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelis@interpeak.se>
******************************************************************************
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#include "ipl2tp_h.h"
#include "ipl2tp_api.h"
#include "ipl2tp_api_tunnel.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"
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
/*
****************************************************************************
* 9 STATIC FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* 10 GLOBAL FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* 11 PUBLIC FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipl2tp_api_tunnel_attribute_set
*===========================================================================
* Description: Set tunnel parameters
* Parameters: key - Tunnel identifier
* attr - Attribute object.
* Returns: IPL2TP_STATUS_OK if success.
* IPL2TP_STATUS_BADID if invalid tunnel ID.
* IPL2TP_STATUS_BADPARAM if bad attribute object.
*/
IP_PUBLIC Ipl2tp_status
ipl2tp_api_tunnel_attribute_set(Ipl2tp_key *key,
Ipl2tp_attrobj attr)
{
Ipl2tp_tunnel *tunnel;
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[key->version]);
status = IPL2TP_STATUS_STATE;
}
else if (key->ident == 0)
{
switch (key->version)
{
case IPL2TP_VERSION_L2TPV3:
status = ipl2tp_attr_tunnel_set(IP_NULL, &ipl2tp.tunnel.v3.attr, attr);
break;
case IPL2TP_VERSION_L2TPV2:
default:
status = ipl2tp_attr_tunnel_set(IP_NULL, &ipl2tp.tunnel.v2.attr, attr);
break;
}
}
else if ((tunnel = ipl2tp_state_tunnel_get(key)) == IP_NULL)
{
IPCOM_LOG2(ERR,
"%s: Called ipl2tp_tunnel_attribute_set() with invalid index: %d",
ipl2tp_versions[key->version],
(int)key->ident);
status = IPL2TP_STATUS_BADID;
}
else
{
status = ipl2tp_attr_tunnel_set(tunnel, &tunnel->attr, attr);
}
IPL2TP_AVAILABLE();
return status;
}
/*
*===========================================================================
* ipl2tp_api_tunnel_attribute_get
*===========================================================================
* Description: Set tunnel parameters
* Parameters: key - Tunnel identifier
* attr - Attribute object.
* replies - Attribute replies
* Returns: IPL2TP_STATUS_OK if success.
* IPL2TP_STATUS_BADID if invalid tunnel ID.
* IPL2TP_STATUS_BADPARAM if bad attribute object.
*/
IP_PUBLIC Ipl2tp_status
ipl2tp_api_tunnel_attribute_get(Ipl2tp_key *key,
Ipl2tp_attrobj attr,
Ipl2tp_attrobj *replies)
{
Ipl2tp_tunnel *tunnel;
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[key->version]);
status = IPL2TP_STATUS_STATE;
}
else if (key->ident == 0)
{
switch (key->version)
{
case IPL2TP_VERSION_L2TPV3:
status = ipl2tp_attr_tunnel_get(IP_NULL, &ipl2tp.tunnel.v3.attr, attr, replies);
break;
case IPL2TP_VERSION_L2TPV2:
default:
status = ipl2tp_attr_tunnel_get(IP_NULL, &ipl2tp.tunnel.v2.attr, attr, replies);
break;
}
}
else if ((tunnel = ipl2tp_state_tunnel_get(key)) == IP_NULL)
{
IPCOM_LOG2(ERR,
"%s: Called ipl2tp_tunnel_attribute_get() with invalid index: %d",
ipl2tp_versions[key->version],
(int)key->ident);
status = IPL2TP_STATUS_BADID;
}
else
{
status = ipl2tp_attr_tunnel_get(tunnel, &tunnel->attr, attr, replies);
}
IPL2TP_AVAILABLE();
return status;
}
/*
*===========================================================================
* ipl2tp_api_tunnel_attribute_query
*===========================================================================
* Description: Get a singular tunnel parameter
* Parameters: key - The tunnel key.
* query - The query
* replies - Where the replies are to be stored.
* Returns:
*
*/
IP_PUBLIC void
ipl2tp_api_tunnel_attribute_query(Ipl2tp_key *key,
int query,
Ipl2tp_attrobj *replies)
{
Ipl2tp_attrobj attr = IP_NULL;
/* Retrieve the type */
ipl2tp_attr_add_query(&attr,
query);
ipl2tp_api_tunnel_attribute_get(key, attr, replies);
ipl2tp_attr_delete(&attr);
}
/*
*===========================================================================
* ipl2tp_api_tunnel_open
*===========================================================================
* Description: Open a new tunnel.
* Parameters: tidp - Array of tunnel ID pointers. If HS is true, this
* MUST be atleast two elements.
* addr - IP address.
* tattr - Tunnel attributes.
* hs - Handshake. If using V3, allow for V2 negotiation.
* Returns: IPL2TP_STATUS_OK if Success.
* IPL2TP_STATUS_DRAIN if creation disabled.
* IPL2TP_STATUS_NOMEM if out of memory.
* IPL2TP_STATUS_BADPARAM if bad attribute object.
* IPL2TP_STATUS_EXISTS if a tunnel already exists to the peer.
*/
IP_PUBLIC Ipl2tp_status
ipl2tp_api_tunnel_open(Ipl2tp_key *tidp,
union Ip_sockaddr_union *addr,
Ipl2tp_attrobj tattr,
int establish,
Ip_bool hs)
{
Ipl2tp_tunnel *tunnel;
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 if (ipl2tp.admin_state == IPL2TP_MIB_DISABLED ||
ipl2tp.drain_tunnels == IPL2TP_MIB_YES)
{
IPCOM_LOG1(WARNING,
"%s: Tunnel creation currently disabled",
ipl2tp_versions[tidp->version]);
status = IPL2TP_STATUS_DRAIN;
}
else if (tidp[0].version == IPL2TP_VERSION_L2TPV2 && ipl2tp.enable_v2 == IPL2TP_MIB_DISABLED)
{
IPCOM_LOG1(ERR,
"%s: IPL2TPV2 is not enabled",
ipl2tp_versions[0]);
status = IPL2TP_STATUS_STATE;
}
else if (tidp[0].version == IPL2TP_VERSION_L2TPV3 && ipl2tp.enable_v3 == IPL2TP_MIB_DISABLED)
{
IPCOM_LOG1(ERR,
"%s: IPL2TPV3 is not enabled",
ipl2tp_versions[0]);
status = IPL2TP_STATUS_STATE;
}
else if ((tunnel = ipl2tp_state_tunnel_find_by_addr(addr, tidp[0].version)) != IP_NULL)
{
/* Old tunnel is available */
tidp[0].ident = tunnel->local.key.ident;
status = IPL2TP_STATUS_EXISTS;
}
else if ((tunnel = ipl2tp_tunnel_new(tidp[0].version, addr)) == IP_NULL)
{
IPCOM_LOG1(ERR,
"%s: Out of memory when creating tunnel",
ipl2tp_versions[tidp[0].version]);
status = IPL2TP_STATUS_NOMEM;
}
else
{
/* Enter tunnel properties */
tunnel->local_open = 1;
/* Set attributes */
if ((status = ipl2tp_attr_tunnel_set(tunnel, &tunnel->attr, tattr)) != IPL2TP_STATUS_OK)
{
ipl2tp_tunnel_delete(tunnel);
}
else
{
if (tidp[0].version == IPL2TP_VERSION_L2TPV3)
{
if (hs)
{
tidp[1].version = 0;
tidp[1].ident = 0;
/* Create version2 slave tunnel */
if ((tunnel->slave = ipl2tp_tunnel_new(IPL2TP_VERSION_L2TPV2, addr)) != IP_NULL)
{
/* */
if (ipl2tp_attr_tunnel_set(tunnel->slave, &tunnel->slave->attr, tattr) != IPL2TP_STATUS_OK)
{
ipl2tp_tunnel_delete(tunnel->slave);
tunnel->slave = IP_NULL;
}
else
{
/* Reverse pointer */
tunnel->slave->state = IPL2TP_TSTATE_WAIT_CTL_REPLY;
tunnel->slave->slave = tunnel;
/* Store the tunnel parameters */
tidp[1].version = IPL2TP_VERSION_L2TPV2;
tidp[1].ident = tunnel->slave->local.key.ident;
}
}
}
}
/* Start tunnel establishhment */
if (establish)
{
tunnel->state = IPL2TP_TSTATE_WAIT_CTL_REPLY;
ipl2tp_message_sccrq(tunnel);
(void)ipl2tp_state_establish_tunnel_timeout_init(tunnel, 1);
}
tidp[0].ident = tunnel->local.key.ident;
}
}
IPL2TP_AVAILABLE();
return status;
}
/*
*===========================================================================
* ipl2tp_api_tunnel_close
*===========================================================================
* Description: Close an IPL2TP tunnel.
* Parameters: key - The tunnel to close.
* Returns: IPL2TP_STATUS_OK if success.
* IPL2TP_STATUS_BADID if invalid tunnel ID.
*/
IP_PUBLIC Ipl2tp_status
ipl2tp_api_tunnel_close(Ipl2tp_key *key)
{
Ipl2tp_status status = IPL2TP_STATUS_OK;
Ipl2tp_tunnel *tunnel;
IPL2TP_OCCUPIED(return IPL2TP_STATUS_OCCUPIED);
if (ipl2tp.state != IPL2TP_STATE_OPEN)
{
IPCOM_LOG1(ERR,
"%s: IPL2TP is not opened",
ipl2tp_versions[key->version]);
status = IPL2TP_STATUS_STATE;
}
else if ((tunnel = ipl2tp_state_tunnel_get(key)) == IP_NULL)
{
IPCOM_LOG2(ERR,
"%s: Called ipl2tp_tunnel_close() with invalid tunnel ID: %d",
ipl2tp_versions[key->version],
(int)key->ident);
status = IPL2TP_STATUS_BADID;
}
else
{
IPL2TP_TUNNEL_RESULT_SET(tunnel,
IPL2TP_STATUS_CLOSE,
IPL2TP_RES_StopCCN_GENERAL_REQUEST,
0,
"Tunnel closed");
/* Send termination message */
if (tunnel->state != IPL2TP_TSTATE_IDLE)
{
ipl2tp_message_stopccn(tunnel);
}
ipl2tp_state_tunnel_teardown(tunnel);
}
IPL2TP_AVAILABLE();
return status;
}
/*
*===========================================================================
* ipl2tp_api_interface_attribute_set
*===========================================================================
* Description: Set tunnel parameters
* Parameters: ifindex - Interface index.
* attr - Attribute object.
* Returns: IPL2TP_STATUS_OK if success.
* IPL2TP_STATUS_BADID if invalid interface index.
* IPL2TP_STATUS_BADPARAM if bad attribute object.
*/
IP_PUBLIC Ipl2tp_status
ipl2tp_api_interface_attribute_set(Ip_u32 ifindex,
Ipl2tp_attrobj attr)
{
Ipl2tp_tunnel *tunnel;
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 if ((tunnel = ipcom_hash_get(ipl2tp.tunnel.hash_ifindex, &ifindex)) == IP_NULL ||
tunnel->state == IPL2TP_TSTATE_VOID)
{
IPCOM_LOG2(ERR,
"%s: Called ipl2tp_interface_attribute_set() with invalid index: %d",
ipl2tp_versions[0],
(int)ifindex);
status = IPL2TP_STATUS_BADID;
}
else
{
status = ipl2tp_attr_tunnel_set(tunnel, &tunnel->attr, attr);
}
IPL2TP_AVAILABLE();
return status;
}
/*
*===========================================================================
* ipl2tp_api_interface_attribute_get
*===========================================================================
* Description: Get tunnel parameters
* Parameters: ifindex - Interface index.
* attr - Attribute object.
* replies - Attribute replies.
* Returns: IPL2TP_STATUS_OK if success.
* IPL2TP_STATUS_BADID if invalid interface index.
* IPL2TP_STATUS_BADPARAM if bad attribute object.
*/
IP_PUBLIC Ipl2tp_status
ipl2tp_api_interface_attribute_get(Ip_u32 ifindex,
Ipl2tp_attrobj attr,
Ipl2tp_attrobj *replies)
{
Ipl2tp_tunnel *tunnel;
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 if ((tunnel = ipcom_hash_get(ipl2tp.tunnel.hash_ifindex, &ifindex)) == IP_NULL ||
tunnel->state == IPL2TP_TSTATE_VOID)
{
IPCOM_LOG2(ERR,
"%s: Called ipl2tp_interface_attribute_get() with invalid index: %d",
ipl2tp_versions[0],
(int)ifindex);
status = IPL2TP_STATUS_BADID;
}
else
{
status = ipl2tp_attr_tunnel_get(tunnel, &tunnel->attr, attr, replies);
}
IPL2TP_AVAILABLE();
return status;
}
/*
*===========================================================================
* ipl2tp_api_tunnel_next
*===========================================================================
* Description: Retrieves the tunnel identifier
* Parameters: last - Last tunnel we retrieved, or IP_NULL if first
* next - [OUT] next tunnel key.
* Returns: IPL2TP_STATUS_OK if next has been properly filled in.
*
*/
IP_PUBLIC Ipl2tp_status
ipl2tp_api_tunnel_next(Ipl2tp_key *last,
Ipl2tp_key *next)
{
Ipl2tp_tunnel *t = IP_NULL;
Ipl2tp_key first;
Ipl2tp_status status = IPL2TP_STATUS_ERROR;
IPL2TP_OCCUPIED(return IPL2TP_STATUS_OCCUPIED);
first.version = IPL2TP_VERSION_L2TPV2;
first.ident = 0;
if (last == IP_NULL)
{
last = &first;
}
/* Default to v2 */
if (last->version == 0)
{
first.ident = last->ident;
last = &first;
}
for (;;)
{
/* First call? */
if (last->ident == 0)
{
switch (last->version)
{
case IPL2TP_VERSION_L2TPV2:
t = IPCOM_LIST_FIRST(&ipl2tp.tunnel.v2.tunnels);
break;
case IPL2TP_VERSION_L2TPV3:
t = IPCOM_LIST_FIRST(&ipl2tp.tunnel.v3.tunnels);
break;
}
}
else
{
/* Locate last tunnel */
t = ipcom_hash_get(ipl2tp.tunnel.hash_id, last);
/* If found, get next in list */
if (t)
{
t = IPCOM_LIST_NEXT(&t->head);
}
}
/* Found a tunnel? */
if (t)
{
next->ident = t->local.key.ident;
next->version = t->local.key.version;
status = IPL2TP_STATUS_OK;
break;
}
else if (last->version == IPL2TP_VERSION_L2TPV2)
{
/* Go through the V3 tunnels */
last = &first;
last->version = IPL2TP_VERSION_L2TPV3;
last->ident = 0;
}
else
{
/* We're done */
break;
}
}
/* */
IPL2TP_AVAILABLE();
return status;
}
/*
*===========================================================================
* ipl2tp_api_ifindex_next
*===========================================================================
* Description: Retrieves the next interface
* Parameters: last - Last ifindex, or 0 if first.
* next - [OUT] next ifindex.
* Returns: IPL2TP_STATUS_OK if next has been properly filled in.
*
*/
IP_PUBLIC Ipl2tp_status
ipl2tp_api_ifindex_next(Ip_u32 last,
Ip_u32 *next)
{
Ipl2tp_tunnel *tunnel;
Ipl2tp_version version = IPL2TP_VERSION_L2TPV2;
Ipl2tp_status status = IPL2TP_STATUS_ERROR;
/* First loop? */
IPL2TP_OCCUPIED(return IPL2TP_STATUS_OCCUPIED);
if (last == 0)
{
/* First tunnel */
tunnel = IPCOM_LIST_FIRST(&ipl2tp.tunnel.v2.tunnels);
}
else
{
/* Lookup last tunnel */
tunnel = ipcom_hash_get(ipl2tp.tunnel.hash_ifindex, &last);
if (tunnel == IP_NULL)
{
IPL2TP_AVAILABLE();
return IPL2TP_STATUS_ERROR;
}
version = tunnel->local.key.version;
tunnel = IPCOM_LIST_NEXT(&tunnel->head);
}
for (;;)
{
if (tunnel == IP_NULL)
{
if (version == IPL2TP_VERSION_L2TPV2)
{
version = IPL2TP_VERSION_L2TPV3;
tunnel = IPCOM_LIST_FIRST(&ipl2tp.tunnel.v3.tunnels);
}
else
{
/* We're done */
break;
}
}
/* Find next valid tunnel */
while (tunnel != IP_NULL)
{
/* Does it have an ifindex */
if (tunnel->attr.ifindex != 0)
{
*next = tunnel->attr.ifindex;
status = IPL2TP_STATUS_OK;
break;
}
/* Get next */
tunnel = IPCOM_LIST_NEXT(&tunnel->head);
}
/* Found one, time to exit */
if (tunnel != IP_NULL)
break;
}
IPL2TP_AVAILABLE();
return status;
}
/*
*===========================================================================
* ipl2tp_api_tunnel_negotiation
*===========================================================================
* Description: Retrieves the tunnel identifier
* Parameters: tidp - Array of two tunnel keys.
* key - The key that has been negotiated, will point to
* the correct entry in the tidp list.
* Returns: IPL2TP_STATUS_OK if key has been properly filled in,
* IPL2TP_STATUS_NEGOTIATING if the tunnels still being negotiated.
*
*/
IP_GLOBAL Ipl2tp_status
ipl2tp_api_tunnel_negotiation(Ipl2tp_key *tidp,
Ipl2tp_key **key)
{
Ipl2tp_status status = IPL2TP_STATUS_ERROR;
int i;
/* First loop? */
IPL2TP_OCCUPIED(return IPL2TP_STATUS_OCCUPIED);
*key = IP_NULL;
for (i = 0; i < 2; i++)
{
Ipl2tp_tunnel *t;
if (tidp[i].version == 0)
continue;
/* Locate last tunnel */
t = ipcom_hash_get(ipl2tp.tunnel.hash_id, &tidp[i]);
if (t != IP_NULL)
{
/* Still have a slave? */
if (t->slave)
{
status = IPL2TP_STATUS_NEGOTIATION;
break;
}
if (t->state > IPL2TP_TSTATE_TEARDOWN)
{
*key = &tidp[i];
status = IPL2TP_STATUS_OK;
break;
}
}
}
IPL2TP_AVAILABLE();
return status;
}
/*
*===========================================================================
* ipl2tp_api_tunnel_authentication_established
*===========================================================================
* Description: Inform IPL2TP that the authentication method is installed
* so the establishment of an outgoing tunnel can continue.
* Parameters: key - Tunnel identifier.
* Returns: IPL2TP_STATUS_STATE if IPL2TP is not open.
* IPL2TP_STATUS_BADID if bad tunnel ID.
*/
IP_PUBLIC Ipl2tp_status
ipl2tp_api_tunnel_authentication_established(Ipl2tp_key *key)
{
Ipl2tp_tunnel *tunnel = IP_NULL;
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 if ((tunnel = ipl2tp_state_tunnel_get(key)) == IP_NULL)
{
IPCOM_LOG2(ERR,
"%s: Called ipl2tp_authentication_established() with invalid tunnel ID: %d",
ipl2tp_versions[key->version],
(int)key->ident);
status = IPL2TP_STATUS_BADID;
}
else if (tunnel->state != IPL2TP_TSTATE_WAIT_AUTH_CB)
{
IPL2TP_TUNNEL_RESULT_SET(tunnel,
IPL2TP_STATUS_STATE,
IPL2TP_RES_StopCCN_STATE_MACHINE,
0,
"Authentication completed in non TSTATE_WAIT_AUTH_CB state");
IPCOM_LOG2(WARNING,
"%s: Called ipl2tp_authentication_established() for tunnel in %s state",
ipl2tp_versions[key->version],
ipl2tp_state_tstate_name(tunnel->state));
status = IPL2TP_STATUS_TEARDOWN;
}
else if (tunnel->sccrq.message == IP_NULL || tunnel->sccrq.avp == IP_NULL)
{
IPL2TP_TUNNEL_RESULT_SET(tunnel,
IPL2TP_STATUS_STATE,
IPL2TP_RES_StopCCN_STATE_MACHINE,
0,
"Authentication completed tunnel with no previous SCCRQ");
IPCOM_LOG1(WARNING,
"%s: Called ipl2tp_authentication_established() for tunnel with no previous SCCRQ",
ipl2tp_versions[key->version]);
status = IPL2TP_STATUS_TEARDOWN;
}
else
{
/* Feed message to the state machine */
status = IPL2TP_TUNNEL_STATE_SCCRQ(tunnel);
}
if (tunnel != IP_NULL)
{
IPL2TP_SAFE_FREE(tunnel->sccrq.message);
ipl2tp_avp_delete(tunnel->sccrq.avp);
tunnel->sccrq.message = IP_NULL;
tunnel->sccrq.avp = IP_NULL;
/* Teardown ? */
if (status == IPL2TP_STATUS_TEARDOWN)
{
/* The tunnel must go away */
if (tunnel->state != IPL2TP_TSTATE_TEARDOWN &&
tunnel->remote.key.ident != 0)
{
ipl2tp_message_stopccn(tunnel);
}
ipl2tp_state_tunnel_teardown(tunnel);
}
/* Send a ZLB if required */
ipl2tp_state_maybe_zlb(tunnel);
}
IPL2TP_AVAILABLE();
return status;
}
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,239 @@
/*
******************************************************************************
* HEADER FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp_attr_h.h,v $ $Revision: 1.2 $
* $Source: /home/interpeak/CVSRoot/ipl2tp/src/ipl2tp_attr_h.h,v $
* $Author: joel $ $Date: 2006-01-30 10:47:45 $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelius@interpeak.se>
******************************************************************************
*/
#ifndef IPL2TP_ATTR_H_H
#define IPL2TP_ATTR_H_H
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/* Attribute object header */
typedef struct
{
Ip_u32 magic; /* Magic cookie */
Ip_u16 flags; /* Attribute object flags */
Ip_u16 pool_max; /* Max size of attribute pool */
Ip_u16 pool_size; /* Size of attribute pool */
Ip_u16 pool_last; /* Last entry in attribute pool */
char pool[1]; /* Attribute pool (can be extended) */
}
Ipl2tp_attribute_object;
typedef struct
{
Ip_u16 tag; /* Attribute tag */
Ip_u16 status; /* Status of operation */
Ip_u16 next; /* Size of this attribute */
Ip_u16 length; /* Length of payload */
}
Ipl2tp_attribute;
/*
****************************************************************************
* 6 FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipl2tp_attr_global_set
*===========================================================================
* Description: Set global attributes.
* Parameters: attrobj - The attribute object.
* Returns: The status code.
*
*/
IP_GLOBAL Ipl2tp_status ipl2tp_attr_global_set(Ipl2tp_attrobj attrobj);
/*
*===========================================================================
* ipl2tp_attr_global_get
*===========================================================================
* Description: Get global attributes.
* Parameters: attrget - The attribute objects to get
* attreply - The replies.
* Returns: The status code.
*
*/
IP_GLOBAL Ipl2tp_status ipl2tp_attr_global_get(Ipl2tp_attrobj attrobj,
Ipl2tp_attrobj *attreply);
/*
*===========================================================================
* ipl2tp_attr_tunnel_set
*===========================================================================
* Description: Set tunnel attributes.
* Parameters: tunnel - The tunnel.
* attr - The tunnel attributes.
* attrobj - Attribute object.
* Returns:
*
*/
IP_GLOBAL Ipl2tp_status ipl2tp_attr_tunnel_set(Ipl2tp_tunnel *tunnel,
Ipl2tp_tunnel_attributes *attr,
Ipl2tp_attrobj attrobj);
/*
*===========================================================================
* ipl2tp_attr_tunnel_set
*===========================================================================
* Description: Set tunnel attributes.
* Parameters: tunnel - The tunnel.
* attr - The tunnel attributes.
* attrget - Attribute object.
* attreply - Reply object
* Returns:
*
*/
IP_GLOBAL Ipl2tp_status ipl2tp_attr_tunnel_get(Ipl2tp_tunnel *tunnel,
Ipl2tp_tunnel_attributes *attr,
Ipl2tp_attrobj attrget,
Ipl2tp_attrobj *attreply);
/*
*===========================================================================
* ipl2tp_attr_session_set
*===========================================================================
* Description: Set session attributes.
* Parameters: session - The session.
* attr - Session attributes
* attrobj - The attributes.
* Returns:
*
*/
IP_GLOBAL Ipl2tp_status ipl2tp_attr_session_set(Ipl2tp_session *session,
Ipl2tp_session_attributes *attr,
Ipl2tp_attrobj attrobj);
/*
*===========================================================================
* ipl2tp_attr_session_set
*===========================================================================
* Description: Set session attributes.
* Parameters: session - The session.
* attr - Session attributes
* attrget - The attributes.
* attreply - The attribute replies
* Returns:
*
*/
IP_GLOBAL Ipl2tp_status ipl2tp_attr_session_get(Ipl2tp_session *session,
Ipl2tp_session_attributes *attr,
Ipl2tp_attrobj attrget,
Ipl2tp_attrobj *attreply);
/*
*===========================================================================
* ipl2tp_attr_tunnel_attribute_copy
*===========================================================================
* Description: Copy tunnel attributes, allocate memory for those
* that are required.
* Parameters: dst - The destination
* src - The source.
* Returns:
*
*/
IP_GLOBAL void ipl2tp_attr_tunnel_attribute_copy(Ipl2tp_tunnel_attributes *dst,
Ipl2tp_tunnel_attributes *src);
/*
*===========================================================================
* ipl2tp_attr_tunnel_attribute_copy
*===========================================================================
* Description: Free memory allocated for tunnel attributes.
* Parameters: attr - The Attributes
* Returns:
*
*/
IP_GLOBAL void ipl2tp_attr_tunnel_attribute_free(Ipl2tp_tunnel_attributes *attr);
/*
*===========================================================================
* ipl2tp_attr_tunnel_attribute_copy
*===========================================================================
* Description: Copy session attributes, allocate memory for those
* that are required.
* Parameters: dst - The destination
* src - The source.
* Returns:
*
*/
IP_GLOBAL void ipl2tp_attr_session_attribute_copy(Ipl2tp_session_attributes *dst,
Ipl2tp_session_attributes *src);
/*
*===========================================================================
* ipl2tp_attr_session_attribute_copy
*===========================================================================
* Description: Free memory allocated for session attributes.
* Parameters: attr - The Attributes
* Returns:
*
*/
IP_GLOBAL void ipl2tp_attr_session_attribute_free(Ipl2tp_session_attributes *attr);
#ifdef __cplusplus
}
#endif
#endif
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,983 @@
/*
******************************************************************************
* INTERPEAK SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp_data.c,v $ $Revision: 1.7.14.1 $
* $Source: /home/interpeak/CVSRoot/ipl2tp/src/ipl2tp_data.c,v $
* $Author: hxu0 $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelis@interpeak.se>
******************************************************************************
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#include "ipl2tp_h.h"
#include "ipl2tp_avp.h"
#include "ipl2tp_data.h"
#include "ipl2tp_state.h"
#include "ipl2tp_attr.h"
#include "ipl2tp_attr_h.h"
#include "ipl2tp_message.h"
#include "ipl2tp_v2.h"
#include "ipl2tp_v3.h"
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
IP_PUBLIC Ipl2tp_context ipl2tp;
/*
****************************************************************************
* 9 STATIC FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipl2tp_data_key_hash
*===========================================================================
* Description:
* Parameters:
* Returns:
*/
IP_STATIC unsigned
ipl2tp_data_key_hash(Ipl2tp_key *key)
{
/* Hash the session ID */
return ipcom_hash_update(key,
sizeof(*key),
0);
}
/*
*===========================================================================
* ipl2tp_data_obj_hash_session
*===========================================================================
* Description:
* Parameters:
* Returns:
*/
IP_STATIC unsigned
ipl2tp_data_obj_hash_session(Ipl2tp_session *session)
{
/* Hash the version & session ID */
return ipcom_hash_update(&session->local.key,
sizeof(session->local.key),
0);
}
/*
*===========================================================================
* ipl2tp_data_cmp_session
*===========================================================================
* Description:
* Parameters:
* Returns:
*/
IP_STATIC Ip_bool
ipl2tp_data_cmp_session(Ipl2tp_session *session,
Ipl2tp_key *key)
{
/* Version & ID must match */
if (session->local.key.version == key->version &&
session->local.key.ident == key->ident)
return IP_TRUE;
return IP_FALSE;
}
/*
*===========================================================================
* ipl2tp_data_obj_hash_tunnel
*===========================================================================
* Description:
* Parameters:
* Returns:
*/
IP_STATIC unsigned
ipl2tp_data_obj_hash_tunnel(Ipl2tp_tunnel *tunnel)
{
/* Hash the tunnel ID */
return ipcom_hash_update(&tunnel->local.key,
sizeof(tunnel->local.key),
0);
}
/*
*===========================================================================
* ipl2tp_data_cmp_tunnel
*===========================================================================
* Description:
* Parameters:
* Returns:
*/
IP_STATIC Ip_bool
ipl2tp_data_cmp_tunnel(Ipl2tp_tunnel *tunnel,
Ipl2tp_key *key)
{
/* Version & ID must match */
if (tunnel->local.key.version == key->version &&
tunnel->local.key.ident == key->ident)
return IP_TRUE;
return IP_FALSE;
}
/*
*===========================================================================
* ipl2tp_data_obj_hash_addr
*===========================================================================
* Description:
* Parameters:
* Returns:
*/
IP_STATIC unsigned
ipl2tp_data_obj_hash_addr(Ipl2tp_tunnel *tunnel)
{
/* Hash the version first */
unsigned val = ipcom_hash_update(&tunnel->local.key.version,
sizeof(tunnel->local.key.version),
0);
/* Hash the tunnel ID */
return ipcom_hash_update(&tunnel->remote.addr,
tunnel->remote.addr.sa.sa_len,
val);
}
/*
*===========================================================================
* ipl2tp_data_key_hash_addr
*===========================================================================
* Description:
* Parameters:
* Returns:
*/
IP_STATIC unsigned
ipl2tp_data_key_hash_addr(Ipl2tp_addr *key)
{
/* Hash the version first */
unsigned val = ipcom_hash_update(&key->key.version,
sizeof(key->key.version),
0);
/* Hash the address */
return ipcom_hash_update(key->addr,
key->addr->sa.sa_len,
val);
}
/*
*===========================================================================
* ipl2tp_data_cmp_addr
*===========================================================================
* Description:
* Parameters:
* Returns:
*/
IP_STATIC Ip_bool
ipl2tp_data_cmp_addr(Ipl2tp_tunnel *tunnel,
Ipl2tp_addr *key)
{
/* Version & addr must match; Tunnel must not be teardown. */
if (tunnel->local.key.version == key->key.version &&
IPL2TP_SOCKADDR_EQUAL(&tunnel->remote.addr.sa, &key->addr->sa) &&
tunnel->state > IPL2TP_TSTATE_TEARDOWN)
return IP_TRUE;
return IP_FALSE;
}
/*
*===========================================================================
* ipl2tp_data_obj_hash_tunnel_assigned
*===========================================================================
* Description:
* Parameters:
* Returns:
*/
IP_STATIC unsigned
ipl2tp_data_obj_hash_tunnel_assigned(Ipl2tp_tunnel *tunnel)
{
/* Hash the addr & version first */
unsigned val = ipl2tp_data_obj_hash_addr(tunnel);
/* Hash the tunnel ID */
return ipcom_hash_update(&tunnel->remote.key.ident,
sizeof(tunnel->remote.key.ident),
val);
}
/*
*===========================================================================
* ipl2tp_data_key_hash_tunnel_assigned
*===========================================================================
* Description:
* Parameters:
* Returns:
*/
IP_STATIC unsigned
ipl2tp_data_key_hash_tunnel_assigned(Ipl2tp_addr *key)
{
/* Hash the addr & version first */
unsigned val = ipl2tp_data_key_hash_addr(key);
/* Hash the session ID */
return ipcom_hash_update(&key->key.ident,
sizeof(key->key.ident),
val);
}
/*
*===========================================================================
* ipl2tp_data_cmp_tunnel_assigned
*===========================================================================
* Description:
* Parameters:
* Returns:
*/
IP_STATIC Ip_bool
ipl2tp_data_cmp_tunnel_assigned(Ipl2tp_tunnel *tunnel,
Ipl2tp_addr *key)
{
/* Addr, Version & ID must match */
if (ipl2tp_data_cmp_addr(tunnel, key) &&
tunnel->remote.key.ident == key->key.ident)
return IP_TRUE;
return IP_FALSE;
}
/*
*===========================================================================
* ipl2tp_data_obj_hash_tunnel_ifindex
*===========================================================================
* Description:
* Parameters:
* Returns:
*/
IP_STATIC unsigned
ipl2tp_data_obj_hash_tunnel_ifindex(Ipl2tp_tunnel *tunnel)
{
/* Hash the tunnel ifindex ID */
return ipcom_hash_update(&tunnel->attr.ifindex,
sizeof(tunnel->attr.ifindex),
0);
}
/*
*===========================================================================
* ipl2tp_data_key_hash_tunnel_assigned
*===========================================================================
* Description:
* Parameters:
* Returns:
*/
IP_STATIC unsigned
ipl2tp_data_key_hash_tunnel_ifindex(Ip_u32 *ifindex)
{
/* Hash the tunnel ifindex ID */
return ipcom_hash_update(ifindex,
sizeof(*ifindex),
0);
}
/*
*===========================================================================
* ipl2tp_data_tunnel_close
*===========================================================================
* Description: Close down a tunnel.
* Parameters: tunnel - The tunnel.
* data - Opaque data (UNUSED)
* Returns:
*
*/
IP_STATIC void
ipl2tp_data_tunnel_close(Ipl2tp_tunnel *tunnel,
void *data)
{
IPL2TP_UNUSED(data);
/* Do teardown */
ipl2tp_state_tunnel_teardown(tunnel);
ipl2tp_tunnel_delete(tunnel);
}
/*
*===========================================================================
* ipl2tp_data_cmp_tunnel_assigned
*===========================================================================
* Description:
* Parameters:
* Returns:
*/
IP_STATIC Ip_bool
ipl2tp_data_cmp_tunnel_ifindex(Ipl2tp_tunnel *tunnel,
Ip_u32 *ifindex)
{
/* The same? */
return tunnel->attr.ifindex == *ifindex;
}
/*
****************************************************************************
* 10 GLOBAL FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipl2tp_data_init
*===========================================================================
* Description: Init the global data object
* Parameters:
* Returns:
*
*/
IP_GLOBAL Ipl2tp_status
ipl2tp_data_init(void)
{
int i;
ipcom_memset(&ipl2tp, 0, sizeof(ipl2tp));
#ifdef IPL2TP_USE_MUTEX
/* Create synchronization mutex */
(void)ipcom_mutex_create(&ipl2tp.mutex);
#endif
/* Init other lists */
ipcom_list_init(&ipl2tp.tunnel.v2.tunnels);
ipcom_list_init(&ipl2tp.tunnel.v3.tunnels);
ipcom_list_init(&ipl2tp.tunnel.free_list);
ipcom_list_init(&ipl2tp.session.free_list);
/* The basic id tunnel hash */
ipl2tp.tunnel.hash_id = ipcom_hash_new((Ipcom_hash_obj_func)ipl2tp_data_obj_hash_tunnel,
(Ipcom_hash_key_func)ipl2tp_data_key_hash,
(Ipcom_hash_cmp_func)ipl2tp_data_cmp_tunnel);
/* The basic remote id tunnel hash */
ipl2tp.tunnel.hash_remote_id = ipcom_hash_new((Ipcom_hash_obj_func)ipl2tp_data_obj_hash_tunnel_assigned,
(Ipcom_hash_key_func)ipl2tp_data_key_hash_tunnel_assigned,
(Ipcom_hash_cmp_func)ipl2tp_data_cmp_tunnel_assigned);
/* The basic remote id tunnel hash */
ipl2tp.tunnel.hash_ifindex = ipcom_hash_new((Ipcom_hash_obj_func)ipl2tp_data_obj_hash_tunnel_ifindex,
(Ipcom_hash_key_func)ipl2tp_data_key_hash_tunnel_ifindex,
(Ipcom_hash_cmp_func)ipl2tp_data_cmp_tunnel_ifindex);
/* The address tunnel hash */
ipl2tp.tunnel.hash_remote_addr = ipcom_hash_new((Ipcom_hash_obj_func)ipl2tp_data_obj_hash_addr,
(Ipcom_hash_key_func)ipl2tp_data_key_hash_addr,
(Ipcom_hash_cmp_func)ipl2tp_data_cmp_addr);
/* The session hash */
ipl2tp.session.hash_id = ipcom_hash_new((Ipcom_hash_obj_func)ipl2tp_data_obj_hash_session,
(Ipcom_hash_key_func)ipl2tp_data_key_hash,
(Ipcom_hash_cmp_func)ipl2tp_data_cmp_session);
/* Did they succeed? */
if (ipl2tp.tunnel.hash_id == IP_NULL || ipl2tp.tunnel.hash_remote_addr == IP_NULL ||
ipl2tp.tunnel.hash_remote_addr == IP_NULL || ipl2tp.tunnel.hash_ifindex == IP_NULL ||
ipl2tp.session.hash_id == IP_NULL)
{
ipl2tp_data_exit();
return IPL2TP_STATUS_NOMEM;
}
/* Tunnel and session IDs start at 1 */
ipl2tp.tunnel.v2.ident = 1;
ipl2tp.tunnel.v3.ident = 1;
ipl2tp.session.v2.ident = 1;
ipl2tp.session.v3.ident = 1;
for (i = 1; i <= IPL2TP_PREALLOCATED_TUNNEL_NO; i++)
{
Ipl2tp_tunnel *tunnel;
if ((tunnel = ipl2tp_tunnel_malloc()) == IP_NULL)
{
ipl2tp_data_exit();
return IPL2TP_STATUS_NOMEM;
}
ipcom_list_insert_first(&ipl2tp.tunnel.free_list,
&tunnel->head);
}
for (i = 1; i <= IPL2TP_PREALLOCATED_SESSION_NO; i++)
{
Ipl2tp_session *session;
if ((session = ipl2tp_session_malloc()) == IP_NULL)
{
IPCOM_LOG1(ERR,
"%s: Out of memory for session descriptors",
ipl2tp_versions[0]);
ipl2tp_data_exit();
return IPL2TP_STATUS_NOMEM;
}
ipcom_list_insert_first(&ipl2tp.session.free_list,
&session->head);
}
/* Serial number starts at 1 */
ipl2tp.call_serial_number = 1;
/* Set default attributes */
ipcom_strncpy(ipl2tp.host_name, IPL2TP_HOST_NAME, IPL2TP_MAX_HOST_NAME_SIZE);
ipl2tp.first_retransmit_sec = IPL2TP_FIRST_RETRANSMIT_SEC;
ipl2tp.tunnel_zombie_sec = IPL2TP_TUNNEL_ZOMBIE_SEC;
ipl2tp.hello_tick_sec = IPL2TP_HELLO_TICK_SEC;
ipl2tp.establish_timeout_sec = IPL2TP_ESTABLISH_TIMEOUT_SEC;
ipl2tp.open_exclusive = IPL2TP_OPEN_EXCLUSIVE;
ipl2tp.admin_state = IPL2TP_MIB_ENABLED;
ipl2tp.drain_tunnels = IPL2TP_MIB_NO;
ipl2tp.enable_outgoing = IPL2TP_MIB_DISABLED;
ipl2tp.enable_v3 = IPL2TP_MIB_DISABLED;
ipl2tp.enable_v2 = IPL2TP_MIB_DISABLED;
ipl2tp.close_unused_tunnels = IPL2TP_MIB_YES;
/* Set default tunnel attributes */
ipl2tp.tunnel.v2.attr.hello_interval_sec = IPL2TP_HELLO_INTERVAL_SEC;
ipl2tp.tunnel.v2.attr.max_retransmit = IPL2TP_MAX_RETRANSMIT;
ipl2tp.tunnel.v2.attr.max_backoff_sec = IPL2TP_MAX_BACKOFF_SEC;
ipl2tp.tunnel.v2.attr.receive_window_size = IPL2TP_RECEIVE_WINDOW_SIZE;
ipl2tp.tunnel.v2.attr.framing_capabilities = IPL2TP_MIB_FRAMING_NONE;
ipl2tp.tunnel.v2.attr.authentication = IPL2TP_MIB_AUTH_NONE;
ipl2tp.tunnel.v2.attr.sequencing = IPL2TP_MIB_NEVER;
ipl2tp.tunnel.v2.attr.hide_avp = IPL2TP_MIB_NO;
ipl2tp.tunnel.v3.attr.hello_interval_sec = IPL2TP_HELLO_INTERVAL_SEC;
ipl2tp.tunnel.v3.attr.max_retransmit = IPL2TP_MAX_RETRANSMIT;
ipl2tp.tunnel.v3.attr.max_backoff_sec = IPL2TP_MAX_BACKOFF_SEC;
ipl2tp.tunnel.v3.attr.receive_window_size = IPL2TP_RECEIVE_WINDOW_SIZE;
ipl2tp.tunnel.v3.attr.framing_capabilities = IPL2TP_MIB_FRAMING_NONE;
ipl2tp.tunnel.v3.attr.authentication = IPL2TP_MIB_AUTH_NONE;
ipl2tp.tunnel.v3.attr.sequencing = IPL2TP_MIB_NEVER;
ipl2tp.tunnel.v3.attr.hide_avp = IPL2TP_MIB_NO;
/* Set default session attributes */
ipl2tp.session.v2.attr.framing_type = IPL2TP_MIB_FRAMING_NONE;
ipl2tp.session.v3.attr.circuit_status = IPL2TP_MIB_DOWN;
ipl2tp.session.v3.attr.l2_out_of_order_reset = IPL2TP_L2_OUT_OF_ORDER_RESET;
/* Mark as initialized */
ipl2tp.magic = IPL2TP_MAGIC;
return IPL2TP_STATUS_OK;
}
/*
*===========================================================================
* ipl2tp_data_exit
*===========================================================================
* Description: Free any resources allocated by ipl2tp_data_init.
* Parameters:
* Returns:
*
*/
IP_GLOBAL void
ipl2tp_data_exit(void)
{
Ipl2tp_tunnel *tunnel;
Ipl2tp_session *session;
#ifdef IPL2TP_USE_MUTEX
ipcom_mutex_delete(&ipl2tp.mutex);
#endif
/* Close down the tunnels & sessions */
ipcom_hash_for_each(ipl2tp.tunnel.hash_id,
(Ipcom_hash_foreach_cb_func)ipl2tp_data_tunnel_close,
IP_NULL);
/* Grab the first session */
while ((session = IPCOM_LIST_FIRST(&ipl2tp.session.free_list)) != IP_NULL)
{
/* Remove it from the queue */
ipcom_list_remove(&session->head);
ipcom_free(session);
}
/* Grab the first session */
while ((tunnel = IPCOM_LIST_FIRST(&ipl2tp.tunnel.free_list)) != IP_NULL)
{
/* Remove it from the queue */
ipcom_list_remove(&tunnel->head);
ipcom_free(tunnel);
}
/* Delete the hashes */
if (ipl2tp.tunnel.hash_remote_addr)
ipcom_hash_delete(ipl2tp.tunnel.hash_remote_addr);
if (ipl2tp.tunnel.hash_remote_id)
ipcom_hash_delete(ipl2tp.tunnel.hash_remote_id);
if (ipl2tp.tunnel.hash_id)
ipcom_hash_delete(ipl2tp.tunnel.hash_id);
if (ipl2tp.tunnel.hash_ifindex)
ipcom_hash_delete(ipl2tp.tunnel.hash_ifindex);
if (ipl2tp.session.hash_id)
ipcom_hash_delete(ipl2tp.session.hash_id);
ipcom_memset(&ipl2tp, 0, sizeof(ipl2tp));
}
/*
*===========================================================================
* ipl2tp_tunnel_new
*===========================================================================
* Description: Retrieve a tunnel descriptor.
* Parameters: version - Version of the tunnel.
* addr - The address of the peer.
* Returns: A new tunnel.
*
*/
IP_GLOBAL Ipl2tp_tunnel *
ipl2tp_tunnel_new(Ipl2tp_version version,
union Ip_sockaddr_union *addr)
{
Ipl2tp_tunnel *t;
/* Try to recycle an old descriptor */
if ((t = IPCOM_LIST_FIRST(&ipl2tp.tunnel.free_list)) != IP_NULL)
{
ipcom_list_remove(&t->head);
}
else
{
t = ipl2tp_tunnel_malloc();
}
/* Initialize */
if (t != IP_NULL)
{
/*lint -e419*/
ipcom_memset(t, 0, sizeof(*t));
ipcom_list_init(&t->session_list);
ipcom_list_init(&t->message_list);
IPCOM_TMO_INIT(&t->timer);
t->state = IPL2TP_TSTATE_IDLE;
t->cwnd = 1;
t->drain_tunnel = IPL2TP_MIB_NO;
ipl2tp.open_tunnels++;
/* Copy the address */
ipcom_memset(&t->remote.addr, 0, sizeof(t->remote.addr));
ipcom_memcpy(&t->remote.addr, addr, addr->sa.sa_len);
t->common.receive_window_size = IPL2TP_RECEIVE_WINDOW_SIZE;
t->ssthresh = t->common.receive_window_size;
/* Create logheader and setup callback table*/
switch (version)
{
case IPL2TP_VERSION_L2TPV2:
ipl2tp_v2_tunnel_init(t);
break;
case IPL2TP_VERSION_L2TPV3:
ipl2tp_v3_tunnel_init(t);
break;
}
/* Add it to the ID and ADDR table */
if ((ipcom_hash_add(ipl2tp.tunnel.hash_id, t) != IPCOM_SUCCESS) ||
(ipcom_hash_add(ipl2tp.tunnel.hash_remote_addr, t) != IPCOM_SUCCESS))
{
IPCOM_LOG1(ERR,
"%s: Unable to add a new tunnel",
ipl2tp_versions[0]);
ipcom_free (t);
return IP_NULL;
}
}
return t;
}
/*
*===========================================================================
* ipl2tp_session_new
*===========================================================================
* Description: Retrieve a session descriptor
* Parameters: tunnel - The tunnel this session belongs to.
* cookie - Cookie for identification of the session.
* cookie_size - Size of the cookie [max 8].
* Returns: The session
*
*/
IP_GLOBAL Ipl2tp_session *
ipl2tp_session_new(Ipl2tp_tunnel *tunnel,
void *cookie,
Ip_u8 cookie_size)
{
Ipl2tp_session *s;
/* Try to recycle an old descriptor */
if ((s = IPCOM_LIST_FIRST(&ipl2tp.session.free_list)) != IP_NULL)
{
ipcom_list_remove(&s->head);
}
else
{
s = ipl2tp_session_malloc();
}
/* Initialize */
if (s != IP_NULL)
{
ipcom_memset(s, 0, sizeof(*s));
IPCOM_TMO_INIT(&s->timer);
/* */
s->state = IPL2TP_SSTATE_IDLE;
s->common.call_serial_number = ipl2tp.call_serial_number++;
/* Grab next session ID based on version */
if (cookie_size)
{
ipl2tp_util_vector_create(&s->local.cookie,
cookie,
cookie_size);
}
s->tunnel = tunnel;
/* Initialize the tunnel */
IPL2TP_TUNNEL_SESSION_INIT(s);
/* Set the tunnel ownership */
ipcom_list_insert_last(&tunnel->session_list, &s->head);
if (ipcom_hash_add(ipl2tp.session.hash_id, s) != IPCOM_SUCCESS)
{
IPCOM_LOG1(ERR,
"%s: Unable to add a new session",
ipl2tp_versions[0]);
ipcom_free(s);
return IP_NULL;
}
ipl2tp.open_sessions++;
}
return s;
}
/*
*===========================================================================
* ipl2tp_tunnel_malloc
*===========================================================================
* Description: Allocate a new tunnel descriptor.
* Parameters:
* Returns: The tunnel.
*
*/
IP_GLOBAL Ipl2tp_tunnel *
ipl2tp_tunnel_malloc(void)
{
Ipl2tp_tunnel *t;
/* Limit the amount of tunnels */
if (ipl2tp.tunnel.total > IPL2TP_TUNNEL_MAX)
{
IPCOM_LOG1(ERR,
"%s: Max no of tunnels created",
ipl2tp_versions[0]);
return IP_NULL;
}
/* Try to get new memory */
if ((t = ipcom_malloc(sizeof(*t))) == IP_NULL)
{
IPCOM_LOG1(ERR,
"%s: Out of memory for tunnel descriptor",
ipl2tp_versions[0]);
return IP_NULL;
}
/* Increase the number of tunnels */
ipl2tp.tunnel.total++;
/* Initialize state and ID */
t->state = IPL2TP_TSTATE_VOID;
return t;
}
/*
*===========================================================================
* ipl2tp_session_malloc
*===========================================================================
* Description: Allocate a new session descriptor.
* Parameters:
* Returns: The session.
*
*/
IP_GLOBAL Ipl2tp_session *
ipl2tp_session_malloc(void)
{
Ipl2tp_session *s;
/* Limit the amount of sessions */
if (ipl2tp.session.total > IPL2TP_SESSION_MAX)
{
IPCOM_LOG1(ERR,
"%s: Max no of sessions created",
ipl2tp_versions[0]);
return IP_NULL;
}
/* Try to get new memory */
if ((s = ipcom_malloc(sizeof(*s))) == IP_NULL)
{
IPCOM_LOG1(ERR,
"%s: Out of memory for sesssion descriptor",
ipl2tp_versions[0]);
return IP_NULL;
}
/* One more session */
ipl2tp.session.total++;
/* Initialize state and ID */
s->state = IPL2TP_SSTATE_VOID;
return s;
}
/*
*===========================================================================
* ipl2tp_tunnel_delete
*===========================================================================
* Description: Delete a tunnel
* Parameters: tunnel - The tunnel descriptor.
* Returns:
*
*/
IP_GLOBAL void
ipl2tp_tunnel_delete(Ipl2tp_tunnel *tunnel)
{
/* */
if (tunnel->slave != IP_NULL)
{
Ipl2tp_tunnel *slave = tunnel->slave;
/* Clear all pointers */
tunnel->slave = IP_NULL;
slave->slave = IP_NULL;
/* Tear the slave down */
ipl2tp_tunnel_delete(slave);
}
/* Cancel any outstanding timer */
ipcom_tmo_cancel(&tunnel->timer);
/* Remove it from the remote tunnel hash */
ipcom_hash_remove(ipl2tp.tunnel.hash_remote_id, tunnel);
/* Remove it from the tunnel hash */
ipcom_hash_remove(ipl2tp.tunnel.hash_id, tunnel);
/* Remove it from the remote address hash */
ipcom_hash_remove(ipl2tp.tunnel.hash_remote_addr, tunnel);
/* Remove it from the ifindex hash */
ipcom_hash_remove(ipl2tp.tunnel.hash_ifindex, tunnel);
/* Flush any outstanding messages */
ipl2tp_state_tunnel_flush(tunnel);
IPL2TP_SAFE_FREE(tunnel->sccrq.message);
ipl2tp_avp_delete(tunnel->sccrq.avp);
tunnel->sccrq.avp = IP_NULL;
tunnel->sccrq.message = IP_NULL;
ipl2tp_attr_tunnel_attribute_free(&tunnel->attr);
IPL2TP_SAFE_FREE(tunnel->last_result.error_message);
IPL2TP_SAFE_FREE(tunnel->last_error.error_message);
IPL2TP_SAFE_FREE(tunnel->expected_response.array);
IPL2TP_SAFE_FREE(tunnel->common.host_name);
IPL2TP_SAFE_FREE(tunnel->common.vendor_name);
IPL2TP_SAFE_FREE(tunnel->common.tie_breaker.array);
tunnel->state = IPL2TP_TSTATE_VOID;
IPL2TP_TUNNEL_DONE(tunnel);
ipcom_list_insert_last(&ipl2tp.tunnel.free_list, &tunnel->head);
if (--ipl2tp.open_tunnels == 0 && ipl2tp.drain_tunnels == IPL2TP_MIB_YES)
{
ipl2tp.admin_state = IPL2TP_MIB_DISABLED;
ipl2tp.drain_tunnels = IPL2TP_MIB_NO;
}
}
/*
*===========================================================================
* ipl2tp_session_delete
*===========================================================================
* Description: Delete a session
* Parameters: session - The session descriptor.
* Returns:
*
*/
IP_GLOBAL void
ipl2tp_session_delete(Ipl2tp_session *session)
{
ipl2tp_attr_session_attribute_free(&session->attr);
IPL2TP_SAFE_FREE(session->local.cookie.array);
/* Is it currently owned by a tunnel? */
if (session->tunnel != IP_NULL)
ipcom_list_remove(&session->head);
/* Remove from the hash */
ipcom_hash_remove(ipl2tp.session.hash_id, session);
/* All done */
IPL2TP_TUNNEL_SESSION_DONE(session);
/* */
session->state = IPL2TP_SSTATE_VOID;
ipcom_list_insert_last(&ipl2tp.session.free_list, &session->head);
ipl2tp.open_sessions--;
}
/*
*===========================================================================
* ipl2tp_disable
*===========================================================================
* Description: Disable IPL2TP temporarily. All tunnels and sessions
* are closed and deleted.
* Parameters:
* Returns: IPL2TP_STATUS_OK if success.
*
*/
IP_GLOBAL Ipl2tp_status
ipl2tp_disable(void)
{
Ipl2tp_tunnel *tnext;
Ipl2tp_tunnel *t;
/* Loop for tunnels */
for (t = IPCOM_LIST_FIRST(&ipl2tp.tunnel.v2.tunnels);
t != IP_NULL;
t = tnext)
{
tnext = IPCOM_LIST_NEXT(&t->head);
IPL2TP_TUNNEL_RESULT_SET(t,
IPL2TP_STATUS_CLOSE,
IPL2TP_RES_StopCCN_GENERAL_REQUEST,
0,
"Tunnel closed");
ipl2tp_message_stopccn(t);
ipl2tp_state_tunnel_teardown(t);
}
/* Loop for tunnels */
for (t = IPCOM_LIST_FIRST(&ipl2tp.tunnel.v3.tunnels);
t != IP_NULL;
t = tnext)
{
tnext = IPCOM_LIST_NEXT(&t->head);
IPL2TP_TUNNEL_RESULT_SET(t,
IPL2TP_STATUS_CLOSE,
IPL2TP_RES_StopCCN_GENERAL_REQUEST,
0,
"Tunnel closed");
ipl2tp_message_stopccn(t);
ipl2tp_state_tunnel_teardown(t);
}
return IPL2TP_STATUS_OK;
}
/*
****************************************************************************
* 11 PUBLIC FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,183 @@
/*
******************************************************************************
* HEADER FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp_data.h,v $ $Revision: 1.2 $
* $Source: /home/interpeak/CVSRoot/ipl2tp/src/ipl2tp_data.h,v $
* $Author: joel $ $Date: 2006-01-30 10:47:45 $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelius@interpeak.se>
******************************************************************************
*/
#ifndef IPL2TP_DATA_H
#define IPL2TP_DATA_H
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 FUNCTIONS
****************************************************************************
*/
extern Ipl2tp_context ipl2tp;
/*
*===========================================================================
* ipl2tp_data_init
*===========================================================================
* Description: Init the global data object
* Parameters:
* Returns:
*
*/
IP_GLOBAL Ipl2tp_status ipl2tp_data_init(void);
/*
*===========================================================================
* ipl2tp_data_exit
*===========================================================================
* Description: Free any resources allocated by ipl2tp_data_init.
* Parameters:
* Returns:
*
*/
IP_GLOBAL void ipl2tp_data_exit(void);
/*
*===========================================================================
* ipl2tp_tunnel_new
*===========================================================================
* Description: Retrieve a tunnel descriptor.
* Parameters: version - Protocol version
* addr - The address being used.
* Returns: A new tunnel.
*
*/
IP_GLOBAL Ipl2tp_tunnel *ipl2tp_tunnel_new(Ipl2tp_version version,
union Ip_sockaddr_union *addr);
/*
*===========================================================================
* ipl2tp_session_new
*===========================================================================
* Description: Retrieve a session descriptor
* Parameters: tunnel - The tunnel this session belongs to.
* cookie - Cookie for identification of the session.
* cookie_size - Size of the cookie [max 8].
* Returns: The session
*
*/
IP_GLOBAL Ipl2tp_session *ipl2tp_session_new(Ipl2tp_tunnel *tunnel,
void *cookie,
Ip_u8 cookie_size);
/*
*===========================================================================
* ipl2tp_tunnel_malloc
*===========================================================================
* Description: Allocate a new tunnel descriptor.
* Parameters:
* Returns: The tunnel.
*
*/
IP_GLOBAL Ipl2tp_tunnel *ipl2tp_tunnel_malloc(void);
/*
*===========================================================================
* ipl2tp_session_malloc
*===========================================================================
* Description: Allocate a new session descriptor.
* Parameters:
* Returns: The session.
*
*/
IP_GLOBAL Ipl2tp_session *ipl2tp_session_malloc(void);
/*
*===========================================================================
* ipl2tp_tunnel_delete
*===========================================================================
* Description: Delete a tunnel
* Parameters: tunnel - The tunnel descriptor.
* Returns:
*
*/
IP_GLOBAL void ipl2tp_tunnel_delete(Ipl2tp_tunnel *tunnel);
/*
*===========================================================================
* ipl2tp_session_delete
*===========================================================================
* Description: Delete a session
* Parameters: session - The session descriptor.
* Returns:
*
*/
IP_GLOBAL void ipl2tp_session_delete(Ipl2tp_session *session);
/*
*===========================================================================
* ipl2tp_disable
*===========================================================================
* Description: Disable IPL2TP temporarily. All tunnels and sessions
* are closed and deleted.
* Parameters:
* Returns: IPL2TP_STATUS_OK if success.
*
*/
IP_GLOBAL Ipl2tp_status ipl2tp_disable(void);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,742 @@
/*
******************************************************************************
* SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp_h.h,v $ $Revision: 1.8.10.1 $
* $Source: /home/interpeak/CVSRoot/ipl2tp/src/ipl2tp_h.h,v $
* $Author: jren $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
*
******************************************************************************
*/
#ifndef _IPL2TP_H_H_
#define _IPL2TP_H_H_
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*
* Main L2TP include file.
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#define IPCOM_USE_CLIB_PROTO
#include "ipcom_type.h"
#include "ipcom_cstyle.h"
#include "ipcom_clib.h"
#include "ipcom_clib2.h"
#include "ipcom_list.h"
#include "ipcom_hash.h"
#include "ipcom_sock.h"
#include "ipcom_sock6.h"
#include "ipcom_syslog.h"
#include "ipcom_tmo.h"
#include "ipcom_type.h"
#include "ipcom_os.h"
#include "ipcom_err.h"
#include "ipl2tp.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
#define IPL2TP_SOCKADDR_EQUAL(x,y) ((x)->sa_len == (y)->sa_len && \
ipcom_memcmp((x), (y), (y)->sa_len) == 0)
#define IPL2TP_SAFE_FREE(x) if ((x) != IP_NULL) ipcom_free(x)
#define IPL2TP_SAFE_ICALLBACK(x,d) ((x) == IP_NULL ? 0 : x d)
#define IPL2TP_SAFE_CALLBACK(x,d) if ((x) != IP_NULL) x d
#define IPL2TP_SAFE_SWAP(y,x) \
if ((y).head.ok) do { \
IPL2TP_SAFE_FREE(x); \
(x) = (y).value; \
(y).value = IP_NULL; \
} while (0)
#define IPL2TP_SAFE_VEC(y,x) \
if ((y).head.ok) do { \
ipl2tp_util_vector_dup(&x, &(y).vec); \
} while (0)
#define IPL2TP_SAFE_ASSIGN(y,x) \
if ((y).head.ok) do { \
(x) = (y).value; \
} while (0)
#define IPL2TP_NTOA_ADDRSIZE (IP_INET6_ADDRSTRLEN + 2)
#define IPL2TP_NTOA_ADDRMASK 3
#define IPL2TP_NUM2STR2(a) #a
#define IPL2TP_NUM2STR(a) IPL2TP_NUM2STR2(a)
/* Bit vector macros */
#define BITMAP(map,bitno) struct \
{ \
Ip_u32 no; \
Ip_u8 bits[((bitno) + 7) / 8]; \
} \
map
#define BITINI(map,bitno) do \
{ \
(map)->no = bitno; \
ipcom_memset((map)->bits, 0, sizeof((map)->bits)); \
} \
while (0)
#define BITSET(map,bit) if ((Ip_u32)(bit) < (map)->no) \
(map)->bits[(bit) / 8] |= (1 << ((bit) % 8))
#define BITCLR(map,bit) if ((Ip_u32)(bit) < (map)->no) \
(map)->bits[(bit) / 8] &= ~(1 << ((bit) % 8))
#define BITTST(map,bit) (((Ip_u32)(bit) < (map)->no) && \
(((map)->bits[(bit) / 8] & (1 << ((bit) % 8))) != 0))
/* Header flag values */
#define IPL2TP_HEADER_FLAG_CONTROL 0x8000
#define IPL2TP_HEADER_FLAG_LENGTH 0x4000
#define IPL2TP_HEADER_FLAG_SEQUENCE 0x0800
#define IPL2TP_HEADER_FLAG_OFFSET 0x0200
#define IPL2TP_HEADER_FLAG_PRIORITY 0x0100
#define IPL2TP_HEADER_FLAG_RESERVED 0x3400
/* Header version field values */
#define IPL2TP_VERSION_MASK 0x000F
#define IPL2TP_VERSION_RESERVED 0x00F0
/*
*===========================================================================
* syslog
*===========================================================================
*/
#if defined(_WRS_CONFIG_IPL2TP_SYSLOG_PRIORITY)
#define IPCOM_SYSLOG_PRIORITY _WRS_CONFIG_IPL2TP_SYSLOG_PRIORITY
#else
#define IPCOM_SYSLOG_PRIORITY IPL2TP_SYSLOG_PRIORITY
#endif
#define IPCOM_SYSLOG_FACILITY IPCOM_LOG_IPL2TP
/*
****************************************************************************
* 5 PUBLIC TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 INTERNAL TYPES
****************************************************************************
*/
typedef struct
{
Ip_u8 *array;
Ip_size_t size;
}
Ipl2tp_vector;
/*
*===========================================================================
* Ipl2tp_State
*===========================================================================
*/
typedef enum
{
IPL2TP_STATE_IDLE,
IPL2TP_STATE_INIT,
IPL2TP_STATE_OPEN
}
Ipl2tp_state;
/*
*===========================================================================
* Ipl2tp_Tunnel_state
*===========================================================================
*/
typedef enum
{
IPL2TP_TSTATE_VOID,
IPL2TP_TSTATE_IDLE,
IPL2TP_TSTATE_TEARDOWN,
IPL2TP_TSTATE_WAIT_CTL_REPLY,
IPL2TP_TSTATE_WAIT_AUTH_CB,
IPL2TP_TSTATE_WAIT_CTL_CONN,
IPL2TP_TSTATE_ESTABLISHED
}
Ipl2tp_tunnel_state;
/*
*===========================================================================
* Ipl2tp_Session_state
*===========================================================================
*/
typedef enum
{
IPL2TP_SSTATE_VOID,
IPL2TP_SSTATE_IDLE,
IPL2TP_SSTATE_WAIT_CS_ANSWER,
IPL2TP_SSTATE_WAIT_TUNNEL,
IPL2TP_SSTATE_WAIT_REPLY,
IPL2TP_SSTATE_WAIT_CONNECT,
IPL2TP_SSTATE_ESTABLISHED
}
Ipl2tp_session_state;
/*
*===========================================================================
* Tunnel_table
*===========================================================================
*
* Tunnel callback table.
*/
struct Ipl2tp_message;
struct Ipl2tp_tunnel;
struct Ipl2tp_session;
struct Ipl2tp_avp;
typedef void (*Ipl2tp_tunnel_message_init)
(
struct Ipl2tp_message *container
);
typedef void (*Ipl2tp_tunnel_message_log)
(
struct Ipl2tp_message *container,
const char *kind
);
typedef void (*Ipl2tp_tunnel_message_digest)
(
struct Ipl2tp_message *container
);
typedef void (*Ipl2tp_tunnel_assign_peer_id)
(
struct Ipl2tp_tunnel *tunnel,
struct Ipl2tp_avp *avp
);
typedef Ipl2tp_status (*Ipl2tp_tunnel_state_machine)
(
struct Ipl2tp_tunnel *tunnel
);
/* Message function */
typedef Ipl2tp_status (*Ipl2tp_message_func)
(
struct Ipl2tp_tunnel *tunnel,
struct Ipl2tp_session *session,
struct Ipl2tp_avp *avp
);
/* Message function */
typedef void (*Ipl2tp_tunnel_func)
(
struct Ipl2tp_tunnel *tunnel
);
/* Message function */
typedef void (*Ipl2tp_tunnel_session_func)
(
struct Ipl2tp_session *session
);
typedef struct Ipl2tp_tunnel_table
{
Ipl2tp_tunnel_message_init message_init; /* Container initialization */
Ipl2tp_tunnel_message_log message_log; /* Log container */
Ipl2tp_tunnel_message_digest message_digest; /* Log container */
Ipl2tp_tunnel_assign_peer_id peer_id; /* Peer ID */
Ipl2tp_tunnel_state_machine state_machine_sccrq; /* State machine */
Ipl2tp_tunnel_func tunnel_done; /* Tunnels done */
Ipl2tp_tunnel_session_func session_init; /* Init session */
Ipl2tp_tunnel_session_func session_done; /* Session done */
Ipl2tp_message_func *messages; /* Messages */
}
Ipl2tp_tunnel_table;
#define IPL2TP_TUNNEL_MESSAGE_INIT(c) ((*((c)->admin.tunnel)->table->message_init) (c))
#define IPL2TP_TUNNEL_MESSAGE_LOG(c,d) ((*((c)->admin.tunnel)->table->message_log) (c,d))
#define IPL2TP_TUNNEL_MESSAGE_DIGEST(c) ((*((c)->admin.tunnel)->table->message_digest) (c))
#define IPL2TP_TUNNEL_ASSIGN_PEER_ID(t,a) ((*(t)->table->peer_id) (t,a))
#define IPL2TP_TUNNEL_STATE_SCCRQ(t) ((*(t)->table->state_machine_sccrq) (t))
#define IPL2TP_TUNNEL_DONE(t) ((*(t)->table->tunnel_done) (t))
#define IPL2TP_TUNNEL_SESSION_INIT(s) ((*(s)->tunnel->table->session_init) (s))
#define IPL2TP_TUNNEL_SESSION_DONE(s) ((*(s)->tunnel->table->session_done) (s))
#define IPL2TP_TUNNEL_RESULT_VAR(result, s, c, e, str) \
do \
{ \
(result)->status = (s); \
(result)->result_code = (c); \
(result)->error_code = (e); \
IPL2TP_SAFE_FREE((result)->error_message); \
(result)->error_message = ipl2tp_util_strdup(str, -1); \
} \
while (0)
#define IPL2TP_TUNNEL_RESULT_VAR_COPY(result, from) \
IPL2TP_TUNNEL_RESULT_VAR((result), \
(from)->status, \
(from)->result_code, \
(from)->error_code, \
(from)->error_message)
#define IPL2TP_TUNNEL_RESULT_SET(tunnel,status,code,error,str) \
IPL2TP_TUNNEL_RESULT_VAR(&(tunnel)->last_result, \
(status), \
(code), \
(error), \
(str))
#define IPL2TP_TUNNEL_RESULT_SAVE(tunnel) \
IPL2TP_TUNNEL_RESULT_VAR_COPY(&(tunnel)->last_error, &(tunnel)->last_result)
#define IPL2TP_TUNNEL_RESULT_RESTORE(tunnel) \
IPL2TP_TUNNEL_RESULT_VAR_COPY(&(tunnel)->last_result, &(tunnel)->last_error)
/*
*===========================================================================
* Tunnel_attributes
*===========================================================================
*
* Tunnel attributes.
*/
typedef struct Ipl2tp_tunnel_attributes
{
Ipl2tp_status_callback scallback; /* Notification callback */
void *user_data; /* Callback data */
char *peer_host_name; /* Peer host name for authentication */
char *preferred_language; /* Peer host name for authentication */
Ip_u32 hello_interval_sec; /* HELLO interval */
Ip_u32 router_id; /* Router id */
Ip_u32 ifindex; /* Interface index */
Ip_u16 max_retransmit; /* Max no of retransmissions */
Ip_u16 max_backoff_sec; /* Max time between retransmissions */
Ip_u16 receive_window_size; /* Receive window size */
Ip_u8 framing_capabilities; /* Framing capabilities */
Ip_u8 bearer_capabilities; /* Bearer capabilities */
Ip_u8 authentication; /* Authentication scheme */
Ip_u8 hmac; /* Hash algorithm. Always MD5 for v2 */
Ip_u8 sequencing; /* Sequencing required */
Ip_u8 hide_avp; /* Use AVP hiding */
Ip_u8 transport; /* Transport */
Ip_u8 align[3];
Ipl2tp_vector pw;
Ipl2tp_vector secret;
}
Ipl2tp_tunnel_attributes;
/*
*===========================================================================
* Tunnel_statistics
*===========================================================================
*
* Tunnel descriptor.
*/
typedef struct Ipl2tp_tunnel_statistics
{
Ip_u32 in_octets; /* Octets received */
Ip_u32 in_packets; /* Packets received */
Ip_u32 in_discards; /* Packets discarded */
Ip_u32 in_errors; /* Input errors */
Ip_u32 out_octets; /* Octets sent */
Ip_u32 out_packets; /* Packets sent */
Ip_u32 control_packets_received; /* Received control packets */
Ip_u32 control_zlb_received; /* Received ZLB packets */
Ip_u32 control_outofseq_received; /* Rec. out-of-order packets */
Ip_u32 control_outofwin_received; /* Rec. out-of-window packets */
Ip_u32 control_packets_sent; /* Sent control packets */
Ip_u32 control_zlb_sent; /* Sent ZLB packets */
Ip_u32 control_timeouts; /* Control channel timeouts */
Ip_u32 total_sessions; /* Sessions since tunnel open */
Ip_u32 failed_sessions; /* Failed sessions */
Ip_u32 active_sessions; /* Active sessions */
}
Ipl2tp_tunnel_statistics;
/*
*===========================================================================
* Tunnel
*===========================================================================
*
* Tunnel descriptor.
*/
typedef struct Ipl2tp_tunnel
{
Ipcom_list head; /* List header */
/* Local administrative information */
struct
{
Ipl2tp_key key; /* Version & Ident */
Ipl2tp_vector nonce;
}
local;
/* Remote information */
struct
{
union Ip_sockaddr_union addr; /* Socket address of peer host */
Ipl2tp_key key; /* Remote version & ident */
Ipl2tp_vector nonce;
}
remote;
Ipl2tp_tunnel_table *table; /* Callback table */
Ipl2tp_tunnel_state state; /* Tunnel state */
Ipcom_list session_list; /* Sessions in this tunnel */
Ipcom_list message_list; /* Output message queue */
Ipcom_tmo timer; /* Timeout timer control block */
/* Stored parameters for use when delaying authentication
* in SCCRQ */
struct
{
void *message;
struct Ipl2tp_avp *avp;
Ip_size_t message_index;
Ip_size_t message_length;
} sccrq;
/* Stored attribute data */
union
{
/* Stored data for V2 L2TP AVP's */
struct
{
Ip_u32 firmware_revision; /* Peer firmware revision */
Ip_u8 protocol_version[2]; /* Peer protocol version */
Ip_u8 framing_capabilities; /* Peer's framing capabilities */
Ip_u8 bearer_capabilities; /* Peer's bearer capabilities */
} v2;
/* Stored data for V3 L2TP AVP's */
struct
{
Ip_u32 router_id; /* Router ID */
char *preferred_language; /* Name of peer host */
Ipl2tp_vector pseudo_wires;
Ipl2tp_vector msg_digest_shared_key;
Ipl2tp_vector hide_avp_shared_key;
} v3;
} v;
struct
{
char *host_name; /* Name of peer host */
char *vendor_name; /* Name of peer vendor */
Ip_u16 receive_window_size; /* Peer's receive window size */
Ipl2tp_vector tie_breaker;
} common;
Ip_u16 ssthresh; /* Slow start threshold */
Ip_u16 cwnd; /* Congestion window */
Ip_u16 ca_ack; /* Acks in congestion avoidance mode */
Ip_u16 ns; /* Sequence number */
Ip_u16 nr; /* Next expected sequence number */
Ip_u16 nsack; /* Sequence number acknowledged */
Ip_u16 nrack; /* Last received nr */
Ip_u16 hello_ticks; /* Idle HELLO ticks */
Ip_u8 needzlb; /* Needs to send a ZLB */
Ip_u8 local_open; /* Opened locally */
Ip_u8 drain_tunnel; /* Drain tunnel */
Ip_u8 align[1];
Ipl2tp_tunnel_attributes attr; /* Attributes */
Ipl2tp_vector expected_response;
Ipl2tp_result last_result; /* Result of current operation */
Ipl2tp_result last_error; /* Result of previous operation */
Ipl2tp_tunnel_statistics statistics; /* Tunnel statistics */
struct Ipl2tp_tunnel *slave; /* Slave tunnel */
}
Ipl2tp_tunnel;
/*
*===========================================================================
* Session_attributes
*===========================================================================
*
* Session attributes.
*/
typedef struct Ipl2tp_session_attributes
{
Ipl2tp_status_callback scallback; /* Notification callback */
Ipl2tp_data_callback dcallback; /* Data callback */
Ipl2tp_sli_callback slicallback; /* SLI callback */
void *user_data; /* Callback data */
char *called_number; /* Called number */
char *calling_number; /* Calling number */
char *sub_address; /* Sub address */
char *private_group_id; /* Private group ID */
Ip_u64 tx_connect_speed64; /* Tx connect speed */
Ip_u64 rx_connect_speed64; /* Rx connect speed */
Ip_u32 tx_connect_speed; /* Tx connect speed */
Ip_u32 rx_connect_speed; /* Rx connect speed */
Ip_u32 minimum_bps; /* Minimum BPS */
Ip_u32 maximum_bps; /* Maximum BPS */
Ip_u32 phys_chan_id; /* Physical channel ID */
Ip_u32 ifindex; /* Interface index */
Ip_u32 l2_out_of_order_reset; /* L2 out of order reset */
Ip_u16 pw_type; /* Pseudowire type */
Ip_u16 circuit_status; /* Circuit status */
Ip_u16 auth_method; /* Authentication method */
Ip_u8 framing_type; /* Framing type */
Ip_u8 bearer_type; /* Bearer type */
Ip_u8 proxy_authen_id; /* Proxy LCP ID */
Ip_u8 data_sequencing; /* V3 data sequencing */
Ip_u8 l2_sublayer; /* V3 L2 sublayer */
Ip_u8 align[2];
Ipl2tp_vector remote_end_id; /* Remote END ID */
Ipl2tp_vector first_received_confreq; /* First received CONFREQ */
Ipl2tp_vector last_received_confreq; /* Last received CONFREQ */
Ipl2tp_vector last_sent_confreq; /* Last sent CONFREQ */
char *proxy_authen_name; /* Proxy LCP name */
Ipl2tp_vector proxy_authen_challenge; /* Proxy LCP challenge */
Ipl2tp_vector proxy_authen_response; /* Proxy LCP response */
}
Ipl2tp_session_attributes;
/*
*===========================================================================
* Session
*===========================================================================
*
* Session descriptor.
*/
typedef struct Ipl2tp_session
{
Ipcom_list head; /* List header */
struct
{
Ipl2tp_key key; /* Version & Ident */
Ipl2tp_vector cookie; /* Cookie for this session */
}
local;
struct
{
Ipl2tp_key key; /* Version & Ident */
Ipl2tp_vector cookie; /* Cookie for this session */
}
remote;
Ipcom_tmo timer; /* Timeout timer control block */
Ipl2tp_tunnel *tunnel; /* Tunnel descriptor */
Ipl2tp_session_state state; /* Session state */
struct
{
Ip_u32 call_serial_number; /* Call serial number */
} common;
union
{
struct
{
Ip_u16 ns; /* Sequence number */
Ip_u16 nr; /* Next expected sequence number */
Ip_u8 sequencing; /* Sequencing required */
} v2;
struct
{
/* Data sequencing */
struct
{
Ip_u32 received; /* Received sequenced frames */
/* L2 sublayer information */
union
{
struct
{
Ip_u32 next_seq; /* Sequence number */
Ip_u32 match_last; /* Last received */
Ip_u32 miss_in_sequence; /* Number of out of order frames */
Ip_u32 miss_last; /* Last miss */
} dfl;
} l2;
} dataseq;
Ip_u16 circuit_status; /* Circuit status */
} v3;
} v;
Ipl2tp_session_attributes attr; /* Attributes */
Ip_u8 local_open; /* Opened locally */
Ip_u8 outgoing; /* Outgoing/Incoming call */
Ip_u8 align[2];
}
Ipl2tp_session;
/*
*===========================================================================
* Ipl2tp_addr
*===========================================================================
*
* Hash key.
*/
typedef struct Ipl2tp_addr
{
Ipl2tp_key key; /* Version & Ident we're looking for */
union Ip_sockaddr_union *addr; /* The address of the peer */
}
Ipl2tp_addr;
/*
*===========================================================================
* Ipl2tp_Context
*===========================================================================
*/
typedef struct Ipl2tp_context
{
Ip_u32 magic; /* Magic cookie */
Ipl2tp_state state; /* Global state */
char host_name[IPL2TP_MAX_HOST_NAME_SIZE]; /* My name */
struct
{
struct
{
Ip_u32 total; /* No of active sessions */
Ip_u16 ident; /* Next session ID */
Ipl2tp_session_attributes attr; /* Default session attributes */
} v2;
struct
{
Ip_u32 total; /* No of active sessions */
Ip_u32 ident; /* Next session ID */
Ipl2tp_session_attributes attr; /* Default session attributes */
} v3;
Ipcom_list free_list; /* Recycled sessions */
Ipcom_hash *hash_id; /* ID hash */
Ip_u32 total; /* No of active tunnels */
} session;
struct
{
struct
{
Ipcom_list tunnels;
Ip_u16 ident;
Ip_u32 total;
Ipl2tp_tunnel_attributes attr; /* Default tunnel attributes */
} v2;
struct
{
Ipcom_list tunnels;
Ip_u32 ident;
Ip_u32 total;
Ipl2tp_tunnel_attributes attr; /* Default tunnel attributes */
} v3;
Ipcom_list free_list; /* Recycled tunnels */
Ipcom_hash *hash_id; /* ID hash */
Ipcom_hash *hash_remote_addr; /* Address hash */
Ipcom_hash *hash_remote_id; /* ID hash */
Ipcom_hash *hash_ifindex; /* IfIndex hash */
Ip_u32 total; /* No of active tunnels */
} tunnel;
Ip_u32 call_serial_number; /* Call serial number */
int open_tunnels; /* No of open tunnels */
int open_sessions; /* No of open sessions */
int first_retransmit_sec; /* Seconds until first retransmit */
int tunnel_zombie_sec; /* Seconds to keep tunnel zombie */
int hello_tick_sec; /* Resolution of HELLO interval */
int establish_timeout_sec; /* Tunnel establishment timeout */
int open_exclusive; /* Use one session per tunnel */
int admin_state; /* Administrative state */
int drain_tunnels; /* Drain all tunnels */
int enable_outgoing; /* Enable LNS-initiated actions */
int enable_v2; /* Enable LNS-initiated actions */
int enable_v3; /* Enable LNS-initiated actions */
int close_unused_tunnels; /* Close unused tunnels */
Ipl2tp_write_callback wcallback; /* Write callback */
#ifdef IPL2TP_USE_MUTEX
Ipcom_mutex mutex; /* Synchronization mutex */
#endif
struct Ipl2tp_util_ntoa
{
char ntoa_buffer[IPL2TP_NTOA_ADDRMASK + 1][IPL2TP_NTOA_ADDRSIZE];
Ip_u32 ntoa_index;
} ntoa;
}
Ipl2tp_context;
/*
****************************************************************************
* INCLUDE FILES
****************************************************************************
*/
#include "ipl2tp_data.h"
#include "ipl2tp_util.h"
#ifdef __cplusplus
}
#endif
#endif
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,282 @@
/*
******************************************************************************
* INTERPEAK SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp_message.c,v $ $Revision: 1.2 $
* $Source: /home/interpeak/CVSRoot/ipl2tp/src/ipl2tp_message.c,v $
* $Author: joel $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelis@interpeak.se>
******************************************************************************
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#include "ipl2tp_h.h"
#include "ipl2tp_avp.h"
#include "ipl2tp_data.h"
#include "ipl2tp_message.h"
#include "ipl2tp_state.h"
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
struct Ipl2tp_message_type
{
const char *name;
Ip_bool recognized;
};
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
static struct Ipl2tp_message_type ipl2tp_message_types[] =
{
{ "ZLB", IP_FALSE }, /* 0 */
{ "SCCRQ", IP_TRUE }, /* 1 */
{ "SCCRP", IP_TRUE }, /* 2 */
{ "SCCCN", IP_TRUE }, /* 3 */
{ "StopCCN", IP_TRUE }, /* 4 */
{ "<reserved 5>", IP_FALSE }, /* 5 */
{ "HELLO", IP_TRUE }, /* 6 */
{ "OCRQ", IP_TRUE }, /* 7 */
{ "OCRP", IP_TRUE }, /* 8 */
{ "OCCN", IP_TRUE }, /* 9 */
{ "ICRQ", IP_TRUE }, /* 10 */
{ "ICRP", IP_TRUE }, /* 11 */
{ "ICCN", IP_TRUE }, /* 12 */
{ "<reserved 13>", IP_FALSE }, /* 13 */
{ "CDN", IP_TRUE }, /* 14 */
{ "WEN", IP_TRUE }, /* 15 */
{ "SLI", IP_TRUE }, /* 16 */
{ "<unimplemented 17>", IP_FALSE }, /* 17 */
{ "<unimplemented 18>", IP_FALSE }, /* 18 */
{ "<unimplemented 19>", IP_FALSE }, /* 19 */
{ "ACK", IP_TRUE }, /* 20 */
};
/*
****************************************************************************
* 9 STATIC FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* 10 GLOBAL FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipl2tp_message_name
*===========================================================================
* Description: Get name of message.
* Parameters: type - Message type.
* Returns: Human readable message name.
*
*/
IP_GLOBAL CONST char *
ipl2tp_message_name(Ip_u16 message_type)
{
if (message_type < (sizeof(ipl2tp_message_types) / sizeof(ipl2tp_message_types[0])))
return ipl2tp_message_types[message_type].name;
return "<invalid>";
}
/*
*===========================================================================
* ipl2tp_message_recognized
*===========================================================================
* Description: Check if message is recognized.
* Parameters: type - Message type.
* Returns: IP_TRUE if message type is recognized, IP_FALSE otherwise.
*
*/
IP_GLOBAL Ip_bool
ipl2tp_message_recognized(Ip_u16 message_type)
{
if (message_type < (sizeof(ipl2tp_message_types) / sizeof(ipl2tp_message_types[0])))
return ipl2tp_message_types[message_type].recognized;
return IP_FALSE;
}
/*
*===========================================================================
* ipl2tp_message_new
*===========================================================================
* Description: Allocate a new L2TP control container.
* Parameters: tunnel - The tunnel the container belongs to.
* session - The session the container belongs to.
* Returns: The container if successful; IP_NULL otherwise.
*
*/
IP_GLOBAL Ipl2tp_message *
ipl2tp_message_new(Ipl2tp_tunnel *tunnel,
Ipl2tp_session *session)
{
Ipl2tp_message *container =
ipcom_malloc(IPL2TP_MAX_MESSAGE_SIZE + sizeof(*container));
if (container == IP_NULL)
{
IPCOM_LOG3(ERR,
"%s(%d,%s): Out of memory for L2TP message",
ipl2tp_versions[tunnel->local.key.version],
(int)tunnel->local.key.ident,
ipl2tp_util_ntoa(&tunnel->remote.addr));
return IP_NULL;
}
if (tunnel->attr.hide_avp != IPL2TP_MIB_NO && tunnel->attr.secret.size == 0)
{
IPCOM_LOG3(WARNING,
"%s(%d,%s): Missing secret for tunnel, hiding disabled",
ipl2tp_versions[tunnel->local.key.version],
(int)tunnel->local.key.ident,
ipl2tp_util_ntoa(&tunnel->remote.addr));
}
/* Enter header fields */
ipcom_list_init(&container->admin.head);
IPCOM_TMO_INIT(&container->admin.timer);
container->admin.tunnel = tunnel;
container->admin.session = session;
container->admin.retransmit = 0;
container->admin.flags = 0;
container->admin.is_zlb = IP_FALSE;
/* Version dependent container initialization */
IPL2TP_TUNNEL_MESSAGE_INIT(container);
/* Ns and Nr values are entered by transport module */
return container;
}
/*
*===========================================================================
* ipl2tp_message_delete
*===========================================================================
* Description: Delete a L2TP control container
* Parameters: container - The container
* Returns:
*
*/
IP_GLOBAL void
ipl2tp_message_delete(Ipl2tp_message *container)
{
/* Cancel possible pending timeout */
ipcom_tmo_cancel(&container->admin.timer);
ipcom_free(container);
}
/*
*===========================================================================
* ipl2tp_message_is_zlb
*===========================================================================
* Description: Mark container as ZLB
* Parameters: container - The container
* Returns:
*
*/
IP_GLOBAL void
ipl2tp_message_is_zlb(Ipl2tp_message *container)
{
/**/
container->admin.is_zlb = IP_TRUE;
}
/*
*===========================================================================
* ipl2tp_message_rq
*===========================================================================
* Description: Send appropriate request based on type of session.
* Parameters: session - The session the container belongs to.
* Returns:
*
*/
IP_GLOBAL Ipl2tp_status
ipl2tp_message_rq(Ipl2tp_session *session)
{
Ipl2tp_status ret;
session->state = IPL2TP_SSTATE_WAIT_REPLY;
if (session->outgoing)
{
/* Outgoing */
ret = ipl2tp_message_ocrq(session);
}
else
{
/* Incoming */
ret = ipl2tp_message_icrq(session);
}
ipl2tp_state_establish_session_timeout_init(session, 1);
return ret;
}
/*
****************************************************************************
* 11 PUBLIC FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,349 @@
/*
******************************************************************************
* HEADER FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp_message.h,v $ $Revision: 1.2 $
* $Source: /home/interpeak/CVSRoot/ipl2tp/src/ipl2tp_message.h,v $
* $Author: joel $ $Date: 2006-01-30 10:47:46 $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelius@interpeak.se>
******************************************************************************
*/
#ifndef IPL2TP_MESSAGE_H
#define IPL2TP_MESSAGE_H
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#include "ipl2tp_v2.h"
#include "ipl2tp_v3.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/* Container flag values */
#define IPL2TP_CONTAINER_SENT 0x01
#define IPL2TP_CONTAINER_RV 0x02
/*
*---------------------------------------------------------------------------
* Message type
*---------------------------------------------------------------------------
*/
#define IPL2TP_MSG_ZLB 0 /*$ ZLB - Zero-Length-Body (internal use) $*/
#define IPL2TP_MSG_SCCRQ 1 /*$ SCCRQ - Start-Control-Connection-Request $*/
#define IPL2TP_MSG_SCCRP 2 /*$ SCCRP - Start-Control-Connection-Reply $*/
#define IPL2TP_MSG_SCCCN 3 /*$ SCCCN - Start-Control-Connection-Connected $*/
#define IPL2TP_MSG_StopCCN 4 /*$ StopCCN - Stop-Control-Connection-Notify $*/
#define IPL2TP_MSG_HELLO 6 /*$ HELLO $*/
#define IPL2TP_MSG_OCRQ 7 /*$ OCRQ - Outgoing-Call-Request $*/
#define IPL2TP_MSG_OCRP 8 /*$ OCRP - Outgoing-Call-Reply $*/
#define IPL2TP_MSG_OCCN 9 /*$ OCCN - Outgoing-Call-Connected $*/
#define IPL2TP_MSG_ICRQ 10 /*$ ICRQ - Incoming-Call-Request $*/
#define IPL2TP_MSG_ICRP 11 /*$ ICRP - Incoming-Call-Reply $*/
#define IPL2TP_MSG_ICCN 12 /*$ ICCN - Incoming-Call-Connected $*/
#define IPL2TP_MSG_CDN 14 /*$ CDN - Call-Disconnect-Notify $*/
#define IPL2TP_MSG_WEN 15 /*$ WEN - WAN-Error-Notify $*/
#define IPL2TP_MSG_SLI 16 /*$ SLI - Set-Link-Info $*/
#define IPL2TP_MSG_ACK 20 /*$ ACK - Explicit acknowledgement $*/
#define IPL2TP_MSG_MAX (IPL2TP_MSG_ACK + 1)
#define ipl2tp_message_call(c,t,s,a)\
(*(((t)->table->messages)[c]))(t,s,a)
#define ipl2tp_message_sccrq(t)\
ipl2tp_message_call(IPL2TP_MSG_SCCRQ, t, IP_NULL, IP_NULL)
#define ipl2tp_message_sccrp(t,a)\
ipl2tp_message_call(IPL2TP_MSG_SCCRP, t, IP_NULL, a)
#define ipl2tp_message_scccn(t,a)\
ipl2tp_message_call(IPL2TP_MSG_SCCCN, t, IP_NULL, a)
#define ipl2tp_message_stopccn(t)\
ipl2tp_message_call(IPL2TP_MSG_StopCCN, t, IP_NULL, IP_NULL)
#define ipl2tp_message_icrq(s)\
ipl2tp_message_call(IPL2TP_MSG_ICRQ, (s)->tunnel, s, IP_NULL)
#define ipl2tp_message_icrp(s)\
ipl2tp_message_call(IPL2TP_MSG_ICRP, (s)->tunnel, s, IP_NULL)
#define ipl2tp_message_iccn(s)\
ipl2tp_message_call(IPL2TP_MSG_ICCN, (s)->tunnel, s, IP_NULL)
#define ipl2tp_message_ocrq(s)\
ipl2tp_message_call(IPL2TP_MSG_OCRQ, (s)->tunnel, s, IP_NULL)
#define ipl2tp_message_ocrp(s)\
ipl2tp_message_call(IPL2TP_MSG_OCRP, (s)->tunnel, s, IP_NULL)
#define ipl2tp_message_occn(s)\
ipl2tp_message_call(IPL2TP_MSG_OCCN, (s)->tunnel, s, IP_NULL)
#define ipl2tp_message_cdn(s)\
ipl2tp_message_call(IPL2TP_MSG_CDN, (s)->tunnel, s, IP_NULL)
#define ipl2tp_message_zlb(t)\
ipl2tp_message_call(IPL2TP_MSG_ZLB, t, IP_NULL, IP_NULL)
#define ipl2tp_message_hello(t)\
ipl2tp_message_call(IPL2TP_MSG_HELLO, t, IP_NULL, IP_NULL)
#define ipl2tp_message_sli(s)\
ipl2tp_message_call(IPL2TP_MSG_SLI, (s)->tunnel, s, IP_NULL)
/*
*---------------------------------------------------------------------------
* Result code
*---------------------------------------------------------------------------
*/
/* StopCCN result codes */
/*$$ BEGIN StopCCN_result_code $*/
#define IPL2TP_RES_StopCCN_GENERAL_REQUEST 1
/*$ General request to clear control connection $*/
#define IPL2TP_RES_StopCCN_GENERAL_ERROR 2
/*$ General error; Error code indicates the problem $*/
#define IPL2TP_RES_StopCCN_CHANNEL_EXISTS 3
/*$ Control channel already exists $*/
#define IPL2TP_RES_StopCCN_NOT_AUTHORIZED 4
/*$ Requester is not authorized to establish a control channel $*/
#define IPL2TP_RES_StopCCN_PROTOCOL_VERSION 5
/*$ The protocol version of the requester is not supported $*/
#define IPL2TP_RES_StopCCN_SHUTDOWN 6
/*$ Requester is being shut down $*/
#define IPL2TP_RES_StopCCN_STATE_MACHINE 7
/*$ Finite State Machine error $*/
/* CDN result codes */
#define IPL2TP_RES_CDN_LOSS_OF_CARRIER 1
/*$ Call disconnected due to loss of carrier $*/
#define IPL2TP_RES_CDN_GENERAL_ERROR 2
/*$ Call disconnected for the reason indicated in error code $*/
#define IPL2TP_RES_CDN_ADMINISTRATIVE 3
/*$ Call disconnected for administrative reasons $*/
#define IPL2TP_RES_CDN_RESOURCE_TEMP 4
/*$ Call failed due to temporary lack of appropriate facilities $*/
#define IPL2TP_RES_CDN_RESOURCE_PERM 5
/*$ Call failed due to permanent lack of appropriate facilities $*/
#define IPL2TP_RES_CDN_INVALID_DEST 6
/*$ Invalid destination $*/
#define IPL2TP_RES_CDN_NO_CARRIER 7
/*$ Call failed due to no carrier detected $*/
#define IPL2TP_RES_CDN_BUSY 8
/*$ Call failed due to detection of a busy signal $*/
#define IPL2TP_RES_CDN_NO_DIAL_TONE 9
/*$ Call failed due to lack of a dial tone $*/
#define IPL2TP_RES_CDN_TIMEOUT 10
/*$ Call was not established within time allotted by LAC $*/
#define IPL2TP_RES_CDN_FRAMING 11
/*$ Call was connected but no appropriate framing was detected $*/
#define IPL2TP_RES_CDN_SESSION_TIE_BREAKER 13
/*$ Call was connected but lost tie breaker $*/
#define IPL2TP_RES_CDN_PW_TYPE 14
/*$ Call was connected but no appropriate pw type was detected $*/
#define IPL2TP_RES_CDN_SEQUENCING_L2_SUBLAYER 15
/*$ Call was connected but sequencing required, no L2 sublayer present $*/
#define IPL2TP_RES_CDN_STATE_MACHINE 16
/*$ Call was connected but a state machine error occured $*/
/* Error codes */
#define IPL2TP_ERR_NO_CONTROL_CONN 1
/*$ No control connection exists yet for this LAC-LNS pair $*/
#define IPL2TP_ERR_WRONG_LENGTH 2
/*$ Length is wrong $*/
#define IPL2TP_ERR_OUT_OF_RANGE 3
/*$ One of the fields was out of range or reserved field was non-zero $*/
#define IPL2TP_ERR_RESOURCE_LIMIT 4
/*$ Insufficient resources to handle this operation now $*/
#define IPL2TP_ERR_SESSION_ID 5
/*$ The Session ID is invalid in this context $*/
#define IPL2TP_ERR_VENDOR_ERROR_LAC 6
/*$ A generic vendor-specific error occurred in the LAC $*/
#define IPL2TP_ERR_TRY_ANOTHER_LNS 7
/*$ Try another LNS destination, if possible $*/
#define IPL2TP_ERR_UNKNOWN_M_AVP 8
/*$ Shutdown due to receipt of an unknown AVP with the M-bit set $*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
*===========================================================================
* Ipl2tp_admin
*===========================================================================
*
* Message administration stuff.
*/
typedef struct Ipl2tp_admin
{
Ipcom_list head; /* List header */
Ipcom_tmo timer; /* Timer control block */
Ipl2tp_tunnel *tunnel; /* Tunnel descriptor */
Ipl2tp_session *session; /* Session descriptor */
Ip_u16 timeout; /* Current timeout */
Ip_u8 retransmit; /* Retransmit counter */
Ip_u8 flags; /* Flags */
Ip_u16 size; /* Total size */
Ip_u16 pre_header; /* Pre header (IP/IP) */
void *digest; /* Pointer to digest */
void *rv_value; /* Random vector value */
Ip_u16 rv_length; /* Random vector length */
Ip_u16 *nr; /* Pointer to NR */
Ip_u16 *ns; /* Pointer to NS */
Ip_u16 *length; /* Length field */
Ip_u8 *start; /* Start of header */
Ip_bool is_zlb; /* Is it a ZLB? */
}
Ipl2tp_admin;
/* The various message forms */
typedef union Ipl2tp_header
{
Ipl2tp_v3_header v3; /* L2TPv3 control */
Ipl2tp_v2_header v2; /* L2TPv2 control */
}
Ipl2tp_header;
/*
*===========================================================================
* Ipl2tp_container
*===========================================================================
*
* Message descriptor with additional headers and stuff.
*/
typedef struct Ipl2tp_message
{
Ipl2tp_admin admin; /* Admin data */
Ip_u32 session; /* When doing tunneling over IP */
Ipl2tp_header header; /* Header */
}
Ipl2tp_message;
/*
****************************************************************************
* 6 FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipl2tp_message_name
*===========================================================================
* Description: Get name of message.
* Parameters: type - Message type.
* Returns: Human readable message name.
*
*/
IP_GLOBAL CONST char * ipl2tp_message_name(Ip_u16 message_type);
/*
*===========================================================================
* ipl2tp_message_recognized
*===========================================================================
* Description: Check if message is recognized.
* Parameters: type - Message type.
* Returns: IP_TRUE if message type is recognized, IP_FALSE otherwise.
*
*/
IP_GLOBAL Ip_bool ipl2tp_message_recognized(Ip_u16 message_type);
/*
*===========================================================================
* ipl2tp_message_new
*===========================================================================
* Description: Allocate a new L2TP control container.
* Parameters: tunnel - The tunnel the container belongs to.
* session - The session the container belongs to.
* Returns: The container if successful; IP_NULL otherwise.
*
*/
IP_GLOBAL Ipl2tp_message *ipl2tp_message_new(Ipl2tp_tunnel *tunnel,
Ipl2tp_session *session);
/*
*===========================================================================
* ipl2tp_message_delete
*===========================================================================
* Description: Delete a L2TP control container
* Parameters: container - The container
* Returns:
*
*/
IP_GLOBAL void ipl2tp_message_delete(Ipl2tp_message *container);
/*
*===========================================================================
* ipl2tp_message_is_zlb
*===========================================================================
* Description: Mark container as ZLB
* Parameters: container - The container
* Returns:
*
*/
IP_GLOBAL void ipl2tp_message_is_zlb(Ipl2tp_message *container);
/*
*===========================================================================
* ipl2tp_message_rq
*===========================================================================
* Description: Send appropriate request based on type of session.
* Parameters: session - The session the container belongs to.
* Returns:
*
*/
IP_GLOBAL Ipl2tp_status ipl2tp_message_rq(Ipl2tp_session *session);
#ifdef __cplusplus
}
#endif
#endif
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,216 @@
/*
******************************************************************************
* INTERPEAK SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp_pseudowire.c,v $ $Revision: 1.3 $
* $Source: /home/interpeak/CVSRoot/ipl2tp/src/ipl2tp_pseudowire.c,v $
* $Author: joel $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelis@interpeak.se>
******************************************************************************
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#include "ipl2tp_h.h"
#include "ipl2tp_api.h"
#include "ipl2tp_avp.h"
#include "ipl2tp_trpt.h"
#include "ipl2tp_util.h"
#include "ipl2tp_pseudowire.h"
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
/*
****************************************************************************
* 9 STATIC FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* 10 GLOBAL FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipl2tp_pw_framing2bits
*===========================================================================
* Description: Convert from framing code to protocol bits.
* Parameters: value - Framing value.
* Returns:
*
*/
IP_GLOBAL Ip_u32
ipl2tp_pw_framing2bits(int value)
{
static CONST Ip_u32 bits[] =
{
0, 0, 1, 2, 3
};
return (value < (signed)(sizeof(bits) / sizeof(bits[0])) ? bits[value] : 0);
}
/*
*===========================================================================
* ipl2tp_pw_bearer2bits
*===========================================================================
* Description: Convert from bearer code to protocol bits.
* Parameters: value - Bearer value.
* Returns:
*
*/
IP_GLOBAL Ip_u32
ipl2tp_pw_bearer2bits(int value)
{
static CONST Ip_u32 bits[] =
{
0, 0, 1, 2, 3
};
return (value < (signed)(sizeof(bits) / sizeof(bits[0])) ? bits[value] : 0);
}
/*
*===========================================================================
* ipl2tp_pw_bits2framing
*===========================================================================
* Description: Convert from protocol bits to framing code.
* Parameters: value - Framing bits.
* Returns:
*
*/
IP_GLOBAL int
ipl2tp_pw_bits2framing(Ip_u32 value)
{
static CONST Ip_u32 bits[] =
{
IPL2TP_MIB_FRAMING_NONE,
IPL2TP_MIB_FRAMING_SYNC,
IPL2TP_MIB_FRAMING_ASYNC,
IPL2TP_MIB_FRAMING_SYNC_ASYNC
};
return (value < (sizeof(bits) / sizeof(bits[0])) ?
bits[value] : IPL2TP_MIB_FRAMING_NONE);
}
/*
*===========================================================================
* ipl2tp_pw_bits2bearer
*===========================================================================
* Description: Convert from protocol bits to bearer code.
* Parameters: value - Bearer bits.
* Returns:
*
*/
IP_GLOBAL int
ipl2tp_pw_bits2bearer(Ip_u32 value)
{
static CONST Ip_u32 bits[] =
{
IPL2TP_MIB_BEARER_NONE,
IPL2TP_MIB_BEARER_DIGITAL,
IPL2TP_MIB_BEARER_ANALOG,
IPL2TP_MIB_BEARER_DIGITAL_ANALOG
};
return (value < (sizeof(bits) / sizeof(bits[0])) ?
bits[value] : IPL2TP_MIB_BEARER_NONE);
}
/*
*===========================================================================
* ipl2tp_pw_valid_type
*===========================================================================
* Description: Verify that the pseudowire type is valid.
* Parameters: tunnel - The tunnel.
* value - The value..
* Returns: IP_TRUE if valid.
*
*/
IP_GLOBAL Ip_bool
ipl2tp_pw_valid_type(Ipl2tp_tunnel *tunnel,
Ip_u16 value)
{
Ip_u16 *pw_types = (Ip_u16 *)tunnel->attr.pw.array;
Ip_size_t i;
/* Verify */
for (i = 0; i < tunnel->attr.pw.size; i++)
{
if (value == pw_types[i])
return IP_TRUE;
}
/* No go */
return IP_FALSE;
}
/*
****************************************************************************
* 11 PUBLIC FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,128 @@
/*
******************************************************************************
* HEADER FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp_pseudowire.h,v $ $Revision: 1.2 $
* $Source: /home/interpeak/CVSRoot/ipl2tp/src/ipl2tp_pseudowire.h,v $
* $Author: joel $ $Date: 2006-01-30 10:47:46 $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelius@interpeak.se>
******************************************************************************
*/
#ifndef IPL2TP_PW_H
#define IPL2TP_PW_H
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipl2tp_pw_framing2bits
*===========================================================================
* Description: Convert from framing code to protocol bits.
* Parameters: value - Framing value.
* Returns:
*
*/
IP_GLOBAL Ip_u32 ipl2tp_pw_framing2bits(int value);
/*
*===========================================================================
* ipl2tp_pw_bearer2bits
*===========================================================================
* Description: Convert from bearer code to protocol bits.
* Parameters: value - Bearer value.
* Returns:
*
*/
IP_GLOBAL Ip_u32 ipl2tp_pw_bearer2bits(int value);
/*
*===========================================================================
* ipl2tp_pw_bits2framing
*===========================================================================
* Description: Convert from protocol bits to framing code.
* Parameters: value - Framing bits.
* Returns:
*
*/
IP_GLOBAL int ipl2tp_pw_bits2framing(Ip_u32 value);
/*
*===========================================================================
* ipl2tp_pw_bits2bearer
*===========================================================================
* Description: Convert from protocol bits to bearer code.
* Parameters: value - Bearer bits.
* Returns:
*
*/
IP_GLOBAL int ipl2tp_pw_bits2bearer(Ip_u32 value);
/*
*===========================================================================
* ipl2tp_pw_valid_type
*===========================================================================
* Description: Verify that the pseudowire type is valid.
* Parameters: tunnel - The tunnel.
* value - The value..
* Returns: IP_TRUE if valid.
*
*/
IP_GLOBAL Ip_bool ipl2tp_pw_valid_type(Ipl2tp_tunnel *tunnel,
Ip_u16 value);
#ifdef __cplusplus
}
#endif
#endif
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,265 @@
/*
******************************************************************************
* HEADER FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp_state.h,v $ $Revision: 1.2 $
* $Source: /home/interpeak/CVSRoot/ipl2tp/src/ipl2tp_state.h,v $
* $Author: joel $ $Date: 2006-01-30 10:47:46 $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelius@interpeak.se>
******************************************************************************
*/
#ifndef IPL2TP_STATE_H
#define IPL2TP_STATE_H
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipl2tp_state_tunnel_find
*===========================================================================
* Description: Get a tunnel for incoming packet
* Parameters: tunnel - Return value.
* avp - AVP descriptor.
* addr - IP address of sender.
* ident - The identifier of the tunnel.
* transport - The transport
* Returns: IPL2TP_STATUS_OK if success.
* IPL2TP_STATUS_IGNORE if the message should be ignored.
* IPL2TP_STATUS_TEARDOWN if the tunnel must be destroyed.
*/
IP_GLOBAL Ipl2tp_status ipl2tp_state_tunnel_find(Ipl2tp_tunnel **tunnel,
Ipl2tp_avp *avp,
union Ip_sockaddr_union *addr,
Ipl2tp_ident ident,
int transport);
/*
*===========================================================================
* ipl2tp_state_session_find
*===========================================================================
* Description: Get a session for incoming packet
* Parameters: session - Return value.
* avp - AVP descriptor.
* tunnel - Tunnel descriptor.
* ident - The identifier of the session.
* Returns: IPL2TP_STATUS_OK if success.
* IPL2TP_STATUS_IGNORE if the message should be ignored.
* IPL2TP_STATUS_TEARDOWN if the session must be destroyed.
*/
IP_GLOBAL Ipl2tp_status ipl2tp_state_session_find(Ipl2tp_session **session,
Ipl2tp_avp *avp,
Ipl2tp_tunnel *tunnel,
Ipl2tp_ident ident);
/*
*===========================================================================
* ipl2tp_session_get
*===========================================================================
* Description: Get session descriptor.
* Parameters: key - Session identifier.
* cookie - Cookie identifier.
* Returns: Session descriptor, or IP_NULL if not found.
*
*/
IP_GLOBAL Ipl2tp_session *ipl2tp_state_session_get(Ipl2tp_key *key,
void *cookie);
/*
*===========================================================================
* ipl2tp_state_tunnel_get
*===========================================================================
* Description: Get tunnel descriptor.
* Parameters: key - Tunnel identifier.
* Returns: Tunnel descriptor, or IP_NULL if not found.
*
*/
IP_GLOBAL Ipl2tp_tunnel *ipl2tp_state_tunnel_get(Ipl2tp_key *key);
/*
*===========================================================================
* ipl2tp_state_tie_break_win
*===========================================================================
* Description: Handle the case when two peers try to establish a tunnel
* at the same time.
* Parameters: tunnel - The new tunnel.
* avp - The AVP
* Returns: 0 if the new tunnel should be destroyed.
* 1 if the new tunnel should be kept.
*
*/
IP_GLOBAL int ipl2tp_state_tie_break_win(Ipl2tp_tunnel *tunnel,
Ipl2tp_avp *avp);
/*
*===========================================================================
* ipl2tp_state_maybe_zlb
*===========================================================================
* Description: Send ZLB if required.
* Parameters: tunnel - Tunnel descriptor.
* Returns:
*
*/
IP_GLOBAL void ipl2tp_state_maybe_zlb(Ipl2tp_tunnel *tunnel);
/*
*===========================================================================
* ipl2tp_state_establish_tunnel_timeout_init
*===========================================================================
* Description: Setup timeout for tunnel establishment.
* Parameters: tunnel - Tunnel descriptor.
* set - Clear timeout if 0, set otherwise.
* Returns:
*
*/
IP_GLOBAL int ipl2tp_state_establish_tunnel_timeout_init(Ipl2tp_tunnel *tunnel,
int set);
/*
*===========================================================================
* ipl2tp_state_establish_session_timeout_init
*===========================================================================
* Description: Setup timeout for session establishment.
* Parameters: session - Session descriptor.
* set - Clear timeout if 0, set otherwise.
* Returns:
*
*/
IP_GLOBAL void ipl2tp_state_establish_session_timeout_init(Ipl2tp_session *session,
int set);
/*
*===========================================================================
* ipl2tp_state_tunnel_teardown
*===========================================================================
* Description: Teardown all sessions in a tunnel, and eventually the tunnel itself.
* Parameters: tunnel - Tunnel descriptor.
* Returns:
*
*/
IP_GLOBAL void ipl2tp_state_tunnel_teardown(Ipl2tp_tunnel *tunnel);
/*
*===========================================================================
* ipl2tp_state_session_teardown
*===========================================================================
* Description: Teardown a session, and also its tunnel if this is
* the last session in the tunnel.
* Parameters: session - Session descriptor.
* Returns:
*
*/
IP_GLOBAL void ipl2tp_state_session_teardown(Ipl2tp_session *session);
/*
*===========================================================================
* ipl2tp_state_tunnel_flush
*===========================================================================
* Description: Delete all outgoing messages.
* Parameters: tunnel - Tunnel descriptor.
* Returns:
*
*/
IP_GLOBAL void ipl2tp_state_tunnel_flush(Ipl2tp_tunnel *tunnel);
/*
*===========================================================================
* ipl2tp_api_tunnel_find_by_addr
*===========================================================================
* Description: Find tunnel by means of IP address.
* Parameters: addr - IP address.
* version - Version
* Returns: Pointer to tunnel descriptor, or IP_NULL if none found.
*
*/
IP_GLOBAL Ipl2tp_tunnel *ipl2tp_state_tunnel_find_by_addr(union Ip_sockaddr_union *addr,
Ipl2tp_version version);
/*
*===========================================================================
* ipl2tp_state_tstate_name
*===========================================================================
* Description: Get name of tunnel state.
* Parameters: state - Tunnel state.
* Returns: Human readable state name.
*
*/
IP_GLOBAL CONST char *ipl2tp_state_tstate_name(Ipl2tp_tunnel_state state);
/*
*===========================================================================
* ipl2tp_state_sstate_name
*===========================================================================
* Description: Get name of session state.
* Parameters: state - Session state.
* Returns: Human readable state name.
*
*/
IP_GLOBAL CONST char *ipl2tp_state_sstate_name(Ipl2tp_session_state state);
#ifdef __cplusplus
}
#endif
#endif
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,577 @@
/*
******************************************************************************
* SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp_trpt.c,v $ $Revision: 1.11 $
* $Source: /home/interpeak/CVSRoot/ipl2tp/src/ipl2tp_trpt.c,v $
* $Author: tneale $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
*
******************************************************************************
*/
/*
****************************************************************************
* DESCRIPTION
****************************************************************************
*
* Reliable transport module.
*/
/*
****************************************************************************
* INCLUDE FILES
****************************************************************************
*/
#include "ipl2tp_h.h"
#include "ipl2tp_trpt.h"
#include "ipl2tp_api.h"
#include "ipl2tp_avp.h"
#include "ipl2tp_message.h"
#include "ipl2tp_state.h"
/*
****************************************************************************
* DEFINES
****************************************************************************
*/
/* Sequence number 'less than' */
#define IPL2TP_LT(a,b) ((((a) - (b)) & 0x8000) != 0)
/*
****************************************************************************
* TYPES
****************************************************************************
*/
/*
****************************************************************************
* LOCAL DATA
****************************************************************************
*/
/*
****************************************************************************
* PUBLIC DATA
****************************************************************************
*/
/*
****************************************************************************
* LOCAL FUNCTIONS
****************************************************************************
*/
IP_STATIC Ip_s32 ipl2tp_trpt_message_timeout(Ipcom_tmo *timer,
Ipl2tp_message *container);
/*
*===========================================================================
* ipl2tp_trpt_control_write
*===========================================================================
* Description: Send a control message.
* Parameters: container - Message to send.
* Returns:
*
*/
IP_STATIC void
ipl2tp_trpt_control_write(Ipl2tp_message *container)
{
Ipl2tp_tunnel *tunnel = container->admin.tunnel;
struct Ip_iovec iov;
/* Log */
IPL2TP_TUNNEL_MESSAGE_LOG(container,
"Sending");
/* Do any digests */
IPL2TP_TUNNEL_MESSAGE_DIGEST(container);
iov.iov_base = container->admin.start;
iov.iov_len = container->admin.size;
/* Write */
IPL2TP_SAFE_CALLBACK(ipl2tp.wcallback,
(tunnel->attr.user_data,
&tunnel->local.key,
&iov,
1,
&tunnel->remote.addr,
tunnel->attr.transport));
tunnel->statistics.out_octets += container->admin.size;
tunnel->statistics.out_packets++;
tunnel->statistics.control_packets_sent++;
/* Schedule retransmission */
if (container->admin.is_zlb)
{
/* ZLB messages are not retransmitted */
ipcom_list_remove(&container->admin.head);
ipl2tp_message_delete(container);
}
else
{
ipcom_tmo_request(&container->admin.timer,
(Ipcom_tmo_func)ipl2tp_trpt_message_timeout,
container,
1000 * container->admin.timeout);
}
}
/*
*===========================================================================
* ipl2tp_trpt_message_timeout
*===========================================================================
* Description: Handle a control message timeout.
* Parameters: timer - The timer structure.
* container - The Message.
* Returns:
*
*/
IP_STATIC Ip_s32
ipl2tp_trpt_message_timeout(Ipcom_tmo *timer,
Ipl2tp_message *container)
{
Ipl2tp_tunnel *tunnel = container->admin.tunnel;
Ip_u16 oldcwnd = tunnel->cwnd;
IPL2TP_UNUSED(timer);
IPL2TP_OCCUPIED(return 0);
/* Log */
IPL2TP_TUNNEL_MESSAGE_LOG(container,
"Transmission timeout");
tunnel->statistics.control_timeouts++;
/* Max retransmissions? */
if (container->admin.retransmit++ >= tunnel->attr.max_retransmit)
{
IPL2TP_TUNNEL_RESULT_SET(tunnel,
IPL2TP_STATUS_TIMEOUT,
IPL2TP_RES_StopCCN_GENERAL_REQUEST,
0,
"Tunnel is down");
/* Yes, bad tunnel */
ipcom_list_remove(&container->admin.head);
ipl2tp_message_delete(container);
ipl2tp_state_tunnel_teardown(tunnel);
IPL2TP_AVAILABLE();
return 0;
}
/* Decrease window sizes */
if ((tunnel->ssthresh = (Ip_u16)(tunnel->cwnd / 2)) < 2)
{
/* SSTHRESH must not be less than 2 */
tunnel->ssthresh = 2;
}
tunnel->cwnd = 1;
if (tunnel->cwnd != oldcwnd)
{
IPCOM_LOG4(INFO,
"%s(%d,%s): New congestion window: %d",
ipl2tp_versions[tunnel->local.key.version],
(int)tunnel->local.key.ident,
ipl2tp_util_ntoa(&tunnel->remote.addr),
(int)tunnel->cwnd);
}
/* Backoff */
if ((container->admin.timeout *= 2) > tunnel->attr.max_backoff_sec)
{
container->admin.timeout = tunnel->attr.max_backoff_sec;
}
/* One more time */
IP_SET_HTONS(container->admin.nr, tunnel->nr);
ipl2tp_trpt_control_write(container);
IPL2TP_AVAILABLE();
return 0;
}
/*
*===========================================================================
* ipl2tp_trpt_hello_timeout
*===========================================================================
* Description: Send HELLO message, and schedule new one.
* Parameters: timer - The timer.
* tunnel - The tunnel to send the hello for.
* Returns:
*
*/
IP_STATIC Ip_s32
ipl2tp_trpt_hello_timeout(Ipcom_tmo *timer,
Ipl2tp_tunnel *tunnel)
{
IPL2TP_UNUSED(timer);
IPL2TP_OCCUPIED(return 0);
/* Check if it's time for HELLO */
if (tunnel->hello_ticks++ >=
(tunnel->attr.hello_interval_sec / ipl2tp.hello_tick_sec))
{
ipl2tp_message_hello(tunnel);
tunnel->hello_ticks = 0;
}
/* Schedule new message */
ipl2tp_trpt_hello_init(tunnel);
IPL2TP_AVAILABLE();
return 0;
}
/*
****************************************************************************
* PUBLIC FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipl2tp_trpt_control_output
*===========================================================================
* Description: Output a L2TP control message
* Parameters: container - The container containing the message.
* Returns:
*
*/
IP_GLOBAL void
ipl2tp_trpt_control_output(Ipl2tp_message *container)
{
Ipl2tp_tunnel *tunnel = container->admin.tunnel;
/* Log */
IPL2TP_TUNNEL_MESSAGE_LOG(container,
"Queuing");
/* Assign new Ns to message (Nr will be entered later) */
IP_SET_HTONS(container->admin.ns, tunnel->ns);
/* ZLB messages do not advance Ns */
if (container->admin.is_zlb == IP_FALSE)
{
tunnel->ns++;
if (tunnel->slave)
tunnel->slave->ns++;
}
tunnel->needzlb = 0;
/* Enter message into transmit queue */
ipcom_list_insert_first(&tunnel->message_list, &container->admin.head);
/* Allowed to transmit? */
if (tunnel->message_list.size <= tunnel->cwnd)
{
/* Yes */
container->admin.flags |= IPL2TP_CONTAINER_SENT;
container->admin.timeout = (Ip_u16)ipl2tp.first_retransmit_sec;
IP_SET_HTONS(container->admin.nr, tunnel->nr);
ipl2tp_trpt_control_write(container);
}
}
/*
*===========================================================================
* ipl2tp_trpt_data_output
*===========================================================================
* Description: Send a data message.
* Parameters: tunnel - Tunnel to use.
* iov - IO vector
* iov_len - Length of IO vector
* Returns:
*
*/
IP_GLOBAL void
ipl2tp_trpt_data_output(Ipl2tp_tunnel *tunnel,
struct Ip_iovec *iov,
int iov_len)
{
int sz;
IPCOM_LOG3(DEBUG,
"%s(%d,%s): Sending L2TP data packet",
ipl2tp_versions[tunnel->local.key.version],
(int)tunnel->local.key.ident,
ipl2tp_util_ntoa(&tunnel->remote.addr));
sz = IPL2TP_SAFE_ICALLBACK(ipl2tp.wcallback,
(tunnel->attr.user_data,
&tunnel->local.key,
iov,
iov_len,
&tunnel->remote.addr,
tunnel->attr.transport));
/* Success? */
if (sz)
{
tunnel->statistics.out_octets += sz;
tunnel->statistics.out_packets++;
}
}
/*
*===========================================================================
* ipl2tp_trpt_sequence_check
*===========================================================================
* Description: Check sequence number of message.
* Parameters: tunnel - The tunnel.
* nr - The NR
* ns - The NS
* is_zlb - Is it a ZLB.
* update - Don't update 'in-sequence' parameters unless set.
* Returns:
*
*/
IP_GLOBAL Ipl2tp_status
ipl2tp_trpt_sequence_check(Ipl2tp_tunnel *tunnel,
Ip_u16 nr,
Ip_u16 ns,
Ip_bool is_zlb,
Ip_bool update)
{
Ipl2tp_status status = IPL2TP_STATUS_IGNORE;
if (update)
{
tunnel->statistics.control_packets_received++;
}
if (is_zlb)
{
if (update == IP_FALSE)
{
/* */
status = IPL2TP_STATUS_OK;
}
else
{
tunnel->statistics.control_zlb_received++;
/* Got ZLB */
if (!IPL2TP_LT(ns, tunnel->nr) &&
IPL2TP_LT(ns, tunnel->nr + tunnel->attr.receive_window_size))
{
IPCOM_LOG4(DEBUG,
"%s(%d,%s): Received %s ZLB",
ipl2tp_versions[tunnel->local.key.version],
(int)tunnel->local.key.ident,
ipl2tp_util_ntoa(&tunnel->remote.addr),
ns == tunnel->nr ? "in-order" : "in-window");
/* Update the values? */
ipl2tp_trpt_tunnel_ack(tunnel, nr);
}
else
{
IPCOM_LOG3(DEBUG,
"%s(%d,%s): Received out of order ZLB",
ipl2tp_versions[tunnel->local.key.version],
(int)tunnel->local.key.ident,
ipl2tp_util_ntoa(&tunnel->remote.addr));
}
}
}
else if (ns == tunnel->nr)
{
/* Expected message, acknowledge */
IPCOM_LOG3(DEBUG,
"%s(%d,%s): Received in-order message",
ipl2tp_versions[tunnel->local.key.version],
(int)tunnel->local.key.ident,
ipl2tp_util_ntoa(&tunnel->remote.addr));
if (update)
{
tunnel->nr++;
tunnel->needzlb = 1;
ipl2tp_trpt_tunnel_ack(tunnel, nr);
}
status = IPL2TP_STATUS_OK;
}
else if (IPL2TP_LT(ns, tunnel->nr))
{
/* Old message, send ZLB and ignore */
IPCOM_LOG4(DEBUG,
"%s(%d,%s): Received duplicate message with Ns:%d, ignored",
ipl2tp_versions[tunnel->local.key.version],
(int)tunnel->local.key.ident,
ipl2tp_util_ntoa(&tunnel->remote.addr),
(int)ns);
tunnel->needzlb = 1;
}
else if (IPL2TP_LT(ns, tunnel->nr + tunnel->attr.receive_window_size))
{
tunnel->statistics.control_outofseq_received++;
/* In receive window but out of order, discard - force the sender
* to retransmit*/
IPCOM_LOG3(DEBUG,
"%s(%d,%s): Received in-window message - discarding",
ipl2tp_versions[tunnel->local.key.version],
(int)tunnel->local.key.ident,
ipl2tp_util_ntoa(&tunnel->remote.addr));
/* ipl2tp_trpt_tunnel_ack(tunnel, nr); */
}
else
{
tunnel->statistics.control_outofwin_received++;
/* Not ready for this message yet, ignore */
IPCOM_LOG3(DEBUG,
"%s(%d,%s): Received premature message",
ipl2tp_versions[tunnel->local.key.version],
(int)tunnel->local.key.ident,
ipl2tp_util_ntoa(&tunnel->remote.addr));
}
return status;
}
/*
*===========================================================================
* ipl2tp_trpt_tunnel_ack
*===========================================================================
* Description: Acknowledge message(s).
* Parameters: tunnel - Tunnel descriptor.
* no - Received sequence number.
* Returns:
*
*/
IP_GLOBAL void
ipl2tp_trpt_tunnel_ack(Ipl2tp_tunnel *tunnel,
Ip_u16 no)
{
Ipl2tp_message *container;
Ipl2tp_message *cprev = IP_NULL;
Ip_u16 oldcwnd = tunnel->cwnd;
int window;
/* Reset HELLO tick */
tunnel->hello_ticks = 0;
tunnel->nrack = no;
/* Acknowledge messages */
for (container = IPCOM_LIST_LAST(&tunnel->message_list);
container != IP_NULL &&
IPL2TP_LT(IP_GET_NTOHS(container->admin.ns), no) &&
(container->admin.flags & IPL2TP_CONTAINER_SENT) != 0;
container = cprev)
{
cprev = IPCOM_LIST_PREV(&container->admin.head);
tunnel->nsack = IP_GET_NTOHS(container->admin.ns);
IPCOM_LOG4(DEBUG,
"%s(%d,%s): Got ack for message Ns:%d",
ipl2tp_versions[tunnel->local.key.version],
(int)tunnel->local.key.ident,
ipl2tp_util_ntoa(&tunnel->remote.addr),
(int)tunnel->nsack);
/* Increase windows */
if (tunnel->cwnd < tunnel->ssthresh)
{
/* Slow start */
tunnel->cwnd++;
tunnel->ca_ack = 0;
}
else
{
/* Congestion avoidance */
if (++tunnel->ca_ack >= tunnel->cwnd)
{
tunnel->cwnd++;
tunnel->ca_ack = 0;
}
}
/* Limit CWND to advertised window */
if (tunnel->cwnd > tunnel->common.receive_window_size)
{
tunnel->cwnd = tunnel->common.receive_window_size;
}
if (tunnel->cwnd != oldcwnd)
{
IPCOM_LOG4(DEBUG,
"%s(%d,%s): New congestion window: %d",
ipl2tp_versions[tunnel->local.key.version],
(int)tunnel->local.key.ident,
ipl2tp_util_ntoa(&tunnel->remote.addr),
(int)tunnel->cwnd);
}
/* Remove message from queue */
ipcom_list_remove(&container->admin.head);
ipl2tp_message_delete(container);
}
/* Transmit more messages, if allowed */
for (container = cprev, window = 0;
container != IP_NULL && window < tunnel->cwnd;
container = cprev, window++)
{
cprev = IPCOM_LIST_PREV(&container->admin.head);
/* Ignore sent messages */
if ((container->admin.flags & IPL2TP_CONTAINER_SENT) == 0)
{
/* Window is not full, send message */
container->admin.flags |= IPL2TP_CONTAINER_SENT;
container->admin.timeout = (Ip_u16)ipl2tp.first_retransmit_sec;
IP_SET_HTONS(container->admin.nr, tunnel->nr);
ipl2tp_trpt_control_write(container);
}
}
}
/*
*===========================================================================
* ipl2tp_trpt_hello_init
*===========================================================================
* Description: Initialize HELLO transmission.
* Parameters: tunnel - The tunnel.
* Returns:
*
*/
IP_GLOBAL void
ipl2tp_trpt_hello_init(Ipl2tp_tunnel *tunnel)
{
if (ipl2tp.hello_tick_sec != 0 && tunnel->attr.hello_interval_sec != 0)
{
/* Schedule HELLO transmission */
ipcom_tmo_request(&tunnel->timer,
(Ipcom_tmo_func)ipl2tp_trpt_hello_timeout,
tunnel,
1000 * ipl2tp.hello_tick_sec);
}
}
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,137 @@
/*
******************************************************************************
* HEADER FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp_trpt.h,v $ $Revision: 1.2 $
* $Source: /home/interpeak/CVSRoot/ipl2tp/src/ipl2tp_trpt.h,v $
* $Author: joel $ $Date: 2006-01-30 10:47:46 $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelius@interpeak.se>
******************************************************************************
*/
#ifndef IPL2TP_TRPT_H
#define IPL2TP_TRPT_H
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
struct Ipl2tp_message;
/*
****************************************************************************
* 6 FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipl2tp_trpt_control_output
*===========================================================================
* Description: Output a L2TP control message
* Parameters: container - The container containing the message.
* Returns:
*
*/
IP_GLOBAL void ipl2tp_trpt_control_output(struct Ipl2tp_message *container);
/*
*===========================================================================
* ipl2tp_trpt_data_output
*===========================================================================
* Description: Send a data message.
* Parameters: tunnel - Tunnel to use.
* iov - IO vector
* iov_len - Length of IO vector
* Returns:
*
*/
IP_GLOBAL void ipl2tp_trpt_data_output(Ipl2tp_tunnel *tunnel,
struct Ip_iovec *iov,
int iov_len);
/*
*===========================================================================
* ipl2tp_trpt_sequence_check
*===========================================================================
* Description: Check sequence number of message.
* Parameters: tunnel - The tunnel.
* nr - The NR
* ns - The NS
* is_zlb - Is it a ZLB.
* update - Don't update 'in-sequence' parameters unless set.
* Returns: The status of the processing.
*
*/
IP_GLOBAL Ipl2tp_status ipl2tp_trpt_sequence_check(Ipl2tp_tunnel *tunnel,
Ip_u16 nr,
Ip_u16 ns,
Ip_bool is_zlb,
Ip_bool update);
/*
*===========================================================================
* ipl2tp_trpt_tunnel_ack
*===========================================================================
* Description: Acknowledge message(s).
* Parameters: tunnel - Tunnel descriptor.
* no - Received sequence number.
* Returns:
*
*/
IP_GLOBAL void ipl2tp_trpt_tunnel_ack(Ipl2tp_tunnel *tunnel,
Ip_u16 no);
/*
*===========================================================================
* ipl2tp_trpt_hello_init
*===========================================================================
* Description: Initialize HELLO transmission.
* Parameters: tunnel - The tunnel.
* Returns:
*
*/
IP_GLOBAL void ipl2tp_trpt_hello_init(Ipl2tp_tunnel *tunnel);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,290 @@
/*
******************************************************************************
* SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp_util.c,v $ $Revision: 1.13.16.2 $
* $Source: /home/interpeak/CVSRoot/ipl2tp/src/ipl2tp_util.c,v $
* $Author: hxu0 $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
*
******************************************************************************
*/
/*
****************************************************************************
* DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* INCLUDE FILES
****************************************************************************
*/
#define IPL2TP_UTIL_C
#include "ipl2tp_h.h"
#include "ipl2tp_util.h"
#include "ipl2tp_api.h"
#include "ipl2tp_avp.h"
#include "ipl2tp_attr.h"
#include "ipl2tp_trpt.h"
/*
****************************************************************************
* DEFINES
****************************************************************************
*/
/*
****************************************************************************
* TYPES
****************************************************************************
*/
/*
****************************************************************************
* LOCAL DATA
****************************************************************************
*/
const char *ipl2tp_versions[] =
{
"IPL2TP",
"IPL2TPv1",
"IPL2TPv2",
"IPL2TPv3"
};
/*
****************************************************************************
* PUBLIC DATA
****************************************************************************
*/
/*
****************************************************************************
* LOCAL FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* PUBLIC FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipl2tp_util_ntoa
*===========================================================================
* Description: Converts an IPvX address to string representation. Result
* ends up in a static buffer which is returned.
* Parameters: addr - The IPvX address.
* Returns: The address in string form.
*
*/
IP_GLOBAL const char *
ipl2tp_util_ntoa(union Ip_sockaddr_union *addr)
{
/* Current buffer */
char* buf = ipl2tp.ntoa.ntoa_buffer[ipl2tp.ntoa.ntoa_index];
ipl2tp.ntoa.ntoa_index = (ipl2tp.ntoa.ntoa_index + 1) & IPL2TP_NTOA_ADDRMASK;
/* Convert */
switch (addr->sa.sa_family)
{
#ifdef IPCOM_USE_INET6
case IP_AF_INET6:
ipcom_inet_ntop(IP_AF_INET6, &addr->sin6.sin6_addr, buf, IPL2TP_NTOA_ADDRSIZE);
break;
#endif
case IP_AF_INET:
ipcom_inet_ntop(IP_AF_INET, &addr->sin.sin_addr, buf, IPL2TP_NTOA_ADDRSIZE);
break;
default:
ipcom_strcpy(buf, "<unknown AF_*>");
break;
}
return buf;
}
/*
*===========================================================================
* ipl2tp_util_vector_random
*===========================================================================
* Description: Generate a random vector.
* Parameters: vector - vector to generate in; if no array
* is preset, it will be dynamically allocated.
* len - Amount of random data to generate.
* Returns:
*
*/
IP_GLOBAL void
ipl2tp_util_vector_random(Ipl2tp_vector *vector,
Ip_size_t len)
{
int vlen = (int)len;
int i;
/* */
if (vector->array == IP_NULL)
{
/* Allocate the array */
vector->array = ipcom_malloc(len);
if(vector->array == IP_NULL)
return;
}
/* Assign vector */
for (i = vlen - 1; i >= 0; i--)
{
vector->array[i] = (Ip_u8)((unsigned long)ipcom_random() % 256);
}
vector->size = len;
}
/*
*===========================================================================
* ipl2tp_util_vector_dup
*===========================================================================
* Description: Duplicate a vector
* Parameters: dst - Destination vector
* src - Source vector
* Returns:
*
*/
IP_GLOBAL void
ipl2tp_util_vector_dup(Ipl2tp_vector *dst,
Ipl2tp_vector *src)
{
int ssize = (int)src->size;
IPL2TP_SAFE_FREE(dst->array);
dst->array = IP_NULL;
if (ssize > 0)
{
dst->array = ipl2tp_util_memdup(src->array, ssize + 1, ssize);
if (dst->array == IP_NULL)
{
dst->size = 0;
return;
}
dst->size = src->size;
/* Just to make it easeier on myself */
dst->array[dst->size] = '\0';
}
}
/*
*===========================================================================
* ipl2tp_util_vector_create
*===========================================================================
* Description: Create a vector using variables
* Parameters: dst - Destination vector
* value - The value to use as vector
* length - The length of value
* Returns:
*
*/
IP_GLOBAL void
ipl2tp_util_vector_create(Ipl2tp_vector *dst,
void *value,
Ip_size_t length)
{
Ipl2tp_vector src;
src.array = value;
src.size = length;
ipl2tp_util_vector_dup(dst, &src);
}
/*
*===========================================================================
* ipl2tp_util_memdup
*===========================================================================
* Description: Do a memory duplication.
* Parameters: m - Memory to duplicate.
* s - Size to allocate.
* l - Length to copy.
* Returns: The new memory block.
*
*/
IP_PUBLIC void *
ipl2tp_util_memdup(CONST void *m,
int s,
int l)
{
void *d;
if (m == IP_NULL)
{
return IP_NULL;
}
if ((d = ipcom_malloc(s)) == IP_NULL)
{
IPCOM_LOG1(ERR,
"%s: Out of memory",
ipl2tp_versions[0]);
}
else
{
ipcom_memcpy(d, m, l);
}
return d;
}
/*
*===========================================================================
* ipl2tp_util_strdup
*===========================================================================
* Description: Do a string duplication.
* Parameters: m - Memory to duplicate.
* l - Length to copy.
* Returns: The new string
*
*/
IP_PUBLIC void *
ipl2tp_util_strdup(CONST void *m,
int l)
{
if (m == IP_NULL || l == 0)
return IP_NULL;
/* Do calculate size */
if (l == -1)
return ipcom_strdup(m);
else
{
char *d = ipl2tp_util_memdup(m, l + 1, l);
if (d)
{
d[l] = '\0';
}
return d;
}
}
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,161 @@
/*
******************************************************************************
* HEADER FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp_util.h,v $ $Revision: 1.2 $
* $Source: /home/interpeak/CVSRoot/ipl2tp/src/ipl2tp_util.h,v $
* $Author: joel $ $Date: 2006-01-30 10:47:46 $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelius@interpeak.se>
******************************************************************************
*/
#ifndef IPL2TP_UTIL_H
#define IPL2TP_UTIL_H
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 FUNCTIONS
****************************************************************************
*/
/* The various version strings */
extern const char *ipl2tp_versions[];
/*
*===========================================================================
* ipl2tp_util_ntoa
*===========================================================================
* Description: Converts an IPvX address to string representation. Result
* ends up in a static buffer which is returned.
* Parameters: addr - The IPvX address.
* Returns: The address in string form.
*
*/
IP_GLOBAL const char *ipl2tp_util_ntoa(union Ip_sockaddr_union *addr);
/*
*===========================================================================
* ipl2tp_util_vector_random
*===========================================================================
* Description: Generate a random vector.
* Parameters: vector - vector to generate in; if no array
* is preset, it will be dynamically allocated.
* len - Length of data to generate.
* Returns:
*
*/
IP_GLOBAL void ipl2tp_util_vector_random(Ipl2tp_vector *vector,
Ip_size_t len);
/*
*===========================================================================
* ipl2tp_util_vector_dup
*===========================================================================
* Description: Duplicate a vector
* Parameters: dst - Destination vector
* src - Source vector
* Returns:
*
*/
IP_GLOBAL void ipl2tp_util_vector_dup(Ipl2tp_vector *dst,
Ipl2tp_vector *src);
/*
*===========================================================================
* ipl2tp_util_vector_create
*===========================================================================
* Description: Create a vector using variables
* Parameters: dst - Destination vector
* value - The value to use as vector
* length - The length of value
* Returns:
*
*/
IP_GLOBAL void ipl2tp_util_vector_create(Ipl2tp_vector *dst,
void *value,
Ip_size_t length);
/*
*===========================================================================
* ipl2tp_util_memdup
*===========================================================================
* Description: Do a memory duplication.
* Parameters: m - Memory to duplicate.
* s - Size to allocate.
* l - Length to copy.
* Returns: The new memory block.
*
*/
IP_GLOBAL void *ipl2tp_util_memdup(CONST void *m,
int s,
int l);
/*
*===========================================================================
* ipl2tp_util_strdup
*===========================================================================
* Description: Do a string duplication.
* Parameters: m - Memory to duplicate.
* l - Length to copy.
* Returns: The new string
*
*/
IP_GLOBAL void *ipl2tp_util_strdup(CONST void *m,
int l);
#ifdef __cplusplus
}
#endif
#endif
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,648 @@
/*
******************************************************************************
* INTERPEAK SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp_v2.c,v $ $Revision: 1.5 $
* $Source: /home/interpeak/CVSRoot/ipl2tp/src/ipl2tp_v2.c,v $
* $Author: tneale $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelis@interpeak.se>
******************************************************************************
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#include "ipl2tp_h.h"
#include "ipl2tp_api.h"
#include "ipl2tp_avp.h"
#include "ipl2tp_attr_h.h"
#include "ipl2tp_data.h"
#include "ipl2tp_message.h"
#include "ipl2tp_state.h"
#include "ipl2tp_trpt.h"
#include "ipl2tp_v2.h"
#include "ipl2tp_v2_state.h"
#include "ipl2tp_v2_message.h"
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
IP_STATIC void
ipl2tp_v2_tunnel_message_init(Ipl2tp_message *container);
IP_STATIC void
ipl2tp_v2_tunnel_message_digest(Ipl2tp_message *container);
IP_STATIC void
ipl2tp_v2_tunnel_message_log(Ipl2tp_message *container,
const char *kind);
IP_STATIC void
ipl2tp_v2_tunnel_assign_peer_id(Ipl2tp_tunnel *tunnel,
Ipl2tp_avp *avp);
IP_STATIC void
ipl2tp_v2_tunnel_done(Ipl2tp_tunnel *tunnel);
IP_STATIC void
ipl2tp_v2_tunnel_session_init(Ipl2tp_session *session);
IP_STATIC void
ipl2tp_v2_tunnel_session_done(Ipl2tp_session *session);
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
static Ipl2tp_tunnel_table ipl2tp_v2_table =
{
ipl2tp_v2_tunnel_message_init,
ipl2tp_v2_tunnel_message_log,
ipl2tp_v2_tunnel_message_digest,
ipl2tp_v2_tunnel_assign_peer_id,
ipl2tp_v2_state_machine_sccrq,
ipl2tp_v2_tunnel_done,
ipl2tp_v2_tunnel_session_init,
ipl2tp_v2_tunnel_session_done,
ipl2tp_v2_messages
};
/*
****************************************************************************
* 9 STATIC FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipl2tp_v2_next_tunnel_id
*===========================================================================
* Description: Find next available tunnel identifier
* Parameters:
* Returns: The next usable tunnel id for v2
*
*/
IP_STATIC Ip_u32
ipl2tp_v2_next_tunnel_id(void)
{
Ipl2tp_key key;
Ip_u32 loops;
/* */
key.version = IPL2TP_VERSION_L2TPV2;
/* Don't loop more than 64K */
for (loops = 0; loops < 0xffff; loops++)
{
/* Do not use value 0 */
if (++ipl2tp.tunnel.v2.ident == 0)
++ipl2tp.tunnel.v2.ident;
/* Set the key */
key.ident = ipl2tp.tunnel.v2.ident;
/* Does it exist already? */
if (ipcom_hash_get(ipl2tp.tunnel.hash_id, &key) == IP_NULL)
return key.ident;
}
/* Could not locate a new value */
return 0;
}
/*
*===========================================================================
* ipl2tp_v2_next_session_id
*===========================================================================
* Description: Find next available session identifier
* Parameters:
* Returns: The next usable session id for that particular version.
*
*/
IP_STATIC Ip_u32
ipl2tp_v2_next_session_id(void)
{
Ipl2tp_key key;
Ip_u32 loops;
key.version = IPL2TP_VERSION_L2TPV2;
/* Don't loop more than 64K */
for (loops = 0; loops < 0xffff; loops++)
{
if (++ipl2tp.session.v2.ident == 0)
ipl2tp.session.v2.ident++;
key.ident = ipl2tp.session.v2.ident;
/* Does it exist already? */
if (ipcom_hash_get(ipl2tp.session.hash_id, &key) == IP_NULL)
return key.ident;
}
/* Could not locate a new value */
return 0;
}
/*
*===========================================================================
* ipl2tp_v2_tunnel_assign_peer_id
*===========================================================================
* Description: Assign peer ID.
* Parameters:
* Returns:
*
*/
IP_STATIC void
ipl2tp_v2_tunnel_assign_peer_id(Ipl2tp_tunnel *tunnel,
Ipl2tp_avp *avp)
{
/* Try remove */
ipcom_hash_remove(ipl2tp.tunnel.hash_remote_id, tunnel);
/* set the tunnel ID */
tunnel->remote.key.ident = avp->assigned_tunnel_id.value;
/* Insert it into the hash table */
ipcom_hash_add(ipl2tp.tunnel.hash_remote_id, tunnel);
}
/*
*===========================================================================
* ipl2tp_v2_tunnel_message_init
*===========================================================================
* Description: Initialize a V2 container
* Parameters: message - The container.
* Returns:
*
*/
IP_STATIC void
ipl2tp_v2_tunnel_message_init(Ipl2tp_message *container)
{
Ipl2tp_tunnel *tunnel = container->admin.tunnel;
Ipl2tp_session *session = container->admin.session;
Ipl2tp_v2_header *header = IPL2TP_V2_HEADER(container);
Ip_u16 tmp;
ipcom_memset(header, 0, sizeof(*header));
/* Enter message fields */
IP_SET_HTONS(&header->flv,
(IPL2TP_HEADER_FLAG_CONTROL |
IPL2TP_HEADER_FLAG_LENGTH |
IPL2TP_HEADER_FLAG_SEQUENCE |
IPL2TP_VERSION_L2TPV2));
/* Set the correct values */
IP_SET_HTONS(&header->length, sizeof(Ipl2tp_v2_header));
IP_SET_HTONS(&header->tunnel_id, (Ip_u16)(tunnel->remote.key.ident));
tmp = (Ip_u16)(session? (Ip_u16) session->remote.key.ident : 0);
IP_SET_HTONS(&header->session_id, tmp);
/* Initialize the digest */
container->admin.digest = IP_NULL;
/* Store the offsets to the NR/NS pair */
container->admin.nr = &header->nr;
container->admin.ns = &header->ns;
/* Store the offset to the pkt start/header length */
container->admin.start = (Ip_u8 *)header;
container->admin.length = &header->length;
container->admin.pre_header = 0;
/* Set initial size */
container->admin.size = sizeof(Ipl2tp_v2_header);
}
/*
*===========================================================================
* ipl2tp_v2_tunnel_message_digest
*===========================================================================
* Description: Calculate a digest
* Parameters: message - The container.
* Returns:
*
*/
IP_STATIC void
ipl2tp_v2_tunnel_message_digest(Ipl2tp_message *container)
{
/* Don't bother */
IPL2TP_UNUSED(container);
}
/*
*===========================================================================
* ipl2tpv2_tunnel_message_log
*===========================================================================
* Description: Log a v2 container message
* Parameters:
* Returns:
*
*/
IP_STATIC void
ipl2tp_v2_tunnel_message_log(Ipl2tp_message *container,
const char *kind)
{
/* Send it to the log function */
ipl2tp_v2_dlog_packet(&container->admin.tunnel->remote.addr,
IPL2TP_V2_HEADER(container),
kind);
}
/*
*===========================================================================
* ipl2tp_v2_tunnel_done
*===========================================================================
* Description: Cleans up the version specific attributes of the
* tunnel.
* Parameters: tunnel - Tunnel.
* Returns:
*
*/
IP_STATIC void
ipl2tp_v2_tunnel_done(Ipl2tp_tunnel *tunnel)
{
/* Remove it from the v2 list */
ipcom_list_remove(&tunnel->head);
/* Down the count */
ipl2tp.tunnel.v2.total--;
}
/*
*===========================================================================
* ipl2tp_v2_tunnel_session_init
*===========================================================================
* Description: Initialize the version specific attributes of the
* session.
* Parameters: session - Session.
* Returns:
*
*/
IP_STATIC void
ipl2tp_v2_tunnel_session_init(Ipl2tp_session *session)
{
session->local.key.ident = ipl2tp_v2_next_session_id();
ipl2tp_attr_session_attribute_copy(&session->attr,
&ipl2tp.session.v2.attr);
/* Only do PPP */
session->attr.pw_type = IPL2TP_ATTR_PW_TYPE_PPP;
/**/
session->local.key.version = IPL2TP_VERSION_L2TPV2;
session->remote.key.version = IPL2TP_VERSION_L2TPV2;
ipl2tp.session.v2.total++;
}
/*
*===========================================================================
* ipl2tpv2_tunnel_session_done
*===========================================================================
* Description: Cleans up the version specific attributes of the
* session.
* Parameters: sesion - Session.
* Returns:
*
*/
IP_STATIC void
ipl2tp_v2_tunnel_session_done(Ipl2tp_session *session)
{
IPL2TP_UNUSED(session);
ipl2tp.session.v2.total--;
}
/*
****************************************************************************
* 10 GLOBAL FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipl2tp_v2_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.
* 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_GLOBAL Ipl2tp_status
ipl2tp_v2_l2tp_input(void *buffer,
void *payload,
Ip_u16 length,
union Ip_sockaddr_union *addr)
{
Ipl2tp_status status = IPL2TP_STATUS_OK;
Ipl2tp_v2_header *message = payload;
Ipl2tp_tunnel *tunnel;
Ip_u16 flags = IP_GET_NTOHS(&message->flv);
Ipl2tp_key tkey;
Ip_u16 found_length;
tkey.version = IPL2TP_VERSION_L2TPV2;
/* Locate the tunnel id */
if (IP_BIT_ISSET(flags, IPL2TP_HEADER_FLAG_LENGTH))
{
/* After the length field */
tkey.ident = IP_GET_HTONS(((Ip_u8 *)payload) + 4);
/* Verify the length */
found_length = IP_GET_NTOHS(&message->length);
}
else
{
/* After the version & flags */
tkey.ident = IP_GET_HTONS(((Ip_u8 *)payload) + 2);
/* We don't know; just assume */
found_length = length;
}
tunnel = ipl2tp_state_tunnel_get(&tkey);
if (tunnel != IP_NULL)
{
tunnel->statistics.in_octets += length;
}
/* Verify length, if possible */
if (found_length != length)
{
if (tunnel != IP_NULL)
tunnel->statistics.in_errors++;
IPCOM_LOG5(WARNING,
"%s(%d,%s): Message length does not match header, %d != %d",
ipl2tp_versions[IPL2TP_VERSION_L2TPV2],
(int)tkey.ident,
ipl2tp_util_ntoa(addr),
(int)found_length,
(int)length);
status = IPL2TP_STATUS_MALFORMED;
goto leave;
}
if (tunnel != IP_NULL)
tunnel->statistics.in_packets++;
/* Control or data? */
if (IP_BIT_ISSET(flags, IPL2TP_HEADER_FLAG_CONTROL))
{
status = ipl2tp_v2_state_control_input(message, length, addr);
}
else
{
Ip_u16 mindex = 4; /* Tunnel, version & flags */
Ipl2tp_session *session;
Ipl2tp_key skey;
skey.version = IPL2TP_VERSION_L2TPV2;
/*
* We will use a plain old index here
* instead of the fancy Umessage types.
*/
/* Get session ID */
if (IP_BIT_ISSET(flags, IPL2TP_HEADER_FLAG_LENGTH))
{
/* Advance past the length field */
mindex += 2;
}
/* Get the session identifier */
skey.ident = IP_GET_NTOHS(((Ip_u8 *)payload) + mindex);
/* Valid session? */
if ((session = ipl2tp_state_session_get(&skey, IP_NULL)) == IP_NULL ||
session->state != IPL2TP_SSTATE_ESTABLISHED)
{
IPCOM_LOG4(WARNING,
"%s(%d,%s); Got data message with invalid session ID: %d",
ipl2tp_versions[IPL2TP_VERSION_L2TPV2],
(int) tkey.ident,
ipl2tp_util_ntoa(addr),
(int) skey.ident);
status = IPL2TP_STATUS_BADID;
goto leave;
}
IPCOM_LOG4(DEBUG,
"%s(%d,%d,%s): Receiving L2TP data packet",
ipl2tp_versions[IPL2TP_VERSION_L2TPV2],
(int)tkey.ident,
(int)skey.ident,
ipl2tp_util_ntoa(addr));
/* Advance to payload or NR/NS */
mindex += 2;
/* Sequencing? */
session->v.v2.sequencing = (Ip_u8)(IP_BIT_ISSET(flags, IPL2TP_HEADER_FLAG_SEQUENCE) != IP_FALSE);
if (session->v.v2.sequencing != 0)
{
/* Go past the NS */
mindex += 2;
/* Retrieve NR */
session->v.v2.nr = IP_GET_NTOHS(((Ip_u8 *)payload) + mindex);
/* Jump past the NR */
mindex += 2;
}
/* Do we have the offset fields? */
if (IP_BIT_ISSET(flags, IPL2TP_HEADER_FLAG_OFFSET))
{
/* First two bytes are the offset field */
/* Move past the offset */
mindex += IP_GET_NTOHS(((Ip_u8 *)payload) + mindex);
/* Move past the offset field */
mindex += 2;
}
IPCOM_LOG4(DEBUG,
"%s(%d,%d,%s): Sending PPP packet",
ipl2tp_versions[IPL2TP_VERSION_L2TPV2],
(int)tkey.ident,
(int)skey.ident,
ipl2tp_util_ntoa(addr));
/* Send to PPP interface */
IPL2TP_SAFE_CALLBACK(session->attr.dcallback,
(session->attr.user_data,
&session->local.key,
buffer,
(Ip_u8 *)payload + mindex,
(Ip_u16)(length - mindex)));
}
leave:
return status;
}
/*
*===========================================================================
* ipl2tp_v2_tunnel_init
*===========================================================================
* Description: Initialize the version specific attributes of the
* tunnel.
* Parameters: tunnel - Tunnel.
* Returns:
*
*/
IP_GLOBAL void
ipl2tp_v2_tunnel_init(Ipl2tp_tunnel *tunnel)
{
/* Initialize the callback table */
tunnel->table = &ipl2tp_v2_table;
/* Store the version used */
tunnel->local.key.version = IPL2TP_VERSION_L2TPV2;
/* Store the version used */
tunnel->remote.key.version = IPL2TP_VERSION_L2TPV2;
/* Grab next available v2 tunnel identifier */
tunnel->local.key.ident = ipl2tp_v2_next_tunnel_id();
/* Insert it into the v2 tunnel list */
ipcom_list_insert_first(&ipl2tp.tunnel.v2.tunnels, &tunnel->head);
/* Copy V2 global attributes. */
ipl2tp_attr_tunnel_attribute_copy(&tunnel->attr,
&ipl2tp.tunnel.v2.attr);
tunnel->v.v2.framing_capabilities = IPL2TP_MIB_FRAMING_NONE;
tunnel->v.v2.bearer_capabilities = IPL2TP_MIB_BEARER_NONE;
/* Up the count. */
ipl2tp.tunnel.v2.total++;
}
/*
*===========================================================================
* ipl2tp_v2_dlog_packet
*===========================================================================
* Description: Log a packet
* Parameters: peer - The sender.
* header - Packet header
* kind - Type of event.
* Returns:
*
*/
IP_GLOBAL void
ipl2tp_v2_dlog_packet(union Ip_sockaddr_union *peer,
Ipl2tp_v2_header *header,
CONST char *kind)
{
Ip_u16 size = IP_GET_NTOHS(&header->length);
Ip_u16 mindex = sizeof(*header);
Ip_u16 mtype = 0;
Ip_u16 flags = IP_GET_HTONS(&header->flv);
/* Are the offset fields availble? */
if (IP_BIT_ISSET(flags, IPL2TP_HEADER_FLAG_OFFSET))
{
Ipl2tp_v2_umessage *umessage = (Ipl2tp_v2_umessage *) header;
mindex = sizeof(*header) + 2;
mindex += IP_GET_NTOHS(&umessage->len_seq_off.offset);
}
if (size > mindex)
{
/* Get message type (assume message type AVP is first) */
Ip_u16 *m16 = (Ip_u16 *)header;
mtype = IP_GET_NTOHS(&m16[mindex / 2 + 3]);
}
IPCOM_LOG9(DEBUG,
"%s(%d,%d,%s): %s %s control packet; Ns:%d Nr:%d L:%d",
ipl2tp_versions[IPL2TP_VERSION_L2TPV2],
(int)IP_GET_NTOHS(&header->tunnel_id),
(int)IP_GET_NTOHS(&header->session_id),
ipl2tp_util_ntoa(peer),
kind,
ipl2tp_message_name(mtype),
IP_GET_NTOHS(&header->ns),
IP_GET_NTOHS(&header->nr),
size);
}
/*
****************************************************************************
* 11 PUBLIC FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,186 @@
/*
******************************************************************************
* HEADER FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp_v2.h,v $ $Revision: 1.3 $
* $Source: /home/interpeak/CVSRoot/ipl2tp/src/ipl2tp_v2.h,v $
* $Author: tneale $ $Date: 2010-04-27 19:25:26 $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelius@interpeak.se>
******************************************************************************
*/
#ifndef IPL2TP_V2_H
#define IPL2TP_V2_H
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
#define IPL2TP_V2_HEADER(c) (&((c)->header.v2))
#define IPL2TP_V2_ZLB(len) ((len) <= sizeof(Ipl2tp_v2_header))
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/* Data version */
typedef union Ipl2tp_v2_umessage
{
struct
{
Ip_u16 flv; /* Flags & Version */
Ip_u16 length; /* Length of message */
Ip_u16 tunnel_id; /* Tunnel ID */
Ip_u16 session_id; /* Session ID */
} len;
struct
{
Ip_u16 flv; /* Flags & Version */
Ip_u16 length; /* Length of message */
Ip_u16 tunnel_id; /* Tunnel ID */
Ip_u16 session_id; /* Session ID */
Ip_u16 ns; /* Sequence number */
Ip_u16 nr; /* Next expected sequence number */
} len_seq;
struct
{
Ip_u16 flv; /* Flags & Version */
Ip_u16 length; /* Length of message */
Ip_u16 tunnel_id; /* Tunnel ID */
Ip_u16 session_id; /* Session ID */
Ip_u16 offset; /* Offset to payload */
} len_off;
struct
{
Ip_u16 flv; /* Flags & Version */
Ip_u16 length; /* Length of message */
Ip_u16 tunnel_id; /* Tunnel ID */
Ip_u16 session_id; /* Session ID */
Ip_u16 ns; /* Sequence number */
Ip_u16 nr; /* Next expected sequence number */
Ip_u16 offset; /* Offset to payload */
} len_seq_off;
Ip_u8 byte[1]; /* Plain byte array */
}
Ipl2tp_v2_umessage;
/*
*===========================================================================
* Message
*===========================================================================
*
* Message header.
*/
typedef struct Ipl2tp_v2_header
{
Ip_u16 flv; /* Flags & Version */
Ip_u16 length; /* Length of message */
Ip_u16 tunnel_id; /* Tunnel ID */
Ip_u16 session_id; /* Session ID */
Ip_u16 ns; /* Sequence number */
Ip_u16 nr; /* Next expected sequence number */
}
Ipl2tp_v2_header;
/*
****************************************************************************
* 6 FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipl2tp_v2_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.
* 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_GLOBAL Ipl2tp_status ipl2tp_v2_l2tp_input(void *buffer,
void *payload,
Ip_u16 length,
union Ip_sockaddr_union *addr);
/*
*===========================================================================
* ipl2tp_v2_tunnel_init
*===========================================================================
* Description: Initialize the version specific attributes of the
* tunnel.
* Parameters: tunnel - Tunnel.
* Returns:
*
*/
IP_GLOBAL void ipl2tp_v2_tunnel_init(Ipl2tp_tunnel *tunnel);
/*
*===========================================================================
* ipl2tp_v2_dlog_packet
*===========================================================================
* Description: Log a packet
* Parameters: peer - The sender.
* header - Packet header
* kind - Type of event.
* Returns:
*
*/
IP_GLOBAL void ipl2tp_v2_dlog_packet(union Ip_sockaddr_union *peer,
Ipl2tp_v2_header *header,
CONST char *kind);
#ifdef __cplusplus
}
#endif
#endif
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,872 @@
/*
******************************************************************************
* INTERPEAK SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp_v2_message.c,v $ $Revision: 1.2 $
* $Source: /home/interpeak/CVSRoot/ipl2tp/src/ipl2tp_v2_message.c,v $
* $Author: joel $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelis@interpeak.se>
******************************************************************************
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#include "ipl2tp_h.h"
#include "ipl2tp_avp.h"
#include "ipl2tp_data.h"
#include "ipl2tp_message.h"
#include "ipl2tp_state.h"
#include "ipl2tp_trpt.h"
#include "ipl2tp_v2.h"
#include "ipl2tp_v2_state.h"
#include "ipl2tp_v2_message.h"
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
IP_STATIC Ipl2tp_status ipl2tp_v2_message_zlb(Ipl2tp_tunnel *tunnel,
Ipl2tp_session *session,
Ipl2tp_avp *avp);
IP_STATIC Ipl2tp_status ipl2tp_v2_message_cdn(Ipl2tp_tunnel *tunnel,
Ipl2tp_session *session,
Ipl2tp_avp *avp);
IP_STATIC Ipl2tp_status ipl2tp_v2_message_occn(Ipl2tp_tunnel *tunnel,
Ipl2tp_session *session,
Ipl2tp_avp *avp);
IP_STATIC Ipl2tp_status ipl2tp_v2_message_ocrq(Ipl2tp_tunnel *tunnel,
Ipl2tp_session *session,
Ipl2tp_avp *avp);
IP_STATIC Ipl2tp_status ipl2tp_v2_message_ocrp(Ipl2tp_tunnel *tunnel,
Ipl2tp_session *session,
Ipl2tp_avp *avp);
IP_STATIC Ipl2tp_status ipl2tp_v2_message_iccn(Ipl2tp_tunnel *tunnel,
Ipl2tp_session *session,
Ipl2tp_avp *avp);
IP_STATIC Ipl2tp_status ipl2tp_v2_message_icrq(Ipl2tp_tunnel *tunnel,
Ipl2tp_session *session,
Ipl2tp_avp *avp);
IP_STATIC Ipl2tp_status ipl2tp_v2_message_icrp(Ipl2tp_tunnel *tunnel,
Ipl2tp_session *session,
Ipl2tp_avp *avp);
IP_STATIC Ipl2tp_status ipl2tp_v2_message_hello(Ipl2tp_tunnel *tunnel,
Ipl2tp_session *session,
Ipl2tp_avp *avp);
IP_STATIC Ipl2tp_status ipl2tp_v2_message_stopccn(Ipl2tp_tunnel *tunnel,
Ipl2tp_session *session,
Ipl2tp_avp *avp);
IP_STATIC Ipl2tp_status ipl2tp_v2_message_scccn(Ipl2tp_tunnel *tunnel,
Ipl2tp_session *session,
Ipl2tp_avp *avp);
IP_STATIC Ipl2tp_status ipl2tp_v2_message_sccrp(Ipl2tp_tunnel *tunnel,
Ipl2tp_session *session,
Ipl2tp_avp *avp);
IP_STATIC Ipl2tp_status ipl2tp_v2_message_sccrq(Ipl2tp_tunnel *tunnel,
Ipl2tp_session *session,
Ipl2tp_avp *avp);
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
/* Message callback table */
Ipl2tp_message_func ipl2tp_v2_messages[IPL2TP_MSG_MAX] =
{
ipl2tp_v2_message_zlb, /* 0 ZLB */
ipl2tp_v2_message_sccrq, /* 1 SCCRQ */
ipl2tp_v2_message_sccrp, /* 2 SCCRP */
ipl2tp_v2_message_scccn, /* 3 SCCCN */
ipl2tp_v2_message_stopccn, /* 4 STOPCCN */
IP_NULL, /* 5 RESERVED */
ipl2tp_v2_message_hello, /* 6 HELLO */
ipl2tp_v2_message_ocrq, /* 7 OCRQ */
ipl2tp_v2_message_ocrp, /* 8 OCRP */
ipl2tp_v2_message_occn, /* 9 OCCN */
ipl2tp_v2_message_icrq, /* 10 ICRQ */
ipl2tp_v2_message_icrp, /* 11 ICRP */
ipl2tp_v2_message_iccn, /* 12 ICCN */
IP_NULL, /* 13 RESERVED */
ipl2tp_v2_message_cdn, /* 14 CDN */
IP_NULL, /* 15 WEN */
IP_NULL, /* 16 SLI */
IP_NULL, /* 17 MDMST */
IP_NULL, /* 18 SRRQ */
IP_NULL, /* 19 SRRP */
IP_NULL /* 20 ACK */
};
/*
****************************************************************************
* 9 STATIC FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipl2tp_v2_message_sccrq
*===========================================================================
* Description: Create and send an SCCRQ message.
* Parameters: tunnel - Pointer to tunnel descriptor.
* session - The session (NULL)
* avp - AVP (NULL)
* Returns:
*
*/
IP_STATIC Ipl2tp_status
ipl2tp_v2_message_sccrq(Ipl2tp_tunnel *tunnel,
Ipl2tp_session *session,
Ipl2tp_avp *avp)
{
Ipl2tp_message *c = ipl2tp_message_new(tunnel, IP_NULL);
IPL2TP_UNUSED(avp);
IPL2TP_UNUSED(session);
if (c != IP_NULL)
{
/* Compulsory part */
ipl2tp_avp_set_message_type(c, IPL2TP_MSG_SCCRQ);
ipl2tp_v2_message_sccrq_avps(tunnel, c);
ipl2tp_avp_set_host_name(c, ipl2tp.host_name);
ipl2tp_avp_set_vendor_name(c, IPL2TP_VENDOR_NAME);
if (ipl2tp.open_exclusive == IPL2TP_MIB_NO)
{
Ipl2tp_vector vec;
Ip_u8 data[8];
vec.array = data;
ipl2tp_util_vector_random(&vec, 8);
ipl2tp_avp_set_tie_breaker(c, &vec);
ipl2tp_util_vector_dup(&tunnel->common.tie_breaker, &vec);
}
ipl2tp_trpt_control_output(c);
}
return IPL2TP_STATUS_OK;
}
/*
*===========================================================================
* ipl2tp_v2_message_sccrp
*===========================================================================
* Description: Create and send an SCCRP message.
* Parameters: tunnel - The tunnel
* session - The session (NULL)
* avp - The AVP we're replying to.
* Returns:
*
*/
IP_STATIC Ipl2tp_status
ipl2tp_v2_message_sccrp(Ipl2tp_tunnel *tunnel,
Ipl2tp_session *session,
Ipl2tp_avp *avp)
{
Ipl2tp_message *c = ipl2tp_message_new(tunnel, IP_NULL);
Ipl2tp_vector resp;
IPL2TP_UNUSED(session);
if (c != IP_NULL)
{
/* Prepare message */
ipl2tp_avp_set_message_type(c, IPL2TP_MSG_SCCRP);
ipl2tp_avp_set_protocol_version(c);
ipl2tp_avp_set_host_name(c, ipl2tp.host_name);
ipl2tp_avp_set_framing_capabilities(c, tunnel->attr.framing_capabilities);
ipl2tp_avp_set_assigned_tunnel_id(c, tunnel->local.key.ident);
if (tunnel->attr.bearer_capabilities != 0)
{
ipl2tp_avp_set_bearer_capabilities(c,
tunnel->attr.bearer_capabilities);
}
if (tunnel->attr.receive_window_size != IPL2TP_RECEIVE_WINDOW_SIZE)
{
ipl2tp_avp_set_receive_window_size(c,
tunnel->attr.receive_window_size);
}
/* Generate challenge if applicable */
if (tunnel->attr.authentication == IPL2TP_MIB_AUTH_CHALLENGE)
{
Ip_u8 cvalue[IPL2TP_MAX_CHALLENGE_LENGTH];
Ipl2tp_vector vec;
vec.array = cvalue;
vec.size = IPL2TP_MAX_CHALLENGE_LENGTH;
ipl2tp_avp_challenge_init(&vec, tunnel, IPL2TP_MSG_SCCRP);
ipl2tp_avp_set_challenge(c, &vec);
}
/* Reply to challenge if necessary */
switch (ipl2tp_avp_challenge_response_init(&resp, tunnel, avp))
{
case IPL2TP_STATUS_OK:
ipl2tp_avp_set_challenge_response(c, &resp);
break;
case IPL2TP_STATUS_IGNORE:
break;
default:
ipl2tp_message_delete(c);
return IPL2TP_STATUS_ERROR;
}
/* Free it if it's used */
IPL2TP_SAFE_FREE(resp.array);
ipl2tp_avp_set_firmware_revision(c, IPL2TP_VERSION_NUM);
ipl2tp_avp_set_vendor_name(c, IPL2TP_VENDOR_NAME);
ipl2tp_trpt_control_output(c);
}
return IPL2TP_STATUS_OK;
}
/*
*===========================================================================
* ipl2tp_v2_message_scccn
*===========================================================================
* Description: Create and send an SCCCN message.
* Parameters: tunnel - The tunnel
* session - The session (NULL)
* avp - The AVP
* Returns: IPL2TP_STATUS_OK if it went OK
*
*/
IP_STATIC Ipl2tp_status
ipl2tp_v2_message_scccn(Ipl2tp_tunnel *tunnel,
Ipl2tp_session *session,
Ipl2tp_avp *avp)
{
Ipl2tp_message *c = ipl2tp_message_new(tunnel, IP_NULL);
Ipl2tp_vector resp;
IPL2TP_UNUSED(session);
if (c != IP_NULL)
{
/* Prepare message */
ipl2tp_avp_set_message_type(c, IPL2TP_MSG_SCCCN);
/* Reply to challenge if necessary */
switch (ipl2tp_avp_challenge_response_init(&resp, tunnel, avp))
{
case IPL2TP_STATUS_OK:
ipl2tp_avp_set_challenge_response(c, &resp);
break;
case IPL2TP_STATUS_IGNORE:
break;
default:
ipl2tp_message_delete(c);
return IPL2TP_STATUS_ERROR;
}
IPL2TP_SAFE_FREE(resp.array);
ipl2tp_trpt_control_output(c);
}
return IPL2TP_STATUS_OK;
}
/*
*===========================================================================
* ipl2tp_v2_message_stopccn
*===========================================================================
* Description: Create and send a StopCCN message.
* Parameters: tunnel - The tunnel.
* session - The session (NULL)
* avp - AVP (NULL)
* Returns:
*
*/
IP_STATIC Ipl2tp_status
ipl2tp_v2_message_stopccn(Ipl2tp_tunnel *tunnel,
Ipl2tp_session *session,
Ipl2tp_avp *avp)
{
IPL2TP_UNUSED(session);
IPL2TP_UNUSED(avp);
if (tunnel->state != IPL2TP_TSTATE_TEARDOWN)
{
Ipl2tp_message *c = ipl2tp_message_new(tunnel, IP_NULL);
if (c != IP_NULL)
{
/* Prepare message */
ipl2tp_avp_set_message_type(c, IPL2TP_MSG_StopCCN);
ipl2tp_avp_set_assigned_tunnel_id(c, tunnel->local.key.ident);
ipl2tp_avp_set_result_code(c,
tunnel->last_result.result_code,
tunnel->last_result.error_code,
tunnel->last_result.error_message);
/* Purge output queue to be sure the StopCCN is sent */
ipl2tp_state_tunnel_flush(tunnel);
ipl2tp_trpt_control_output(c);
}
}
return IPL2TP_STATUS_OK;
}
/*
*===========================================================================
* ipl2tp_v2_message_hello
*===========================================================================
* Description: Create and send a HELLO message.
* Parameters: tunnel - Pointer to tunnel descriptor.
* session - Session (NULL)
* avp - The AVP (NULL)
* Returns:
*
*/
IP_STATIC Ipl2tp_status
ipl2tp_v2_message_hello(Ipl2tp_tunnel *tunnel,
Ipl2tp_session *session,
Ipl2tp_avp *avp)
{
Ipl2tp_message *c = ipl2tp_message_new(tunnel, IP_NULL);
IPL2TP_UNUSED(avp);
IPL2TP_UNUSED(session);
if (c != IP_NULL)
{
ipl2tp_avp_set_message_type(c, IPL2TP_MSG_HELLO);
ipl2tp_trpt_control_output(c);
}
return IPL2TP_STATUS_OK;
}
/*
*===========================================================================
* ipl2tp_v2_message_icrq
*===========================================================================
* Description: Create and send an ICRQ message.
* Parameters: tunnel - The tunnel
* session - Pointer to session descriptor.
* avp - AVP (NULL)
* Returns:
*
*/
IP_STATIC Ipl2tp_status
ipl2tp_v2_message_icrq(Ipl2tp_tunnel *tunnel,
Ipl2tp_session *session,
Ipl2tp_avp *avp)
{
Ipl2tp_message *c = ipl2tp_message_new(tunnel,session);
IPL2TP_UNUSED(avp);
if (c != IP_NULL)
{
/* Prepare message */
ipl2tp_avp_set_message_type(c, IPL2TP_MSG_ICRQ);
ipl2tp_avp_set_assigned_session_id(c, session->local.key.ident);
ipl2tp_avp_set_call_serial_number(c, session->common.call_serial_number);
if (session->attr.bearer_type != 0)
{
ipl2tp_avp_set_bearer_type(c, session->attr.bearer_type);
}
if (session->attr.calling_number != IP_NULL)
{
ipl2tp_avp_set_calling_number(c, session->attr.calling_number);
}
if (session->attr.called_number != IP_NULL)
{
ipl2tp_avp_set_called_number(c, session->attr.called_number);
}
if (session->attr.phys_chan_id != 0)
{
ipl2tp_avp_set_physical_channel_id(c, session->attr.phys_chan_id);
}
if (session->attr.sub_address != IP_NULL)
{
ipl2tp_avp_set_sub_address(c, session->attr.sub_address);
}
ipl2tp_trpt_control_output(c);
}
return IPL2TP_STATUS_OK;
}
/*
*===========================================================================
* ipl2tp_v2_message_icrp
*===========================================================================
* Description: Create and send an ICRP message.
* Parameters: tunnel - The tunnel
* session - Pointer to session descriptor.
* avp - AVP (NULL)
* Returns:
*
*/
IP_STATIC Ipl2tp_status
ipl2tp_v2_message_icrp(Ipl2tp_tunnel *tunnel,
Ipl2tp_session *session,
Ipl2tp_avp *avp)
{
Ipl2tp_message *c = ipl2tp_message_new(tunnel,session);
IPL2TP_UNUSED(avp);
if (c != IP_NULL)
{
/* Prepare message */
ipl2tp_avp_set_message_type(c, IPL2TP_MSG_ICRP);
ipl2tp_avp_set_assigned_session_id(c, session->local.key.ident);
ipl2tp_trpt_control_output(c);
}
return IPL2TP_STATUS_OK;
}
/*
*===========================================================================
* ipl2tp_v2_message_iccn
*===========================================================================
* Description: Create and send an ICCN message.
* Parameters: tunnel - The tunnel
* session - Pointer to session descriptor.
* avp - AVP (NULL)
* Returns:
*
*/
IP_STATIC Ipl2tp_status
ipl2tp_v2_message_iccn(Ipl2tp_tunnel *tunnel,
Ipl2tp_session *session,
Ipl2tp_avp *avp)
{
Ipl2tp_message *c = ipl2tp_message_new(tunnel,session);
IPL2TP_UNUSED(avp);
if (c != IP_NULL)
{
/* Prepare message */
ipl2tp_avp_set_message_type(c, IPL2TP_MSG_ICCN);
ipl2tp_avp_set_tx_connect_speed(c, session->attr.tx_connect_speed);
ipl2tp_avp_set_framing_type(c, session->attr.framing_type);
if (session->attr.rx_connect_speed != 0)
{
ipl2tp_avp_set_rx_connect_speed(c, session->attr.rx_connect_speed);
}
if (session->attr.private_group_id != IP_NULL)
{
ipl2tp_avp_set_private_group_id(c, session->attr.private_group_id);
}
if (session->tunnel->attr.sequencing == IPL2TP_MIB_ALWAYS)
{
ipl2tp_avp_set_sequencing_required(c);
}
if (session->attr.first_received_confreq.size != 0)
{
ipl2tp_avp_set_initial_received_lcp_confreq(c,
&session->attr.first_received_confreq);
}
if (session->attr.last_received_confreq.size != 0)
{
ipl2tp_avp_set_last_received_lcp_confreq(c,
&session->attr.last_received_confreq);
}
else if (session->attr.first_received_confreq.size != 0)
{
/* If single CONFREQ, last == first */
ipl2tp_avp_set_last_received_lcp_confreq(c,
&session->attr.first_received_confreq);
}
if (session->attr.last_sent_confreq.size != 0)
{
ipl2tp_avp_set_last_sent_lcp_confreq(c,
&session->attr.last_sent_confreq);
}
if (session->attr.auth_method != 0)
{
ipl2tp_avp_set_proxy_authen_type(c, session->attr.auth_method);
}
if (session->attr.proxy_authen_name != IP_NULL)
{
ipl2tp_avp_set_proxy_authen_name(c, session->attr.proxy_authen_name);
}
if (session->attr.proxy_authen_challenge.size != 0)
{
ipl2tp_avp_set_proxy_authen_challenge(c,
&session->attr.proxy_authen_challenge);
}
if (session->attr.proxy_authen_id != 0)
{
ipl2tp_avp_set_proxy_authen_id(c, session->attr.proxy_authen_id);
}
if (session->attr.proxy_authen_response.size != 0)
{
ipl2tp_avp_set_proxy_authen_response(c,
&session->attr.proxy_authen_response);
}
ipl2tp_trpt_control_output(c);
}
return IPL2TP_STATUS_OK;
}
/*
*===========================================================================
* ipl2tp_v2_message_ocrq
*===========================================================================
* Description: Create and send an OCRQ message.
* Parameters: tunnel - The tunnel
* session - Pointer to session descriptor.
* avp - AVP (NULL)
* Returns:
*
*/
IP_STATIC Ipl2tp_status
ipl2tp_v2_message_ocrq(Ipl2tp_tunnel *tunnel,
Ipl2tp_session *session,
Ipl2tp_avp *avp)
{
Ipl2tp_message *c = ipl2tp_message_new(tunnel,session);
IPL2TP_UNUSED(avp);
if (c != IP_NULL)
{
/* Prepare message */
ipl2tp_avp_set_message_type(c, IPL2TP_MSG_OCRQ);
ipl2tp_avp_set_assigned_session_id(c, session->local.key.ident);
ipl2tp_avp_set_call_serial_number(c, session->common.call_serial_number);
ipl2tp_avp_set_minimum_bps(c, session->attr.minimum_bps);
ipl2tp_avp_set_maximum_bps(c, session->attr.maximum_bps);
ipl2tp_avp_set_framing_type(c, session->attr.framing_type);
if (session->attr.bearer_type != 0)
{
ipl2tp_avp_set_bearer_type(c, session->attr.bearer_type);
}
if (session->attr.called_number != IP_NULL)
{
ipl2tp_avp_set_called_number(c, session->attr.called_number);
}
if (session->attr.sub_address != IP_NULL)
{
ipl2tp_avp_set_sub_address(c, session->attr.sub_address);
}
ipl2tp_trpt_control_output(c);
}
return IPL2TP_STATUS_OK;
}
/*
*===========================================================================
* ipl2tp_v2_message_ocrp
*===========================================================================
* Description: Create and send an OCRP message.
* Parameters: tunnel - The tunnel
* session - Pointer to session descriptor.
* avp - AVP (NULL)
* Returns:
*
*/
IP_STATIC Ipl2tp_status
ipl2tp_v2_message_ocrp(Ipl2tp_tunnel *tunnel,
Ipl2tp_session *session,
Ipl2tp_avp *avp)
{
Ipl2tp_message *c = ipl2tp_message_new(tunnel,session);
IPL2TP_UNUSED(avp);
if (c != IP_NULL)
{
/* Prepare message */
ipl2tp_avp_set_message_type(c, IPL2TP_MSG_OCRP);
ipl2tp_avp_set_assigned_session_id(c, session->local.key.ident);
if (session->attr.phys_chan_id != 0)
{
ipl2tp_avp_set_physical_channel_id(c, session->attr.phys_chan_id);
}
ipl2tp_trpt_control_output(c);
}
return IPL2TP_STATUS_OK;
}
/*
*===========================================================================
* ipl2tp_v2_message_occn
*===========================================================================
* Description: Create and send an OCCN message.
* Parameters:
* Returns:
*
*/
IP_STATIC Ipl2tp_status
ipl2tp_v2_message_occn(Ipl2tp_tunnel *tunnel,
Ipl2tp_session *session,
Ipl2tp_avp *avp)
{
Ipl2tp_message *c = ipl2tp_message_new(tunnel,session);
IPL2TP_UNUSED(avp);
if (c != IP_NULL)
{
/* Prepare message */
ipl2tp_avp_set_message_type(c, IPL2TP_MSG_OCCN);
ipl2tp_avp_set_tx_connect_speed(c, session->attr.tx_connect_speed);
ipl2tp_avp_set_framing_type(c, session->attr.framing_type);
if (session->attr.rx_connect_speed != 0)
{
ipl2tp_avp_set_rx_connect_speed(c, session->attr.rx_connect_speed);
}
if (session->tunnel->attr.sequencing == IPL2TP_MIB_ALWAYS)
{
ipl2tp_avp_set_sequencing_required(c);
}
ipl2tp_trpt_control_output(c);
}
return IPL2TP_STATUS_OK;
}
/*
*===========================================================================
* ipl2tp_v2_message_cdn
*===========================================================================
* Description: Create and send a CDN message.
* Parameters:
* Returns:
*
*/
IP_STATIC Ipl2tp_status
ipl2tp_v2_message_cdn(Ipl2tp_tunnel *tunnel,
Ipl2tp_session *session,
Ipl2tp_avp *avp)
{
IPL2TP_UNUSED(avp);
if (session->state != IPL2TP_SSTATE_WAIT_TUNNEL)
{
Ipl2tp_message *c = ipl2tp_message_new(tunnel,session);
IPL2TP_UNUSED(avp);
if (c != IP_NULL)
{
/* Prepare message */
ipl2tp_avp_set_message_type(c, IPL2TP_MSG_CDN);
ipl2tp_avp_set_assigned_session_id(c, session->local.key.ident);
ipl2tp_avp_set_result_code(c,
tunnel->last_result.result_code,
tunnel->last_result.error_code,
tunnel->last_result.error_message);
ipl2tp_trpt_control_output(c);
}
}
return IPL2TP_STATUS_OK;
}
/*
*===========================================================================
* ipl2tp_v2_message_zlb
*===========================================================================
* Description: Create and send a ZLB message.
* Parameters:
* Returns:
*
*/
IP_STATIC Ipl2tp_status
ipl2tp_v2_message_zlb(Ipl2tp_tunnel *tunnel,
Ipl2tp_session *session,
Ipl2tp_avp *avp)
{
Ipl2tp_message *c = ipl2tp_message_new(tunnel, IP_NULL);
IPL2TP_UNUSED(session);
IPL2TP_UNUSED(avp);
if (c != IP_NULL)
{
ipl2tp_message_is_zlb(c);
ipl2tp_trpt_control_output(c);
tunnel->statistics.control_zlb_sent++;
}
return IPL2TP_STATUS_OK;
}
/*
****************************************************************************
* 10 GLOBAL FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipl2tp_v2_message_sccrq
*===========================================================================
* Description: Create and send an SCCRQ message.
* Parameters: tunnel - Pointer to tunnel descriptor.
* session - The session (NULL)
* avp - AVP (NULL)
* Returns:
*
*/
IP_GLOBAL Ipl2tp_status
ipl2tp_v2_message_sccrq_avps(Ipl2tp_tunnel *tunnel,
Ipl2tp_message *c)
{
/* Compulsory part */
ipl2tp_avp_set_protocol_version(c);
ipl2tp_avp_set_framing_capabilities(c, tunnel->attr.framing_capabilities);
ipl2tp_avp_set_assigned_tunnel_id(c, tunnel->local.key.ident);
/* Optional part */
if (tunnel->attr.bearer_capabilities != 0)
{
ipl2tp_avp_set_bearer_capabilities(c,
tunnel->attr.bearer_capabilities);
}
if (tunnel->attr.receive_window_size != IPL2TP_RECEIVE_WINDOW_SIZE)
{
ipl2tp_avp_set_receive_window_size(c,
tunnel->attr.receive_window_size);
}
/* Generate challenge if applicable */
if (tunnel->attr.authentication == IPL2TP_MIB_AUTH_CHALLENGE)
{
Ip_u8 cvalue[IPL2TP_MAX_CHALLENGE_LENGTH];
Ipl2tp_vector vec;
vec.array = cvalue;
vec.size = IPL2TP_MAX_CHALLENGE_LENGTH;
ipl2tp_avp_challenge_init(&vec, tunnel, IPL2TP_MSG_SCCRQ);
ipl2tp_avp_set_challenge(c, &vec);
}
ipl2tp_avp_set_firmware_revision(c, IPL2TP_VERSION_NUM);
return IPL2TP_STATUS_OK;
}
/*
****************************************************************************
* 11 PUBLIC FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,84 @@
/*
******************************************************************************
* HEADER FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp_v2_message.h,v $ $Revision: 1.2 $
* $Source: /home/interpeak/CVSRoot/ipl2tp/src/ipl2tp_v2_message.h,v $
* $Author: joel $ $Date: 2006-01-30 10:47:46 $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelius@interpeak.se>
******************************************************************************
*/
#ifndef IPL2TP_V2_MESSAGE_H
#define IPL2TP_V2_MESSAGE_H
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 FUNCTIONS
****************************************************************************
*/
extern Ipl2tp_message_func ipl2tp_v2_messages[IPL2TP_MSG_MAX];
/*
*===========================================================================
* ipl2tp_v2_message_sccrq
*===========================================================================
* Description: Create and send an SCCRQ message.
* Parameters: tunnel - Pointer to tunnel descriptor.
* session - The session (NULL)
* avp - AVP (NULL)
* Returns:
*
*/
IP_GLOBAL Ipl2tp_status ipl2tp_v2_message_sccrq_avps(Ipl2tp_tunnel *tunnel,
Ipl2tp_message *c);
#ifdef __cplusplus
}
#endif
#endif
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,217 @@
/*
******************************************************************************
* INTERPEAK SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp_v2_pw.c,v $ $Revision: 1.5.16.1 $
* $Source: /home/interpeak/CVSRoot/ipl2tp/src/ipl2tp_v2_pw.c,v $
* $Author: jren $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelis@interpeak.se>
******************************************************************************
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#include "ipl2tp_h.h"
#include "ipl2tp_api.h"
#include "ipl2tp_avp.h"
#include "ipl2tp_data.h"
#include "ipl2tp_message.h"
#include "ipl2tp_state.h"
#include "ipl2tp_pseudowire.h"
#include "ipl2tp_trpt.h"
#include "ipl2tp_v2.h"
#include "ipl2tp_v2_state.h"
#include "ipl2tp_v2_pw.h"
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
/*
****************************************************************************
* 9 STATIC FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* 10 GLOBAL FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipl2tp_v2_pw_ppp_input
*===========================================================================
* Description: Feed an incoming PPP packet to the IPL2TP engine.
* Parameters: session - The session which the packet belongs to.
* buffer - PPP packet.
* length - Length of PPP packet.
* offset - Number of bytes before 'buffer' that may be used.
* align - Alignment requirement for output buffer.
* Returns: IPL2TP_STATUS_OK if success.
* IPL2TP_STATUS_BADID if invalid session ID.
*/
IP_GLOBAL Ipl2tp_status
ipl2tp_v2_pw_ppp_input(Ipl2tp_session *session,
void *buffer,
int length,
int offset,
int align)
{
Ipl2tp_tunnel *tunnel = session->tunnel;
Ipl2tp_v2_umessage *message;
int rhsize = 8;
int hsize;
Ip_u16 flv;
struct Ip_iovec iov[2];
int iov_len = 0;
char hdr[32];
/* Sequencing required? */
if (session->v.v2.sequencing != 0)
{
rhsize += 4;
}
/* Remember min header size */
hsize = rhsize;
/* Check alignment */
#ifdef IPL2TP_V2_STRICT_HEADER_ALIGNMENT
if ((((int)buffer - hsize) % align) != 0)
{
hsize += 2;
hsize += (((int)buffer - hsize) % align);
}
#endif
/* Header fits in allocated offset? */
if (hsize > offset)
{
iov[iov_len].iov_base = hdr;
iov[iov_len].iov_len = hsize;
iov_len++;
iov[iov_len].iov_base = buffer;
iov[iov_len].iov_len = length;
iov_len++;
message = (Ipl2tp_v2_umessage *) hdr;
}
else
{
Ip_u8 *frame = buffer;
message = (Ipl2tp_v2_umessage *)(frame - hsize);
iov[iov_len].iov_base = message;
iov[iov_len].iov_len = length + hsize;
iov_len++;
}
/* Enter header fields */
flv = IPL2TP_HEADER_FLAG_LENGTH;
flv |= IPL2TP_VERSION_L2TPV2;
IP_SET_HTONS(&message->len_seq.length, (hsize + length));
IP_SET_HTONS(&message->len_seq.tunnel_id, ((Ip_u16) (tunnel->remote.key.ident)));
IP_SET_HTONS(&message->len_seq.session_id, ((Ip_u16) (session->remote.key.ident)));
/* Enter sequence number */
if (session->v.v2.sequencing != 0)
{
Ip_u16 seq = session->v.v2.ns++;
flv |= IPL2TP_HEADER_FLAG_SEQUENCE;
IP_SET_HTONS(&message->len_seq.ns, seq);
message->len_seq.nr = 0;
}
#ifdef IPL2TP_V2_STRICT_HEADER_ALIGNMENT
/* Enter offset */
if (hsize != rhsize)
{
flv |= IPL2TP_HEADER_FLAG_OFFSET;
if (session->v.v2.sequencing == 0)
{
IP_SET_HTONS(&message->len_off.offset,
hsize - sizeof(message->len_off));
}
else
{
IP_SET_HTONS(&message->len_seq_off.offset,
hsize - sizeof(message->len_seq_off));
}
}
#endif
IP_SET_HTONS(&message->len_seq.flv, flv);
ipl2tp_trpt_data_output(tunnel,
iov,
iov_len);
return IPL2TP_STATUS_OK;
}
/*
****************************************************************************
* 11 PUBLIC FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,88 @@
/*
******************************************************************************
* HEADER FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp_v2_pw.h,v $ $Revision: 1.2 $
* $Source: /home/interpeak/CVSRoot/ipl2tp/src/ipl2tp_v2_pw.h,v $
* $Author: joel $ $Date: 2006-01-30 10:47:46 $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelius@interpeak.se>
******************************************************************************
*/
#ifndef IPL2TP_V2_PW_H
#define IPL2TP_V2_PW_H
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipl2tp_v2_pw_ppp_input
*===========================================================================
* Description: Feed an incoming PPP packet to the IPL2TP engine.
* Parameters: session - The session which the packet belongs to.
* buffer - PPP packet.
* length - Length of PPP packet.
* offset - Number of bytes before 'buffer' that may be used.
* align - Alignment requirement for output buffer.
* Returns: IPL2TP_STATUS_OK if success.
* IPL2TP_STATUS_BADID if invalid session ID.
*/
IP_GLOBAL Ipl2tp_status ipl2tp_v2_pw_ppp_input(Ipl2tp_session *session,
void *buffer,
int length,
int offset,
int align);
#ifdef __cplusplus
}
#endif
#endif
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,93 @@
/*
******************************************************************************
* HEADER FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp_v2_state.h,v $ $Revision: 1.2 $
* $Source: /home/interpeak/CVSRoot/ipl2tp/src/ipl2tp_v2_state.h,v $
* $Author: joel $ $Date: 2006-01-30 10:47:47 $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelius@interpeak.se>
******************************************************************************
*/
#ifndef IPL2TP_V2_STATE_H
#define IPL2TP_V2_STATE_H
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipl2tp_v2_state_machine_sccrq
*===========================================================================
* Description: Handle an incoming IPL2TP message according to state.
* Parameters: tunnel - Tunnel descriptor.
* Returns: IPL2TP_SUCCESS - Success.
*
*/
IP_GLOBAL Ipl2tp_status ipl2tp_v2_state_machine_sccrq(Ipl2tp_tunnel *tunnel);
/*
*===========================================================================
* ipl2tp_v2_state_control_input
*===========================================================================
* Description: Handle an incoming L2TP control packet.
* Parameters: packet - An L2TP packet.
* ipaddr - IP address of sender.
* Returns: IPL2TP_SUCCESS - Success.
*
*/
IP_GLOBAL Ipl2tp_status ipl2tp_v2_state_control_input(Ipl2tp_v2_header *message,
Ip_u16 length,
union Ip_sockaddr_union *addr);
#ifdef __cplusplus
}
#endif
#endif
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,630 @@
/*
******************************************************************************
* INTERPEAK SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp_v3.c,v $ $Revision: 1.6.12.3 $
* $Source: /home/interpeak/CVSRoot/ipl2tp/src/ipl2tp_v3.c,v $
* $Author: jren $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelis@interpeak.se>
******************************************************************************
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#include "ipl2tp_h.h"
#include "ipl2tp_api.h"
#include "ipl2tp_avp.h"
#include "ipl2tp_attr_h.h"
#include "ipl2tp_data.h"
#include "ipl2tp_message.h"
#include "ipl2tp_state.h"
#include "ipl2tp_pseudowire.h"
#include "ipl2tp_trpt.h"
#include "ipl2tp_v3.h"
#include "ipl2tp_v3_state.h"
#include "ipl2tp_v3_message.h"
#include "ipl2tp_v3_pw.h"
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
IP_STATIC void
ipl2tp_v3_tunnel_message_init(Ipl2tp_message *container);
IP_STATIC void
ipl2tp_v3_tunnel_message_digest(Ipl2tp_message *container);
IP_STATIC void
ipl2tp_v3_tunnel_message_log(Ipl2tp_message *container,
const char *kind);
IP_STATIC void
ipl2tp_v3_tunnel_assign_peer_id(Ipl2tp_tunnel *tunnel,
Ipl2tp_avp *avp);
IP_STATIC void
ipl2tp_v3_tunnel_done(Ipl2tp_tunnel *tunnel);
IP_STATIC void
ipl2tp_v3_tunnel_session_init(Ipl2tp_session *session);
IP_STATIC void
ipl2tp_v3_tunnel_session_done(Ipl2tp_session *session);
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
static Ipl2tp_tunnel_table ipl2tp_v3_table =
{
ipl2tp_v3_tunnel_message_init,
ipl2tp_v3_tunnel_message_log,
ipl2tp_v3_tunnel_message_digest,
ipl2tp_v3_tunnel_assign_peer_id,
ipl2tp_v3_state_machine_sccrq,
ipl2tp_v3_tunnel_done,
ipl2tp_v3_tunnel_session_init,
ipl2tp_v3_tunnel_session_done,
ipl2tp_v3_messages
};
/*
****************************************************************************
* 9 STATIC FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipl2tp_v3_next_tunnel_id
*===========================================================================
* Description: Find next available tunnel identifier
* Parameters:
* Returns: The next usable tunnel id for v3
*
*/
IP_STATIC Ip_u32
ipl2tp_v3_next_tunnel_id(void)
{
Ipl2tp_key key;
Ip_u32 loops;
/* */
key.version = IPL2TP_VERSION_L2TPV3;
/* Don't loop more than 64K */
for (loops = 0; loops < 0xffff; loops++)
{
/* Do not use value 0 */
if (++ipl2tp.tunnel.v3.ident == 0)
++ipl2tp.tunnel.v3.ident;
/* Set the key */
key.ident = ipl2tp.tunnel.v3.ident;
/* Does it exist already? */
if (ipcom_hash_get(ipl2tp.tunnel.hash_id, &key) == IP_NULL)
return key.ident;
}
/* Could not locate a new value */
return 0;
}
/*
*===========================================================================
* ipl2tp_v3_next_session_id
*===========================================================================
* Description: Find next available session identifier
* Parameters:
* Returns: The next usable session id for that particular version.
*
*/
IP_STATIC Ip_u32
ipl2tp_v3_next_session_id(void)
{
Ipl2tp_key key;
Ip_u32 loops;
key.version = IPL2TP_VERSION_L2TPV3;
/* Don't loop more than 64K */
for (loops = 0; loops < 0xffff; loops++)
{
if (++ipl2tp.session.v3.ident == 0)
ipl2tp.session.v3.ident++;
key.ident = ipl2tp.session.v3.ident;
/* Does it exist already? */
if (ipcom_hash_get(ipl2tp.session.hash_id, &key) == IP_NULL)
return key.ident;
}
/* Could not locate a new value */
return 0;
}
/*
*===========================================================================
* ipl2tp_v3_tunnel_message_init
*===========================================================================
* Description: Initialize a V3 container.
* Parameters: message - The container
* Returns:
*
*/
IP_STATIC void
ipl2tp_v3_tunnel_message_init(Ipl2tp_message *container)
{
Ipl2tp_tunnel *tunnel = container->admin.tunnel;
Ipl2tp_v3_header *header = IPL2TP_V3_HEADER(container);
ipcom_memset(header, 0, sizeof(*header));
if (tunnel->slave)
{
/* The T,L and S flags MUST be set. */
IP_SET_HTONS(&header->flv,
(IPL2TP_HEADER_FLAG_CONTROL |
IPL2TP_HEADER_FLAG_LENGTH |
IPL2TP_HEADER_FLAG_SEQUENCE |
IPL2TP_VERSION_L2TPV2));;
}
else
{
/* The T,L and S flags MUST be set. */
IP_SET_HTONS(&header->flv,
(IPL2TP_HEADER_FLAG_CONTROL |
IPL2TP_HEADER_FLAG_LENGTH |
IPL2TP_HEADER_FLAG_SEQUENCE |
IPL2TP_VERSION_L2TPV3));;
}
/* Set the correct values */
IP_SET_HTONS(&header->length, sizeof(Ipl2tp_v3_header));
IP_SET_HTONL(&header->tunnel_id, tunnel->remote.key.ident);
/* Initialize the digest */
container->admin.digest = IP_NULL;
/* Store the offsets to the NR/NS pair */
container->admin.nr = &header->nr;
container->admin.ns = &header->ns;
/* Store the offset to the pkt start/header length */
container->admin.start = (Ip_u8 *)header;
container->admin.length = &header->length;
container->admin.pre_header = 0;
/* Set initial size */
container->admin.size = sizeof(Ipl2tp_v3_header);
if (tunnel->attr.transport == IPL2TP_ATTR_TRANSPORT_IP)
{
container->admin.pre_header += 4;
container->admin.size += 4;
container->admin.start -= 4;
/* Initialize to zero */
IP_SET_HTONL(container->admin.start, 0);
}
}
/*
*===========================================================================
* ipl2tp_v3_tunnel_message_digest
*===========================================================================
* Description: Calculate a digest
* Parameters: message - The container.
* Returns:
*
*/
IP_STATIC void
ipl2tp_v3_tunnel_message_digest(Ipl2tp_message *container)
{
Ipl2tp_tunnel *tunnel = container->admin.tunnel;
if (container->admin.digest)
{
/**/
switch (tunnel->attr.hmac)
{
case IPL2TP_MIB_AUTH_MD5:
ipl2tp_avp_hmac_md5_digest(tunnel,
container->admin.start + container->admin.pre_header,
container->admin.size - container->admin.pre_header,
&tunnel->local.nonce,
&tunnel->remote.nonce,
container->admin.digest);
break;
case IPL2TP_MIB_AUTH_SHA:
ipl2tp_avp_hmac_sha_digest(tunnel,
container->admin.start + container->admin.pre_header,
container->admin.size - container->admin.pre_header,
&tunnel->local.nonce,
&tunnel->remote.nonce,
container->admin.digest);
break;
}
}
}
/*
*===========================================================================
* ipl2tp_v3_tunnel_message_log
*===========================================================================
* Description: Log a v3 container message
* Parameters:
* Returns:
*
*/
IP_STATIC void
ipl2tp_v3_tunnel_message_log(Ipl2tp_message *container,
const char *kind)
{
/* Send it to the log function */
ipl2tp_v3_dlog_packet(&container->admin.tunnel->remote.addr,
IPL2TP_V3_HEADER(container),
kind);
}
/*
*===========================================================================
* ipl2tp_v3_tunnel_assign_peer_id
*===========================================================================
* Description: Assign peer ID.
* Parameters:
* Returns:
*
*/
IP_STATIC void
ipl2tp_v3_tunnel_assign_peer_id(Ipl2tp_tunnel *tunnel,
Ipl2tp_avp *avp)
{
/* Try remove */
ipcom_hash_remove(ipl2tp.tunnel.hash_remote_id, tunnel);
/* set the tunnel ID */
tunnel->remote.key.ident = avp->assigned_control_connection_id.value;
/* Insert it into the hash table */
ipcom_hash_add(ipl2tp.tunnel.hash_remote_id, tunnel);
}
/*
*===========================================================================
* ipl2tp_v3_tunnel_done
*===========================================================================
* Description: Cleans up the version specific attributes of the
* tunnel.
* Parameters: tunnel - Tunnel.
* Returns:
*
*/
IP_STATIC void
ipl2tp_v3_tunnel_done(Ipl2tp_tunnel *tunnel)
{
IPL2TP_SAFE_FREE(tunnel->v.v3.pseudo_wires.array);
IPL2TP_SAFE_FREE(tunnel->v.v3.msg_digest_shared_key.array);
IPL2TP_SAFE_FREE(tunnel->v.v3.hide_avp_shared_key.array);
IPL2TP_SAFE_FREE(tunnel->v.v3.preferred_language);
/* Remove it from the v3 list */
ipcom_list_remove(&tunnel->head);
/* Down the count */
ipl2tp.tunnel.v3.total--;
}
/*
*===========================================================================
* ipl2tp_v3_tunnel_session_init
*===========================================================================
* Description: Initialize the version specific attributes of the
* session.
* Parameters: session - Session.
* Returns:
*
*/
IP_STATIC void
ipl2tp_v3_tunnel_session_init(Ipl2tp_session *session)
{
session->local.key.ident = ipl2tp_v3_next_session_id();
/* Copy global attributes */
ipl2tp_attr_session_attribute_copy(&session->attr,
&ipl2tp.session.v3.attr);
session->local.key.version = IPL2TP_VERSION_L2TPV3;
session->remote.key.version = IPL2TP_VERSION_L2TPV3;
/* Initialize to down */
session->v.v3.circuit_status = IPL2TP_MIB_DOWN;
ipl2tp.session.v3.total++;
}
/*
*===========================================================================
* ipl2tp_v3_tunnel_session_done
*===========================================================================
* Description: Cleans up the version specific attributes of the
* session.
* Parameters: sesion - Session.
* Returns:
*
*/
IP_STATIC void
ipl2tp_v3_tunnel_session_done(Ipl2tp_session *session)
{
IPL2TP_UNUSED(session);
ipl2tp.session.v3.total--;
}
/*
****************************************************************************
* 10 GLOBAL FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipl2tp_v3_l2tp_ip_input
*===========================================================================
* Description: Feed an incoming IP encap L2TP packet to the L2TPv3 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 - The transport
* 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_GLOBAL Ipl2tp_status
ipl2tp_v3_l2tp_input(void *buffer,
void *payload,
Ip_u16 length,
union Ip_sockaddr_union *addr,
int transport)
{
Ipl2tp_status status;
Ipl2tp_key key;
Ip_u8 *data;
Ipl2tp_session *session;
Ip_u16 stat_len = length;
key.version = IPL2TP_VERSION_L2TPV3;
if (transport == IPL2TP_ATTR_TRANSPORT_UDP)
{
/* Determine whether it's a control packet or a session packet */
Ipl2tp_v3_udp *header = payload;
Ip_u16 flags = IP_GET_NTOHS(&header->flv);
/* Is the header flag control bit set? */
if (IP_BIT_ISSET(flags, IPL2TP_HEADER_FLAG_CONTROL))
{
/* Feed it to the control function */
status = ipl2tp_v3_state_control_input(payload,
length,
addr,
transport);
return status;
}
else
{
data = (Ip_u8 *) header + 8;
key.ident = IP_GET_NTOHL(&header->session_id);
/* Remove the header */
length -= 8;
}
}
else
{
data = payload;
key.ident = IP_GET_NTOHL(data);
/* Move past the session identifier */
data += 4;
length -= 4;
/* The basic control session ID */
if (key.ident == 0)
{
/* Feed it to the control function */
status = ipl2tp_v3_state_control_input((void *)data,
length,
addr,
transport);
return status;
}
}
session = ipl2tp_state_session_get(&key, data);
/* Valid session? */
if (session == IP_NULL ||
session->state != IPL2TP_SSTATE_ESTABLISHED)
{
IPCOM_LOG3(WARNING,
"%s(%s): Got data message with invalid session ID: %d",
ipl2tp_versions[IPL2TP_VERSION_L2TPV3],
ipl2tp_util_ntoa(addr),
(int) key.ident);
status = IPL2TP_STATUS_BADID;
}
else
{
if (session->tunnel != IP_NULL)
{
session->tunnel->statistics.in_octets += stat_len;
session->tunnel->statistics.in_packets++;
}
/* Move past the cookie */
data += session->local.cookie.size;
/* Remove the cookie */
length -= session->local.cookie.size;
/* Do feed it to the data input */
status = ipl2tp_v3_pw_session_data(buffer,
session,
data,
length);
if (status != IPL2TP_STATUS_OK && session->tunnel != IP_NULL)
session->tunnel->statistics.in_errors++;
}
return status;
}
/*
*===========================================================================
* ipl2tp_v3_tunnel_init
*===========================================================================
* Description: Initialize the version specific attributes of the
* tunnel.
* Parameters: tunnel - Tunnel.
* Returns:
*
*/
IP_GLOBAL void
ipl2tp_v3_tunnel_init(Ipl2tp_tunnel *tunnel)
{
/* Initialize the callback table */
tunnel->table = &ipl2tp_v3_table;
/* Store the version used */
tunnel->local.key.version = IPL2TP_VERSION_L2TPV3;
/* Grab next available v2 tunnel identifier */
tunnel->local.key.ident = ipl2tp_v3_next_tunnel_id();
/* Store remote version key */
tunnel->remote.key.version = IPL2TP_VERSION_L2TPV3;
/* Insert it into the V3 tunnel list */
ipcom_list_insert_first(&ipl2tp.tunnel.v3.tunnels, &tunnel->head);
/* Copy global attributes */
ipl2tp_attr_tunnel_attribute_copy(&tunnel->attr,
&ipl2tp.tunnel.v3.attr);
/* Up the count. */
ipl2tp.tunnel.v3.total++;
}
/*
*===========================================================================
* ipl2tp_v3_dlog_packet
*===========================================================================
* Description: Do log the packet.
* Parameters: peer - The remote end.
* header - The packet header.
* kind - Description of the event.
* Returns:
*
*/
IP_GLOBAL void
ipl2tp_v3_dlog_packet(union Ip_sockaddr_union *peer,
Ipl2tp_v3_header *header,
CONST char *kind)
{
Ip_u16 size = IP_GET_NTOHS(&header->length);
Ip_u16 mindex = sizeof(*header);
Ip_u16 mtype = 0;
if (size > mindex)
{
/* Get message type (assume message type AVP is first) */
Ip_u16 *m16 = (Ip_u16 *)header;
mtype = IP_GET_NTOHS(&m16[mindex / 2 + 3]);
}
IPCOM_LOG8(DEBUG,
"%s(%s): %s %s control packet; T:%d Ns:%d Nr:%d L:%d",
ipl2tp_versions[IPL2TP_VERSION_L2TPV3],
ipl2tp_util_ntoa(peer),
kind,
ipl2tp_message_name(mtype),
IP_GET_NTOHL(&header->tunnel_id),
IP_GET_NTOHS(&header->ns),
IP_GET_NTOHS(&header->nr),
size);
}
/*
****************************************************************************
* 11 PUBLIC FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,150 @@
/*
******************************************************************************
* HEADER FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp_v3.h,v $ $Revision: 1.2 $
* $Source: /home/interpeak/CVSRoot/ipl2tp/src/ipl2tp_v3.h,v $
* $Author: joel $ $Date: 2006-01-30 10:47:47 $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelius@interpeak.se>
******************************************************************************
*/
#ifndef IPL2TP_V3_H
#define IPL2TP_V3_H
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
#define IPL2TP_V3_HEADER(c) (&((c)->header.v3))
#define IPL2TP_V3_ZLB(l,t) \
((l) <= sizeof(Ipl2tp_v3_header) || (t) == IPL2TP_MSG_ACK)
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/* Control version */
typedef struct Ipl2tp_v3_header
{
Ip_u16 flv; /* Flags & Version */
Ip_u16 length; /* Length of message */
Ip_u32 tunnel_id; /* 32 bit control connection ID */
Ip_u16 ns; /* Sequence number */
Ip_u16 nr; /* Next expected sequence number */
}
Ipl2tp_v3_header;
/* L2TPv3 over UDP */
typedef struct Ipl2tp_v3_udp
{
Ip_u16 flv; /* Flags & Version */
Ip_u16 __reserved; /* Reserved */
Ip_u32 session_id; /* 32 bit session ID */
/* Cookie */
}
Ipl2tp_v3_udp;
/*
****************************************************************************
* 6 FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipl2tp_v3_l2tp_ip_input
*===========================================================================
* Description: Feed an incoming IP encap L2TP packet to the L2TPv3 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
* 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_GLOBAL Ipl2tp_status ipl2tp_v3_l2tp_input(void *buffer,
void *payload,
Ip_u16 length,
union Ip_sockaddr_union *addr,
int transport);
/*
*===========================================================================
* ipl2tp_v3_tunnel_init
*===========================================================================
* Description: Initialize the version specific attributes of the
* tunnel.
* Parameters: tunnel - Tunnel.
* Returns:
*
*/
IP_GLOBAL void ipl2tp_v3_tunnel_init(Ipl2tp_tunnel *tunnel);
/*
*===========================================================================
* ipl2tp_v3_dlog_packet
*===========================================================================
* Description: Do log the packet.
* Parameters: peer - The remote end.
* header - The packet header.
* kind - Description of the event.
* Returns:
*
*/
IP_GLOBAL void ipl2tp_v3_dlog_packet(union Ip_sockaddr_union *peer,
Ipl2tp_v3_header *header,
CONST char *kind);
#ifdef __cplusplus
}
#endif
#endif
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,69 @@
/*
******************************************************************************
* HEADER FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp_v3_message.h,v $ $Revision: 1.2 $
* $Source: /home/interpeak/CVSRoot/ipl2tp/src/ipl2tp_v3_message.h,v $
* $Author: joel $ $Date: 2006-01-30 10:47:47 $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelius@interpeak.se>
******************************************************************************
*/
#ifndef IPL2TP_V3_MESSAGE_H
#define IPL2TP_V3_MESSAGE_H
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 FUNCTIONS
****************************************************************************
*/
extern Ipl2tp_message_func ipl2tp_v3_messages[IPL2TP_MSG_MAX];
#ifdef __cplusplus
}
#endif
#endif
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,472 @@
/*
******************************************************************************
* INTERPEAK SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp_v3_pw.c,v $ $Revision: 1.6.12.1 $
* $Source: /home/interpeak/CVSRoot/ipl2tp/src/ipl2tp_v3_pw.c,v $
* $Author: jren $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelis@interpeak.se>
******************************************************************************
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#include "ipl2tp_h.h"
#include "ipl2tp_api.h"
#include "ipl2tp_avp.h"
#include "ipl2tp_data.h"
#include "ipl2tp_message.h"
#include "ipl2tp_state.h"
#include "ipl2tp_pseudowire.h"
#include "ipl2tp_trpt.h"
#include "ipl2tp_v3.h"
#include "ipl2tp_v3_state.h"
#include "ipl2tp_v3_pw.h"
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/* L2 sequence valid flag */
#define IPL2TP_V3_DS_L2_DEFAULT_SEQ_FLAG 0x40000000
#define IPL2TP_V3_DS_L2_DEFAULT_SEQ_MASK 0x00ffffff
#define IPL2TP_V3_DS_L2_DEFAULT_LTE 0x007fffff
#define IPL2TP_V3_PW_L2_SEQUENCE_MISS_OUT_OF_WINDOW 0
#define IPL2TP_V3_PW_L2_SEQUENCE_MISS_DUPLICATE 1
#define IPL2TP_V3_PW_L2_SEQUENCE_MATCH_IN_WINDOW 2
#define IPL2TP_V3_PW_L2_SEQUENCE_MATCH_EXPECTED 3
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
/*
****************************************************************************
* 9 STATIC FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipl2tp_v3_pw_header
*===========================================================================
* Description: Create the pseudowire header, including data sequencing.
* Parameters: session - The session
* buf - The buffer
* is_ip - Is it IP?
* Returns: The size of the header.
*
*/
IP_STATIC Ip_size_t
ipl2tp_v3_pw_header(Ipl2tp_session *session,
Ip_u8 *buf,
Ip_bool is_ip)
{
Ip_size_t res = 0;
if (session->tunnel->attr.transport == IPL2TP_ATTR_TRANSPORT_UDP)
{
/* No flags set */
IP_SET_HTONS(&buf[res], IPL2TP_VERSION_L2TPV3);
res += 2;
/* Reserved field should be zero */
IP_SET_HTONS(&buf[res], 0);
res += 2;
}
/* Set session identifier */
IP_SET_HTONL(&buf[res], session->remote.key.ident);
res += 4;
/* If there's a cookie, set it */
if (session->remote.cookie.size)
{
ipcom_memcpy(&buf[res],
session->remote.cookie.array,
session->remote.cookie.size);
res += session->remote.cookie.size;
}
/* Deal with sequencing */
if (session->attr.data_sequencing != IPL2TP_ATTR_DATA_SEQUENCING_NEVER)
{
/* Only know how to deal with sublayer default */
if (session->attr.l2_sublayer == IPL2TP_ATTR_L2_SUBLAYER_DEFAULT)
{
Ip_u32 seq = 0;
/* Either always, or non ip */
if (session->attr.data_sequencing == IPL2TP_ATTR_DATA_SEQUENCING_ALWAYS ||
is_ip == IP_FALSE)
{
seq = session->v.v3.dataseq.l2.dfl.next_seq++;
/* Wrap if we go above the 24 bits we have available */
if (session->v.v3.dataseq.l2.dfl.next_seq > IPL2TP_V3_DS_L2_DEFAULT_SEQ_MASK)
session->v.v3.dataseq.l2.dfl.next_seq = 0;
seq |= IPL2TP_V3_DS_L2_DEFAULT_SEQ_FLAG;
}
IP_SET_HTONL(&buf[res], seq);
res += 4;
}
}
return res;
}
/*
*===========================================================================
* ipl2tp_v3_pw_l2_sequence
*===========================================================================
* Description: Calculate the 'flattened' difference between
* the sequence numbers.
* Parameters: first - First received packet for this sequencing
* current - The current sequence number
* last - Last received sequence number
* window - Window size.
* Returns: The difference.
*
*/
IP_STATIC int
ipl2tp_v3_pw_l2_sequence(Ip_bool first,
Ip_u32 current,
Ip_u32 last,
Ip_u32 window)
{
Ip_u32 top;
Ip_u32 diff;
top = current;
if (top < last)
top += window;
/* Get the total difference in the 'flattened' seq nr space */
diff = top - last;
IPCOM_LOG5(ERR,
"window: %u, first = %u, current = %u, last = %u, diff = %u",
window, first, current, last, diff);
/* Wraparound? */
if (diff > window / 2)
/* Outside the window, LE */
return IPL2TP_V3_PW_L2_SEQUENCE_MISS_OUT_OF_WINDOW;
else if (diff == 0 && first == IP_FALSE)
/* Equal to previous received sequenced packet */
return IPL2TP_V3_PW_L2_SEQUENCE_MISS_DUPLICATE;
else if (diff > 1)
/* Within the window but out of order */
return IPL2TP_V3_PW_L2_SEQUENCE_MATCH_IN_WINDOW;
/* Perfect frame */
return IPL2TP_V3_PW_L2_SEQUENCE_MATCH_EXPECTED;
}
/*
****************************************************************************
* 10 GLOBAL FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipl2tp_v3_pw_ethernet_input
*===========================================================================
* Description: Feed an incoming Ethernet packet to the IPL2TP engine.
* Parameters: session - The session which the packet belongs to.
* buffer - The ethernet frame
* length - Length of ethernet frame.
* offset - Number of bytes before 'buffer' that may be used.
* align - Alignment requirement for output buffer.
* is_ip - Is this an IP packet?
* Returns: IPL2TP_STATUS_OK if success.
* IPL2TP_STATUS_BADID if invalid session ID.
*/
IP_GLOBAL Ipl2tp_status
ipl2tp_v3_pw_ethernet_input(Ipl2tp_session *session,
void *buffer,
int length,
int offset,
int align,
Ip_bool is_ip)
{
Ipl2tp_tunnel *tunnel = session->tunnel;
struct Ip_iovec vec[2];
Ip_u8 hdr[4 + 4 + 4 + 8]; /* Max transport header */
Ip_size_t hsize;
Ip_u8 *frame = buffer;
int iovlen = 0;
/**/
IPL2TP_UNUSED(align);
hsize = ipl2tp_v3_pw_header(session, hdr, is_ip);
/* Can we just append the header? */
if ((Ip_size_t)offset >= hsize)
{
frame -= hsize;
length += hsize;
/* Copy in the header */
ipcom_memcpy(frame, hdr, hsize);
/* Store it in the io vector */
vec[iovlen].iov_base = frame;
vec[iovlen].iov_len = length;
iovlen++;
}
else
{
/* Vector them up */
vec[iovlen].iov_base = hdr;
vec[iovlen].iov_len = hsize;
iovlen++;
vec[iovlen].iov_base = frame;
vec[iovlen].iov_len = length;
iovlen++;
}
/* And transmit */
ipl2tp_trpt_data_output(tunnel,
vec,
iovlen);
return IPL2TP_STATUS_OK;
}
/*
*===========================================================================
* ipl2tp_v3_pw_session_data
*===========================================================================
* Description: Feed the incoming data to the proper callback.
* Parameters: buffer - Original buffer
* session - The session in question.
* data - The data we're looking at
* size - Size of the data
* Returns: The status.
*
*/
IP_GLOBAL Ipl2tp_status
ipl2tp_v3_pw_session_data(void *buffer,
Ipl2tp_session *session,
Ip_u8 *data,
Ip_size_t size)
{
/* Data sequencing? */
if (session->attr.data_sequencing)
{
/* Which sublayer are we using? */
if (session->attr.l2_sublayer == IPL2TP_ATTR_L2_SUBLAYER_DEFAULT)
{
Ip_u32 ds = IP_GET_NTOHL(data);
/* Remove the sublayer */
data += 4;
size -= 4;
/* Is there a valid sequence number*/
if (IP_BIT_ISSET(ds, IPL2TP_V3_DS_L2_DEFAULT_SEQ_FLAG))
{
int type;
/* Remove the flags */
ds &= IPL2TP_V3_DS_L2_DEFAULT_SEQ_MASK;
/* The number of sequence numbers we have 'above' our
* last received one */
type = ipl2tp_v3_pw_l2_sequence(session->v.v3.dataseq.received == 0,
ds,
session->v.v3.dataseq.l2.dfl.match_last,
IPL2TP_V3_DS_L2_DEFAULT_SEQ_MASK);
/* Duplicate; just abort */
if (type == IPL2TP_V3_PW_L2_SEQUENCE_MISS_DUPLICATE)
{
if (session->tunnel != IP_NULL)
IPCOM_LOG4(DEBUG,
"%s(%d,%d,%s): Duplicate session level data frame.",
ipl2tp_versions[IPL2TP_VERSION_L2TPV3],
(int)session->tunnel->local.key.ident,
(int)session->local.key.ident,
ipl2tp_util_ntoa(&session->tunnel->remote.addr));
return IPL2TP_STATUS_IGNORE;
}
/* We're out of window */
if (type == IPL2TP_V3_PW_L2_SEQUENCE_MISS_OUT_OF_WINDOW)
{
if (session->tunnel != IP_NULL)
IPCOM_LOG4(DEBUG,
"%s(%d,%d,%s): Out of window session level data frame.",
ipl2tp_versions[IPL2TP_VERSION_L2TPV3],
(int)session->tunnel->local.key.ident,
(int)session->local.key.ident,
ipl2tp_util_ntoa(&session->tunnel->remote.addr));
/* Deal with out of order */
if (session->v.v3.dataseq.l2.dfl.miss_in_sequence == 0)
{
session->v.v3.dataseq.l2.dfl.miss_last = ds;
session->v.v3.dataseq.l2.dfl.miss_in_sequence = 1;
return IPL2TP_STATUS_IGNORE;
}
else
{
int oorder = ipl2tp_v3_pw_l2_sequence(IP_FALSE,
ds,
session->v.v3.dataseq.l2.dfl.miss_last,
IPL2TP_V3_DS_L2_DEFAULT_SEQ_MASK);
/* If its not in order, reset out of order counter */
if (oorder != IPL2TP_V3_PW_L2_SEQUENCE_MATCH_EXPECTED)
{
session->v.v3.dataseq.l2.dfl.miss_last = ds;
session->v.v3.dataseq.l2.dfl.miss_in_sequence = 1;
return IPL2TP_STATUS_IGNORE;
}
/* Reset if we have this many L2 sequence number in line misses */
if (++session->v.v3.dataseq.l2.dfl.miss_in_sequence < session->attr.l2_out_of_order_reset)
{
session->v.v3.dataseq.l2.dfl.miss_last = ds;
return IPL2TP_STATUS_IGNORE;
}
if (session->tunnel != IP_NULL)
IPCOM_LOG4(DEBUG,
"%s(%d,%d,%s): Out of window session level data frame -- too many misses, resetting sequence.",
ipl2tp_versions[IPL2TP_VERSION_L2TPV3],
(int)session->tunnel->local.key.ident,
(int)session->local.key.ident,
ipl2tp_util_ntoa(&session->tunnel->remote.addr));
}
}
/* Either EXPECTED or IN_WINDOW; just accept both */
if (type == IPL2TP_V3_PW_L2_SEQUENCE_MATCH_IN_WINDOW)
{
if (session->tunnel != IP_NULL)
IPCOM_LOG4(DEBUG,
"%s(%d,%d,%s): In window session level data frame",
ipl2tp_versions[IPL2TP_VERSION_L2TPV3],
(int)session->tunnel->local.key.ident,
(int)session->local.key.ident,
ipl2tp_util_ntoa(&session->tunnel->remote.addr));
}
if (type == IPL2TP_V3_PW_L2_SEQUENCE_MATCH_EXPECTED)
{
if (session->tunnel != IP_NULL)
IPCOM_LOG4(DEBUG,
"%s(%d,%d,%s): In sequence session level data frame",
ipl2tp_versions[IPL2TP_VERSION_L2TPV3],
(int)session->tunnel->local.key.ident,
(int)session->local.key.ident,
ipl2tp_util_ntoa(&session->tunnel->remote.addr));
}
/* Feed this message; it's a match */
session->v.v3.dataseq.l2.dfl.match_last = ds;
session->v.v3.dataseq.l2.dfl.miss_in_sequence = 0;
session->v.v3.dataseq.received++;
}
}
}
if (session->tunnel != IP_NULL)
IPCOM_LOG4(DEBUG,
"%s(%d,%d,%s): Session data received",
ipl2tp_versions[IPL2TP_VERSION_L2TPV3],
(int)session->tunnel->local.key.ident,
(int)session->local.key.ident,
ipl2tp_util_ntoa(&session->tunnel->remote.addr));
if (session->attr.circuit_status != IPL2TP_MIB_UP ||
session->v.v3.circuit_status != IPL2TP_MIB_UP)
{
if (session->tunnel != IP_NULL)
IPCOM_LOG4(INFO,
"%s(%d,%d,%s): Session circuit is not currently up, frame discarded",
ipl2tp_versions[IPL2TP_VERSION_L2TPV3],
(int)session->tunnel->local.key.ident,
(int)session->local.key.ident,
ipl2tp_util_ntoa(&session->tunnel->remote.addr));
return IPL2TP_STATUS_CIRCUIT_DOWN;
}
/* Send to user interface */
IPL2TP_SAFE_CALLBACK(session->attr.dcallback,
(session->attr.user_data,
&session->local.key,
buffer,
data,
(Ip_u16)size));
/* Do process */
return IPL2TP_STATUS_OK;
}
/*
****************************************************************************
* 11 PUBLIC FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,109 @@
/*
******************************************************************************
* HEADER FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp_v3_pw.h,v $ $Revision: 1.2 $
* $Source: /home/interpeak/CVSRoot/ipl2tp/src/ipl2tp_v3_pw.h,v $
* $Author: joel $ $Date: 2006-01-30 10:47:47 $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelius@interpeak.se>
******************************************************************************
*/
#ifndef IPL2TP_V3_PW_H
#define IPL2TP_V3_PW_H
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipl2tp_v3_pw_ethernet_input
*===========================================================================
* Description: Feed an incoming Ethernet packet to the IPL2TP engine.
* Parameters: session - The session which the packet belongs to.
* buffer - The ethernet frame
* length - Length of ethernet frame.
* offset - Number of bytes before 'buffer' that may be used.
* align - Alignment requirement for output buffer.
* is_ip - Is this an IP packet?
* Returns: IPL2TP_STATUS_OK if success.
* IPL2TP_STATUS_BADID if invalid session ID.
*/
IP_GLOBAL Ipl2tp_status
ipl2tp_v3_pw_ethernet_input(Ipl2tp_session *session,
void *buffer,
int length,
int offset,
int align,
Ip_bool is_ip);
/*
*===========================================================================
* ipl2tp_v3_pw_session_data
*===========================================================================
* Description: Feed the incoming data to the proper callback.
* Parameters: buffer - Original buffer
* session - The session in question.
* data - The data we're looking at
* size - Size of the data
* Returns: The status.
*
*/
IP_GLOBAL Ipl2tp_status ipl2tp_v3_pw_session_data(void *buffer,
Ipl2tp_session *session,
Ip_u8 *data,
Ip_size_t size);
#ifdef __cplusplus
}
#endif
#endif
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,98 @@
/*
******************************************************************************
* HEADER FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp_v3_state.h,v $ $Revision: 1.2 $
* $Source: /home/interpeak/CVSRoot/ipl2tp/src/ipl2tp_v3_state.h,v $
* $Author: joel $ $Date: 2006-01-30 10:47:47 $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelius@interpeak.se>
******************************************************************************
*/
#ifndef IPL2TP_V3_STATE_H
#define IPL2TP_V3_STATE_H
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipl2tp_v3_state_machine_sccrq
*===========================================================================
* Description: Handle an incoming IPL2TP SCCRQ according to state.
* Parameters: tunnel - Tunnel descriptor.
* Returns: IPL2TP_SUCCESS - Success.
*
*/
IP_GLOBAL Ipl2tp_status ipl2tp_v3_state_machine_sccrq(Ipl2tp_tunnel *tunnel);
/*
*===========================================================================
* ipl2tp_v3_state_control_input
*===========================================================================
* Description: Handle an incoming L2TP control packet.
* Parameters: packet - An L2TP packet.
* ipaddr - IP address of sender.
* transport - The transport used
* Returns: IPL2TP_SUCCESS - Success.
*
*/
IP_GLOBAL Ipl2tp_status ipl2tp_v3_state_control_input(Ipl2tp_v3_header *header,
Ip_u16 length,
union Ip_sockaddr_union *addr,
int transport);
#ifdef __cplusplus
}
#endif
#endif
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/