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

873 lines
28 KiB
C

/*
******************************************************************************
* 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
****************************************************************************
*/