Hi guys, I'm trying to hack kernel networking stack. My linux-4.19 on vm forwards packets from eth0 to eth1 and encrypts them on their way. On NF_INET_POST_ROUTING nf hook I want to catch them and substitute with packets with bigger size. (I wanna implement kinda ESP tunneling mode by myself). I need encapsulate my ipv6 packet within new ipv6 and encrypt internals. So, I need packet with bigger size. I kfree_skb() old packet and allocate new, than substitute. You can see it in my_hook() func.
The problem is: it doesn't work for unknown reason - each time packet flows through my hook, kernel gets crashed(Null pointer dereferencing). Maybe there is my mistake in using api? What i should do? Maybe there is utterly other way to accomplish my idea?
Code:
#include <linux/module.h>
#include <linux/init.h>
#include <linux/netfilter.h>
#include <linux/string.h>
#include <uapi/linux/ipv6.h>
#include <linux/ipv6.h>
#include <uapi/linux/netfilter.h>
#include <uapi/linux/netfilter_ipv4.h> // it is for NF_IP_PRI_FIRST
#include <linux/gfp.h>
unsigned int my_hook(void *priv,
struct sk_buff *skb,
const struct nf_hook_state *state)
{
// struct ipv6hdr *header = ipv6_hdr(skb);
struct sk_buff *n;
if (strcmp("eth1", state->out->name)) // not equal
return NF_ACCEPT;
pr_info("Caught packet directed to eth1\n");
n = skb_copy(skb, GFP_KERNEL);
if (n == NULL) {
pr_info("buffer is not allocated!");
return NF_ACCEPT;
}
kfree_skb(skb);
skb = n;
return NF_ACCEPT;
}
struct nf_hook_ops my_hook_ops[] = {
{
.hook = my_hook, //nf_hookfn *
.dev = NULL, //struct net_device *
.priv = NULL, // void *
.pf = NFPROTO_IPV6, // u_int8_t
.hooknum = NF_INET_POST_ROUTING, //unsigned int
.priority = NF_IP_PRI_FIRST, // int
}
};
static int __init my_init(void)
{
int ret;
pr_info("module loading\n");
ret = nf_register_net_hook(&init_net, my_hook_ops);
return 0;
}
static void __exit my_exit(void)
{
nf_unregister_net_hook(&init_net, my_hook_ops);
pr_info("module unloading\n");
return;
}