1 /* This NetX test concentrates on the raw packet IP send/receive operation. */
2
3 #include "tx_api.h"
4 #include "nx_api.h"
5 #include "nx_tcp.h"
6 #include "nx_udp.h"
7
8 extern void test_control_return(UINT status);
9
10 #if !defined(NX_DISABLE_IPV4)
11
12 #define DEMO_STACK_SIZE 2048
13
14
15 /* Define the ThreadX and NetX object control blocks... */
16
17 static TX_THREAD ntest_0;
18
19 static NX_PACKET_POOL pool_0;
20 static NX_IP ip_0;
21 static NX_IP ip_1;
22
23
24 /* Define the counters used in the test application... */
25
26 static ULONG error_counter;
27 static CHAR *ip_0_memory_ptr;
28 static CHAR *ip_1_memory_ptr;
29 static CHAR *arp_0_memory_ptr;
30 static CHAR *arp_1_memory_ptr;
31 static NX_TCP_SOCKET tcp_server_socket;
32 static NX_TCP_SOCKET tcp_client_socket;
33 static NX_UDP_SOCKET udp_server_socket;
34 static NX_UDP_SOCKET udp_client_socket;
35
36
37 /* Define thread prototypes. */
38
39 static void ntest_0_entry(ULONG thread_input);
40 extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req);
41
42
43 /* Define what the initial system looks like. */
44
45 #ifdef CTEST
test_application_define(void * first_unused_memory)46 VOID test_application_define(void *first_unused_memory)
47 #else
48 void netx_ip_raw_packet_test_application_define(void *first_unused_memory)
49 #endif
50 {
51
52 CHAR *pointer;
53 UINT status;
54
55
56 /* Setup the working pointer. */
57 pointer = (CHAR *) first_unused_memory;
58
59 error_counter = 0;
60 ip_0_memory_ptr = NX_NULL;
61 ip_1_memory_ptr = NX_NULL;
62 arp_0_memory_ptr = NX_NULL;
63 arp_1_memory_ptr = NX_NULL;
64
65 /* Create the main thread. */
66 tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0,
67 pointer, DEMO_STACK_SIZE,
68 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
69 pointer = pointer + DEMO_STACK_SIZE;
70
71 /* Initialize the NetX system. */
72 nx_system_initialize();
73
74 /* Create a packet pool. */
75 status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 512, pointer, 8192);
76 pointer = pointer + 8192;
77
78 if (status)
79 error_counter++;
80
81 /* Create IP instances. */
82 ip_0_memory_ptr = pointer;
83 status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 9), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256,
84 pointer, 2048, 1);
85 pointer = pointer + 2048;
86 ip_1_memory_ptr = pointer;
87 status = nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 10), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256,
88 pointer, 2048, 1);
89 pointer = pointer + 2048;
90
91 /* Enable ARP and supply ARP cache memory for IP Instance 0. */
92 arp_0_memory_ptr = pointer;
93 status = nx_arp_enable(&ip_0, (void *) pointer, 1024);
94 pointer = pointer + 1024;
95 arp_1_memory_ptr = pointer;
96 status += nx_arp_enable(&ip_1, (void *) pointer, 1024);
97 pointer = pointer + 1024;
98 if (status)
99 error_counter++;
100 }
101
102
103 #ifndef NX_DISABLE_FRAGMENTATION
104 static UCHAR buff[256];
105 #endif /* NX_DISABLE_FRAGMENTATION */
106
107 /* Define the test threads. */
108
ntest_0_entry(ULONG thread_input)109 static void ntest_0_entry(ULONG thread_input)
110 {
111
112 UINT status;
113 ULONG ip_address;
114 ULONG mask;
115 ULONG value;
116 ULONG ip_total_packets_sent;
117 ULONG ip_total_bytes_sent;
118 ULONG ip_total_packets_received;
119 ULONG ip_total_bytes_received;
120 ULONG ip_invalid_packets;
121 ULONG ip_receive_packets_dropped;
122 ULONG ip_receive_checksum_errors;
123 ULONG ip_send_packets_dropped;
124 ULONG ip_total_fragments_sent;
125 ULONG ip_total_fragments_received;
126 NX_PACKET *my_packet;
127
128
129 /* Print out test information banner. */
130 printf("NetX Test: IP Raw Packet Test........................................");
131
132 /* Check for earlier error. */
133 if (error_counter)
134 {
135
136 printf("ERROR!\n");
137 test_control_return(1);
138 }
139
140 /* Pickup the IP address. */
141 status = nx_ip_address_get(&ip_0, &ip_address, &mask);
142
143 /* Check for an error. */
144 if ((status) || (ip_address != IP_ADDRESS(1, 2, 3, 9)))
145 {
146
147 printf("ERROR!\n");
148 test_control_return(1);
149 }
150
151 /* Set the IP address. */
152 status = nx_ip_address_set(&ip_0, IP_ADDRESS(1, 2, 3, 13), 0xFFFFFF00UL);
153 status += nx_ip_address_get(&ip_0, &ip_address, &mask);
154
155 /* Check for an error. */
156 if ((status) || (ip_address != IP_ADDRESS(1, 2, 3, 13)))
157 {
158
159 printf("ERROR!\n");
160 test_control_return(1);
161 }
162
163 /* Delete both IP instances. */
164 status = nx_ip_delete(&ip_0);
165 status += nx_ip_delete(&ip_1);
166
167 /* Check for an error. */
168 if (status)
169 {
170
171 printf("ERROR!\n");
172 test_control_return(1);
173 }
174
175 /* Create IP instances. */
176 status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256,
177 ip_0_memory_ptr, 2048, 1);
178 status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256,
179 ip_1_memory_ptr, 2048, 1);
180 /* Enable ARP and supply ARP cache memory for IP Instance 0. */
181 status += nx_arp_enable(&ip_0, (void *) arp_0_memory_ptr, 1024);
182 status += nx_arp_enable(&ip_1, (void *) arp_1_memory_ptr, 1024);
183
184 /* Enable TCP for IP instances. */
185 status += nx_tcp_enable(&ip_0);
186 status += nx_tcp_enable(&ip_1);
187
188 /* Enable UDP for IP instances. */
189 status += nx_udp_enable(&ip_0);
190 status += nx_udp_enable(&ip_1);
191
192 /* Check the status of the IP instances. */
193 status += nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &value, NX_IP_PERIODIC_RATE);
194
195 /* Check for an error. */
196 if ((status) || (value != NX_IP_INITIALIZE_DONE))
197 {
198
199 printf("ERROR!\n");
200 test_control_return(1);
201 }
202
203 /* Call driver directly. */
204 status = nx_ip_driver_direct_command(&ip_0, NX_LINK_GET_STATUS, &value);
205
206 /* Check for an error. */
207 if (status)
208 {
209
210 printf("ERROR!\n");
211 test_control_return(1);
212 }
213
214 /* Enable and disable forwarding. */
215 status = nx_ip_forwarding_enable(&ip_0);
216 status += nx_ip_forwarding_disable(&ip_0);
217
218 /* Check for an error. */
219 if (status)
220 {
221
222 printf("ERROR!\n");
223 test_control_return(1);
224 }
225
226 #ifndef NX_DISABLE_FRAGMENTATION
227 /* Enable and disable fragmenting. */
228 status = nx_ip_fragment_enable(&ip_0);
229 status += nx_ip_fragment_disable(&ip_0);
230 status += nx_ip_fragment_enable(&ip_0);
231 status += nx_ip_fragment_enable(&ip_1);
232 status += nx_ip_fragment_disable(&ip_1);
233 status += nx_ip_fragment_enable(&ip_1);
234
235 /* Check for an error. */
236 if (status)
237 {
238
239 printf("ERROR!\n");
240 test_control_return(1);
241 }
242 #endif
243
244 /* Set the gateway address. */
245 status = nx_ip_gateway_address_set(&ip_0, IP_ADDRESS(1, 2, 3, 87));
246
247 /* Check for an error. */
248 if (status)
249 {
250
251 printf("ERROR!\n");
252 test_control_return(1);
253 }
254
255 /* Get IP info. */
256 status = nx_ip_info_get(&ip_0, &ip_total_packets_sent,
257 &ip_total_bytes_sent,
258 &ip_total_packets_received,
259 &ip_total_bytes_received,
260 &ip_invalid_packets,
261 &ip_receive_packets_dropped,
262 &ip_receive_checksum_errors,
263 &ip_send_packets_dropped,
264 &ip_total_fragments_sent,
265 &ip_total_fragments_received);
266
267 /* Check status. */
268 if ((status) || (ip_total_packets_sent) || (ip_total_bytes_sent) || (ip_total_packets_received) ||
269 (ip_total_bytes_received) || (ip_invalid_packets) || (ip_receive_packets_dropped) || (ip_receive_checksum_errors) ||
270 (ip_send_packets_dropped) || (ip_total_fragments_sent) || (ip_total_fragments_received))
271 {
272
273 printf("ERROR!\n");
274 test_control_return(1);
275 }
276
277 /* Enable raw IP packet sending and receiving. This can only be done between two NetX nodes. */
278 status = nx_ip_raw_packet_enable(&ip_0);
279 status += nx_ip_raw_packet_enable(&ip_1);
280
281 #ifndef NX_DISABLE_FRAGMENTATION
282 /* Allocate a packet. */
283 status += nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER);
284
285 /* Write ABCs into the packet payload! */
286 status += nx_packet_data_append(my_packet, buff, sizeof(buff), &pool_0, NX_WAIT_FOREVER);
287
288 /* Check status. */
289 if (status != NX_SUCCESS)
290 {
291
292 printf("ERROR!\n");
293 test_control_return(1);
294 }
295
296 /* Send the raw IP packet. */
297 status = nx_ip_raw_packet_send(&ip_0, my_packet, IP_ADDRESS(1, 2, 3, 5), NX_IP_NORMAL);
298
299 /* Check status. */
300 if (status != NX_SUCCESS)
301 {
302
303 printf("ERROR!\n");
304 test_control_return(1);
305 }
306 #endif /* NX_DISABLE_FRAGMENTATION */
307
308 /* Allocate another packet. */
309 status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER);
310
311 /* Check status. */
312 if (status != NX_SUCCESS)
313 {
314
315 printf("ERROR!\n");
316 test_control_return(1);
317 }
318
319 /* Write ABCs into the packet payload! */
320 memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28);
321
322 /* Adjust the write pointer. */
323 my_packet -> nx_packet_length = 28;
324 my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28;
325
326 #ifdef __PRODUCT_NETXDUO__
327 /* Send the second raw IP packet. */
328 status = nx_ip_raw_packet_source_send(&ip_0, my_packet, IP_ADDRESS(1, 2, 3, 5), 0, NX_IP_NORMAL);
329 #else
330 status = nx_ip_raw_packet_send(&ip_0, my_packet, IP_ADDRESS(1, 2, 3, 5), NX_IP_NORMAL);
331 #endif /* __PRODUCT_NETXDUO__ */
332
333 /* Check status. */
334 if (status != NX_SUCCESS)
335 {
336
337 printf("ERROR!\n");
338 test_control_return(1);
339 }
340
341 /* Allocate another packet. */
342 status = nx_packet_allocate(&pool_0, &my_packet, NX_UDP_PACKET, TX_WAIT_FOREVER);
343
344 /* Check status. */
345 if (status != NX_SUCCESS)
346 {
347
348 printf("ERROR!\n");
349 test_control_return(1);
350 }
351
352 /* Write ABCs into the packet payload! */
353 memcpy(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28);
354
355 /* Adjust the write pointer. */
356 my_packet -> nx_packet_length = 28;
357 my_packet -> nx_packet_append_ptr = my_packet -> nx_packet_prepend_ptr + 28;
358
359 /* Send the third raw IP packet. */
360 status = nx_ip_raw_packet_send(&ip_0, my_packet, IP_ADDRESS(1, 2, 3, 5), NX_IP_NORMAL);
361
362 /* Check status. */
363 if (status != NX_SUCCESS)
364 {
365
366 printf("ERROR!\n");
367 test_control_return(1);
368 }
369
370 #ifndef NX_DISABLE_FRAGMENTATION
371 /* Now, pickup the three raw packets that should be queued on the other IP instance. */
372 status = nx_ip_raw_packet_receive(&ip_1, &my_packet, NX_IP_PERIODIC_RATE);
373 status += nx_packet_release(my_packet);
374 /* Check status. */
375 if (status != NX_SUCCESS)
376 {
377
378 printf("ERROR!\n");
379 test_control_return(1);
380 }
381 #endif /* NX_DISABLE_FRAGMENTATION */
382
383 /* Receive the second packet. */
384 status = nx_ip_raw_packet_receive(&ip_1, &my_packet, NX_IP_PERIODIC_RATE);
385 status += nx_packet_release(my_packet);
386 /* Check status. */
387 if (status != NX_SUCCESS)
388 {
389
390 printf("ERROR!\n");
391 test_control_return(1);
392 }
393
394 /* Receive the third packet. */
395 status = nx_ip_raw_packet_receive(&ip_1, &my_packet, NX_IP_PERIODIC_RATE);
396 status += nx_packet_release(my_packet);
397 /* Check status. */
398 if (status != NX_SUCCESS)
399 {
400
401 printf("ERROR!\n");
402 test_control_return(1);
403 }
404
405 /* Attempt to receive a packet on an empty queue.... should be an error. */
406 status = nx_ip_raw_packet_receive(&ip_1, &my_packet, NX_NO_WAIT);
407
408 /* Check status. */
409 if (status != NX_NO_PACKET)
410 {
411
412 printf("ERROR!\n");
413 test_control_return(1);
414 }
415
416 /* Check TCP connection when raw packet is enabled. */
417 /* Create a server socket. */
418 status = nx_tcp_socket_create(&ip_1, &tcp_server_socket, "Server Socket",
419 NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 200,
420 NX_NULL, NX_NULL);
421
422 /* Setup this thread to listen. */
423 status += nx_tcp_server_socket_listen(&ip_1, 12, &tcp_server_socket, 5, NX_NULL);
424
425 /* Create a client socket. */
426 status += nx_tcp_socket_create(&ip_0, &tcp_client_socket, "Client Socket",
427 NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 300,
428 NX_NULL, NX_NULL);
429
430 /* Bind the socket. */
431 status += nx_tcp_client_socket_bind(&tcp_client_socket, 12, NX_WAIT_FOREVER);
432
433 /* Connect to server. */
434 nx_tcp_client_socket_connect(&tcp_client_socket, IP_ADDRESS(1, 2, 3, 5), 12, NX_NO_WAIT);
435
436 /* If accept return successfully, then it handles an illegal option length for MSS. */
437 status += nx_tcp_server_socket_accept(&tcp_server_socket, NX_IP_PERIODIC_RATE);
438
439 /* Check if client is in establish state. */
440 status += nx_tcp_socket_state_wait(&tcp_client_socket, NX_TCP_ESTABLISHED, NX_NO_WAIT);
441
442 /* Check status. */
443 if (status)
444 {
445
446 printf("ERROR!\n");
447 test_control_return(1);
448 }
449
450 /* Allocate a packet. */
451 status = nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, 5 * NX_IP_PERIODIC_RATE);
452
453 /* Append data. */
454 status += nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, NX_NO_WAIT);
455
456 /* Send a packet from server to client. */
457 status += nx_tcp_socket_send(&tcp_server_socket, my_packet, NX_NO_WAIT);
458
459 /* Receive packet from server. */
460 status += nx_tcp_socket_receive(&tcp_client_socket, &my_packet, 5 * NX_IP_PERIODIC_RATE);
461
462 /* Check status and received data. */
463 if(status || memcmp(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28))
464 status++;
465
466 /* Release packet. */
467 status += nx_packet_release(my_packet);
468
469 /* Disconnect. */
470 nx_tcp_socket_disconnect(&tcp_server_socket, NX_NO_WAIT);
471 nx_tcp_socket_disconnect(&tcp_client_socket, NX_NO_WAIT);
472 nx_tcp_server_socket_unaccept(&tcp_server_socket);
473
474 /* Check if both sockets are closed. */
475 status += nx_tcp_socket_state_wait(&tcp_client_socket, NX_TCP_CLOSED, NX_NO_WAIT);
476 status += nx_tcp_socket_state_wait(&tcp_client_socket, NX_TCP_CLOSED, NX_NO_WAIT);
477
478 /* Check status. */
479 if (status)
480 {
481
482 printf("ERROR!\n");
483 test_control_return(1);
484 }
485
486 /* Check UDP connection when raw packet is enabled. */
487 /* Create two UDP sockets. */
488 status = nx_udp_socket_create(&ip_0, &udp_client_socket, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5);
489 status += nx_udp_socket_create(&ip_1, &udp_server_socket, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5);
490
491 /* Bind the UDP socket to the IP port. */
492 status += nx_udp_socket_bind(&udp_client_socket, 0x89, NX_NO_WAIT);
493 status += nx_udp_socket_bind(&udp_server_socket, 0x89, NX_NO_WAIT);
494
495 /* Allocate a packet. */
496 status += nx_packet_allocate(&pool_0, &my_packet, NX_TCP_PACKET, 5 * NX_IP_PERIODIC_RATE);
497
498 /* Append data. */
499 status += nx_packet_data_append(my_packet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28, &pool_0, NX_NO_WAIT);
500
501 /* Send the UDP packet. */
502 status += nx_udp_socket_send(&udp_client_socket, my_packet, IP_ADDRESS(1, 2, 3, 5), 0x89);
503
504 /* Receive a UDP packet. */
505 status += nx_udp_socket_receive(&udp_server_socket, &my_packet, 5 * NX_IP_PERIODIC_RATE);
506
507 /* Check status and received data. */
508 if(status || memcmp(my_packet -> nx_packet_prepend_ptr, "ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 28))
509 status++;
510
511 /* Unbind the UDP socket. */
512 status += nx_udp_socket_unbind(&udp_client_socket);
513 status += nx_udp_socket_unbind(&udp_server_socket);
514
515 /* Check status. */
516 if (status)
517 {
518
519 printf("ERROR!\n");
520 test_control_return(1);
521 }
522
523
524 /* Disable the raw IP capability on both IP instances. */
525 status = nx_ip_raw_packet_disable(&ip_0);
526 status += nx_ip_raw_packet_disable(&ip_1);
527
528 /* Check status. */
529 if (status)
530 {
531
532 printf("ERROR!\n");
533 test_control_return(1);
534 }
535 else
536 {
537
538 printf("SUCCESS!\n");
539 test_control_return(0);
540 }
541 }
542 #else
543
544 #ifdef CTEST
test_application_define(void * first_unused_memory)545 VOID test_application_define(void *first_unused_memory)
546 #else
547 void netx_ip_raw_packet_test_application_define(void *first_unused_memory)
548 #endif
549 {
550
551 /* Print out test information banner. */
552 printf("NetX Test: IP Raw Packet Test........................................N/A\n");
553
554 test_control_return(3);
555 }
556 #endif
557
558