/* SPDX-License-Identifier: LGPL-2.1-only */
/*
 * Copyright (c) 2003-2012 Thomas Graf <tgraf@suug.ch>
 */

/**
 * @defgroup core Core Library (libnl)
 *
 * Socket handling, connection management, sending and receiving of data,
 * message construction and parsing, object caching system, ...
 *
 * This is the API reference of the core library. It is not meant as a guide
 * but as a reference. Please refer to the core library guide for detailed
 * documentation on the library architecture and examples:
 *
 * * @ref_asciidoc{core,_,Netlink Core Library Development Guide}
 *
 *
 * @{
 */

#include "nl-default.h"

#include <linux/socket.h>

#include <netlink/netlink.h>
#include <netlink/utils.h>
#include <netlink/handlers.h>
#include <netlink/msg.h>
#include <netlink/attr.h>

#include "nl-core.h"
#include "nl-priv-dynamic-core/nl-core.h"
#include "nl-aux-core/nl-core.h"
#include "nl-priv-dynamic-core/cache-api.h"

/**
 * @defgroup core_types Data Types
 *
 * Core library data types
 * @{
 * @}
 *
 * @defgroup send_recv Send & Receive Data
 *
 * Connection management, sending & receiving of data
 *
 * Related sections in the development guide:
 * - @core_doc{core_send_recv, Sending & Receiving}
 * - @core_doc{core_sockets, Sockets}
 *
 * @{
 *
 * Header
 * ------
 * ~~~~{.c}
 * #include <netlink/netlink.h>
 * ~~~~
 */

/**
 * @name Connection Management
 * @{
 */

/**
 * Create file descriptor and bind socket.
 * @arg sk		Netlink socket (required)
 * @arg protocol	Netlink protocol to use (required)
 *
 * Creates a new Netlink socket using `socket()` and binds the socket to the
 * protocol and local port specified in the `sk` socket object. Fails if
 * the socket is already connected.
 *
 * @note If available, the `close-on-exec` (`SOCK_CLOEXEC`) feature is enabled
 *       automatically on the new file descriptor. This causes the socket to
 *       be closed automatically if any of the `exec` family functions succeed.
 *       This is essential for multi threaded programs.
 *
 * @note The local port (`nl_socket_get_local_port()`) is unspecified after
 *       creating a new socket. It only gets determined when accessing the
 *       port the first time or during `nl_connect()`. When nl_connect()
 *       fails during `bind()` due to `ADDRINUSE`, it will retry with
 *       different ports if the port is unspecified. Unless you want to enforce
 *       the use of a specific local port, don't access the local port (or
 *       reset it to `unspecified` by calling `nl_socket_set_local_port(sk, 0)`).
 *       This capability is indicated by
 *       `%NL_CAPABILITY_NL_CONNECT_RETRY_GENERATE_PORT_ON_ADDRINUSE`.
 *
 * @note nl_connect() creates and sets the file descriptor. You can setup the file
 *       descriptor yourself by creating and binding it, and then calling
 *       nl_socket_set_fd(). The result will be the same.
 *
 * @see nl_socket_alloc()
 * @see nl_close()
 * @see nl_socket_set_fd()
 *
 * @return 0 on success or a negative error code.
 *
 * @retval -NLE_BAD_SOCK Socket is already connected
 */
