1 /* This NetX test concentrates on the basic BSD RAW blocking operation. */
2
3 #include "tx_api.h"
4 #include "nx_api.h"
5 #if defined(__PRODUCT_NETXDUO__) && !defined(NX_DISABLE_IPV4)
6 #ifdef NX_BSD_ENABLE
7 #include "nxd_bsd.h"
8 #include "nx_icmpv6.h"
9 #define DEMO_STACK_SIZE 8192
10
11
12 /* Define the ThreadX and NetX object control blocks... */
13
14 static TX_THREAD ntest_0;
15 static TX_THREAD ntest_1;
16
17 static NX_PACKET_POOL pool_0;
18 static NX_IP ip_0;
19 static NX_IP ip_1;
20 static ULONG bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)];
21 #define BSD_THREAD_PRIORITY 2
22 #define NUM_CLIENTS 20
23 /* Define the counters used in the test application... */
24
25 static ULONG error_counter;
26
27
28 /* Define thread prototypes. */
29
30 static void ntest_0_entry(ULONG thread_input);
31 static void ntest_1_entry(ULONG thread_input);
32 extern void test_control_return(UINT status);
33 extern void _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req);
34 static void validate_bsd_structure(void);
35 #ifdef FEATURE_NX_IPV6
36 static NXD_ADDRESS ipv6_address_ip0;
37 static NXD_ADDRESS ipv6_address_ip1;
38 #endif /* FEATURE_NX_IPV6 */
39 static char *requests[4] = {"Request1", "Request2", "Request3", "Request4"};
40 static char *response[4] = {"Response1", "Response2", "Response3", "Response4"};
41 extern UINT _nxd_ip_raw_packet_send(NX_IP *ip_ptr, NX_PACKET *packet_ptr, NXD_ADDRESS *destination_ip, ULONG protocol, UINT ttl, ULONG tos);
42 /* Define what the initial system looks like. */
43
44 #ifdef CTEST
test_application_define(void * first_unused_memory)45 VOID test_application_define(void *first_unused_memory)
46 #else
47 void netx_bsd_raw_basic_blocking_test_application_define(void *first_unused_memory)
48 #endif
49 {
50
51 CHAR *pointer;
52 UINT status;
53
54
55 /* Setup the working pointer. */
56 pointer = (CHAR *) first_unused_memory;
57
58 error_counter = 0;
59
60 /* Create the main thread. */
61 tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0,
62 pointer, DEMO_STACK_SIZE,
63 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START);
64
65 pointer = pointer + DEMO_STACK_SIZE;
66
67 /* Create the main thread. */
68 tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0,
69 pointer, DEMO_STACK_SIZE,
70 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
71
72 pointer = pointer + DEMO_STACK_SIZE;
73
74
75 /* Initialize the NetX system. */
76 nx_system_initialize();
77
78 /* Create a packet pool. */
79 status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, pointer, (256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 2);
80 pointer = pointer + (256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 2;
81
82 if (status)
83 error_counter++;
84
85 /* Create an IP instance. */
86 status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256,
87 pointer, 2048, 1);
88 pointer = pointer + 2048;
89
90 /* Create another IP instance. */
91 status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256,
92 pointer, 2048, 2);
93 pointer = pointer + 2048;
94 if (status)
95 error_counter++;
96
97 /* Enable ARP and supply ARP cache memory for IP Instance 0. */
98 status = nx_arp_enable(&ip_0, (void *) pointer, 1024);
99 pointer = pointer + 1024;
100 if (status)
101 error_counter++;
102
103 /* Enable ARP and supply ARP cache memory for IP Instance 1. */
104 status = nx_arp_enable(&ip_1, (void *) pointer, 1024);
105 pointer = pointer + 1024;
106 if (status)
107 error_counter++;
108
109 /* Enable raw processing for both IP instances. */
110 status += nx_ip_raw_packet_enable(&ip_0);
111 status += nx_ip_raw_packet_enable(&ip_1);
112
113 /* Enable BSD */
114 status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY);
115
116 /* Check RAW enable and BSD init status. */
117 if (status)
118 error_counter++;
119 }
120
test_raw_server_ipv4(void)121 static void test_raw_server_ipv4(void)
122 {
123 int sockfd;
124 struct sockaddr_in remote_addr;
125 struct sockaddr_ll sock_addr;
126 int ret;
127 char buf[30];
128 int addrlen;
129
130
131 sockfd = socket(AF_INET, SOCK_RAW, 100);
132 if(sockfd < 0)
133 error_counter++;
134
135 /* Receive data from the client. */
136 addrlen = sizeof(remote_addr);
137 ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr*)&remote_addr, &addrlen);
138 if(ret <= 0)
139 error_counter++;
140
141 if(addrlen != sizeof(struct sockaddr_in))
142 error_counter++;
143
144 if((remote_addr.sin_family != AF_INET) ||
145 (remote_addr.sin_addr.s_addr != htonl(IP_ADDRESS(1,2,3,5))))
146 error_counter++;
147
148 /* Validate the data. */
149 if((ret != (int)(strlen(requests[0]) + 20)) || strncmp((buf + 20), requests[0], (ret - 20)))
150 error_counter++;
151
152 /* Send a response back. */
153 ret = sendto(sockfd, response[0], strlen(response[0]), 0, (struct sockaddr*)&remote_addr, addrlen);
154 if(ret != (int)strlen(response[0]))
155 error_counter++;
156
157
158 /* Close downt he socket. */
159 ret = soc_close(sockfd);
160 if(ret < 0)
161 error_counter++;
162
163 #ifdef NX_BSD_RAW_SUPPORT
164 /* Test raw packet type. */
165 sockfd = socket(AF_PACKET, SOCK_RAW, 200);
166 if(sockfd < 0)
167 error_counter++;
168
169 sock_addr.sll_family = AF_PACKET;
170 sock_addr.sll_ifindex = 0;
171 ret = sendto(sockfd, response[0], strlen(response[0]), 0, (struct sockaddr*)&sock_addr, sizeof(sock_addr));
172 if(ret != (int)strlen(response[0]))
173 error_counter++;
174
175 /* Close downt he socket. */
176 ret = soc_close(sockfd);
177 if(ret < 0)
178 error_counter++;
179 #endif
180
181
182 /* Give the reciever a chance to receive the raw data. */
183 tx_thread_sleep(2);
184
185 }
186
187 #ifdef FEATURE_NX_IPV6
test_raw_server_ipv6(void)188 static void test_raw_server_ipv6(void)
189 {
190 int sockfd;
191 struct sockaddr_in6 remote_addr;
192 int ret;
193 char buf[50];
194 int addrlen;
195
196
197 sockfd = socket(AF_INET6, SOCK_RAW, 100);
198 if(sockfd < 0)
199 error_counter++;
200
201 /* Receive data from the client. */
202 addrlen = sizeof(remote_addr);
203 ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr*)&remote_addr, &addrlen);
204 if(ret <= 0)
205 error_counter++;
206
207 if(addrlen != sizeof(struct sockaddr_in6))
208 error_counter++;
209
210 if((remote_addr.sin6_family != AF_INET6) ||
211 (remote_addr.sin6_addr._S6_un._S6_u32[0] != htonl(ipv6_address_ip1.nxd_ip_address.v6[0])) ||
212 (remote_addr.sin6_addr._S6_un._S6_u32[1] != htonl(ipv6_address_ip1.nxd_ip_address.v6[1])) ||
213 (remote_addr.sin6_addr._S6_un._S6_u32[2] != htonl(ipv6_address_ip1.nxd_ip_address.v6[2])) ||
214 (remote_addr.sin6_addr._S6_un._S6_u32[3] != htonl(ipv6_address_ip1.nxd_ip_address.v6[3])))
215 error_counter++;
216
217
218 /* Validate the data. */
219 if((ret != (INT)(strlen(requests[0]) )) || strncmp((buf ), requests[0], ret ))
220 error_counter++;
221
222 /* Send a response back. */
223 ret = sendto(sockfd, response[0], strlen(response[0]), 0, (struct sockaddr*)&remote_addr, addrlen);
224 if(ret != (INT)strlen(response[0]))
225 error_counter++;
226
227
228 /* Close downt he socket. */
229 ret = soc_close(sockfd);
230 if(ret < 0)
231 error_counter++;
232
233 /* Give the reciever a chance to receive the raw data. */
234 tx_thread_sleep(2);
235
236 }
237
238 #endif
239
240
241 /* Define the test threads. */
ntest_0_entry(ULONG thread_input)242 static void ntest_0_entry(ULONG thread_input)
243 {
244 #ifdef FEATURE_NX_IPV6
245 UINT status;
246 char mac_ip0[6];
247 char mac_ip1[6];
248 #endif
249 printf("NetX Test: Basic BSD Raw Blocking Test...................");
250
251 /* Check for earlier error. */
252 if (error_counter)
253 {
254
255 printf("ERROR!\n");
256 test_control_return(1);
257 }
258 #ifdef FEATURE_NX_IPV6
259 /* First set up IPv6 addresses. */
260 ipv6_address_ip0.nxd_ip_version = NX_IP_VERSION_V6;
261 ipv6_address_ip0.nxd_ip_address.v6[0] = 0xfe800000;
262 ipv6_address_ip0.nxd_ip_address.v6[1] = 0x00000000;
263 ipv6_address_ip0.nxd_ip_address.v6[2] = 0x021122ff;
264 ipv6_address_ip0.nxd_ip_address.v6[3] = 0xfe334456;
265
266 ipv6_address_ip1.nxd_ip_version = NX_IP_VERSION_V6;
267 ipv6_address_ip1.nxd_ip_address.v6[0] = 0xfe800000;
268 ipv6_address_ip1.nxd_ip_address.v6[1] = 0x00000000;
269 ipv6_address_ip1.nxd_ip_address.v6[2] = 0x021122ff;
270 ipv6_address_ip1.nxd_ip_address.v6[3] = 0xfe334457;
271
272 status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_ip0, 64, NX_NULL);
273 status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_ip1, 64, NX_NULL);
274
275 status += nxd_ipv6_enable(&ip_0);
276 status += nxd_ipv6_enable(&ip_1);
277
278 mac_ip0[0] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw >> 8;
279 mac_ip0[1] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF;
280 mac_ip0[2] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff;
281 mac_ip0[3] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff;
282 mac_ip0[4] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff;
283 mac_ip0[5] = ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff;
284
285 mac_ip1[0] = ip_1.nx_ip_interface[0].nx_interface_physical_address_msw >> 8;
286 mac_ip1[1] = ip_1.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF;
287 mac_ip1[2] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff;
288 mac_ip1[3] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff;
289 mac_ip1[4] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff;
290 mac_ip1[5] = ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw & 0xff;
291
292 status += nxd_nd_cache_entry_set(&ip_0, ipv6_address_ip1.nxd_ip_address.v6, 0, mac_ip1);
293 status += nxd_nd_cache_entry_set(&ip_1, ipv6_address_ip0.nxd_ip_address.v6, 0, mac_ip0);
294
295 if(status)
296 error_counter++;
297 #endif
298 test_raw_server_ipv4();
299
300 /* Now open another socket and attempt to connect to the correct remote
301 host but an unexpected port so we expect an unsuccessful connections. */
302 #if 0
303 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
304 if(sockfd < 0)
305 error_counter++;
306 #endif
307
308 /* Allow the stateless autoaddress configuration/DAD to finish */
309 tx_thread_sleep(3);
310
311 #ifdef FEATURE_NX_IPV6
312 test_raw_server_ipv6();
313 #endif
314
315 validate_bsd_structure();
316 tx_thread_sleep(2);
317 if(error_counter)
318 printf("ERROR!\n");
319 else
320 printf("SUCCESS!\n");
321
322 if(error_counter)
323 test_control_return(1);
324
325 test_control_return(0);
326 }
327
ntest_1_entry(ULONG thread_input)328 static void ntest_1_entry(ULONG thread_input)
329 {
330
331 UINT status;
332 NX_PACKET *packet_ptr;
333 ULONG actual_status;
334 NXD_ADDRESS dest_addr;
335
336
337
338 /* Ensure the IP instance has been initialized. */
339 status = nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE);
340
341 /* Check status... */
342 if (status != NX_SUCCESS)
343 {
344
345 printf("ERROR!\n");
346 test_control_return(3);
347 }
348
349 /* Allocate a packet. */
350 status = nx_packet_allocate(&pool_0, &packet_ptr, NX_IP_PACKET, NX_WAIT_FOREVER);
351 if (status)
352 error_counter++;
353
354 /* Fill in the packet with data */
355 memcpy(packet_ptr -> nx_packet_prepend_ptr, requests[0], strlen(requests[0]));
356
357 packet_ptr -> nx_packet_length = strlen(requests[0]);
358 packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
359
360 /* Send a RAW packet */
361 dest_addr.nxd_ip_version = NX_IP_VERSION_V4;
362 dest_addr.nxd_ip_address.v4 = IP_ADDRESS(1,2,3,4);
363 status = _nxd_ip_raw_packet_send(&ip_1, packet_ptr, &dest_addr, 100, 128, 0);
364 if(status)
365 error_counter++;
366
367 error_counter++;
368 tx_thread_sleep(1);
369 /* Ready to reaceive a message */
370 status = nx_ip_raw_packet_receive(&ip_1, &packet_ptr, NX_IP_PERIODIC_RATE);
371 if(status)
372 error_counter++;
373
374
375 /* Validate the content. */
376 if(packet_ptr -> nx_packet_length != strlen(response[0]))
377 error_counter++;
378 else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[0], strlen(response[0])))
379 error_counter++;
380 else
381 error_counter--;
382
383 #ifdef FEATURE_NX_IPV6
384 /* Test IPv6 */
385 tx_thread_sleep(5);
386 /* Allocate a packet. */
387 status = nx_packet_allocate(&pool_0, &packet_ptr, NX_IP_PACKET, NX_WAIT_FOREVER);
388 if (status)
389 error_counter++;
390
391 /* Fill in the packet with data */
392 memcpy(packet_ptr -> nx_packet_prepend_ptr, requests[0], strlen(requests[0]));
393
394 packet_ptr -> nx_packet_length = strlen(requests[0]);
395 packet_ptr -> nx_packet_append_ptr = packet_ptr -> nx_packet_prepend_ptr + packet_ptr -> nx_packet_length;
396
397 status = _nxd_ip_raw_packet_send(&ip_1, packet_ptr, &ipv6_address_ip0, 100, 128, 0);
398 if(status)
399 error_counter++;
400
401 error_counter++;
402 tx_thread_sleep(1);
403 /* Ready to reaceive a message */
404 status = nx_ip_raw_packet_receive(&ip_1, &packet_ptr, NX_IP_PERIODIC_RATE);
405 if(status)
406 error_counter++;
407
408 /* Validate the content. */
409 if(packet_ptr -> nx_packet_length != strlen(response[0]))
410 error_counter++;
411 else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[0], strlen(response[0])))
412 error_counter++;
413 else
414 error_counter--;
415
416 #endif
417 }
418
419 extern NX_BSD_SOCKET nx_bsd_socket_array[NX_BSD_MAX_SOCKETS];
420 extern TX_BLOCK_POOL nx_bsd_socket_block_pool;
validate_bsd_structure(void)421 static void validate_bsd_structure(void)
422 {
423 int i;
424 /* Make sure every BSD socket should be free by now. */
425
426 for(i = 0; i < NX_BSD_MAX_SOCKETS; i++)
427 {
428 if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE)
429 {
430 error_counter++;
431 }
432
433 if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket ||
434 nx_bsd_socket_array[i].nx_bsd_socket_udp_socket)
435 {
436 error_counter++;
437 }
438 }
439
440 /* Make sure all the NX SOCKET control blocks are released. */
441 if(nx_bsd_socket_block_pool.tx_block_pool_available !=
442 nx_bsd_socket_block_pool.tx_block_pool_total)
443 {
444 error_counter++;
445 }
446
447 /* Make sure all the sockets are released */
448 if(ip_0.nx_ip_tcp_created_sockets_ptr ||
449 ip_0.nx_ip_udp_created_sockets_ptr)
450 {
451 error_counter++;
452 return;
453 }
454
455 }
456
457 #endif /* NX_BSD_ENABLE */
458
459 #else /* __PRODUCT_NETXDUO__ */
460
461 extern void test_control_return(UINT status);
462 #ifdef CTEST
test_application_define(void * first_unused_memory)463 VOID test_application_define(void *first_unused_memory)
464 #else
465 void netx_bsd_raw_basic_blocking_test_application_define(void *first_unused_memory)
466 #endif
467 {
468 printf("NetX Test: Basic BSD Raw Blocking Test...................N/A\n");
469 test_control_return(3);
470 }
471 #endif /* __PRODUCT_NETXDUO__ */
472
473