4 * Parser for display filters
6 * $Id: dfilter-grammar.y,v 1.1 2000/09/27 04:54:47 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.
32 #ifdef HAVE_SYS_TYPES_H
33 # include <sys/types.h>
36 #ifdef HAVE_NETINET_IN_H
37 # include <netinet/in.h>
40 #ifdef NEED_SNPRINTF_H
46 # include "snprintf.h"
73 #include "dfilter-int.h"
79 static GNode* dfilter_mknode_join(GNode *n1, enum node_type ntype, int operand, GNode *n2);
80 static GNode* dfilter_mknode_unary(int operand, GNode *n2);
81 static GNode* dfilter_mknode_numeric_variable(gint id);
82 static GNode* dfilter_mknode_numeric_value(guint32 val);
83 static GNode* dfilter_mknode_floating_variable(gint id);
84 static GNode* dfilter_mknode_floating_value(double val);
85 static GNode* dfilter_mknode_ether_value(gchar*);
86 static GNode* dfilter_mknode_ether_variable(gint id);
87 static GNode* dfilter_mknode_ipxnet_value(guint32);
88 static GNode* dfilter_mknode_ipxnet_variable(gint id);
89 static GNode* dfilter_mknode_ipv4_value(char *host, int nmask_bits);
90 static GNode* dfilter_mknode_ipv4_variable(gint id);
91 static GNode* dfilter_mknode_ipv6_value(char *host);
92 static GNode* dfilter_mknode_ipv6_variable(gint id);
93 static GNode* dfilter_mknode_existence(gint id);
94 static GNode* dfilter_mknode_bytes_value(GByteArray *barray);
95 static GNode* dfilter_mknode_bytes_variable(gint id, gint offset, guint length);
96 static GNode* dfilter_mknode_string_value(char *s);
97 static GNode* dfilter_mknode_string_variable(gint id);
99 static guint32 string_to_guint32(char *s, gboolean *success);
100 static double string_to_double(char *s, gboolean *success);
101 static int ether_str_to_guint8_array(const char *s, guint8 *mac);
102 static guint dfilter_get_bytes_variable_offset(GNode *gnode);
103 static guint dfilter_get_bytes_value_length(GNode* gnode);
104 static void dfilter_set_bytes_variable_length(GNode *gnode, guint length);
105 static guint dfilter_get_bytes_variable_length(GNode *gnode);
106 static gint dfilter_get_bytes_variable_field_registered_length(GNode *gnode);
107 static char* dfilter_get_variable_abbrev(GNode *gnode);
108 static int check_bytes_variable_sanity(GNode *gnode);
110 /* This is the dfilter we're currently processing. It's how
111 * dfilter_compile communicates with us.
113 dfilter *global_df = NULL;
118 gint operand; /* logical, relation, alternation */
121 gint type; /* using macros defined below, in this yacc grammar */
131 %type <node> statement expression relation
132 %type <node> numeric_value numeric_variable
133 %type <node> floating_value floating_variable
134 %type <node> ether_value ether_variable
135 %type <node> ipxnet_value ipxnet_variable
136 %type <node> ipv4_value ipv4_variable
137 %type <node> ipv6_value ipv6_variable
138 %type <node> string_value string_variable
139 %type <node> variable_name
140 %type <node> bytes_value bytes_variable
142 %type <operand> numeric_relation
143 %type <operand> equality_relation
144 %type <operand> bytes_relation
146 %type <variable> any_variable_type
148 %token <variable> T_FT_UINT8
149 %token <variable> T_FT_UINT16
150 %token <variable> T_FT_UINT24
151 %token <variable> T_FT_UINT32
152 %token <variable> T_FT_INT8
153 %token <variable> T_FT_INT16
154 %token <variable> T_FT_INT24
155 %token <variable> T_FT_INT32
156 %token <variable> T_FT_ETHER
157 %token <variable> T_FT_IPv4
158 %token <variable> T_FT_IPv6
159 %token <variable> T_FT_NONE
160 %token <variable> T_FT_BYTES
161 %token <variable> T_FT_BOOLEAN
162 %token <variable> T_FT_STRING
163 %token <variable> T_FT_IPXNET
164 %token <variable> T_FT_DOUBLE
166 %token <string> T_VAL_UNQUOTED_STRING
167 %token <string> T_VAL_QUOTED_STRING
168 %token <string> T_VAL_BYTE_STRING
169 %token <byte_range> T_VAL_BYTE_RANGE
171 %token <operand> TOK_AND TOK_OR TOK_NOT TOK_XOR
172 %token <operand> TOK_EQ TOK_NE TOK_GT TOK_GE TOK_LT TOK_LE
181 statement: expression
183 global_df->dftree = $1;
185 | /* NULL */ { if (global_df != NULL) global_df->dftree = NULL; }
188 expression: '(' expression ')' { $$ = $2; }
189 | expression TOK_AND expression { $$ = dfilter_mknode_join($1, logical, $2, $3); }
190 | expression TOK_OR expression { $$ = dfilter_mknode_join($1, logical, $2, $3); }
191 | expression TOK_XOR expression { $$ = dfilter_mknode_join($1, logical, $2, $3); }
192 | TOK_NOT expression { $$ = dfilter_mknode_unary(TOK_NOT, $2); }
193 | relation { $$ = $1; }
194 | variable_name { $$ = $1; }
195 | expression error { YYABORT; }
198 relation: numeric_variable numeric_relation numeric_value
200 $$ = dfilter_mknode_join($1, relation, $2, $3);
202 | numeric_variable numeric_relation numeric_variable
204 $$ = dfilter_mknode_join($1, relation, $2, $3);
207 | floating_variable numeric_relation floating_value
209 $$ = dfilter_mknode_join($1, relation, $2, $3);
211 | floating_variable numeric_relation floating_variable
213 $$ = dfilter_mknode_join($1, relation, $2, $3);
216 | ether_variable equality_relation ether_value
218 $$ = dfilter_mknode_join($1, relation, $2, $3);
220 | ether_variable equality_relation ether_variable
222 $$ = dfilter_mknode_join($1, relation, $2, $3);
225 | ipxnet_variable equality_relation ipxnet_value
227 $$ = dfilter_mknode_join($1, relation, $2, $3);
229 | ipxnet_variable equality_relation ipxnet_variable
231 $$ = dfilter_mknode_join($1, relation, $2, $3);
234 | string_variable equality_relation string_value
236 $$ = dfilter_mknode_join($1, relation, $2, $3);
238 | string_variable equality_relation string_variable
240 $$ = dfilter_mknode_join($1, relation, $2, $3);
244 | ipv4_variable numeric_relation ipv4_value
246 $$ = dfilter_mknode_join($1, relation, $2, $3);
248 | ipv4_variable numeric_relation ipv4_variable
250 $$ = dfilter_mknode_join($1, relation, $2, $3);
253 | ipv6_variable equality_relation ipv6_value
255 $$ = dfilter_mknode_join($1, relation, $2, $3);
257 | ipv6_variable equality_relation ipv6_variable
259 $$ = dfilter_mknode_join($1, relation, $2, $3);
262 | bytes_variable bytes_relation bytes_value
266 a_len = dfilter_get_bytes_variable_length($1);
267 b_len = dfilter_get_bytes_value_length($3);
270 dfilter_set_bytes_variable_length($1, b_len);
274 if (!check_bytes_variable_sanity($1)) {
278 if (a_len != b_len) {
279 dfilter_fail("Field \"%s\" has %u byte%s being compared, but %u byte%s "
281 dfilter_get_variable_abbrev($1),
282 a_len, plurality(a_len, "", "s"),
283 b_len, plurality(b_len, "", "s"),
284 plurality(b_len, "was", "were"));
288 $$ = dfilter_mknode_join($1, relation, $2, $3);
290 | bytes_variable bytes_relation bytes_variable
294 a_len = dfilter_get_bytes_variable_length($1);
295 b_len = dfilter_get_bytes_variable_length($3);
297 if (!check_bytes_variable_sanity($1)) {
301 if (!check_bytes_variable_sanity($3)) {
305 if (a_len != b_len) {
306 dfilter_fail("Fields \"%s\" and \"%s\" are being compared with "
307 "disparate lengths of %u byte%s and %u byte%s.",
308 dfilter_get_variable_abbrev($1),
309 dfilter_get_variable_abbrev($3),
310 a_len, plurality(a_len, "", "s"),
311 b_len, plurality(b_len, "", "s"));
315 $$ = dfilter_mknode_join($1, relation, $2, $3);
321 numeric_value: T_VAL_UNQUOTED_STRING
324 $$ = dfilter_mknode_numeric_value(string_to_guint32($1, &success));
332 ether_value: T_VAL_BYTE_STRING
334 $$ = dfilter_mknode_ether_value($1);
342 string_value: T_VAL_UNQUOTED_STRING
344 $$ = dfilter_mknode_string_value($1);
350 | T_VAL_QUOTED_STRING
352 $$ = dfilter_mknode_string_value($1);
360 ipxnet_value: T_VAL_UNQUOTED_STRING
363 $$ = dfilter_mknode_ipxnet_value(string_to_guint32($1, &success));
371 floating_value: T_VAL_UNQUOTED_STRING
374 $$ = dfilter_mknode_floating_value(string_to_double($1, &success));
383 /* e.g., 0.0, 0.1, 0.01 ... */
385 $$ = dfilter_mknode_floating_value(string_to_double($1, &success));
393 ipv4_value: T_VAL_UNQUOTED_STRING
395 $$ = dfilter_mknode_ipv4_value($1, 32);
404 $$ = dfilter_mknode_ipv4_value($1, 32);
411 | T_VAL_UNQUOTED_STRING '/' T_VAL_UNQUOTED_STRING
416 nmask_bits = string_to_guint32($3, &success);
423 if (nmask_bits > 32) {
424 dfilter_fail("The number of netmask bits in \"%s/%s\" should "
425 "be between 0 and 32.", $1, $3);
431 $$ = dfilter_mknode_ipv4_value($1, nmask_bits);
439 | T_VAL_BYTE_STRING '/' T_VAL_UNQUOTED_STRING
444 nmask_bits = string_to_guint32($3, &success);
451 if (nmask_bits > 32) {
452 dfilter_fail("The number of netmask bits in \"%s/%s\" should "
453 "be between 0 and 32.", $1, $3);
458 $$ = dfilter_mknode_ipv4_value($1, nmask_bits);
467 ipv6_value: T_VAL_UNQUOTED_STRING
469 $$ = dfilter_mknode_ipv6_value($1);
478 $$ = dfilter_mknode_ipv6_value($1);
486 bytes_value: T_VAL_BYTE_STRING
490 /* the next function appends to list_of_byte_arrays for me */
491 barray = byte_str_to_guint8_array($1);
492 $$ = dfilter_mknode_bytes_value(barray);
496 | T_VAL_UNQUOTED_STRING
503 val32 = string_to_guint32($1, &success);
509 dfilter_fail("The value \"%s\" cannot be stored in a single-byte byte-string. "
510 "Use the multi-byte \"xx:yy\" representation.", $1);
514 val8 = (guint8) val32;
515 barray = g_byte_array_new();
516 global_df->list_of_byte_arrays = g_slist_append(global_df->list_of_byte_arrays, barray);
517 g_byte_array_append(barray, &val8, 1);
519 $$ = dfilter_mknode_bytes_value(barray);
524 numeric_variable: T_FT_UINT8 { $$ = dfilter_mknode_numeric_variable($1.id); }
525 | T_FT_UINT16 { $$ = dfilter_mknode_numeric_variable($1.id); }
526 | T_FT_UINT24 { $$ = dfilter_mknode_numeric_variable($1.id); }
527 | T_FT_UINT32 { $$ = dfilter_mknode_numeric_variable($1.id); }
528 | T_FT_INT8 { $$ = dfilter_mknode_numeric_variable($1.id); }
529 | T_FT_INT16 { $$ = dfilter_mknode_numeric_variable($1.id); }
530 | T_FT_INT24 { $$ = dfilter_mknode_numeric_variable($1.id); }
531 | T_FT_INT32 { $$ = dfilter_mknode_numeric_variable($1.id); }
534 ether_variable: T_FT_ETHER { $$ = dfilter_mknode_ether_variable($1.id); }
537 floating_variable: T_FT_DOUBLE { $$ = dfilter_mknode_floating_variable($1.id); }
540 ipxnet_variable: T_FT_IPXNET { $$ = dfilter_mknode_ipxnet_variable($1.id); }
543 ipv4_variable: T_FT_IPv4 { $$ = dfilter_mknode_ipv4_variable($1.id); }
546 ipv6_variable: T_FT_IPv6 { $$ = dfilter_mknode_ipv6_variable($1.id); }
549 string_variable: T_FT_STRING { $$ = dfilter_mknode_string_variable($1.id); }
552 variable_name: any_variable_type
557 if ($1.type == T_FT_BOOLEAN) {
558 /* Make "variable == TRUE" for BOOLEAN variable */
559 variable = dfilter_mknode_numeric_variable($1.id);
560 value = dfilter_mknode_numeric_value(TRUE);
561 $$ = dfilter_mknode_join(variable, relation, TOK_EQ, value);
564 $$ = dfilter_mknode_existence($1.id);
569 bytes_variable: any_variable_type T_VAL_BYTE_RANGE
571 $$ = dfilter_mknode_bytes_variable($1.id, $2.offset, $2.length);
575 any_variable_type: T_FT_UINT8 { $$ = $1; }
576 | T_FT_UINT16 { $$ = $1; }
577 | T_FT_UINT24 { $$ = $1; }
578 | T_FT_UINT32 { $$ = $1; }
579 | T_FT_INT8 { $$ = $1; }
580 | T_FT_INT16 { $$ = $1; }
581 | T_FT_INT24 { $$ = $1; }
582 | T_FT_INT32 { $$ = $1; }
583 | T_FT_DOUBLE { $$ = $1; }
584 | T_FT_ETHER { $$ = $1; }
585 | T_FT_IPv4 { $$ = $1; }
586 | T_FT_IPv6 { $$ = $1; }
587 | T_FT_IPXNET { $$ = $1; }
588 | T_FT_NONE { $$ = $1; }
589 | T_FT_BYTES { $$ = $1; }
590 | T_FT_BOOLEAN { $$ = $1; }
591 | T_FT_STRING { $$ = $1; }
594 numeric_relation: TOK_EQ { $$ = TOK_EQ; }
595 | TOK_NE { $$ = TOK_NE; }
596 | TOK_GT { $$ = TOK_GT; }
597 | TOK_GE { $$ = TOK_GE; }
598 | TOK_LT { $$ = TOK_LT; }
599 | TOK_LE { $$ = TOK_LE; }
602 equality_relation: TOK_EQ { $$ = TOK_EQ; }
603 | TOK_NE { $$ = TOK_NE; }
606 bytes_relation: TOK_EQ { $$ = TOK_EQ; }
607 | TOK_NE { $$ = TOK_NE; }
608 | TOK_GT { $$ = TOK_GT; }
609 | TOK_LT { $$ = TOK_LT; }
615 dfilter_mknode_join(GNode *n1, enum node_type ntype, int operand, GNode *n2)
617 dfilter_node *node_root;
620 node_root = g_mem_chunk_alloc(global_df->node_memchunk);
621 node_root->ntype = ntype;
622 node_root->elem_size = 0;
623 node_root->fill_array_variable_func = NULL;
624 node_root->fill_array_value_func = NULL;
625 node_root->check_relation_func = NULL;
626 if (ntype == relation) {
627 node_root->value.relation = operand;
629 else if (ntype == logical) {
630 node_root->value.logical = operand;
633 g_assert_not_reached();
636 gnode_root = g_node_new(node_root);
637 g_node_append(gnode_root, n1);
638 g_node_append(gnode_root, n2);
644 dfilter_mknode_unary(int operand, GNode *n2)
646 dfilter_node *node_root;
649 node_root = g_mem_chunk_alloc(global_df->node_memchunk);
650 node_root->ntype = logical;
651 node_root->value.logical = operand;
652 node_root->elem_size = 0;
653 node_root->fill_array_variable_func = NULL;
654 node_root->fill_array_value_func = NULL;
655 node_root->check_relation_func = NULL;
657 gnode_root = g_node_new(node_root);
658 g_node_append(gnode_root, n2);
665 dfilter_mknode_numeric_variable(gint id)
670 node = g_mem_chunk_alloc(global_df->node_memchunk);
671 node->ntype = variable;
672 node->elem_size = sizeof(guint32);
673 node->fill_array_variable_func = fill_array_numeric_variable;
674 node->fill_array_value_func = NULL;
675 node->check_relation_func = check_relation_numeric;
676 node->value.variable = id;
677 gnode = g_node_new(node);
683 dfilter_mknode_ether_variable(gint id)
688 node = g_mem_chunk_alloc(global_df->node_memchunk);
689 node->ntype = variable;
690 node->elem_size = sizeof(guint8) * 6;
691 node->fill_array_variable_func = fill_array_ether_variable;
692 node->fill_array_value_func = NULL;
693 node->check_relation_func = check_relation_ether;
694 node->value.variable = id;
695 gnode = g_node_new(node);
701 dfilter_mknode_floating_variable(gint id)
706 node = g_mem_chunk_alloc(global_df->node_memchunk);
707 node->ntype = variable;
708 node->elem_size = sizeof(double);
709 node->fill_array_variable_func = fill_array_floating_variable;
710 node->fill_array_value_func = NULL;
711 node->check_relation_func = check_relation_floating;
712 node->value.variable = id;
713 gnode = g_node_new(node);
719 dfilter_mknode_ipxnet_variable(gint id)
724 node = g_mem_chunk_alloc(global_df->node_memchunk);
725 node->ntype = variable;
726 node->elem_size = sizeof(guint8) * 4;
727 node->fill_array_variable_func = fill_array_numeric_variable; /* cheating ! */
728 node->fill_array_value_func = NULL;
729 node->check_relation_func = check_relation_numeric; /* cheating ! */
730 node->value.variable = id;
731 gnode = g_node_new(node);
737 dfilter_mknode_ipv4_variable(gint id)
742 node = g_mem_chunk_alloc(global_df->node_memchunk);
743 node->ntype = variable;
744 node->elem_size = sizeof(ipv4_addr);
745 node->fill_array_variable_func = fill_array_ipv4_variable;
746 node->fill_array_value_func = NULL;
747 node->check_relation_func = check_relation_ipv4;
748 node->value.variable = id;
749 gnode = g_node_new(node);
755 dfilter_mknode_ipv6_variable(gint id)
760 node = g_mem_chunk_alloc(global_df->node_memchunk);
761 node->ntype = variable;
762 node->elem_size = 16;
763 node->fill_array_variable_func = fill_array_ipv6_variable;
764 node->fill_array_value_func = NULL;
765 node->check_relation_func = check_relation_ipv6;
766 node->value.variable = id;
767 gnode = g_node_new(node);
773 dfilter_mknode_string_variable(gint id)
778 node = g_mem_chunk_alloc(global_df->node_memchunk);
779 node->ntype = variable;
780 node->elem_size = sizeof(char*);
781 node->fill_array_variable_func = fill_array_string_variable;
782 node->fill_array_value_func = NULL;
783 node->check_relation_func = check_relation_string;
784 node->value.variable = id;
785 gnode = g_node_new(node);
791 dfilter_mknode_bytes_variable(gint id, gint offset, guint length)
796 node = g_mem_chunk_alloc(global_df->node_memchunk);
797 node->ntype = variable;
798 node->elem_size = sizeof(GByteArray*);
799 node->fill_array_variable_func = fill_array_bytes_variable;
800 node->fill_array_value_func = NULL;
801 node->check_relation_func = check_relation_bytes;
802 node->value.variable = id;
803 node->offset = offset;
804 node->length = length;
805 gnode = g_node_new(node);
810 /* Gets length of variable represented by node from proto_register */
812 dfilter_get_bytes_variable_field_registered_length(GNode *gnode)
814 dfilter_node *node = gnode->data;
816 /* Is this really a bytes_variable? */
817 g_assert(node->fill_array_variable_func == fill_array_bytes_variable);
819 return proto_registrar_get_length(node->value.variable);
822 /* Sets the length of a bytes_variable node */
824 dfilter_set_bytes_variable_length(GNode *gnode, guint length)
826 dfilter_node *node = gnode->data;
828 /* Is this really a bytes_variable? */
829 g_assert(node->fill_array_variable_func == fill_array_bytes_variable);
831 node->length = length;
834 /* Gets the length of a bytes_variable node */
836 dfilter_get_bytes_variable_length(GNode *gnode)
838 dfilter_node *node = gnode->data;
840 /* Is this really a bytes_variable? */
841 g_assert(node->fill_array_variable_func == fill_array_bytes_variable);
846 /* Gets the offset of a bytes_variable node */
848 dfilter_get_bytes_variable_offset(GNode *gnode)
850 dfilter_node *node = gnode->data;
852 /* Is this really a bytes_variable? */
853 g_assert(node->fill_array_variable_func == fill_array_bytes_variable);
859 dfilter_get_variable_abbrev(GNode *gnode)
861 dfilter_node *node = gnode->data;
863 return proto_registrar_get_abbrev(node->value.variable);
867 dfilter_mknode_numeric_value(guint32 val)
872 node = g_mem_chunk_alloc(global_df->node_memchunk);
873 node->ntype = numeric;
874 node->elem_size = sizeof(guint32);
875 node->fill_array_variable_func = NULL;
876 node->fill_array_value_func = fill_array_numeric_value;
877 node->check_relation_func = check_relation_numeric;
878 node->value.numeric = val;
879 gnode = g_node_new(node);
885 dfilter_mknode_floating_value(double val)
890 node = g_mem_chunk_alloc(global_df->node_memchunk);
891 node->ntype = floating;
892 node->elem_size = sizeof(double);
893 node->fill_array_variable_func = NULL;
894 node->fill_array_value_func = fill_array_floating_value;
895 node->check_relation_func = check_relation_floating;
896 node->value.floating = val;
897 gnode = g_node_new(node);
902 /* Returns NULL on bad parse of ETHER value */
904 dfilter_mknode_ether_value(gchar *byte_string)
909 node = g_mem_chunk_alloc(global_df->node_memchunk);
911 node->elem_size = sizeof(guint8) * 6;
912 node->fill_array_variable_func = NULL;
913 node->fill_array_value_func = fill_array_ether_value;
914 node->check_relation_func = check_relation_ether;
916 if (!ether_str_to_guint8_array(byte_string, &node->value.ether[0])) {
917 /* Rather than free the mem_chunk allocation, let it
918 * stay. It will be cleaned up when "dfilter_compile()"
919 * calls "dfilter_destroy()". */
920 dfilter_fail("\"%s\" is not a valid hardware address.",
925 gnode = g_node_new(node);
930 dfilter_mknode_ipxnet_value(guint32 ipx_net_val)
935 node = g_mem_chunk_alloc(global_df->node_memchunk);
936 node->ntype = ipxnet;
937 node->elem_size = sizeof(guint8) * 4;
938 node->fill_array_variable_func = NULL;
939 node->fill_array_value_func = fill_array_numeric_value; /* cheating ! */
940 node->check_relation_func = check_relation_numeric; /* cheating ! */
941 node->value.numeric = ipx_net_val;
942 gnode = g_node_new(node);
947 /* Returns NULL on bad parse of IP value */
949 dfilter_mknode_ipv4_value(char *host, int nmask_bits)
955 node = g_mem_chunk_alloc(global_df->node_memchunk);
956 node->ntype = numeric;
957 node->elem_size = sizeof(ipv4_addr);
958 node->fill_array_variable_func = NULL;
959 node->fill_array_value_func = fill_array_ipv4_value;
960 node->check_relation_func = check_relation_ipv4;
961 if (!get_host_ipaddr(host, &addr)) {
962 /* Rather than free the mem_chunk allocation, let it
963 * stay. It will be cleaned up when "dfilter_compile()"
964 * calls "dfilter_destroy()". */
965 dfilter_fail("\"%s\" isn't a valid host name or IP address.",
969 ipv4_addr_set_host_order_addr(&node->value.ipv4, addr);
970 ipv4_addr_set_netmask_bits(&node->value.ipv4, nmask_bits);
972 gnode = g_node_new(node);
976 /* Returns NULL on bad parse of IPv6 value */
978 dfilter_mknode_ipv6_value(char *host)
983 node = g_mem_chunk_alloc(global_df->node_memchunk);
985 node->elem_size = 16;
986 node->fill_array_variable_func = NULL;
987 node->fill_array_value_func = fill_array_ipv6_value;
988 node->check_relation_func = check_relation_ipv6;
990 if (!get_host_ipaddr6(host, (struct e_in6_addr*)&node->value.ipv6[0])) {
991 /* Rather than free the mem_chunk allocation, let it
992 * stay. It will be cleaned up when "dfilter_compile()"
993 * calls "dfilter_destroy()". */
994 dfilter_fail("\"%s\" isn't a valid IPv6 address.",
999 gnode = g_node_new(node);
1005 dfilter_mknode_string_value(char *s)
1010 node = g_mem_chunk_alloc(global_df->node_memchunk);
1011 node->ntype = string;
1012 node->elem_size = sizeof(char*);
1013 node->fill_array_variable_func = NULL;
1014 node->fill_array_value_func = fill_array_string_value;
1015 node->check_relation_func = check_relation_string;
1016 node->value.string = g_strdup(s);
1017 global_df->list_of_strings = g_slist_append(global_df->list_of_strings,
1018 node->value.string);
1019 gnode = g_node_new(node);
1026 dfilter_mknode_bytes_value(GByteArray *barray)
1031 node = g_mem_chunk_alloc(global_df->node_memchunk);
1032 node->ntype = bytes;
1033 node->elem_size = sizeof(GByteArray*);
1034 node->fill_array_variable_func = NULL;
1035 node->fill_array_value_func = fill_array_bytes_value;
1036 node->check_relation_func = check_relation_bytes;
1037 node->value.bytes = barray;
1038 node->offset = G_MAXINT;
1039 node->length = barray->len;
1040 gnode = g_node_new(node);
1045 /* Given a node representing a bytes_value, returns
1046 * the length of the byte array */
1048 dfilter_get_bytes_value_length(GNode* gnode)
1050 dfilter_node *node = gnode->data;
1052 g_assert(node->ntype == bytes);
1053 return node->length;
1057 string_to_guint32(char *s, gboolean *success)
1062 val = strtoul(s, &endptr, 0);
1064 if (endptr == s || *endptr != '\0') {
1065 /* This isn't a valid number. */
1066 dfilter_fail("\"%s\" is not a valid number.", s);
1069 if (errno == ERANGE) {
1071 if (val == ULONG_MAX) {
1072 dfilter_fail("\"%s\" causes an integer overflow.", s);
1075 dfilter_fail("\"%s\" is not an integer.", s);
1079 return (guint32)val;
1083 string_to_double(char *s, gboolean *success)
1085 char *endptr = NULL;
1088 retval = strtod(s, &endptr);
1092 dfilter_fail("\"%s\" is not a valid floating-point number.", s);
1096 if (errno == ERANGE) {
1099 dfilter_fail("\"%s\" causes a floating-point underflow.", s);
1101 else if (retval == HUGE_VAL) {
1102 dfilter_fail("\"%s\" causes a floating-point overflow.", s);
1105 dfilter_fail("\"%s\" is not a valid floating-point.", s);
1112 dfilter_mknode_existence(gint id)
1117 node = g_mem_chunk_alloc(global_df->node_memchunk);
1118 node->ntype = existence;
1119 node->elem_size = sizeof(guint32);
1120 node->fill_array_variable_func = NULL;
1121 node->fill_array_value_func = NULL;
1122 node->check_relation_func = NULL;
1123 node->value.variable = id;
1124 gnode = g_node_new(node);
1130 /* converts a string representing an ether HW address
1131 * to a guint8 array.
1133 * Returns 0 on failure, 1 on success.
1136 ether_str_to_guint8_array(const char *s, guint8 *mac)
1138 char ether_str[18]; /* 2+1+2+1+2+1+2+1+2+1+2 + 1 */
1142 if (strlen(s) > 17) {
1145 strcpy(ether_str, s); /* local copy of string */
1147 while ((p = strtok(str, "-:."))) {
1148 /* catch short strings with too many hex bytes: 0.0.0.0.0.0.0 */
1152 mac[i] = (guint8) strtoul(p, NULL, 16);
1154 /* subsequent calls to strtok() require NULL as arg 1 */
1158 return 0; /* failed to read 6 hex pairs */
1160 return 1; /* read exactly 6 hex pairs */
1165 check_bytes_variable_sanity(GNode *gnode)
1167 int a_off, a_len, reg_len, t_off;
1169 a_off = dfilter_get_bytes_variable_offset(gnode);
1170 a_len = dfilter_get_bytes_variable_length(gnode);
1171 reg_len = dfilter_get_bytes_variable_field_registered_length(gnode);
1174 t_off = a_off >= 0 ? a_off : reg_len + a_off;
1175 if (t_off + a_len > reg_len) {
1176 dfilter_fail("The \"%s\" field is only %u byte%s wide, but "
1177 "%u byte%s %s supplied.",
1178 dfilter_get_variable_abbrev(gnode),
1179 reg_len, plurality(reg_len, "", "s"),
1180 a_len, plurality(a_len, "", "s"),
1181 plurality(a_len, "was", "were"));