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

1077 lines
30 KiB
C

/*
******************************************************************************
* SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipl2tp_example.c,v $ $Revision: 1.11 $
* $Source: /home/interpeak/CVSRoot/ipl2tp/config/ipl2tp_example.c,v $
* $Author: tneale $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
*
******************************************************************************
*/
/*
****************************************************************************
* DESCRIPTION
****************************************************************************
*
* L2TP example file.
*/
/*
****************************************************************************
* INCLUDE FILES
****************************************************************************
*/
#ifdef IP_PORT_VXWORKS
#ifdef IPCOM_USE_CLIB_PROTO
#undef IPCOM_USE_CLIB_PROTO
#endif
#ifndef IPCOM_KERNEL
#define IPCOM_KERNEL
#endif
/* Synchronize build with configuration definitions */
#include "ipcom_config.h"
#ifdef INCLUDE_IPPPP
#define IPPPP
#endif
#ifdef INCLUDE_IPL2TP
#define IPL2TP
#endif
#ifdef IPPPP
#include "ipppp_config.h"
#include "ipppp.h"
#endif
#include <ipcom_hash.h>
#include <ipl2tp_api.h>
#include <ipl2tp_attr.h>
#include <ipl2tp_example.h>
#include <ipl2tp_example_v2.h>
#include <ipl2tp_example_v3.h>
#include <ipcom_netif.h>
#include <ipcom_syslog.h>
#include <ipcom_clib.h>
#include <ipcom_err.h>
#include <ipcom_ipd.h>
#include "ipl2tp.h"
#include "ipl2tp_api_session.h"
#else
#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 "ipnet_h.h"
#include "ipl2tp.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"
#include "ipl2tp_example_v3.h"
#ifdef IPPPP
#include "ipppp.h"
#endif
#endif /* IP_PORT_VXWORKS */
/*
****************************************************************************
* DEFINES
****************************************************************************
*/
/* L2TP control port */
#define IPL2TP_PORT_NUMBER 1701
/* Extra header space allocated before L2TP header */
#define HEADER_SPACE 0
#define LF "\n"
#define ARGC_NAME -1
#define ARGC_DESCR -2
/* PPP protocols */
#define PPPP_LCP 0xc021 /* Link Control Protocol */
#define PPPP_IPCP 0x8021 /* IP Control Protocol */
#define PPPP_PAP 0xc023 /* Password Authentication Protocol */
#define PPPP_CHAP 0xc223 /* Cryptographic Handshake Auth. Prot. */
#define PPPP_IP 0x0021 /* Internet Protocol */
/* PPP CP (LCP, IPCP, etc) codes */
#define PPP_CP_CONFREQ 1 /* Configuration Request */
#define PPP_CP_CONFACK 2 /* Configuration Ack */
#define PPP_CP_CONFNAK 3 /* Configuration Nak */
#define PPP_CP_CONFREJ 4 /* Configuration Reject */
#define PPP_CP_TERMREQ 5 /* Termination Request */
#define PPP_CP_TERMACK 6 /* Termination Ack */
#define PPP_CP_CODEREJ 7 /* Code Reject */
#define PPP_CP_PROTREJ 8 /* Protocol Reject, */
#define PPP_CP_ECHOREQ 9 /* Echo Request */
#define PPP_CP_ECHOREP 10 /* Echo Reply */
#define PPP_CP_DISCREQ 11 /* Discard Request */
#ifndef IP_IPPROTO_L2TP
#define IP_IPPROTO_L2TP 115
#endif
/*
****************************************************************************
* TYPES
****************************************************************************
*/
typedef struct Ipl2tp_cache_head
{
struct Ipl2tp_cache_head *next;
}
Ipl2tp_cache_head;
/*
****************************************************************************
* LOCAL DATA
****************************************************************************
*/
/* List of free cache buffers */
IP_STATIC Ipl2tp_cache_head *free_list = IP_NULL;
/* Main socket fd */
IP_STATIC Ip_fd udp_fd = IP_INVALID_SOCKET;
IP_STATIC Ip_fd ip_fd = IP_INVALID_SOCKET;
/* Output flag */
IP_STATIC int l2tp_output = 0;
/*
****************************************************************************
* PUBLIC DATA
****************************************************************************
*/
int ipl2tp_buffer_free = 1;
Ipcom_hash *ipl2tp_example_sessions = IP_NULL;
Ipcom_list ipl2tp_example_fds;
/*
****************************************************************************
* EXTERNAL DATA
****************************************************************************
*/
/* Poke vars */
IP_EXTERN int poke_count;
IP_EXTERN int poke_mtype;
IP_EXTERN int poke_avp;
IP_EXTERN int poke_offset;
IP_EXTERN int poke_value;
IP_EXTERN int poke_skip;
IP_EXTERN Ip_u16 session_table[];
IP_EXTERN Ip_u16 session_table_size;
/*
****************************************************************************
* PROTOTYPES
****************************************************************************
*/
IP_PUBLIC Ip_err ipl2tp_create(void);
IP_PUBLIC Ip_err ipl2tp_start(void);
#if 0
/* PPP/L2TPv2 integration for third-party PPP */
IP_PUBLIC int ppp_input_hook(int ifindex,
void *pppbuf,
Ip_size_t length,
Ip_size_t offset);
IP_PUBLIC int ppp_output_hook(Ip_u32 ifindex,
void *pppbuf,
Ip_u32 length,
Ip_u32 offset);
IP_PUBLIC int ppp_open_hook(int ifindex,
int protocol);
IP_PUBLIC int ppp_writedone_hook(int ifindex,
void *pppbuf,
void *cookie);
#endif
/*
****************************************************************************
* LOCAL FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipl2tp_data_obj_hash_tunnel_assigned
*===========================================================================
* Description:
* Parameters:
* Returns:
*/
IP_STATIC unsigned
ipl2tp_example_obj_hash_key(Ipl2tp_key *key)
{
/* Hash the version first */
unsigned val = ipcom_hash_update(&key->version,
sizeof(key->version),
0);
/* Hash the key ID */
return ipcom_hash_update(&key->ident,
sizeof(key->ident),
val);
}
/*
*===========================================================================
* ipl2tp_data_cmp_tunnel_assigned
*===========================================================================
* Description:
* Parameters:
* Returns:
*/
IP_STATIC Ip_bool
ipl2tp_example_cmp_key(Ipl2tp_key *obj_key,
Ipl2tp_key *key)
{
/* Addr, Version & ID must match */
return obj_key->version == key->version && obj_key->ident == key->ident;
}
/*
*===========================================================================
* ipl2tp_cache_malloc
*===========================================================================
* Description: Allocate buffer from local cache
* Parameters:
* Returns:
*
*/
IP_STATIC void *
ipl2tp_cache_malloc(Ip_u32 size)
{
Ipl2tp_cache_head *head;
Ip_u32 msr;
msr = ipcom_interrupt_disable();
if (free_list != IP_NULL)
{
head = free_list;
free_list = head->next;
ipcom_interrupt_enable(msr);
}
else
{
ipcom_interrupt_enable(msr);
if ((head = ipcom_malloc(sizeof(*head) + size)) == IP_NULL)
{
return IP_NULL;
}
}
return head + 1;
}
/*
*===========================================================================
* ipl2tp_cache_free
*===========================================================================
* Description: Return buffer to local cache. Allows data to be freed
* within interrupt context.
* Parameters:
* Returns:
*
*/
IP_STATIC void
ipl2tp_cache_free(void *buf)
{
Ipl2tp_cache_head *head = buf;
Ip_u32 msr;
head--;
msr = ipcom_interrupt_disable();
head->next = free_list;
free_list = head;
ipcom_interrupt_enable(msr);
}
/*
*===========================================================================
* ipl2tp_ppp_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_ppp_data_cb(void *user_data, Ipl2tp_key *id,
void *buffer, void *payload, Ip_u16 length)
{
#ifdef IP_PORT_VXWORKS
int ifindex = (long)user_data;
#else
int ifindex = (int)user_data;
#endif
(void)id;
(void)buffer;
(void)payload;
(void)length;
/* Do the write */
if (ifindex != -1)
{
l2tp_output = 1;
/*
** Insert PPP write routine here, e.g.:
** ppplink_write(ifindex, payload, length, HEADER_SPACE, buffer);
*/
#ifdef IPPPP_USE_PPPL2TP
if (user_data == (void *)0x0)
{
#ifdef IPPPP_USE_PPPL2TP_LNS
if ((ipcom_sysvar_get_conf_as_int("ipppp.l2tp.server", IP_NULL, IP_NULL) != 1) ||
((ifindex = ipppp_pppl2tp_if_create_server(id)) < 0))
{
ipcom_printf ("Failed to create new server interface."IP_LF);
return;
}
#else
ipcom_printf ("Data callback: no ifindex."IP_LF);
return;
#endif
}
ipppp_pppl2tp_input (ifindex, payload, length);
#endif
l2tp_output = 0;
}
}
/*
*===========================================================================
* ipl2tp_l2tp_read
*===========================================================================
* Description: Read a L2TP control message via UDP.
* Parameters:
* Returns:
*
*/
IP_STATIC int
ipl2tp_l2tp_read(Ip_fd fd,
Ip_u8 **buf,
union Ip_sockaddr_union *ipp)
{
Ip_socklen_t faddrsize = sizeof(*ipp);
int length;
Ip_u8 *buffer;
/* Get buffer */
if ((buffer = ipl2tp_cache_malloc(HEADER_SPACE +
IPL2TP_MAX_MESSAGE_SIZE)) == IP_NULL)
{
ipcom_printf("Out of memory when reading L2TP socket"IP_LF);
return 0;
}
/* Receive an UDP packet */
if ((length = ipcom_recvfrom(fd, buffer, IPL2TP_MAX_MESSAGE_SIZE, 0,
&ipp->sa,
&faddrsize)) < 0)
{
ipcom_printf("ipl2tp_l2tp_read() failed with errno: %d"IP_LF,
ipcom_errno);
ipl2tp_cache_free(buffer);
return 0;
}
*buf = buffer;
return length;
}
/*
*===========================================================================
* ipl2tp_l2tp_write
*===========================================================================
* Description: Send a L2TP control message via UDP.
* Parameters: message - Message to send.
* addr - Destination IP address.
* Returns:
*
*/
IP_STATIC int
ipl2tp_l2tp_write(void *user_data,
Ipl2tp_key *key,
struct Ip_iovec *iov,
int iovlen,
union Ip_sockaddr_union *addr,
int transport)
{
int sz;
int fd;
struct Ip_msghdr msg;
(void)user_data;
(void)key;
if (transport == IPL2TP_ATTR_TRANSPORT_UDP)
{
fd = udp_fd;
}
else if (transport == IPL2TP_ATTR_TRANSPORT_IP)
{
fd = ip_fd;
}
else
{
ipcom_printf("Bad transport %u!!"IP_LF, transport);
return -1;
}
ipcom_memset(&msg, 0, sizeof(msg));
/* Set it up */
msg.msg_iov = iov;
msg.msg_iovlen = iovlen;
msg.msg_name = &addr->sa;
msg.msg_namelen = addr->sa.sa_len;
/* Transmit the UDP packet */
if ((sz = ipcom_sendmsg(fd, &msg, 0)) < 0)
{
ipcom_printf("ipl2tp_l2tp_write() failed with errno: %d"IP_LF,
ipcom_errno);
return 0;
}
return sz;
}
#if 0
/* L2TP Debugging */
/*
*===========================================================================
* peek_poke
*===========================================================================
* Description: Peek and optionally poke at incoming L2TP data.
* Parameters: data - Data buffer.
* Returns:
*
*/
IP_STATIC int
peek_poke(Ip_u8 *data)
{
if (poke_count != 0 && /* Poke active */
(data[0] & 0x80) != 0 && /* Control msg */
(poke_mtype == 0 || /* Wildcard */
(data[3] > 12 && /* Non-ZLB */
poke_mtype == data[19]))) /* Msg type match */
{
poke_count--;
if (poke_skip != 0)
{
/* Skip message */
return 0;
}
if (poke_avp != 0)
{
int mindex;
int length;
/* Find correct AVP */
for (mindex = 12, length = 1;
length != 0 && mindex < data[3];
mindex += length)
{
/* Only allow 8-bit length */
length = data[mindex + 1];
if (data[mindex + 5] == poke_avp)
{
data[mindex + poke_offset] = (Ip_u8)poke_value;
break;
}
}
}
else
{
data[poke_offset] = (Ip_u8)poke_value;
}
}
return 1;
}
#endif
/*
*===========================================================================
* ipl2tps
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC
IPCOM_PROCESS(ipl2tps)
{
Ip_fd ipd_fd = IP_INVALID_SOCKET;
Ip_bool ipd_init = 0;
#ifdef IPPPP_USE_PPPL2TP
Ip_fd ipl2tp_ppp_ipc_recv_fd = IP_INVALID_SOCKET;
#endif
ipcom_proc_init();
#ifdef IPPPP_USE_PPPL2TP
if ((ipl2tp_ppp_ipc_recv_fd = ipppp_pppl2tp_pkt_que_open()) == IP_INVALID_SOCKET)
{
ipcom_printf("Cannot allocate data packet output socket, errno: %d"IP_LF, ipcom_errno);
goto leave;
}
#endif
/* Get socket */
if ((udp_fd = ipcom_socket(IP_AF_INET, IP_SOCK_DGRAM, IP_IPPROTO_UDP)) < 0)
{
ipcom_printf("Cannot allocate socket, errno: %d"IP_LF,
ipcom_errno);
goto leave;
}
else
{
union Ip_sockaddr_union uaddr;
/* Bind to L2TP port */
ipcom_memset(&uaddr, 0, sizeof(uaddr));
uaddr.sin.sin_family = IP_AF_INET;
uaddr.sin.sin_addr.s_addr = IP_INADDR_ANY;
uaddr.sin.sin_port = ip_htons(IPL2TP_PORT_NUMBER);
uaddr.sin.sin_len = sizeof(struct Ip_sockaddr_in);
if (ipcom_bind(udp_fd, &uaddr.sa, sizeof(struct Ip_sockaddr_in)) < 0)
{
ipcom_printf("Cannot bind socket, errno: %d"IP_LF,
ipcom_errno);
ipcom_socketclose(udp_fd);
goto leave;
}
}
/* Get socket */
if ((ip_fd = ipcom_socket(IP_AF_INET, IP_SOCK_RAW, IP_IPPROTO_L2TP)) < 0)
{
ipcom_printf("Cannot allocate socket, errno: %d"IP_LF,
ipcom_errno);
ipcom_socketclose(udp_fd);
goto leave;
}
/* Init IPD */
if (ipd_init == 0 &&
ipcom_ipd_init("ipl2tp", IPCOM_SUCCESS, &ipd_fd) != IPCOM_SUCCESS)
{
ipcom_printf("Cannot initialize ipd: %s"IP_LF,
ipcom_strerror(ipcom_errno));
goto leave;
}
ipd_init = 1;
/* Enter read loop (never return) */
for (;;)
{
Ip_fd_set fds;
Ipl2tp_example_fd_entry_t *fd;
int fd_max;
struct Ip_timeval tv;
int ret;
IP_FD_ZERO(&fds);
IP_FD_SET(udp_fd, &fds);
IP_FD_SET(ip_fd, &fds);
IP_FD_SET(ipd_fd, &fds);
fd_max = IP_MAX(udp_fd, ip_fd);
fd_max = IP_MAX(fd_max, ipd_fd);
#ifdef IPPPP_USE_PPPL2TP
IP_FD_SET(ipl2tp_ppp_ipc_recv_fd, &fds);
fd_max = IP_MAX(fd_max, ipl2tp_ppp_ipc_recv_fd);
#endif
fd = IPCOM_LIST_FIRST(&ipl2tp_example_fds);
while (fd != IP_NULL)
{
Ipl2tp_example_fd_entry_t *nfd = IPCOM_LIST_NEXT(&fd->next);
if (fd->data != IP_NULL)
{
IP_FD_SET(fd->fd, &fds);
fd_max = IP_MAX(fd_max, fd->fd);
}
else
{
ipcom_list_remove(&fd->next);
ipcom_socketclose(fd->fd);
ipcom_free(fd);
}
fd = nfd;
}
tv.tv_sec = 0;
tv.tv_usec = 10000;
if ((ret = ipcom_socketselect(fd_max + 1, &fds, IP_NULL, IP_NULL, &tv)) > 0)
{
union Ip_sockaddr_union uaddr;
int length;
Ip_u8 *buffer;
if (IP_FD_ISSET(ipd_fd, &fds))
{
int event;
event = ipcom_ipd_input(ipd_fd);
if (event == IPCOM_IPD_EVENT_RECONFIGURE)
goto leave;
}
#ifdef IPPPP_USE_PPPL2TP
if (IP_FD_ISSET(ipl2tp_ppp_ipc_recv_fd, &fds))
{
Ipppp_pppl2tp_pkt_que_entry que_entry;
Ipcom_netif *netif;
Ipcom_pkt *pkt;
char addrstr[IP_INET_ADDRSTRLEN];
/* Read message and feed it to L2TP main input */
if (ipppp_pppl2tp_pkt_que_recv(&que_entry, &uaddr) == IPCOM_SUCCESS)
{
if ((que_entry.netif == IP_NULL) ||
(que_entry.pkt == IP_NULL))
{
ipcom_printf("ipl2tps: L2TPv2 pkt from %s:%d contains null ptr(s)."IP_LF,
ipcom_inet_ntop(IP_AF_INET, &uaddr.sin.sin_addr, addrstr, sizeof(addrstr)),
ipcom_ntohs(uaddr.sin.sin_port));
}
else
{
pkt = que_entry.pkt;
netif = que_entry.netif;
ipppp_pppl2tp_output(netif, pkt);
}
}
else
ipcom_printf("ipl2tps: PPP pkt recv failed."IP_LF);
}
#endif /* IPPPP_USE_PPPL2TP */
if (IP_FD_ISSET(udp_fd, &fds))
{
/* Read message and feed it to L2TP main input */
if ((length = ipl2tp_l2tp_read(udp_fd, &buffer, &uaddr)) > 0)
{
ipl2tp_api_l2tp_input(buffer,
buffer + HEADER_SPACE,
(Ip_u16)length,
&uaddr,
IPL2TP_ATTR_TRANSPORT_UDP);
/* Free buffer if not in PPP output queue */
if (ipl2tp_buffer_free)
{
ipl2tp_cache_free(buffer);
}
}
}
if (IP_FD_ISSET(ip_fd, &fds))
{
/* Read message and feed it to L2TP main input */
if ((length = ipl2tp_l2tp_read(ip_fd, &buffer, &uaddr)) > 0)
{
/* Remove the IP header before invoking */
ipl2tp_api_l2tp_input(buffer,
buffer + HEADER_SPACE + 20,
(Ip_u16)(length - 20),
&uaddr,
IPL2TP_ATTR_TRANSPORT_IP);
/* Free buffer if not in PPP output queue */
if (ipl2tp_buffer_free)
{
ipl2tp_cache_free(buffer);
}
}
}
fd = IPCOM_LIST_FIRST(&ipl2tp_example_fds);
while (fd != IP_NULL)
{
Ipl2tp_example_fd_entry_t *nfd = IPCOM_LIST_NEXT(&fd->next);
if (fd->data!= IP_NULL && IP_FD_ISSET(fd->fd, &fds))
{
/* Read message and feed it to L2TP main input */
if ((length = ipl2tp_l2tp_read(fd->fd, &buffer, &uaddr)) > 0)
{
if (fd->data != IP_NULL)
{
(*fd->data) (fd,
buffer,
buffer + HEADER_SPACE,
length);
}
/* Free buffer if not in PPP output queue */
if (ipl2tp_buffer_free)
{
ipl2tp_cache_free(buffer);
}
}
}
fd = nfd;
}
}
else if (ret < 0)
{
ipcom_printf("select error"IP_LF);
}
}
leave:
/* Have to call ipd init if not done yet */
if (ipd_init == 0 &&
ipcom_ipd_init("ipl2tp", IPCOM_ERR_FAILED, &ipd_fd) == IPCOM_SUCCESS)
{
ipd_init = 1;
}
if (ipd_init != 0)
{
(void)ipcom_ipd_exit("ipl2tp", ipd_fd);
}
ipcom_proc_exit();
}
/*
*===========================================================================
* ipl2tp_create
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_PUBLIC Ip_err
ipl2tp_create(void)
{
return ipl2tp_api_init() == IPL2TP_STATUS_OK ? IPCOM_SUCCESS : IPCOM_ERR_FAILED;
}
/*
* For VxWorks, the start-up routine uses run time configuration.
*/
/*
*===========================================================================
* ipl2tp_start
*===========================================================================
* Description: Start L2TP daemon.
* Parameters:
* Returns:
*
*/
IP_PUBLIC Ip_err
ipl2tp_start(void)
{
Ip_u16 pw_list[] =
{
IPL2TP_ATTR_PW_TYPE_ETHERNET,
IPL2TP_ATTR_PW_TYPE_ETHERNET_VLAN
};
Ipl2tp_attrobj attr = IP_NULL;
Ipl2tp_attrobj tattr2 = IP_NULL;
Ipl2tp_attrobj sattr2 = IP_NULL;
Ipl2tp_attrobj tattr3 = IP_NULL;
Ipl2tp_attrobj sattr3 = IP_NULL;
Ipl2tp_callback cb;
Ip_err ret;
#ifdef IP_PORT_VXWORKS
Ip_u32 enable_v2;
Ip_u32 enable_v3;
#endif
ipl2tp_example_sessions = ipcom_hash_new((Ipcom_hash_obj_func)ipl2tp_example_obj_hash_key,
(Ipcom_hash_key_func)ipl2tp_example_obj_hash_key,
(Ipcom_hash_cmp_func)ipl2tp_example_cmp_key);
ipcom_list_init(&ipl2tp_example_fds);
/* Initialize */
ret = ipl2tp_attr_strappend(&attr,
IPL2TP_ATTR_SET_HOST_NAME,
#ifdef IP_PORT_VXWORKS
L2TP_HOST_NAME);
#else
"LAC");
#endif
if (ret != IPL2TP_STATUS_OK)
return (IPCOM_ERR_FAILED);
cb.write_callback = (Ipl2tp_write_callback)ipl2tp_l2tp_write;
if ((ipl2tp_attr_pappend(&attr,
IPL2TP_ATTR_SET_L2TP_WRITE_CALLBACK,
(void *)cb.voidptr) != IPL2TP_STATUS_OK) ||
(ipl2tp_attr_iappend(&attr,
IPL2TP_ATTR_SET_ENABLE_OUTGOING,
IPL2TP_MIB_YES) != IPL2TP_STATUS_OK))
return (IPCOM_ERR_FAILED);
#ifdef IP_PORT_VXWORKS
#if L2TP_VERSION_2_ENABLE == TRUE
enable_v2 = IPL2TP_MIB_YES;
#else
enable_v2 = IPL2TP_MIB_NO;
#endif
#if L2TP_VERSION_3_ENABLE == TRUE
enable_v3 = IPL2TP_MIB_YES;
#else
enable_v3 = IPL2TP_MIB_NO;
#endif
if ((ipl2tp_attr_iappend(&attr,
IPL2TP_ATTR_SET_ENABLE_L2TP_V2,
enable_v2) != IPL2TP_STATUS_OK) ||
(ipl2tp_attr_iappend(&attr,
IPL2TP_ATTR_SET_ENABLE_L2TP_V3,
enable_v3) != IPL2TP_STATUS_OK))
return (IPCOM_ERR_FAILED);
#endif /* IP_PORT_VXWORKS */
cb.status_callback = (Ipl2tp_status_callback)ipl2tp_example_tstatus_v2;
if (ipl2tp_attr_pappend(&tattr2,
IPL2TP_TATTR_SET_STATUS_CALLBACK,
(void *)cb.voidptr) != IPL2TP_STATUS_OK)
return (IPCOM_ERR_FAILED);
cb.status_callback = (Ipl2tp_status_callback)ipl2tp_example_tstatus_v3;
if (ipl2tp_attr_pappend(&tattr3,
IPL2TP_TATTR_SET_STATUS_CALLBACK,
(void *)cb.voidptr) != IPL2TP_STATUS_OK)
return (IPCOM_ERR_FAILED);
if (ipl2tp_attr_vappend(&tattr3,
IPL2TP_TATTR_SET_LOCAL_PSEUDOWIRE_CAPABILITIES_LIST,
(void *)pw_list,
sizeof(pw_list)) != IPL2TP_STATUS_OK)
return (IPCOM_ERR_FAILED);
cb.status_callback = (Ipl2tp_status_callback)ipl2tp_example_sstatus_v2;
if (ipl2tp_attr_pappend(&sattr2,
IPL2TP_SATTR_SET_STATUS_CALLBACK,
(void *)cb.voidptr) != IPL2TP_STATUS_OK)
return (IPCOM_ERR_FAILED);
cb.ppp_callback = (Ipl2tp_ppp_callback)ipl2tp_ppp_data_cb;
if (ipl2tp_attr_pappend(&sattr2,
IPL2TP_SATTR_SET_DATA_CALLBACK,
(void *)cb.voidptr) != IPL2TP_STATUS_OK)
return (IPCOM_ERR_FAILED);
cb.status_callback = (Ipl2tp_status_callback)ipl2tp_example_sstatus_v3;
if ((ipl2tp_attr_pappend(&sattr3,
IPL2TP_SATTR_SET_STATUS_CALLBACK,
(void *)cb.voidptr) != IPL2TP_STATUS_OK) ||
(ipl2tp_attr_iappend(&sattr3,
IPL2TP_SATTR_SET_PSEUDOWIRE_TYPE,
IPL2TP_ATTR_PW_TYPE_ETHERNET_VLAN) != IPL2TP_STATUS_OK))
return (IPCOM_ERR_FAILED);
if (ipl2tp_api_open(attr, tattr2, tattr3, sattr2, sattr3) != IPL2TP_STATUS_OK)
return (IPCOM_ERR_FAILED);
ipl2tp_attr_delete(&attr);
ipl2tp_attr_delete(&tattr2);
ipl2tp_attr_delete(&sattr2);
ipl2tp_attr_delete(&tattr3);
ipl2tp_attr_delete(&sattr3);
/* Spawn new daemon process */
return ipcom_proc_acreate("l2tps", ipl2tps, IP_NULL, IP_NULL);
}
#if 0
/* PPP/L2TPv2 integration for third-party PPP */
/*
*===========================================================================
* ppp_input_hook
*===========================================================================
* Description: PPP packet input hook.
* Parameters: ifindex - Interface index.
* pppbuf - PPP packet.
* length - Length of PPP packet.
* offset . ???
* Returns: 0 to let PPP frame be parsed, else silently discarded.
*
*/
IP_PUBLIC int
ppp_input_hook(int ifindex,
void *pppbuf,
Ip_size_t length,
Ip_size_t offset)
{
Ipl2tp_key *key = ipl2tp_cmd_session_key(ifindex);
/* Did we locate a session key for this index? */
if (key == IP_NULL)
return 0;
ipl2tp_api_session_ppp_input(key, pppbuf, length, offset, 0, IP_TRUE);
return 1;
}
/*
*===========================================================================
* ppp_output_hook
*===========================================================================
* Description: PPP packet output hook. This hook may be called reentrantly
* in interrupt context. Such calls will be ignored, which means
* that an occasional CONFREQ may be lost. However, this only
* happens in the case of PPP congestion, which should never
* occur during LCP negotiation.
* Parameters: ifindex - Interface index.
* pppbuf - PPP packet.
* length - Length of PPP packet.
* offset - ???
* Returns: 0 to let PPP frame be parsed, else silently discarded.
*
*/
IP_PUBLIC int
ppp_output_hook(Ip_u32 ifindex,
void *pppbuf,
Ip_u32 length,
Ip_u32 offset)
{
(void)ifindex;
(void)pppbuf;
(void)length;
(void)offset;
return l2tp_output == 0;
}
/*
*===========================================================================
* ppp_open_hook
*===========================================================================
* Description: PPP link
* Parameters: ifindex - Interface index.
* protocol - Protocol code.
* Returns:
*
*/
IP_PUBLIC int
ppp_open_hook(int ifindex,
int protocol)
{
(void)ifindex;
switch (ip_ntohs(protocol))
{
case PPPP_LCP:
case PPPP_PAP:
case PPPP_CHAP:
case PPPP_IPCP:
break;
default:
return 1;
}
return 0;
}
/*
*===========================================================================
* ppp_writedone_hook
*===========================================================================
* Description: Release buffer when not required any more.
* Parameters: ifindex - Interface index.
* pppbuf - PPP buffer.
* cookie - Original buffer pointer.
* Returns:
*
*/
IP_PUBLIC int
ppp_writedone_hook(int ifindex,
void *pppbuf,
void *cookie)
{
(void)ifindex;
(void)pppbuf;
ipl2tp_cache_free(cookie);
return 0;
}
#endif /* 0 */
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/