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