BadVPN – Blame information for rev 1

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