int nl_connect(struct nl_sock *sk, int protocol)
{
	int err, flags = 0;
	int errsv;
	socklen_t addrlen;
	struct sockaddr_nl local = { 0 };
	int try_bind = 1;

#ifdef SOCK_CLOEXEC
	flags |= SOCK_CLOEXEC;
#endif

	if (sk->s_fd != -1)
		return -NLE_BAD_SOCK;

	sk->s_fd = socket(AF_NETLINK, SOCK_RAW | flags, protocol);
	if (sk->s_fd < 0) {
		errsv = errno;
		NL_DBG(4, "nl_connect(%p): socket() failed with %d (%s)\n", sk, errsv,
			nl_strerror_l(errsv));
		err = -nl_syserr2nlerr(errsv);
		goto errout;
	}

	err = nl_socket_set_buffer_size(sk, 0, 0);
	if (err < 0)
		goto errout;

	if (_nl_socket_is_local_port_unspecified (sk)) {
		uint32_t port;
		uint32_t used_ports[32] = { 0 };
		int ntries = 0;

		while (1) {
			if (ntries++ > 5) {
				/* try only a few times. We hit this only if many ports are already in
				 * use but allocated *outside* libnl/generate_local_port(). */
				_nl_socket_set_local_port_no_release (sk, 0);
				break;
			}

			port = _nl_socket_set_local_port_no_release(sk, 1);
			if (port == 0)
				break;

			err = bind(sk->s_fd, (struct sockaddr*) &sk->s_local,
				   sizeof(sk->s_local));
			if (err == 0) {
				try_bind = 0;
				break;
			}

			errsv = errno;
			if (errsv == EADDRINUSE) {
				NL_DBG(4, "nl_connect(%p): local port %u already in use. Retry.\n", sk, (unsigned) port);
				_nl_socket_used_ports_set(used_ports, port);
			} else {
				NL_DBG(4, "nl_connect(%p): bind() for port %u failed with %d (%s)\n",
					sk, (unsigned) port, errsv, nl_strerror_l(errsv));
				_nl_socket_used_ports_release_all(used_ports);
				err = -nl_syserr2nlerr(errsv);
				goto errout;
			}
		}
		_nl_socket_used_ports_release_all(used_ports);
	}
	if (try_bind) {
		err = bind(sk->s_fd, (struct sockaddr*) &sk->s_local,
			   sizeof(sk->s_local));
		if (err != 0) {
			errsv = errno;
			NL_DBG(4, "nl_connect(%p): bind() failed with %d (%s)\n",
				sk, errsv, nl_strerror_l(errsv));
			err = -nl_syserr2nlerr(errsv);
			goto errout;
		}
	}

	addrlen = sizeof(local);
	err = getsockname(sk->s_fd, (struct sockaddr *) &local,
			  &addrlen);
	if (err < 0) {
		NL_DBG(4, "nl_connect(%p): getsockname() failed with %d (%s)\n",
			sk, errno, nl_strerror_l(errno));
		err = -nl_syserr2nlerr(errno);
		goto errout;
	}

	if (addrlen != sizeof(local)) {
		err = -NLE_NOADDR;
		goto errout;
	}

	if (local.nl_family != AF_NETLINK) {
		err = -NLE_AF_NOSUPPORT;
		goto errout;
	}

	if (sk->s_local.nl_pid != local.nl_pid) {
		/* The port id is different. That can happen if the port id was zero
		 * and kernel assigned a local port. */
		nl_socket_set_local_port (sk, local.nl_pid);
	}
	sk->s_local = local;
	sk->s_proto = protocol;

	return 0;
errout:
	if (sk->s_fd != -1) {
		close(sk->s_fd);
		sk->s_fd = -1;
	}

	return err;
}

/**
 * Close Netlink socket
 * @arg sk		Netlink socket (required)
 *
 * Closes the Netlink socket using `close()`.
 *
 * @note The socket is closed automatically if a `struct nl_sock` object is
 *       freed using `nl_socket_free()`.
 *
 * @see nl_connect()
 */
void nl_close(struct nl_sock *sk)
{
	if (sk->s_fd >= 0) {
		close(sk->s_fd);
		sk->s_fd = -1;
	}

	sk->s_proto = 0;
}

/** @} */

/**
 * @name Send
 * @{
 */

/**
 * Transmit raw data over Netlink socket.
 * @arg sk		Netlink socket (required)
 * @arg buf		Buffer carrying data to send (required)
 * @arg size		Size of buffer (required)
 *
 * Transmits "raw" data over the specified Netlink socket. Unlike the other
 * transmit functions it does not modify the data in any way. It directly
 * passes the buffer \c buf of \c size to sendto().
 *
 * The message is addressed to the peer as specified in the socket by either
 * the nl_socket_set_peer_port() or nl_socket_set_peer_groups() function.
 *
 * @note Because there is no indication on the message boundaries of the data
 *       being sent, the \c NL_CB_MSG_OUT callback handler will not be invoked
 *       for data that is being sent using this function.
 *
 * @see nl_socket_set_peer_port()
 * @see nl_socket_set_peer_groups()
 * @see nl_sendmsg()
 *
 * @return Number of bytes sent or a negative error code.
 */
int nl_sendto(struct nl_sock *sk, void *buf, size_t size)
{
	int ret;

	if (!buf)
		return -NLE_INVAL;

	if (sk->s_fd < 0)
		return -NLE_BAD_SOCK;

	ret = sendto(sk->s_fd, buf, size, 0, (struct sockaddr *)
		     &sk->s_peer, sizeof(sk->s_peer));
	if (ret < 0) {
		NL_DBG(4, "nl_sendto(%p): sendto() failed with %d (%s)\n",
			sk, errno, nl_strerror_l(errno));
		return -nl_syserr2nlerr(errno);
	}

	return ret;
}

/**
 * Transmit Netlink message using sendmsg()
 * @arg sk		Netlink socket (required)
 * @arg msg		Netlink message to be sent (required)
 * @arg hdr		sendmsg() message header (required)
 *
 * Transmits the message specified in \c hdr over the Netlink socket using the
 * sendmsg() system call.
 *
 * @attention
 * The `msg` argument will *not* be used to derive the message payload that
 * is being sent out. The `msg` argument is *only* passed on to the
 * `NL_CB_MSG_OUT` callback. The caller is responsible to initialize the
 * `hdr` struct properly and have it point to the message payload and
 * socket address.
 *
 * @note
 * This function uses `nlmsg_set_src()` to modify the `msg` argument prior to
 * invoking the `NL_CB_MSG_OUT` callback to provide the local port number.
 *
 * @callback This function triggers the `NL_CB_MSG_OUT` callback.
 *
 * @attention
 * Think twice before using this function. It provides a low level access to
 * the Netlink socket. Among other limitations, it does not add credentials
 * even if enabled or respect the destination address specified in the `msg`
 * object.
 *
 * @see nl_socket_set_local_port()
 * @see nl_send_auto()
 * @see nl_send_iovec()
 *
 * @return Number of bytes sent on success or a negative error code.
 *
 * @lowlevel
 */
