Skip to content

Instantly share code, notes, and snippets.

@edubart
Created May 9, 2020 15:25
Show Gist options
  • Save edubart/cf0fb63cadb7a2541ebf0e8c6073ddaf to your computer and use it in GitHub Desktop.
Save edubart/cf0fb63cadb7a2541ebf0e8c6073ddaf to your computer and use it in GitHub Desktop.
Network traffic entropy calculator in kernel
#ifndef __KERNEL__
#define __KERNEL__
#endif
#ifndef MODULE
#define MODULE
#endif
#include <generated/autoconf.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/timer.h>
MODULE_AUTHOR("Eduardo Bart <[email protected]>");
MODULE_DESCRIPTION("Calculate traffic entropy");
MODULE_LICENSE("GPL");
#define MIN_PACKET_COUNT 100
#define MIN_THRESHOLD 400
unsigned int packet_count;
unsigned int bytes_count;
int per_byte_count[256];
struct timer_list check_timer;
int calculate_entropy(void)
{
long i, p, q, entropy;
if(bytes_count == 0)
return 0;
entropy = 0;
q = ilog2(bytes_count);
for(i=0;i<256;++i) {
p = per_byte_count[i];
if(p > 0) {
entropy -= p * (ilog2(p) - q);
}
}
entropy = (entropy * 1000) / (bytes_count * 8);
return entropy;
}
void check_entropy(unsigned long hz)
{
if(packet_count > MIN_PACKET_COUNT) {
int entropy = calculate_entropy();
printk("input traffic entropy: %d\n", entropy);
}
packet_count = 0;
bytes_count = 0;
memset(per_byte_count, 0, sizeof(per_byte_count));
mod_timer(&check_timer, jiffies + hz);
}
static unsigned int input_hook(unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
unsigned int i;
packet_count++;
bytes_count += skb->len;
for(i=0;i<skb->len;++i)
per_byte_count[(unsigned char)skb->data[i]]++;
return NF_ACCEPT;
}
static struct nf_hook_ops input_hook_reg __read_mostly = {
.hook = input_hook,
.pf = PF_INET,
.hooknum = NF_INET_LOCAL_IN,
.priority = NF_IP_PRI_FIRST
};
static int __init entropy_init(void)
{
nf_register_hook(&input_hook_reg);
setup_timer(&check_timer, check_entropy, msecs_to_jiffies(1000));
check_entropy(msecs_to_jiffies(1000));
printk(KERN_INFO "Successfully loaded entropy.\n");
return 0;
}
static void __exit entropy_exit(void)
{
del_timer(&check_timer);
nf_unregister_hook(&input_hook_reg);
printk(KERN_INFO "Successfully unloaded entropy.\n");
}
module_init(entropy_init);
module_exit(entropy_exit);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment