1 
2 /* This NetX test concentrates on the UCP operation.  */
3 
4 #include   "tx_api.h"
5 #include   "nx_api.h"
6 #include   "nx_tcp.h"
7 #include   "nx_udp.h"
8 
9 extern void    test_control_return(UINT status);
10 #if defined NX_NAT_ENABLE && defined __PRODUCT_NETXDUO__ && (NX_MAX_PHYSICAL_INTERFACES >= 2) && !defined(NX_DISABLE_IPV4)
11 #include   "nx_nat.h"
12 
13 #define     DEMO_STACK_SIZE         2048
14 
15 /* Define the ThreadX and NetX object control blocks...  */
16 
17 static TX_THREAD                    thread_0;
18 
19 /* Set up the NAT components. */
20 
21 /* Create a NAT instance, packet pool and translation table. */
22 
23 NX_PACKET_POOL                      nat_packet_pool;
24 NX_NAT_DEVICE                       nat_server;
25 NX_IP                               nat_ip;
26 NX_IP                               local_ip;
27 NX_IP                               external_ip;
28 NX_UDP_SOCKET                       local_socket;
29 NX_UDP_SOCKET                       external_socket;
30 
31 
32 /* Configure the NAT network parameters. */
33 
34 /* Set NetX IP packet pool packet size. This should be less than the Maximum Transmit Unit (MTU) of
35    the driver (allow enough room for the Ethernet header plus padding bytes for frame alignment).  */
36 #define NX_NAT_PACKET_SIZE                          1536
37 
38 
39 /* Set the size of the NAT IP packet pool.  */
40 #define NX_NAT_PACKET_POOL_SIZE                     (NX_NAT_PACKET_SIZE * 10)
41 
42 /* Set NetX IP helper thread stack size. */
43 #define NX_NAT_IP_THREAD_STACK_SIZE                 2048
44 
45 /* Set the server IP thread priority */
46 #define NX_NAT_IP_THREAD_PRIORITY                   2
47 
48 /* Set ARP cache size of a NAT ip instance. */
49 #define NX_NAT_ARP_CACHE_SIZE                       1024
50 
51 /* Set NAT entries memory size. */
52 #define NX_NAT_ENTRY_CACHE_SIZE                     1024
53 
54 /* Define NAT IP addresses, local host private IP addresses and external host IP address. */
55 #define NX_NAT_LOCAL_IPADR              (IP_ADDRESS(192, 168, 2, 1))
56 #define NX_NAT_LOCAL_HOST1              (IP_ADDRESS(192, 168, 2, 3))
57 #define NX_NAT_LOCAL_HOST2              (IP_ADDRESS(192, 168, 2, 10))
58 #define NX_NAT_LOCAL_GATEWAY            (IP_ADDRESS(192, 168, 2, 1))
59 #define NX_NAT_LOCAL_NETMASK            (IP_ADDRESS(255, 255, 255, 0))
60 #define NX_NAT_EXTERNAL_IPADR           (IP_ADDRESS(192, 168, 0, 10))
61 #define NX_NAT_EXTERNAL_HOST            (IP_ADDRESS(192, 168, 0, 100))
62 #define NX_NAT_EXTERNAL_GATEWAY         (IP_ADDRESS(192, 168, 0, 1))
63 #define NX_NAT_EXTERNAL_NETMASK         (IP_ADDRESS(255, 255, 255, 0))
64 
65 /* Create NAT structures for preloading NAT tables with static
66    entries for local server hosts. */
67 NX_NAT_TRANSLATION_ENTRY            server_inbound_entry_udp;
68 
69 /* Set up generic network driver for demo program. */
70 extern void    _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req);
71 extern UINT    (*advanced_packet_process_callback)(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr);
72 
73 
74 /* Define thread prototypes.  */
75 
76 static void    thread_0_entry(ULONG thread_input);
77 static void    thread_1_entry(ULONG thread_input);
78 static UINT    packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr);
79 
80 
81 /* Define what the initial system looks like.  */
82 #ifdef CTEST
test_application_define(void * first_unused_memory)83 VOID test_application_define(void *first_unused_memory)
84 #else
85 void    netx_nat_invalid_header_test_application_define(void *first_unused_memory)
86 #endif
87 {
88 
89 UINT     status;
90 UCHAR    *pointer;
91 UINT     error_counter = 0;
92 
93     /* Initialize the NetX system. */
94     nx_system_initialize();
95 
96     /* Setup the pointer to unallocated memory.  */
97     pointer =  (UCHAR *) first_unused_memory;
98 
99     /* Create the main thread.  */
100     tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
101                      pointer, DEMO_STACK_SIZE,
102                      4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
103     pointer =  pointer + DEMO_STACK_SIZE;
104 
105     /* Create NAT packet pool. */
106     status =  nx_packet_pool_create(&nat_packet_pool, "NAT Packet Pool",
107                                     NX_NAT_PACKET_SIZE, pointer,
108                                     NX_NAT_PACKET_POOL_SIZE);
109 
110     /* Update pointer to unallocated (free) memory. */
111     pointer = pointer + NX_NAT_PACKET_POOL_SIZE;
112 
113     /* Check status.  */
114     if (status)
115         return;
116 
117     /* Create IP instances for NAT server (global network) */
118     status = nx_ip_create(&nat_ip, "NAT IP Instance", NX_NAT_EXTERNAL_IPADR, NX_NAT_EXTERNAL_NETMASK,
119                           &nat_packet_pool, _nx_ram_network_driver_1500, pointer,
120                           NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY);
121 
122     /* Update pointer to unallocated (free) memory. */
123     pointer =  pointer + NX_NAT_IP_THREAD_STACK_SIZE;
124 
125     /* Check status.  */
126     if (status)
127     {
128         error_counter++;
129         return;
130     }
131 
132     /* Set the private interface(private network).  */
133     status += nx_ip_interface_attach(&nat_ip, "Private Interface", NX_NAT_LOCAL_IPADR, NX_NAT_LOCAL_NETMASK, _nx_ram_network_driver_1500);
134 
135     /* Check status.  */
136     if (status)
137     {
138         error_counter++;
139         return;
140     }
141 
142     /* Create IP instances for Local network IP instance */
143     status = nx_ip_create(&local_ip, "Local IP Instance", NX_NAT_LOCAL_HOST1, NX_NAT_LOCAL_NETMASK,
144                           &nat_packet_pool, _nx_ram_network_driver_1500, pointer,
145                           NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY);
146 
147     /* Update pointer to unallocated (free) memory. */
148     pointer =  pointer + NX_NAT_IP_THREAD_STACK_SIZE;
149 
150     /* Check status.  */
151     if (status)
152     {
153         error_counter++;
154         return;
155     }
156 
157     /* Create IP instances for external network IP instance */
158     status = nx_ip_create(&external_ip, "External IP Instance", NX_NAT_EXTERNAL_HOST, NX_NAT_EXTERNAL_NETMASK,
159                           &nat_packet_pool, _nx_ram_network_driver_1500, pointer,
160                           NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY);
161 
162     /* Update pointer to unallocated (free) memory. */
163     pointer =  pointer + NX_NAT_IP_THREAD_STACK_SIZE;
164 
165     /* Check status.  */
166     if (status)
167     {
168         error_counter++;
169         return;
170     }
171 
172     /* Set the global network gateway for NAT IP instance.  */
173     status = nx_ip_gateway_address_set(&nat_ip, NX_NAT_EXTERNAL_GATEWAY);
174 
175     /* Check status.  */
176     if (status)
177     {
178         error_counter++;
179         return;
180     }
181 
182     /* Set the global network gateway for Local IP instance.  */
183     status = nx_ip_gateway_address_set(&local_ip, NX_NAT_LOCAL_GATEWAY);
184 
185     /* Check status.  */
186     if (status)
187     {
188         error_counter++;
189         return;
190     }
191 
192     /* Set the global network gateway for External IP instance.  */
193     status = nx_ip_gateway_address_set(&external_ip, NX_NAT_EXTERNAL_GATEWAY);
194 
195     /* Check status.  */
196     if (status)
197     {
198         error_counter++;
199         return;
200     }
201 
202 
203     /* Enable ARP and supply ARP cache memory for NAT IP instance. */
204     status =  nx_arp_enable(&nat_ip, (void **) pointer,
205                             NX_NAT_ARP_CACHE_SIZE);
206 
207     /* Check status.  */
208     if (status)
209     {
210         error_counter++;
211         return;
212     }
213 
214     /* Update pointer to unallocated (free) memory. */
215     pointer = pointer + NX_NAT_ARP_CACHE_SIZE;
216 
217     /* Enable ARP and supply ARP cache memory for Local IP instance. */
218     status =  nx_arp_enable(&local_ip, (void **) pointer,
219                             NX_NAT_ARP_CACHE_SIZE);
220 
221     /* Check status.  */
222     if (status)
223     {
224         error_counter++;
225         return;
226     }
227 
228     /* Update pointer to unallocated (free) memory. */
229     pointer = pointer + NX_NAT_ARP_CACHE_SIZE;
230 
231     /* Enable ARP and supply ARP cache memory for External IP instance. */
232     status =  nx_arp_enable(&external_ip, (void **) pointer,
233                             NX_NAT_ARP_CACHE_SIZE);
234 
235     /* Check status.  */
236     if (status)
237     {
238         error_counter++;
239         return;
240     }
241 
242     /* Update pointer to unallocated (free) memory. */
243     pointer = pointer + NX_NAT_ARP_CACHE_SIZE;
244 
245     /* Enable UDP traffic.  */
246     status =  nx_udp_enable(&nat_ip);
247     status += nx_udp_enable(&local_ip);
248     status += nx_udp_enable(&external_ip);
249 
250     /* Check status.  */
251     if (status)
252     {
253         error_counter++;
254         return;
255     }
256 
257     /* Create a NetX NAT server and cache with a global interface index.  */
258     status =  nx_nat_create(&nat_server, &nat_ip, 0, pointer, NX_NAT_ENTRY_CACHE_SIZE);
259 
260     /* Check status.  */
261     if (status)
262     {
263         error_counter++;
264         return;
265     }
266 
267     /* Update pointer to unallocated (free) memory. */
268     pointer = pointer + NX_NAT_ENTRY_CACHE_SIZE;
269 }
270 
271 /* Define the test threads.  */
272 
thread_0_entry(ULONG thread_input)273 static void    thread_0_entry(ULONG thread_input)
274 {
275 
276 UINT        status;
277 NX_PACKET   *my_packet;
278 
279 
280     /* Print out test information banner.  */
281     printf("NetX Test:   NAT Invalid Header Test...................................");
282 
283     /* Create a UDP local socket.  */
284     status = nx_udp_socket_create(&local_ip, &local_socket, "Local Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5);
285 
286     /* Check status.  */
287     if (status)
288     {
289         printf("ERROR!\n");
290         test_control_return(1);
291     }
292 
293     /* Bind the UDP socket to the IP port 0x88.  */
294     status =  nx_udp_socket_bind(&local_socket, 0x88, TX_WAIT_FOREVER);
295 
296     /* Check status.  */
297     if (status)
298     {
299 
300         printf("ERROR!\n");
301         test_control_return(1);
302     }
303 
304     /* Create a UDP External socket.  */
305     status = nx_udp_socket_create(&external_ip, &external_socket, "External Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5);
306 
307     /* Check status.  */
308     if (status)
309     {
310         printf("ERROR!\n");
311         test_control_return(1);
312     }
313     /* Bind the UDP socket to the IP port 0x89.  */
314     status =  nx_udp_socket_bind(&external_socket, 0x89, TX_WAIT_FOREVER);
315 
316     /* Check status.  */
317     if (status)
318     {
319 
320         printf("ERROR!\n");
321         test_control_return(1);
322     }
323 
324     /* Enable the NAT service.  */
325     nx_nat_enable(&nat_server);
326 
327     advanced_packet_process_callback = packet_process;
328 
329     /***********************************************************************/
330     /*         External Socket sends udp packet to Local Socket            */
331     /***********************************************************************/
332 
333     /* Let other threads run again.  */
334     tx_thread_relinquish();
335 
336     /* Allocate a packet.  */
337     status =  nx_packet_allocate(&nat_packet_pool, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER);
338 
339     /* Check status.  */
340     if (status != NX_SUCCESS)
341     {
342         printf("ERROR!\n");
343         test_control_return(1);
344     }
345 
346     /* Write ABCs into the packet payload!  */
347     memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ  ", 28);
348 
349     /* Adjust the write pointer.  */
350     my_packet -> nx_packet_length =  28;
351     my_packet -> nx_packet_append_ptr =  my_packet -> nx_packet_prepend_ptr + 28;
352 
353     /* Send the UDP packet.  */
354     status =  nx_udp_socket_send(&external_socket, my_packet, NX_NAT_EXTERNAL_IPADR, 0x88);
355 
356     /* Check status.  */
357     if (status)
358     {
359 
360         printf("ERROR!\n");
361         test_control_return(1);
362     }
363 
364     /* Unbind the UDP local socket.  */
365     status =  nx_udp_socket_unbind(&local_socket);
366 
367     /* Check status.  */
368     if (status)
369     {
370 
371         printf("ERROR!\n");
372         test_control_return(1);
373     }
374 
375     /* Delete the UDP Local socket.  */
376     status =  nx_udp_socket_delete(&local_socket);
377 
378     /* Check status.  */
379     if (status)
380     {
381 
382         printf("ERROR!\n");
383         test_control_return(1);
384     }
385 
386     /* Unbind the UDP external socket.  */
387     status =  nx_udp_socket_unbind(&external_socket);
388 
389     /* Check status.  */
390     if (status)
391     {
392 
393         printf("ERROR!\n");
394         test_control_return(1);
395     }
396 
397     /* Delete the UDP external socket.  */
398     status =  nx_udp_socket_delete(&external_socket);
399 
400     /* Check status.  */
401     if (status)
402     {
403 
404         printf("ERROR!\n");
405         test_control_return(1);
406     }
407 
408     /* Check invalid packet release.  */
409     if (nat_packet_pool.nx_packet_pool_invalid_releases != 0)
410     {
411 
412         printf("ERROR!\n");
413         test_control_return(1);
414     }
415 
416     /* Output success.  */
417     printf("SUCCESS!\n");
418     test_control_return(0);
419 }
420 
packet_process(NX_IP * ip_ptr,NX_PACKET * packet_ptr,UINT * operation_ptr,UINT * delay_ptr)421 static UINT    packet_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT *operation_ptr, UINT *delay_ptr)
422 {
423 NX_IPV4_HEADER *ip_header_ptr;
424 ULONG           ip_header_length;
425 ULONG           checksum;
426 ULONG           val;
427 
428     if ((ip_ptr != &external_ip) || (packet_ptr -> nx_packet_length < 30))
429     {
430 
431         /* Not the target packet. */
432         return NX_TRUE;
433     }
434 
435     /* Trim the packet length to be less than UDP header.  */
436     /* Adjust the append pointer and length.  */
437     packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + 27;
438     packet_ptr -> nx_packet_length = 27;
439 
440     /* Get the IPv4 header.  */
441     ip_header_ptr = (NX_IPV4_HEADER *)packet_ptr -> nx_packet_prepend_ptr;
442 
443     /* Convert to host byte order. */
444     NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_0);
445     NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2);
446 
447     ip_header_ptr -> nx_ip_header_word_0 = ((ip_header_ptr -> nx_ip_header_word_0) & 0xFFFF0000) | 27;
448     ip_header_length = ((ip_header_ptr -> nx_ip_header_word_0 & NX_IP_LENGTH_MASK) >> 24) * sizeof(ULONG);
449 
450     /* Clear the checksum.  */
451     ip_header_ptr -> nx_ip_header_word_2 &= 0xFFFF0000;
452     NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2);
453 
454     /* Convert to network byte order. */
455     NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_0);
456 
457     checksum = _nx_ip_checksum_compute(packet_ptr, NX_IP_VERSION_V4,
458                                        /* Length is the size of IP header, including options */
459                                        ip_header_length,
460                                        /* IPv4 header checksum does not use src/dest addresses */
461                                        NULL, NULL);
462 
463     val = (ULONG)(~checksum);
464     val = val & NX_LOWER_16_MASK;
465 
466     /* Convert to network byte order. */
467     NX_CHANGE_ULONG_ENDIAN(val);
468 
469     /* Now store the checksum in the IP header.  */
470     ip_header_ptr -> nx_ip_header_word_2 =  ip_header_ptr -> nx_ip_header_word_2 | val;
471 
472     advanced_packet_process_callback = NX_NULL;
473     return NX_TRUE;
474 }
475 
476 #else
477 
478 extern void    test_control_return(UINT status);
479 
480 #ifdef CTEST
test_application_define(void * first_unused_memory)481 VOID test_application_define(void *first_unused_memory)
482 #else
483 void    netx_nat_invalid_header_test_application_define(void *first_unused_memory)
484 #endif
485 {
486     printf("NetX Test:   NAT Invalid Header Test...................................N/A\n");
487     test_control_return(3);
488 }
489 #endif
490