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