Index: utils/nfqnl_test.c =================================================================== --- utils/nfqnl_test.c (révision 4261) +++ utils/nfqnl_test.c (copie de travail) @@ -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 (révision 4261) +++ include/libnfnetlink_queue/libnfnetlink_queue.h (copie de travail) @@ -2,6 +2,10 @@ * * (C) 2005 by Harald Welte * + * + * Changelog : + * (2005/08/11) added parsing function (Eric Leblond ) + * * 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 (révision 4261) +++ src/libnfnetlink_queue.c (copie de travail) @@ -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,87 @@ } 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 + *************************************************************/ + +#define nfnl_get_data(tb, attr, type) \ + ({ type __ret = 0; \ + if (tb[attr-1]) \ + __ret = *(type *)NFA_DATA(tb[attr-1]); \ + __ret; \ + }) + +#define nfnl_get_pointer_to_data(tb, attr, type) \ + ({ type *__ret = NULL; \ + if (tb[attr-1]) \ + __ret = NFA_DATA(tb[attr-1]); \ + __ret; \ + }) + +struct nfqnl_msg_packet_hdr * nfqnl_get_msg_packet_hdr(struct nfattr *nfa[]){ + return nfnl_get_pointer_to_data(nfa,NFQA_PACKET_HDR,struct nfqnl_msg_packet_hdr ); +} + +uint32_t nfqnl_get_nfmark(struct nfattr *nfa[]){ + return nfnl_get_data(nfa, NFQA_MARK, u_int32_t); +} + +struct nfqnl_msg_packet_timestamp * nfqnl_get_timestamp(struct nfattr *nfa[]){ + return nfnl_get_pointer_to_data(nfa,NFQA_TIMESTAMP,struct nfqnl_msg_packet_timestamp); +} + +/* return 0 if not set */ +int nfqnl_get_indev(struct nfattr *nfa[],u_int32_t* indev, u_int32_t* physindev){ + if (indev){ + *indev=nfnl_get_data(nfa, NFQA_IFINDEX_INDEV, u_int32_t); + if (physindev){ + *physindev=nfnl_get_data(nfa, NFQA_IFINDEX_PHYSINDEV, u_int32_t); + } + 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 (outdev){ + *outdev=nfnl_get_data(nfa, NFQA_IFINDEX_OUTDEV, u_int32_t); + if (physoutdev){ + *physoutdev=nfnl_get_data(nfa, NFQA_IFINDEX_PHYSOUTDEV, u_int32_t); + } + return 1; + } + return 0; +} + +struct nfqnl_msg_packet_hw * nfqnl_get_packet_hw(struct nfattr *nfa[]){ + return nfnl_get_pointer_to_data(nfa,NFQA_HWADDR,struct nfqnl_msg_packet_hw); +} + +int nfqnl_get_payload(struct nfattr *nfa[],char ** data,unsigned int* datalen){ + if (datalen) { + *data=nfnl_get_pointer_to_data(nfa, NFQA_PAYLOAD, char*); + if (*data){ + *datalen=NFA_PAYLOAD(nfa[NFQA_PAYLOAD-1]); + return 1; + } + } + return 0; +} + + + Index: src/Makefile.am =================================================================== --- src/Makefile.am (révision 4261) +++ src/Makefile.am (copie de travail) @@ -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=