From: Eric Leblond <eric@inl.fr>
To: laforge@netfilter.org
Cc: netfilter-devel@lists.netfilter.org,
Vincent Deffontaines <vincent@inl.fr>
Subject: [PATCH] message parsing functions for nfqueue
Date: Thu, 11 Aug 2005 23:01:46 +0200 [thread overview]
Message-ID: <1123794106.4980.11.camel@porky> (raw)
[-- Attachment #1.1: Type: text/plain, Size: 700 bytes --]
Hi,
This is a patch against libnfnetlink_queue.
It adds "high" level functions to access to the data contained in a
nfqueue message. These are mostly encapsulation of NFA macros.
The exemple provided in the utils directory now uses these functions.
I've also modified NuFW to use the new API to test its usability. The
obtained code is clean and the port was easy, thus I consider it
improves the situation. Although, it may miss some higher level
functions to access to multiple fields at the same time. I've thought
about some but they may be too NuFW oriented.
Feedbacks welcome.
BR,
--
Eric Leblond <eric@regit.org>
NuFW, Now User Filtering Works : http://www.nufw.org
[-- Attachment #1.2: libnfnetlink_nfqueue.diff --]
[-- Type: text/x-patch, Size: 9779 bytes --]
Index: utils/nfqnl_test.c
===================================================================
--- utils/nfqnl_test.c (revision 4237)
+++ utils/nfqnl_test.c (working copy)
@@ -11,35 +11,37 @@
static u_int32_t print_pkt (struct nfattr *tb[])
{
int id = 0;
-
- if (tb[NFQA_PACKET_HDR-1]) {
- struct nfqnl_msg_packet_hdr *ph =
- NFA_DATA(tb[NFQA_PACKET_HDR-1]);
+ struct nfqnl_msg_packet_hdr *ph;
+ u_int32_t mark,ifi;
+ int ret;
+ unsigned int datalength;
+ char * data;
+
+ ph = nfqnl_get_msg_packet_hdr(tb);
+ if (ph){
id = ntohl(ph->packet_id);
printf("hw_protocol=0x%04x hook=%u id=%u ",
ntohs(ph->hw_protocol), ph->hook, id);
}
-
- if (tb[NFQA_MARK-1]) {
- u_int32_t mark =
- ntohl(*(u_int32_t *)NFA_DATA(tb[NFQA_MARK-1]));
+
+ mark=nfqnl_get_nfmark(tb);
+ if (mark) {
printf("mark=%u ", mark);
}
- if (tb[NFQA_IFINDEX_INDEV-1]) {
- u_int32_t ifi =
- ntohl(*(u_int32_t *)NFA_DATA(tb[NFQA_IFINDEX_INDEV-1]));
- printf("indev=%u ", ifi);
+ ret=nfqnl_get_indev(tb,&ifi,NULL);
+ if (ret) {
+ printf("indev=%u ", ntohl(ifi));
}
- if (tb[NFQA_IFINDEX_OUTDEV-1]) {
- u_int32_t ifi =
- ntohl(*(u_int32_t *)NFA_DATA(tb[NFQA_IFINDEX_OUTDEV-1]));
- printf("outdev=%u ", ifi);
+ ret=nfqnl_get_outdev(tb,&ifi,NULL);
+ if (ret) {
+ printf("outdev=%u ", ntohl(ifi));
}
- if (tb[NFQA_PAYLOAD-1]) {
- printf("payload_len=%d ", NFA_PAYLOAD(tb[NFQA_PAYLOAD-1]));
+ ret=nfqnl_get_payload(tb,&data,&datalength);
+ if (ret) {
+ printf("payload_len=%d ", datalength);
}
fputc('\n', stdout);
Index: include/libnfnetlink_queue/libnfnetlink_queue.h
===================================================================
--- include/libnfnetlink_queue/libnfnetlink_queue.h (revision 4237)
+++ include/libnfnetlink_queue/libnfnetlink_queue.h (working copy)
@@ -2,6 +2,10 @@
*
* (C) 2005 by Harald Welte <laforge@gnumonks.org>
*
+ *
+ * Changelog :
+ * (2005/08/11) added parsing function (Eric Leblond <regit@inl.fr>)
+ *
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
*/
@@ -21,7 +25,7 @@
extern struct nfnl_handle *nfqnl_nfnlh(struct nfqnl_handle *h);
extern int nfqnl_fd(struct nfqnl_handle *h);
-typedef nfqnl_callback(struct nfqnl_q_handle *gh, struct nfgenmsg *nfmsg,
+typedef int nfqnl_callback(struct nfqnl_q_handle *gh, struct nfgenmsg *nfmsg,
struct nfattr *nfa[], void *data);
@@ -47,10 +51,33 @@
u_int32_t verdict,
u_int32_t data_len,
unsigned char *buf);
+
extern int nfqnl_set_verdict_mark(struct nfqnl_q_handle *qh,
u_int32_t id,
u_int32_t verdict,
u_int32_t mark,
u_int32_t datalen,
unsigned char *buf);
+
+/* message parsing function */
+
+extern struct nfqnl_msg_packet_hdr * nfqnl_get_msg_packet_hdr(struct nfattr *nfa[]);
+
+extern u_int32_t nfqnl_get_nfmark(struct nfattr *nfa[]);
+
+extern struct nfqnl_msg_packet_timestamp * nfqnl_get_timestamp(struct nfattr *nfa[]);
+
+/* return 0 if not set */
+extern int nfqnl_get_indev(struct nfattr *nfa[],u_int32_t* indev, u_int32_t* physindev);
+
+/* return 0 if not set */
+extern int nfqnl_get_outdev(struct nfattr *nfa[],u_int32_t* outdev, u_int32_t* physoutdev);
+
+extern struct nfqnl_msg_packet_hw * nfqnl_get_packet_hw(struct nfattr *nfa[]);
+
+/* return 0 if problem */
+extern int nfqnl_get_payload(struct nfattr *nfa[],char ** data,unsigned int* datalen);
+
+
+
#endif /* __LIBNFQNETLINK_H */
Index: src/libnfnetlink_queue.c
===================================================================
--- src/libnfnetlink_queue.c (revision 4237)
+++ src/libnfnetlink_queue.c (working copy)
@@ -89,9 +89,9 @@
}
/* build a NFQNL_MSG_CONFIG message */
-static int
+ static int
__build_send_cfg_msg(struct nfqnl_handle *h, u_int8_t command,
- u_int16_t queuenum, u_int16_t pf)
+ u_int16_t queuenum, u_int16_t pf)
{
char buf[NFNL_HEADER_LEN
+NFA_LENGTH(sizeof(struct nfqnl_msg_config_cmd))];
@@ -99,7 +99,7 @@
struct nlmsghdr *nmh = (struct nlmsghdr *) buf;
nfnl_fill_hdr(&h->nfnlh, nmh, 0, AF_UNSPEC, queuenum,
- NFQNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
+ NFQNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
cmd.command = command;
cmd.pf = htons(pf);
@@ -109,7 +109,7 @@
}
static int __nfqnl_rcv_pkt(struct nlmsghdr *nlh, struct nfattr *nfa[],
- void *data)
+ void *data)
{
struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
struct nfqnl_handle *h = data;
@@ -196,9 +196,9 @@
/* bind this socket to a specific queue number */
struct nfqnl_q_handle *nfqnl_create_queue(struct nfqnl_handle *h,
- u_int16_t num,
- nfqnl_callback *cb,
- void *data)
+ u_int16_t num,
+ nfqnl_callback *cb,
+ void *data)
{
int ret;
struct nfqnl_q_handle *qh;
@@ -243,7 +243,7 @@
}
int nfqnl_set_mode(struct nfqnl_q_handle *qh,
- u_int8_t mode, u_int32_t range)
+ u_int8_t mode, u_int32_t range)
{
char buf[NFNL_HEADER_LEN
+NFA_LENGTH(sizeof(struct nfqnl_msg_config_params))];
@@ -251,19 +251,19 @@
struct nlmsghdr *nmh = (struct nlmsghdr *) buf;
nfnl_fill_hdr(&qh->h->nfnlh, nmh, 0, AF_UNSPEC, qh->id,
- NFQNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
+ NFQNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK);
params.copy_range = htonl(range);
params.copy_mode = mode;
nfnl_addattr_l(nmh, sizeof(buf), NFQA_CFG_PARAMS, ¶ms,
- sizeof(params));
+ sizeof(params));
return nfnl_talk(&qh->h->nfnlh, nmh, 0, 0, NULL, NULL, NULL);
}
static int __set_verdict(struct nfqnl_q_handle *qh, u_int32_t id,
- u_int32_t verdict, u_int32_t mark, int set_mark,
- u_int32_t data_len, unsigned char *data)
+ u_int32_t verdict, u_int32_t mark, int set_mark,
+ u_int32_t data_len, unsigned char *data)
{
struct nfqnl_msg_verdict_hdr vh;
char buf[NFNL_HEADER_LEN
@@ -278,8 +278,8 @@
vh.id = htonl(id);
nfnl_fill_hdr(&qh->h->nfnlh, nmh, 0, AF_UNSPEC, qh->id,
- NFQNL_MSG_VERDICT, NLM_F_REQUEST);
-
+ NFQNL_MSG_VERDICT, NLM_F_REQUEST);
+
/* add verdict header */
nfnl_addattr_l(nmh, sizeof(buf), NFQA_VERDICT_HDR, &vh, sizeof(vh));
@@ -294,7 +294,7 @@
struct nfattr data_attr;
nfnl_build_nfa_iovec(&iov[1], &data_attr, NFQA_PAYLOAD,
- data_len, data);
+ data_len, data);
nvecs += 2;
}
@@ -302,15 +302,98 @@
}
int nfqnl_set_verdict(struct nfqnl_q_handle *qh, u_int32_t id,
- u_int32_t verdict, u_int32_t data_len,
- unsigned char *buf)
+ u_int32_t verdict, u_int32_t data_len,
+ unsigned char *buf)
{
return __set_verdict(qh, id, verdict, 0, 0, data_len, buf);
}
int nfqnl_set_verdict_mark(struct nfqnl_q_handle *qh, u_int32_t id,
- u_int32_t verdict, u_int32_t mark,
- u_int32_t datalen, unsigned char *buf)
+ u_int32_t verdict, u_int32_t mark,
+ u_int32_t datalen, unsigned char *buf)
{
return __set_verdict(qh, id, verdict, mark, 1, datalen, buf);
}
+
+/*************************************************************
+ * Message parsing functions
+ *************************************************************/
+
+
+struct nfqnl_msg_packet_hdr * nfqnl_get_msg_packet_hdr(struct nfattr *nfa[]){
+ if (nfa){
+ if (nfa[NFQA_PACKET_HDR-1]) {
+ return (struct nfqnl_msg_packet_hdr *)NFA_DATA(nfa[NFQA_PACKET_HDR-1]);
+ }
+ }
+ return NULL;
+}
+
+uint32_t nfqnl_get_nfmark(struct nfattr *nfa[]){
+ if (nfa){
+ if (nfa[NFQA_MARK-1]) {
+ return ntohl(*(u_int32_t *)NFA_DATA(nfa[NFQA_MARK-1]));
+ }
+ }
+ return 0;
+}
+
+struct nfqnl_msg_packet_timestamp * nfqnl_get_timestamp(struct nfattr *nfa[]){
+ if (nfa){
+ if (nfa[NFQA_TIMESTAMP-1]) {
+ return (struct nfqnl_msg_packet_timestamp *)NFA_DATA(nfa[NFQA_TIMESTAMP-1]);
+ }
+ }
+ return NULL;
+}
+
+/* return 0 if not set */
+int nfqnl_get_indev(struct nfattr *nfa[],u_int32_t* indev, u_int32_t* physindev){
+ if (nfa){
+ if (indev && nfa[NFQA_IFINDEX_INDEV-1]) {
+ *indev = ntohl(*(u_int32_t *)NFA_DATA(nfa[NFQA_IFINDEX_INDEV-1]));
+ if (physindev && nfa[NFQA_IFINDEX_PHYSINDEV-1] ) {
+ *physindev = ntohl(*(u_int32_t *)NFA_DATA(nfa[NFQA_IFINDEX_PHYSINDEV-1]));
+ }
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* return 0 if not set */
+int nfqnl_get_outdev(struct nfattr *nfa[],u_int32_t* outdev, u_int32_t* physoutdev){
+ if (nfa){
+ if (outdev && nfa[NFQA_IFINDEX_OUTDEV-1]) {
+ *outdev = ntohl(*(u_int32_t *)NFA_DATA(nfa[NFQA_IFINDEX_OUTDEV-1]));
+ if (physoutdev && nfa[NFQA_IFINDEX_PHYSOUTDEV-1]) {
+ *physoutdev = ntohl(*(u_int32_t *)NFA_DATA(nfa[NFQA_IFINDEX_PHYSOUTDEV-1]));
+ }
+ return 1;
+ }
+ }
+ return 0;
+}
+
+struct nfqnl_msg_packet_hw * nfqnl_get_packet_hw(struct nfattr *nfa[]){
+ if (nfa){
+ if (nfa[NFQA_HWADDR-1]) {
+ return (struct nfqnl_msg_packet_hw*)NFA_DATA(nfa[NFQA_HWADDR-1]);
+ }
+ }
+ return NULL;
+}
+
+int nfqnl_get_payload(struct nfattr *nfa[],char ** data,unsigned int* datalen){
+ if (nfa && datalen) {
+ if (nfa[NFQA_PAYLOAD-1]) {
+ *data=NFA_DATA(nfa[NFQA_PAYLOAD-1]);
+ *datalen=NFA_PAYLOAD(nfa[NFQA_PAYLOAD-1]);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+
Index: src/Makefile.am
===================================================================
--- src/Makefile.am (revision 4237)
+++ src/Makefile.am (working copy)
@@ -2,7 +2,7 @@
#EXTRA_DIST = $(man_MANS) acinclude.m4
-INCLUDES = $(all_includes) -I$(top_srcdir)/include -I${KERNELDIR}
+INCLUDES = $(all_includes) -I$(top_srcdir)/include -I${KERNELDIR}
AM_CFLAGS=-fPIC -Wall
LIBS=
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
next reply other threads:[~2005-08-11 21:01 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-08-11 21:01 Eric Leblond [this message]
2005-08-11 22:48 ` [PATCH] message parsing functions for nfqueue Harald Welte
2005-08-12 12:41 ` Harald Welte
2005-08-12 1:30 ` Pablo Neira
2005-08-12 8:42 ` Eric Leblond
2005-08-12 12:04 ` Harald Welte
2005-09-14 19:57 ` Eric Leblond
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1123794106.4980.11.camel@porky \
--to=eric@inl.fr \
--cc=laforge@netfilter.org \
--cc=netfilter-devel@lists.netfilter.org \
--cc=vincent@inl.fr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.