28 #include <netlink-private/netlink.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>
91 flags |= SOCK_CLOEXEC;
97 sk->s_fd = socket(AF_NETLINK, SOCK_RAW | flags, protocol);
99 err = -nl_syserr2nlerr(errno);
103 if (!(sk->s_flags & NL_SOCK_BUFSIZE_SET)) {
109 err = bind(sk->s_fd, (
struct sockaddr*) &sk->s_local,
110 sizeof(sk->s_local));
112 err = -nl_syserr2nlerr(errno);
116 addrlen =
sizeof(sk->s_local);
117 err = getsockname(sk->s_fd, (
struct sockaddr *) &sk->s_local,
120 err = -nl_syserr2nlerr(errno);
124 if (addrlen !=
sizeof(sk->s_local)) {
129 if (sk->s_local.nl_family != AF_NETLINK) {
130 err = -NLE_AF_NOSUPPORT;
134 sk->s_proto = protocol;
138 if (sk->s_fd != -1) {
197 int nl_sendto(
struct nl_sock *sk,
void *buf,
size_t size)
205 return -NLE_BAD_SOCK;
207 ret = sendto(sk->s_fd, buf, size, 0, (
struct sockaddr *)
208 &sk->s_peer,
sizeof(sk->s_peer));
210 return -nl_syserr2nlerr(errno);
251 int nl_sendmsg(
struct nl_sock *sk,
struct nl_msg *msg,
struct msghdr *hdr)
257 return -NLE_BAD_SOCK;
259 nlmsg_set_src(msg, &sk->s_local);
266 ret = sendmsg(sk->s_fd, hdr, 0);
268 return -nl_syserr2nlerr(errno);
270 NL_DBG(4,
"sent %d bytes\n", ret);
294 int nl_send_iovec(
struct nl_sock *sk,
struct nl_msg *msg,
struct iovec *iov,
unsigned iovlen)
296 struct sockaddr_nl *dst;
298 struct msghdr hdr = {
299 .msg_name = (
void *) &sk->s_peer,
300 .msg_namelen =
sizeof(
struct sockaddr_nl),
302 .msg_iovlen = iovlen,
308 dst = nlmsg_get_dst(msg);
309 if (dst->nl_family == AF_NETLINK)
313 creds = nlmsg_get_creds(msg);
315 char buf[CMSG_SPACE(
sizeof(
struct ucred))];
316 struct cmsghdr *cmsg;
318 hdr.msg_control = buf;
319 hdr.msg_controllen =
sizeof(buf);
321 cmsg = CMSG_FIRSTHDR(&hdr);
322 cmsg->cmsg_level = SOL_SOCKET;
323 cmsg->cmsg_type = SCM_CREDENTIALS;
324 cmsg->cmsg_len = CMSG_LEN(
sizeof(
struct ucred));
325 memcpy(CMSG_DATA(cmsg), creds,
sizeof(
struct ucred));
368 int nl_send(
struct nl_sock *sk,
struct nl_msg *msg)
370 struct nl_cb *cb = sk->s_cb;
373 return cb->cb_send_ow(sk, msg);
404 struct nlmsghdr *nlh;
408 nlh->nlmsg_pid = sk->s_local.nl_pid;
411 nlh->nlmsg_seq = sk->s_seq_next++;
413 if (msg->nm_protocol == -1)
414 msg->nm_protocol = sk->s_proto;
416 nlh->nlmsg_flags |= NLM_F_REQUEST;
418 if (!(sk->s_flags & NL_NO_AUTO_ACK))
419 nlh->nlmsg_flags |= NLM_F_ACK;
478 return wait_for_ack(sk);
577 int nl_recv(
struct nl_sock *sk,
struct sockaddr_nl *nla,
578 unsigned char **buf,
struct ucred **creds)
582 static int page_size = 0;
584 struct msghdr msg = {
585 .msg_name = (
void *) nla,
586 .msg_namelen =
sizeof(
struct sockaddr_nl),
590 struct ucred* tmpcreds = NULL;
596 if (sk->s_flags & NL_MSG_PEEK)
597 flags |= MSG_PEEK | MSG_TRUNC;
600 page_size = getpagesize() * 4;
602 iov.iov_len = sk->s_bufsize ? : page_size;
603 iov.iov_base = malloc(iov.iov_len);
610 if (creds && (sk->s_flags & NL_SOCK_PASSCRED)) {
611 msg.msg_controllen = CMSG_SPACE(
sizeof(
struct ucred));
612 msg.msg_control = malloc(msg.msg_controllen);
613 if (!msg.msg_control) {
620 n = recvmsg(sk->s_fd, &msg, flags);
626 if (errno == EINTR) {
627 NL_DBG(3,
"recvmsg() returned EINTR, retrying\n");
630 retval = -nl_syserr2nlerr(errno);
634 if (msg.msg_flags & MSG_CTRUNC) {
636 msg.msg_controllen *= 2;
637 tmp = realloc(msg.msg_control, msg.msg_controllen);
642 msg.msg_control = tmp;
646 if (iov.iov_len < n || (msg.msg_flags & MSG_TRUNC)) {
652 tmp = realloc(iov.iov_base, iov.iov_len);
668 if (msg.msg_namelen !=
sizeof(
struct sockaddr_nl)) {
669 retval = -NLE_NOADDR;
673 if (creds && (sk->s_flags & NL_SOCK_PASSCRED)) {
674 struct cmsghdr *cmsg;
676 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
677 if (cmsg->cmsg_level != SOL_SOCKET)
679 if (cmsg->cmsg_type != SCM_CREDENTIALS)
681 tmpcreds = malloc(
sizeof(*tmpcreds));
686 memcpy(tmpcreds, CMSG_DATA(cmsg),
sizeof(*tmpcreds));
693 free(msg.msg_control);
710 #define NL_CB_CALL(cb, type, msg) \
712 err = nl_cb_call(cb, type, msg); \
727 static int recvmsgs(
struct nl_sock *sk,
struct nl_cb *cb)
729 int n, err = 0, multipart = 0, interrupted = 0, nrecv = 0;
730 unsigned char *buf = NULL;
731 struct nlmsghdr *hdr;
738 struct sockaddr_nl nla = {0};
739 struct nl_msg *msg = NULL;
740 struct ucred *creds = NULL;
743 NL_DBG(3,
"Attempting to read from %p\n", sk);
745 n = cb->cb_recv_ow(sk, &nla, &buf, &creds);
747 n =
nl_recv(sk, &nla, &buf, &creds);
752 NL_DBG(3,
"recvmsgs(%p): Read %d bytes\n", sk, n);
754 hdr = (
struct nlmsghdr *) buf;
756 NL_DBG(3,
"recvmsgs(%p): Processing valid message...\n", sk);
765 nlmsg_set_proto(msg, sk->s_proto);
766 nlmsg_set_src(msg, &nla);
768 nlmsg_set_creds(msg, creds);
784 }
else if (!(sk->s_flags & NL_NO_AUTO_ACK)) {
785 if (hdr->nlmsg_seq != sk->s_seq_expect) {
789 err = -NLE_SEQ_MISMATCH;
795 if (hdr->nlmsg_type == NLMSG_DONE ||
796 hdr->nlmsg_type == NLMSG_ERROR ||
797 hdr->nlmsg_type == NLMSG_NOOP ||
798 hdr->nlmsg_type == NLMSG_OVERRUN) {
802 NL_DBG(3,
"recvmsgs(%p): Increased expected " \
803 "sequence number to %d\n",
804 sk, sk->s_seq_expect);
807 if (hdr->nlmsg_flags & NLM_F_MULTI)
810 if (hdr->nlmsg_flags & NLM_F_DUMP_INTR) {
824 if (hdr->nlmsg_flags & NLM_F_ACK) {
836 if (hdr->nlmsg_type == NLMSG_DONE) {
846 else if (hdr->nlmsg_type == NLMSG_NOOP) {
856 else if (hdr->nlmsg_type == NLMSG_OVERRUN) {
860 err = -NLE_MSG_OVERFLOW;
866 else if (hdr->nlmsg_type == NLMSG_ERROR) {
869 if (hdr->nlmsg_len <
nlmsg_size(
sizeof(*e))) {
877 err = -NLE_MSG_TRUNC;
880 }
else if (e->error) {
883 err = cb->cb_err(&nla, e,
890 err = -nl_syserr2nlerr(e->error);
894 err = -nl_syserr2nlerr(e->error);
920 goto continue_reading;
930 err = -NLE_DUMP_INTR;
952 if (cb->cb_recvmsgs_ow)
953 return cb->cb_recvmsgs_ow(sk, cb);
955 return recvmsgs(sk, cb);
997 static int ack_wait_handler(
struct nl_msg *msg,
void *arg)
1029 int (*parser)(
struct nl_cache_ops *,
struct sockaddr_nl *,
1030 struct nlmsghdr *,
struct nl_parser_param *);
1031 struct nl_object *result;
1034 static int __store_answer(
struct nl_object *obj,
struct nl_parser_param *p)
1036 struct pickup_param *pp = p->pp_arg;
1047 static int __pickup_answer(
struct nl_msg *msg,
void *arg)
1049 struct pickup_param *pp = arg;
1050 struct nl_parser_param parse_arg = {
1051 .pp_cb = __store_answer,
1055 return pp->parser(NULL, &msg->nm_src, msg->nm_nlh, &parse_arg);
1069 int (*parser)(
struct nl_cache_ops *,
struct sockaddr_nl *,
1070 struct nlmsghdr *,
struct nl_parser_param *),
1071 struct nl_object **result)
1075 struct pickup_param pp = {
1089 *result = pp.result;