From a6eadd7919db2ca0d6965676dec6c020c7f22eca Mon Sep 17 00:00:00 2001 From: Hans Dedecker Date: Thu, 26 Jan 2017 18:29:09 +0100 Subject: [PATCH 1/1] odhcpd: rework IPv6 interface address dump Rework the IPv6 address dump logic to make it more robust and generate syslog traces in case of error situations Signed-off-by: Hans Dedecker --- src/odhcpd.c | 73 ++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 41 insertions(+), 32 deletions(-) diff --git a/src/odhcpd.c b/src/odhcpd.c index 6a3ba86..5e05977 100644 --- a/src/odhcpd.c +++ b/src/odhcpd.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -236,48 +237,56 @@ ssize_t odhcpd_get_interface_addresses(int ifindex, continue; syslog(LOG_WARNING, "Failed to receive IPv6 address rtnetlink message (%s)", strerror(errno)); - return ret; + ret = -1; + goto out; } } - if (nhm->nlmsg_type != RTM_NEWADDR) { - syslog(LOG_WARNING, "Unexpected rtnetlink message (%d) in response to IPv6 address dump", nhm->nlmsg_type); - break; - } - - // Skip address but keep clearing socket buffer - if (ret >= (ssize_t)cnt) - continue; + switch (nhm->nlmsg_type) { + case RTM_NEWADDR: { + // Skip address but keep clearing socket buffer + if (ret >= (ssize_t)cnt) + continue; - struct ifaddrmsg *ifa = NLMSG_DATA(nhm); - if (ifa->ifa_scope != RT_SCOPE_UNIVERSE || - (ifindex && ifa->ifa_index != (unsigned)ifindex)) - continue; + struct ifaddrmsg *ifa = NLMSG_DATA(nhm); + if (ifa->ifa_scope != RT_SCOPE_UNIVERSE || + (ifindex && ifa->ifa_index != (unsigned)ifindex)) + continue; - struct rtattr *rta = (struct rtattr*)&ifa[1]; - size_t alen = NLMSG_PAYLOAD(nhm, sizeof(*ifa)); - memset(&addrs[ret], 0, sizeof(addrs[ret])); - addrs[ret].prefix = ifa->ifa_prefixlen; - - while (RTA_OK(rta, alen)) { - if (rta->rta_type == IFA_ADDRESS) { - memcpy(&addrs[ret].addr, RTA_DATA(rta), - sizeof(struct in6_addr)); - } else if (rta->rta_type == IFA_CACHEINFO) { - struct ifa_cacheinfo *ifc = RTA_DATA(rta); - addrs[ret].preferred = ifc->ifa_prefered; - addrs[ret].valid = ifc->ifa_valid; + struct rtattr *rta = (struct rtattr*)&ifa[1]; + size_t alen = NLMSG_PAYLOAD(nhm, sizeof(*ifa)); + memset(&addrs[ret], 0, sizeof(addrs[ret])); + addrs[ret].prefix = ifa->ifa_prefixlen; + + while (RTA_OK(rta, alen)) { + if (rta->rta_type == IFA_ADDRESS) { + memcpy(&addrs[ret].addr, RTA_DATA(rta), + sizeof(struct in6_addr)); + } else if (rta->rta_type == IFA_CACHEINFO) { + struct ifa_cacheinfo *ifc = RTA_DATA(rta); + addrs[ret].preferred = ifc->ifa_prefered; + addrs[ret].valid = ifc->ifa_valid; + } + + rta = RTA_NEXT(rta, alen); } - rta = RTA_NEXT(rta, alen); - } + if (ifa->ifa_flags & IFA_F_DEPRECATED) + addrs[ret].preferred = 0; - if (ifa->ifa_flags & IFA_F_DEPRECATED) - addrs[ret].preferred = 0; + ++ret; + break; + } + case NLMSG_DONE: + goto out; + default: + syslog(LOG_WARNING, "Unexpected rtnetlink message (%d) in response to IPv6 address dump", nhm->nlmsg_type); + ret = -1; + goto out; + } - ++ret; } - +out: return ret; } -- 2.11.0