Exemple #1
0
int main(int argc, char **argv) {
  int rv;
  char buf[4096] __attribute__ ((aligned));

  q_setup();

  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);
}
Exemple #2
0
/* nfq initialize
 */
void              fwnfq_init(void)
{
	g_message("Opening library handle");
	h = nfq_open();
	if (!h)
		g_error("Error during nfq_open()");
	
	g_message("unbinding existing nf_queue handler for AF_INET (if any)");
	if (nfq_unbind_pf(h, AF_INET) < 0)
		g_warning("Error during nfq_unbind_pf()");
	
	g_message("Binding nfnetlink_queue as nf_queue handler for AF_INET");
	if (nfq_bind_pf(h, AF_INET) < 0)
		g_error("Error during nfq_bind_pf()");
	
	g_message("Binding this socket to queue '0'");
	qh = nfq_create_queue(h,  0, &fwnfq_callback, NULL);
	if (!qh) 
		g_error("Error during nfq_create_queue()\n");

	g_message("Setting copy_packet mode");
	if (nfq_set_mode(qh, NFQNL_COPY_PACKET, 0xffff) < 0)
		g_error("Can't set packet_copy mode");
  
	nh = nfq_nfnlh(h);
	fd = nfnl_fd(nh);
}
QHandler::QHandler(unsigned short qid) : qid(qid)
{
	// Default these to 0, so we won't handle anything.
	lowerHashLimit = 0;
	upperHashLimit = 0;

	std::cout << "Opening library..." << std::endl;
	h = nfq_open();
	if (h == 0) { throw std::runtime_error("Cannot open lib"); }
	// Unbind existing handler
	if (nfq_unbind_pf(h, AF_INET) < 0) {
	    std::cerr << "error during nfq_unbind_pf() - maybe this is ok\n";
	}
	// Bind new handler
	if (nfq_bind_pf(h, AF_INET) < 0) {
	    throw std::runtime_error("nfq_bind_pf failed");
	}
	qh = nfq_create_queue(h,  QueueId, &packet_callback, this);
	if (qh == 0) { throw std::runtime_error("Cannot create queue"); }
	// Set packet copy mode...
	if (nfq_set_mode(qh, NFQNL_COPY_PACKET, 0xffff) < 0) {
	    throw std::runtime_error("nfq_set_mode failed");
	}

	// Get the nl handle and file descriptor...
	nh = nfq_nfnlh(h);
	sock = nfnl_fd(nh);
	// So far so good.
	// Set our socket non blocking.
	SetNonBlocking(sock);
}
Exemple #4
0
response_t destroy_queue(int q_num, q_data_t **q_data, thread_data_t *data) {

    int cq_idx;
    response_t r;

    syslog(LOG_NOTICE,"[%d] q_num: %d\n\r", data->idx, q_num);

    if((cq_idx = get_queue_idx(q_num, q_data)) >= 0) {

        if(q_data[cq_idx]->pid > 0)
            pthread_cancel(q_data[cq_idx]->thread);

        nfq_destroy_queue(q_data[cq_idx]->qh);
        nfq_unbind_pf(q_data[cq_idx]->h, AF_INET);
        nfq_close(q_data[cq_idx]->h);

        q_data[cq_idx]->pid = 0;
        q_data[cq_idx]->q_num = -1;
        q_data[cq_idx]->qh = NULL;
        q_data[cq_idx]->h = NULL;

        r.cs = erl_mk_atom("ok");
        r.rsp = erl_mk_atom("ok");

    } else {
        r.cs = erl_mk_atom("error");
        r.rsp = erl_mk_estring("no such queue", strlen("no such queue"));
    }
    return r;
}
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);
}
static struct nfq_handle* setup_netfilter_queue()
{
    struct nfq_handle* nfq_h = NULL;
    if(UNLIKELY(NULL == (nfq_h = nfq_open())))
    {
        fprintf(stderr,"Error: unable to initialize netfilter queue\n");
        goto error;
    }
    if(UNLIKELY(0 > nfq_unbind_pf(nfq_h,AF_INET)))
    {
        fprintf(stderr,"Error: unable to unbind netfilter handle\n");
        goto error;
    }
    if(UNLIKELY(0 > nfq_bind_pf(nfq_h,AF_INET)))
    {
        fprintf(stderr,"Error: unable to bind netfilter handle\n");
        goto error;
    }

