proxy_dhcp6ds.c revision f0c792e78a8bf77c28c7814441e514bea7c5362b
/* -*- indent-tabs-mode: nil; -*- */
/**
* Simple stateless DHCPv6 (RFC 3736) server.
*/
#include "winutils.h"
#include "dhcp6.h"
#include "proxy.h"
#include <string.h>
/* ff02::1:2 - "All_DHCP_Relay_Agents_and_Servers" link-scoped multicast */
};
/* ff05::1:3 - "All_DHCP_Servers" site-scoped multicast */
};
static struct udp_pcb *dhcp6ds_pcb;
/* prebuilt Server ID option */
/* prebuilt DNS Servers option */
/**
* Initialize DHCP6 server.
*
* Join DHCP6 multicast groups.
* Create and bind server pcb.
* Prebuild fixed parts of reply.
*/
{
int i;
/*
* XXX: TODO: This is a leftover from testing with IPv6 mapped
* loopback with a special IPv6->IPv4 mapping hack in pxudp.c
*/
/* advertise ourself as DNS resolver - will be proxied to host */
for (i = 1; i < LWIP_IPV6_NUM_ADDRESSES; ++i) {
{
break;
}
}
DPRINTF0(("%s: failed to join All_DHCP_Relay_Agents_and_Servers: %s\n",
goto err;
}
DPRINTF0(("%s: failed to join All_DHCP_Servers: %s\n",
goto err1;
}
dhcp6ds_pcb = udp_new_ip6();
if (dhcp6ds_pcb == NULL) {
goto err2;
}
goto err3;
}
} while (0)
/*
* XXX: TODO: This is a leftover from testing with IPv6 mapped
* loopback with a special IPv6->IPv4 mapping hack in pxudp.c
*/
return ERR_OK;
err3:
dhcp6ds_pcb = NULL;
err2:
err1:
err:
return error;
}
static void
{
int copied;
struct pbuf *q;
LWIP_ASSERT1(p != NULL);
if (copied != sizeof(msg_header)) {
pbuf_free(p);
return;
}
msg_type = msg_header[0];
pbuf_free(p);
return;
}
roff = 0;
msg_header[0] = DHCP6_REPLY;
roff += sizeof(msg_header);
/* loop over options */
while (p->tot_len > 0) {
/* fetch option code */
pbuf_free(p);
return;
}
/* fetch option length */
pbuf_free(p);
return;
}
/* enough data? */
DPRINTF(("%s: option %u truncated: expect %u, got %u\n",
pbuf_free(p);
return;
}
if (opt == DHCP6_OPTION_CLIENTID) {
u16_t s;
/* "A DUID can be no more than 128 octets long (not
including the type code)." */
if (optlen > 130) {
pbuf_free(p);
return;
}
roff += sizeof(s);
roff += sizeof(s);
}
else if (opt == DHCP6_OPTION_ORO) {
int i, nopts;
if (optlen % 2 != 0) {
goto bad_oro;
}
DPRINTF2(("%s: failed to allocate space for Option Request\n",
__func__));
goto bad_oro;
}
for (i = 0; i < nopts; ++i) {
};
bad_oro: /* empty */;
}
}
pbuf_free(p); /* done */
roff += sizeof(dhcp6ds_serverid);
roff += sizeof(dhcp6ds_dns);
if (q == NULL) {
return;
}
DPRINTF(("%s: pbuf_take(%d) failed: %s\n",
pbuf_free(q);
return;
}
DPRINTF(("%s: udp_sendto failed: %s\n",
}
pbuf_free(q);
}