>From 7da5a365c9908972726243b12b91666352c1ee31 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Wed, 27 Mar 2013 10:19:35 +0100 Subject: [PATCH 2/2] mnl_socket_peer_address: Add function to retrieve the sender address This allows callers of mnl_socket_recvfrom to examine the address, for instance, to give special treatment to messages sent by the kernel. Signed-off-by: Florian Weimer --- include/libmnl/libmnl.h | 1 + src/libmnl.map | 4 ++++ src/socket.c | 24 ++++++++++++++++++++---- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/include/libmnl/libmnl.h b/include/libmnl/libmnl.h index 5145ba5..74995fa 100644 --- a/include/libmnl/libmnl.h +++ b/include/libmnl/libmnl.h @@ -33,6 +33,7 @@ extern int mnl_socket_get_fd(struct mnl_socket *nl); extern unsigned int mnl_socket_get_portid(const struct mnl_socket *nl); extern ssize_t mnl_socket_sendto(struct mnl_socket *nl, const void *req, size_t siz); extern ssize_t mnl_socket_recvfrom(struct mnl_socket *nl, void *buf, size_t siz); +extern struct sockaddr_nl *mnl_socket_peer_address(struct mnl_socket *nl); extern int mnl_socket_setsockopt(struct mnl_socket *nl, int type, void *buf, socklen_t len); extern int mnl_socket_getsockopt(const struct mnl_socket *nl, int type, void *buf, socklen_t *len); diff --git a/src/libmnl.map b/src/libmnl.map index dbc332e..626ea87 100644 --- a/src/libmnl.map +++ b/src/libmnl.map @@ -69,6 +69,10 @@ global: local: *; }; +LIBMNL_1.0.3 { + mnl_socket_peer_address; +}; + LIBMNL_1.1 { mnl_attr_parse_payload; } LIBMNL_1.0; diff --git a/src/socket.c b/src/socket.c index c77af91..1d956a0 100644 --- a/src/socket.c +++ b/src/socket.c @@ -8,6 +8,7 @@ */ #include +#include #include #include #include @@ -69,6 +70,7 @@ struct mnl_socket { int fd; struct sockaddr_nl addr; + struct sockaddr_nl peer; }; /** @@ -206,14 +208,13 @@ ssize_t mnl_socket_recvfrom(struct mnl_socket *nl, void *buf, size_t bufsiz) { ssize_t ret; - struct sockaddr_nl addr; struct iovec iov = { .iov_base = buf, .iov_len = bufsiz, }; struct msghdr msg = { - .msg_name = &addr, - .msg_namelen = sizeof(struct sockaddr_nl), + .msg_name = &nl->peer, + .msg_namelen = sizeof(nl->peer), .msg_iov = &iov, .msg_iovlen = 1, .msg_control = NULL, @@ -221,8 +222,10 @@ mnl_socket_recvfrom(struct mnl_socket *nl, void *buf, size_t bufsiz) .msg_flags = 0, }; ret = recvmsg(nl->fd, &msg, 0); - if (ret == -1) + if (ret == -1) { + memset(&nl->peer, 0, sizeof(nl->peer)); return ret; + } if (msg.msg_flags & MSG_TRUNC) { errno = ENOSPC; @@ -237,6 +240,19 @@ mnl_socket_recvfrom(struct mnl_socket *nl, void *buf, size_t bufsiz) EXPORT_SYMBOL(mnl_socket_recvfrom); /** + * mnl_socket_peer_address - return the sender of the last message + * + * The address is only valid after a successful call to + * mnl_socket_recvfrom(). The returned pointer is valid until + * mnl_socket_close() is called; it must not be freed by the caller. + */ +struct sockaddr_nl * +mnl_socket_peer_address(struct mnl_socket *nl) +{ + return &nl->peer; +} + +/** * mnl_socket_close - close a given netlink socket * \param nl netlink socket obtained via mnl_socket_open() * -- 1.8.1.4