X-Git-Url: http://git.onelab.eu/?p=transforward.git;a=blobdiff_plain;f=transforward.c;fp=transforward.c;h=da61ceebb98062dfaf3af6a97339b06ecbdf24db;hp=0000000000000000000000000000000000000000;hb=71b2cf441369c34aff3033d39e1c79e27bc39eb4;hpb=9098a187a66c5b4854f08b71a4d7266aaa644e40 diff --git a/transforward.c b/transforward.c new file mode 100644 index 0000000..da61cee --- /dev/null +++ b/transforward.c @@ -0,0 +1,105 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define VERSION_STR "0.0.1" + +#ifndef CONFIG_X86_64 +#error "This code does not support your architecture" +#endif + +MODULE_AUTHOR("Sapan Bhatia "); +MODULE_DESCRIPTION("Transparent port forwarding for LXC."); +MODULE_LICENSE("GPL"); +MODULE_VERSION(VERSION_STR); + +static int address_in_root(unsigned int haddr) { + printk(KERN_CRIT "In address_in_root: %d",haddr); + struct net_device *dev; + struct net *net = &init_net; + + for_each_netdev(net, dev) { + unsigned int ifhaddr = inet_select_addr(dev,0,0); + printk(KERN_CRIT "Checking address: %d",ifhaddr); + if (haddr == ifhaddr) return 1; + } + return 0; +} + +static int inet_bind_entry(struct socket *sock, struct sockaddr *uaddr, int addr_len) { + struct sockaddr_in *addr = (struct sockaddr_in *)uaddr; + unsigned int snum = ntohs(addr->sin_addr.s_addr); + if (address_in_root(snum)) { + put_net(sock_net(sock->sk)); + sock_net_set(sock->sk, get_net(&init_net)); + printk(KERN_CRIT "Rewiring netns"); + } + jprobe_return(); + return 0; +} + + +static struct jprobe net_probe = { + .entry = (kprobe_opcode_t *) inet_bind_entry +}; + + +static void __exit transforward_exit(void) +{ + unregister_jprobe(&net_probe); + printk("Transforward: Stopped transforward.\n"); +} + + + +static int __init transforward_init(void) +{ + int ret = 0; + printk("Transforward: starting transforward version %s.\n", + VERSION_STR); + net_probe.kp.addr = + (kprobe_opcode_t *) kallsyms_lookup_name("inet_bind"); + if (!net_probe.kp.addr) { + printk("Couldn't find %s to plant kretprobe\n", "inet_bind"); + return -1; + } + + if ((ret = register_jprobe(&net_probe)) <0) { + printk("register_jprobe failed, returned %d\n", ret); + return -1; + } + printk("Planted jprobe at %p, handler addr %p\n", + net_probe.kp.addr, net_probe.entry); + + return ret; +} + +module_init(transforward_init); +module_exit(transforward_exit);