mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-08-23 22:56:00 +00:00
Add unit tests for DHCP
Three simple tests that test the basic functionality of the DHCP client. They require that UDP checksums are off for now.
This commit is contained in:
parent
c622985fda
commit
679d3fd5b3
789
test/unit/dhcp/test_dhcp.c
Normal file
789
test/unit/dhcp/test_dhcp.c
Normal file
|
@ -0,0 +1,789 @@
|
||||||
|
#include "test_dhcp.h"
|
||||||
|
|
||||||
|
#include "lwip/netif.h"
|
||||||
|
#include "lwip/dhcp.h"
|
||||||
|
#include "netif/etharp.h"
|
||||||
|
|
||||||
|
struct netif net_test;
|
||||||
|
|
||||||
|
static u8_t broadcast[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||||
|
|
||||||
|
static u8_t magic_cookie[] = { 0x63, 0x82, 0x53, 0x63 };
|
||||||
|
|
||||||
|
static u8_t dhcp_offer[] = {
|
||||||
|
0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d, // To unit
|
||||||
|
0x00, 0x0F, 0xEE, 0x30, 0xAB, 0x22, // From Remote host
|
||||||
|
0x08, 0x00, // Protocol: IP
|
||||||
|
0x45, 0x10, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, 0x36, 0xcc, 0xc3, 0xaa, 0xbd, 0xab, 0xc3, 0xaa, 0xbd, 0xc8, // IP header
|
||||||
|
0x00, 0x43, 0x00, 0x44, 0x01, 0x34, 0x6a, 0xa9, // UDP header
|
||||||
|
|
||||||
|
0x02, // Type == Boot reply
|
||||||
|
0x01, 0x06, // Hw Ethernet, 6 bytes addrlen
|
||||||
|
0x00, // 0 hops
|
||||||
|
0xAA, 0xAA, 0xAA, 0xAA, // Transaction id, will be overwritten
|
||||||
|
0x00, 0x00, // 0 seconds elapsed
|
||||||
|
0x00, 0x00, // Flags (unicast)
|
||||||
|
0x00, 0x00, 0x00, 0x00, // Client ip
|
||||||
|
0xc3, 0xaa, 0xbd, 0xc8, // Your IP
|
||||||
|
0xc3, 0xaa, 0xbd, 0xab, // DHCP server ip
|
||||||
|
0x00, 0x00, 0x00, 0x00, // relay agent
|
||||||
|
0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // MAC addr + padding
|
||||||
|
|
||||||
|
// Empty server name and boot file name
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00,
|
||||||
|
|
||||||
|
0x63, 0x82, 0x53, 0x63, // Magic cookie
|
||||||
|
0x35, 0x01, 0x02, // Message type: Offer
|
||||||
|
0x36, 0x04, 0xc3, 0xaa, 0xbd, 0xab, // Server identifier (IP)
|
||||||
|
0x33, 0x04, 0x00, 0x00, 0x00, 0x78, // Lease time 2 minutes
|
||||||
|
0x03, 0x04, 0xc3, 0xaa, 0xbd, 0xab, // Router IP
|
||||||
|
0x01, 0x04, 0xff, 0xff, 0xff, 0x00, // Subnet mask
|
||||||
|
0xff, // End option
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Padding
|
||||||
|
};
|
||||||
|
|
||||||
|
static u8_t dhcp_ack[] = {
|
||||||
|
0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d, // To unit
|
||||||
|
0x00, 0x0f, 0xEE, 0x30, 0xAB, 0x22, // From remote host
|
||||||
|
0x08, 0x00, // Proto IP
|
||||||
|
0x45, 0x10, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, 0x36, 0xcc, 0xc3, 0xaa, 0xbd, 0xab, 0xc3, 0xaa, 0xbd, 0xc8, // IP header
|
||||||
|
0x00, 0x43, 0x00, 0x44, 0x01, 0x34, 0x67, 0xa8, // UDP header
|
||||||
|
0x02, // Bootp reply
|
||||||
|
0x01, 0x06, // Hw type Eth, len 6
|
||||||
|
0x00, // 0 hops
|
||||||
|
0xAA, 0xAA, 0xAA, 0xAA,
|
||||||
|
0x00, 0x00, // 0 seconds elapsed
|
||||||
|
0x00, 0x00, // Flags (unicast)
|
||||||
|
0x00, 0x00, 0x00, 0x00, // Client IP
|
||||||
|
0xc3, 0xaa, 0xbd, 0xc8, // Your IP
|
||||||
|
0xc3, 0xaa, 0xbd, 0xab, // DHCP server IP
|
||||||
|
0x00, 0x00, 0x00, 0x00, // Relay agent
|
||||||
|
0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Macaddr + padding
|
||||||
|
|
||||||
|
// Empty server name and boot file name
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00,
|
||||||
|
|
||||||
|
0x63, 0x82, 0x53, 0x63, // Magic cookie
|
||||||
|
0x35, 0x01, 0x05, // Dhcp message type ack
|
||||||
|
0x36, 0x04, 0xc3, 0xaa, 0xbd, 0xab, // DHCP server identifier
|
||||||
|
0x33, 0x04, 0x00, 0x00, 0x00, 0x78, // Lease time 2 minutes
|
||||||
|
0x03, 0x04, 0xc3, 0xaa, 0xbd, 0xab, // Router IP
|
||||||
|
0x01, 0x04, 0xff, 0xff, 0xff, 0x00, // Netmask
|
||||||
|
0xff, // End marker
|
||||||
|
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Padding
|
||||||
|
};
|
||||||
|
|
||||||
|
static u8_t arpreply[] = {
|
||||||
|
0x00, 0x23, 0xC1, 0xDE, 0xD0, 0x0D, // dst mac
|
||||||
|
0x00, 0x32, 0x44, 0x20, 0x01, 0x02, // src mac
|
||||||
|
0x08, 0x06, // proto arp
|
||||||
|
0x00, 0x01, // hw eth
|
||||||
|
0x08, 0x00, // proto ip
|
||||||
|
0x06, // hw addr len 6
|
||||||
|
0x04, // proto addr len 4
|
||||||
|
0x00, 0x02, // arp reply
|
||||||
|
0x00, 0x32, 0x44, 0x20, 0x01, 0x02, // sender mac
|
||||||
|
0xc3, 0xaa, 0xbd, 0xc8, // sender ip
|
||||||
|
0x00, 0x23, 0xC1, 0xDE, 0xD0, 0x0D, // target mac
|
||||||
|
0x00, 0x00, 0x00, 0x00, // target ip
|
||||||
|
};
|
||||||
|
|
||||||
|
static int txpacket;
|
||||||
|
static enum tcase {
|
||||||
|
TEST_LWIP_DHCP,
|
||||||
|
TEST_LWIP_DHCP_NAK,
|
||||||
|
TEST_LWIP_DHCP_RELAY,
|
||||||
|
} tcase;
|
||||||
|
|
||||||
|
static int debug = 0;
|
||||||
|
static void setdebug(int a) {debug = a;}
|
||||||
|
|
||||||
|
static int tick = 0;
|
||||||
|
static void tick_lwip()
|
||||||
|
{
|
||||||
|
tick++;
|
||||||
|
if (tick % 5 == 0) {
|
||||||
|
dhcp_fine_tmr();
|
||||||
|
}
|
||||||
|
if (tick % 600 == 0) {
|
||||||
|
dhcp_coarse_tmr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void send_pkt(struct netif *netif, u8_t *data, u32_t len)
|
||||||
|
{
|
||||||
|
struct pbuf *p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
|
||||||
|
struct pbuf *q;
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
// Dump data
|
||||||
|
u32_t i;
|
||||||
|
printf("RX data (len %d)", p->tot_len);
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
printf(" %02X", data[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
fail_unless(p != NULL);
|
||||||
|
for(q = p; q != NULL; q = q->next) {
|
||||||
|
memcpy(q->payload, data, q->len);
|
||||||
|
data += q->len;
|
||||||
|
}
|
||||||
|
netif->input(p, netif);
|
||||||
|
}
|
||||||
|
|
||||||
|
static err_t lwip_tx_func(struct netif *netif, struct pbuf *p);
|
||||||
|
|
||||||
|
static err_t testif_init(struct netif *netif)
|
||||||
|
{
|
||||||
|
netif->name[0] = 'c';
|
||||||
|
netif->name[1] = 'h';
|
||||||
|
netif->output = etharp_output;
|
||||||
|
netif->linkoutput = lwip_tx_func;
|
||||||
|
netif->mtu = 1500;
|
||||||
|
netif->hwaddr_len = 6;
|
||||||
|
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
|
||||||
|
|
||||||
|
netif->hwaddr[0] = 0x00;
|
||||||
|
netif->hwaddr[1] = 0x23;
|
||||||
|
netif->hwaddr[2] = 0xC1;
|
||||||
|
netif->hwaddr[3] = 0xDE;
|
||||||
|
netif->hwaddr[4] = 0xD0;
|
||||||
|
netif->hwaddr[5] = 0x0D;
|
||||||
|
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dhcp_setup()
|
||||||
|
{
|
||||||
|
txpacket = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dhcp_teardown()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void check_pkt(struct pbuf *p, u32_t pos, u8_t *mem, u32_t len)
|
||||||
|
{
|
||||||
|
fail_if((pos + len) > p->tot_len);
|
||||||
|
while (pos > p->len && p->next) {
|
||||||
|
pos -= p->len;
|
||||||
|
p = p->next;
|
||||||
|
}
|
||||||
|
fail_if(p == NULL);
|
||||||
|
fail_unless(pos + len <= p->len); // All data we seek within same pbuf
|
||||||
|
|
||||||
|
u8_t *data = p->payload;
|
||||||
|
fail_if(memcmp(&data[pos], mem, len), "data at pos %d, len %d in packet %d did not match", pos, len, txpacket);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void check_pkt_fuzzy(struct pbuf *p, u32_t startpos, u8_t *mem, u32_t len)
|
||||||
|
{
|
||||||
|
fail_if((startpos + len) > p->tot_len);
|
||||||
|
while (startpos > p->len && p->next) {
|
||||||
|
startpos -= p->len;
|
||||||
|
p = p->next;
|
||||||
|
}
|
||||||
|
fail_if(p == NULL);
|
||||||
|
fail_unless(startpos + len <= p->len); // All data we seek within same pbuf
|
||||||
|
|
||||||
|
int found = 0;
|
||||||
|
u32_t i;
|
||||||
|
u8_t *data = p->payload;
|
||||||
|
for (i = startpos; i <= (p->len - len); i++) {
|
||||||
|
if (memcmp(&data[i], mem, len) == 0) {
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fail_unless(found);
|
||||||
|
}
|
||||||
|
|
||||||
|
static err_t lwip_tx_func(struct netif *netif, struct pbuf *p)
|
||||||
|
{
|
||||||
|
fail_unless(netif == &net_test);
|
||||||
|
txpacket++;
|
||||||
|
|
||||||
|
if (debug) {
|
||||||
|
// Dump data
|
||||||
|
printf("TX data (pkt %d, len %d, tick %d)", txpacket, p->tot_len, tick);
|
||||||
|
struct pbuf *pp = p;
|
||||||
|
do {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < pp->len; i++) {
|
||||||
|
printf(" %02X", ((u8_t *) pp->payload)[i]);
|
||||||
|
}
|
||||||
|
if (pp->next) {
|
||||||
|
pp = pp->next;
|
||||||
|
}
|
||||||
|
} while (pp->next);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (tcase) {
|
||||||
|
case TEST_LWIP_DHCP:
|
||||||
|
switch (txpacket) {
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
check_pkt(p, 0, broadcast, 6); // eth level dest: broadcast
|
||||||
|
check_pkt(p, 6, netif->hwaddr, 6); // eth level src: unit mac
|
||||||
|
|
||||||
|
u8_t ipproto[] = { 0x08, 0x00 };
|
||||||
|
check_pkt(p, 12, ipproto, sizeof(ipproto)); // eth level proto: ip
|
||||||
|
|
||||||
|
u8_t bootp_start[] = { 0x01, 0x01, 0x06, 0x00}; // bootp request, eth, hwaddr len 6, 0 hops
|
||||||
|
check_pkt(p, 42, bootp_start, sizeof(bootp_start));
|
||||||
|
|
||||||
|
u8_t ipaddrs[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
|
check_pkt(p, 53, ipaddrs, sizeof(ipaddrs));
|
||||||
|
|
||||||
|
check_pkt(p, 70, netif->hwaddr, 6); // mac addr inside bootp
|
||||||
|
|
||||||
|
check_pkt(p, 278, magic_cookie, sizeof(magic_cookie));
|
||||||
|
|
||||||
|
// Check dchp message type, can be at different positions
|
||||||
|
if (txpacket == 1) {
|
||||||
|
u8_t dhcp_discover_opt[] = { 0x35, 0x01, 0x01 };
|
||||||
|
check_pkt_fuzzy(p, 282, dhcp_discover_opt, sizeof(dhcp_discover_opt));
|
||||||
|
} else if (txpacket == 2) {
|
||||||
|
u8_t dhcp_request_opt[] = { 0x35, 0x01, 0x03 };
|
||||||
|
check_pkt_fuzzy(p, 282, dhcp_request_opt, sizeof(dhcp_request_opt));
|
||||||
|
|
||||||
|
u8_t requested_ipaddr[] = { 0x32, 0x04, 0xc3, 0xaa, 0xbd, 0xc8 }; // Ask for offered IP
|
||||||
|
check_pkt_fuzzy(p, 282, requested_ipaddr, sizeof(requested_ipaddr));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 3:
|
||||||
|
case 4:
|
||||||
|
case 5:
|
||||||
|
{
|
||||||
|
check_pkt(p, 0, broadcast, 6); // eth level dest: broadcast
|
||||||
|
check_pkt(p, 6, netif->hwaddr, 6); // eth level src: unit mac
|
||||||
|
|
||||||
|
u8_t arpproto[] = { 0x08, 0x06 };
|
||||||
|
check_pkt(p, 12, arpproto, sizeof(arpproto)); // eth level proto: ip
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TEST_LWIP_DHCP_NAK:
|
||||||
|
{
|
||||||
|
fail_unless(txpacket == 4);
|
||||||
|
check_pkt(p, 0, broadcast, 6); // eth level dest: broadcast
|
||||||
|
check_pkt(p, 6, netif->hwaddr, 6); // eth level src: unit mac
|
||||||
|
|
||||||
|
u8_t ipproto[] = { 0x08, 0x00 };
|
||||||
|
check_pkt(p, 12, ipproto, sizeof(ipproto)); // eth level proto: ip
|
||||||
|
|
||||||
|
u8_t bootp_start[] = { 0x01, 0x01, 0x06, 0x00}; // bootp request, eth, hwaddr len 6, 0 hops
|
||||||
|
check_pkt(p, 42, bootp_start, sizeof(bootp_start));
|
||||||
|
|
||||||
|
u8_t ipaddrs[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
|
check_pkt(p, 53, ipaddrs, sizeof(ipaddrs));
|
||||||
|
|
||||||
|
check_pkt(p, 70, netif->hwaddr, 6); // mac addr inside bootp
|
||||||
|
|
||||||
|
check_pkt(p, 278, magic_cookie, sizeof(magic_cookie));
|
||||||
|
|
||||||
|
u8_t dhcp_nak_opt[] = { 0x35, 0x01, 0x04 };
|
||||||
|
check_pkt_fuzzy(p, 282, dhcp_nak_opt, sizeof(dhcp_nak_opt)); // NAK the ack
|
||||||
|
|
||||||
|
u8_t requested_ipaddr[] = { 0x32, 0x04, 0xc3, 0xaa, 0xbd, 0xc8 }; // offered IP
|
||||||
|
check_pkt_fuzzy(p, 282, requested_ipaddr, sizeof(requested_ipaddr));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case TEST_LWIP_DHCP_RELAY:
|
||||||
|
switch (txpacket) {
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
check_pkt(p, 0, broadcast, 6); // eth level dest: broadcast
|
||||||
|
check_pkt(p, 6, netif->hwaddr, 6); // eth level src: unit mac
|
||||||
|
|
||||||
|
u8_t ipproto[] = { 0x08, 0x00 };
|
||||||
|
check_pkt(p, 12, ipproto, sizeof(ipproto)); // eth level proto: ip
|
||||||
|
|
||||||
|
u8_t bootp_start[] = { 0x01, 0x01, 0x06, 0x00}; // bootp request, eth, hwaddr len 6, 0 hops
|
||||||
|
check_pkt(p, 42, bootp_start, sizeof(bootp_start));
|
||||||
|
|
||||||
|
u8_t ipaddrs[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
|
check_pkt(p, 53, ipaddrs, sizeof(ipaddrs));
|
||||||
|
|
||||||
|
check_pkt(p, 70, netif->hwaddr, 6); // mac addr inside bootp
|
||||||
|
|
||||||
|
check_pkt(p, 278, magic_cookie, sizeof(magic_cookie));
|
||||||
|
|
||||||
|
// Check dchp message type, can be at different positions
|
||||||
|
if (txpacket == 1) {
|
||||||
|
u8_t dhcp_discover_opt[] = { 0x35, 0x01, 0x01 };
|
||||||
|
check_pkt_fuzzy(p, 282, dhcp_discover_opt, sizeof(dhcp_discover_opt));
|
||||||
|
} else if (txpacket == 2) {
|
||||||
|
u8_t dhcp_request_opt[] = { 0x35, 0x01, 0x03 };
|
||||||
|
check_pkt_fuzzy(p, 282, dhcp_request_opt, sizeof(dhcp_request_opt));
|
||||||
|
|
||||||
|
u8_t requested_ipaddr[] = { 0x32, 0x04, 0x4f, 0x8a, 0x33, 0x05 }; // Ask for offered IP
|
||||||
|
check_pkt_fuzzy(p, 282, requested_ipaddr, sizeof(requested_ipaddr));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 3:
|
||||||
|
case 4:
|
||||||
|
case 5:
|
||||||
|
{
|
||||||
|
check_pkt(p, 0, broadcast, 6); // eth level dest: broadcast
|
||||||
|
check_pkt(p, 6, netif->hwaddr, 6); // eth level src: unit mac
|
||||||
|
|
||||||
|
u8_t arpproto[] = { 0x08, 0x06 };
|
||||||
|
check_pkt(p, 12, arpproto, sizeof(arpproto)); // eth level proto: ip
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 6:
|
||||||
|
{
|
||||||
|
u8_t fake_arp[6] = { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xab };
|
||||||
|
check_pkt(p, 0, fake_arp, 6); // eth level dest: broadcast
|
||||||
|
check_pkt(p, 6, netif->hwaddr, 6); // eth level src: unit mac
|
||||||
|
|
||||||
|
u8_t ipproto[] = { 0x08, 0x00 };
|
||||||
|
check_pkt(p, 12, ipproto, sizeof(ipproto)); // eth level proto: ip
|
||||||
|
|
||||||
|
u8_t bootp_start[] = { 0x01, 0x01, 0x06, 0x00}; // bootp request, eth, hwaddr len 6, 0 hops
|
||||||
|
check_pkt(p, 42, bootp_start, sizeof(bootp_start));
|
||||||
|
|
||||||
|
u8_t ipaddrs[] = { 0x00, 0x4f, 0x8a, 0x33, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
|
check_pkt(p, 53, ipaddrs, sizeof(ipaddrs));
|
||||||
|
|
||||||
|
check_pkt(p, 70, netif->hwaddr, 6); // mac addr inside bootp
|
||||||
|
|
||||||
|
check_pkt(p, 278, magic_cookie, sizeof(magic_cookie));
|
||||||
|
|
||||||
|
// Check dchp message type, can be at different positions
|
||||||
|
u8_t dhcp_request_opt[] = { 0x35, 0x01, 0x03 };
|
||||||
|
check_pkt_fuzzy(p, 282, dhcp_request_opt, sizeof(dhcp_request_opt));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test basic happy flow DHCP session.
|
||||||
|
* Validate that xid is checked.
|
||||||
|
*/
|
||||||
|
START_TEST(test_dhcp)
|
||||||
|
{
|
||||||
|
struct ip_addr addr;
|
||||||
|
struct ip_addr netmask;
|
||||||
|
struct ip_addr gw;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
tcase = TEST_LWIP_DHCP;
|
||||||
|
setdebug(0);
|
||||||
|
|
||||||
|
IP4_ADDR(&addr, 0, 0, 0, 0);
|
||||||
|
IP4_ADDR(&netmask, 0, 0, 0, 0);
|
||||||
|
IP4_ADDR(&gw, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
netif_add(&net_test, &addr, &netmask, &gw, &net_test, testif_init, ethernet_input);
|
||||||
|
|
||||||
|
dhcp_start(&net_test);
|
||||||
|
|
||||||
|
fail_unless(txpacket == 1); // DHCP discover sent
|
||||||
|
u32_t xid = net_test.dhcp->xid; // Write bad xid, not using htonl!
|
||||||
|
memcpy(&dhcp_offer[46], &xid, 4);
|
||||||
|
send_pkt(&net_test, dhcp_offer, sizeof(dhcp_offer));
|
||||||
|
|
||||||
|
// Interface down
|
||||||
|
fail_if(netif_is_up(&net_test));
|
||||||
|
|
||||||
|
// IP addresses should be zero
|
||||||
|
fail_if(memcmp(&addr, &net_test.ip_addr, sizeof(struct ip_addr)));
|
||||||
|
fail_if(memcmp(&netmask, &net_test.netmask, sizeof(struct ip_addr)));
|
||||||
|
fail_if(memcmp(&gw, &net_test.gw, sizeof(struct ip_addr)));
|
||||||
|
|
||||||
|
fail_unless(txpacket == 1, "TX %d packets, expected 1", txpacket); // Nothing more sent
|
||||||
|
xid = htonl(net_test.dhcp->xid);
|
||||||
|
memcpy(&dhcp_offer[46], &xid, 4); // insert correct transaction id
|
||||||
|
send_pkt(&net_test, dhcp_offer, sizeof(dhcp_offer));
|
||||||
|
|
||||||
|
fail_unless(txpacket == 2, "TX %d packets, expected 2", txpacket); // DHCP request sent
|
||||||
|
xid = net_test.dhcp->xid; // Write bad xid, not using htonl!
|
||||||
|
memcpy(&dhcp_ack[46], &xid, 4);
|
||||||
|
send_pkt(&net_test, dhcp_ack, sizeof(dhcp_ack));
|
||||||
|
|
||||||
|
fail_unless(txpacket == 2, "TX %d packets, still expected 2", txpacket); // No more sent
|
||||||
|
xid = htonl(net_test.dhcp->xid); // xid updated
|
||||||
|
memcpy(&dhcp_ack[46], &xid, 4); // insert transaction id
|
||||||
|
send_pkt(&net_test, dhcp_ack, sizeof(dhcp_ack));
|
||||||
|
|
||||||
|
for (i = 0; i < 20; i++)
|
||||||
|
tick_lwip();
|
||||||
|
fail_unless(txpacket == 4, "TX %d packets, expected 4", txpacket); // ARP requests sent
|
||||||
|
|
||||||
|
// Interface up
|
||||||
|
fail_unless(netif_is_up(&net_test));
|
||||||
|
|
||||||
|
// Now it should have taken the IP
|
||||||
|
IP4_ADDR(&addr, 195, 170, 189, 200);
|
||||||
|
IP4_ADDR(&netmask, 255, 255, 255, 0);
|
||||||
|
IP4_ADDR(&gw, 195, 170, 189, 171);
|
||||||
|
fail_if(memcmp(&addr, &net_test.ip_addr, sizeof(struct ip_addr)));
|
||||||
|
fail_if(memcmp(&netmask, &net_test.netmask, sizeof(struct ip_addr)));
|
||||||
|
fail_if(memcmp(&gw, &net_test.gw, sizeof(struct ip_addr)));
|
||||||
|
|
||||||
|
netif_remove(&net_test);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test that IP address is not taken and NAK is sent if someone
|
||||||
|
* replies to ARP requests for the offered address.
|
||||||
|
*/
|
||||||
|
START_TEST(test_dhcp_nak)
|
||||||
|
{
|
||||||
|
struct ip_addr addr;
|
||||||
|
struct ip_addr netmask;
|
||||||
|
struct ip_addr gw;
|
||||||
|
|
||||||
|
tcase = TEST_LWIP_DHCP;
|
||||||
|
setdebug(0);
|
||||||
|
|
||||||
|
IP4_ADDR(&addr, 0, 0, 0, 0);
|
||||||
|
IP4_ADDR(&netmask, 0, 0, 0, 0);
|
||||||
|
IP4_ADDR(&gw, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
netif_add(&net_test, &addr, &netmask, &gw, &net_test, testif_init, ethernet_input);
|
||||||
|
|
||||||
|
dhcp_start(&net_test);
|
||||||
|
|
||||||
|
fail_unless(txpacket == 1); // DHCP discover sent
|
||||||
|
u32_t xid = net_test.dhcp->xid; // Write bad xid, not using htonl!
|
||||||
|
memcpy(&dhcp_offer[46], &xid, 4);
|
||||||
|
send_pkt(&net_test, dhcp_offer, sizeof(dhcp_offer));
|
||||||
|
|
||||||
|
// Interface down
|
||||||
|
fail_if(netif_is_up(&net_test));
|
||||||
|
|
||||||
|
// IP addresses should be zero
|
||||||
|
fail_if(memcmp(&addr, &net_test.ip_addr, sizeof(struct ip_addr)));
|
||||||
|
fail_if(memcmp(&netmask, &net_test.netmask, sizeof(struct ip_addr)));
|
||||||
|
fail_if(memcmp(&gw, &net_test.gw, sizeof(struct ip_addr)));
|
||||||
|
|
||||||
|
fail_unless(txpacket == 1); // Nothing more sent
|
||||||
|
xid = htonl(net_test.dhcp->xid);
|
||||||
|
memcpy(&dhcp_offer[46], &xid, 4); // insert correct transaction id
|
||||||
|
send_pkt(&net_test, dhcp_offer, sizeof(dhcp_offer));
|
||||||
|
|
||||||
|
fail_unless(txpacket == 2); // DHCP request sent
|
||||||
|
xid = net_test.dhcp->xid; // Write bad xid, not using htonl!
|
||||||
|
memcpy(&dhcp_ack[46], &xid, 4);
|
||||||
|
send_pkt(&net_test, dhcp_ack, sizeof(dhcp_ack));
|
||||||
|
|
||||||
|
fail_unless(txpacket == 2); // No more sent
|
||||||
|
xid = htonl(net_test.dhcp->xid); // xid updated
|
||||||
|
memcpy(&dhcp_ack[46], &xid, 4); // insert transaction id
|
||||||
|
send_pkt(&net_test, dhcp_ack, sizeof(dhcp_ack));
|
||||||
|
|
||||||
|
fail_unless(txpacket == 3); // ARP request sent
|
||||||
|
|
||||||
|
tcase = TEST_LWIP_DHCP_NAK; // Switch testcase
|
||||||
|
|
||||||
|
// Send arp reply, mark offered IP as taken
|
||||||
|
send_pkt(&net_test, arpreply, sizeof(arpreply));
|
||||||
|
|
||||||
|
fail_unless(txpacket == 4); // DHCP nak sent
|
||||||
|
|
||||||
|
netif_remove(&net_test);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test case based on captured data where
|
||||||
|
* replies are sent from a different IP than the
|
||||||
|
* one the client unicasted to.
|
||||||
|
*/
|
||||||
|
START_TEST(test_dhcp_relayed)
|
||||||
|
{
|
||||||
|
u8_t relay_offer[] = {
|
||||||
|
0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d,
|
||||||
|
0x00, 0x22, 0x93, 0x5a, 0xf7, 0x60,
|
||||||
|
0x08, 0x00, 0x45, 0x00,
|
||||||
|
0x01, 0x38, 0xfd, 0x53, 0x00, 0x00, 0x40, 0x11,
|
||||||
|
0x78, 0x46, 0x4f, 0x8a, 0x32, 0x02, 0x4f, 0x8a,
|
||||||
|
0x33, 0x05, 0x00, 0x43, 0x00, 0x44, 0x01, 0x24,
|
||||||
|
0x38, 0x72, 0x02, 0x01, 0x06, 0x00, 0x51, 0x35,
|
||||||
|
0xb6, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x4f, 0x8a, 0x33, 0x05, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x0a, 0xb5, 0x04, 0x01, 0x00, 0x23,
|
||||||
|
0xc1, 0xde, 0xd0, 0x0d, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82,
|
||||||
|
0x53, 0x63, 0x01, 0x04, 0xff, 0xff, 0xfe, 0x00,
|
||||||
|
0x03, 0x04, 0x4f, 0x8a, 0x32, 0x01, 0x06, 0x08,
|
||||||
|
0x4f, 0x8a, 0x00, 0xb4, 0x55, 0x08, 0x1f, 0xd1,
|
||||||
|
0x1c, 0x04, 0x4f, 0x8a, 0x33, 0xff, 0x33, 0x04,
|
||||||
|
0x00, 0x00, 0x54, 0x49, 0x35, 0x01, 0x02, 0x36,
|
||||||
|
0x04, 0x0a, 0xb5, 0x04, 0x01, 0xff
|
||||||
|
};
|
||||||
|
|
||||||
|
u8_t relay_ack1[] = {
|
||||||
|
0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d, 0x00, 0x22,
|
||||||
|
0x93, 0x5a, 0xf7, 0x60, 0x08, 0x00, 0x45, 0x00,
|
||||||
|
0x01, 0x38, 0xfd, 0x55, 0x00, 0x00, 0x40, 0x11,
|
||||||
|
0x78, 0x44, 0x4f, 0x8a, 0x32, 0x02, 0x4f, 0x8a,
|
||||||
|
0x33, 0x05, 0x00, 0x43, 0x00, 0x44, 0x01, 0x24,
|
||||||
|
0x35, 0x71, 0x02, 0x01, 0x06, 0x00, 0x51, 0x35,
|
||||||
|
0xb6, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x4f, 0x8a, 0x33, 0x05, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x0a, 0xb5, 0x04, 0x01, 0x00, 0x23,
|
||||||
|
0xc1, 0xde, 0xd0, 0x0d, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82,
|
||||||
|
0x53, 0x63, 0x01, 0x04, 0xff, 0xff, 0xfe, 0x00,
|
||||||
|
0x03, 0x04, 0x4f, 0x8a, 0x32, 0x01, 0x06, 0x08,
|
||||||
|
0x4f, 0x8a, 0x00, 0xb4, 0x55, 0x08, 0x1f, 0xd1,
|
||||||
|
0x1c, 0x04, 0x4f, 0x8a, 0x33, 0xff, 0x33, 0x04,
|
||||||
|
0x00, 0x00, 0x54, 0x49, 0x35, 0x01, 0x05, 0x36,
|
||||||
|
0x04, 0x0a, 0xb5, 0x04, 0x01, 0xff
|
||||||
|
};
|
||||||
|
|
||||||
|
u8_t relay_ack2[] = {
|
||||||
|
0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d,
|
||||||
|
0x00, 0x22, 0x93, 0x5a, 0xf7, 0x60,
|
||||||
|
0x08, 0x00, 0x45, 0x00,
|
||||||
|
0x01, 0x38, 0xfa, 0x18, 0x00, 0x00, 0x40, 0x11,
|
||||||
|
0x7b, 0x81, 0x4f, 0x8a, 0x32, 0x02, 0x4f, 0x8a,
|
||||||
|
0x33, 0x05, 0x00, 0x43, 0x00, 0x44, 0x01, 0x24,
|
||||||
|
0x02, 0x6b, 0x02, 0x01, 0x06, 0x00, 0x49, 0x8b,
|
||||||
|
0x6e, 0xab, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x8a,
|
||||||
|
0x33, 0x05, 0x4f, 0x8a, 0x33, 0x05, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x0a, 0xb5, 0x04, 0x01, 0x00, 0x23,
|
||||||
|
0xc1, 0xde, 0xd0, 0x0d, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82,
|
||||||
|
0x53, 0x63, 0x01, 0x04, 0xff, 0xff, 0xfe, 0x00,
|
||||||
|
0x03, 0x04, 0x4f, 0x8a, 0x32, 0x01, 0x06, 0x08,
|
||||||
|
0x4f, 0x8a, 0x00, 0xb4, 0x55, 0x08, 0x1f, 0xd1,
|
||||||
|
0x1c, 0x04, 0x4f, 0x8a, 0x33, 0xff, 0x33, 0x04,
|
||||||
|
0x00, 0x00, 0x54, 0x60, 0x35, 0x01, 0x05, 0x36,
|
||||||
|
0x04, 0x0a, 0xb5, 0x04, 0x01, 0xff };
|
||||||
|
|
||||||
|
u8_t arp_resp[] = {
|
||||||
|
0x00, 0x23, 0xc1, 0xde, 0xd0, 0x0d, // DEST
|
||||||
|
0x00, 0x22, 0x93, 0x5a, 0xf7, 0x60, // SRC
|
||||||
|
0x08, 0x06, // Type: ARP
|
||||||
|
0x00, 0x01, // HW: Ethernet
|
||||||
|
0x08, 0x00, // PROTO: IP
|
||||||
|
0x06, // HW size
|
||||||
|
0x04, // PROTO size
|
||||||
|
0x00, 0x02, // OPCODE: Reply
|
||||||
|
|
||||||
|
0x12, 0x34, 0x56, 0x78, 0x9a, 0xab, // Target MAC
|
||||||
|
0x4f, 0x8a, 0x32, 0x01, // Target IP
|
||||||
|
|
||||||
|
0x00, 0x23, 0xc1, 0x00, 0x06, 0x50, // src mac
|
||||||
|
0x4f, 0x8a, 0x33, 0x05, // src ip
|
||||||
|
|
||||||
|
// Padding follows..
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00 };
|
||||||
|
|
||||||
|
struct ip_addr addr;
|
||||||
|
struct ip_addr netmask;
|
||||||
|
struct ip_addr gw;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
tcase = TEST_LWIP_DHCP_RELAY;
|
||||||
|
setdebug(0);
|
||||||
|
|
||||||
|
IP4_ADDR(&addr, 0, 0, 0, 0);
|
||||||
|
IP4_ADDR(&netmask, 0, 0, 0, 0);
|
||||||
|
IP4_ADDR(&gw, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
netif_add(&net_test, &addr, &netmask, &gw, &net_test, testif_init, ethernet_input);
|
||||||
|
|
||||||
|
dhcp_start(&net_test);
|
||||||
|
|
||||||
|
fail_unless(txpacket == 1); // DHCP discover sent
|
||||||
|
|
||||||
|
// Interface down
|
||||||
|
fail_if(netif_is_up(&net_test));
|
||||||
|
|
||||||
|
// IP addresses should be zero
|
||||||
|
fail_if(memcmp(&addr, &net_test.ip_addr, sizeof(struct ip_addr)));
|
||||||
|
fail_if(memcmp(&netmask, &net_test.netmask, sizeof(struct ip_addr)));
|
||||||
|
fail_if(memcmp(&gw, &net_test.gw, sizeof(struct ip_addr)));
|
||||||
|
|
||||||
|
fail_unless(txpacket == 1); // Nothing more sent
|
||||||
|
u32_t xid = htonl(net_test.dhcp->xid);
|
||||||
|
memcpy(&relay_offer[46], &xid, 4); // insert correct transaction id
|
||||||
|
send_pkt(&net_test, relay_offer, sizeof(relay_offer));
|
||||||
|
|
||||||
|
// request sent?
|
||||||
|
fail_unless(txpacket == 2, "txpkt = %d, should be 2", txpacket);
|
||||||
|
xid = htonl(net_test.dhcp->xid); // xid updated
|
||||||
|
memcpy(&relay_ack1[46], &xid, 4); // insert transaction id
|
||||||
|
send_pkt(&net_test, relay_ack1, sizeof(relay_ack1));
|
||||||
|
|
||||||
|
for (i = 0; i < 25; i++)
|
||||||
|
tick_lwip();
|
||||||
|
fail_unless(txpacket == 4, "txpkt should be 5, is %d", txpacket); // ARP requests sent
|
||||||
|
|
||||||
|
// Interface up
|
||||||
|
fail_unless(netif_is_up(&net_test));
|
||||||
|
|
||||||
|
// Now it should have taken the IP
|
||||||
|
IP4_ADDR(&addr, 79, 138, 51, 5);
|
||||||
|
IP4_ADDR(&netmask, 255, 255, 254, 0);
|
||||||
|
IP4_ADDR(&gw, 79, 138, 50, 1);
|
||||||
|
fail_if(memcmp(&addr, &net_test.ip_addr, sizeof(struct ip_addr)));
|
||||||
|
fail_if(memcmp(&netmask, &net_test.netmask, sizeof(struct ip_addr)));
|
||||||
|
fail_if(memcmp(&gw, &net_test.gw, sizeof(struct ip_addr)));
|
||||||
|
|
||||||
|
fail_unless(txpacket == 4, "txpacket = %d", txpacket);
|
||||||
|
|
||||||
|
for (i = 0; i < 108000 - 25; i++) {
|
||||||
|
tick_lwip();
|
||||||
|
}
|
||||||
|
|
||||||
|
fail_unless(netif_is_up(&net_test));
|
||||||
|
fail_unless(txpacket == 5, "txpacket = %d", txpacket);
|
||||||
|
|
||||||
|
// We need to send arp response here..
|
||||||
|
|
||||||
|
send_pkt(&net_test, arp_resp, sizeof(arp_resp));
|
||||||
|
|
||||||
|
fail_unless(txpacket == 6, "txpacket = %d", txpacket);
|
||||||
|
fail_unless(netif_is_up(&net_test));
|
||||||
|
|
||||||
|
xid = htonl(net_test.dhcp->xid); // xid updated
|
||||||
|
memcpy(&relay_ack2[46], &xid, 4); // insert transaction id
|
||||||
|
send_pkt(&net_test, relay_ack2, sizeof(relay_ack2));
|
||||||
|
|
||||||
|
for (i = 0; i < 100000; i++) {
|
||||||
|
tick_lwip();
|
||||||
|
}
|
||||||
|
|
||||||
|
fail_unless(txpacket == 6, "txpacket = %d", txpacket);
|
||||||
|
|
||||||
|
netif_remove(&net_test);
|
||||||
|
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
/** Create the suite including all tests for this module */
|
||||||
|
Suite *
|
||||||
|
dhcp_suite(void)
|
||||||
|
{
|
||||||
|
TFun tests[] = {
|
||||||
|
test_dhcp,
|
||||||
|
test_dhcp_nak,
|
||||||
|
test_dhcp_relayed
|
||||||
|
};
|
||||||
|
return create_suite("DHCP", tests, sizeof(tests)/sizeof(TFun), dhcp_setup, dhcp_teardown);
|
||||||
|
}
|
8
test/unit/dhcp/test_dhcp.h
Normal file
8
test/unit/dhcp/test_dhcp.h
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#ifndef __TEST_DHCP_H__
|
||||||
|
#define __TEST_DHCP_H__
|
||||||
|
|
||||||
|
#include "../lwip_check.h"
|
||||||
|
|
||||||
|
Suite* dhcp_suite(void);
|
||||||
|
|
||||||
|
#endif
|
|
@ -5,6 +5,7 @@
|
||||||
#include "tcp/test_tcp_oos.h"
|
#include "tcp/test_tcp_oos.h"
|
||||||
#include "core/test_mem.h"
|
#include "core/test_mem.h"
|
||||||
#include "etharp/test_etharp.h"
|
#include "etharp/test_etharp.h"
|
||||||
|
#include "dhcp/test_dhcp.h"
|
||||||
|
|
||||||
#include "lwip/init.h"
|
#include "lwip/init.h"
|
||||||
|
|
||||||
|
@ -19,7 +20,8 @@ int main()
|
||||||
tcp_suite,
|
tcp_suite,
|
||||||
tcp_oos_suite,
|
tcp_oos_suite,
|
||||||
mem_suite,
|
mem_suite,
|
||||||
etharp_suite
|
etharp_suite,
|
||||||
|
dhcp_suite
|
||||||
};
|
};
|
||||||
size_t num = sizeof(suites)/sizeof(void*);
|
size_t num = sizeof(suites)/sizeof(void*);
|
||||||
LWIP_ASSERT("No suites defined", num > 0);
|
LWIP_ASSERT("No suites defined", num > 0);
|
||||||
|
|
|
@ -37,6 +37,10 @@
|
||||||
#define LWIP_NETCONN 0
|
#define LWIP_NETCONN 0
|
||||||
#define LWIP_SOCKET 0
|
#define LWIP_SOCKET 0
|
||||||
|
|
||||||
|
/* Enable DHCP to test it, disable UDP checksum to easier inject packets */
|
||||||
|
#define LWIP_DHCP 1
|
||||||
|
#define CHECKSUM_CHECK_UDP 0
|
||||||
|
|
||||||
/* Minimal changes to opt.h required for tcp unit tests: */
|
/* Minimal changes to opt.h required for tcp unit tests: */
|
||||||
#define MEM_SIZE 16000
|
#define MEM_SIZE 16000
|
||||||
#define TCP_SND_QUEUELEN 40
|
#define TCP_SND_QUEUELEN 40
|
||||||
|
|
Loading…
Reference in New Issue
Block a user