]> git.ipfire.org Git - thirdparty/bird.git/blob - filter/f-util.c
Filters are now a tiny bit stronger (if is actually working ;-)
[thirdparty/bird.git] / filter / f-util.c
1 /*
2 * Filters: utility functions
3 *
4 * Copyright 1998 Pavel Machek <pavel@ucw.cz>
5 *
6 * Can be freely distributed and used under the terms of the GNU GPL.
7 */
8
9 #include <stdio.h>
10 #include <fcntl.h>
11 #include <unistd.h>
12 #include <sys/signal.h>
13
14 #include "nest/bird.h"
15 #include "lib/lists.h"
16 #include "lib/resource.h"
17 #include "lib/socket.h"
18 #include "nest/route.h"
19 #include "nest/protocol.h"
20 #include "nest/iface.h"
21 #include "conf/conf.h"
22 #include "filter/filter.h"
23
24 struct f_inst *last_func = NULL;
25
26 #define runtime die
27
28 static struct f_val
29 interpret(struct f_inst *what)
30 {
31 struct symbol *sym;
32 struct f_val v1, v2, res;
33
34 res.type = T_VOID;
35 if (!what)
36 return res;
37
38 switch(what->code) {
39 case ',':
40 interpret(what->arg1);
41 interpret(what->arg2);
42 break;
43 case '+':
44 v1 = interpret(what->arg1);
45 v2 = interpret(what->arg2);
46 if (v1.type != v2.type)
47 runtime( "Can not operate with values of incompatible types" );
48
49 switch (res.type = v1.type) {
50 case T_VOID: runtime( "Can not operate with values of type void" );
51 case T_INT: res.val.i = v1.val.i + v2.val.i; break;
52 default: runtime( "Usage of unknown type" );
53 }
54 break;
55 case '=':
56 v1 = interpret(what->arg2);
57 sym = what->arg1;
58 switch (res.type = v1.type) {
59 case T_VOID: runtime( "Can not assign void values" );
60 case T_INT:
61 if (sym->class != SYM_VARIABLE_INT)
62 runtime( "Variable of bad type" );
63 sym->aux = v1.val.i;
64 break;
65 }
66 break;
67 case 'c':
68 res.type = T_INT;
69 res.val.i = (int) what->arg1;
70 break;
71 case 'i':
72 res.type = T_INT;
73 res.val.i = * ((int *) what->arg1);
74 break;
75 case 'p':
76 v1 = interpret(what->arg1);
77 printf( "Printing: " );
78 switch (v1.type) {
79 case T_VOID: printf( "(void)" ); break;
80 case T_INT: printf( "%d", v1.val.i ); break;
81 default: runtime( "Print of variable of unknown type" );
82 }
83 printf( "\n" );
84 break;
85 case '?':
86 v1 = interpret(what->arg1);
87 if (v1.type != T_INT)
88 runtime( "If requires integer expression" );
89 if (v1.val.i)
90 res = interpret(what->arg2);
91 break;
92 case 'D':
93 printf( "DEBUGGING PRINT\n" );
94 break;
95 case '0':
96 printf( "No operation\n" );
97 break;
98 case 'd':
99 printf( "Puts: %s\n", what->arg1 );
100 break;
101 case '!':
102 die( "Filter asked me to die" );
103 default:
104 die( "Unknown insruction %d(%c)", what->code, what->code & 0xff);
105 }
106 if (what->next)
107 return interpret(what->next);
108 return res;
109 }
110
111 void
112 filters_postconfig(void)
113 {
114 if (!last_func)
115 printf( "No function defined\n" );
116 else {
117 interpret(last_func);
118 }
119 }
120
121 struct f_inst *
122 f_new_inst(void)
123 {
124 struct f_inst * ret;
125 ret = cfg_alloc(sizeof(struct f_inst));
126 ret->code = 0;
127 ret->arg1 = ret->arg2 = ret->next = NULL;
128 return ret;
129 }
130
131 int
132 f_run(struct symbol *filter, struct rte *rtein, struct rte **rteout)
133 {
134 struct f_inst *inst;
135 debug( "Running filter `%s'...", filter->name );
136
137 inst = filter->def;
138 interpret(inst);
139 debug( "done\n" );
140 return F_ACCEPT;
141 }