/* 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;
*/
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;
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)