Include "snprintf.h" if necessary, to squelch some "gcc -Wall"
[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.13 1999/08/20 20:45:14 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 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 <byte_range>     T_VAL_BYTE_RANGE
143
144 %token <operand>        TOK_AND TOK_OR TOK_NOT TOK_XOR
145 %token <operand>        TOK_EQ TOK_NE TOK_GT TOK_GE TOK_LT TOK_LE
146 %token <operand>        TOK_TRUE TOK_FALSE
147
148 %left TOK_AND
149 %left TOK_OR
150 %left TOK_XOR
151 %nonassoc TOK_NOT
152
153 %%
154
155 statement: expression
156                 {
157                         global_df->dftree = $1;
158                 }
159         |       /* NULL */ { global_df->dftree = NULL; }
160         ;
161
162 expression:     '(' expression ')' { $$ = $2; }
163         |       expression TOK_AND expression { $$ = dfilter_mknode_join($1, logical, $2, $3); }
164         |       expression TOK_OR expression { $$ = dfilter_mknode_join($1, logical, $2, $3); }
165         |       expression TOK_XOR expression { $$ = dfilter_mknode_join($1, logical, $2, $3); }
166         |       TOK_NOT expression { $$ = dfilter_mknode_unary(TOK_NOT, $2); }
167         |       relation { $$ = $1; }
168         |       variable_name { $$ = $1; }
169         ;
170
171 relation:       numeric_variable numeric_relation numeric_value
172                 {
173                         $$ = dfilter_mknode_join($1, relation, $2, $3);
174                 }
175         |       numeric_variable numeric_relation numeric_variable
176                 {
177                         $$ = dfilter_mknode_join($1, relation, $2, $3);
178                 }
179
180         |       ether_variable equality_relation ether_value
181                 {
182                         $$ = dfilter_mknode_join($1, relation, $2, $3);
183                 }
184         |       ether_variable equality_relation ether_variable
185                 {
186                         $$ = dfilter_mknode_join($1, relation, $2, $3);
187                 }
188
189         |       ipxnet_variable equality_relation ipxnet_value
190                 {
191                         $$ = dfilter_mknode_join($1, relation, $2, $3);
192                 }
193         |       ipxnet_variable equality_relation ipxnet_variable
194                 {
195                         $$ = dfilter_mknode_join($1, relation, $2, $3);
196                 }
197
198
199         |       ipv4_variable numeric_relation ipv4_value
200                 {
201                         $$ = dfilter_mknode_join($1, relation, $2, $3);
202                 }
203         |       ipv4_variable numeric_relation ipv4_variable
204                 {
205                         $$ = dfilter_mknode_join($1, relation, $2, $3);
206                 }
207
208         |       bytes_variable bytes_relation bytes_value
209                 {
210                         $$ = dfilter_mknode_join($1, relation, $2, $3);
211                 }
212         |       bytes_variable bytes_relation bytes_variable
213                 {
214                         $$ = dfilter_mknode_join($1, relation, $2, $3);
215                 }
216
217         |       boolean_variable equality_relation boolean_value
218                 {
219                         $$ = dfilter_mknode_join($1, relation, $2, $3);
220                 }
221         |       boolean_variable equality_relation boolean_variable
222                 {
223                         $$ = dfilter_mknode_join($1, relation, $2, $3);
224                 }
225
226         ;
227
228
229 numeric_value:  T_VAL_UNQUOTED_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_UNQUOTED_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 boolean_value:  TOK_TRUE                { $$ = dfilter_mknode_boolean_value($1); }
279         |       TOK_FALSE               { $$ = dfilter_mknode_boolean_value($1); }
280         ;
281
282
283 numeric_variable:       T_FT_UINT8      { $$ = dfilter_mknode_numeric_variable($1); }
284         |               T_FT_UINT16     { $$ = dfilter_mknode_numeric_variable($1); }
285         |               T_FT_UINT32     { $$ = dfilter_mknode_numeric_variable($1); }
286         ;
287
288 ether_variable:         T_FT_ETHER      { $$ = dfilter_mknode_ether_variable($1); }
289         ;
290
291 ipxnet_variable:        T_FT_IPXNET     { $$ = dfilter_mknode_ipxnet_variable($1); }
292         ;
293
294 ipv4_variable:          T_FT_IPv4       { $$ = dfilter_mknode_ipv4_variable($1); }
295         ;
296
297 variable_name:          any_variable_type       { $$ = dfilter_mknode_existence($1); }
298         ;
299
300 bytes_variable:         any_variable_type T_VAL_BYTE_RANGE
301                 {
302                         $$ = dfilter_mknode_bytes_variable($1, $2.offset, $2.length);
303                 }
304         ;
305
306 boolean_variable:       T_FT_BOOLEAN    { $$ = dfilter_mknode_boolean_variable($1); }
307         ;
308
309 any_variable_type:      T_FT_UINT8 { $$ = $1; }
310         |               T_FT_UINT16 { $$ = $1; }
311         |               T_FT_UINT32 { $$ = $1; }
312         |               T_FT_ETHER { $$ = $1; }
313         |               T_FT_IPv4 { $$ = $1; }
314         |               T_FT_NONE { $$ = $1; }
315         |               T_FT_BYTES { $$ = $1; }
316         |               T_FT_BOOLEAN { $$ = $1; }
317         |               T_FT_STRING { $$ = $1; }
318         ;
319
320 numeric_relation:       TOK_EQ { $$ = TOK_EQ; }
321         |               TOK_NE { $$ = TOK_NE; }
322         |               TOK_GT { $$ = TOK_GT; }
323         |               TOK_GE { $$ = TOK_GE; }
324         |               TOK_LT { $$ = TOK_LT; }
325         |               TOK_LE { $$ = TOK_LE; }
326         ;
327
328 equality_relation:      TOK_EQ { $$ = TOK_EQ; }
329         |               TOK_NE { $$ = TOK_NE; }
330         ;
331
332 bytes_relation:         TOK_EQ { $$ = TOK_EQ; }
333         |               TOK_NE { $$ = TOK_NE; }
334         |               TOK_GT { $$ = TOK_GT; }
335         |               TOK_LT { $$ = TOK_LT; }
336         ;
337
338 %%
339
340 static GNode*
341 dfilter_mknode_join(GNode *n1, enum node_type ntype, int operand, GNode *n2)
342 {
343         dfilter_node    *node_root;
344         GNode           *gnode_root;
345
346         node_root = g_mem_chunk_alloc(global_df->node_memchunk);
347         node_root->ntype = ntype;
348         node_root->elem_size = 0;
349         node_root->fill_array_func = NULL;
350         node_root->check_relation_func = NULL;
351         if (ntype == relation) {
352                 node_root->value.relation = operand;
353         }
354         else if (ntype == logical) {
355                 node_root->value.logical = operand;
356         }
357         else {
358                 g_assert_not_reached();
359         }
360
361         gnode_root = g_node_new(node_root);
362         g_node_append(gnode_root, n1);
363         g_node_append(gnode_root, n2);
364
365         return gnode_root;
366 }
367
368 static GNode*
369 dfilter_mknode_unary(int operand, GNode *n2)
370 {
371         dfilter_node    *node_root;
372         GNode           *gnode_root;
373
374         node_root = g_mem_chunk_alloc(global_df->node_memchunk);
375         node_root->ntype = logical;
376         node_root->value.logical = operand;
377         node_root->elem_size = 0;
378         node_root->fill_array_func = NULL;
379         node_root->check_relation_func = NULL;
380
381         gnode_root = g_node_new(node_root);
382         g_node_append(gnode_root, n2);
383
384         return gnode_root;
385 }
386
387
388 static GNode*
389 dfilter_mknode_numeric_variable(gint id)
390 {
391         dfilter_node    *node;
392         GNode           *gnode;
393
394         node = g_mem_chunk_alloc(global_df->node_memchunk);
395         node->ntype = variable;
396         node->elem_size = sizeof(guint32);
397         node->fill_array_func = fill_array_numeric_variable;
398         node->check_relation_func = check_relation_numeric;
399         node->value.variable = id;
400         gnode = g_node_new(node);
401
402         return gnode;
403 }
404
405 static GNode*
406 dfilter_mknode_ether_variable(gint id)
407 {
408         dfilter_node    *node;
409         GNode           *gnode;
410
411         node = g_mem_chunk_alloc(global_df->node_memchunk);
412         node->ntype = variable;
413         node->elem_size = sizeof(guint8) * 6;
414         node->fill_array_func = fill_array_ether_variable;
415         node->check_relation_func = check_relation_ether;
416         node->value.variable = id;
417         gnode = g_node_new(node);
418
419         return gnode;
420 }
421
422 static GNode*
423 dfilter_mknode_ipxnet_variable(gint id)
424 {
425         dfilter_node    *node;
426         GNode           *gnode;
427
428         node = g_mem_chunk_alloc(global_df->node_memchunk);
429         node->ntype = variable;
430         node->elem_size = sizeof(guint8) * 4;
431         node->fill_array_func = fill_array_numeric_variable; /* cheating ! */
432         node->check_relation_func = check_relation_numeric; /* cheating ! */
433         node->value.variable = id;
434         gnode = g_node_new(node);
435
436         return gnode;
437 }
438
439 static GNode*
440 dfilter_mknode_ipv4_variable(gint id)
441 {
442         dfilter_node    *node;
443         GNode           *gnode;
444
445         node = g_mem_chunk_alloc(global_df->node_memchunk);
446         node->ntype = variable;
447         node->elem_size = sizeof(guint32);
448         node->fill_array_func = fill_array_numeric_variable; /* cheating ! */
449         node->check_relation_func = check_relation_numeric; /* cheating ! */
450         node->value.variable = id;
451         gnode = g_node_new(node);
452
453         return gnode;
454 }
455
456 static GNode*
457 dfilter_mknode_bytes_variable(gint id, gint offset, guint length)
458 {
459         dfilter_node    *node;
460         GNode           *gnode;
461
462         node = g_mem_chunk_alloc(global_df->node_memchunk);
463         node->ntype = variable;
464         node->elem_size = sizeof(GByteArray*);
465         node->fill_array_func = fill_array_bytes_variable;
466         node->check_relation_func = check_relation_bytes;
467         node->value.variable = id;
468         node->offset = offset;
469         node->length = length;
470         gnode = g_node_new(node);
471
472         return gnode;
473 }
474
475 static GNode*
476 dfilter_mknode_boolean_variable(gint id)
477 {
478         dfilter_node    *node;
479         GNode           *gnode;
480
481         node = g_mem_chunk_alloc(global_df->node_memchunk);
482         node->ntype = variable;
483         node->elem_size = sizeof(guint32);
484         node->fill_array_func = fill_array_boolean_variable; /* cheating ! */
485         node->check_relation_func = check_relation_boolean; /* cheating ! */
486         node->value.variable = id;
487         gnode = g_node_new(node);
488
489         return gnode;
490 }
491
492 static GNode*
493 dfilter_mknode_numeric_value(guint32 val)
494 {
495         dfilter_node    *node;
496         GNode           *gnode;
497
498         node = g_mem_chunk_alloc(global_df->node_memchunk);
499         node->ntype = numeric;
500         node->elem_size = sizeof(guint32);
501         node->fill_array_func = fill_array_numeric_value;
502         node->check_relation_func = check_relation_numeric;
503         node->value.numeric = val;
504         gnode = g_node_new(node);
505
506         return gnode;
507 }
508
509 /* Returns NULL on bad parse of ETHER value */
510 static GNode*
511 dfilter_mknode_ether_value(gchar *byte_string)
512 {
513         dfilter_node    *node;
514         GNode           *gnode;
515
516         node = g_mem_chunk_alloc(global_df->node_memchunk);
517         node->ntype = ether;
518         node->elem_size = sizeof(guint8) * 6;
519         node->fill_array_func = fill_array_ether_value;
520         node->check_relation_func = check_relation_ether;
521
522         if (!ether_str_to_guint8_array(byte_string, &node->value.ether[0])) {
523                 /* Rather than free the mem_chunk allocation, let it
524                  * stay. It will be cleaned up in the next call to
525                  * dfilter_clear() */
526                 dfilter_error_msg = &dfilter_error_msg_buf[0];
527                 snprintf(dfilter_error_msg, sizeof(dfilter_error_msg_buf),
528                         "\"%s\" is not a valid hardware address.", byte_string);
529                 return NULL;
530         }
531
532         gnode = g_node_new(node);
533         return gnode;
534 }
535
536 static GNode*
537 dfilter_mknode_ipxnet_value(guint32 ipx_net_val)
538 {
539         dfilter_node    *node;
540         GNode           *gnode;
541
542         node = g_mem_chunk_alloc(global_df->node_memchunk);
543         node->ntype = ipxnet;
544         node->elem_size = sizeof(guint8) * 4;
545         node->fill_array_func = fill_array_numeric_value; /* cheating ! */
546         node->check_relation_func = check_relation_numeric; /* cheating ! */
547         node->value.numeric = ipx_net_val;
548         gnode = g_node_new(node);
549
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         return gnode;
569 }
570
571 static GNode*
572 dfilter_mknode_bytes_value(GByteArray *barray)
573 {
574         dfilter_node    *node;
575         GNode           *gnode;
576
577         node = g_mem_chunk_alloc(global_df->node_memchunk);
578         node->ntype = bytes;
579         node->elem_size = sizeof(GByteArray*);
580         node->fill_array_func = fill_array_bytes_value;
581         node->check_relation_func = check_relation_bytes;
582         node->value.bytes = barray;
583         node->offset = G_MAXINT;
584         node->length = barray->len;
585         gnode = g_node_new(node);
586
587         return gnode;
588 }
589
590 static GNode*
591 dfilter_mknode_boolean_value(gint truth_value)
592 {
593         dfilter_node    *node;
594         GNode           *gnode;
595
596         node = g_mem_chunk_alloc(global_df->node_memchunk);
597         node->ntype = numeric;
598         node->elem_size = sizeof(guint32);
599         node->fill_array_func = fill_array_boolean_value;
600         node->check_relation_func = check_relation_boolean;
601         node->value.boolean = truth_value == TOK_TRUE ? TRUE : FALSE;
602         gnode = g_node_new(node);
603
604         return gnode;
605 }
606
607 static guint32
608 string_to_value(char *s)
609 {
610         char    *endptr;
611         guint32 val;
612
613         val = strtoul(s, &endptr, 0);
614         /* I should probably check errno here */
615
616         return (guint32)val;
617 }
618         
619 static GNode*
620 dfilter_mknode_existence(gint id)
621 {
622         dfilter_node    *node;
623         GNode           *gnode;
624
625         node = g_mem_chunk_alloc(global_df->node_memchunk);
626         node->ntype = existence;
627         node->elem_size = sizeof(guint32);
628         node->fill_array_func = NULL;
629         node->check_relation_func = NULL;
630         node->value.variable = id;
631         gnode = g_node_new(node);
632
633         return gnode;
634 }
635
636 /* converts a string representing an ether HW address
637  * to a guint8 array.
638  *
639  * Returns 0 on failure, 1 on success.
640  */
641 static int
642 ether_str_to_guint8_array(const char *s, guint8 *mac)
643 {
644         char    ether_str[18]; /* 2+1+2+1+2+1+2+1+2+1+2 + 1 */
645         char    *p, *str;
646         int     i = 0;
647
648         if (strlen(s) > 17) {
649                 return 0;
650         }
651         strcpy(ether_str, s); /* local copy of string */
652         str = ether_str;
653         while ((p = strtok(str, "-:."))) {
654                 /* catch short strings with too many hex bytes: 0.0.0.0.0.0.0 */
655                 if (i > 5) {
656                         return 0;
657                 }
658                 mac[i] = (guint8) strtoul(p, NULL, 16);
659                 i++;
660                 /* subsequent calls to strtok() require NULL as arg 1 */
661                 str = NULL;
662         }
663         if (i != 6)
664                 return 0;       /* failed to read 6 hex pairs */
665         else
666                 return 1;       /* read exactly 6 hex pairs */
667 }
668