summaryrefslogtreecommitdiffstats
path: root/ulogd/libipulog
diff options
context:
space:
mode:
Diffstat (limited to 'ulogd/libipulog')
-rw-r--r--ulogd/libipulog/Makefile2
-rw-r--r--ulogd/libipulog/include/libipulog/libipulog.h4
-rw-r--r--ulogd/libipulog/libipulog.c56
-rw-r--r--ulogd/libipulog/ulog_test.c15
4 files changed, 61 insertions, 16 deletions
diff --git a/ulogd/libipulog/Makefile b/ulogd/libipulog/Makefile
index e737363..ea6b27a 100644
--- a/ulogd/libipulog/Makefile
+++ b/ulogd/libipulog/Makefile
@@ -2,7 +2,7 @@ CC = gcc
CFLAGS = -I./include # -g
ulog_test: ulog_test.c libipulog.a
- $(CC) $(CFLAGS) -i ulog_test.c libipulog.a -o ulog_test
+ $(CC) $(CFLAGS) ulog_test.c libipulog.a -o ulog_test
libipulog.o: libipulog.c
$(CC) $(CFLAGS) -c libipulog.c -o libipulog.o
diff --git a/ulogd/libipulog/include/libipulog/libipulog.h b/ulogd/libipulog/include/libipulog/libipulog.h
index 9f920dd..9b0c277 100644
--- a/ulogd/libipulog/include/libipulog/libipulog.h
+++ b/ulogd/libipulog/include/libipulog/libipulog.h
@@ -23,7 +23,9 @@ void ipulog_destroy_handle(struct ipulog_handle *h);
ssize_t ipulog_read(struct ipulog_handle *h,
unsigned char *buf, size_t len, int timeout);
-ulog_packet_msg_t *ipulog_get_packet(const unsigned char *buf);
+ulog_packet_msg_t *ipulog_get_packet(struct ipulog_handle *h,
+ const unsigned char *buf,
+ size_t len);
void ipulog_perror(const char *s);
diff --git a/ulogd/libipulog/libipulog.c b/ulogd/libipulog/libipulog.c
index d7838b6..4aa12e5 100644
--- a/ulogd/libipulog/libipulog.c
+++ b/ulogd/libipulog/libipulog.c
@@ -1,5 +1,5 @@
/*
- * libipulog.c, $Revision: 1.4 $
+ * libipulog.c, $Revision: 1.5 $
*
* netfilter ULOG userspace library.
*
@@ -9,7 +9,7 @@
* This library is still under development, so be aware of sudden interface
* changes
*
- * $Id: libipulog.c,v 1.4 2000/08/12 07:11:29 laforge Exp $
+ * $Id: libipulog.c,v 1.5 2000/09/22 06:57:16 laforge Exp $
*/
#include <stdlib.h>
@@ -25,6 +25,7 @@ struct ipulog_handle
u_int8_t blocking;
struct sockaddr_nl local;
struct sockaddr_nl peer;
+ struct nlmsghdr* last_nlhdr;
};
/* internal */
@@ -41,9 +42,10 @@ enum
IPULOG_ERR_NLEOF,
IPULOG_ERR_TRUNC,
IPULOG_ERR_INVGR,
+ IPULOG_ERR_INVNL,
};
-#define IPULOG_MAXERR IPULOG_ERR_INVGR
+#define IPULOG_MAXERR IPULOG_ERR_INVNL
static int ipulog_errno = IPULOG_ERR_NONE;
@@ -59,10 +61,11 @@ struct ipulog_errmap_t
{ IPULOG_ERR_SOCKET, "Unable to create netlink socket" },
{ IPULOG_ERR_BIND, "Unable to bind netlink socket" },
{ IPULOG_ERR_RECVBUF, "Receive buffer size invalid" },
- { IPULOG_ERR_RECV, "Receive buffer size invalid" },
+ { IPULOG_ERR_RECV, "Error during netlink receive" },
{ IPULOG_ERR_NLEOF, "Received EOF on netlink socket" },
{ IPULOG_ERR_TRUNC, "Receive message truncated" },
{ IPULOG_ERR_INVGR, "Invalid group specified" },
+ { IPULOG_ERR_INVNL, "Invalid netlink message" },
};
static ssize_t ipulog_netlink_recvfrom(const struct ipulog_handle *h,
@@ -94,7 +97,7 @@ static ssize_t ipulog_netlink_recvfrom(const struct ipulog_handle *h,
return -1;
}
nlh = (struct nlmsghdr *)buf;
- if (nlh->nlmsg_flags & MSG_TRUNC || nlh->nlmsg_len > status)
+ if (nlh->nlmsg_flags & MSG_TRUNC || status > len)
{
ipulog_errno = IPULOG_ERR_TRUNC;
return -1;
@@ -186,9 +189,48 @@ ssize_t ipulog_read(struct ipulog_handle *h, unsigned char *buf,
/* get a pointer to the actual start of the ipulog packet,
use this to strip netlink header */
-ulog_packet_msg_t *ipulog_get_packet(const unsigned char *buf)
+ulog_packet_msg_t *ipulog_get_packet(struct ipulog_handle *h,
+ const unsigned char *buf,
+ size_t len)
{
- return NLMSG_DATA((struct nlmsghdr *) buf);
+ struct nlmsghdr *nlh;
+ size_t remain_len;
+
+ /* if last header in handle not inside this buffer,
+ * drop reference to last header */
+ if ((unsigned char *)h->last_nlhdr > (buf + len) ||
+ (unsigned char *)h->last_nlhdr < buf) {
+ h->last_nlhdr = NULL;
+ }
+
+ if (!h->last_nlhdr) {
+ /* fist message in buffer */
+ nlh = (struct nlmsghdr *) buf;
+ if (!NLMSG_OK(nlh, len)) {
+ /* ERROR */
+ ipulog_errno = IPULOG_ERR_INVNL;
+ return NULL;
+ }
+ } else {
+ /* we are in n-th part of multilink message */
+ if (h->last_nlhdr->nlmsg_type == NLMSG_DONE) {
+ /* if last part in multilink message, return */
+ h->last_nlhdr = NULL;
+ return NULL;
+ }
+
+ /* calculate remaining lenght from lasthdr to end of buffer */
+ remain_len = (len -
+ ((unsigned char *)h->last_nlhdr - buf));
+ nlh = NLMSG_NEXT(h->last_nlhdr, remain_len);
+ }
+
+ /* update last_nlhdr field */
+ if (nlh->nlmsg_flags & NLM_F_MULTI) {
+ h->last_nlhdr = nlh;
+ }
+
+ return NLMSG_DATA(nlh);
}
/* print a human readable description of the last error to stderr */
diff --git a/ulogd/libipulog/ulog_test.c b/ulogd/libipulog/ulog_test.c
index 71238b6..c9ef9b7 100644
--- a/ulogd/libipulog/ulog_test.c
+++ b/ulogd/libipulog/ulog_test.c
@@ -1,4 +1,4 @@
-/* ulog_test, $Revision: 1.2 $
+/* ulog_test, $Revision: 1.3 $
*
* small testing program for libipulog, part of the netfilter ULOG target
* for the linux 2.4 netfilter subsystem.
@@ -7,7 +7,7 @@
*
* this code is released under the terms of GNU GPL
*
- * $Id: ulog_test.c,v 1.2 2000/07/31 15:02:33 laforge Exp $
+ * $Id: ulog_test.c,v 1.3 2000/09/22 06:57:16 laforge Exp $
*/
#include <stdio.h>
@@ -42,7 +42,7 @@ int main(int argc, char *argv[])
{
struct ipulog_handle *h;
unsigned char* buf;
- size_t len;
+ int len;
ulog_packet_msg_t *upkt;
int i;
@@ -67,14 +67,15 @@ int main(int argc, char *argv[])
/* loop receiving packets and handling them over to handle_packet */
for (i = 0; i < atoi(argv[1]); i++) {
- len = ipulog_read(h, buf, BUFSIZ, 1);
+ len = ipulog_read(h, buf, MYBUFSIZ, 1);
if (len < 0) {
ipulog_perror("ulog_test: short read");
exit(1);
}
- upkt = ipulog_get_packet(buf);
- printf("%d: ", len);
- handle_packet(upkt);
+ printf("%d bytes received\n", len);
+ while (upkt = ipulog_get_packet(h, buf, len)) {
+ handle_packet(upkt);
+ }
}
/* just to give it a cleaner look */