debuggers.hg

view xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/vfr.c @ 654:18c36f61f4cd

bitkeeper revision 1.345 (3f12be5aIxtVNJz4gdn0zwGqyPofFQ)

Merge labyrinth.cl.cam.ac.uk:/auto/groups/xeno/BK/xeno.bk
into labyrinth.cl.cam.ac.uk:/auto/anfs/scratch/labyrinth/iap10/xeno-clone/xeno.bk
author iap10@labyrinth.cl.cam.ac.uk
date Mon Jul 14 14:29:46 2003 +0000 (2003-07-14)
parents cda951fc1bef fc9e10724592
children
line source
1 /******************************************************************************
2 * vfr.c
3 *
4 * Interface to the virtual firewall/router.
5 *
6 */
8 #include <linux/config.h>
9 #include <linux/module.h>
10 #include <linux/kernel.h>
11 #include <linux/sched.h>
12 #include <linux/slab.h>
13 #include <linux/string.h>
14 #include <linux/errno.h>
15 #include <linux/proc_fs.h>
17 #include <asm/hypervisor-ifs/network.h>
19 static struct proc_dir_entry *proc_vfr;
21 static unsigned char readbuf[1024];
23 extern struct proc_dir_entry *xeno_base;
25 /* Helpers, implemented at the bottom. */
26 u32 getipaddr(const char *buff, unsigned int len);
27 u16 antous(const char *buff, int len);
28 int anton(const char *buff, int len);
30 static int vfr_read_proc(char *page, char **start, off_t off,
31 int count, int *eof, void *data)
32 {
33 strcpy(page, readbuf);
34 *readbuf = '\0';
35 *eof = 1;
36 *start = page;
37 return strlen(page);
38 }
40 /* The format for the vfr interface is as follows:
41 *
42 * COMMAND <field>=<val> [<field>=<val> [...]]
43 *
44 * where:
45 *
46 * COMMAND = { ACCEPT | COUNT }
47 *
48 * field=val pairs are as follows:
49 *
50 * field = { srcaddr | dstaddr }
51 * val is a dot seperated, numeric IP address.
52 *
53 * field = { srcport | dstport }
54 * val is a (16-bit) unsigned int
55 *
56 * field = { proto }
57 * val = { IP | TCP | UDP | ARP }
58 *
59 */
61 #define isspace(_x) ( ((_x)==' ') || ((_x)=='\t') || ((_x)=='\v') || \
62 ((_x)=='\f') || ((_x)=='\r') || ((_x)=='\n') )
64 static int vfr_write_proc(struct file *file, const char *buffer,
65 u_long count, void *data)
66 {
67 network_op_t op;
68 int ret, len;
69 int ts, te, tl; // token start, end, and length
70 int fs, fe, fl; // field.
72 len = count;
73 ts = te = 0;
75 memset(&op, 0, sizeof(network_op_t));
77 // get the command:
78 while ( count && isspace(buffer[ts]) ) { ts++; count--; } // skip spaces.
79 te = ts;
80 while ( count && !isspace(buffer[te]) ) { te++; count--; } // command end
81 if ( te <= ts ) goto bad;
82 tl = te - ts;
84 if ( strncmp(&buffer[ts], "ADD", tl) == 0 )
85 {
86 op.cmd = NETWORK_OP_ADDRULE;
87 }
88 else if ( strncmp(&buffer[ts], "DELETE", tl) == 0 )
89 {
90 op.cmd = NETWORK_OP_DELETERULE;
91 }
92 else if ( strncmp(&buffer[ts], "PRINT", tl) == 0 )
93 {
94 op.cmd = NETWORK_OP_GETRULELIST;
95 goto doneparsing;
96 }
98 ts = te;
100 // get the action
101 while ( count && (buffer[ts] == ' ') ) { ts++; count--; } // skip spaces.
102 te = ts;
103 while ( count && (buffer[te] != ' ') ) { te++; count--; } // command end
104 if ( te <= ts ) goto bad;
105 tl = te - ts;
107 if ( strncmp(&buffer[ts], "ACCEPT", tl) == 0 )
108 {
109 op.u.net_rule.action = NETWORK_ACTION_ACCEPT;
110 goto keyval;
111 }
112 if ( strncmp(&buffer[ts], "COUNT", tl) == 0 )
113 {
114 op.u.net_rule.action = NETWORK_ACTION_COUNT;
115 goto keyval;
116 }
118 // default case;
119 return (len);
122 // get the key=val pairs.
123 keyval:
124 while (count)
125 {
126 //get field
127 ts = te; while ( count && isspace(buffer[ts]) ) { ts++; count--; }
128 te = ts;
129 while ( count && !isspace(buffer[te]) && (buffer[te] != '=') )
130 { te++; count--; }
131 if ( te <= ts )
132 goto doneparsing;
133 tl = te - ts;
134 fs = ts; fe = te; fl = tl; // save the field markers.
135 // skip " = " (ignores extra equals.)
136 while ( count && (isspace(buffer[te]) || (buffer[te] == '=')) )
137 { te++; count--; }
138 ts = te;
139 while ( count && !isspace(buffer[te]) ) { te++; count--; }
140 tl = te - ts;
142 if ( (fl <= 0) || (tl <= 0) ) goto bad;
144 /* NB. Prefix matches must go first! */
145 if (strncmp(&buffer[fs], "src", fl) == 0)
146 {
147 op.u.net_rule.src_vif = VIF_ANY_INTERFACE;
148 }
149 else if (strncmp(&buffer[fs], "dst", fl) == 0)
150 {
151 op.u.net_rule.dst_vif = VIF_PHYSICAL_INTERFACE;
152 }
153 else if (strncmp(&buffer[fs], "srcaddr", fl) == 0)
154 {
155 op.u.net_rule.src_addr = getipaddr(&buffer[ts], tl);
156 }
157 else if (strncmp(&buffer[fs], "dstaddr", fl) == 0)
158 {
159 op.u.net_rule.dst_addr = getipaddr(&buffer[ts], tl);
160 }
161 else if (strncmp(&buffer[fs], "srcaddrmask", fl) == 0)
162 {
163 op.u.net_rule.src_addr_mask = getipaddr(&buffer[ts], tl);
164 }
165 else if (strncmp(&buffer[fs], "dstaddrmask", fl) == 0)
166 {
167 op.u.net_rule.dst_addr_mask = getipaddr(&buffer[ts], tl);
168 }
169 else if (strncmp(&buffer[fs], "srcport", fl) == 0)
170 {
171 op.u.net_rule.src_port = antous(&buffer[ts], tl);
172 }
173 else if (strncmp(&buffer[fs], "dstport", fl) == 0)
174 {
175 op.u.net_rule.dst_port = antous(&buffer[ts], tl);
176 }
177 else if (strncmp(&buffer[fs], "srcportmask", fl) == 0)
178 {
179 op.u.net_rule.src_port_mask = antous(&buffer[ts], tl);
180 }
181 else if (strncmp(&buffer[fs], "dstportmask", fl) == 0)
182 {
183 op.u.net_rule.dst_port_mask = antous(&buffer[ts], tl);
184 }
185 else if (strncmp(&buffer[fs], "srcdom", fl) == 0)
186 {
187 op.u.net_rule.src_vif |= anton(&buffer[ts], tl)<<VIF_DOMAIN_SHIFT;
188 }
189 else if (strncmp(&buffer[fs], "srcidx", fl) == 0)
190 {
191 op.u.net_rule.src_vif |= anton(&buffer[ts], tl);
192 }
193 else if (strncmp(&buffer[fs], "dstdom", fl) == 0)
194 {
195 op.u.net_rule.dst_vif |= anton(&buffer[ts], tl)<<VIF_DOMAIN_SHIFT;
196 }
197 else if (strncmp(&buffer[fs], "dstidx", fl) == 0)
198 {
199 op.u.net_rule.dst_vif |= anton(&buffer[ts], tl);
200 }
201 else if ( (strncmp(&buffer[fs], "proto", fl) == 0))
202 {
203 if (strncmp(&buffer[ts], "any", tl) == 0)
204 op.u.net_rule.proto = NETWORK_PROTO_ANY;
205 if (strncmp(&buffer[ts], "ip", tl) == 0)
206 op.u.net_rule.proto = NETWORK_PROTO_IP;
207 if (strncmp(&buffer[ts], "tcp", tl) == 0)
208 op.u.net_rule.proto = NETWORK_PROTO_TCP;
209 if (strncmp(&buffer[ts], "udp", tl) == 0)
210 op.u.net_rule.proto = NETWORK_PROTO_UDP;
211 if (strncmp(&buffer[ts], "arp", tl) == 0)
212 op.u.net_rule.proto = NETWORK_PROTO_ARP;
213 }
214 }
216 doneparsing:
217 ret = HYPERVISOR_network_op(&op);
218 return(len);
220 bad:
221 return(len);
224 }
226 static int __init init_module(void)
227 {
228 *readbuf = '\0';
229 proc_vfr = create_proc_entry ("vfr", 0600, xeno_base);
230 if ( proc_vfr != NULL )
231 {
232 proc_vfr->owner = THIS_MODULE;
233 proc_vfr->nlink = 1;
234 proc_vfr->read_proc = vfr_read_proc;
235 proc_vfr->write_proc = vfr_write_proc;
236 printk("Successfully installed virtual firewall/router interface\n");
237 }
238 return 0;
239 }
241 static void __exit cleanup_module(void)
242 {
243 if ( proc_vfr == NULL ) return;
244 remove_proc_entry("vfr", xeno_base);
245 proc_vfr = NULL;
246 }
248 module_init(init_module);
249 module_exit(cleanup_module);
251 /* Helper functions start here: */
253 int anton(const char *buff, int len)
254 {
255 int ret;
256 char c;
257 int sign = 1;
259 ret = 0;
261 if (len == 0) return 0;
262 if (*buff == '-') { sign = -1; buff++; len--; }
264 while ( (len) && ((c = *buff) >= '0') && (c <= '9') )
265 {
266 ret *= 10;
267 ret += c - '0';
268 buff++; len--;
269 }
271 ret *= sign;
272 return ret;
273 }
275 u16 antous(const char *buff, int len)
276 {
277 u16 ret;
278 char c;
280 ret = 0;
282 while ( (len) && ((c = *buff) >= '0') && (c <= '9') )
283 {
284 ret *= 10;
285 ret += c - '0';
286 buff++; len--;
287 }
289 return ret;
290 }
292 u32 getipaddr(const char *buff, unsigned int len)
293 {
294 char c;
295 u32 ret, val;
297 ret = 0; val = 0;
299 while ( len )
300 {
301 if (!((((c = *buff) >= '0') && ( c <= '9')) || ( c == '.' ) ) )
302 {
303 return(0); // malformed.
304 }
306 if ( c == '.' ) {
307 if (val > 255) return (0); //malformed.
308 ret = ret << 8;
309 ret += val;
310 val = 0;
311 len--; buff++;
312 continue;
313 }
314 val *= 10;
315 val += c - '0';
316 buff++; len--;
317 }
318 ret = ret << 8;
319 ret += val;
321 return (ret);
322 }