int nl_sendmsg(struct nl_sock *sk, struct nl_msg *msg, struct msghdr *hdr)
{
	struct nl_cb *cb;
	int ret;

	if (sk->s_fd < 0)
		return -NLE_BAD_SOCK;

	nlmsg_set_src(msg, &sk->s_local);

	cb = sk->s_cb;
	if (cb->cb_set[NL_CB_MSG_OUT])
		if ((ret = nl_cb_call(cb, NL_CB_MSG_OUT, msg)) != NL_OK)
			return ret;

	ret = sendmsg(sk->s_fd, hdr, 0);
	if (ret < 0) {
		NL_DBG(4, "nl_sendmsg(%p): sendmsg() failed with %d (%s)\n",
			sk, errno, nl_strerror_l(errno));
		return -nl_syserr2nlerr(errno);
	}

	NL_DBG(4, "sent %d bytes\n", ret);
	return ret;
}


/**
 * Transmit Netlink message (taking IO vector)
 * @arg sk		Netlink socket (required)
 * @arg msg		Netlink message to be sent (required)
 * @arg iov		IO vector to be sent (required)
 * @arg iovlen		Number of struct iovec to be sent (required)
 *
 * This function is identical to nl_send() except that instead of taking a
 * `struct nl_msg` object it takes an IO vector. Please see the description
 * of `nl_send()`.
 *
 * @callback This function triggers the `NL_CB_MSG_OUT` callback.
 *
 * @see nl_send()
 *
 * @return Number of bytes sent on success or a negative error code.
 *
 * @lowlevel
 */
int nl_send_iovec(struct nl_sock *sk, struct nl_msg *msg, struct iovec *iov, unsigned iovlen)
{
	struct sockaddr_nl *dst;
	struct ucred *creds;
	struct msghdr hdr = {
		.msg_name = (void *) &sk->s_peer,
		.msg_namelen = sizeof(struct sockaddr_nl),
		.msg_iov = iov,
		.msg_iovlen = iovlen,
	};
	char buf[CMSG_SPACE(sizeof(struct ucred))];

	/* Overwrite destination if specified in the message itself, defaults
	 * to the peer address of the socket.
	 */
	dst = nlmsg_get_dst(msg);
	if (dst->nl_family == AF_NETLINK)
		hdr.msg_name = dst;

	/* Add credentials if present. */
	creds = nlmsg_get_creds(msg);
	if (creds != NULL) {
		struct cmsghdr *cmsg;

		hdr.msg_control = buf;
		hdr.msg_controllen = sizeof(buf);

		cmsg = CMSG_FIRSTHDR(&hdr);
		cmsg->cmsg_level = SOL_SOCKET;
		cmsg->cmsg_type = SCM_CREDENTIALS;
		cmsg->cmsg_len = CMSG_LEN(sizeof(struct ucred));
		memcpy(CMSG_DATA(cmsg), creds, sizeof(struct ucred));
	}

	return nl_sendmsg(sk, msg, &hdr);
}

/**
 * Transmit Netlink message
 * @arg sk		Netlink socket (required)
 * @arg msg		Netlink message (required)
 *
 * Transmits the Netlink message `msg` over the Netlink socket using the
 * `sendmsg()` system call. This function is based on `nl_send_iovec()` but
 * takes care of initializing a `struct iovec` based on the `msg` object.
 *
 * The message is addressed to the peer as specified in the socket by either
 * the nl_socket_set_peer_port() or nl_socket_set_peer_groups() function.
 * The peer address can be overwritten by specifying an address in the `msg`
 * object using nlmsg_set_dst().
 *
 * If present in the `msg`, credentials set by the nlmsg_set_creds() function
 * are added to the control buffer of the message.
 *
 * @par Overwriting Capability:
 * Calls to this function can be overwritten by providing an alternative using
 * the nl_cb_overwrite_send() function.
 *
 * @callback This function triggers the `NL_CB_MSG_OUT` callback.
 *
 * @attention
 * Unlike `nl_send_auto()`, this function does *not* finalize the message in
 * terms of automatically adding needed flags or filling out port numbers.
 *
 * @see nl_send_auto()
 * @see nl_send_iovec()
 * @see nl_socket_set_peer_port()
 * @see nl_socket_set_peer_groups()
 * @see nlmsg_set_dst()
 * @see nlmsg_set_creds()
 * @see nl_cb_overwrite_send()
 *
 * @return Number of bytes sent on success or a negative error code.
*/
int nl_send(struct nl_sock *sk, struct nl_msg *msg)
{
	struct nl_cb *cb = sk->s_cb;

	if (cb->cb_send_ow)
		return cb->cb_send_ow(sk, msg);
	else {
		struct iovec iov = {
			.iov_base = (void *) nlmsg_hdr(msg),
			.iov_len = nlmsg_hdr(msg)->nlmsg_len,
		};

		return nl_send_iovec(sk, msg, &iov, 1);
	}
}

