1
2 /* This NetX test concentrates on the TCP operation. */
3
4 #include "tx_api.h"
5 #include "nx_api.h"
6 #include "nx_tcp.h"
7
8 extern void test_control_return(UINT status);
9 #if defined NX_NAT_ENABLE && defined __PRODUCT_NETXDUO__ && (NX_MAX_PHYSICAL_INTERFACES >= 2) && !defined(NX_DISABLE_IPV4)
10 #include "nx_nat.h"
11
12 #define DEMO_STACK_SIZE 2048
13
14 /* Define the ThreadX and NetX object control blocks... */
15
16 static TX_THREAD thread_0;
17 static TX_THREAD thread_1;
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_TCP_SOCKET local_socket;
29 NX_TCP_SOCKET nat_socket;
30 NX_TCP_SOCKET external_socket;
31
32
33 /* Configure the NAT network parameters. */
34
35 /* Set NetX IP packet pool packet size. This should be less than the Maximum Transmit Unit (MTU) of
36 the driver (allow enough room for the Ethernet header plus padding bytes for frame alignment). */
37 #define NX_NAT_PACKET_SIZE 1536
38
39
40 /* Set the size of the NAT IP packet pool. */
41 #define NX_NAT_PACKET_POOL_SIZE (NX_NAT_PACKET_SIZE * 10)
42
43 /* Set NetX IP helper thread stack size. */
44 #define NX_NAT_IP_THREAD_STACK_SIZE 2048
45
46 /* Set the server IP thread priority */
47 #define NX_NAT_IP_THREAD_PRIORITY 2
48
49 /* Set ARP cache size of a NAT ip instance. */
50 #define NX_NAT_ARP_CACHE_SIZE 1024
51
52 /* Set NAT entries memory size. */
53 #define NX_NAT_ENTRY_CACHE_SIZE 1024
54
55 /* Define NAT IP addresses, local host private IP addresses and external host IP address. */
56 #define NX_NAT_LOCAL_IPADR (IP_ADDRESS(192, 168, 2, 1))
57 #define NX_NAT_LOCAL_HOST1 (IP_ADDRESS(192, 168, 2, 3))
58 #define NX_NAT_LOCAL_HOST2 (IP_ADDRESS(192, 168, 2, 10))
59 #define NX_NAT_LOCAL_GATEWAY (IP_ADDRESS(192, 168, 2, 1))
60 #define NX_NAT_LOCAL_NETMASK (IP_ADDRESS(255, 255, 255, 0))
61 #define NX_NAT_EXTERNAL_IPADR (IP_ADDRESS(192, 168, 0, 10))
62 #define NX_NAT_EXTERNAL_HOST (IP_ADDRESS(192, 168, 0, 100))
63 #define NX_NAT_EXTERNAL_GATEWAY (IP_ADDRESS(192, 168, 0, 1))
64 #define NX_NAT_EXTERNAL_NETMASK (IP_ADDRESS(255, 255, 255, 0))
65
66 /* Create NAT structures for preloading NAT tables with static
67 entries for local server hosts. */
68 NX_NAT_TRANSLATION_ENTRY server_inbound_entry_tcp1;
69 NX_NAT_TRANSLATION_ENTRY server_inbound_entry_tcp2;
70
71 /* Set up generic network driver for demo program. */
72 extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req);
73
74
75 /* Define thread prototypes. */
76
77 static void thread_0_entry(ULONG thread_input);
78 static void thread_1_entry(ULONG thread_input);
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_tcp_port_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 the main thread. */
106 tx_thread_create(&thread_1, "thread 1", thread_1_entry, 0,
107 pointer, DEMO_STACK_SIZE,
108 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
109 pointer = pointer + DEMO_STACK_SIZE;
110
111 /* Create NAT packet pool. */
112 status = nx_packet_pool_create(&nat_packet_pool, "NAT Packet Pool",
113 NX_NAT_PACKET_SIZE, pointer,
114 NX_NAT_PACKET_POOL_SIZE);
115
116 /* Update pointer to unallocated (free) memory. */
117 pointer = pointer + NX_NAT_PACKET_POOL_SIZE;
118
119 /* Check status. */
120 if (status)
121 return;
122
123 /* Create IP instances for NAT server (global network) */
124 status = nx_ip_create(&nat_ip, "NAT IP Instance", NX_NAT_EXTERNAL_IPADR, NX_NAT_EXTERNAL_NETMASK,
125 &nat_packet_pool, _nx_ram_network_driver_1500, pointer,
126 NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY);
127
128 /* Update pointer to unallocated (free) memory. */
129 pointer = pointer + NX_NAT_IP_THREAD_STACK_SIZE;
130
131 /* Check status. */
132 if (status)
133 {
134 error_counter++;
135 return;
136 }
137
138 /* Set the private interface(private network). */
139 status += nx_ip_interface_attach(&nat_ip, "Private Interface", NX_NAT_LOCAL_IPADR, NX_NAT_LOCAL_NETMASK, _nx_ram_network_driver_1500);
140
141 /* Check status. */
142 if (status)
143 {
144 error_counter++;
145 return;
146 }
147
148 /* Create IP instances for Local network IP instance */
149 status = nx_ip_create(&local_ip, "Local IP Instance", NX_NAT_LOCAL_HOST1, NX_NAT_LOCAL_NETMASK,
150 &nat_packet_pool, _nx_ram_network_driver_1500, pointer,
151 NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY);
152
153 /* Update pointer to unallocated (free) memory. */
154 pointer = pointer + NX_NAT_IP_THREAD_STACK_SIZE;
155
156 /* Check status. */
157 if (status)
158 {
159 error_counter++;
160 return;
161 }
162
163 /* Create IP instances for external network IP instance */
164 status = nx_ip_create(&external_ip, "External IP Instance", NX_NAT_EXTERNAL_HOST, NX_NAT_EXTERNAL_NETMASK,
165 &nat_packet_pool, _nx_ram_network_driver_1500, pointer,
166 NX_NAT_IP_THREAD_STACK_SIZE, NX_NAT_IP_THREAD_PRIORITY);
167
168 /* Update pointer to unallocated (free) memory. */
169 pointer = pointer + NX_NAT_IP_THREAD_STACK_SIZE;
170
171 /* Check status. */
172 if (status)
173 {
174 error_counter++;
175 return;
176 }
177
178 /* Set the global network gateway for NAT IP instance. */
179 status = nx_ip_gateway_address_set(&nat_ip, NX_NAT_EXTERNAL_GATEWAY);
180
181 /* Check status. */
182 if (status)
183 {
184 error_counter++;
185 return;
186 }
187
188 /* Set the global network gateway for Local IP instance. */
189 status = nx_ip_gateway_address_set(&local_ip, NX_NAT_LOCAL_GATEWAY);
190
191 /* Check status. */
192 if (status)
193 {
194 error_counter++;
195 return;
196 }
197
198 /* Set the global network gateway for External IP instance. */
199 status = nx_ip_gateway_address_set(&external_ip, NX_NAT_EXTERNAL_GATEWAY);
200
201 /* Check status. */
202 if (status)
203 {
204 error_counter++;
205 return;
206 }
207
208
209 /* Enable ARP and supply ARP cache memory for NAT IP isntance. */
210 status = nx_arp_enable(&nat_ip, (void **) pointer,
211 NX_NAT_ARP_CACHE_SIZE);
212
213 /* Check status. */
214 if (status)
215 {
216 error_counter++;
217 return;
218 }
219
220 /* Update pointer to unallocated (free) memory. */
221 pointer = pointer + NX_NAT_ARP_CACHE_SIZE;
222
223 /* Enable ARP and supply ARP cache memory for Local IP isntance. */
224 status = nx_arp_enable(&local_ip, (void **) pointer,
225 NX_NAT_ARP_CACHE_SIZE);
226
227 /* Check status. */
228 if (status)
229 {
230 error_counter++;
231 return;
232 }
233
234 /* Update pointer to unallocated (free) memory. */
235 pointer = pointer + NX_NAT_ARP_CACHE_SIZE;
236
237 /* Enable ARP and supply ARP cache memory for External IP isntance. */
238 status = nx_arp_enable(&external_ip, (void **) pointer,
239 NX_NAT_ARP_CACHE_SIZE);
240
241 /* Check status. */
242 if (status)
243 {
244 error_counter++;
245 return;
246 }
247
248 /* Update pointer to unallocated (free) memory. */
249 pointer = pointer + NX_NAT_ARP_CACHE_SIZE;
250
251 /* Enable TCP traffic. */
252 status += nx_tcp_enable(&local_ip);
253 status += nx_tcp_enable(&nat_ip);
254 status += nx_tcp_enable(&external_ip);
255
256 /* Check status. */
257 if (status)
258 {
259 error_counter++;
260 return;
261 }
262
263 /* Create a NetX NAT server and cache with a global interface index. */
264 status = nx_nat_create(&nat_server, &nat_ip, 0, pointer, NX_NAT_ENTRY_CACHE_SIZE);
265
266 /* Check status. */
267 if (status)
268 {
269 error_counter++;
270 return;
271 }
272
273 /* Update pointer to unallocated (free) memory. */
274 pointer = pointer + NX_NAT_ENTRY_CACHE_SIZE;
275
276 /* Enable the NAT service. */
277 nx_nat_enable(&nat_server);
278 }
279
280 /* Define the test threads. */
281
thread_0_entry(ULONG thread_input)282 static void thread_0_entry(ULONG thread_input)
283 {
284
285 UINT status;
286 NX_PACKET *my_packet;
287 ULONG packets_sent, bytes_sent, packets_received, bytes_received, retransmit_packets, packets_queued, checksum_errors, socket_state, transmit_queue_depth, transmit_window, receive_window;
288
289
290 /* Print out test information banner. */
291 printf("NetX Test: NAT TCP Port Processing Test..............................");
292
293 /* Create a TCP socket for NAT IP instance. */
294 status = nx_tcp_socket_create(&nat_ip, &nat_socket, "NAT Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, NX_NULL, NX_NULL);
295
296 /* Check status. */
297 if (status)
298 {
299 printf("ERROR!\n");
300 test_control_return(1);
301 }
302
303 /* Bind the socket to the IP port as NX_NAT_START_TCP_PORT. */
304 status = nx_tcp_client_socket_bind(&nat_socket, NX_NAT_START_TCP_PORT, NX_WAIT_FOREVER);
305
306 /* Check status. */
307 if (status)
308 {
309
310 printf("ERROR!\n");
311 test_control_return(1);
312 }
313
314 /* Preload a NAT entry with same external TCP port of NAT socket. */
315 status = nx_nat_inbound_entry_create(&nat_server, &server_inbound_entry_tcp1, NX_NAT_LOCAL_HOST1, NX_NAT_START_TCP_PORT, NX_NAT_START_TCP_PORT, NX_PROTOCOL_TCP);
316
317 /* Check status. */
318 if (status != NX_NAT_PORT_UNAVAILABLE)
319 {
320
321 printf("ERROR!\n");
322 test_control_return(1);
323 }
324
325 /* Preload a NAT entry with different external TCP port of NAT socket. */
326 status = nx_nat_inbound_entry_create(&nat_server, &server_inbound_entry_tcp1, NX_NAT_LOCAL_HOST1, NX_NAT_START_TCP_PORT - 1, NX_NAT_START_TCP_PORT, NX_PROTOCOL_TCP);
327
328 /* Check status. */
329 if (status)
330 {
331
332 printf("ERROR!\n");
333 test_control_return(1);
334 }
335
336 /* Preload a NAT entry with same external TCP port of NAT entry. */
337 status = nx_nat_inbound_entry_create(&nat_server, &server_inbound_entry_tcp2, NX_NAT_LOCAL_HOST1, NX_NAT_START_TCP_PORT - 1, NX_NAT_START_TCP_PORT, NX_PROTOCOL_TCP);
338
339 /* Check status. */
340 if (status != NX_NAT_PORT_UNAVAILABLE)
341 {
342
343 printf("ERROR!\n");
344 test_control_return(1);
345 }
346
347 /* Delete the inbound entry. */
348 status = nx_nat_inbound_entry_delete(&nat_server, &server_inbound_entry_tcp1);
349
350 /* Check status. */
351 if (status)
352 {
353
354 printf("ERROR!\n");
355 test_control_return(1);
356 }
357
358 /* Create a TCP local socket. */
359 status = nx_tcp_socket_create(&local_ip, &local_socket, "Local Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200, NX_NULL, NX_NULL);
360
361 /* Check status. */
362 if (status)
363 {
364 printf("ERROR!\n");
365 test_control_return(1);
366 }
367
368 /* Bind the socket to the IP port 0x88. */
369 status = nx_tcp_client_socket_bind(&local_socket, 0x88, NX_WAIT_FOREVER);
370
371 /* Check status. */
372 if (status)
373 {
374
375 printf("ERROR!\n");
376 test_control_return(1);
377 }
378
379 /***********************************************************************/
380 /* Local Socket sends tcp packet to External Socket */
381 /***********************************************************************/
382
383 /* Let other threads run again. */
384 tx_thread_relinquish();
385
386 /* Attempt to connect the socket. */
387 status = nx_tcp_client_socket_connect(&local_socket, NX_NAT_EXTERNAL_HOST, 0x89, 5 * NX_IP_PERIODIC_RATE);
388
389 /* Check status. */
390 if (status)
391 {
392 printf("ERROR!\n");
393 test_control_return(1);
394 }
395
396 /* Wait for established state. */
397 status = nx_tcp_socket_state_wait(&local_socket, NX_TCP_ESTABLISHED, 5 * NX_IP_PERIODIC_RATE);
398
399 /* Check status. */
400 if (status)
401 {
402 printf("ERROR!\n");
403 test_control_return(1);
404 }
405
406 /* Allocate a packet. */
407 status = nx_packet_allocate(&nat_packet_pool, &my_packet, NX_TCP_PACKET, TX_WAIT_FOREVER);
408
409 /* Check status. */
410 if (status != NX_SUCCESS)
411 {
412 printf("ERROR!\n");
413 test_control_return(1);
414 }
415
416 /* Write ABCs into the packet payload! */
417 memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28);
418
419 /* Adjust the write pointer. */
420 my_packet -> nx_packet_length = 28;
421 my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28;
422
423 /* Send the TCP packet. */
424 status = nx_tcp_socket_send(&local_socket, my_packet, 5 * NX_IP_PERIODIC_RATE);
425
426 /* Check status. */
427 if (status)
428 {
429
430 printf("ERROR!\n");
431 test_control_return(1);
432 }
433
434 /* Check status. */
435 if (status)
436 {
437
438 printf("ERROR!\n");
439 test_control_return(1);
440 }
441
442 /* Let other threads run again. */
443 tx_thread_relinquish();
444
445 /* Disconnect this socket. */
446 status = nx_tcp_socket_disconnect(&local_socket, 5 * NX_IP_PERIODIC_RATE);
447
448 /* Determine if the status is valid. */
449 if (status)
450 {
451 printf("ERROR!\n");
452 test_control_return(1);
453 }
454
455 /* Unbind the socket. */
456 status = nx_tcp_client_socket_unbind(&local_socket);
457
458 /* Check for error. */
459 if (status)
460 {
461 printf("ERROR!\n");
462 test_control_return(1);
463 }
464
465 /* Get information about this socket. */
466 status = nx_tcp_socket_info_get(&local_socket, &packets_sent, &bytes_sent,
467 &packets_received, &bytes_received,
468 &retransmit_packets, &packets_queued,
469 &checksum_errors, &socket_state,
470 &transmit_queue_depth, &transmit_window,
471 &receive_window);
472
473 #ifndef NX_DISABLE_TCP_INFO
474
475 if((packets_sent != 1) || (bytes_sent != 28))
476 {
477 printf("ERROR!\n");
478 test_control_return(1);
479 }
480 #endif
481
482 /* Check for errors. */
483 if ((status) || (packets_received) || (bytes_received) ||
484 (retransmit_packets) || (packets_queued) || (checksum_errors) || (socket_state != NX_TCP_CLOSED) ||
485 (transmit_queue_depth) || (transmit_window != 100) || (receive_window != 200))
486 {
487 printf("ERROR!\n");
488 test_control_return(1);
489 }
490
491 /* Delete the socket. */
492 status = nx_tcp_socket_delete(&local_socket);
493
494 /* Check for error. */
495 if (status)
496 {
497 printf("ERROR!\n");
498 test_control_return(1);
499 }
500
501 /* Check the NAT forwarded count. */
502 #ifndef NX_DISABLE_NAT_INFO
503 if ((nat_server.forwarded_packets_received != 8) || (nat_server.forwarded_packets_sent != 8) ||(nat_server.forwarded_packets_dropped != 0))
504 {
505 printf("ERROR!\n");
506 test_control_return(1);
507 }
508 #endif
509
510 /* Output success. */
511 printf("SUCCESS!\n");
512 test_control_return(0);
513 }
514
515
thread_1_entry(ULONG thread_input)516 static void thread_1_entry(ULONG thread_input)
517 {
518
519 UINT status;
520 NX_PACKET *my_packet;
521 ULONG peer_ip_address;
522 ULONG peer_port;
523
524
525 /* Create a socket. */
526 status = nx_tcp_socket_create(&external_ip, &external_socket, "External Server Socket",
527 NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100,
528 NX_NULL, NX_NULL);
529
530 /* Check for error. */
531 if (status)
532 {
533 printf("ERROR!\n");
534 test_control_return(1);
535 }
536
537 /***********************************************************************/
538 /* External Socket receives the udp packet from Local Socket */
539 /***********************************************************************/
540
541 /* Setup this thread to listen. */
542 status = nx_tcp_server_socket_listen(&external_ip, 0x89, &external_socket, 5, NX_NULL);
543
544 /* Check for error. */
545 if (status)
546 {
547 printf("ERROR!\n");
548 test_control_return(1);
549 }
550
551 /* Accept a client socket connection. */
552 status = nx_tcp_server_socket_accept(&external_socket, NX_WAIT_FOREVER);
553
554 /* Check for error. */
555 if (status)
556 {
557 printf("ERROR!\n");
558 test_control_return(1);
559 }
560
561 /* Check the peer socket port. */
562 status = nx_tcp_socket_peer_info_get(&external_socket, &peer_ip_address, &peer_port);
563
564 /* Check status. */
565 if ((status) || (peer_ip_address != NX_NAT_EXTERNAL_IPADR) || (peer_port != NX_NAT_START_TCP_PORT + 1))
566 {
567 printf("ERROR!\n");
568 test_control_return(1);
569 }
570
571 /* Receive a TCP message from the socket. */
572 status = nx_tcp_socket_receive(&external_socket, &my_packet, 5 * NX_IP_PERIODIC_RATE);
573
574 /* Check for error. */
575 if (status)
576 {
577 printf("ERROR!\n");
578 test_control_return(1);
579 }
580 else
581 {
582
583 /* Release the packet. */
584 nx_packet_release(my_packet);
585 }
586
587 /* Disconnect the server socket. */
588 status = nx_tcp_socket_disconnect(&external_socket, 5 * NX_IP_PERIODIC_RATE);
589
590 /* Check for error. */
591 if (status)
592 {
593 printf("ERROR!\n");
594 test_control_return(1);
595 }
596
597 /* Unaccept the server socket. */
598 status = nx_tcp_server_socket_unaccept(&external_socket);
599
600 /* Check for error. */
601 if (status)
602 {
603 printf("ERROR!\n");
604 test_control_return(1);
605 }
606
607 /* Unlisten on the server port. */
608 status = nx_tcp_server_socket_unlisten(&external_ip, 0x89);
609
610 /* Check for error. */
611 if (status)
612 {
613 printf("ERROR!\n");
614 test_control_return(1);
615 }
616
617 /* Delete the socket. */
618 status = nx_tcp_socket_delete(&external_socket);
619
620 /* Check for error. */
621 if (status)
622 {
623 printf("ERROR!\n");
624 test_control_return(1);
625 }
626 }
627
628 #else
629
630 #ifdef CTEST
test_application_define(void * first_unused_memory)631 VOID test_application_define(void *first_unused_memory)
632 #else
633 void netx_nat_tcp_port_test_application_define(void *first_unused_memory)
634 #endif
635 {
636 printf("NetX Test: NAT TCP Port Processing Test..............................N/A\n");
637 test_control_return(3);
638 }
639 #endif
640