    return nfq_h;

error:
    if(nfq_h) nfq_close(nfq_h);
    return NULL;
}
Exemple #7
0
bool NetherNetlink::initialize()
{
	nfqHandle = nfq_open();

	if(!nfqHandle)
	{
		LOGE("Error during nfq_open()");
		return (false);
	}

	if(nfq_unbind_pf(nfqHandle, AF_INET) < 0)
	{
		LOGE("Error during nfq_unbind_pf() (no permission?)");
		return (false);
	}

	if(nfq_bind_pf(nfqHandle, AF_INET) < 0)
	{
		LOGE("Error during nfq_bind_pf()");
		return (false);
	}

	queueHandle = nfq_create_queue(nfqHandle, queue, &callback, this);

	if(!queueHandle)
	{
		LOGE("Error during nfq_create_queue()");
		return (false);
	}

	if(nfq_set_queue_flags(queueHandle, NFQA_CFG_F_SECCTX, NFQA_CFG_F_SECCTX))
		LOGI("This kernel version does not allow to retrieve security context");

	if(nfq_set_mode(queueHandle, netherConfig.copyPackets ? NFQNL_COPY_PACKET : NFQNL_COPY_META, 0xffff) < 0)
	{
		LOGE("Can't set packet_copy mode");
		nfq_destroy_queue(queueHandle);
		return (false);
	}

	if(nfq_set_queue_flags(queueHandle, NFQA_CFG_F_UID_GID, NFQA_CFG_F_UID_GID))
	{
		LOGE("This kernel version does not allow to retrieve process UID/GID");
		nfq_destroy_queue(queueHandle);
		return (false);
	}

	if (netherConfig.interfaceInfo)
	{
		nlif = nlif_open();

		if(!nlif)
			LOGI("Failed to initialize NLIF subsystem, interface information won't be available");
		else
			nlif_query(nlif);
	}

	return (true);
}
int queue_unbind(struct queue *self, int af_family)
{
        if (nfq_unbind_pf(self->_h, af_family)) {
                throw_exception("error during nfq_unbind_pf()");
                return -1;
        }
        return 0;
}
Exemple #9
0
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);
}
Exemple #10
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;
}
Exemple #11
0
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;
}
Exemple #12
0
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);
}
Exemple #13
0
/**
 * 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;
}
Exemple #14
0
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;
}
Exemple #15
0
/*
 * Initialize stdin and nfq hook, then loop forever. Callback() does all the real work.
 */
int main(int argc, char **argv) {

	int fd;
    int rv;
    char buf[4096] __attribute__ ((aligned));

	if(getuid() != 0) {
        fail("Only root can use me.");
    }

	/* make stdin non-blocking, i.e. optional */
	int flags = fcntl(0, F_GETFL, 0);
	flags |= O_NONBLOCK;
	fcntl(0, F_SETFL, flags);


	/* signal handler will close nfq hooks on exit */
	if(signal(SIGINT, sig_handler) == SIG_IGN)
        signal(SIGINT, SIG_IGN);
    if(signal(SIGHUP, sig_handler) == SIG_IGN)
        signal(SIGINT, SIG_IGN);
    if(signal(SIGTERM, sig_handler) == SIG_IGN)
        signal(SIGINT, SIG_IGN);

	/* hook callback() into userspace netlink queue */
	if (!(nfqh = nfq_open()))
		fail("nfq_open() failed");

	if (0 > nfq_unbind_pf(nfqh, AF_INET))
		fail("nfq_unbind_pf failed");

	if (0 > nfq_bind_pf(nfqh, AF_INET))
		fail("nfq_bind_pf failed");

	if (!(qh = nfq_create_queue(nfqh, 0, &callback, NULL)))
		fail("nfq_create_queue failed");

	if (0 > nfq_set_mode(qh, NFQNL_COPY_META, 0xffff))
		fail("nfq_set_mode failed");

	nh = nfq_nfnlh(nfqh);
	fd = nfnl_fd(nh);


	printf("Commencing packet mangling..\n");

	clock_gettime(CLOCK_REALTIME, &last_time);

	while ((rv = recv(fd, buf, sizeof(buf), 0)) && rv >= 0)
		nfq_handle_packet(nfqh, buf, rv);


    printf("Exiting..\n");
    return 0;
}
Exemple #16
0
/*
 * Open a netlink connection and returns file descriptor
 */
