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