1 /**************************************************************************/
2 /**************************************************************************/
3 /**                                                                       */
4 /** NetX PPPoE Server stack Component                                     */
5 /**                                                                       */
6 /**   This is a small demo of the high-performance NetX PPPoE Server      */
7 /**   stack. This demo includes IP instance, PPPoE Server and PPP Server  */
8 /**   stack. Create one IP instance includes two interfaces to support    */
9 /**   for normal IP stack and PPPoE Server, PPPoE Server can use the      */
10 /**   mutex of IP instance to send PPPoE message when share one Ethernet  */
11 /**   driver. PPPoE Server work with normal IP instance at the same time. */
12 /**                                                                       */
13 /**   Note1: Substitute your Ethernet driver instead of                   */
14 /**   _nx_ram_network_driver before run this demo                         */
15 /**                                                                       */
16 /**   Note2: Prerequisite for using PPPoE.                                */
17 /**   Redefine NX_PHYSICAL_HEADER to 24 to ensure enough space for filling*/
18 /**   in physical header. Physical header:14(Ethernet header)             */
19 /**    + 6(PPPoE header) + 2(PPP header) + 2(four-byte aligment)          */
20 /**                                                                       */
21 /**************************************************************************/
22 /**************************************************************************/
23 
24 
25       /*****************************************************************/
26       /*                          NetX Stack                           */
27       /*****************************************************************/
28 
29                                             /***************************/
30                                             /*        PPP Server       */
31                                             /***************************/
32 
33                                             /***************************/
34                                             /*       PPPoE Server      */
35                                             /***************************/
36       /***************************/         /***************************/
37       /*    Normal Ethernet Type */         /*    PPPoE Ethernet Type  */
38       /***************************/         /***************************/
39       /***************************/         /***************************/
40       /*       Interface 0       */         /*       Interface 1       */
41       /***************************/         /***************************/
42 
43       /*****************************************************************/
44       /*                       Ethernet Dirver                         */
45       /*****************************************************************/
46 
47 #include   "tx_api.h"
48 #include   "nx_api.h"
49 #include   "nx_ppp.h"
50 #include   "nx_pppoe_server.h"
51 
52 #ifndef NX_DISABLE_IPV4
53 
54 /* Defined NX_PPP_PPPOE_ENABLE if using PPP, since PPP module has been modified to match PPPoE module under this definition.  */
55 #ifdef NX_PPP_PPPOE_ENABLE
56 
57 /* If the driver is not initialized in other module, define NX_PPPOE_SERVER_INITIALIZE_DRIVER_ENABLE to initialize the driver in PPPoE module .
58    In this demo, the driver has been initialized in IP module.  */
59 #ifndef NX_PPPOE_SERVER_INITIALIZE_DRIVER_ENABLE
60 
61 /* NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE:
62    If defined, enables the feature that controls the PPPoE session.
63    PPPoE server does not automatically response to the request until application call specific API.  */
64 
65 /* Define the block size.  */
66 #define     NX_PACKET_POOL_SIZE     ((1536 + sizeof(NX_PACKET)) * 30)
67 #define     DEMO_STACK_SIZE         2048
68 #define     PPPOE_THREAD_SIZE       2048
69 
70 /* Define the ThreadX and NetX object control blocks...  */
71 TX_THREAD               thread_0;
72 
73 /* Define the packet pool and IP instance for normal IP instnace.  */
74 NX_PACKET_POOL          pool_0;
75 NX_IP                   ip_0;
76 
77 /* Define the PPP Server instance.  */
78 NX_PPP                  ppp_server;
79 
80 /* Define the PPPoE Server instance.  */
81 NX_PPPOE_SERVER         pppoe_server;
82 
83 /* Define the counters.  */
84 CHAR                    *pointer;
85 ULONG                   error_counter;
86 
87 /* Define thread prototypes.  */
88 void    thread_0_entry(ULONG thread_input);
89 
90 /***** Substitute your PPP driver entry function here *********/
91 extern void    _nx_ppp_driver(NX_IP_DRIVER *driver_req_ptr);
92 
93 /***** Substitute your Ethernet driver entry function here *********/
94 extern void    _nx_ram_network_driver(NX_IP_DRIVER *driver_req_ptr);
95 
96 /* Define the callback functions.  */
97 void    PppDiscoverReq(UINT interfaceHandle);
98 void    PppOpenReq(UINT interfaceHandle, ULONG length, UCHAR *data);
99 void    PppCloseRsp(UINT interfaceHandle);
100 void    PppCloseReq(UINT interfaceHandle);
101 void    PppTransmitDataReq(UINT interfaceHandle, ULONG length, UCHAR *data, UINT packet_id);
102 void    PppReceiveDataRsp(UINT interfaceHandle, UCHAR *data);
103 
104 /* Define the porting layer function for PPP. */
105 void    ppp_server_packet_send(NX_PACKET *packet_ptr);
106 
107 /* Define main entry point.  */
108 
main()109 int main()
110 {
111 
112     /* Enter the ThreadX kernel.  */
113     tx_kernel_enter();
114 }
115 
verify_login(CHAR * name,CHAR * password)116 UINT verify_login(CHAR *name, CHAR *password)
117 {
118 
119 if ((name[0] == 'm') &&
120     (name[1] == 'y') &&
121     (name[2] == 'n') &&
122     (name[3] == 'a') &&
123     (name[4] == 'm') &&
124     (name[5] == 'e') &&
125     (name[6] == (CHAR) 0) &&
126     (password[0] == 'm') &&
127     (password[1] == 'y') &&
128     (password[2] == 'p') &&
129     (password[3] == 'a') &&
130     (password[4] == 's') &&
131     (password[5] == 's') &&
132     (password[6] == 'w') &&
133     (password[7] == 'o') &&
134     (password[8] == 'r') &&
135     (password[9] == 'd') &&
136     (password[10] == (CHAR) 0))
137         return(NX_SUCCESS);
138    else
139         return(NX_PPP_ERROR);
140 }
141 
142 /* Define what the initial system looks like.  */
143 
tx_application_define(void * first_unused_memory)144 void    tx_application_define(void *first_unused_memory)
145 {
146 
147 UINT    status;
148 
149     /* Setup the working pointer.  */
150     pointer =  (CHAR *) first_unused_memory;
151 
152     /* Initialize the NetX system.  */
153     nx_system_initialize();
154 
155     /* Create a packet pool for normal IP instance.  */
156     status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool",
157                                    (1536 + sizeof(NX_PACKET)),
158                                    pointer, NX_PACKET_POOL_SIZE);
159     pointer = pointer + NX_PACKET_POOL_SIZE;
160 
161     /* Check for error.  */
162     if (status)
163         error_counter++;
164 
165     /* Create an normal IP instance.  */
166     status = nx_ip_create(&ip_0, "NetX IP Instance", IP_ADDRESS(192, 168, 100, 43), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver,
167                           pointer, 2048, 1);
168     pointer = pointer + 2048;
169 
170     /* Check for error.  */
171     if (status)
172         error_counter++;
173 
174     /* Create the PPP instance.  */
175     status = nx_ppp_create(&ppp_server, "PPP Instance", &ip_0, pointer, 2048, 1, &pool_0, NX_NULL, NX_NULL);
176     pointer = pointer + 2048;
177 
178     /* Check for PPP create error.   */
179     if (status)
180         error_counter++;
181 
182     /* Set the PPP packet send function.  */
183     status = nx_ppp_packet_send_set(&ppp_server, ppp_server_packet_send);
184 
185     /* Check for PPP packet send function set error.   */
186     if (status)
187         error_counter++;
188 
189     /* Define IP address. This PPP instance is effectively the server since it has both IP addresses. */
190     status = nx_ppp_ip_address_assign(&ppp_server, IP_ADDRESS(192, 168, 10, 43), IP_ADDRESS(192, 168, 10, 44));
191 
192     /* Check for PPP IP address assign error.   */
193     if (status)
194         error_counter++;
195 
196     /* Setup PAP, this PPP instance is effectively the server since it will verify the name and password.  */
197     status = nx_ppp_pap_enable(&ppp_server, NX_NULL, verify_login);
198 
199     /* Check for PPP PAP enable error.  */
200     if (status)
201         error_counter++;
202 
203     /* Attach an interface for PPP.  */
204     status = nx_ip_interface_attach(&ip_0, "Second Interface For PPP", IP_ADDRESS(0, 0, 0, 0), 0, nx_ppp_driver);
205 
206     /* Check for error.  */
207     if (status)
208         error_counter++;
209 
210     /* Enable ARP and supply ARP cache memory for Normal IP Instance.  */
211     status = nx_arp_enable(&ip_0, (void *) pointer, 1024);
212     pointer = pointer + 1024;
213 
214     /* Check for ARP enable errors.  */
215     if (status)
216         error_counter++;
217 
218     /* Enable ICMP */
219     status = nx_icmp_enable(&ip_0);
220     if(status)
221         error_counter++;
222 
223     /* Enable UDP traffic.  */
224     status =  nx_udp_enable(&ip_0);
225     if (status)
226         error_counter++;
227 
228     /* Enable TCP traffic.  */
229     status =  nx_tcp_enable(&ip_0);
230     if (status)
231         error_counter++;
232 
233     /* Create the main thread.  */
234     tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
235                      pointer, DEMO_STACK_SIZE,
236                      4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
237     pointer =  pointer + DEMO_STACK_SIZE;
238 
239 }
240 
241 /* Define the test threads.  */
242 
thread_0_entry(ULONG thread_input)243 void    thread_0_entry(ULONG thread_input)
244 {
245 UINT    status;
246 ULONG   ip_status;
247 
248     /* Create the PPPoE instance.  */
249     status =  nx_pppoe_server_create(&pppoe_server, (UCHAR *)"PPPoE Server",  &ip_0, 0, _nx_ram_network_driver,  &pool_0, pointer, PPPOE_THREAD_SIZE, 4);
250     pointer = pointer + PPPOE_THREAD_SIZE;
251     if (status)
252     {
253         error_counter++;
254         return;
255     }
256 
257     /* Set the callback notify function.  */
258     status = nx_pppoe_server_callback_notify_set(&pppoe_server, PppDiscoverReq, PppOpenReq, PppCloseRsp, PppCloseReq, PppTransmitDataReq, PppReceiveDataRsp);
259     if (status)
260     {
261         error_counter++;
262         return;
263     }
264 
265 #ifdef NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE
266     /* Call function function to set the default service Name.  */
267     /*
268     PppInitInd(length, aData);
269     */
270 #endif /* NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE */
271 
272     /* Enable PPPoE Server.  */
273     status = nx_pppoe_server_enable(&pppoe_server);
274     if (status)
275     {
276         error_counter++;
277         return;
278     }
279 
280     /* Get the PPPoE Client physical address and Session ID after establish PPPoE Session.  */
281     /*
282     status = nx_pppoe_server_session_get(&pppoe_server, interfaceHandle, &client_mac_msw, &client_mac_lsw, &session_id);
283     if (status)
284         error_counter++;
285     */
286 
287     /* Wait for the link to come up.  */
288     status = nx_ip_interface_status_check(&ip_0, 1, NX_IP_ADDRESS_RESOLVED, &ip_status, NX_WAIT_FOREVER);
289     if (status)
290     {
291         error_counter++;
292         return;
293     }
294 
295 #ifdef NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE
296     /* Call PPPoE function to terminate the PPPoE Session.  */
297     /*
298     PppCloseInd(interfaceHandle, causeCode);
299     */
300 #endif /* NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE  */
301 }
302 
PppDiscoverReq(UINT interfaceHandle)303 void    PppDiscoverReq(UINT interfaceHandle)
304 {
305 
306     /* Receive the PPPoE Discovery Initiation Message.  */
307 
308 #ifdef NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE
309     /* Call PPPoE function to allow TTP's software to define the Service Name field of the PADO packet.  */
310     PppDiscoverCnf(0, NX_NULL, interfaceHandle);
311 #endif /* NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE  */
312 }
313 
PppOpenReq(UINT interfaceHandle,ULONG length,UCHAR * data)314 void    PppOpenReq(UINT interfaceHandle, ULONG length, UCHAR *data)
315 {
316 
317     /*  Get the notify that receive the PPPoE Discovery Request Message.  */
318 
319 #ifdef NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE
320     /* Call PPPoE function to allow TTP's software to accept the PPPoE session.  */
321     PppOpenCnf(NX_TRUE, interfaceHandle);
322 #endif /* NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE  */
323 }
324 
PppCloseRsp(UINT interfaceHandle)325 void    PppCloseRsp(UINT interfaceHandle)
326 {
327 
328     /*  Get the notify that receive the PPPoE Discovery Terminate Message.  */
329 
330 #ifdef NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE
331     /* Call PPPoE function to allow TTP's software to confirm that the handle has been freed.  */
332     PppCloseCnf(interfaceHandle);
333 #endif /* NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE  */
334 }
335 
PppCloseReq(UINT interfaceHandle)336 void    PppCloseReq(UINT interfaceHandle)
337 {
338 
339     /*  Get the notify that PPPoE Discovery Terminate Message has been sent.  */
340 
341 }
342 
PppTransmitDataReq(UINT interfaceHandle,ULONG length,UCHAR * data,UINT packet_id)343 void    PppTransmitDataReq(UINT interfaceHandle, ULONG length, UCHAR *data, UINT packet_id)
344 {
345 
346 NX_PACKET   *packet_ptr;
347 
348     /* Get the notify that receive the PPPoE Session data.  */
349 
350     /* Call PPP Server to receive the PPP data fame.  */
351     packet_ptr = (NX_PACKET *)(packet_id);
352     nx_ppp_packet_receive(&ppp_server, packet_ptr);
353 
354 #ifdef NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE
355     /* Call PPPoE function to confirm that the data has been processed.  */
356     PppTransmitDataCnf(interfaceHandle, data, packet_id);
357 #endif /* NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE  */
358 }
359 
PppReceiveDataRsp(UINT interfaceHandle,UCHAR * data)360 void    PppReceiveDataRsp(UINT interfaceHandle, UCHAR *data)
361 {
362 
363     /* Get the notify that the PPPoE Session data has been sent.  */
364 
365 }
366 
367 /* PPP Server send function.  */
ppp_server_packet_send(NX_PACKET * packet_ptr)368 void    ppp_server_packet_send(NX_PACKET *packet_ptr)
369 {
370 
371 /* For PPP test, the session should be the first session, so set interfaceHandle as 0.  */
372 UINT    interfaceHandle = 0;
373 
374 #ifdef NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE
375 NX_PACKET *temp_packet = packet_ptr;
376 
377     while(packet_ptr)
378     {
379 
380         /* Call functions to be provided by PPPoE for TTP.  */
381         PppReceiveDataInd(interfaceHandle, (packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr), packet_ptr -> nx_packet_prepend_ptr);
382 
383         /* Move to the next packet structure.  */
384         packet_ptr =  packet_ptr -> nx_packet_next;
385     }
386 
387     nx_packet_transmit_release(temp_packet);
388 #else
389     /* Directly Call PPPoE send function to send out the data through PPPoE module.  */
390     nx_pppoe_server_session_packet_send(&pppoe_server, interfaceHandle, packet_ptr);
391 #endif /* NX_PPPOE_SERVER_SESSION_CONTROL_ENABLE  */
392 }
393 #endif /* NX_PPPOE_SERVER_INITIALIZE_DRIVER_ENABLE  */
394 
395 #endif /* NX_PPP_PPPOE_ENABLE  */
396 
397 #endif /* NX_DISABLE_IPV4  */
398