116 lines
2.6 KiB
C
116 lines
2.6 KiB
C
|
/*
|
||
|
* 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 "filter.h"
|
||
|
#include "state.h"
|
||
|
#include "lexer.h"
|
||
|
#include "parser.h"
|
||
|
#include "expression.h"
|
||
|
#include "../lib/logger.h"
|
||
|
|
||
|
#include <string.h>
|
||
|
|
||
|
extern int yyparse(void);
|
||
|
|
||
|
node_t *zfilter;
|
||
|
|
||
|
static int validate_node(node_t *node, fielddefset_t *fields)
|
||
|
{
|
||
|
int index, found = 0;
|
||
|
if (node->type == OP) {
|
||
|
// These end up getting validated later
|
||
|
if (node->value.op == AND || node->value.op == OR) {
|
||
|
return 1;
|
||
|
}
|
||
|
// Comparison node (=, >, <, etc.)
|
||
|
// Validate that the field (left child) exists in the fieldset
|
||
|
for (index = 0; index < fields->len; index++) {
|
||
|
if (fields->fielddefs[index].name) {
|
||
|
if (strcmp(fields->fielddefs[index].name,
|
||
|
node->left_child->value.field
|
||
|
.fieldname) == 0) {
|
||
|
node->left_child->value.field.index =
|
||
|
index;
|
||
|
found = 1;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (!found) {
|
||
|
fprintf(stderr, "Field '%s' does not exist\n",
|
||
|
node->left_child->value.field.fieldname);
|
||
|
return 0;
|
||
|
}
|
||
|
// Fieldname is fine, match the type.
|
||
|
switch (node->right_child->type) {
|
||
|
case STRING:
|
||
|
if (strcmp(fields->fielddefs[index].type, "string") ==
|
||
|
0) {
|
||
|
return 1;
|
||
|
} else {
|
||
|
fprintf(stderr,
|
||
|
"Field '%s' is not of type 'string'\n",
|
||
|
fields->fielddefs[index].name);
|
||
|
return 0;
|
||
|
}
|
||
|
case INT:
|
||
|
if (strcmp(fields->fielddefs[index].type, "int") == 0 ||
|
||
|
strcmp(fields->fielddefs[index].type, "bool") ==
|
||
|
0) {
|
||
|
return 1;
|
||
|
} else {
|
||
|
fprintf(stderr,
|
||
|
"Field '%s' is not of type 'int'\n",
|
||
|
fields->fielddefs[index].name);
|
||
|
return 0;
|
||
|
}
|
||
|
default:
|
||
|
return 0;
|
||
|
}
|
||
|
} else {
|
||
|
// All non-op nodes are valid
|
||
|
return 1;
|
||
|
}
|
||
|
// Didn't validate
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int parse_filter_string(char *filter)
|
||
|
{
|
||
|
YY_BUFFER_STATE buffer_state = yy_scan_string(filter);
|
||
|
int status = yyparse();
|
||
|
yy_delete_buffer(buffer_state);
|
||
|
if (status) {
|
||
|
// Error
|
||
|
log_error("zmap", "Unable to parse filter string: '%s'",
|
||
|
filter);
|
||
|
return 0;
|
||
|
}
|
||
|
zconf.filter.expression = zfilter;
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* 0 Valid
|
||
|
* -1 Invalid Field Name
|
||
|
* -2 Type Mismatch
|
||
|
*/
|
||
|
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));
|
||
|
}
|