All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] libmnl: Add filtering support to library as a convienience
@ 2013-03-26 14:20 Neil Horman
  2013-03-26 20:50 ` Pablo Neira Ayuso
  0 siblings, 1 reply; 5+ messages in thread
From: Neil Horman @ 2013-03-26 14:20 UTC (permalink / raw)
  To: netfilter-devel
  Cc: Neil Horman, Pablo Neira Ayuso, Florian Weimer, Hushan Jia

Theres been recent discussion about detecting and discarding unwanted netlink
messages in libmnl, so that we can avoid having applications get spoofed by user
space processes sending messages with malformed netlink headers.  Commonly
applications want to be able to only receive messages from the kernel, but
libmnl currently doesn't offer a mechanism to do that.  This patch adds such a
mechanism.  It creates a function mnl_socket_recvfrom_filter, that adds an
extra function pointer parameter which is used to interrogate recieved frames
and filter them based on a desired criteria.  It also adds a convieninece
function mnl_recvfrom_filter_user which can be passed as the filter agrument in
mnl_socket_recvfrom_filter, so as to prevent individual applications from
re-inventing the wheel over and over again.

Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: Pablo Neira Ayuso <pablo@netfilter.org>
CC: Florian Weimer <fweimer@redhat.com>
CC: Hushan Jia <hushan.jia@gmail.com>
---
 include/libmnl/libmnl.h |  3 ++
 src/libmnl.map          |  6 ++++
 src/socket.c            | 84 ++++++++++++++++++++++++++++++++++++++++++-------
 3 files changed, 82 insertions(+), 11 deletions(-)

diff --git a/include/libmnl/libmnl.h b/include/libmnl/libmnl.h
index a647fd9..2375d25 100644
--- a/include/libmnl/libmnl.h
+++ b/include/libmnl/libmnl.h
@@ -33,6 +33,9 @@ extern int mnl_socket_get_fd(const struct mnl_socket *nl);
 extern unsigned int mnl_socket_get_portid(const struct mnl_socket *nl);
 extern ssize_t mnl_socket_sendto(const struct mnl_socket *nl, const void *req, size_t siz);
 extern ssize_t mnl_socket_recvfrom(const struct mnl_socket *nl, void *buf, size_t siz);
+extern ssize_t mnl_socket_recvfrom_filter(const struct mnl_socket *nl, void *buf, size_t size,
+					  int(*filter)(const struct mnl_socket *, struct msghdr*));
+extern int mnl_recvfrom_filter_user(const struct mnl_socket*, struct msghdr*);
 extern int mnl_socket_setsockopt(const 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..ad7dc3d 100644
--- a/src/libmnl.map
+++ b/src/libmnl.map
@@ -72,3 +72,9 @@ local: *;
 LIBMNL_1.1 {
   mnl_attr_parse_payload;
 } LIBMNL_1.0;
+
+
+LIBMNL_1.2 {
+  mnl_socket_recvfrom_filter;
+  mnl_recvfrom_filter_user;
+};
diff --git a/src/socket.c b/src/socket.c
index 6d54563..767eaeb 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -188,6 +188,26 @@ mnl_socket_sendto(const struct mnl_socket *nl, const void *buf, size_t len)
 }
 EXPORT_SYMBOL(mnl_socket_sendto);
 
+static ssize_t
+__mnl_socket_recvfrom(const struct mnl_socket *nl, struct msghdr *msg)
+{
+	ssize_t ret;
+
+	ret = recvmsg(nl->fd, msg, 0);
+	if (ret == -1)
+		return ret;
+
+	if (msg->msg_flags & MSG_TRUNC) {
+		errno = ENOSPC;
+		return -1;
+	}
+	if (msg->msg_namelen != sizeof(struct sockaddr_nl)) {
+		errno = EINVAL;
+		return -1;
+	}
+	return ret;
+}
+
 /**
  * mnl_socket_recvfrom - receive a netlink message
  * \param nl netlink socket obtained via mnl_socket_open()
@@ -205,6 +225,34 @@ EXPORT_SYMBOL(mnl_socket_sendto);
 ssize_t
 mnl_socket_recvfrom(const struct mnl_socket *nl, void *buf, size_t bufsiz)
 {
+	return mnl_socket_recvfrom_filter(nl, buf, bufsiz, NULL);
+}
+EXPORT_SYMBOL(mnl_socket_recvfrom);
+
+/**
+ * mnl_socket_recvfrom_filter - receive a netlink message after filtering
+ * \param nl netlink socket obtained via mnl_socket_open()
+ * \param buf buffer that you want to use to store the netlink message
+ * \param bufsiz size of the buffer passed to store the netlink message
+ * \param filter function pointer to method to filter messages
+ *
+ * On error, it returns -1 and errno is appropriately set. If errno is set
+ * to ENOSPC, it means that the buffer that you have passed to store the
+ * netlink message is too small, so you have received a truncated message.
+ * To avoid this, you have to allocate a buffer of MNL_SOCKET_BUFFER_SIZE
+ * (which is 8KB, see linux/netlink.h for more information). Using this
+ * buffer size ensures that your buffer is big enough to store the netlink
+ * message without truncating it. For every frame that is successfully received
+ * the filter function is called (if set), a negative return from the filter
+ * function causes the message to be discarded, and the filter error code is
+ * returned to the caller of mnl_socket_recvfrom_filter.  A zero return code
+ * from the filter function returns the message to the caller. 
+ * 
+ */
+ssize_t
+mnl_socket_recvfrom_filter(const struct mnl_socket *nl, void *buf, size_t bufsiz,
+			   int(*filter)(const struct mnl_socket*, struct msghdr*))
+{
 	ssize_t ret;
 	struct sockaddr_nl addr;
 	struct iovec iov = {
@@ -220,21 +268,35 @@ mnl_socket_recvfrom(const struct mnl_socket *nl, void *buf, size_t bufsiz)
 		.msg_controllen	= 0,
 		.msg_flags	= 0,
 	};
-	ret = recvmsg(nl->fd, &msg, 0);
+retry:
+	ret = __mnl_socket_recvfrom(nl, &msg);
 	if (ret == -1)
 		return ret;
-
-	if (msg.msg_flags & MSG_TRUNC) {
-		errno = ENOSPC;
-		return -1;
-	}
-	if (msg.msg_namelen != sizeof(struct sockaddr_nl)) {
-		errno = EINVAL;
-		return -1;
-	}
+	if (filter)
+		ret = filter(nl, &msg);
 	return ret;
 }
-EXPORT_SYMBOL(mnl_socket_recvfrom);
+EXPORT_SYMBOL(mnl_socket_recvfrom_filter);
+
+/**
+ * mnl_recvfrom_filter_user - helper function to filter user messages
+ * \param nl netlink socket that a message was received on
+ * \param msg - pointer to the msghdr of the received message
+ *
+ * This function is meant to be passed as the filter argument to
+ * mnl_socket_recvfrom_filter.  It is a convienience function to automatically 
+ * filter out messages originating from user space hosts. 
+ *
+ * returns zero, if the message originated from the kernel
+ * returns non-zero if the message did not originate from the kernel
+ */
+int mnl_recvfrom_filter_user(const struct mnl_socket *nl, struct msghdr *msg)
+{
+	struct sockaddr_nl *addr = msg->msg_name;
+
+	return (addr->nl_pid == 0) ? 0 : -1;
+}
+EXPORT_SYMBOL(mnl_recvfrom_filter_user);
 
 /**
  * mnl_socket_close - close a given netlink socket
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] libmnl: Add filtering support to library as a convienience
  2013-03-26 14:20 [PATCH] libmnl: Add filtering support to library as a convienience Neil Horman
@ 2013-03-26 20:50 ` Pablo Neira Ayuso
  2013-03-27  9:21   ` Florian Weimer
  2013-03-27 12:55   ` Neil Horman
  0 siblings, 2 replies; 5+ messages in thread
