#include /* Needed by all modules */ #include /* Needed for KERN_ALERT */ #include #include #include #include #include #include MODULE_AUTHOR ("Eike Ritter "); MODULE_DESCRIPTION ("Extensions to the firewall") ; MODULE_LICENSE("GPL"); struct nf_hook_ops *reg; unsigned int FirewallExtensionHook (unsigned int hooknum, struct sk_buff **skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) { struct sock *sk; struct dentry *dentry; struct vm_area_struct * vma; const unsigned char *filename = ""; struct inet_sock *inet; struct mm_struct *mm; sk = (*skb)->sk; if (!sk) { printk (KERN_INFO "firewall: netfilter called with empty socket!\n");; return NF_ACCEPT; } if (sk->sk_protocol == IPPROTO_UDP) { /* printk (KERN_INFO "firewall: netfilter called with UDP-packet.\n"); */ return NF_ACCEPT; } if (sk->sk_protocol != IPPROTO_TCP) { printk (KERN_INFO "firewall: netfilter called with non-TCP-non-UDP-packet.\n"); return NF_ACCEPT; } inet = inet_sk (sk); if (!inet) { printk (KERN_INFO "firewall: netfilter passed TCP-packet with bad header!\n"); return NF_ACCEPT; } if (!in_irq() && !in_softirq() && (mm = get_task_mm(current))) { /* now in user context, and virtual memory available */ down_read(&mm->mmap_sem); vma = mm->mmap; while (vma) { if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file) break; vma = vma->vm_next; } if (vma) { dentry = dget(vma->vm_file->f_dentry); /* Name of process calling the operation */ filename = dentry->d_name.name; } up_read(&mm->mmap_sem); mmput(mm); if (sk->sk_state == TCP_SYN_SENT) { printk (KERN_INFO "firewall: Starting connection \n"); printk (KERN_INFO "firewall: Socket created for file %s\n", filename); printk (KERN_INFO "firewall: Destination address = %u.%u.%u.%u, destination port = %d\n", NIPQUAD(inet->daddr), htons(inet->dport)); if (htons (inet->dport) == 80) { tcp_done (sk); /* terminate connection */ return NF_DROP; } } /* else { printk (KERN_INFO "firewall: TCP-socket for file %s\n", filename); printk (KERN_INFO "firewall: Destination address = %u.%u.%u.%u, destination port = %d\n", NIPQUAD(inet->daddr), htons(inet->dport)); } */ } /* else { printk (KERN_INFO "firewallElse: TCP-packet sent while not in user context\n"); } */ return NF_ACCEPT; } EXPORT_SYMBOL (FirewallExtensionHook); int init_module(void) { int errno; reg = kmalloc (sizeof (struct nf_hook_ops), GFP_KERNEL); if (!reg) { return -ENOMEM; } reg->hook = FirewallExtensionHook; reg->pf = PF_INET; reg->owner = THIS_MODULE; reg->hooknum = NF_IP_LOCAL_OUT; errno = nf_register_hook (reg); if (errno) { printk (KERN_INFO "Firewall extension could not be registered!\n"); kfree (reg); } else { printk(KERN_INFO "Firewall extensions module loaded\n"); } // A non 0 return means init_module failed; module can't be loaded. return errno; } void cleanup_module(void) { nf_unregister_hook (reg); kfree (reg); printk(KERN_INFO "Firewall extensions module unloaded\n"); }