28 #include <netlink-local.h>
29 #include <netlink/netlink.h>
30 #include <netlink/utils.h>
31 #include <netlink/handlers.h>
32 #include <netlink/msg.h>
33 #include <netlink/attr.h>
82 flags |= SOCK_CLOEXEC;
85 sk->s_fd = socket(AF_NETLINK, SOCK_RAW | flags, protocol);
87 err = -nl_syserr2nlerr(errno);
91 if (!(sk->s_flags & NL_SOCK_BUFSIZE_SET)) {
97 err = bind(sk->s_fd, (
struct sockaddr*) &sk->s_local,
100 err = -nl_syserr2nlerr(errno);
104 addrlen =
sizeof(sk->s_local);
105 err = getsockname(sk->s_fd, (
struct sockaddr *) &sk->s_local,
108 err = -nl_syserr2nlerr(errno);
112 if (addrlen !=
sizeof(sk->s_local)) {
117 if (sk->s_local.nl_family != AF_NETLINK) {
118 err = -NLE_AF_NOSUPPORT;
122 sk->s_proto = protocol;
160 int nl_sendto(
struct nl_sock *sk,
void *buf,
size_t size)
164 ret = sendto(sk->s_fd, buf, size, 0, (
struct sockaddr *)
165 &sk->s_peer,
sizeof(sk->s_peer));
167 return -nl_syserr2nlerr(errno);
179 int nl_sendmsg(
struct nl_sock *sk,
struct nl_msg *msg,
struct msghdr *hdr)
184 nlmsg_set_src(msg, &sk->s_local);
191 ret = sendmsg(sk->s_fd, hdr, 0);
193 return -nl_syserr2nlerr(errno);
195 NL_DBG(4,
"sent %d bytes\n", ret);
209 int nl_send_iovec(
struct nl_sock *sk,
struct nl_msg *msg,
struct iovec *iov,
unsigned iovlen)
211 struct sockaddr_nl *dst;
213 struct msghdr hdr = {
214 .msg_name = (
void *) &sk->s_peer,
215 .msg_namelen =
sizeof(
struct sockaddr_nl),
217 .msg_iovlen = iovlen,
223 dst = nlmsg_get_dst(msg);
224 if (dst->nl_family == AF_NETLINK)
228 creds = nlmsg_get_creds(msg);
230 char buf[CMSG_SPACE(
sizeof(
struct ucred))];
231 struct cmsghdr *cmsg;
233 hdr.msg_control = buf;
234 hdr.msg_controllen =
sizeof(buf);
236 cmsg = CMSG_FIRSTHDR(&hdr);
237 cmsg->cmsg_level = SOL_SOCKET;
238 cmsg->cmsg_type = SCM_CREDENTIALS;
239 cmsg->cmsg_len = CMSG_LEN(
sizeof(
struct ucred));
240 memcpy(CMSG_DATA(cmsg), creds,
sizeof(
struct ucred));
255 int nl_send(
struct nl_sock *sk,
struct nl_msg *msg)
265 void nl_complete_msg(
struct nl_sock *sk,
struct nl_msg *msg)
267 struct nlmsghdr *nlh;
270 if (nlh->nlmsg_pid == 0)
271 nlh->nlmsg_pid = sk->s_local.nl_pid;
273 if (nlh->nlmsg_seq == 0)
274 nlh->nlmsg_seq = sk->s_seq_next++;
276 if (msg->nm_protocol == -1)
277 msg->nm_protocol = sk->s_proto;
279 nlh->nlmsg_flags |= NLM_F_REQUEST;
281 if (!(sk->s_flags & NL_NO_AUTO_ACK))
282 nlh->nlmsg_flags |= NLM_F_ACK;
285 void nl_auto_complete(
struct nl_sock *sk,
struct nl_msg *msg)
287 nl_complete_msg(sk, msg);
307 struct nl_cb *cb = sk->s_cb;
309 nl_complete_msg(sk, msg);
312 return cb->cb_send_ow(sk, msg);
317 int nl_send_auto_complete(
struct nl_sock *sk,
struct nl_msg *msg)
350 return wait_for_ack(sk);
384 err = nl_send_auto_complete(sk, msg);
417 int nl_recv(
struct nl_sock *sk,
struct sockaddr_nl *nla,
418 unsigned char **buf,
struct ucred **creds)
422 static int page_size = 0;
424 struct msghdr msg = {
425 .msg_name = (
void *) nla,
426 .msg_namelen =
sizeof(
struct sockaddr_nl),
433 struct cmsghdr *cmsg;
435 memset(nla, 0,
sizeof(*nla));
437 if (sk->s_flags & NL_MSG_PEEK)
438 flags |= MSG_PEEK | MSG_TRUNC;
441 page_size = getpagesize();
443 iov.iov_len = page_size;
444 iov.iov_base = *buf = malloc(iov.iov_len);
446 if (sk->s_flags & NL_SOCK_PASSCRED) {
447 msg.msg_controllen = CMSG_SPACE(
sizeof(
struct ucred));
448 msg.msg_control = calloc(1, msg.msg_controllen);
452 n = recvmsg(sk->s_fd, &msg, flags);
456 if (errno == EINTR) {
457 NL_DBG(3,
"recvmsg() returned EINTR, retrying\n");
459 }
else if (errno == EAGAIN) {
460 NL_DBG(3,
"recvmsg() returned EAGAIN, aborting\n");
463 free(msg.msg_control);
465 return -nl_syserr2nlerr(errno);
469 if (msg.msg_flags & MSG_CTRUNC) {
470 msg.msg_controllen *= 2;
471 msg.msg_control = realloc(msg.msg_control, msg.msg_controllen);
473 }
else if (iov.iov_len < n || msg.msg_flags & MSG_TRUNC) {
478 iov.iov_base = *buf = realloc(*buf, iov.iov_len);
481 }
else if (flags != 0) {
487 if (msg.msg_namelen !=
sizeof(
struct sockaddr_nl)) {
488 free(msg.msg_control);
493 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
494 if (cmsg->cmsg_level == SOL_SOCKET &&
495 cmsg->cmsg_type == SCM_CREDENTIALS) {
497 *creds = calloc(1,
sizeof(
struct ucred));
498 memcpy(*creds, CMSG_DATA(cmsg),
sizeof(
struct ucred));
504 free(msg.msg_control);
508 free(msg.msg_control);
514 #define NL_CB_CALL(cb, type, msg) \
516 err = nl_cb_call(cb, type, msg); \
531 static int recvmsgs(
struct nl_sock *sk,
struct nl_cb *cb)
533 int n, err = 0, multipart = 0, interrupted = 0, nrecv = 0;
534 unsigned char *buf = NULL;
535 struct nlmsghdr *hdr;
536 struct sockaddr_nl nla = {0};
537 struct nl_msg *msg = NULL;
538 struct ucred *creds = NULL;
541 NL_DBG(3,
"Attempting to read from %p\n", sk);
543 n = cb->cb_recv_ow(sk, &nla, &buf, &creds);
545 n =
nl_recv(sk, &nla, &buf, &creds);
550 NL_DBG(3,
"recvmsgs(%p): Read %d bytes\n", sk, n);
552 hdr = (
struct nlmsghdr *) buf;
554 NL_DBG(3,
"recvmsgs(%p): Processing valid message...\n", sk);
563 nlmsg_set_proto(msg, sk->s_proto);
564 nlmsg_set_src(msg, &nla);
566 nlmsg_set_creds(msg, creds);
582 }
else if (!(sk->s_flags & NL_NO_AUTO_ACK)) {
583 if (hdr->nlmsg_seq != sk->s_seq_expect) {
587 err = -NLE_SEQ_MISMATCH;
593 if (hdr->nlmsg_type == NLMSG_DONE ||
594 hdr->nlmsg_type == NLMSG_ERROR ||
595 hdr->nlmsg_type == NLMSG_NOOP ||
596 hdr->nlmsg_type == NLMSG_OVERRUN) {
600 NL_DBG(3,
"recvmsgs(%p): Increased expected " \
601 "sequence number to %d\n",
602 sk, sk->s_seq_expect);
605 if (hdr->nlmsg_flags & NLM_F_MULTI)
608 if (hdr->nlmsg_flags & NLM_F_DUMP_INTR) {
622 if (hdr->nlmsg_flags & NLM_F_ACK) {
634 if (hdr->nlmsg_type == NLMSG_DONE) {
644 else if (hdr->nlmsg_type == NLMSG_NOOP) {
654 else if (hdr->nlmsg_type == NLMSG_OVERRUN) {
658 err = -NLE_MSG_OVERFLOW;
664 else if (hdr->nlmsg_type == NLMSG_ERROR) {
667 if (hdr->nlmsg_len <
nlmsg_size(
sizeof(*e))) {
675 err = -NLE_MSG_TRUNC;
678 }
else if (e->error) {
681 err = cb->cb_err(&nla, e,
688 err = -nl_syserr2nlerr(e->error);
692 err = -nl_syserr2nlerr(e->error);
718 goto continue_reading;
728 err = -NLE_DUMP_INTR;
750 if (cb->cb_recvmsgs_ow)
751 return cb->cb_recvmsgs_ow(sk, cb);
753 return recvmsgs(sk, cb);
795 static int ack_wait_handler(
struct nl_msg *msg,
void *arg)
827 int (*parser)(
struct nl_cache_ops *,
struct sockaddr_nl *,
834 struct pickup_param *pp = p->
pp_arg;
845 static int __pickup_answer(
struct nl_msg *msg,
void *arg)
847 struct pickup_param *pp = arg;
849 .
pp_cb = __store_answer,
853 return pp->parser(NULL, &msg->nm_src, msg->nm_nlh, &parse_arg);
867 int (*parser)(
struct nl_cache_ops *,
struct sockaddr_nl *,
873 struct pickup_param pp = {