1 /*
2  * Wireshark - Network traffic analyzer
3  * By Gerald Combs <gerald@wireshark.org>
4  * Copyright 2001 Gerald Combs
5  *
6  * SPDX-License-Identifier: GPL-2.0-or-later
7  */
8 
9 #include "config.h"
10 
11 #include "dfvm.h"
12 
13 #include <ftypes/ftypes-int.h>
14 #include <wsutil/ws_assert.h>
15 
16 dfvm_insn_t*
dfvm_insn_new(dfvm_opcode_t op)17 dfvm_insn_new(dfvm_opcode_t op)
18 {
19 	dfvm_insn_t	*insn;
20 
21 	insn = g_new(dfvm_insn_t, 1);
22 	insn->op = op;
23 	insn->arg1 = NULL;
24 	insn->arg2 = NULL;
25 	insn->arg3 = NULL;
26 	insn->arg4 = NULL;
27 	return insn;
28 }
29 
30 static void
dfvm_value_free(dfvm_value_t * v)31 dfvm_value_free(dfvm_value_t *v)
32 {
33 	switch (v->type) {
34 		case FVALUE:
35 			FVALUE_FREE(v->value.fvalue);
36 			break;
37 		case DRANGE:
38 			drange_free(v->value.drange);
39 			break;
40 		case PCRE:
41 			g_regex_unref(v->value.pcre);
42 			break;
43 		default:
44 			/* nothing */
45 			;
46 	}
47 	g_free(v);
48 }
49 
50 void
dfvm_insn_free(dfvm_insn_t * insn)51 dfvm_insn_free(dfvm_insn_t *insn)
52 {
53 	if (insn->arg1) {
54 		dfvm_value_free(insn->arg1);
55 	}
56 	if (insn->arg2) {
57 		dfvm_value_free(insn->arg2);
58 	}
59 	if (insn->arg3) {
60 		dfvm_value_free(insn->arg3);
61 	}
62 	if (insn->arg4) {
63 		dfvm_value_free(insn->arg4);
64 	}
65 	g_free(insn);
66 }
67 
68 
69 dfvm_value_t*
dfvm_value_new(dfvm_value_type_t type)70 dfvm_value_new(dfvm_value_type_t type)
71 {
72 	dfvm_value_t	*v;
73 
74 	v = g_new(dfvm_value_t, 1);
75 	v->type = type;
76 	return v;
77 }
78 
79 
80 void
dfvm_dump(FILE * f,dfilter_t * df)81 dfvm_dump(FILE *f, dfilter_t *df)
82 {
83 	int		id, length;
84 	dfvm_insn_t	*insn;
85 	dfvm_value_t	*arg1;
86 	dfvm_value_t	*arg2;
87 	dfvm_value_t	*arg3;
88 	dfvm_value_t	*arg4;
89 	char		*value_str;
90 	GSList		*range_list;
91 	drange_node	*range_item;
92 
93 	/* First dump the constant initializations */
94 	fprintf(f, "Constants:\n");
95 	length = df->consts->len;
96 	for (id = 0; id < length; id++) {
97 
98 		insn = (dfvm_insn_t	*)g_ptr_array_index(df->consts, id);
99 		arg1 = insn->arg1;
100 		arg2 = insn->arg2;
101 
102 		switch (insn->op) {
103 			case PUT_FVALUE:
104 				value_str = fvalue_to_string_repr(NULL, arg1->value.fvalue,
105 					FTREPR_DFILTER, BASE_NONE);
106 				fprintf(f, "%05d PUT_FVALUE\t%s <%s> -> reg#%u\n",
107 					id, value_str,
108 					fvalue_type_name(arg1->value.fvalue),
109 					arg2->value.numeric);
110 				wmem_free(NULL, value_str);
111 				break;
112 			case PUT_PCRE:
113 				fprintf(f, "%05d PUT_PCRE\t%s -> reg#%u\n",
114 					id,
115 					g_regex_get_pattern(arg1->value.pcre),
116 					arg2->value.numeric);
117 				break;
118 			case CHECK_EXISTS:
119 			case READ_TREE:
120 			case CALL_FUNCTION:
121 			case MK_RANGE:
122 			case ANY_EQ:
123 			case ALL_NE:
124 			case ANY_NE:
125 			case ANY_GT:
126 			case ANY_GE:
127 			case ANY_LT:
128 			case ANY_LE:
129 			case ANY_BITWISE_AND:
130 			case ANY_CONTAINS:
131 			case ANY_MATCHES:
132 			case ANY_IN_RANGE:
133 			case NOT:
134 			case RETURN:
135 			case IF_TRUE_GOTO:
136 			case IF_FALSE_GOTO:
137 			default:
138 				ws_assert_not_reached();
139 				break;
140 		}
141 	}
142 
143 	fprintf(f, "\nInstructions:\n");
144 	/* Now dump the operations */
145 	length = df->insns->len;
146 	for (id = 0; id < length; id++) {
147 
148 		insn = (dfvm_insn_t	*)g_ptr_array_index(df->insns, id);
149 		arg1 = insn->arg1;
150 		arg2 = insn->arg2;
151 		arg3 = insn->arg3;
152 		arg4 = insn->arg4;
153 
154 		switch (insn->op) {
155 			case CHECK_EXISTS:
156 				fprintf(f, "%05d CHECK_EXISTS\t%s\n",
157 					id, arg1->value.hfinfo->abbrev);
158 				break;
159 
160 			case READ_TREE:
161 				fprintf(f, "%05d READ_TREE\t\t%s -> reg#%u\n",
162 					id, arg1->value.hfinfo->abbrev,
163 					arg2->value.numeric);
164 				break;
165 
166 			case CALL_FUNCTION:
167 				fprintf(f, "%05d CALL_FUNCTION\t%s (",
168 					id, arg1->value.funcdef->name);
169 				if (arg3) {
170 					fprintf(f, "reg#%u", arg3->value.numeric);
171 				}
172 				if (arg4) {
173 					fprintf(f, ", reg#%u", arg4->value.numeric);
174 				}
175 				fprintf(f, ") --> reg#%u\n", arg2->value.numeric);
176 				break;
177 
178 			case PUT_FVALUE:
179 				/* We already dumped these */
180 				ws_assert_not_reached();
181 				break;
182 
183 			case PUT_PCRE:
184 				/* We already dumped these */
185 				ws_assert_not_reached();
186 				break;
187 
188 			case MK_RANGE:
189 				arg3 = insn->arg3;
190 				fprintf(f, "%05d MK_RANGE\t\treg#%u[",
191 					id,
192 					arg1->value.numeric);
193 				for (range_list = arg3->value.drange->range_list;
194 				     range_list != NULL;
195 				     range_list = range_list->next) {
196 					range_item = (drange_node *)range_list->data;
197 					switch (range_item->ending) {
198 
199 					case DRANGE_NODE_END_T_UNINITIALIZED:
200 						fprintf(f, "?");
201 						break;
202 
203 					case DRANGE_NODE_END_T_LENGTH:
204 						fprintf(f, "%d:%d",
205 						    range_item->start_offset,
206 						    range_item->length);
207 						break;
208 
209 					case DRANGE_NODE_END_T_OFFSET:
210 						fprintf(f, "%d-%d",
211 						    range_item->start_offset,
212 						    range_item->end_offset);
213 						break;
214 
215 					case DRANGE_NODE_END_T_TO_THE_END:
216 						fprintf(f, "%d:",
217 						    range_item->start_offset);
218 						break;
219 					}
220 					if (range_list->next != NULL)
221 						fprintf(f, ",");
222 				}
223 				fprintf(f, "] -> reg#%u\n",
224 					arg2->value.numeric);
225 				break;
226 
227 			case ANY_EQ:
228 				fprintf(f, "%05d ANY_EQ\t\treg#%u == reg#%u\n",
229 					id, arg1->value.numeric, arg2->value.numeric);
230 				break;
231 
232 			case ALL_NE:
233 				fprintf(f, "%05d ALL_NE\t\treg#%u == reg#%u\n",
234 					id, arg1->value.numeric, arg2->value.numeric);
235 				break;
236 
237 			case ANY_NE:
238 				fprintf(f, "%05d ANY_NE\t\treg#%u == reg#%u\n",
239 					id, arg1->value.numeric, arg2->value.numeric);
240 				break;
241 
242 			case ANY_GT:
243 				fprintf(f, "%05d ANY_GT\t\treg#%u == reg#%u\n",
244 					id, arg1->value.numeric, arg2->value.numeric);
245 				break;
246 
247 			case ANY_GE:
248 				fprintf(f, "%05d ANY_GE\t\treg#%u == reg#%u\n",
249 					id, arg1->value.numeric, arg2->value.numeric);
250 				break;
251 
252 			case ANY_LT:
253 				fprintf(f, "%05d ANY_LT\t\treg#%u == reg#%u\n",
254 					id, arg1->value.numeric, arg2->value.numeric);
255 				break;
256 
257 			case ANY_LE:
258 				fprintf(f, "%05d ANY_LE\t\treg#%u == reg#%u\n",
259 					id, arg1->value.numeric, arg2->value.numeric);
260 				break;
261 
262 			case ANY_BITWISE_AND:
263 				fprintf(f, "%05d ANY_BITWISE_AND\t\treg#%u == reg#%u\n",
264 					id, arg1->value.numeric, arg2->value.numeric);
265 				break;
266 
267 			case ANY_CONTAINS:
268 				fprintf(f, "%05d ANY_CONTAINS\treg#%u contains reg#%u\n",
269 					id, arg1->value.numeric, arg2->value.numeric);
270 				break;
271 
272 			case ANY_MATCHES:
273 				fprintf(f, "%05d ANY_MATCHES\treg#%u matches reg#%u\n",
274 					id, arg1->value.numeric, arg2->value.numeric);
275 				break;
276 
277 			case ANY_IN_RANGE:
278 				fprintf(f, "%05d ANY_IN_RANGE\treg#%u in range reg#%u,reg#%u\n",
279 					id, arg1->value.numeric, arg2->value.numeric,
280 					arg3->value.numeric);
281 				break;
282 
283 			case NOT:
284 				fprintf(f, "%05d NOT\n", id);
285 				break;
286 
287 			case RETURN:
288 				fprintf(f, "%05d RETURN\n", id);
289 				break;
290 
291 			case IF_TRUE_GOTO:
292 				fprintf(f, "%05d IF-TRUE-GOTO\t%u\n",
293 						id, arg1->value.numeric);
294 				break;
295 
296 			case IF_FALSE_GOTO:
297 				fprintf(f, "%05d IF-FALSE-GOTO\t%u\n",
298 						id, arg1->value.numeric);
299 				break;
300 
301 			default:
302 				ws_assert_not_reached();
303 				break;
304 		}
305 	}
306 }
307 
308 /* Reads a field from the proto_tree and loads the fvalues into a register,
309  * if that field has not already been read. */
310 static gboolean
read_tree(dfilter_t * df,proto_tree * tree,header_field_info * hfinfo,int reg)311 read_tree(dfilter_t *df, proto_tree *tree, header_field_info *hfinfo, int reg)
312 {
313 	GPtrArray	*finfos;
314 	field_info	*finfo;
315 	int		i, len;
316 	GList		*fvalues = NULL;
317 	gboolean	found_something = FALSE;
318 
319 	/* Already loaded in this run of the dfilter? */
320 	if (df->attempted_load[reg]) {
321 		if (df->registers[reg]) {
322 			return TRUE;
323 		}
324 		else {
325 			return FALSE;
326 		}
327 	}
328 
329 	df->attempted_load[reg] = TRUE;
330 
331 	while (hfinfo) {
332 		finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
333 		if ((finfos == NULL) || (g_ptr_array_len(finfos) == 0)) {
334 			hfinfo = hfinfo->same_name_next;
335 			continue;
336 		}
337 		else {
338 			found_something = TRUE;
339 		}
340 
341 		len = finfos->len;
342 		for (i = 0; i < len; i++) {
343 			finfo = (field_info *)g_ptr_array_index(finfos, i);
344 			fvalues = g_list_prepend(fvalues, &finfo->value);
345 		}
346 
347 		hfinfo = hfinfo->same_name_next;
348 	}
349 
350 	if (!found_something) {
351 		return FALSE;
352 	}
353 
354 	df->registers[reg] = fvalues;
355 	// These values are referenced only, do not try to free it later.
356 	df->owns_memory[reg] = FALSE;
357 	return TRUE;
358 }
359 
360 
361 /* Put a constant value in a register. These will not be cleared by
362  * free_register_overhead. */
363 static gboolean
put_fvalue(dfilter_t * df,fvalue_t * fv,int reg)364 put_fvalue(dfilter_t *df, fvalue_t *fv, int reg)
365 {
366 	df->registers[reg] = g_list_append(NULL, fv);
367 	df->owns_memory[reg] = FALSE;
368 	return TRUE;
369 }
370 
371 /* Put a constant PCRE in a register. These will not be cleared by
372  * free_register_overhead. */
373 static gboolean
put_pcre(dfilter_t * df,GRegex * pcre,int reg)374 put_pcre(dfilter_t *df, GRegex *pcre, int reg)
375 {
376 	df->registers[reg] = g_list_append(NULL, pcre);
377 	df->owns_memory[reg] = FALSE;
378 	return TRUE;
379 }
380 
381 enum match_how {
382 	MATCH_ANY,
383 	MATCH_ALL
384 };
385 
386 typedef gboolean (*DFVMMatchFunc)(const fvalue_t*, const fvalue_t*);
387 
388 static gboolean
cmp_test(dfilter_t * df,enum match_how how,DFVMMatchFunc match_func,int reg1,int reg2)389 cmp_test(dfilter_t *df, enum match_how how, DFVMMatchFunc match_func, int reg1, int reg2)
390 {
391 	GList	*list_a, *list_b;
392 	gboolean want_all = (how == MATCH_ALL);
393 	gboolean want_any = (how == MATCH_ANY);
394 	gboolean have_match;
395 
396 	list_a = df->registers[reg1];
397 
398 	while (list_a) {
399 		list_b = df->registers[reg2];
400 		while (list_b) {
401 			have_match = match_func(list_a->data, list_b->data);
402 			if (want_all && !have_match) {
403 				return FALSE;
404 			}
405 			else if (want_any && have_match) {
406 				return TRUE;
407 			}
408 			list_b = g_list_next(list_b);
409 		}
410 		list_a = g_list_next(list_a);
411 	}
412 	/* want_all || !want_any */
413 	return want_all;
414 }
415 
416 static inline gboolean
any_test(dfilter_t * df,DFVMMatchFunc cmp,int reg1,int reg2)417 any_test(dfilter_t *df, DFVMMatchFunc cmp, int reg1, int reg2)
418 {
419 	/* cmp(A) <=> cmp(a1) OR cmp(a2) OR cmp(a3) OR ... */
420 	return cmp_test(df, MATCH_ANY, cmp, reg1, reg2);
421 }
422 
423 static inline gboolean
all_test(dfilter_t * df,DFVMMatchFunc cmp,int reg1,int reg2)424 all_test(dfilter_t *df, DFVMMatchFunc cmp, int reg1, int reg2)
425 {
426 	/* cmp(A) <=> cmp(a1) AND cmp(a2) AND cmp(a3) AND ... */
427 	return cmp_test(df, MATCH_ALL, cmp, reg1, reg2);
428 }
429 
430 static inline gboolean
any_eq(dfilter_t * df,int reg1,int reg2)431 any_eq(dfilter_t *df, int reg1, int reg2)
432 {
433 	/* A any_eq B <=> a1 == b1 OR a2 == b2 OR a3 == b3 OR ... */
434 	return any_test(df, fvalue_eq, reg1, reg2);
435 }
436 
437 static inline gboolean
any_ne(dfilter_t * df,int reg1,int reg2)438 any_ne(dfilter_t *df, int reg1, int reg2)
439 {
440 	/* A any_ne B <=> a1 != b1 OR a2 != b2 OR a3 != b3 OR ... */
441 	return any_test(df, fvalue_ne, reg1, reg2);
442 }
443 
444 static inline gboolean
all_ne(dfilter_t * df,int reg1,int reg2)445 all_ne(dfilter_t *df, int reg1, int reg2)
446 {
447 	/* A all_ne B <=> a1 != b1 AND a2 != b2 AND a3 != b3 AND ... */
448 	return all_test(df, fvalue_ne, reg1, reg2);
449 }
450 
451 static gboolean
any_matches(dfilter_t * df,int reg1,int reg2)452 any_matches(dfilter_t *df, int reg1, int reg2)
453 {
454 	GList	*list_a, *list_b;
455 
456 	list_a = df->registers[reg1];
457 
458 	while (list_a) {
459 		list_b = df->registers[reg2];
460 		while (list_b) {
461 			if (fvalue_matches((fvalue_t *)list_a->data, (GRegex *)list_b->data)) {
462 				return TRUE;
463 			}
464 			list_b = g_list_next(list_b);
465 		}
466 		list_a = g_list_next(list_a);
467 	}
468 	return FALSE;
469 }
470 
471 static gboolean
any_in_range(dfilter_t * df,int reg1,int reg2,int reg3)472 any_in_range(dfilter_t *df, int reg1, int reg2, int reg3)
473 {
474 	GList	*list1, *list_low, *list_high;
475 	fvalue_t *low, *high;
476 
477 	list1 = df->registers[reg1];
478 	list_low = df->registers[reg2];
479 	list_high = df->registers[reg3];
480 
481 	/* The first register contains the values associated with a field, the
482 	 * second and third arguments are expected to be a single value for the
483 	 * lower and upper bound respectively. These cannot be fields and thus
484 	 * the list length MUST be one. This should have been enforced by
485 	 * grammar.lemon.
486 	 */
487 	ws_assert(list_low && !g_list_next(list_low));
488 	ws_assert(list_high && !g_list_next(list_high));
489 	low = (fvalue_t *)list_low->data;
490 	high = (fvalue_t *)list_high->data;
491 
492 	while (list1) {
493 		fvalue_t *value = (fvalue_t *)list1->data;
494 		if (fvalue_ge(value, low) && fvalue_le(value, high)) {
495 			return TRUE;
496 		}
497 		list1 = g_list_next(list1);
498 	}
499 	return FALSE;
500 }
501 
502 
503 static void
free_owned_register(gpointer data,gpointer user_data _U_)504 free_owned_register(gpointer data, gpointer user_data _U_)
505 {
506 	fvalue_t *value = (fvalue_t *)data;
507 	FVALUE_FREE(value);
508 }
509 
510 /* Clear registers that were populated during evaluation (leaving constants
511  * intact). If we created the values, then these will be freed as well. */
512 static void
free_register_overhead(dfilter_t * df)513 free_register_overhead(dfilter_t* df)
514 {
515 	guint i;
516 
517 	for (i = 0; i < df->num_registers; i++) {
518 		df->attempted_load[i] = FALSE;
519 		if (df->registers[i]) {
520 			if (df->owns_memory[i]) {
521 				g_list_foreach(df->registers[i], free_owned_register, NULL);
522 				df->owns_memory[i] = FALSE;
523 			}
524 			g_list_free(df->registers[i]);
525 			df->registers[i] = NULL;
526 		}
527 	}
528 }
529 
530 /* Takes the list of fvalue_t's in a register, uses fvalue_slice()
531  * to make a new list of fvalue_t's (which are ranges, or byte-slices),
532  * and puts the new list into a new register. */
533 static void
mk_range(dfilter_t * df,int from_reg,int to_reg,drange_t * d_range)534 mk_range(dfilter_t *df, int from_reg, int to_reg, drange_t *d_range)
535 {
536 	GList		*from_list, *to_list;
537 	fvalue_t	*old_fv, *new_fv;
538 
539 	to_list = NULL;
540 	from_list = df->registers[from_reg];
541 
542 	while (from_list) {
543 		old_fv = (fvalue_t*)from_list->data;
544 		new_fv = fvalue_slice(old_fv, d_range);
545 		/* Assert here because semcheck.c should have
546 		 * already caught the cases in which a slice
547 		 * cannot be made. */
548 		ws_assert(new_fv);
549 		to_list = g_list_append(to_list, new_fv);
550 
551 		from_list = g_list_next(from_list);
552 	}
553 
554 	df->registers[to_reg] = to_list;
555 	df->owns_memory[to_reg] = TRUE;
556 }
557 
558 
559 
560 gboolean
dfvm_apply(dfilter_t * df,proto_tree * tree)561 dfvm_apply(dfilter_t *df, proto_tree *tree)
562 {
563 	int		id, length;
564 	gboolean	accum = TRUE;
565 	dfvm_insn_t	*insn;
566 	dfvm_value_t	*arg1;
567 	dfvm_value_t	*arg2;
568 	dfvm_value_t	*arg3 = NULL;
569 	dfvm_value_t	*arg4 = NULL;
570 	header_field_info	*hfinfo;
571 	GList		*param1;
572 	GList		*param2;
573 
574 	ws_assert(tree);
575 
576 	length = df->insns->len;
577 
578 	for (id = 0; id < length; id++) {
579 
580 	  AGAIN:
581 		insn = (dfvm_insn_t	*)g_ptr_array_index(df->insns, id);
582 		arg1 = insn->arg1;
583 		arg2 = insn->arg2;
584 
585 		switch (insn->op) {
586 			case CHECK_EXISTS:
587 				hfinfo = arg1->value.hfinfo;
588 				while(hfinfo) {
589 					accum = proto_check_for_protocol_or_field(tree,
590 							hfinfo->id);
591 					if (accum) {
592 						break;
593 					}
594 					else {
595 						hfinfo = hfinfo->same_name_next;
596 					}
597 				}
598 				break;
599 
600 			case READ_TREE:
601 				accum = read_tree(df, tree,
602 						arg1->value.hfinfo, arg2->value.numeric);
603 				break;
604 
605 			case CALL_FUNCTION:
606 				arg3 = insn->arg3;
607 				arg4 = insn->arg4;
608 				param1 = NULL;
609 				param2 = NULL;
610 				if (arg3) {
611 					param1 = df->registers[arg3->value.numeric];
612 				}
613 				if (arg4) {
614 					param2 = df->registers[arg4->value.numeric];
615 				}
616 				accum = arg1->value.funcdef->function(param1, param2,
617 						&df->registers[arg2->value.numeric]);
618 				// functions create a new value, so own it.
619 				df->owns_memory[arg2->value.numeric] = TRUE;
620 				break;
621 
622 			case MK_RANGE:
623 				arg3 = insn->arg3;
624 				mk_range(df,
625 						arg1->value.numeric, arg2->value.numeric,
626 						arg3->value.drange);
627 				break;
628 
629 			case ANY_EQ:
630 				accum = any_eq(df, arg1->value.numeric, arg2->value.numeric);
631 				break;
632 
633 			case ALL_NE:
634 				accum = all_ne(df, arg1->value.numeric, arg2->value.numeric);
635 				break;
636 
637 			case ANY_NE:
638 				accum = any_ne(df, arg1->value.numeric, arg2->value.numeric);
639 				break;
640 
641 			case ANY_GT:
642 				accum = any_test(df, fvalue_gt,
643 						arg1->value.numeric, arg2->value.numeric);
644 				break;
645 
646 			case ANY_GE:
647 				accum = any_test(df, fvalue_ge,
648 						arg1->value.numeric, arg2->value.numeric);
649 				break;
650 
651 			case ANY_LT:
652 				accum = any_test(df, fvalue_lt,
653 						arg1->value.numeric, arg2->value.numeric);
654 				break;
655 
656 			case ANY_LE:
657 				accum = any_test(df, fvalue_le,
658 						arg1->value.numeric, arg2->value.numeric);
659 				break;
660 
661 			case ANY_BITWISE_AND:
662 				accum = any_test(df, fvalue_bitwise_and,
663 						arg1->value.numeric, arg2->value.numeric);
664 				break;
665 
666 			case ANY_CONTAINS:
667 				accum = any_test(df, fvalue_contains,
668 						arg1->value.numeric, arg2->value.numeric);
669 				break;
670 
671 			case ANY_MATCHES:
672 				accum = any_matches(df,
673 						arg1->value.numeric, arg2->value.numeric);
674 				break;
675 
676 			case ANY_IN_RANGE:
677 				arg3 = insn->arg3;
678 				accum = any_in_range(df, arg1->value.numeric,
679 						arg2->value.numeric,
680 						arg3->value.numeric);
681 				break;
682 
683 			case NOT:
684 				accum = !accum;
685 				break;
686 
687 			case RETURN:
688 				free_register_overhead(df);
689 				return accum;
690 
691 			case IF_TRUE_GOTO:
692 				if (accum) {
693 					id = arg1->value.numeric;
694 					goto AGAIN;
695 				}
696 				break;
697 
698 			case IF_FALSE_GOTO:
699 				if (!accum) {
700 					id = arg1->value.numeric;
701 					goto AGAIN;
702 				}
703 				break;
704 
705 			case PUT_FVALUE:
706 #if 0
707 				/* These were handled in the constants initialization */
708 				accum = put_fvalue(df,
709 						arg1->value.fvalue, arg2->value.numeric);
710 				break;
711 #endif
712 
713 			case PUT_PCRE:
714 #if 0
715 				/* These were handled in the constants initialization */
716 				accum = put_pcre(df,
717 						arg1->value.pcre, arg2->value.numeric);
718 				break;
719 #endif
720 
721 			default:
722 				ws_assert_not_reached();
723 				break;
724 		}
725 	}
726 
727 	ws_assert_not_reached();
728 	return FALSE; /* to appease the compiler */
729 }
730 
731 void
dfvm_init_const(dfilter_t * df)732 dfvm_init_const(dfilter_t *df)
733 {
734 	int		id, length;
735 	dfvm_insn_t	*insn;
736 	dfvm_value_t	*arg1;
737 	dfvm_value_t	*arg2;
738 
739 	length = df->consts->len;
740 
741 	for (id = 0; id < length; id++) {
742 
743 		insn = (dfvm_insn_t	*)g_ptr_array_index(df->consts, id);
744 		arg1 = insn->arg1;
745 		arg2 = insn->arg2;
746 
747 		switch (insn->op) {
748 			case PUT_FVALUE:
749 				put_fvalue(df,
750 						arg1->value.fvalue, arg2->value.numeric);
751 				break;
752 			case PUT_PCRE:
753 				put_pcre(df,
754 						arg1->value.pcre, arg2->value.numeric);
755 				break;
756 			case CHECK_EXISTS:
757 			case READ_TREE:
758 			case CALL_FUNCTION:
759 			case MK_RANGE:
760 			case ANY_EQ:
761 			case ALL_NE:
762 			case ANY_NE:
763 			case ANY_GT:
764 			case ANY_GE:
765 			case ANY_LT:
766 			case ANY_LE:
767 			case ANY_BITWISE_AND:
768 			case ANY_CONTAINS:
769 			case ANY_MATCHES:
770 			case ANY_IN_RANGE:
771 			case NOT:
772 			case RETURN:
773 			case IF_TRUE_GOTO:
774 			case IF_FALSE_GOTO:
775 			default:
776 				ws_assert_not_reached();
777 				break;
778 		}
779 	}
780 
781 	return;
782 }
783 
784 /*
785  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
786  *
787  * Local variables:
788  * c-basic-offset: 8
789  * tab-width: 8
790  * indent-tabs-mode: t
791  * End:
792  *
793  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
794  * :indentSize=8:tabSize=8:noTabs=false:
795  */
796