34 #include <sys/ioctl.h>
35 #include <netinet/in.h>
36 #include <linux/types.h>
37 #include <linux/netfilter.h>
38 #include <libnetfilter_queue/libnetfilter_queue.h>
41 #include "include/private.h"
56 struct nfq_q_handle *
qh;
62 static struct nfq_list {
66 static int32_t nfqueue_hash(
const void *data,
int key) {
68 const uint16_t *hashkey = (key) ? data : &nfq->
pf;
73 static void nfqueues_close(
void *data) {
75 if (nfqueues->queues) {
81 static void nfqueue_close(
void *data) {
84 nfq_unbind_pf(nfq->
h, nfq->
pf);
89 static void nfqueue_close_q(
void *data) {
93 nfq_destroy_queue(nfq_q->
qh);
106 static void *nfqueue_thread(
void *data) {
108 fd_set rd_set, act_set;
115 FD_SET(nfq->
fd, &rd_set);
116 fcntl(nfq->
fd, F_SETFD, O_NONBLOCK);
117 ioctl(nfq->
fd, FIONBIO, &opt);
124 selfd = select(nfq->
fd + 1, &act_set, NULL, NULL, &tv);
127 if ((selfd < 0 && errno == EINTR) || (!selfd)) {
134 if ((FD_ISSET(nfq->
fd, &act_set)) &&
135 ((len = recv(nfq->
fd, buf,
sizeof(buf), 0)) >= 0)) {
137 nfq_handle_packet(nfq->
h, buf, len);
148 if (!(nfq =
objalloc(
sizeof(*nfq), nfqueue_close))) {
153 if (!(nfq->
h = nfq_open())) {
158 if (nfq_unbind_pf(nfq->
h, pf)) {
163 if (nfq_bind_pf(nfq->
h, pf)) {
168 if ((nfq->
fd = nfq_fd(nfq->
h)) < 0) {
176 if (!(nfqueues =
objalloc(
sizeof(*nfqueues), nfqueues_close))) {
182 if ((nfqueues->queues || (nfqueues->queues =
create_bucketlist(0, nfqueue_hash))) &&
195 static int nfqueue_callback(
struct nfq_q_handle *qh,
struct nfgenmsg *msg,
struct nfq_data *nfad,
void *data) {
203 uint32_t verdict = NF_DROP;
205 if ((ph = nfq_get_msg_packet_hdr(nfad))) {
206 id = ntohl(ph->packet_id);
208 mark = nfq_get_nfmark(nfad);
210 if ((len = nfq_get_payload(nfad, &pkt)) <= 0) {
215 verdict = nfq_q->
cb(nfad, ph, (
char *)pkt, len, nfq_q->
data, &mark, &mangle);
218 if (mangle && !(len =
objsize(mangle))) {
223 ret = nfq_set_verdict2(qh,
id, verdict, mark, len, (mangle) ? mangle : pkt);
234 if (!(nfq_q =
objalloc(
sizeof(*nfq_q), nfqueue_close_q))) {
240 !(nfq_q->
nfq || (nfq_q->
nfq = nfqueue_init(pf)))) {
247 if (!(nfq_q->
qh = nfq_create_queue(nfq_q->
nfq->
h, num, &nfqueue_callback, nfq_q))) {
260 nfq_set_mode(nfq_q->
qh, mode, range);
266 struct iphdr *ip = (
struct iphdr *)pkt;
268 uint32_t id, mark, ifi;
269 uint16_t tlen, left = len;
270 char saddr[INET_ADDRSTRLEN], daddr[INET_ADDRSTRLEN];
273 id = ntohl(ph->packet_id);
274 snprintf(tmp, left,
"hw_protocol=0x%04x hook=%u id=%u ",
275 ntohs(ph->hw_protocol), ph->hook,
id);
281 if ((mark = nfq_get_nfmark(tb))) {
282 snprintf(tmp, left,
"mark=%u ", mark);
288 if ((ifi = nfq_get_indev(tb))) {
289 snprintf(tmp, left,
"indev=%u ", ifi);
295 if ((ifi = nfq_get_outdev(tb))) {
296 snprintf(tmp, left,
"outdev=%u ", ifi);
302 if (pkt && (ip->version == 4)) {
303 union l4hdr *l4 = (
union l4hdr *)(pkt + (ip->ihl*4));
305 inet_ntop(AF_INET, &ip->saddr, saddr, INET_ADDRSTRLEN);
306 inet_ntop(AF_INET, &ip->daddr, daddr, INET_ADDRSTRLEN);
308 snprintf(tmp, left,
"src=%s dst=%s proto=%i ", saddr, daddr, ip->protocol);
313 switch(ip->protocol) {
315 snprintf(tmp, left,
"sport=%i dport=%i ", ntohs(l4->tcp.source), ntohs(l4->tcp.dest));
318 snprintf(tmp, left,
"sport=%i dport=%i ", ntohs(l4->udp.source), ntohs(l4->udp.dest));
321 snprintf(tmp, left,
"type=%i code=%i id=%i ", l4->icmp.type, l4->icmp.code, ntohs(l4->icmp.un.echo.id));
void * create_bucketlist(int bitmask, blisthash hash_function)
int objref(void *data)
Reference a object.
#define testflag(obj, flag)
Atomically test a flag in the flags field of a referenced object.
int objlock(void *data)
Lock the reference.
uint32_t(* nfqueue_cb)(struct nfq_data *, struct nfqnl_msg_packet_hdr *, char *, uint32_t, void *, uint32_t *, void **)
void * objalloc(int size, objdestroy)
Allocate a referenced lockable object.
struct nfq_data nfq_data
Forward decleration of structure.
#define setflag(obj, flag)
Atomically set a flag in the flags field of a referenced object.
int objcnt(void *data)
Return current reference count.
DTS Application library API Include file.
uint16_t snprintf_pkt(struct nfq_data *tb, struct nfqnl_msg_packet_hdr *ph, uint8_t *pkt, char *buff, uint16_t len)
struct thread_pvt * framework_mkthread(threadfunc, threadcleanup, threadsighandler, void *data, int flags)
create a thread result must be unreferenced
struct nfqnl_msg_packet_hdr nfqnl_msg_packet_hdr
Forward decleration of structure.
int objunlock(void *data)
Unlock a reference.
int framework_threadok(void)
let threads check there status.
int objsize(void *data)
Size requested for data.
const char * inet_ntop(int af, const void *src, char *dest, socklen_t size)
Win32 implementation of inet_ntop.
int addtobucket(struct bucket_list *blist, void *data)
Add a reference to the bucketlist.
void * bucket_list_find_key(struct bucket_list *list, const void *key)
Find and return a reference to a item matching supplied key.
void remove_bucket_item(struct bucket_list *blist, void *data)
Remove and unreference a item from the list.
int objunref(void *data)
Drop reference held.
Bucket list, hold hashed objects in buckets.
struct nfq_queue * nfqueue_attach(uint16_t pf, uint16_t num, uint8_t mode, uint32_t range, nfqueue_cb cb, void *data)