0

I'm trying to use nfqueue, came across this code:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <linux/types.h>
#include <linux/netfilter.h>        /* for NF_ACCEPT */

#include <libnetfilter_queue/libnetfilter_queue.h>

/* returns packet id */
static u_int32_t print_pkt (struct nfq_data *tb)
{
    int id = 0;
    struct nfqnl_msg_packet_hdr *ph;
    struct nfqnl_msg_packet_hw *hwph;
    u_int32_t mark,ifi; 
    int ret;
    char *data;

    ph = nfq_get_msg_packet_hdr(tb);
    if (ph) {
        id = ntohl(ph->packet_id);
        printf("hw_protocol=0x%04x hook=%u id=%u ",
            ntohs(ph->hw_protocol), ph->hook, id);
    }

    hwph = nfq_get_packet_hw(tb);
    if (hwph) {
        int i, hlen = ntohs(hwph->hw_addrlen);

        printf("hw_src_addr=");
        for (i = 0; i < hlen-1; i++)
            printf("%02x:", hwph->hw_addr[i]);
        printf("%02x ", hwph->hw_addr[hlen-1]);
    }

    mark = nfq_get_nfmark(tb);
    if (mark)
        printf("mark=%u ", mark);

    ifi = nfq_get_indev(tb);
    if (ifi)
        printf("indev=%u ", ifi);

    ifi = nfq_get_outdev(tb);
    if (ifi)
        printf("outdev=%u ", ifi);
    ifi = nfq_get_physindev(tb);
    if (ifi)
        printf("physindev=%u ", ifi);

    ifi = nfq_get_physoutdev(tb);
    if (ifi)
        printf("physoutdev=%u ", ifi);

    ret = nfq_get_payload(tb, &data);
    if (ret >= 0)
        printf("payload_len=%d ", ret);

    fputc('\n', stdout);

    return id;
}


static int cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg,
          struct nfq_data *nfa, void *data)
{
    u_int32_t id = print_pkt(nfa);
    printf("entering callback\n");
    return nfq_set_verdict(qh, id, NF_ACCEPT, 0, NULL);
}

int main(int argc, char **argv)
{
    struct nfq_handle *h;
    struct nfq_q_handle *qh;
    int fd;
    int rv;
    char buf[4096] __attribute__ ((aligned));

    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, 1, &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);
}

However, compiling outputs this error:

g++ r.cpp -o r

r.cpp:8:10: fatal error: libnetfilter_queue/libnetfilter_queue.h: No such file or directory
 #include <libnetfilter_queue/libnetfilter_queue.h>
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

which obviously means I'm missing the h file. however, I really struggle to understand where is the right place to get this file from, and how to link it.

Aykhan Hagverdili
  • 28,141
  • 6
  • 41
  • 93
  • Can you see it somewhere in your drives? – Yunnosch Sep 14 '19 at 11:38
  • What makes you think that the file exists or should exist or that you need it? – Yunnosch Sep 14 '19 at 11:39
  • 1
    Have you tried to search for e.g. `libnetfilter_queue.h`, both on your system and on the Internet? Have you tried to install a package such as `libnetfilter` or `libnetfilter-dev`? – Some programmer dude Sep 14 '19 at 11:40
  • 1
    after running find / -name "*netfilter_queue*", can safely say nope lol where do I get this file and where should i put it? –  Sep 14 '19 at 11:40
  • not found in official page of https://netfilter.org/projects/libnetfilter_queue/downloads.html –  Sep 14 '19 at 11:41
  • and no such package –  Sep 14 '19 at 11:41
  • You are trying to include "libnetfilter_queue.h" you have shown that you drive does not contain "netfilter_queue". That is not the same. – Yunnosch Sep 14 '19 at 11:42
  • tried this apt-get install libnfnetlink-dev didnt change compile error –  Sep 14 '19 at 11:43
  • @Yunnosch please explain (i use wild cards so it would match) –  Sep 14 '19 at 11:43
  • What is the source of the code you are trying to compile? Does it have docs? – Yunnosch Sep 14 '19 at 11:43
  • Ah I see. You probably need to learn about https://stackoverflow.com/editing-help#comment-formatting to get that kind of info across. – Yunnosch Sep 14 '19 at 11:44
  • yeah its here https://netfilter.org/projects/libnetfilter_queue/downloads.html I cant understand from here how to download properly –  Sep 14 '19 at 11:44
  • ohhh the wildcards are there i promise lol –  Sep 14 '19 at 11:45
  • Read the link, it explains how to make them visible instead of promising. ;-) – Yunnosch Sep 14 '19 at 11:45
  • Your way of compiling does not include any `-I` parts. That could be an obstacle. – Yunnosch Sep 14 '19 at 11:46
  • What am i missing, how do i start this –  Sep 14 '19 at 11:47
  • Have a look here https://stackoverflow.com/questions/19651222/how-to-include-header-from-self-compiled-library – Yunnosch Sep 14 '19 at 11:51
  • Possible duplicate of [How to include header from self compiled library?](https://stackoverflow.com/questions/19651222/how-to-include-header-from-self-compiled-library) – Yunnosch Sep 14 '19 at 11:51

1 Answers1

0

There is a directory named libnetfilter_queue, inside of it there is a file named libnetfilter_queue.h to access the file you need to add the directory libnetfilter_queue to your include directories.


To do that in g++ you need to use the -I option with the path to the directory.

for example:

g++ r.cpp -o -I/liblibnetfilter_queue/ r

If you are unsure what is the path to libnetfilter_queue you can download it here. It’s located at

libnetfilter_queue-1.0.3.tar.bz2/libnetfilter_queue-1.0.3/include/libnetfilter_queue/

or alternatively install the appropriate package with your package manger and it should automatically be added to your default include directory.

tomer zeitune
  • 1,080
  • 1
  • 12
  • 14
  • thank you so much, i found what you refer to, however, after copying it as you said I still get the same error, any idea how? should I modify the include line? –  Sep 14 '19 at 12:00
  • g++ r.cpp -I /libnetfilter_queue-1.0.3/include/libnetfilter_queue/ -o r thats my failed attempt –  Sep 14 '19 at 12:01
  • 3
    Downloading random files off the Internet in order to solve compilation problems rarely works out in the long run, as there's probably other stuff that's missing or broken. You need to figure out which package on your Linux distribution installs the netfilter development files, and install it. That's how to do this correctly. This is a bad answer. – Sam Varshavchik Sep 14 '19 at 12:02
  • Why though? can you see a way to install libnetfilter_queue in this case? the files are from the official docs –  Sep 14 '19 at 12:04
  • Oh wow, following your question I downloaded apt-get install libnetfilter-queue-dev it skipped to the next error, so I'm guessing fixed? is this really the recommended way to handle CPP header files? –  Sep 14 '19 at 12:06
  • 2
    Yes, believe it or not, the right way to install header files on Linux is to actually install the correct package that installs them, instead of downloading some random file with apparently the same name, somewhere off the Internet, and hoping that it's the right one. – Sam Varshavchik Sep 14 '19 at 12:15
  • @SamVarshavchik edited the question to inform the reader that they can download the header file needed using their package manager. Thank you for your advice. – tomer zeitune Sep 17 '19 at 05:04