summaryrefslogtreecommitdiff
path: root/rdns_scan/zmap4rdns/src/expression.c
blob: 12ccd61652b5ab2ad4d2436f94ad84d44bfe9efd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/*
 * ZMap Copyright 2013 Regents of the University of Michigan
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy
 * of the License at http://www.apache.org/licenses/LICENSE-2.0
 */

#include "expression.h"
#include "fieldset.h"

#include "../lib/xalloc.h"

/* Static helper functions */

static node_t *alloc_node();
static int eval_gt_node(node_t *node, fieldset_t *fields);
static int eval_lt_node(node_t *node, fieldset_t *fields);
static int eval_eq_node(node_t *node, fieldset_t *fields);
static int eval_lt_eq_node(node_t *node, fieldset_t *fields);
static int eval_gt_eq_node(node_t *node, fieldset_t *fields);

static node_t *alloc_node()
{
	node_t *node = xmalloc(sizeof(node_t));
	return node;
}

static int eval_gt_node(node_t *node, fieldset_t *fields)
{
	int index = node->left_child->value.field.index;
	uint64_t expected = node->right_child->value.int_literal;
	uint64_t actual = fs_get_uint64_by_index(fields, index);
	return (actual > expected);
}

static int eval_lt_node(node_t *node, fieldset_t *fields)
{
	int index = node->left_child->value.field.index;
	uint64_t expected = node->right_child->value.int_literal;
	uint64_t actual = fs_get_uint64_by_index(fields, index);
	return (actual < expected);
}

static int eval_eq_node(node_t *node, fieldset_t *fields)
{
	node_t *literal = node->right_child;
	int index = node->left_child->value.field.index;
	char *expected, *actual;
	switch (literal->type) {
	case STRING:
		expected = literal->value.string_literal;
		actual = fs_get_string_by_index(fields, index);
		return (strcmp(expected, actual) == 0);
		break;
	case INT:
		return (fs_get_uint64_by_index(fields, index) ==
			literal->value.int_literal);
		break;
	default:
		printf("wat\n");
		break;
	}
	return 0;
}

static int eval_lt_eq_node(node_t *node, fieldset_t *fields)
{
	return !(eval_gt_node(node, fields));
}

static int eval_gt_eq_node(node_t *node, fieldset_t *fields)
{
	return !(eval_lt_node(node, fields));
}

/* Exposed functions */

node_t *make_op_node(enum operation op)
{
	node_t *node = alloc_node();
	node->type = OP;
	node->value.op = op;
	return node;
}

node_t *make_field_node(char *fieldname)
{
	node_t *node = alloc_node();
	node->type = FIELD;
	node->value.field.fieldname = fieldname;
	return node;
}

node_t *make_string_node(char *literal)
{
	node_t *node = alloc_node();
	node->type = STRING;
	node->value.string_literal = literal;
	return node;
}

node_t *make_int_node(int literal)
{
	node_t *node = alloc_node();
	node->type = INT;
	node->value.int_literal = literal;
	return node;
}

int evaluate_expression(node_t *root, fieldset_t *fields)
{
	if (!root)
		return 1;
	switch (root->type) { /* XXX Not sure if runs */
	case FIELD:
	case STRING:
	case INT:
		return 1;
	case OP:
		break;
	}
	switch (root->value.op) {
	case GT:
		return eval_gt_node(root, fields);
	case LT:
		return eval_lt_node(root, fields);
	case EQ:
		return eval_eq_node(root, fields);
	case NEQ:
		return (!eval_eq_node(root, fields));
	case LT_EQ:
		return eval_lt_eq_node(root, fields);
	case GT_EQ:
		return eval_gt_eq_node(root, fields);
	case AND:
		return (evaluate_expression(root->left_child, fields) &&
			evaluate_expression(root->right_child, fields));
	case OR:
		return (evaluate_expression(root->left_child, fields) ||
			evaluate_expression(root->right_child, fields));
	}
	return 0;
}

void print_expression(node_t *root)
{
	if (!root)
		return;
	printf("%s", "( ");
	print_expression(root->left_child);
	switch (root->type) {
	case OP:
		printf(" %i ", root->value.op);
		break;
	case FIELD:
		printf(" (%s", root->value.field.fieldname);
		break;
	case STRING:
		printf("%s) ", root->value.string_literal);
		break;
	case INT:
		printf(" %llu) ", (long long unsigned)root->value.int_literal);
		break;
	default:
		break;
	}
	print_expression(root->right_child);
	printf("%s", " )");
}