1 /* This NetX test concentrates on the basic BSD TCP blocking operation.  */
2 /* The BSD APIs involved in this test are:  socket(), connect(), send(), soc_close() */
3 
4 #include   "tx_api.h"
5 #include   "nx_api.h"
6 #ifdef NX_BSD_ENABLE
7 #include   "nx_icmpv6.h"
8 #include   "nxd_bsd.h"
9 #include   "nxd_dns.h"
10 #define     DEMO_STACK_SIZE         4096
11 
12 
13 static char response_cname_www_baidu_com[100] = {
14 0x18, 0x03, 0x73, 0x33, 0xc1, 0xbd, 0xc8, 0x3a,
15 0x35, 0x60, 0x4b, 0x46, 0x08, 0x00, 0x45, 0x00,
16 0x00, 0x56, 0xa6, 0x10, 0x00, 0x00, 0x40, 0x11,
17 0x52, 0xcc, 0xc0, 0xa8, 0x00, 0x01, 0xc0, 0xa8,
18 0x00, 0x69, 0x00, 0x35, 0xc7, 0x20, 0x00, 0x42,
19 0x1b, 0x3d, 0x00, 0x02, 0x81, 0x80, 0x00, 0x01,
20 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0x77,
21 0x77, 0x77, 0x05, 0x62, 0x61, 0x69, 0x64, 0x75,
22 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x05, 0x00,
23 0x01, 0xc0, 0x0c, 0x00, 0x05, 0x00, 0x01, 0x00,
24 0x00, 0x01, 0xe7, 0x00, 0x0f, 0x03, 0x77, 0x77,
25 0x77, 0x01, 0x61, 0x06, 0x73, 0x68, 0x69, 0x66,
26 0x65, 0x6e, 0xc0, 0x16 };
27 
28 static char response_a_www_baidu_com[132] = {
29 0x00, 0x15, 0x5d, 0x64, 0x17, 0x05, 0x8c, 0xec, /* ..]d.... */
30 0x4b, 0x68, 0xd1, 0xfe, 0x08, 0x00, 0x45, 0x00, /* Kh....E. */
31 0x00, 0x76, 0x63, 0x9e, 0x40, 0x00, 0x40, 0x11, /* .vc.@.@. */
32 0x8d, 0x6d, 0xc0, 0xa8, 0x64, 0x02, 0xc0, 0xa8, /* .m..d... */
33 0x64, 0x18, 0x00, 0x35, 0xc1, 0x9f, 0x00, 0x62, /* d..5...b */
34 0x23, 0x29, 0x11, 0x95, 0x81, 0x80, 0x00, 0x01, /* #)...... */
35 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03, 0x77, /* .......w */
36 0x77, 0x77, 0x05, 0x62, 0x61, 0x69, 0x64, 0x75, /* ww.baidu */
37 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, /* .com.... */
38 0x01, 0xc0, 0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, /* ........ */
39 0x00, 0x02, 0x01, 0x00, 0x0f, 0x03, 0x77, 0x77, /* ......ww */
40 0x77, 0x01, 0x61, 0x06, 0x73, 0x68, 0x69, 0x66, /* w.a.shif */
41 0x65, 0x6e, 0xc0, 0x16, 0xc0, 0x2b, 0x00, 0x01, /* en...+.. */
42 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, /* ..... .. */
43 0x73, 0xef, 0xd2, 0x1b, 0xc0, 0x2b, 0x00, 0x01, /* s....+.. */
44 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, /* ..... .. */
45 0x73, 0xef, 0xd3, 0x70                          /* s..p */
46 };
47 
48 /* Define the ThreadX and NetX object control blocks...  */
49 
50 static TX_THREAD               ntest_0;
51 static TX_THREAD               ntest_1;
52 
53 static NX_PACKET_POOL          pool_0;
54 static NX_IP                   ip_0;
55 static NX_IP                   ip_1;
56 static NX_TCP_SOCKET           server_socket;
57 static ULONG                   bsd_thread_area[DEMO_STACK_SIZE / sizeof(ULONG)];
58 static TX_SEMAPHORE            sema_0;
59 static TX_SEMAPHORE            sema_1;
60 static NX_DNS                  client_dns;
61 static NX_UDP_SOCKET           udp_socket;
62 #define BSD_THREAD_PRIORITY    2
63 #define NUM_CLIENTS            10
64 #define DNS_START_OFFSET       (14 + 20 + 8)
65 /* Define the counters used in the test application...  */
66 
67 static ULONG                   error_counter;
68 static UINT                    response_sequence;
69 static ULONG                   packet_pool_area[(256 + sizeof(NX_PACKET)) * (NUM_CLIENTS + 4) * 8 / 4];
70 
71 /* Define thread prototypes.  */
72 
73 static void    ntest_0_entry(ULONG thread_input);
74 static void    ntest_1_entry(ULONG thread_input);
75 extern void    test_control_return(UINT status);
76 extern void    _nx_ram_network_driver_256(struct NX_IP_DRIVER_STRUCT *driver_req);
77 static void    validate_bsd_structure(void);
78 extern NX_BSD_SOCKET  nx_bsd_socket_array[NX_BSD_MAX_SOCKETS];
79 #ifdef FEATURE_NX_IPV6
80 static NXD_ADDRESS ipv6_address_ip0;
81 static NXD_ADDRESS ipv6_address_ip1;
82 #endif
83 static char *send_buffer = "Hello World";
84 static char *requests[4] = {"Request1", "Request2", "Request3", "Request4"};
85 static char *response[4] = {"Response1", "Response2", "Response3", "Response4"};
86 static void validate_bsd_structure(void);
87 #ifdef __PRODUCT_NETXDUO__
88 static char large_msg[1000];
89 #endif
90 /* Define what the initial system looks like.  */
91 
92 #ifdef CTEST
test_application_define(void * first_unused_memory)93 VOID test_application_define(void *first_unused_memory)
94 #else
95 void    netx_bsd_getaddrinfo_test_application_define(void *first_unused_memory)
96 #endif
97 {
98 
99 CHAR    *pointer;
100 UINT    status;
101 
102 
103     /* Setup the working pointer.  */
104     pointer =  (CHAR *) first_unused_memory;
105 
106     error_counter =  0;
107 
108     /* Create the main thread.  */
109     tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0,
110                      pointer, DEMO_STACK_SIZE,
111                      3, 3, TX_NO_TIME_SLICE, TX_AUTO_START);
112 
113     pointer =  pointer + DEMO_STACK_SIZE;
114 
115     /* Create the main thread.  */
116     tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0,
117                      pointer, DEMO_STACK_SIZE,
118                      3, 3, TX_NO_TIME_SLICE, TX_AUTO_START);
119 
120     pointer =  pointer + DEMO_STACK_SIZE;
121 
122 
123     /* Initialize the NetX system.  */
124     nx_system_initialize();
125 
126     /* Create a packet pool.  */
127     status =  nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 256, packet_pool_area, sizeof(packet_pool_area));
128 
129 
130     if (status)
131         error_counter++;
132 
133     /* Create an IP instance.  */
134     status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256,
135                     pointer, 2048, 1);
136     pointer =  pointer + 2048;
137 
138     /* Create another IP instance.  */
139     status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_256,
140                     pointer, 2048, 1);
141     pointer =  pointer + 2048;
142     if (status)
143         error_counter++;
144 
145     /* Enable ARP and supply ARP cache memory for IP Instance 0.  */
146     status =  nx_arp_enable(&ip_0, (void *) pointer, 1024);
147     pointer = pointer + 1024;
148     if (status)
149         error_counter++;
150 
151     /* Enable ARP and supply ARP cache memory for IP Instance 1.  */
152     status  =  nx_arp_enable(&ip_1, (void *) pointer, 1024);
153     pointer = pointer + 1024;
154     if (status)
155         error_counter++;
156 
157     /* Enable TCP processing for both IP instances.  */
158     status =  nx_tcp_enable(&ip_0);
159     status += nx_tcp_enable(&ip_1);
160 
161     /* Check TCP enable status.  */
162     if (status)
163         error_counter++;
164 
165     status =  nx_udp_enable(&ip_0);
166     status += nx_udp_enable(&ip_1);
167 
168     /* Check UDP enable status.  */
169     if (status)
170         error_counter++;
171 
172     /* Enable BSD */
173     status += bsd_initialize(&ip_0, &pool_0, (CHAR*)&bsd_thread_area[0], sizeof(bsd_thread_area), BSD_THREAD_PRIORITY);
174 
175     /* Check BSD enable status.  */
176     if (status)
177         error_counter++;
178 
179     status = tx_semaphore_create(&sema_0, "SEMA 0", 0);
180     status += tx_semaphore_create(&sema_1, "SEMA 1", 0);
181     if(status)
182         error_counter++;
183 }
184 typedef struct client_info_struct
185 {
186     int sockfd;
187     int message_id;
188 } client_info;
189 
190 static client_info client_data[NUM_CLIENTS];
191 static ULONG stack_space[NUM_CLIENTS][DEMO_STACK_SIZE / sizeof(ULONG)];
192 static TX_THREAD helper_thread[NUM_CLIENTS];
193 #ifdef FEATURE_NX_IPV6
194 static ULONG stack_space6[NUM_CLIENTS][DEMO_STACK_SIZE / sizeof(ULONG)];
195 static TX_THREAD helper_thread6[NUM_CLIENTS];
196 #endif
bsd_server_helper_thread_entry(ULONG thread_input)197 static VOID bsd_server_helper_thread_entry(ULONG thread_input)
198 {
199 int         ret;
200 int         sockfd, message_id;
201 char        buf[30];
202 int         sockaddr_len;
203 fd_set      read_fds, write_fds, except_fds;
204 struct timeval wait_time;
205 #ifdef FEATURE_NX_IPV6
206 struct sockaddr_in6 remote_address;
207 #else
208 struct sockaddr_in remote_address;
209 #endif
210 
211     sockfd = client_data[thread_input].sockfd;
212     message_id = client_data[thread_input].message_id;
213     /* Receive data from the client. */
214     if(message_id == 2)
215     {
216 #ifdef FEATURE_NX_IPV6
217         sockaddr_len = sizeof(struct sockaddr_in6);
218 #else
219         sockaddr_len = sizeof(struct sockaddr_in);
220 #endif
221         ret = recvfrom(sockfd, (char*)buf, sizeof(buf), 0, (struct sockaddr*)&remote_address, &sockaddr_len);
222 
223         if(ret < 0)
224             error_counter++;
225         if(nx_bsd_socket_array[sockfd - 0x20].nx_bsd_socket_family == AF_INET)
226         {
227             if(sockaddr_len != sizeof(struct sockaddr_in))
228                 error_counter++;
229             if(((struct sockaddr_in*)&remote_address) -> sin_family != AF_INET)
230                 error_counter++;
231             if(((struct sockaddr_in*)&remote_address) -> sin_addr.s_addr != htonl(0x01020305))
232                 error_counter++;
233         }
234 #ifdef FEATURE_NX_IPV6
235         else if(nx_bsd_socket_array[sockfd - 0x20].nx_bsd_socket_family == AF_INET6)
236         {
237             if(sockaddr_len != sizeof(struct sockaddr_in6))
238                 error_counter++;
239             if((remote_address.sin6_addr._S6_un._S6_u32[0] != htonl(ipv6_address_ip1.nxd_ip_address.v6[0])) ||
240                (remote_address.sin6_addr._S6_un._S6_u32[1] != htonl(ipv6_address_ip1.nxd_ip_address.v6[1])) ||
241                (remote_address.sin6_addr._S6_un._S6_u32[2] != htonl(ipv6_address_ip1.nxd_ip_address.v6[2])) ||
242                (remote_address.sin6_addr._S6_un._S6_u32[3] != htonl(ipv6_address_ip1.nxd_ip_address.v6[3])))
243                 error_counter++;
244         }
245 #endif
246     }
247     else
248     {
249 
250         /* Peek message test. */
251         ret = recv(sockfd, buf, sizeof(buf), MSG_PEEK);
252 
253         /* Validate the data. */
254         if((ret != (int)strlen(requests[message_id & 3])) || strncmp(buf, requests[message_id & 3], ret))
255             error_counter++;
256 
257         ret = recv(sockfd, buf, sizeof(buf), 0);
258     }
259     if(ret <= 0)
260         error_counter++;
261 
262     /* Validate the data. */
263     if((ret != (int)strlen(requests[message_id & 3])) || strncmp(buf, requests[message_id & 3], ret))
264         error_counter++;
265 
266     /* Invoke recvfrom with MSG_DONTWAIT flag. */
267     ret = recvfrom(sockfd, (char*)buf, sizeof(buf), MSG_DONTWAIT, (struct sockaddr*)&remote_address, &sockaddr_len);
268     if(ret >= 0)
269         error_counter++;
270     else if((errno != EWOULDBLOCK) || (errno != EAGAIN))
271         error_counter++;
272 
273     /* Invoke recv with MSG_DONTWAIT flag. */
274     ret = recv(sockfd, (char*)buf, sizeof(buf), MSG_DONTWAIT);
275     if(ret >= 0)
276         error_counter++;
277     else if((errno != EWOULDBLOCK) || (errno != EAGAIN))
278         error_counter++;
279 
280     /* Send a response back. */
281     ret = send(sockfd, response[message_id & 3], strlen(response[message_id & 3]), 0);
282     if(ret != (int)strlen(response[message_id & 3]))
283         error_counter++;
284 
285     tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE);
286 
287 #ifdef __PRODUCT_NETXDUO__
288     /* Invoke send with MSG_DONTWAIT flag. The message is larger than tx_window. Partial data should be sent. */
289     ret = send(sockfd, large_msg, sizeof(large_msg), MSG_DONTWAIT);
290     if (ret <= 0)
291         error_counter++;
292 #endif
293 
294     FD_ZERO(&read_fds);
295     FD_ZERO(&write_fds);
296     FD_ZERO(&except_fds);
297     FD_SET(sockfd, &read_fds);
298     FD_SET(sockfd, &write_fds);
299     FD_SET(sockfd, &except_fds);
300 
301     ret = soc_close(sockfd);
302     if(ret < 0)
303         error_counter++;
304 
305     wait_time.tv_sec = 1;
306     wait_time.tv_usec = 0;
307     select(sockfd + 1, &read_fds, &write_fds, &except_fds, &wait_time);
308     if((FD_ISSET(sockfd, &read_fds) && FD_ISSET(sockfd, &write_fds) && FD_ISSET(sockfd, &except_fds)) == 0)
309         error_counter++;
310 
311     tx_semaphore_put(&sema_0);
312     return;
313 }
314 
315 
test_tcp_client4(void)316 static void test_tcp_client4(void)
317 {
318 int sockfd;
319 struct sockaddr_in local_addr;
320 #ifdef FEATURE_NX_IPV6
321 struct sockaddr_in6 local_addr6;
322 int port;
323 int sockfd1;
324 #endif
325 int bytes_sent;
326 int ret;
327 char buf;
328 struct addrinfo *server_info;
329 
330     if (getaddrinfo("1.2.3.5", "12", NX_NULL, &server_info) != 0)
331     {
332         error_counter++;
333         return;
334     }
335 
336     sockfd = socket(server_info -> ai_family, server_info -> ai_socktype,
337                     server_info -> ai_protocol);
338     if(sockfd < 0)
339         error_counter++;
340 
341     if(connect(sockfd, server_info -> ai_addr, server_info -> ai_addrlen) < 0)
342         error_counter++;
343 
344     freeaddrinfo(server_info);
345 
346     bytes_sent = send(sockfd, send_buffer, strlen(send_buffer), 0);
347 
348     if(bytes_sent != (int)strlen(send_buffer))
349         error_counter++;
350 
351 #ifdef FEATURE_NX_IPV6
352     /* Get the port bind to any. */
353     port = nx_bsd_socket_array[sockfd - NX_BSD_SOCKFD_START].nx_bsd_socket_tcp_socket -> nx_tcp_socket_port;
354 
355     sockfd1 = socket(AF_INET6, SOCK_STREAM, 0);
356     if(sockfd1 < 0)
357         error_counter++;
358 
359     memset(&local_addr6, 0, sizeof(local_addr6));
360     local_addr6.sin6_family = AF_INET6;
361     local_addr6.sin6_port = htons(port);
362 
363     /* Bind to the same port. */
364     ret = bind(sockfd1, (struct sockaddr*)&local_addr6, sizeof(local_addr6));
365     if(ret < 0)
366         error_counter++;
367 
368     ret = soc_close(sockfd1);
369     if(ret < 0)
370         error_counter++;
371 #endif
372 
373     /* Call recv before peer orderly shutdown. */
374     ret = recv(sockfd, &buf, 1, 0);
375     if (ret != 0)
376         error_counter++;
377 
378     /* Make sure the other side gets the message. */
379     tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE);
380 
381     /* Call recv after peer orderly shutdown. */
382     ret = recv(sockfd, &buf, 1, 0);
383     if (ret != 0)
384         error_counter++;
385 
386     ret = soc_close(sockfd);
387     if(ret < 0)
388         error_counter++;
389 
390 }
391 
test_tcp_server4(void)392 static void test_tcp_server4(void)
393 {
394 int                sockfd;
395 struct sockaddr_in remote_addr, local_addr;
396 int                address_length;
397 int                ret;
398 int                newsock;
399 int                i;
400 UINT               status;
401 struct addrinfo    hints, *server_info;
402 
403     memset(&hints, 0, sizeof(hints));
404     hints.ai_family = AF_INET;
405     hints.ai_socktype = SOCK_STREAM;
406     hints.ai_flags = AI_PASSIVE;
407 
408     if (getaddrinfo(NX_NULL, "12345", &hints, &server_info) != 0)
409     {
410         error_counter++;
411         return;
412     }
413 
414     sockfd = socket(server_info -> ai_family, server_info -> ai_socktype,
415                     server_info -> ai_protocol);
416     if(sockfd < 0)
417         error_counter++;
418 
419     ret = bind(sockfd, server_info -> ai_addr, server_info -> ai_addrlen);
420     if(ret < 0)
421         error_counter++;
422 
423     freeaddrinfo(server_info);
424 
425     ret = listen(sockfd, 5);
426     if(ret < 0)
427         error_counter++;
428 
429     /* 3 iterations. */
430     for(i = 0; i < NUM_CLIENTS; i++)
431     {
432         address_length = sizeof(remote_addr);
433 
434         newsock = accept(sockfd, (struct sockaddr*)&remote_addr, &address_length);
435 
436         if(newsock <= 0)
437             error_counter++;
438         else if(address_length != sizeof(remote_addr))
439             error_counter++;
440         else if((remote_addr.sin_family != AF_INET) || (remote_addr.sin_addr.s_addr != htonl(0x01020305)))
441             error_counter++;
442 
443         address_length = sizeof(local_addr);
444         ret = getsockname(newsock, (struct sockaddr*)&local_addr, &address_length);
445         if(ret < 0)
446             error_counter++;
447         else if(address_length != sizeof(local_addr))
448             error_counter++;
449         else if(local_addr.sin_family != AF_INET)
450             error_counter++;
451         else if(local_addr.sin_port != htons(12345))
452             error_counter++;
453         else if(local_addr.sin_addr.s_addr != htonl(IP_ADDRESS(1, 2, 3, 4)))
454             error_counter++;
455 
456         address_length = sizeof(remote_addr);
457         ret = getpeername(newsock, (struct sockaddr*)&remote_addr, &address_length);
458         if(ret < 0)
459             error_counter++;
460         else if(address_length != sizeof(remote_addr))
461             error_counter++;
462         else if(remote_addr.sin_family != AF_INET)
463             error_counter++;
464         else if(remote_addr.sin_addr.s_addr != htonl(IP_ADDRESS(1,2,3,5)))
465             error_counter++;
466 
467 
468         /* Set the client data */
469         client_data[i].sockfd = newsock;
470         client_data[i].message_id = i;
471 
472         /* Create a helper thread to handle the new socket. */
473         status = tx_thread_create(&helper_thread[i], "helper thread", bsd_server_helper_thread_entry,
474                                   i, stack_space[i], DEMO_STACK_SIZE, 2, 2, TX_NO_TIME_SLICE, TX_AUTO_START);
475         if(status != TX_SUCCESS)
476             error_counter++;
477 
478         tx_thread_relinquish();
479     }
480 
481     /* Close downt he socket. */
482     ret = soc_close(sockfd);
483     if(ret < 0)
484         error_counter++;
485 
486     for(i = 0; i < NUM_CLIENTS; i++)
487     {
488 
489         /* Wakeup server thread. */
490         tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE);
491     }
492 }
493 
494 
495 #ifdef FEATURE_NX_IPV6
test_tcp_client6(void)496 static void test_tcp_client6(void)
497 {
498 int                 sockfd;
499 int                 bytes_sent;
500 int                 ret;
501 struct addrinfo    *server_info;
502 
503     if (getaddrinfo("fe80::211:22ff:fe33:4457", "12", NX_NULL, &server_info) != 0)
504     {
505         error_counter++;
506         return;
507     }
508 
509     sockfd = socket(server_info -> ai_family, server_info -> ai_socktype,
510                     server_info -> ai_protocol);
511     if(sockfd < 0)
512         error_counter++;
513 
514     if(connect(sockfd, server_info -> ai_addr, server_info -> ai_addrlen) < 0)
515         error_counter++;
516 
517     freeaddrinfo(server_info);
518 
519     bytes_sent = send(sockfd, send_buffer, strlen(send_buffer), 0);
520 
521     if(bytes_sent != (INT)strlen(send_buffer))
522         error_counter++;
523 
524     /* Make sure the other side gets the message. */
525     tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE);
526 
527     ret = soc_close(sockfd);
528     if(ret < 0)
529         error_counter++;
530 
531 }
532 
test_tcp_server6(void)533 static void test_tcp_server6(void)
534 {
535 int                 sockfd;
536 struct sockaddr_in6 remote_addr, local_addr;
537 int                 address_length;
538 int                 ret;
539 int                 newsock;
540 int                 i;
541 UINT                status;
542 struct addrinfo    hints, *server_info;
543 
544     memset(&hints, 0, sizeof(hints));
545     hints.ai_family = AF_INET6;
546     hints.ai_socktype = SOCK_STREAM;
547     hints.ai_flags = AI_PASSIVE;
548 
549     if (getaddrinfo(NX_NULL, "12346", &hints, &server_info) != 0)
550     {
551         error_counter++;
552         return;
553     }
554 
555     sockfd = socket(server_info -> ai_family, server_info -> ai_socktype,
556                     server_info -> ai_protocol);
557     if(sockfd < 0)
558         error_counter++;
559 
560     ret = bind(sockfd, server_info -> ai_addr, server_info -> ai_addrlen);
561     if(ret < 0)
562         error_counter++;
563 
564     freeaddrinfo(server_info);
565 
566     ret = listen(sockfd, 5);
567     if(ret < 0)
568         error_counter++;
569 
570     /* 3 iterations. */
571     for(i = 0; i < NUM_CLIENTS; i++)
572     {
573         address_length = sizeof(remote_addr);
574 
575         newsock = accept(sockfd, (struct sockaddr*)&remote_addr, &address_length);
576 
577         if(newsock <= 0)
578             error_counter++;
579 
580         if(address_length != sizeof(struct sockaddr_in6))
581             error_counter++;
582 
583         if((remote_addr.sin6_family != AF_INET6) ||
584            (remote_addr.sin6_addr._S6_un._S6_u32[0] != htonl(ipv6_address_ip1.nxd_ip_address.v6[0])) ||
585            (remote_addr.sin6_addr._S6_un._S6_u32[1] != htonl(ipv6_address_ip1.nxd_ip_address.v6[1])) ||
586            (remote_addr.sin6_addr._S6_un._S6_u32[2] != htonl(ipv6_address_ip1.nxd_ip_address.v6[2])) ||
587            (remote_addr.sin6_addr._S6_un._S6_u32[3] != htonl(ipv6_address_ip1.nxd_ip_address.v6[3])))
588             error_counter++;
589 
590         address_length = sizeof(local_addr);
591         ret = getsockname(newsock, (struct sockaddr*)&local_addr, &address_length);
592         if(ret < 0)
593             error_counter++;
594         else if(address_length != sizeof(local_addr))
595             error_counter++;
596         else if(local_addr.sin6_family != AF_INET6)
597             error_counter++;
598         else if(local_addr.sin6_port != htons(12346))
599             error_counter++;
600         else if((local_addr.sin6_addr._S6_un._S6_u32[0] != htonl(ipv6_address_ip0.nxd_ip_address.v6[0])) ||
601                 (local_addr.sin6_addr._S6_un._S6_u32[1] != htonl(ipv6_address_ip0.nxd_ip_address.v6[1])) ||
602                 (local_addr.sin6_addr._S6_un._S6_u32[2] != htonl(ipv6_address_ip0.nxd_ip_address.v6[2])) ||
603                 (local_addr.sin6_addr._S6_un._S6_u32[3] != htonl(ipv6_address_ip0.nxd_ip_address.v6[3])))
604             error_counter++;
605 
606         address_length = sizeof(remote_addr);
607         ret = getpeername(newsock, (struct sockaddr*)&remote_addr, &address_length);
608         if(ret < 0)
609             error_counter++;
610         else if(address_length != sizeof(remote_addr))
611             error_counter++;
612         else if(remote_addr.sin6_family != AF_INET6)
613             error_counter++;
614         else if((remote_addr.sin6_family != AF_INET6) ||
615                 (remote_addr.sin6_addr._S6_un._S6_u32[0] != htonl(ipv6_address_ip1.nxd_ip_address.v6[0])) ||
616                 (remote_addr.sin6_addr._S6_un._S6_u32[1] != htonl(ipv6_address_ip1.nxd_ip_address.v6[1])) ||
617                 (remote_addr.sin6_addr._S6_un._S6_u32[2] != htonl(ipv6_address_ip1.nxd_ip_address.v6[2])) ||
618                 (remote_addr.sin6_addr._S6_un._S6_u32[3] != htonl(ipv6_address_ip1.nxd_ip_address.v6[3])))
619             error_counter++;
620 
621 
622 
623         /* Set the client data */
624         client_data[i].sockfd = newsock;
625         client_data[i].message_id = i;
626 
627         /* Create a helper thread to handle the new socket. */
628         status = tx_thread_create(&helper_thread6[i], "helper thread", bsd_server_helper_thread_entry,
629                          i, stack_space6[i], DEMO_STACK_SIZE, 2, 2, TX_NO_TIME_SLICE, TX_AUTO_START);
630         if(status)
631             error_counter++;
632 
633         tx_thread_relinquish();
634     }
635 
636     /* Close downt he socket. */
637     ret = soc_close(sockfd);
638     if(ret < 0)
639         error_counter++;
640 
641     for(i = 0; i < NUM_CLIENTS; i++)
642     {
643 
644         /* Wakeup server thread. */
645         tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE);
646     }
647 }
648 
649 #endif
650 
close_before_accept_test()651 static void    close_before_accept_test()
652 {
653 int     server_fd, client_fd;
654 int     ret;
655 struct  sockaddr_in remote_addr, local_addr;
656 
657     /* Setup server socket. */
658     server_fd = socket(AF_INET, SOCK_STREAM, 0);
659     if(server_fd < 0)
660         error_counter++;
661 
662     local_addr.sin_family = AF_INET;
663     local_addr.sin_port = htons(12345);
664     local_addr.sin_addr.s_addr = INADDR_ANY;
665 
666     ret = bind(server_fd, (struct sockaddr*)&local_addr, sizeof(local_addr));
667     if(ret < 0)
668         error_counter++;
669 
670     ret = listen(server_fd, 5);
671     if(ret < 0)
672         error_counter++;
673 
674     /* Setup client socket. */
675     client_fd = socket(AF_INET, SOCK_STREAM, 0);
676     if(client_fd < 0)
677         error_counter++;
678 
679     remote_addr.sin_family = AF_INET;
680     remote_addr.sin_port = htons(12345);
681     remote_addr.sin_addr.s_addr = htonl(0x01020304);
682 
683     if(connect(client_fd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)) < 0)
684         error_counter++;
685 
686     /* Close before calling accept. */
687     soc_close(server_fd);
688     soc_close(client_fd);
689 }
690 
691 
692 /* Define the test threads.  */
ntest_0_entry(ULONG thread_input)693 static void    ntest_0_entry(ULONG thread_input)
694 {
695 int                sockfd;
696 struct sockaddr_in remote_addr;
697 #ifdef FEATURE_NX_IPV6
698 char mac_ip0[6];
699 char mac_ip1[6];
700 UINT status;
701 #endif
702 int                ret;
703 
704 
705     printf("NetX Test:   Basic BSD getaddrinfo Test....................");
706 
707     /* Check for earlier error.  */
708     if (error_counter)
709     {
710 
711         printf("ERROR!\n");
712         test_control_return(1);
713     }
714 #ifdef FEATURE_NX_IPV6
715     /* First set up IPv6 addresses. */
716     ipv6_address_ip0.nxd_ip_version = NX_IP_VERSION_V6;
717     ipv6_address_ip0.nxd_ip_address.v6[0] = 0xfe800000;
718     ipv6_address_ip0.nxd_ip_address.v6[1] = 0x00000000;
719     ipv6_address_ip0.nxd_ip_address.v6[2] = 0x021122ff;
720     ipv6_address_ip0.nxd_ip_address.v6[3] = 0xfe334456;
721 
722     ipv6_address_ip1.nxd_ip_version = NX_IP_VERSION_V6;
723     ipv6_address_ip1.nxd_ip_address.v6[0] = 0xfe800000;
724     ipv6_address_ip1.nxd_ip_address.v6[1] = 0x00000000;
725     ipv6_address_ip1.nxd_ip_address.v6[2] = 0x021122ff;
726     ipv6_address_ip1.nxd_ip_address.v6[3] = 0xfe334457;
727 
728     status = nxd_ipv6_address_set(&ip_0, 0, &ipv6_address_ip0, 64, NX_NULL);
729     status += nxd_ipv6_address_set(&ip_1, 0, &ipv6_address_ip1, 64, NX_NULL);
730 
731     status += nxd_ipv6_enable(&ip_0);
732     status += nxd_ipv6_enable(&ip_1);
733 
734     mac_ip0[0] = (CHAR)(ip_0.nx_ip_interface[0].nx_interface_physical_address_msw >> 8);
735     mac_ip0[1] = ip_0.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF;
736     mac_ip0[2] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff;
737     mac_ip0[3] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff;
738     mac_ip0[4] = (ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff;
739     mac_ip0[5] = ip_0.nx_ip_interface[0].nx_interface_physical_address_lsw  & 0xff;
740 
741     mac_ip1[0] = (CHAR)(ip_1.nx_ip_interface[0].nx_interface_physical_address_msw >> 8);
742     mac_ip1[1] = ip_1.nx_ip_interface[0].nx_interface_physical_address_msw & 0xFF;
743     mac_ip1[2] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 24) & 0xff;
744     mac_ip1[3] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 16) & 0xff;
745     mac_ip1[4] = (ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw >> 8) & 0xff;
746     mac_ip1[5] = ip_1.nx_ip_interface[0].nx_interface_physical_address_lsw  & 0xff;
747 
748     status += nxd_nd_cache_entry_set(&ip_0, ipv6_address_ip1.nxd_ip_address.v6, 0,  mac_ip1);
749     status += nxd_nd_cache_entry_set(&ip_1, ipv6_address_ip0.nxd_ip_address.v6, 0,  mac_ip0);
750 
751     if(status)
752         error_counter++;
753 #endif
754 
755     close_before_accept_test();
756 
757     tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE);
758     test_tcp_client4();
759 
760     tx_semaphore_put(&sema_1);
761     test_tcp_server4();
762 
763 #ifdef FEATURE_NX_IPV6
764     tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE);
765     test_tcp_client6();
766 
767     tx_semaphore_put(&sema_1);
768     test_tcp_server6();
769 #endif
770 
771     tx_semaphore_get(&sema_0, 5 * NX_IP_PERIODIC_RATE);
772     /* Now open another socket and attempt to connect to the correct remote
773        host but an unexpected port so we expect an unsuccessful connections. */
774     sockfd = socket(AF_INET, SOCK_STREAM, 0);
775     if(sockfd < 0)
776         error_counter++;
777 
778     remote_addr.sin_family = AF_INET;
779     remote_addr.sin_port = htons(13);
780     remote_addr.sin_addr.s_addr = htonl(0x01020305);
781 
782     if(connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)) >= 0)
783         error_counter++;
784     if(errno != ECONNREFUSED)
785         error_counter++;
786 
787     ret = soc_close(sockfd);
788     if(ret < 0)
789         error_counter++;
790 
791     /* Now open another socket and attempt to connect to the an incorrect
792        remote host so we expect an unsuccessful connections. */
793     sockfd = socket(AF_INET, SOCK_STREAM, 0);
794     if(sockfd < 0)
795         error_counter++;
796 
797 
798     remote_addr.sin_family = AF_INET;
799     remote_addr.sin_port = htons(13);
800     remote_addr.sin_addr.s_addr = htonl(0x01020306);
801 
802     if(connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr)) >= 0)
803         error_counter++;
804 
805     if(errno != ETIMEDOUT)
806         error_counter++;
807     ret = soc_close(sockfd);
808     if(ret < 0)
809         error_counter++;
810 
811     /* After the previous failed connection, make sure we can still open a socket. */
812     sockfd = socket(AF_INET, SOCK_STREAM, 0);
813     if(sockfd < 0)
814         error_counter++;
815 
816     ret = soc_close(sockfd);
817     if(ret < 0)
818         error_counter++;
819 
820     validate_bsd_structure();
821 
822     if(error_counter)
823         printf("ERROR!\n");
824     else
825         printf("SUCCESS!\n");
826 
827     if(error_counter)
828         test_control_return(1);
829 
830     test_control_return(0);
831 }
832 
833 static NX_TCP_SOCKET tcp_sockets[NUM_CLIENTS];
multiple_client4(void)834 static void    multiple_client4(void)
835 {
836 
837 int           i;
838 UINT          status = NX_SUCCESS;
839 NX_PACKET     *packet_ptr;
840     for(i = 0; i < NUM_CLIENTS; i++)
841     {
842         status +=  nx_tcp_socket_create(&ip_1, &tcp_sockets[i], "Server Socket",
843                                         NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100,
844                                         NX_NULL, NX_NULL);
845         status +=  nx_tcp_client_socket_bind(&tcp_sockets[i], NX_ANY_PORT, 0);
846     }
847     if(status != NX_SUCCESS)
848         error_counter++;
849 
850     status = NX_SUCCESS;
851     for(i = 0; i < NUM_CLIENTS; i++)
852     {
853         status += nx_tcp_client_socket_connect(&tcp_sockets[i], IP_ADDRESS(1, 2, 3, 4), 12345, NX_IP_PERIODIC_RATE);
854 
855     }
856     if(status != NX_SUCCESS)
857         error_counter++;
858 
859     status = NX_SUCCESS;
860 
861     /* Send messages to each server */
862     for(i = 0; i < NUM_CLIENTS; i++)
863     {
864         status += nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT);
865         status += nx_packet_data_append(packet_ptr, requests[i & 3], strlen(requests[i & 3]),
866                                         &pool_0, NX_NO_WAIT);
867         status += nx_tcp_socket_send(&tcp_sockets[i], packet_ptr, NX_IP_PERIODIC_RATE);
868 
869     }
870 
871     if(status != NX_SUCCESS)
872         error_counter++;
873 
874     status = NX_SUCCESS;
875     /* Receive 3 messages. */
876 
877     for(i = 0; i < NUM_CLIENTS; i++)
878     {
879         status = nx_tcp_socket_receive(&tcp_sockets[i], &packet_ptr, 2 * NX_IP_PERIODIC_RATE);
880         if(status != NX_SUCCESS)
881         {
882             error_counter++;
883             continue;
884         }
885 
886         /* Validate the received data. */
887         else if(packet_ptr -> nx_packet_length != strlen(response[i & 3]))
888             error_counter++;
889         else if(strncmp((char*)packet_ptr -> nx_packet_prepend_ptr, response[i & 3], packet_ptr -> nx_packet_length))
890             error_counter++;
891         nx_packet_release(packet_ptr);
892     }
893 
894     for(i = 0; i < NUM_CLIENTS; i++)
895     {
896 
897         /* Wakeup server thread. */
898         tx_semaphore_put(&sema_1);
899     }
900 
901     /* Shutdown the socket. */
902     for(i = 0; i < NUM_CLIENTS; i++)
903     {
904 
905         status = nx_tcp_socket_disconnect(&tcp_sockets[i], 1 * NX_IP_PERIODIC_RATE);
906         if(status == NX_NOT_CONNECTED || status == NX_DISCONNECT_FAILED)
907             status = 0;
908 
909         if(tcp_sockets[i].nx_tcp_socket_bound_next)
910             status += nx_tcp_client_socket_unbind(&tcp_sockets[i]);
911 
912 
913         status += nx_tcp_socket_delete(&tcp_sockets[i]);
914 
915         if(status != NX_SUCCESS)
916             error_counter++;
917     }
918 
919 
920 }
921 
922 
923 #ifdef FEATURE_NX_IPV6
multiple_client6(void)924 static void    multiple_client6(void)
925 {
926 
927 int           i;
928 UINT          status = NX_SUCCESS;
929 NX_PACKET     *packet_ptr;
930     for(i = 0; i < NUM_CLIENTS; i++)
931     {
932         status +=  nx_tcp_socket_create(&ip_1, &tcp_sockets[i], "Server Socket",
933                                         NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100,
934                                         NX_NULL, NX_NULL);
935         status +=  nx_tcp_client_socket_bind(&tcp_sockets[i], NX_ANY_PORT, 0);
936     }
937     if(status != NX_SUCCESS)
938         error_counter++;
939 
940     status = NX_SUCCESS;
941     for(i = 0; i < NUM_CLIENTS; i++)
942     {
943         status += nxd_tcp_client_socket_connect(&tcp_sockets[i], &ipv6_address_ip0, 12346, NX_IP_PERIODIC_RATE);
944     }
945     if(status != NX_SUCCESS)
946         error_counter++;
947 
948     status = NX_SUCCESS;
949 
950     /* Send messages to each server */
951     for(i = 0; i < NUM_CLIENTS; i++)
952     {
953         status += nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT);
954         status += nx_packet_data_append(packet_ptr, requests[i & 3], strlen(requests[i & 3]),
955                                         &pool_0, NX_NO_WAIT);
956         status += nx_tcp_socket_send(&tcp_sockets[i], packet_ptr, NX_IP_PERIODIC_RATE);
957 
958     }
959 
960     if(status != NX_SUCCESS)
961         error_counter++;
962 
963     status = NX_SUCCESS;
964     /* Receive 3 messages. */
965 
966     for(i = 0; i < NUM_CLIENTS; i++)
967     {
968         status = nx_tcp_socket_receive(&tcp_sockets[i], &packet_ptr, 2 * NX_IP_PERIODIC_RATE);
969         if(status != NX_SUCCESS)
970         {
971             error_counter++;
972             continue;
973         }
974 
975         /* Validate the received data. */
976         else if(packet_ptr -> nx_packet_length != strlen(response[i & 3]))
977             error_counter++;
978         else if(strncmp((char *)packet_ptr -> nx_packet_prepend_ptr, response[i & 3], packet_ptr -> nx_packet_length))
979             error_counter++;
980         nx_packet_release(packet_ptr);
981     }
982 
983     for(i = 0; i < NUM_CLIENTS; i++)
984     {
985 
986         /* Wakeup server thread. */
987         tx_semaphore_put(&sema_1);
988     }
989 
990     /* Shutdown the socket. */
991     for(i = 0; i < NUM_CLIENTS; i++)
992     {
993 
994         nx_tcp_socket_disconnect(&tcp_sockets[i], 1 * NX_IP_PERIODIC_RATE);
995 
996         if(tcp_sockets[i].nx_tcp_socket_bound_next)
997             status = nx_tcp_client_socket_unbind(&tcp_sockets[i]);
998         status += nx_tcp_socket_delete(&tcp_sockets[i]);
999 
1000         if(status != NX_SUCCESS)
1001             error_counter++;
1002     }
1003 
1004 }
1005 #endif
1006 
netx_tcp_server(void)1007 static void    netx_tcp_server(void)
1008 {
1009 NX_PACKET       *packet_ptr;
1010 UINT             status;
1011     /* Create a socket.  */
1012     status =  nx_tcp_socket_create(&ip_1, &server_socket, "Server Socket",
1013                                    NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 100,
1014                                    NX_NULL, NX_NULL);
1015 
1016     /* Check for error.  */
1017     if (status)
1018         error_counter++;
1019 
1020     /* Setup this thread to listen.  */
1021     status =  nx_tcp_server_socket_listen(&ip_1, 12, &server_socket, 5, NX_NULL);
1022 
1023     /* Check for error.  */
1024     if (status)
1025         error_counter++;
1026 
1027     /* Accept a client socket connection.  */
1028     status =  nx_tcp_server_socket_accept(&server_socket, 1 * NX_IP_PERIODIC_RATE);
1029 
1030     /* Check for error.  */
1031     if (status)
1032         error_counter++;
1033 
1034     /* Receive a TCP message from the socket.  */
1035     status =  nx_tcp_socket_receive(&server_socket, &packet_ptr, 2 * NX_IP_PERIODIC_RATE);
1036 
1037     /* Check for error.  */
1038     if ((status) || (packet_ptr -> nx_packet_length != strlen(send_buffer)))
1039         error_counter++;
1040     else
1041     {
1042         if(memcmp(packet_ptr -> nx_packet_prepend_ptr, send_buffer, strlen(send_buffer)))
1043            error_counter++;
1044 
1045         nx_packet_release(packet_ptr);
1046     }
1047 
1048     tx_semaphore_put(&sema_0);
1049 
1050     /* Disconnect the server socket.  */
1051     status =  nx_tcp_socket_disconnect(&server_socket, 1 * NX_IP_PERIODIC_RATE);
1052 
1053     /* Check for error.  */
1054     if (status)
1055         error_counter++;
1056 
1057     /* Unaccept the server socket.  */
1058     status =  nx_tcp_server_socket_unaccept(&server_socket);
1059 
1060     /* Check for error.  */
1061     if (status)
1062         error_counter++;
1063 
1064     /* Setup server socket for listening again.  */
1065     status =  nx_tcp_server_socket_unlisten(&ip_1, 12);
1066 
1067     /* Check for error.  */
1068     if (status)
1069         error_counter++;
1070 
1071     nx_tcp_socket_delete(&server_socket);
1072 }
1073 
nx_dns_response_packet_send(NX_UDP_SOCKET * server_socket,UINT port,USHORT transmit_id,UCHAR * data,UINT length)1074 static UINT   nx_dns_response_packet_send(NX_UDP_SOCKET *server_socket, UINT port,
1075                                           USHORT transmit_id, UCHAR *data, UINT length)
1076 {
1077 UINT        status;
1078 NX_PACKET   *response_packet;
1079 UCHAR        *data_ptr;
1080 
1081     /* Allocate a response packet.  */
1082     status =  nx_packet_allocate(&pool_0, &response_packet, NX_UDP_PACKET, NX_NO_WAIT);
1083 
1084     /* Check status.  */
1085     if (status)
1086     {
1087         error_counter++;
1088     }
1089 
1090     /* Write the DNS response messages into the packet payload!  */
1091     memcpy(response_packet -> nx_packet_prepend_ptr, data + DNS_START_OFFSET, length - DNS_START_OFFSET);
1092 
1093     /* Adjust the write pointer.  */
1094     response_packet -> nx_packet_length = length - DNS_START_OFFSET;
1095     response_packet -> nx_packet_append_ptr =  response_packet -> nx_packet_prepend_ptr + response_packet -> nx_packet_length;
1096 
1097     /* Update the DNS transmit ID.  */
1098     data_ptr = response_packet -> nx_packet_prepend_ptr + NX_DNS_ID_OFFSET;
1099     *data_ptr++ = (UCHAR)(transmit_id >> 8);
1100     *data_ptr = (UCHAR)transmit_id;
1101 
1102     /* Send the UDP packet with the correct port.  */
1103     status =  nx_udp_socket_send(server_socket, response_packet, IP_ADDRESS(1, 2, 3, 4), port);
1104 
1105     /* Check the status.  */
1106     if (status)
1107         nx_packet_release(response_packet);
1108 
1109     return status;
1110 }
1111 
receive_packet_function(NX_UDP_SOCKET * socket_ptr)1112 static void    receive_packet_function(NX_UDP_SOCKET *socket_ptr)
1113 {
1114 NX_PACKET *packet_ptr;
1115 USHORT     transmit_id;
1116 UCHAR     *data_ptr;
1117 UINT       port;
1118 
1119     nx_udp_socket_receive(socket_ptr, &packet_ptr, NX_NO_WAIT);
1120     nx_udp_packet_info_extract(packet_ptr, NX_NULL ,NX_NULL, &port, NX_NULL);
1121 
1122     /* Get the DNS transmit ID.  */
1123     data_ptr = packet_ptr -> nx_packet_prepend_ptr + NX_DNS_ID_OFFSET;
1124     transmit_id = *data_ptr++;
1125     transmit_id =  (USHORT)((transmit_id << 8) | *data_ptr);
1126 
1127     nx_packet_release(packet_ptr);
1128 
1129     if (response_sequence == 0)
1130     {
1131         nx_dns_response_packet_send(socket_ptr, port, transmit_id, response_a_www_baidu_com, sizeof(response_a_www_baidu_com));
1132     }
1133     else
1134     {
1135         nx_dns_response_packet_send(socket_ptr, port, transmit_id, response_cname_www_baidu_com, sizeof(response_cname_www_baidu_com));
1136     }
1137 
1138     response_sequence++;
1139 }
1140 
dns_test()1141 static void    dns_test()
1142 {
1143 struct addrinfo hints, *addrinfo;
1144 
1145     /* Initialize DNS client. */
1146     nx_dns_create(&client_dns, &ip_0, (UCHAR *)"DNS Client");
1147 #ifdef NX_DNS_CLIENT_USER_CREATE_PACKET_POOL
1148     nx_dns_packet_pool_set(&client_dns, &pool_0);
1149 #endif
1150     nx_dns_server_add(&client_dns, IP_ADDRESS(1, 2, 3, 5));
1151 
1152     /* Create a UDP socket to respond DNS query. */
1153     nx_udp_socket_create(&ip_1, &udp_socket, "Socket 1", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5);
1154     nx_udp_socket_bind(&udp_socket, 53, TX_WAIT_FOREVER);
1155     nx_udp_socket_receive_notify(&udp_socket, receive_packet_function);
1156     response_sequence = 0;
1157 
1158     /* Get CName by getaddrinfo. */
1159     memset(&hints, 0, sizeof(hints));
1160     hints.ai_family = AF_INET;
1161     hints.ai_socktype = SOCK_STREAM;
1162     hints.ai_flags = AI_CANONNAME;
1163     if (getaddrinfo("www.baidu.com", "80", &hints, &addrinfo) != 0)
1164     {
1165         printf("ERROR!\n");
1166         test_control_return(1);
1167     }
1168     if (addrinfo -> ai_canonname == NX_NULL)
1169     {
1170         printf("ERROR!\n");
1171         test_control_return(1);
1172     }
1173 #ifdef NX_DNS_ENABLE_EXTENDED_RR_TYPES
1174     if (strcmp(addrinfo -> ai_canonname, "www.a.shifen.com"))
1175 #else
1176     if (strcmp(addrinfo -> ai_canonname, "www.baidu.com"))
1177 #endif
1178     {
1179         printf("ERROR!\n");
1180         test_control_return(1);
1181     }
1182     freeaddrinfo(addrinfo);
1183 
1184     nx_udp_socket_unbind(&udp_socket);
1185     nx_udp_socket_delete(&udp_socket);
1186     nx_dns_delete(&client_dns);
1187 }
1188 
ntest_1_entry(ULONG thread_input)1189 static void    ntest_1_entry(ULONG thread_input)
1190 {
1191 
1192 UINT            status;
1193 ULONG           actual_status;
1194 
1195 
1196 
1197     /* Ensure the IP instance has been initialized.  */
1198     status =  nx_ip_status_check(&ip_1, NX_IP_INITIALIZE_DONE, &actual_status, 1 * NX_IP_PERIODIC_RATE);
1199 
1200     /* Check status...  */
1201     if (status != NX_SUCCESS)
1202     {
1203 
1204         printf("ERROR!\n");
1205         test_control_return(1);
1206     }
1207 
1208 #ifdef NX_BSD_ENABLE_DNS
1209     dns_test();
1210 #endif
1211 
1212     tx_semaphore_put(&sema_0);
1213 
1214     netx_tcp_server();
1215 
1216     /* Server run first. */
1217     tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE);
1218 
1219     /* Simulate a multiple client conneting to the same server. */
1220     multiple_client4();
1221 
1222 #ifdef FEATURE_NX_IPV6
1223     tx_semaphore_put(&sema_0);
1224     netx_tcp_server();
1225 
1226     tx_semaphore_get(&sema_1, 5 * NX_IP_PERIODIC_RATE);
1227     multiple_client6();
1228 #endif
1229 
1230     /* Client finished. */
1231     tx_semaphore_put(&sema_0);
1232 }
1233 
1234 
1235 extern TX_BLOCK_POOL nx_bsd_socket_block_pool;
validate_bsd_structure(void)1236 static void validate_bsd_structure(void)
1237 {
1238 int i;
1239     /* Make sure every BSD socket should be free by now. */
1240 
1241     for(i = 0; i < NX_BSD_MAX_SOCKETS; i++)
1242     {
1243         if(nx_bsd_socket_array[i].nx_bsd_socket_status_flags & NX_BSD_SOCKET_IN_USE)
1244         {
1245             error_counter++;
1246         }
1247 
1248         if(nx_bsd_socket_array[i].nx_bsd_socket_tcp_socket ||
1249            nx_bsd_socket_array[i].nx_bsd_socket_udp_socket)
1250         {
1251             error_counter++;
1252         }
1253     }
1254 
1255     /* Make sure all the NX SOCKET control blocks are released. */
1256     if(nx_bsd_socket_block_pool.tx_block_pool_available !=
1257        nx_bsd_socket_block_pool.tx_block_pool_total)
1258     {
1259         error_counter++;
1260     }
1261 
1262     /* Make sure all the sockets are released */
1263     if(ip_0.nx_ip_tcp_created_sockets_ptr ||
1264        ip_0.nx_ip_udp_created_sockets_ptr)
1265     {
1266         error_counter++;
1267         return;
1268     }
1269 }
1270 
1271 #endif /* NX_BSD_ENABLE */
1272