Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <linux/module.h> /* Needed by all modules */
- #include <linux/kernel.h> /* Needed for KERN_ALERT */
- #include <linux/netfilter.h>
- #include <linux/netfilter_ipv4.h>
- #include <linux/skbuff.h>
- #include <linux/compiler.h>
- #include <net/tcp.h>
- #include <linux/namei.h>
- #include <linux/proc_fs.h>
- #include <linux/slab.h>
- #include <asm/uaccess.h>
- #include <linux/list.h>
- MODULE_AUTHOR ("Eike Ritter <E.Ritter@cs.bham.ac.uk>");
- MODULE_DESCRIPTION ("Extensions to the firewall") ;
- MODULE_LICENSE("GPL");
- #define BUFFERLENGTH 256
- #define LIST_RULES 'L'
- #define PROC_ENTRY_FILENAME "firewallExtension"
- DECLARE_RWSEM(file_access); /* semaphore to protect counter access */
- static struct proc_dir_entry *Our_Proc_File;
- /* make IP4-addresses readable */
- #define NIPQUAD(addr) \
- ((unsigned char *)&addr)[0], \
- ((unsigned char *)&addr)[1], \
- ((unsigned char *)&addr)[2], \
- ((unsigned char *)&addr)[3]
- struct nf_hook_ops *reg;
- struct rules_list{
- char* rule;
- struct list_head list;
- };
- struct rules_list storedRules;
- //firewall part
- unsigned int FirewallExtensionHook (const struct nf_hook_ops *ops,
- struct sk_buff *skb,
- const struct net_device *in,
- const struct net_device *out,
- int (*okfn)(struct sk_buff *)) {
- struct tcphdr *tcp;
- struct tcphdr _tcph;
- struct sock *sk;
- sk = skb->sk;
- if (!sk) {
- printk (KERN_INFO "firewall: netfilter called with empty socket!\n");;
- return NF_ACCEPT;
- }
- if (sk->sk_protocol != IPPROTO_TCP) {
- printk (KERN_INFO "firewall: netfilter called with non-TCP-packet.\n");
- return NF_ACCEPT;
- }
- /* get the tcp-header for the packet */
- tcp = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(struct tcphdr), &_tcph);
- if (!tcp) {
- printk (KERN_INFO "Could not get tcp-header!\n");
- return NF_ACCEPT;
- }
- if (tcp->syn) {
- struct iphdr *ip;
- printk (KERN_INFO "firewall: Starting connection \n");
- ip = ip_hdr (skb);
- if (!ip) {
- printk (KERN_INFO "firewall: Cannot get IP header!\n!");
- }
- else {
- printk (KERN_INFO "firewall: Destination address = %u.%u.%u.%u\n", NIPQUAD(ip->daddr));
- }
- printk (KERN_INFO "firewall: destination port = %d\n", ntohs(tcp->dest));
- //check user context, check current process name
- //then check for rules
- if (in_irq() || in_softirq()) {
- printk (KERN_INFO "Not in user context - retry packet\n");
- return NF_ACCEPT;
- }
- if (ntohs (tcp->dest) == 80) {
- tcp_done (sk); /* terminate connection immediately */
- printk (KERN_INFO "Connection shut down\n");
- return NF_DROP;
- }
- }
- return NF_ACCEPT;
- }
- EXPORT_SYMBOL (FirewallExtensionHook);
- static struct nf_hook_ops firewallExtension_ops = {
- .hook = FirewallExtensionHook,
- .pf = PF_INET,
- .priority = NF_IP_PRI_FIRST,
- .hooknum = NF_INET_LOCAL_OUT
- };
- //interface part
- ssize_t kernelWrite (struct file *file, const char __user *buffer, size_t length, loff_t *offset) {
- int bytes_read = 0;
- struct rules_list* tmp;
- char* tempMsg;
- char* msgPtr;
- if(length <1){
- return -EINVAL;
- }
- printk(KERN_INFO "Length is %zu.\n",length);
- //get data - store in list
- //if L list
- //else add a rule
- tempMsg = (char*)kmalloc(length,GFP_KERNEL);
- msgPtr = tempMsg;
- while(length && bytes_read < BUFFERLENGTH){
- get_user(*(msgPtr++),buffer++);
- length--;
- bytes_read++;
- }
- // do a reset mechanic for new rule set L:
- printk(KERN_INFO "Added - %c.\n",tempMsg[0]);
- if(*tempMsg == 'L'){
- //print
- kfree(tempMsg);
- printk(KERN_INFO "WE FREE");
- }else{// doing L does below.. ?
- //assume its one line due to correct entry.
- tmp = (struct rules_list *)kmalloc(sizeof(struct rules_list),GFP_KERNEL);
- tmp->rule = tempMsg;
- down_write(&file_access);
- //create and add.
- list_add(&(tmp->list),&(storedRules.list));
- up_write(&file_access);
- printk(KERN_INFO "Added New Rule Succesfully");
- //printk(KERN_INFO *tempMsg);
- }
- printk(KERN_INFO "Read %d bytes.\n",bytes_read);
- return bytes_read;
- }
- int procfs_open(struct inode *inode, struct file *file)
- {
- printk (KERN_INFO "firewallExtension-PROCFS opened\n");
- try_module_get(THIS_MODULE);
- return 0;
- }
- int procfs_close(struct inode *inode, struct file *file)
- {
- printk (KERN_INFO "firewallExtension-PROCFS closed\n");
- module_put(THIS_MODULE);
- return 0; /* success */
- }
- const struct file_operations File_Ops_4_Our_Proc_File = {
- .owner = THIS_MODULE,
- .write = kernelWrite,
- .open = procfs_open,
- .release = procfs_close,
- };
- int init_module(void)
- {
- int errno;
- errno = nf_register_hook (&firewallExtension_ops); /* register the hook */
- if (errno) {
- printk (KERN_INFO "Firewall extension could not be registered!\n");
- }
- else {
- printk(KERN_INFO "Firewall extensions module loaded\n");
- }
- //procfile
- Our_Proc_File = proc_create_data (PROC_ENTRY_FILENAME, 0644, NULL, &File_Ops_4_Our_Proc_File, NULL);
- /* check if the /proc file was created successfuly */
- if (Our_Proc_File == NULL){
- printk(KERN_ALERT "Error: Could not initialize /proc/%s\n",
- PROC_ENTRY_FILENAME);
- return -ENOMEM;
- }
- printk(KERN_INFO "/proc/%s created\n", PROC_ENTRY_FILENAME);
- INIT_LIST_HEAD(&storedRules.list); // right or wrong?
- // A non 0 return means init_module failed; module can't be loaded.
- return errno;
- }
- void cleanup_module(void)
- {
- struct rules_list *tmp;
- struct list_head *pos,*q;
- remove_proc_entry(PROC_ENTRY_FILENAME, NULL);
- nf_unregister_hook (&firewallExtension_ops); /* restore everything to normal */
- printk(KERN_INFO "/proc/%s removed\n", PROC_ENTRY_FILENAME);
- //clean the list
- list_for_each_safe(pos,q,&storedRules.list){
- tmp =list_entry(pos,struct rules_list,list);
- list_del(pos);
- kfree(tmp->rule);
- kfree(tmp);
- }
- printk(KERN_INFO "Firewall extensions module unloaded\n");
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement