169 #include <netlink-local.h>
170 #include <netlink/netlink.h>
171 #include <netlink/utils.h>
172 #include <netlink/handlers.h>
173 #include <netlink/msg.h>
174 #include <netlink/attr.h>
196 handle->h_fd = socket(AF_NETLINK, SOCK_RAW, protocol);
197 if (handle->h_fd < 0) {
198 err = nl_error(1,
"socket(AF_NETLINK, ...) failed");
202 if (!(handle->h_flags & NL_SOCK_BUFSIZE_SET)) {
208 err = bind(handle->h_fd, (
struct sockaddr*) &handle->h_local,
209 sizeof(handle->h_local));
211 err = nl_error(1,
"bind() failed");
215 addrlen =
sizeof(handle->h_local);
216 err = getsockname(handle->h_fd, (
struct sockaddr *) &handle->h_local,
219 err = nl_error(1,
"getsockname failed");
223 if (addrlen !=
sizeof(handle->h_local)) {
224 err = nl_error(EADDRNOTAVAIL,
"Invalid address length");
228 if (handle->h_local.nl_family != AF_NETLINK) {
229 err = nl_error(EPFNOSUPPORT,
"Address format not supported");
233 handle->h_proto = protocol;
249 if (handle->h_fd >= 0) {
271 int nl_sendto(
struct nl_handle *handle,
void *buf,
size_t size)
275 ret = sendto(handle->h_fd, buf, size, 0, (
struct sockaddr *)
276 &handle->h_peer,
sizeof(handle->h_peer));
278 return nl_errno(errno);
290 int nl_sendmsg(
struct nl_handle *handle,
struct nl_msg *msg,
struct msghdr *hdr)
303 nlmsg_set_src(msg, &handle->h_local);
310 ret = sendmsg(handle->h_fd, hdr, 0);
312 return nl_errno(errno);
325 int nl_send(
struct nl_handle *handle,
struct nl_msg *msg)
330 struct msghdr hdr = {
331 .msg_name = (
void *) &handle->h_peer,
338 dst = nlmsg_get_dst(msg);
343 creds = nlmsg_get_creds(msg);
345 char buf[CMSG_SPACE(
sizeof(
struct ucred))];
346 struct cmsghdr *cmsg;
348 hdr.msg_control = buf;
349 hdr.msg_controllen =
sizeof(buf);
351 cmsg = CMSG_FIRSTHDR(&hdr);
352 cmsg->cmsg_level = SOL_SOCKET;
353 cmsg->cmsg_type = SCM_CREDENTIALS;
354 cmsg->cmsg_len = CMSG_LEN(
sizeof(
struct ucred));
355 memcpy(CMSG_DATA(cmsg), creds,
sizeof(
struct ucred));
376 struct nl_cb *cb = handle->h_cb;
385 if (msg->nm_protocol == -1)
386 msg->nm_protocol = handle->h_proto;
391 return cb->cb_send_ow(handle, msg);
418 return nl_errno(ENOMEM);
461 unsigned char **buf,
struct ucred **creds)
465 static int page_size = 0;
467 struct msghdr msg = {
468 .msg_name = (
void *) nla,
476 struct cmsghdr *cmsg;
478 if (handle->h_flags & NL_MSG_PEEK)
482 page_size = getpagesize();
484 iov.iov_len = page_size;
485 iov.iov_base = *buf = calloc(1, iov.iov_len);
487 if (handle->h_flags & NL_SOCK_PASSCRED) {
488 msg.msg_controllen = CMSG_SPACE(
sizeof(
struct ucred));
489 msg.msg_control = calloc(1, msg.msg_controllen);
493 n = recvmsg(handle->h_fd, &msg, flags);
497 if (errno == EINTR) {
498 NL_DBG(3,
"recvmsg() returned EINTR, retrying\n");
500 }
else if (errno == EAGAIN) {
501 NL_DBG(3,
"recvmsg() returned EAGAIN, aborting\n");
504 free(msg.msg_control);
506 return nl_error(errno,
"recvmsg failed");
510 if (iov.iov_len < n ||
511 msg.msg_flags & MSG_TRUNC) {
515 iov.iov_base = *buf = realloc(*buf, iov.iov_len);
517 }
else if (msg.msg_flags & MSG_CTRUNC) {
518 msg.msg_controllen *= 2;
519 msg.msg_control = realloc(msg.msg_control, msg.msg_controllen);
521 }
else if (flags != 0) {
527 if (msg.msg_namelen !=
sizeof(
struct sockaddr_nl)) {
528 free(msg.msg_control);
530 return nl_error(EADDRNOTAVAIL,
"socket address size mismatch");
533 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
534 if (cmsg->cmsg_level == SOL_SOCKET &&
535 cmsg->cmsg_type == SCM_CREDENTIALS) {
536 *creds = calloc(1,
sizeof(
struct ucred));
537 memcpy(*creds, CMSG_DATA(cmsg),
sizeof(
struct ucred));
542 free(msg.msg_control);
546 free(msg.msg_control);
551 #define NL_CB_CALL(cb, type, msg) \
553 err = nl_cb_call(cb, type, msg); \
567 static int recvmsgs(
struct nl_handle *handle,
struct nl_cb *cb)
569 int n, err = 0, multipart = 0;
570 unsigned char *buf = NULL;
573 struct nl_msg *msg = NULL;
574 struct ucred *creds = NULL;
577 NL_DBG(3,
"Attempting to read from %p\n", handle);
579 n = cb->cb_recv_ow(handle, &nla, &buf, &creds);
581 n =
nl_recv(handle, &nla, &buf, &creds);
586 NL_DBG(3,
"recvmsgs(%p): Read %d bytes\n", handle, n);
590 NL_DBG(3,
"recgmsgs(%p): Processing valid message...\n",
596 err = nl_errno(ENOMEM);
600 nlmsg_set_proto(msg, handle->h_proto);
601 nlmsg_set_src(msg, &nla);
603 nlmsg_set_creds(msg, creds);
615 else if (hdr->
nlmsg_seq != handle->h_seq_expect) {
619 err = nl_error(EINVAL,
620 "Sequence number mismatch");
631 handle->h_seq_expect++;
632 NL_DBG(3,
"recvmsgs(%p): Increased expected " \
633 "sequence number to %d\n",
634 handle, handle->h_seq_expect);
677 err = nl_error(EOVERFLOW,
"Overrun");
694 err = nl_error(EINVAL,
695 "Truncated error message");
698 }
else if (e->
error) {
701 err = cb->cb_err(&nla, e,
708 err = nl_error(-e->
error,
713 err = nl_error(-e->
error,
740 goto continue_reading;
769 if (cb->cb_recvmsgs_ow)
770 return cb->cb_recvmsgs_ow(handle, cb);
772 return recvmsgs(handle, cb);
787 static int ack_wait_handler(
struct nl_msg *msg,
void *arg)
807 return nl_get_errno();