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) {
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),
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;
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,
struct interface {
struct avl_node avl;
+ int ifflags;
int ifindex;
char *ifname;
const char *name;
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);