/**
 * Finalize Netlink message
 * @arg sk		Netlink socket (required)
 * @arg msg		Netlink message (required)
 *
 * This function finalizes a Netlink message by completing the message with
 * desirable flags and values depending on the socket configuration.
 *
 *  - If not yet filled out, the source address of the message (`nlmsg_pid`)
 *    will be set to the local port number of the socket.
 *  - If not yet specified, the next available sequence number is assigned
 *    to the message (`nlmsg_seq`).
 *  - If not yet specified, the protocol field of the message will be set to
 *    the protocol field of the socket.
 *  - The `NLM_F_REQUEST` Netlink message flag will be set.
 *  - The `NLM_F_ACK` flag will be set if Auto-ACK mode is enabled on the
 *    socket.
 */
void nl_complete_msg(struct nl_sock *sk, struct nl_msg *msg)
{
	struct nlmsghdr *nlh;

	nlh = nlmsg_hdr(msg);
	if (nlh->nlmsg_pid == NL_AUTO_PORT)
		nlh->nlmsg_pid = nl_socket_get_local_port(sk);

	if (nlh->nlmsg_seq == NL_AUTO_SEQ)
		nlh->nlmsg_seq = nl_socket_use_seq(sk);

	if (msg->nm_protocol == -1)
		msg->nm_protocol = sk->s_proto;

	nlh->nlmsg_flags |= NLM_F_REQUEST;

	if (!(sk->s_flags & NL_NO_AUTO_ACK))
		nlh->nlmsg_flags |= NLM_F_ACK;
}

/**
 * Finalize and transmit Netlink message
 * @arg sk		Netlink socket (required)
 * @arg msg		Netlink message (required)
 *
 * Finalizes the message by passing it to `nl_complete_msg()` and transmits it
 * by passing it to `nl_send()`.
 *
 * @callback This function triggers the `NL_CB_MSG_OUT` callback.
 *
 * @see nl_complete_msg()
 * @see nl_send()
 *
 * @return Number of bytes sent or a negative error code.
 */
int nl_send_auto(struct nl_sock *sk, struct nl_msg *msg)
{
	nl_complete_msg(sk, msg);

	return nl_send(sk, msg);
}

/**
 * Finalize and transmit Netlink message and wait for ACK or error message
 * @arg sk		Netlink socket (required)
 * @arg msg		Netlink message (required)
 *
 * Passes the `msg` to `nl_send_auto()` to finalize and transmit it. Frees the
 * message and waits (sleeps) for the ACK or error message to be received.
 *
 * @attention
 * Disabling Auto-ACK (nl_socket_disable_auto_ack()) will cause this function
 * to return immediately after transmitting the message. However, the peer may
 * still be returning an error message in response to the request. It is the
 * responsibility of the caller to handle such messages.
 *
 * @callback This function triggers the `NL_CB_MSG_OUT` callback.
 *
 * @attention
 * This function frees the `msg` object after transmitting it by calling
 * `nlmsg_free()`.
 *
 * @see nl_send_auto().
 * @see nl_wait_for_ack()
 *
 * @return 0 on success or a negative error code.
 */
int nl_send_sync(struct nl_sock *sk, struct nl_msg *msg)
{
	int err;

	err = nl_send_auto(sk, msg);
	nlmsg_free(msg);
	if (err < 0)
		return err;

	return wait_for_ack(sk);
}

/**
 * Construct and transmit a Netlink message
 * @arg sk		Netlink socket (required)
 * @arg type		Netlink message type (required)
 * @arg flags		Netlink message flags (optional)
 * @arg buf		Data buffer (optional)
 * @arg size		Size of data buffer (optional)
 *
 * Allocates a new Netlink message based on `type` and `flags`. If `buf`
 * points to payload of length `size` that payload will be appended to the
 * message.
 *
 * Sends out the message using `nl_send_auto()` and frees the message
 * afterwards.
 *
 * @see nl_send_auto()
 *
 * @return Number of characters sent on success or a negative error code.
 * @retval -NLE_NOMEM Unable to allocate Netlink message
 */
int nl_send_simple(struct nl_sock *sk, int type, int flags, void *buf,
		   size_t size)
{
	int err;
	struct nl_msg *msg;

	msg = nlmsg_alloc_simple(type, flags);
	if (!msg)
		return -NLE_NOMEM;

	if (buf && size) {
		err = nlmsg_append(msg, buf, size, NLMSG_ALIGNTO);
		if (err < 0)
			goto errout;
	}

	err = nl_send_auto(sk, msg);
errout:
	nlmsg_free(msg);

	return err;
}

/** @} */

/**
 * @name Receive
 * @{
 */

