#include "rtcp.h" #ifndef __FAVOR_BSD #define __FAVOR_BSD #endif #ifndef __USE_BSD #define __USE_BSD #endif #include #include #include #include #include #include #include #include #include static int bounce(struct nfq_q_handle *q, struct nfgenmsg *m, struct nfq_data *d, void *a) { int id; int ret; struct ip *ip; struct udphdr *udp; uint32_t addr; uint16_t port; (void)m; (void)a; id = ntohl((nfq_get_msg_packet_hdr(d))->packet_id); nfq_get_payload(d, (char **)&ip); udp = (struct udphdr *)((uint32_t *) ip + ip->ip_hl); addr = ip->ip_src.s_addr; ip->ip_src.s_addr = ip->ip_dst.s_addr; ip->ip_dst.s_addr = addr; port = udp->uh_sport; udp->uh_sport = udp->uh_dport; udp->uh_dport = port; ret = nfq_set_verdict(q, id, NF_ACCEPT, ntohs(ip->ip_len), (unsigned char *)ip); if (ret < 0) { fputs("Error setting verdict.\n", stderr); exit(EXIT_FAILURE); } return ret; } int main(int argc, char **argv) { char buf[1500]; int fd; int ret; ssize_t size; struct nfq_handle *h; struct nfq_q_handle *q; (void)argc; (void)argv; h = nfq_open(); if (!h) { fputs("Error opening the queue interface.\n", stderr); exit(EXIT_FAILURE); } /* * From the netfilter mailinglist: "The entire unregistration * stuff is a horrible hack, the only reason why it (still) * exists is because registration of the same handler returns * EEXIST instead of silently ignoring it. The best fix for now * is to ignore the return value of nfq_unbind_pf()." */ nfq_unbind_pf(h, AF_INET); ret = nfq_bind_pf(h, AF_INET); if (ret < 0) { fputs("Error binding the queue handler.\n", stderr); exit(EXIT_FAILURE); } q = nfq_create_queue(h, 1, bounce, NULL); if (!q) { fputs("Error creating the incoming queue.\n", stderr); exit(EXIT_FAILURE); } ret = nfq_set_mode(q, NFQNL_COPY_PACKET, sizeof(buf)); if (ret < 0) { fputs("Error setting up the incoming queue.\n", stderr); exit(EXIT_FAILURE); } fd = nfq_fd(h); while ((size = recv(fd, buf, sizeof(buf), 0)) > 0) nfq_handle_packet(h, buf, size); nfq_destroy_queue(q); nfq_close(h); return EXIT_SUCCESS; }