diff --git a/include/netlink/netfilter/queue_msg.h b/include/netlink/netfilter/queue_msg.h index 95a5d65..24ed081 100644 --- a/include/netlink/netfilter/queue_msg.h +++ b/include/netlink/netfilter/queue_msg.h @@ -93,7 +93,9 @@ extern unsigned int nfnl_queue_msg_get_verdict(const struct nfnl_queue_msg *); extern struct nl_msg * nfnl_queue_msg_build_verdict(const struct nfnl_queue_msg *); extern int nfnl_queue_msg_send_verdict(struct nl_sock *, const struct nfnl_queue_msg *); - +extern int nfnl_queue_msg_send_verdict_payload(struct nl_sock *, + const struct nfnl_queue_msg *, + const void *, unsigned ); #ifdef __cplusplus } #endif diff --git a/lib/netfilter/queue_msg.c b/lib/netfilter/queue_msg.c index af50fa0..ab0a58b 100644 --- a/lib/netfilter/queue_msg.c +++ b/lib/netfilter/queue_msg.c @@ -7,6 +7,7 @@ * of the License. * * Copyright (c) 2007, 2008 Patrick McHardy + * Copyright (c) 2010 Karl Hiramoto */ /** @@ -189,6 +190,12 @@ nla_put_failure: return NULL; } +/** +* Send a message verdict/mark +* @arg nlh netlink messsage header +* @arg msg queue msg +* @return 0 on OK or error code +*/ int nfnl_queue_msg_send_verdict(struct nl_sock *nlh, const struct nfnl_queue_msg *msg) { @@ -206,6 +213,51 @@ int nfnl_queue_msg_send_verdict(struct nl_sock *nlh, return wait_for_ack(nlh); } +/** +* Send a message verdict including the payload +* @arg nlh netlink messsage header +* @arg msg queue msg +* @arg payload_data packet payload data +* @arg payload_len payload length +* @return 0 on OK or error code +*/ +int nfnl_queue_msg_send_verdict_payload(struct nl_sock *nlh, + const struct nfnl_queue_msg *msg, + const void *payload_data, unsigned payload_len) +{ + struct nl_msg *nlmsg; + int err; + struct iovec iov[3]; + struct nlattr nla; + + nlmsg = nfnl_queue_msg_build_verdict(msg); + if (nlmsg == NULL) + return -NLE_NOMEM; + + memset(iov, 0, sizeof(iov)); + + iov[0].iov_base = (void *) nlmsg_hdr(nlmsg); + iov[0].iov_len = nlmsg_hdr(nlmsg)->nlmsg_len; + + nla.nla_type = NFQA_PAYLOAD; + nla.nla_len = payload_len + sizeof(nla); + nlmsg_hdr(nlmsg)->nlmsg_len += nla.nla_len; + + iov[1].iov_base = (void *) &nla; + iov[1].iov_len = sizeof(nla); + + iov[2].iov_base = (void *) payload_data; + iov[2].iov_len = NLA_ALIGN(payload_len); + + nl_auto_complete(nlh, nlmsg); + err = nl_send_iovec(nlh, nlmsg, iov, 3); + + nlmsg_free(nlmsg); + if (err < 0) + return err; + return wait_for_ack(nlh); +} + #define NFNLMSG_QUEUE_TYPE(type) NFNLMSG_TYPE(NFNL_SUBSYS_QUEUE, (type)) static struct nl_cache_ops nfnl_queue_msg_ops = { .co_name = "netfilter/queue_msg", diff --git a/lib/netfilter/queue_msg_obj.c b/lib/netfilter/queue_msg_obj.c index aa03b15..97813e8 100644 --- a/lib/netfilter/queue_msg_obj.c +++ b/lib/netfilter/queue_msg_obj.c @@ -197,6 +197,11 @@ uint16_t nfnl_queue_msg_get_group(const struct nfnl_queue_msg *msg) return msg->queue_msg_group; } +/** +* Set the protocol family +* @arg msg NF queue message +* @arg family AF_XXX address family example: AF_INET, AF_UNIX, etc +*/ void nfnl_queue_msg_set_family(struct nfnl_queue_msg *msg, uint8_t family) { msg->queue_msg_family = family; @@ -424,6 +429,11 @@ const void *nfnl_queue_msg_get_payload(const struct nfnl_queue_msg *msg, int *le return msg->queue_msg_payload; } +/** +* Return the number of items matching a filter in the cache +* @arg msg queue msg +* @arg verdict NF_DROP, NF_ACCEPT, NF_REPEAT, etc +*/ void nfnl_queue_msg_set_verdict(struct nfnl_queue_msg *msg, unsigned int verdict) {