enum dhcpv4_msg msg, const uint8_t *mac, struct in_addr reqaddr,
const char *hostname);
-
// Create socket and register events
int init_dhcpv4(void)
{
int setup_dhcpv4_interface(struct interface *iface, bool enable)
{
if (iface->dhcpv4_event.uloop.fd > 0) {
+ uloop_fd_delete(&iface->dhcpv4_event.uloop);
close(iface->dhcpv4_event.uloop.fd);
iface->dhcpv4_event.uloop.fd = -1;
}
INIT_LIST_HEAD(&iface->dhcpv4_assignments);
int sock = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, IPPROTO_UDP);
+ if (sock < 0) {
+ syslog(LOG_ERR, "Failed to create DHCPv4 server socket: %s",
+ strerror(errno));
+ return -1;
+ }
// Basic IPv6 configuration
int val = 1;
(addr.s_addr & mask.s_addr);
iface->dhcpv4_end.s_addr = htonl(end) |
(addr.s_addr & mask.s_addr);
- } else if (ntohl(mask.s_addr) <= 0xffffffc0) {
+ } else if (ntohl(mask.s_addr) <= 0xfffffff0) {
start = addr.s_addr & mask.s_addr;
end = addr.s_addr & mask.s_addr;
if (ntohl(mask.s_addr) <= 0xffffff00) {
iface->dhcpv4_start.s_addr = start | htonl(100);
iface->dhcpv4_end.s_addr = end | htonl(250);
- } else {
+ } else if (ntohl(mask.s_addr) <= 0xffffffc0) {
+ iface->dhcpv4_start.s_addr = start | htonl(10);
+ iface->dhcpv4_end.s_addr = end | htonl(60);
+ } else if (ntohl(mask.s_addr) <= 0xffffffe0) {
iface->dhcpv4_start.s_addr = start | htonl(10);
- iface->dhcpv4_end.s_addr = end | htonl(59);
+ iface->dhcpv4_end.s_addr = end | htonl(30);
+ } else {
+ iface->dhcpv4_start.s_addr = start | htonl(3);
+ iface->dhcpv4_end.s_addr = end | htonl(12);
}
}
// Construct entry
size_t hostlen = strlen(lease->hostname) + 1;
struct dhcpv4_assignment *a = calloc(1, sizeof(*a) + hostlen);
-
+ if (!a) {
+ syslog(LOG_ERR, "Calloc failed for static lease on interface %s",
+ iface->ifname);
+ return -1;
+ }
a->addr = ntohl(lease->ipaddr.s_addr);
memcpy(a->hwaddr, lease->mac.ether_addr_octet, sizeof(a->hwaddr));
memcpy(a->hostname, lease->hostname, hostlen);
} else if (opt->type == DHCPV4_OPT_SERVERID && opt->len == 4) {
if (memcmp(opt->data, &ifaddr.sin_addr, 4))
return;
+ } else if (iface->filter_class && opt->type == DHCPV4_OPT_USER_CLASS) {
+ uint8_t *c = opt->data, *cend = &opt->data[opt->len];
+ for (; c < cend && &c[*c] < cend; c = &c[1 + *c]) {
+ size_t elen = strlen(iface->filter_class);
+ if (*c == elen && !memcmp(&c[1], iface->filter_class, elen))
+ return; // Ignore from homenet
+ }
}
}
if (!a && !iface->no_dynamic_dhcp) { // Create new binding
a = calloc(1, sizeof(*a) + hostlen);
+ if (!a) {
+ syslog(LOG_ERR, "Failed to calloc binding on interface %s", iface->ifname);
+ return NULL;
+ }
memcpy(a->hwaddr, mac, sizeof(a->hwaddr));
memcpy(a->hostname, hostname, hostlen);
if (assigned && !a->hostname[0] && hostname) {
a = realloc(a, sizeof(*a) + hostlen);
+ if (!a) {
+ syslog(LOG_ERR, "Failed to realloc binding on interface %s", iface->ifname);
+ return NULL;
+ }
memcpy(a->hostname, hostname, hostlen);
// Fixup list