[LIBNFNETLINK] Introduce nfnl_listen_for_msecs

Pablo Neira Ayuso pablo at eurodev.net
Tue Feb 7 02:47:38 CET 2006


Hi Harald,

The patch attached introduces a new function called
nfnl_listen_for_msecs. This is useful for polling netlink events.

I have enqueued a patch for libnetfilter_conntrack that implements
nfct_event_conntrack_for_msecs. I apply it by myself once this gets
applied ;)

cheers,

-- 
Pablo
-------------- next part --------------
Index: include/libnfnetlink/libnfnetlink.h
===================================================================
--- include/libnfnetlink/libnfnetlink.h	(revision 6450)
+++ include/libnfnetlink/libnfnetlink.h	(working copy)
@@ -76,6 +76,11 @@
 extern int nfnl_listen(struct nfnl_handle *,
                       int (*)(struct sockaddr_nl *, struct nlmsghdr *, void *),
                       void *);
+/* simple challenge/response with timeout (polling) */
+extern int nfnl_listen_for_msecs(struct nfnl_handle *,
+				 int (*)(struct sockaddr_nl *, 
+					 struct nlmsghdr *, void *),
+				 void *, int timeout);
 
 /* receiving */
 extern ssize_t nfnl_recv(const struct nfnl_handle *h, unsigned char *buf, size_t len);
Index: src/libnfnetlink.c
===================================================================
--- src/libnfnetlink.c	(revision 6450)
+++ src/libnfnetlink.c	(working copy)
@@ -24,6 +24,9 @@
  * 2006-01-26 Harald Welte <laforge at netfilter.org>:
  * 	remove bogus nfnlh->local.nl_pid from nfnl_open ;)
  * 	add 16bit attribute functions
+ *
+ * 2006-02-07 Pablo Neira Ayuso <pablo at netfilter.org>:
+ * 	introduce nfnl_listen_for_msecs
  */
 
 #include <stdlib.h>
@@ -36,6 +39,7 @@
 
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <poll.h>
 
 #include <linux/netlink.h>
 
@@ -397,27 +401,11 @@
 
 	return status;
 }
-/**
- * nfnl_listen: listen for one or more netlink messages
- *
- * nfnhl: libnfnetlink handle
- * handler: callback function to be called for every netlink message
- *          - the callback handler should normally return 0
- *          - but may return a negative error code which will cause
- *            nfnl_listen to return immediately with the same error code
- *          - or return a postivie error code which will cause 
- *            nfnl_listen to return after it has finished processing all
- *            the netlink messages in the current packet
- *          Thus a positive error code will terminate nfnl_listen "soon"
- *          without any loss of data, a negative error code will terminate
- *          nfnl_listen "very soon" and throw away data already read from
- *          the netlink socket.
- * jarg: opaque argument passed on to callback
- *
- */
-int nfnl_listen(struct nfnl_handle *nfnlh,
-		int (*handler)(struct sockaddr_nl *, struct nlmsghdr *n,
-			       void *), void *jarg)
+
+int nfnl_listen_for_msecs(struct nfnl_handle *nfnlh,
+			  int (*handler)(struct sockaddr_nl *, 
+				  	 struct nlmsghdr *n, void *), 
+			  void *jarg, int timeout)
 {
 	struct sockaddr_nl nladdr;
 	char buf[NFNL_BUFFSIZE];
@@ -434,12 +422,26 @@
 		0
 	};
 
+	struct pollfd ufds = {
+		.fd = nfnlh->fd,
+		.events = POLLIN | POLLPRI | POLLERR,
+		.revents = 0
+	};
+
 	memset(&nladdr, 0, sizeof(nladdr));
 	nladdr.nl_family = AF_NETLINK;
 	iov.iov_base = buf;
 	iov.iov_len = sizeof(buf);
 
 	while (! quit) {
+		if (poll(&ufds, 1, timeout) == -1) {
+			perror("poll error");
+			return -errno;
+		}
+		if (ufds.revents & POLLERR)
+			break;
+		if (!(ufds.revents & (POLLIN | POLLPRI)))
+			break;
 		remain = recvmsg(nfnlh->fd, &msg, 0);
 		if (remain < 0) {
 			if (errno == EINTR)
@@ -510,6 +512,31 @@
 	return quit;
 }
 
+/**
+ * nfnl_listen: listen for one or more netlink messages
+ *
+ * nfnhl: libnfnetlink handle
+ * handler: callback function to be called for every netlink message
+ *          - the callback handler should normally return 0
+ *          - but may return a negative error code which will cause
+ *            nfnl_listen to return immediately with the same error code
+ *          - or return a postivie error code which will cause 
+ *            nfnl_listen to return after it has finished processing all
+ *            the netlink messages in the current packet
+ *          Thus a positive error code will terminate nfnl_listen "soon"
+ *          without any loss of data, a negative error code will terminate
+ *          nfnl_listen "very soon" and throw away data already read from
+ *          the netlink socket.
+ * jarg: opaque argument passed on to callback
+ *
+ */
+int nfnl_listen(struct nfnl_handle *nfnlh,
+		int (*handler)(struct sockaddr_nl *, struct nlmsghdr *n,
+			       void *), void *jarg)
+{
+	return nfnl_listen_for_msecs(nfnlh, handler, jarg, -1);
+}
+
 int nfnl_talk(struct nfnl_handle *nfnlh, struct nlmsghdr *n, pid_t peer,
 	      unsigned groups, struct nlmsghdr *answer,
 	      int (*junk)(struct sockaddr_nl *, struct nlmsghdr *n, void *),


More information about the netfilter-devel mailing list