Skip to content

Instantly share code, notes, and snippets.

@nkapliev
Last active Mar 19, 2020
Embed
What would you like to do?
Linux kernel 4.4+ netfilter packet capturing boilerplate.
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/ip.h>
#include <linux/netfilter.h>
//#undef __KERNEL__
#include <linux/netfilter_ipv4.h>
//#define __KERNEL__
// I am using this code on my VM. Was interested in capturing only non-bridge packets
const __be32 HOST_IP_ADDR = 20687040;
const __be32 LOCAL_IP_ADDR = 171681984;
static struct nf_hook_ops nfin;
static struct nf_hook_ops nfout;
// In every netfilter guid you will find Linux kernel 2.x version of netfilter:
//typedef unsigned int nf_hookfn(unsigned int hooknum,
// struct sk_buff *skb,
// const struct net_device *in,
// const struct net_device *out,
// int (*okfn)(struct sk_buff *))
//{
// In 4.3- it was look like this:
//typedef unsigned int nf_hookfn(const struct nf_hook_ops *ops,
// struct sk_buff *skb,
// const struct nf_hook_state *state);
// Since 4.4+ it was generalised:
static unsigned int hook_func_in(void *priv,
struct sk_buff *skb,
const struct nf_hook_state *state)
{
struct ethhdr *eth;
struct iphdr *ip_header;
eth = (struct ethhdr*)skb_mac_header(skb);
ip_header = (struct iphdr *)skb_network_header(skb);
if (HOST_IP_ADDR == ip_header->saddr)
return NF_ACCEPT;
printk("NF_IP_LOCAL_IN hook:\n");
printk("src mac %pM, dst mac %pM\n", eth->h_source, eth->h_dest);
printk("src IP addr:=%pI4\n", &ip_header->saddr);
return NF_ACCEPT;
}
static unsigned int hook_func_in(void *priv,
struct sk_buff *skb,
const struct nf_hook_state *state)
{
struct ethhdr *eth;
struct iphdr *ip_header;
eth = (struct ethhdr*)skb_mac_header(skb);
ip_header = (struct iphdr *)skb_network_header(skb);
if (LOCAL_IP_ADDR == ip_header->saddr)
return NF_ACCEPT;
printk("NF_IP_LOCAL_OUT hook:\n");
printk("src mac %pM, dst mac %pM\n", eth->h_source, eth->h_dest);
printk("src IP addr:=%pI4\n", &ip_header->saddr);
return NF_ACCEPT;
}
static int __init init_main(void)
{
nfin.hook = hook_func_in;
nfin.hooknum = 1; // NF_IP_LOCAL_IN // TODO
nfin.pf = PF_INET;
nfin.priority = NF_IP_PRI_FIRST;
nf_register_hook(&nfin);
nfout.hook = hook_func_out;
nfout.hooknum = 3; // NF_IP_LOCAL_OUT // TODO
nfout.pf = PF_INET;
nfout.priority = NF_IP_PRI_FIRST;
nf_register_hook(&nfout);
return 0;
}
static void __exit cleanup_main(void)
{
nf_unregister_hook(&nfin);
nf_unregister_hook(&nfout);
}
module_init(init_main);
module_exit(cleanup_main);
obj-m += ip_mac_packet_logger.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
install:
insmod ip_mac_packet_logger.ko
remove:
rmmod ip_mac_packet_logger.ko
@BugsBountyHunter
Copy link

BugsBountyHunter commented Mar 19, 2020

can you help me with what I do if I need to print packets like in Wireshark application?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment