用于修改数据包的Linux模块(Netfilter)

时间:2012-04-29 11:56:11

标签: linux module packet

有人能告诉我如何使用Netfilter挂钩修改linux模块的数据包数据?

谢谢!

2 个答案:

答案 0 :(得分:2)

没有必要编写自己的netfilter模块。您可以使用iptables中的QUEUE目标从用户空间访问它,并编写一个处理队列的守护进程。

这方面的例子相对较少,但有些确实存在。它通常用于过滤,但你也可以(我相信)重新注入修改后的数据包(至少在iptables的mangle表中)。

答案 1 :(得分:1)

尝试以下程序

写入IPTABLES规则以将数据包传递到用户空间数据包

# iptables -A INPUT -p TCP -j QUEUE

编译并执行为

$ gcc test.c -lipq
$ sudo ./a.out

源代码

#include <netinet/in.h> 
#include <linux/netfilter.h> 
#include <libipq.h> 
#include <stdio.h> 
#include <stdlib.h>


#define BUFSIZE 2048
static void die(struct ipq_handle *h)
{
    ipq_perror("passer");
    ipq_destroy_handle(h);
    exit(1);
}
int main(int argc, char **argv)
{
    int status, i=0;
    unsigned char buf[BUFSIZE];
    struct ipq_handle *h;
    h = ipq_create_handle(0, NFPROTO_IPV4);

    if (!h)     die(h);

    status = ipq_set_mode(h, IPQ_COPY_PACKET, BUFSIZE);

    if (status < 0) die(h);

    do{
        i++;
        status = ipq_read(h, buf, BUFSIZE, 0);

        if (status < 0) die(h);

        switch (ipq_message_type(buf)) {
            case NLMSG_ERROR:
                fprintf(stderr, "Received error message %d\n",
                ipq_get_msgerr(buf));
                break;
            case IPQM_PACKET:
            {
                ipq_packet_msg_t *m = ipq_get_packet(buf);
                printf("\nReceived Packet");
                /****YOUR CODE TO MODIFY PACKET GOES HERE****/
                status = ipq_set_verdict(h, m->packet_id, NF_ACCEPT, 0, NULL);
                if (status < 0)  die(h);
                break;
            }
            default:
                fprintf(stderr, "Unknown message type!\n");
                break;
        }
    } while (1);
    ipq_destroy_handle(h);
    return 0;
}