]> git.decadent.org.uk Git - odhcp6c.git/blobdiff - src/ra.c
Basic error checking when initializing ra
[odhcp6c.git] / src / ra.c
index aa03ff4d3ab8f6235b38aa8f069c785d3486a10e..64cc8d85ac7ab961382ac80f7aaf6c4557fa4030 100644 (file)
--- a/src/ra.c
+++ b/src/ra.c
@@ -59,13 +59,23 @@ int ra_init(const char *ifname, const struct in6_addr *ifid)
 {
        const pid_t ourpid = getpid();
        sock = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC, IPPROTO_ICMPV6);
+       if (sock < 0)
+               return -1;
+
        if_index = if_nametoindex(ifname);
+       if (!if_index)
+               return -1;
+
        strncpy(if_name, ifname, sizeof(if_name) - 1);
        lladdr = *ifid;
 
        rtnl = socket(AF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_ROUTE);
+       if (rtnl < 0)
+               return -1;
+
        struct sockaddr_nl rtnl_kernel = { .nl_family = AF_NETLINK };
-       connect(rtnl, (const struct sockaddr*)&rtnl_kernel, sizeof(rtnl_kernel));
+       if (connect(rtnl, (const struct sockaddr*)&rtnl_kernel, sizeof(rtnl_kernel)) < 0)
+               return -1;
 
        int val = RTNLGRP_LINK;
        setsockopt(rtnl, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &val, sizeof(val));
@@ -150,6 +160,7 @@ static void update_proc(const char *sect, const char *opt, uint32_t value)
 
 bool ra_link_up(void)
 {
+       static bool firstcall = true;
        struct {
                struct nlmsghdr hdr;
                struct ifinfomsg msg;
@@ -161,19 +172,22 @@ bool ra_link_up(void)
 
        do {
                read = recv(rtnl, &resp, sizeof(resp), MSG_DONTWAIT);
-               if (!NLMSG_OK(&resp.hdr, read) || resp.hdr.nlmsg_type != RTM_NEWLINK ||
+               if (read < 0 || !NLMSG_OK(&resp.hdr, (size_t)read) ||
+                               resp.hdr.nlmsg_type != RTM_NEWLINK ||
                                resp.msg.ifi_index != if_index)
                        continue;
 
                bool hascarrier = resp.msg.ifi_flags & IFF_LOWER_UP;
-               if (nocarrier && hascarrier)
+               if (!firstcall && nocarrier != !hascarrier)
                        ret = true;
 
                nocarrier = !hascarrier;
+               firstcall = false;
        } while (read > 0);
 
        if (ret) {
-               syslog(LOG_NOTICE, "carrier up event on %s", if_name);
+               syslog(LOG_NOTICE, "carrier => %i event on %s", (int)!nocarrier, if_name);
+
                rs_attempt = 0;
                ra_send_rs(SIGALRM);
        }