Typo
[transforward.git] / transforward.c
1 #include <linux/module.h>
2 #include <linux/moduleparam.h>
3 #include <linux/types.h>
4 #include <linux/kernel.h>
5 #include <linux/fs_struct.h>
6 #include <linux/fs.h>
7 #include <linux/mm.h>
8 #include <linux/reboot.h>
9 #include <linux/delay.h>
10 #include <linux/proc_fs.h>
11 #include <asm/uaccess.h>
12 #include <linux/sysrq.h>
13 #include <linux/timer.h>
14 #include <linux/time.h>
15 #include <linux/lglock.h>
16 #include <linux/init.h>
17 #include <linux/idr.h>
18 #include <linux/namei.h>
19 #include <linux/bitops.h>
20 #include <linux/mount.h>
21 #include <linux/dcache.h>
22 #include <linux/spinlock.h>
23 #include <linux/completion.h>
24 #include <linux/sched.h>
25 #include <linux/seq_file.h>
26 #include <linux/kprobes.h>
27 #include <linux/kallsyms.h>
28 #include <linux/nsproxy.h>
29 #include <net/sock.h>
30 #include <linux/inetdevice.h>
31
32 #define VERSION_STR "0.0.1"
33
34 #ifndef CONFIG_X86_64
35 #error "This code does not support your architecture"
36 #endif
37
38 MODULE_AUTHOR("Sapan Bhatia <sapanb@cs.princeton.edu>");
39 MODULE_DESCRIPTION("Transparent port forwarding for LXC.");
40 MODULE_LICENSE("GPL");
41 MODULE_VERSION(VERSION_STR);
42
43 static int address_in_root(unsigned int haddr) {
44     //printk(KERN_CRIT "In address_in_root: %u",haddr);
45     struct net_device *dev;
46     struct net *net = &init_net;
47
48     for_each_netdev(net, dev) {
49             unsigned int ifhaddr = inet_select_addr(dev,0,0);
50             //printk(KERN_CRIT "Checking address: %u",ifhaddr);
51             if (haddr == ifhaddr) return 1;
52     }
53     return 0;
54 }
55
56 static int inet_bind_entry(struct socket *sock, struct sockaddr *uaddr, int addr_len) {
57     struct sockaddr_in *addr = (struct sockaddr_in *)uaddr;
58     unsigned int snum = addr->sin_addr.s_addr;
59     if (address_in_root(snum)) {
60         put_net(sock_net(sock->sk));
61         sock_net_set(sock->sk, get_net(&init_net)); 
62         //printk(KERN_CRIT "Rewiring netns");
63     }
64     jprobe_return();
65     return 0;
66 }
67
68
69 static struct jprobe net_probe = {
70         .entry = (kprobe_opcode_t *) inet_bind_entry
71 };
72
73
74 static void __exit transforward_exit(void)
75 {
76         unregister_jprobe(&net_probe);
77         printk("Transforward: Stopped transforward.\n");
78 }
79
80
81
82 static int __init transforward_init(void)
83 {
84     int ret = 0;
85         printk("Transforward: starting transforward version %s.\n",
86                VERSION_STR);
87           net_probe.kp.addr = 
88                   (kprobe_opcode_t *) kallsyms_lookup_name("inet_bind");
89           if (!net_probe.kp.addr) {
90                   printk("Couldn't find %s to plant kretprobe\n", "inet_bind");
91                   return -1;
92           }
93   
94           if ((ret = register_jprobe(&net_probe)) <0) {
95                   printk("register_jprobe failed, returned %u\n", ret);
96                   return -1;
97           }
98           //printk("Planted jprobe at %p, handler addr %p\n",
99                  //net_probe.kp.addr, net_probe.entry);
100
101         return ret;
102 }
103
104 module_init(transforward_init);
105 module_exit(transforward_exit);