X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fodhcpd.git;a=blobdiff_plain;f=src%2Fdhcpv4.c;h=b8e0c95d8efcb27a175868043f632d844243f6b3;hp=38b4f9ba5bb9869a19da709897117dc5665e2c37;hb=d12c7b8c39bc0f727bde5aa34595e9a581891dca;hpb=8b19de666e02f24280728938dd985ecb3673b83e diff --git a/src/dhcpv4.c b/src/dhcpv4.c index 38b4f9b..b8e0c95 100644 --- a/src/dhcpv4.c +++ b/src/dhcpv4.c @@ -37,7 +37,7 @@ static void handle_dhcpv4(void *addr, void *data, size_t len, static struct dhcpv4_assignment* dhcpv4_lease(struct interface *iface, enum dhcpv4_msg msg, const uint8_t *mac, struct in_addr reqaddr, const char *hostname); - +static const char *excluded_class = "HOMENET"; // Create socket and register events int init_dhcpv4(void) @@ -49,6 +49,7 @@ 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; } @@ -58,6 +59,11 @@ int setup_dhcpv4_interface(struct interface *iface, bool enable) 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; @@ -65,7 +71,7 @@ int setup_dhcpv4_interface(struct interface *iface, bool enable) setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &val, sizeof(val)); setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &val, sizeof(val)); - val = IPTOS_CLASS_CS6; + val = IPTOS_PREC_INTERNETCONTROL; setsockopt(sock, IPPROTO_IP, IP_TOS, &val, sizeof(val)); val = IP_PMTUDISC_DONT; @@ -119,8 +125,8 @@ int setup_dhcpv4_interface(struct interface *iface, bool enable) end = addr.s_addr & mask.s_addr; if (ntohl(mask.s_addr) <= 0xffffff00) { - iface->dhcpv4_start.s_addr = start | htonl(20); - iface->dhcpv4_end.s_addr = end | htonl(199); + iface->dhcpv4_start.s_addr = start | htonl(100); + iface->dhcpv4_end.s_addr = end | htonl(250); } else { iface->dhcpv4_start.s_addr = start | htonl(10); iface->dhcpv4_end.s_addr = end | htonl(59); @@ -136,7 +142,11 @@ int setup_dhcpv4_interface(struct interface *iface, bool enable) // 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); @@ -168,7 +178,7 @@ int setup_dhcpv4_interface(struct interface *iface, bool enable) if (iface->dhcpv4_leasetime < 60) - iface->dhcpv4_leasetime = 1800; + iface->dhcpv4_leasetime = 43200; iface->dhcpv4_event.uloop.fd = sock; iface->dhcpv4_event.handle_dgram = handle_dhcpv4; @@ -284,6 +294,13 @@ static void handle_dhcpv4(void *addr, void *data, size_t len, } else if (opt->type == DHCPV4_OPT_SERVERID && opt->len == 4) { if (memcmp(opt->data, &ifaddr.sin_addr, 4)) return; + } else if (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(excluded_class); + if (*c == elen && !memcmp(&c[1], excluded_class, elen)) + return; // Ignore from homenet + } } } @@ -463,6 +480,10 @@ static struct dhcpv4_assignment* dhcpv4_lease(struct interface *iface, 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); @@ -471,6 +492,10 @@ static struct dhcpv4_assignment* dhcpv4_lease(struct interface *iface, 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