简体   繁体   English

使用libnetfilter_queue的简单程序不起作用

[英]simple program using libnetfilter_queue isn't working

I'm trying to learn how to use libnetfilter_queue. 我正在尝试学习如何使用libnetfilter_queue。 I've compiled the example provided with the library. 我已经编译了库提供的示例。

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

Launching the executable it doesn't receive anything. 启动可执行文件它不会收到任何东西。 I also followed this thread and tried to use netcat to generate traffic but again i didn't see any packet Maybe I'm missing something to really interact with filter queues? 我也跟着这个线程并尝试使用netcat来生成流量但是我没有看到任何数据包也许我错过了与过滤器队列真正交互的东西?

Yes, you have. 是的,你有。 If your firewall lets the packets trough the rules nothing will happen and the packets wont left the kernel space. 如果您的防火墙允许数据包通过规则,则不会发生任何事情,数据包也不会离开内核空间。 But if you setting up some rules that send the packets to the user space, your programm will work. 但是,如果您设置一些将数据包发送到用户空间的规则,您的程序将起作用。

iptables -A INPUT -i eth0 -j NFQUEUE --queue-num 0

This line will send all packets from the INPUT with the --in-interface eth0 into the userspace. 此行将使用--in-interface eth0将所有来自INPUT的数据包发送到用户空间。

libnetfilter_queue is as it's named, a filter. libnetfilter_queue就像它的名字一样,是一个过滤器。 That means, it filters out traffic based on the settings you give it when you create and open the queue. 这意味着,它会根据您在创建和打开队列时提供的设置过滤掉流量。

If you do not send any traffic through this filter, the filter has nothing to work on. 如果您不通过此过滤器发送任何流量,则过滤器无需处理任何操作。 How much (what kind of) traffic that goes through this filter, you must set in iptable. 通过此过滤器需要多少(什么样的)流量,您必须在iptable中设置。

Iptable works as a firewall into, through or out of your system. Iptable作为防火墙进入,通过退出系统。 Libnetfilter_queue lets you control what to do with the filtered traffic. Libnetfilter_queue允许您控制如何处理过滤后的流量。

Hope this helps you somewhat. 希望这对你有所帮助。

Reading that thread I found I haven't added iptables rules... Adding those rules make the trick. 阅读那个线程,我发现我没有添加iptables规则......添加这些规则就可以了。

So I always need to set iptables rules to get packets using netfilter library? 所以我总是需要设置iptables规则来使用netfilter库获取数据包?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM