Get rid of a debugging fprintf.
[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.38 2000/02/05 06:07:16 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 #include <errno.h>
55 #include <math.h>
56
57 #ifndef _STDLIB_H
58 #include <stdlib.h>
59 #endif
60
61 #ifndef __PROTO_H__
62 #include "proto.h"
63 #endif
64
65 #ifndef __PACKET_H__
66 #include "packet.h"
67 #endif
68
69 #ifndef __DFILTER_H__
70 #include "dfilter.h"
71 #endif
72
73 #include "dfilter-int.h"
74
75 #ifndef __RESOLV_H__
76 #include "resolv.h"
77 #endif
78
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
97 static guint32 string_to_guint32(char *s, gboolean *success);
98 static double string_to_double(char *s, gboolean *success);
99 static int ether_str_to_guint8_array(const char *s, guint8 *mac);
100 static guint dfilter_get_bytes_variable_offset(GNode *gnode);
101 static guint dfilter_get_bytes_value_length(GNode* gnode);
102 static void dfilter_set_bytes_variable_length(GNode *gnode, guint length);
103 static guint dfilter_get_bytes_variable_length(GNode *gnode);
104 static gint dfilter_get_bytes_variable_field_registered_length(GNode *gnode);
105 static char* dfilter_get_variable_abbrev(GNode *gnode);
106 static int check_bytes_variable_sanity(GNode *gnode);
107
108 /* This is the dfilter we're currently processing. It's how
109  * dfilter_compile communicates with us.
110  */
111 dfilter *global_df = NULL;
112
113 %}
114
115 %union {
116         gint            operand;        /* logical, relation, alternation */
117         struct {
118                 gint    id;
119                 gint    type;           /* using macros defined below, in this yacc grammar */
120         } variable;
121         GNode*          node;
122         gchar*          string;
123         struct {
124                 gint    offset;
125                 guint   length;
126         } byte_range;
127 }
128
129 %type <node>    statement expression relation
130 %type <node>    numeric_value numeric_variable
131 %type <node>    floating_value floating_variable
132 %type <node>    ether_value ether_variable
133 %type <node>    ipxnet_value ipxnet_variable
134 %type <node>    ipv4_value ipv4_variable
135 %type <node>    ipv6_value ipv6_variable
136 %type <node>    variable_name
137 %type <node>    bytes_value bytes_variable
138
139 %type <operand> numeric_relation
140 %type <operand> equality_relation
141 %type <operand> bytes_relation
142
143 %type <variable>        any_variable_type
144
145 %token <variable>       T_FT_UINT8
146 %token <variable>       T_FT_UINT16
147 %token <variable>       T_FT_UINT24
148 %token <variable>       T_FT_UINT32
149 %token <variable>       T_FT_INT8
150 %token <variable>       T_FT_INT16
151 %token <variable>       T_FT_INT24
152 %token <variable>       T_FT_INT32
153 %token <variable>       T_FT_ETHER
154 %token <variable>       T_FT_IPv4
155 %token <variable>       T_FT_IPv6
156 %token <variable>       T_FT_NONE
157 %token <variable>       T_FT_BYTES
158 %token <variable>       T_FT_BOOLEAN
159 %token <variable>       T_FT_STRING
160 %token <variable>       T_FT_IPXNET
161 %token <variable>       T_FT_DOUBLE
162
163 %token <string>         T_VAL_UNQUOTED_STRING
164 %token <string>         T_VAL_BYTE_STRING
165 %token <byte_range>     T_VAL_BYTE_RANGE
166
167 %token <operand>        TOK_AND TOK_OR TOK_NOT TOK_XOR
168 %token <operand>        TOK_EQ TOK_NE TOK_GT TOK_GE TOK_LT TOK_LE
169
170 %expect 4
171 %left TOK_AND
172 %left TOK_OR TOK_XOR
173 %nonassoc TOK_NOT
174
175 %%
176
177 statement: expression
178                 {
179                         global_df->dftree = $1;
180                 }
181         |       /* NULL */ { if (global_df != NULL) global_df->dftree = NULL; }
182         ;
183
184 expression:     '(' expression ')' { $$ = $2; }
185         |       expression TOK_AND expression { $$ = dfilter_mknode_join($1, logical, $2, $3); }
186         |       expression TOK_OR expression { $$ = dfilter_mknode_join($1, logical, $2, $3); }
187         |       expression TOK_XOR expression { $$ = dfilter_mknode_join($1, logical, $2, $3); }
188         |       TOK_NOT expression { $$ = dfilter_mknode_unary(TOK_NOT, $2); }
189         |       relation { $$ = $1; }
190         |       variable_name { $$ = $1; }
191         |       expression error { YYABORT; }
192         ;
193
194 relation:       numeric_variable numeric_relation numeric_value
195                 {
196                         $$ = dfilter_mknode_join($1, relation, $2, $3);
197                 }
198         |       numeric_variable numeric_relation numeric_variable
199                 {
200                         $$ = dfilter_mknode_join($1, relation, $2, $3);
201                 }
202
203         |       floating_variable numeric_relation floating_value
204                 {
205                         $$ = dfilter_mknode_join($1, relation, $2, $3);
206                 }
207         |       floating_variable numeric_relation floating_variable
208                 {
209                         $$ = dfilter_mknode_join($1, relation, $2, $3);
210                 }
211
212         |       ether_variable equality_relation ether_value
213                 {
214                         $$ = dfilter_mknode_join($1, relation, $2, $3);
215                 }
216         |       ether_variable equality_relation ether_variable
217                 {
218                         $$ = dfilter_mknode_join($1, relation, $2, $3);
219                 }
220
221         |       ipxnet_variable equality_relation ipxnet_value
222                 {
223                         $$ = dfilter_mknode_join($1, relation, $2, $3);
224                 }
225         |       ipxnet_variable equality_relation ipxnet_variable
226                 {
227                         $$ = dfilter_mknode_join($1, relation, $2, $3);
228                 }
229
230
231         |       ipv4_variable numeric_relation ipv4_value
232                 {
233                         $$ = dfilter_mknode_join($1, relation, $2, $3);
234                 }
235         |       ipv4_variable numeric_relation ipv4_variable
236                 {
237                         $$ = dfilter_mknode_join($1, relation, $2, $3);
238                 }
239
240         |       ipv6_variable equality_relation ipv6_value
241                 {
242                         $$ = dfilter_mknode_join($1, relation, $2, $3);
243                 }
244         |       ipv6_variable equality_relation ipv6_variable
245                 {
246                         $$ = dfilter_mknode_join($1, relation, $2, $3);
247                 }
248
249         |       bytes_variable bytes_relation bytes_value
250                 {
251                         int a_len, b_len;
252
253                         a_len = dfilter_get_bytes_variable_length($1);
254                         b_len = dfilter_get_bytes_value_length($3);
255
256                         if (a_len == 0) {
257                                 dfilter_set_bytes_variable_length($1, b_len);
258                                 a_len = b_len;
259                         }
260
261                         if (!check_bytes_variable_sanity($1)) {
262                                 YYERROR;
263                         }
264
265                         if (a_len != b_len) {
266                                 dfilter_fail("Field \"%s\" has %u byte%s being compared, but %u byte%s "
267                                         "%s supplied.",
268                                         dfilter_get_variable_abbrev($1),
269                                         a_len, plurality(a_len, "", "s"),
270                                         b_len, plurality(b_len, "", "s"),
271                                                plurality(b_len, "was", "were"));
272                                 YYERROR;
273                         }
274
275                         $$ = dfilter_mknode_join($1, relation, $2, $3);
276                 }
277         |       bytes_variable bytes_relation bytes_variable
278                 {
279                         int a_len, b_len;
280
281                         a_len = dfilter_get_bytes_variable_length($1);
282                         b_len = dfilter_get_bytes_variable_length($3);
283
284                         if (!check_bytes_variable_sanity($1)) {
285                                 YYERROR;
286                         }
287
288                         if (!check_bytes_variable_sanity($3)) {
289                                 YYERROR;
290                         }
291
292                         if (a_len != b_len) {
293                                 dfilter_fail("Fields \"%s\" and \"%s\" are being compared with "
294                                         "disparate lengths of %u byte%s and %u byte%s.",
295                                         dfilter_get_variable_abbrev($1),
296                                         dfilter_get_variable_abbrev($3),
297                                         a_len, plurality(a_len, "", "s"),
298                                         b_len, plurality(b_len, "", "s"));
299                                 YYERROR;
300                         }
301
302                         $$ = dfilter_mknode_join($1, relation, $2, $3);
303                 }
304
305         ;
306
307
308 numeric_value:  T_VAL_UNQUOTED_STRING
309         {
310                 gboolean success;
311                 $$ = dfilter_mknode_numeric_value(string_to_guint32($1, &success));
312                 g_free($1);
313                 if (!success) {
314                         YYERROR;
315                 }
316          }
317         ;
318
319 ether_value:    T_VAL_BYTE_STRING
320         {
321                 $$ = dfilter_mknode_ether_value($1);
322                 g_free($1);
323                 if ($$ == NULL) {
324                         YYERROR;
325                 }
326         }
327         ;
328
329 ipxnet_value:   T_VAL_UNQUOTED_STRING
330         {
331                 gboolean success;
332                 $$ = dfilter_mknode_ipxnet_value(string_to_guint32($1, &success));
333                 g_free($1);
334                 if (!success) {
335                         YYERROR;
336                 }
337         }
338         ;
339
340 floating_value: T_VAL_UNQUOTED_STRING
341         {
342                 gboolean success;
343                 $$ = dfilter_mknode_floating_value(string_to_double($1, &success));
344                 g_free($1);
345                 if (!success) {
346                         YYERROR;
347                 }
348         }
349
350         |       T_VAL_BYTE_STRING
351         {
352                 /* e.g., 0.0, 0.1, 0.01 ... */
353                 gboolean success;
354                 $$ = dfilter_mknode_floating_value(string_to_double($1, &success));
355                 g_free($1);
356                 if (!success) {
357                         YYERROR;
358                 }
359         }
360         ;
361
362 ipv4_value:     T_VAL_UNQUOTED_STRING
363         {
364                 $$ = dfilter_mknode_ipv4_value($1, 32);
365                 g_free($1);
366                 if ($$ == NULL) {
367                         YYERROR;
368                 }
369         }
370
371         |       T_VAL_BYTE_STRING
372         {
373                 $$ = dfilter_mknode_ipv4_value($1, 32);
374                 g_free($1);
375                 if ($$ == NULL) {
376                         YYERROR;
377                 }
378         }
379
380         |       T_VAL_UNQUOTED_STRING '/' T_VAL_UNQUOTED_STRING
381         {
382                 gboolean        success;
383                 guint32         nmask_bits;
384
385                 nmask_bits = string_to_guint32($3, &success);
386                 if (!success) {
387                         g_free($1);
388                         g_free($3);
389                         YYERROR;
390                 }
391
392                 if (nmask_bits > 32) {
393                         dfilter_fail("The number of netmask bits in \"%s/%s\" should "
394                                 "be between 0 and 32.", $1, $3);
395                         g_free($1);
396                         g_free($3);
397                         YYERROR;
398                 }
399
400                 $$ = dfilter_mknode_ipv4_value($1, nmask_bits);
401                 g_free($1);
402                 g_free($3);
403                 if ($$ == NULL) {
404                         YYERROR;
405                 }
406         }
407
408         |       T_VAL_BYTE_STRING '/' T_VAL_UNQUOTED_STRING
409         {
410                 gboolean        success;
411                 guint32         nmask_bits;
412
413                 nmask_bits = string_to_guint32($3, &success);
414                 if (!success) {
415                         g_free($1);
416                         g_free($3);
417                         YYERROR;
418                 }
419
420                 if (nmask_bits > 32) {
421                         dfilter_fail("The number of netmask bits in \"%s/%s\" should "
422                                 "be between 0 and 32.", $1, $3);
423                         g_free($1);
424                         g_free($3);
425                         YYERROR;
426                 }
427                 $$ = dfilter_mknode_ipv4_value($1, nmask_bits);
428                 g_free($1);
429                 g_free($3);
430                 if ($$ == NULL) {
431                         YYERROR;
432                 }
433         }
434         ;
435
436 ipv6_value:     T_VAL_UNQUOTED_STRING
437                 {
438                         $$ = dfilter_mknode_ipv6_value($1);
439                         g_free($1);
440                         if ($$ == NULL) {
441                                 YYERROR;
442                         }
443                 }
444
445         |       T_VAL_BYTE_STRING
446                 {
447                         $$ = dfilter_mknode_ipv6_value($1);
448                         g_free($1);
449                         if ($$ == NULL) {
450                                 YYERROR;
451                         }
452                 }
453         ;
454
455 bytes_value:    T_VAL_BYTE_STRING
456         {
457                 GByteArray      *barray;
458
459                 /* the next function appends to list_of_byte_arrays for me */
460                 barray = byte_str_to_guint8_array($1);
461                 $$ = dfilter_mknode_bytes_value(barray);
462                 g_free($1);
463         }
464
465         |       T_VAL_UNQUOTED_STRING
466         {
467                 gboolean        success;
468                 guint32         val32;
469                 guint8          val8;
470                 GByteArray      *barray;
471
472                 val32 = string_to_guint32($1, &success);
473                 if (!success) {
474                         g_free($1);
475                         YYERROR;
476                 }
477                 if (val32 > 0xff) {
478                         dfilter_fail("The value \"%s\" cannot be stored in a single-byte byte-string. "
479                                 "Use the multi-byte \"xx:yy\" representation.", $1);
480                         g_free($1);
481                         YYERROR;
482                 }
483                 val8 = (guint8) val32;
484                 barray = g_byte_array_new();
485                 global_df->list_of_byte_arrays = g_slist_append(global_df->list_of_byte_arrays, barray);
486                 g_byte_array_append(barray, &val8, 1);
487
488                 $$ = dfilter_mknode_bytes_value(barray);
489                 g_free($1);
490         }
491         ;
492
493 numeric_variable:       T_FT_UINT8      { $$ = dfilter_mknode_numeric_variable($1.id); }
494         |               T_FT_UINT16     { $$ = dfilter_mknode_numeric_variable($1.id); }
495         |               T_FT_UINT24     { $$ = dfilter_mknode_numeric_variable($1.id); }
496         |               T_FT_UINT32     { $$ = dfilter_mknode_numeric_variable($1.id); }
497         |               T_FT_INT8       { $$ = dfilter_mknode_numeric_variable($1.id); }
498         |               T_FT_INT16      { $$ = dfilter_mknode_numeric_variable($1.id); }
499         |               T_FT_INT24      { $$ = dfilter_mknode_numeric_variable($1.id); }
500         |               T_FT_INT32      { $$ = dfilter_mknode_numeric_variable($1.id); }
501         ;
502
503 ether_variable:         T_FT_ETHER      { $$ = dfilter_mknode_ether_variable($1.id); }
504         ;
505
506 floating_variable:      T_FT_DOUBLE     { $$ = dfilter_mknode_floating_variable($1.id); }
507         ;
508
509 ipxnet_variable:        T_FT_IPXNET     { $$ = dfilter_mknode_ipxnet_variable($1.id); }
510         ;
511
512 ipv4_variable:          T_FT_IPv4       { $$ = dfilter_mknode_ipv4_variable($1.id); }
513         ;
514
515 ipv6_variable:          T_FT_IPv6       { $$ = dfilter_mknode_ipv6_variable($1.id); }
516         ;
517
518 variable_name:          any_variable_type
519         {
520                 GNode   *variable;
521                 GNode   *value;
522
523                 if ($1.type == T_FT_BOOLEAN) {
524                         /* Make "variable == TRUE" for BOOLEAN variable */
525                         variable = dfilter_mknode_numeric_variable($1.id);
526                         value = dfilter_mknode_numeric_value(TRUE);
527                         $$ = dfilter_mknode_join(variable, relation, TOK_EQ, value);
528                 }
529                 else {
530                         $$ = dfilter_mknode_existence($1.id);
531                 }
532         }
533         ;
534
535 bytes_variable:         any_variable_type T_VAL_BYTE_RANGE
536                 {
537                         $$ = dfilter_mknode_bytes_variable($1.id, $2.offset, $2.length);
538                 }
539         ;
540
541 any_variable_type:      T_FT_UINT8      { $$ = $1; }
542         |               T_FT_UINT16     { $$ = $1; }
543         |               T_FT_UINT24     { $$ = $1; }
544         |               T_FT_UINT32     { $$ = $1; }
545         |               T_FT_INT8       { $$ = $1; }
546         |               T_FT_INT16      { $$ = $1; }
547         |               T_FT_INT24      { $$ = $1; }
548         |               T_FT_INT32      { $$ = $1; }
549         |               T_FT_DOUBLE     { $$ = $1; }
550         |               T_FT_ETHER      { $$ = $1; }
551         |               T_FT_IPv4       { $$ = $1; }
552         |               T_FT_IPv6       { $$ = $1; }
553         |               T_FT_IPXNET     { $$ = $1; }
554         |               T_FT_NONE       { $$ = $1; }
555         |               T_FT_BYTES      { $$ = $1; }
556         |               T_FT_BOOLEAN    { $$ = $1; }
557         |               T_FT_STRING     { $$ = $1; }
558         ;
559
560 numeric_relation:       TOK_EQ { $$ = TOK_EQ; }
561         |               TOK_NE { $$ = TOK_NE; }
562         |               TOK_GT { $$ = TOK_GT; }
563         |               TOK_GE { $$ = TOK_GE; }
564         |               TOK_LT { $$ = TOK_LT; }
565         |               TOK_LE { $$ = TOK_LE; }
566         ;
567
568 equality_relation:      TOK_EQ { $$ = TOK_EQ; }
569         |               TOK_NE { $$ = TOK_NE; }
570         ;
571
572 bytes_relation:         TOK_EQ { $$ = TOK_EQ; }
573         |               TOK_NE { $$ = TOK_NE; }
574         |               TOK_GT { $$ = TOK_GT; }
575         |               TOK_LT { $$ = TOK_LT; }
576         ;
577
578 %%
579
580 static GNode*
581 dfilter_mknode_join(GNode *n1, enum node_type ntype, int operand, GNode *n2)
582 {
583         dfilter_node    *node_root;
584         GNode           *gnode_root;
585
586         node_root = g_mem_chunk_alloc(global_df->node_memchunk);
587         node_root->ntype = ntype;
588         node_root->elem_size = 0;
589         node_root->fill_array_func = NULL;
590         node_root->check_relation_func = NULL;
591         if (ntype == relation) {
592                 node_root->value.relation = operand;
593         }
594         else if (ntype == logical) {
595                 node_root->value.logical = operand;
596         }
597         else {
598                 g_assert_not_reached();
599         }
600
601         gnode_root = g_node_new(node_root);
602         g_node_append(gnode_root, n1);
603         g_node_append(gnode_root, n2);
604
605         return gnode_root;
606 }
607
608 static GNode*
609 dfilter_mknode_unary(int operand, GNode *n2)
610 {
611         dfilter_node    *node_root;
612         GNode           *gnode_root;
613
614         node_root = g_mem_chunk_alloc(global_df->node_memchunk);
615         node_root->ntype = logical;
616         node_root->value.logical = operand;
617         node_root->elem_size = 0;
618         node_root->fill_array_func = NULL;
619         node_root->check_relation_func = NULL;
620
621         gnode_root = g_node_new(node_root);
622         g_node_append(gnode_root, n2);
623
624         return gnode_root;
625 }
626
627
628 static GNode*
629 dfilter_mknode_numeric_variable(gint id)
630 {
631         dfilter_node    *node;
632         GNode           *gnode;
633
634         node = g_mem_chunk_alloc(global_df->node_memchunk);
635         node->ntype = variable;
636         node->elem_size = sizeof(guint32);
637         node->fill_array_func = fill_array_numeric_variable;
638         node->check_relation_func = check_relation_numeric;
639         node->value.variable = id;
640         gnode = g_node_new(node);
641
642         return gnode;
643 }
644
645 static GNode*
646 dfilter_mknode_ether_variable(gint id)
647 {
648         dfilter_node    *node;
649         GNode           *gnode;
650
651         node = g_mem_chunk_alloc(global_df->node_memchunk);
652         node->ntype = variable;
653         node->elem_size = sizeof(guint8) * 6;
654         node->fill_array_func = fill_array_ether_variable;
655         node->check_relation_func = check_relation_ether;
656         node->value.variable = id;
657         gnode = g_node_new(node);
658
659         return gnode;
660 }
661
662 static GNode*
663 dfilter_mknode_floating_variable(gint id)
664 {
665         dfilter_node    *node;
666         GNode           *gnode;
667
668         node = g_mem_chunk_alloc(global_df->node_memchunk);
669         node->ntype = variable;
670         node->elem_size = sizeof(double);
671         node->fill_array_func = fill_array_floating_variable;
672         node->check_relation_func = check_relation_floating;
673         node->value.variable = id;
674         gnode = g_node_new(node);
675
676         return gnode;
677 }
678
679 static GNode*
680 dfilter_mknode_ipxnet_variable(gint id)
681 {
682         dfilter_node    *node;
683         GNode           *gnode;
684
685         node = g_mem_chunk_alloc(global_df->node_memchunk);
686         node->ntype = variable;
687         node->elem_size = sizeof(guint8) * 4;
688         node->fill_array_func = fill_array_numeric_variable; /* cheating ! */
689         node->check_relation_func = check_relation_numeric; /* cheating ! */
690         node->value.variable = id;
691         gnode = g_node_new(node);
692
693         return gnode;
694 }
695
696 static GNode*
697 dfilter_mknode_ipv4_variable(gint id)
698 {
699         dfilter_node    *node;
700         GNode           *gnode;
701
702         node = g_mem_chunk_alloc(global_df->node_memchunk);
703         node->ntype = variable;
704         node->elem_size = sizeof(ipv4_addr);
705         node->fill_array_func = fill_array_ipv4_variable;
706         node->check_relation_func = check_relation_ipv4;
707         node->value.variable = id;
708         gnode = g_node_new(node);
709
710         return gnode;
711 }
712
713 static GNode*
714 dfilter_mknode_ipv6_variable(gint id)
715 {
716         dfilter_node    *node;
717         GNode           *gnode;
718
719         node = g_mem_chunk_alloc(global_df->node_memchunk);
720         node->ntype = variable;
721         node->elem_size = 16;
722         node->fill_array_func = fill_array_ipv6_variable;
723         node->check_relation_func = check_relation_ipv6; 
724         node->value.variable = id;
725         gnode = g_node_new(node);
726
727         return gnode;
728 }
729
730 static GNode*
731 dfilter_mknode_bytes_variable(gint id, gint offset, guint length)
732 {
733         dfilter_node    *node;
734         GNode           *gnode;
735
736         node = g_mem_chunk_alloc(global_df->node_memchunk);
737         node->ntype = variable;
738         node->elem_size = sizeof(GByteArray*);
739         node->fill_array_func = fill_array_bytes_variable;
740         node->check_relation_func = check_relation_bytes;
741         node->value.variable = id;
742         node->offset = offset;
743         node->length = length;
744         gnode = g_node_new(node);
745
746         return gnode;
747 }
748
749 /* Gets length of variable represented by node from proto_register */
750 static gint
751 dfilter_get_bytes_variable_field_registered_length(GNode *gnode)
752 {
753         dfilter_node    *node = gnode->data;
754
755         /* Is this really a bytes_variable? */
756         g_assert(node->fill_array_func = fill_array_bytes_variable);
757
758         return proto_registrar_get_length(node->value.variable);
759 }
760
761 /* Sets the length of a bytes_variable node */
762 static void
763 dfilter_set_bytes_variable_length(GNode *gnode, guint length)
764 {
765         dfilter_node    *node = gnode->data;
766
767         /* Is this really a bytes_variable? */
768         g_assert(node->fill_array_func = fill_array_bytes_variable);
769
770         node->length = length;
771 }
772
773 /* Gets the length of a bytes_variable node */
774 static guint
775 dfilter_get_bytes_variable_length(GNode *gnode)
776 {
777         dfilter_node    *node = gnode->data;
778
779         /* Is this really a bytes_variable? */
780         g_assert(node->fill_array_func = fill_array_bytes_variable);
781
782         return node->length;
783 }
784
785 /* Gets the offset of a bytes_variable node */
786 static guint
787 dfilter_get_bytes_variable_offset(GNode *gnode)
788 {
789         dfilter_node    *node = gnode->data;
790
791         /* Is this really a bytes_variable? */
792         g_assert(node->fill_array_func = fill_array_bytes_variable);
793
794         return node->offset;
795 }
796
797 static char*
798 dfilter_get_variable_abbrev(GNode *gnode)
799 {
800         dfilter_node    *node = gnode->data;
801
802         return proto_registrar_get_abbrev(node->value.variable);
803 }
804
805 static GNode*
806 dfilter_mknode_numeric_value(guint32 val)
807 {
808         dfilter_node    *node;
809         GNode           *gnode;
810
811         node = g_mem_chunk_alloc(global_df->node_memchunk);
812         node->ntype = numeric;
813         node->elem_size = sizeof(guint32);
814         node->fill_array_func = fill_array_numeric_value;
815         node->check_relation_func = check_relation_numeric;
816         node->value.numeric = val;
817         gnode = g_node_new(node);
818
819         return gnode;
820 }
821
822 static GNode*
823 dfilter_mknode_floating_value(double val)
824 {
825         dfilter_node    *node;
826         GNode           *gnode;
827
828         node = g_mem_chunk_alloc(global_df->node_memchunk);
829         node->ntype = floating;
830         node->elem_size = sizeof(double);
831         node->fill_array_func = fill_array_floating_value;
832         node->check_relation_func = check_relation_floating;
833         node->value.floating = val;
834         gnode = g_node_new(node);
835
836         return gnode;
837 }
838
839 /* Returns NULL on bad parse of ETHER value */
840 static GNode*
841 dfilter_mknode_ether_value(gchar *byte_string)
842 {
843         dfilter_node    *node;
844         GNode           *gnode;
845
846         node = g_mem_chunk_alloc(global_df->node_memchunk);
847         node->ntype = ether;
848         node->elem_size = sizeof(guint8) * 6;
849         node->fill_array_func = fill_array_ether_value;
850         node->check_relation_func = check_relation_ether;
851
852         if (!ether_str_to_guint8_array(byte_string, &node->value.ether[0])) {
853                 /* Rather than free the mem_chunk allocation, let it
854                  * stay. It will be cleaned up when "dfilter_compile()"
855                  * calls "dfilter_destroy()". */
856                 dfilter_fail("\"%s\" is not a valid hardware address.",
857                     byte_string);
858                 return NULL;
859         }
860
861         gnode = g_node_new(node);
862         return gnode;
863 }
864
865 static GNode*
866 dfilter_mknode_ipxnet_value(guint32 ipx_net_val)
867 {
868         dfilter_node    *node;
869         GNode           *gnode;
870
871         node = g_mem_chunk_alloc(global_df->node_memchunk);
872         node->ntype = ipxnet;
873         node->elem_size = sizeof(guint8) * 4;
874         node->fill_array_func = fill_array_numeric_value; /* cheating ! */
875         node->check_relation_func = check_relation_numeric; /* cheating ! */
876         node->value.numeric = ipx_net_val;
877         gnode = g_node_new(node);
878
879         return gnode;
880 }
881
882 /* Returns NULL on bad parse of IP value */
883 static GNode*
884 dfilter_mknode_ipv4_value(char *host, int nmask_bits)
885 {
886         dfilter_node    *node;
887         GNode           *gnode;
888         guint32         addr;
889
890         node = g_mem_chunk_alloc(global_df->node_memchunk);
891         node->ntype = numeric;
892         node->elem_size = sizeof(ipv4_addr);
893         node->fill_array_func = fill_array_ipv4_value;
894         node->check_relation_func = check_relation_ipv4;
895         if (!get_host_ipaddr(host, &addr)) {
896                 /* Rather than free the mem_chunk allocation, let it
897                  * stay. It will be cleaned up when "dfilter_compile()"
898                  * calls "dfilter_destroy()". */
899                 dfilter_fail("\"%s\" isn't a valid host name or IP address.",
900                     host);
901                 return NULL;
902         }
903         ipv4_addr_set_host_order_addr(&node->value.ipv4, addr);
904         ipv4_addr_set_netmask_bits(&node->value.ipv4, nmask_bits);
905
906         gnode = g_node_new(node);
907         return gnode;
908 }
909
910 /* Returns NULL on bad parse of IPv6 value */
911 static GNode*
912 dfilter_mknode_ipv6_value(char *host)
913 {
914         dfilter_node    *node;
915         GNode           *gnode;
916
917         node = g_mem_chunk_alloc(global_df->node_memchunk);
918         node->ntype = ipv6;
919         node->elem_size = 16;
920         node->fill_array_func = fill_array_ipv6_value;
921         node->check_relation_func = check_relation_ipv6;
922
923         if (!get_host_ipaddr6(host, (struct e_in6_addr*)&node->value.ipv6[0])) {
924                 /* Rather than free the mem_chunk allocation, let it
925                  * stay. It will be cleaned up when "dfilter_compile()"
926                  * calls "dfilter_destroy()". */
927                 dfilter_fail("\"%s\" isn't a valid IPv6 address.",
928                     host);
929                 return NULL;
930         }
931
932         gnode = g_node_new(node);
933         return gnode;
934 }
935
936 static GNode*
937 dfilter_mknode_bytes_value(GByteArray *barray)
938 {
939         dfilter_node    *node;
940         GNode           *gnode;
941
942         node = g_mem_chunk_alloc(global_df->node_memchunk);
943         node->ntype = bytes;
944         node->elem_size = sizeof(GByteArray*);
945         node->fill_array_func = fill_array_bytes_value;
946         node->check_relation_func = check_relation_bytes;
947         node->value.bytes = barray;
948         node->offset = G_MAXINT;
949         node->length = barray->len;
950         gnode = g_node_new(node);
951
952         return gnode;
953 }
954
955 /* Given a node representing a bytes_value, returns
956  * the length of the byte array */
957 static guint
958 dfilter_get_bytes_value_length(GNode* gnode)
959 {
960         dfilter_node    *node = gnode->data;
961
962         g_assert(node->ntype == bytes);
963         return node->length;
964 }
965
966 static guint32
967 string_to_guint32(char *s, gboolean *success)
968 {
969         char    *endptr;
970         guint32 val;
971
972         val = strtoul(s, &endptr, 0);
973         *success = TRUE;
974         if (endptr == s || *endptr != '\0') {
975                 /* This isn't a valid number. */
976                 dfilter_fail("\"%s\" is not a valid number.", s);
977                 *success = FALSE;
978         }
979         if (errno == ERANGE) {
980                 *success = FALSE;
981                 if (val == ULONG_MAX) {
982                         dfilter_fail("\"%s\" causes an integer overflow.", s);
983                 }
984                 else {
985                         dfilter_fail("\"%s\" is not an integer.", s);
986                 }
987         }
988
989         return (guint32)val;
990 }
991
992 static double
993 string_to_double(char *s, gboolean *success)
994 {
995         char    *endptr = NULL;
996         double  retval;
997
998         retval = strtod(s, &endptr);
999         *success = TRUE;
1000
1001         if (endptr == s) {
1002                 dfilter_fail("\"%s\" is not a valid floating-point number.", s);
1003                 *success = FALSE;
1004         }
1005
1006         if (errno == ERANGE) {
1007                 *success = FALSE;
1008                 if (retval == 0) {
1009                         dfilter_fail("\"%s\" causes a floating-point underflow.", s);
1010                 }
1011                 else if (retval == HUGE_VAL) {
1012                         dfilter_fail("\"%s\" causes a floating-point overflow.", s);
1013                 }
1014                 else {
1015                         dfilter_fail("\"%s\" is not a valid floating-point.", s);
1016                 }
1017         }
1018         return retval;
1019 }
1020         
1021 static GNode*
1022 dfilter_mknode_existence(gint id)
1023 {
1024         dfilter_node    *node;
1025         GNode           *gnode;
1026
1027         node = g_mem_chunk_alloc(global_df->node_memchunk);
1028         node->ntype = existence;
1029         node->elem_size = sizeof(guint32);
1030         node->fill_array_func = NULL;
1031         node->check_relation_func = NULL;
1032         node->value.variable = id;
1033         gnode = g_node_new(node);
1034
1035         return gnode;
1036 }
1037
1038
1039 /* converts a string representing an ether HW address
1040  * to a guint8 array.
1041  *
1042  * Returns 0 on failure, 1 on success.
1043  */
1044 static int
1045 ether_str_to_guint8_array(const char *s, guint8 *mac)
1046 {
1047         char    ether_str[18]; /* 2+1+2+1+2+1+2+1+2+1+2 + 1 */
1048         char    *p, *str;
1049         int     i = 0;
1050
1051         if (strlen(s) > 17) {
1052                 return 0;
1053         }
1054         strcpy(ether_str, s); /* local copy of string */
1055         str = ether_str;
1056         while ((p = strtok(str, "-:."))) {
1057                 /* catch short strings with too many hex bytes: 0.0.0.0.0.0.0 */
1058                 if (i > 5) {
1059                         return 0;
1060                 }
1061                 mac[i] = (guint8) strtoul(p, NULL, 16);
1062                 i++;
1063                 /* subsequent calls to strtok() require NULL as arg 1 */
1064                 str = NULL;
1065         }
1066         if (i != 6)
1067                 return 0;       /* failed to read 6 hex pairs */
1068         else
1069                 return 1;       /* read exactly 6 hex pairs */
1070 }
1071
1072
1073 static int
1074 check_bytes_variable_sanity(GNode *gnode)
1075 {
1076         int a_off, a_len, reg_len, t_off;
1077
1078         a_off = dfilter_get_bytes_variable_offset(gnode);
1079         a_len = dfilter_get_bytes_variable_length(gnode);
1080         reg_len = dfilter_get_bytes_variable_field_registered_length(gnode);
1081
1082         if (reg_len > 0) {
1083                 t_off = a_off >= 0 ? a_off : reg_len + a_off;
1084                 if (t_off + a_len > reg_len) {
1085                         dfilter_fail("The \"%s\" field is only %u byte%s wide, but "
1086                                 "%u byte%s %s supplied.",
1087                                 dfilter_get_variable_abbrev(gnode),
1088                                 reg_len, plurality(reg_len, "", "s"),
1089                                 a_len, plurality(a_len, "", "s"),
1090                                        plurality(a_len, "was", "were"));
1091                         return 0;
1092                 }
1093         }
1094         return 1;
1095 }