Create a "dfilter-int.h" file, containing stuff used internally to the
[obnox/wireshark/wip.git] / dfilter-grammar.y
1 %{
2
3 /* dfilter-grammar.y
4  * Parser for display filters
5  *
6  * $Id: dfilter-grammar.y,v 1.8 1999/08/12 21:16:31 guy Exp $
7  *
8  * Ethereal - Network traffic analyzer
9  * By Gerald Combs <gerald@zing.org>
10  * Copyright 1998 Gerald Combs
11  *
12  * 
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  * 
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  * 
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
26  */
27
28 #define yylex dfilter_lex
29
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33
34 #ifdef HAVE_SYS_TYPES_H
35 # include <sys/types.h>
36 #endif
37
38 #ifdef HAVE_NETINET_IN_H
39 # include <netinet/in.h>
40 #endif
41
42 #ifndef __GLIB_H__
43 #include <glib.h>
44 #endif
45
46 #include <string.h> /* during testing */
47
48 #ifndef _STDLIB_H
49 #include <stdlib.h>
50 #endif
51
52 #ifndef __PROTO_H__
53 #include "proto.h"
54 #endif
55
56 #ifndef __PACKET_H__
57 #include "packet.h"
58 #endif
59
60 #ifndef __DFILTER_H__
61 #include "dfilter.h"
62 #endif
63
64 #include "dfilter-int.h"
65
66 #ifndef __RESOLV_H__
67 #include "resolv.h"
68 #endif
69
70 void dfilter_yacc_init(void);
71 static GNode* dfilter_mknode_join(GNode *n1, enum node_type ntype, int operand, GNode *n2);
72 static GNode* dfilter_mknode_unary(int operand, GNode *n2);
73 static GNode* dfilter_mknode_numeric_variable(gint id);
74 static GNode* dfilter_mknode_numeric_value(guint32 val);
75 static GNode* dfilter_mknode_ether_value(guint8*);
76 static GNode* dfilter_mknode_ether_variable(gint id);
77 static GNode* dfilter_mknode_ipxnet_value(guint32);
78 static GNode* dfilter_mknode_ipxnet_variable(gint id);
79 static GNode* dfilter_mknode_ipv4_value(char *host);
80 static GNode* dfilter_mknode_ipv4_variable(gint id);
81 static GNode* dfilter_mknode_existence(gint id);
82 static GNode* dfilter_mknode_bytes_value(GByteArray *barray);
83 static GNode* dfilter_mknode_bytes_variable(gint id, gint offset, guint length);
84 static GNode* dfilter_mknode_boolean_value(gint truth_value);
85 static GNode* dfilter_mknode_boolean_variable(gint id);
86
87 static guint32 string_to_value(char *s);
88
89 /* space for dfilter_nodes */
90 GMemChunk *gmc_dfilter_nodes = NULL;
91
92 /* this is how we pass display filter tree (dfcode) back to calling routine */
93 GNode *dfilter_tree = NULL;
94
95 /* list of byte arrays we allocate during parse. We can traverse this list
96  * faster than the tree when we go back and free the byte arrays */
97 GSList *dfilter_list_byte_arrays = NULL;
98
99 %}
100
101 %union {
102         gint            operand;        /* logical, relation, alternation */
103         gint            variable;
104         GNode*          node;
105         gchar*          id;
106         GByteArray*     bytes;
107         guint8          ether[6];
108         struct {
109                 gint    offset;
110                 guint   length;
111         } byte_range;
112 }
113
114 %type <node>    statement expression relation
115 %type <node>    numeric_value numeric_variable
116 %type <node>    ether_value ether_variable
117 %type <node>    ipxnet_value ipxnet_variable
118 %type <node>    ipv4_value ipv4_variable
119 %type <node>    variable_name
120 %type <node>    bytes_value bytes_variable
121 %type <node>    boolean_value boolean_variable
122
123 %type <operand> numeric_relation
124 %type <operand> equality_relation
125 %type <operand> bytes_relation
126
127 %type <variable>        any_variable_type
128
129 %token <variable>       T_FT_UINT8
130 %token <variable>       T_FT_UINT16
131 %token <variable>       T_FT_UINT32
132 %token <variable>       T_FT_ETHER
133 %token <variable>       T_FT_IPv4
134 %token <variable>       T_FT_NONE
135 %token <variable>       T_FT_BYTES
136 %token <variable>       T_FT_BOOLEAN
137 %token <variable>       T_FT_STRING
138 %token <variable>       T_FT_IPXNET
139
140 %token <id>             T_VAL_UNQUOTED_STRING
141 %token <ether>          T_VAL_ETHER
142 %token <bytes>          T_VAL_BYTES
143 %token <byte_range>     T_VAL_BYTE_RANGE
144
145 %token <operand>        TOK_AND TOK_OR TOK_NOT TOK_XOR
146 %token <operand>        TOK_EQ TOK_NE TOK_GT TOK_GE TOK_LT TOK_LE
147 %token <operand>        TOK_TRUE TOK_FALSE
148
149 %left TOK_AND
150 %left TOK_OR
151 %left TOK_XOR
152 %nonassoc TOK_NOT
153
154 %%
155
156 statement: expression
157                 {
158                         dfilter_tree = $1;
159                 }
160         |       /* NULL */ { dfilter_tree = NULL; }
161         ;
162
163 expression:     '(' expression ')' { $$ = $2; }
164         |       expression TOK_AND expression { $$ = dfilter_mknode_join($1, logical, $2, $3); }
165         |       expression TOK_OR expression { $$ = dfilter_mknode_join($1, logical, $2, $3); }
166         |       expression TOK_XOR expression { $$ = dfilter_mknode_join($1, logical, $2, $3); }
167         |       TOK_NOT expression { $$ = dfilter_mknode_unary(TOK_NOT, $2); }
168         |       relation { $$ = $1; }
169         |       variable_name { $$ = $1; }
170         ;
171
172 relation:       numeric_variable numeric_relation numeric_value
173                 {
174                         $$ = dfilter_mknode_join($1, relation, $2, $3);
175                 }
176         |       numeric_variable numeric_relation numeric_variable
177                 {
178                         $$ = dfilter_mknode_join($1, relation, $2, $3);
179                 }
180
181         |       ether_variable equality_relation ether_value
182                 {
183                         $$ = dfilter_mknode_join($1, relation, $2, $3);
184                 }
185         |       ether_variable equality_relation ether_variable
186                 {
187                         $$ = dfilter_mknode_join($1, relation, $2, $3);
188                 }
189
190         |       ipxnet_variable equality_relation ipxnet_value
191                 {
192                         $$ = dfilter_mknode_join($1, relation, $2, $3);
193                 }
194         |       ipxnet_variable equality_relation ipxnet_variable
195                 {
196                         $$ = dfilter_mknode_join($1, relation, $2, $3);
197                 }
198
199
200         |       ipv4_variable numeric_relation ipv4_value
201                 {
202                         $$ = dfilter_mknode_join($1, relation, $2, $3);
203                 }
204         |       ipv4_variable numeric_relation ipv4_variable
205                 {
206                         $$ = dfilter_mknode_join($1, relation, $2, $3);
207                 }
208
209         |       bytes_variable bytes_relation bytes_value
210                 {
211                         $$ = dfilter_mknode_join($1, relation, $2, $3);
212                 }
213         |       bytes_variable bytes_relation bytes_variable
214                 {
215                         $$ = dfilter_mknode_join($1, relation, $2, $3);
216                 }
217
218         |       boolean_variable equality_relation boolean_value
219                 {
220                         $$ = dfilter_mknode_join($1, relation, $2, $3);
221                 }
222         |       boolean_variable equality_relation boolean_variable
223                 {
224                         $$ = dfilter_mknode_join($1, relation, $2, $3);
225                 }
226
227         ;
228
229
230 numeric_value:  T_VAL_UNQUOTED_STRING
231         {
232                 $$ = dfilter_mknode_numeric_value(string_to_value($1));
233                 g_free($1);
234          }
235         ;
236
237 ether_value:    T_VAL_ETHER
238                 {
239                         $$ = dfilter_mknode_ether_value($1);
240                 }
241         ;
242
243 ipxnet_value:   T_VAL_UNQUOTED_STRING
244                 {
245                         $$ = dfilter_mknode_ipxnet_value(string_to_value($1));
246                 }
247         ;
248
249 ipv4_value:     T_VAL_UNQUOTED_STRING
250         {
251                 $$ = dfilter_mknode_ipv4_value($1);
252                 g_free($1);
253         }
254         ;
255
256 bytes_value:    T_VAL_BYTES
257         {                                                               /* 2 - 5, or > 6 bytes */
258                  $$ = dfilter_mknode_bytes_value($1);
259         }
260
261         |       T_VAL_UNQUOTED_STRING
262         {                                                               /* one or 4 bytes */
263                 GByteArray      *barray;
264
265                 /* the next function appends to dfilter_list_byte_arrays for me */
266                 barray = byte_str_to_guint8_array($1);
267                 $$ = dfilter_mknode_bytes_value(barray);
268                 g_free($1);
269         }
270
271         |       T_VAL_ETHER
272         {                                                               /* 6 bytes */
273                 GByteArray      *barray = g_byte_array_new();
274
275                 dfilter_list_byte_arrays = g_slist_append(dfilter_list_byte_arrays, barray);
276                 g_byte_array_append(barray, $1, 6);
277                 $$ = dfilter_mknode_bytes_value(barray);
278         }
279         ;
280
281
282 boolean_value:  TOK_TRUE                { $$ = dfilter_mknode_boolean_value($1); }
283         |       TOK_FALSE               { $$ = dfilter_mknode_boolean_value($1); }
284         ;
285
286
287 numeric_variable:       T_FT_UINT8      { $$ = dfilter_mknode_numeric_variable($1); }
288         |               T_FT_UINT16     { $$ = dfilter_mknode_numeric_variable($1); }
289         |               T_FT_UINT32     { $$ = dfilter_mknode_numeric_variable($1); }
290         ;
291
292 ether_variable:         T_FT_ETHER      { $$ = dfilter_mknode_ether_variable($1); }
293         ;
294
295 ipxnet_variable:        T_FT_IPXNET     { $$ = dfilter_mknode_ipxnet_variable($1); }
296         ;
297
298 ipv4_variable:          T_FT_IPv4       { $$ = dfilter_mknode_ipv4_variable($1); }
299         ;
300
301 variable_name:          any_variable_type       { $$ = dfilter_mknode_existence($1); }
302         ;
303
304 bytes_variable:         any_variable_type T_VAL_BYTE_RANGE
305                 {
306                         $$ = dfilter_mknode_bytes_variable($1, $2.offset, $2.length);
307                 }
308         ;
309
310 boolean_variable:       T_FT_BOOLEAN    { $$ = dfilter_mknode_boolean_variable($1); }
311         ;
312
313 any_variable_type:      T_FT_UINT8 { $$ = $1; }
314         |               T_FT_UINT16 { $$ = $1; }
315         |               T_FT_UINT32 { $$ = $1; }
316         |               T_FT_ETHER { $$ = $1; }
317         |               T_FT_IPv4 { $$ = $1; }
318         |               T_FT_NONE { $$ = $1; }
319         |               T_FT_BYTES { $$ = $1; }
320         |               T_FT_BOOLEAN { $$ = $1; }
321         |               T_FT_STRING { $$ = $1; }
322         ;
323
324 numeric_relation:       TOK_EQ { $$ = TOK_EQ; }
325         |               TOK_NE { $$ = TOK_NE; }
326         |               TOK_GT { $$ = TOK_GT; }
327         |               TOK_GE { $$ = TOK_GE; }
328         |               TOK_LT { $$ = TOK_LT; }
329         |               TOK_LE { $$ = TOK_LE; }
330         ;
331
332 equality_relation:      TOK_EQ { $$ = TOK_EQ; }
333         |               TOK_NE { $$ = TOK_NE; }
334         ;
335
336 bytes_relation:         TOK_EQ { $$ = TOK_EQ; }
337         |               TOK_NE { $$ = TOK_NE; }
338         |               TOK_GT { $$ = TOK_GT; }
339         |               TOK_LT { $$ = TOK_LT; }
340         ;
341
342 %%
343
344 void
345 dfilter_yacc_init(void)
346 {
347         if (gmc_dfilter_nodes)
348                 g_mem_chunk_destroy(gmc_dfilter_nodes);
349
350         gmc_dfilter_nodes = g_mem_chunk_new("gmc_dfilter_nodes",
351                 sizeof(dfilter_node), 50 * sizeof(dfilter_node),
352                 G_ALLOC_ONLY);
353
354         if (dfilter_list_byte_arrays) {
355                 /* clear the byte arrays */
356                 g_slist_free(dfilter_list_byte_arrays);
357         }
358                 
359 }
360
361 void
362 dfilter_yacc_cleanup(void)
363 {
364         if (gmc_dfilter_nodes)
365                 g_mem_chunk_destroy(gmc_dfilter_nodes);
366 }
367
368
369 static GNode*
370 dfilter_mknode_join(GNode *n1, enum node_type ntype, int operand, GNode *n2)
371 {
372         dfilter_node    *node_root;
373         GNode           *gnode_root;
374
375         node_root = g_mem_chunk_alloc(gmc_dfilter_nodes);
376         node_root->ntype = ntype;
377         node_root->elem_size = 0;
378         node_root->fill_array_func = NULL;
379         node_root->check_relation_func = NULL;
380         if (ntype == relation) {
381                 node_root->value.relation = operand;
382         }
383         else if (ntype == logical) {
384                 node_root->value.logical = operand;
385         }
386         else {
387                 g_assert_not_reached();
388         }
389
390         gnode_root = g_node_new(node_root);
391         g_node_append(gnode_root, n1);
392         g_node_append(gnode_root, n2);
393
394         return gnode_root;
395 }
396
397 static GNode*
398 dfilter_mknode_unary(int operand, GNode *n2)
399 {
400         dfilter_node    *node_root;
401         GNode           *gnode_root;
402
403         node_root = g_mem_chunk_alloc(gmc_dfilter_nodes);
404         node_root->ntype = logical;
405         node_root->value.logical = operand;
406         node_root->elem_size = 0;
407         node_root->fill_array_func = NULL;
408         node_root->check_relation_func = NULL;
409
410         gnode_root = g_node_new(node_root);
411         g_node_append(gnode_root, n2);
412
413         return gnode_root;
414 }
415
416
417 static GNode*
418 dfilter_mknode_numeric_variable(gint id)
419 {
420         dfilter_node    *node;
421         GNode           *gnode;
422
423         node = g_mem_chunk_alloc(gmc_dfilter_nodes);
424         node->ntype = variable;
425         node->elem_size = sizeof(guint32);
426         node->fill_array_func = fill_array_numeric_variable;
427         node->check_relation_func = check_relation_numeric;
428         node->value.variable = id;
429         gnode = g_node_new(node);
430
431         return gnode;
432 }
433
434 static GNode*
435 dfilter_mknode_ether_variable(gint id)
436 {
437         dfilter_node    *node;
438         GNode           *gnode;
439
440         node = g_mem_chunk_alloc(gmc_dfilter_nodes);
441         node->ntype = variable;
442         node->elem_size = sizeof(guint8) * 6;
443         node->fill_array_func = fill_array_ether_variable;
444         node->check_relation_func = check_relation_ether;
445         node->value.variable = id;
446         gnode = g_node_new(node);
447
448         return gnode;
449 }
450
451 static GNode*
452 dfilter_mknode_ipxnet_variable(gint id)
453 {
454         dfilter_node    *node;
455         GNode           *gnode;
456
457         node = g_mem_chunk_alloc(gmc_dfilter_nodes);
458         node->ntype = variable;
459         node->elem_size = sizeof(guint8) * 4;
460         node->fill_array_func = fill_array_numeric_variable; /* cheating ! */
461         node->check_relation_func = check_relation_numeric; /* cheating ! */
462         node->value.variable = id;
463         gnode = g_node_new(node);
464
465         return gnode;
466 }
467
468 static GNode*
469 dfilter_mknode_ipv4_variable(gint id)
470 {
471         dfilter_node    *node;
472         GNode           *gnode;
473
474         node = g_mem_chunk_alloc(gmc_dfilter_nodes);
475         node->ntype = variable;
476         node->elem_size = sizeof(guint32);
477         node->fill_array_func = fill_array_numeric_variable; /* cheating ! */
478         node->check_relation_func = check_relation_numeric; /* cheating ! */
479         node->value.variable = id;
480         gnode = g_node_new(node);
481
482         return gnode;
483 }
484
485 static GNode*
486 dfilter_mknode_bytes_variable(gint id, gint offset, guint length)
487 {
488         dfilter_node    *node;
489         GNode           *gnode;
490
491         node = g_mem_chunk_alloc(gmc_dfilter_nodes);
492         node->ntype = variable;
493         node->elem_size = sizeof(GByteArray*);
494         node->fill_array_func = fill_array_bytes_variable;
495         node->check_relation_func = check_relation_bytes;
496         node->value.variable = id;
497         node->offset = offset;
498         node->length = length;
499         gnode = g_node_new(node);
500
501         return gnode;
502 }
503
504 static GNode*
505 dfilter_mknode_boolean_variable(gint id)
506 {
507         dfilter_node    *node;
508         GNode           *gnode;
509
510         node = g_mem_chunk_alloc(gmc_dfilter_nodes);
511         node->ntype = variable;
512         node->elem_size = sizeof(guint32);
513         node->fill_array_func = fill_array_boolean_variable; /* cheating ! */
514         node->check_relation_func = check_relation_boolean; /* cheating ! */
515         node->value.variable = id;
516         gnode = g_node_new(node);
517
518         return gnode;
519 }
520
521 static GNode*
522 dfilter_mknode_numeric_value(guint32 val)
523 {
524         dfilter_node    *node;
525         GNode           *gnode;
526
527         node = g_mem_chunk_alloc(gmc_dfilter_nodes);
528         node->ntype = numeric;
529         node->elem_size = sizeof(guint32);
530         node->fill_array_func = fill_array_numeric_value;
531         node->check_relation_func = check_relation_numeric;
532         node->value.numeric = val;
533         gnode = g_node_new(node);
534
535         return gnode;
536 }
537
538 static GNode*
539 dfilter_mknode_ether_value(guint8 *ether_bytes)
540 {
541         dfilter_node    *node;
542         GNode           *gnode;
543
544         node = g_mem_chunk_alloc(gmc_dfilter_nodes);
545         node->ntype = ether;
546         node->elem_size = sizeof(guint8) * 6;
547         node->fill_array_func = fill_array_ether_value;
548         node->check_relation_func = check_relation_ether;
549
550         memcpy(&node->value.ether, ether_bytes, 6);
551
552         gnode = g_node_new(node);
553         return gnode;
554 }
555
556 static GNode*
557 dfilter_mknode_ipxnet_value(guint32 ipx_net_val)
558 {
559         dfilter_node    *node;
560         GNode           *gnode;
561
562         node = g_mem_chunk_alloc(gmc_dfilter_nodes);
563         node->ntype = ipxnet;
564         node->elem_size = sizeof(guint8) * 4;
565         node->fill_array_func = fill_array_numeric_value; /* cheating ! */
566         node->check_relation_func = check_relation_numeric; /* cheating ! */
567         node->value.numeric = ipx_net_val;
568         gnode = g_node_new(node);
569
570         return gnode;
571 }
572
573 static GNode*
574 dfilter_mknode_ipv4_value(char *host)
575 {
576         dfilter_node    *node;
577         GNode           *gnode;
578
579         node = g_mem_chunk_alloc(gmc_dfilter_nodes);
580         node->ntype = numeric;
581         node->elem_size = sizeof(guint32);
582         node->fill_array_func = fill_array_numeric_value; /* cheating ! */
583         node->check_relation_func = check_relation_numeric; /* cheating ! */
584         node->value.numeric = get_host_ipaddr(host);
585         node->value.numeric = htonl(node->value.numeric);
586         gnode = g_node_new(node);
587
588         return gnode;
589 }
590
591 static GNode*
592 dfilter_mknode_bytes_value(GByteArray *barray)
593 {
594         dfilter_node    *node;
595         GNode           *gnode;
596
597         node = g_mem_chunk_alloc(gmc_dfilter_nodes);
598         node->ntype = bytes;
599         node->elem_size = sizeof(GByteArray*);
600         node->fill_array_func = fill_array_bytes_value;
601         node->check_relation_func = check_relation_bytes;
602         node->value.bytes = barray;
603         node->offset = G_MAXINT;
604         node->length = barray->len;
605         gnode = g_node_new(node);
606
607         return gnode;
608 }
609
610 static GNode*
611 dfilter_mknode_boolean_value(gint truth_value)
612 {
613         dfilter_node    *node;
614         GNode           *gnode;
615
616         node = g_mem_chunk_alloc(gmc_dfilter_nodes);
617         node->ntype = numeric;
618         node->elem_size = sizeof(guint32);
619         node->fill_array_func = fill_array_boolean_value;
620         node->check_relation_func = check_relation_boolean;
621         node->value.boolean = truth_value == TOK_TRUE ? TRUE : FALSE;
622         gnode = g_node_new(node);
623
624         return gnode;
625 }
626
627 static guint32
628 string_to_value(char *s)
629 {
630         char    *endptr;
631         guint32 val;
632
633         val = strtoul(s, &endptr, 0);
634         /* I should probably check errno here */
635
636         return (guint32)val;
637 }
638         
639 static GNode*
640 dfilter_mknode_existence(gint id)
641 {
642         dfilter_node    *node;
643         GNode           *gnode;
644
645         node = g_mem_chunk_alloc(gmc_dfilter_nodes);
646         node->ntype = existence;
647         node->elem_size = sizeof(guint32);
648         node->fill_array_func = NULL;
649         node->check_relation_func = NULL;
650         node->value.variable = id;
651         gnode = g_node_new(node);
652
653         return gnode;
654 }