/**
 * Receive data from netlink socket
 * @arg sk		Netlink socket (required)
 * @arg nla		Netlink socket structure to hold address of peer (required)
 * @arg buf		Destination pointer for message content (required)
 * @arg creds		Destination pointer for credentials (optional)
 *
 * Receives data from a connected netlink socket using recvmsg() and returns
 * the number of bytes read. The read data is stored in a newly allocated
 * buffer that is assigned to \c *buf. The peer's netlink address will be
 * stored in \c *nla.
 *
 * This function blocks until data is available to be read unless the socket
 * has been put into non-blocking mode using nl_socket_set_nonblocking() in
 * which case this function will return immediately with a return value of
 * -NLA_AGAIN (versions before 3.2.22 returned instead 0, in which case you
 * should check first clear errno and then check for errno EAGAIN).
 *
 * The buffer size used when reading from the netlink socket and thus limiting
 * the maximum size of a netlink message that can be read defaults to the size
 * of a memory page (getpagesize()). The buffer size can be modified on a per
 * socket level using the function nl_socket_set_msg_buf_size().
 *
 * If message peeking is enabled using nl_socket_enable_msg_peek() the size of
 * the message to be read will be determined using the MSG_PEEK flag prior to
 * performing the actual read. This leads to an additional recvmsg() call for
 * every read operation which has performance implications and is not
 * recommended for high throughput protocols.
 *
 * An eventual interruption of the recvmsg() system call is automatically
 * handled by retrying the operation.
 *
 * If receiving of credentials has been enabled using the function
 * nl_socket_set_passcred(), this function will allocate a new struct ucred
 * filled with the received credentials and assign it to \c *creds. The caller
 * is responsible for freeing the buffer.
 *
 * @note The caller is responsible to free the returned data buffer and if
 *       enabled, the credentials buffer.
 *
 * @see nl_socket_set_nonblocking()
 * @see nl_socket_set_msg_buf_size()
 * @see nl_socket_enable_msg_peek()
 * @see nl_socket_set_passcred()
 *
 * @return Number of bytes read, 0 on EOF, 0 on no data event (non-blocking
 *         mode), or a negative error code.
 */
int nl_recv(struct nl_sock *sk, struct sockaddr_nl *nla,
	    unsigned char **buf, struct ucred **creds)
{
	ssize_t n;
	int flags = 0;
	static int page_size = 0; /* GLOBAL! */
	struct iovec iov;
	struct msghdr msg = {
		.msg_name = (void *) nla,
		.msg_namelen = sizeof(struct sockaddr_nl),
		.msg_iov = &iov,
		.msg_iovlen = 1,
	};
	struct ucred* tmpcreds = NULL;
	int retval = 0;

	if (!buf || !nla)
		return -NLE_INVAL;

	if (   (sk->s_flags & NL_MSG_PEEK)
	    || (!(sk->s_flags & NL_MSG_PEEK_EXPLICIT) && sk->s_bufsize == 0))
		flags |= MSG_PEEK | MSG_TRUNC;

	if (page_size == 0)
		page_size = getpagesize() * 4;

	iov.iov_len = sk->s_bufsize ? sk->s_bufsize : ((size_t)page_size);
	iov.iov_base = malloc(iov.iov_len);

	if (!iov.iov_base) {
		retval = -NLE_NOMEM;
		goto abort;
	}

	if (creds && (sk->s_flags & NL_SOCK_PASSCRED)) {
		msg.msg_controllen = CMSG_SPACE(sizeof(struct ucred));
		msg.msg_control = malloc(msg.msg_controllen);
		if (!msg.msg_control) {
			retval = -NLE_NOMEM;
			goto abort;
		}
	}
retry:

	n = recvmsg(sk->s_fd, &msg, flags);
	if (!n) {
		retval = 0;
		goto abort;
	}
	if (n < 0) {
		if (errno == EINTR) {
			NL_DBG(3, "recvmsg() returned EINTR, retrying\n");
			goto retry;
		}

		NL_DBG(4, "recvmsg(%p): nl_recv() failed with %d (%s)\n",
			sk, errno, nl_strerror_l(errno));
		retval = -nl_syserr2nlerr(errno);
		goto abort;
	}

	if (msg.msg_flags & MSG_CTRUNC) {
		void *tmp;

		if (msg.msg_controllen == 0) {
			retval = -NLE_MSG_TRUNC;
			NL_DBG(4, "recvmsg(%p): Received unexpected control data", sk);
			goto abort;
		}

		msg.msg_controllen *= 2;
		tmp = realloc(msg.msg_control, msg.msg_controllen);
		if (!tmp) {
			retval = -NLE_NOMEM;
			goto abort;
		}
		msg.msg_control = tmp;
		goto retry;
	}

	if (iov.iov_len < ((size_t)n) || (msg.msg_flags & MSG_TRUNC)) {
		void *tmp;

		/* respond with error to an incomplete message */
		if (flags == 0) {
			retval = -NLE_MSG_TRUNC;
			goto abort;
		}

		/* Provided buffer is not long enough, enlarge it
		 * to size of n (which should be total length of the message)
		 * and try again. */
		iov.iov_len = n;
		tmp = realloc(iov.iov_base, iov.iov_len);
		if (!tmp) {
			retval = -NLE_NOMEM;
			goto abort;
		}
		iov.iov_base = tmp;
		flags = 0;
		goto retry;
	}

	if (flags != 0) {
		/* Buffer is big enough, do the actual reading */
		flags = 0;
		goto retry;
	}

	if (msg.msg_namelen != sizeof(struct sockaddr_nl)) {
		retval =  -NLE_NOADDR;
		goto abort;
	}

	if (creds && (sk->s_flags & NL_SOCK_PASSCRED)) {
		struct cmsghdr *cmsg;

		for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
			if (cmsg->cmsg_level != SOL_SOCKET)
				continue;
			if (cmsg->cmsg_type != SCM_CREDENTIALS)
				continue;
			tmpcreds = malloc(sizeof(*tmpcreds));
			if (!tmpcreds) {
				retval = -NLE_NOMEM;
				goto abort;
			}
			memcpy(tmpcreds, CMSG_DATA(cmsg), sizeof(*tmpcreds));
			break;
		}
	}

	retval = n;
