内核模块不打印数据包信息

时间:2015-06-08 15:18:32

标签: c linux networking linux-kernel packet-capture

我想使用ac内核模块捕获到达接口的所有网络数据包。我的拓扑结构类似于A ---> B ---> C,这意味着A发送UDP数据包到C的IP,但数据包将通过B。

我的问题是:在B方面,通过tcpdump,我可以用IP(A)---> IP(C)捕获数据包,但是,在内核代码中,它不会捕获此类事件(例如,没有打印输出消息,如下面的代码示例所示。)。

我的代码与How to echo a packet in kernel space using netfilter hooks?中的前一个代码非常相似,在这里我还粘贴了以下关键部分。

拜托,有人有想法解决它吗?哪里错了?

非常感谢你。

ps,如果“A”直接UDP包到“B”(目标IP是B)。然后它成功打印出消息...(/ proc / sys / net / ipv4 / ip_forward是1,没有iptables规则丢弃数据包。)..我尝试了debian 6.0和ubuntu 14.04真正的PC,并且它们都没有工作......但是,当我尝试使用Ubuntu 14.04的虚拟机时,它可以工作..

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/netfilter.h>
#include <linux/netdevice.h>
#include <linux/ip.h>
#include <linux/udp.h>
#include <linux/mm.h>
#include <linux/err.h>
#include <linux/crypto.h>
#include <linux/init.h>
#include <linux/crypto.h>
#include <linux/scatterlist.h>
#include <net/ip.h>
#include <net/udp.h>
#include <net/route.h>
#include <net/checksum.h>
#include <linux/netfilter_ipv4.h>

#define IP_HDR_LEN 20
#define UDP_HDR_LEN 8
#define TOT_HDR_LEN 28

static unsigned int pkt_echo_begin(unsigned int hooknum,
                        struct sk_buff *skb,
                        const struct net_device *in,
                        const struct net_device *out,
                        int (*okfn)(struct sk_buff *));

static struct nf_hook_ops pkt_echo_ops __read_mostly = {
    .pf = NFPROTO_IPV4,
    .priority = 1,
    .hooknum = NF_INET_PRE_ROUTING,
    .hook = pkt_echo_begin,
};

static int __init pkt_echo_init(void)
{
    printk(KERN_ALERT "\npkt_echo module started ...");
    return nf_register_hook(&pkt_echo_ops);
}

static void __exit pkt_echo_exit(void)
{
    nf_unregister_hook(&pkt_echo_ops);
    printk(KERN_ALERT "pkt_echo module stopped ...");
}

static unsigned int pkt_echo_begin (unsigned int hooknum,
                        struct sk_buff *skb,
                        const struct net_device *in,
                        const struct net_device *out,
                        int (*okfn)(struct sk_buff *))
{
    struct iphdr *iph;
    struct udphdr *udph;
    unsigned char *data;

    unsigned char *temp;

    __u16 dst_port, src_port;
    int data_len;

    if (skb) {
        iph = (struct iphdr *) skb_header_pointer (skb, 0, 0, NULL);

        if (iph && iph->protocol &&(iph->protocol == IPPROTO_UDP)) {
            udph = (struct udphdr *) skb_header_pointer (skb, IP_HDR_LEN, 0, NULL);
            src_port = ntohs (udph->source);
            dst_port = ntohs (udph->dest);

            if (dst_port == 6000) {
                printk(KERN_ALERT "\n UDP packet goes in"); 
// NOTE: Here we have nothing, but tcpdump works and can capture the packet.

                ......

            }
        }
    }
    return NF_ACCEPT;
}

0 个答案:

没有答案