Incredibly hacky evaluate implementation
This commit is contained in:
parent
f7939bfbcb
commit
29c291c562
@ -1,11 +1,17 @@
|
|||||||
#include "expression.h"
|
#include "expression.h"
|
||||||
|
#include "fieldset.H"
|
||||||
|
|
||||||
#include "../lib/xalloc.h"
|
#include "../lib/xalloc.h"
|
||||||
|
|
||||||
/* Static helper functions */
|
/* Static helper functions */
|
||||||
|
|
||||||
static node_t* alloc_node();
|
static node_t* alloc_node();
|
||||||
static int eval_single_node(node_t* 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()
|
static node_t* alloc_node()
|
||||||
{
|
{
|
||||||
@ -14,6 +20,54 @@ static node_t* alloc_node()
|
|||||||
return node;
|
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 */
|
/* Exposed functions */
|
||||||
|
|
||||||
node_t* make_op_node(enum operation op)
|
node_t* make_op_node(enum operation op)
|
||||||
@ -48,10 +102,37 @@ node_t* make_int_node(int literal)
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
int evaluate_expression(node_t *root) {
|
int evaluate_expression(node_t *root, fieldset_t *fields) {
|
||||||
if (!root) return 0;
|
if (!root) return 1;
|
||||||
int result = 1;
|
switch (root->type) { /* XXX Not sure if runs */
|
||||||
return result;
|
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) {
|
void print_expression(node_t *root) {
|
||||||
@ -69,7 +150,7 @@ void print_expression(node_t *root) {
|
|||||||
printf("%s) ", root->value.string_literal);
|
printf("%s) ", root->value.string_literal);
|
||||||
break;
|
break;
|
||||||
case INT:
|
case INT:
|
||||||
printf(" %d) ", root->value.int_literal);
|
printf(" %llu) ", (long long unsigned) root->value.int_literal);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
#ifndef ZMAP_TREE_H
|
#ifndef ZMAP_TREE_H
|
||||||
#define ZMAP_TREE_H
|
#define ZMAP_TREE_H
|
||||||
|
|
||||||
|
#include "fieldset.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
enum operation {
|
enum operation {
|
||||||
GT, LT, EQ, NEQ, AND, OR, LT_EQ, GT_EQ
|
GT, LT, EQ, NEQ, AND, OR, LT_EQ, GT_EQ
|
||||||
@ -21,7 +24,7 @@ struct field_id {
|
|||||||
union node_value {
|
union node_value {
|
||||||
struct field_id field;
|
struct field_id field;
|
||||||
char *string_literal;
|
char *string_literal;
|
||||||
int int_literal;
|
uint64_t int_literal;
|
||||||
enum operation op;
|
enum operation op;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -40,8 +43,6 @@ node_t* make_string_node(char *literal);
|
|||||||
|
|
||||||
node_t* make_int_node(int literal);
|
node_t* make_int_node(int literal);
|
||||||
|
|
||||||
int evaluate_expression(node_t *root);
|
int evaluate_expression(node_t *root, fieldset_t *fields);
|
||||||
|
|
||||||
void print_expression(node_t *root);
|
|
||||||
|
|
||||||
#endif /* ZMAP_TREE_H */
|
#endif /* ZMAP_TREE_H */
|
38
src/filter.c
38
src/filter.c
@ -4,10 +4,32 @@
|
|||||||
#include "y.tab.h"
|
#include "y.tab.h"
|
||||||
#include "../lib/logger.h"
|
#include "../lib/logger.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
extern int yyparse();
|
extern int yyparse();
|
||||||
|
|
||||||
node_t *zfilter;
|
node_t *zfilter;
|
||||||
|
|
||||||
|
static int validate_node(node_t *node, fielddefset_t *fields)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
if (node->type != FIELD) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_FIELDS; i++) {
|
||||||
|
if (fields->fielddefs[i].name) {
|
||||||
|
if (strcmp(fields->fielddefs[i].name, node->value.field.fieldname) == 0) {
|
||||||
|
node->value.field.index = i;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Didn't find it
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int parse_filter_string(char *filter)
|
int parse_filter_string(char *filter)
|
||||||
{
|
{
|
||||||
YY_BUFFER_STATE buffer_state = yy_scan_string(filter);
|
YY_BUFFER_STATE buffer_state = yy_scan_string(filter);
|
||||||
@ -23,4 +45,18 @@ int parse_filter_string(char *filter)
|
|||||||
printf("%s\n", "");
|
printf("%s\n", "");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int validate_filter(node_t *root, fielddefset_t *fields)
|
||||||
|
{
|
||||||
|
int valid;
|
||||||
|
if (!root) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
valid = validate_node(root, fields);
|
||||||
|
if (!valid) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return (validate_filter(root->left_child, fields) && validate_filter(root->right_child, fields));
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define ZMAP_FILTER_H
|
#define ZMAP_FILTER_H
|
||||||
|
|
||||||
#include "expression.h"
|
#include "expression.h"
|
||||||
|
#include "fieldset.h"
|
||||||
|
|
||||||
struct output_filter {
|
struct output_filter {
|
||||||
node_t *expression;
|
node_t *expression;
|
||||||
@ -9,4 +10,6 @@ struct output_filter {
|
|||||||
|
|
||||||
int parse_filter_string(char *filter);
|
int parse_filter_string(char *filter);
|
||||||
|
|
||||||
|
int validate_filter(node_t *root, fielddefset_t *fields);
|
||||||
|
|
||||||
#endif /* ZMAP_FILTER_H */
|
#endif /* ZMAP_FILTER_H */
|
@ -745,7 +745,7 @@ do_action: /* This label is used only to access EOF actions. */
|
|||||||
case 1:
|
case 1:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
#line 10 "lexer.l"
|
#line 10 "lexer.l"
|
||||||
yylval.int_literal = atoi(yytext); return T_NUMBER;
|
yylval.int_literal = (uint64_t) atoll(yytext); return T_NUMBER;
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
case 2:
|
case 2:
|
||||||
/* rule 2 can match eol */
|
/* rule 2 can match eol */
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
%option noinput
|
%option noinput
|
||||||
%option nounput
|
%option nounput
|
||||||
%%
|
%%
|
||||||
[0-9]+ yylval.int_literal = atoi(yytext); return T_NUMBER;
|
[0-9]+ yylval.int_literal = (uint64_t) atoll(yytext); return T_NUMBER;
|
||||||
\n /* Ignore end of line */
|
\n /* Ignore end of line */
|
||||||
[ \t]+ /* Ignore whitespace */
|
[ \t]+ /* Ignore whitespace */
|
||||||
!= return T_NOT_EQ;
|
!= return T_NOT_EQ;
|
||||||
|
@ -501,9 +501,15 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
// Parse and validate the output filter, if any
|
// Parse and validate the output filter, if any
|
||||||
if (args.output_filter_arg) {
|
if (args.output_filter_arg) {
|
||||||
|
// Run it through yyparse to build the expression tree
|
||||||
if (!parse_filter_string(args.output_filter_arg)) {
|
if (!parse_filter_string(args.output_filter_arg)) {
|
||||||
log_fatal("zmap", "Unable to parse filter expression");
|
log_fatal("zmap", "Unable to parse filter expression");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check the fields used against the fieldset in use
|
||||||
|
if (!validate_filter(zconf.filter.expression, &zconf.fsconf.defs)) {
|
||||||
|
log_fatal("zmap", "Field does not exist");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SET_BOOL(zconf.dryrun, dryrun);
|
SET_BOOL(zconf.dryrun, dryrun);
|
||||||
|
Loading…
Reference in New Issue
Block a user