abort:
	free(msg.msg_control);

	if (retval <= 0) {
		free(iov.iov_base);
		iov.iov_base = NULL;
		free(tmpcreds);
		tmpcreds = NULL;
	} else
		*buf = iov.iov_base;

	if (creds)
		*creds = tmpcreds;

	return retval;
}

/** @cond SKIP */
#define NL_CB_CALL(cb, type, msg) \
do { \
	err = nl_cb_call(cb, type, msg); \
	switch (err) { \
	case NL_OK: \
		err = 0; \
		break; \
	case NL_SKIP: \
		goto skip; \
	case NL_STOP: \
		goto stop; \
	default: \
		goto out; \
	} \
} while (0)
/** @endcond */

static int recvmsgs(struct nl_sock *sk, struct nl_cb *cb)
{
	int n, err = 0, multipart = 0, interrupted = 0, nrecv = 0;
	unsigned char *buf = NULL;
	struct nlmsghdr *hdr;

	/*
	nla is passed on to not only to nl_recv() but may also be passed
	to a function pointer provided by the caller which may or may not
	initialize the variable. Thomas Graf.
	*/
	struct sockaddr_nl nla = {0};
	struct nl_msg *msg = NULL;
	struct ucred *creds = NULL;

continue_reading:
	NL_DBG(3, "Attempting to read from %p\n", sk);
	if (cb->cb_recv_ow)
		n = cb->cb_recv_ow(sk, &nla, &buf, &creds);
	else
		n = nl_recv(sk, &nla, &buf, &creds);

	if (n <= 0)
		return n;

	NL_DBG(3, "recvmsgs(%p): Read %d bytes\n", sk, n);

	hdr = (struct nlmsghdr *) buf;
	while (nlmsg_ok(hdr, n)) {
		NL_DBG(3, "recvmsgs(%p): Processing valid message...\n", sk);

		nlmsg_free(msg);
		msg = nlmsg_convert(hdr);
		if (!msg) {
			err = -NLE_NOMEM;
			goto out;
		}

		nlmsg_set_proto(msg, sk->s_proto);
		nlmsg_set_src(msg, &nla);
		if (creds)
			nlmsg_set_creds(msg, creds);

		nrecv++;

		/* Raw callback is the first, it gives the most control
		 * to the user and he can do his very own parsing. */
		if (cb->cb_set[NL_CB_MSG_IN])
			NL_CB_CALL(cb, NL_CB_MSG_IN, msg);

		/* Sequence number checking. The check may be done by
		 * the user, otherwise a very simple check is applied
		 * enforcing strict ordering */
		if (cb->cb_set[NL_CB_SEQ_CHECK]) {
			NL_CB_CALL(cb, NL_CB_SEQ_CHECK, msg);

		/* Only do sequence checking if auto-ack mode is enabled */
		} else if (!(sk->s_flags & NL_NO_AUTO_ACK)) {
			if (hdr->nlmsg_seq != sk->s_seq_expect) {
				if (cb->cb_set[NL_CB_INVALID])
					NL_CB_CALL(cb, NL_CB_INVALID, msg);
				else {
					err = -NLE_SEQ_MISMATCH;
					goto out;
				}
			}
		}

		if (hdr->nlmsg_type == NLMSG_DONE ||
		    hdr->nlmsg_type == NLMSG_ERROR ||
		    hdr->nlmsg_type == NLMSG_NOOP ||
		    hdr->nlmsg_type == NLMSG_OVERRUN) {
			/* We can't check for !NLM_F_MULTI since some netlink
			 * users in the kernel are broken. */
			sk->s_seq_expect++;
			NL_DBG(3, "recvmsgs(%p): Increased expected " \
			       "sequence number to %d\n",
			       sk, sk->s_seq_expect);
		}

		if (hdr->nlmsg_flags & NLM_F_MULTI)
			multipart = 1;

		if (hdr->nlmsg_flags & NLM_F_DUMP_INTR) {
			if (cb->cb_set[NL_CB_DUMP_INTR])
				NL_CB_CALL(cb, NL_CB_DUMP_INTR, msg);
			else {
				/*
				 * We have to continue reading to clear
				 * all messages until a NLMSG_DONE is
				 * received and report the inconsistency.
				 */
				interrupted = 1;
			}
		}

		/* Other side wishes to see an ack for this message */
		if (hdr->nlmsg_flags & NLM_F_ACK) {
			if (cb->cb_set[NL_CB_SEND_ACK])
				NL_CB_CALL(cb, NL_CB_SEND_ACK, msg);
			else {
				/* FIXME: implement */
			}
		}

		/* messages terminates a multipart message, this is
		 * usually the end of a message and therefore we slip
		 * out of the loop by default. the user may overrule
		 * this action by skipping this packet. */
		if (hdr->nlmsg_type == NLMSG_DONE) {
			multipart = 0;
			if (cb->cb_set[NL_CB_FINISH])
				NL_CB_CALL(cb, NL_CB_FINISH, msg);
		}

		/* Message to be ignored, the default action is to
		 * skip this message if no callback is specified. The
		 * user may overrule this action by returning
		 * NL_PROCEED. */
		else if (hdr->nlmsg_type == NLMSG_NOOP) {
			if (cb->cb_set[NL_CB_SKIPPED])
				NL_CB_CALL(cb, NL_CB_SKIPPED, msg);
			else
				goto skip;
		}

		/* Data got lost, report back to user. The default action is to
		 * quit parsing. The user may overrule this action by retuning
		 * NL_SKIP or NL_PROCEED (dangerous) */
		else if (hdr->nlmsg_type == NLMSG_OVERRUN) {
			if (cb->cb_set[NL_CB_OVERRUN])
				NL_CB_CALL(cb, NL_CB_OVERRUN, msg);
			else {
				err = -NLE_MSG_OVERFLOW;
				goto out;
			}
		}

		/* Message carries a nlmsgerr */
		else if (hdr->nlmsg_type == NLMSG_ERROR) {
			struct nlmsgerr *e = nlmsg_data(hdr);

			if (hdr->nlmsg_len <
			    ((unsigned)nlmsg_size(sizeof(*e)))) {
				/* Truncated error message, the default action
				 * is to stop parsing. The user may overrule
				 * this action by returning NL_SKIP or
				 * NL_PROCEED (dangerous) */
				if (cb->cb_set[NL_CB_INVALID])
					NL_CB_CALL(cb, NL_CB_INVALID, msg);
				else {
					err = -NLE_MSG_TRUNC;
					goto out;
				}
			} else if (e->error) {
				NL_DBG(4, "recvmsgs(%p): RTNETLINK responded with %d (%s)\n",
					sk, -e->error, nl_strerror_l(-e->error));

				/* Error message reported back from kernel. */
				if (cb->cb_err) {
					err = cb->cb_err(&nla, e,
							 cb->cb_err_arg);
					if (err < 0)
						goto out;
					else if (err == NL_SKIP)
						goto skip;
					else if (err == NL_STOP) {
						err = -nl_syserr2nlerr(e->error);
						goto out;
					}
				} else {
					err = -nl_syserr2nlerr(e->error);
					goto out;
				}
			} else if (cb->cb_set[NL_CB_ACK])
				NL_CB_CALL(cb, NL_CB_ACK, msg);
		} else {
			/* Valid message (not checking for MULTIPART bit to
			 * get along with broken kernels. NL_SKIP has no
			 * effect on this.  */
			if (cb->cb_set[NL_CB_VALID])
				NL_CB_CALL(cb, NL_CB_VALID, msg);
		}
skip:
		err = 0;
		hdr = nlmsg_next(hdr, &n);
	}

	nlmsg_free(msg);
	free(buf);
	free(creds);
	buf = NULL;
	msg = NULL;
	creds = NULL;

	if (multipart) {
		/* Multipart message not yet complete, continue reading */
		goto continue_reading;
	}
stop:
	err = 0;
out:
	nlmsg_free(msg);
	free(buf);
	free(creds);

	if (interrupted)
		err = -NLE_DUMP_INTR;

	if (!err)
		err = nrecv;

	return err;
}

