static void forward_router_advertisement(uint8_t *data, size_t len);
static void handle_icmpv6(void *addr, void *data, size_t len,
- struct interface *iface);
+ struct interface *iface, void *dest);
static void send_router_advert(struct uloop_timeout *event);
static void sigusr1_refresh(int signal);
int setup_router_interface(struct interface *iface, bool enable)
{
+ if (!fp_route || router_event.uloop.fd < 0)
+ return -1;
+
struct ipv6_mreq all_nodes = {ALL_IPV6_NODES, iface->ifindex};
struct ipv6_mreq all_routers = {ALL_IPV6_ROUTERS, iface->ifindex};
// Event handler for incoming ICMPv6 packets
static void handle_icmpv6(void *addr, void *data, size_t len,
- struct interface *iface)
+ struct interface *iface, _unused void *dest)
{
struct icmp6_hdr *hdr = data;
char line[512], ifname[16];
bool found_default = false;
- struct odhcpd_ipaddr p = {IN6ADDR_ANY_INIT, 0, false, 0, 0, 0};
+ struct odhcpd_ipaddr p = {IN6ADDR_ANY_INIT, 0, 0, false, 0, 0, 0};
while (fgets(line, sizeof(line), fp_route)) {
uint32_t rflags;
if (sscanf(line, "00000000000000000000000000000000 00 "
for (ssize_t i = 0; i < len; ++i) {
if (n[i].prefix <= 64 && n[i].prefix >= p.prefix &&
!odhcpd_bmemcmp(&p.addr, &n[i].addr, p.prefix)) {
- n[i].prefix = p.prefix;
+ n[i].dprefix = p.prefix;
break;
}
}
bool have_public = false;
size_t cnt = 0;
- struct in6_addr *dns_addr = NULL;
+ struct in6_addr dns_pref = IN6ADDR_ANY_INIT, *dns_addr = &dns_pref;
uint32_t dns_time = 0;
size_t dns_cnt = 1;
if (addr->preferred > dns_time) {
dns_time = addr->preferred;
- dns_addr = &addr->addr;
+ dns_pref = addr->addr;
}
}
dns_time = 2 * MaxRtrAdvInterval;
}
- if (!dns_addr)
+ if (!dns_addr || IN6_IS_ADDR_UNSPECIFIED(dns_addr))
dns_cnt = 0;
struct {
for (ssize_t i = 0; i < ipcnt; ++i) {
struct odhcpd_ipaddr *addr = &addrs[i];
- if (addr->prefix > 64 || addr->prefix == 0) {
+ if (addr->dprefix > 64 || addr->dprefix == 0 ||
+ (addr->dprefix == 64 && addr->prefix == 64)) {
continue; // Address not suitable
- } else if (addr->prefix > 32) {
- addr->addr.s6_addr32[1] &= htonl(~((1U << (64 - addr->prefix)) - 1));
- } else if (addr->prefix <= 32) {
- addr->addr.s6_addr32[0] &= htonl(~((1U << (32 - addr->prefix)) - 1));
+ } else if (addr->dprefix > 32) {
+ addr->addr.s6_addr32[1] &= htonl(~((1U << (64 - addr->dprefix)) - 1));
+ } else if (addr->dprefix <= 32) {
+ addr->addr.s6_addr32[0] &= htonl(~((1U << (32 - addr->dprefix)) - 1));
addr->addr.s6_addr32[1] = 0;
}
routes[routes_cnt].type = ND_OPT_ROUTE_INFO;
routes[routes_cnt].len = sizeof(*routes) / 8;
- routes[routes_cnt].prefix = addr->prefix;
+ routes[routes_cnt].prefix = addr->dprefix;
routes[routes_cnt].flags = 0;
if (iface->route_preference < 0)
routes[routes_cnt].flags |= ND_RA_PREF_LOW;
routes[routes_cnt].lifetime = htonl(addr->valid);
routes[routes_cnt].addr[0] = addr->addr.s6_addr32[0];
routes[routes_cnt].addr[1] = addr->addr.s6_addr32[1];
- routes[routes_cnt].addr[2] = addr->addr.s6_addr32[2];
- routes[routes_cnt].addr[3] = addr->addr.s6_addr32[3];
+ routes[routes_cnt].addr[2] = 0;
+ routes[routes_cnt].addr[3] = 0;
++routes_cnt;
}