From: Pablo Neira Ayuso @ 2013-03-26 20:50 UTC (permalink / raw)
  To: Neil Horman; +Cc: netfilter-devel, Florian Weimer, Hushan Jia

Hi Neil,

On Tue, Mar 26, 2013 at 10:20:43AM -0400, Neil Horman wrote:
> Theres been recent discussion about detecting and discarding unwanted netlink
> messages in libmnl, so that we can avoid having applications get spoofed by user
> space processes sending messages with malformed netlink headers.  Commonly
> applications want to be able to only receive messages from the kernel, but
> libmnl currently doesn't offer a mechanism to do that.  This patch adds such a
> mechanism.  It creates a function mnl_socket_recvfrom_filter, that adds an
> extra function pointer parameter which is used to interrogate recieved frames
> and filter them based on a desired criteria.  It also adds a convieninece
> function mnl_recvfrom_filter_user which can be passed as the filter agrument in
> mnl_socket_recvfrom_filter, so as to prevent individual applications from
> re-inventing the wheel over and over again.

I remember that report from Florian. After some discussion, I proposed
this solution:

commit 20e1db19db5d6b9e4e83021595eab0dc8f107bef
Author: Pablo Neira Ayuso <pablo@netfilter.org>
Date:   Thu Aug 23 02:09:11 2012 +0000

    netlink: fix possible spoofing from non-root processes

