Created
May 9, 2020 15:25
-
-
Save edubart/cf0fb63cadb7a2541ebf0e8c6073ddaf to your computer and use it in GitHub Desktop.
Network traffic entropy calculator in kernel
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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