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