1 /* If the client includes a list fo parameters in a DHCPDISCOVER message, it MUST include that list in any subsequent DHCPREQUEST messsages.
2 * rfc 2131, page 21, 3.5 Client parameters in DHCP
3 *
4 */
5 #include "tx_api.h"
6 #include "nx_api.h"
7 #include "netx_dhcp_clone_function.h"
8 #include "nxd_dhcp_client.h"
9 #include "nxd_dhcp_server.h"
10 #include "nx_ipv4.h"
11
12 extern void test_control_return(UINT status);
13
14 #if !defined(NX_DISABLE_IPV4)
15
16 #define DEMO_STACK_SIZE 4096
17 #define NX_PACKET_SIZE 1536
18 #define NX_PACKET_POOL_SIZE NX_PACKET_SIZE * 8
19
20 #define NX_DHCP_SERVER_IP_ADDRESS_0 IP_ADDRESS(10,0,0,1)
21 #define START_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,10)
22 #define END_IP_ADDRESS_LIST_0 IP_ADDRESS(10,0,0,19)
23
24 #define NX_DHCP_SUBNET_MASK_0 IP_ADDRESS(255,255,255,0)
25 #define NX_DHCP_DEFAULT_GATEWAY_0 IP_ADDRESS(10,0,0,1)
26 #define NX_DHCP_DNS_SERVER_0 IP_ADDRESS(10,0,0,1)
27
28
29 /* Define the ThreadX and NetX object control blocks... */
30 static TX_THREAD client_thread;
31 static NX_PACKET_POOL client_pool;
32 static NX_IP client_ip;
33 static NX_DHCP dhcp_client;
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
40 /* Define the counters used in the demo application... */
41
42 static ULONG error_counter;
43 static CHAR *pointer;
44
45 static UINT dhcp_offer_flag;
46 static UINT dhcp_request_flag;
47
48 /* Define thread prototypes. */
49
50 static void server_thread_entry(ULONG thread_input);
51 static void client_thread_entry(ULONG thread_input);
52
53 /******** Optionally substitute your Ethernet driver here. ***********/
54 extern void _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req);
55 static void my_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr);
56
57 /* Define what the initial system looks like. */
58
59 #ifdef CTEST
test_application_define(void * first_unused_memory)60 VOID test_application_define(void *first_unused_memory)
61 #else
62 void netx_dhcp_03_05_01_test_application_define(void *first_unused_memory)
63 #endif
64 {
65
66 UINT status;
67
68 /* Setup the working pointer. */
69 pointer = (CHAR *) first_unused_memory;
70
71 /* Create the client thread. */
72 tx_thread_create(&client_thread, "thread client", client_thread_entry, 0,
73 pointer, DEMO_STACK_SIZE,
74 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
75 pointer = pointer + DEMO_STACK_SIZE;
76
77 /* Create the server thread. */
78 tx_thread_create(&server_thread, "thread server", server_thread_entry, 0,
79 pointer, DEMO_STACK_SIZE,
80 3, 3, TX_NO_TIME_SLICE, TX_AUTO_START);
81 pointer = pointer + DEMO_STACK_SIZE;
82
83 /* Initialize the NetX system. */
84 nx_system_initialize();
85
86 /* Create the client packet pool. */
87 status = nx_packet_pool_create(&client_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE);
88 pointer = pointer + NX_PACKET_POOL_SIZE;
89
90 /* Check for pool creation error. */
91 if (status)
92 error_counter++;
93
94 /* Create the server packet pool. */
95 status = nx_packet_pool_create(&server_pool, "NetX Main Packet Pool", 1024, pointer, NX_PACKET_POOL_SIZE);
96 pointer = pointer + NX_PACKET_POOL_SIZE;
97
98 /* Check for pool creation error. */
99 if (status)
100 error_counter++;
101
102 /* Create an IP instance for the DHCP Client. */
103 status = nx_ip_create(&client_ip, "DHCP Client", IP_ADDRESS(0, 0, 0, 0), 0xFFFFFF00UL, &client_pool, _nx_ram_network_driver_1500, pointer, 2048, 1);
104
105 pointer = pointer + 2048;
106
107 /* Check for IP create errors. */
108 if (status)
109 error_counter++;
110
111 /* Create an IP instance for the DHCP Server. */
112 status = nx_ip_create(&server_ip, "DHCP Server", NX_DHCP_SERVER_IP_ADDRESS_0, 0xFFFFFF00UL, &server_pool, _nx_ram_network_driver_1500, pointer, 2048, 1);
113
114 pointer = pointer + 2048;
115
116 /* Check for IP create errors. */
117 if (status)
118 error_counter++;
119
120 /* Enable ARP and supply ARP cache memory for DHCP Client IP. */
121 status = nx_arp_enable(&client_ip, (void *) pointer, 1024);
122 pointer = pointer + 1024;
123
124 /* Check for ARP enable errors. */
125 if (status)
126 error_counter++;
127
128 /* Enable ARP and supply ARP cache memory for DHCP Server IP. */
129 status = nx_arp_enable(&server_ip, (void *) pointer, 1024);
130 pointer = pointer + 1024;
131
132 /* Check for ARP enable errors. */
133 if (status)
134 error_counter++;
135
136 /* Enable UDP traffic. */
137 status = nx_udp_enable(&client_ip);
138
139 /* Check for UDP enable errors. */
140 if (status)
141 error_counter++;
142
143 /* Enable UDP traffic. */
144 status = nx_udp_enable(&server_ip);
145
146 /* Check for UDP enable errors. */
147 if (status)
148 error_counter++;
149
150 /* Enable ICMP. */
151 status = nx_icmp_enable(&client_ip);
152
153 /* Check for errors. */
154 if (status)
155 error_counter++;
156
157 /* Enable ICMP. */
158 status = nx_icmp_enable(&server_ip);
159
160 /* Check for errors. */
161 if (status)
162 error_counter++;
163
164 return;
165 }
166
167 /* Define the test threads. */
168
server_thread_entry(ULONG thread_input)169 void server_thread_entry(ULONG thread_input)
170 {
171
172 UINT status;
173 UINT iface_index;
174 UINT addresses_added;
175
176 printf("NetX Test: DHCP 03_05_01 Test........................................");
177
178 /* Create the DHCP Server. */
179 status = nx_dhcp_server_create(&dhcp_server, &server_ip, pointer, DEMO_STACK_SIZE,
180 "DHCP Server", &server_pool);
181
182 pointer = pointer + DEMO_STACK_SIZE;
183
184 /* Check for errors creating the DHCP Server. */
185 if (status)
186 error_counter++;
187
188 /* Load the assignable DHCP IP addresses for the first interface. */
189 iface_index = 0;
190
191 status = nx_dhcp_create_server_ip_address_list(&dhcp_server, iface_index, START_IP_ADDRESS_LIST_0,
192 END_IP_ADDRESS_LIST_0, &addresses_added);
193
194 /* Check for errors creating the list. */
195 if (status)
196 error_counter++;
197
198 /* Verify all the addresses were added to the list. */
199 if (addresses_added != 10)
200 error_counter++;
201
202 status = nx_dhcp_set_interface_network_parameters(&dhcp_server, iface_index, NX_DHCP_SUBNET_MASK_0,
203 NX_DHCP_DEFAULT_GATEWAY_0, NX_DHCP_DNS_SERVER_0);
204
205 /* Check for errors setting network parameters. */
206 if (status)
207 error_counter++;
208
209 server_ip.nx_ip_udp_packet_receive = my_udp_packet_receive;
210
211 /* Start DHCP Server task. */
212 status = nx_dhcp_server_start(&dhcp_server);
213
214 /* Check for errors starting up the DHCP server. */
215 if (status)
216 error_counter++;
217
218 tx_thread_sleep(3 * NX_IP_PERIODIC_RATE);
219
220 if((error_counter) || (dhcp_request_flag == 0))
221 {
222 printf("ERROR!\n");
223 test_control_return(1);
224 }
225 else
226 {
227 printf("SUCCESS!\n");
228 test_control_return(0);
229 }
230
231 return;
232 }
233
234 /* Define the test threads. */
235
client_thread_entry(ULONG thread_input)236 void client_thread_entry(ULONG thread_input)
237 {
238
239 UINT status;
240
241 dhcp_offer_flag = 0;
242 dhcp_request_flag = 0;
243
244 /* Create the DHCP instance. */
245 status = nx_dhcp_create(&dhcp_client, &client_ip, "dhcp_client");
246 if (status)
247 error_counter++;
248
249 #ifdef NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL
250 status = nx_dhcp_packet_pool_set(&dhcp_client, &client_pool);
251 if (status)
252 error_counter++;
253 #endif /* NX_DHCP_CLIENT_USER_CREATE_PACKET_POOL */
254
255 /* Start the DHCP Client. */
256 status = nx_dhcp_start(&dhcp_client);
257 if (status)
258 error_counter++;
259
260 /* Wait for DHCP to assign the IP address. */
261 do
262 {
263 /* Check for address resolution. */
264 status = nx_ip_status_check(&client_ip, NX_IP_ADDRESS_RESOLVED, (ULONG *) &status, NX_IP_PERIODIC_RATE);
265
266 /* Check status. */
267 if (status)
268 {
269 /* wait a bit. */
270 tx_thread_sleep(NX_IP_PERIODIC_RATE);
271 }
272
273 } while (status != NX_SUCCESS);
274
275 /* Stopping the DHCP client. */
276 nx_dhcp_stop(&dhcp_client);
277
278 /* All done. Return resources to NetX and ThreadX. */
279 nx_dhcp_delete(&dhcp_client);
280
281 return;
282 }
283
my_udp_packet_receive(NX_IP * ip_ptr,NX_PACKET * packet_ptr)284 void my_udp_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr)
285 {
286
287 UINT status;
288 ULONG message_type;
289 static ULONG discover_parameters;
290 ULONG request_parameters;
291
292 /* Get the dhcp message type. */
293 status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 8), NX_DHCP_SERVER_OPTION_DHCP_TYPE,
294 &message_type, (packet_ptr -> nx_packet_length - 8));
295 if(status)
296 error_counter++;
297
298 /* Check if the message is a DHCPOFFER. */
299 if(message_type == NX_DHCP_TYPE_DHCPDISCOVER)
300 {
301 dhcp_offer_flag++;
302
303 /* Get the dhcp parameters. */
304 status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 8), NX_DHCP_OPTION_DHCP_PARAMETERS,
305 &discover_parameters, (packet_ptr -> nx_packet_length - 8));
306 if(status)
307 error_counter++;
308 }
309 else if((message_type == NX_DHCP_TYPE_DHCPREQUEST) && (dhcp_offer_flag == 1))
310 {
311 dhcp_request_flag++;
312
313 /* Get the dhcp parameters. */
314 status = dhcp_get_option_value((packet_ptr -> nx_packet_prepend_ptr + 8), NX_DHCP_OPTION_DHCP_PARAMETERS,
315 &request_parameters, (packet_ptr -> nx_packet_length - 8));
316 if(status)
317 error_counter++;
318
319 if(discover_parameters != request_parameters)
320 error_counter++;
321
322 /* Restore the udp packet receiving function. */
323 server_ip.nx_ip_udp_packet_receive = _nx_udp_packet_receive;
324 }
325
326 /* Let server receives the packet. */
327 _nx_udp_packet_receive(ip_ptr, packet_ptr);
328 }
329 #else
330
331 #ifdef CTEST
test_application_define(void * first_unused_memory)332 VOID test_application_define(void *first_unused_memory)
333 #else
334 void netx_dhcp_03_05_01_test_application_define(void *first_unused_memory)
335 #endif
336 {
337
338 /* Print out test information banner. */
339 printf("NetX Test: NetX DHCP 03_05_01 Test...................................N/A\n");
340
341 test_control_return(3);
342 }
343 #endif