Logo Search packages:      
Sourcecode: libnl version File versions  Download package

int nl_recv ( struct nl_handle *  handle,
struct sockaddr_nl nla,
unsigned char **  buf 
)

Receive netlink message from netlink socket.

  • handle Netlink handle.
  • nla Destination pointer for peer's netlink address.
  • buf Destination pointer for message content.
Receives a netlink message, allocates a buffer in *buf and stores the message content. The peer's netlink address is stored in *nla. The caller is responsible for freeing the buffer allocated in *buf if a positive value is returned. Interruped system calls are handled by repeating the read. The input buffer size is determined by peeking before the actual read is done.

A non-blocking sockets causes the function to return immediately if no data is available.

Returns:
Number of octets read, 0 on EOF or a negative error code.

Definition at line 605 of file nl.c.

Referenced by nl_recvmsgs().

{
      int n;
      int flags = MSG_PEEK;

      struct iovec iov = {
            .iov_len = 4096,
      };

      struct msghdr msg = {
            .msg_name = (void *) nla,
            .msg_namelen = sizeof(sizeof(struct sockaddr_nl)),
            .msg_iov = &iov,
            .msg_iovlen = 1,
            .msg_control = NULL,
            .msg_controllen = 0,
            .msg_flags = 0,
      };

      iov.iov_base = *buf = calloc(1, iov.iov_len);

retry:

      if ((n = recvmsg(handle->h_fd, &msg, flags)) <= 0) {
            if (!n)
                  goto abort;
            else if (n < 0) {
                  if (errno == EINTR)
                        goto retry;
                  else if (errno == EAGAIN)
                        goto abort;
                  else {
                        free(*buf);
                        return nl_error(errno, "recvmsg failed");
                  }
            }
      }
      
      if (iov.iov_len < n) {
            /* Provided buffer is not long enough, enlarge it
             * and try again. */
            iov.iov_len *= 2;
            iov.iov_base = *buf = realloc(*buf, iov.iov_len);
            goto retry;
      } else if (flags != 0) {
            /* Buffer is big enough, do the actual reading */
            flags = 0;
            goto retry;
      }

      if (msg.msg_namelen != sizeof(struct sockaddr_nl)) {
            free(*buf);
            return nl_error(EADDRNOTAVAIL, "socket address size mismatch");
      }

      return n;

abort:
      free(*buf);
      return 0;
}


Generated by  Doxygen 1.6.0   Back to index