From a3c179d2af76c658dbeac434118d85b8630d000a Mon Sep 17 00:00:00 2001 From: "/C=DE/ST=Berlin/L=Berlin/O=Netfilter Project/OU=Development/CN=laforge/emailAddress=laforge@netfilter.org" Date: Sat, 30 Jul 2005 16:39:46 +0000 Subject: Add nfnl_rcvbufsiz(), nfnl_msg_get_first(), nfnl_msg_get_next() --- libnfnetlink.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- libnfnetlink.h | 12 ++++++++- 2 files changed, 87 insertions(+), 2 deletions(-) diff --git a/libnfnetlink.c b/libnfnetlink.c index 80cb0c4..ef7a18e 100644 --- a/libnfnetlink.c +++ b/libnfnetlink.c @@ -17,6 +17,7 @@ #include #include +#include #include #include "libnfnetlink.h" @@ -187,7 +188,8 @@ void nfnl_fill_hdr(struct nfnl_handle *nfnlh, } struct nfattr * -nfnl_parse_hdr(struct nfnl_handle *nfnlh, const struct nlmsghdr *nlh, +nfnl_parse_hdr(const struct nfnl_handle *nfnlh, + const struct nlmsghdr *nlh, struct nfgenmsg **genmsg) { if (nlh->nlmsg_len < NLMSG_LENGTH(sizeof(struct nfgenmsg))) @@ -550,3 +552,76 @@ void nfnl_build_nfa_iovec(struct iovec *iov, struct nfattr *nfa, iov[1].iov_base = val; iov[1].iov_len = NFA_ALIGN(len); } + +#ifndef SO_RCVBUFFORCE +#define SO_RCVBUFFORCE (33) +#endif + +unsigned int nfnl_rcvbufsiz(struct nfnl_handle *h, unsigned int size) +{ + int status; + socklen_t socklen = sizeof(size); + unsigned int read_size = 0; + + /* first we try the FORCE option, which is introduced in kernel + * 2.6.14 to give "root" the ability to override the system wide + * maximum */ + status = setsockopt(h->fd, SOL_SOCKET, SO_RCVBUFFORCE, &size, socklen); + if (status < 0) { + /* if this didn't work, we try at least to get the system + * wide maximum (or whatever the user requested) */ + setsockopt(h->fd, SOL_SOCKET, SO_RCVBUF, &size, socklen); + } + getsockopt(h->fd, SOL_SOCKET, SO_RCVBUF, &read_size, &socklen); + + return read_size; +} + + +struct nlmsghdr *nfnl_get_msg_first(struct nfnl_handle *h, + const unsigned char *buf, + size_t len) +{ + struct nlmsghdr *nlh; + + /* first message in buffer */ + nlh = (struct nlmsghdr *)buf; + if (!NLMSG_OK(nlh, len)) + return NULL; + h->last_nlhdr = nlh; + + return nlh; +} + +struct nlmsghdr *nfnl_get_msg_next(struct nfnl_handle *h, + const unsigned char *buf, + size_t len) +{ + struct nlmsghdr *nlh; + size_t remain_len; + + /* if last header in handle not inside this buffer, + * drop reference to last header */ + if (!h->last_nlhdr || + (unsigned char *)h->last_nlhdr > (buf + len) || + (unsigned char *)h->last_nlhdr < buf) { + h->last_nlhdr = NULL; + return NULL; + } + + /* n-th part of multipart message */ + if (h->last_nlhdr->nlmsg_type == NLMSG_DONE || + h->last_nlhdr->nlmsg_flags & NLM_F_MULTI) { + /* if last part in multipart message or no + * multipart message at all, return */ + h->last_nlhdr = NULL; + return NULL; + } + + remain_len = (len - ((unsigned char *)h->last_nlhdr - buf)); + nlh = NLMSG_NEXT(h->last_nlhdr, remain_len); + + h->last_nlhdr = nlh; + + return nlh; +} diff --git a/libnfnetlink.h b/libnfnetlink.h index 43ed151..95ec004 100644 --- a/libnfnetlink.h +++ b/libnfnetlink.h @@ -23,6 +23,7 @@ struct nfnl_handle { u_int8_t subsys_id; u_int32_t seq; u_int32_t dump; + struct nlmsghdr *last_nlhdr; }; /* get a new library handle */ @@ -39,7 +40,7 @@ extern void nfnl_fill_hdr(struct nfnl_handle *, struct nlmsghdr *, unsigned int, u_int8_t, u_int16_t, u_int16_t, u_int16_t); -extern struct nfattr *nfnl_parse_hdr(struct nfnl_handle *nfnlh, +extern struct nfattr *nfnl_parse_hdr(const struct nfnl_handle *nfnlh, const struct nlmsghdr *nlh, struct nfgenmsg **genmsg); @@ -70,6 +71,15 @@ 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 struct nlmsghdr *nfnl_get_msg_first(struct nfnl_handle *h, + const unsigned char *buf, + size_t len); +extern struct nlmsghdr *nfnl_get_msg_next(struct nfnl_handle *h, + const unsigned char *buf, + size_t len); extern void nfnl_dump_packet(struct nlmsghdr *, int, char *); #endif /* __LIBNFNETLINK_H */ -- cgit v1.2.3