Greg Steiert / pegasus_dev

Dependents:   blinky_max32630fthr

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers test_dhcp.c Source File

test_dhcp.c

00001 #include "test_dhcp.h"
00002 
00003 #include "lwip/netif.h"
00004 #include "lwip/dhcp.h"
00005 #include "netif/etharp.h"
00006 
00007 struct netif net_test;
00008 
00009 static const u8_t broadcast[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
00010 
00011 static const u8_t magic_cookie[] = { 0x63, 0x82, 0x53, 0x63 };
00012 
00013 static u8_t dhcp_offer[] = {
00014     0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d, /* To unit */
00015     0x00, 0x0F, 0xEE, 0x30, 0xAB, 0x22, /* From Remote host */
00016     0x08, 0x00, /* Protocol: IP */
00017     0x45, 0x10, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, 0x36, 0xcc, 0xc3, 0xaa, 0xbd, 0xab, 0xc3, 0xaa, 0xbd, 0xc8, /* IP header */
00018     0x00, 0x43, 0x00, 0x44, 0x01, 0x34, 0x00, 0x00, /* UDP header */
00019 
00020     0x02, /* Type == Boot reply */
00021     0x01, 0x06, /* Hw Ethernet, 6 bytes addrlen */
00022     0x00, /* 0 hops */
00023     0xAA, 0xAA, 0xAA, 0xAA, /* Transaction id, will be overwritten */
00024     0x00, 0x00, /* 0 seconds elapsed */
00025     0x00, 0x00, /* Flags (unicast) */
00026     0x00, 0x00, 0x00, 0x00, /* Client ip */
00027     0xc3, 0xaa, 0xbd, 0xc8, /* Your IP */
00028     0xc3, 0xaa, 0xbd, 0xab, /* DHCP server ip */
00029     0x00, 0x00, 0x00, 0x00, /* relay agent */
00030     0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* MAC addr + padding */
00031 
00032     /* Empty server name and boot file name */
00033     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00034     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00035     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00036     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00037     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00038     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00039     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00040     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00041     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00042     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00043     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00044     0x00, 0x00, 0x00, 0x00,
00045 
00046     0x63, 0x82, 0x53, 0x63, /* Magic cookie */
00047     0x35, 0x01, 0x02, /* Message type: Offer */
00048     0x36, 0x04, 0xc3, 0xaa, 0xbd, 0xab, /* Server identifier (IP) */
00049     0x33, 0x04, 0x00, 0x00, 0x00, 0x78, /* Lease time 2 minutes */
00050     0x03, 0x04, 0xc3, 0xaa, 0xbd, 0xab, /* Router IP */
00051     0x01, 0x04, 0xff, 0xff, 0xff, 0x00, /* Subnet mask */
00052     0xff, /* End option */
00053     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00054     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Padding */
00055 };
00056 
00057 static u8_t dhcp_ack[] = {
00058     0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d, /* To unit */
00059     0x00, 0x0f, 0xEE, 0x30, 0xAB, 0x22, /* From remote host */
00060     0x08, 0x00, /* Proto IP */
00061     0x45, 0x10, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, 0x36, 0xcc, 0xc3, 0xaa, 0xbd, 0xab, 0xc3, 0xaa, 0xbd, 0xc8, /* IP header */
00062     0x00, 0x43, 0x00, 0x44, 0x01, 0x34, 0x00, 0x00, /* UDP header */
00063     0x02, /* Bootp reply */
00064     0x01, 0x06, /* Hw type Eth, len 6 */
00065     0x00, /* 0 hops */
00066     0xAA, 0xAA, 0xAA, 0xAA,
00067     0x00, 0x00, /* 0 seconds elapsed */
00068     0x00, 0x00, /* Flags (unicast) */
00069     0x00, 0x00, 0x00, 0x00, /* Client IP */
00070     0xc3, 0xaa, 0xbd, 0xc8, /* Your IP */
00071     0xc3, 0xaa, 0xbd, 0xab, /* DHCP server IP */
00072     0x00, 0x00, 0x00, 0x00, /* Relay agent */
00073     0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Macaddr + padding */
00074 
00075     /* Empty server name and boot file name */
00076     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00077     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00078     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00079     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00080     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00081     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00082     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00083     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00084     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00085     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00086     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00087     0x00, 0x00, 0x00, 0x00,
00088 
00089     0x63, 0x82, 0x53, 0x63, /* Magic cookie */
00090     0x35, 0x01, 0x05, /* Dhcp message type ack */
00091     0x36, 0x04, 0xc3, 0xaa, 0xbd, 0xab, /* DHCP server identifier */
00092     0x33, 0x04, 0x00, 0x00, 0x00, 0x78, /* Lease time 2 minutes */
00093     0x03, 0x04, 0xc3, 0xaa, 0xbd, 0xab, /* Router IP */
00094     0x01, 0x04, 0xff, 0xff, 0xff, 0x00, /* Netmask */
00095     0xff, /* End marker */
00096 
00097     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00098     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Padding */
00099 };
00100 
00101 static const u8_t arpreply[] = {
00102     0x00, 0x23, 0xC1, 0xDE, 0xD0, 0x0D, /* dst mac */
00103     0x00, 0x32, 0x44, 0x20, 0x01, 0x02, /* src mac */
00104     0x08, 0x06, /* proto arp */
00105     0x00, 0x01, /* hw eth */
00106     0x08, 0x00, /* proto ip */
00107     0x06, /* hw addr len 6 */
00108     0x04, /* proto addr len 4 */
00109     0x00, 0x02, /* arp reply */
00110     0x00, 0x32, 0x44, 0x20, 0x01, 0x02, /* sender mac */
00111     0xc3, 0xaa, 0xbd, 0xc8, /* sender ip */
00112     0x00, 0x23, 0xC1, 0xDE, 0xD0, 0x0D, /* target mac */
00113     0x00, 0x00, 0x00, 0x00, /* target ip */
00114 };
00115 
00116 static int txpacket;
00117 static enum tcase {
00118   TEST_LWIP_DHCP,
00119   TEST_LWIP_DHCP_NAK,
00120   TEST_LWIP_DHCP_RELAY,
00121   TEST_LWIP_DHCP_NAK_NO_ENDMARKER
00122 } tcase;
00123 
00124 static int debug = 0;
00125 static void setdebug(int a) {debug = a;}
00126 
00127 static int tick = 0;
00128 static void tick_lwip(void)
00129 {
00130   tick++;
00131   if (tick % 5 == 0) {
00132     dhcp_fine_tmr();
00133   }
00134   if (tick % 600 == 0) {
00135     dhcp_coarse_tmr();
00136   }
00137 }
00138 
00139 static void send_pkt(struct netif *netif, const u8_t *data, size_t len)
00140 {
00141   struct pbuf *p, *q;
00142   LWIP_ASSERT("pkt too big", len <= 0xFFFF);
00143   p = pbuf_alloc(PBUF_RAW, (u16_t)len, PBUF_POOL);
00144 
00145   if (debug) {
00146     /* Dump data */
00147     u32_t i;
00148     printf("RX data (len %d)", p->tot_len);
00149     for (i = 0; i < len; i++) {
00150       printf(" %02X", data[i]);
00151     }
00152     printf("\n");
00153   }
00154 
00155   fail_unless(p != NULL);
00156   for(q = p; q != NULL; q = q->next) {
00157     memcpy(q->payload, data, q->len);
00158     data += q->len;
00159   }
00160   netif->input(p, netif);
00161 }
00162 
00163 static err_t lwip_tx_func(struct netif *netif, struct pbuf *p);
00164 
00165 static err_t testif_init(struct netif *netif)
00166 {
00167   netif->name[0] = 'c';
00168   netif->name[1] = 'h';
00169   netif->output = etharp_output;
00170   netif->linkoutput = lwip_tx_func;
00171   netif->mtu = 1500;
00172   netif->hwaddr_len = 6;
00173   netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
00174 
00175   netif->hwaddr[0] = 0x00;
00176   netif->hwaddr[1] = 0x23;
00177   netif->hwaddr[2] = 0xC1;
00178   netif->hwaddr[3] = 0xDE;
00179   netif->hwaddr[4] = 0xD0;
00180   netif->hwaddr[5] = 0x0D;
00181 
00182   return ERR_OK;
00183 }
00184 
00185 static void dhcp_setup(void)
00186 {
00187   txpacket = 0;
00188 }
00189 
00190 static void dhcp_teardown(void)
00191 {
00192 }
00193 
00194 static void check_pkt(struct pbuf *p, u32_t pos, const u8_t *mem, u32_t len)
00195 {
00196   u8_t *data;
00197 
00198   fail_if((pos + len) > p->tot_len);
00199   while (pos > p->len && p->next) {
00200     pos -= p->len;
00201     p = p->next;
00202   }
00203   fail_if(p == NULL);
00204   fail_unless(pos + len <= p->len); /* All data we seek within same pbuf */
00205 
00206   data = (u8_t*)p->payload;
00207   fail_if(memcmp(&data[pos], mem, len), "data at pos %d, len %d in packet %d did not match", pos, len, txpacket);
00208 }
00209 
00210 static void check_pkt_fuzzy(struct pbuf *p, u32_t startpos, const u8_t *mem, u32_t len)
00211 {
00212   int found;
00213   u32_t i;
00214   u8_t *data;
00215 
00216   fail_if((startpos + len) > p->tot_len);
00217   while (startpos > p->len && p->next) {
00218     startpos -= p->len;
00219     p = p->next;
00220   }
00221   fail_if(p == NULL);
00222   fail_unless(startpos + len <= p->len); /* All data we seek within same pbuf */
00223 
00224   found = 0;
00225   data = (u8_t*)p->payload;
00226   for (i = startpos; i <= (p->len - len); i++) {
00227     if (memcmp(&data[i], mem, len) == 0) {
00228       found = 1;
00229       break;
00230     }
00231   }
00232   fail_unless(found);
00233 }
00234 
00235 static err_t lwip_tx_func(struct netif *netif, struct pbuf *p)
00236 {
00237   fail_unless(netif == &net_test);
00238   txpacket++;
00239 
00240   if (debug) {
00241     struct pbuf *pp = p;
00242     /* Dump data */
00243     printf("TX data (pkt %d, len %d, tick %d)", txpacket, p->tot_len, tick);
00244     do {
00245       int i;
00246       for (i = 0; i < pp->len; i++) {
00247         printf(" %02X", ((u8_t *) pp->payload)[i]);
00248       }
00249       if (pp->next) {
00250         pp = pp->next;
00251       }
00252     } while (pp->next);
00253     printf("\n");
00254   }
00255 
00256   switch (tcase) {
00257   case TEST_LWIP_DHCP:
00258     switch (txpacket) {
00259     case 1:
00260     case 2:
00261       {
00262         const u8_t ipproto[] = { 0x08, 0x00 };
00263         const u8_t bootp_start[] = { 0x01, 0x01, 0x06, 0x00}; /* bootp request, eth, hwaddr len 6, 0 hops */
00264         const u8_t ipaddrs[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
00265 
00266         check_pkt(p, 0, broadcast, 6); /* eth level dest: broadcast */
00267         check_pkt(p, 6, netif->hwaddr, 6); /* eth level src: unit mac */
00268 
00269         check_pkt(p, 12, ipproto, sizeof(ipproto)); /* eth level proto: ip */
00270 
00271         check_pkt(p, 42, bootp_start, sizeof(bootp_start));
00272 
00273         check_pkt(p, 53, ipaddrs, sizeof(ipaddrs));
00274 
00275         check_pkt(p, 70, netif->hwaddr, 6); /* mac addr inside bootp */
00276 
00277         check_pkt(p, 278, magic_cookie, sizeof(magic_cookie));
00278 
00279         /* Check dchp message type, can be at different positions */
00280         if (txpacket == 1) {
00281           u8_t dhcp_discover_opt[] = { 0x35, 0x01, 0x01 };
00282           check_pkt_fuzzy(p, 282, dhcp_discover_opt, sizeof(dhcp_discover_opt));
00283         } else if (txpacket == 2) {
00284           u8_t dhcp_request_opt[] = { 0x35, 0x01, 0x03 };
00285           u8_t requested_ipaddr[] = { 0x32, 0x04, 0xc3, 0xaa, 0xbd, 0xc8 }; /* Ask for offered IP */
00286 
00287           check_pkt_fuzzy(p, 282, dhcp_request_opt, sizeof(dhcp_request_opt));
00288           check_pkt_fuzzy(p, 282, requested_ipaddr, sizeof(requested_ipaddr));
00289         }
00290         break;
00291       }
00292     case 3:
00293     case 4:
00294     case 5:
00295       {
00296         const u8_t arpproto[] = { 0x08, 0x06 };
00297 
00298         check_pkt(p, 0, broadcast, 6); /* eth level dest: broadcast */
00299         check_pkt(p, 6, netif->hwaddr, 6); /* eth level src: unit mac */
00300 
00301         check_pkt(p, 12, arpproto, sizeof(arpproto)); /* eth level proto: ip */
00302         break;
00303       }
00304       default:
00305         fail();
00306         break;
00307     }
00308     break;
00309 
00310   case TEST_LWIP_DHCP_NAK:
00311     {
00312       const u8_t ipproto[] = { 0x08, 0x00 };
00313       const u8_t bootp_start[] = { 0x01, 0x01, 0x06, 0x00}; /* bootp request, eth, hwaddr len 6, 0 hops */
00314       const u8_t ipaddrs[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
00315       const u8_t dhcp_nak_opt[] = { 0x35, 0x01, 0x04 };
00316       const u8_t requested_ipaddr[] = { 0x32, 0x04, 0xc3, 0xaa, 0xbd, 0xc8 }; /* offered IP */
00317 
00318       fail_unless(txpacket == 4);
00319       check_pkt(p, 0, broadcast, 6); /* eth level dest: broadcast */
00320       check_pkt(p, 6, netif->hwaddr, 6); /* eth level src: unit mac */
00321 
00322       check_pkt(p, 12, ipproto, sizeof(ipproto)); /* eth level proto: ip */
00323 
00324       check_pkt(p, 42, bootp_start, sizeof(bootp_start));
00325 
00326       check_pkt(p, 53, ipaddrs, sizeof(ipaddrs));
00327 
00328       check_pkt(p, 70, netif->hwaddr, 6); /* mac addr inside bootp */
00329 
00330       check_pkt(p, 278, magic_cookie, sizeof(magic_cookie));
00331 
00332       check_pkt_fuzzy(p, 282, dhcp_nak_opt, sizeof(dhcp_nak_opt)); /* NAK the ack */
00333 
00334       check_pkt_fuzzy(p, 282, requested_ipaddr, sizeof(requested_ipaddr));
00335       break;
00336     }
00337 
00338   case TEST_LWIP_DHCP_RELAY:
00339     switch (txpacket) {
00340     case 1:
00341     case 2:
00342       {
00343         const u8_t ipproto[] = { 0x08, 0x00 };
00344         const u8_t bootp_start[] = { 0x01, 0x01, 0x06, 0x00}; /* bootp request, eth, hwaddr len 6, 0 hops */
00345         const u8_t ipaddrs[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
00346 
00347         check_pkt(p, 0, broadcast, 6); /* eth level dest: broadcast */
00348         check_pkt(p, 6, netif->hwaddr, 6); /* eth level src: unit mac */
00349 
00350         check_pkt(p, 12, ipproto, sizeof(ipproto)); /* eth level proto: ip */
00351 
00352         check_pkt(p, 42, bootp_start, sizeof(bootp_start));
00353 
00354         check_pkt(p, 53, ipaddrs, sizeof(ipaddrs));
00355 
00356         check_pkt(p, 70, netif->hwaddr, 6); /* mac addr inside bootp */
00357 
00358         check_pkt(p, 278, magic_cookie, sizeof(magic_cookie));
00359 
00360         /* Check dchp message type, can be at different positions */
00361         if (txpacket == 1) {
00362           u8_t dhcp_discover_opt[] = { 0x35, 0x01, 0x01 };
00363           check_pkt_fuzzy(p, 282, dhcp_discover_opt, sizeof(dhcp_discover_opt));
00364         } else if (txpacket == 2) {
00365           u8_t dhcp_request_opt[] = { 0x35, 0x01, 0x03 };
00366           u8_t requested_ipaddr[] = { 0x32, 0x04, 0x4f, 0x8a, 0x33, 0x05 }; /* Ask for offered IP */
00367 
00368           check_pkt_fuzzy(p, 282, dhcp_request_opt, sizeof(dhcp_request_opt));
00369           check_pkt_fuzzy(p, 282, requested_ipaddr, sizeof(requested_ipaddr));
00370         }
00371         break;
00372       }
00373     case 3:
00374     case 4:
00375     case 5:
00376     case 6:
00377       {
00378         const u8_t arpproto[] = { 0x08, 0x06 };
00379 
00380         check_pkt(p, 0, broadcast, 6); /* eth level dest: broadcast */
00381         check_pkt(p, 6, netif->hwaddr, 6); /* eth level src: unit mac */
00382 
00383         check_pkt(p, 12, arpproto, sizeof(arpproto)); /* eth level proto: ip */
00384         break;
00385       }
00386     case 7:
00387       {
00388         const u8_t fake_arp[6] = { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xab };
00389         const u8_t ipproto[] = { 0x08, 0x00 };
00390         const u8_t bootp_start[] = { 0x01, 0x01, 0x06, 0x00}; /* bootp request, eth, hwaddr len 6, 0 hops */
00391         const u8_t ipaddrs[] = { 0x00, 0x4f, 0x8a, 0x33, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
00392         const u8_t dhcp_request_opt[] = { 0x35, 0x01, 0x03 };
00393 
00394         check_pkt(p, 0, fake_arp, 6); /* eth level dest: broadcast */
00395         check_pkt(p, 6, netif->hwaddr, 6); /* eth level src: unit mac */
00396 
00397         check_pkt(p, 12, ipproto, sizeof(ipproto)); /* eth level proto: ip */
00398 
00399         check_pkt(p, 42, bootp_start, sizeof(bootp_start));
00400 
00401         check_pkt(p, 53, ipaddrs, sizeof(ipaddrs));
00402 
00403         check_pkt(p, 70, netif->hwaddr, 6); /* mac addr inside bootp */
00404 
00405         check_pkt(p, 278, magic_cookie, sizeof(magic_cookie));
00406 
00407         /* Check dchp message type, can be at different positions */
00408         check_pkt_fuzzy(p, 282, dhcp_request_opt, sizeof(dhcp_request_opt));
00409         break;
00410       }
00411     default:
00412       fail();
00413       break;
00414     }
00415     break;
00416 
00417   default:
00418     break;
00419   }
00420 
00421   return ERR_OK;
00422 }
00423 
00424 /*
00425  * Test basic happy flow DHCP session.
00426  * Validate that xid is checked.
00427  */
00428 START_TEST(test_dhcp)
00429 {
00430   ip4_addr_t addr;
00431   ip4_addr_t netmask;
00432   ip4_addr_t gw;
00433   int i;
00434   u32_t xid;
00435   LWIP_UNUSED_ARG(_i);
00436 
00437   tcase = TEST_LWIP_DHCP;
00438   setdebug(0);
00439 
00440   IP4_ADDR(&addr, 0, 0, 0, 0);
00441   IP4_ADDR(&netmask, 0, 0, 0, 0);
00442   IP4_ADDR(&gw, 0, 0, 0, 0);
00443 
00444   netif_add(&net_test, &addr, &netmask, &gw, &net_test, testif_init, ethernet_input);
00445   netif_set_up(&net_test);
00446 
00447   dhcp_start(&net_test);
00448 
00449   fail_unless(txpacket == 1); /* DHCP discover sent */
00450   xid = net_test.dhcp->xid; /* Write bad xid, not using htonl! */
00451   memcpy(&dhcp_offer[46], &xid, 4);
00452   send_pkt(&net_test, dhcp_offer, sizeof(dhcp_offer));
00453 
00454   /* IP addresses should be zero */
00455   fail_if(memcmp(&addr, &net_test.ip_addr, sizeof(ip4_addr_t)));
00456   fail_if(memcmp(&netmask, &net_test.netmask, sizeof(ip4_addr_t)));
00457   fail_if(memcmp(&gw, &net_test.gw, sizeof(ip4_addr_t)));
00458 
00459   fail_unless(txpacket == 1, "TX %d packets, expected 1", txpacket); /* Nothing more sent */
00460   xid = htonl(net_test.dhcp->xid);
00461   memcpy(&dhcp_offer[46], &xid, 4); /* insert correct transaction id */
00462   send_pkt(&net_test, dhcp_offer, sizeof(dhcp_offer));
00463 
00464   fail_unless(txpacket == 2, "TX %d packets, expected 2", txpacket); /* DHCP request sent */
00465   xid = net_test.dhcp->xid; /* Write bad xid, not using htonl! */
00466   memcpy(&dhcp_ack[46], &xid, 4);
00467   send_pkt(&net_test, dhcp_ack, sizeof(dhcp_ack));
00468 
00469   fail_unless(txpacket == 2, "TX %d packets, still expected 2", txpacket); /* No more sent */
00470   xid = htonl(net_test.dhcp->xid); /* xid updated */
00471   memcpy(&dhcp_ack[46], &xid, 4); /* insert transaction id */
00472   send_pkt(&net_test, dhcp_ack, sizeof(dhcp_ack));
00473 
00474   for (i = 0; i < 20; i++) {
00475     tick_lwip();
00476   }
00477   fail_unless(txpacket == 5, "TX %d packets, expected 5", txpacket); /* ARP requests sent */
00478 
00479   /* Interface up */
00480   fail_unless(netif_is_up(&net_test));
00481 
00482   /* Now it should have taken the IP */
00483   IP4_ADDR(&addr, 195, 170, 189, 200);
00484   IP4_ADDR(&netmask, 255, 255, 255, 0);
00485   IP4_ADDR(&gw, 195, 170, 189, 171);
00486   fail_if(memcmp(&addr, &net_test.ip_addr, sizeof(ip4_addr_t)));
00487   fail_if(memcmp(&netmask, &net_test.netmask, sizeof(ip4_addr_t)));
00488   fail_if(memcmp(&gw, &net_test.gw, sizeof(ip4_addr_t)));
00489 
00490   netif_remove(&net_test);
00491 }
00492 END_TEST
00493 
00494 /*
00495  * Test that IP address is not taken and NAK is sent if someone
00496  * replies to ARP requests for the offered address.
00497  */
00498 START_TEST(test_dhcp_nak)
00499 {
00500   ip4_addr_t addr;
00501   ip4_addr_t netmask;
00502   ip4_addr_t gw;
00503   u32_t xid;
00504   LWIP_UNUSED_ARG(_i);
00505 
00506   tcase = TEST_LWIP_DHCP;
00507   setdebug(0);
00508 
00509   IP4_ADDR(&addr, 0, 0, 0, 0);
00510   IP4_ADDR(&netmask, 0, 0, 0, 0);
00511   IP4_ADDR(&gw, 0, 0, 0, 0);
00512 
00513   netif_add(&net_test, &addr, &netmask, &gw, &net_test, testif_init, ethernet_input);
00514   netif_set_up(&net_test);
00515 
00516   dhcp_start(&net_test);
00517 
00518   fail_unless(txpacket == 1); /* DHCP discover sent */
00519   xid = net_test.dhcp->xid; /* Write bad xid, not using htonl! */
00520   memcpy(&dhcp_offer[46], &xid, 4);
00521   send_pkt(&net_test, dhcp_offer, sizeof(dhcp_offer));
00522 
00523   /* IP addresses should be zero */
00524   fail_if(memcmp(&addr, &net_test.ip_addr, sizeof(ip4_addr_t)));
00525   fail_if(memcmp(&netmask, &net_test.netmask, sizeof(ip4_addr_t)));
00526   fail_if(memcmp(&gw, &net_test.gw, sizeof(ip4_addr_t)));
00527 
00528   fail_unless(txpacket == 1); /* Nothing more sent */
00529   xid = htonl(net_test.dhcp->xid);
00530   memcpy(&dhcp_offer[46], &xid, 4); /* insert correct transaction id */
00531   send_pkt(&net_test, dhcp_offer, sizeof(dhcp_offer));
00532 
00533   fail_unless(txpacket == 2); /* DHCP request sent */
00534   xid = net_test.dhcp->xid; /* Write bad xid, not using htonl! */
00535   memcpy(&dhcp_ack[46], &xid, 4);
00536   send_pkt(&net_test, dhcp_ack, sizeof(dhcp_ack));
00537 
00538   fail_unless(txpacket == 2); /* No more sent */
00539   xid = htonl(net_test.dhcp->xid); /* xid updated */
00540   memcpy(&dhcp_ack[46], &xid, 4); /* insert transaction id */
00541   send_pkt(&net_test, dhcp_ack, sizeof(dhcp_ack));
00542 
00543   fail_unless(txpacket == 3); /* ARP request sent */
00544 
00545   tcase = TEST_LWIP_DHCP_NAK; /* Switch testcase */
00546 
00547   /* Send arp reply, mark offered IP as taken */
00548   send_pkt(&net_test, arpreply, sizeof(arpreply));
00549 
00550   fail_unless(txpacket == 4); /* DHCP nak sent */
00551 
00552   netif_remove(&net_test);
00553 }
00554 END_TEST
00555 
00556 /*
00557  * Test case based on captured data where
00558  * replies are sent from a different IP than the
00559  * one the client unicasted to.
00560  */
00561 START_TEST(test_dhcp_relayed)
00562 {
00563   u8_t relay_offer[] = {
00564   0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d,
00565   0x00, 0x22, 0x93, 0x5a, 0xf7, 0x60,
00566   0x08, 0x00, 0x45, 0x00,
00567   0x01, 0x38, 0xfd, 0x53, 0x00, 0x00, 0x40, 0x11,
00568   0x78, 0x46, 0x4f, 0x8a, 0x32, 0x02, 0x4f, 0x8a,
00569   0x33, 0x05, 0x00, 0x43, 0x00, 0x44, 0x01, 0x24,
00570   0x00, 0x00, 0x02, 0x01, 0x06, 0x00, 0x51, 0x35,
00571   0xb6, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00572   0x00, 0x00, 0x4f, 0x8a, 0x33, 0x05, 0x00, 0x00,
00573   0x00, 0x00, 0x0a, 0xb5, 0x04, 0x01, 0x00, 0x23,
00574   0xc1, 0xde, 0xd0, 0x0d, 0x00, 0x00, 0x00, 0x00,
00575   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00576   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00577   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00578   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00579   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00580   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00581   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00582   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00583   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00584   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00585   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00586   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00587   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00588   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00589   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00590   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00591   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00592   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00593   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00594   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00595   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00596   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00597   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00598   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00599   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82,
00600   0x53, 0x63, 0x01, 0x04, 0xff, 0xff, 0xfe, 0x00,
00601   0x03, 0x04, 0x4f, 0x8a, 0x32, 0x01, 0x06, 0x08,
00602   0x4f, 0x8a, 0x00, 0xb4, 0x55, 0x08, 0x1f, 0xd1,
00603   0x1c, 0x04, 0x4f, 0x8a, 0x33, 0xff, 0x33, 0x04,
00604   0x00, 0x00, 0x54, 0x49, 0x35, 0x01, 0x02, 0x36,
00605   0x04, 0x0a, 0xb5, 0x04, 0x01, 0xff
00606   };
00607 
00608   u8_t relay_ack1[] = {
00609   0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d, 0x00, 0x22,
00610   0x93, 0x5a, 0xf7, 0x60, 0x08, 0x00, 0x45, 0x00,
00611   0x01, 0x38, 0xfd, 0x55, 0x00, 0x00, 0x40, 0x11,
00612   0x78, 0x44, 0x4f, 0x8a, 0x32, 0x02, 0x4f, 0x8a,
00613   0x33, 0x05, 0x00, 0x43, 0x00, 0x44, 0x01, 0x24,
00614   0x00, 0x00, 0x02, 0x01, 0x06, 0x00, 0x51, 0x35,
00615   0xb6, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00616   0x00, 0x00, 0x4f, 0x8a, 0x33, 0x05, 0x00, 0x00,
00617   0x00, 0x00, 0x0a, 0xb5, 0x04, 0x01, 0x00, 0x23,
00618   0xc1, 0xde, 0xd0, 0x0d, 0x00, 0x00, 0x00, 0x00,
00619   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00620   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00621   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00622   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00623   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00624   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00625   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00626   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00627   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00628   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00629   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00630   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00631   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00632   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00633   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00634   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00635   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00636   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00637   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00638   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00639   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00640   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00641   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00642   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00643   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82,
00644   0x53, 0x63, 0x01, 0x04, 0xff, 0xff, 0xfe, 0x00,
00645   0x03, 0x04, 0x4f, 0x8a, 0x32, 0x01, 0x06, 0x08,
00646   0x4f, 0x8a, 0x00, 0xb4, 0x55, 0x08, 0x1f, 0xd1,
00647   0x1c, 0x04, 0x4f, 0x8a, 0x33, 0xff, 0x33, 0x04,
00648   0x00, 0x00, 0x54, 0x49, 0x35, 0x01, 0x05, 0x36,
00649   0x04, 0x0a, 0xb5, 0x04, 0x01, 0xff
00650   };
00651 
00652   u8_t relay_ack2[] = {
00653   0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d,
00654   0x00, 0x22, 0x93, 0x5a, 0xf7, 0x60,
00655   0x08, 0x00, 0x45, 0x00,
00656   0x01, 0x38, 0xfa, 0x18, 0x00, 0x00, 0x40, 0x11,
00657   0x7b, 0x81, 0x4f, 0x8a, 0x32, 0x02, 0x4f, 0x8a,
00658   0x33, 0x05, 0x00, 0x43, 0x00, 0x44, 0x01, 0x24,
00659   0x00, 0x00, 0x02, 0x01, 0x06, 0x00, 0x49, 0x8b,
00660   0x6e, 0xab, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x8a,
00661   0x33, 0x05, 0x4f, 0x8a, 0x33, 0x05, 0x00, 0x00,
00662   0x00, 0x00, 0x0a, 0xb5, 0x04, 0x01, 0x00, 0x23,
00663   0xc1, 0xde, 0xd0, 0x0d, 0x00, 0x00, 0x00, 0x00,
00664   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00665   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00666   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00667   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00668   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00669   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00670   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00671   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00672   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00673   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00674   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00675   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00676   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00677   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00678   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00679   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00680   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00681   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00682   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00683   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00684   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00685   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00686   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00687   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00688   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82,
00689   0x53, 0x63, 0x01, 0x04, 0xff, 0xff, 0xfe, 0x00,
00690   0x03, 0x04, 0x4f, 0x8a, 0x32, 0x01, 0x06, 0x08,
00691   0x4f, 0x8a, 0x00, 0xb4, 0x55, 0x08, 0x1f, 0xd1,
00692   0x1c, 0x04, 0x4f, 0x8a, 0x33, 0xff, 0x33, 0x04,
00693   0x00, 0x00, 0x54, 0x60, 0x35, 0x01, 0x05, 0x36,
00694   0x04, 0x0a, 0xb5, 0x04, 0x01, 0xff };
00695 
00696   const u8_t arp_resp[] = {
00697   0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d, /* DEST */
00698   0x00, 0x22, 0x93, 0x5a, 0xf7, 0x60, /* SRC */
00699   0x08, 0x06, /* Type: ARP */
00700   0x00, 0x01, /* HW: Ethernet */
00701   0x08, 0x00, /* PROTO: IP */
00702   0x06, /* HW size */
00703   0x04, /* PROTO size */
00704   0x00, 0x02, /* OPCODE: Reply */
00705 
00706   0x12, 0x34, 0x56, 0x78, 0x9a, 0xab, /* Target MAC */
00707   0x4f, 0x8a, 0x32, 0x01, /* Target IP */
00708 
00709   0x00, 0x23, 0xc1, 0x00, 0x06, 0x50, /* src mac */
00710   0x4f, 0x8a, 0x33, 0x05, /* src ip */
00711 
00712   /* Padding follows.. */
00713   0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00714   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00715   0x00, 0x00, 0x00, 0x00 };
00716 
00717   ip4_addr_t addr;
00718   ip4_addr_t netmask;
00719   ip4_addr_t gw;
00720   int i;
00721   u32_t xid;
00722   LWIP_UNUSED_ARG(_i);
00723 
00724   tcase = TEST_LWIP_DHCP_RELAY;
00725   setdebug(0);
00726 
00727   IP4_ADDR(&addr, 0, 0, 0, 0);
00728   IP4_ADDR(&netmask, 0, 0, 0, 0);
00729   IP4_ADDR(&gw, 0, 0, 0, 0);
00730 
00731   netif_add(&net_test, &addr, &netmask, &gw, &net_test, testif_init, ethernet_input);
00732   netif_set_up(&net_test);
00733 
00734   dhcp_start(&net_test);
00735 
00736   fail_unless(txpacket == 1); /* DHCP discover sent */
00737 
00738   /* IP addresses should be zero */
00739   fail_if(memcmp(&addr, &net_test.ip_addr, sizeof(ip4_addr_t)));
00740   fail_if(memcmp(&netmask, &net_test.netmask, sizeof(ip4_addr_t)));
00741   fail_if(memcmp(&gw, &net_test.gw, sizeof(ip4_addr_t)));
00742 
00743   fail_unless(txpacket == 1); /* Nothing more sent */
00744   xid = htonl(net_test.dhcp->xid);
00745   memcpy(&relay_offer[46], &xid, 4); /* insert correct transaction id */
00746   send_pkt(&net_test, relay_offer, sizeof(relay_offer));
00747 
00748   /* request sent? */
00749   fail_unless(txpacket == 2, "txpkt = %d, should be 2", txpacket);
00750   xid = htonl(net_test.dhcp->xid); /* xid updated */
00751   memcpy(&relay_ack1[46], &xid, 4); /* insert transaction id */
00752   send_pkt(&net_test, relay_ack1, sizeof(relay_ack1));
00753 
00754   for (i = 0; i < 25; i++) {
00755     tick_lwip();
00756   }
00757   fail_unless(txpacket == 5, "txpkt should be 5, is %d", txpacket); /* ARP requests sent */
00758 
00759   /* Interface up */
00760   fail_unless(netif_is_up(&net_test));
00761 
00762   /* Now it should have taken the IP */
00763   IP4_ADDR(&addr, 79, 138, 51, 5);
00764   IP4_ADDR(&netmask, 255, 255, 254, 0);
00765   IP4_ADDR(&gw, 79, 138, 50, 1);
00766   fail_if(memcmp(&addr, &net_test.ip_addr, sizeof(ip4_addr_t)));
00767   fail_if(memcmp(&netmask, &net_test.netmask, sizeof(ip4_addr_t)));
00768   fail_if(memcmp(&gw, &net_test.gw, sizeof(ip4_addr_t)));
00769 
00770   fail_unless(txpacket == 5, "txpacket = %d", txpacket);
00771 
00772   for (i = 0; i < 108000 - 25; i++) {
00773     tick_lwip();
00774   }
00775 
00776   fail_unless(netif_is_up(&net_test));
00777   fail_unless(txpacket == 6, "txpacket = %d", txpacket);
00778 
00779   /* We need to send arp response here.. */
00780 
00781   send_pkt(&net_test, arp_resp, sizeof(arp_resp));
00782 
00783   fail_unless(txpacket == 7, "txpacket = %d", txpacket);
00784   fail_unless(netif_is_up(&net_test));
00785 
00786   xid = htonl(net_test.dhcp->xid); /* xid updated */
00787   memcpy(&relay_ack2[46], &xid, 4); /* insert transaction id */
00788   send_pkt(&net_test, relay_ack2, sizeof(relay_ack2));
00789 
00790   for (i = 0; i < 100000; i++) {
00791     tick_lwip();
00792   }
00793 
00794   fail_unless(txpacket == 7, "txpacket = %d", txpacket);
00795 
00796   netif_remove(&net_test);
00797 
00798 }
00799 END_TEST
00800 
00801 START_TEST(test_dhcp_nak_no_endmarker)
00802 {
00803   ip4_addr_t addr;
00804   ip4_addr_t netmask;
00805   ip4_addr_t gw;
00806 
00807   u8_t dhcp_nack_no_endmarker[] = {
00808     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x54, 0x75,
00809     0xd0, 0x26, 0xd0, 0x0d, 0x08, 0x00, 0x45, 0x00,
00810     0x01, 0x15, 0x38, 0x86, 0x00, 0x00, 0xff, 0x11,
00811     0xc0, 0xa8, 0xc0, 0xa8, 0x01, 0x01, 0xff, 0xff,
00812     0xff, 0xff, 0x00, 0x43, 0x00, 0x44, 0x01, 0x01,
00813     0x00, 0x00, 0x02, 0x01, 0x06, 0x00, 0x7a, 0xcb,
00814     0xba, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00815     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00816     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23,
00817     0xc1, 0xde, 0xd0, 0x0d, 0x00, 0x00, 0x00, 0x00,
00818     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00819     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00820     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00821     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00822     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00823     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00824     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00825     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00826     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00827     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00828     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00829     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00830     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00831     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00832     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00833     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00834     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00835     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00836     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00837     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00838     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00839     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00840     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00841     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00842     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82,
00843     0x53, 0x63, 0x35, 0x01, 0x06, 0x36, 0x04, 0xc0,
00844     0xa8, 0x01, 0x01, 0x31, 0xef, 0xad, 0x72, 0x31,
00845     0x43, 0x4e, 0x44, 0x30, 0x32, 0x35, 0x30, 0x43,
00846     0x52, 0x47, 0x44, 0x38, 0x35, 0x36, 0x3c, 0x08,
00847     0x4d, 0x53, 0x46, 0x54, 0x20, 0x35, 0x2e, 0x30,
00848     0x37, 0x0d, 0x01, 0x0f, 0x03, 0x06, 0x2c, 0x2e,
00849     0x2f, 0x1f, 0x21, 0x79, 0xf9, 0x2b, 0xfc, 0xff,
00850     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x71,
00851     0xf3, 0x5b, 0xe2, 0x71, 0x2e, 0x01, 0x08, 0x03,
00852     0x04, 0xc0, 0xa8, 0x01, 0x01, 0xff, 0xeb, 0x1e,
00853     0x44, 0xec, 0xeb, 0x1e, 0x30, 0x37, 0x0c, 0x01,
00854     0x0f, 0x03, 0x06, 0x2c, 0x2e, 0x2f, 0x1f, 0x21,
00855     0x79, 0xf9, 0x2b, 0xff, 0x25, 0xc0, 0x09, 0xd6,
00856     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00857     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
00858   };
00859   u32_t xid;
00860   LWIP_UNUSED_ARG(_i);
00861 
00862   tcase = TEST_LWIP_DHCP_NAK_NO_ENDMARKER;
00863   setdebug(0);
00864 
00865   IP4_ADDR(&addr, 0, 0, 0, 0);
00866   IP4_ADDR(&netmask, 0, 0, 0, 0);
00867   IP4_ADDR(&gw, 0, 0, 0, 0);
00868 
00869   netif_add(&net_test, &addr, &netmask, &gw, &net_test, testif_init, ethernet_input);
00870   netif_set_up(&net_test);
00871 
00872   dhcp_start(&net_test);
00873 
00874   fail_unless(txpacket == 1); /* DHCP discover sent */
00875   xid = net_test.dhcp->xid; /* Write bad xid, not using htonl! */
00876   memcpy(&dhcp_offer[46], &xid, 4);
00877   send_pkt(&net_test, dhcp_offer, sizeof(dhcp_offer));
00878 
00879   /* IP addresses should be zero */
00880   fail_if(memcmp(&addr, &net_test.ip_addr, sizeof(ip4_addr_t)));
00881   fail_if(memcmp(&netmask, &net_test.netmask, sizeof(ip4_addr_t)));
00882   fail_if(memcmp(&gw, &net_test.gw, sizeof(ip4_addr_t)));
00883 
00884   fail_unless(txpacket == 1); /* Nothing more sent */
00885   xid = htonl(net_test.dhcp->xid);
00886   memcpy(&dhcp_offer[46], &xid, 4); /* insert correct transaction id */
00887   send_pkt(&net_test, dhcp_offer, sizeof(dhcp_offer));
00888   
00889   fail_unless(net_test.dhcp->state == DHCP_STATE_REQUESTING);
00890 
00891   fail_unless(txpacket == 2); /* No more sent */
00892   xid = htonl(net_test.dhcp->xid); /* xid updated */
00893   memcpy(&dhcp_nack_no_endmarker[46], &xid, 4); /* insert transaction id */
00894   send_pkt(&net_test, dhcp_nack_no_endmarker, sizeof(dhcp_nack_no_endmarker));
00895 
00896   /* NAK should put us in another state for a while, no other way detecting it */
00897   fail_unless(net_test.dhcp->state != DHCP_STATE_REQUESTING);
00898 
00899   netif_remove(&net_test);
00900 }
00901 END_TEST
00902 
00903 
00904 /** Create the suite including all tests for this module */
00905 Suite *
00906 dhcp_suite(void)
00907 {
00908   testfunc tests[] = {
00909     TESTFUNC(test_dhcp),
00910     TESTFUNC(test_dhcp_nak),
00911     TESTFUNC(test_dhcp_relayed),
00912     TESTFUNC(test_dhcp_nak_no_endmarker)
00913   };
00914   return create_suite("DHCP", tests, sizeof(tests)/sizeof(testfunc), dhcp_setup, dhcp_teardown);
00915 }