c8ab1c54b8d3e2ff45bd76f7b844cd3eb6e8edd3
[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.14 1999/08/20 21:19:27 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 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31
32 #ifdef HAVE_SYS_TYPES_H
33 # include <sys/types.h>
34 #endif
35
36 #ifdef HAVE_NETINET_IN_H
37 # include <netinet/in.h>
38 #endif
39
40 #ifdef NEED_SNPRINTF_H
41 # ifdef HAVE_STDARG_H
42 #  include <stdarg.h>
43 # else
44 #  include <varargs.h>
45 # endif
46 # include "snprintf.h"
47 #endif
48
49 #ifndef __GLIB_H__
50 #include <glib.h>
51 #endif
52
53 #include <string.h>
54
55 #ifndef _STDLIB_H
56 #include <stdlib.h>
57 #endif
58
59 #ifndef __PROTO_H__
60 #include "proto.h"
61 #endif
62
63 #ifndef __PACKET_H__
64 #include "packet.h"
65 #endif
66
67 #ifndef __DFILTER_H__
68 #include "dfilter.h"
69 #endif
70
71 #include "dfilter-int.h"
72
73 #ifndef __RESOLV_H__
74 #include "resolv.h"
75 #endif
76
77 static GNode* dfilter_mknode_join(GNode *n1, enum node_type ntype, int operand, GNode *n2);
78 static GNode* dfilter_mknode_unary(int operand, GNode *n2);
79 static GNode* dfilter_mknode_numeric_variable(gint id);
80 static GNode* dfilter_mknode_numeric_value(guint32 val);
81 static GNode* dfilter_mknode_ether_value(gchar*);
82 static GNode* dfilter_mknode_ether_variable(gint id);
83 static GNode* dfilter_mknode_ipxnet_value(guint32);
84 static GNode* dfilter_mknode_ipxnet_variable(gint id);
85 static GNode* dfilter_mknode_ipv4_value(char *host);
86 static GNode* dfilter_mknode_ipv4_variable(gint id);
87 static GNode* dfilter_mknode_existence(gint id);
88 static GNode* dfilter_mknode_bytes_value(GByteArray *barray);
89 static GNode* dfilter_mknode_bytes_variable(gint id, gint offset, guint length);
90 static GNode* dfilter_mknode_boolean_value(gint truth_value);
91 static GNode* dfilter_mknode_boolean_variable(gint id);
92
93 static guint32 string_to_value(char *s);
94 static int ether_str_to_guint8_array(const char *s, guint8 *mac);
95
96 /* This is the dfilter we're currently processing. It's how
97  * dfilter_compile communicates with us.
98  */
99 dfilter *global_df = NULL;;
100
101 %}
102
103 %union {
104         gint            operand;        /* logical, relation, alternation */
105         gint            variable;
106         GNode*          node;
107         gchar*          string;
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 <string>         T_VAL_UNQUOTED_STRING
141 %token <string>         T_VAL_BYTE_STRING
142 %token <string>         T_VAL_NUMBER_STRING
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                         global_df->dftree = $1;
159                 }
160         |       /* NULL */ { global_df->dftree = 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_NUMBER_STRING
231         {
232                 $$ = dfilter_mknode_numeric_value(string_to_value($1));
233                 g_free($1);
234          }
235         ;
236
237 ether_value:    T_VAL_BYTE_STRING
238         {
239                 $$ = dfilter_mknode_ether_value($1);
240                 g_free($1);
241                 if ($$ == NULL) {
242                         YYERROR;
243                 }
244         }
245         ;
246
247 ipxnet_value:   T_VAL_NUMBER_STRING
248         {
249                 $$ = dfilter_mknode_ipxnet_value(string_to_value($1));
250                 g_free($1);
251         }
252         ;
253
254 ipv4_value:     T_VAL_UNQUOTED_STRING
255                 {
256                         $$ = dfilter_mknode_ipv4_value($1);
257                         g_free($1);
258                 }
259
260         |       T_VAL_BYTE_STRING
261                 {
262                         $$ = dfilter_mknode_ipv4_value($1);
263                         g_free($1);
264                 }
265         ;
266
267 bytes_value:    T_VAL_BYTE_STRING
268         {
269                 GByteArray      *barray;
270
271                 /* the next function appends to list_of_byte_arrays for me */
272                 barray = byte_str_to_guint8_array($1);
273                 $$ = dfilter_mknode_bytes_value(barray);
274                 g_free($1);
275         }
276         ;
277
278
279 boolean_value:  TOK_TRUE                { $$ = dfilter_mknode_boolean_value($1); }
280         |       TOK_FALSE               { $$ = dfilter_mknode_boolean_value($1); }
281         ;
282
283
284 numeric_variable:       T_FT_UINT8      { $$ = dfilter_mknode_numeric_variable($1); }
285         |               T_FT_UINT16     { $$ = dfilter_mknode_numeric_variable($1); }
286         |               T_FT_UINT32     { $$ = dfilter_mknode_numeric_variable($1); }
287         ;
288
289 ether_variable:         T_FT_ETHER      { $$ = dfilter_mknode_ether_variable($1); }
290         ;
291
292 ipxnet_variable:        T_FT_IPXNET     { $$ = dfilter_mknode_ipxnet_variable($1); }
293         ;
294
295 ipv4_variable:          T_FT_IPv4       { $$ = dfilter_mknode_ipv4_variable($1); }
296         ;
297
298 variable_name:          any_variable_type       { $$ = dfilter_mknode_existence($1); }
299         ;
300
301 bytes_variable:         any_variable_type T_VAL_BYTE_RANGE
302                 {
303                         $$ = dfilter_mknode_bytes_variable($1, $2.offset, $2.length);
304                 }
305         ;
306
307 boolean_variable:       T_FT_BOOLEAN    { $$ = dfilter_mknode_boolean_variable($1); }
308         ;
309
310 any_variable_type:      T_FT_UINT8 { $$ = $1; }
311         |               T_FT_UINT16 { $$ = $1; }
312         |               T_FT_UINT32 { $$ = $1; }
313         |               T_FT_ETHER { $$ = $1; }
314         |               T_FT_IPv4 { $$ = $1; }
315         |               T_FT_NONE { $$ = $1; }
316         |               T_FT_BYTES { $$ = $1; }
317         |               T_FT_BOOLEAN { $$ = $1; }
318         |               T_FT_STRING { $$ = $1; }
319         ;
320
321 numeric_relation:       TOK_EQ { $$ = TOK_EQ; }
322         |               TOK_NE { $$ = TOK_NE; }
323         |               TOK_GT { $$ = TOK_GT; }
324         |               TOK_GE { $$ = TOK_GE; }
325         |               TOK_LT { $$ = TOK_LT; }
326         |               TOK_LE { $$ = TOK_LE; }
327         ;
328
329 equality_relation:      TOK_EQ { $$ = TOK_EQ; }
330         |               TOK_NE { $$ = TOK_NE; }
331         ;
332
333 bytes_relation:         TOK_EQ { $$ = TOK_EQ; }
334         |               TOK_NE { $$ = TOK_NE; }
335         |               TOK_GT { $$ = TOK_GT; }
336         |               TOK_LT { $$ = TOK_LT; }
337         ;
338
339 %%
340
341 static GNode*
342 dfilter_mknode_join(GNode *n1, enum node_type ntype, int operand, GNode *n2)
343 {
344         dfilter_node    *node_root;
345         GNode           *gnode_root;
346
347         node_root = g_mem_chunk_alloc(global_df->node_memchunk);
348         node_root->ntype = ntype;
349         node_root->elem_size = 0;
350         node_root->fill_array_func = NULL;
351         node_root->check_relation_func = NULL;
352         if (ntype == relation) {
353                 node_root->value.relation = operand;
354         }
355         else if (ntype == logical) {
356                 node_root->value.logical = operand;
357         }
358         else {
359                 g_assert_not_reached();
360         }
361
362         gnode_root = g_node_new(node_root);
363         g_node_append(gnode_root, n1);
364         g_node_append(gnode_root, n2);
365
366         return gnode_root;
367 }
368
369 static GNode*
370 dfilter_mknode_unary(int operand, GNode *n2)
371 {
372         dfilter_node    *node_root;
373         GNode           *gnode_root;
374
375         node_root = g_mem_chunk_alloc(global_df->node_memchunk);
376         node_root->ntype = logical;
377         node_root->value.logical = operand;
378         node_root->elem_size = 0;
379         node_root->fill_array_func = NULL;
380         node_root->check_relation_func = NULL;
381
382         gnode_root = g_node_new(node_root);
383         g_node_append(gnode_root, n2);
384
385         return gnode_root;
386 }
387
388
389 static GNode*
390 dfilter_mknode_numeric_variable(gint id)
391 {
392         dfilter_node    *node;
393         GNode           *gnode;
394
395         node = g_mem_chunk_alloc(global_df->node_memchunk);
396         node->ntype = variable;
397         node->elem_size = sizeof(guint32);
398         node->fill_array_func = fill_array_numeric_variable;
399         node->check_relation_func = check_relation_numeric;
400         node->value.variable = id;
401         gnode = g_node_new(node);
402
403         return gnode;
404 }
405
406 static GNode*
407 dfilter_mknode_ether_variable(gint id)
408 {
409         dfilter_node    *node;
410         GNode           *gnode;
411
412         node = g_mem_chunk_alloc(global_df->node_memchunk);
413         node->ntype = variable;
414         node->elem_size = sizeof(guint8) * 6;
415         node->fill_array_func = fill_array_ether_variable;
416         node->check_relation_func = check_relation_ether;
417         node->value.variable = id;
418         gnode = g_node_new(node);
419
420         return gnode;
421 }
422
423 static GNode*
424 dfilter_mknode_ipxnet_variable(gint id)
425 {
426         dfilter_node    *node;
427         GNode           *gnode;
428
429         node = g_mem_chunk_alloc(global_df->node_memchunk);
430         node->ntype = variable;
431         node->elem_size = sizeof(guint8) * 4;
432         node->fill_array_func = fill_array_numeric_variable; /* cheating ! */
433         node->check_relation_func = check_relation_numeric; /* cheating ! */
434         node->value.variable = id;
435         gnode = g_node_new(node);
436
437         return gnode;
438 }
439
440 static GNode*
441 dfilter_mknode_ipv4_variable(gint id)
442 {
443         dfilter_node    *node;
444         GNode           *gnode;
445
446         node = g_mem_chunk_alloc(global_df->node_memchunk);
447         node->ntype = variable;
448         node->elem_size = sizeof(guint32);
449         node->fill_array_func = fill_array_numeric_variable; /* cheating ! */
450         node->check_relation_func = check_relation_numeric; /* cheating ! */
451         node->value.variable = id;
452         gnode = g_node_new(node);
453
454         return gnode;
455 }
456
457 static GNode*
458 dfilter_mknode_bytes_variable(gint id, gint offset, guint length)
459 {
460         dfilter_node    *node;
461         GNode           *gnode;
462
463         node = g_mem_chunk_alloc(global_df->node_memchunk);
464         node->ntype = variable;
465         node->elem_size = sizeof(GByteArray*);
466         node->fill_array_func = fill_array_bytes_variable;
467         node->check_relation_func = check_relation_bytes;
468         node->value.variable = id;
469         node->offset = offset;
470         node->length = length;
471         gnode = g_node_new(node);
472
473         return gnode;
474 }
475
476 static GNode*
477 dfilter_mknode_boolean_variable(gint id)
478 {
479         dfilter_node    *node;
480         GNode           *gnode;
481
482         node = g_mem_chunk_alloc(global_df->node_memchunk);
483         node->ntype = variable;
484         node->elem_size = sizeof(guint32);
485         node->fill_array_func = fill_array_boolean_variable; /* cheating ! */
486         node->check_relation_func = check_relation_boolean; /* cheating ! */
487         node->value.variable = id;
488         gnode = g_node_new(node);
489
490         return gnode;
491 }
492
493 static GNode*
494 dfilter_mknode_numeric_value(guint32 val)
495 {
496         dfilter_node    *node;
497         GNode           *gnode;
498
499         node = g_mem_chunk_alloc(global_df->node_memchunk);
500         node->ntype = numeric;
501         node->elem_size = sizeof(guint32);
502         node->fill_array_func = fill_array_numeric_value;
503         node->check_relation_func = check_relation_numeric;
504         node->value.numeric = val;
505         gnode = g_node_new(node);
506
507         return gnode;
508 }
509
510 /* Returns NULL on bad parse of ETHER value */
511 static GNode*
512 dfilter_mknode_ether_value(gchar *byte_string)
513 {
514         dfilter_node    *node;
515         GNode           *gnode;
516
517         node = g_mem_chunk_alloc(global_df->node_memchunk);
518         node->ntype = ether;
519         node->elem_size = sizeof(guint8) * 6;
520         node->fill_array_func = fill_array_ether_value;
521         node->check_relation_func = check_relation_ether;
522
523         if (!ether_str_to_guint8_array(byte_string, &node->value.ether[0])) {
524                 /* Rather than free the mem_chunk allocation, let it
525                  * stay. It will be cleaned up in the next call to
526                  * dfilter_clear() */
527                 dfilter_error_msg = &dfilter_error_msg_buf[0];
528                 snprintf(dfilter_error_msg, sizeof(dfilter_error_msg_buf),
529                         "\"%s\" is not a valid hardware address.", byte_string);
530                 return NULL;
531         }
532
533         gnode = g_node_new(node);
534         return gnode;
535 }
536
537 static GNode*
538 dfilter_mknode_ipxnet_value(guint32 ipx_net_val)
539 {
540         dfilter_node    *node;
541         GNode           *gnode;
542
543         node = g_mem_chunk_alloc(global_df->node_memchunk);
544         node->ntype = ipxnet;
545         node->elem_size = sizeof(guint8) * 4;
546         node->fill_array_func = fill_array_numeric_value; /* cheating ! */
547         node->check_relation_func = check_relation_numeric; /* cheating ! */
548         node->value.numeric = ipx_net_val;
549         gnode = g_node_new(node);
550
551         return gnode;
552 }
553
554 static GNode*
555 dfilter_mknode_ipv4_value(char *host)
556 {
557         dfilter_node    *node;
558         GNode           *gnode;
559
560         node = g_mem_chunk_alloc(global_df->node_memchunk);
561         node->ntype = numeric;
562         node->elem_size = sizeof(guint32);
563         node->fill_array_func = fill_array_numeric_value; /* cheating ! */
564         node->check_relation_func = check_relation_numeric; /* cheating ! */
565         node->value.numeric = get_host_ipaddr(host);
566         node->value.numeric = htonl(node->value.numeric);
567         gnode = g_node_new(node);
568
569         return gnode;
570 }
571
572 static GNode*
573 dfilter_mknode_bytes_value(GByteArray *barray)
574 {
575         dfilter_node    *node;
576         GNode           *gnode;
577
578         node = g_mem_chunk_alloc(global_df->node_memchunk);
579         node->ntype = bytes;
580         node->elem_size = sizeof(GByteArray*);
581         node->fill_array_func = fill_array_bytes_value;
582         node->check_relation_func = check_relation_bytes;
583         node->value.bytes = barray;
584         node->offset = G_MAXINT;
585         node->length = barray->len;
586         gnode = g_node_new(node);
587
588         return gnode;
589 }
590
591 static GNode*
592 dfilter_mknode_boolean_value(gint truth_value)
593 {
594         dfilter_node    *node;
595         GNode           *gnode;
596
597         node = g_mem_chunk_alloc(global_df->node_memchunk);
598         node->ntype = numeric;
599         node->elem_size = sizeof(guint32);
600         node->fill_array_func = fill_array_boolean_value;
601         node->check_relation_func = check_relation_boolean;
602         node->value.boolean = truth_value == TOK_TRUE ? TRUE : FALSE;
603         gnode = g_node_new(node);
604
605         return gnode;
606 }
607
608 static guint32
609 string_to_value(char *s)
610 {
611         char    *endptr;
612         guint32 val;
613
614         val = strtoul(s, &endptr, 0);
615         /* I should probably check errno here */
616
617         return (guint32)val;
618 }
619         
620 static GNode*
621 dfilter_mknode_existence(gint id)
622 {
623         dfilter_node    *node;
624         GNode           *gnode;
625
626         node = g_mem_chunk_alloc(global_df->node_memchunk);
627         node->ntype = existence;
628         node->elem_size = sizeof(guint32);
629         node->fill_array_func = NULL;
630         node->check_relation_func = NULL;
631         node->value.variable = id;
632         gnode = g_node_new(node);
633
634         return gnode;
635 }
636
637 /* converts a string representing an ether HW address
638  * to a guint8 array.
639  *
640  * Returns 0 on failure, 1 on success.
641  */
642 static int
643 ether_str_to_guint8_array(const char *s, guint8 *mac)
644 {
645         char    ether_str[18]; /* 2+1+2+1+2+1+2+1+2+1+2 + 1 */
646         char    *p, *str;
647         int     i = 0;
648
649         if (strlen(s) > 17) {
650                 return 0;
651         }
652         strcpy(ether_str, s); /* local copy of string */
653         str = ether_str;
654         while ((p = strtok(str, "-:."))) {
655                 /* catch short strings with too many hex bytes: 0.0.0.0.0.0.0 */
656                 if (i > 5) {
657                         return 0;
658                 }
659                 mac[i] = (guint8) strtoul(p, NULL, 16);
660                 i++;
661                 /* subsequent calls to strtok() require NULL as arg 1 */
662                 str = NULL;
663         }
664         if (i != 6)
665                 return 0;       /* failed to read 6 hex pairs */
666         else
667                 return 1;       /* read exactly 6 hex pairs */
668 }
669