I want to write a custom netfilter module to log the HTTP headers of the incoming HTTP requests but it didn't work for me, I either receive empty or random data in the logs. Here is the code I'm using. Any contribution is welcome, thank you in advance.
module:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/ip.h>
#include <linux/tcp.h> // Include for struct tcphdr
static struct nf_hook_ops nfho;
static int sc_get_http_info(struct sk_buff *skb)
{
struct iphdr *iph = ip_hdr(skb);
struct tcphdr *tcph;
// Ensure the packet contains a TCP header
if (skb->protocol != htons(ETH_P_IP))
return 0;
tcph = tcp_hdr(skb);
if (tcph) {
unsigned char *data = (unsigned char *)tcph + tcph->doff * 4;
unsigned int dlen = skb->len - (iph->ihl * 4) - (tcph->doff * 4);
printk(KERN_INFO "HTTP Packet Header:\n");
printk(KERN_INFO "%.*s\n", dlen, data);
}
return 0;
}
unsigned int hook_func(void *priv, struct sk_buff *skb, const struct nf_hook_state *state) {
struct iphdr *ip_header;
// Extract IP header from the packet
ip_header = ip_hdr(skb);
// Log the IP header fields
printk(KERN_INFO "Source IP: %pI4\n", &ip_header->saddr);
printk(KERN_INFO "Destination IP: %pI4\n", &ip_header->daddr);
sc_get_https_info(skb); // Print HTTP packet header
return NF_ACCEPT; // Accept the packet
}
static int __init my_init(void) {
nfho.hook = hook_func;
nfho.hooknum = NF_INET_PRE_ROUTING; // Intercept incoming packets
nfho.pf = PF_INET;
nfho.priority = NF_IP_PRI_FIRST;
nf_register_net_hook(&init_net, &nfho);
printk(KERN_INFO "Netfilter module loaded\n");
return 0;
}
static void __exit my_exit(void) {
nf_unregister_net_hook(&init_net, &nfho);
printk(KERN_INFO "Netfilter module unloaded\n");
}
module_init(my_init);
module_exit(my_exit);
MODULE_LICENSE("GPL");
I tried some previous code like the one above, but the problem is that I don't know how to actually track the HTTP header of the packets to be able to log it and further make filtering based on the HTTP header contents. I expect to have a response on how to get that data, I think it's a problem of offset.