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)
479 flags |= MSG_PEEK | MSG_TRUNC;
482 page_size = getpagesize() * 4;
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 (msg.msg_flags & MSG_CTRUNC) {
511 msg.msg_controllen *= 2;
512 msg.msg_control = realloc(msg.msg_control, msg.msg_controllen);
514 }
else if (iov.iov_len < n || msg.msg_flags & MSG_TRUNC) {
519 iov.iov_base = *buf = realloc(*buf, iov.iov_len);
522 }
else if (flags != 0) {
528 if (msg.msg_namelen !=
sizeof(
struct sockaddr_nl)) {
529 free(msg.msg_control);
531 return nl_error(EADDRNOTAVAIL,
"socket address size mismatch");
534 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
535 if (cmsg->cmsg_level == SOL_SOCKET &&
536 cmsg->cmsg_type == SCM_CREDENTIALS) {
537 *creds = calloc(1,
sizeof(
struct ucred));
538 memcpy(*creds, CMSG_DATA(cmsg),
sizeof(
struct ucred));
543 free(msg.msg_control);
547 free(msg.msg_control);
552 #define NL_CB_CALL(cb, type, msg) \
554 err = nl_cb_call(cb, type, msg); \
568 static int recvmsgs(
struct nl_handle *handle,
struct nl_cb *cb)
570 int n, err = 0, multipart = 0;
571 unsigned char *buf = NULL;
574 struct nl_msg *msg = NULL;
575 struct ucred *creds = NULL;
578 NL_DBG(3,
"Attempting to read from %p\n", handle);
580 n = cb->cb_recv_ow(handle, &nla, &buf, &creds);
582 n =
nl_recv(handle, &nla, &buf, &creds);
587 NL_DBG(3,
"recvmsgs(%p): Read %d bytes\n", handle, n);
591 NL_DBG(3,
"recgmsgs(%p): Processing valid message...\n",
597 err = nl_errno(ENOMEM);
601 nlmsg_set_proto(msg, handle->h_proto);
602 nlmsg_set_src(msg, &nla);
604 nlmsg_set_creds(msg, creds);
616 else if (hdr->
nlmsg_seq != handle->h_seq_expect) {
620 err = nl_error(EINVAL,
621 "Sequence number mismatch");
632 handle->h_seq_expect++;
633 NL_DBG(3,
"recvmsgs(%p): Increased expected " \
634 "sequence number to %d\n",
635 handle, handle->h_seq_expect);
678 err = nl_error(EOVERFLOW,
"Overrun");
695 err = nl_error(EINVAL,
696 "Truncated error message");
699 }
else if (e->
error) {
702 err = cb->cb_err(&nla, e,
709 err = nl_error(-e->
error,
714 err = nl_error(-e->
error,
741 goto continue_reading;
770 if (cb->cb_recvmsgs_ow)
771 return cb->cb_recvmsgs_ow(handle, cb);
773 return recvmsgs(handle, cb);
788 static int ack_wait_handler(
struct nl_msg *msg,
void *arg)
808 return nl_get_errno();