4 * Parser for display filters
6 * $Id: dfilter-grammar.y,v 1.6 1999/08/11 16:25:07 gram Exp $
8 * Ethereal - Network traffic analyzer
9 * By Gerald Combs <gerald@zing.org>
10 * Copyright 1998 Gerald Combs
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.
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.
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.
28 #define yylex dfilter_lex
34 #ifdef HAVE_SYS_TYPES_H
35 # include <sys/types.h>
38 #ifdef HAVE_NETINET_IN_H
39 # include <netinet/in.h>
46 #include <string.h> /* during testing */
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);
85 static guint32 string_to_value(char *s);
87 /* space for dfilter_nodes */
88 GMemChunk *gmc_dfilter_nodes = NULL;
90 /* this is how we pass display filter tree (dfcode) back to calling routine */
91 GNode *dfilter_tree = NULL;
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;
100 gint operand; /* logical, relation, alternation */
112 %type <node> statement expression relation
113 %type <node> numeric_value numeric_variable
114 %type <node> ether_value ether_variable
115 %type <node> ipxnet_value ipxnet_variable
116 %type <node> ipv4_value ipv4_variable
117 %type <node> variable_name
118 %type <node> bytes_value bytes_variable
119 %type <node> boolean_value boolean_variable
121 %type <operand> numeric_relation
122 %type <operand> equality_relation
123 %type <operand> bytes_relation
125 %type <variable> any_variable_type
127 %token <variable> T_FT_UINT8
128 %token <variable> T_FT_UINT16
129 %token <variable> T_FT_UINT32
130 %token <variable> T_FT_ETHER
131 %token <variable> T_FT_IPv4
132 %token <variable> T_FT_NONE
133 %token <variable> T_FT_BYTES
134 %token <variable> T_FT_BOOLEAN
135 %token <variable> T_FT_STRING
136 %token <variable> T_FT_IPXNET
138 %token <id> T_VAL_UNQUOTED_STRING
139 %token <ether> T_VAL_ETHER
140 %token <bytes> T_VAL_BYTES
141 %token <byte_range> T_VAL_BYTE_RANGE
143 %token <operand> TOK_AND TOK_OR TOK_NOT TOK_XOR
144 %token <operand> TOK_EQ TOK_NE TOK_GT TOK_GE TOK_LT TOK_LE
145 %token <operand> TOK_TRUE TOK_FALSE
154 statement: expression
158 | /* NULL */ { dfilter_tree = NULL; }
161 expression: '(' expression ')' { $$ = $2; }
162 | expression TOK_AND expression { $$ = dfilter_mknode_join($1, logical, $2, $3); }
163 | expression TOK_OR expression { $$ = dfilter_mknode_join($1, logical, $2, $3); }
164 | expression TOK_XOR expression { $$ = dfilter_mknode_join($1, logical, $2, $3); }
165 | TOK_NOT expression { $$ = dfilter_mknode_unary(TOK_NOT, $2); }
166 | relation { $$ = $1; }
167 | variable_name { $$ = $1; }
170 relation: numeric_variable numeric_relation numeric_value
172 $$ = dfilter_mknode_join($1, relation, $2, $3);
174 | numeric_variable numeric_relation numeric_variable
176 $$ = dfilter_mknode_join($1, relation, $2, $3);
179 | ether_variable equality_relation ether_value
181 $$ = dfilter_mknode_join($1, relation, $2, $3);
183 | ether_variable equality_relation ether_variable
185 $$ = dfilter_mknode_join($1, relation, $2, $3);
188 | ipxnet_variable equality_relation ipxnet_value
190 $$ = dfilter_mknode_join($1, relation, $2, $3);
192 | ipxnet_variable equality_relation ipxnet_variable
194 $$ = dfilter_mknode_join($1, relation, $2, $3);
198 | ipv4_variable numeric_relation ipv4_value
200 $$ = dfilter_mknode_join($1, relation, $2, $3);
202 | ipv4_variable numeric_relation ipv4_variable
204 $$ = dfilter_mknode_join($1, relation, $2, $3);
207 | bytes_variable bytes_relation bytes_value
209 $$ = dfilter_mknode_join($1, relation, $2, $3);
211 | bytes_variable bytes_relation bytes_variable
213 $$ = dfilter_mknode_join($1, relation, $2, $3);
216 | boolean_variable equality_relation boolean_value
218 $$ = dfilter_mknode_join($1, relation, $2, $3);
220 | boolean_variable equality_relation boolean_variable
222 $$ = dfilter_mknode_join($1, relation, $2, $3);
228 numeric_value: T_VAL_UNQUOTED_STRING
230 $$ = dfilter_mknode_numeric_value(string_to_value($1));
235 ether_value: T_VAL_ETHER
237 $$ = dfilter_mknode_ether_value($1);
241 ipxnet_value: T_VAL_UNQUOTED_STRING
243 $$ = dfilter_mknode_ipxnet_value(string_to_value($1));
247 ipv4_value: T_VAL_UNQUOTED_STRING
249 $$ = dfilter_mknode_ipv4_value($1);
254 bytes_value: T_VAL_BYTES
255 { /* 2 - 5, or > 6 bytes */
256 $$ = dfilter_mknode_bytes_value($1);
259 | T_VAL_UNQUOTED_STRING
261 GByteArray *barray = g_byte_array_new();
265 dfilter_list_byte_arrays = g_slist_append(dfilter_list_byte_arrays, barray);
266 val = (guint8) strtoul($1, &endptr, 16);
267 g_byte_array_append(barray, &val, 1);
268 $$ = dfilter_mknode_bytes_value(barray);
274 GByteArray *barray = g_byte_array_new();
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);
283 boolean_value: TOK_TRUE { $$ = dfilter_mknode_boolean_value($1); }
284 | TOK_FALSE { $$ = dfilter_mknode_boolean_value($1); }
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); }
293 ether_variable: T_FT_ETHER { $$ = dfilter_mknode_ether_variable($1); }
296 ipxnet_variable: T_FT_IPXNET { $$ = dfilter_mknode_ipxnet_variable($1); }
299 ipv4_variable: T_FT_IPv4 { $$ = dfilter_mknode_ipv4_variable($1); }
302 variable_name: any_variable_type { $$ = dfilter_mknode_existence($1); }
305 bytes_variable: any_variable_type T_VAL_BYTE_RANGE
307 $$ = dfilter_mknode_bytes_variable($1, $2.offset, $2.length);
311 boolean_variable: T_FT_BOOLEAN { $$ = dfilter_mknode_boolean_variable($1); }
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; }
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; }
333 equality_relation: TOK_EQ { $$ = TOK_EQ; }
334 | TOK_NE { $$ = TOK_NE; }
337 bytes_relation: TOK_EQ { $$ = TOK_EQ; }
338 | TOK_NE { $$ = TOK_NE; }
339 | TOK_GT { $$ = TOK_GT; }
340 | TOK_LT { $$ = TOK_LT; }
346 dfilter_yacc_init(void)
348 if (gmc_dfilter_nodes)
349 g_mem_chunk_destroy(gmc_dfilter_nodes);
351 gmc_dfilter_nodes = g_mem_chunk_new("gmc_dfilter_nodes",
352 sizeof(dfilter_node), 50 * sizeof(dfilter_node),
355 if (dfilter_list_byte_arrays) {
356 /* clear the byte arrays */
357 g_slist_free(dfilter_list_byte_arrays);
363 dfilter_yacc_cleanup(void)
365 if (gmc_dfilter_nodes)
366 g_mem_chunk_destroy(gmc_dfilter_nodes);
371 dfilter_mknode_join(GNode *n1, enum node_type ntype, int operand, GNode *n2)
373 dfilter_node *node_root;
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;
384 else if (ntype == logical) {
385 node_root->value.logical = operand;
388 g_assert_not_reached();
391 gnode_root = g_node_new(node_root);
392 g_node_append(gnode_root, n1);
393 g_node_append(gnode_root, n2);
399 dfilter_mknode_unary(int operand, GNode *n2)
401 dfilter_node *node_root;
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;
411 gnode_root = g_node_new(node_root);
412 g_node_append(gnode_root, n2);
419 dfilter_mknode_numeric_variable(gint id)
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);
436 dfilter_mknode_ether_variable(gint id)
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);
453 dfilter_mknode_ipxnet_variable(gint id)
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);
470 dfilter_mknode_ipv4_variable(gint id)
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);
487 dfilter_mknode_bytes_variable(gint id, gint offset, guint length)
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);
506 dfilter_mknode_boolean_variable(gint id)
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);
523 dfilter_mknode_numeric_value(guint32 val)
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);
540 dfilter_mknode_ether_value(guint8 *ether_bytes)
545 node = g_mem_chunk_alloc(gmc_dfilter_nodes);
547 node->elem_size = sizeof(guint8) * 6;
548 node->fill_array_func = fill_array_ether_value;
549 node->check_relation_func = check_relation_ether;
551 memcpy(&node->value.ether, ether_bytes, 6);
553 gnode = g_node_new(node);
558 dfilter_mknode_ipxnet_value(guint32 ipx_net_val)
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);
575 dfilter_mknode_ipv4_value(char *host)
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);
593 dfilter_mknode_bytes_value(GByteArray *barray)
598 node = g_mem_chunk_alloc(gmc_dfilter_nodes);
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);
612 dfilter_mknode_boolean_value(gint truth_value)
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);
629 string_to_value(char *s)
634 val = strtoul(s, &endptr, 0);
635 /* I should probably check errno here */
641 dfilter_mknode_existence(gint id)
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);