3594f66cf3671e5bfe11ccadd76dc611a50b4cc5
[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.20 1999/10/07 21:47:20 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 #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
91 static guint32 string_to_value(char *s);
92 static int ether_str_to_guint8_array(const char *s, guint8 *mac);
93
94 /* This is the dfilter we're currently processing. It's how
95  * dfilter_compile communicates with us.
96  */
97 dfilter *global_df = NULL;;
98
99 /* list of GNodes allocated during parsing. If the parsing fails, we'll
100  * use this list to free all the GNodes. If the parsing succeeds, we'll
101  * just clear this list since dfilter_clear_filter() will take care of
102  * freeing the GNodes when they're no longer needed.
103  */
104 GSList *gnode_slist = NULL;
105
106 %}
107
108 %union {
109         gint            operand;        /* logical, relation, alternation */
110         struct {
111                 gint    id;
112                 gint    type;           /* using macros defined below, in this yacc grammar */
113         } variable;
114         GNode*          node;
115         gchar*          string;
116         struct {
117                 gint    offset;
118                 guint   length;
119         } byte_range;
120 }
121
122 %type <node>    statement expression relation
123 %type <node>    numeric_value numeric_variable
124 %type <node>    ether_value ether_variable
125 %type <node>    ipxnet_value ipxnet_variable
126 %type <node>    ipv4_value ipv4_variable
127 %type <node>    variable_name
128 %type <node>    bytes_value bytes_variable
129
130 %type <operand> numeric_relation
131 %type <operand> equality_relation
132 %type <operand> bytes_relation
133
134 %type <variable>        any_variable_type
135
136 %token <variable>       T_FT_UINT8
137 %token <variable>       T_FT_UINT16
138 %token <variable>       T_FT_UINT32
139 %token <variable>       T_FT_ETHER
140 %token <variable>       T_FT_IPv4
141 %token <variable>       T_FT_NONE
142 %token <variable>       T_FT_BYTES
143 %token <variable>       T_FT_BOOLEAN
144 %token <variable>       T_FT_STRING
145 %token <variable>       T_FT_IPXNET
146
147 %token <string>         T_VAL_UNQUOTED_STRING
148 %token <string>         T_VAL_BYTE_STRING
149 %token <string>         T_VAL_NUMBER_STRING
150 %token <byte_range>     T_VAL_BYTE_RANGE
151
152 %token <operand>        TOK_AND TOK_OR TOK_NOT TOK_XOR
153 %token <operand>        TOK_EQ TOK_NE TOK_GT TOK_GE TOK_LT TOK_LE
154 %token <operand>        TOK_TRUE TOK_FALSE
155
156 %left TOK_AND
157 %left TOK_OR
158 %left TOK_XOR
159 %nonassoc TOK_NOT
160
161 %%
162
163 statement: expression
164                 {
165                         global_df->dftree = $1;
166                 }
167         |       /* NULL */ { if (global_df != NULL) global_df->dftree = NULL; }
168         ;
169
170 expression:     '(' expression ')' { $$ = $2; }
171         |       expression TOK_AND expression { $$ = dfilter_mknode_join($1, logical, $2, $3); }
172         |       expression TOK_OR expression { $$ = dfilter_mknode_join($1, logical, $2, $3); }
173         |       expression TOK_XOR expression { $$ = dfilter_mknode_join($1, logical, $2, $3); }
174         |       TOK_NOT expression { $$ = dfilter_mknode_unary(TOK_NOT, $2); }
175         |       relation { $$ = $1; }
176         |       variable_name { $$ = $1; }
177         |       expression error { YYABORT; }
178         ;
179
180 relation:       numeric_variable numeric_relation numeric_value
181                 {
182                         $$ = dfilter_mknode_join($1, relation, $2, $3);
183                 }
184         |       numeric_variable numeric_relation numeric_variable
185                 {
186                         $$ = dfilter_mknode_join($1, relation, $2, $3);
187                 }
188
189         |       ether_variable equality_relation ether_value
190                 {
191                         $$ = dfilter_mknode_join($1, relation, $2, $3);
192                 }
193         |       ether_variable equality_relation ether_variable
194                 {
195                         $$ = dfilter_mknode_join($1, relation, $2, $3);
196                 }
197
198         |       ipxnet_variable equality_relation ipxnet_value
199                 {
200                         $$ = dfilter_mknode_join($1, relation, $2, $3);
201                 }
202         |       ipxnet_variable equality_relation ipxnet_variable
203                 {
204                         $$ = dfilter_mknode_join($1, relation, $2, $3);
205                 }
206
207
208         |       ipv4_variable numeric_relation ipv4_value
209                 {
210                         $$ = dfilter_mknode_join($1, relation, $2, $3);
211                 }
212         |       ipv4_variable numeric_relation ipv4_variable
213                 {
214                         $$ = dfilter_mknode_join($1, relation, $2, $3);
215                 }
216
217         |       bytes_variable bytes_relation bytes_value
218                 {
219                         $$ = dfilter_mknode_join($1, relation, $2, $3);
220                 }
221         |       bytes_variable bytes_relation bytes_variable
222                 {
223                         $$ = dfilter_mknode_join($1, relation, $2, $3);
224                 }
225
226         ;
227
228
229 numeric_value:  T_VAL_NUMBER_STRING
230         {
231                 $$ = dfilter_mknode_numeric_value(string_to_value($1));
232                 g_free($1);
233          }
234         ;
235
236 ether_value:    T_VAL_BYTE_STRING
237         {
238                 $$ = dfilter_mknode_ether_value($1);
239                 g_free($1);
240                 if ($$ == NULL) {
241                         YYERROR;
242                 }
243         }
244         ;
245
246 ipxnet_value:   T_VAL_NUMBER_STRING
247         {
248                 $$ = dfilter_mknode_ipxnet_value(string_to_value($1));
249                 g_free($1);
250         }
251         ;
252
253 ipv4_value:     T_VAL_UNQUOTED_STRING
254                 {
255                         $$ = dfilter_mknode_ipv4_value($1);
256                         g_free($1);
257                 }
258
259         |       T_VAL_BYTE_STRING
260                 {
261                         $$ = dfilter_mknode_ipv4_value($1);
262                         g_free($1);
263                 }
264         ;
265
266 bytes_value:    T_VAL_BYTE_STRING
267         {
268                 GByteArray      *barray;
269
270                 /* the next function appends to list_of_byte_arrays for me */
271                 barray = byte_str_to_guint8_array($1);
272                 $$ = dfilter_mknode_bytes_value(barray);
273                 g_free($1);
274         }
275         ;
276
277
278 numeric_variable:       T_FT_UINT8      { $$ = dfilter_mknode_numeric_variable($1.id); }
279         |               T_FT_UINT16     { $$ = dfilter_mknode_numeric_variable($1.id); }
280         |               T_FT_UINT32     { $$ = dfilter_mknode_numeric_variable($1.id); }
281         ;
282
283 ether_variable:         T_FT_ETHER      { $$ = dfilter_mknode_ether_variable($1.id); }
284         ;
285
286 ipxnet_variable:        T_FT_IPXNET     { $$ = dfilter_mknode_ipxnet_variable($1.id); }
287         ;
288
289 ipv4_variable:          T_FT_IPv4       { $$ = dfilter_mknode_ipv4_variable($1.id); }
290         ;
291
292 variable_name:          any_variable_type
293         {
294                 GNode   *variable;
295                 GNode   *value;
296
297                 if ($1.type == T_FT_BOOLEAN) {
298                         /* Make "variable == TRUE" for BOOLEAN variable */
299                         variable = dfilter_mknode_numeric_variable($1.id);
300                         value = dfilter_mknode_numeric_value(TRUE);
301                         $$ = dfilter_mknode_join(variable, relation, TOK_EQ, value);
302                 }
303                 else {
304                         $$ = dfilter_mknode_existence($1.id);
305                 }
306         }
307         ;
308
309 bytes_variable:         any_variable_type T_VAL_BYTE_RANGE
310                 {
311                         $$ = dfilter_mknode_bytes_variable($1.id, $2.offset, $2.length);
312                 }
313         ;
314
315 any_variable_type:      T_FT_UINT8 { $$ = $1; }
316         |               T_FT_UINT16 { $$ = $1; }
317         |               T_FT_UINT32 { $$ = $1; }
318         |               T_FT_ETHER { $$ = $1; }
319         |               T_FT_IPv4 { $$ = $1; }
320         |               T_FT_IPXNET { $$ = $1; }
321         |               T_FT_NONE { $$ = $1; }
322         |               T_FT_BYTES { $$ = $1; }
323         |               T_FT_BOOLEAN { $$ = $1; }
324         |               T_FT_STRING { $$ = $1; }
325         ;
326
327 numeric_relation:       TOK_EQ { $$ = TOK_EQ; }
328         |               TOK_NE { $$ = TOK_NE; }
329         |               TOK_GT { $$ = TOK_GT; }
330         |               TOK_GE { $$ = TOK_GE; }
331         |               TOK_LT { $$ = TOK_LT; }
332         |               TOK_LE { $$ = TOK_LE; }
333         ;
334
335 equality_relation:      TOK_EQ { $$ = TOK_EQ; }
336         |               TOK_NE { $$ = TOK_NE; }
337         ;
338
339 bytes_relation:         TOK_EQ { $$ = TOK_EQ; }
340         |               TOK_NE { $$ = TOK_NE; }
341         |               TOK_GT { $$ = TOK_GT; }
342         |               TOK_LT { $$ = TOK_LT; }
343         ;
344
345 %%
346
347 static GNode*
348 dfilter_mknode_join(GNode *n1, enum node_type ntype, int operand, GNode *n2)
349 {
350         dfilter_node    *node_root;
351         GNode           *gnode_root;
352
353         node_root = g_mem_chunk_alloc(global_df->node_memchunk);
354         node_root->ntype = ntype;
355         node_root->elem_size = 0;
356         node_root->fill_array_func = NULL;
357         node_root->check_relation_func = NULL;
358         if (ntype == relation) {
359                 node_root->value.relation = operand;
360         }
361         else if (ntype == logical) {
362                 node_root->value.logical = operand;
363         }
364         else {
365                 g_assert_not_reached();
366         }
367
368         gnode_root = g_node_new(node_root);
369         g_node_append(gnode_root, n1);
370         g_node_append(gnode_root, n2);
371
372         gnode_slist = g_slist_append(gnode_slist, gnode_root);
373         return gnode_root;
374 }
375
376 static GNode*
377 dfilter_mknode_unary(int operand, GNode *n2)
378 {
379         dfilter_node    *node_root;
380         GNode           *gnode_root;
381
382         node_root = g_mem_chunk_alloc(global_df->node_memchunk);
383         node_root->ntype = logical;
384         node_root->value.logical = operand;
385         node_root->elem_size = 0;
386         node_root->fill_array_func = NULL;
387         node_root->check_relation_func = NULL;
388
389         gnode_root = g_node_new(node_root);
390         g_node_append(gnode_root, n2);
391
392         gnode_slist = g_slist_append(gnode_slist, gnode_root);
393         return gnode_root;
394 }
395
396
397 static GNode*
398 dfilter_mknode_numeric_variable(gint id)
399 {
400         dfilter_node    *node;
401         GNode           *gnode;
402
403         node = g_mem_chunk_alloc(global_df->node_memchunk);
404         node->ntype = variable;
405         node->elem_size = sizeof(guint32);
406         node->fill_array_func = fill_array_numeric_variable;
407         node->check_relation_func = check_relation_numeric;
408         node->value.variable = id;
409         gnode = g_node_new(node);
410
411         gnode_slist = g_slist_append(gnode_slist, gnode);
412         return gnode;
413 }
414
415 static GNode*
416 dfilter_mknode_ether_variable(gint id)
417 {
418         dfilter_node    *node;
419         GNode           *gnode;
420
421         node = g_mem_chunk_alloc(global_df->node_memchunk);
422         node->ntype = variable;
423         node->elem_size = sizeof(guint8) * 6;
424         node->fill_array_func = fill_array_ether_variable;
425         node->check_relation_func = check_relation_ether;
426         node->value.variable = id;
427         gnode = g_node_new(node);
428
429         gnode_slist = g_slist_append(gnode_slist, gnode);
430         return gnode;
431 }
432
433 static GNode*
434 dfilter_mknode_ipxnet_variable(gint id)
435 {
436         dfilter_node    *node;
437         GNode           *gnode;
438
439         node = g_mem_chunk_alloc(global_df->node_memchunk);
440         node->ntype = variable;
441         node->elem_size = sizeof(guint8) * 4;
442         node->fill_array_func = fill_array_numeric_variable; /* cheating ! */
443         node->check_relation_func = check_relation_numeric; /* cheating ! */
444         node->value.variable = id;
445         gnode = g_node_new(node);
446
447         gnode_slist = g_slist_append(gnode_slist, gnode);
448         return gnode;
449 }
450
451 static GNode*
452 dfilter_mknode_ipv4_variable(gint id)
453 {
454         dfilter_node    *node;
455         GNode           *gnode;
456
457         node = g_mem_chunk_alloc(global_df->node_memchunk);
458         node->ntype = variable;
459         node->elem_size = sizeof(guint32);
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         gnode_slist = g_slist_append(gnode_slist, gnode);
466         return gnode;
467 }
468
469 static GNode*
470 dfilter_mknode_bytes_variable(gint id, gint offset, guint length)
471 {
472         dfilter_node    *node;
473         GNode           *gnode;
474
475         node = g_mem_chunk_alloc(global_df->node_memchunk);
476         node->ntype = variable;
477         node->elem_size = sizeof(GByteArray*);
478         node->fill_array_func = fill_array_bytes_variable;
479         node->check_relation_func = check_relation_bytes;
480         node->value.variable = id;
481         node->offset = offset;
482         node->length = length;
483         gnode = g_node_new(node);
484
485         gnode_slist = g_slist_append(gnode_slist, gnode);
486         return gnode;
487 }
488
489 static GNode*
490 dfilter_mknode_numeric_value(guint32 val)
491 {
492         dfilter_node    *node;
493         GNode           *gnode;
494
495         node = g_mem_chunk_alloc(global_df->node_memchunk);
496         node->ntype = numeric;
497         node->elem_size = sizeof(guint32);
498         node->fill_array_func = fill_array_numeric_value;
499         node->check_relation_func = check_relation_numeric;
500         node->value.numeric = val;
501         gnode = g_node_new(node);
502
503         gnode_slist = g_slist_append(gnode_slist, gnode);
504         return gnode;
505 }
506
507 /* Returns NULL on bad parse of ETHER value */
508 static GNode*
509 dfilter_mknode_ether_value(gchar *byte_string)
510 {
511         dfilter_node    *node;
512         GNode           *gnode;
513
514         node = g_mem_chunk_alloc(global_df->node_memchunk);
515         node->ntype = ether;
516         node->elem_size = sizeof(guint8) * 6;
517         node->fill_array_func = fill_array_ether_value;
518         node->check_relation_func = check_relation_ether;
519
520         if (!ether_str_to_guint8_array(byte_string, &node->value.ether[0])) {
521                 /* Rather than free the mem_chunk allocation, let it
522                  * stay. It will be cleaned up in the next call to
523                  * dfilter_clear() */
524                 dfilter_error_msg = &dfilter_error_msg_buf[0];
525                 snprintf(dfilter_error_msg, sizeof(dfilter_error_msg_buf),
526                         "\"%s\" is not a valid hardware address.", byte_string);
527                 return NULL;
528         }
529
530         gnode = g_node_new(node);
531         gnode_slist = g_slist_append(gnode_slist, gnode);
532         return gnode;
533 }
534
535 static GNode*
536 dfilter_mknode_ipxnet_value(guint32 ipx_net_val)
537 {
538         dfilter_node    *node;
539         GNode           *gnode;
540
541         node = g_mem_chunk_alloc(global_df->node_memchunk);
542         node->ntype = ipxnet;
543         node->elem_size = sizeof(guint8) * 4;
544         node->fill_array_func = fill_array_numeric_value; /* cheating ! */
545         node->check_relation_func = check_relation_numeric; /* cheating ! */
546         node->value.numeric = ipx_net_val;
547         gnode = g_node_new(node);
548
549         gnode_slist = g_slist_append(gnode_slist, gnode);
550         return gnode;
551 }
552
553 static GNode*
554 dfilter_mknode_ipv4_value(char *host)
555 {
556         dfilter_node    *node;
557         GNode           *gnode;
558
559         node = g_mem_chunk_alloc(global_df->node_memchunk);
560         node->ntype = numeric;
561         node->elem_size = sizeof(guint32);
562         node->fill_array_func = fill_array_numeric_value; /* cheating ! */
563         node->check_relation_func = check_relation_numeric; /* cheating ! */
564         node->value.numeric = get_host_ipaddr(host);
565         node->value.numeric = htonl(node->value.numeric);
566         gnode = g_node_new(node);
567
568         gnode_slist = g_slist_append(gnode_slist, gnode);
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         gnode_slist = g_slist_append(gnode_slist, gnode);
589         return gnode;
590 }
591
592 static guint32
593 string_to_value(char *s)
594 {
595         char    *endptr;
596         guint32 val;
597
598         val = strtoul(s, &endptr, 0);
599         /* I should probably check errno here */
600
601         return (guint32)val;
602 }
603         
604 static GNode*
605 dfilter_mknode_existence(gint id)
606 {
607         dfilter_node    *node;
608         GNode           *gnode;
609
610         node = g_mem_chunk_alloc(global_df->node_memchunk);
611         node->ntype = existence;
612         node->elem_size = sizeof(guint32);
613         node->fill_array_func = NULL;
614         node->check_relation_func = NULL;
615         node->value.variable = id;
616         gnode = g_node_new(node);
617
618         gnode_slist = g_slist_append(gnode_slist, gnode);
619         return gnode;
620 }
621
622
623 /* converts a string representing an ether HW address
624  * to a guint8 array.
625  *
626  * Returns 0 on failure, 1 on success.
627  */
628 static int
629 ether_str_to_guint8_array(const char *s, guint8 *mac)
630 {
631         char    ether_str[18]; /* 2+1+2+1+2+1+2+1+2+1+2 + 1 */
632         char    *p, *str;
633         int     i = 0;
634
635         if (strlen(s) > 17) {
636                 return 0;
637         }
638         strcpy(ether_str, s); /* local copy of string */
639         str = ether_str;
640         while ((p = strtok(str, "-:."))) {
641                 /* catch short strings with too many hex bytes: 0.0.0.0.0.0.0 */
642                 if (i > 5) {
643                         return 0;
644                 }
645                 mac[i] = (guint8) strtoul(p, NULL, 16);
646                 i++;
647                 /* subsequent calls to strtok() require NULL as arg 1 */
648                 str = NULL;
649         }
650         if (i != 6)
651                 return 0;       /* failed to read 6 hex pairs */
652         else
653                 return 1;       /* read exactly 6 hex pairs */
654 }
655