as a gateway.
Thanks to Christos Zoulas.
char *cp;
struct sockaddr *sa, *rti_info[RTAX_MAX];
struct sockaddr_dl *sdl;
+ struct sockaddr_in *sin;
+ struct ipv4_addr *ia;
cp = (char *)(void *)(rtm + 1);
sa = (struct sockaddr *)(void *)cp;
sdl = (struct sockaddr_dl *)(void *)rti_info[RTAX_IFP];
rt->iface = if_findsdl(ctx, sdl);
} else if (rtm->rtm_addrs & RTA_GATEWAY) {
- sdl = (struct sockaddr_dl *)(void *)rti_info[RTAX_GATEWAY];
- if (sdl->sdl_family == AF_LINK)
+ sa = rti_info[RTAX_GATEWAY];
+ switch (sa->sa_family) {
+ case AF_LINK:
+ sdl = (void *)sa;
rt->iface = if_findsdl(ctx, sdl);
+ break;
+ case AF_INET:
+ sin = (void *)sa;
+ if ((ia = ipv4_findmaskaddr(ctx, &sin->sin_addr)))
+ rt->iface = ia->iface;
+ break;
+ default:
+ errno = EAFNOSUPPORT;
+ logger(ctx, LOG_ERR, "%s: %m", __func__);
+ return -1;
+ }
}
/* If we don't have an interface and it's a host route, it maybe
if (rt->iface == NULL &&
!(~rtm->rtm_flags & (RTF_HOST | RTF_GATEWAY)))
{
- struct ipv4_addr *ia;
-
if ((ia = ipv4_findaddr(ctx, &rt->dest)))
rt->iface = ia->iface;
}
return NULL;
}
+static struct ipv4_addr *
+ipv4_iffindmaskaddr(struct interface *ifp, const struct in_addr *addr)
+{
+ struct ipv4_state *state;
+ struct ipv4_addr *ap;
+
+ state = IPV4_STATE(ifp);
+ if (state) {
+ TAILQ_FOREACH (ap, &state->addrs, next) {
+ if ((ap->addr.s_addr & ap->net.s_addr) ==
+ (addr->s_addr & ap->net.s_addr))
+ return ap;
+ }
+ }
+ return NULL;
+}
+
struct ipv4_addr *
ipv4_findaddr(struct dhcpcd_ctx *ctx, const struct in_addr *addr)
{
return NULL;
}
+struct ipv4_addr *
+ipv4_findmaskaddr(struct dhcpcd_ctx *ctx, const struct in_addr *addr)
+{
+ struct interface *ifp;
+ struct ipv4_addr *ap;
+
+ TAILQ_FOREACH(ifp, ctx->ifaces, next) {
+ ap = ipv4_iffindmaskaddr(ifp, addr);
+ if (ap)
+ return ap;
+ }
+ return NULL;
+}
+
int
ipv4_srcaddr(const struct rt *rt, struct in_addr *addr)
{
const struct in_addr *, const struct in_addr *);
struct ipv4_addr *ipv4_iffindlladdr(struct interface *);
struct ipv4_addr *ipv4_findaddr(struct dhcpcd_ctx *, const struct in_addr *);
+struct ipv4_addr *ipv4_findmaskaddr(struct dhcpcd_ctx *,
+ const struct in_addr *);
int ipv4_srcaddr(const struct rt *, struct in_addr *);
void ipv4_handleifa(struct dhcpcd_ctx *, int, struct if_head *, const char *,
const struct in_addr *, const struct in_addr *, const struct in_addr *,