Mercurial > hg > dhcpcd
changeset 977:51d5c78d622b draft
Ensure that routes go via the correct interface and set netmask correctly.
| author | Roy Marples <roy@marples.name> |
|---|---|
| date | Sun, 14 Sep 2008 09:07:34 +0000 |
| parents | aa7187c07fce |
| children | 3a250c33e88d |
| files | if-bsd.c |
| diffstat | 1 files changed, 29 insertions(+), 38 deletions(-) [+] |
line wrap: on
line diff
--- a/if-bsd.c Sun Sep 14 09:06:22 2008 +0000 +++ b/if-bsd.c Sun Sep 14 09:07:34 2008 +0000 @@ -116,9 +116,9 @@ struct rtm { struct rt_msghdr hdr; - char buffer[sizeof(su) * 5]; + char buffer[sizeof(su) * 4]; } rtm; - char *bp = rtm.buffer; + char *bp = rtm.buffer, *p; size_t l; int retval = 0; @@ -137,57 +137,48 @@ rtm.hdr.rtm_flags = RTF_UP | RTF_STATIC; if (netmask->s_addr == INADDR_BROADCAST) rtm.hdr.rtm_flags |= RTF_HOST; + else + rtm.hdr.rtm_flags |= RTF_GATEWAY; /* This order is important */ - rtm.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK; - rtm.hdr.rtm_addrs |= RTA_IFP | RTA_IFA; + rtm.hdr.rtm_addrs = RTA_DST | RTA_NETMASK | RTA_IFP; + if (gateway->s_addr != INADDR_ANY) + rtm.hdr.rtm_addrs |= RTA_GATEWAY; +#define ADDSU(_su) \ + l = SA_SIZE(&(_su.sa)); \ + memcpy(bp, &(_su), l); \ + bp += l; #define ADDADDR(_addr) \ memset (&su, 0, sizeof(su)); \ su.sin.sin_family = AF_INET; \ su.sin.sin_len = sizeof(su.sin); \ memcpy (&su.sin.sin_addr, _addr, sizeof(su.sin.sin_addr)); \ - l = SA_SIZE (&(su.sa)); \ - memcpy (bp, &(su), l); \ - bp += l; + ADDSU(su); ADDADDR(destination); + if (gateway->s_addr != INADDR_ANY) + ADDADDR(gateway); - if (gateway->s_addr == INADDR_ANY) { - /* Make us a link layer socket */ - memset(&su, 0, sizeof(su)); - su.sdl.sdl_len = sizeof(su.sdl); - su.sdl.sdl_family = AF_LINK; - su.sdl.sdl_nlen = strlen(iface->name); - memcpy(&su.sdl.sdl_data, iface->name, (size_t)su.sdl.sdl_nlen); - su.sdl.sdl_alen = iface->hwlen; - memcpy(((unsigned char *)&su.sdl.sdl_data) + su.sdl.sdl_nlen, - iface->hwaddr, (size_t)su.sdl.sdl_alen); + /* Ensure that netmask is set correctly */ + memset (&su, 0, sizeof(su)); + su.sin.sin_family = AF_INET; + su.sin.sin_len = sizeof(su.sin); + memcpy (&su.sin.sin_addr, &netmask->s_addr, sizeof(su.sin.sin_addr)); + p = su.sa.sa_len + (char *)&su; + for (su.sa.sa_len = 0; p > (char *)&su; ) + if (*--p != 0) { + su.sa.sa_len = 1 + p - (char *)&su; + break; + } + ADDSU(su); - l = SA_SIZE(&(su.sa)); - memcpy(bp, &su, l); - bp += l; - } else { - rtm.hdr.rtm_flags |= RTF_GATEWAY; - ADDADDR(gateway); - } - - ADDADDR(netmask); /* Make us a link layer socket for IFP */ memset(&su, 0, sizeof(su)); + su.sdl.sdl_family = AF_LINK; su.sdl.sdl_len = sizeof(su.sdl); - su.sdl.sdl_family = AF_LINK; - su.sdl.sdl_nlen = strlen(iface->name); - memcpy(&su.sdl.sdl_data, iface->name, (size_t)su.sdl.sdl_nlen); - su.sdl.sdl_alen = iface->hwlen; - memcpy(((unsigned char *)&su.sdl.sdl_data) + su.sdl.sdl_nlen, - iface->hwaddr, (size_t)su.sdl.sdl_alen); - - l = SA_SIZE(&(su.sa)); - memcpy(bp, &su, l); - bp += l; - ADDADDR(&iface->addr); /* IFA */ -#undef ADDADDR + link_addr(iface->name, &su.sdl); + ADDSU(su); rtm.hdr.rtm_msglen = l = bp - (char *)&rtm; if (write(s, &rtm, l) == -1)
