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