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