/**
 * Receive a set of messages from a netlink socket and report parsed messages
 * @arg sk		Netlink socket.
 * @arg cb		set of callbacks to control behaviour.
 *
 * This function is identical to nl_recvmsgs() to the point that it will
 * return the number of parsed messages instead of 0 on success.
 *
 * @see nl_recvmsgs()
 *
 * @return Number of received messages or a negative error code from nl_recv().
 */
int nl_recvmsgs_report(struct nl_sock *sk, struct nl_cb *cb)
{
	if (cb->cb_recvmsgs_ow)
		return cb->cb_recvmsgs_ow(sk, cb);
	else
		return recvmsgs(sk, cb);
}

/**
 * Receive a set of messages from a netlink socket.
 * @arg sk		Netlink socket.
 * @arg cb		set of callbacks to control behaviour.
 *
 * Repeatedly calls nl_recv() or the respective replacement if provided
 * by the application (see nl_cb_overwrite_recv()) and parses the
 * received data as netlink messages. Stops reading if one of the
 * callbacks returns NL_STOP or nl_recv returns either 0 or a negative error code.
 *
 * A non-blocking sockets causes the function to return immediately if
 * no data is available.
 *
 * @see nl_recvmsgs_report()
 *
 * @return 0 on success or a negative error code from nl_recv().
 */
