kernel module does not print packet info

716 views Asked by At

I would like to use a c kernel module to capture all the network packets coming to an interface.. My topology is something like A--->B--->C, which means A sends a UDP packet to C's IP, but the packet will go through B.

My problem is that: at B side, by tcpdump, I can really capture the packet with IP(A)--->IP(C), however, in the kernel code, it does not capture such event (e.g. no print out messages as shown in the following code sample.).

My code is pretty much similar as one previous thread in How to echo a packet in kernel space using netfilter hooks?, and here I also paste the key parts in the following.

Please, someone has the idea to solve it? anywhere wrong?

Thank you so much.

ps, if "A" directly UDP packet to "B" (destination IP is B). then it successfully print out the message...(/proc/sys/net/ipv4/ip_forward is 1, and there is no iptables rule to drop the packet.).. I tried on debian 6.0 and ubuntu 14.04 real PC, and none of them is working..however, when I tried on a virtual machine with Ubuntu 14.04, it works..

#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

There are 0 answers