1
2 #include "tx_api.h"
3 #include "nx_api.h"
4 #include "nxd_dhcp_client.h"
5 #include "nxd_dhcp_server.h"
6
7 extern void test_control_return(UINT status);
8
9 #if !defined(NX_DISABLE_IPV4)
10
11 #define DEMO_STACK_SIZE 4096
12 #define NX_PACKET_SIZE 1536
13 #define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8
14
15 #define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1)
16 #define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,2)
17 #define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,5)
18
19
20 typedef struct DHCP_TEST_STRUCT
21 {
22 char *dhcp_test_pkt_data;
23 int dhcp_test_pkt_size;
24 } DHCP_TEST;
25
26 #define CLIENT_MSG_COUNT 2
27 static DHCP_TEST dhcp_test[CLIENT_MSG_COUNT];
28 UINT client_complete = NX_FALSE;
29
30 /* Define the ThreadX and NetX object control blocks... */
31 static TX_THREAD client_thread;
32 static NX_PACKET_POOL client_pool;
33 static NX_IP client_ip;
34
35 static TX_THREAD server_thread;
36 static NX_PACKET_POOL server_pool;
37 static NX_IP server_ip;
38 static NX_DHCP_SERVER dhcp_server;
39 static NX_UDP_SOCKET client_socket;
40
41 /* Define the counters used in the demo application... */
42
43 static ULONG error_counter;
44 static CHAR *pointer;
45
46 /* Define thread prototypes. */
47
48 static void server_thread_entry(ULONG thread_input);
49 static void client_thread_entry(ULONG thread_input);
50
51 /******** Optionally substitute your Ethernet driver here. ***********/
52 extern void _nx_ram_network_driver_1024(struct NX_IP_DRIVER_STRUCT *driver_req);
53 static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *client_socket, UINT packet_number);
54 static void dhcp_test_initialize();
55
56 /* Frame (366 bytes) */
57 static char discover[366] = {
58 0x01, 0x01, /* .C.4.... */
59 0x06, 0x00, 0x42, 0x2a, 0x4c, 0xf5, 0x00, 0x00, /* ..B*L... */
60 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
61 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
62 0x00, 0x00, 0x80, 0x86, 0xf2, 0x83, 0x15, 0xd5, /* ........ */
63 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
64 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
65 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
66 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
68 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
69 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
70 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
71 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
72 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
73 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
74 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
75 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
76 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
77 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
78 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
79 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
80 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
81 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
82 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
83 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
84 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
85 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
86 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
87 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
88 0x00, 0x00, 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, /* ..c.Sc5. */
89 0x01, 0x3d, 0x07, 0x01, 0x80, 0x86, 0xf2, 0x83, /* .=...... */
90 0x15, 0xd5, 0x0c, 0x06, 0x57, 0x59, 0x2d, 0x50, /* ....WY-P */
91 0x53, 0x54, 0x3c, 0x08, 0x4d, 0x53, 0x46, 0x54, /* ST<.MSFT */
92 0x20, 0x35, 0x2e, 0x30, 0x37, 0x0c, 0x01, 0x0f, /* 5.07... */
93 0x03, 0x06, 0x2c, 0x2e, 0x2f, 0x1f, 0x21, 0x79, /* ..,./.!y */
94 0xf9, 0x2b, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, /* .+...... */
95 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
96 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* ...... */
97 };
98
99 static int discover_size = 304;
100
101 /* Frame (385 bytes) */
102 static char request[385] = {
103 0x01, 0x01, /* .C.GO... */
104 0x06, 0x00, 0x42, 0x2a, 0x4c, 0xf5, 0x04, 0x00, /* ..B*L... */
105 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
107 0x00, 0x00, 0x80, 0x86, 0xf2, 0x83, 0x15, 0xd5, /* ........ */
108 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
109 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
110 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
111 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
112 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
113 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
114 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
115 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
116 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
117 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
118 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
119 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
120 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
121 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
122 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
123 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
124 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
125 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
126 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
127 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
128 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
129 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
130 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
131 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
132 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
133 0x00, 0x00, 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, /* ..c.Sc5. */
134 0x03, 0x3d, 0x07, 0x01, 0x80, 0x86, 0xf2, 0x83, /* .=...... */
135 0x15, 0xd5, 0x32, 0x04, 0x0a, 0x00, 0x00, 0x02, /* ..2..... */
136 0x36, 0x04, 0x0a, 0x00, 0x00, 0x01, 0x0c, 0x06, /* 6....... */
137 0x57, 0x59, 0x2d, 0x50, 0x53, 0x54, 0x51, 0x14, /* WY-PSTQ. */
138 0x00, 0x00, 0x00, 0x57, 0x59, 0x2d, 0x50, 0x53, /* ...WY-PS */
139 0x54, 0x2e, 0x66, 0x63, 0x69, 0x2e, 0x73, 0x6d, /* T.fci.sm */
140 0x69, 0x2e, 0x61, 0x64, 0x3c, 0x08, 0x4d, 0x53, /* i.ad<.MS */
141 0x46, 0x54, 0x20, 0x35, 0x2e, 0x30, 0x37, 0x0c, /* FT 5.07. */
142 0x01, 0x0f, 0x03, 0x06, 0x2c, 0x2e, 0x2f, 0x1f, /* ....,./. */
143 0x21, 0x79, 0xf9, 0x2b, 0x00, 0x00, 0x00, 0x01, /* !y.+.... */
144 0x00 /* . */
145 };
146
147 static int request_size = 323;
148
149
150 /* Define what the initial system looks like. */
151
152 #ifdef CTEST
test_application_define(void * first_unused_memory)153 VOID test_application_define(void *first_unused_memory)
154 #else
155 void netx_dhcp_server_improper_term_test_application_define(void *first_unused_memory)
156 #endif
157 {
158
159 UINT status;
160
161
162 /* Setup the working pointer. */
163 pointer = (CHAR *) first_unused_memory;
164
165 /* Create the client thread. */
166 tx_thread_create(&client_thread, "thread client", client_thread_entry, 0,
167 pointer, DEMO_STACK_SIZE,
168 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
169 pointer = pointer + DEMO_STACK_SIZE;
170
171 /* Create the server thread. */
172 tx_thread_create(&server_thread, "thread server", server_thread_entry, 0,
173 pointer, DEMO_STACK_SIZE,
174 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START);
175 pointer = pointer + DEMO_STACK_SIZE;
176
177 /* Initialize the NetX system. */
178 nx_system_initialize();
179
180 /* Create the client packet pool. */
181 status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE);
182 pointer = pointer + NX_PACKET_POOL_SIZE;
183
184 /* Check for pool creation error. */
185 if (status)
186 error_counter++;
187
188 /* Create the server packet pool. */
189 status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE);
190 pointer = pointer + NX_PACKET_POOL_SIZE;
191
192 /* Check for pool creation error. */
193 if (status)
194 error_counter++;
195
196 /* Create an IP instance for the DHCP Client. */
197 status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool,
198 _nx_ram_network_driver_1024, pointer, 2048, 1);
199
200 pointer = pointer + 2048;
201
202 /* Check for IP create errors. */
203 if (status)
204 error_counter++;
205
206 /* Create an IP instance for the DHCP Server. */
207 status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool,
208 _nx_ram_network_driver_1024, pointer, 2048, 1);
209
210 pointer = pointer + 2048;
211
212 /* Check for IP create errors. */
213 if (status)
214 error_counter++;
215
216 /* Enable ARP and supply ARP cache memory for DHCP Client IP. */
217 status = nx_arp_enable(&client_ip, (void *) pointer, 1024);
218 pointer = pointer + 1024;
219
220 /* Check for ARP enable errors. */
221 if (status)
222 error_counter++;
223
224 /* Enable ARP and supply ARP cache memory for DHCP Server IP. */
225 status = nx_arp_enable(&server_ip, (void *) pointer, 1024);
226 pointer = pointer + 1024;
227
228 /* Check for ARP enable errors. */
229 if (status)
230 error_counter++;
231
232 /* Enable UDP traffic. */
233 status = nx_udp_enable(&client_ip);
234
235 /* Check for UDP enable errors. */
236 if (status)
237 error_counter++;
238
239 /* Enable UDP traffic. */
240 status = nx_udp_enable(&server_ip);
241
242 /* Check for UDP enable errors. */
243 if (status)
244 error_counter++;
245
246 /* Enable ICMP. */
247 status = nx_icmp_enable(&client_ip);
248
249 /* Check for errors. */
250 if (status)
251 error_counter++;
252
253 /* Enable ICMP. */
254 status = nx_icmp_enable(&server_ip);
255
256 /* Check for errors. */
257 if (status)
258 error_counter++;
259
260 return;
261 }
262
263 /* Define the test threads. */
264
server_thread_entry(ULONG thread_input)265 void server_thread_entry(ULONG thread_input)
266 {
267
268 UINT status;
269 UINT iface_index;
270 UINT addresses_added;
271
272 printf("NetX Test: DHCP Server Improper Termination Test.....................");
273
274 /* Check for earlier errors. */
275 if(error_counter)
276 {
277 printf("ERROR!\n");
278 test_control_return(1);
279 }
280
281 /* Create the DHCP Server. */
282 status = nx_dhcp_server_create(&dhcp_server, &server_ip, pointer, DEMO_STACK_SIZE, "DHCP Server", &server_pool);
283
284 pointer = pointer + DEMO_STACK_SIZE;
285
286 /* Check for errors creating the DHCP Server. */
287 if (status)
288 error_counter++;
289
290 /* Load the assignable DHCP IP addresses for the first interface. */
291 iface_index = 0;
292
293 status = nx_dhcp_create_server_ip_address_list(&dhcp_server, iface_index, START_IP_ADDRESS_LIST_0,
294 END_IP_ADDRESS_LIST_0, &addresses_added);
295
296 /* Check for errors creating the list. */
297 if (status)
298 {
299 error_counter++;
300 }
301
302 /* Verify all the addresses were added to the list. */
303 if (addresses_added != 4)
304 {
305 error_counter++;
306 }
307
308 /* Start DHCP Server task. */
309 status = nx_dhcp_server_start(&dhcp_server);
310
311 /* Check for errors starting up the DHCP server. */
312 if (status)
313 {
314 error_counter++;
315 }
316
317 while(!client_complete)
318 tx_thread_sleep(1 * NX_IP_PERIODIC_RATE);
319
320 /* Check that the server did not receive a valid request */
321 if (dhcp_server.nx_dhcp_requests_received > 0)
322 {
323 error_counter++;
324 }
325
326 if (error_counter)
327 {
328 printf("ERROR!\n");
329 test_control_return(1);
330 }
331 else
332 {
333 printf("SUCCESS!\n");
334 test_control_return(0);
335 }
336
337 return;
338 }
339
340
341 /* This thread task simulates DHCP Client sending requests. */
client_thread_entry(ULONG thread_input)342 void client_thread_entry(ULONG thread_input)
343 {
344
345 NX_PACKET *my_packet;
346 UINT i;
347 ULONG actual_status;
348 UINT status;
349
350
351 /* Check for earlier errors. */
352 if(error_counter)
353 {
354 client_complete = NX_TRUE;
355 return;
356 }
357
358 #ifdef FEATURE_NX_IPV6
359 /* Sleep 4 seconds to finish DAD. */
360 tx_thread_sleep(4 * NX_IP_PERIODIC_RATE);
361 #endif /* FEATURE_NX_IPV6 */
362
363 /* Ensure the IP instance has been initialized. */
364 status = nx_ip_status_check(&server_ip, NX_IP_INITIALIZE_DONE, &actual_status, 100);
365
366 /* Check status...*/
367 if(status != NX_SUCCESS)
368 {
369 error_counter++;
370 return;
371 }
372
373 /* Load up the Client messages. */
374 dhcp_test_initialize();
375
376 status = nx_udp_socket_create(&client_ip, &client_socket, "Client Socket", NX_IP_NORMAL, NX_FRAGMENT_OKAY, 0x80, 5);
377
378 /* Check status. */
379 if (status)
380 {
381 error_counter++;
382 }
383
384 /* Bind the UDP socket to the IP port. */
385 status = nx_udp_socket_bind(&client_socket, 68, TX_WAIT_FOREVER);
386
387 /* Check status. */
388 if (status)
389 {
390 error_counter++;
391 return;
392 }
393
394 /* Act as the DHCP Client to send DHCP discover and request packets. */
395 for (i = 0; i < CLIENT_MSG_COUNT; i++ )
396 {
397
398 /* Send the DHCP client packet. */
399 status = nx_dhcp_response_packet_send(&client_socket, i);
400
401 /* Check status. */
402 if (status)
403 {
404 error_counter++;
405 }
406
407 /* Receive a UDP packet. */
408 status = nx_udp_socket_receive(&client_socket, &my_packet, NX_IP_PERIODIC_RATE);
409
410 /* Check status. */
411 if (status)
412 {
413
414 if (i == 1)
415 {
416
417 /* This is correct. The Client should not get a message because the server rejected the request packet. */
418 }
419 else /* i == 0*/
420 {
421 /* There should be a response to the discovery message, so this is an error. */
422 error_counter++;
423 continue;
424 }
425
426 }
427 else
428 {
429 nx_packet_release(my_packet);
430 }
431
432 }
433
434 status = nx_udp_socket_unbind(&client_socket);
435
436 /* Delete the UDP socket. */
437 status |= nx_udp_socket_delete(&client_socket);
438
439 /* Check status. */
440 if (status)
441 {
442 error_counter++;
443 }
444
445 client_complete = NX_TRUE;
446 }
447
448
nx_dhcp_response_packet_send(NX_UDP_SOCKET * client_socket,UINT packet_number)449 static UINT nx_dhcp_response_packet_send(NX_UDP_SOCKET *client_socket, UINT packet_number)
450 {
451
452 UINT status;
453 NX_PACKET *client_packet;
454
455
456
457 /* Allocate a response packet. */
458 status = nx_packet_allocate(&client_pool, &client_packet, NX_UDP_PACKET, TX_WAIT_FOREVER);
459
460 /* Check status. */
461 if (status)
462 {
463 error_counter++;
464 return status;
465 }
466
467 memset(client_packet -> nx_packet_prepend_ptr, 0, (client_packet -> nx_packet_data_end - client_packet -> nx_packet_prepend_ptr));
468
469 /* Write the DHCP Client messages into the packet payload! */
470 memcpy(client_packet -> nx_packet_prepend_ptr,
471 dhcp_test[packet_number].dhcp_test_pkt_data,
472 dhcp_test[packet_number].dhcp_test_pkt_size);
473
474 /* Adjust the write pointer. */
475 client_packet -> nx_packet_length = dhcp_test[packet_number].dhcp_test_pkt_size;
476 client_packet -> nx_packet_append_ptr = client_packet -> nx_packet_prepend_ptr + client_packet -> nx_packet_length;
477
478 /* Send the UDP packet with the correct port. */
479 status = nx_udp_socket_send(client_socket, client_packet, IP_ADDRESS(255,255,255,255), 67);
480 /* Check the status. */
481 if (status)
482 {
483 error_counter++;
484 nx_packet_release(client_packet);
485 }
486
487 return status;
488 }
489
dhcp_test_initialize()490 static void dhcp_test_initialize()
491 {
492 dhcp_test[0].dhcp_test_pkt_data = &discover[0];
493 dhcp_test[0].dhcp_test_pkt_size = discover_size;
494 dhcp_test[1].dhcp_test_pkt_data = &request[0];
495 dhcp_test[1].dhcp_test_pkt_size = request_size;
496
497
498 }
499 #else
500
501 #ifdef CTEST
test_application_define(void * first_unused_memory)502 VOID test_application_define(void *first_unused_memory)
503 #else
504 void netx_dhcp_server_improper_term_test_application_define(void *first_unused_memory)
505 #endif
506 {
507
508 /* Print out test information banner. */
509 printf("NetX Test: NetX DHCP Server Improper Termination Test................N/A\n");
510
511 test_control_return(3);
512 }
513 #endif
514