mirror of
https://github.com/azure-rtos/netx.git
synced 2023-08-10 07:57:54 +08:00
392 lines
14 KiB
C
392 lines
14 KiB
C
/**************************************************************************/
|
|
/**************************************************************************/
|
|
/** */
|
|
/** NetX PPPoE Server stack Component */
|
|
/** */
|
|
/** This is a small demo of the high-performance NetX PPPoE Server */
|
|
/** stack. This demo includes IP instance, PPPoE Server and PPP Server */
|
|
/** stack. Create one IP instance includes two interfaces to support */
|
|
/** for normal IP stack and PPPoE Server, PPPoE Server can use the */
|
|
/** mutex of IP instance to send PPPoE message when share one Ethernet */
|
|
/** driver. PPPoE Server work with normal IP instance at the same time. */
|
|
/** */
|
|
/** Note1: Substitute your Ethernet driver instead of */
|
|
/** _nx_ram_network_driver before run this demo */
|
|
/** */
|
|
/** Note2: Prerequisite for using PPPoE. */
|
|
/** Redefine NX_PHYSICAL_HEADER to 24 to ensure enough space for filling*/
|
|
/** in physical header. Physical header:14(Ethernet header) */
|
|
/** + 6(PPPoE header) + 2(PPP header) + 2(four-byte aligment) */
|
|
/** */
|
|
/**************************************************************************/
|
|
/**************************************************************************/
|
|
|
|
|
|
/*****************************************************************/
|
|
/* NetX Stack */
|
|
/*****************************************************************/
|
|
|
|
/***************************/
|
|
/* PPP Server */
|
|
/***************************/
|
|
|
|
/***************************/
|
|
/* PPPoE Server */
|
|
/***************************/
|
|
/***************************/ /***************************/
|
|
/* Normal Ethernet Type */ /* PPPoE Ethernet Type */
|
|
/***************************/ /***************************/
|
|
/***************************/ /***************************/
|
|
/* Interface 0 */ /* Interface 1 */
|
|
/***************************/ /***************************/
|
|
|
|
/*****************************************************************/
|
|
/* Ethernet Dirver */
|
|
/*****************************************************************/
|
|
|
|
#include "tx_api.h"
|
|
#include "nx_api.h"
|
|
#include "nx_ppp.h"
|
|
#include "nx_pppoe_server.h"
|
|
|
|
|
|
/* Defined NX_PPP_PPPOE_ENABLE if using PPP, since PPP module has been modified to match PPPoE module under this definition. */
|
|
#ifdef NX_PPP_PPPOE_ENABLE
|
|
|
|
/* If the driver is not initialized in other module, define NX_PPPOE_SERVER_INITIALIZE_DRIVER_ENABLE to initialize the driver in PPPoE module .
|
|
In this demo, the driver has been initialized in IP module. */
|
|
#ifndef NX_PPPOE_SERVER_INITIALIZE_DRIVER_ENABLE
|
|
|
|
/* NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE:
|
|
If defined, enables the feature that controls the PPPoE session.
|
|
PPPoE server does not automatically response to the request until application call specific API. */
|
|
|
|
/* Define the block size. */
|
|
#define NX_PACKET_POOL_SIZE ((1536 + sizeof(NX_PACKET)) * 30)
|
|
#define DEMO_STACK_SIZE 2048
|
|
#define PPPOE_THREAD_SIZE 2048
|
|
|
|
/* Define the ThreadX and NetX object control blocks... */
|
|
TX_THREAD thread_0;
|
|
|
|
/* Define the packet pool and IP instance for normal IP instnace. */
|
|
NX_PACKET_POOL pool_0;
|
|
NX_IP ip_0;
|
|
|
|
/* Define the PPP Server instance. */
|
|
NX_PPP ppp_server;
|
|
|
|
/* Define the PPPoE Server instance. */
|
|
NX_PPPOE_SERVER pppoe_server;
|
|
|
|
/* Define the counters. */
|
|
CHAR *pointer;
|
|
ULONG error_counter;
|
|
|
|
/* Define thread prototypes. */
|
|
void thread_0_entry(ULONG thread_input);
|
|
|
|
/***** Substitute your PPP driver entry function here *********/
|
|
extern void _nx_ppp_driver(NX_IP_DRIVER *driver_req_ptr);
|
|
|
|
/***** Substitute your Ethernet driver entry function here *********/
|
|
extern void _nx_ram_network_driver(NX_IP_DRIVER *driver_req_ptr);
|
|
|
|
/* Define the callback functions. */
|
|
void PppDiscoverReq(UINT interfaceHandle);
|
|
void PppOpenReq(UINT interfaceHandle, ULONG length, UCHAR *data);
|
|
void PppCloseRsp(UINT interfaceHandle);
|
|
void PppCloseReq(UINT interfaceHandle);
|
|
void PppTransmitDataReq(UINT interfaceHandle, ULONG length, UCHAR *data, UINT packet_id);
|
|
void PppReceiveDataRsp(UINT interfaceHandle, UCHAR *data);
|
|
|
|
/* Define the porting layer function for PPP. */
|
|
void ppp_server_packet_send(NX_PACKET *packet_ptr);
|
|
|
|
/* Define main entry point. */
|
|
|
|
int main()
|
|
{
|
|
|
|
/* Enter the ThreadX kernel. */
|
|
tx_kernel_enter();
|
|
}
|
|
|
|
UINT verify_login(CHAR *name, CHAR *password)
|
|
{
|
|
|
|
if ((name[0] == 'm') &&
|
|
(name[1] == 'y') &&
|
|
(name[2] == 'n') &&
|
|
(name[3] == 'a') &&
|
|
(name[4] == 'm') &&
|
|
(name[5] == 'e') &&
|
|
(name[6] == (CHAR) 0) &&
|
|
(password[0] == 'm') &&
|
|
(password[1] == 'y') &&
|
|
(password[2] == 'p') &&
|
|
(password[3] == 'a') &&
|
|
(password[4] == 's') &&
|
|
(password[5] == 's') &&
|
|
(password[6] == 'w') &&
|
|
(password[7] == 'o') &&
|
|
(password[8] == 'r') &&
|
|
(password[9] == 'd') &&
|
|
(password[10] == (CHAR) 0))
|
|
return(NX_SUCCESS);
|
|
else
|
|
return(NX_PPP_ERROR);
|
|
}
|
|
|
|
/* Define what the initial system looks like. */
|
|
|
|
void tx_application_define(void *first_unused_memory)
|
|
{
|
|
|
|
UINT status;
|
|
|
|
/* Setup the working pointer. */
|
|
pointer = (CHAR *) first_unused_memory;
|
|
|
|
/* Initialize the NetX system. */
|
|
nx_system_initialize();
|
|
|
|
/* Create a packet pool for normal IP instance. */
|
|
status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool",
|
|
(1536 + sizeof(NX_PACKET)),
|
|
pointer, NX_PACKET_POOL_SIZE);
|
|
pointer = pointer + NX_PACKET_POOL_SIZE;
|
|
|
|
/* Check for error. */
|
|
if (status)
|
|
error_counter++;
|
|
|
|
/* Create an normal IP instance. */
|
|
status = nx_ip_create(&ip_0, "NetX IP Instance", IP_ADDRESS(192, 168, 100, 43), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver,
|
|
pointer, 2048, 1);
|
|
pointer = pointer + 2048;
|
|
|
|
/* Check for error. */
|
|
if (status)
|
|
error_counter++;
|
|
|
|
/* Create the PPP instance. */
|
|
status = nx_ppp_create(&ppp_server, "PPP Instance", &ip_0, pointer, 2048, 1, &pool_0, NX_NULL, NX_NULL);
|
|
pointer = pointer + 2048;
|
|
|
|
/* Check for PPP create error. */
|
|
if (status)
|
|
error_counter++;
|
|
|
|
/* Set the PPP packet send function. */
|
|
status = nx_ppp_packet_send_set(&ppp_server, ppp_server_packet_send);
|
|
|
|
/* Check for PPP packet send function set error. */
|
|
if (status)
|
|
error_counter++;
|
|
|
|
/* Define IP address. This PPP instance is effectively the server since it has both IP addresses. */
|
|
status = nx_ppp_ip_address_assign(&ppp_server, IP_ADDRESS(192, 168, 10, 43), IP_ADDRESS(192, 168, 10, 44));
|
|
|
|
/* Check for PPP IP address assign error. */
|
|
if (status)
|
|
error_counter++;
|
|
|
|
/* Setup PAP, this PPP instance is effectively the server since it will verify the name and password. */
|
|
status = nx_ppp_pap_enable(&ppp_server, NX_NULL, verify_login);
|
|
|
|
/* Check for PPP PAP enable error. */
|
|
if (status)
|
|
error_counter++;
|
|
|
|
/* Attach an interface for PPP. */
|
|
status = nx_ip_interface_attach(&ip_0, "Second Interface For PPP", IP_ADDRESS(0, 0, 0, 0), 0, nx_ppp_driver);
|
|
|
|
/* Check for error. */
|
|
if (status)
|
|
error_counter++;
|
|
|
|
/* Enable ARP and supply ARP cache memory for Normal IP Instance. */
|
|
status = nx_arp_enable(&ip_0, (void *) pointer, 1024);
|
|
pointer = pointer + 1024;
|
|
|
|
/* Check for ARP enable errors. */
|
|
if (status)
|
|
error_counter++;
|
|
|
|
/* Enable ICMP */
|
|
status = nx_icmp_enable(&ip_0);
|
|
if(status)
|
|
error_counter++;
|
|
|
|
/* Enable UDP traffic. */
|
|
status = nx_udp_enable(&ip_0);
|
|
if (status)
|
|
error_counter++;
|
|
|
|
/* Enable TCP traffic. */
|
|
status = nx_tcp_enable(&ip_0);
|
|
if (status)
|
|
error_counter++;
|
|
|
|
/* Create the main thread. */
|
|
tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
|
|
pointer, DEMO_STACK_SIZE,
|
|
4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
|
|
pointer = pointer + DEMO_STACK_SIZE;
|
|
|
|
}
|
|
|
|
/* Define the test threads. */
|
|
|
|
void thread_0_entry(ULONG thread_input)
|
|
{
|
|
UINT status;
|
|
ULONG ip_status;
|
|
|
|
/* Create the PPPoE instance. */
|
|
status = nx_pppoe_server_create(&pppoe_server, (UCHAR *)"PPPoE Server", &ip_0, 0, _nx_ram_network_driver, &pool_0, pointer, PPPOE_THREAD_SIZE, 4);
|
|
pointer = pointer + PPPOE_THREAD_SIZE;
|
|
if (status)
|
|
{
|
|
error_counter++;
|
|
return;
|
|
}
|
|
|
|
/* Set the callback notify function. */
|
|
status = nx_pppoe_server_callback_notify_set(&pppoe_server, PppDiscoverReq, PppOpenReq, PppCloseRsp, PppCloseReq, PppTransmitDataReq, PppReceiveDataRsp);
|
|
if (status)
|
|
{
|
|
error_counter++;
|
|
return;
|
|
}
|
|
|
|
#ifdef NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE
|
|
/* Call function function to set the default service Name. */
|
|
/*
|
|
PppInitInd(length, aData);
|
|
*/
|
|
#endif /* NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE */
|
|
|
|
/* Enable PPPoE Server. */
|
|
status = nx_pppoe_server_enable(&pppoe_server);
|
|
if (status)
|
|
{
|
|
error_counter++;
|
|
return;
|
|
}
|
|
|
|
/* Get the PPPoE Client physical address and Session ID after establish PPPoE Session. */
|
|
/*
|
|
status = nx_pppoe_server_session_get(&pppoe_server, interfaceHandle, &client_mac_msw, &client_mac_lsw, &session_id);
|
|
if (status)
|
|
error_counter++;
|
|
*/
|
|
|
|
/* Wait for the link to come up. */
|
|
status = nx_ip_interface_status_check(&ip_0, 1, NX_IP_ADDRESS_RESOLVED, &ip_status, NX_WAIT_FOREVER);
|
|
if (status)
|
|
{
|
|
error_counter++;
|
|
return;
|
|
}
|
|
|
|
#ifdef NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE
|
|
/* Call PPPoE function to terminate the PPPoE Session. */
|
|
/*
|
|
PppCloseInd(interfaceHandle, causeCode);
|
|
*/
|
|
#endif /* NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE */
|
|
}
|
|
|
|
void PppDiscoverReq(UINT interfaceHandle)
|
|
{
|
|
|
|
/* Receive the PPPoE Discovery Initiation Message. */
|
|
|
|
#ifdef NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE
|
|
/* Call PPPoE function to allow TTP's software to define the Service Name field of the PADO packet. */
|
|
PppDiscoverCnf(0, NX_NULL, interfaceHandle);
|
|
#endif /* NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE */
|
|
}
|
|
|
|
void PppOpenReq(UINT interfaceHandle, ULONG length, UCHAR *data)
|
|
{
|
|
|
|
/* Get the notify that receive the PPPoE Discovery Request Message. */
|
|
|
|
#ifdef NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE
|
|
/* Call PPPoE function to allow TTP's software to accept the PPPoE session. */
|
|
PppOpenCnf(NX_TRUE, interfaceHandle);
|
|
#endif /* NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE */
|
|
}
|
|
|
|
void PppCloseRsp(UINT interfaceHandle)
|
|
{
|
|
|
|
/* Get the notify that receive the PPPoE Discovery Terminate Message. */
|
|
|
|
#ifdef NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE
|
|
/* Call PPPoE function to allow TTP's software to confirm that the handle has been freed. */
|
|
PppCloseCnf(interfaceHandle);
|
|
#endif /* NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE */
|
|
}
|
|
|
|
void PppCloseReq(UINT interfaceHandle)
|
|
{
|
|
|
|
/* Get the notify that PPPoE Discovery Terminate Message has been sent. */
|
|
|
|
}
|
|
|
|
void PppTransmitDataReq(UINT interfaceHandle, ULONG length, UCHAR *data, UINT packet_id)
|
|
{
|
|
|
|
NX_PACKET *packet_ptr;
|
|
|
|
/* Get the notify that receive the PPPoE Session data. */
|
|
|
|
/* Call PPP Server to receive the PPP data fame. */
|
|
packet_ptr = (NX_PACKET *)(packet_id);
|
|
nx_ppp_packet_receive(&ppp_server, packet_ptr);
|
|
|
|
#ifdef NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE
|
|
/* Call PPPoE function to confirm that the data has been processed. */
|
|
PppTransmitDataCnf(interfaceHandle, data, packet_id);
|
|
#endif /* NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE */
|
|
}
|
|
|
|
void PppReceiveDataRsp(UINT interfaceHandle, UCHAR *data)
|
|
{
|
|
|
|
/* Get the notify that the PPPoE Session data has been sent. */
|
|
|
|
}
|
|
|
|
/* PPP Server send function. */
|
|
void ppp_server_packet_send(NX_PACKET *packet_ptr)
|
|
{
|
|
|
|
/* For PPP test, the session should be the first session, so set interfaceHandle as 0. */
|
|
UINT interfaceHandle = 0;
|
|
|
|
#ifdef NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE
|
|
while(packet_ptr)
|
|
{
|
|
|
|
/* Call functions to be provided by PPPoE for TTP. */
|
|
PppReceiveDataInd(interfaceHandle, (packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr), packet_ptr -> nx_packet_prepend_ptr);
|
|
|
|
/* Move to the next packet structure. */
|
|
packet_ptr = packet_ptr -> nx_packet_next;
|
|
}
|
|
#else
|
|
/* Directly Call PPPoE send function to send out the data through PPPoE module. */
|
|
nx_pppoe_server_session_packet_send(&pppoe_server, interfaceHandle, packet_ptr);
|
|
#endif /* NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE */
|
|
}
|
|
#endif /* NX_PPPOE_SERVER_INITIALIZE_DRIVER_ENABLE */
|
|
|
|
#endif /* NX_PPP_PPPOE_ENABLE */
|
|
|