00001
00002 #include <stdio.h>
00003 #include <stdlib.h>
00004 #include <unistd.h>
00005 #include <netinet/in.h>
00006 #include <linux/types.h>
00007 #include <errno.h>
00008 #include <linux/netfilter.h>
00009
00010 #include <libnetfilter_queue/libnetfilter_queue.h>
00011
00012
00013 static u_int32_t print_pkt (struct nfq_data *tb)
00014 {
00015 int id = 0;
00016 struct nfqnl_msg_packet_hdr *ph;
00017 struct nfqnl_msg_packet_hw *hwph;
00018 u_int32_t mark,ifi;
00019 int ret;
00020 char *data;
00021
00022 ph = nfq_get_msg_packet_hdr(tb);
00023 if (ph) {
00024 id = ntohl(ph->packet_id);
00025 printf("hw_protocol=0x%04x hook=%u id=%u ",
00026 ntohs(ph->hw_protocol), ph->hook, id);
00027 }
00028
00029 hwph = nfq_get_packet_hw(tb);
00030 if (hwph) {
00031 int i, hlen = ntohs(hwph->hw_addrlen);
00032
00033 printf("hw_src_addr=");
00034 for (i = 0; i < hlen-1; i++)
00035 printf("%02x:", hwph->hw_addr[i]);
00036 printf("%02x ", hwph->hw_addr[hlen-1]);
00037 }
00038
00039 mark = nfq_get_nfmark(tb);
00040 if (mark)
00041 printf("mark=%u ", mark);
00042
00043 ifi = nfq_get_indev(tb);
00044 if (ifi)
00045 printf("indev=%u ", ifi);
00046
00047 ifi = nfq_get_outdev(tb);
00048 if (ifi)
00049 printf("outdev=%u ", ifi);
00050 ifi = nfq_get_physindev(tb);
00051 if (ifi)
00052 printf("physindev=%u ", ifi);
00053
00054 ifi = nfq_get_physoutdev(tb);
00055 if (ifi)
00056 printf("physoutdev=%u ", ifi);
00057
00058 ret = nfq_get_payload(tb, &data);
00059 if (ret >= 0)
00060 printf("payload_len=%d ", ret);
00061
00062 fputc('\n', stdout);
00063
00064 return id;
00065 }
00066
00067
00068 static int cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg,
00069 struct nfq_data *nfa, void *data)
00070 {
00071 u_int32_t id = print_pkt(nfa);
00072 printf("entering callback\n");
00073 return nfq_set_verdict(qh, id, NF_ACCEPT, 0, NULL);
00074 }
00075
00076 int main(int argc, char **argv)
00077 {
00078 struct nfq_handle *h;
00079 struct nfq_q_handle *qh;
00080 struct nfnl_handle *nh;
00081 int fd;
00082 int rv;
00083 char buf[4096] __attribute__ ((aligned));
00084
00085 printf("opening library handle\n");
00086 h = nfq_open();
00087 if (!h) {
00088 fprintf(stderr, "error during nfq_open()\n");
00089 exit(1);
00090 }
00091
00092 nfnl_rcvbufsiz(nfq_nfnlh(h), 1024);
00093
00094 printf("unbinding existing nf_queue handler for AF_INET (if any)\n");
00095 if (nfq_unbind_pf(h, AF_INET) < 0) {
00096 fprintf(stderr, "error during nfq_unbind_pf()\n");
00097 exit(1);
00098 }
00099
00100 printf("binding nfnetlink_queue as nf_queue handler for AF_INET\n");
00101 if (nfq_bind_pf(h, AF_INET) < 0) {
00102 fprintf(stderr, "error during nfq_bind_pf()\n");
00103 exit(1);
00104 }
00105
00106 printf("binding this socket to queue '0'\n");
00107 qh = nfq_create_queue(h, 0, &cb, NULL);
00108 if (!qh) {
00109 fprintf(stderr, "error during nfq_create_queue()\n");
00110 exit(1);
00111 }
00112
00113 printf("setting copy_packet mode\n");
00114 if (nfq_set_mode(qh, NFQNL_COPY_PACKET, 0xffff) < 0) {
00115 fprintf(stderr, "can't set packet_copy mode\n");
00116 exit(1);
00117 }
00118
00119 fd = nfq_fd(h);
00120
00121 close(1);
00122
00123 while ((rv = recv(fd, buf, sizeof(buf), 0))) {
00124 if (rv == -1) {
00125 if (errno == ENOBUFS) {
00126 fprintf(stderr, "ENOBUFS !!!!!!!!\n");
00127 continue;
00128 } else
00129 break;
00130 }
00131 printf("pkt received\n");
00132 nfq_handle_packet(h, buf, rv);
00133 }
00134
00135 printf("unbinding from queue 0\n");
00136 nfq_destroy_queue(qh);
00137
00138 #ifdef INSANE
00139
00140
00141 printf("unbinding from AF_INET\n");
00142 nfq_unbind_pf(h, AF_INET);
00143 #endif
00144
00145 printf("closing library handle\n");
00146 nfq_close(h);
00147
00148 exit(0);
00149 }