Basically, it disables netlink-to-netlink communications between
non-root processes (with the exception of NETLINK_USERSOCK), so
non-root processes cannot spoof messages anymore.

Regards.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] libmnl: Add filtering support to library as a convienience
  2013-03-26 20:50 ` Pablo Neira Ayuso
@ 2013-03-27  9:21   ` Florian Weimer
  2013-04-19  2:20     ` Pablo Neira Ayuso
  2013-03-27 12:55   ` Neil Horman
  1 sibling, 1 reply; 5+ messages in thread
From: Florian Weimer @ 2013-03-27  9:21 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: Neil Horman, netfilter-devel, Hushan Jia

[-- Attachment #1: Type: text/plain, Size: 903 bytes --]

On 03/26/2013 09:50 PM, Pablo Neira Ayuso wrote:

> I remember that report from Florian. After some discussion, I proposed
> this solution:
>
> commit 20e1db19db5d6b9e4e83021595eab0dc8f107bef
> Author: Pablo Neira Ayuso <pablo@netfilter.org>
> Date:   Thu Aug 23 02:09:11 2012 +0000
>
>      netlink: fix possible spoofing from non-root processes
>
> Basically, it disables netlink-to-netlink communications between
> non-root processes (with the exception of NETLINK_USERSOCK), so
> non-root processes cannot spoof messages anymore.

We are a bit in a bind here because we need to support kernels without 
this patch, and we don't want to add symbols to libmnl which aren't part 
of upstream.

Perhaps an interface to access the sender socket address would be an 
acceptable compromise, like the attached patch?  That would be useful 
independently.

-- 
Florian Weimer / Red Hat Product Security Team

[-- Attachment #2: 0001-Functions-which-modify-state-should-not-take-const-a.patch --]
[-- Type: text/x-patch, Size: 3217 bytes --]

>From 2a6246b9158df6c4ef1000a5a92b599a1f393f7f Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
Date: Wed, 27 Mar 2013 10:10:01 +0100
Subject: [PATCH 1/2] Functions which modify state should not take const
 arguments

Sending and receiving packets and changing socket options
modify the internal socket state, which was not reflected in the
prototype.  mnl_socket_get_fd provides access to the underlying
file descriptor, which indirectly allows modification.

Signed-off-by: Florian Weimer <fweimer@redhat.com>
---
 include/libmnl/libmnl.h | 8 ++++----
 src/socket.c            | 8 ++++----
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/include/libmnl/libmnl.h b/include/libmnl/libmnl.h
index a647fd9..5145ba5 100644
--- a/include/libmnl/libmnl.h
+++ b/include/libmnl/libmnl.h
@@ -29,11 +29,11 @@ struct mnl_socket;
 extern struct mnl_socket *mnl_socket_open(int type);
 extern int mnl_socket_bind(struct mnl_socket *nl, unsigned int groups, pid_t pid);
 extern int mnl_socket_close(struct mnl_socket *nl);
-extern int mnl_socket_get_fd(const struct mnl_socket *nl);
+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(const struct mnl_socket *nl, const void *req, size_t siz);
-extern ssize_t mnl_socket_recvfrom(const struct mnl_socket *nl, void *buf, size_t siz);
-extern int mnl_socket_setsockopt(const struct mnl_socket *nl, int type, void *buf, socklen_t len);
+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 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/socket.c b/src/socket.c
index 6d54563..c77af91 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -82,7 +82,7 @@ struct mnl_socket {
  *
  * This function returns the file descriptor of a given netlink socket.
  */
-int mnl_socket_get_fd(const struct mnl_socket *nl)
+int mnl_socket_get_fd(struct mnl_socket *nl)
 {
 	return nl->fd;
 }
@@ -178,7 +178,7 @@ EXPORT_SYMBOL(mnl_socket_bind);
  * returns the number of bytes sent.
  */
 ssize_t
-mnl_socket_sendto(const struct mnl_socket *nl, const void *buf, size_t len)
+mnl_socket_sendto(struct mnl_socket *nl, const void *buf, size_t len)
 {
 	static const struct sockaddr_nl snl = {
 		.nl_family = AF_NETLINK
@@ -203,7 +203,7 @@ EXPORT_SYMBOL(mnl_socket_sendto);
  * message without truncating it.
  */
 ssize_t
-mnl_socket_recvfrom(const struct mnl_socket *nl, void *buf, size_t bufsiz)
+mnl_socket_recvfrom(struct mnl_socket *nl, void *buf, size_t bufsiz)
 {
 	ssize_t ret;
 	struct sockaddr_nl addr;
@@ -276,7 +276,7 @@ EXPORT_SYMBOL(mnl_socket_close);
  *
  * On error, this function returns -1 and errno is appropriately set.
  */
-int mnl_socket_setsockopt(const struct mnl_socket *nl, int type,
+int mnl_socket_setsockopt(struct mnl_socket *nl, int type,
 			  void *buf, socklen_t len)
 {
 	return setsockopt(nl->fd, SOL_NETLINK, type, buf, len);
-- 
1.8.1.4


[-- Attachment #3: 0002-mnl_socket_peer_address-Add-function-to-retrieve-the.patch --]
[-- Type: text/x-patch, Size: 3357 bytes --]

>From 7da5a365c9908972726243b12b91666352c1ee31 Mon Sep 17 00:00:00 2001
From: Florian Weimer <fweimer@redhat.com>
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 <fweimer@redhat.com>
---
 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 <libmnl/libmnl.h>
+#include <string.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <stdlib.h>
@@ -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


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] libmnl: Add filtering support to library as a convienience
  2013-03-26 20:50 ` Pablo Neira Ayuso
  2013-03-27  9:21   ` Florian Weimer
@ 2013-03-27 12:55   ` Neil Horman
  1 sibling, 0 replies; 5+ messages in thread
From: Neil Horman @ 2013-03-27 12:55 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel, Florian Weimer, Hushan Jia

On Tue, Mar 26, 2013 at 09:50:28PM +0100, Pablo Neira Ayuso wrote:
> Hi Neil,
> 
> On Tue, Mar 26, 2013 at 10:20:43AM -0400, Neil Horman wrote:
> > Theres been recent discussion about detecting and discarding unwanted netlink
> > messages in libmnl, so that we can avoid having applications get spoofed by user
> > space processes sending messages with malformed netlink headers.  Commonly
> > applications want to be able to only receive messages from the kernel, but
> > libmnl currently doesn't offer a mechanism to do that.  This patch adds such a
> > mechanism.  It creates a function mnl_socket_recvfrom_filter, that adds an
> > extra function pointer parameter which is used to interrogate recieved frames
> > and filter them based on a desired criteria.  It also adds a convieninece
> > function mnl_recvfrom_filter_user which can be passed as the filter agrument in
> > mnl_socket_recvfrom_filter, so as to prevent individual applications from
> > re-inventing the wheel over and over again.
> 
> I remember that report from Florian. After some discussion, I proposed
> this solution:
> 
> commit 20e1db19db5d6b9e4e83021595eab0dc8f107bef
> Author: Pablo Neira Ayuso <pablo@netfilter.org>
> Date:   Thu Aug 23 02:09:11 2012 +0000
> 
>     netlink: fix possible spoofing from non-root processes
> 
> Basically, it disables netlink-to-netlink communications between
> non-root processes (with the exception of NETLINK_USERSOCK), so
> non-root processes cannot spoof messages anymore.
> 
> Regards.
> 
Ah, thank you pablo, wish Florian or I had seen this previously.

Regards
Neil


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] libmnl: Add filtering support to library as a convienience
  2013-03-27  9:21   ` Florian Weimer
@ 2013-04-19  2:20     ` Pablo Neira Ayuso
  0 siblings, 0 replies; 5+ messages in thread
From: Pablo Neira Ayuso @ 2013-04-19  2:20 UTC (permalink / raw)
  To: Florian Weimer; +Cc: Neil Horman, netfilter-devel, Hushan Jia

On Wed, Mar 27, 2013 at 10:21:03AM +0100, Florian Weimer wrote:
[...]
> From 2a6246b9158df6c4ef1000a5a92b599a1f393f7f Mon Sep 17 00:00:00 2001
> From: Florian Weimer <fweimer@redhat.com>
> Date: Wed, 27 Mar 2013 10:10:01 +0100
> Subject: [PATCH 1/2] Functions which modify state should not take const
>  arguments
> 
> Sending and receiving packets and changing socket options
> modify the internal socket state, which was not reflected in the
> prototype.  mnl_socket_get_fd provides access to the underlying
> file descriptor, which indirectly allows modification.
> 
> Signed-off-by: Florian Weimer <fweimer@redhat.com>
> ---
>  include/libmnl/libmnl.h | 8 ++++----
>  src/socket.c            | 8 ++++----
>  2 files changed, 8 insertions(+), 8 deletions(-)
> 
> diff --git a/include/libmnl/libmnl.h b/include/libmnl/libmnl.h
> index a647fd9..5145ba5 100644
> --- a/include/libmnl/libmnl.h
> +++ b/include/libmnl/libmnl.h
> @@ -29,11 +29,11 @@ struct mnl_socket;
>  extern struct mnl_socket *mnl_socket_open(int type);
>  extern int mnl_socket_bind(struct mnl_socket *nl, unsigned int groups, pid_t pid);
>  extern int mnl_socket_close(struct mnl_socket *nl);
> -extern int mnl_socket_get_fd(const struct mnl_socket *nl);
> +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(const struct mnl_socket *nl, const void *req, size_t siz);
> -extern ssize_t mnl_socket_recvfrom(const struct mnl_socket *nl, void *buf, size_t siz);
> -extern int mnl_socket_setsockopt(const struct mnl_socket *nl, int type, void *buf, socklen_t len);
> +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 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/socket.c b/src/socket.c
> index 6d54563..c77af91 100644
> --- a/src/socket.c
> +++ b/src/socket.c
> @@ -82,7 +82,7 @@ struct mnl_socket {
>   *
>   * This function returns the file descriptor of a given netlink socket.
>   */
> -int mnl_socket_get_fd(const struct mnl_socket *nl)
> +int mnl_socket_get_fd(struct mnl_socket *nl)
>  {
>  	return nl->fd;
>  }
> @@ -178,7 +178,7 @@ EXPORT_SYMBOL(mnl_socket_bind);
>   * returns the number of bytes sent.
>   */
>  ssize_t
> -mnl_socket_sendto(const struct mnl_socket *nl, const void *buf, size_t len)
> +mnl_socket_sendto(struct mnl_socket *nl, const void *buf, size_t len)
>  {
>  	static const struct sockaddr_nl snl = {
>  		.nl_family = AF_NETLINK
> @@ -203,7 +203,7 @@ EXPORT_SYMBOL(mnl_socket_sendto);
>   * message without truncating it.
>   */
>  ssize_t
> -mnl_socket_recvfrom(const struct mnl_socket *nl, void *buf, size_t bufsiz)
> +mnl_socket_recvfrom(struct mnl_socket *nl, void *buf, size_t bufsiz)
>  {
>  	ssize_t ret;
>  	struct sockaddr_nl addr;
> @@ -276,7 +276,7 @@ EXPORT_SYMBOL(mnl_socket_close);
>   *
>   * On error, this function returns -1 and errno is appropriately set.
>   */
> -int mnl_socket_setsockopt(const struct mnl_socket *nl, int type,
> +int mnl_socket_setsockopt(struct mnl_socket *nl, int type,
>  			  void *buf, socklen_t len)
>  {
>  	return setsockopt(nl->fd, SOL_NETLINK, type, buf, len);
> -- 
> 1.8.1.4
> 

> From 7da5a365c9908972726243b12b91666352c1ee31 Mon Sep 17 00:00:00 2001
> From: Florian Weimer <fweimer@redhat.com>
> 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 <fweimer@redhat.com>
> ---
>  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 <libmnl/libmnl.h>
> +#include <string.h>
>  #include <sys/types.h>
>  #include <sys/socket.h>
>  #include <stdlib.h>
> @@ -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)

I prefer if you send me a patch to add a new recvfrom function (with
new name) that allows you to pass the sockaddr_nl:

mnl_socket_recvfrom_addr

I prefer not to deconstify all those functions and not to increase the
size of mnl_socket.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2013-04-19  2:20 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-03-26 14:20 [PATCH] libmnl: Add filtering support to library as a convienience Neil Horman
2013-03-26 20:50 ` Pablo Neira Ayuso
2013-03-27  9:21   ` Florian Weimer
2013-04-19  2:20     ` Pablo Neira Ayuso
2013-03-27 12:55   ` Neil Horman

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.