chiark / gitweb /
rtnl: fix sockaddr confusion
[elogind.git] / src / libsystemd-rtnl / rtnl-message.c
index 17183ab9130d84d2998ce7e73026f2259adce283..eae73a65b47bdd2034364b1a149aa790ec5e0ddd 100644 (file)
@@ -344,13 +344,19 @@ static int message_receive_need(sd_rtnl *rtnl, size_t *need) {
 
 /* returns the number of bytes sent, or a negative error code */
 int socket_write_message(sd_rtnl *nl, sd_rtnl_message *m) {
+        union {
+                struct sockaddr sa;
+                struct sockaddr_nl nl;
+        } addr = {
+                .nl.nl_family = AF_NETLINK,
+        };
         ssize_t k;
 
         assert_return(nl, -EINVAL);
         assert_return(m, -EINVAL);
 
         k = sendto(nl->fd, m->hdr, m->hdr->nlmsg_len,
-                        0, &nl->sockaddr.sa, sizeof(nl->sockaddr));
+                        0, &addr.sa, sizeof(addr));
         if (k < 0)
                 return (errno == EAGAIN) ? 0 : -errno;
 
@@ -364,7 +370,11 @@ int socket_write_message(sd_rtnl *nl, sd_rtnl_message *m) {
  */
 int socket_read_message(sd_rtnl *nl, sd_rtnl_message **ret) {
         sd_rtnl_message *m;
-        socklen_t addr_len = sizeof(nl->sockaddr);
+        union {
+                struct sockaddr sa;
+                struct sockaddr_nl nl;
+        } addr;
+        socklen_t addr_len;
         int r;
         ssize_t k;
         size_t need;
@@ -380,34 +390,23 @@ int socket_read_message(sd_rtnl *nl, sd_rtnl_message **ret) {
         if (r < 0)
                 return r;
 
-        r = message_receive_need(nl, &need);
-        if (r < 0)
-                return r;
-
-        m->hdr = realloc(m->hdr, need);
-        if (!m->hdr)
-                return -ENOMEM;
+        addr_len = sizeof(addr);
 
         k = recvfrom(nl->fd, m->hdr, need,
-                        0, &nl->sockaddr.sa, &addr_len);
+                        0, &addr.sa, &addr_len);
         if (k < 0)
-                k = (errno == EAGAIN) ? 0 : -errno; /* no data? weird... */
+                k = (errno == EAGAIN) ? 0 : -errno; /* no data */
         else if (k == 0)
                 k = -ECONNRESET; /* connection was closed by the kernel */
-        else if (addr_len != sizeof(nl->sockaddr.nl) ||
-                        nl->sockaddr.nl.nl_family != AF_NETLINK)
+        else if (addr_len != sizeof(addr.nl) ||
+                        addr.nl.nl_family != AF_NETLINK)
                 k = -EIO; /* not a netlink message */
-        else if (nl->sockaddr.nl.nl_pid != 0)
+        else if (addr.nl.nl_pid != 0)
                 k = 0; /* not from the kernel */
         else if ((size_t) k < sizeof(struct nlmsghdr) ||
                         (size_t) k < m->hdr->nlmsg_len)
                 k = -EIO; /* too small (we do accept too big though) */
-        else if (m->hdr->nlmsg_type == NLMSG_NOOP)
-                k = 0;
-        else if (m->hdr->nlmsg_type == NLMSG_ERROR &&
-                        m->hdr->nlmsg_len < NLMSG_LENGTH(sizeof(struct nlmsgerr)))
-                k = -EIO;
-        else if ((pid_t) m->hdr->nlmsg_pid != getpid())
+        else if (m->hdr->nlmsg_pid != nl->sockaddr.nl.nl_pid)
                 k = 0; /* not for us */
 
         if (k > 0)