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