in f27, <asm/uaccess.h> uses struct task_struct, that is defined in <linux/sched.h>
[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 <linux/sched.h>
12 #include <asm/uaccess.h>
13 #include <linux/sysrq.h>
14 #include <linux/timer.h>
15 #include <linux/time.h>
16 /*#include <linux/lglock.h>*/
17 #include <linux/init.h>
18 #include <linux/idr.h>
19 #include <linux/namei.h>
20 #include <linux/bitops.h>
21 #include <linux/mount.h>
22 #include <linux/dcache.h>
23 #include <linux/spinlock.h>
24 #include <linux/completion.h>
25 #include <linux/sched.h>
26 #include <linux/seq_file.h>
27 #include <linux/kprobes.h>
28 #include <linux/kallsyms.h>
29 #include <linux/nsproxy.h>
30 #include <net/sock.h>
31 #include <linux/inetdevice.h>
32
33 #define VERSION_STR "0.0.1"
34
35 #ifndef CONFIG_X86_64
36 #error "This code does not support your architecture"
37 #endif
38
39 MODULE_AUTHOR("Sapan Bhatia <sapanb@cs.princeton.edu>");
40 MODULE_DESCRIPTION("Transparent port forwarding for LXC.");
41 MODULE_LICENSE("GPL");
42 MODULE_VERSION(VERSION_STR);
43
44 struct proc_dir_entry *proc_entry;
45
46 static int address_in_root(unsigned int haddr) {
47     struct net_device *dev;
48     struct net *net = &init_net;
49
50     for_each_netdev(net, dev) {
51             unsigned int ifhaddr = inet_select_addr(dev,0,0);
52             //printk(KERN_CRIT "Checking address: %u",ifhaddr);
53             if (haddr == ifhaddr) return 1;
54     }
55     return 0;
56 }
57
58 static int inet_bind_entry(struct socket *sock, struct sockaddr *uaddr, int addr_len) {
59     struct sockaddr_in *addr = (struct sockaddr_in *)uaddr;
60     unsigned int snum = addr->sin_addr.s_addr;
61         //printk(KERN_CRIT "Checking address %d",snum);
62     if (address_in_root(snum)) {
63         put_net(sock_net(sock->sk));
64         sock_net_set(sock->sk, get_net(&init_net)); 
65         //printk(KERN_CRIT "Rewiring netns");
66     }
67     jprobe_return();
68     return 0;
69 }
70
71 static struct file *do_last_probe(struct nameidata *nd, struct path *path,
72                          const struct open_flags *op, const char *pathname) {
73     
74     
75     jprobe_return();
76
77 }
78
79 static struct jprobe net_probe = {
80         .entry = (kprobe_opcode_t *) inet_bind_entry
81 };
82
83
84 static void __exit transforward_exit(void)
85 {
86         unregister_jprobe(&net_probe);
87         printk("Transforward: Stopped transforward.\n");
88 }
89
90 int once_only=0;
91
92 static int init_probes(void)
93 {
94     int ret = 0;
95         printk("Transforward: starting transforward version %s.\n",
96                VERSION_STR);
97           net_probe.kp.addr = 
98                   (kprobe_opcode_t *) kallsyms_lookup_name("inet_bind");
99           if (!net_probe.kp.addr) {
100                   printk("Couldn't find %s to plant kretprobe\n", "inet_bind");
101                   return -1;
102           }
103   
104           if ((ret = register_jprobe(&net_probe)) <0) {
105                   printk("register_jprobe failed, returned %u\n", ret);
106                   return -1;
107           }
108
109         return ret;
110 }
111
112 /*  as per http://www.tldp.org/LDP/lkmpg/2.4/html/c577.htm
113     the declaration of write in the file_operations struct reads:
114     ssize_t (*write) (struct file *, const char *, size_t, loff_t *);
115 */
116 ssize_t procfile_write(struct file *file, const char *buffer, size_t count, loff_t *data) {             
117         if (!once_only) {
118                 once_only=1;
119                 if (init_probes()==-1)
120                         printk(KERN_CRIT "Could not install procprotect probes. Reload module to retry.");
121                 else 
122                         printk(KERN_CRIT "Activated transforward module");
123         }
124     return count;
125 }
126 static const struct file_operations transforward_fops = {
127     .owner = THIS_MODULE,
128     .write = procfile_write
129 };
130
131 static int __init transforward_init(void)
132 {
133     int ret = 0;
134         printk("Transforward: starting transforward version %s.\n",
135                VERSION_STR);
136
137     proc_entry = proc_create("transforward", 0644, NULL, &transforward_fops);
138         return ret;
139 }
140
141 module_init(transforward_init);
142 module_exit(transforward_exit);