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,48 @@
/* 00comp_ipnet_l2tp.cdf - IPNet L2TP configuration file */
/*
* Copyright (c) 2009 Wind River Systems, Inc.
*
* The right to copy, distribute or otherwise make use of this software
* may be licensed only pursuant to the terms of an applicable Wind River
* license agreement. No license to Wind River intellectual property rights
* is granted herein. All rights not licensed by Wind River are reserved
* by Wind River.
*/
/*
modification history
--------------------
01a,18jun09,ten created.
*/
Component INCLUDE_IPL2TP {
NAME L2TP
SYNOPSIS L2TP
MODULES ipl2tp_api.o
CONFIGLETTES ipl2tp_config.c ipl2tp_example.c
CFG_PARAMS L2TP_VERSION_2_ENABLE \
L2TP_VERSION_3_ENABLE \
L2TP_HOST_NAME
}
Parameter L2TP_VERSION_2_ENABLE {
NAME Enable L2TP Version 2
SYNOPSIS Enables L2TP protocol version 2
TYPE BOOL
DEFAULT FALSE
}
Parameter L2TP_VERSION_3_ENABLE {
NAME Enable L2TP Version 3
SYNOPSIS Enables L2TP protocol version 3
TYPE BOOL
DEFAULT TRUE
}
Parameter L2TP_HOST_NAME {
NAME L2TP Host Name
SYSNOPSIS Name of local L2TP host
TYPE char *
DEFAULT "LAC"
}
@@ -0,0 +1,11 @@
# Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: common.vxconfig,v $ $Revision: 1.3 $
# $Source: /home/interpeak/CVSRoot/ipl2tp/config/common.vxconfig,v $
# $Author: myakan $
# $State: Exp $ $Locker: $
#
# INTERPEAK_COPYRIGHT_STRING
#hidden option that enables IPL2TP
config SUPPORTS_L2TP
bool
default y
@@ -0,0 +1,128 @@
/*
******************************************************************************
* INTERPEAK CONFIGURATION SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp_config.c,v $ $Revision: 1.4 $
* $Source: /home/interpeak/CVSRoot/ipl2tp/config/ipl2tp_config.c,v $
* $Author: joel $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
*
******************************************************************************
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 INCLUDE FILES
****************************************************************************
*/
#include <ipcom_type.h>
#include <ipcom_cstyle.h>
#include <ipcom_err.h>
#include <ipcom_shell.h>
#include <ipcom_sysvar.h>
#include <ipl2tp.h>
#include <ipl2tp_cmd.h>
/*
****************************************************************************
* 3 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 4 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 5 EXTERN PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 LOCAL PROTOTYPES
****************************************************************************
*/
IP_PUBLIC Ip_err ipl2tp_configure(void);
/*
****************************************************************************
* 7 DATA
****************************************************************************
*/
IP_STATIC IP_CONST Ipcom_sysvar ipl2tp_conf_sysvar[] =
{
{ "ipl2tp.v3.control.any.attributes", "secret=interop local_router_id=0" },
{ "ipl2tp.v3.circuit.0.name", "mycircuit" },
{ "ipl2tp.v3.circuit.0.interface", "eth0" },
{ "ipl2tp.v3.circuit.0.vlan", "21" },
{ "ipl2tp.v3.circuit.0.attributes", "pseudowire_type=ethernet_vlan data_sequencing=0" },
/* End of configuration - DO NOT REMOVE! */
{ IP_NULL, IP_NULL }
};
/*
****************************************************************************
* 8 STATIC FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* 9 GLOBAL FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* 10 PUBLIC FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipl2tp_configure
*===========================================================================
* Description: Configure FTP server.
* Parameters:
* Returns:
*
*/
IP_PUBLIC Ip_err
ipl2tp_configure(void)
{
/* Add the sysvars */
ipcom_sysvar_setv(ipl2tp_conf_sysvar, 0);
/* Init shell commands */
(void)ipcom_shell_add_cmd("l2tp", "l2tp <command> <parameters>",
"L2TP client control",
ipl2tp_cmd_main,
IPCOM_SHELL_PRIO_SAME,
IPCOM_PROC_STACK_DEFAULT);
return IPCOM_SUCCESS;
}
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,146 @@
/*
******************************************************************************
* SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp_config.h,v $ $Revision: 1.6 $
* $Source: /home/interpeak/CVSRoot/ipl2tp/config/ipl2tp_config.h,v $
* $Author: tneale $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
*
******************************************************************************
*/
#ifndef _IPL2TP_CONFIG_H_
#define _IPL2TP_CONFIG_H_
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*
* L2TP configuration file.
*/
/*
****************************************************************************
* 2 INCLUDE FILES
****************************************************************************
*/
/*
****************************************************************************
* 3 GENERAL
****************************************************************************
*/
/*
*===========================================================================
* IPL2TP_SYSLOG_PRIORITY
*===========================================================================
* Initial L2TP syslog system priority.
*/
#ifdef IP_DEBUG
#define IPL2TP_SYSLOG_PRIORITY IPCOM_LOG_DEBUG
#else
#define IPL2TP_SYSLOG_PRIORITY IPCOM_LOG_WARNING
#endif
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/* Version */
#define IPL2TP_VERSION_NUM 160
#define IPL2TP_VERSION_STR "6.0.0"
#define IPL2TP_VERSION_API 4
/* Protocol version */
#define IPL2TP_PROTOCOL_VER 1
#define IPL2TP_PROTOCOL_REV 0
/* Host name */
#define IPL2TP_VENDOR_NAME "WindRiver"
#define IPL2TP_HOST_NAME "IPL2TP"
/* Default receive window size */
#define IPL2TP_RECEIVE_WINDOW_SIZE 4
/* Max no of retransmissions */
#define IPL2TP_MAX_RETRANSMIT 5
/* Seconds until first retransmission */
#define IPL2TP_FIRST_RETRANSMIT_SEC 1
/* Max seconds between retransmissions */
#define IPL2TP_MAX_BACKOFF_SEC 8
/* Seconds to keep a tunnel after StopCCN is received */
#define IPL2TP_TUNNEL_ZOMBIE_SEC 32
/* Seconds between HELLO messages */
#define IPL2TP_HELLO_INTERVAL_SEC 60
/* Seconds between HELLO ticks (resolution of HELLO transmission) */
#define IPL2TP_HELLO_TICK_SEC 10
/* Tunnel establishment timeout */
#define IPL2TP_ESTABLISH_TIMEOUT_SEC 60
/* Force a single session per tunnel */
#define IPL2TP_OPEN_EXCLUSIVE IPL2TP_MIB_NO
/* Run-time log level */
#define IPL2TP_RUNTIME_LOGLEVEL IPL2TP_LOGLEVEL_ALL
/* Max size of control message sent by us */
#define IPL2TP_MAX_MESSAGE_SIZE 2048
/* Max size of error message */
#define IPL2TP_MAX_ERROR_MESSAGE_SIZE 256
/* Min and max length of CHAP challenges */
#define IPL2TP_MIN_CHALLENGE_LENGTH 16
#define IPL2TP_MAX_CHALLENGE_LENGTH 16
/* Max size of host name */
#define IPL2TP_MAX_HOST_NAME_SIZE 64
/* Max size of fixed AVP value */
#define IPL2TP_MAX_AVP_VALUE_SIZE (32 - 6) /* 'call errors' is 32 octets */
/* Size of sent data headers */
#define IPL2TP_DATA_HEADER_SIZE 12
#define IPL2TP_MISALIGNED_DATA_HEADER_SIZE 14
/* No of preallocated descriptors */
#define IPL2TP_PREALLOCATED_TUNNEL_NO 100
#define IPL2TP_PREALLOCATED_SESSION_NO 100
/* Max numbers */
#define IPL2TP_TUNNEL_MAX 8192
#define IPL2TP_SESSION_MAX 8192
/* Initial size of attribute pool */
#define IPL2TP_ATTRPOOL_SIZE 8
/* Max attribute type in an AVP */
#define IPL2TP_AVP_MAX 75
/* Number of in-sequence out of window data messages before we reset
* the sequence counter */
#define IPL2TP_L2_OUT_OF_ORDER_RESET 10
/* Use mutex */
#define IPL2TP_USE_MUTEX 1
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,97 @@
/*
******************************************************************************
* HEADER FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp_example.h,v $ $Revision: 1.3 $
* $Source: /home/interpeak/CVSRoot/ipl2tp/config/ipl2tp_example.h,v $
* $Author: tneale $ $Date: 2010-05-13 21:15:09 $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelius@interpeak.se>
******************************************************************************
*/
#ifndef IPL2TP_EXAMPLE_H
#define IPL2TP_EXAMPLE_H
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
struct Ipl2tp_example_fd_entry;
typedef void (*Ipl2tp_example_data_cb)
(
struct Ipl2tp_example_fd_entry *entry,
void *buffer,
void *data,
Ip_size_t size
);
typedef struct Ipl2tp_example_fd_entry
{
Ipcom_list next;
Ip_fd fd;
void *ptr;
Ipl2tp_example_data_cb data;
}
Ipl2tp_example_fd_entry_t;
typedef struct Ipl2tp_example_session
{
Ipl2tp_key key;
void *circuit;
}
Ipl2tp_example_session_t;
extern Ipcom_hash *ipl2tp_example_sessions;
extern Ipcom_list ipl2tp_example_fds;
extern char ipl2tp_poke_abort[4];
/*
****************************************************************************
* 6 FUNCTIONS
****************************************************************************
*/
#ifdef __cplusplus
}
#endif
#endif
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,372 @@
/*
******************************************************************************
* INTERPEAK SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp_example_v2.c,v $ $Revision: 1.6 $
* $Source: /home/interpeak/CVSRoot/ipl2tp/config/ipl2tp_example_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
****************************************************************************
*/
#define IPCOM_USE_CLIB_PROTO
#include "ipcom_clib.h"
#include "ipcom_clib2.h"
#include "ipcom_err.h"
#include "ipcom_ipd.h"
#include "ipcom_os.h"
#include "ipcom_shell.h"
#include "ipcom_sock2.h"
#include "ipcom_syslog.h"
#include "ipcom_type.h"
#include "ipcom_hash.h"
#include "ipcom_sysvar.h"
#include "ipcom_netif.h"
#include "ipl2tp_h.h"
#include "ipl2tp_api.h"
#include "ipl2tp_api_tunnel.h"
#include "ipl2tp_api_session.h"
#include "ipl2tp_attr.h"
#include "ipl2tp_cmd.h"
#include "ipl2tp_example.h"
#include "ipl2tp_example_v2.h"
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
/*
****************************************************************************
* 9 STATIC FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* 10 GLOBAL FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipl2tp_example_tstatus_v2
*===========================================================================
* Description: Tunnel status callback.
* Parameters: user_data - User callback data.
* key - Tunnel ID.
* status - Pointer to status info.
* Returns:
*
*/
IP_GLOBAL int
ipl2tp_example_tstatus_v2(void *user_data,
Ipl2tp_key *key,
Ipl2tp_result *result)
{
#define A_AUTH IPL2TP_MIB_AUTH_NONE
#define A_SECRET "interop"
#define A_NAME "hel"
(void)user_data;
switch (result->status)
{
case IPL2TP_STATUS_OK:
switch (result->result_code)
{
case IPL2TP_OUTGOING_AUTHENTICATION:
{
/* Allocate an attribute object */
Ipl2tp_attrobj attr = IP_NULL;
Ipl2tp_attrobj replies = IP_NULL;
ipl2tp_attr_add_query(&attr,
IPL2TP_TATTR_GET_l2tpTunnelStatsRemoteHostName);
/* Retrieve the attributes, the answers will end up in 'replies' */
ipl2tp_api_tunnel_attribute_get(key, attr, &replies);
IPCOM_LOG3(DEBUG,
"IPL2TPv2: TUNNEL (IPL2TP_OUTGOING_AUTHENTICATION) v%d %d requested by '%s'",
key->version, key->ident,
ipl2tp_attr_strdata(ipl2tp_attr_first(replies)));
ipl2tp_attr_delete(&replies);
/* Add integer attribute */
ipl2tp_attr_clear(attr);
/* Set authentication */
if (ipl2tp_attr_iappend(&attr,
IPL2TP_TATTR_SET_l2tpTunnelConfigAuthentication, A_AUTH) != IPL2TP_STATUS_OK ||
/* Add string peer host name */
ipl2tp_attr_strappend(&attr, IPL2TP_TATTR_SET_PEER_HOST_NAME, A_NAME) != IPL2TP_STATUS_OK ||
/* Add authentication vector */
ipl2tp_attr_vappend(&attr,
IPL2TP_TATTR_SET_l2tpTunnelConfigSecret,
A_SECRET, (int)ipcom_strlen(A_SECRET)) != IPL2TP_STATUS_OK)
{
IPCOM_LOG3(WARNING,
"IPL2TPv2: v%d %d requested by '%s': unable to set attributes",
key->version, key->ident,
ipl2tp_attr_strdata(ipl2tp_attr_first(replies)));
}
else
{
/* Do set the attributes */
ipl2tp_api_tunnel_attribute_set(key, attr);
}
/* Delete the attribute object */
ipl2tp_attr_delete(&attr);
if (ipcom_strcmp(ipl2tp_poke_abort, "toa") == 0)
return 1;
/* We've installed the authentication data required,
* do continue the tunnel processing and attempt to establish */
ipl2tp_api_tunnel_authentication_established(key);
break;
}
case IPL2TP_OUTGOING_REQUEST:
{
Ipl2tp_attrobj replies = IP_NULL;
Ipl2tp_attrobj attr = IP_NULL;
ipl2tp_attr_add_query(&attr,
IPL2TP_TATTR_GET_l2tpTunnelStatsRemoteHostName);
/* Retrieve the attributes, the answers will end up in 'replies' */
ipl2tp_api_tunnel_attribute_get(key, attr, &replies);
IPCOM_LOG3(DEBUG,
"IPL2TPv2: TUNNEL (IPL2TP_OUTGOING_REQUEST) v%d %d requested by '%s'",
key->version, key->ident,
ipl2tp_attr_strdata(ipl2tp_attr_first(replies)));
ipl2tp_attr_delete(&replies);
ipl2tp_attr_delete(&attr);
if (ipcom_strcmp(ipl2tp_poke_abort, "tor") == 0)
return 1;
break;
}
case IPL2TP_OUTGOING_ESTABLISHED:
IPCOM_LOG2(DEBUG,
"IPL2TPv2: TUNNEL (IPL2TP_OUTGOING_ESTABLISHED) v%d %d opened",
key->version, key->ident);
if (ipcom_strcmp(ipl2tp_poke_abort, "toe") == 0)
return 1;
break;
case IPL2TP_INCOMING_ESTABLISHED:
IPCOM_LOG2(DEBUG,
"IPL2TPv2: TUNNEL (IPL2TP_INCOMING_ESTABLISHED) v%d %d opened",
key->version, key->ident);
if (ipcom_strcmp(ipl2tp_poke_abort, "tie") == 0)
return 1;
break;
}
break;
case IPL2TP_STATUS_NEGOTIATION:
IPCOM_LOG2(DEBUG,
"IPL2TPv2: TUNNEL (IPL2TP_STATUS_NEGOTIATION) v%d %d closed obsoleted by version negotiation",
key->version, key->ident);
break;
default:
IPCOM_LOG5(DEBUG,
"IPL2TPv2: TUNNEL (%u) v%d %d closed with status %d, %s",
result->status,
key->version, key->ident,
(int)result->status,
ipl2tp_api_errname(result->status));
break;
}
return 0;
}
/*
*===========================================================================
* ipl2tp_example_sstatus_v2
*===========================================================================
* Description: Session status callback.
* Parameters: user_data - User callback data.
* key - Session ID.
* status - Pointer to status info.
* Returns:
*
*/
IP_GLOBAL int
ipl2tp_example_sstatus_v2(void *user_data,
Ipl2tp_key *key,
Ipl2tp_result *result)
{
unsigned long ifindexul = (unsigned long)user_data;
int ifindex = (int)ifindexul;
int ret = 1;
(void)ifindex;
switch (result->status)
{
case IPL2TP_STATUS_OK:
switch (result->result_code)
{
case IPL2TP_OUTGOING_REQUEST:
{
Ipl2tp_attrobj replies = IP_NULL;
ipl2tp_api_session_attribute_query(key,
IPL2TP_SATTR_GET_CALLED_NUMBER,
&replies);
IPCOM_LOG4(DEBUG,
"IPL2TPv2: SESSION (IPL2TP_OUTGOING_REQUEST) v%d %d %s to '%s'",
key->version, key->ident,
ipl2tp_api_session_type(key),
ipl2tp_attr_strdata(ipl2tp_attr_first(replies)));
ipl2tp_attr_delete(&replies);
if (ipcom_strcmp(ipl2tp_poke_abort, "sor") == 0)
goto leave;
break;
}
case IPL2TP_OUTGOING_REPLY:
{
Ipl2tp_attrobj attr = IP_NULL;
IPCOM_LOG3(DEBUG,
"IPL2TPv2: SESSION (IPL2TP_OUTGOING_REPLY) v%d %d %s",
key->version, key->ident,
ipl2tp_api_session_type(key));
if (ipl2tp_attr_iappend(&attr,
IPL2TP_SATTR_SET_TX_CONNECT_SPEED,
38400) != IPL2TP_STATUS_OK ||
ipl2tp_attr_iappend(&attr,
IPL2TP_SATTR_SET_FRAMING_TYPE,
IPL2TP_MIB_FRAMING_ASYNC) != IPL2TP_STATUS_OK)
{
IPCOM_LOG3(WARNING,
"IPL2TPv2: SESSION (IPL2TP_OUTGOING_REPLY) v%d %d %s unable to set attributes",
key->version, key->ident,
ipl2tp_api_session_type(key));
}
else
{
ipl2tp_api_session_attribute_set(key, attr);
}
ipl2tp_attr_delete(&attr);
if (ipcom_strcmp(ipl2tp_poke_abort, "sop") == 0)
goto leave;
ipl2tp_api_session_outgoing_established(key, 0, 0, "");
break;
}
case IPL2TP_OUTGOING_ESTABLISHED:
IPCOM_LOG3(DEBUG,
"IPL2TPv2: SESSION (IPL2TP_OUTGOING_ESTABLISHED) v%d %d %s",
key->version, key->ident,
ipl2tp_api_session_type(key));
if (ipcom_strcmp(ipl2tp_poke_abort, "soe") == 0)
goto leave;
break;
case IPL2TP_INCOMING_REQUEST:
/* Setup */
IPCOM_LOG3(DEBUG,
"IPL2TPv2: SESSION (IPL2TP_INCOMING_REQUEST) v%d %d %s",
key->version, key->ident,
ipl2tp_api_session_type(key));
ipl2tp_api_session_incoming_established(key, 0, 0, "");
break;
case IPL2TP_INCOMING_ESTABLISHED:
IPCOM_LOG3(DEBUG,
"IPL2TPv2: SESSION (IPL2TP_INCOMING_ESTABLISHED) v%d %d %s",
key->version, key->ident,
ipl2tp_api_session_type(key));
if (ipcom_strcmp(ipl2tp_poke_abort, "sie") == 0)
goto leave;
break;
}
break;
default:
IPCOM_LOG4(DEBUG,
"IPL2TPv2: SESSION (%u) v%d %d closed with status %s",
(int)result->status,
key->version, key->ident,
ipl2tp_api_errname(result->status));
break;
}
ret = 0;
leave:
return ret;
}
/*
****************************************************************************
* 11 PUBLIC FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,100 @@
/*
******************************************************************************
* HEADER FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp_example_v2.h,v $ $Revision: 1.2 $
* $Source: /home/interpeak/CVSRoot/ipl2tp/config/ipl2tp_example_v2.h,v $
* $Author: joel $ $Date: 2006-01-30 10:46:59 $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelius@interpeak.se>
******************************************************************************
*/
#ifndef IPL2TP_EXAMPLE_V2_H
#define IPL2TP_EXAMPLE_V2_H
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipl2tp_example_sstatus_v3
*===========================================================================
* Description: Session status callback.
* Parameters: user_data - User callback data.
* key - Session ID.
* status - Pointer to status info.
* Returns:
*
*/
IP_GLOBAL int ipl2tp_example_sstatus_v2(void *user_data,
Ipl2tp_key *key,
Ipl2tp_result *result);
/*
*===========================================================================
* ipl2tp_example_tstatus_v3
*===========================================================================
* Description: Tunnel status callback.
* Parameters: user_data - User callback data.
* key - Tunnel ID.
* status - Pointer to status info.
* Returns:
*
*/
IP_GLOBAL int ipl2tp_example_tstatus_v2(void *user_data,
Ipl2tp_key *key,
Ipl2tp_result *result);
#ifdef __cplusplus
}
#endif
#endif
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,974 @@
/*
******************************************************************************
* INTERPEAK SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp_example_v3.c,v $ $Revision: 1.13.10.4 $
* $Source: /home/interpeak/CVSRoot/ipl2tp/config/ipl2tp_example_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
****************************************************************************
*/
#define IPCOM_USE_CLIB_PROTO
#include "ipcom_clib.h"
#include "ipcom_clib2.h"
#include "ipcom_err.h"
#include "ipcom_ipd.h"
#include "ipcom_os.h"
#include "ipcom_shell.h"
#include "ipcom_sock2.h"
#include "ipcom_syslog.h"
#include "ipcom_type.h"
#include "ipcom_hash.h"
#include "ipcom_sysvar.h"
#include "ipcom_netif.h"
#include "ipcom_strlib.h"
#include "ipl2tp_h.h"
#include "ipl2tp_api.h"
#include "ipl2tp_api_tunnel.h"
#include "ipl2tp_api_session.h"
#include "ipl2tp_attr.h"
#include "ipl2tp_cmd.h"
#include "ipl2tp_example.h"
#include "ipl2tp_example_v3.h"
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
typedef struct Ipl2tp_v3_circuit
{
char *name;
char *intf;
Ip_u32 ifnum;
int pw_type;
int vlan_tag;
}
Ipl2tp_v3_circuit_t;
typedef struct Ipl2tp_v3_ethernet_circuit
{
Ipl2tp_example_session_t session;
Ipl2tp_example_fd_entry_t *fd_eth;
}
Ipl2tp_v3_ethernet_circuit_t;
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
/*
****************************************************************************
* 9 STATIC FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipl2tp_eth_data_cb
*===========================================================================
* Description: Data callback.
* Parameters: user_data - User callback data.
* buffer - Original data buffer.
* payload - Payload pointer in data buffer.
* length - Length of payload.
* Returns:
*
*/
IP_STATIC void
ipl2tp_example_session_eth_data_output(void *user_data,
Ipl2tp_key *key,
void *buffer,
void *payload,
Ip_u16 length)
{
Ipl2tp_v3_ethernet_circuit_t *session = user_data;
IPL2TP_UNUSED(key);
IPL2TP_UNUSED(buffer);
/* Do the write */
if (session != IP_NULL)
{
struct Ip_sockaddr_ll to_ll;
Ipl2tp_v3_circuit_t *circuit = session->session.circuit;
/* Modify the frame */
if (circuit->pw_type == IPL2TP_ATTR_PW_TYPE_ETHERNET_VLAN &&
circuit->vlan_tag != 0)
{
Ip_u8 *frame = payload;
Ip_u16 vid = IP_GET_HTONS(frame + 14);
vid = (Ip_u16)(vid & 0xf000);
vid = (Ip_u16)(vid | (Ip_u16)(circuit->vlan_tag & 0x0fff));
IP_SET_HTONS(frame + 14, vid);
}
ipcom_memset(&to_ll, 0, sizeof(to_ll));
to_ll.sll_len = (Ip_u8)sizeof(to_ll);
to_ll.sll_family = IP_AF_PACKET;
to_ll.sll_ifindex = circuit->ifnum;
if (ipcom_sendto(session->fd_eth->fd, payload, length, 0,
(struct Ip_sockaddr *)&to_ll, sizeof(to_ll)) < 0)
{
IPCOM_LOG0(ERR, "IPL2TPv3: Error in ipcom send");
}
}
}
IP_STATIC void
ipl2tp_example_session_eth_data_input(Ipl2tp_example_fd_entry_t *entry,
void *buffer,
void *data,
Ip_size_t size)
{
Ip_ptrdiff_t offset = (Ip_u8 *)data - (Ip_u8 *)buffer;
/* Get the eth session ID */
Ipl2tp_v3_ethernet_circuit_t *session = entry->ptr;
/* Done */
ipl2tp_api_session_ethernet_input(&session->session.key,
data,
(int)size,
(int)offset,
0,
IP_TRUE);
}
/*
*===========================================================================
* ipl2tp_example_session_check_eth_interface
*===========================================================================
* Description: Determine if interface is currently in use by another circuit
* Parameters: key: session key of sessio to be compared against
* intf: name of interface
* Returns: 1 if the interface is currently in use by another session
* 0 otherwise
*
*/
IP_STATIC int
ipl2tp_example_session_check_eth_interface(Ipl2tp_key * key, char * intf)
{
Ipl2tp_status status;
Ipl2tp_key this_tkey, next_tkey;
Ipl2tp_key this_skey, next_skey;
Ipl2tp_v3_circuit_t *circuit;
Ipl2tp_v3_ethernet_circuit_t *session;
if ((intf == IP_NULL) || (ipcom_strlen(intf) == 0))
return (0);
/* Get the first tunnel, if there is one */
this_tkey.ident = 0;
this_tkey.version = IPL2TP_VERSION_L2TPV3;
if ((status = ipl2tp_api_tunnel_next(&this_tkey, &next_tkey)) != IPL2TP_STATUS_OK)
return (0);
/* Go through all tunnels */
while (status == IPL2TP_STATUS_OK)
{
/* If status is OK, next_tkey.ident must be non-zero */
this_tkey.ident = next_tkey.ident;
/* Get the first session if there is one */
if ((status = ipl2tp_api_session_next(&this_tkey, IP_NULL, &next_skey)) != IPL2TP_STATUS_OK)
continue;
/* Go through all sessions in this tunnel */
while (status == IPL2TP_STATUS_OK)
{
/* If status is OK, next_skey.ident must be non-zero, so use it */
this_skey.ident = next_skey.ident;
this_skey.version = next_skey.version;
/* Check the version - this only applies to version 3 */
if (this_skey.version != IPL2TP_VERSION_L2TPV3)
continue;
/* Check for a match, if the session is different */
if (this_skey.ident != key->ident)
{
session = ipcom_hash_get(ipl2tp_example_sessions, &this_skey);
if (session == IP_NULL)
continue;
/* Check the interface name */
circuit = (Ipl2tp_v3_circuit_t *)session->session.circuit;
if (ipcom_strcmp(circuit->intf, intf) == 0)
return (1);
}
/* Get the next session, if there is one */
status = ipl2tp_api_session_next(&this_tkey, &this_skey, &next_skey);
}
/* Get the next tunnel if there is one */
status = ipl2tp_api_tunnel_next(&this_tkey, &next_tkey);
}
return (0);
}
/*
*===========================================================================
* ipl2tp_example_session_eth_destroy
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC void
ipl2tp_example_session_eth_destroy(Ipl2tp_key *key)
{
Ipl2tp_v3_ethernet_circuit_t *session = ipcom_hash_get(ipl2tp_example_sessions, key);
if (session != IP_NULL)
{
struct Ip_ifreq ifreq;
Ipl2tp_attrobj attr = IP_NULL;
Ipl2tp_v3_circuit_t *circuit = session->session.circuit;
if (ipl2tp_example_session_check_eth_interface(key, circuit->intf) == 0)
{
IPCOM_LOG1(DEBUG, "Interface %s has no other users", circuit->intf);
/* OK to turn off promisc mode */
ipcom_memset(&ifreq, 0, sizeof(struct Ip_ifreq));
ipcom_strncpy(ifreq.ifr_name, circuit->intf, IP_IFNAMSIZ - 1);
if (ipcom_socketioctl(session->fd_eth->fd, IP_SIOCGIFFLAGS, &ifreq) < 0)
IPCOM_LOG1(ERR,
"IPL2TPv3: failed to get interface flags: %s",
ipcom_strerror(ipcom_errno));
else
{
IP_BIT_CLR(ifreq.ip_ifr_flags, IP_IFF_PROMISC);
if (ipcom_socketioctl(session->fd_eth->fd, IP_SIOCSIFFLAGS, &ifreq) < 0)
IPCOM_LOG1(ERR,
"IPL2TPv3: failed to set interface flags: %s",
ipcom_strerror(ipcom_errno));
}
}
else
IPCOM_LOG1(DEBUG, "Interface %s does have other users", circuit->intf);
/* Remove the object */
ipcom_hash_remove(ipl2tp_example_sessions, session);
/* Remove the socket */
session->fd_eth->data = IP_NULL;
session->fd_eth = IP_NULL;
/* Free the session */
ipcom_free(session->session.circuit);
ipcom_free(session);
/* Set the user data */
if (ipl2tp_attr_pappend(&attr,
IPL2TP_SATTR_SET_USER_DATA,
IP_NULL) == IPL2TP_STATUS_OK)
{
ipl2tp_api_session_attribute_set(key, attr);
ipl2tp_attr_delete(&attr);
}
}
}
/*
*===========================================================================
* ipl2tp_example_session_eth_create
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC Ipl2tp_v3_ethernet_circuit_t *
ipl2tp_example_session_eth_create(Ipl2tp_v3_circuit_t *circuit,
Ipl2tp_key *key)
{
Ipl2tp_v3_ethernet_circuit_t *session;
Ipl2tp_attrobj attr = IP_NULL;
struct Ip_ifreq ifreq;
Ipl2tp_callback cb;
session = ipcom_calloc(1, sizeof(*session));
if (session == IP_NULL)
goto fail;
ipcom_memcpy(&session->session.key, key, sizeof(*key));
session->session.circuit = circuit;
session->fd_eth = ipcom_malloc(sizeof(*session->fd_eth));
if (session->fd_eth == IP_NULL)
goto fail;
/* Create socket for catching packets destined to proxied MNs */
session->fd_eth->fd = ipcom_socket(IP_AF_PACKET, IP_SOCK_RAW, 0);
if (session->fd_eth->fd == IP_INVALID_SOCKET)
goto fail;
/* Bind raw socket to device */
if (ipcom_setsockopt(session->fd_eth->fd, IP_SOL_SOCKET, IP_SO_BINDTODEVICE,
circuit->intf, IP_IFNAMSIZ) == IP_SOCKERR)
{
ipcom_socketclose(session->fd_eth->fd);
goto fail;
}
ipcom_memset(&ifreq, 0, sizeof(struct Ip_ifreq));
ipcom_if_indextoname(circuit->ifnum, ifreq.ifr_name);
if (ipcom_socketioctl(session->fd_eth->fd, IP_SIOCGIFFLAGS, &ifreq) < 0)
{
IPCOM_LOG1(ERR,
"IPL2TPv3: failed to get interface flags: %s",
ipcom_strerror(ipcom_errno));
goto fail;
}
IP_BIT_SET(ifreq.ip_ifr_flags, IP_IFF_PROMISC);
if (ipcom_socketioctl(session->fd_eth->fd, IP_SIOCSIFFLAGS, &ifreq) < 0)
{
IPCOM_LOG1(ERR,
"IPL2TPv3: failed to set interface flags: %s",
ipcom_strerror(ipcom_errno));
goto fail;
}
session->fd_eth->ptr = session;
session->fd_eth->data = ipl2tp_example_session_eth_data_input;
if (ipcom_hash_add(ipl2tp_example_sessions, session) != IPCOM_SUCCESS)
{
IPCOM_LOG0(ERR, "IPL2TPv3: failed to add session");
goto fail;
}
ipcom_list_insert_last(&ipl2tp_example_fds, &session->fd_eth->next);
/* Set the user data */
if (ipl2tp_attr_pappend(&attr,
IPL2TP_SATTR_SET_USER_DATA,
session) != IPL2TP_STATUS_OK)
{
IPCOM_LOG0(ERR, "IPL2TPv3: failed to set sesion user data");
goto fail;
}
/* Set the data callback */
cb.eth_callback = (Ipl2tp_eth_callback)ipl2tp_example_session_eth_data_output;
if (ipl2tp_attr_pappend(&attr,
IPL2TP_SATTR_SET_DATA_CALLBACK,
(void *)cb.voidptr) != IPL2TP_STATUS_OK ||
ipl2tp_attr_iappend(&attr,
IPL2TP_SATTR_SET_LOCAL_CIRCUIT_STATUS,
IPL2TP_MIB_UP) != IPL2TP_STATUS_OK)
{
IPCOM_LOG0(WARNING, "IPL2TPv3: failed to set attributes");
}
ipl2tp_api_session_attribute_set(key, attr);
ipl2tp_attr_delete(&attr);
return session;
fail:
if (session)
{
if (session->fd_eth)
ipcom_free(session->fd_eth);
ipcom_free(session);
}
ipcom_free(circuit);
return IP_NULL;
}
/*
*===========================================================================
* ipl2tp_example_session_to_link
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC Ipl2tp_v3_circuit_t *
ipl2tp_example_session_to_circuit(Ipl2tp_key *key,
int type)
{
Ipl2tp_v3_circuit_t *circuit;
Ipl2tp_attrobj replies = IP_NULL;
Ipl2tp_attrobj attr = IP_NULL;
Ipl2tp_attr a;
Ip_u32 id;
char buf[128];
char *ctype;
int i;
int argc;
char **argv = IP_NULL;
ipl2tp_api_session_attribute_query(key,
IPL2TP_SATTR_GET_REMOTE_END_ID,
&replies);
if ((a = ipl2tp_attr_first(replies)) == IP_NULL)
return IP_NULL;
if (ipl2tp_attr_length(a) != 4)
return IP_NULL;
/* Get the router ID */
id = IP_GET_NTOHL(ipl2tp_attr_vdata(a));
ipl2tp_attr_delete(&replies);
/* Parse the circuit */
circuit = ipcom_calloc(1, sizeof(*circuit));
if(circuit == IP_NULL)
{
return IP_NULL;
}
/* */
ipcom_snprintf(buf, sizeof(buf), "ipl2tp.v3.circuit.%ld.name", id);
if ((circuit->name = ipcom_sysvar_get(buf, IP_NULL, IP_NULL)) == IP_NULL)
goto fail;
ipcom_snprintf(buf, sizeof(buf), "ipl2tp.v3.circuit.%ld.interface", id);
if ((circuit->intf = ipcom_sysvar_get(buf, IP_NULL, IP_NULL)) == IP_NULL)
goto fail;
ipcom_snprintf(buf, sizeof(buf), "ipl2tp.v3.circuit.%ld.attributes", id);
if ((ctype = ipcom_sysvar_get(buf, IP_NULL, IP_NULL)) == IP_NULL)
{
ipcom_snprintf(buf, sizeof(buf), "ipl2tp.v3.circuit.any.attributes");
if ((ctype = ipcom_sysvar_get(buf, IP_NULL, IP_NULL)) == IP_NULL)
goto fail;
}
/* Got the argument vector; time to explode it */
if (ipcom_parse_argstr(ctype, (int *)&argc, &argv) != 0)
{
ipcom_free(ctype);
goto fail;
}
for (i = 0; i < argc; i++)
{
char *value;
Ipl2tp_attr_info *info;
/**/
if ((info = ipl2tp_api_attribute_find(ipl2tp_session_tags, argv[i], &value)) == IP_NULL)
{
IPCOM_LOG2(ERR,
"L2TP: circuit %s: Invalid attribute %s",
circuit->name, argv[i]);
continue;
}
if (ipl2tp_api_attribute_parse(&attr,info,&value) == IP_FALSE)
{
IPCOM_LOG3(ERR,
"L2TP: circuit %s: Invalid attribute %s and value %s",
circuit->name, argv[i], value);
continue;
}
}
ipl2tp_api_session_attribute_set(key,attr);
ipl2tp_attr_delete(&attr);
ipcom_free(argv);
ipcom_free(ctype);
/* Retrieve the pseudowire type of the session */
ipl2tp_api_session_attribute_query(key,
IPL2TP_SATTR_GET_PSEUDOWIRE_TYPE,
&replies);
if((a = ipl2tp_attr_first(replies)) == IP_NULL)
{
ipl2tp_attr_delete(&replies);
goto fail;
}
/* Does it match? */
circuit->pw_type = ipl2tp_attr_idata(a);
ipl2tp_attr_delete(&replies);
if (circuit->pw_type != type)
{
IPCOM_LOG3(ERR,
"L2TP: circuit %s: Invalid pseudowire %u vs %u",
circuit->name,
circuit->pw_type,
type);
goto fail;
}
/* No interface */
if ((circuit->ifnum = ipcom_if_nametoindex(circuit->intf)) == 0)
goto fail;
/* VLAN tag */
ipcom_snprintf(buf, sizeof(buf), "ipl2tp.v3.circuit.%ld.vlan", id);
circuit->vlan_tag = ipcom_sysvar_get_as_int0(buf, 0);
return circuit;
fail:
if (circuit->name != IP_NULL)
ipcom_free(circuit->name);
if (circuit->intf != IP_NULL)
ipcom_free(circuit->intf);
ipcom_free(circuit);
return IP_NULL;
}
/*
*===========================================================================
* ipl2tp_example_session_eth_setup
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC Ipl2tp_v3_ethernet_circuit_t *
ipl2tp_example_session_eth_setup(Ipl2tp_key *key,
int type)
{
Ipl2tp_v3_circuit_t *circuit;
/* Destroy any previous sessions */
ipl2tp_example_session_eth_destroy(key);
/* Setup this end of the tunnel */
if ((circuit = ipl2tp_example_session_to_circuit(key, type)) == IP_NULL)
return IP_NULL;
/* Create the session */
return ipl2tp_example_session_eth_create(circuit, key);
}
/*
*===========================================================================
* ipl2tp_example_session_eth_status
*===========================================================================
* Description: Session status callback.
* Parameters: user_data - User callback data.
* key - Session ID.
* status - Pointer to status info.
* Returns:
*
*/
IP_STATIC int
ipl2tp_example_session_eth_status(void *user_data,
Ipl2tp_key *key,
Ipl2tp_result *result,
int type)
{
Ipl2tp_v3_ethernet_circuit_t *session = user_data;
switch (result->status)
{
case IPL2TP_STATUS_OK:
switch (result->result_code)
{
case IPL2TP_OUTGOING_REQUEST:
{
/* Setup */
if ((session = ipl2tp_example_session_eth_setup(key, type)) == IP_NULL)
return IPL2TP_STATUS_BADID;
IPCOM_LOG4(DEBUG,
"IPL2TPv3: SESSION (IPL2TP_OUTGOING_REQUEST) session[%s] v%d %d %s",
((Ipl2tp_v3_circuit_t *)session->session.circuit)->name,
key->version, key->ident,
ipl2tp_api_session_type(key));
break;
}
case IPL2TP_OUTGOING_REPLY:
{
IPCOM_LOG3(DEBUG,
"IPL2TPv3: SESSION (IPL2TP_OUTGOING_REPLY) v%d %d %s",
key->version, key->ident,
ipl2tp_api_session_type(key));
ipl2tp_api_session_outgoing_established(key, 0, 0, "");
break;
}
case IPL2TP_OUTGOING_ESTABLISHED:
/* */
if (session == IP_NULL)
{
/* Setup */
if ((session = ipl2tp_example_session_eth_setup(key, type)) == IP_NULL)
return IPL2TP_STATUS_BADID;
}
IPCOM_LOG4(DEBUG,
"IPL2TPv3: SESSION (IPL2TP_OUTGOING_ESTABLISHED) session[%s] v%d %d %s",
((Ipl2tp_v3_circuit_t *)session->session.circuit)->name,
key->version, key->ident,
ipl2tp_api_session_type(key));
break;
case IPL2TP_INCOMING_REQUEST:
/* Destroy any previous sessions */
/* Setup */
if ((session = ipl2tp_example_session_eth_setup(key, type)) == IP_NULL)
return IPL2TP_STATUS_BADID;
IPCOM_LOG4(DEBUG,
"IPL2TPv3: SESSION (IPL2TP_INCOMING_REQUEST) session[%s] v%d %d %s",
((Ipl2tp_v3_circuit_t *)session->session.circuit)->name,
key->version, key->ident,
ipl2tp_api_session_type(key));
ipl2tp_api_session_incoming_established(key, 0, 0, "");
break;
case IPL2TP_INCOMING_ESTABLISHED:
/* */
if (session == IP_NULL)
{
/* Setup */
if ((session = ipl2tp_example_session_eth_setup(key, type)) == IP_NULL)
return IPL2TP_STATUS_BADID;
}
IPCOM_LOG4(DEBUG,
"IPL2TPv3: SESSION (IPL2TP_INCOMING_ESTABLISHED) session[%s] v%d %d %s",
((Ipl2tp_v3_circuit_t *)session->session.circuit)->name,
key->version, key->ident,
ipl2tp_api_session_type(key));
break;
}
break;
default:
IPCOM_LOG6(DEBUG,
"IPL2TPv3: SESSION (%u) Session[%s] v%d %d %s closed with status %s",
(int)result->status,
session? ((Ipl2tp_v3_circuit_t *)session->session.circuit)->name : "<invalid>",
key->version, key->ident,
ipl2tp_api_session_type(key),
ipl2tp_api_errname(result->status));
ipl2tp_example_session_eth_destroy(key);
break;
}
return 0;
}
/*
*===========================================================================
* ipl2tp_example_tunnel_auth
*===========================================================================
* Description: Set the tunnel auth if available.
* Parameters:
* Returns:
*
*/
IP_STATIC void
ipl2tp_example_tunnel_auth(Ipl2tp_key *key,
Ip_u32 rID,
const char *peer)
{
char buf[128];
char *ctype;
Ipl2tp_attrobj attr = IP_NULL;
int argc;
char **argv = IP_NULL;
int i;
do
{
IPCOM_LOG2(INFO,
"L2TP: Verifying attributes for %ld@%s",
rID, peer);
ipcom_snprintf(buf, sizeof(buf), "ipl2tp.v3.control.%ld.attributes", rID);
if ((ctype = ipcom_sysvar_get(buf, IP_NULL, IP_NULL)) != IP_NULL)
break;
ipcom_snprintf(buf, sizeof(buf), "ipl2tp.v3.control.%s.attributes", peer);
if ((ctype = ipcom_sysvar_get(buf, IP_NULL, IP_NULL)) != IP_NULL)
break;
ipcom_snprintf(buf, sizeof(buf), "ipl2tp.v3.control.any.attributes");
if ((ctype = ipcom_sysvar_get(buf, IP_NULL, IP_NULL)) != IP_NULL)
break;
return;
} while (0);
/* Got the argument vector; time to explode it */
if (ipcom_parse_argstr(ctype, (int *)&argc, &argv) != 0)
{
ipcom_free(ctype);
return;
}
for (i = 0; i < argc; i++)
{
char *value;
Ipl2tp_attr_info *info;
/**/
if ((info = ipl2tp_api_attribute_find(ipl2tp_tunnel_tags, argv[i], &value)) == IP_NULL)
{
IPCOM_LOG1(ERR,
"L2TP: tunnel: Invalid attribute %s",
argv[i]);
continue;
}
if (ipl2tp_api_attribute_parse(&attr,info,&value) == IP_FALSE)
{
IPCOM_LOG2(ERR,
"L2TP: Invalid attribute %s and value %s",
argv[i], value);
continue;
}
}
ipl2tp_api_tunnel_attribute_set(key,attr);
ipl2tp_attr_delete(&attr);
ipcom_free(argv);
ipcom_free(ctype);
}
/*
****************************************************************************
* 10 GLOBAL FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipl2tp_example_sstatus_v3
*===========================================================================
* Description: Session status callback.
* Parameters: user_data - User callback data.
* key - Session ID.
* status - Pointer to status info.
* Returns:
*
*/
IP_GLOBAL int
ipl2tp_example_sstatus_v3(void *user_data,
Ipl2tp_key *key,
Ipl2tp_result *result)
{
int type;
Ipl2tp_attrobj replies = IP_NULL;
Ipl2tp_attr a;
ipl2tp_api_session_attribute_query(key,
IPL2TP_SATTR_GET_PSEUDOWIRE_TYPE,
&replies);
if((a = ipl2tp_attr_first(replies)) == IP_NULL)
{
ipl2tp_attr_delete(&replies);
return IPL2TP_STATUS_BADAVP;
}
type = ipl2tp_attr_idata(a);
ipl2tp_attr_delete(&replies);
/* ETHERNET pseudowire type */
if (type == IPL2TP_ATTR_PW_TYPE_ETHERNET ||
type == IPL2TP_ATTR_PW_TYPE_ETHERNET_VLAN)
{
/* */
return ipl2tp_example_session_eth_status(user_data, key, result, type);
}
return IPL2TP_STATUS_BADPW;
}
/*
*===========================================================================
* ipl2tp_example_tstatus_v3
*===========================================================================
* Description: Tunnel status callback.
* Parameters: user_data - User callback data.
* key - Tunnel ID.
* status - Pointer to status info.
* Returns:
*
*/
IP_GLOBAL int
ipl2tp_example_tstatus_v3(void *user_data,
Ipl2tp_key *key,
Ipl2tp_result *result)
{
Ipl2tp_attrobj replies = IP_NULL;
Ipl2tp_attrobj attr = IP_NULL;
Ipl2tp_attr a;
Ip_u32 rID;
const char *peer;
IPL2TP_UNUSED(user_data);
/* Get the remote info */
ipl2tp_attr_add_query(&attr, IPL2TP_TATTR_GET_REMOTE_ROUTER_ID);
ipl2tp_attr_add_query(&attr, IPL2TP_TATTR_GET_l2tpTunnelStatsRemoteHostName);
ipl2tp_api_tunnel_attribute_get(key, attr, &replies);
ipl2tp_attr_delete(&attr);
/* Get the router ID */
a = ipl2tp_attr_first(replies);
if(a == IP_NULL)
{
ipl2tp_attr_delete(&replies);
return 0;
}
rID = ipl2tp_attr_idata(a);
/* Get the remote host name */
a = ipl2tp_attr_next(a);
peer = ipl2tp_attr_strdata(a);
switch (result->status)
{
case IPL2TP_STATUS_OK:
switch (result->result_code)
{
case IPL2TP_OUTGOING_AUTHENTICATION:
{
/* Allocate an attribute object */
IPCOM_LOG3(DEBUG,
"IPL2TPv3: TUNNEL (IPL2TP_OUTGOING_AUTHENTICATION) v%d %d requested by '%s'",
key->version, key->ident,
peer);
ipl2tp_example_tunnel_auth(key, rID, peer);
/* We've installed the authentication data required,
* do continue the tunnel processing and attempt to establish */
ipl2tp_api_tunnel_authentication_established(key);
break;
}
case IPL2TP_OUTGOING_REQUEST:
{
IPCOM_LOG3(DEBUG,
"IPL2TPv3: TUNNEL (IPL2TP_OUTGOING_REQUEST) v%d %d from '%s'",
key->version, key->ident,
peer);
break;
}
case IPL2TP_OUTGOING_ESTABLISHED:
IPCOM_LOG2(DEBUG,
"IPL2TPv3: TUNNEL (IPL2TP_OUTGOING_ESTABLISHED) v%d %d opened",
key->version, key->ident);
break;
case IPL2TP_INCOMING_ESTABLISHED:
IPCOM_LOG2(DEBUG,
"IPL2TPv3: TUNNEL (IPL2TP_INCOMING_ESTABLISHED) v%d %d opened",
key->version, key->ident);
break;
}
break;
case IPL2TP_STATUS_NEGOTIATION:
IPCOM_LOG2(DEBUG,
"IPL2TPv3: TUNNEL (IPL2TP_STATUS_NEGOTIATION) v%d %d closed obsoleted by version negotiation",
key->version, key->ident);
break;
default:
IPCOM_LOG4(DEBUG,
"IPL2TPv3: TUNNEL (%u) v%d %d closed with status %s",
(int)result->status,
key->version, key->ident,
ipl2tp_api_errname(result->status));
break;
}
ipl2tp_attr_delete(&replies);
return 0;
}
/*
****************************************************************************
* 11 PUBLIC FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,99 @@
/*
******************************************************************************
* HEADER FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp_example_v3.h,v $ $Revision: 1.2 $
* $Source: /home/interpeak/CVSRoot/ipl2tp/config/ipl2tp_example_v3.h,v $
* $Author: joel $ $Date: 2006-01-30 10:46:59 $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelius@interpeak.se>
******************************************************************************
*/
#ifndef IPL2TP_EXAMPLE_V3_H
#define IPL2TP_EXAMPLE_V3_H
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipl2tp_example_sstatus_v3
*===========================================================================
* Description: Session status callback.
* Parameters: user_data - User callback data.
* key - Session ID.
* status - Pointer to status info.
* Returns:
*
*/
IP_GLOBAL int ipl2tp_example_sstatus_v3(void *user_data,
Ipl2tp_key *key,
Ipl2tp_result *result);
/*
*===========================================================================
* ipl2tp_example_tstatus_v3
*===========================================================================
* Description: Tunnel status callback.
* Parameters: user_data - User callback data.
* key - Tunnel ID.
* status - Pointer to status info.
* Returns:
*
*/
IP_GLOBAL int ipl2tp_example_tstatus_v3(void *user_data,
Ipl2tp_key *key,
Ipl2tp_result *result);
#ifdef __cplusplus
}
#endif
#endif
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,11 @@
IPTARGETS := lib
ifneq ($(IPMAKEFILE),)
include $(IPMAKEFILE)
else
include $(IPCOM_ROOT)/Makefile
endif
include ipl2tp.mk
include $(IPCOM_ROOT)/gmake/ipcom_make.mk
lib: dirs $(IPLIBFILE)
@@ -0,0 +1,95 @@
#############################################################################
# IPL2TP.MK
#
# Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp.mk,v $ $Revision: 1.6 $
# $Source: /home/interpeak/CVSRoot/ipl2tp/gmake/ipl2tp.mk,v $
# $Author: tneale $ $Date: 2010-04-27 19:25:25 $
# $State: Exp $ $Locker: $
#
# INTERPEAK_COPYRIGHT_STRING
#
#############################################################################
#############################################################################
# PRODUCT
###########################################################################
IPPROD ?= ipl2tp
#############################################################################
# DEFINE
###########################################################################
IPDEFINE += -DIPL2TP
#############################################################################
# INCLUDE
###########################################################################
IPINCLUDE += -I$(IPL2TP_ROOT)/config
IPINCLUDE += -I$(IPL2TP_ROOT)/include
IPINCLUDE += -I$(IPL2TP_ROOT)/src
IPLIBINCLUDE += -I$(IPL2TP_ROOT)/src
#############################################################################
# OBJECTS
###########################################################################
# Configuration
IPLIBOBJECTS_C += ipl2tp_config.o
IPLIBOBJECTS_C += ipl2tp_example.o
IPLIBOBJECTS += ipl2tp_example_v2.o
IPLIBOBJECTS += ipl2tp_example_v3.o
# Main
IPLIBOBJECTS += ipl2tp_api.o
IPLIBOBJECTS += ipl2tp_api_session.o
IPLIBOBJECTS += ipl2tp_api_tunnel.o
IPLIBOBJECTS += ipl2tp_attr.o
IPLIBOBJECTS += ipl2tp_avp.o
IPLIBOBJECTS += ipl2tp_cmd.o
IPLIBOBJECTS += ipl2tp_data.o
IPLIBOBJECTS += ipl2tp_message.o
IPLIBOBJECTS += ipl2tp_pseudowire.o
IPLIBOBJECTS += ipl2tp_state.o
IPLIBOBJECTS += ipl2tp_trpt.o
IPLIBOBJECTS += ipl2tp_util.o
IPLIBOBJECTS += ipl2tp_v2.o
IPLIBOBJECTS += ipl2tp_v2_message.o
IPLIBOBJECTS += ipl2tp_v2_pw.o
IPLIBOBJECTS += ipl2tp_v2_state.o
IPLIBOBJECTS += ipl2tp_v3.o
IPLIBOBJECTS += ipl2tp_v3_message.o
IPLIBOBJECTS += ipl2tp_v3_pw.o
IPLIBOBJECTS += ipl2tp_v3_state.o
# Compiles the xxx_config.o if the $SKIP_CONFIG macro is either not defined
# or set to anything other than true.
ifneq ($(SKIP_CONFIG),true)
IPLIBOBJECTS += $(IPLIBOBJECTS_C)
endif
#############################################################################
# VPATH
###########################################################################
IPSRCDIRS += $(IPL2TP_ROOT)/src $(IPL2TP_ROOT)/config
#############################################################################
# LIB
###########################################################################
IPLIBS += $(IPLIBROOT)/libipl2tp.a
###########################################################################
# END OF IPL2TP.MK
###########################################################################
@@ -0,0 +1,753 @@
/* ipl2tp.h - Layer 2 Tunneling Protocol. */
/*
DESCRIPTION
Callback routines for IPL2TP.
*/
/*
******************************************************************************
* HEADER FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp.h,v $ $Revision: 1.11 $
* $Source: /home/interpeak/CVSRoot/ipl2tp/include/ipl2tp.h,v $
* $Author: tneale $ $Date: 2010-04-27 19:25:25 $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelius@interpeak.se>
******************************************************************************
*/
#ifndef IPL2TP_H
#define IPL2TP_H
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#include "ipcom_type.h"
#include "ipl2tp_config.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
#define IPL2TP_MAGIC 0x5AAA555A
#define IPL2TP_RELEASE 60800
/* Select synchronization */
#ifdef IPL2TP_USE_MUTEX
#define IPL2TP_OCCUPIED(action) ipcom_mutex_lock(ipl2tp.mutex)
#define IPL2TP_AVAILABLE() ipcom_mutex_unlock(ipl2tp.mutex)
#else
#define IPL2TP_OCCUPIED(action) \
do \
{ \
if (ipl2tp_occupied++ != 0) \
{ \
IPCOM_LOG0(EMERG, "Concurrent calls to IPL2TP"); \
ipl2tp_occupied--; \
action; \
} \
} \
while (0)
#define IPL2TP_AVAILABLE() \
do \
{ \
ipl2tp_occupied--; \
} \
while (0)
#error 0
#endif
#define IPL2TP_UNUSED(x) ((void) (x))
/* C stuff */
#define CONST const
/* Callback codes */
#define IPL2TP_OUTGOING_AUTHENTICATION 0
#define IPL2TP_OUTGOING_REQUEST 1
#define IPL2TP_OUTGOING_REPLY 2
#define IPL2TP_OUTGOING_ESTABLISHED 3
#define IPL2TP_INCOMING_REQUEST 4
#define IPL2TP_INCOMING_ESTABLISHED 5
/* MIB values */
#define IPL2TP_MIB_FRAMING_NONE 1
#define IPL2TP_MIB_FRAMING_SYNC 2
#define IPL2TP_MIB_FRAMING_ASYNC 3
#define IPL2TP_MIB_FRAMING_SYNC_ASYNC 4
#define IPL2TP_MIB_BEARER_NONE 1
#define IPL2TP_MIB_BEARER_DIGITAL 2
#define IPL2TP_MIB_BEARER_ANALOG 3
#define IPL2TP_MIB_BEARER_DIGITAL_ANALOG 4
#define IPL2TP_MIB_AUTH_NONE 1
#define IPL2TP_MIB_AUTH_SIMPLE 2
#define IPL2TP_MIB_AUTH_CHALLENGE 3
#define IPL2TP_MIB_AUTH_DIGEST 4
#define IPL2TP_MIB_ENABLED 1
#define IPL2TP_MIB_DISABLED 2
#define IPL2TP_MIB_YES 1
#define IPL2TP_MIB_NO 2
#define IPL2TP_MIB_L2TP 5
#define IPL2TP_MIB_ONDEMAND 1
#define IPL2TP_MIB_NEVER 2
#define IPL2TP_MIB_ALWAYS 3
#define IPL2TP_MIB_IDLE 1
#define IPL2TP_MIB_CONNECTING 2
#define IPL2TP_MIB_ESTABLISHED 3
#define IPL2TP_MIB_DISCONNECTING 4
#define IPL2TP_MIB_LOCALLY 1
#define IPL2TP_MIB_REMOTELY 2
#define IPL2TP_MIB_LAC_INCOMING 1
#define IPL2TP_MIB_LNS_INCOMING 2
#define IPL2TP_MIB_LAC_OUTGOING 3
#define IPL2TP_MIB_LNS_OUTGOING 4
#define IPL2TP_MIB_NONE 1
#define IPL2TP_MIB_REMOTE 2
#define IPL2TP_MIB_LOCAL 3
#define IPL2TP_MIB_BOTH 4
#define IPL2TP_MIB_UP 1
#define IPL2TP_MIB_DOWN 2
#define IPL2TP_MIB_DORMANT 5
/* */
#define IPL2TP_MIB_AUTH_MD5 0
#define IPL2TP_MIB_AUTH_SHA 1
#define IPL2TP_VERSION_L2F 0x01
#define IPL2TP_VERSION_L2TPV2 0x02
#define IPL2TP_VERSION_L2TPV3 0x03
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
typedef Ip_u32 Ipl2tp_ident;
typedef Ip_u32 Ipl2tp_version;
/* Key to identify a session based on version & ident */
typedef struct Ipl2tp_key
{
Ipl2tp_version version;
Ipl2tp_ident ident;
}
Ipl2tp_key;
/*
*===========================================================================
* Ipl2tp_status
*===========================================================================
*
*/
/*lint -e641*/
typedef enum
{
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 disbled */
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, /* Pseudowire type not in capabilities */
IPL2TP_STATUS_BADL2, /* Unknown L2 sublayer */
IPL2TP_STATUS_BADSEQUENCING,/* Unknown data sequencing, or no L2 */
IPL2TP_STATUS_BADVERSION, /* Bad version */
IPL2TP_STATUS_CIRCUIT_DOWN, /* Circuit is down */
IPL2TP_STATUS_NEGOTIATION /* Version negotiation */
}
Ipl2tp_status;
/*
*===========================================================================
* Ipl2tp_result
*===========================================================================
*/
typedef struct
{
Ipl2tp_status status; /* Status of operation */
Ip_u16 result_code; /* Result code as in RFC2661 */
Ip_u16 error_code; /* Error code as in RFC2661 */
char *error_message; /* Error message as in RFC2661 */
}
Ipl2tp_result;
/*******************************************************************************
*
* Ipl2tp_status_callback - Callback for tunnel and session status changes.
*
* Callback reporting a change in tunnel or session status.
*
* This is the prototype for the user-defined callback routine that is called when there
* is a change in status on one of the tunnels or sessions. The status is found in the
* result->status variable.
*
* A status value of IPL2TP_STATUS_OK indicates that a tunnel or session
* establishment is in progress. The result->result_code value gives additional
* information about the current state of the new tunnel/session.
*
* Note that the status argument points to a static location which
* is valid only in the context of the callback. An application has
* to move the contents of *status to a local variable in order to
* use it after the callback has returned. The same thing applies
* to error_message.
*
* TUNNEL RESULT CODES
*
* The following result codes are valid in the tunnel status callback:
* \is
* \i 'IPL2TP_OUTGOING_AUTHENTICATION'
* A tunnel establishment is initiated by an LNS, and the LAC application is
* prompted to enter authentication attributes for the new tunnel. Only the two
* following attributes are valid:
* \ts
* 'IPL2TP_TATTR_GET_l2tpTunnelStatsRemoteHostName'
* 'IPL2TP_TATTR_GET_tunnelRemoteAddress'
* \te
* Note that IPL2TP exits after this callback, and the LAC application is
* responsible for resuming tunnel establishment by calling
* ipl2tp_authentication_established().
*
* \i 'IPL2TP_OUTGOING_REQUEST'
* A new tunnel is requested by an LNS, and the LAC application is given the
* opportunity to modify tunnel attributes before replying to the LNS.
*
* \i 'IPL2TP_OUTGOING_ESTABLISHED'
* A new tunnel is established by an LNS.
*
* \i 'IPL2TP_INCOMING_ESTABLISHED'
* A new tunnel is established by the LAC.
* \ie
*
* SESSION RESULT CODES
*
* The following result codes are valid in the session status callback:
* \is
* \i 'IPL2TP_OUTGOING_REQUEST'
* A session establishment is initiated by an LNS, and the LAC
* application is given the opportunity to enter the
* 'IPL2TP_SATTR_SET_PHYS_CHAN_ID' attribute before
* replying to the LNS.
*
* \i 'IPL2TP_OUTGOING_REPLY'
* A new session is requested by an LNS, and the LAC application is
* prompted to place a call according to the session attributes. Note
* that IPL2TP exits after this callback, and the LAC application
* is responsible for resuming session establishment by calling
* ipl2tp_outgoing_session_established().
*
* \i 'IPL2TP_OUTGOING_ESTABLISHED'
* A new outgoing session is established and ready to transfer data.
*
* \i 'IPL2TP_INCOMING_ESTABLISHED'
* A new incoming session is established and ready to transfer data.
*
* \ie
*
* Note that the result argument points to a location that is valid only in the context
* of the callback routine. An application has to move the data pointed to by result to
* a static variable in order to use it after the callback has returned.
*
* The return value controls if the tunnel/session is established or not. A nonzero
* return value tears down the tunnel/session whereas a zero value
* continues the establishment process.
*
* This callback is unique to each tunnel or session. The tunnel callback may be
* registered as an attribute in any of the ipl2tp_open(), ipl2tp_tunnel_open(),
* ipl2tp_session_open() and ipl2tp_tunnel_control() calls. The session callback may
* be entered as an attribute in any of the ipl2tp_open(), ipl2tp_session_open() and
* ipl2tp_session_control() calls.
*
* SYNOPSIS
* \cs
* typedef int (*Ipl2tp_status_callback)(void *user_data, Ipl2tp_key *key, Ipl2tp_result *result);
* \ce
*
* PARAMETERS
* \is
* \i 'user_data' User data as specified in ipl2tp_xxx_open().
* \i 'key' Tunnel or session ID.
* \i 'result' A pointer to the status information.
* \ie
*
* RETURNS
* \is
* \i '0' if the new tunnel or session should continue the establishment process.
* \i '1' if the new tunnel or session should be closed immediately.
* \ie
*
*
* EXAMPLE
* \cs
* static void tunnel_cb(void *user_data, Ipl2tp_key *key, Ipl2tp_result *result)
* {
* switch (result->status)
* {
* case IPL2TP_STATUS_OK:
* switch (result->result_code)
* {
* case IPL2TP_OUTGOING_AUTHENTICATION:
* {
* Ipl2tp_attrobj attr = IP_NULL;
* Ipl2tp_attrobj replies = IP_NULL;
*
* /@ Get remote host name @/
* ipl2tp_attr_iappend(&attr, IPL2TP_TATTR_RO_l2tpTunnelStatsRemoteHostName, 0);
* ipl2tp_api_tunnel_attribute_get(key, attr, &replies);
* printf("Authentication request by LNS '%s'\n",
* ipl2tp_attr_pdata(ipl2tp_attr_first(replies)));
*
* /@ Set authentication @/
* ipl2tp_attr_delete(replies);
* ipl2tp_attr_clear(attr);
* ipl2tp_attr_iappend(&attr, IPL2TP_TATTR_RW_l2tpTunnelConfigAuthentication,
* IPL2TP_MIB_AUTH_CHALLENGE);
*
* ipl2tp_attr_vappend(&attr,
* IPL2TP_TATTR_RW_l2tpTunnelConfigSecret,
* "our_secret", strlen("our_secret"));
* ipl2tp_api_tunnel_attribute_set(key, attr);
*
* /@ Continue tunnel establishment @/
* ipl2tp_authentication_established(key);
* ipl2tp_attr_delete(attr);
* break;
* }
*
* case IPL2TP_OUTGOING_REQUEST:
* {
* Ipl2tp_attrobj attrobj = IP_NULL;
* Ipl2tp_attrobj replies = IP_NULL;
*
* /@ Get remote host name @/
* ipl2tp_attr_iappend(&attr, IPL2TP_TATTR_RO_l2tpTunnelStatsRemoteHostName, 0);
* ipl2tp_api_tunnel_attribute_get(id, attr, &replies);
* printf("Tunnel request by LNS '%s'\n", ipl2tp_attr_pdata(ipl2tp_attr_first(replies)));
* ipl2tp_attr_delete(attr);
* ipl2tp_attr_delete(replies);
* break;
* }
*
* case IPL2TP_OUTGOING_ESTABLISHED:
* printf("Tunnel %d opened by LNS\n", key->ident);
* break;
*
* case IPL2TP_INCOMING_ESTABLISHED:
* printf("Tunnel %d opened by LAC\n", key->ident);
* break;
* }
* break;
*
* default:
* printf("Tunnel %d closed with status %d, %s",
* key->ident, (int)result->status,
* ipl2tp_api_errname(result->status));
*
* break;
* }
* return 0;
* }
* \ce
*
*
* SEE ALSO
*
* Ipl2tp_data_callback(), Ipl2tp_sli_callback(), Ipl2tp_write_callback()
*
* ERRNO
* None
*/
typedef int (*Ipl2tp_status_callback)
(
void *user_data, /* User-supplied data */
Ipl2tp_key *key, /* Tunnel or session ID */
Ipl2tp_result *result /* Status of operation */
);
/*******************************************************************************
*
* Ipl2tp_data_callback - Callback for sending to remote device.
*
* Called when sending PPP data to the remote device.
*
* This is the prototype for the user-defined callback routine that is called when
* sending PPP data to a remote device. It typically calls a PPP interface for raw
* output of a message.
*
* The opaque parameter is the same as the argument to ipl2tp_l2tp_input(), and may
* be used to optimize performance by eliminating a memory allocation and copy
* operation.
*
* This callback is unique to each session, and is registered as an attribute in any of
* the ipl2tp_open(), ipl2tp_session_open() and ipl2tp_session_control() calls.
*
* SYNOPSIS
* \cs
* typedef void (*Ipl2tp_data_callback)(void *user_data, Ipl2t_key *key, void *payload, Ip_u16 length, void *opaque);
* \ce
*
* PARAMETERS
* \is
* \i 'user_data' User data from IPL2TP_SATTR_SET_USER_DATA attribute.
* \i 'key' Session ID.
* \i 'payload' Pointer to the PPP payload.
* \i 'length' Length of the PPP payload.
* \i 'opaque' Opaque user data as specified in ipl2tp_l2tp_input().
* \ie
*
* RETURNS
* \is
* \i None
* \ie
*
* EXAMPLE
* \cs
* static void data_cb(void *user_data, Ipl2tp_key *key, void *payload, Ip_u16 length, void *opaque)
* {
* /@ Do the write @/
* ppp_write(user_data, payload, length, opaque);
* }
*
*
* void example(void)
* {
* Ipl2tp_attrobj attrobj = ipl2tp_attr_new();
* Ipl2tp_key skey;
*
* /@ Set data callback attribute @/
* ipl2tp_attr_pappend(&attrobj, IPL2TP_SATTR_RW_DATA_CALLBACK, data_cb);
*
* /@ Open session @/
* skey.version = IPL2TP_VERSION_L2TPV2;
* if (ipl2tp_session_open(&skey, tkey, IP_NULL, IP_NULL, attrobj) != IPL2TP_STATUS_OK)
* {
* printf("Failed at session_open()\n");
* }
*
* ipl2tp_attr_delete(attrobj);
* }
* \ce
*
*
* SEE ALSO
*
* ipl2tp_api_ppp_input(), ipl2tp_api_l2tp_input(), Ipl2tp_status_callback(),
* Ipl2tp_sli_callback(), Ipl2tp_write_callback()
*
* ERRNO
* None
*/
typedef void (*Ipl2tp_data_callback)
(
void *user_data, /* User-supplied data */
Ipl2tp_key *key, /* Session ID */
void *buffer, /* Original buffer */
void *payload, /* Payload location in buffer */
Ip_u16 length /* Length of payload */
);
/*******************************************************************************
*
* Ipl2tp_sli_callback - Callback for received data.
*
* Called when receiving a SLI packet from the LNS.
*
* This is the prototype for the user-defined callback routine that is called when a SLI
* message is received from the peer host. The SLI message contains ACCM values
* for both directions of PPP communication.
*
* The send_accm value controls data sent from IPL2TP to the remote device, and
* the receive_accm value controls data sent from the remote device to IPL2TP.
*
* This callback is unique to each session, and is registered as an attribute in any of
* the ipl2tp_api_open(), ipl2tp_api_session_open() and ipl2tp_api_session_control()
* calls.
*
* SYNOPSIS
* \cs
* typedef void (*Ipl2tp_sli_callback)(void *user_data, Ipl2tp_key *key, Ip_u32 send_accm, Ip_u32 receive_accm);
* \ce
*
* PARAMETERS
* \is
* \i 'user_data' User data as specified in ipl2tp_session_open().
* \i 'key' Session ID.
* \i 'send_accm' ACCM for sending data.
* \i 'receive_accm' ACCM for receiving data.
* \ie
*
* RETURNS
* \is
* \i None
* \ie
*
* EXAMPLE
* \cs
* static void sli_cb(void *user_data, Ipl2tp_key *key, Ip_u32 send_accm, Ip_u32 receive_accm)
* {
* /@ Update PPP async module @/
* ppp_accm(user_data, send_accm, receive_accm);
* }
*
*
* void example(void)
* {
* Ipl2tp_attrobj attrobj = ipl2tp_attr_new();
* Ipl2tp_key skey;
*
* /@ Set SLI attribute @/
* ipl2tp_attr_pappend(&attrobj,
* IPL2TP_SATTR_RW_SLI_CALLBACK, sli_cb);
*
* /@ Open session @/
* skey.version = IPL2TP_VERSION_L2TPV2;
* if (ipl2tp_session_open(&skey, tkey, IP_NULL, IP_NULL, attrobj) != IPL2TP_STATUS_OK)
* {
* printf("Failed at session_open()\n");
* }
*
* ipl2tp_attr_delete(attrobj);
* }
* \ce
*
*
* SEE ALSO
*
* ipl2tp_api_ppp_input(), ipl2tp_api_l2tp_input(), Ipl2tp_status_callback(),
* Ipl2tp_data_callback(), Ipl2tp_write_callback()
*
* ERRNO
* None
*/
typedef void (*Ipl2tp_sli_callback)
(
void *user_data, /* User-supplied data */
Ipl2tp_key *key, /* Session ID */
Ip_u32 send_accm, /* Send ACCM */
Ip_u32 receive_accm /* Receive ACCM */
);
/*******************************************************************************
*
* Ipl2tp_write_callback - Callback for sending messages to peer L2TP device.
*
* Called when sending L2TP data to the remote L2TP peer device. Returns
* the number of sent bytes.
*
* This is the prototype for the user-defined callback routine that is called when
* sending L2TP messages to the peer L2TP device. It typically sends messages to an
* UDP socket.
*
* This callback is common to all tunnels and sessions, and is registered with the
* IPL2TP_ATTR_SET_L2TP_WRITE_CALLBACK attribute in the ipl2tp_open()
* call.
*
* SYNOPSIS
* \cs
* typedef void (*Ipl2tp_write_callback)(void *user_data, Ipl2tp_key *key, void *message, int length, union Ip_sockaddr_union *addr, void *opaque);
* \ce
*
* PARAMETERS
* \is
* \i 'user_data' User data as specified in ipl2tp_tunnel_open().
* \i 'key' Tunnel ID.
* \i 'message' Message pointer.
* \i 'length' Length of message.
* \i 'ipaddr' IP address to send the message to.
* \i 'opaque' Opaque user data from the ipl2tp_ppp_input() routine, or IP_NULL for control messages.
* \ie
*
* RETURNS
* \is
* \i None
* \ie
*
* EXAMPLE
* \cs
* static void l2tp_write(void *user_data, Ipl2tp_key *key, void *message, int length, union Ip_sockaddr_union *addr, void *opaque)
* {
* /@ Transmit the UDP packet @/
* if (sendto(socketfd, (char *)message, length, 0, (struct sockaddr *)&addr->sa, sizeof(addr->sin)) < 0)
* {
* printf("Error writing UDP packet\n");
* }
* }
*
* void example(void)
* {
* Ipl2tp_attrobj attrobj;
*
* /@ Initialize @/
* ipl2tp_api_init();
*
* /@ Create attribute object @/
* attrobj = ipl2tp_attr_new();
* ipl2tp_attr_pappend(&attrobj, IPL2TP_ATTR_RW_L2TP_WRITE_CALLBACK, l2tp_write);
*
* /@ Open IPL2TP @/
* ipl2tp_api_open(attrobj, IP_NULL, IP_NULL, IP_NULL, IP_NULL);
* ipl2tp_attr_delete(attrobj);
* }
* \ce
*
* SEE ALSO
*
* ipl2tp_api_ppp_input(), ipl2tp_api_l2tp_input(), Ipl2tp_status_callback(),
* Ipl2tp_data_callback(), Ipl2tp_sli_callback()
*
* ERRNO
* None
*/
typedef int (*Ipl2tp_write_callback)
(
void *user_data, /* User-supplied data */
Ipl2tp_key *key, /* Tunnel ID */
struct Ip_iovec *iov, /* I/O vector */
int iov_len, /* Length of I/O vector */
union Ip_sockaddr_union *peer, /* IP address to send to */
Ip_u8 transport /* Transport type */
);
/*
*===========================================================================
* Ipl2tp_ppp_callback
*===========================================================================
*
* Called when receiving a SLI packet from LNS.
*/
typedef void (*Ipl2tp_ppp_callback)
(
void *user_data, /* User-supplied data */
Ipl2tp_key *key, /* Session ID */
void *buffer, /* Callback data */
void *payload, /* Payload pointer */
Ip_u16 length /* Length of payload */
);
/*
*===========================================================================
* Ipl2tp_eth_callback
*===========================================================================
*
* Called when receiving a SLI packet from LNS.
*/
typedef void (*Ipl2tp_eth_callback)
(
void *user_data, /* User callback data */
Ipl2tp_key *key, /* Session ID */
void *buffer, /* Original data buffer */
void *payload, /* Payload pointer */
Ip_u16 length /* Length of payload */
);
/*
*===========================================================================
* Ipl2tp_callback
*===========================================================================
*
* Union for passing function pointers
*/
typedef union Ipl2tp_callback
{
Ipl2tp_status_callback status_callback;
Ipl2tp_data_callback data_callback;
Ipl2tp_sli_callback sli_callback;
Ipl2tp_write_callback write_callback;
Ipl2tp_ppp_callback ppp_callback;
Ipl2tp_eth_callback eth_callback;
void *voidptr;
} Ipl2tp_callback;
/*
****************************************************************************
* 6 FUNCTIONS
****************************************************************************
*/
#ifdef __cplusplus
}
#endif
#endif
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,892 @@
/* ipl2tp_api.h - IPL2TP API. */
/*
DESCRIPTION
API for Layer 2 Tunneling Protocol.
*/
/*
******************************************************************************
* SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp_api.h,v $ $Revision: 1.6 $
* $Source: /home/interpeak/CVSRoot/ipl2tp/include/ipl2tp_api.h,v $
* $Author: tneale $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
*
******************************************************************************
*/
#ifndef _IPL2TP_API_H_
#define _IPL2TP_API_H_
/*
****************************************************************************
* DESCRIPTION
****************************************************************************
*
* Public IPL2TP Application Programming Interface.
*/
/*
****************************************************************************
* INCLUDE FILES
****************************************************************************
*/
#include "ipl2tp_attr.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
****************************************************************************
* DEFINES
****************************************************************************
*/
/*
****************************************************************************
* TYPES
****************************************************************************
*/
/*
****************************************************************************
* PUBLIC DATA
****************************************************************************
*/
IP_EXTERN int ipl2tp_occupied;
/*
****************************************************************************
* PUBLIC FUNCTIONS
****************************************************************************
*/
/*******************************************************************************
*
* ipl2tp_api_version - Get the IPL2TP API version.
*
* Get the IPL2TP API version.
*
* SYNOPSIS
* \cs
* int ipl2tp_api_version(void);
* \ce
*
* PARAMETERS
* \is
* \i None
* \ie
*
* RETURNS
* \is
* \i API version.
* \ie
*
* EXAMPLE
* \cs
* void example(void)
* {
* printf("IPL2TP API version: %d\n", ipl2tp_api_version());
* }
* \ce
*
* SEE ALSO
*
* ERRNO
* None
*/
IP_EXTERN const char *ipl2tp_version(void);
/*
*===========================================================================
* ipl2tp_api_version_api
*===========================================================================
* 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.
*
* \NOMANUAL
*
*/
IP_EXTERN int ipl2tp_api_version(void);
/*******************************************************************************
*
* ipl2tp_api_init - Initialize IPL2TP.
*
* Perform initialization of IPL2TP, i.e. setup internal data structures, allocate
* memory buffers and initialize library modules.
*
* SYNOPSIS
* \cs
* Ipl2tp_status ipl2tp_api_init(void);
* \ce
*
* PARAMETERS
* \is
* \i None
* \ie
*
* RETURNS
* \is
* \i 'IPL2TP_STATUS_OK' if success.
* \i 'IPL2TP_STATUS_NOMEM' if out of memory.
* \ie
*
*
* EXAMPLE
* \cs
* void example(void)
* {
* if (ipl2tp_api_init() != IPL2TP_STATUS_OK)
* {
* error(-1);
* }
* }
* \ce
*
* SEE ALSO
*
* ipl2tp_exit()
*
* ERRNO
* None
*/
IP_EXTERN Ipl2tp_status ipl2tp_api_init(void);
/*******************************************************************************
*
* ipl2tp_api_exit - Terminate IPL2TP.
*
* Terminate IPL2TP. This means returning all allocated memory, and clearing
* internal data.
*
* Note that all tunnels and sessions must be closed before calling ipl2tp_api_exit().
* This is done with a call to ipl2tp_api_close(). If tunnels and sessions take a while
* to close, e.g. in the case of network congestion, ipl2tp_api_exit() may fail.
*
* SYNOPSIS
* \cs
* Ipl2tp_status ipl2tp_api_exit(void);
* \ce
*
* PARAMETERS
* \is
* \i None
* \ie
*
* RETURNS
* \is
* \i 'IPL2TP_STATUS_OK' if success.
* \i 'IPL2TP_STATUS_STATE' if wrong state.
* \i 'IPL2TP_STATUS_BUSY' if tunnels/sessions open.
* \ie
*
* EXAMPLE
* \cs
* void example(void)
* {
* if (ipl2tp_api_exit() != IPL2TP_STATUS_OK)
* {
* error(-1);
* }
* }
* \ce
*
*
* SEE ALSO
*
* ipl2tp_api_init()
*
* ERRNO
* None
*/
IP_EXTERN Ipl2tp_status ipl2tp_api_exit(void);
/*******************************************************************************
*
* ipl2tp_api_open - Open and configure IPL2TP.
*
* Open and configure IPL2TP, which means that global attributes, default tunnel
* attributes and default session attributes are set.
*
* Refer to the functions ipl2tp_control(), ipl2tp_tunnel_control() and
* ipl2tp_session_control() for a description of available attributes.
*
* SYNOPSIS
* \cs
* Ipl2tp_status ipl2tp_api_open(Ipl2tp_attrobj attr, Ipl2tp_attrobj tattr_v2, Ipl2tp_attrobj tattr_v3, Ipl2tp_attrobj sattr_v2, Ipl2tp_attrobj sattr_v3);
* \ce
*
* PARAMETERS
* \is
* \i 'attr' Global IPL2TP attributes.
* \i 'tattr_v2' Default tunnel attributes for L2TPV2.
* \i 'tattr_v3 Default' tunnel attributes for L2TPV3.
* \i 'sattr_v2 Default' session attributes for L2TPV2.
* \i 'sattr_v3 Default' session attributes for L2TPV3.
* \ie
*
* RETURNS
* \is
* \i 'IPL2TP_STATUS_OK' if success.
* \i 'IPL2TP_STATUS_STATE' if wrong state.
* \i 'IPL2TP_STATUS_BADPARAM' if a bad attribute object(s) is present.
* \ie
*
* EXAMPLE
* \cs
* void example(void)
* {
* Ipl2tp_attrobj attr = IP_NULL;
*
* /@ Initialize @/
* ipl2tp_api_init();
*
* /@ Create attribute object @/
* ipl2tp_attr_strappend(&attr, IPL2TP_ATTR_SET_HOST_NAME, "myname");
* ipl2tp_api_open(attr, IP_NULL, IP_NULL, IP_NULL, IP_NULL);
* ipl2tp_attr_delete(&attr);
* }
* \ce
*
*
* SEE ALSO
*
* ipl2tp_api_close(), ipl2tp_api_attribute_set(), ipl2tp_api_attribute_get(),
* ipl2tp_api_session_attribute_get(), ipl2tp_api_session_attribute_set()
*
* ERRNO
* None
*/
IP_EXTERN 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_api_close - Close IPL2TP.
*
* Close IPL2TP, which means that all tunnels and sessions are terminated. Note that
* the close operations are only started with this call. The actual completion may take
* several seconds depending on the number of open tunnels/sessions and on network
* congestion.
*
* SYNOPSIS
* \cs
* Ipl2tp_status ipl2tp_api_close(void);
* \ce
*
* PARAMETERS
* \is
* \i None
* \ie
*
* RETURNS
* \is
* \i 'IPL2TP_STATUS_OK' if success.
* \i 'IPL2TP_STATUS_STATE' if wrong state.
* \ie
*
*
* EXAMPLE
* \cs
* void example(void)
* {
* if (ipl2tp_api_close() != IPL2TP_STATUS_OK)
* {
* printf("Close error\n");
* }
* }
* \ce
*
*
* SEE ALSO
*
* ipl2tp_api_open()
*
* ERRNO
* None
*/
IP_EXTERN Ipl2tp_status ipl2tp_api_close(void);
/*******************************************************************************
*
* ipl2tp_api_attribute_set - Set global IPL2TP attributes.
*
* Set the global IPL2TP attributes. Refer to the attribute functions named
* ipl2tp_attr_xxx() for information of how to enter values into and obtain values
* from an attribute object.
*
* A return status of IPL2TP_STATUS_BADPARAM indicates that at least one of
* the attributes had an invalid value. The invalid attribute may be located by using
* the ipl2tp_attr_status() function. The offending attribute has a status of
* IPL2TP_STATUS_BADPARAM.
*
* Attribute types are:
* \ts
* 'integer': 32-bit unsigned integer.
* 'integer64': 64-bit unsigned integer
* 'pointer': General-purpose pointer.
* 'string': Pointer to null-terminated character string.
* 'vector': General-purpose vector with variable length.
* 'address': Address.
* 'key': Tunnel/Session key information.
* \te
* All attributes that set a value may also be used in the ipl2tp_api_open() call.
*
* SYNOPSIS
* \cs
* Ipl2tp_status ipl2tp_api_attribute_set(Ipl2tp_attrobj attrobj);
* \ce
*
* PARAMETERS
* \is
* \i 'attrobj' Global IPL2TP attributes.
* \ie
*
* ATTRIBUTES
* \is
* \i 'IPL2TP_ATTR_SET_ENABLE_OUTGOING'
* \ts
* Type: integer.
* Set the outgoing flag that selects if outgoing tunnels or sessions may be created. A non-zero value enables the outgoing functionality.
* \te
*
* \i 'IPL2TP_ATTR_SET_ESTABLISH_TIMEOUT_SEC'
* \ts
* Type: integer.
* Set the timeout for tunnel and session establishment. If a tunnel or session establishment has not been completed within this time, a teardown is performed. Note that a tunnel that is created in the idle state is not affected by this timeout.
* \te
*
* \i 'IPL2TP_ATTR_SET_FIRST_RETRANSMIT_SEC'
* \ts
* Type: integer.
* Set the number of seconds until the first retransmission of a control message.
* \te
*
* \i 'IPL2TP_ATTR_SET_HELLO_TICK_SEC'
* \ts
* Type: integer.
* Set the resolution of the HELLO message transmission. A small value creates more accurate HELLO message intervals, to the expense of increased overhead.
* \te
*
* \i 'IPL2TP_ATTR_SET_HOST_NAME'
* \ts
* Type: string.
* Set the IPL2TP host name, reported to the peer host.
* \te
*
* \i 'IPL2TP_ATTR_SET_L2TP_WRITE_CALLBACK'
* \ts
* Type: pointer.
* Set the function pointer of the L2TP write callback routine. The callback is called whenever there is an L2TP message that should be transported to the LNS. This is typically a routine that writes to an UDP socket. The callback routine uses the Ipl2tp_write_callback() prototype.
* \te
*
* \i 'IPL2TP_ATTR_SET_OPEN_EXCLUSIVE'
* \ts
* Type: integer.
* Set the exclusive tunnel flag. IPL2TP_MIB_YES means that it is possible to create multiple tunnels to the same LNS, and that IPL2TP tries to create new tunnels for all future sessions.
* \te
*
* \i 'IPL2TP_ATTR_SET_TUNNEL_ZOMBIE_SEC'
* \ts
* Type: integer.
* Set the number of seconds a tunnel is kept alive after a teardown. This time is to ensure that the reliable control channel is able to complete the delivery of a message before the tunnel disappears.
* \te
*
* \i 'IPL2TP_ATTR_SET_l2tpAdminState'
* \ts
* Type: integer.
* Set the global administrative state of IPL2TP.
* Valid values are:
* 'IPL2TP_MIB_ENABLED' Enable IPL2TP
* 'IPL2TP_MIB_DISABLED' Disable IPL2TP
* When setting IPL2TP to the disabled state, an immediate teardown of all open tunnels is performed.
* \te
*
* \i 'IPL2TP_ATTR_SET_l2tpDrainTunnels'
* \ts
* Type: integer.
* Set the global draining state of IPL2TP. When draining is enabled, no additional tunnel or session establishments are accepted.
* Valid values are:
* 'IPL2TP_MIB_YES' Enable draining
* 'IPL2TP_MIB_NO' Disable draining
* When draining is enabled and the last tunnel is closed, the administrative state of IPL2TP transitions to 'IPL2TP_MIB_DISABLED'.
* \te
*
* \i 'IPL2TP_ATTR_SET_l2tpFirmwareRev'
* \ts
* Type: integer.
* Set IPL2TP firmware revision number. For example, version 1.0.5 is returned as the decimal number 105.
* \te
*
* \i 'IPL2TP_ATTR_SET_l2tpVendorName'
* \ts
* Type: string.
* Set the IPL2TP vendor name.
* \te
*
* \i 'IPL2TP_ATTR_SET_ENABLE_L2TP_V2'
* \ts
* Type: integer.
* Enable or disable L2TP version 2.
* A value of 'IPL2TP_MIB_YES' means enabled, and a value of 'IPL2TP_MIB_NO' means disabled.
* \te
*
* \i 'IPL2TP_ATTR_SET_ENABLE_L2TP_V3'
* \ts
* Type: integer.
* Enable or disable L2TP version 3.
* A value of 'IPL2TP_MIB_YES' means enabled and a value of 'IPL2TP_MIB_NO' means disabled.
* \te
*
* \i 'IPL2TP_ATTR_SET_CLOSE_UNUSED_TUNNELS'
* \ts
* Type: integer.
* If 'IPL2TP_MIB_YES' (default), the L2TP system closes tunnels when all sessions belonging to it are closed. If 'IPL2TP_MIB_NO', the tunnels remain open.
* \te
* \ie
*
* RETURNS
* \is
* \i 'IPL2TP_STATUS_OK' if success.
* \i 'IPL2TP_STATUS_BADPARAM' if a bad attribute object(s) is present.
* \ie
*
* EXAMPLE
* \cs
* void example(void)
* {
* Ipl2tp_attrobj attrobj = IP_NULL;
*
* /@ Create attribute object @/
* ipl2tp_attr_iappend(&attrobj, IPL2TP_ATTR_SET_ENABLE_OUTGOING, IPL2TP_MIB_YES);
*
* /@ Set parameter and free attribute object @/
* ipl2tp_api_attribute_set(attrobj);
* ipl2tp_attr_delete(&attrobj);
* }
* \ce
*
*
* SEE ALSO
*
* ipl2tp_attr_new(), ipl2tp_attr_delete(), ipl2tp_attr_iappend(),
* ipl2tp_attr_pappend()
*
* ERRNO
* None
*/
IP_EXTERN Ipl2tp_status ipl2tp_api_attribute_set(Ipl2tp_attrobj attr);
/*******************************************************************************
*
* ipl2tp_api_attribute_get - Get global IPL2TP attributes.
*
* Get the global IPL2TP attributes. Refer to the attribute functions named
* ipl2tp_attr_xxx() for information of how to enter values into and obtain values
* from an attribute object.
*
* A return status of IPL2TP_STATUS_BADPARAM indicates that at least one of
* the attributes had an invalid value. The invalid attribute may be located by using
* the ipl2tp_attr_status() function. The offending attribute has a status of
* IPL2TP_STATUS_BADPARAM.
*
* Attribute types are:
* \ts
* 'integer' 32-bit unsigned integer.
* 'integer64' 64-bit unsigned integer.
* 'pointer' General-purpose pointer.
* 'string' Pointer to null-terminated character string.
* 'vector' General-purpose vector with variable length.
* 'address' Address.
* 'key' Tunnel/Session key information.
* \te
* All attributes that set a value may also be used in the ipl2tp_api_open() call.
*
* When invoking 'ipl2tp_api_attribute_get', the replies are appended to the
* 'replies' variable. The 'replies' variable is dynamically allocated by the system,
* and need only be initialized to IP_NULL prior to the call.
*
* SYNOPSIS
* \cs
* Ipl2tp_status ipl2tp_api_attribute_get(Ipl2tp_attrobj attrobj, Ipl2tp_attrobj *replies);
* \ce
*
* PARAMETERS
* \is
* \i 'attrobj' Global IPL2TP attributes.
*
* \i 'replies' Pointer to the attribute object that contains the replies.
* \ie
*
* ATTRIBUTES
* \is
* \i 'IPL2TP_ATTR_GET_ENABLE_OUTGOING'
*\ts
* Type: integer.
* Get the outgoing flag that selects if outgoing tunnels or sessions may be created. A non-zero value enables the outgoing functionality.
* \te
*
* \i 'IPL2TP_ATTR_GET_ESTABLISH_TIMEOUT_SEC'
* \ts
* Type: integer.
* Get the timeout for tunnel and session establishment. If a tunnel or session establishment has not been completed within this time, a teardown is performed.
* Note that a tunnel that is created in the idle state is not affected by this timeout.
* \te
*
* \i 'IPL2TP_ATTR_GET_FIRST_RETRANSMIT_SEC'
* \ts
* Type: integer.
* Get the number of seconds until the first retransmission of a control message.
* \te
*
* \i 'IPL2TP_ATTR_GET_HELLO_TICK_SEC'
* \ts
* Type: integer.
* Get the resolution of the HELLO message transmission. A small value creates more accurate HELLO message intervals, to the expense of increased overhead.
* \te
*
* \i 'IPL2TP_ATTR_GET_HOST_NAME'
* \ts
* Type: string.
* Get the IPL2TP host name reported to the peer host.
* \te
*
* \i 'IPL2TP_ATTR_GET_L2TP_WRITE_CALLBACK'
* \ts
* Type: pointer.
* Get the function pointer of the L2TP write callback routine. The callback is called whenever there is an L2TP message that should be transported to the LNS. This is typically a routine that writes to an UDP socket. The callback routine uses the Ipl2tp_write_callback() prototype.
* \te
*
* \i 'IPL2TP_ATTR_GET_OPEN_EXCLUSIVE'
* \ts
* Type: integer.
* Get the exclusive tunnel flag.
* 'IPL2TP_MIB_YES' means that it is possible to create multiple tunnels to the same LNS, and that IPL2TP tries to create new tunnels for all future sessions.
* \te
*
* \i 'IPL2TP_ATTR_GET_OPEN_SESSIONS'
* \ts
* Type: integer.
* Get the number of currently open sessions in all tunnels.
* \te
*
* \i 'IPL2TP_ATTR_GET_OPEN_TUNNELS'
* \ts
* Type: integer.
* Get the number of currently open tunnels.
* Note that this also includes tunnels in the zombie state, i.e. tunnels that have been torn down and are waiting for the reliable transport to complete their operation.
* \te
*
* \i 'IPL2TP_ATTR_GET_TUNNEL_ZOMBIE_SEC'
* \ts
* Type: integer.
* Get the number of seconds a tunnel is kept alive after a teardown. This time is to ensure that the reliable control channel is able to complete the delivery of a message before the tunnel disappears.
* \te
*
* \i 'IPL2TP_ATTR_GET_l2tpAdminState'
* \ts
* Type: integer.
* Get the global administrative state of IPL2TP.
* Valid values are:
* 'IPL2TP_MIB_ENABLED' IPL2TP enabled
* 'IPL2TP_MIB_DISABLED' IPL2TP disabled
* \te
*
* \i 'IPL2TP_ATTR_GET_l2tpDrainTunnels'
* \ts
* Type: integer.
* Get the global draining state of IPL2TP.
* Note that getting this attribute always returns 'IPL2TP_MIB_NO'. To check the current state, use the 'IPL2TP_ATTR_GET_l2tpDrainingTunnels' attribute.
* \te
*
* \i 'IPL2TP_ATTR_GET_l2tpDrainingTunnels'
* \ts
* Type: integer.
* Get the global draining state of IPL2TP.
* Valid values are:
* 'IPL2TP_MIB_YES' Draining is enabled
* 'IPL2TP_MIB_NO' Draining is disabled
* \te
*
* \i 'IPL2TP_ATTR_GET_l2tpFirmwareRev'
* \ts
* Type: integer.
* Get the IPL2TP firmware revision number. For example, version 1.0.5 is returned as the decimal number 105.
* \te
*
* \i 'IPL2TP_ATTR_GET_l2tpProtocolVersion'
* \ts
* Type: vector.
* Get the supported L2TP protocol versions. The value is returned as a vector of octet pairs, where the first octet indicates the version, and the second contains the revision.
* \te
*
* \i 'IPL2TP_ATTR_GET_l2tpVendorName'
* \ts
* Type: string.
* Get the IPL2TP vendor name.
* \te
*
* \i 'IPL2TP_ATTR_GET_ENABLE_L2TP_V2'
* \ts
* Type: integer.
* Get the L2TP enabled value for version 2.
* A value of 'IPL2TP_MIB_YES' means enabled, and a value of 'IPL2TP_MIB_NO' means disabled.
* \te
*
* \i 'IPL2TP_ATTR_GET_ENABLE_L2TP_V3'
* \ts
* Type: integer.
* Get the L2TP enabled value for version 3.
* A value of 'IPL2TP_MIB_YES' means enabled and a value of 'IPL2TP_MIB_No' means disabled.
* \te
*
* \i 'IPL2TP_ATTR_GET_CLOSE_UNUSED_TUNNELS'
* \ts
* Type: integer.
* If 'IPL2TP_MIB_YES' (default), the L2TP system closes tunnels when all sessions belonging to it are closed. If 'IPL2TP_MIB_NO', tunnels remains open.
* \te
* \ie
*
* RETURNS
* \is
* \i 'IPL2TP_STATUS_OK' if success.
* \i 'IPL2TP_STATUS_BADPARAM' if a bad attribute object(s) is present.
* \ie
*
* EXAMPLE
* \cs
* void example(void)
* {
* Ipl2tp_attrobj attrobj = IP_NULL;
* Ipl2tp_attrobj replies = IP_NULL;
*
* /@ Create attribute object @/
* ipl2tp_attr_add_query(&attrobj, IPL2TP_ATTR_SET_ENABLE_OUTGOING);
* ipl2tp_api_attribute_get(attrobj, &replies);
*
* /@ Free attribute object @/
* ipl2tp_attr_delete(&attrobj);
* ipl2tp_attr_delete(&replies);
* }
* \ce
*
* SEE ALSO
*
* ipl2tp_api_attribute_set()
*
* ERRNO
* None
*/
IP_EXTERN Ipl2tp_status ipl2tp_api_attribute_get(Ipl2tp_attrobj attr,
Ipl2tp_attrobj *replies);
/*******************************************************************************
*
* ipl2tp_api_l2tp_input - Send an L2TP packet to IPL2TP for processing.
*
* The buffer pointer is a pointer to the original starting point of the buffer. Payload points to the
* beginning of the input. If the IP transport method is used, payload must point
* PAST the IP header. That is, the IP header must be EXCLUDED from the data
* sent into the function.
*
* SYNOPSIS
* \cs
* Ipl2tp_status ipl2tp_api_l2tp_input(void *buffer, void *payload, Ip_u16 length, union Ip_sockaddr_union *addr, int transport);
* \ce
*
* PARAMETERS
* \is
* \i 'buffer' Pointer to original buffer.
* \i 'payload' Pointer to the packet payload, i.e. the L2TP header.
* \i 'length' Length of payload.
* \i 'addr' IP address of sender.
* \i 'transport' The transport method is either 'IPL2TP_ATTR_TRANSPORT_UDP' or 'IPL2TP_ATTR_TRANSPORT_IP'.
* \ie
*
* RETURNS
* \is
* \i 'IPL2TP_STATUS_OK' if success.
* \i 'IPL2TP_STATUS_BADID' if the message session ID is invalid.
* \i 'IPL2TP_STATUS_NOTL2TP' if this is a non-L2TP message.
* \i 'IPL2TP_STATUS_MALFORMED' if the message is malformed.
* \i 'IPL2TP_STATUS_IGNORE' if the message is ignored.
* \i 'IPL2TP_STATUS_TEARDOWN'' if a tunnel or session teardown is required.
* \i Additional error codes may be returned by the user-specified data callback routine.
* \ie
*
* EXAMPLE
* \cs
* void example(void)
* {
* struct Ip_sockaddr_in in4;
* Ip_u8 *buffer;
* int length;
*
* /@ Get buffer @/
* buffer = malloc(IPL2TP_MAX_MESSAGE_SIZE + EXTRA);
* in4.sin_family = IP_AF_INET;
* in4.sin_len = sizeof(in4);
*
* /@ Read from socket @/
* if ((length = read_socket(buffer + EXTRA, &in4.sin_addr)) > 0)
* {
* ipl2tp_api_l2tp_input(buffer + EXTRA, (Ip_u16)length,
* &in4, buffer, IPL2TP_ATTR_TRANSPORT_UDP);
* }
* }
* \ce
*
*
* SEE ALSO
*
* ipl2tp_ppp_input(), Ipl2tp_write_callback(), Ipl2tp_data_callback()
*
* ERRNO
* None
*/
IP_EXTERN Ipl2tp_status ipl2tp_api_l2tp_input(void *buffer,
void *payload,
Ip_u16 length,
union Ip_sockaddr_union *addr,
int transport);
/*******************************************************************************
*
* ipl2tp_api_errname - Return a textual description of an error code.
*
* Return a textual description of an error code.
*
* SYNOPSIS
* \cs
* char *ipl2tp_api_errname(Ipl2tp_status status);
* \ce
*
* PARAMETERS
* \is
* \i 'status' Status code obtained in an IPL2TP call.
* \ie
*
* RETURNS
* \is
* \i A string describing the error.
* \ie
*
* EXAMPLE
* \cs
* void example(void)
* {
* Ipl2tp_status status;
*
* if ((status = ipl2tp_api_exit()) != IPL2TP_STATUS_OK)
* {
* printf("Error %s\n", ipl2tp_api_errname(status));
* }
* }
* \ce
*
* SEE ALSO
*
* ERRNO
* None
*/
IP_EXTERN CONST char *ipl2tp_api_errname(Ipl2tp_status status);
/*
*===========================================================================
* 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.
*
* \NOMANUAL
*
*/
IP_EXTERN Ipl2tp_attr_info *ipl2tp_api_attribute_find(Ipl2tp_attr_info *info,
char *name,
char **value);
/*
*===========================================================================
* 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:
*
* \NOMANUAL
*
*/
IP_PUBLIC Ip_bool ipl2tp_api_attribute_parse(Ipl2tp_attrobj *attr,
Ipl2tp_attr_info *info,
char **value);
/*
*===========================================================================
* 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.
*
* \NOMANUAL
*
*/
IP_EXTERN Ip_bool ipl2tp_api_attribute_address_parse(char *str,
union Ip_sockaddr_union *uaddr);
/*
*===========================================================================
* ipl2tp_api_attribute_info
*===========================================================================
* Description: Map a tag to an info structure
* Parameters: tag - The tag.
* Returns: The attribute's information structure.
*
* \NOMANUAL
*
*/
IP_EXTERN Ipl2tp_attr_info *ipl2tp_api_attribute_info(int tag);
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
#endif
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,283 @@
/*
******************************************************************************
* HEADER FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp_cmd.h,v $ $Revision: 1.9 $
* $Source: /home/interpeak/CVSRoot/ipl2tp/include/ipl2tp_cmd.h,v $
* $Author: tneale $ $Date: 2010-06-04 18:01:11 $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelius@interpeak.se>
******************************************************************************
*/
#ifndef IPL2TP_CMD_H
#define IPL2TP_CMD_H
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 FUNCTIONS
****************************************************************************
*/
extern int ipl2tp_buffer_free;
/*
****************************************************************************
* PUBLIC FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipl2tp_cmd_session_key
*===========================================================================
* Description: Find a session key based on ifindex
* Parameters: ifindex - The interface index.
* Returns:
*
*/
IP_EXTERN Ipl2tp_key *ipl2tp_cmd_session_key(Ip_u32 ifindex);
/*
*===========================================================================
* ipl2tp_cmd_session_hash_add
*===========================================================================
* Description: Add an interface index - session ID pair to the hash table.
* Parameters: ifindex - The interface index.
* skey - pointer to key having session ID.
* Returns: None.
*
*/
IP_EXTERN Ip_err ipl2tp_cmd_session_hash_add(Ip_u32 ifindex, Ipl2tp_key *skey);
/*
*===========================================================================
* ipl2tp_cmd_session_hash_remove
*===========================================================================
* Description: Remove an interface index - session ID pair from the hash table.
* Parameters: ifindex - The interface index.
* skey - pointer to key having session ID.
* Returns: None.
*
*/
IP_EXTERN Ip_err ipl2tp_cmd_session_hash_remove(Ip_u32 ifindex);
/*
*===========================================================================
* ipl2tp_cmd_topen
*===========================================================================
* Description: Tunnel open command.
* Parameters: argc - No of arguments.
* argv - Argument vector.
* Returns: 0 if success.
*
*/
IP_EXTERN int ipl2tp_cmd_topen(int argc, char **argv);
/*
*===========================================================================
* ipl2tp_cmd_tclose
*===========================================================================
* Description: Tunnel close command.
* Parameters: argc - No of arguments.
* argv - Argument vector.
* Returns: 0 if success.
*
*/
IP_EXTERN int ipl2tp_cmd_tclose(int argc, char **argv);
/*
*===========================================================================
* ipl2tp_cmd_sopen
*===========================================================================
* Description: Session open command.
* Parameters: argc - No of arguments.
* argv - Argument vector.
* Returns: 0 if success.
*
*/
IP_EXTERN int ipl2tp_cmd_sopen(int argc, char **argv);
/*
*===========================================================================
* ipl2tp_cmd_sclose
*===========================================================================
* Description: Session close command.
* Parameters: argc - No of arguments.
* argv - Argument vector.
* Returns: 0 if success.
*
*/
IP_EXTERN int ipl2tp_cmd_sclose(int argc, char **argv);
/*
*===========================================================================
* ipl2tp_cmd_attr
*===========================================================================
* Description: Attribute command.
* Parameters: argc - No of arguments.
* argv - Argument vector.
* Returns: 0 if success.
*
*/
IP_EXTERN int ipl2tp_cmd_attr(int argc, char **argv);
/*
*===========================================================================
* ipl2tp_cmd_tattr
*===========================================================================
* Description: Tunnel attribute command.
* Parameters: argc - No of arguments.
* argv - Argument vector.
* Returns: 0 if success.
*
*/
IP_EXTERN int ipl2tp_cmd_tattr(int argc, char **argv);
/*
*===========================================================================
* ipl2tp_cmd_sattr
*===========================================================================
* Description: Session attribute command.
* Parameters: argc - No of arguments.
* argv - Argument vector.
* Returns: 0 if success.
*
*/
IP_EXTERN int ipl2tp_cmd_sattr(int argc, char **argv);
/*
*===========================================================================
* ipl2tp_cmd_stats
*===========================================================================
* Description: Statistics command.
* Parameters: argc - No of arguments.
* argv - Argument vector.
* Returns: 0 if success.
*
*/
IP_EXTERN int ipl2tp_cmd_stats(int argc, char **argv);
/*
*===========================================================================
* ipl2tp_cmd_tstats
*===========================================================================
* Description: Tunnel statistics command.
* Parameters: argc - No of arguments.
* argv - Argument vector.
* Returns: 0 if success
*
*/
IP_EXTERN int ipl2tp_cmd_tstats(int argc, char **argv);
/*
*===========================================================================
* ipl2tp_cmd_sstats
*===========================================================================
* Description: Session statistics command.
* Parameters: argc - No of arguments.
* argv - Argument vector.
* Returns: 0 if success
*
*/
IP_EXTERN int ipl2tp_cmd_sstats(int argc, char **argv);
/*
*===========================================================================
* ipl2tp_cmd_poke
*===========================================================================
* Description: Setup poke information for incoming messages.
* Parameters: argc - No of arguments.
* argv - Argument vector.
* Returns: 0 if success.
*
*/
IP_EXTERN int ipl2tp_cmd_poke(int argc, char **argv);
/*
*===========================================================================
* ipl2tp_cmd_main
*===========================================================================
* Description: Main L2TP command.
* Parameters: argc - No of arguments.
* argv - Argument vector.
* Returns: 0 if success.
*
*/
IP_EXTERN int ipl2tp_cmd_main(int argc, char **argv);
/*
*===========================================================================
* ipl2tp_cmdd
*===========================================================================
* Description: Init & socket daemon.
* Parameters:
* Returns:
*
*/
IP_EXTERN void ipl2tp_cmdd(void);
#ifdef __cplusplus
}
#endif
#endif
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -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
****************************************************************************
*/