projects
/
project
/
odhcpd.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Fix a segfault in state-script handling
[project/odhcpd.git]
/
src
/
dhcpv4.c
diff --git
a/src/dhcpv4.c
b/src/dhcpv4.c
index
38b4f9b
..
49b75f4
100644
(file)
--- a/
src/dhcpv4.c
+++ b/
src/dhcpv4.c
@@
-38,6
+38,8
@@
static struct dhcpv4_assignment* dhcpv4_lease(struct interface *iface,
enum dhcpv4_msg msg, const uint8_t *mac, struct in_addr reqaddr,
const char *hostname);
enum dhcpv4_msg msg, const uint8_t *mac, struct in_addr reqaddr,
const char *hostname);
+// Magic option for hnet internal (4B enterprise ID, 1B data-len, 1B subopt-code, 1B subopt-len)
+static uint8_t hnet_internal_data[7] = {0x00, 0x00, 0x76, 0xfe, 2, 1, 0};
// Create socket and register events
int init_dhcpv4(void)
// Create socket and register events
int init_dhcpv4(void)
@@
-49,6
+51,7
@@
int init_dhcpv4(void)
int setup_dhcpv4_interface(struct interface *iface, bool enable)
{
if (iface->dhcpv4_event.uloop.fd > 0) {
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;
}
close(iface->dhcpv4_event.uloop.fd);
iface->dhcpv4_event.uloop.fd = -1;
}
@@
-58,6
+61,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);
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;
// Basic IPv6 configuration
int val = 1;
@@
-65,7
+73,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));
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;
setsockopt(sock, IPPROTO_IP, IP_TOS, &val, sizeof(val));
val = IP_PMTUDISC_DONT;
@@
-119,8
+127,8
@@
int setup_dhcpv4_interface(struct interface *iface, bool enable)
end = addr.s_addr & mask.s_addr;
if (ntohl(mask.s_addr) <= 0xffffff00) {
end = addr.s_addr & mask.s_addr;
if (ntohl(mask.s_addr) <= 0xffffff00) {
- iface->dhcpv4_start.s_addr = start | htonl(
2
0);
- iface->dhcpv4_end.s_addr = end | htonl(
199
);
+ iface->dhcpv4_start.s_addr = start | htonl(
10
0);
+ 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);
} else {
iface->dhcpv4_start.s_addr = start | htonl(10);
iface->dhcpv4_end.s_addr = end | htonl(59);
@@
-136,7
+144,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);
// 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);
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
+180,7
@@
int setup_dhcpv4_interface(struct interface *iface, bool enable)
if (iface->dhcpv4_leasetime < 60)
if (iface->dhcpv4_leasetime < 60)
- iface->dhcpv4_leasetime =
18
00;
+ iface->dhcpv4_leasetime =
432
00;
iface->dhcpv4_event.uloop.fd = sock;
iface->dhcpv4_event.handle_dgram = handle_dhcpv4;
iface->dhcpv4_event.uloop.fd = sock;
iface->dhcpv4_event.handle_dgram = handle_dhcpv4;
@@
-284,6
+296,10
@@
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_SERVERID && opt->len == 4) {
if (memcmp(opt->data, &ifaddr.sin_addr, 4))
return;
+ } else if (opt->type == DHCPV4_OPT_VENDOR_SPECIFIC_INFORMATION &&
+ opt->len == sizeof(hnet_internal_data)) {
+ if (!memcmp(opt->data, hnet_internal_data, sizeof(hnet_internal_data)))
+ return; // Ignoring hnet internal routers
}
}
}
}
@@
-463,6
+479,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 && !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);
memcpy(a->hwaddr, mac, sizeof(a->hwaddr));
memcpy(a->hostname, hostname, hostlen);
@@
-471,6
+491,10
@@
static struct dhcpv4_assignment* dhcpv4_lease(struct interface *iface,
if (assigned && !a->hostname[0] && hostname) {
a = realloc(a, sizeof(*a) + 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
memcpy(a->hostname, hostname, hostlen);
// Fixup list