1 /* This test case focus on a bug that nx_ftp_client_request_packet will be released multiple times in NX_FTP_QUIT command process. */
2 #include    "tx_api.h"
3 #include    "fx_api.h"
4 #include    "nx_api.h"
5 #include    "nxd_ftp_server.h"
6 
7 extern void     test_control_return(UINT);
8 
9 #if !defined(NX_DISABLE_IPV4) && !defined(NX_DISABLE_PACKET_INFO)
10 
11 #define     DEMO_STACK_SIZE         4096
12 
13 /* Define the ThreadX, NetX, and FileX object control blocks...  */
14 static TX_THREAD               server_thread;
15 static TX_THREAD               client_thread;
16 static NX_PACKET_POOL          server_pool;
17 static NX_IP                   server_ip;
18 static NX_PACKET_POOL          client_pool;
19 static NX_IP                   client_ip;
20 static FX_MEDIA                ram_disk;
21 
22 
23 /* Define the NetX FTP object control blocks.  */
24 static NX_TCP_SOCKET           client_socket;
25 static NX_FTP_SERVER           ftp_server;
26 
27 /* Define the counters used in the demo application...  */
28 static ULONG                   error_counter = 0;
29 static UINT                    test_done = NX_FALSE;
30 
31 /* Define the memory area for the FileX RAM disk.  */
32 static UCHAR                   ram_disk_memory[32000];
33 static UCHAR                   ram_disk_sector_cache[512];
34 
35 
36 #define FTP_SERVER_ADDRESS  IP_ADDRESS(1,2,3,4)
37 #define FTP_CLIENT_ADDRESS  IP_ADDRESS(1,2,3,5)
38 
39 extern UINT  _fx_media_format(FX_MEDIA *media_ptr, VOID (*driver)(FX_MEDIA *media), VOID *driver_info_ptr, UCHAR *memory_ptr, UINT memory_size,
40                         CHAR *volume_name, UINT number_of_fats, UINT directory_entries, UINT hidden_sectors,
41                         ULONG total_sectors, UINT bytes_per_sector, UINT sectors_per_cluster,
42                         UINT heads, UINT sectors_per_track);
43 
44 /* Define the FileX and NetX driver entry functions.  */
45 extern void     _fx_ram_driver(FX_MEDIA *media_ptr);
46 extern void     _nx_ram_network_driver_512(NX_IP_DRIVER *driver_req_ptr);
47 
48 static void    client_thread_entry(ULONG thread_input);
49 static void    thread_server_entry(ULONG thread_input);
50 static UINT    send_data(CHAR *data);
51 
52 
53 /* Define server login/logout functions.  These are stubs for functions that would
54    validate a client login request.   */
55 static UINT    server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info);
56 static UINT    server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info);
57 
58 #ifdef CTEST
test_application_define(void * first_unused_memory)59 VOID test_application_define(void *first_unused_memory)
60 #else
61 void    netx_ftp_server_dangling_pinter_test_application_define(void *first_unused_memory)
62 #endif
63 {
64 
65 UINT    status;
66 UCHAR   *pointer;
67 
68 
69     /* Setup the working pointer.  */
70     pointer =  (UCHAR *) first_unused_memory;
71 
72     /* Create a helper thread for the server. */
73     tx_thread_create(&server_thread, "FTP Server thread", thread_server_entry, 0,
74                      pointer, DEMO_STACK_SIZE,
75                      4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
76 
77     pointer =  pointer + DEMO_STACK_SIZE;
78 
79     /* Initialize NetX.  */
80     nx_system_initialize();
81 
82     /* Create the packet pool for the FTP Server.  */
83     status = nx_packet_pool_create(&server_pool, "NetX Server Packet Pool", 512, pointer, 8192);
84     pointer = pointer + 8192;
85     if (status)
86         error_counter++;
87 
88     /* Create the IP instance for the FTP Server.  */
89     status = nx_ip_create(&server_ip, "NetX Server IP Instance", FTP_SERVER_ADDRESS, 0xFFFFFF00UL,
90                                         &server_pool, _nx_ram_network_driver_512, pointer, 2048, 1);
91     pointer = pointer + 2048;
92     if (status)
93         error_counter++;
94 
95     /* Enable ARP and supply ARP cache memory for server IP instance.  */
96     status = nx_arp_enable(&server_ip, (void *) pointer, 1024);
97     pointer = pointer + 1024;
98     if (status)
99         error_counter++;
100 
101     /* Enable TCP.  */
102     status = nx_tcp_enable(&server_ip);
103     if (status)
104         error_counter++;
105 
106     /* Create the FTP server.  */
107     status =  nx_ftp_server_create(&ftp_server, "FTP Server Instance", &server_ip, &ram_disk, pointer, DEMO_STACK_SIZE, &server_pool,
108                                    server_login, server_logout);
109     pointer =  pointer + DEMO_STACK_SIZE;
110     if (status)
111         error_counter++;
112 
113     /* Now set up the FTP Client. */
114 
115     /* Create the main FTP client thread.  */
116     status = tx_thread_create(&client_thread, "FTP Client thread ", client_thread_entry, 0,
117             pointer, DEMO_STACK_SIZE,
118             6, 6, TX_NO_TIME_SLICE, TX_AUTO_START);
119     pointer = pointer + DEMO_STACK_SIZE ;
120     if (status)
121         error_counter++;
122 
123     /* Create a packet pool for the FTP client.  */
124     status =  nx_packet_pool_create(&client_pool, "NetX Client Packet Pool", 256, pointer, 8192);
125     pointer =  pointer + 8192;
126     if (status)
127         error_counter++;
128 
129     /* Create an IP instance for the FTP client.  */
130     status = nx_ip_create(&client_ip, "NetX Client IP Instance", FTP_CLIENT_ADDRESS, 0xFFFFFF00UL,
131                                                 &client_pool, _nx_ram_network_driver_512, pointer, 2048, 1);
132     pointer = pointer + 2048;
133     if (status)
134         error_counter++;
135 
136     /* Enable ARP and supply ARP cache memory for the FTP Client IP.  */
137     status = nx_arp_enable(&client_ip, (void *) pointer, 1024);
138     pointer = pointer + 1024;
139     if (status)
140         error_counter++;
141 
142     /* Enable TCP for client IP instance.  */
143     status = nx_tcp_enable(&client_ip);
144     if (status)
145         error_counter++;
146 
147 }
148 
149 /* Define the FTP client thread.  */
150 
client_thread_entry(ULONG thread_input)151 void    client_thread_entry(ULONG thread_input)
152 {
153 
154 UINT        status;
155 UINT        i;
156 
157     /* Format the RAM disk - the memory for the RAM disk was defined above.  */
158     status = _fx_media_format(&ram_disk,
159                             _fx_ram_driver,                  /* Driver entry                */
160                             ram_disk_memory,                 /* RAM disk memory pointer     */
161                             ram_disk_sector_cache,           /* Media buffer pointer        */
162                             sizeof(ram_disk_sector_cache),   /* Media buffer size           */
163                             "MY_RAM_DISK",                   /* Volume Name                 */
164                             1,                               /* Number of FATs              */
165                             32,                              /* Directory Entries           */
166                             0,                               /* Hidden sectors              */
167                             256,                             /* Total sectors               */
168                             128,                             /* Sector size                 */
169                             1,                               /* Sectors per cluster         */
170                             1,                               /* Heads                       */
171                             1);                              /* Sectors per track           */
172 
173     /* Check status.  */
174     if (status)
175         error_counter++;
176 
177     /* Open the RAM disk.  */
178     status = fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory, ram_disk_sector_cache, sizeof(ram_disk_sector_cache));
179     if (status)
180         error_counter++;
181 
182     /* Create an FTP client socket.  */
183     status =  nx_tcp_socket_create(&client_ip, &client_socket, "FTP Client Socket", NX_IP_NORMAL,
184                                    NX_DONT_FRAGMENT, NX_IP_TIME_TO_LIVE, 512, NX_NULL, NX_NULL);
185     if (status)
186         error_counter++;
187 
188     for (i = 0; i <= NX_FTP_MAX_CLIENTS; i++)
189     {
190 
191         /* Bind to any port.  */
192         status =  nx_tcp_client_socket_bind(&client_socket, NX_ANY_PORT, NX_NO_WAIT);
193         if (status)
194             error_counter++;
195 
196         /* Now connect with the NetX FTP (IPv4) server. */
197         status =  nx_tcp_client_socket_connect(&client_socket, FTP_SERVER_ADDRESS, NX_FTP_SERVER_CONTROL_PORT,
198                                             NX_IP_PERIODIC_RATE);
199         if (status)
200             error_counter++;
201 
202         status =  send_data("USER aaa\n");
203         if (status)
204             error_counter++;
205 
206         status =  send_data("PASS aaa\n");
207         if (status)
208             error_counter++;
209 
210         if (i != NX_FTP_MAX_CLIENTS)
211         {
212             status =  send_data("TYPE I\n");
213             if (status)
214                 error_counter++;
215 
216             status =  send_data("STOR 1.txt\n");
217             if (status)
218                 error_counter++;
219 
220             status =  send_data("RNFR 1.txt\n");
221             if (status)
222                 error_counter++;
223         }
224 
225         status =  send_data("QUIT\n");
226         if (status)
227             error_counter++;
228 
229         /* Disconnect from the server.  */
230         nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE);
231         nx_tcp_client_socket_unbind(&client_socket);
232     }
233 
234     /* Cleanup the socket.  */
235     nx_tcp_client_socket_unbind(&client_socket);
236     nx_tcp_socket_delete(&client_socket);
237 
238     /* Set the flag.  */
239     test_done = NX_TRUE;
240 }
241 
242 
243 /* Define the helper FTP server thread.  */
thread_server_entry(ULONG thread_input)244 void    thread_server_entry(ULONG thread_input)
245 {
246 
247 UINT    status;
248 
249     /* Print out test information banner.  */
250     printf("NetX Test:   FTP Server Dangling Pointer Test..........................");
251 
252     /* Check for earlier error. */
253     if(error_counter)
254     {
255         printf("ERROR!\n");
256         test_control_return(1);
257     }
258 
259     /* OK to start the ftp Server.   */
260     status = nx_ftp_server_start(&ftp_server);
261     if (status)
262         error_counter++;
263 
264     /* OK to restart the ftp Server.   */
265     status = nx_ftp_server_stop(&ftp_server);
266     status += nx_ftp_server_start(&ftp_server);
267     if (status)
268         error_counter++;
269 
270     /* Wait for test.  */
271     while(test_done == NX_FALSE)
272         tx_thread_sleep(NX_IP_PERIODIC_RATE);
273 
274     status = nx_ftp_server_delete(&ftp_server);
275     if(status)
276         error_counter++;
277 
278     /* Make sure there is no invalid release.  */
279     if (server_pool.nx_packet_pool_invalid_releases)
280         error_counter++;
281 
282     if(error_counter)
283     {
284         printf("ERROR!\n");
285         test_control_return(1);
286     }
287     else
288     {
289         printf("SUCCESS!\n");
290         test_control_return(0);
291     }
292 }
293 
send_data(CHAR * data)294 static UINT  send_data(CHAR *data)
295 {
296 UINT status;
297 NX_PACKET *packet_ptr;
298 
299     status = nx_packet_allocate(&client_pool, &packet_ptr, NX_TCP_PACKET, NX_IP_PERIODIC_RATE);
300     if (status)
301         return(status);
302 
303     status = nx_packet_data_append(packet_ptr, data, strlen(data), &client_pool, NX_IP_PERIODIC_RATE);
304     if (status)
305     {
306         nx_packet_release(packet_ptr);
307         return(status);
308     }
309 
310     status = nx_tcp_socket_send(&client_socket, packet_ptr, NX_IP_PERIODIC_RATE);
311     if (status)
312     {
313         nx_packet_release(packet_ptr);
314         return(status);
315     }
316 
317     /* Return success.  */
318     return(NX_SUCCESS);
319 }
320 
321 
server_login(struct NX_FTP_SERVER_STRUCT * ftp_server_ptr,ULONG client_ip_address,UINT client_port,CHAR * name,CHAR * password,CHAR * extra_info)322 static UINT  server_login(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info)
323 {
324     /* Always return success.  */
325     return(NX_SUCCESS);
326 }
327 
server_logout(struct NX_FTP_SERVER_STRUCT * ftp_server_ptr,ULONG client_ip_address,UINT client_port,CHAR * name,CHAR * password,CHAR * extra_info)328 static UINT  server_logout(struct NX_FTP_SERVER_STRUCT *ftp_server_ptr, ULONG client_ip_address, UINT client_port, CHAR *name, CHAR *password, CHAR *extra_info)
329 {
330     /* Always return success.  */
331     return(NX_SUCCESS);
332 }
333 #else
334 
335 #ifdef CTEST
test_application_define(void * first_unused_memory)336 VOID test_application_define(void *first_unused_memory)
337 #else
338 void    netx_ftp_server_dangling_pinter_test_application_define(void *first_unused_memory)
339 #endif
340 {
341 
342     /* Print out test information banner.  */
343     printf("NetX Test:   FTP Server Dangling Pointer Test..........................N/A\n");
344 
345     test_control_return(3);
346 }
347 #endif