8 #include <libmnl/libmnl.h> 
    9 #include <linux/netfilter.h> 
   10 #include <linux/netfilter/nfnetlink.h> 
   12 #include <linux/types.h> 
   13 #include <linux/netfilter/nfnetlink_queue.h> 
   15 #include <libnetfilter_queue/libnetfilter_queue.h> 
   17 static struct mnl_socket *nl;
 
   19 static struct nlmsghdr *
 
   20 nfq_build_header(
char *buf, 
int type, uint32_t queue_num)
 
   22         struct nlmsghdr *nlh = mnl_nlmsg_put_header(buf);
 
   23         nlh->nlmsg_type = (NFNL_SUBSYS_QUEUE << 8) | type;
 
   24         nlh->nlmsg_flags = NLM_F_REQUEST;
 
   26         struct nfgenmsg *nfg = mnl_nlmsg_put_extra_header(nlh, 
sizeof(*nfg));
 
   27         nfg->nfgen_family = AF_UNSPEC;
 
   28         nfg->version = NFNETLINK_V0;
 
   29         nfg->res_id = htons(queue_num);
 
   35 nfq_send_verdict(
int queue_num, uint32_t 
id, uint8_t *pkt, uint16_t pktlen)
 
   37         char buf[MNL_SOCKET_BUFFER_SIZE];
 
   41         nlh = nfq_build_header(buf, NFQNL_MSG_VERDICT, queue_num);
 
   42         nfq_nlmsg_verdict_build(nlh, 
id, NF_ACCEPT);
 
   43         nfq_nlmsg_verdict_payload(nlh, pkt, pktlen);
 
   45         if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
 
   46                 perror(
"mnl_socket_send");
 
   53 static int queue_cb(
const struct nlmsghdr *nlh, 
void *data)
 
   55         struct nfqnl_msg_packet_hdr *ph = NULL;
 
   56         struct nlattr *attr[NFQA_MAX+1];
 
   63                 perror(
"problems parsing");
 
   67         nfg = mnl_nlmsg_get_payload(nlh);
 
   69         ph = (
struct nfqnl_msg_packet_hdr *)
 
   70                 mnl_attr_get_payload(attr[NFQA_PACKET_HDR]);
 
   72                 perror(
"problems retrieving metaheader");
 
   76         id = ntohl(ph->packet_id);
 
   78         printf(
"packet received (id=%u hw=0x%04x hook=%u)\n",
 
   79                 id, ntohs(ph->hw_protocol), ph->hook);
 
   81         pkt = mnl_attr_get_payload(attr[NFQA_PAYLOAD]);
 
   82         pktlen = mnl_attr_get_payload_len(attr[NFQA_PAYLOAD]);
 
   84         nfq_send_verdict(ntohs(nfg->res_id), 
id, pkt, pktlen);
 
   89 int main(
int argc, 
char *argv[])
 
   91         char buf[MNL_SOCKET_BUFFER_SIZE];
 
   94         unsigned int portid, queue_num;
 
   97                 printf(
"Usage: %s [queue_num]\n", argv[0]);
 
  100         queue_num = atoi(argv[1]);
 
  102         nl = mnl_socket_open(NETLINK_NETFILTER);
 
  104                 perror(
"mnl_socket_open");
 
  108         if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
 
  109                 perror(
"mnl_socket_bind");
 
  112         portid = mnl_socket_get_portid(nl);
 
  114         nlh = nfq_build_header(buf, NFQNL_MSG_CONFIG, 0);
 
  115         nfq_nlmsg_cfg_build_request(nlh, AF_INET, NFQNL_CFG_CMD_PF_UNBIND);
 
  117         if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
 
  118                 perror(
"mnl_socket_send");
 
  122         nlh = nfq_build_header(buf, NFQNL_MSG_CONFIG, 0);
 
  123         nfq_nlmsg_cfg_build_request(nlh, AF_INET, NFQNL_CFG_CMD_PF_BIND);
 
  125         if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
 
  126                 perror(
"mnl_socket_send");
 
  130         nlh = nfq_build_header(buf, NFQNL_MSG_CONFIG, queue_num);
 
  131         nfq_nlmsg_cfg_build_request(nlh, AF_INET, NFQNL_CFG_CMD_BIND);
 
  133         if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
 
  134                 perror(
"mnl_socket_send");
 
  138         nlh = nfq_build_header(buf, NFQNL_MSG_CONFIG, queue_num);
 
  139         nfq_nlmsg_cfg_add_copy(nlh, NFQNL_COPY_PACKET, 0xffff);
 
  141         if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
 
  142                 perror(
"mnl_socket_send");
 
  146         ret = mnl_socket_recvfrom(nl, buf, 
sizeof(buf));
 
  148                 perror(
"mnl_socket_recvfrom");
 
  154                 ret = mnl_cb_run(buf, ret, 0, portid, queue_cb, NULL);
 
  156                         perror(
"mnl_cb_run");
 
  160                 ret = mnl_socket_recvfrom(nl, buf, 
sizeof(buf));
 
  162                         perror(
"mnl_socket_recvfrom");
 
  167         mnl_socket_close(nl);
 
int nfq_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr **attr)