ReactOS 0.4.16-dev-257-g6aa11ac
test_dhcp.c
Go to the documentation of this file.
1#include "test_dhcp.h"
2
3#include "lwip/netif.h"
4#include "lwip/dhcp.h"
5#include "lwip/prot/dhcp.h"
6#include "lwip/etharp.h"
7#include "lwip/inet.h"
8#include "netif/ethernet.h"
9
10#if LWIP_ACD
11#if LWIP_DHCP_DOES_ACD_CHECK
12#define DHCP_TEST_NUM_ARP_FRAMES 5
13#else
14#define DHCP_TEST_NUM_ARP_FRAMES 0
15#endif
16#else
17#define DHCP_TEST_NUM_ARP_FRAMES 1
18#endif
19
20
21static struct netif net_test;
22
23static const u8_t broadcast[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
24
25static const u8_t magic_cookie[] = { 0x63, 0x82, 0x53, 0x63 };
26
27static u8_t dhcp_offer[] = {
28 0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d, /* To unit */
29 0x00, 0x0F, 0xEE, 0x30, 0xAB, 0x22, /* From Remote host */
30 0x08, 0x00, /* Protocol: IP */
31 0x45, 0x10, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, 0x36, 0xcc, 0xc3, 0xaa, 0xbd, 0xab, 0xc3, 0xaa, 0xbd, 0xc8, /* IP header */
32 0x00, 0x43, 0x00, 0x44, 0x01, 0x34, 0x00, 0x00, /* UDP header */
33
34 0x02, /* Type == Boot reply */
35 0x01, 0x06, /* Hw Ethernet, 6 bytes addrlen */
36 0x00, /* 0 hops */
37 0xAA, 0xAA, 0xAA, 0xAA, /* Transaction id, will be overwritten */
38 0x00, 0x00, /* 0 seconds elapsed */
39 0x00, 0x00, /* Flags (unicast) */
40 0x00, 0x00, 0x00, 0x00, /* Client ip */
41 0xc3, 0xaa, 0xbd, 0xc8, /* Your IP */
42 0xc3, 0xaa, 0xbd, 0xab, /* DHCP server ip */
43 0x00, 0x00, 0x00, 0x00, /* relay agent */
44 0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MAC addr + padding */
45
46 /* Empty server name and boot file name */
47 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
48 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
49 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
50 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
52 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
53 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
54 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
55 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
56 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58 0x00, 0x00, 0x00, 0x00,
59
60 0x63, 0x82, 0x53, 0x63, /* Magic cookie */
61 0x35, 0x01, 0x02, /* Message type: Offer */
62 0x36, 0x04, 0xc3, 0xaa, 0xbd, 0xab, /* Server identifier (IP) */
63 0x33, 0x04, 0x00, 0x00, 0x00, 0x78, /* Lease time 2 minutes */
64 0x03, 0x04, 0xc3, 0xaa, 0xbd, 0xab, /* Router IP */
65 0x01, 0x04, 0xff, 0xff, 0xff, 0x00, /* Subnet mask */
66 0xff, /* End option */
67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Padding */
69};
70
71static u8_t dhcp_ack[] = {
72 0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d, /* To unit */
73 0x00, 0x0f, 0xEE, 0x30, 0xAB, 0x22, /* From remote host */
74 0x08, 0x00, /* Proto IP */
75 0x45, 0x10, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, 0x36, 0xcc, 0xc3, 0xaa, 0xbd, 0xab, 0xc3, 0xaa, 0xbd, 0xc8, /* IP header */
76 0x00, 0x43, 0x00, 0x44, 0x01, 0x34, 0x00, 0x00, /* UDP header */
77 0x02, /* Bootp reply */
78 0x01, 0x06, /* Hw type Eth, len 6 */
79 0x00, /* 0 hops */
80 0xAA, 0xAA, 0xAA, 0xAA,
81 0x00, 0x00, /* 0 seconds elapsed */
82 0x00, 0x00, /* Flags (unicast) */
83 0x00, 0x00, 0x00, 0x00, /* Client IP */
84 0xc3, 0xaa, 0xbd, 0xc8, /* Your IP */
85 0xc3, 0xaa, 0xbd, 0xab, /* DHCP server IP */
86 0x00, 0x00, 0x00, 0x00, /* Relay agent */
87 0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Macaddr + padding */
88
89 /* Empty server name and boot file name */
90 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
91 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
92 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
93 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
94 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
95 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
96 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
97 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
98 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
99 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
100 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
101 0x00, 0x00, 0x00, 0x00,
102
103 0x63, 0x82, 0x53, 0x63, /* Magic cookie */
104 0x35, 0x01, 0x05, /* Dhcp message type ack */
105 0x36, 0x04, 0xc3, 0xaa, 0xbd, 0xab, /* DHCP server identifier */
106 0x33, 0x04, 0x00, 0x00, 0x00, 0x78, /* Lease time 2 minutes */
107 0x03, 0x04, 0xc3, 0xaa, 0xbd, 0xab, /* Router IP */
108 0x01, 0x04, 0xff, 0xff, 0xff, 0x00, /* Netmask */
109 0xff, /* End marker */
110
111 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
112 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Padding */
113};
114
115static const u8_t arpreply[] = {
116 0x00, 0x23, 0xC1, 0xDE, 0xD0, 0x0D, /* dst mac */
117 0x00, 0x32, 0x44, 0x20, 0x01, 0x02, /* src mac */
118 0x08, 0x06, /* proto arp */
119 0x00, 0x01, /* hw eth */
120 0x08, 0x00, /* proto ip */
121 0x06, /* hw addr len 6 */
122 0x04, /* proto addr len 4 */
123 0x00, 0x02, /* arp reply */
124 0x00, 0x32, 0x44, 0x20, 0x01, 0x02, /* sender mac */
125 0xc3, 0xaa, 0xbd, 0xc8, /* sender ip */
126 0x00, 0x23, 0xC1, 0xDE, 0xD0, 0x0D, /* target mac */
127 0x00, 0x00, 0x00, 0x00, /* target ip */
128};
129
130static int txpacket;
131static enum tcase {
139
140static int debug = 0;
141static void setdebug(int a) {debug = a;}
142
143static int tick = 0;
144static void tick_lwip(void)
145{
146 tick++;
147#if LWIP_DHCP_DOES_ACD_CHECK
148 acd_tmr();
149#endif
150 if (tick % 5 == 0) {
151 dhcp_fine_tmr();
152 }
153 if (tick % 600 == 0) {
154 dhcp_coarse_tmr();
155 }
156}
157
158static void send_pkt(struct netif *netif, const u8_t *data, size_t len)
159{
160 struct pbuf *p, *q;
161 LWIP_ASSERT("pkt too big", len <= 0xFFFF);
163
164 if (debug) {
165 /* Dump data */
166 u32_t i;
167 printf("RX data (len %d)", p->tot_len);
168 for (i = 0; i < len; i++) {
169 printf(" %02X", data[i]);
170 }
171 printf("\n");
172 }
173
174 fail_unless(p != NULL);
175 for(q = p; q != NULL; q = q->next) {
176 memcpy(q->payload, data, q->len);
177 data += q->len;
178 }
179 netif->input(p, netif);
180}
181
182static err_t lwip_tx_func(struct netif *netif, struct pbuf *p);
183
185{
186 netif->name[0] = 'c';
187 netif->name[1] = 'h';
188 netif->output = etharp_output;
190 netif->mtu = 1500;
191 netif->hwaddr_len = 6;
193
194 netif->hwaddr[0] = 0x00;
195 netif->hwaddr[1] = 0x23;
196 netif->hwaddr[2] = 0xC1;
197 netif->hwaddr[3] = 0xDE;
198 netif->hwaddr[4] = 0xD0;
199 netif->hwaddr[5] = 0x0D;
200
201 return ERR_OK;
202}
203
204static void dhcp_setup(void)
205{
206 txpacket = 0;
207 lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
208}
209
210static void dhcp_teardown(void)
211{
212 lwip_check_ensure_no_alloc(SKIP_POOL(MEMP_SYS_TIMEOUT));
213}
214
215static void check_pkt(struct pbuf *p, u32_t pos, const u8_t *mem, u32_t len)
216{
217 u8_t *data;
218
219 fail_if((pos + len) > p->tot_len);
220 while (pos > p->len && p->next) {
221 pos -= p->len;
222 p = p->next;
223 }
224 fail_if(p == NULL);
225 fail_unless(pos + len <= p->len); /* All data we seek within same pbuf */
226
227 data = (u8_t*)p->payload;
228 fail_if(memcmp(&data[pos], mem, len), "data at pos %d, len %d in packet %d did not match", pos, len, txpacket);
229}
230
231static void check_pkt_fuzzy(struct pbuf *p, u32_t startpos, const u8_t *mem, u32_t len)
232{
233 int found;
234 u32_t i;
235 u8_t *data;
236
237 fail_if((startpos + len) > p->tot_len);
238 while (startpos > p->len && p->next) {
239 startpos -= p->len;
240 p = p->next;
241 }
242 fail_if(p == NULL);
243 fail_unless(startpos + len <= p->len); /* All data we seek within same pbuf */
244
245 found = 0;
246 data = (u8_t*)p->payload;
247 for (i = startpos; i <= (p->len - len); i++) {
248 if (memcmp(&data[i], mem, len) == 0) {
249 found = 1;
250 break;
251 }
252 }
253 fail_unless(found);
254}
255
256static err_t lwip_tx_func(struct netif *netif, struct pbuf *p)
257{
258 fail_unless(netif == &net_test);
259 txpacket++;
260
261 if (debug) {
262 struct pbuf *pp = p;
263 /* Dump data */
264 printf("TX data (pkt %d, len %d, tick %d)", txpacket, p->tot_len, tick);
265 do {
266 int i;
267 for (i = 0; i < pp->len; i++) {
268 printf(" %02X", ((u8_t *) pp->payload)[i]);
269 }
270 if (pp->next) {
271 pp = pp->next;
272 }
273 } while (pp->next);
274 printf("\n");
275 }
276
277 switch (tcase) {
278 case TEST_LWIP_DHCP:
279 switch (txpacket) {
280 case 1:
281 case 2:
282 {
283 const u8_t ipproto[] = { 0x08, 0x00 };
284 const u8_t bootp_start[] = { 0x01, 0x01, 0x06, 0x00}; /* bootp request, eth, hwaddr len 6, 0 hops */
285 const u8_t ipaddrs[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
286
287 check_pkt(p, 0, broadcast, 6); /* eth level dest: broadcast */
288 check_pkt(p, 6, netif->hwaddr, 6); /* eth level src: unit mac */
289
290 check_pkt(p, 12, ipproto, sizeof(ipproto)); /* eth level proto: ip */
291
292 check_pkt(p, 42, bootp_start, sizeof(bootp_start));
293
294 check_pkt(p, 53, ipaddrs, sizeof(ipaddrs));
295
296 check_pkt(p, 70, netif->hwaddr, 6); /* mac addr inside bootp */
297
298 check_pkt(p, 278, magic_cookie, sizeof(magic_cookie));
299
300 /* Check dhcp message type, can be at different positions */
301 if (txpacket == 1) {
302 u8_t dhcp_discover_opt[] = { 0x35, 0x01, 0x01 };
303 check_pkt_fuzzy(p, 282, dhcp_discover_opt, sizeof(dhcp_discover_opt));
304 } else if (txpacket == 2) {
305 u8_t dhcp_request_opt[] = { 0x35, 0x01, 0x03 };
306 u8_t requested_ipaddr[] = { 0x32, 0x04, 0xc3, 0xaa, 0xbd, 0xc8 }; /* Ask for offered IP */
307
308 check_pkt_fuzzy(p, 282, dhcp_request_opt, sizeof(dhcp_request_opt));
309 check_pkt_fuzzy(p, 282, requested_ipaddr, sizeof(requested_ipaddr));
310 }
311 break;
312 }
313#if DHCP_TEST_NUM_ARP_FRAMES > 0
314 case 3:
315#if DHCP_TEST_NUM_ARP_FRAMES > 1
316 case 4:
317#if DHCP_TEST_NUM_ARP_FRAMES > 2
318 case 5:
319#if DHCP_TEST_NUM_ARP_FRAMES > 3
320 case 6:
321#if DHCP_TEST_NUM_ARP_FRAMES > 4
322 case 7:
323#endif
324#endif
325#endif
326#endif
327 {
328 const u8_t arpproto[] = { 0x08, 0x06 };
329
330 check_pkt(p, 0, broadcast, 6); /* eth level dest: broadcast */
331 check_pkt(p, 6, netif->hwaddr, 6); /* eth level src: unit mac */
332
333 check_pkt(p, 12, arpproto, sizeof(arpproto)); /* eth level proto: ip */
334 break;
335 }
336#endif
337 default:
338 fail();
339 break;
340 }
341 break;
342
344 {
345 const u8_t ipproto[] = { 0x08, 0x00 };
346 const u8_t bootp_start[] = { 0x01, 0x01, 0x06, 0x00}; /* bootp request, eth, hwaddr len 6, 0 hops */
347 const u8_t ipaddrs[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
348 const u8_t dhcp_nak_opt[] = { 0x35, 0x01, 0x04 };
349 const u8_t requested_ipaddr[] = { 0x32, 0x04, 0xc3, 0xaa, 0xbd, 0xc8 }; /* offered IP */
350
351 fail_unless(txpacket == 4);
352 check_pkt(p, 0, broadcast, 6); /* eth level dest: broadcast */
353 check_pkt(p, 6, netif->hwaddr, 6); /* eth level src: unit mac */
354
355 check_pkt(p, 12, ipproto, sizeof(ipproto)); /* eth level proto: ip */
356
357 check_pkt(p, 42, bootp_start, sizeof(bootp_start));
358
359 check_pkt(p, 53, ipaddrs, sizeof(ipaddrs));
360
361 check_pkt(p, 70, netif->hwaddr, 6); /* mac addr inside bootp */
362
363 check_pkt(p, 278, magic_cookie, sizeof(magic_cookie));
364
365 check_pkt_fuzzy(p, 282, dhcp_nak_opt, sizeof(dhcp_nak_opt)); /* NAK the ack */
366
367 check_pkt_fuzzy(p, 282, requested_ipaddr, sizeof(requested_ipaddr));
368 break;
369 }
370
372 switch (txpacket) {
373 case 1:
374 case 2:
375 {
376 const u8_t ipproto[] = { 0x08, 0x00 };
377 const u8_t bootp_start[] = { 0x01, 0x01, 0x06, 0x00}; /* bootp request, eth, hwaddr len 6, 0 hops */
378 const u8_t ipaddrs[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
379
380 check_pkt(p, 0, broadcast, 6); /* eth level dest: broadcast */
381 check_pkt(p, 6, netif->hwaddr, 6); /* eth level src: unit mac */
382
383 check_pkt(p, 12, ipproto, sizeof(ipproto)); /* eth level proto: ip */
384
385 check_pkt(p, 42, bootp_start, sizeof(bootp_start));
386
387 check_pkt(p, 53, ipaddrs, sizeof(ipaddrs));
388
389 check_pkt(p, 70, netif->hwaddr, 6); /* mac addr inside bootp */
390
391 check_pkt(p, 278, magic_cookie, sizeof(magic_cookie));
392
393 /* Check dhcp message type, can be at different positions */
394 if (txpacket == 1) {
395 u8_t dhcp_discover_opt[] = { 0x35, 0x01, 0x01 };
396 check_pkt_fuzzy(p, 282, dhcp_discover_opt, sizeof(dhcp_discover_opt));
397 } else if (txpacket == 2) {
398 u8_t dhcp_request_opt[] = { 0x35, 0x01, 0x03 };
399 u8_t requested_ipaddr[] = { 0x32, 0x04, 0x4f, 0x8a, 0x33, 0x05 }; /* Ask for offered IP */
400
401 check_pkt_fuzzy(p, 282, dhcp_request_opt, sizeof(dhcp_request_opt));
402 check_pkt_fuzzy(p, 282, requested_ipaddr, sizeof(requested_ipaddr));
403 }
404 break;
405 }
406 case 3:
407#if DHCP_TEST_NUM_ARP_FRAMES > 0
408 case 4:
409#if DHCP_TEST_NUM_ARP_FRAMES > 1
410 case 5:
411#if DHCP_TEST_NUM_ARP_FRAMES > 2
412 case 6:
413#if DHCP_TEST_NUM_ARP_FRAMES > 3
414 case 7:
415#if DHCP_TEST_NUM_ARP_FRAMES > 4
416 case 8:
417#endif
418#endif
419#endif
420#endif
421 {
422 const u8_t arpproto[] = { 0x08, 0x06 };
423
424 check_pkt(p, 0, broadcast, 6); /* eth level dest: broadcast */
425 check_pkt(p, 6, netif->hwaddr, 6); /* eth level src: unit mac */
426
427 check_pkt(p, 12, arpproto, sizeof(arpproto)); /* eth level proto: ip */
428 break;
429 }
430#endif
432 {
433 const u8_t fake_arp[6] = { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xab };
434 const u8_t ipproto[] = { 0x08, 0x00 };
435 const u8_t bootp_start[] = { 0x01, 0x01, 0x06, 0x00}; /* bootp request, eth, hwaddr len 6, 0 hops */
436 const u8_t ipaddrs[] = { 0x00, 0x4f, 0x8a, 0x33, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
437 const u8_t dhcp_request_opt[] = { 0x35, 0x01, 0x03 };
438
439 check_pkt(p, 0, fake_arp, 6); /* eth level dest: broadcast */
440 check_pkt(p, 6, netif->hwaddr, 6); /* eth level src: unit mac */
441
442 check_pkt(p, 12, ipproto, sizeof(ipproto)); /* eth level proto: ip */
443
444 check_pkt(p, 42, bootp_start, sizeof(bootp_start));
445
446 check_pkt(p, 53, ipaddrs, sizeof(ipaddrs));
447
448 check_pkt(p, 70, netif->hwaddr, 6); /* mac addr inside bootp */
449
450 check_pkt(p, 278, magic_cookie, sizeof(magic_cookie));
451
452 /* Check dhcp message type, can be at different positions */
453 check_pkt_fuzzy(p, 282, dhcp_request_opt, sizeof(dhcp_request_opt));
454 break;
455 }
456 default:
457 fail();
458 break;
459 }
460 break;
461
462 default:
463 break;
464 }
465
466 return ERR_OK;
467}
468
469/*
470 * Test basic happy flow DHCP session.
471 * Validate that xid is checked.
472 */
473START_TEST(test_dhcp)
474{
475 ip4_addr_t addr;
476 ip4_addr_t netmask;
477 ip4_addr_t gw;
478 int i;
479 u32_t xid;
480 LWIP_UNUSED_ARG(_i);
481
483 setdebug(0);
484
485 IP4_ADDR(&addr, 0, 0, 0, 0);
486 IP4_ADDR(&netmask, 0, 0, 0, 0);
487 IP4_ADDR(&gw, 0, 0, 0, 0);
488
489 netif_add(&net_test, &addr, &netmask, &gw, &net_test, testif_init, ethernet_input);
492
493 dhcp_start(&net_test);
494
495 fail_unless(txpacket == 1); /* DHCP discover sent */
496 xid = netif_dhcp_data(&net_test)->xid; /* Write bad xid, not using htonl! */
497 memcpy(&dhcp_offer[46], &xid, 4);
499
500 /* IP addresses should be zero */
501 fail_if(memcmp(&addr, &net_test.ip_addr, sizeof(ip4_addr_t)));
502 fail_if(memcmp(&netmask, &net_test.netmask, sizeof(ip4_addr_t)));
503 fail_if(memcmp(&gw, &net_test.gw, sizeof(ip4_addr_t)));
504
505 fail_unless(txpacket == 1, "TX %d packets, expected 1", txpacket); /* Nothing more sent */
506 xid = htonl(netif_dhcp_data(&net_test)->xid);
507 memcpy(&dhcp_offer[46], &xid, 4); /* insert correct transaction id */
509
510 fail_unless(txpacket == 2, "TX %d packets, expected 2", txpacket); /* DHCP request sent */
511 xid = netif_dhcp_data(&net_test)->xid; /* Write bad xid, not using htonl! */
512 memcpy(&dhcp_ack[46], &xid, 4);
514
515 fail_unless(txpacket == 2, "TX %d packets, still expected 2", txpacket); /* No more sent */
516 xid = htonl(netif_dhcp_data(&net_test)->xid); /* xid updated */
517 memcpy(&dhcp_ack[46], &xid, 4); /* insert transaction id */
519
520 fail_unless(txpacket == 2);
521
522 for (i = 0; i < 200; i++) {
523 tick_lwip();
524 }
525 fail_unless(txpacket == (2 + DHCP_TEST_NUM_ARP_FRAMES), "TX %d packets, expected %d", txpacket, (2 + DHCP_TEST_NUM_ARP_FRAMES));
526
527 /* Interface up */
528 fail_unless(netif_is_up(&net_test));
529
530 /* Now it should have taken the IP */
531 IP4_ADDR(&addr, 195, 170, 189, 200);
532 IP4_ADDR(&netmask, 255, 255, 255, 0);
533 IP4_ADDR(&gw, 195, 170, 189, 171);
534 fail_if(memcmp(&addr, &net_test.ip_addr, sizeof(ip4_addr_t)));
535 fail_if(memcmp(&netmask, &net_test.netmask, sizeof(ip4_addr_t)));
536 fail_if(memcmp(&gw, &net_test.gw, sizeof(ip4_addr_t)));
537
539 dhcp_stop(&net_test);
540 dhcp_cleanup(&net_test);
542}
543END_TEST
544
545/*
546 * Test that IP address is not taken and NAK is sent if someone
547 * replies to ARP requests for the offered address.
548 */
549START_TEST(test_dhcp_nak)
550{
551 ip4_addr_t addr;
552 ip4_addr_t netmask;
553 ip4_addr_t gw;
554 u32_t xid;
555 LWIP_UNUSED_ARG(_i);
556
558 setdebug(0);
559
560 IP4_ADDR(&addr, 0, 0, 0, 0);
561 IP4_ADDR(&netmask, 0, 0, 0, 0);
562 IP4_ADDR(&gw, 0, 0, 0, 0);
563
564 netif_add(&net_test, &addr, &netmask, &gw, &net_test, testif_init, ethernet_input);
567
568 dhcp_start(&net_test);
569
570 fail_unless(txpacket == 1); /* DHCP discover sent */
571 xid = netif_dhcp_data(&net_test)->xid; /* Write bad xid, not using htonl! */
572 memcpy(&dhcp_offer[46], &xid, 4);
574
575 /* IP addresses should be zero */
576 fail_if(memcmp(&addr, &net_test.ip_addr, sizeof(ip4_addr_t)));
577 fail_if(memcmp(&netmask, &net_test.netmask, sizeof(ip4_addr_t)));
578 fail_if(memcmp(&gw, &net_test.gw, sizeof(ip4_addr_t)));
579
580 fail_unless(txpacket == 1); /* Nothing more sent */
581 xid = htonl(netif_dhcp_data(&net_test)->xid);
582 memcpy(&dhcp_offer[46], &xid, 4); /* insert correct transaction id */
584
585 fail_unless(txpacket == 2); /* DHCP request sent */
586 xid = netif_dhcp_data(&net_test)->xid; /* Write bad xid, not using htonl! */
587 memcpy(&dhcp_ack[46], &xid, 4);
589
590 fail_unless(txpacket == 2); /* No more sent */
591 xid = htonl(netif_dhcp_data(&net_test)->xid); /* xid updated */
592 memcpy(&dhcp_ack[46], &xid, 4); /* insert transaction id */
594
595 fail_unless(txpacket == 2); /* ARP request sent */
596
597 while (txpacket == 2) {
598 tick_lwip();
599 }
600 fail_unless(txpacket == 3);
601
602 tcase = TEST_LWIP_DHCP_NAK; /* Switch testcase */
603
604 /* Send arp reply, mark offered IP as taken */
606
607 fail_unless(txpacket == 4); /* DHCP nak sent */
608
610 dhcp_stop(&net_test);
611 dhcp_cleanup(&net_test);
613}
614END_TEST
615
616/*
617 * Test case based on captured data where
618 * replies are sent from a different IP than the
619 * one the client unicasted to.
620 */
621START_TEST(test_dhcp_relayed)
622{
623 u8_t relay_offer[] = {
624 0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d,
625 0x00, 0x22, 0x93, 0x5a, 0xf7, 0x60,
626 0x08, 0x00, 0x45, 0x00,
627 0x01, 0x38, 0xfd, 0x53, 0x00, 0x00, 0x40, 0x11,
628 0x78, 0x46, 0x4f, 0x8a, 0x32, 0x02, 0x4f, 0x8a,
629 0x33, 0x05, 0x00, 0x43, 0x00, 0x44, 0x01, 0x24,
630 0x00, 0x00, 0x02, 0x01, 0x06, 0x00, 0x51, 0x35,
631 0xb6, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
632 0x00, 0x00, 0x4f, 0x8a, 0x33, 0x05, 0x00, 0x00,
633 0x00, 0x00, 0x0a, 0xb5, 0x04, 0x01, 0x00, 0x23,
634 0xc1, 0xde, 0xd0, 0x0d, 0x00, 0x00, 0x00, 0x00,
635 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
636 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
637 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
638 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
639 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
640 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
641 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
642 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
643 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
644 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
645 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
646 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
647 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
648 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
649 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
650 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
651 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
652 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
653 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
654 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
655 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
656 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
657 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
658 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
659 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82,
660 0x53, 0x63, 0x01, 0x04, 0xff, 0xff, 0xfe, 0x00,
661 0x03, 0x04, 0x4f, 0x8a, 0x32, 0x01, 0x06, 0x08,
662 0x4f, 0x8a, 0x00, 0xb4, 0x55, 0x08, 0x1f, 0xd1,
663 0x1c, 0x04, 0x4f, 0x8a, 0x33, 0xff, 0x33, 0x04,
664 0x00, 0x00, 0x54, 0x49, 0x35, 0x01, 0x02, 0x36,
665 0x04, 0x0a, 0xb5, 0x04, 0x01, 0xff
666 };
667
668 u8_t relay_ack1[] = {
669 0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d, 0x00, 0x22,
670 0x93, 0x5a, 0xf7, 0x60, 0x08, 0x00, 0x45, 0x00,
671 0x01, 0x38, 0xfd, 0x55, 0x00, 0x00, 0x40, 0x11,
672 0x78, 0x44, 0x4f, 0x8a, 0x32, 0x02, 0x4f, 0x8a,
673 0x33, 0x05, 0x00, 0x43, 0x00, 0x44, 0x01, 0x24,
674 0x00, 0x00, 0x02, 0x01, 0x06, 0x00, 0x51, 0x35,
675 0xb6, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
676 0x00, 0x00, 0x4f, 0x8a, 0x33, 0x05, 0x00, 0x00,
677 0x00, 0x00, 0x0a, 0xb5, 0x04, 0x01, 0x00, 0x23,
678 0xc1, 0xde, 0xd0, 0x0d, 0x00, 0x00, 0x00, 0x00,
679 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
680 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
681 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
682 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
683 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
684 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
685 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
686 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
687 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
688 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
689 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
690 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
691 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
692 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
693 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
694 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
695 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
696 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
697 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
698 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
699 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
700 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
701 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
702 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
703 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82,
704 0x53, 0x63, 0x01, 0x04, 0xff, 0xff, 0xfe, 0x00,
705 0x03, 0x04, 0x4f, 0x8a, 0x32, 0x01, 0x06, 0x08,
706 0x4f, 0x8a, 0x00, 0xb4, 0x55, 0x08, 0x1f, 0xd1,
707 0x1c, 0x04, 0x4f, 0x8a, 0x33, 0xff, 0x33, 0x04,
708 0x00, 0x00, 0x54, 0x49, 0x35, 0x01, 0x05, 0x36,
709 0x04, 0x0a, 0xb5, 0x04, 0x01, 0xff
710 };
711
712 u8_t relay_ack2[] = {
713 0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d,
714 0x00, 0x22, 0x93, 0x5a, 0xf7, 0x60,
715 0x08, 0x00, 0x45, 0x00,
716 0x01, 0x38, 0xfa, 0x18, 0x00, 0x00, 0x40, 0x11,
717 0x7b, 0x81, 0x4f, 0x8a, 0x32, 0x02, 0x4f, 0x8a,
718 0x33, 0x05, 0x00, 0x43, 0x00, 0x44, 0x01, 0x24,
719 0x00, 0x00, 0x02, 0x01, 0x06, 0x00, 0x49, 0x8b,
720 0x6e, 0xab, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x8a,
721 0x33, 0x05, 0x4f, 0x8a, 0x33, 0x05, 0x00, 0x00,
722 0x00, 0x00, 0x0a, 0xb5, 0x04, 0x01, 0x00, 0x23,
723 0xc1, 0xde, 0xd0, 0x0d, 0x00, 0x00, 0x00, 0x00,
724 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
725 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
726 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
727 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
728 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
729 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
730 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
731 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
732 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
733 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
734 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
735 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
736 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
737 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
738 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
739 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
740 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
741 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
742 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
743 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
744 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
745 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
746 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
747 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
748 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82,
749 0x53, 0x63, 0x01, 0x04, 0xff, 0xff, 0xfe, 0x00,
750 0x03, 0x04, 0x4f, 0x8a, 0x32, 0x01, 0x06, 0x08,
751 0x4f, 0x8a, 0x00, 0xb4, 0x55, 0x08, 0x1f, 0xd1,
752 0x1c, 0x04, 0x4f, 0x8a, 0x33, 0xff, 0x33, 0x04,
753 0x00, 0x00, 0x54, 0x60, 0x35, 0x01, 0x05, 0x36,
754 0x04, 0x0a, 0xb5, 0x04, 0x01, 0xff };
755
756 const u8_t arp_resp[] = {
757 0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d, /* DEST */
758 0x00, 0x22, 0x93, 0x5a, 0xf7, 0x60, /* SRC */
759 0x08, 0x06, /* Type: ARP */
760 0x00, 0x01, /* HW: Ethernet */
761 0x08, 0x00, /* PROTO: IP */
762 0x06, /* HW size */
763 0x04, /* PROTO size */
764 0x00, 0x02, /* OPCODE: Reply */
765
766 0x12, 0x34, 0x56, 0x78, 0x9a, 0xab, /* Target MAC */
767 0x4f, 0x8a, 0x32, 0x01, /* Target IP */
768
769 0x00, 0x23, 0xc1, 0x00, 0x06, 0x50, /* src mac */
770 0x4f, 0x8a, 0x33, 0x05, /* src ip */
771
772 /* Padding follows.. */
773 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
774 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
775 0x00, 0x00, 0x00, 0x00 };
776
777 ip4_addr_t addr;
778 ip4_addr_t netmask;
779 ip4_addr_t gw;
780 int i;
781 u32_t xid;
782 LWIP_UNUSED_ARG(_i);
783
785 setdebug(0);
786
787 IP4_ADDR(&addr, 0, 0, 0, 0);
788 IP4_ADDR(&netmask, 0, 0, 0, 0);
789 IP4_ADDR(&gw, 0, 0, 0, 0);
790
791 netif_add(&net_test, &addr, &netmask, &gw, &net_test, testif_init, ethernet_input);
794
795 dhcp_start(&net_test);
796
797 fail_unless(txpacket == 1); /* DHCP discover sent */
798
799 /* IP addresses should be zero */
800 fail_if(memcmp(&addr, &net_test.ip_addr, sizeof(ip4_addr_t)));
801 fail_if(memcmp(&netmask, &net_test.netmask, sizeof(ip4_addr_t)));
802 fail_if(memcmp(&gw, &net_test.gw, sizeof(ip4_addr_t)));
803
804 fail_unless(txpacket == 1); /* Nothing more sent */
805 xid = htonl(netif_dhcp_data(&net_test)->xid);
806 memcpy(&relay_offer[46], &xid, 4); /* insert correct transaction id */
807 send_pkt(&net_test, relay_offer, sizeof(relay_offer));
808
809 /* request sent? */
810 fail_unless(txpacket == 2, "txpkt = %d, should be 2", txpacket);
811 xid = htonl(netif_dhcp_data(&net_test)->xid); /* xid updated */
812 memcpy(&relay_ack1[46], &xid, 4); /* insert transaction id */
813 send_pkt(&net_test, relay_ack1, sizeof(relay_ack1));
814
815 for (i = 0; i < 200; i++) {
816 tick_lwip();
817 }
818 fail_unless(txpacket == (2 + DHCP_TEST_NUM_ARP_FRAMES), "TX %d packets, expected %d", txpacket, (2 + DHCP_TEST_NUM_ARP_FRAMES));
819
820 /* Interface up */
821 fail_unless(netif_is_up(&net_test));
822
823 /* Now it should have taken the IP */
824 IP4_ADDR(&addr, 79, 138, 51, 5);
825 IP4_ADDR(&netmask, 255, 255, 254, 0);
826 IP4_ADDR(&gw, 79, 138, 50, 1);
827 fail_if(memcmp(&addr, &net_test.ip_addr, sizeof(ip4_addr_t)));
828 fail_if(memcmp(&netmask, &net_test.netmask, sizeof(ip4_addr_t)));
829 fail_if(memcmp(&gw, &net_test.gw, sizeof(ip4_addr_t)));
830
831 fail_unless(txpacket == (2 + DHCP_TEST_NUM_ARP_FRAMES), "TX %d packets, expected %d", txpacket, (2 + DHCP_TEST_NUM_ARP_FRAMES));
832
833 for (i = 0; i < 108000 - 25; i++) {
834 tick_lwip();
835 }
836
837 fail_unless(netif_is_up(&net_test));
838 fail_unless(txpacket == (3 + DHCP_TEST_NUM_ARP_FRAMES), "TX %d packets, expected %d", txpacket, (3 + DHCP_TEST_NUM_ARP_FRAMES));
839
840 /* We need to send arp response here.. */
841
842 send_pkt(&net_test, arp_resp, sizeof(arp_resp));
843
844 fail_unless(txpacket == (4 + DHCP_TEST_NUM_ARP_FRAMES), "TX %d packets, expected %d", txpacket, (4 + DHCP_TEST_NUM_ARP_FRAMES));
845 fail_unless(netif_is_up(&net_test));
846
847 xid = htonl(netif_dhcp_data(&net_test)->xid); /* xid updated */
848 memcpy(&relay_ack2[46], &xid, 4); /* insert transaction id */
849 send_pkt(&net_test, relay_ack2, sizeof(relay_ack2));
850
851 for (i = 0; i < 100000; i++) {
852 tick_lwip();
853 }
854
855 fail_unless(txpacket == (4 + DHCP_TEST_NUM_ARP_FRAMES), "TX %d packets, expected %d", txpacket, (5 + DHCP_TEST_NUM_ARP_FRAMES));
856
858 dhcp_stop(&net_test);
859 dhcp_cleanup(&net_test);
861
862}
863END_TEST
864
865START_TEST(test_dhcp_nak_no_endmarker)
866{
867 ip4_addr_t addr;
868 ip4_addr_t netmask;
869 ip4_addr_t gw;
870
871 u8_t dhcp_nack_no_endmarker[] = {
872 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x54, 0x75,
873 0xd0, 0x26, 0xd0, 0x0d, 0x08, 0x00, 0x45, 0x00,
874 0x01, 0x15, 0x38, 0x86, 0x00, 0x00, 0xff, 0x11,
875 0xc0, 0xa8, 0xc0, 0xa8, 0x01, 0x01, 0xff, 0xff,
876 0xff, 0xff, 0x00, 0x43, 0x00, 0x44, 0x01, 0x01,
877 0x00, 0x00, 0x02, 0x01, 0x06, 0x00, 0x7a, 0xcb,
878 0xba, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
879 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
880 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23,
881 0xc1, 0xde, 0xd0, 0x0d, 0x00, 0x00, 0x00, 0x00,
882 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
883 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
884 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
885 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
886 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
887 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
888 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
889 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
890 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
891 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
892 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
893 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
894 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
895 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
896 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
897 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
898 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
899 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
900 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
901 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
902 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
903 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
904 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
905 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
906 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82,
907 0x53, 0x63, 0x35, 0x01, 0x06, 0x36, 0x04, 0xc0,
908 0xa8, 0x01, 0x01, 0x31, 0xef, 0xad, 0x72, 0x31,
909 0x43, 0x4e, 0x44, 0x30, 0x32, 0x35, 0x30, 0x43,
910 0x52, 0x47, 0x44, 0x38, 0x35, 0x36, 0x3c, 0x08,
911 0x4d, 0x53, 0x46, 0x54, 0x20, 0x35, 0x2e, 0x30,
912 0x37, 0x0d, 0x01, 0x0f, 0x03, 0x06, 0x2c, 0x2e,
913 0x2f, 0x1f, 0x21, 0x79, 0xf9, 0x2b, 0xfc, 0xff,
914 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x71,
915 0xf3, 0x5b, 0xe2, 0x71, 0x2e, 0x01, 0x08, 0x03,
916 0x04, 0xc0, 0xa8, 0x01, 0x01, 0xff, 0xeb, 0x1e,
917 0x44, 0xec, 0xeb, 0x1e, 0x30, 0x37, 0x0c, 0x01,
918 0x0f, 0x03, 0x06, 0x2c, 0x2e, 0x2f, 0x1f, 0x21,
919 0x79, 0xf9, 0x2b, 0xff, 0x25, 0xc0, 0x09, 0xd6,
920 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
921 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
922 };
923 u32_t xid;
924 struct dhcp* dhcp;
925 u8_t tries;
926 u16_t request_timeout;
927 LWIP_UNUSED_ARG(_i);
928
930 setdebug(0);
931
932 IP4_ADDR(&addr, 0, 0, 0, 0);
933 IP4_ADDR(&netmask, 0, 0, 0, 0);
934 IP4_ADDR(&gw, 0, 0, 0, 0);
935
936 netif_add(&net_test, &addr, &netmask, &gw, &net_test, testif_init, ethernet_input);
939
940 dhcp_start(&net_test);
941 dhcp = netif_dhcp_data(&net_test);
942
943 fail_unless(txpacket == 1); /* DHCP discover sent */
944 xid = dhcp->xid; /* Write bad xid, not using htonl! */
945 memcpy(&dhcp_offer[46], &xid, 4);
947
948 /* IP addresses should be zero */
949 fail_if(memcmp(&addr, &net_test.ip_addr, sizeof(ip4_addr_t)));
950 fail_if(memcmp(&netmask, &net_test.netmask, sizeof(ip4_addr_t)));
951 fail_if(memcmp(&gw, &net_test.gw, sizeof(ip4_addr_t)));
952
953 fail_unless(txpacket == 1); /* Nothing more sent */
954 xid = htonl(dhcp->xid);
955 memcpy(&dhcp_offer[46], &xid, 4); /* insert correct transaction id */
957
958 fail_unless(dhcp->state == DHCP_STATE_REQUESTING);
959
960 fail_unless(txpacket == 2); /* No more sent */
961 xid = htonl(dhcp->xid); /* xid updated */
962 memcpy(&dhcp_nack_no_endmarker[46], &xid, 4); /* insert transaction id */
963 tries = dhcp->tries;
964 request_timeout = dhcp->request_timeout;
965 send_pkt(&net_test, dhcp_nack_no_endmarker, sizeof(dhcp_nack_no_endmarker));
966
967 /* NAK should be ignored */
968 fail_unless(dhcp->state == DHCP_STATE_REQUESTING);
969 fail_unless(txpacket == 2); /* No more sent */
970 fail_unless(xid == htonl(dhcp->xid));
971 fail_unless(tries == dhcp->tries);
972 fail_unless(request_timeout == dhcp->request_timeout);
973
975 dhcp_stop(&net_test);
976 dhcp_cleanup(&net_test);
978}
979END_TEST
980
981START_TEST(test_dhcp_invalid_overload)
982{
983 u8_t dhcp_offer_invalid_overload[] = {
984 0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d, /* To unit */
985 0x00, 0x0F, 0xEE, 0x30, 0xAB, 0x22, /* From Remote host */
986 0x08, 0x00, /* Protocol: IP */
987 0x45, 0x10, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, 0x36, 0xcc, 0xc3, 0xaa, 0xbd, 0xab, 0xc3, 0xaa, 0xbd, 0xc8, /* IP header */
988 0x00, 0x43, 0x00, 0x44, 0x01, 0x34, 0x00, 0x00, /* UDP header */
989
990 0x02, /* Type == Boot reply */
991 0x01, 0x06, /* Hw Ethernet, 6 bytes addrlen */
992 0x00, /* 0 hops */
993 0xAA, 0xAA, 0xAA, 0xAA, /* Transaction id, will be overwritten */
994 0x00, 0x00, /* 0 seconds elapsed */
995 0x00, 0x00, /* Flags (unicast) */
996 0x00, 0x00, 0x00, 0x00, /* Client ip */
997 0xc3, 0xaa, 0xbd, 0xc8, /* Your IP */
998 0xc3, 0xaa, 0xbd, 0xab, /* DHCP server ip */
999 0x00, 0x00, 0x00, 0x00, /* relay agent */
1000 0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MAC addr + padding */
1001
1002 /* Empty server name */
1003 0x34, 0x01, 0x02, 0xff, /* Overload: SNAME + END */
1004 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1005 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1006 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1007 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1008 /* Empty boot file name */
1009 0x34, 0x01, 0x01, 0xff, /* Overload FILE + END */
1010 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1011 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1012 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1013 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1014 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1015 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1016 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1017 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1018
1019 0x63, 0x82, 0x53, 0x63, /* Magic cookie */
1020 0x35, 0x01, 0x02, /* Message type: Offer */
1021 0x36, 0x04, 0xc3, 0xaa, 0xbd, 0xab, /* Server identifier (IP) */
1022 0x33, 0x04, 0x00, 0x00, 0x00, 0x78, /* Lease time 2 minutes */
1023 0x03, 0x04, 0xc3, 0xaa, 0xbd, 0xab, /* Router IP */
1024 0x01, 0x04, 0xff, 0xff, 0xff, 0x00, /* Subnet mask */
1025 0x34, 0x01, 0x03, /* Overload: FILE + SNAME */
1026 0xff, /* End option */
1027 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1028 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Padding */
1029 };
1030 ip4_addr_t addr;
1031 ip4_addr_t netmask;
1032 ip4_addr_t gw;
1033 u32_t xid;
1034 LWIP_UNUSED_ARG(_i);
1035
1037 setdebug(0);
1038
1039 IP4_ADDR(&addr, 0, 0, 0, 0);
1040 IP4_ADDR(&netmask, 0, 0, 0, 0);
1041 IP4_ADDR(&gw, 0, 0, 0, 0);
1042
1043 netif_add(&net_test, &addr, &netmask, &gw, &net_test, testif_init, ethernet_input);
1046
1047 dhcp_start(&net_test);
1048
1049 fail_unless(txpacket == 1); /* DHCP discover sent */
1050 xid = htonl(netif_dhcp_data(&net_test)->xid);
1051 memcpy(&dhcp_offer_invalid_overload[46], &xid, 4); /* insert correct transaction id */
1052 dhcp_offer_invalid_overload[311] = 3;
1053 send_pkt(&net_test, dhcp_offer_invalid_overload, sizeof(dhcp_offer_invalid_overload));
1054 /* IP addresses should be zero */
1055 fail_if(memcmp(&addr, &net_test.ip_addr, sizeof(ip4_addr_t)));
1056 fail_if(memcmp(&netmask, &net_test.netmask, sizeof(ip4_addr_t)));
1057 fail_if(memcmp(&gw, &net_test.gw, sizeof(ip4_addr_t)));
1058 fail_unless(txpacket == 1); /* Nothing more sent */
1059
1060 dhcp_offer_invalid_overload[311] = 2;
1061 send_pkt(&net_test, dhcp_offer_invalid_overload, sizeof(dhcp_offer_invalid_overload));
1062 /* IP addresses should be zero */
1063 fail_if(memcmp(&addr, &net_test.ip_addr, sizeof(ip4_addr_t)));
1064 fail_if(memcmp(&netmask, &net_test.netmask, sizeof(ip4_addr_t)));
1065 fail_if(memcmp(&gw, &net_test.gw, sizeof(ip4_addr_t)));
1066 fail_unless(txpacket == 1); /* Nothing more sent */
1067
1068 dhcp_offer_invalid_overload[311] = 1;
1069 send_pkt(&net_test, dhcp_offer_invalid_overload, sizeof(dhcp_offer_invalid_overload));
1070 /* IP addresses should be zero */
1071 fail_if(memcmp(&addr, &net_test.ip_addr, sizeof(ip4_addr_t)));
1072 fail_if(memcmp(&netmask, &net_test.netmask, sizeof(ip4_addr_t)));
1073 fail_if(memcmp(&gw, &net_test.gw, sizeof(ip4_addr_t)));
1074 fail_unless(txpacket == 1); /* Nothing more sent */
1075
1076 dhcp_offer_invalid_overload[311] = 0;
1077 send_pkt(&net_test, dhcp_offer_invalid_overload, sizeof(dhcp_offer));
1078
1079 fail_unless(netif_dhcp_data(&net_test)->state == DHCP_STATE_REQUESTING);
1080
1081 fail_unless(txpacket == 2); /* No more sent */
1082 xid = htonl(netif_dhcp_data(&net_test)->xid); /* xid updated */
1083
1084 tcase = TEST_NONE;
1085 dhcp_stop(&net_test);
1086 dhcp_cleanup(&net_test);
1088}
1089END_TEST
1090
1092Suite *
1094{
1095 testfunc tests[] = {
1096 TESTFUNC(test_dhcp),
1097 TESTFUNC(test_dhcp_nak),
1098 TESTFUNC(test_dhcp_relayed),
1099 TESTFUNC(test_dhcp_nak_no_endmarker),
1100 TESTFUNC(test_dhcp_invalid_overload)
1101 };
1102 return create_suite("DHCP", tests, sizeof(tests)/sizeof(testfunc), dhcp_setup, dhcp_teardown);
1103}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
static int state
Definition: maze.c:121
#define START_TEST(x)
Definition: atltest.h:75
void dhcp(struct packet *packet)
Definition: dhclient.c:674
#define NULL
Definition: types.h:112
#define LWIP_ASSERT(message, assertion)
Definition: debug.h:116
@ DHCP_STATE_REQUESTING
Definition: dhcp.h:101
#define printf
Definition: freeldr.h:97
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
GLenum const GLvoid * addr
Definition: glext.h:9621
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
uint32_t u32_t
Definition: arch.h:129
uint8_t u8_t
Definition: arch.h:125
#define LWIP_UNUSED_ARG(x)
Definition: arch.h:373
uint16_t u16_t
Definition: arch.h:127
s8_t err_t
Definition: err.h:96
@ ERR_OK
Definition: err.h:55
#define NETIF_FLAG_ETHARP
Definition: netif.h:97
#define NETIF_FLAG_BROADCAST
Definition: netif.h:87
#define netif_is_up(netif)
Definition: netif.h:479
void netif_remove(struct netif *netif)
Definition: netif.c:764
struct netif * netif_add(struct netif *netif, void *state, netif_init_fn init, netif_input_fn input)
Definition: netif.c:287
void netif_set_link_up(struct netif *netif)
Definition: netif.c:1018
void netif_set_up(struct netif *netif)
Definition: netif.c:871
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
Definition: pbuf.c:224
@ PBUF_POOL
Definition: pbuf.h:167
@ PBUF_RAW
Definition: pbuf.h:111
#define a
Definition: ke_i.h:78
Suite * create_suite(const char *name, testfunc *tests, size_t num_tests, SFun setup, SFun teardown)
#define SKIP_POOL(x)
Definition: lwip_check.h:48
void lwip_check_ensure_no_alloc(unsigned int skip)
#define TESTFUNC(x)
Definition: lwip_check.h:22
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define htonl(x)
Definition: module.h:214
#define for
Definition: utility.h:88
static struct test_info tests[]
LONGLONG xid
Definition: nfs41_driver.c:106
struct define * next
Definition: compiler.c:65
Definition: mem.c:349
Definition: netif.h:269
u8_t flags
Definition: netif.h:354
char name[2]
Definition: netif.h:356
netif_input_fn input
Definition: netif.h:297
u8_t hwaddr[NETIF_MAX_HWADDR_LEN]
Definition: netif.h:350
u16_t mtu
Definition: netif.h:344
netif_linkoutput_fn linkoutput
Definition: netif.h:308
u8_t hwaddr_len
Definition: netif.h:352
Definition: pbuf.h:186
struct pbuf * next
Definition: pbuf.h:188
u16_t len
Definition: pbuf.h:203
void * payload
Definition: pbuf.h:191
static void dhcp_teardown(void)
Definition: test_dhcp.c:210
tcase
Definition: test_dhcp.c:131
@ TEST_LWIP_DHCP_NAK_NO_ENDMARKER
Definition: test_dhcp.c:135
@ TEST_LWIP_DHCP
Definition: test_dhcp.c:132
@ TEST_LWIP_DHCP_INVALID_OVERLOAD
Definition: test_dhcp.c:136
@ TEST_LWIP_DHCP_RELAY
Definition: test_dhcp.c:134
@ TEST_LWIP_DHCP_NAK
Definition: test_dhcp.c:133
@ TEST_NONE
Definition: test_dhcp.c:137
static err_t lwip_tx_func(struct netif *netif, struct pbuf *p)
Definition: test_dhcp.c:256
static void check_pkt(struct pbuf *p, u32_t pos, const u8_t *mem, u32_t len)
Definition: test_dhcp.c:215
static u8_t dhcp_offer[]
Definition: test_dhcp.c:27
static void send_pkt(struct netif *netif, const u8_t *data, size_t len)
Definition: test_dhcp.c:158
static const u8_t magic_cookie[]
Definition: test_dhcp.c:25
static void dhcp_setup(void)
Definition: test_dhcp.c:204
static void check_pkt_fuzzy(struct pbuf *p, u32_t startpos, const u8_t *mem, u32_t len)
Definition: test_dhcp.c:231
static int txpacket
Definition: test_dhcp.c:130
static void setdebug(int a)
Definition: test_dhcp.c:141
static u8_t dhcp_ack[]
Definition: test_dhcp.c:71
static const u8_t broadcast[6]
Definition: test_dhcp.c:23
static const u8_t arpreply[]
Definition: test_dhcp.c:115
static err_t testif_init(struct netif *netif)
Definition: test_dhcp.c:184
static int debug
Definition: test_dhcp.c:140
static void tick_lwip(void)
Definition: test_dhcp.c:144
END_TEST Suite * dhcp_suite(void)
Definition: test_dhcp.c:1093
static int tick
Definition: test_dhcp.c:143
#define DHCP_TEST_NUM_ARP_FRAMES
Definition: test_dhcp.c:17
static struct netif net_test
Definition: test_dhcp.c:21