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