int netlink_open_connection(void *data)
{
    struct nfnl_handle *nh;

#ifdef UFD_DEBUG
    printf("opening library handle\n");
#endif
    h = nfq_open();
    if (!h)
    {
        fprintf(stderr, "error during nfq_open()\n");
        exit(1);
    }

#ifdef UFD_DEBUG
    printf("unbinding existing nf_queue handler for AF_INET (if any)\n");
#endif
    if (nfq_unbind_pf(h, AF_INET) < 0)
    {
        fprintf(stderr, "error during nfq_unbind_pf()\n");
        exit(1);
    }

#ifdef UFD_DEBUG
    printf("binding nfnetlink_queue as nf_queue handler for AF_INET\n");
#endif
    if (nfq_bind_pf(h, AF_INET) < 0)
    {
        fprintf(stderr, "error during nfq_bind_pf()\n");
        exit(1);
    }

#ifdef UFD_DEBUG
    printf("binding this socket to queue '0'\n");
#endif
    qh = nfq_create_queue(h,  0, &cb, NULL);
    if (!qh)
    {
        fprintf(stderr, "error during nfq_create_queue()\n");
        exit(1);
    }

#ifdef UFD_DEBUG
    printf("setting copy_packet mode\n");
#endif
    if (nfq_set_mode(qh, NFQNL_COPY_PACKET, 0xffff) < 0)
    {
        fprintf(stderr, "can't set packet_copy mode\n");
        exit(1);
    }

    nh = nfq_nfnlh(h);
    return nfnl_fd(nh);
}
Exemple #17
0
/*-
-- qhandle = nfq.unbind_pf(qhandle, family)

Protocol family is one of "inet", "inet6".

Return is qhandle on success and nil,emsg,errno on failure.
*/
static int unbind_pf(lua_State* L)
{
    struct nfq_handle* h = check_handle(L);
    int pf = check_PF(L, 2);

    if(nfq_unbind_pf(h, pf) < 0) {
        return push_error(L);
    }

    lua_settop(L, 1);

    return 1;
}
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);
}
Exemple #19
0
/* ---------------------------------------------------------------------------- */
void              fwnfq_destroy(void)
{  
	g_message("Unbinding from queue 0");
	nfq_destroy_queue(qh);
  
#ifdef INSANE
	/* normally, applications SHOULD NOT issue this command, since
	 * it detaches other programs/sockets from AF_INET, too ! */
	g_message("Unbinding from AF_INET");
	nfq_unbind_pf(h, AF_INET);
#endif

	g_message("Closing library handle");
	nfq_close(h);
}
Exemple #20
0
static int
OpenAndConfNFqueue(){

        struct nfq_q_handle *myQueue;
        struct nfnl_handle *netlinkHandle;

        int fd = 0, e = 0;

	inet_pton(AF_INET, "239.255.255.250", &(ssdp.sin_addr));

        /* Get a queue connection handle from the module */
        if (!(nfqHandle = nfq_open())) {
		syslog(LOG_ERR, "Error in nfq_open(): %m");
                return -1;
        }

        /* Unbind the handler from processing any IP packets
           Not totally sure why this is done, or if it's necessary... */
        if ((e = nfq_unbind_pf(nfqHandle, AF_INET)) < 0) {
		syslog(LOG_ERR, "Error in nfq_unbind_pf(): %m");
                return -1;
        }

        /* Bind this handler to process IP packets... */
        if (nfq_bind_pf(nfqHandle, AF_INET) < 0) {
		syslog(LOG_ERR, "Error in nfq_bind_pf(): %m");
                return -1;
        }

        /*      Install a callback on queue -Q */
        if (!(myQueue = nfq_create_queue(nfqHandle,  nfqueue, &nfqueue_cb, NULL))) {
		syslog(LOG_ERR, "Error in nfq_create_queue(): %m");
                return -1;
        }

        /*      Turn on packet copy mode */
        if (nfq_set_mode(myQueue, NFQNL_COPY_PACKET, 0xffff) < 0) {
		syslog(LOG_ERR, "Error setting packet copy mode (): %m");
                return -1;
        }

        netlinkHandle = nfq_nfnlh(nfqHandle);
        fd = nfnl_fd(netlinkHandle);

	return fd;

}
Exemple #21
0
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;
}
Exemple #22
0
void disruptor_nfq_init() {
	/* Library initialisation */
	d_nfq.h = nfq_open();
	if (!d_nfq.h) {
		log_error("error during nfq_open()");
		exit(1);
	}
	log_debug("unbinding existing nf_queue handler for AF_INET (if any)");
	if (nfq_unbind_pf(d_nfq.h, AF_INET) < 0) {
		log_error("error during nfq_unbind_pf()");
		exit(1);
	}
	log_debug("binding nfnetlink_queue as nf_queue handler for AF_INET");
	if (nfq_bind_pf(d_nfq.h, AF_INET) < 0) {
		log_error("error during nfq_bind_pf()");
		exit(1);
	}
}
Exemple #23
0
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;
}
Exemple #24
0
int teardown_nfq()
{
    log_debug("unbinding from queue %d", NF_QUEUE_NUM);
    if (nfq_destroy_queue(g_nfq_qh) != 0) {
        log_error("error during nfq_destroy_queue()");
        return -1;
    }

#ifdef INSANE
    // normally, applications SHOULD NOT issue this command, since
    // it detaches other programs/sockets from AF_INET, too ! */
    log_debug("unbinding from AF_INET");
    nfq_unbind_pf(g_nfq_h, AF_INET);
#endif

    log_debug("closing library handle");
    if (nfq_close(g_nfq_h) != 0) {
        log_error("error during nfq_close()");
        return -1;
    }

    return 0;
}
Exemple #25
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;
}
struct nfq_handle *get_handle() {
    struct nfq_handle *h;

    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);
    }

    return h;
}
Exemple #27
0
Fichier : main.c Projet : lmatz/NAT
int main(int argc, char **argv) {

	struct nfq_handle *nfqHandle;
	struct nfq_q_handle *myQueue;
	struct nfnl_handle *netlinkHandle;

	int fd, res;
	char buf[BUFF_SIZE];

	if (argc!=4) {
		fprintf(stderr,"Error in number of arguments\n");
		exit(-1);
	}

	// get the public IP address. And the public IP address is host byte order.
	publicIP = inet_network(argv[1]);
	if (publicIP == 0) {
		fprintf(stderr,"Error in public IP\n");
		exit(-1);
	}
	fprintf(stdout,"publicIP: %u\n",publicIP);

	// get the subnet IP address. And the subnet IP address is host byte order.
	internalIP = inet_network(argv[2]);
	if (internalIP == 0) {
		fprintf(stderr,"Error in internal IP\n");
		exit(-1);
	}
	fprintf(stdout,"internalIP: %u\n",internalIP);
	mask = mask << (32-atoi(argv[3]));
	subnetIP = internalIP & mask;
	fprintf(stdout,"subnetIP: %u\n",subnetIP);

	initUdp( &udpHead );
	initTcp( &tcpHead );

	if ( !(nfqHandle = nfq_open())) {
		fprintf(stderr, "Error in nfq_open()\n");
		exit(-1);
	}

	if ( nfq_unbind_pf(nfqHandle, AF_INET) < 0 ) {
		fprintf(stderr, "Error in nfq_unbind_pf()\n");
		exit(-1);
	}

	if ( nfq_bind_pf(nfqHandle, AF_INET) < 0) {
		fprintf(stderr, "Error in nfq_bind_pf()\n");
		exit(-1);
	}

	if ( !(myQueue = nfq_create_queue(nfqHandle, 0, &Callback123, NULL)) ) {
		fprintf(stderr, "Error in nfq_create_queue()\n");
		exit(1);
	}

	if ( nfq_set_mode(myQueue, NFQNL_COPY_PACKET, 0xffff) <0 ) {
		fprintf(stderr, "Could not set packet copy mode\n");
		exit(1);
	}

	netlinkHandle = nfq_nfnlh(nfqHandle);
	fd = nfnl_fd(netlinkHandle);

	
	fprintf(stdout,"ready to receive packets\n");

	//Start to process the packet we receive.
	while ( (res = recv(fd, buf , sizeof(buf), 0))  && res>=0 ) {
		
		printf("\n\n\n*******NEW ONE*******\n");
		fprintf(stdout,"in the loop\n");
		nfq_handle_packet(nfqHandle, buf , res);
	}
	//End the process


	nfq_destroy_queue(myQueue);

	nfq_close(nfqHandle);

	return 0;

}
Exemple #28
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;
}
Exemple #29
0
/* The nfq capture routine.
*/
int
nfq_capture(fko_srv_options_t *opts)
{
    int                 res, child_pid, fd_flags;
    int                 nfq_errcnt = 0;
    int                 pending_break = 0;
    int                 status;
    char                nfq_buf[1500];
    int                 chk_rm_all = 0;

    /* Netfilter-related handles
    */
    int                  nfq_fd;
    struct nfq_handle   *nfq_h;
    struct nfq_q_handle *nfq_qh;
    struct nfnl_handle  *nfq_nh;

    nfq_h = nfq_open();
    if (!nfq_h) {
        log_msg(LOG_ERR, "[*] nfq_open error\n");
        clean_exit(opts, FW_CLEANUP, EXIT_FAILURE);
    }

    /* Unbind existing nf_queue handler for AF_INET (if any)
    */
    res = nfq_unbind_pf(nfq_h, AF_INET);
    if (res < 0)  {
        log_msg(LOG_WARNING, "[*] Error during nfq_unbind_pf() error: %d\n", res);
    }

    /* Bind the given queue connection handle to process packets.
    */
    res =  nfq_bind_pf(nfq_h, AF_INET);
    if ( res < 0) {
        log_msg(LOG_ERR, "Error during nfq_bind_pf(), error: %d\n", res);
        clean_exit(opts, FW_CLEANUP, EXIT_FAILURE);
    }

    /* Create queue
    */
    nfq_qh = nfq_create_queue(nfq_h,  atoi(opts->config[CONF_NFQ_QUEUE_NUMBER]), &process_nfq_packet, opts);
    if (!nfq_qh) {
        log_msg(LOG_ERR, "Error during nfq_create_queue()\n");
        clean_exit(opts, FW_CLEANUP, EXIT_FAILURE);
    }

    /* Set the amount of data to be copied to userspace for each packet
     * queued to the given queue.
    */
    if (nfq_set_mode(nfq_qh, NFQNL_COPY_PACKET, 0xffff) < 0) {
        log_msg(LOG_ERR, "Can't set packet_copy mode\n");
        clean_exit(opts, FW_CLEANUP, EXIT_FAILURE);
    }

    /* Get the netlink handle associated with the given queue connection
     * handle. Then use it to get the file descriptor we will use for
     * receiving the queued packets
    */
    nfq_nh = nfq_nfnlh(nfq_h);
    nfq_fd = nfnl_fd(nfq_nh);

    /* Set our nfq handle nonblocking mode.
     *
    */
    if((fd_flags = fcntl(nfq_fd, F_GETFL, 0)) < 0)
    {
        log_msg(LOG_ERR, "nfq_capture: fcntl F_GETFL error: %s",
            strerror(errno));
        clean_exit(opts, FW_CLEANUP, EXIT_FAILURE);
    }

    fd_flags |= O_NONBLOCK;

    if(fcntl(nfq_fd, F_SETFL, fd_flags) < 0)
    {
        log_msg(LOG_ERR, "nfq_capture: fcntl F_SETFL error setting O_NONBLOCK: %s",
            strerror(errno));
        exit(EXIT_FAILURE);
    }

    /* Initialize our signal handlers. You can check the return value for
     * the number of signals that were *not* set.  Those that were not set
     * will be listed in the log/stderr output.
    */
    if(set_sig_handlers() > 0)
        log_msg(LOG_ERR, "Errors encountered when setting signal handlers.");

    log_msg(LOG_INFO, "Starting fwknopd main event loop.");

    /* Jump into our home-grown packet cature loop.
    */
    while(1)
    {
        /* If we got a SIGCHLD and it was the tcp server, then handle it here.
        ** XXX: --DSS Do we need this here?  I'm guessing we would not be using
        **            the TCP server in NF_QUEUE capture mode.
        */
        if(got_sigchld)
        {
            if(opts->tcp_server_pid > 0)
            {
                child_pid = waitpid(0, &status, WNOHANG);

                if(child_pid == opts->tcp_server_pid)
                {
                    if(WIFSIGNALED(status))
                        log_msg(LOG_WARNING, "TCP server got signal: %i",  WTERMSIG(status));

                    log_msg(LOG_WARNING,
                        "TCP server exited with status of %i. Attempting restart.",
                        WEXITSTATUS(status)
                    );

                    opts->tcp_server_pid = 0;

                    /* Attempt to restart tcp server ? */
                    usleep(1000000);
                    run_tcp_server(opts);
                }
            }

            got_sigchld = 0;
        }

        /* Any signal except USR1, USR2, and SIGCHLD mean break the loop.
        */
        if(got_signal != 0)
        {
            if(got_sigint || got_sigterm || got_sighup)
            {
                pending_break = 1;
            }
            else if(got_sigusr1 || got_sigusr2)
            {
                /* Not doing anything with these yet.
                */
                got_sigusr1 = got_sigusr2 = 0;
                got_signal = 0;
            }
            else
                got_signal = 0;
        }

        res = recv(nfq_fd, nfq_buf, sizeof(nfq_buf), 0);

        /* Count processed packets
        */
        if(res > 0)
        {
            nfq_handle_packet(nfq_h, nfq_buf, res);

            /* Count the set of processed packets (nfq_dispatch() return
             * value) - we use this as a comparison for --packet-limit regardless
             * of SPA packet validity at this point.
            */
            opts->packet_ctr += res;
            if (opts->packet_ctr_limit && opts->packet_ctr >= opts->packet_ctr_limit)
            {
                log_msg(LOG_WARNING,
                    "* Incoming packet count limit of %i reached",
                    opts->packet_ctr_limit
                );

                pending_break = 1;
            }
        }
        /* If there was an error, complain and go on (to an extent before
         * giving up).
        */
        else if(res < 0 && errno != EAGAIN)
        {

            log_msg(LOG_ERR, "[*] Error reading from  nfq descriptor: %s", strerror);

            if(nfq_errcnt++ > MAX_NFQ_ERRORS_BEFORE_BAIL)
            {
                log_msg(LOG_ERR, "[*] %i consecutive nfq errors.  Giving up",
                    nfq_errcnt
                );
                clean_exit(opts, FW_CLEANUP, EXIT_FAILURE);
            }

        }
        else if(pending_break == 1 || res == -2)
        {
            log_msg(LOG_INFO, "Gracefully leaving the fwknopd event loop.");
            break;
        }
        else
            nfq_errcnt = 0;

        /* Check for any expired firewall rules and deal with them.
        */
        check_firewall_rules(opts, chk_rm_all);

        usleep(atoi(opts->config[CONF_NFQ_LOOP_SLEEP]));
    }

    nfq_destroy_queue(nfq_qh);
    nfq_close(nfq_h);

    return(0);
}
Exemple #30
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];

	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);
	}

	nh = nfq_nfnlh(h);
	fd = nfnl_fd(nh);

	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);
}