157 lines
4.6 KiB
Diff
157 lines
4.6 KiB
Diff
diff --git a/configure.in b/configure.in
|
|
index fbcbd61..6a71da3 100644
|
|
--- a/configure.in
|
|
+++ b/configure.in
|
|
@@ -4,7 +4,7 @@ AC_INIT
|
|
|
|
AC_CANONICAL_SYSTEM
|
|
|
|
-AM_INIT_AUTOMAKE(libnfnetlink, 0.0.30)
|
|
+AM_INIT_AUTOMAKE(libnfnetlink, 0.0.33)
|
|
|
|
AC_PROG_CC
|
|
AC_EXEEXT
|
|
diff --git a/include/libnfnetlink/libnfnetlink.h b/include/libnfnetlink/libnfnetlink.h
|
|
index de77caa..37fa663 100644
|
|
--- a/include/libnfnetlink/libnfnetlink.h
|
|
+++ b/include/libnfnetlink/libnfnetlink.h
|
|
@@ -56,6 +56,9 @@ extern struct nfnl_subsys_handle *nfnl_subsys_open(struct nfnl_handle *,
|
|
unsigned int);
|
|
extern void nfnl_subsys_close(struct nfnl_subsys_handle *);
|
|
|
|
+/* set receive buffer size (for nfnl_catch) */
|
|
+extern void nfnl_set_rcv_buffer_size(struct nfnl_handle *h, unsigned int size);
|
|
+
|
|
/* sending of data */
|
|
extern int nfnl_send(struct nfnl_handle *, struct nlmsghdr *);
|
|
extern int nfnl_sendmsg(const struct nfnl_handle *, const struct msghdr *msg,
|
|
@@ -170,7 +173,8 @@ extern int nfnl_parse_attr(struct nfattr **, int, struct nfattr *, int);
|
|
extern void nfnl_build_nfa_iovec(struct iovec *iov, struct nfattr *nfa,
|
|
u_int16_t type, u_int32_t len,
|
|
unsigned char *val);
|
|
-extern unsigned int nfnl_rcvbufsiz(struct nfnl_handle *h, unsigned int size);
|
|
+extern unsigned int nfnl_rcvbufsiz(const struct nfnl_handle *h,
|
|
+ unsigned int size);
|
|
|
|
|
|
extern void nfnl_dump_packet(struct nlmsghdr *, int, char *);
|
|
diff --git a/src/libnfnetlink.c b/src/libnfnetlink.c
|
|
index 6cbc43e..6b91631 100644
|
|
--- a/src/libnfnetlink.c
|
|
+++ b/src/libnfnetlink.c
|
|
@@ -85,6 +85,7 @@ struct nfnl_handle {
|
|
u_int32_t subscriptions;
|
|
u_int32_t seq;
|
|
u_int32_t dump;
|
|
+ u_int32_t rcv_buffer_size; /* for nfnl_catch */
|
|
struct nlmsghdr *last_nlhdr;
|
|
struct nfnl_subsys_handle subsys[NFNL_MAX_SUBSYS+1];
|
|
};
|
|
@@ -184,6 +185,7 @@ struct nfnl_handle *nfnl_open(void)
|
|
goto err_close;
|
|
}
|
|
nfnlh->seq = time(NULL);
|
|
+ nfnlh->rcv_buffer_size = NFNL_BUFFSIZE;
|
|
|
|
/* don't set pid here, only first socket of process has real pid !!!
|
|
* binding to pid '0' will default */
|
|
@@ -211,6 +213,19 @@ err_free:
|
|
}
|
|
|
|
/**
|
|
+ * nfnl_set_rcv_buffer_size - set the size of the receive buffer
|
|
+ * @h: libnfnetlink handler
|
|
+ * @size: buffer size
|
|
+ *
|
|
+ * This function sets the size of the receive buffer size, i.e. the size
|
|
+ * of the buffer used by nfnl_recv. Default value is 4096 bytes.
|
|
+ */
|
|
+void nfnl_set_rcv_buffer_size(struct nfnl_handle *h, unsigned int size)
|
|
+{
|
|
+ h->rcv_buffer_size = size;
|
|
+}
|
|
+
|
|
+/**
|
|
* nfnl_subsys_open - open a netlink subsystem
|
|
* @nfnlh: libnfnetlink handle
|
|
* @subsys_id: which nfnetlink subsystem we are interested in
|
|
@@ -943,7 +958,7 @@ void nfnl_build_nfa_iovec(struct iovec *iov, struct nfattr *nfa,
|
|
*
|
|
* This function returns the new size of the socket buffer.
|
|
*/
|
|
-unsigned int nfnl_rcvbufsiz(struct nfnl_handle *h, unsigned int size)
|
|
+unsigned int nfnl_rcvbufsiz(const struct nfnl_handle *h, unsigned int size)
|
|
{
|
|
int status;
|
|
socklen_t socklen = sizeof(size);
|
|
@@ -1129,6 +1144,7 @@ int nfnl_check_attributes(const struct nfnl_handle *h,
|
|
* the kernel which we don't understand
|
|
* yet. We have to silently ignore this
|
|
* for the sake of future compatibility */
|
|
+ attr = NFA_NEXT(attr, attrlen);
|
|
continue;
|
|
}
|
|
nfa[flavor - 1] = attr;
|
|
@@ -1190,6 +1206,7 @@ int nfnl_handle_packet(struct nfnl_handle *h, char *buf, int len)
|
|
return -1;
|
|
|
|
len -= rlen;
|
|
+ buf += rlen;
|
|
}
|
|
return 0;
|
|
}
|
|
@@ -1453,52 +1470,11 @@ int nfnl_iterator_next(const struct nfnl_handle *h, struct nfnl_iterator *it)
|
|
int nfnl_catch(struct nfnl_handle *h)
|
|
{
|
|
int ret;
|
|
- unsigned int size = NFNL_BUFFSIZE;
|
|
|
|
assert(h);
|
|
|
|
- /*
|
|
- * Since nfqueue can send big packets, we don't know how big
|
|
- * must be the buffer that have to store the received data.
|
|
- */
|
|
- {
|
|
- unsigned char buf[size];
|
|
- struct sockaddr_nl peer;
|
|
- struct iovec iov = {
|
|
- .iov_len = size,
|
|
- };
|
|
- struct msghdr msg = {
|
|
- .msg_name = (void *) &peer,
|
|
- .msg_namelen = sizeof(peer),
|
|
- .msg_iov = &iov,
|
|
- .msg_iovlen = 1,
|
|
- .msg_control = NULL,
|
|
- .msg_controllen = 0,
|
|
- .msg_flags = 0
|
|
- };
|
|
-
|
|
- memset(&peer, 0, sizeof(peer));
|
|
- peer.nl_family = AF_NETLINK;
|
|
- iov.iov_base = buf;
|
|
- iov.iov_len = size;
|
|
-
|
|
-retry: ret = recvmsg(h->fd, &msg, MSG_PEEK);
|
|
- if (ret == -1) {
|
|
- /* interrupted syscall must retry */
|
|
- if (errno == EINTR)
|
|
- goto retry;
|
|
- /* otherwise give up */
|
|
- return -1;
|
|
- }
|
|
-
|
|
- if (msg.msg_flags & MSG_TRUNC)
|
|
- /* maximum size of data received from netlink */
|
|
- size = 65535;
|
|
- }
|
|
-
|
|
- /* now, receive data from netlink */
|
|
while (1) {
|
|
- unsigned char buf[size];
|
|
+ unsigned char buf[h->rcv_buffer_size];
|
|
|
|
ret = nfnl_recv(h, buf, sizeof(buf));
|
|
if (ret == -1) {
|