From 1cfa410e80de0676aff995848c421e820e2338fe Mon Sep 17 00:00:00 2001 From: laforge Date: Tue, 30 Jan 2001 11:32:11 +0000 Subject: added support for multipart netlink messages --- ulogd/libipulog.old/include/libipulog/libipulog.h | 4 +- ulogd/libipulog.old/libipulog.c | 56 ++++++++++++++++++++--- 2 files changed, 52 insertions(+), 8 deletions(-) (limited to 'ulogd') diff --git a/ulogd/libipulog.old/include/libipulog/libipulog.h b/ulogd/libipulog.old/include/libipulog/libipulog.h index 9f920dd..9b0c277 100644 --- a/ulogd/libipulog.old/include/libipulog/libipulog.h +++ b/ulogd/libipulog.old/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.old/libipulog.c b/ulogd/libipulog.old/libipulog.c index ddfbdcd..9d647ae 100644 --- a/ulogd/libipulog.old/libipulog.c +++ b/ulogd/libipulog.old/libipulog.c @@ -1,5 +1,5 @@ /* - * libipulog.c, $Revision: 1.5 $ + * libipulog.c, $Revision: 1.6 $ * * 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.5 2000/09/22 06:57:16 laforge Exp $ + * $Id: libipulog.c,v 1.6 2001/01/30 09:28:04 laforge Exp $ */ #include @@ -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 */ -- cgit v1.2.3