summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorMikael Magnusson <mikma@users.sourceforge.net>2023-02-07 16:53:00 +0000
committerHans Dedecker <dedeckeh@gmail.com>2023-02-16 21:28:57 +0100
commitdfab0fad85c8b705c483343c99907c229413f7b2 (patch)
tree9591db574930209d4ec72726fb07a096caaef04c /src
parenta92c0a73d018cd6453dcf253d9617f97311becab (diff)
dhcpv4: detect noarp interfaces
Don't add ARP entries to interfaces with IFF_NOARP, it causes problems with for example WireGuard interfaces (which requires this change to be usable with DHCPv4-over-DHCPv6). Signed-off-by: Mikael Magnusson <mikma@users.sourceforge.net>
Diffstat (limited to 'src')
-rw-r--r--src/config.c3
-rw-r--r--src/dhcpv4.c12
-rw-r--r--src/netlink.c7
-rw-r--r--src/odhcpd.c12
-rw-r--r--src/odhcpd.h2
5 files changed, 30 insertions, 6 deletions
diff --git a/src/config.c b/src/config.c
index 4e3db86..9b1f659 100644
--- a/src/config.c
+++ b/src/config.c
@@ -582,6 +582,9 @@ int config_parse_interface(void *data, size_t len, const char *name, bool overwr
if (!iface->ifindex &&
(iface->ifindex = if_nametoindex(iface->ifname)) <= 0)
goto err;
+
+ if ((iface->ifflags = odhcpd_get_flags(iface)) < 0)
+ goto err;
}
if (get_addrs) {
diff --git a/src/dhcpv4.c b/src/dhcpv4.c
index 7ac7af9..2b2f41e 100644
--- a/src/dhcpv4.c
+++ b/src/dhcpv4.c
@@ -897,12 +897,14 @@ void dhcpv4_handle_msg(void *addr, void *data, size_t len,
dest.sin_addr = reply.yiaddr;
dest.sin_port = htons(DHCPV4_CLIENT_PORT);
- memcpy(arp.arp_ha.sa_data, req->chaddr, 6);
- memcpy(&arp.arp_pa, &dest, sizeof(arp.arp_pa));
- memcpy(arp.arp_dev, iface->ifname, sizeof(arp.arp_dev));
+ if (!(iface->ifflags & IFF_NOARP)) {
+ memcpy(arp.arp_ha.sa_data, req->chaddr, 6);
+ memcpy(&arp.arp_pa, &dest, sizeof(arp.arp_pa));
+ memcpy(arp.arp_dev, iface->ifname, sizeof(arp.arp_dev));
- if (ioctl(sock, SIOCSARP, &arp) < 0)
- syslog(LOG_ERR, "ioctl(SIOCSARP): %m");
+ if (ioctl(sock, SIOCSARP, &arp) < 0)
+ syslog(LOG_ERR, "ioctl(SIOCSARP): %m");
+ }
}
if (send_reply(&reply, PACKET_SIZE(&reply, cookie),
diff --git a/src/netlink.c b/src/netlink.c
index 63a0f8b..4a352a6 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -308,7 +308,12 @@ static int handle_rtm_link(struct nlmsghdr *hdr)
ifname = nla_get_string(nla[IFLA_IFNAME]);
avl_for_each_element(&interfaces, iface, avl) {
- if (strcmp(iface->ifname, ifname) || iface->ifindex == ifi->ifi_index)
+ if (strcmp(iface->ifname, ifname))
+ continue;
+
+ iface->ifflags = ifi->ifi_flags;
+
+ if (iface->ifindex == ifi->ifi_index)
continue;
iface->ifindex = ifi->ifi_index;
diff --git a/src/odhcpd.c b/src/odhcpd.c
index 9797507..554e5f1 100644
--- a/src/odhcpd.c
+++ b/src/odhcpd.c
@@ -171,6 +171,18 @@ int odhcpd_get_mac(const struct interface *iface, uint8_t mac[6])
return 0;
}
+int odhcpd_get_flags(const struct interface *iface)
+{
+ struct ifreq ifr;
+
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, iface->ifname, sizeof(ifr.ifr_name) - 1);
+ if (ioctl(ioctl_sock, SIOCGIFFLAGS, &ifr) < 0)
+ return -1;
+
+ return ifr.ifr_flags;
+}
+
/* Forwards a packet on a specific interface */
ssize_t odhcpd_send(int socket, struct sockaddr_in6 *dest,
diff --git a/src/odhcpd.h b/src/odhcpd.h
index 5ba6854..d829033 100644
--- a/src/odhcpd.h
+++ b/src/odhcpd.h
@@ -238,6 +238,7 @@ struct dhcp_assignment {
struct interface {
struct avl_node avl;
+ int ifflags;
int ifindex;
char *ifname;
const char *name;
@@ -401,6 +402,7 @@ int odhcpd_get_interface_dns_addr(const struct interface *iface,
struct in6_addr *addr);
int odhcpd_get_interface_config(const char *ifname, const char *what);
int odhcpd_get_mac(const struct interface *iface, uint8_t mac[6]);
+int odhcpd_get_flags(const struct interface *iface);
struct interface* odhcpd_get_interface_by_index(int ifindex);
int odhcpd_urandom(void *data, size_t len);