int nl_recvmsgs(struct nl_sock *sk, struct nl_cb *cb)
{
	int err;

	if ((err = nl_recvmsgs_report(sk, cb)) > 0)
		err = 0;

	return err;
}

/**
 * Receive a set of message from a netlink socket using handlers in nl_sock.
 * @arg sk		Netlink socket.
 *
 * Calls nl_recvmsgs() with the handlers configured in the netlink socket.
 */
int nl_recvmsgs_default(struct nl_sock *sk)
{
	return nl_recvmsgs(sk, sk->s_cb);

}

static int ack_wait_handler(struct nl_msg *msg, void *arg)
{
	return NL_STOP;
}

/**
 * Wait for ACK.
 * @arg sk		Netlink socket.
 * @pre The netlink socket must be in blocking state.
 *
 * Waits until an ACK is received for the latest not yet acknowledged
 * netlink message.
 */
int nl_wait_for_ack(struct nl_sock *sk)
{
	int err;
	struct nl_cb *cb;

	cb = nl_cb_clone(sk->s_cb);
	if (cb == NULL)
		return -NLE_NOMEM;

	nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_wait_handler, NULL);
	err = nl_recvmsgs(sk, cb);
	nl_cb_put(cb);

	return err;
}

/** @cond SKIP */
struct pickup_param
{
	int (*parser)(struct nl_cache_ops *, struct sockaddr_nl *,
		      struct nlmsghdr *, struct nl_parser_param *);
	struct nl_object *result;
	int *syserror;
};

static int __store_answer(struct nl_object *obj, struct nl_parser_param *p)
{
	struct pickup_param *pp = p->pp_arg;
	/*
	 * the parser will put() the object at the end, expecting the cache
	 * to take the reference.
	 */
	nl_object_get(obj);
	pp->result =  obj;

	return 0;
}

static int __pickup_answer(struct nl_msg *msg, void *arg)
{
	struct pickup_param *pp = arg;
	struct nl_parser_param parse_arg = {
		.pp_cb = __store_answer,
		.pp_arg = pp,
	};

	return pp->parser(NULL, &msg->nm_src, msg->nm_nlh, &parse_arg);
}

static int __pickup_answer_syserr(struct sockaddr_nl *nla, struct nlmsgerr *nlerr, void *arg)
{
	*(((struct pickup_param *) arg)->syserror) = nlerr->error;

	return -nl_syserr2nlerr(nlerr->error);
}

/** @endcond */

/**
 * Pickup netlink answer, parse is and return object
 * @arg sk              Netlink socket
 * @arg parser          Parser function to parse answer
 * @arg result          Result pointer to return parsed object
 *
 * @return 0 on success or a negative error code.
 */
int nl_pickup(struct nl_sock *sk,
              int (*parser)(struct nl_cache_ops *, struct sockaddr_nl *,
                            struct nlmsghdr *, struct nl_parser_param *),
              struct nl_object **result)
{
	return nl_pickup_keep_syserr(sk, parser, result, NULL);
}

/**
 * Pickup netlink answer, parse is and return object with preserving system error
 * @arg sk              Netlink socket
 * @arg parser          Parser function to parse answer
 * @arg result          Result pointer to return parsed object
 * @arg syserr          Result pointer for the system error in case of failure
 *
 * @return 0 on success or a negative error code.
 */
int nl_pickup_keep_syserr(struct nl_sock *sk,
                          int (*parser)(struct nl_cache_ops *, struct sockaddr_nl *,
                                        struct nlmsghdr *, struct nl_parser_param *),
                          struct nl_object **result,
                          int *syserror)
{
	struct nl_cb *cb;
	int err;
	struct pickup_param pp = {
		.parser = parser,
	};

	cb = nl_cb_clone(sk->s_cb);
	if (cb == NULL)
		return -NLE_NOMEM;

	nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, __pickup_answer, &pp);
	if (syserror) {
		*syserror = 0;
		pp.syserror = syserror;
		nl_cb_err(cb, NL_CB_CUSTOM, __pickup_answer_syserr, &pp);
	}

	err = nl_recvmsgs(sk, cb);
	if (err < 0)
		goto errout;

	*result = pp.result;
errout:
	nl_cb_put(cb);

	return err;
}

/** @} */

/**
 * @name Deprecated
 * @{
 */

/**
 * @deprecated Please use nl_complete_msg()
 */
void nl_auto_complete(struct nl_sock *sk, struct nl_msg *msg)
{
	nl_complete_msg(sk, msg);
}

/**
 * @deprecated Please use nl_send_auto()
 */
int nl_send_auto_complete(struct nl_sock *sk, struct nl_msg *msg)
{
	return nl_send_auto(sk, msg);
}


/** @} */

/** @} */

/** @} */
