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>
84 flags |= SOCK_CLOEXEC;
90 sk->s_fd = socket(AF_NETLINK, SOCK_RAW | flags, protocol);
92 err = -nl_syserr2nlerr(errno);
96 if (!(sk->s_flags & NL_SOCK_BUFSIZE_SET)) {
102 err = bind(sk->s_fd, (
struct sockaddr*) &sk->s_local,
103 sizeof(sk->s_local));
105 err = -nl_syserr2nlerr(errno);
109 addrlen =
sizeof(sk->s_local);
110 err = getsockname(sk->s_fd, (
struct sockaddr *) &sk->s_local,
113 err = -nl_syserr2nlerr(errno);
117 if (addrlen !=
sizeof(sk->s_local)) {
122 if (sk->s_local.nl_family != AF_NETLINK) {
123 err = -NLE_AF_NOSUPPORT;
127 sk->s_proto = protocol;
131 if (sk->s_fd != -1) {
167 int nl_sendto(
struct nl_sock *sk,
void *buf,
size_t size)
171 ret = sendto(sk->s_fd, buf, size, 0, (
struct sockaddr *)
172 &sk->s_peer,
sizeof(sk->s_peer));
174 return -nl_syserr2nlerr(errno);
186 int nl_sendmsg(
struct nl_sock *sk,
struct nl_msg *msg,
struct msghdr *hdr)
191 nlmsg_set_src(msg, &sk->s_local);
198 ret = sendmsg(sk->s_fd, hdr, 0);
200 return -nl_syserr2nlerr(errno);
202 NL_DBG(4,
"sent %d bytes\n", ret);
216 int nl_send_iovec(
struct nl_sock *sk,
struct nl_msg *msg,
struct iovec *iov,
unsigned iovlen)
218 struct sockaddr_nl *dst;
220 struct msghdr hdr = {
221 .msg_name = (
void *) &sk->s_peer,
222 .msg_namelen =
sizeof(
struct sockaddr_nl),
224 .msg_iovlen = iovlen,
230 dst = nlmsg_get_dst(msg);
231 if (dst->nl_family == AF_NETLINK)
235 creds = nlmsg_get_creds(msg);
237 char buf[CMSG_SPACE(
sizeof(
struct ucred))];
238 struct cmsghdr *cmsg;
240 hdr.msg_control = buf;
241 hdr.msg_controllen =
sizeof(buf);
243 cmsg = CMSG_FIRSTHDR(&hdr);
244 cmsg->cmsg_level = SOL_SOCKET;
245 cmsg->cmsg_type = SCM_CREDENTIALS;
246 cmsg->cmsg_len = CMSG_LEN(
sizeof(
struct ucred));
247 memcpy(CMSG_DATA(cmsg), creds,
sizeof(
struct ucred));
262 int nl_send(
struct nl_sock *sk,
struct nl_msg *msg)
272 void nl_complete_msg(
struct nl_sock *sk,
struct nl_msg *msg)
274 struct nlmsghdr *nlh;
278 nlh->nlmsg_pid = sk->s_local.nl_pid;
281 nlh->nlmsg_seq = sk->s_seq_next++;
283 if (msg->nm_protocol == -1)
284 msg->nm_protocol = sk->s_proto;
286 nlh->nlmsg_flags |= NLM_F_REQUEST;
288 if (!(sk->s_flags & NL_NO_AUTO_ACK))
289 nlh->nlmsg_flags |= NLM_F_ACK;
292 void nl_auto_complete(
struct nl_sock *sk,
struct nl_msg *msg)
294 nl_complete_msg(sk, msg);
314 struct nl_cb *cb = sk->s_cb;
316 nl_complete_msg(sk, msg);
319 return cb->cb_send_ow(sk, msg);
324 int nl_send_auto_complete(
struct nl_sock *sk,
struct nl_msg *msg)
357 return wait_for_ack(sk);
391 err = nl_send_auto_complete(sk, msg);
424 int nl_recv(
struct nl_sock *sk,
struct sockaddr_nl *nla,
425 unsigned char **buf,
struct ucred **creds)
429 static int page_size = 0;
431 struct msghdr msg = {
432 .msg_name = (
void *) nla,
433 .msg_namelen =
sizeof(
struct sockaddr_nl),
440 struct cmsghdr *cmsg;
442 memset(nla, 0,
sizeof(*nla));
444 if (sk->s_flags & NL_MSG_PEEK)
445 flags |= MSG_PEEK | MSG_TRUNC;
448 page_size = getpagesize();
450 iov.iov_len = sk->s_bufsize ? : page_size;
451 iov.iov_base = *buf = malloc(iov.iov_len);
453 if (sk->s_flags & NL_SOCK_PASSCRED) {
454 msg.msg_controllen = CMSG_SPACE(
sizeof(
struct ucred));
455 msg.msg_control = calloc(1, msg.msg_controllen);
459 n = recvmsg(sk->s_fd, &msg, flags);
463 if (errno == EINTR) {
464 NL_DBG(3,
"recvmsg() returned EINTR, retrying\n");
466 }
else if (errno == EAGAIN) {
467 NL_DBG(3,
"recvmsg() returned EAGAIN, aborting\n");
470 free(msg.msg_control);
472 return -nl_syserr2nlerr(errno);
476 if (msg.msg_flags & MSG_CTRUNC) {
477 msg.msg_controllen *= 2;
478 msg.msg_control = realloc(msg.msg_control, msg.msg_controllen);
480 }
else if (iov.iov_len < n || msg.msg_flags & MSG_TRUNC) {
485 iov.iov_base = *buf = realloc(*buf, iov.iov_len);
488 }
else if (flags != 0) {
494 if (msg.msg_namelen !=
sizeof(
struct sockaddr_nl)) {
495 free(msg.msg_control);
500 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
501 if (cmsg->cmsg_level == SOL_SOCKET &&
502 cmsg->cmsg_type == SCM_CREDENTIALS) {
504 *creds = calloc(1,
sizeof(
struct ucred));
505 memcpy(*creds, CMSG_DATA(cmsg),
sizeof(
struct ucred));
511 free(msg.msg_control);
515 free(msg.msg_control);
521 #define NL_CB_CALL(cb, type, msg) \
523 err = nl_cb_call(cb, type, msg); \
538 static int recvmsgs(
struct nl_sock *sk,
struct nl_cb *cb)
540 int n, err = 0, multipart = 0, interrupted = 0, nrecv = 0;
541 unsigned char *buf = NULL;
542 struct nlmsghdr *hdr;
543 struct sockaddr_nl nla = {0};
544 struct nl_msg *msg = NULL;
545 struct ucred *creds = NULL;
548 NL_DBG(3,
"Attempting to read from %p\n", sk);
550 n = cb->cb_recv_ow(sk, &nla, &buf, &creds);
552 n =
nl_recv(sk, &nla, &buf, &creds);
557 NL_DBG(3,
"recvmsgs(%p): Read %d bytes\n", sk, n);
559 hdr = (
struct nlmsghdr *) buf;
561 NL_DBG(3,
"recvmsgs(%p): Processing valid message...\n", sk);
570 nlmsg_set_proto(msg, sk->s_proto);
571 nlmsg_set_src(msg, &nla);
573 nlmsg_set_creds(msg, creds);
589 }
else if (!(sk->s_flags & NL_NO_AUTO_ACK)) {
590 if (hdr->nlmsg_seq != sk->s_seq_expect) {
594 err = -NLE_SEQ_MISMATCH;
600 if (hdr->nlmsg_type == NLMSG_DONE ||
601 hdr->nlmsg_type == NLMSG_ERROR ||
602 hdr->nlmsg_type == NLMSG_NOOP ||
603 hdr->nlmsg_type == NLMSG_OVERRUN) {
607 NL_DBG(3,
"recvmsgs(%p): Increased expected " \
608 "sequence number to %d\n",
609 sk, sk->s_seq_expect);
612 if (hdr->nlmsg_flags & NLM_F_MULTI)
615 if (hdr->nlmsg_flags & NLM_F_DUMP_INTR) {
629 if (hdr->nlmsg_flags & NLM_F_ACK) {
641 if (hdr->nlmsg_type == NLMSG_DONE) {
651 else if (hdr->nlmsg_type == NLMSG_NOOP) {
661 else if (hdr->nlmsg_type == NLMSG_OVERRUN) {
665 err = -NLE_MSG_OVERFLOW;
671 else if (hdr->nlmsg_type == NLMSG_ERROR) {
674 if (hdr->nlmsg_len <
nlmsg_size(
sizeof(*e))) {
682 err = -NLE_MSG_TRUNC;
685 }
else if (e->error) {
688 err = cb->cb_err(&nla, e,
695 err = -nl_syserr2nlerr(e->error);
699 err = -nl_syserr2nlerr(e->error);
725 goto continue_reading;
735 err = -NLE_DUMP_INTR;
757 if (cb->cb_recvmsgs_ow)
758 return cb->cb_recvmsgs_ow(sk, cb);
760 return recvmsgs(sk, cb);
802 static int ack_wait_handler(
struct nl_msg *msg,
void *arg)
834 int (*parser)(
struct nl_cache_ops *,
struct sockaddr_nl *,
841 struct pickup_param *pp = p->
pp_arg;
852 static int __pickup_answer(
struct nl_msg *msg,
void *arg)
854 struct pickup_param *pp = arg;
856 .
pp_cb = __store_answer,
860 return pp->parser(NULL, &msg->nm_src, msg->nm_nlh, &parse_arg);
874 int (*parser)(
struct nl_cache_ops *,
struct sockaddr_nl *,
880 struct pickup_param pp = {