#include #include #include #include #include #include /* for NF_ACCEPT */ #include #include #include #include /* for usleep() */ /* returns packet id */ /* static u_int32_t print_pkt (struct nfq_data *tb) { int id = 0; struct nfqnl_msg_packet_hdr *ph; struct nfqnl_msg_packet_hw *hwph; u_int32_t mark,ifi; int ret; unsigned char *data; //char *data; ph = nfq_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); } hwph = nfq_get_packet_hw(tb); if (hwph) { int i, hlen = ntohs(hwph->hw_addrlen); printf("hw_src_addr="); for (i = 0; i < hlen-1; i++) printf("%02x:", hwph->hw_addr[i]); printf("%02x ", hwph->hw_addr[hlen-1]); } mark = nfq_get_nfmark(tb); if (mark) printf("mark=%u ", mark); ifi = nfq_get_indev(tb); if (ifi) printf("indev=%u ", ifi); ifi = nfq_get_outdev(tb); if (ifi) printf("outdev=%u ", ifi); ifi = nfq_get_physindev(tb); if (ifi) printf("physindev=%u ", ifi); ifi = nfq_get_physoutdev(tb); if (ifi) printf("physoutdev=%u ", ifi); ret = nfq_get_payload(tb, &data); if (ret >= 0) printf("payload_len=%d ", ret); fputc('\n', stdout); return id; } */ /* From doc: * - qh The queue handle returned by nfq_create_queue * - nfmsg message object that contains the packet * - nfad Netlink packet data handle * - data the value passed to the data parameter of nfq_create_queue */ static int cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, struct nfq_data *nfa, void *data) { //fprintf(stderr, "entering callback\n"); //u_int32_t id = print_pkt(nfa); struct nfqnl_msg_packet_hdr *ph; ph = nfq_get_msg_packet_hdr(nfa); u_int32_t id = ntohl(ph->packet_id); struct timespec tp; struct tm* lt; if ( clock_gettime(0, &tp) == 0 ) { lt = localtime(&tp.tv_sec); printf("%02d:%02d:%02d.%.6ld: setting verdict : accept the packet...\n", lt->tm_hour, lt->tm_min, lt->tm_sec, tp.tv_nsec/1000); } return nfq_set_verdict(qh, id, NF_ACCEPT, 0, NULL); } int main(int argc, char* argv[]) { struct nfq_handle *h; struct nfq_q_handle *qh; int fd; int rv; char buf[4096] __attribute__ ((aligned)); h = nfq_open(); if (!h) { fprintf(stderr, "error during nfq_open()\n"); exit(1); } printf("unbinding existing nf_queue handler for AF_INET (if any)\n"); if (nfq_unbind_pf(h, AF_INET) < 0) { fprintf(stderr, "error during nfq_unbind_pf()\n"); exit(1); } printf("binding nfnetlink_queue as nf_queue handler for AF_INET\n"); if (nfq_bind_pf(h, AF_INET) < 0) { fprintf(stderr, "error during nfq_bind_pf()\n"); exit(1); } printf("binding this socket to queue\n"); qh = nfq_create_queue(h, 666, &cb, NULL); if (!qh) { fprintf(stderr, "error during nfq_create_queue()\n"); exit(1); } printf("setting copy_packet mode\n"); if (nfq_set_mode(qh, NFQNL_COPY_PACKET, 0xffff) < 0) { fprintf(stderr, "can't set packet_copy mode\n"); exit(1); } fd = nfq_fd(h); fprintf(stderr, "waiting for input...\n"); // while ((rv = recv(fd, buf, sizeof(buf), 0)) >= 0) { // printf("pkt received\n"); // nfq_handle_packet(h, buf, rv); // printf("after handle_packet\n\n"); // } struct timespec tp; struct tm* lt; while ( (rv = recv(fd, buf, sizeof(buf), 0)) >= 0 ) { if ( clock_gettime(0, &tp) == 0 ) { lt = localtime(&tp.tv_sec); printf("%02d:%02d:%02d.%.6ld: recv returned %d\n", lt->tm_hour, lt->tm_min, lt->tm_sec, tp.tv_nsec/1000, rv); } /* if( rv < 0 ) perror("error during with recv()"); else if( rv == 0 ) printf("recv() returned 0\n"); else { nfq_handle_packet(h, buf, rv); //printf("after handle_packet\n\n"); } */ nfq_handle_packet(h, buf, rv); //usleep(100000); } printf("unbinding from queue\n"); nfq_destroy_queue(qh); #ifdef INSANE /* normally, applications SHOULD NOT issue this command, since * it detaches other programs/sockets from AF_INET, too ! */ printf("unbinding from AF_INET\n"); if( nfq_unbind_pf(h, AF_INET) != 0 ) { fprintf(stderr, "error during nfq_unbind_pf()\n"); } #endif printf("closing library handle\n"); if( nfq_close(h) != 0 ) { fprintf(stderr, "error during nfq_close()\n"); } return 0; }