9 #include <libmnl/libmnl.h> 
   10 #include <linux/netfilter.h> 
   11 #include <linux/netfilter/nfnetlink.h> 
   13 #include <linux/types.h> 
   14 #include <linux/netfilter/nfnetlink_queue.h> 
   16 #include <libnetfilter_queue/libnetfilter_queue.h> 
   19 #include <linux/netfilter/nfnetlink_conntrack.h> 
   21 static struct mnl_socket *nl;
 
   23 static struct nlmsghdr *
 
   24 nfq_hdr_put(
char *buf, 
int type, uint32_t queue_num)
 
   26         struct nlmsghdr *nlh = mnl_nlmsg_put_header(buf);
 
   27         nlh->nlmsg_type = (NFNL_SUBSYS_QUEUE << 8) | type;
 
   28         nlh->nlmsg_flags = NLM_F_REQUEST;
 
   30         struct nfgenmsg *nfg = mnl_nlmsg_put_extra_header(nlh, 
sizeof(*nfg));
 
   31         nfg->nfgen_family = AF_UNSPEC;
 
   32         nfg->version = NFNETLINK_V0;
 
   33         nfg->res_id = htons(queue_num);
 
   39 nfq_send_verdict(
int queue_num, uint32_t 
id)
 
   41         char buf[MNL_SOCKET_BUFFER_SIZE];
 
   45         nlh = nfq_hdr_put(buf, NFQNL_MSG_VERDICT, queue_num);
 
   46         nfq_nlmsg_verdict_put(nlh, 
id, NF_ACCEPT);
 
   49         nest = mnl_attr_nest_start(nlh, NFQA_CT);
 
   52         mnl_attr_put_u32(nlh, CTA_MARK, htonl(42));
 
   56         mnl_attr_nest_end(nlh, nest);
 
   58         if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
 
   59                 perror(
"mnl_socket_send");
 
   64 static int queue_cb(
const struct nlmsghdr *nlh, 
void *data)
 
   66         struct nfqnl_msg_packet_hdr *ph = NULL;
 
   67         struct nlattr *attr[NFQA_MAX+1] = {};
 
   68         uint32_t 
id = 0, skbinfo;
 
   73                 perror(
"problems parsing");
 
   77         nfg = mnl_nlmsg_get_payload(nlh);
 
   79         if (attr[NFQA_PACKET_HDR] == NULL) {
 
   80                 fputs(
"metaheader not set\n", stderr);
 
   84         ph = mnl_attr_get_payload(attr[NFQA_PACKET_HDR]);
 
   86         plen = mnl_attr_get_payload_len(attr[NFQA_PAYLOAD]);
 
   89         skbinfo = attr[NFQA_SKB_INFO] ? ntohl(mnl_attr_get_u32(attr[NFQA_SKB_INFO])) : 0;
 
   91         if (attr[NFQA_CAP_LEN]) {
 
   92                 uint32_t orig_len = ntohl(mnl_attr_get_u32(attr[NFQA_CAP_LEN]));
 
   97         if (skbinfo & NFQA_SKB_GSO)
 
  100         id = ntohl(ph->packet_id);
 
  101         printf(
"packet received (id=%u hw=0x%04x hook=%u, payload len %u",
 
  102                 id, ntohs(ph->hw_protocol), ph->hook, plen);
 
  111         if (skbinfo & NFQA_SKB_CSUMNOTREADY)
 
  112                 printf(
", checksum not ready");
 
  115         nfq_send_verdict(ntohs(nfg->res_id), 
id);
 
  120 int main(
int argc, 
char *argv[])
 
  124         size_t sizeof_buf = 0xffff + (MNL_SOCKET_BUFFER_SIZE/2);
 
  125         struct nlmsghdr *nlh;
 
  127         unsigned int portid, queue_num;
 
  130                 printf(
"Usage: %s [queue_num]\n", argv[0]);
 
  133         queue_num = atoi(argv[1]);
 
  135         nl = mnl_socket_open(NETLINK_NETFILTER);
 
  137                 perror(
"mnl_socket_open");
 
  141         if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
 
  142                 perror(
"mnl_socket_bind");
 
  145         portid = mnl_socket_get_portid(nl);
 
  147         buf = malloc(sizeof_buf);
 
  149                 perror(
"allocate receive buffer");
 
  154         nlh = nfq_hdr_put(buf, NFQNL_MSG_CONFIG, 0);
 
  157         if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
 
  158                 perror(
"mnl_socket_send");
 
  162         nlh = nfq_hdr_put(buf, NFQNL_MSG_CONFIG, 0);
 
  165         if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
 
  166                 perror(
"mnl_socket_send");
 
  170         nlh = nfq_hdr_put(buf, NFQNL_MSG_CONFIG, queue_num);
 
  173         if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
 
  174                 perror(
"mnl_socket_send");
 
  178         nlh = nfq_hdr_put(buf, NFQNL_MSG_CONFIG, queue_num);
 
  179         nfq_nlmsg_cfg_put_params(nlh, NFQNL_COPY_PACKET, 0xffff);
 
  181         mnl_attr_put_u32(nlh, NFQA_CFG_FLAGS, htonl(NFQA_CFG_F_GSO));
 
  182         mnl_attr_put_u32(nlh, NFQA_CFG_MASK, htonl(NFQA_CFG_F_GSO));
 
  184         if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
 
  185                 perror(
"mnl_socket_send");
 
  194         mnl_socket_setsockopt(nl, NETLINK_NO_ENOBUFS, &ret, 
sizeof(
int));
 
  197                 ret = mnl_socket_recvfrom(nl, buf, sizeof_buf);
 
  199                         perror(
"mnl_socket_recvfrom");
 
  203                 ret = mnl_cb_run(buf, ret, 0, portid, queue_cb, NULL);
 
  205                         perror(
"mnl_cb_run");
 
  210         mnl_socket_close(nl);
 
void nfq_nlmsg_cfg_put_cmd(struct nlmsghdr *nlh, uint16_t pf, uint8_t cmd)
 
int nfq_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr **attr)