[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