int main(int argc, char **argv) { struct nfq_handle *h; struct nfq_q_handle *qh; struct nfnl_handle *nh; int fd; int rv; char buf[4096] __attribute__ ((aligned)); printf("Simple latency simulator\n"); printf("(C) 2009, 2010 by Holger Freyther\n"); printf("(C) 2005 by Harald Welte\n"); handle_options(argc, argv); 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 '0'\n"); qh = nfq_create_queue(h, 0, &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_META, 0xffff) < 0) { fprintf(stderr, "can't set packet_copy mode\n"); exit(1); } fd = nfq_fd(h); while ((rv = recv(fd, buf, sizeof(buf), 0)) && rv >= 0) { nfq_handle_packet(h, buf, rv); } printf("unbinding from queue 0\n"); nfq_destroy_queue(qh); printf("closing library handle\n"); nfq_close(h); exit(0); }
int createQueue(struct nfq_handle *h, int queue_num, int (*callback)(struct nfq_q_handle *, struct nfgenmsg *, struct nfq_data *, void *)) { // get code from nfqnl_test.c struct nfq_q_handle *qh; int fd = 0; int rv = 0; printf("binding this socket to queue %d\n", queue_num); qh = nfq_create_queue(h, queue_num, callback, NULL); if (!qh) { fprintf(stderr, "error during nfq_create_queue()\n"); exit(1); } printf("setting copy_packet mode Boo Yeah!!\n"); if (nfq_set_mode(qh, NFQNL_COPY_PACKET, 0xffff) < 0) { fprintf(stderr, "can't set packet_copy mode\n"); exit(1); } printf("Packet Mode Set\n"); fd = nfq_fd(h); if(nfq_set_queue_maxlen(qh, 100) < 0 ) { fprintf(stderr,"---\nCannot set queue max len \n---"); } return fd; }
void disruptor_nfq_handle_traffic() { /*handle the incoming packets*/ d_nfq.fd = nfq_fd(d_nfq.h); while ((d_nfq.recv_pkt_sz = recv(d_nfq.fd, d_nfq.buf, sizeof(d_nfq.buf), 0)) >= 0) { nfq_handle_packet(d_nfq.h, d_nfq.buf, d_nfq.recv_pkt_sz); /* send packet to callback */ } }
int queue_get_fd(struct queue *self) { if (self->_h == NULL) { throw_exception("queue is not open"); return -1; } return nfq_fd(self->_h); }
int NetherNetlink::getDescriptor() { if(nfqHandle) return (nfq_fd(nfqHandle)); else LOGE("nfq not initialized"); return (-1); }
int main(int argc, char **argv) { struct nfq_handle *qh; struct nfq_q_handle *qqh; // struct nfnl_handle *nh; int fd; int rv; char buf[4096] __attribute__ ((aligned)); struct nfct_handle *cth; if (init_nfct(&cth) != 0) { exit(1); } if (init_nfq(&qh, &qqh, cth) != 0) { exit(1); } fd = nfq_fd(qh); for (;;) { if ((rv = recv(fd, buf, sizeof(buf), 0)) >= 0) { printf("pkt received\n"); nfq_handle_packet(qh, buf, rv); continue; } /* if your application is too slow to digest the packets that * are sent from kernel-space, the socket buffer that we use * to enqueue packets may fill up returning ENOBUFS. Depending * on your application, this error may be ignored. Please, see * the doxygen documentation of this library on how to improve * this situation. */ if (rv < 0 && errno == ENOBUFS) { printf("losing packets!\n"); continue; } perror("recv failed"); break; } printf("unbinding from queue 0\n"); nfq_destroy_queue(qqh); #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"); nfq_unbind_pf(h, AF_INET); #endif printf("closing library handle\n"); nfq_close(qh); nfct_close(cth); exit(0); }
int nfq() { int len, fd; char buf[BUFSIZE]= {0}; struct nfq_handle *h; //call nfq_open() to open a NFQUEUE handler h = nfq_open(); if(!h) { fprintf(stderr, "error during nfq_open()\n"); exit(1); } //unbinging existing nf_queue handler for PE_INET(if any) if(nfq_unbind_pf(h, PF_INET) < 0) { fprintf(stderr, "error during nfq_unbind_pf()\n"); exit(1); } //binding nfnetlink_queue as nf_queue handler for PF_INET if(nfq_bind_pf(h, PF_INET) < 0) { fprintf(stderr, "error during nfq_bind_pf()\n"); exit(1); } //binding this socket to queue '0' gqh = nfq_create_queue(h, 0, &queue_cb, NULL); if(!gqh) { fprintf(stderr,"error during nfq_create_queue()\n"); exit(1); } //setting copy_packet mode if(nfq_set_mode(gqh, NFQNL_COPY_PACKET, 0xffff) < 0) { fprintf(stderr, "can't set packet_copy_mode\n"); exit(1); } //get the file descriptor associated with the nfqueue handler fd = nfq_fd(h); //handle a packet received from the nfqueue subsystem CONTINUE: while ((len = recv(fd, buf, BUFSIZE, 0)) && len >= 0) { nfq_handle_packet(h, buf, len); } debug_log("error len=%d" ,len); sleep(2); goto CONTINUE; nfq_destroy_queue(gqh); nfq_close(h); return 0; }
static void packetsrv_activity_cb(struct ev_loop *loop, ev_io *w, int revents) { if (revents & EV_READ) { unsigned char buffer[BUFSIZ]; int rv; int fd = nfq_fd(h); /* read one packet */ rv = recv(fd, buffer, sizeof(buffer), 0); if (rv < 0) { struct nlif_handle *nlif_handle = (struct nlif_handle *) w->data; log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_WARNING, "[!] Error of read on netfilter queue socket (code %i, errno %d): %s!", rv, errno, strerror(errno)); log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_SERIOUS_MESSAGE, "Reopen netlink connection."); packetsrv_close(0); #ifdef HAVE_NFQ_INDEV_NAME fd = packetsrv_open(nlif_handle); #else fd = packetsrv_open(NULL); #endif if (fd < 0) { log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_CRITICAL, "[!] FATAL ERROR: Fail to reopen netlink connection!"); exit(EXIT_FAILURE); } ev_io_stop(loop, w); ev_io_set(w, fd, EV_READ); ev_io_start(loop, w); return; } ev_io_stop(loop, &tls.ev_io); /* process the packet */ nfq_handle_packet(h, (char *) buffer, rv); pckt_rx++; ev_io_start(loop, &tls.ev_io); } if (revents & EV_ERROR) { struct nlif_handle *nlif_handle = (struct nlif_handle *) w->data; int fd; packetsrv_close(0); ev_io_stop(loop, w); #ifdef HAVE_NFQ_INDEV_NAME fd = packetsrv_open(nlif_handle); #else fd = packetsrv_open(NULL); #endif ev_io_set(w, fd, EV_READ); ev_io_start(loop, w); } }
int divert_open(int port, divert_cb cb) { unsigned int bufsize = 1024 * 1024 * 1; unsigned int rc; char *m; int fd, flags; _h = nfq_open(); if (!_h) err(1, "nfq_open()"); rc = nfnl_rcvbufsiz(nfq_nfnlh(_h), bufsize); if (rc != bufsize) xprintf(XP_DEBUG, "Buffer size %u wanted %u\n", rc, bufsize); /* reset in case of previous crash */ if (nfq_unbind_pf(_h, AF_INET) < 0) err(1, "nfq_unbind_pf()"); if (nfq_bind_pf(_h, AF_INET) < 0) err(1, "nfq_bind_pf()"); _q = nfq_create_queue(_h, port, packet_input, cb); if (!_q) err(1, "nfq_create_queue()"); if (nfq_set_mode(_q, NFQNL_COPY_PACKET, 0xffff) < 0) err(1, "nfq_set_mode()"); if (nfq_set_queue_maxlen(_q, 10000) < 0) err(1, "nfq_set_queue_maxlen()"); xprintf(XP_DEFAULT, "Divert packets using iptables -j NFQUEUE --queue-num %d\n", port); m = driver_param(0); if (m) { _mark = strtoul(m, NULL, 16); xprintf(XP_DEFAULT, "Also, add -m mark --mark 0x0/0x%x\n", _mark); } fd = nfq_fd(_h); flags = fcntl(fd, F_GETFL); if (flags == -1) err(1, "fcntl()"); if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) err(1, "fcntl()"); open_raw(); return fd; }
void* routeRecordMain(void* arg){ randomValue = createLongRandomValue(); char* gatewayIP = getIPAddress(INTERFACE); gatewayAddr = getInAddr(gatewayIP); initializeRRFilterList(); struct nfq_handle* 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); } //nfq_callback* cb = (nfq_callback*) calloc(1, sizeof(nfq_callback)); printf("binding this socket to queue '0'\n"); struct nfq_q_handle* qh = nfq_create_queue(h, 0, &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); } int fd = nfq_fd(h); int rv = -1; char* buf = (char*) calloc(1, 100001); while ((rv = recv(fd, buf, 10000, 0)) >= 0) { printf("pkt received\n received: [%d]\n\n", rv); nfq_handle_packet(h, buf, rv); } printf("unbinding from queue 0\n"); nfq_destroy_queue(qh); printf("closing library handle\n"); nfq_close(h); pthread_exit(NULL); }
int tc_nfq_socket_init(struct nfq_handle **h, struct nfq_q_handle **qh, nfq_callback *cb, int max_queue_len) { int fd; tc_log_info(LOG_NOTICE, 0, "opening library handle"); *h = nfq_open(); if (!(*h)) { tc_log_info(LOG_ERR, errno, "error during nfq_open()"); return TC_INVALID_SOCKET; } tc_log_info(LOG_NOTICE, 0, "unbinding existing nf_queue handler for AF_INET (if any)"); if (nfq_unbind_pf((*h), AF_INET) < 0) { tc_log_info(LOG_ERR, errno, "error during nfq_unbind_pf()"); return TC_INVALID_SOCKET; } tc_log_info(LOG_NOTICE, 0, "binding nfnetlink_queue as nf_queue handler for AF_INET"); if (nfq_bind_pf((*h), AF_INET) < 0) { tc_log_info(LOG_ERR, errno, "error during nfq_bind_pf()"); return TC_INVALID_SOCKET; } tc_log_info(LOG_NOTICE, 0, "binding this socket to queue"); *qh = nfq_create_queue((*h), 0, cb, NULL); if (!(*qh)) { tc_log_info(LOG_ERR, errno, "error during nfq_create_queue()"); return TC_INVALID_SOCKET; } tc_log_info(LOG_NOTICE, 0, "setting copy_packet mode"); if (nfq_set_mode((*qh), NFQNL_COPY_PACKET, RESP_MAX_USEFUL_SIZE) < 0) { tc_log_info(LOG_ERR, errno, "can't set packet_copy mode"); return TC_INVALID_SOCKET; } if (max_queue_len > 0) { if (nfq_set_queue_maxlen((*qh), (uint32_t) max_queue_len) < 0) { tc_log_info(LOG_ERR, errno, "can't set queue max length:%d", max_queue_len); tc_log_info(LOG_WARN, 0, "unable to set queue maxlen"); tc_log_info(LOG_WARN, 0, "your kernel probably doesn't support it"); } } fd = nfq_fd(*h); nfnl_rcvbufsiz(nfq_nfnlh(*h), 16777216); return fd; }
/** * This is the main function used by each worker thread that is spawned * when the startFilterThread() method of the HostFilter class is used. * @return 0 upon success, 1 upon failure. */ void* hostFilterMain(void* arg) { // declaration of local variables int fd; int bytes; char packetBuffer[1500]; struct nfq_handle *handle; struct nfq_q_handle *queueHandle; // attempt to open a queue connection handle from the netfilter module if (!(handle = nfq_open())) { std::cerr << "ERROR: nfq_open()" << std::endl; exit(1); } // unbind the handle to prevent any inability to bind if (nfq_unbind_pf(handle, AF_INET) < 0) { std::cerr << "ERROR: nfq_unbind_pf()" << std::endl; exit(1); } // bind the handle so that it can process IPv4 packets if (nfq_bind_pf(handle, AF_INET) < 0) { std::cerr << "ERROR: nfq_bind_pf()" << std::endl; exit(1); } // create the handle for the nfq queue and ensure that it is linked to a callback if (!(queueHandle = nfq_create_queue(handle, 0, &cb, arg))) { std::cerr << "ERROR: nfq_create_queue()" << std::endl; exit(1); } // enable all packet data for every queued packet to be copied and read into user space if (nfq_set_mode(queueHandle, NFQNL_COPY_PACKET, 0xffff) < 0) { std::cerr << "ERROR: packet copy mode" << std::endl; exit(1); } // create a file descriptor that can be used to read from the queue fd = nfq_fd(handle); if (fd == -1) { std::cerr << "ERROR: nfq_fd()" << std::endl; exit(1); } // when a packet is received from the queue go and handle it with the callback while (true) { if ((bytes = recv(fd, packetBuffer, sizeof(packetBuffer), 0)) >= 0) { std::cout << "A packet has been received at the queue" << std::endl; nfq_handle_packet(handle, packetBuffer, bytes); } } return NULL; }
int main(int argc, char** argv) { int fd; ssize_t rv; char buf[4096]; struct nfq_handle* h; struct nfq_q_handle* qh; int i=0; h = nfq_open(); if (!h) { fprintf(stderr, "error during nfq_open()\n"); exit(1); } if (nfq_unbind_pf(h, AF_INET) < 0) { fprintf(stderr, "error during nfq_unbind_pf()\n"); exit(1); } if (nfq_bind_pf(h, AF_INET) < 0) { fprintf(stderr, "error during nfq_bind_pf()\n"); exit(1); } printf("Binding to queue 0...\n"); qh = nfq_create_queue(h, 0, &cb, NULL); if (!qh) { fprintf(stderr, "error during nfq_create_queue()\n"); exit(1); } printf("Copying packets...\n"); if (nfq_set_mode(qh, NFQNL_COPY_PACKET, 0xffff) < 0) { fprintf(stderr, "error during nfq_set_mode()\n"); exit(1); } fd = nfq_fd(h); memset(buf, 0, 4096); while ((rv = recv(fd, buf, sizeof(buf), 0)) && rv >= 0) { for (i = 0; i < rv; i++) printf("%02x\n", *(buf+i)); printf("\n\n"); nfq_handle_packet(h, buf, rv); } nfq_destroy_queue(qh); nfq_close(h); }
int tc_nfq_socket_init(struct nfq_handle **h, struct nfq_q_handle **qh, nfq_callback *cb) { int fd; tc_log_info(LOG_NOTICE, 0, "opening library handle"); *h = nfq_open(); if (!(*h)) { tc_log_info(LOG_ERR, errno, "error during nfq_open()"); return TC_INVALID_SOCKET; } tc_log_info(LOG_NOTICE, 0, "unbinding existing nf_queue handler for AF_INET (if any)"); if (nfq_unbind_pf((*h), AF_INET) < 0) { tc_log_info(LOG_ERR, errno, "error during nfq_unbind_pf()"); return TC_INVALID_SOCKET; } tc_log_info(LOG_NOTICE, 0, "binding nfnetlink_queue as nf_queue handler for AF_INET"); if (nfq_bind_pf((*h), AF_INET) < 0) { tc_log_info(LOG_ERR, errno, "error during nfq_bind_pf()"); return TC_INVALID_SOCKET; } tc_log_info(LOG_NOTICE, 0, "binding this socket to queue"); *qh = nfq_create_queue((*h), 0, cb, NULL); if (!(*qh)) { tc_log_info(LOG_ERR, errno, "error during nfq_create_queue()"); return TC_INVALID_SOCKET; } tc_log_info(LOG_NOTICE, 0, "setting copy_packet mode"); if (nfq_set_mode((*qh), NFQNL_COPY_PACKET, RESP_MAX_USEFUL_SIZE) < 0) { tc_log_info(LOG_ERR, errno, "can't set packet_copy mode"); return TC_INVALID_SOCKET; } fd = nfq_fd(*h); nfnl_rcvbufsiz(nfq_nfnlh(*h), 4096*4096); return fd; }
int main(int argc, char** argv) { struct nfq_handle* nfq_h; struct nfq_q_handle* qh; int fd, rv; nfq_h = setup_netfilter_queue(); if(!nfq_h) return -1; qh = create_q_handle(nfq_h, &log_packet, NULL); if(!qh) return -1; fd = nfq_fd(nfq_h); while((rv = recv(fd, nfq_buffer, sizeof(nfq_buffer), 0))) { nfq_handle_packet(nfq_h, (char*)nfq_buffer, rv); } return 0; }
void *read_queue_loop(void *arg) { q_data_t *data = (q_data_t *)arg; int rv, fd; char buf[4096] __attribute__ ((aligned)); data->pid = syscall(SYS_gettid); fd = nfq_fd(data->h); syslog(LOG_NOTICE, "Packet read thread started, queue: %d, TID: %d...\n\r", data->q_num, data->pid); while ((rv = recv(fd, buf, sizeof(buf), 0)) && rv >= 0) { pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); nfq_handle_packet(data->h, buf, rv); pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); } pthread_exit(NULL); }
int setup_nfq() { g_nfq_h = nfq_open(); if (!g_nfq_h) { log_error("error during nfq_open()"); return -1; } log_debug("unbinding existing nf_queue handler for AF_INET (if any)"); if (nfq_unbind_pf(g_nfq_h, AF_INET) < 0) { log_error("error during nfq_unbind_pf()"); return -1; } log_debug("binding nfnetlink_queue as nf_queue handler for AF_INET"); if (nfq_bind_pf(g_nfq_h, AF_INET) < 0) { log_error("error during nfq_bind_pf()"); return -1; } // set up a queue log_debug("binding this socket to queue %d", NF_QUEUE_NUM); g_nfq_qh = nfq_create_queue(g_nfq_h, NF_QUEUE_NUM, &cb, NULL); if (!g_nfq_qh) { log_error("error during nfq_create_queue()"); return -1; } log_debug("setting copy_packet mode"); if (nfq_set_mode(g_nfq_qh, NFQNL_COPY_PACKET, 0xffff) < 0) { log_error("can't set packet_copy mode"); return -1; } g_nfq_fd = nfq_fd(g_nfq_h); return 0; }
int q_setup() { printf("opening library handle\n"); 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 '0'\n"); qh = nfq_create_queue(h, 0, &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); return 0; }
int main(int argc, char *argv[]) { struct nfq_handle *h; struct nfq_q_handle *q; int rv, fd, queue_id; char buf[4096] __attribute__ ((aligned)); src_or_dst = src; target_ip_address = "10.0.0.101"; if (argc != 4) { usage(argv[0]); return -1; } queue_id = atoi(argv[1]); if (strcmp(argv[2], "src") == 0) { src_or_dst = src; } else if (strcmp(argv[2], "dst") == 0) { src_or_dst = dst; } else { usage(argv[0]); return -1; } if (inet_pton(AF_INET, argv[3], buf) != 1) { usage(argv[0]); return -1; } target_ip_address = argv[3]; h = nfq_open(); if (!h) { fprintf(stderr, "Error during nfq_open()\n"); return 1; } if (nfq_unbind_pf(h, AF_INET) < 0) { fprintf(stderr, "Error during nfq_unbind_pf()\n"); return 1; } if (nfq_bind_pf(h, AF_INET) < 0) { fprintf(stderr, "Error during nfq_bind_pf()\n"); return 1; } q = nfq_create_queue(h, queue_id, &cb, NULL); if (!q) { fprintf(stderr, "Error during nfq_create_queue()\n"); return 1; } if (nfq_set_mode(q, NFQNL_COPY_PACKET, 0xffff) < 0) { fprintf(stderr, "Can't set packet_copy mode\n"); return 1; } fd = nfq_fd(h); while ((rv = recv(fd, buf, sizeof(buf), 0)) && rv >= 0) { nfq_handle_packet(h, buf, rv); } return 0; }
static struct packet_module_state *init_state(int thread_id) { static const u_int16_t proto_family[] = { AF_INET, AF_INET6 }; int i; struct packet_module_state *state = malloc(sizeof(struct packet_module_state)); if (!state) { return NULL; } /* Setup nfqueue connection */ state->handle = nfq_open(); if (!state->handle) { message(HAKA_LOG_ERROR, MODULE_NAME, L"unable to open nfqueue handle"); cleanup_state(state); return NULL; } for (i=0; i<sizeof(proto_family)/sizeof(proto_family[0]); ++i) { if (nfq_unbind_pf(state->handle, proto_family[i]) < 0) { message(HAKA_LOG_ERROR, MODULE_NAME, L"cannot unbind queue"); cleanup_state(state); return NULL; } if (nfq_bind_pf(state->handle, proto_family[i]) < 0) { message(HAKA_LOG_ERROR, MODULE_NAME, L"cannot bind queue"); cleanup_state(state); return NULL; } state->send_fd = open_send_socket(false); if (state->send_fd < 0) { cleanup_state(state); return NULL; } state->send_mark_fd = open_send_socket(true); if (state->send_fd < 0) { cleanup_state(state); return NULL; } } state->queue = nfq_create_queue(state->handle, thread_id, &packet_callback, state); if (!state->queue) { message(HAKA_LOG_ERROR, MODULE_NAME, L"cannot create queue"); cleanup_state(state); return NULL; } if (nfq_set_mode(state->queue, NFQNL_COPY_PACKET, PACKET_BUFFER_SIZE) < 0) { message(HAKA_LOG_ERROR, MODULE_NAME, L"cannot set mode to copy packet"); cleanup_state(state); return NULL; } state->fd = nfq_fd(state->handle); /* Change nfq queue len and netfilter receive size */ if (nfq_set_queue_maxlen(state->queue, nfqueue_len) < 0) { message(HAKA_LOG_WARNING, MODULE_NAME, L"cannot change netfilter queue len"); } nfnl_rcvbufsiz(nfq_nfnlh(state->handle), nfqueue_len * 1500); return state; }
/** * Open a netlink connection and returns file descriptor */ int packetsrv_open(void *data) { int ret; log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_DEBUG, "Opening netfilter queue socket"); log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_DEBUG, "[!] Don't forget to load kernel modules nfnetlink and nfnetlink_queue (using modprobe command)"); /* opening library handle */ h = nfq_open(); if (!h) { log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_CRITICAL, "[!] Error during nfq_open()"); return -1; } /* unbinding existing nf_queue handler for AF_INET (if any) */ /* ignoring return, see http://www.spinics.net/lists/netfilter/msg42063.html */ nfq_unbind_pf(h, AF_INET); /* binding nfnetlink_queue as nf_queue handler for AF_INET */ if (nfq_bind_pf(h, AF_INET) < 0) { log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_CRITICAL, "[!] Error during nfq_bind_pf()"); return -1; } if (!nufw_no_ipv6) { /* unbinding existing nf_queue handler for AF_INET6 (if any) */ nfq_unbind_pf(h, AF_INET6); /* binding nfnetlink_queue as nf_queue handler for AF_INET6 */ if (nfq_bind_pf(h, AF_INET6) < 0) { log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_CRITICAL, "[!] Error during nfq_bind_pf()"); log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_CRITICAL, "Maybe you need to compile NF_NETLINK* kernel options as modules (not built in the kernel!)"); return -1; } } ret = nfnl_rcvbufsiz(nfq_nfnlh(h), 10 * 65536); log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_CRITICAL, "rcv buf size set to %d (%d asked)", ret, 10 * 65536); /* binding this socket to queue number ::nfqueue_num * and install our packet handler */ log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_DEBUG, "[+] Binding to netfilter queue %d", nfqueue_num); hndl = nfq_create_queue(h, nfqueue_num, (nfq_callback *) & treat_packet, data); if (!hndl) { log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_CRITICAL, "[!] Error during nfq_create_queue() (queue %d busy ?)", nfqueue_num); return -1; } /* setting copy_packet mode */ if (nfq_set_mode(hndl, NFQNL_COPY_PACKET, 0xffff) < 0) { log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_CRITICAL, "[!] Can't set packet_copy mode"); return -1; } #ifdef HAVE_NFQ_SET_QUEUE_MAXLEN /* setting queue length */ if (queue_maxlen) { if (nfq_set_queue_maxlen(hndl, queue_maxlen) < 0) { if (nufw_set_mark) { log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_CRITICAL, "[!] Can't set queue length, and mark will be set, leaving !"); exit(EXIT_FAILURE); } else { log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_CRITICAL, "[!] Can't set queue length, continuing anyway"); } } } #endif return nfq_fd(h); }
int main(int argc, char **argv) { struct nfq_handle *h; struct nfq_q_handle *qh; int fd; int rv; char buf[4096] __attribute__ ((aligned)); printf("Obteniendo el handle de la libreria: "); h = nfq_open(); if (!h) { fprintf(stderr, "Ha fallado\n"); exit(1); } else printf(" OK !\n"); printf("Haciendo unbind (por si existe alguno de AF_INET): "); if (nfq_unbind_pf(h, AF_INET) < 0) { fprintf(stderr, "error nfq_unbind_pf()\n"); exit(1); } else printf(" OK!\n"); printf("Vinculando nfnetlink_queue de tipo nf_queue handler para AF_INET:"); if (nfq_bind_pf(h, AF_INET) < 0) { fprintf(stderr, "error nfq_bind_pf()\n"); exit(1); } else printf(" OK!\n"); printf("Creando la vinculacion de la funcion callback con Queue 0, socket receptor: "); qh = nfq_create_queue(h, 0, &cb, NULL); if (!qh) { fprintf(stderr, "error during nfq_create_queue()\n"); exit(1); } else printf(" OK !\n"); printf("Definiendo que cantidad de paquete queremos recibir (no queremos todo para estas pruebas): "); if (nfq_set_mode(qh, NFQNL_COPY_PACKET, 0xffff) < 0) { fprintf(stderr, "FALLO el COPY_META mode\n"); exit(1); } else printf("OK\n"); fd = nfq_fd(h); printf("Realizando conexión a memcache: "); memc= memcached_create(NULL); servers= memcached_server_list_append(servers, "localhost", 11211, &rc); rc= memcached_server_push(memc, servers); if (rc == MEMCACHED_SUCCESS) printf(" OK ! \n"); else { printf("error conectando a memcache: %s\n",memcached_strerror(memc, rc)); exit(0); } printf("Realizando INIT de MySQL: "); con = mysql_init(NULL); if (con == NULL) { printf(" FAIL\n"); exit(1); } else printf("OK\n"); printf("Realizando Conexion a MYQSL: "); if (mysql_real_connect(con, "localhost", "root", "FIXMEPASSWORD", "nfqueue", 0, NULL, 0) == NULL) { printf(" FAILED\n"); exit(1); } else printf(" OKI\n"); printf("Todo Listo !\n Entrando en bucle principal de recepcion ..\n"); while ((rv = recv(fd, buf, sizeof(buf), 0))) { // Si todo ha ido bien, gestionamos el paquete: if (rv>=0) nfq_handle_packet(h, buf, rv); // es posible que tengamos packet loss porque // nuestro codigo es lento y se llena la queue: else if ( errno == ENOBUFS) { fflush(stdout); printf("!"); } // O "simplemente", que algo haya ido mal: else { printf("ERROR \n"); fflush(stdout); break; } } // Teoricamente, nunca llegaremos aqui, pero si llegamos // Habra que liberar bien y tal: printf("unbinding de queue 0\n"); nfq_destroy_queue(qh); printf("cerrando library handle\n"); nfq_close(h); exit(0); }
/*- - nfq.loop(cb, copy) cb - a function called for every queued packet, it returns "accept" or "drop" meaning to do that to the packet. For no return value, the default is "accept". If it returns a second argument, it must be a string, and replaces the current packet. copy - "none", "meta", "packet", default to "packet" */ static int loop(lua_State *L) { static const char* copy_opt[] = { "none", "meta", "packet", NULL }; static int copy_val[] = { NFQNL_COPY_NONE, NFQNL_COPY_META, NFQNL_COPY_PACKET }; int copy = copy_val[luaL_checkoption(L, 2, "packet", copy_opt)]; int af = AF_INET; /* Could be an argument, if we ever did non-INET. */ struct nfq_handle *h = NULL; struct nfq_q_handle *qh = NULL; int fd = -1; int nreturn = 0; char buf[4096] __attribute__ ((aligned)); ssize_t recvsz; h = nfq_open(); if(!h) goto err; if (nfq_unbind_pf(h, af) < 0) goto err; if (nfq_bind_pf(h, af) < 0) goto err; qh = nfq_create_queue(h, 0, &cb, L); if(!qh) goto err; if (nfq_set_mode(qh, copy, 0xffff /* larger than an ethernet frame */) < 0) goto err; fd = nfq_fd(h); while ((recvsz = recv(fd, buf, sizeof(buf), 0)) >= 0) { nfq_handle_packet(h, buf, recvsz); } if(recvsz < 0) goto err; goto cleanup; err: lua_pushnil(L); lua_pushstring(L, strerror(errno)); nreturn = 2; cleanup: if(qh) nfq_destroy_queue(qh); if(h) nfq_close(h); return nreturn; }
int main(int argc, char **argv) { struct nfq_handle *h; struct nfq_q_handle *qh; struct nfnl_handle *nh; int fd; int rv; char buf[4096] __attribute__ ((aligned)); printf("opening library handle\n"); 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 '0'\n"); qh = nfq_create_queue(h, 0, &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); while ((rv = recv(fd, buf, sizeof(buf), 0)) && rv >= 0) { printf("pkt received\n"); nfq_handle_packet(h, buf, rv); } printf("unbinding from queue 0\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"); nfq_unbind_pf(h, AF_INET); #endif printf("closing library handle\n"); nfq_close(h); exit(0); }
int main(int argc, char **argv) { struct nfq_handle *h; int fd, i, rc; int rv; pthread_t tid[NUM_THREADS+1]; int id[NUM_THREADS+1]; char buf[4096] __attribute__ ((aligned)); init_queue(&p_queue); sem_init(&sem_queue, 0, 0); /*** launch threads **/ for (i=1; i<= NUM_THREADS; i++) { id[i] = i; rc = pthread_create(&tid[i], NULL, sender_threads, &id[i]); } printf("opening library handle\n"); 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 '0'\n"); qh = nfq_create_queue(h, 0, &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); while ((rv = recv(fd, buf, sizeof(buf), 0)) && rv >= 0) { printf("pkt received\n"); nfq_handle_packet(h, buf, rv); } printf("unbinding from queue 0\n"); nfq_destroy_queue(qh); // clean up threads for (i=1; i<= NUM_THREADS; i++) pthread_join(tid[i], NULL); pthread_mutex_destroy (&lock_queue); sem_destroy(&sem_queue); #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"); nfq_unbind_pf(h, AF_INET); #endif printf("closing library handle\n"); nfq_close(h); exit(0); }
int main(int argc, char **argv) { struct nfq_handle *h; struct nfq_q_handle *qh; struct nfnl_handle *nh; int fd; int rv; char buf[4096] __attribute__ ((aligned)); struct sigaction intsig; FILE *fp; if((fp = fopen(pwd, "r")) == NULL){ printf("fopen(r) errer\n"); return 0; } memset(Mal_Site_Table, 0, 6400); for(int i=0; !feof(fp); i++){ fscanf(fp, "%s", Mal_Site_Table[i]); } intsig.sa_handler = sig_int; sigemptyset(&intsig.sa_mask); intsig.sa_flags = 0; if (sigaction(SIGINT, &intsig, 0) == -1) { printf ("signal(SIGINT) error"); return -1; } system("iptables -A OUTPUT -p ip -j NFQUEUE --queue-num 0"); printf("opening library handle\n"); 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 '0'\n"); qh = nfq_create_queue(h, 0, &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); for (;;) { if ((rv = recv(fd, buf, sizeof(buf), 0)) >= 0) { nfq_handle_packet(h, buf, rv); continue; } /* if your application is too slow to digest the packets that * are sent from kernel-space, the socket buffer that we use * to enqueue packets may fill up returning ENOBUFS. Depending * on your application, this error may be ignored. Please, see * the doxygen documentation of this library on how to improve * this situation. */ if (rv < 0 && errno == ENOBUFS) { printf("losing packets!\n"); continue; } perror("recv failed"); break; } printf("unbinding from queue 0\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"); nfq_unbind_pf(h, AF_INET); #endif printf("closing library handle\n"); nfq_close(h); exit(0); }
TmEcode NFQInitThread(NFQThreadVars *nfq_t, uint32_t queue_maxlen) { #ifndef OS_WIN32 struct timeval tv; int opt; #endif NFQQueueVars *nfq_q = NFQGetQueue(nfq_t->nfq_index); if (nfq_q == NULL) { SCLogError(SC_ERR_NFQ_OPEN, "no queue for given index"); return TM_ECODE_FAILED; } SCLogDebug("opening library handle"); nfq_q->h = nfq_open(); if (!nfq_q->h) { SCLogError(SC_ERR_NFQ_OPEN, "nfq_open() failed"); return TM_ECODE_FAILED; } if (nfq_g.unbind == 0) { /* VJ: on my Ubuntu Hardy system this fails the first time it's * run. Ignoring the error seems to have no bad effects. */ SCLogDebug("unbinding existing nf_queue handler for AF_INET (if any)"); if (nfq_unbind_pf(nfq_q->h, AF_INET) < 0) { SCLogError(SC_ERR_NFQ_UNBIND, "nfq_unbind_pf() for AF_INET failed"); exit(EXIT_FAILURE); } if (nfq_unbind_pf(nfq_q->h, AF_INET6) < 0) { SCLogError(SC_ERR_NFQ_UNBIND, "nfq_unbind_pf() for AF_INET6 failed"); exit(EXIT_FAILURE); } nfq_g.unbind = 1; SCLogDebug("binding nfnetlink_queue as nf_queue handler for AF_INET and AF_INET6"); if (nfq_bind_pf(nfq_q->h, AF_INET) < 0) { SCLogError(SC_ERR_NFQ_BIND, "nfq_bind_pf() for AF_INET failed"); exit(EXIT_FAILURE); } if (nfq_bind_pf(nfq_q->h, AF_INET6) < 0) { SCLogError(SC_ERR_NFQ_BIND, "nfq_bind_pf() for AF_INET6 failed"); exit(EXIT_FAILURE); } } SCLogInfo("binding this thread %d to queue '%" PRIu32 "'", nfq_t->nfq_index, nfq_q->queue_num); /* pass the thread memory as a void ptr so the * callback function has access to it. */ nfq_q->qh = nfq_create_queue(nfq_q->h, nfq_q->queue_num, &NFQCallBack, (void *)nfq_t); if (nfq_q->qh == NULL) { SCLogError(SC_ERR_NFQ_CREATE_QUEUE, "nfq_create_queue failed"); return TM_ECODE_FAILED; } SCLogDebug("setting copy_packet mode"); /* 05DC = 1500 */ //if (nfq_set_mode(nfq_t->qh, NFQNL_COPY_PACKET, 0x05DC) < 0) { if (nfq_set_mode(nfq_q->qh, NFQNL_COPY_PACKET, 0xFFFF) < 0) { SCLogError(SC_ERR_NFQ_SET_MODE, "can't set packet_copy mode"); return TM_ECODE_FAILED; } #ifdef HAVE_NFQ_MAXLEN if (queue_maxlen > 0) { SCLogInfo("setting queue length to %" PRId32 "", queue_maxlen); /* non-fatal if it fails */ if (nfq_set_queue_maxlen(nfq_q->qh, queue_maxlen) < 0) { SCLogWarning(SC_ERR_NFQ_MAXLEN, "can't set queue maxlen: your kernel probably " "doesn't support setting the queue length"); } } #endif /* HAVE_NFQ_MAXLEN */ #ifndef OS_WIN32 /* set netlink buffer size to a decent value */ nfnl_rcvbufsiz(nfq_nfnlh(nfq_q->h), queue_maxlen * 1500); SCLogInfo("setting nfnl bufsize to %" PRId32 "", queue_maxlen * 1500); nfq_q->nh = nfq_nfnlh(nfq_q->h); nfq_q->fd = nfnl_fd(nfq_q->nh); NFQMutexInit(nfq_q); /* Set some netlink specific option on the socket to increase performance */ opt = 1; #ifdef NETLINK_BROADCAST_SEND_ERROR setsockopt(nfq_q->fd, SOL_NETLINK, NETLINK_BROADCAST_SEND_ERROR, &opt, sizeof(int)); #endif /* Don't send error about no buffer space available but drop the packets instead */ #ifdef NETLINK_NO_ENOBUFS setsockopt(nfq_q->fd, SOL_NETLINK, NETLINK_NO_ENOBUFS, &opt, sizeof(int)); #endif #ifdef HAVE_NFQ_SET_QUEUE_FLAGS if (nfq_config.flags & NFQ_FLAG_FAIL_OPEN) { uint32_t flags = NFQA_CFG_F_FAIL_OPEN; uint32_t mask = NFQA_CFG_F_FAIL_OPEN; int r = nfq_set_queue_flags(nfq_q->qh, mask, flags); if (r == -1) { SCLogWarning(SC_ERR_NFQ_SET_MODE, "can't set fail-open mode: %s", strerror(errno)); } else { SCLogInfo("fail-open mode should be set on queue"); } } #endif /* set a timeout to the socket so we can check for a signal * in case we don't get packets for a longer period. */ tv.tv_sec = 1; tv.tv_usec = 0; if(setsockopt(nfq_q->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) == -1) { SCLogWarning(SC_ERR_NFQ_SETSOCKOPT, "can't set socket timeout: %s", strerror(errno)); } SCLogDebug("nfq_q->h %p, nfq_q->nh %p, nfq_q->qh %p, nfq_q->fd %" PRId32 "", nfq_q->h, nfq_q->nh, nfq_q->qh, nfq_q->fd); #else /* OS_WIN32 */ NFQMutexInit(nfq_q); nfq_q->ovr.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); nfq_q->fd = nfq_fd(nfq_q->h); SCLogDebug("nfq_q->h %p, nfq_q->qh %p, nfq_q->fd %p", nfq_q->h, nfq_q->qh, nfq_q->fd); #endif /* OS_WIN32 */ return TM_ECODE_OK; }
/* * NFQUEUE main loop * Reads packet and calls callback */ static void *nkn_nfqueue_thread(void *arg) { struct nfq_handle *nfq_h; struct nfq_q_handle *nfq_q_h; int64_t thread_id = (int64_t) arg; char buf[65536] __attribute__ ((aligned)); int fd, rv, opt, ret; int queue_created; char t_name[50]; #if 0 char mem_pool_str[64]; #endif snprintf(t_name, 50, "nfqueue-%ld", thread_id); prctl(PR_SET_NAME, t_name, 0, 0, 0); #if 0 snprintf(mem_pool_str, sizeof(mem_pool_str), "nfqueuemempool-%ld", thread_id); nkn_mem_create_thread_pool(mem_pool_str); #endif #ifdef PROCESS_IN_NF_THREAD nkn_dpi_event_handle_init(thread_id); #endif UNUSED_ARGUMENT(arg); while (1) { queue_created = 0; nfq_h = nfq_open(); if (!nfq_h) { DBG_LOG(ERROR, MOD_DPI_URIF, "error during nfq_open()\n"); goto end; } if (nfq_unbind_pf(nfq_h, AF_INET) < 0) { DBG_LOG(ERROR, MOD_DPI_URIF, "error during nfq_unbind_pf()\n"); goto end; } if (nfq_bind_pf(nfq_h, AF_INET) < 0) { if (errno != EEXIST) { DBG_LOG(ERROR, MOD_DPI_URIF, "error during nfq_bind_pf()\n"); goto end; } } nfq_q_h = nfq_create_queue(nfq_h, thread_id, &nkn_nfqueue_callback, arg); if (!nfq_q_h) { DBG_LOG(ERROR, MOD_DPI_URIF, "error during nfq_create_queue()\n"); goto end; } queue_created = 1; if (nfq_set_mode(nfq_q_h, NFQNL_COPY_PACKET, 0xffff) < 0) { DBG_LOG(ERROR, MOD_DPI_URIF, "can't set packet_copy mode\n"); goto end; } fd = nfq_fd(nfq_h); opt = 0; ret = setsockopt(fd, SOL_NETLINK, NETLINK_BROADCAST_SEND_ERROR, &opt, sizeof(int)); if (ret < 0) { DBG_LOG(ERROR, MOD_DPI_URIF, "Failed to un set broadcast send error\n"); } opt = 1; ret = setsockopt(fd, SOL_NETLINK, NETLINK_NO_ENOBUFS, &opt, sizeof(int)); if (ret < 0) { DBG_LOG(ERROR, MOD_DPI_URIF, "Failed to set no enobug\n"); } opt = 1024 * 1024 * 256; ret = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(int)); if (ret < 0) { DBG_LOG(ERROR, MOD_DPI_URIF, "Failed to set recv buf size\n"); } ret = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &opt, sizeof(int)); if (ret < 0) { DBG_LOG(ERROR, MOD_DPI_URIF, "Failed to set send buf size\n"); } while ((rv = recv(fd, buf, sizeof(buf), 0)) && rv >= 0) { nfq_handle_packet(nfq_h, buf, rv); } end:; if (queue_created) nfq_destroy_queue(nfq_q_h); nfq_close(nfq_h); /* * Wait for 2 secs before retrying */ sleep(2); } return NULL; }
static int nfq_daq_initialize ( const DAQ_Config_t* cfg, void** handle, char* errBuf, size_t errMax) { if(cfg->name && *(cfg->name)) { snprintf(errBuf, errMax, "The nfq DAQ module does not support interface or readback mode!"); return DAQ_ERROR_INVAL; } // setup internal stuff NfqImpl *impl = calloc(1, sizeof(*impl)); if ( !impl ) { snprintf(errBuf, errMax, "%s: failed to allocate nfq context\n", __FUNCTION__); return DAQ_ERROR_NOMEM; } if ( nfq_daq_get_setup(impl, cfg, errBuf, errMax) != DAQ_SUCCESS ) { nfq_daq_shutdown(impl); return DAQ_ERROR; } if ( (impl->buf = malloc(MSG_BUF_SIZE)) == NULL ) { snprintf(errBuf, errMax, "%s: failed to allocate nfq buffer\n", __FUNCTION__); nfq_daq_shutdown(impl); return DAQ_ERROR_NOMEM; } // setup input stuff // 1. get a new q handle if ( !(impl->nf_handle = nfq_open()) ) { snprintf(errBuf, errMax, "%s: failed to get handle for nfq\n", __FUNCTION__); nfq_daq_shutdown(impl); return DAQ_ERROR; } // 2. now use the new q handle to rip the rug out from other // nfq users / handles? actually that doesn't seem to // happen which is good, but then why is this *supposed* // to be necessary? especially since we haven't bound to // a qid yet, and that is exclusive anyway. if ( (IP4(impl) && nfq_unbind_pf(impl->nf_handle, PF_INET) < 0) || (IP6(impl) && nfq_unbind_pf(impl->nf_handle, PF_INET6) < 0) ) { snprintf(errBuf, errMax, "%s: failed to unbind protocols for nfq\n", __FUNCTION__); //nfq_daq_shutdown(impl); //return DAQ_ERROR; } // 3. select protocols for the q handle // this is necessary but insufficient because we still // must configure iptables externally, eg: // // iptables -A OUTPUT -p icmp -j NFQUEUE [--queue-num <#>] // (# defaults to 0). // // :( iptables rules should be managed automatically to avoid // queueing packets to nowhere or waiting for packets that // will never come. (ie this bind should take the -p, -s, // etc args you can pass to iptables and create the dang // rule!) if ( (IP4(impl) && nfq_bind_pf(impl->nf_handle, PF_INET) < 0) || (IP6(impl) && nfq_bind_pf(impl->nf_handle, PF_INET6) < 0) ) { snprintf(errBuf, errMax, "%s: failed to bind protocols for nfq\n", __FUNCTION__); nfq_daq_shutdown(impl); return DAQ_ERROR; } // 4. bind to/allocate the specified nfqueue instance // (this is the puppy specified via iptables as in // above example.) // // ** there can be at most 1 nf_queue per qid if ( !(impl->nf_queue = nfq_create_queue( impl->nf_handle, impl->qid, daq_nfq_callback, impl)) ) { snprintf(errBuf, errMax, "%s: nf queue creation failed\n", __FUNCTION__); nfq_daq_shutdown(impl); return DAQ_ERROR; } // 5. configure copying for maximum overhead if ( nfq_set_mode(impl->nf_queue, NFQNL_COPY_PACKET, IP_MAXPACKET) < 0 ) { snprintf(errBuf, errMax, "%s: unable to set packet copy mode\n", __FUNCTION__); nfq_daq_shutdown(impl); return DAQ_ERROR; } // 6. set queue length (optional) if ( impl->qlen > 0 && nfq_set_queue_maxlen(impl->nf_queue, impl->qlen)) { snprintf(errBuf, errMax, "%s: unable to set queue length\n", __FUNCTION__); nfq_daq_shutdown(impl); return DAQ_ERROR; } // 7. get the q socket descriptor // (after getting not 1 but 2 handles!) impl->sock = nfq_fd(impl->nf_handle); // setup output stuff // we've got 2 handles and a socket descriptor but, incredibly, // no way to inject? if ( impl->device && strcasecmp(impl->device, "ip") ) { impl->link = eth_open(impl->device); if ( !impl->link ) { snprintf(errBuf, errMax, "%s: can't open %s!\n", __FUNCTION__, impl->device); nfq_daq_shutdown(impl); return DAQ_ERROR; } } else { impl->net = ip_open(); if ( !impl->net ) { snprintf(errBuf, errMax, "%s: can't open ip!\n", __FUNCTION__); nfq_daq_shutdown(impl); return DAQ_ERROR; } } impl->state = DAQ_STATE_INITIALIZED; *handle = impl; return DAQ_SUCCESS; }
int main(int argc, char **argv) { struct nfq_handle *h; struct nfq_q_handle *qh; fd_set sockets; int fd; int rv; char buf[MAX_PACKET_SIZE] __attribute__ ((aligned)); int s, sock_out, len, t; struct sockaddr_un local, remote; if ((s = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) { perror("socket"); exit(1); } local.sun_family = AF_UNIX; strcpy(local.sun_path, SOCK_PATH_S); unlink(local.sun_path); len = strlen(local.sun_path) + sizeof(local.sun_family); if (bind(s, (struct sockaddr *)&local, len) == -1) { perror("bind"); exit(1); } remote.sun_family = AF_UNIX; strcpy(remote.sun_path, SOCK_PATH); // unlink(remote.sun_path); if (connect(s, (struct sockaddr*)&remote, sizeof(remote))) { perror("connect"); exit(1); } /* if (listen(s, 5) == -1) { perror("listen"); exit(1); } */ for(;;) { printf("opening library handle\n"); 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 '0'\n"); qh = nfq_create_queue(h, 0, &cb, &s); 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); } if (nfq_set_queue_maxlen(qh, 1024) < 0) { perror("length"); } fd = nfq_fd(h); t = sizeof(remote); /* if ((sock_out = accept(s, (struct sockaddr *)&remote, &t)) == -1) { perror("accept"); exit(1); } */ for (;;) { int nready; int i; FD_ZERO(&sockets); FD_SET(fd, &sockets); FD_SET(s, &sockets); int maxfd = MAX(fd, s); nready = select(maxfd + 1, &sockets, NULL, NULL, NULL); if (nready == -1) { perror("select"); exit(1); } for(i=maxfd; i>= 0 && nready>0; i--) { if(FD_ISSET(i, &sockets)) { nready--; if (i == fd) { if ((rv = recv(fd, buf, sizeof(buf), 0)) >= 0) { nfq_handle_packet(h, buf, rv); continue; } /* if your application is too slow to digest the packets that * are sent from kernel-space, the socket buffer that we use * to enqueue packets may fill up returning ENOBUFS. Depending * on your application, this error may be ignored. Please, see * the doxygen documentation of this library on how to improve * this situation. */ if (rv < 0 && errno == ENOBUFS) { printf("losing packets!\n"); continue; } perror("recv failed"); break; } if (i == s) { if ((rv = recv(s, buf, sizeof(buf), 0)) >= 0) { set_verdict(qh, (verdict_msg*)buf); continue; } } } } } } printf("unbinding from queue 0\n"); nfq_destroy_queue(qh); printf("closing library handle\n"); nfq_close(h); close(s); exit(0); }