uloop_end();
}
-
static void print_usage(const char *app)
{
printf(
);
}
+static bool ipv6_enabled(void)
+{
+ int fd = socket(AF_INET6, SOCK_DGRAM, 0);
+
+ if (fd < 0)
+ return false;
+
+ close(fd);
+
+ return true;
+}
int main(int argc, char **argv)
{
ioctl_sock = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+ if (ioctl_sock < 0)
+ return 4;
+
if ((urandom_fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC)) < 0)
return 4;
if (netlink_init())
return 4;
- if (router_init())
- return 4;
+ if (ipv6_enabled()) {
+ if (router_init())
+ return 4;
- if (dhcpv6_init())
- return 4;
+ if (dhcpv6_init())
+ return 4;
- if (ndp_init())
+ if (ndp_init())
+ return 4;
+ }
+#ifndef DHCPV4_SUPPORT
+ else
return 4;
-
-#ifdef DHCPV4_SUPPORT
+#else
if (dhcpv4_init())
return 4;
#endif
snprintf(buf, sizeof(buf), sysctl_pattern, ifname, what);
int fd = open(buf, O_RDONLY);
+ if (fd < 0)
+ return -1;
+
ssize_t len = read(fd, buf, sizeof(buf) - 1);
close(fd);
ssize_t sent = sendmsg(socket, &msg, MSG_DONTWAIT);
if (sent < 0)
- syslog(LOG_NOTICE, "Failed to send to %s%%%s (%m)",
- ipbuf, iface->ifname);
+ syslog(LOG_NOTICE, "Failed to send to %s%%%s@%s (%m)",
+ ipbuf, iface->name, iface->ifname);
else
- syslog(LOG_DEBUG, "Sent %li bytes to %s%%%s",
- (long)sent, ipbuf, iface->ifname);
+ syslog(LOG_DEBUG, "Sent %zd bytes to %s%%%s@%s",
+ sent, ipbuf, iface->name, iface->ifname);
return sent;
}
struct interface* odhcpd_get_interface_by_index(int ifindex)
{
struct interface *iface;
- list_for_each_entry(iface, &interfaces, head)
- if (iface->ifindex == ifindex)
- return iface;
-
- return NULL;
-}
-
-
-struct interface* odhcpd_get_interface_by_name(const char *name)
-{
- struct interface *iface;
- list_for_each_entry(iface, &interfaces, head)
- if (!strcmp(iface->ifname, name))
- return iface;
- return NULL;
-}
-
-
-struct interface* odhcpd_get_master_interface(void)
-{
- struct interface *iface;
- list_for_each_entry(iface, &interfaces, head)
- if (iface->master)
+ avl_for_each_element(&interfaces, iface, avl) {
+ if (iface->ifindex == ifindex)
return iface;
+ }
return NULL;
}
-
/* Convenience function to receive and do basic validation of packets */
static void odhcpd_receive_packets(struct uloop_fd *u, _unused unsigned int events)
{
if (u->error) {
int ret = -1;
socklen_t ret_len = sizeof(ret);
- getsockopt(u->fd, SOL_SOCKET, SO_ERROR, &ret, &ret_len);
+
u->error = false;
- if (e->handle_error)
+ if (e->handle_error && getsockopt(u->fd, SOL_SOCKET, SO_ERROR, &ret, &ret_len) == 0)
e->handle_error(e, ret);
}
/* From netlink */
if (addr.nl.nl_family == AF_NETLINK) {
- syslog(LOG_DEBUG, "Received %li Bytes from %s%%%s", (long)len,
- ipbuf, "netlink");
+ syslog(LOG_DEBUG, "Received %zd Bytes from %s%%netlink", len,
+ ipbuf);
e->handle_dgram(&addr, data_buf, len, NULL, dest);
return;
} else if (destiface != 0) {
struct interface *iface;
- list_for_each_entry(iface, &interfaces, head) {
+
+ avl_for_each_element(&interfaces, iface, avl) {
if (iface->ifindex != destiface)
continue;
- syslog(LOG_DEBUG, "Received %li Bytes from %s%%%s", (long)len,
- ipbuf, iface->ifname);
+ syslog(LOG_DEBUG, "Received %zd Bytes from %s%%%s@%s", len,
+ ipbuf, iface->name, iface->ifname);
e->handle_dgram(&addr, data_buf, len, iface, dest);
}
return true;
}
+
+bool odhcpd_valid_hostname(const char *name)
+{
+#define MAX_LABEL 63
+ const char *c, *label, *label_end;
+ int label_sz = 0;
+
+ for (c = name, label_sz = 0, label = name, label_end = name + strcspn(name, ".") - 1;
+ *c && label_sz <= MAX_LABEL; c++) {
+ if ((*c >= '0' && *c <= '9') ||
+ (*c >= 'A' && *c <= 'Z') ||
+ (*c >= 'a' && *c <= 'z')) {
+ label_sz++;
+ continue;
+ }
+
+ if ((*c == '_' || *c == '-') && c != label && c != label_end) {
+ label_sz++;
+ continue;
+ }
+
+ if (*c == '.') {
+ if (*(c + 1)) {
+ label = c + 1;
+ label_end = label + strcspn(label, ".") - 1;
+ label_sz = 0;
+ }
+ continue;
+ }
+
+ return false;
+ }
+
+ return (label_sz && label_sz <= MAX_LABEL ? true : false);
+}