From bc3ec6456a0a56a1664d5cf5769a5920bdd80eae Mon Sep 17 00:00:00 2001 From: Alex Halderman Date: Tue, 1 Oct 2013 17:05:47 -0400 Subject: [PATCH 01/53] What Eric and Zakir said --- lib/blacklist.c | 15 +++++++++ lib/constraint.c | 81 +++++++++++++++++++++++++++++++++++++++++++----- lib/constraint.h | 6 ++-- 3 files changed, 93 insertions(+), 9 deletions(-) diff --git a/lib/blacklist.c b/lib/blacklist.c index 49eaa32..a486444 100644 --- a/lib/blacklist.c +++ b/lib/blacklist.c @@ -125,5 +125,20 @@ int blacklist_init_from_files(char *whitelist_filename, char *blacklist_filename uint64_t allowed = blacklist_count_allowed(); log_debug("blacklist", "%lu addresses allowed to be scanned (%0.0f%% of address space)", allowed, allowed*100./((long long int)1 << 32)); + + /* + // test + log_debug("blacklist", "testing started"); + uint64_t count = constraint_count_ips(constraint, ADDR_ALLOWED); + for (unsigned int i=0; i < count; i++) { + int ip = constraint_lookup_index(constraint, i, ADDR_ALLOWED); + if ((i & 0xFFFFFF) == 0) + log_info("blacklist", "%x", i & 0xFF000000); + if (constraint_lookup_ip(constraint, ip) != ADDR_ALLOWED) { + log_error("blacklist", "test failed for index %d", i); + } + } + log_debug("blacklist", "testing complete"); + */ return 0; } diff --git a/lib/constraint.c b/lib/constraint.c index aa8d0b9..17a5164 100644 --- a/lib/constraint.c +++ b/lib/constraint.c @@ -50,6 +50,7 @@ typedef struct node { struct node *l; struct node *r; value_t value; + uint64_t count; } node_t; // As an optimization, we precompute lookups for every prefix of this @@ -60,6 +61,8 @@ struct _constraint { node_t *root; // root node of the tree node_t **radix; // array of nodes for every RADIX_LENGTH prefix int optimized; // is radix populated and up-to-date? + int painted; // have we precomputed counts for each node? + value_t paint_value; // value for which we precomputed counts }; // Tree operations respect the invariant that every node that isn't a @@ -176,7 +179,7 @@ static int _lookup_ip(node_t *root, uint32_t address) // Return the value pertaining to an address. // (Note: address must be in host byte order.) -int constraint_lookup_ip(constraint_t *con, uint32_t address) +value_t constraint_lookup_ip(constraint_t *con, uint32_t address) { assert(con); if (con->optimized) { @@ -193,27 +196,91 @@ int constraint_lookup_ip(constraint_t *con, uint32_t address) } } +// Return the nth painted IP address. +static int _lookup_index(node_t *root, uint64_t n) +{ + assert(root); + node_t *node = root; + uint32_t ip = 0; + uint32_t mask = 0x80000000; + for (;;) { + if (IS_LEAF(node)) { + return ip | n; + } + if (n < node->l->count) { + node = node->l; + } else { + n -= node->l->count; + node = node->r; + ip |= mask; + } + mask >>= 1; + } +} + +// For a given value, return the IP address with zero-based index n. +// (i.e., if there are three addresses with value 0xFF, looking up index 1 +// will return the second one). +// Note that the tree must have been previously painted with this value. +uint32_t constraint_lookup_index(constraint_t *con, uint64_t index, value_t value) +{ + assert(con); + if (!con->painted || con->paint_value != value) { + constraint_paint_value(con, value); + } + if (con->optimized) { + // TK TK TK + } + + assert(index < con->root->count); + return _lookup_index(con->root, index); +} + + // Implement count_ips by recursing on halves of the tree. Size represents // the number of addresses in a prefix at the current level of the tree. -static uint64_t _count_ips_recurse(node_t *node, value_t value, uint64_t size) +// If paint is specified, each node will have its count set to the number of +// leaves under it set to value. +static uint64_t _count_ips_recurse(node_t *node, value_t value, uint64_t size, int paint) { assert(node); + uint64_t n; if (IS_LEAF(node)) { if (node->value == value) { - return size; + n = size; } else { - return 0; + n = 0; } + } else { + n = _count_ips_recurse(node->l, value, size >> 1, paint) + + _count_ips_recurse(node->r, value, size >> 1, paint); } - return _count_ips_recurse(node->l, value, size >> 1) + - _count_ips_recurse(node->r, value, size >> 1); + if (paint) { + node->count = n; + } + return n; +} + +// For each node, precompute the count of leaves beneath it set to value. +// Note that the tree can be painted for only one value at a time. +void constraint_paint_value(constraint_t *con, value_t value) +{ + assert(con); + log_info("constraint", "Painting value %lu", value); + _count_ips_recurse(con->root, value, (uint64_t)1 << 32, 1); + con->painted = 1; + con->paint_value = value; } // Return the number of addresses that have a given value. uint64_t constraint_count_ips(constraint_t *con, value_t value) { assert(con); - return _count_ips_recurse(con->root, value, (uint64_t)1 << 32); + if (con->painted && con->paint_value == value) { + return con->root->count; + } else { + return _count_ips_recurse(con->root, value, (uint64_t)1 << 32, 0); + } } // Initialize the tree. diff --git a/lib/constraint.h b/lib/constraint.h index 3e914a3..2e4f28b 100644 --- a/lib/constraint.h +++ b/lib/constraint.h @@ -2,13 +2,15 @@ #define _CONSTRAINT_H typedef struct _constraint constraint_t; -typedef int value_t; +typedef unsigned int value_t; constraint_t* constraint_init(value_t value); void constraint_free(constraint_t *con); void constraint_set(constraint_t *con, uint32_t prefix, int len, value_t value); void constraint_optimize(constraint_t *con); -int constraint_lookup_ip(constraint_t *con, uint32_t address); +value_t constraint_lookup_ip(constraint_t *con, uint32_t address); uint64_t constraint_count_ips(constraint_t *con, value_t value); +uint32_t constraint_lookup_index(constraint_t *con, uint64_t index, value_t value); +void constraint_paint_value(constraint_t *con, value_t value); #endif //_CONSTRAINT_H From 8ecbd038b5529dfb2373365e1b51c9abd1ce992c Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 3 Oct 2013 02:28:19 -0400 Subject: [PATCH 02/53] Adding radix support to constraints This allows us to lookup an index -> ip address much faster (16 seconds for ~3.7 billion addresses with sparse blacklist, vs 65 sec before radix array). Setting the PREFIX_LEN to /20, as this appears to give a good tradeoff between radix population time (<1ms), runtime (16s), and memory footprint (4MB). --- lib/blacklist.c | 6 +- lib/constraint.c | 226 +++++++++++++++++------------------------------ lib/constraint.h | 3 +- 3 files changed, 89 insertions(+), 146 deletions(-) diff --git a/lib/blacklist.c b/lib/blacklist.c index a486444..93bf98e 100644 --- a/lib/blacklist.c +++ b/lib/blacklist.c @@ -25,6 +25,10 @@ static constraint_t *constraint = NULL; +uint32_t blacklist_lookup_index(uint64_t index) { + return constraint_lookup_index(constraint, index, ADDR_ALLOWED); +} + // check whether a single IP address is allowed to be scanned. // 1 => is allowed // 0 => is not allowed @@ -121,7 +125,7 @@ int blacklist_init_from_files(char *whitelist_filename, char *blacklist_filename if (blacklist_filename) { init(blacklist_filename, "blacklist", ADDR_DISALLOWED); } - constraint_optimize(constraint); + constraint_paint_value(constraint, ADDR_ALLOWED); uint64_t allowed = blacklist_count_allowed(); log_debug("blacklist", "%lu addresses allowed to be scanned (%0.0f%% of address space)", allowed, allowed*100./((long long int)1 << 32)); diff --git a/lib/constraint.c b/lib/constraint.c index 17a5164..c49e91d 100644 --- a/lib/constraint.c +++ b/lib/constraint.c @@ -55,13 +55,13 @@ typedef struct node { // As an optimization, we precompute lookups for every prefix of this // length: -#define RADIX_LENGTH 16 +#define RADIX_LENGTH 20 struct _constraint { - node_t *root; // root node of the tree - node_t **radix; // array of nodes for every RADIX_LENGTH prefix - int optimized; // is radix populated and up-to-date? - int painted; // have we precomputed counts for each node? + node_t *root; // root node of the tree + uint32_t *radix; // array of prefixes (/RADIX_LENGTH) that are painted paint_value + size_t radix_len; // number of prefixes in radix array + int painted; // have we precomputed counts for each node? value_t paint_value; // value for which we precomputed counts }; @@ -153,7 +153,7 @@ void constraint_set(constraint_t *con, uint32_t prefix, int len, value_t value) { assert(con); _set_recurse(con->root, prefix, len, value); - con->optimized = 0; + con->painted = 0; } // Return the value pertaining to an address, according to the tree @@ -182,18 +182,7 @@ static int _lookup_ip(node_t *root, uint32_t address) value_t constraint_lookup_ip(constraint_t *con, uint32_t address) { assert(con); - if (con->optimized) { - // Use radix optimization - node_t *node = con->radix[address >> (32 - RADIX_LENGTH)]; - if (IS_LEAF(node)) { - return node->value; - } - return _lookup_ip(node, address << RADIX_LENGTH); - } else { - // Do a full lookup using the tree - log_trace("constraint", "Unoptimized lookup"); - return _lookup_ip(con->root, address); - } + return _lookup_ip(con->root, address); } // Return the nth painted IP address. @@ -228,32 +217,45 @@ uint32_t constraint_lookup_index(constraint_t *con, uint64_t index, value_t valu if (!con->painted || con->paint_value != value) { constraint_paint_value(con, value); } - if (con->optimized) { - // TK TK TK + + uint64_t radix_idx = index / (1 << (32 - RADIX_LENGTH)); + if (radix_idx < con->radix_len) { + // Radix lookup + uint32_t radix_offset = index % (1 << (32 - RADIX_LENGTH)); // TODO: bitwise maths + return con->radix[radix_idx] | radix_offset; } + // Otherwise, do the "slow" lookup in tree. + // Note that tree counts do NOT include things in the radix, + // so we subtract these off here. + index -= con->radix_len * (1 << (32 - RADIX_LENGTH)); assert(index < con->root->count); return _lookup_index(con->root, index); } - // Implement count_ips by recursing on halves of the tree. Size represents // the number of addresses in a prefix at the current level of the tree. // If paint is specified, each node will have its count set to the number of // leaves under it set to value. -static uint64_t _count_ips_recurse(node_t *node, value_t value, uint64_t size, int paint) +// If exclude_radix is specified, the number of addresses will exlcude prefixes +// that are a /RADIX_LENGTH or larger +static uint64_t _count_ips_recurse(node_t *node, value_t value, uint64_t size, int paint, int exclude_radix) { assert(node); uint64_t n; if (IS_LEAF(node)) { if (node->value == value) { n = size; + // Exclude prefixes already included in the radix + if (exclude_radix && size >= (1 << (32 -RADIX_LENGTH))) { + n = 0; + } } else { n = 0; } } else { - n = _count_ips_recurse(node->l, value, size >> 1, paint) + - _count_ips_recurse(node->r, value, size >> 1, paint); + n = _count_ips_recurse(node->l, value, size >> 1, paint, exclude_radix) + + _count_ips_recurse(node->r, value, size >> 1, paint, exclude_radix); } if (paint) { node->count = n; @@ -261,51 +263,6 @@ static uint64_t _count_ips_recurse(node_t *node, value_t value, uint64_t size, i return n; } -// For each node, precompute the count of leaves beneath it set to value. -// Note that the tree can be painted for only one value at a time. -void constraint_paint_value(constraint_t *con, value_t value) -{ - assert(con); - log_info("constraint", "Painting value %lu", value); - _count_ips_recurse(con->root, value, (uint64_t)1 << 32, 1); - con->painted = 1; - con->paint_value = value; -} - -// Return the number of addresses that have a given value. -uint64_t constraint_count_ips(constraint_t *con, value_t value) -{ - assert(con); - if (con->painted && con->paint_value == value) { - return con->root->count; - } else { - return _count_ips_recurse(con->root, value, (uint64_t)1 << 32, 0); - } -} - -// Initialize the tree. -// All addresses will initally have the given value. -constraint_t* constraint_init(value_t value) -{ - log_trace("constraint", "Initializing"); - constraint_t* con = malloc(sizeof(constraint_t)); - con->root = _create_leaf(value); - con->radix = calloc(sizeof(node_t *), 1 << RADIX_LENGTH); - assert(con->radix); - con->optimized = 0; - return con; -} - -// Deinitialize and free the tree. -void constraint_free(constraint_t *con) -{ - assert(con); - log_trace("constraint", "Cleaning up"); - _destroy_subtree(con->root); - free(con->radix); - free(con); -} - // Return a node that determines the values for the addresses with // the given prefix. This is either the internal node that // corresponds to the end of the prefix or a leaf node that @@ -317,8 +274,9 @@ static node_t* _lookup_node(node_t *root, uint32_t prefix, int len) node_t *node = root; uint32_t mask = 0x80000000; + int i; - for (int i=0; i < len; i++) { + for (i=0; i < len; i++) { if (IS_LEAF(node)) { return node; } @@ -332,21 +290,66 @@ static node_t* _lookup_node(node_t *root, uint32_t prefix, int len) return node; } -// After values have been set, precompute prefix lookups. -void constraint_optimize(constraint_t *con) +// For each node, precompute the count of leaves beneath it set to value. +// Note that the tree can be painted for only one value at a time. +void constraint_paint_value(constraint_t *con, value_t value) { assert(con); - if (con->optimized) { - return; - } - log_trace("constraint", "Optimizing constraints"); - for (uint32_t i=0; i < (1 << RADIX_LENGTH); i++) { + log_info("constraint", "Painting value %lu", value); + + // Paint everything except what we will put in radix + _count_ips_recurse(con->root, value, (uint64_t)1 << 32, 1, 1); + + // Fill in the radix array with a list of addresses + uint32_t i; + con->radix_len = 0; + for (i=0; i < (1 << RADIX_LENGTH); i++) { uint32_t prefix = i << (32 - RADIX_LENGTH); - con->radix[i] = _lookup_node(con->root, prefix, RADIX_LENGTH); + node_t *node = _lookup_node(con->root, prefix, RADIX_LENGTH); + if (IS_LEAF(node) && node->value == value) { + // Add this prefix to the radix + con->radix[con->radix_len++] = prefix; + } } - con->optimized = 1; + log_info("constraint", "%lu IPs in radix array, %lu IPs in tree", + con->radix_len * (1 << (32 - RADIX_LENGTH)), con->root->count); + con->painted = 1; + con->paint_value = value; } +// Return the number of addresses that have a given value. +uint64_t constraint_count_ips(constraint_t *con, value_t value) +{ + assert(con); + if (con->painted && con->paint_value == value) { + return con->root->count + con->radix_len * (1 << (32 - RADIX_LENGTH)); + } else { + return _count_ips_recurse(con->root, value, (uint64_t)1 << 32, 0, 0); + } +} + +// Initialize the tree. +// All addresses will initally have the given value. +constraint_t* constraint_init(value_t value) +{ + log_trace("constraint", "Initializing"); + constraint_t* con = malloc(sizeof(constraint_t)); + con->root = _create_leaf(value); + con->radix = calloc(sizeof(uint32_t), 1 << RADIX_LENGTH); + assert(con->radix); + con->painted = 0; + return con; +} + +// Deinitialize and free the tree. +void constraint_free(constraint_t *con) +{ + assert(con); + log_trace("constraint", "Cleaning up"); + _destroy_subtree(con->root); + free(con->radix); + free(con); +} /* int main(void) @@ -384,68 +387,3 @@ int main(void) } */ -/* -static int init(constraint_t *con, char *file, const char *name, value_t value) -{ - FILE *fp; - char line[1000]; - int blocked = 0; - - fp = fopen(file, "r"); - if (fp == NULL) { - log_fatal(name, "Unable to open %s file: %s: %s", - name, file, strerror(errno)); - } - - while (fgets(line, sizeof(line), fp) != NULL) { - char *comment = strchr(line, '#'); - if (comment) { - *comment = '\0'; - } - char ip[33]; - if ((sscanf(line, "%32s", ip)) == EOF) { - continue; - } - int prefix_len; - char *slash = strchr(ip, '/'); - if (slash == NULL) { - log_fatal(name, - "Unable to parse %s file: %s", - name, file); - } - // split apart network and prefix length - *slash = '\0'; - prefix_len = atoi(&slash[1]); - constraint_set(con, ntohl(inet_addr(ip)), prefix_len, value); - - blocked++; - } - fclose(fp); - return 0; -} - - - -void main() -{ - log_init(stderr, LOG_TRACE); - - constraint_t *con = constraint_init(1); - init(con, "blacklist.prefixes", "blacklist", 0); - //constraint_optimize(con); - - printf("count(0)=%lu\n", constraint_count_ips(con, 0)); - printf("count(1)=%lu\n", constraint_count_ips(con, 1)); - - uint32_t i=0, count=0; - do { - if (constraint_lookup_ip(con, i)) - count++; - } while (++i != 0); - printf("derived count(1)=%u\n", count); - - constraint_free(con); - -} - - */ diff --git a/lib/constraint.h b/lib/constraint.h index 2e4f28b..3c77e8a 100644 --- a/lib/constraint.h +++ b/lib/constraint.h @@ -1,13 +1,14 @@ #ifndef _CONSTRAINT_H #define _CONSTRAINT_H +#include + typedef struct _constraint constraint_t; typedef unsigned int value_t; constraint_t* constraint_init(value_t value); void constraint_free(constraint_t *con); void constraint_set(constraint_t *con, uint32_t prefix, int len, value_t value); -void constraint_optimize(constraint_t *con); value_t constraint_lookup_ip(constraint_t *con, uint32_t address); uint64_t constraint_count_ips(constraint_t *con, value_t value); uint32_t constraint_lookup_index(constraint_t *con, uint64_t index, value_t value); From 408e46d93923843f3e36be140193dc96ccf2f997 Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 3 Oct 2013 02:47:31 -0400 Subject: [PATCH 03/53] add blacklist_lookup_index proto --- lib/blacklist.h | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/blacklist.h b/lib/blacklist.h index 5604171..22f271a 100644 --- a/lib/blacklist.h +++ b/lib/blacklist.h @@ -3,6 +3,7 @@ #ifndef _BLACKLIST_H #define _BLACKLIST_H +uint32_t blacklist_lookup_index(uint64_t index); int blacklist_is_allowed(uint32_t s_addr); void blacklist_prefix(char *ip, int prefix_len); void whitelist_prefix(char *ip, int prefix_len); From 3aa0f27b51fe9741a7f018932c632554f5ecda98 Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 3 Oct 2013 02:48:46 -0400 Subject: [PATCH 04/53] constraints stores network order; we want to return host order --- lib/blacklist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/blacklist.c b/lib/blacklist.c index 93bf98e..a33860a 100644 --- a/lib/blacklist.c +++ b/lib/blacklist.c @@ -26,7 +26,7 @@ static constraint_t *constraint = NULL; uint32_t blacklist_lookup_index(uint64_t index) { - return constraint_lookup_index(constraint, index, ADDR_ALLOWED); + return ntohl(constraint_lookup_index(constraint, index, ADDR_ALLOWED)); } // check whether a single IP address is allowed to be scanned. From d2112701b05f564cde4d6ae9ffdcc18de4b7daf3 Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 3 Oct 2013 02:49:50 -0400 Subject: [PATCH 05/53] have cyclic use blacklist_lookup_index --- src/cyclic.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/cyclic.c b/src/cyclic.c index a42c7f4..61972e3 100644 --- a/src/cyclic.c +++ b/src/cyclic.c @@ -67,8 +67,10 @@ static const uint64_t psub1_f[] = { 2, 3, 5, 131, 364289 }; static uint64_t primroot = 0; static uint64_t current = 0; +static uint64_t num_addrs = 0; + #define COPRIME 1 -#define NOT_COPRIME 0 +#define NOT_COPRIME 0 // check whether two integers are coprime static int check_coprime(uint64_t check) @@ -145,6 +147,7 @@ int cyclic_init(uint32_t primroot_, uint32_t current_) return -1; } + num_addrs = blacklist_count_allowed(); // make sure current is an allowed ip cyclic_get_next_ip(); @@ -153,7 +156,7 @@ int cyclic_init(uint32_t primroot_, uint32_t current_) uint32_t cyclic_get_curr_ip(void) { - return (uint32_t) current; + return (uint32_t) blacklist_lookup_index(current); } uint32_t cyclic_get_primroot(void) @@ -174,11 +177,10 @@ uint32_t cyclic_get_next_ip(void) { while (1) { uint32_t candidate = cyclic_get_next_elem(); - if (!blacklist_is_allowed(candidate)) { - zsend.blacklisted++; - } else { - return candidate; + if (candidate < num_addrs) { + return blacklist_lookup_index(candidate); } + zsend.blacklisted++; } } From ec1b76148986ede46f9fa001d013203ce347a159 Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 3 Oct 2013 03:50:12 -0400 Subject: [PATCH 06/53] Support multiple cyclic groups for smaller subnets We will choose the first one in the list that is large enough to support the number of hosts chosen. This speeds up scanning small networks considerably: e.g. /16s can be scanned in <200ms (+ cooldown) --- src/cyclic.c | 97 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 72 insertions(+), 25 deletions(-) diff --git a/src/cyclic.c b/src/cyclic.c index 61972e3..04424d3 100644 --- a/src/cyclic.c +++ b/src/cyclic.c @@ -57,13 +57,48 @@ #include "aesrand.h" #define LSRC "cyclic" -#define PRIME 4294967311 // 2^32 + 15 -#define KNOWN_PRIMROOT 3 -// distinct prime factors of 2^32 + 15 -static const uint64_t psub1_f[] = { 2, 3, 5, 131, 364289 }; +typedef struct cyclic_group { + uint64_t prime; + uint64_t known_primroot; + size_t num_prime_factors; // number of unique prime factors of (prime-1) + uint64_t prime_factors[10]; // unique prime factors of (prime-1) +} cyclic_group_t; -// selected primitive root that we'll use as the generator +// We will pick the first cyclic group from this list that is +// larger than the number of IPs in our whitelist. E.g. for an +// entire Internet scan, this would be cyclic32 +// Note: this list should remain ordered by size (primes) ascending. +static cyclic_group_t groups[] = { +{ // 2^16 + 1 + .prime = 65537, + .known_primroot = 3, + .prime_factors = {2}, + .num_prime_factors = 1 +}, +{ // 2^24 + 43 + .prime = 16777259, + .known_primroot = 2, + .prime_factors = {2, 23, 103, 3541}, + .num_prime_factors = 4 +}, +{ // 2^28 + 3 + .prime = 268435459, + .known_primroot = 2, + .prime_factors = {2, 3, 19, 87211}, + .num_prime_factors = 4 +}, +{ // 2^32 + 15 + .prime = 4294967311, + .known_primroot = 3, + .prime_factors = {2, 3, 5, 131, 364289}, + .num_prime_factors = 5 +} +}; + + +// selected prime/primitive root that we'll use as the generator +static uint64_t prime = 0; static uint64_t primroot = 0; static uint64_t current = 0; @@ -73,14 +108,14 @@ static uint64_t num_addrs = 0; #define NOT_COPRIME 0 // check whether two integers are coprime -static int check_coprime(uint64_t check) +static int check_coprime(uint64_t check, const cyclic_group_t *group) { - for (unsigned i=0; i < sizeof(psub1_f)/sizeof(psub1_f[0]); i++) { - if (psub1_f[i] > check && !(psub1_f[i] % check)) { + for (unsigned i=0; i < group->num_prime_factors; i++) { + if (group->prime_factors[i] > check && !(group->prime_factors[i] % check)) { return NOT_COPRIME; - } else if (psub1_f[i] < check && !(check % psub1_f[i])) { + } else if (group->prime_factors[i] < check && !(check % group->prime_factors[i])) { return NOT_COPRIME; - } else if (psub1_f[i] == check) { + } else if (group->prime_factors[i] == check) { return NOT_COPRIME; } } @@ -88,18 +123,18 @@ static int check_coprime(uint64_t check) } // find gen of cyclic group Z modulo PRIME -static uint64_t find_primroot(void) +static uint64_t find_primroot(const cyclic_group_t *group) { // what luck, rand() returns a uint32_t! uint32_t candidate = (uint32_t) aesrand_getword() & 0xFFFF; - while(check_coprime(candidate) != COPRIME) { + while(check_coprime(candidate, group) != COPRIME) { ++candidate; } // pre-modded result is gigantic so use GMP mpz_t base, power, prime, primroot; - mpz_init_set_d(base, (double) KNOWN_PRIMROOT); + mpz_init_set_d(base, (double) group->known_primroot); mpz_init_set_d(power, (double) candidate); - mpz_init_set_d(prime, (double) PRIME); + mpz_init_set_d(prime, (double) group->prime); mpz_init(primroot); mpz_powm(primroot, base, power, prime); uint64_t retv = (uint64_t) mpz_get_ui(primroot); @@ -114,6 +149,24 @@ int cyclic_init(uint32_t primroot_, uint32_t current_) { assert(!(!primroot_ && current_)); + // Initialize blacklist + if (blacklist_init_from_files(zconf.whitelist_filename, + zconf.blacklist_filename)) { + return -1; + } + num_addrs = blacklist_count_allowed(); + + uint32_t i; + const cyclic_group_t *cur_group = NULL; + for (i=0; i num_addrs) { + cur_group = &groups[i]; + log_info("cyclic", "using prime %lu, known_primroot %lu", cur_group->prime, cur_group->known_primroot); + prime = groups[i].prime; + break; + } + } + if (zconf.use_seed) { aesrand_init(zconf.seed+1); } else { @@ -121,7 +174,7 @@ int cyclic_init(uint32_t primroot_, uint32_t current_) } if (!primroot_) { do { - primroot = find_primroot(); + primroot = find_primroot(cur_group); } while (primroot >= (1LL << 32)); log_debug(LSRC, "primitive root: %lld", primroot); current = (uint32_t) aesrand_getword() & 0xFFFF; @@ -142,12 +195,6 @@ int cyclic_init(uint32_t primroot_, uint32_t current_) } } zconf.generator = primroot; - if (blacklist_init_from_files(zconf.whitelist_filename, - zconf.blacklist_filename)) { - return -1; - } - - num_addrs = blacklist_count_allowed(); // make sure current is an allowed ip cyclic_get_next_ip(); @@ -156,7 +203,7 @@ int cyclic_init(uint32_t primroot_, uint32_t current_) uint32_t cyclic_get_curr_ip(void) { - return (uint32_t) blacklist_lookup_index(current); + return (uint32_t) blacklist_lookup_index(current-1); } uint32_t cyclic_get_primroot(void) @@ -168,7 +215,7 @@ static inline uint32_t cyclic_get_next_elem(void) { do { current *= primroot; - current %= PRIME; + current %= prime; } while (current >= (1LL << 32)); return (uint32_t) current; } @@ -177,8 +224,8 @@ uint32_t cyclic_get_next_ip(void) { while (1) { uint32_t candidate = cyclic_get_next_elem(); - if (candidate < num_addrs) { - return blacklist_lookup_index(candidate); + if (candidate-1 < num_addrs) { + return blacklist_lookup_index(candidate-1); } zsend.blacklisted++; } From 19c4a049325b7cc1401e1300bd8e7ed37ecaad6c Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 3 Oct 2013 04:17:03 -0400 Subject: [PATCH 07/53] demote spurious log_infos to log_debug --- lib/constraint.c | 4 ++-- src/cyclic.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/constraint.c b/lib/constraint.c index c49e91d..2f70dd2 100644 --- a/lib/constraint.c +++ b/lib/constraint.c @@ -295,7 +295,7 @@ static node_t* _lookup_node(node_t *root, uint32_t prefix, int len) void constraint_paint_value(constraint_t *con, value_t value) { assert(con); - log_info("constraint", "Painting value %lu", value); + log_trace("constraint", "Painting value %lu", value); // Paint everything except what we will put in radix _count_ips_recurse(con->root, value, (uint64_t)1 << 32, 1, 1); @@ -311,7 +311,7 @@ void constraint_paint_value(constraint_t *con, value_t value) con->radix[con->radix_len++] = prefix; } } - log_info("constraint", "%lu IPs in radix array, %lu IPs in tree", + log_debug("constraint", "%lu IPs in radix array, %lu IPs in tree", con->radix_len * (1 << (32 - RADIX_LENGTH)), con->root->count); con->painted = 1; con->paint_value = value; diff --git a/src/cyclic.c b/src/cyclic.c index 04424d3..7d2eeee 100644 --- a/src/cyclic.c +++ b/src/cyclic.c @@ -161,7 +161,7 @@ int cyclic_init(uint32_t primroot_, uint32_t current_) for (i=0; i num_addrs) { cur_group = &groups[i]; - log_info("cyclic", "using prime %lu, known_primroot %lu", cur_group->prime, cur_group->known_primroot); + log_debug("cyclic", "using prime %lu, known_primroot %lu", cur_group->prime, cur_group->known_primroot); prime = groups[i].prime; break; } From 154fb015259af688045266ce30da3cfaeb936f0f Mon Sep 17 00:00:00 2001 From: Justin Lecher Date: Fri, 20 Sep 2013 14:05:48 +0200 Subject: [PATCH 08/53] Convert plain Makefile into cmake The package can be configured with 4 different options: -DWITH_REDIS=ON Enable support for Redis DB -DWITH_JSON=ON Enable support for JSON based output -DENABLE_DEVELOPMENT=ON Enable all warnings and make them fatal -DENABLE_HARDENING=ON Compile and link with some hardening Use the new system by creating a build directory and change into that. And then call the following cmake -DWITH_REDIS=OFF -DWITH_JSON=ON -DENABLE_DEVELOPMENT=ON -DENABLE_HARDENING=ON /path/to/source/dir/ make make DESTDIR="/..." install Signed-off-by: Justin Lecher Merged by David Adrian - Remove src/Makefile - Updated .gitignore for CMake --- .gitignore | 4 ++ CMakeLists.txt | 72 +++++++++++++++++++++++++++++++++++ src/CMakeLists.txt | 94 ++++++++++++++++++++++++++++++++++++++++++++++ src/Makefile | 81 --------------------------------------- 4 files changed, 170 insertions(+), 81 deletions(-) create mode 100644 CMakeLists.txt create mode 100644 src/CMakeLists.txt delete mode 100644 src/Makefile diff --git a/.gitignore b/.gitignore index 16cfc29..4c3dc40 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,7 @@ *~ \#* src/zmap +CMakeFiles +*.cmake +Makefile +CMakeCache.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..8e2d2b4 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,72 @@ +cmake_minimum_required (VERSION 2.6) +project (ZMAP C) + +option(WITH_REDIS "Build with support for Redis DB" OFF) +option(WITH_JSON "Build with support for JSON" OFF) +option(ENABLE_DEVELOPMENT "Enable development specific compiler and linker flags" OFF) +option(ENABLE_HARDENING "Add hardening specific compiler and linker flags" OFF) + +if(ENABLE_DEVELOPMENT) + # Hardening and warnings for building with gcc + # Maybe add -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations + set(GCCWARNINGS + "-Wall -Wformat=2 -Wno-format-nonliteral" + "-pedantic -fno-strict-aliasing" + "-Wextra" + "-Wfloat-equal -Wundef -Wwrite-strings -Wredundant-decls" + "-Wnested-externs -Wbad-function-cast -Winit-self" + "-Wmissing-noreturn -Wnormalized=id" + "-Wstack-protector" + "-Werror" + ) + + # Fix line breaks + string(REPLACE ";" " " GCCWARNINGS "${GCCWARNINGS}") + + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GCCWARNINGS} -g") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -g") +endif() + +if(ENABLE_HARDENING) + set(GCCHARDENING "-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fstack-protector-all -fwrapv -fPIC --param ssp-buffer-size=1") + set(LDHARDENING "-z relro -z now") + + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${GCCHARDENING}") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${LDHARDENING}") +endif() + +if(WITH_REDIS) + set(REDIS_LIBS hiredis) + add_definitions("-DREDIS") +endif() + +if(WITH_JSON) + include(FindPkgConfig) + pkg_check_modules(JSON json-c) + if(NOT JSON_FOUND) + set(JSON_CFLAGS "") + set(JSON_LIBS "-ljson-c") + include_directories("/usr/local/include/json-c/") + endif() + + add_definitions("-DJSON") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${JSON_CFLAGS}") +endif() + +# Standard FLAGS +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99") +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pthread") + +# Extra target FLAGS +set(CMAKE_C_FLAGS_DEBUG "-O2 -g") +set(CMAKE_C_FLAGS_RELEASE "-O2") + +add_subdirectory(src) + +# Install conf files +FILE(GLOB CONF_FILES "conf/*") +install( + FILES + ${CONF_FILES} + DESTINATION "/etc/zmap/" + ) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..50bf1ee --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,94 @@ +include_directories( + "${CMAKE_CURRENT_BINARY_DIR}" + ${PROJECT_SOURCE_DIR}/lib + ${PROJECT_SOURCE_DIR}/src + ${PROJECT_SOURCE_DIR}/src/output_modules + ) + +SET(LIB_SOURCES + ${PROJECT_SOURCE_DIR}/lib/blacklist.c + ${PROJECT_SOURCE_DIR}/lib/constraint.c + ${PROJECT_SOURCE_DIR}/lib/logger.c + ${PROJECT_SOURCE_DIR}/lib/random.c + ${PROJECT_SOURCE_DIR}/lib/rijndael-alg-fst.c +) + +# ADD YOUR PROBE MODULE HERE +SET(EXTRA_PROBE_MODULES + + ) + +# ADD YOUR OUTPUT MODULE HERE +SET(EXTRA_OUTPUT_MODULES + + ) + +SET(OUTPUT_MODULE_SOURCES +# output_modules/module_extended_file.c +# output_modules/module_simple_file.c + output_modules/module_csv.c + output_modules/output_modules.c + ) + +SET(PROBE_MODULE_SOURCES + probe_modules/module_icmp_echo.c + probe_modules/module_tcp_synscan.c + probe_modules/module_udp.c + probe_modules/packet.c + probe_modules/probe_modules.c + ) + +SET(SOURCES + aesrand.c + cyclic.c + fieldset.c + get_gateway.c + monitor.c + recv.c + send.c + state.c + validate.c + zmap.c + zopt_compat.c + "${CMAKE_CURRENT_BINARY_DIR}/zopt.h" + ${EXTRA_PROBE_MODULES} + ${EXTRA_OUTPUT_MODULES} + ${PROBE_MODULE_SOURCES} + ${OUTPUT_MODULE_SOURCES} + ${LIB_SOURCES} + ) + +if (WITH_JSON) + SET(SOURCES ${SOURCES} output_modules/module_json.c) +endif() + +if (WITH_REDIS) + SET(SOURCES ${SOURCES} ${PROJECT_SOURCE_DIR}/lib/redis.c output_modules/module_redis.c) +endif() + +add_custom_command(OUTPUT zopt.h + COMMAND gengetopt -C --no-help --no-version -i "${CMAKE_CURRENT_SOURCE_DIR}/zopt.ggo" -F "${CMAKE_CURRENT_BINARY_DIR}/zopt" + ) + +add_executable(zmap ${SOURCES}) + +target_link_libraries( + zmap + pcap gmp m + ${REDIS_LIBS} + ${JSON_LIBRARIES} + ) + +# Install binary +install( + TARGETS + zmap + RUNTIME DESTINATION sbin +) + +# Install Manpages +install( + FILES + zmap.1 + DESTINATION share/man/man1 + ) diff --git a/src/Makefile b/src/Makefile deleted file mode 100644 index a1446dd..0000000 --- a/src/Makefile +++ /dev/null @@ -1,81 +0,0 @@ -INCLUDE+=-I../lib -I./ -Ioutput_modules -LDFLAGS+=-pthread -LDLIBS+=-lpcap -lgmp -lm -TARGETS=zmap -VPATH=../lib:output_modules:probe_modules -PREFIX=/usr/local - -INSTALL=install -INSTALLDATA=install -m 644 -mandir=$(PREFIX)/man/man1/ -oldmanfile=/usr/share/man/man1/zmap.1 -bindir=$(PREFIX)/sbin - -# Hardening and warnings for building with gcc -# Maybe add -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -GCCWARNINGS = -Wall -Wformat=2 -Wno-format-nonliteral\ --pedantic -fno-strict-aliasing \ --Wextra \ --Wfloat-equal -Wundef -Wwrite-strings -Wredundant-decls \ --Wnested-externs -Wbad-function-cast -Winit-self \ --Wmissing-noreturn -Wnormalized=id \ --Wstack-protector - -GCCHARDENING=-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fstack-protector-all -fwrapv -fPIC --param ssp-buffer-size=1 -LDHARDENING=-z relro -z now - -EXTRACFLAGS=-std=gnu99 -g -O2 $(GCCHARDENING) $(GCCWARNINGS) $(EXTRA_CFLAGS) -Werror -EXTRALDFLAGS= $(LDHARDENING) - -CFLAGS+=$(INCLUDE) $(EXTRACFLAGS) -LDFLAGS+=$(EXTRALDFLAGS) - -probemodules=module_tcp_synscan.o module_icmp_echo.o module_udp.o #ADD YOUR PROBE MODULE HERE -outputmodules= module_csv.o #ADD YOUR OUTPUT MODULE HERE - -objects=constraint.o blacklist.o cyclic.o logger.o send.o recv.o state.o monitor.o zopt_compat.o zmap.o random.o output_modules.o packet.o probe_modules.o ${probemodules} ${outputmodules} validate.o rijndael-alg-fst.o get_gateway.o aesrand.o fieldset.o -redis_objects=module_redis.o redis.o - -ifeq ($(REDIS), true) - LDLIBS+=-lhiredis - objects+=$(redis_objects) - CFLAGS+=-DREDIS -endif - -ifeq ($(JSON), true) - LDLIBS+=$(shell pkg-config --libs json-c) - CFLAGS+=-DJSON $(shell pkg-config --cflags json-c) - objects+=module_json.o -endif - -all: $(TARGETS) - -$(TARGETS): - $(CC) $(CFLAGS) $(DFLAGS) $(LDFLAGS) $^ -o $@ $(LDLIBS) - -zmap: $(objects) - -zopt_compat.o: zopt.c - -zopt.c zopt.h: zopt.ggo - gengetopt -C --no-help --no-version -i $^ -F $* - -install: zmap - $(INSTALL) zmap $(bindir)/zmap - test -d /etc/zmap || (mkdir /etc/zmap && $(INSTALLDATA) ../conf/* /etc/zmap/) - test -f $(oldmanfile) && rm -f $(oldmanfile) && mandb -f $(oldmanfile) || /bin/true # remove old man page if it's there - test -d $(mandir) || mkdir -p $(mandir) - $(INSTALLDATA) ./zmap.1 $(mandir) - @echo "\n**************\nSuccess! ZMap is installed. Try running (as root):\nzmap -p 80 -N 10 -B 1M -o -\n**************" - -uninstall: - test -f $(oldmanfile) && rm -f $(oldmanfile) && mandb -f $(oldmanfile) || /bin/true # remove old man page if it's there - test -f $(mandir)/zmap.1 && rm -f $(mandir)/zmap.1 && mandb -f $(mandir)/zmap.1 || /bin/true # remove current man page if it's there - rm -f $(bindir)/zmap - - -clean: - -rm -f $(objects) $(redis_objects) $(TARGETS) - -.PHONY: install clean - From 21fa755c13c09d9a470bf5966d809bde395483ba Mon Sep 17 00:00:00 2001 From: David Adrian Date: Thu, 3 Oct 2013 12:14:36 -0400 Subject: [PATCH 09/53] Finish moving zmap to CMake - Generalize libjson support in CMakeLists - Remove zopt.h, zopt.c from the repository --- .gitignore | 2 + CMakeLists.txt | 10 +- src/zopt.c | 1399 ------------------------------------------------ src/zopt.h | 306 ----------- 4 files changed, 7 insertions(+), 1710 deletions(-) delete mode 100644 src/zopt.c delete mode 100644 src/zopt.h diff --git a/.gitignore b/.gitignore index 4c3dc40..889d9e6 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,5 @@ CMakeFiles *.cmake Makefile CMakeCache.txt +src/zopt.h +src/zopt.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 8e2d2b4..0a403b7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,11 +42,11 @@ endif() if(WITH_JSON) include(FindPkgConfig) - pkg_check_modules(JSON json-c) - if(NOT JSON_FOUND) - set(JSON_CFLAGS "") - set(JSON_LIBS "-ljson-c") - include_directories("/usr/local/include/json-c/") + pkg_check_modules(JSON json) + if(JSON_FOUND) + include_directories(JSON_INCLUDE_DIRS) + else() + message(FATAL_ERROR "Did not find libjson") endif() add_definitions("-DJSON") diff --git a/src/zopt.c b/src/zopt.c deleted file mode 100644 index 3210e44..0000000 --- a/src/zopt.c +++ /dev/null @@ -1,1399 +0,0 @@ -/* - File autogenerated by gengetopt version 2.22.5 - generated with the following command: - gengetopt -C --no-help --no-version -i zopt.ggo -F zopt - - The developers of gengetopt consider the fixed text that goes in all - gengetopt output files to be in the public domain: - we make no copyright claims on it. -*/ - -/* If we use autoconf. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include - -#ifndef FIX_UNUSED -#define FIX_UNUSED(X) (void) (X) /* avoid warnings for unused params */ -#endif - -#include - -#include "zopt.h" - -const char *gengetopt_args_info_purpose = "A fast Internet-wide scanner."; - -const char *gengetopt_args_info_usage = "Usage: zmap [OPTIONS]..."; - -const char *gengetopt_args_info_description = ""; - -const char *gengetopt_args_info_help[] = { - "Basic arguments:", - " -p, --target-port=port TCP port number to scan (for SYN scans)", - " -o, --output-file=name Output file", - " -b, --blacklist-file=path File of subnets to exclude, in CIDR notation, \n e.g. 192.168.0.0/16", - " -w, --whitelist-file=path File of subnets to constrain scan to, in CIDR \n notation, e.g. 192.168.0.0/16", - " -f, --output-fields=fields Fields that should be output in result set", - "\nScan options:", - " -n, --max-targets=n Cap number of targets to probe (as a number or \n a percentage of the address space)", - " -N, --max-results=n Cap number of results to return", - " -t, --max-runtime=ses Cap length of time for sending packets", - " -r, --rate=pps Set send rate in packets/sec", - " -B, --bandwidth=bps Set send rate in bits/second (supports suffixes \n G, M and K)", - " -c, --cooldown-time=secs How long to continue receiving after sending \n last probe (default=`8')", - " -e, --seed=n Seed used to select address permutation", - " -T, --sender-threads=n Threads used to send packets (default=`1')", - " -P, --probes=n Number of probes to send to each IP \n (default=`1')", - " -d, --dryrun Don't actually send packets", - "\nNetwork options:", - " -s, --source-port=port|range Source port(s) for scan packets", - " -S, --source-ip=ip|range Source address(es) for scan packets", - " -G, --gateway-mac=addr Specify gateway MAC address", - " -i, --interface=name Specify network interface to use", - " -X, --vpn Sends IP packets instead of Ethernet (for VPNs)", - "\nAdvanced options:", - " -M, --probe-module=name Select probe module (default=`tcp_synscan')", - " -O, --output-module=name Select output module (default=`simple_file')", - " --probe-args=args Arguments to pass to probe module", - " --output-args=args Arguments to pass to output module", - " --list-output-modules List available output modules", - " --list-probe-modules List available probe modules", - " --list-output-fields List all fields that can be output by selected \n probe module", - "\nAdditional options:", - " -C, --config=filename Read a configuration file, which can specify \n any of these options \n (default=`/etc/zmap/zmap.conf')", - " -q, --quiet Do not print status updates", - " -g, --summary Print configuration and summary at end of scan", - " -v, --verbosity=n Level of log detail (0-5) (default=`3')", - " -h, --help Print help and exit", - " -V, --version Print version and exit", - "\nExamples:\n zmap -p 443 (scans the whole Internet for hosts with port 443 open)\n zmap -N 5 -B 10M -p 80 -o - (find 5 HTTP servers, scanning at 10 Mb/s)", - 0 -}; - -typedef enum {ARG_NO - , ARG_STRING - , ARG_INT -} cmdline_parser_arg_type; - -static -void clear_given (struct gengetopt_args_info *args_info); -static -void clear_args (struct gengetopt_args_info *args_info); - -static int -cmdline_parser_internal (int argc, char **argv, struct gengetopt_args_info *args_info, - struct cmdline_parser_params *params, const char *additional_error); - -struct line_list -{ - char * string_arg; - struct line_list * next; -}; - -static struct line_list *cmd_line_list = 0; -static struct line_list *cmd_line_list_tmp = 0; - -static void -free_cmd_list(void) -{ - /* free the list of a previous call */ - if (cmd_line_list) - { - while (cmd_line_list) { - cmd_line_list_tmp = cmd_line_list; - cmd_line_list = cmd_line_list->next; - free (cmd_line_list_tmp->string_arg); - free (cmd_line_list_tmp); - } - } -} - - -static char * -gengetopt_strdup (const char *s); - -static -void clear_given (struct gengetopt_args_info *args_info) -{ - args_info->target_port_given = 0 ; - args_info->output_file_given = 0 ; - args_info->blacklist_file_given = 0 ; - args_info->whitelist_file_given = 0 ; - args_info->output_fields_given = 0 ; - args_info->max_targets_given = 0 ; - args_info->max_results_given = 0 ; - args_info->max_runtime_given = 0 ; - args_info->rate_given = 0 ; - args_info->bandwidth_given = 0 ; - args_info->cooldown_time_given = 0 ; - args_info->seed_given = 0 ; - args_info->sender_threads_given = 0 ; - args_info->probes_given = 0 ; - args_info->dryrun_given = 0 ; - args_info->source_port_given = 0 ; - args_info->source_ip_given = 0 ; - args_info->gateway_mac_given = 0 ; - args_info->interface_given = 0 ; - args_info->vpn_given = 0 ; - args_info->probe_module_given = 0 ; - args_info->output_module_given = 0 ; - args_info->probe_args_given = 0 ; - args_info->output_args_given = 0 ; - args_info->list_output_modules_given = 0 ; - args_info->list_probe_modules_given = 0 ; - args_info->list_output_fields_given = 0 ; - args_info->config_given = 0 ; - args_info->quiet_given = 0 ; - args_info->summary_given = 0 ; - args_info->verbosity_given = 0 ; - args_info->help_given = 0 ; - args_info->version_given = 0 ; -} - -static -void clear_args (struct gengetopt_args_info *args_info) -{ - FIX_UNUSED (args_info); - args_info->target_port_orig = NULL; - args_info->output_file_arg = NULL; - args_info->output_file_orig = NULL; - args_info->blacklist_file_arg = NULL; - args_info->blacklist_file_orig = NULL; - args_info->whitelist_file_arg = NULL; - args_info->whitelist_file_orig = NULL; - args_info->output_fields_arg = NULL; - args_info->output_fields_orig = NULL; - args_info->max_targets_arg = NULL; - args_info->max_targets_orig = NULL; - args_info->max_results_orig = NULL; - args_info->max_runtime_orig = NULL; - args_info->rate_orig = NULL; - args_info->bandwidth_arg = NULL; - args_info->bandwidth_orig = NULL; - args_info->cooldown_time_arg = 8; - args_info->cooldown_time_orig = NULL; - args_info->seed_orig = NULL; - args_info->sender_threads_arg = 1; - args_info->sender_threads_orig = NULL; - args_info->probes_arg = 1; - args_info->probes_orig = NULL; - args_info->source_port_arg = NULL; - args_info->source_port_orig = NULL; - args_info->source_ip_arg = NULL; - args_info->source_ip_orig = NULL; - args_info->gateway_mac_arg = NULL; - args_info->gateway_mac_orig = NULL; - args_info->interface_arg = NULL; - args_info->interface_orig = NULL; - args_info->probe_module_arg = gengetopt_strdup ("tcp_synscan"); - args_info->probe_module_orig = NULL; - args_info->output_module_arg = gengetopt_strdup ("simple_file"); - args_info->output_module_orig = NULL; - args_info->probe_args_arg = NULL; - args_info->probe_args_orig = NULL; - args_info->output_args_arg = NULL; - args_info->output_args_orig = NULL; - args_info->config_arg = gengetopt_strdup ("/etc/zmap/zmap.conf"); - args_info->config_orig = NULL; - args_info->verbosity_arg = 3; - args_info->verbosity_orig = NULL; - -} - -static -void init_args_info(struct gengetopt_args_info *args_info) -{ - - - args_info->target_port_help = gengetopt_args_info_help[1] ; - args_info->output_file_help = gengetopt_args_info_help[2] ; - args_info->blacklist_file_help = gengetopt_args_info_help[3] ; - args_info->whitelist_file_help = gengetopt_args_info_help[4] ; - args_info->output_fields_help = gengetopt_args_info_help[5] ; - args_info->max_targets_help = gengetopt_args_info_help[7] ; - args_info->max_results_help = gengetopt_args_info_help[8] ; - args_info->max_runtime_help = gengetopt_args_info_help[9] ; - args_info->rate_help = gengetopt_args_info_help[10] ; - args_info->bandwidth_help = gengetopt_args_info_help[11] ; - args_info->cooldown_time_help = gengetopt_args_info_help[12] ; - args_info->seed_help = gengetopt_args_info_help[13] ; - args_info->sender_threads_help = gengetopt_args_info_help[14] ; - args_info->probes_help = gengetopt_args_info_help[15] ; - args_info->dryrun_help = gengetopt_args_info_help[16] ; - args_info->source_port_help = gengetopt_args_info_help[18] ; - args_info->source_ip_help = gengetopt_args_info_help[19] ; - args_info->gateway_mac_help = gengetopt_args_info_help[20] ; - args_info->interface_help = gengetopt_args_info_help[21] ; - args_info->vpn_help = gengetopt_args_info_help[22] ; - args_info->probe_module_help = gengetopt_args_info_help[24] ; - args_info->output_module_help = gengetopt_args_info_help[25] ; - args_info->probe_args_help = gengetopt_args_info_help[26] ; - args_info->output_args_help = gengetopt_args_info_help[27] ; - args_info->list_output_modules_help = gengetopt_args_info_help[28] ; - args_info->list_probe_modules_help = gengetopt_args_info_help[29] ; - args_info->list_output_fields_help = gengetopt_args_info_help[30] ; - args_info->config_help = gengetopt_args_info_help[32] ; - args_info->quiet_help = gengetopt_args_info_help[33] ; - args_info->summary_help = gengetopt_args_info_help[34] ; - args_info->verbosity_help = gengetopt_args_info_help[35] ; - args_info->help_help = gengetopt_args_info_help[36] ; - args_info->version_help = gengetopt_args_info_help[37] ; - -} - -void -cmdline_parser_print_version (void) -{ - printf ("%s %s\n", - (strlen(CMDLINE_PARSER_PACKAGE_NAME) ? CMDLINE_PARSER_PACKAGE_NAME : CMDLINE_PARSER_PACKAGE), - CMDLINE_PARSER_VERSION); -} - -static void print_help_common(void) { - cmdline_parser_print_version (); - - if (strlen(gengetopt_args_info_purpose) > 0) - printf("\n%s\n", gengetopt_args_info_purpose); - - if (strlen(gengetopt_args_info_usage) > 0) - printf("\n%s\n", gengetopt_args_info_usage); - - printf("\n"); - - if (strlen(gengetopt_args_info_description) > 0) - printf("%s\n\n", gengetopt_args_info_description); -} - -void -cmdline_parser_print_help (void) -{ - int i = 0; - print_help_common(); - while (gengetopt_args_info_help[i]) - printf("%s\n", gengetopt_args_info_help[i++]); -} - -void -cmdline_parser_init (struct gengetopt_args_info *args_info) -{ - clear_given (args_info); - clear_args (args_info); - init_args_info (args_info); -} - -void -cmdline_parser_params_init(struct cmdline_parser_params *params) -{ - if (params) - { - params->override = 0; - params->initialize = 1; - params->check_required = 1; - params->check_ambiguity = 0; - params->print_errors = 1; - } -} - -struct cmdline_parser_params * -cmdline_parser_params_create(void) -{ - struct cmdline_parser_params *params = - (struct cmdline_parser_params *)malloc(sizeof(struct cmdline_parser_params)); - cmdline_parser_params_init(params); - return params; -} - -static void -free_string_field (char **s) -{ - if (*s) - { - free (*s); - *s = 0; - } -} - - -static void -cmdline_parser_release (struct gengetopt_args_info *args_info) -{ - - free_string_field (&(args_info->target_port_orig)); - free_string_field (&(args_info->output_file_arg)); - free_string_field (&(args_info->output_file_orig)); - free_string_field (&(args_info->blacklist_file_arg)); - free_string_field (&(args_info->blacklist_file_orig)); - free_string_field (&(args_info->whitelist_file_arg)); - free_string_field (&(args_info->whitelist_file_orig)); - free_string_field (&(args_info->output_fields_arg)); - free_string_field (&(args_info->output_fields_orig)); - free_string_field (&(args_info->max_targets_arg)); - free_string_field (&(args_info->max_targets_orig)); - free_string_field (&(args_info->max_results_orig)); - free_string_field (&(args_info->max_runtime_orig)); - free_string_field (&(args_info->rate_orig)); - free_string_field (&(args_info->bandwidth_arg)); - free_string_field (&(args_info->bandwidth_orig)); - free_string_field (&(args_info->cooldown_time_orig)); - free_string_field (&(args_info->seed_orig)); - free_string_field (&(args_info->sender_threads_orig)); - free_string_field (&(args_info->probes_orig)); - free_string_field (&(args_info->source_port_arg)); - free_string_field (&(args_info->source_port_orig)); - free_string_field (&(args_info->source_ip_arg)); - free_string_field (&(args_info->source_ip_orig)); - free_string_field (&(args_info->gateway_mac_arg)); - free_string_field (&(args_info->gateway_mac_orig)); - free_string_field (&(args_info->interface_arg)); - free_string_field (&(args_info->interface_orig)); - free_string_field (&(args_info->probe_module_arg)); - free_string_field (&(args_info->probe_module_orig)); - free_string_field (&(args_info->output_module_arg)); - free_string_field (&(args_info->output_module_orig)); - free_string_field (&(args_info->probe_args_arg)); - free_string_field (&(args_info->probe_args_orig)); - free_string_field (&(args_info->output_args_arg)); - free_string_field (&(args_info->output_args_orig)); - free_string_field (&(args_info->config_arg)); - free_string_field (&(args_info->config_orig)); - free_string_field (&(args_info->verbosity_orig)); - - - - clear_given (args_info); -} - - -static void -write_into_file(FILE *outfile, const char *opt, const char *arg, const char *values[]) -{ - FIX_UNUSED (values); - if (arg) { - fprintf(outfile, "%s=\"%s\"\n", opt, arg); - } else { - fprintf(outfile, "%s\n", opt); - } -} - - -int -cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info) -{ - int i = 0; - - if (!outfile) - { - fprintf (stderr, "%s: cannot dump options to stream\n", CMDLINE_PARSER_PACKAGE); - return EXIT_FAILURE; - } - - if (args_info->target_port_given) - write_into_file(outfile, "target-port", args_info->target_port_orig, 0); - if (args_info->output_file_given) - write_into_file(outfile, "output-file", args_info->output_file_orig, 0); - if (args_info->blacklist_file_given) - write_into_file(outfile, "blacklist-file", args_info->blacklist_file_orig, 0); - if (args_info->whitelist_file_given) - write_into_file(outfile, "whitelist-file", args_info->whitelist_file_orig, 0); - if (args_info->output_fields_given) - write_into_file(outfile, "output-fields", args_info->output_fields_orig, 0); - if (args_info->max_targets_given) - write_into_file(outfile, "max-targets", args_info->max_targets_orig, 0); - if (args_info->max_results_given) - write_into_file(outfile, "max-results", args_info->max_results_orig, 0); - if (args_info->max_runtime_given) - write_into_file(outfile, "max-runtime", args_info->max_runtime_orig, 0); - if (args_info->rate_given) - write_into_file(outfile, "rate", args_info->rate_orig, 0); - if (args_info->bandwidth_given) - write_into_file(outfile, "bandwidth", args_info->bandwidth_orig, 0); - if (args_info->cooldown_time_given) - write_into_file(outfile, "cooldown-time", args_info->cooldown_time_orig, 0); - if (args_info->seed_given) - write_into_file(outfile, "seed", args_info->seed_orig, 0); - if (args_info->sender_threads_given) - write_into_file(outfile, "sender-threads", args_info->sender_threads_orig, 0); - if (args_info->probes_given) - write_into_file(outfile, "probes", args_info->probes_orig, 0); - if (args_info->dryrun_given) - write_into_file(outfile, "dryrun", 0, 0 ); - if (args_info->source_port_given) - write_into_file(outfile, "source-port", args_info->source_port_orig, 0); - if (args_info->source_ip_given) - write_into_file(outfile, "source-ip", args_info->source_ip_orig, 0); - if (args_info->gateway_mac_given) - write_into_file(outfile, "gateway-mac", args_info->gateway_mac_orig, 0); - if (args_info->interface_given) - write_into_file(outfile, "interface", args_info->interface_orig, 0); - if (args_info->vpn_given) - write_into_file(outfile, "vpn", 0, 0 ); - if (args_info->probe_module_given) - write_into_file(outfile, "probe-module", args_info->probe_module_orig, 0); - if (args_info->output_module_given) - write_into_file(outfile, "output-module", args_info->output_module_orig, 0); - if (args_info->probe_args_given) - write_into_file(outfile, "probe-args", args_info->probe_args_orig, 0); - if (args_info->output_args_given) - write_into_file(outfile, "output-args", args_info->output_args_orig, 0); - if (args_info->list_output_modules_given) - write_into_file(outfile, "list-output-modules", 0, 0 ); - if (args_info->list_probe_modules_given) - write_into_file(outfile, "list-probe-modules", 0, 0 ); - if (args_info->list_output_fields_given) - write_into_file(outfile, "list-output-fields", 0, 0 ); - if (args_info->config_given) - write_into_file(outfile, "config", args_info->config_orig, 0); - if (args_info->quiet_given) - write_into_file(outfile, "quiet", 0, 0 ); - if (args_info->summary_given) - write_into_file(outfile, "summary", 0, 0 ); - if (args_info->verbosity_given) - write_into_file(outfile, "verbosity", args_info->verbosity_orig, 0); - if (args_info->help_given) - write_into_file(outfile, "help", 0, 0 ); - if (args_info->version_given) - write_into_file(outfile, "version", 0, 0 ); - - - i = EXIT_SUCCESS; - return i; -} - -int -cmdline_parser_file_save(const char *filename, struct gengetopt_args_info *args_info) -{ - FILE *outfile; - int i = 0; - - outfile = fopen(filename, "w"); - - if (!outfile) - { - fprintf (stderr, "%s: cannot open file for writing: %s\n", CMDLINE_PARSER_PACKAGE, filename); - return EXIT_FAILURE; - } - - i = cmdline_parser_dump(outfile, args_info); - fclose (outfile); - - return i; -} - -void -cmdline_parser_free (struct gengetopt_args_info *args_info) -{ - cmdline_parser_release (args_info); -} - -/** @brief replacement of strdup, which is not standard */ -char * -gengetopt_strdup (const char *s) -{ - char *result = 0; - if (!s) - return result; - - result = (char*)malloc(strlen(s) + 1); - if (result == (char*)0) - return (char*)0; - strcpy(result, s); - return result; -} - -int -cmdline_parser (int argc, char **argv, struct gengetopt_args_info *args_info) -{ - return cmdline_parser2 (argc, argv, args_info, 0, 1, 1); -} - -int -cmdline_parser_ext (int argc, char **argv, struct gengetopt_args_info *args_info, - struct cmdline_parser_params *params) -{ - int result; - result = cmdline_parser_internal (argc, argv, args_info, params, 0); - - if (result == EXIT_FAILURE) - { - cmdline_parser_free (args_info); - exit (EXIT_FAILURE); - } - - return result; -} - -int -cmdline_parser2 (int argc, char **argv, struct gengetopt_args_info *args_info, int override, int initialize, int check_required) -{ - int result; - struct cmdline_parser_params params; - - params.override = override; - params.initialize = initialize; - params.check_required = check_required; - params.check_ambiguity = 0; - params.print_errors = 1; - - result = cmdline_parser_internal (argc, argv, args_info, ¶ms, 0); - - if (result == EXIT_FAILURE) - { - cmdline_parser_free (args_info); - exit (EXIT_FAILURE); - } - - return result; -} - -int -cmdline_parser_required (struct gengetopt_args_info *args_info, const char *prog_name) -{ - FIX_UNUSED (args_info); - FIX_UNUSED (prog_name); - return EXIT_SUCCESS; -} - - -static char *package_name = 0; - -/** - * @brief updates an option - * @param field the generic pointer to the field to update - * @param orig_field the pointer to the orig field - * @param field_given the pointer to the number of occurrence of this option - * @param prev_given the pointer to the number of occurrence already seen - * @param value the argument for this option (if null no arg was specified) - * @param possible_values the possible values for this option (if specified) - * @param default_value the default value (in case the option only accepts fixed values) - * @param arg_type the type of this option - * @param check_ambiguity @see cmdline_parser_params.check_ambiguity - * @param override @see cmdline_parser_params.override - * @param no_free whether to free a possible previous value - * @param multiple_option whether this is a multiple option - * @param long_opt the corresponding long option - * @param short_opt the corresponding short option (or '-' if none) - * @param additional_error possible further error specification - */ -static -int update_arg(void *field, char **orig_field, - unsigned int *field_given, unsigned int *prev_given, - char *value, const char *possible_values[], - const char *default_value, - cmdline_parser_arg_type arg_type, - int check_ambiguity, int override, - int no_free, int multiple_option, - const char *long_opt, char short_opt, - const char *additional_error) -{ - char *stop_char = 0; - const char *val = value; - int found; - char **string_field; - FIX_UNUSED (field); - - stop_char = 0; - found = 0; - - if (!multiple_option && prev_given && (*prev_given || (check_ambiguity && *field_given))) - { - if (short_opt != '-') - fprintf (stderr, "%s: `--%s' (`-%c') option given more than once%s\n", - package_name, long_opt, short_opt, - (additional_error ? additional_error : "")); - else - fprintf (stderr, "%s: `--%s' option given more than once%s\n", - package_name, long_opt, - (additional_error ? additional_error : "")); - return 1; /* failure */ - } - - FIX_UNUSED (default_value); - - if (field_given && *field_given && ! override) - return 0; - if (prev_given) - (*prev_given)++; - if (field_given) - (*field_given)++; - if (possible_values) - val = possible_values[found]; - - switch(arg_type) { - case ARG_INT: - if (val) *((int *)field) = strtol (val, &stop_char, 0); - break; - case ARG_STRING: - if (val) { - string_field = (char **)field; - if (!no_free && *string_field) - free (*string_field); /* free previous string */ - *string_field = gengetopt_strdup (val); - } - break; - default: - break; - }; - - /* check numeric conversion */ - switch(arg_type) { - case ARG_INT: - if (val && !(stop_char && *stop_char == '\0')) { - fprintf(stderr, "%s: invalid numeric value: %s\n", package_name, val); - return 1; /* failure */ - } - break; - default: - ; - }; - - /* store the original value */ - switch(arg_type) { - case ARG_NO: - break; - default: - if (value && orig_field) { - if (no_free) { - *orig_field = value; - } else { - if (*orig_field) - free (*orig_field); /* free previous string */ - *orig_field = gengetopt_strdup (value); - } - } - }; - - return 0; /* OK */ -} - - -int -cmdline_parser_internal ( - int argc, char **argv, struct gengetopt_args_info *args_info, - struct cmdline_parser_params *params, const char *additional_error) -{ - int c; /* Character of the parsed option. */ - - int error = 0; - struct gengetopt_args_info local_args_info; - - int override; - int initialize; - int check_required; - int check_ambiguity; - - package_name = argv[0]; - - override = params->override; - initialize = params->initialize; - check_required = params->check_required; - check_ambiguity = params->check_ambiguity; - - if (initialize) - cmdline_parser_init (args_info); - - cmdline_parser_init (&local_args_info); - - optarg = 0; - optind = 0; - opterr = params->print_errors; - optopt = '?'; - - while (1) - { - int option_index = 0; - - static struct option long_options[] = { - { "target-port", 1, NULL, 'p' }, - { "output-file", 1, NULL, 'o' }, - { "blacklist-file", 1, NULL, 'b' }, - { "whitelist-file", 1, NULL, 'w' }, - { "output-fields", 1, NULL, 'f' }, - { "max-targets", 1, NULL, 'n' }, - { "max-results", 1, NULL, 'N' }, - { "max-runtime", 1, NULL, 't' }, - { "rate", 1, NULL, 'r' }, - { "bandwidth", 1, NULL, 'B' }, - { "cooldown-time", 1, NULL, 'c' }, - { "seed", 1, NULL, 'e' }, - { "sender-threads", 1, NULL, 'T' }, - { "probes", 1, NULL, 'P' }, - { "dryrun", 0, NULL, 'd' }, - { "source-port", 1, NULL, 's' }, - { "source-ip", 1, NULL, 'S' }, - { "gateway-mac", 1, NULL, 'G' }, - { "interface", 1, NULL, 'i' }, - { "vpn", 0, NULL, 'X' }, - { "probe-module", 1, NULL, 'M' }, - { "output-module", 1, NULL, 'O' }, - { "probe-args", 1, NULL, 0 }, - { "output-args", 1, NULL, 0 }, - { "list-output-modules", 0, NULL, 0 }, - { "list-probe-modules", 0, NULL, 0 }, - { "list-output-fields", 0, NULL, 0 }, - { "config", 1, NULL, 'C' }, - { "quiet", 0, NULL, 'q' }, - { "summary", 0, NULL, 'g' }, - { "verbosity", 1, NULL, 'v' }, - { "help", 0, NULL, 'h' }, - { "version", 0, NULL, 'V' }, - { 0, 0, 0, 0 } - }; - - c = getopt_long (argc, argv, "p:o:b:w:f:n:N:t:r:B:c:e:T:P:ds:S:G:i:XM:O:C:qgv:hV", long_options, &option_index); - - if (c == -1) break; /* Exit from `while (1)' loop. */ - - switch (c) - { - case 'p': /* TCP port number to scan (for SYN scans). */ - - - if (update_arg( (void *)&(args_info->target_port_arg), - &(args_info->target_port_orig), &(args_info->target_port_given), - &(local_args_info.target_port_given), optarg, 0, 0, ARG_INT, - check_ambiguity, override, 0, 0, - "target-port", 'p', - additional_error)) - goto failure; - - break; - case 'o': /* Output file. */ - - - if (update_arg( (void *)&(args_info->output_file_arg), - &(args_info->output_file_orig), &(args_info->output_file_given), - &(local_args_info.output_file_given), optarg, 0, 0, ARG_STRING, - check_ambiguity, override, 0, 0, - "output-file", 'o', - additional_error)) - goto failure; - - break; - case 'b': /* File of subnets to exclude, in CIDR notation, e.g. 192.168.0.0/16. */ - - - if (update_arg( (void *)&(args_info->blacklist_file_arg), - &(args_info->blacklist_file_orig), &(args_info->blacklist_file_given), - &(local_args_info.blacklist_file_given), optarg, 0, 0, ARG_STRING, - check_ambiguity, override, 0, 0, - "blacklist-file", 'b', - additional_error)) - goto failure; - - break; - case 'w': /* File of subnets to constrain scan to, in CIDR notation, e.g. 192.168.0.0/16. */ - - - if (update_arg( (void *)&(args_info->whitelist_file_arg), - &(args_info->whitelist_file_orig), &(args_info->whitelist_file_given), - &(local_args_info.whitelist_file_given), optarg, 0, 0, ARG_STRING, - check_ambiguity, override, 0, 0, - "whitelist-file", 'w', - additional_error)) - goto failure; - - break; - case 'f': /* Fields that should be output in result set. */ - - - if (update_arg( (void *)&(args_info->output_fields_arg), - &(args_info->output_fields_orig), &(args_info->output_fields_given), - &(local_args_info.output_fields_given), optarg, 0, 0, ARG_STRING, - check_ambiguity, override, 0, 0, - "output-fields", 'f', - additional_error)) - goto failure; - - break; - case 'n': /* Cap number of targets to probe (as a number or a percentage of the address space). */ - - - if (update_arg( (void *)&(args_info->max_targets_arg), - &(args_info->max_targets_orig), &(args_info->max_targets_given), - &(local_args_info.max_targets_given), optarg, 0, 0, ARG_STRING, - check_ambiguity, override, 0, 0, - "max-targets", 'n', - additional_error)) - goto failure; - - break; - case 'N': /* Cap number of results to return. */ - - - if (update_arg( (void *)&(args_info->max_results_arg), - &(args_info->max_results_orig), &(args_info->max_results_given), - &(local_args_info.max_results_given), optarg, 0, 0, ARG_INT, - check_ambiguity, override, 0, 0, - "max-results", 'N', - additional_error)) - goto failure; - - break; - case 't': /* Cap length of time for sending packets. */ - - - if (update_arg( (void *)&(args_info->max_runtime_arg), - &(args_info->max_runtime_orig), &(args_info->max_runtime_given), - &(local_args_info.max_runtime_given), optarg, 0, 0, ARG_INT, - check_ambiguity, override, 0, 0, - "max-runtime", 't', - additional_error)) - goto failure; - - break; - case 'r': /* Set send rate in packets/sec. */ - - - if (update_arg( (void *)&(args_info->rate_arg), - &(args_info->rate_orig), &(args_info->rate_given), - &(local_args_info.rate_given), optarg, 0, 0, ARG_INT, - check_ambiguity, override, 0, 0, - "rate", 'r', - additional_error)) - goto failure; - - break; - case 'B': /* Set send rate in bits/second (supports suffixes G, M and K). */ - - - if (update_arg( (void *)&(args_info->bandwidth_arg), - &(args_info->bandwidth_orig), &(args_info->bandwidth_given), - &(local_args_info.bandwidth_given), optarg, 0, 0, ARG_STRING, - check_ambiguity, override, 0, 0, - "bandwidth", 'B', - additional_error)) - goto failure; - - break; - case 'c': /* How long to continue receiving after sending last probe. */ - - - if (update_arg( (void *)&(args_info->cooldown_time_arg), - &(args_info->cooldown_time_orig), &(args_info->cooldown_time_given), - &(local_args_info.cooldown_time_given), optarg, 0, "8", ARG_INT, - check_ambiguity, override, 0, 0, - "cooldown-time", 'c', - additional_error)) - goto failure; - - break; - case 'e': /* Seed used to select address permutation. */ - - - if (update_arg( (void *)&(args_info->seed_arg), - &(args_info->seed_orig), &(args_info->seed_given), - &(local_args_info.seed_given), optarg, 0, 0, ARG_INT, - check_ambiguity, override, 0, 0, - "seed", 'e', - additional_error)) - goto failure; - - break; - case 'T': /* Threads used to send packets. */ - - - if (update_arg( (void *)&(args_info->sender_threads_arg), - &(args_info->sender_threads_orig), &(args_info->sender_threads_given), - &(local_args_info.sender_threads_given), optarg, 0, "1", ARG_INT, - check_ambiguity, override, 0, 0, - "sender-threads", 'T', - additional_error)) - goto failure; - - break; - case 'P': /* Number of probes to send to each IP. */ - - - if (update_arg( (void *)&(args_info->probes_arg), - &(args_info->probes_orig), &(args_info->probes_given), - &(local_args_info.probes_given), optarg, 0, "1", ARG_INT, - check_ambiguity, override, 0, 0, - "probes", 'P', - additional_error)) - goto failure; - - break; - case 'd': /* Don't actually send packets. */ - - - if (update_arg( 0 , - 0 , &(args_info->dryrun_given), - &(local_args_info.dryrun_given), optarg, 0, 0, ARG_NO, - check_ambiguity, override, 0, 0, - "dryrun", 'd', - additional_error)) - goto failure; - - break; - case 's': /* Source port(s) for scan packets. */ - - - if (update_arg( (void *)&(args_info->source_port_arg), - &(args_info->source_port_orig), &(args_info->source_port_given), - &(local_args_info.source_port_given), optarg, 0, 0, ARG_STRING, - check_ambiguity, override, 0, 0, - "source-port", 's', - additional_error)) - goto failure; - - break; - case 'S': /* Source address(es) for scan packets. */ - - - if (update_arg( (void *)&(args_info->source_ip_arg), - &(args_info->source_ip_orig), &(args_info->source_ip_given), - &(local_args_info.source_ip_given), optarg, 0, 0, ARG_STRING, - check_ambiguity, override, 0, 0, - "source-ip", 'S', - additional_error)) - goto failure; - - break; - case 'G': /* Specify gateway MAC address. */ - - - if (update_arg( (void *)&(args_info->gateway_mac_arg), - &(args_info->gateway_mac_orig), &(args_info->gateway_mac_given), - &(local_args_info.gateway_mac_given), optarg, 0, 0, ARG_STRING, - check_ambiguity, override, 0, 0, - "gateway-mac", 'G', - additional_error)) - goto failure; - - break; - case 'i': /* Specify network interface to use. */ - - - if (update_arg( (void *)&(args_info->interface_arg), - &(args_info->interface_orig), &(args_info->interface_given), - &(local_args_info.interface_given), optarg, 0, 0, ARG_STRING, - check_ambiguity, override, 0, 0, - "interface", 'i', - additional_error)) - goto failure; - - break; - case 'X': /* Sends IP packets instead of Ethernet (for VPNs). */ - - - if (update_arg( 0 , - 0 , &(args_info->vpn_given), - &(local_args_info.vpn_given), optarg, 0, 0, ARG_NO, - check_ambiguity, override, 0, 0, - "vpn", 'X', - additional_error)) - goto failure; - - break; - case 'M': /* Select probe module. */ - - - if (update_arg( (void *)&(args_info->probe_module_arg), - &(args_info->probe_module_orig), &(args_info->probe_module_given), - &(local_args_info.probe_module_given), optarg, 0, "tcp_synscan", ARG_STRING, - check_ambiguity, override, 0, 0, - "probe-module", 'M', - additional_error)) - goto failure; - - break; - case 'O': /* Select output module. */ - - - if (update_arg( (void *)&(args_info->output_module_arg), - &(args_info->output_module_orig), &(args_info->output_module_given), - &(local_args_info.output_module_given), optarg, 0, "simple_file", ARG_STRING, - check_ambiguity, override, 0, 0, - "output-module", 'O', - additional_error)) - goto failure; - - break; - case 'C': /* Read a configuration file, which can specify any of these options. */ - - - if (update_arg( (void *)&(args_info->config_arg), - &(args_info->config_orig), &(args_info->config_given), - &(local_args_info.config_given), optarg, 0, "/etc/zmap/zmap.conf", ARG_STRING, - check_ambiguity, override, 0, 0, - "config", 'C', - additional_error)) - goto failure; - - break; - case 'q': /* Do not print status updates. */ - - - if (update_arg( 0 , - 0 , &(args_info->quiet_given), - &(local_args_info.quiet_given), optarg, 0, 0, ARG_NO, - check_ambiguity, override, 0, 0, - "quiet", 'q', - additional_error)) - goto failure; - - break; - case 'g': /* Print configuration and summary at end of scan. */ - - - if (update_arg( 0 , - 0 , &(args_info->summary_given), - &(local_args_info.summary_given), optarg, 0, 0, ARG_NO, - check_ambiguity, override, 0, 0, - "summary", 'g', - additional_error)) - goto failure; - - break; - case 'v': /* Level of log detail (0-5). */ - - - if (update_arg( (void *)&(args_info->verbosity_arg), - &(args_info->verbosity_orig), &(args_info->verbosity_given), - &(local_args_info.verbosity_given), optarg, 0, "3", ARG_INT, - check_ambiguity, override, 0, 0, - "verbosity", 'v', - additional_error)) - goto failure; - - break; - case 'h': /* Print help and exit. */ - - - if (update_arg( 0 , - 0 , &(args_info->help_given), - &(local_args_info.help_given), optarg, 0, 0, ARG_NO, - check_ambiguity, override, 0, 0, - "help", 'h', - additional_error)) - goto failure; - - break; - case 'V': /* Print version and exit. */ - - - if (update_arg( 0 , - 0 , &(args_info->version_given), - &(local_args_info.version_given), optarg, 0, 0, ARG_NO, - check_ambiguity, override, 0, 0, - "version", 'V', - additional_error)) - goto failure; - - break; - - case 0: /* Long option with no short option */ - /* Arguments to pass to probe module. */ - if (strcmp (long_options[option_index].name, "probe-args") == 0) - { - - - if (update_arg( (void *)&(args_info->probe_args_arg), - &(args_info->probe_args_orig), &(args_info->probe_args_given), - &(local_args_info.probe_args_given), optarg, 0, 0, ARG_STRING, - check_ambiguity, override, 0, 0, - "probe-args", '-', - additional_error)) - goto failure; - - } - /* Arguments to pass to output module. */ - else if (strcmp (long_options[option_index].name, "output-args") == 0) - { - - - if (update_arg( (void *)&(args_info->output_args_arg), - &(args_info->output_args_orig), &(args_info->output_args_given), - &(local_args_info.output_args_given), optarg, 0, 0, ARG_STRING, - check_ambiguity, override, 0, 0, - "output-args", '-', - additional_error)) - goto failure; - - } - /* List available output modules. */ - else if (strcmp (long_options[option_index].name, "list-output-modules") == 0) - { - - - if (update_arg( 0 , - 0 , &(args_info->list_output_modules_given), - &(local_args_info.list_output_modules_given), optarg, 0, 0, ARG_NO, - check_ambiguity, override, 0, 0, - "list-output-modules", '-', - additional_error)) - goto failure; - - } - /* List available probe modules. */ - else if (strcmp (long_options[option_index].name, "list-probe-modules") == 0) - { - - - if (update_arg( 0 , - 0 , &(args_info->list_probe_modules_given), - &(local_args_info.list_probe_modules_given), optarg, 0, 0, ARG_NO, - check_ambiguity, override, 0, 0, - "list-probe-modules", '-', - additional_error)) - goto failure; - - } - /* List all fields that can be output by selected probe module. */ - else if (strcmp (long_options[option_index].name, "list-output-fields") == 0) - { - - - if (update_arg( 0 , - 0 , &(args_info->list_output_fields_given), - &(local_args_info.list_output_fields_given), optarg, 0, 0, ARG_NO, - check_ambiguity, override, 0, 0, - "list-output-fields", '-', - additional_error)) - goto failure; - - } - - break; - case '?': /* Invalid option. */ - /* `getopt_long' already printed an error message. */ - goto failure; - - default: /* bug: option not considered. */ - fprintf (stderr, "%s: option unknown: %c%s\n", CMDLINE_PARSER_PACKAGE, c, (additional_error ? additional_error : "")); - abort (); - } /* switch */ - } /* while */ - - - - - cmdline_parser_release (&local_args_info); - - if ( error ) - return (EXIT_FAILURE); - - return 0; - -failure: - - cmdline_parser_release (&local_args_info); - return (EXIT_FAILURE); -} - -#ifndef CONFIG_FILE_LINE_SIZE -#define CONFIG_FILE_LINE_SIZE 2048 -#endif -#define ADDITIONAL_ERROR " in configuration file " - -#define CONFIG_FILE_LINE_BUFFER_SIZE (CONFIG_FILE_LINE_SIZE+3) -/* 3 is for "--" and "=" */ - -static int -_cmdline_parser_configfile (const char *filename, int *my_argc) -{ - FILE* file; - char my_argv[CONFIG_FILE_LINE_BUFFER_SIZE+1]; - char linebuf[CONFIG_FILE_LINE_SIZE]; - int line_num = 0; - int result = 0, equal; - char *fopt, *farg; - char *str_index; - size_t len, next_token; - char delimiter; - - if ((file = fopen(filename, "r")) == 0) - { - fprintf (stderr, "%s: Error opening configuration file '%s'\n", - CMDLINE_PARSER_PACKAGE, filename); - return EXIT_FAILURE; - } - - while ((fgets(linebuf, CONFIG_FILE_LINE_SIZE, file)) != 0) - { - ++line_num; - my_argv[0] = '\0'; - len = strlen(linebuf); - if (len > (CONFIG_FILE_LINE_BUFFER_SIZE-1)) - { - fprintf (stderr, "%s:%s:%d: Line too long in configuration file\n", - CMDLINE_PARSER_PACKAGE, filename, line_num); - result = EXIT_FAILURE; - break; - } - - /* find first non-whitespace character in the line */ - next_token = strspn (linebuf, " \t\r\n"); - str_index = linebuf + next_token; - - if ( str_index[0] == '\0' || str_index[0] == '#') - continue; /* empty line or comment line is skipped */ - - fopt = str_index; - - /* truncate fopt at the end of the first non-valid character */ - next_token = strcspn (fopt, " \t\r\n="); - - if (fopt[next_token] == '\0') /* the line is over */ - { - farg = 0; - equal = 0; - goto noarg; - } - - /* remember if equal sign is present */ - equal = (fopt[next_token] == '='); - fopt[next_token++] = '\0'; - - /* advance pointers to the next token after the end of fopt */ - next_token += strspn (fopt + next_token, " \t\r\n"); - - /* check for the presence of equal sign, and if so, skip it */ - if ( !equal ) - if ((equal = (fopt[next_token] == '='))) - { - next_token++; - next_token += strspn (fopt + next_token, " \t\r\n"); - } - str_index += next_token; - - /* find argument */ - farg = str_index; - if ( farg[0] == '\"' || farg[0] == '\'' ) - { /* quoted argument */ - str_index = strchr (++farg, str_index[0] ); /* skip opening quote */ - if (! str_index) - { - fprintf - (stderr, - "%s:%s:%d: unterminated string in configuration file\n", - CMDLINE_PARSER_PACKAGE, filename, line_num); - result = EXIT_FAILURE; - break; - } - } - else - { /* read up the remaining part up to a delimiter */ - next_token = strcspn (farg, " \t\r\n#\'\""); - str_index += next_token; - } - - /* truncate farg at the delimiter and store it for further check */ - delimiter = *str_index, *str_index++ = '\0'; - - /* everything but comment is illegal at the end of line */ - if (delimiter != '\0' && delimiter != '#') - { - str_index += strspn(str_index, " \t\r\n"); - if (*str_index != '\0' && *str_index != '#') - { - fprintf - (stderr, - "%s:%s:%d: malformed string in configuration file\n", - CMDLINE_PARSER_PACKAGE, filename, line_num); - result = EXIT_FAILURE; - break; - } - } - - noarg: - if (!strcmp(fopt,"include")) { - if (farg && *farg) { - result = _cmdline_parser_configfile(farg, my_argc); - } else { - fprintf(stderr, "%s:%s:%d: include requires a filename argument.\n", - CMDLINE_PARSER_PACKAGE, filename, line_num); - } - continue; - } - len = strlen(fopt); - strcat (my_argv, len > 1 ? "--" : "-"); - strcat (my_argv, fopt); - if (len > 1 && ((farg && *farg) || equal)) - strcat (my_argv, "="); - if (farg && *farg) - strcat (my_argv, farg); - ++(*my_argc); - - cmd_line_list_tmp = (struct line_list *) malloc (sizeof (struct line_list)); - cmd_line_list_tmp->next = cmd_line_list; - cmd_line_list = cmd_line_list_tmp; - cmd_line_list->string_arg = gengetopt_strdup(my_argv); - } /* while */ - - if (file) - fclose(file); - return result; -} - -int -cmdline_parser_configfile ( - const char *filename, - struct gengetopt_args_info *args_info, - int override, int initialize, int check_required) -{ - struct cmdline_parser_params params; - - params.override = override; - params.initialize = initialize; - params.check_required = check_required; - params.check_ambiguity = 0; - params.print_errors = 1; - - return cmdline_parser_config_file (filename, args_info, ¶ms); -} - -int -cmdline_parser_config_file (const char *filename, - struct gengetopt_args_info *args_info, - struct cmdline_parser_params *params) -{ - int i, result; - int my_argc = 1; - char **my_argv_arg; - char *additional_error; - - /* store the program name */ - cmd_line_list_tmp = (struct line_list *) malloc (sizeof (struct line_list)); - cmd_line_list_tmp->next = cmd_line_list; - cmd_line_list = cmd_line_list_tmp; - cmd_line_list->string_arg = gengetopt_strdup (CMDLINE_PARSER_PACKAGE); - - result = _cmdline_parser_configfile(filename, &my_argc); - - if (result != EXIT_FAILURE) { - my_argv_arg = (char **) malloc((my_argc+1) * sizeof(char *)); - cmd_line_list_tmp = cmd_line_list; - - for (i = my_argc - 1; i >= 0; --i) { - my_argv_arg[i] = cmd_line_list_tmp->string_arg; - cmd_line_list_tmp = cmd_line_list_tmp->next; - } - - my_argv_arg[my_argc] = 0; - - additional_error = (char *)malloc(strlen(filename) + strlen(ADDITIONAL_ERROR) + 1); - strcpy (additional_error, ADDITIONAL_ERROR); - strcat (additional_error, filename); - result = - cmdline_parser_internal (my_argc, my_argv_arg, args_info, - params, - additional_error); - - free (additional_error); - free (my_argv_arg); - } - - free_cmd_list(); - if (result == EXIT_FAILURE) - { - cmdline_parser_free (args_info); - exit (EXIT_FAILURE); - } - - return result; -} diff --git a/src/zopt.h b/src/zopt.h deleted file mode 100644 index d5bbead..0000000 --- a/src/zopt.h +++ /dev/null @@ -1,306 +0,0 @@ -/** @file zopt.h - * @brief The header file for the command line option parser - * generated by GNU Gengetopt version 2.22.5 - * http://www.gnu.org/software/gengetopt. - * DO NOT modify this file, since it can be overwritten - * @author GNU Gengetopt by Lorenzo Bettini */ - -#ifndef ZOPT_H -#define ZOPT_H - -/* If we use autoconf. */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include /* for FILE */ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#ifndef CMDLINE_PARSER_PACKAGE -/** @brief the program name (used for printing errors) */ -#define CMDLINE_PARSER_PACKAGE "zmap" -#endif - -#ifndef CMDLINE_PARSER_PACKAGE_NAME -/** @brief the complete program name (used for help and version) */ -#define CMDLINE_PARSER_PACKAGE_NAME "zmap" -#endif - -#ifndef CMDLINE_PARSER_VERSION -/** @brief the program version */ -#define CMDLINE_PARSER_VERSION "1.0.0" -#endif - -/** @brief Where the command line options are stored */ -struct gengetopt_args_info -{ - int target_port_arg; /**< @brief TCP port number to scan (for SYN scans). */ - char * target_port_orig; /**< @brief TCP port number to scan (for SYN scans) original value given at command line. */ - const char *target_port_help; /**< @brief TCP port number to scan (for SYN scans) help description. */ - char * output_file_arg; /**< @brief Output file. */ - char * output_file_orig; /**< @brief Output file original value given at command line. */ - const char *output_file_help; /**< @brief Output file help description. */ - char * blacklist_file_arg; /**< @brief File of subnets to exclude, in CIDR notation, e.g. 192.168.0.0/16. */ - char * blacklist_file_orig; /**< @brief File of subnets to exclude, in CIDR notation, e.g. 192.168.0.0/16 original value given at command line. */ - const char *blacklist_file_help; /**< @brief File of subnets to exclude, in CIDR notation, e.g. 192.168.0.0/16 help description. */ - char * whitelist_file_arg; /**< @brief File of subnets to constrain scan to, in CIDR notation, e.g. 192.168.0.0/16. */ - char * whitelist_file_orig; /**< @brief File of subnets to constrain scan to, in CIDR notation, e.g. 192.168.0.0/16 original value given at command line. */ - const char *whitelist_file_help; /**< @brief File of subnets to constrain scan to, in CIDR notation, e.g. 192.168.0.0/16 help description. */ - char * output_fields_arg; /**< @brief Fields that should be output in result set. */ - char * output_fields_orig; /**< @brief Fields that should be output in result set original value given at command line. */ - const char *output_fields_help; /**< @brief Fields that should be output in result set help description. */ - char * max_targets_arg; /**< @brief Cap number of targets to probe (as a number or a percentage of the address space). */ - char * max_targets_orig; /**< @brief Cap number of targets to probe (as a number or a percentage of the address space) original value given at command line. */ - const char *max_targets_help; /**< @brief Cap number of targets to probe (as a number or a percentage of the address space) help description. */ - int max_results_arg; /**< @brief Cap number of results to return. */ - char * max_results_orig; /**< @brief Cap number of results to return original value given at command line. */ - const char *max_results_help; /**< @brief Cap number of results to return help description. */ - int max_runtime_arg; /**< @brief Cap length of time for sending packets. */ - char * max_runtime_orig; /**< @brief Cap length of time for sending packets original value given at command line. */ - const char *max_runtime_help; /**< @brief Cap length of time for sending packets help description. */ - int rate_arg; /**< @brief Set send rate in packets/sec. */ - char * rate_orig; /**< @brief Set send rate in packets/sec original value given at command line. */ - const char *rate_help; /**< @brief Set send rate in packets/sec help description. */ - char * bandwidth_arg; /**< @brief Set send rate in bits/second (supports suffixes G, M and K). */ - char * bandwidth_orig; /**< @brief Set send rate in bits/second (supports suffixes G, M and K) original value given at command line. */ - const char *bandwidth_help; /**< @brief Set send rate in bits/second (supports suffixes G, M and K) help description. */ - int cooldown_time_arg; /**< @brief How long to continue receiving after sending last probe (default='8'). */ - char * cooldown_time_orig; /**< @brief How long to continue receiving after sending last probe original value given at command line. */ - const char *cooldown_time_help; /**< @brief How long to continue receiving after sending last probe help description. */ - int seed_arg; /**< @brief Seed used to select address permutation. */ - char * seed_orig; /**< @brief Seed used to select address permutation original value given at command line. */ - const char *seed_help; /**< @brief Seed used to select address permutation help description. */ - int sender_threads_arg; /**< @brief Threads used to send packets (default='1'). */ - char * sender_threads_orig; /**< @brief Threads used to send packets original value given at command line. */ - const char *sender_threads_help; /**< @brief Threads used to send packets help description. */ - int probes_arg; /**< @brief Number of probes to send to each IP (default='1'). */ - char * probes_orig; /**< @brief Number of probes to send to each IP original value given at command line. */ - const char *probes_help; /**< @brief Number of probes to send to each IP help description. */ - const char *dryrun_help; /**< @brief Don't actually send packets help description. */ - char * source_port_arg; /**< @brief Source port(s) for scan packets. */ - char * source_port_orig; /**< @brief Source port(s) for scan packets original value given at command line. */ - const char *source_port_help; /**< @brief Source port(s) for scan packets help description. */ - char * source_ip_arg; /**< @brief Source address(es) for scan packets. */ - char * source_ip_orig; /**< @brief Source address(es) for scan packets original value given at command line. */ - const char *source_ip_help; /**< @brief Source address(es) for scan packets help description. */ - char * gateway_mac_arg; /**< @brief Specify gateway MAC address. */ - char * gateway_mac_orig; /**< @brief Specify gateway MAC address original value given at command line. */ - const char *gateway_mac_help; /**< @brief Specify gateway MAC address help description. */ - char * interface_arg; /**< @brief Specify network interface to use. */ - char * interface_orig; /**< @brief Specify network interface to use original value given at command line. */ - const char *interface_help; /**< @brief Specify network interface to use help description. */ - const char *vpn_help; /**< @brief Sends IP packets instead of Ethernet (for VPNs) help description. */ - char * probe_module_arg; /**< @brief Select probe module (default='tcp_synscan'). */ - char * probe_module_orig; /**< @brief Select probe module original value given at command line. */ - const char *probe_module_help; /**< @brief Select probe module help description. */ - char * output_module_arg; /**< @brief Select output module (default='simple_file'). */ - char * output_module_orig; /**< @brief Select output module original value given at command line. */ - const char *output_module_help; /**< @brief Select output module help description. */ - char * probe_args_arg; /**< @brief Arguments to pass to probe module. */ - char * probe_args_orig; /**< @brief Arguments to pass to probe module original value given at command line. */ - const char *probe_args_help; /**< @brief Arguments to pass to probe module help description. */ - char * output_args_arg; /**< @brief Arguments to pass to output module. */ - char * output_args_orig; /**< @brief Arguments to pass to output module original value given at command line. */ - const char *output_args_help; /**< @brief Arguments to pass to output module help description. */ - const char *list_output_modules_help; /**< @brief List available output modules help description. */ - const char *list_probe_modules_help; /**< @brief List available probe modules help description. */ - const char *list_output_fields_help; /**< @brief List all fields that can be output by selected probe module help description. */ - char * config_arg; /**< @brief Read a configuration file, which can specify any of these options (default='/etc/zmap/zmap.conf'). */ - char * config_orig; /**< @brief Read a configuration file, which can specify any of these options original value given at command line. */ - const char *config_help; /**< @brief Read a configuration file, which can specify any of these options help description. */ - const char *quiet_help; /**< @brief Do not print status updates help description. */ - const char *summary_help; /**< @brief Print configuration and summary at end of scan help description. */ - int verbosity_arg; /**< @brief Level of log detail (0-5) (default='3'). */ - char * verbosity_orig; /**< @brief Level of log detail (0-5) original value given at command line. */ - const char *verbosity_help; /**< @brief Level of log detail (0-5) help description. */ - const char *help_help; /**< @brief Print help and exit help description. */ - const char *version_help; /**< @brief Print version and exit help description. */ - - unsigned int target_port_given ; /**< @brief Whether target-port was given. */ - unsigned int output_file_given ; /**< @brief Whether output-file was given. */ - unsigned int blacklist_file_given ; /**< @brief Whether blacklist-file was given. */ - unsigned int whitelist_file_given ; /**< @brief Whether whitelist-file was given. */ - unsigned int output_fields_given ; /**< @brief Whether output-fields was given. */ - unsigned int max_targets_given ; /**< @brief Whether max-targets was given. */ - unsigned int max_results_given ; /**< @brief Whether max-results was given. */ - unsigned int max_runtime_given ; /**< @brief Whether max-runtime was given. */ - unsigned int rate_given ; /**< @brief Whether rate was given. */ - unsigned int bandwidth_given ; /**< @brief Whether bandwidth was given. */ - unsigned int cooldown_time_given ; /**< @brief Whether cooldown-time was given. */ - unsigned int seed_given ; /**< @brief Whether seed was given. */ - unsigned int sender_threads_given ; /**< @brief Whether sender-threads was given. */ - unsigned int probes_given ; /**< @brief Whether probes was given. */ - unsigned int dryrun_given ; /**< @brief Whether dryrun was given. */ - unsigned int source_port_given ; /**< @brief Whether source-port was given. */ - unsigned int source_ip_given ; /**< @brief Whether source-ip was given. */ - unsigned int gateway_mac_given ; /**< @brief Whether gateway-mac was given. */ - unsigned int interface_given ; /**< @brief Whether interface was given. */ - unsigned int vpn_given ; /**< @brief Whether vpn was given. */ - unsigned int probe_module_given ; /**< @brief Whether probe-module was given. */ - unsigned int output_module_given ; /**< @brief Whether output-module was given. */ - unsigned int probe_args_given ; /**< @brief Whether probe-args was given. */ - unsigned int output_args_given ; /**< @brief Whether output-args was given. */ - unsigned int list_output_modules_given ; /**< @brief Whether list-output-modules was given. */ - unsigned int list_probe_modules_given ; /**< @brief Whether list-probe-modules was given. */ - unsigned int list_output_fields_given ; /**< @brief Whether list-output-fields was given. */ - unsigned int config_given ; /**< @brief Whether config was given. */ - unsigned int quiet_given ; /**< @brief Whether quiet was given. */ - unsigned int summary_given ; /**< @brief Whether summary was given. */ - unsigned int verbosity_given ; /**< @brief Whether verbosity was given. */ - unsigned int help_given ; /**< @brief Whether help was given. */ - unsigned int version_given ; /**< @brief Whether version was given. */ - -} ; - -/** @brief The additional parameters to pass to parser functions */ -struct cmdline_parser_params -{ - int override; /**< @brief whether to override possibly already present options (default 0) */ - int initialize; /**< @brief whether to initialize the option structure gengetopt_args_info (default 1) */ - int check_required; /**< @brief whether to check that all required options were provided (default 1) */ - int check_ambiguity; /**< @brief whether to check for options already specified in the option structure gengetopt_args_info (default 0) */ - int print_errors; /**< @brief whether getopt_long should print an error message for a bad option (default 1) */ -} ; - -/** @brief the purpose string of the program */ -extern const char *gengetopt_args_info_purpose; -/** @brief the usage string of the program */ -extern const char *gengetopt_args_info_usage; -/** @brief all the lines making the help output */ -extern const char *gengetopt_args_info_help[]; - -/** - * The command line parser - * @param argc the number of command line options - * @param argv the command line options - * @param args_info the structure where option information will be stored - * @return 0 if everything went fine, NON 0 if an error took place - */ -int cmdline_parser (int argc, char **argv, - struct gengetopt_args_info *args_info); - -/** - * The command line parser (version with additional parameters - deprecated) - * @param argc the number of command line options - * @param argv the command line options - * @param args_info the structure where option information will be stored - * @param override whether to override possibly already present options - * @param initialize whether to initialize the option structure my_args_info - * @param check_required whether to check that all required options were provided - * @return 0 if everything went fine, NON 0 if an error took place - * @deprecated use cmdline_parser_ext() instead - */ -int cmdline_parser2 (int argc, char **argv, - struct gengetopt_args_info *args_info, - int override, int initialize, int check_required); - -/** - * The command line parser (version with additional parameters) - * @param argc the number of command line options - * @param argv the command line options - * @param args_info the structure where option information will be stored - * @param params additional parameters for the parser - * @return 0 if everything went fine, NON 0 if an error took place - */ -int cmdline_parser_ext (int argc, char **argv, - struct gengetopt_args_info *args_info, - struct cmdline_parser_params *params); - -/** - * Save the contents of the option struct into an already open FILE stream. - * @param outfile the stream where to dump options - * @param args_info the option struct to dump - * @return 0 if everything went fine, NON 0 if an error took place - */ -int cmdline_parser_dump(FILE *outfile, - struct gengetopt_args_info *args_info); - -/** - * Save the contents of the option struct into a (text) file. - * This file can be read by the config file parser (if generated by gengetopt) - * @param filename the file where to save - * @param args_info the option struct to save - * @return 0 if everything went fine, NON 0 if an error took place - */ -int cmdline_parser_file_save(const char *filename, - struct gengetopt_args_info *args_info); - -/** - * Print the help - */ -void cmdline_parser_print_help(void); -/** - * Print the version - */ -void cmdline_parser_print_version(void); - -/** - * Initializes all the fields a cmdline_parser_params structure - * to their default values - * @param params the structure to initialize - */ -void cmdline_parser_params_init(struct cmdline_parser_params *params); - -/** - * Allocates dynamically a cmdline_parser_params structure and initializes - * all its fields to their default values - * @return the created and initialized cmdline_parser_params structure - */ -struct cmdline_parser_params *cmdline_parser_params_create(void); - -/** - * Initializes the passed gengetopt_args_info structure's fields - * (also set default values for options that have a default) - * @param args_info the structure to initialize - */ -void cmdline_parser_init (struct gengetopt_args_info *args_info); -/** - * Deallocates the string fields of the gengetopt_args_info structure - * (but does not deallocate the structure itself) - * @param args_info the structure to deallocate - */ -void cmdline_parser_free (struct gengetopt_args_info *args_info); - -/** - * The config file parser (deprecated version) - * @param filename the name of the config file - * @param args_info the structure where option information will be stored - * @param override whether to override possibly already present options - * @param initialize whether to initialize the option structure my_args_info - * @param check_required whether to check that all required options were provided - * @return 0 if everything went fine, NON 0 if an error took place - * @deprecated use cmdline_parser_config_file() instead - */ -int cmdline_parser_configfile (const char *filename, - struct gengetopt_args_info *args_info, - int override, int initialize, int check_required); - -/** - * The config file parser - * @param filename the name of the config file - * @param args_info the structure where option information will be stored - * @param params additional parameters for the parser - * @return 0 if everything went fine, NON 0 if an error took place - */ -int cmdline_parser_config_file (const char *filename, - struct gengetopt_args_info *args_info, - struct cmdline_parser_params *params); - -/** - * Checks that all the required options were specified - * @param args_info the structure to check - * @param prog_name the name of the program that will be used to print - * possible errors - * @return - */ -int cmdline_parser_required (struct gengetopt_args_info *args_info, - const char *prog_name); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* ZOPT_H */ From 9693b66024e4dfc5b2603a5c9399f5ab5c828761 Mon Sep 17 00:00:00 2001 From: David Adrian Date: Fri, 13 Sep 2013 15:32:17 -0400 Subject: [PATCH 10/53] Initial import of filter parser Current runs as its own program, partially implemented. Commiting for the sake of sharing access / backup. Still needs a lot of work. --- filter_sandbox/.gitignore | 2 + filter_sandbox/Makefile | 8 + filter_sandbox/README | 7 + filter_sandbox/lex.yy.c | 1807 +++++++++++++++++++++++++++++++++++++ filter_sandbox/parser.y | 347 +++++++ filter_sandbox/scanner.l | 256 ++++++ filter_sandbox/tree.c | 69 ++ filter_sandbox/tree.h | 44 + filter_sandbox/y.output | 303 +++++++ filter_sandbox/y.tab.c | 1687 ++++++++++++++++++++++++++++++++++ filter_sandbox/y.tab.h | 80 ++ filter_sandbox/zmap.l | 22 + filter_sandbox/zmap.y | 134 +++ 13 files changed, 4766 insertions(+) create mode 100644 filter_sandbox/.gitignore create mode 100644 filter_sandbox/Makefile create mode 100644 filter_sandbox/README create mode 100644 filter_sandbox/lex.yy.c create mode 100644 filter_sandbox/parser.y create mode 100644 filter_sandbox/scanner.l create mode 100644 filter_sandbox/tree.c create mode 100644 filter_sandbox/tree.h create mode 100644 filter_sandbox/y.output create mode 100644 filter_sandbox/y.tab.c create mode 100644 filter_sandbox/y.tab.h create mode 100644 filter_sandbox/zmap.l create mode 100644 filter_sandbox/zmap.y diff --git a/filter_sandbox/.gitignore b/filter_sandbox/.gitignore new file mode 100644 index 0000000..2883a20 --- /dev/null +++ b/filter_sandbox/.gitignore @@ -0,0 +1,2 @@ +.output +test diff --git a/filter_sandbox/Makefile b/filter_sandbox/Makefile new file mode 100644 index 0000000..243e279 --- /dev/null +++ b/filter_sandbox/Makefile @@ -0,0 +1,8 @@ +all: + gcc -c tree.c -o tree.o + lex zmap.l + yacc -d --debug --verbose zmap.y + gcc tree.o lex.yy.c y.tab.c -o test + +clean: + rm *.o a.out test diff --git a/filter_sandbox/README b/filter_sandbox/README new file mode 100644 index 0000000..5f20d79 --- /dev/null +++ b/filter_sandbox/README @@ -0,0 +1,7 @@ +make + +./text + +Example Input: + +(ipaddr = 8 && herp = 6) || (field = value && yolo = swag) diff --git a/filter_sandbox/lex.yy.c b/filter_sandbox/lex.yy.c new file mode 100644 index 0000000..8c248d4 --- /dev/null +++ b/filter_sandbox/lex.yy.c @@ -0,0 +1,1807 @@ + +#line 3 "lex.yy.c" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 35 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +typedef uint64_t flex_uint64_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; +#endif /* ! C99 */ + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! FLEXINT_H */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +/* C99 requires __STDC__ to be defined as 1. */ +#if defined (__STDC__) + +#define YY_USE_CONST + +#endif /* defined (__STDC__) */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart(yyin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +extern yy_size_t yyleng; + +extern FILE *yyin, *yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, (yytext_ptr) ) + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + yy_size_t yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) + +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; +static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ +yy_size_t yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 0; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart (FILE *input_file ); +void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); +void yy_delete_buffer (YY_BUFFER_STATE b ); +void yy_flush_buffer (YY_BUFFER_STATE b ); +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); +void yypop_buffer_state (void ); + +static void yyensure_buffer_stack (void ); +static void yy_load_buffer_state (void ); +static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); + +#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) + +YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); +YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); +YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ); + +void *yyalloc (yy_size_t ); +void *yyrealloc (void *,yy_size_t ); +void yyfree (void * ); + +#define yy_new_buffer yy_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer(yyin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer(yyin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ + +typedef unsigned char YY_CHAR; + +FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; + +typedef int yy_state_type; + +extern int yylineno; + +int yylineno = 1; + +extern char *yytext; +#define yytext_ptr yytext + +static yy_state_type yy_get_previous_state (void ); +static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); +static int yy_get_next_buffer (void ); +static void yy_fatal_error (yyconst char msg[] ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ + yyleng = (yy_size_t) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; + +#define YY_NUM_RULES 15 +#define YY_END_OF_BUFFER 16 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static yyconst flex_int16_t yy_accept[26] = + { 0, + 0, 0, 16, 15, 3, 2, 15, 15, 12, 13, + 1, 11, 9, 10, 15, 15, 3, 4, 7, 1, + 6, 5, 14, 8, 0 + } ; + +static yyconst flex_int32_t yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 4, 1, 1, 1, 1, 5, 1, 6, + 7, 1, 1, 1, 1, 1, 1, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 1, 1, 9, + 10, 11, 1, 1, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 1, 1, 1, 1, 1, 1, 12, 12, 12, 12, + + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 1, 13, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst flex_int32_t yy_meta[14] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, + 1, 2, 1 + } ; + +static yyconst flex_int16_t yy_base[27] = + { 0, + 0, 0, 24, 25, 21, 25, 12, 16, 25, 25, + 12, 9, 25, 8, 0, 4, 14, 25, 25, 7, + 25, 25, 0, 25, 25, 12 + } ; + +static yyconst flex_int16_t yy_def[27] = + { 0, + 25, 1, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 26, 25, 25, 25, 25, 25, + 25, 25, 26, 25, 0, 25 + } ; + +static yyconst flex_int16_t yy_nxt[39] = + { 0, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 23, 20, 17, 24, 22, 21, 20, + 19, 18, 17, 25, 3, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25 + } ; + +static yyconst flex_int16_t yy_chk[39] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 26, 20, 17, 16, 14, 12, 11, + 8, 7, 5, 3, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25 + } ; + +static yy_state_type yy_last_accepting_state; +static char *yy_last_accepting_cpos; + +extern int yy_flex_debug; +int yy_flex_debug = 0; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *yytext; +#line 1 "zmap.l" +#line 2 "zmap.l" +#include +#include "y.tab.h" +#line 466 "lex.yy.c" + +#define INITIAL 0 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +static int yy_init_globals (void ); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int yylex_destroy (void ); + +int yyget_debug (void ); + +void yyset_debug (int debug_flag ); + +YY_EXTRA_TYPE yyget_extra (void ); + +void yyset_extra (YY_EXTRA_TYPE user_defined ); + +FILE *yyget_in (void ); + +void yyset_in (FILE * in_str ); + +FILE *yyget_out (void ); + +void yyset_out (FILE * out_str ); + +yy_size_t yyget_leng (void ); + +char *yyget_text (void ); + +int yyget_lineno (void ); + +void yyset_lineno (int line_number ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap (void ); +#else +extern int yywrap (void ); +#endif +#endif + + static void yyunput (int c,char *buf_ptr ); + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ); +#endif + +#ifndef YY_NO_INPUT + +#ifdef __cplusplus +static int yyinput (void ); +#else +static int input (void ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO fwrite( yytext, yyleng, 1, yyout ) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + yy_size_t n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int yylex (void); + +#define YY_DECL int yylex (void) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + +#line 6 "zmap.l" + +#line 650 "lex.yy.c" + + if ( !(yy_init) ) + { + (yy_init) = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer(yyin,YY_BUF_SIZE ); + } + + yy_load_buffer_state( ); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = (yy_c_buf_p); + + /* Support of yytext. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = (yy_start); +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 26 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 25 ); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + yy_act = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = (yy_hold_char); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + +case 1: +YY_RULE_SETUP +#line 7 "zmap.l" +yylval.int_literal = atoi(yytext); return T_NUMBER; + YY_BREAK +case 2: +/* rule 2 can match eol */ +YY_RULE_SETUP +#line 8 "zmap.l" +/* Ignore end of line */ + YY_BREAK +case 3: +YY_RULE_SETUP +#line 9 "zmap.l" +/* Ignore whitespace */ + YY_BREAK +case 4: +YY_RULE_SETUP +#line 10 "zmap.l" +return T_NOT_EQ; + YY_BREAK +case 5: +YY_RULE_SETUP +#line 11 "zmap.l" +return T_GT_EQ; + YY_BREAK +case 6: +YY_RULE_SETUP +#line 12 "zmap.l" +return T_LT_EQ; + YY_BREAK +case 7: +YY_RULE_SETUP +#line 13 "zmap.l" +return T_AND; + YY_BREAK +case 8: +YY_RULE_SETUP +#line 14 "zmap.l" +return T_OR; + YY_BREAK +case 9: +YY_RULE_SETUP +#line 15 "zmap.l" +return '='; + YY_BREAK +case 10: +YY_RULE_SETUP +#line 16 "zmap.l" +return '>'; + YY_BREAK +case 11: +YY_RULE_SETUP +#line 17 "zmap.l" +return '<'; + YY_BREAK +case 12: +YY_RULE_SETUP +#line 18 "zmap.l" +return '('; + YY_BREAK +case 13: +YY_RULE_SETUP +#line 19 "zmap.l" +return ')'; + YY_BREAK +case 14: +YY_RULE_SETUP +#line 20 "zmap.l" +yylval.string_literal = strdup(yytext); return T_FIELD; + YY_BREAK +case 15: +YY_RULE_SETUP +#line 22 "zmap.l" +ECHO; + YY_BREAK +#line 809 "lex.yy.c" +case YY_STATE_EOF(INITIAL): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = (yy_c_buf_p); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( yywrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ +} /* end of yylex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (void) +{ + register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + register char *source = (yytext_ptr); + register int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + yy_size_t num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER; + + int yy_c_buf_p_offset = + (int) ((yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + yy_size_t new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart(yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + } + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (void) +{ + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = (yy_start); + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 26 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +{ + register int yy_is_jam; + register char *yy_cp = (yy_c_buf_p); + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 26 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 25); + + return yy_is_jam ? 0 : yy_current_state; +} + + static void yyunput (int c, register char * yy_bp ) +{ + register char *yy_cp; + + yy_cp = (yy_c_buf_p); + + /* undo effects of setting up yytext */ + *yy_cp = (yy_hold_char); + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register yy_size_t number_to_move = (yy_n_chars) + 2; + register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; + register char *source = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; + + while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + (yytext_ptr) = yy_bp; + (yy_hold_char) = *yy_cp; + (yy_c_buf_p) = yy_cp; +} + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (void) +#else + static int input (void) +#endif + +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart(yyin ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap( ) ) + return 0; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve yytext */ + (yy_hold_char) = *++(yy_c_buf_p); + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ + void yyrestart (FILE * input_file ) +{ + + if ( ! YY_CURRENT_BUFFER ){ + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer(yyin,YY_BUF_SIZE ); + } + + yy_init_buffer(YY_CURRENT_BUFFER,input_file ); + yy_load_buffer_state( ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ + void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) +{ + + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + yy_load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + +static void yy_load_buffer_state (void) +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer(b,file ); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * + */ + void yy_delete_buffer (YY_BUFFER_STATE b ) +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yyfree((void *) b->yy_ch_buf ); + + yyfree((void *) b ); +} + +#ifndef __cplusplus +extern int isatty (int ); +#endif /* __cplusplus */ + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ + static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) + +{ + int oerrno = errno; + + yy_flush_buffer(b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ + void yy_flush_buffer (YY_BUFFER_STATE b ) +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + yy_load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) +{ + if (new_buffer == NULL) + return; + + yyensure_buffer_stack(); + + /* This block is copied from yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void yypop_buffer_state (void) +{ + if (!YY_CURRENT_BUFFER) + return; + + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void yyensure_buffer_stack (void) +{ + yy_size_t num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer(b ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to yylex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * yy_scan_bytes() instead. + */ +YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) +{ + + return yy_scan_bytes(yystr,strlen(yystr) ); +} + +/** Setup the input buffer state to scan the given bytes. The next call to yylex() will + * scan from a @e copy of @a bytes. + * @param bytes the byte buffer to scan + * @param len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n, i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = _yybytes_len + 2; + buf = (char *) yyalloc(n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer(buf,n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yy_fatal_error (yyconst char* msg ) +{ + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = (yy_hold_char); \ + (yy_c_buf_p) = yytext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the current line number. + * + */ +int yyget_lineno (void) +{ + + return yylineno; +} + +/** Get the input stream. + * + */ +FILE *yyget_in (void) +{ + return yyin; +} + +/** Get the output stream. + * + */ +FILE *yyget_out (void) +{ + return yyout; +} + +/** Get the length of the current token. + * + */ +yy_size_t yyget_leng (void) +{ + return yyleng; +} + +/** Get the current token. + * + */ + +char *yyget_text (void) +{ + return yytext; +} + +/** Set the current line number. + * @param line_number + * + */ +void yyset_lineno (int line_number ) +{ + + yylineno = line_number; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param in_str A readable stream. + * + * @see yy_switch_to_buffer + */ +void yyset_in (FILE * in_str ) +{ + yyin = in_str ; +} + +void yyset_out (FILE * out_str ) +{ + yyout = out_str ; +} + +int yyget_debug (void) +{ + return yy_flex_debug; +} + +void yyset_debug (int bdebug ) +{ + yy_flex_debug = bdebug ; +} + +static int yy_init_globals (void) +{ + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from yylex_destroy(), so don't allocate here. + */ + + (yy_buffer_stack) = 0; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + (yy_c_buf_p) = (char *) 0; + (yy_init) = 0; + (yy_start) = 0; + +/* Defined in main.c */ +#ifdef YY_STDINIT + yyin = stdin; + yyout = stdout; +#else + yyin = (FILE *) 0; + yyout = (FILE *) 0; +#endif + + /* For future reference: Set errno on error, since we are called by + * yylex_init() + */ + return 0; +} + +/* yylex_destroy is for both reentrant and non-reentrant scanners. */ +int yylex_destroy (void) +{ + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + yypop_buffer_state(); + } + + /* Destroy the stack itself. */ + yyfree((yy_buffer_stack) ); + (yy_buffer_stack) = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * yylex() is called, initialization will occur. */ + yy_init_globals( ); + + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) +{ + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * s ) +{ + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *yyalloc (yy_size_t size ) +{ + return (void *) malloc( size ); +} + +void *yyrealloc (void * ptr, yy_size_t size ) +{ + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); +} + +void yyfree (void * ptr ) +{ + free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#line 22 "zmap.l" + + diff --git a/filter_sandbox/parser.y b/filter_sandbox/parser.y new file mode 100644 index 0000000..15cc097 --- /dev/null +++ b/filter_sandbox/parser.y @@ -0,0 +1,347 @@ +/* File: parser.y + * -------------- + * Yacc input file to generate the parser for the compiler. + * + * pp2: your job is to write a parser that will construct the parse tree + * and if no parse errors were found, print it. The parser should + * accept the language as described in specification, and as augmented + * in the pp2 handout. + */ + +%{ + + /* Just like lex, the text within this first region delimited by %{ and %} + * is assumed to be C/C++ code and will be copied verbatim to the y.tab.c + * file ahead of the definitions of the yyparse() function. Add other header + * file inclusions or C++ variable declarations/prototypes that are needed + * by your code here. + */ +#include "scanner.h" // for yylex +#include "parser.h" +#include "errors.h" +#include + using namespace std; + void yyerror(const char *msg); // standard error-handling routine + +%} + + /* The section before the first %% is the Definitions section of the yacc + * input file. Here is where you declare tokens and types, add precedence + * and associativity options, and so on. + */ + + /* yylval + * ------ + * Here we define the type of the yylval global variable that is used by + * the scanner to store attibute information about the token just scanned + * and thus communicate that information to the parser. + * + * pp2: You will need to add new fields to this union as you add different + * attributes to your non-terminal symbols. + */ + %union { + int integerConstant; + bool boolConstant; + char *stringConstant; + double doubleConstant; + char identifier[MaxIdentLen+1]; // +1 for terminating null + Decl *decl; + VarDecl *varDecl; + Case *caseNode; + Default *defaultNode; + List *declList; + Stmt *stmt; + List *stmtList; + List *varDeclList; +List *caseList; + Expr *expr; + Type *type; + List *exprList; + List *typeList; + } + +/* Tokens + * ------ + * Here we tell yacc about all the token types that we are using. + * Yacc will assign unique numbers to these and export the #define + * in the generated y.tab.h header file. + */ +%token T_Void T_Bool T_Int T_Double T_String T_Class +%token T_LessEqual T_GreaterEqual T_Equal T_NotEqual T_Dims +%token T_And T_Or T_Null T_Extends T_This T_Interface T_Implements +%token T_While T_For T_If T_Else T_Return T_Break +%token T_New T_NewArray T_Print T_ReadInteger T_ReadLine + +%token T_Identifier +%token T_StringConstant +%token T_IntConstant +%token T_DoubleConstant +%token T_BoolConstant + +%token T_Increm T_Decrem T_Switch T_Case T_Default + +%nonassoc NON_ELSE +%nonassoc T_Else +%nonassoc '=' +%left T_Or +%left T_And +%left T_Equal T_NotEqual +%nonassoc '<' T_LessEqual T_GreaterEqual '>' +%left '+' '-' +%left '*' '/' '%' +%left NEG '!' INCRDECR +%left '[' '.' + +/* Non-terminal types + * ------------------ + * In order for yacc to assign/access the correct field of $$, $1, we + * must to declare which field is appropriate for the non-terminal. + * As an example, this first type declaration establishes that the DeclList + * non-terminal uses the field named "declList" in the yylval union. This + * means that when we are setting $$ for a reduction for DeclList ore reading + * $n which corresponds to a DeclList nonterminal we are accessing the field + * of the union named "declList" which is of type List. + * pp2: You'll need to add many of these of your own. + */ +%type DeclList +%type VarDeclList +%type Formals +%type Decl +%type FnDecl +%type VarDecl +%type Variable +%type Stmt +%type WhileStmt +%type IfStmt +%type ForStmt +%type BreakStmt +%type ReturnStmt +%type PrintStmt +%type StmtBlock +%type StmtList +%type Expr +%type EmptyExpr +%type Type +%type Field +%type FieldList +%type ClassDecl +%type InterfaceDecl +%type InterfaceList +%type Prototype +%type PrototypeList +%type ExprList +%type Actuals +%type LValue +%type Constant +%type Call +%type SwitchStmt +%type CaseList +%type Case +%type Default + +%% +/* Rules + * ----- + * All productions and actions should be placed between the start and stop + * %% markers which delimit the Rules section. + + */ +Program : DeclList { + Program *program = new Program($1); + // if no errors, advance to next phase + if (ReportError::NumErrors() == 0) + program->Print(0); + } +; + +DeclList : DeclList Decl { ($$=$1)->Append($2); } +| Decl { ($$ = new List)->Append($1); } +; + +Decl : VarDecl { $$ = $1; } +| FnDecl {$$ = $1;} +| ClassDecl {$$ = $1;} +| InterfaceDecl {$$ = $1;} +; + +VarDeclList : VarDeclList VarDecl { ($$=$1)->Append($2); } +| VarDecl { ($$ = new List)->Append($1); } +; + +VarDecl : Variable ';' {$$ = $1;}; + +Variable : Type T_Identifier {$$ = new VarDecl(new Identifier(@2, $2), $1); }; + +ClassDecl : T_Class T_Identifier '{' FieldList '}' {$$ = new ClassDecl(new Identifier(@2, $2), 0, new List, $4);} +| T_Class T_Identifier T_Extends T_Identifier '{' FieldList '}' {$$ = new ClassDecl(new Identifier(@2, $2), new NamedType(new Identifier(@4, $4)), new List, $6);} + | T_Class T_Identifier T_Extends T_Identifier T_Implements InterfaceList '{' FieldList '}' {$$ = new ClassDecl(new Identifier(@2, $2), new NamedType(new Identifier(@4, $4)), $6, $8);} + | T_Class T_Identifier T_Implements InterfaceList '{' FieldList '}' {$$ = new ClassDecl(new Identifier(@2, $2), 0, $4, $6);} +; + +InterfaceList: T_Identifier ',' InterfaceList {($$=$3)->Append(new NamedType(new Identifier(@1, $1)));} +| T_Identifier {($$=new List)->Append(new NamedType(new Identifier(@1, $1)));} + +FieldList : FieldList Field {($$ = $1)->Append($2);} + | /* empty */ {$$ = new List;} +; + + Type: T_Int {$$ = Type::intType; } + | T_Double {$$ = Type::doubleType; } + |T_Bool {$$ = Type::boolType; } + |T_String {$$ = Type::stringType; } + |T_Identifier {$$ = new NamedType(new Identifier(@1, $1)); } +|Type T_Dims {$$ = new ArrayType(@1, $1); } +; + +FnDecl : Type T_Identifier '(' Formals ')' StmtBlock {$$ = new FnDecl(new Identifier(@2, $2), $1, $4); ((FnDecl *)$$)->SetFunctionBody($6); } +| T_Void T_Identifier '(' Formals ')' StmtBlock {$$ = new FnDecl(new Identifier(@2, $2), Type::voidType, $4); ((FnDecl *)$$)->SetFunctionBody($6); } +; + +Formals : Variable {($$ = new List)->Append($1);} +| Formals ',' Variable {($$ = $1)->Append($3);} +| {$$ = new List;} +; + +Field : VarDecl {$$ = $1;} +| FnDecl {$$ = $1;} +; + +InterfaceDecl : T_Interface T_Identifier '{' PrototypeList '}' {$$ = new InterfaceDecl(new Identifier(@2, $2), $4);}; + +PrototypeList : PrototypeList Prototype {($$=$1)->Append($2);} +| {$$ = new List;} +; +Prototype : Type T_Identifier '(' Formals ')' ';' {$$ = new FnDecl(new Identifier(@2, $2), $1, $4);} + | T_Void T_Identifier '(' Formals ')' ';' {$$ = new FnDecl(new Identifier(@2, $2), Type::voidType, $4);} +; + +StmtBlock : '{' VarDeclList StmtList '}' { $$ = new StmtBlock($2, $3);} + | '{' VarDeclList '}' { $$ = new StmtBlock($2, new List);} + | '{' StmtList '}' { $$ = new StmtBlock(new List, $2);} +| '{' '}' { $$ = new StmtBlock(new List, new List);} +; + +StmtList : StmtList Stmt { ($$=$1)->Append($2);} +| Stmt { ($$ = new List)->Append($1); } +; + +Stmt : EmptyExpr ';' {$$ = $1; } + | IfStmt {$$ = $1; } + | WhileStmt {$$ = $1; } + | ForStmt {$$ = $1; } + | BreakStmt {$$ = $1; } + | ReturnStmt {$$ = $1; } + | PrintStmt {$$ = $1; } + | StmtBlock {$$ = $1; } + | SwitchStmt {$$ = $1; } +; + +IfStmt : T_If '(' Expr ')' Stmt %prec NON_ELSE {$$ = new IfStmt($3, $5, 0); } + | T_If '(' Expr ')' Stmt T_Else Stmt { $$ = new IfStmt($3, $5, $7); } + ; +SwitchStmt : T_Switch '(' Expr ')' '{' CaseList Default '}' { $$ = new SwitchStmt($3, $6, $7);} + | T_Switch '(' Expr ')' '{' CaseList '}' { $$ = new SwitchStmt($3, $6, 0);}; + +CaseList : CaseList Case {($$ = $1)->Append($2);} +| Case {($$ = new List)->Append($1);} +; + +Case : T_Case T_IntConstant ':' StmtList {$$ = new Case(new IntConstant(@2, $2), $4);} +| T_Case T_IntConstant ':' {$$ = new Case(new IntConstant(@2, $2), new List);}; + +Default : T_Default ':' StmtList {$$ = new Default($3);} +| T_Default ':' {$$ = new Default(new List);}; + +WhileStmt : T_While '(' Expr ')' Stmt {$$ = new WhileStmt($3, $5); } +; +ForStmt : T_For '(' EmptyExpr ';' Expr ';' EmptyExpr ')' Stmt {$$ = new ForStmt($3, $5, $7, $9); } +; + +ReturnStmt : T_Return EmptyExpr ';' { $$ = new ReturnStmt(@1, $2); }; + +BreakStmt : T_Break ';' {$$ = new BreakStmt(@1); }; + +PrintStmt : T_Print '(' ExprList ')' ';' {$$ = new PrintStmt($3);}; + +ExprList : Expr {($$ = new List)->Append($1);} + | ExprList ',' Expr {($$ = $1)->Append($3);} +; + + EmptyExpr : Expr {$$ = $1; } + | {$$ = new EmptyExpr; } + ; + +Expr : LValue '=' Expr {$$ = new AssignExpr($1, new Operator(@2, "=") , $3); }; +| Constant {$$ = $1;} +| LValue {$$ = $1; } +| T_This {$$ = new This(@1);} +| Call {$$ = $1;} +|'(' Expr ')' {$$ = $2;} +| Expr '+' Expr {$$ = new ArithmeticExpr($1, new Operator(@2, "+"), $3);} +| Expr '-' Expr {$$ = new ArithmeticExpr($1, new Operator(@2, "-"), $3);} +| Expr '*' Expr {$$ = new ArithmeticExpr($1, new Operator(@2, "*"), $3);} +| Expr '/' Expr {$$ = new ArithmeticExpr($1, new Operator(@2, "/"), $3);} +| Expr '%' Expr {$$ = new ArithmeticExpr($1, new Operator(@2, "%"), $3);} +| '-' Expr %prec NEG {$$ = new ArithmeticExpr(new Operator(@2, "-"), $2);} +| Expr '<' Expr {$$ = new RelationalExpr($1, new Operator(@2, "<"), $3);} +| Expr T_LessEqual Expr {$$ = new RelationalExpr($1, new Operator(@2, "<="), $3);} +| Expr '>' Expr {$$ = new RelationalExpr($1, new Operator(@2, ">"), $3);} +| Expr T_GreaterEqual Expr {$$ = new RelationalExpr($1, new Operator(@2, ">="), $3);} +| Expr T_Equal Expr {$$ = new EqualityExpr($1, new Operator(@2, "=="), $3);} +| Expr T_NotEqual Expr {$$ = new EqualityExpr($1, new Operator(@2, "!="), $3);} +| Expr T_And Expr {$$ = new LogicalExpr($1, new Operator(@2, "&&"), $3);} +| Expr T_Or Expr {$$ = new LogicalExpr($1, new Operator(@2, "||"), $3);} +| '!' Expr {$$ = new LogicalExpr(new Operator(@1, "!"), $2);} +| T_ReadInteger '(' ')' {$$ = new ReadIntegerExpr(@1);} +| T_ReadLine '(' ')' {$$ = new ReadLineExpr(@1);} +| T_New '(' T_Identifier ')' {$$ = new NewExpr(@1, new NamedType(new Identifier(@3, $3)) );} +| T_NewArray '('Expr ',' Type')' {$$ = new NewArrayExpr(@1, $3, $5);} +| LValue T_Increm %prec INCRDECR {$$ = new PostfixExpr($1, new Operator(@2, "++"));} +| LValue T_Decrem %prec INCRDECR {$$ = new PostfixExpr($1, new Operator(@2, "--"));} +; + +LValue : T_Identifier {$$ = new FieldAccess(0, new Identifier(@1, $1)); } +| Expr '.' T_Identifier {$$ = new FieldAccess($1, new Identifier(@3, $3));} +| Expr '[' Expr ']' {$$ = new ArrayAccess(@1, $1, $3);} +; + +Call : T_Identifier '(' Actuals ')' {$$ = new Call(@1, 0, new Identifier(@1, $1), $3);} +| Expr '.' T_Identifier '(' Actuals ')' {$$ = new Call(@1, $1, new Identifier(@3, $3), $5);} +; + +Actuals: ExprList {$$ = $1;} +| {$$ = new List;} +; + +Constant: T_IntConstant {$$ = new IntConstant(@1, $1);} +| T_DoubleConstant {$$ = new DoubleConstant(@1, $1);} +| T_BoolConstant {$$ = new BoolConstant(@1, $1);} +| T_StringConstant {$$ = new StringConstant(@1, $1);} +| T_Null {$$ = new NullConstant(@1); } +; +%% + +/* The closing %% above marks the end of the Rules section and the beginning + * of the User Subroutines section. All text from here to the end of the + * file is copied verbatim to the end of the generated y.tab.c file. + * This section is where you put definitions of helper functions. + */ + +/* Function: InitParser + * -------------------- + * This function will be called before any calls to yyparse(). It is designed + * to give you an opportunity to do anything that must be done to initialize + * the parser (set global variables, configure starting state, etc.). One + * thing it already does for you is assign the value of the global variable + * yydebug that controls whether yacc prints debugging information about + * parser actions (shift/reduce) and contents of state stack during parser. + * If set to false, no information is printed. Setting it to true will give + * you a running trail that might be helpful when debugging your parser. + * Please be sure the variable is set to false when submitting your final + * version. + */ +void InitParser() +{ + PrintDebug("parser", "Initializing parser"); + yydebug = false; +} diff --git a/filter_sandbox/scanner.l b/filter_sandbox/scanner.l new file mode 100644 index 0000000..6294ee4 --- /dev/null +++ b/filter_sandbox/scanner.l @@ -0,0 +1,256 @@ +/* File: scanner.l + * ---------------- + * Lex input file to generate the scanner for the compiler. + */ + +%{ +#include +#include "scanner.h" +#include "utility.h" // for PrintDebug() +#include "errors.h" +#include +#include +#include + +using std::string; +using std::cout; +using std::endl; + +/* Global variable: yylval + * ----------------------- + * This global variable is how we get attribute information about the token + * just scanned to the client. The scanner sets the global variable + * appropriately and since it's global the client can just read it. In the + * future, this variable will be declared for us in the y.tab.c file + * produced by Yacc, but for now, we declare it manually. + */ +YYSTYPE yylval; // manually declared for pp1, later Yacc provides + +/* Global variable: yylloc + * ----------------------- + * This global variable is how we get position information about the token + * just scanned to the client. (Operates similarly to yylval above) + */ +struct yyltype yylloc; // manually dclared for pp1, later Yacc provides + +/* Macro: YY_USER_ACTION + * --------------------- + * This flex built-in macro can be defined to provide an action which is + * always executed prior to any matched rule's action. Basically, it is + * a way of having a piece of code common to all actions factored out to + * this routine. We already defined it for you and left the empty + * function DoBeforeEachAction ready for your use as needed. It will + * be called once for each pattern scanned from the file, before + * executing its action. + */ +static void DoBeforeEachAction(); +#define YY_USER_ACTION DoBeforeEachAction(); + +static void set_value(TokenType); + +%} + +ALPHA [a-zA-Z] +ALPHANUM [a-zA-Z0-9] +WORDCHAR [a-zA-Z0-9_] +DIGIT [0-9] +HEX 0(x|X)[0-9a-fA-F]+ +WHITESPACE [ \t\n] + +%% + + /* Keywords */ +void return T_Void; +int return T_Int; +double return T_Double; +bool return T_Bool; +string return T_String; +class return T_Class; +interface return T_Interface; +null return T_Null; +this return T_This; +extends return T_Extends; +implements return T_Implements; +for return T_For; +while return T_While; +if return T_If; +else return T_Else; +return return T_Return; +break return T_Break; +New return T_New; +NewArray return T_NewArray; + + /* Type Constants */ +true|false {set_value(T_BoolConstant); return T_BoolConstant;} +{HEX}|{DIGIT}+ {set_value(T_IntConstant); return T_IntConstant;} +{DIGIT}+\.{DIGIT}*((E|e)(\+|-)?{DIGIT}+)? {set_value(T_DoubleConstant); return T_DoubleConstant;} +\"[^\"\n]*\" {set_value(T_StringConstant); return T_StringConstant;} +\"[^\"\n]* {ReportError::UntermString(&yylloc, yytext);} + + /* Whitespace */ +{WHITESPACE} ; + + /* Identifier */ +{ALPHA}{WORDCHAR}* {set_value(T_Identifier); return T_Identifier;} + + /* Operators */ +"<=" return T_LessEqual; +>= return T_GreaterEqual; +== return T_Equal; +!= return T_NotEqual; +&& return T_And; +"||" return T_Or; +\+ return '+'; +- return '-'; +\* return '*'; +\/ return '/'; +% return '%'; +\< return '<'; +\> return '>'; += return '='; +! return '!'; +; return ';'; +, return ','; +\. return '.'; +"[" return '['; +"]" return ']'; +"(" return '('; +")" return ')'; +"{" return '{'; +"}" return '}'; + +. ReportError::UnrecogChar(&yylloc, *yytext); + +%% + +static bool text_to_bool(char *yytext) { + if (!strcmp(yytext, "true")) { + return true; + } else if (!strcmp(yytext, "false")) { + return false; + } else { + Failure("Unrecognized value in function text_to_bool()"); + } + + // This will never be called + exit(1); +} + +static int text_to_int(char *yytext) { + if (strlen(yytext) >= 2 && (yytext[1] == 'x' || yytext[1] == 'X')) { + int num; + int decimal = 0; + for (int i = 2; i < yyleng; i++) { + char c = isalpha(yytext[i]) ? toupper(yytext[i]) : yytext[i]; + switch(c) { + case 'A': num = 10; break; + case 'B': num = 11; break; + case 'C': num = 12; break; + case 'D': num = 13; break; + case 'E': num = 14; break; + case 'F': num = 15; break; + default: num = yytext[i] - 48; break; + } + decimal += num * pow(16, yyleng - i - 1); // The exponent is the inverse of the char position + } + return decimal; + } + return atoi(yytext); +} + +static double text_to_double(char *yytext) { + int i = 0; + double ret = 0; + bool decimal = false; + double divisor = 1; + bool pose = true; + bool exponent = false; + std::string num; + while(i < yyleng){ + num = num + yytext[i]; + if(yytext[i] == 'E' || yytext[i] == 'e'){ + exponent = true; + ret = ret + atoi(num.c_str())/divisor; + num.clear(); + if(yytext[i + 1] == '-'){ + pose = false; + i++; + } + else if(yytext[i + 1] == '+') i++; + } + if(decimal) divisor *= 10; + if(yytext[i] == '.'){ + ret = atoi(num.c_str()); + decimal = true; + num.clear(); + } + i++; + } + + if(exponent) return ret * pow(10, atoi(num.c_str())); + else return ret + atoi(num.c_str())/divisor; +} + +static void set_identifier(char *identifier) { + int num_chars = yyleng + 1; // The characters plus the null character + if (yyleng > MaxIdentLen) { + ReportError::LongIdentifier(&yylloc, yytext); + num_chars = MaxIdentLen; + } + + strncpy(identifier, yytext, num_chars); + assert(identifier[MaxIdentLen + 1] == 0); +} + +static void set_value(TokenType t) { + switch(t) { + case T_BoolConstant: yylval.boolConstant = text_to_bool(yytext); break; + case T_IntConstant: yylval.integerConstant = text_to_int(yytext); break; + case T_DoubleConstant: yylval.doubleConstant = text_to_double(yytext); break; + case T_StringConstant: yylval.stringConstant = yytext; break; + case T_Identifier: set_identifier(yylval.identifier); break; + default: Failure("Unrecognized token %d in set_value()", (int) t); + } +} + +/* Function: InitScanner + * --------------------- + * This function will be called before any calls to yylex(). It is designed + * to give you an opportunity to do anything that must be done to initialize + * the scanner (set global variables, configure starting state, etc.). One + * thing it already does for you is assign the value of the global variable + * yy_flex_debug that controls whether flex prints debugging information + * about each token and what rule was matched. If set to false, no information + * is printed. Setting it to true will give you a running trail that might + * be helpful when debugging your scanner. Please be sure the variable is + * set to false when submitting your final version. + */ +void InitScanner() +{ + yy_flex_debug = false; + PrintDebug("lex", "Initializing scanner"); +} + + +/* Function: DoBeforeEachAction() + * ------------------------------ + * This function is installed as the YY_USER_ACTION. This is a place + * to group code common to all actions. + */ +static void DoBeforeEachAction() +{ + // TODO: This section looks hacky to me + static int col_pos = 1; + static int line_pos = 1; + + if (*yytext == '\n') { + line_pos++; + col_pos = 0; + } + + yylloc.first_column = col_pos; + yylloc.last_column = col_pos + yyleng - 1; + yylloc.first_line = line_pos; + + col_pos += yyleng; +} diff --git a/filter_sandbox/tree.c b/filter_sandbox/tree.c new file mode 100644 index 0000000..76adc99 --- /dev/null +++ b/filter_sandbox/tree.c @@ -0,0 +1,69 @@ +#include "tree.h" + +node_t* alloc_node() +{ + node_t *node = (node_t*) malloc(sizeof(node_t)); + memset(node, 0, sizeof(node_t)); + return node; +} + +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.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) { + int result = 1; + return result; +} + +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.fieldname); + break; + case STRING: + printf("%s) ", root->value.string_literal); + break; + case INT: + printf(" %d) ", root->value.int_literal); + break; + default: + break; + } + print_expression(root->right_child); + printf("%s", " )"); +} diff --git a/filter_sandbox/tree.h b/filter_sandbox/tree.h new file mode 100644 index 0000000..232afef --- /dev/null +++ b/filter_sandbox/tree.h @@ -0,0 +1,44 @@ +#ifndef ZMAP_TREE_H +#define ZMAP_TREE_H + +#include +#include +#include + +enum operation { + GT, LT, EQ, NEQ, AND, OR, LT_EQ, GT_EQ +}; + +enum node_type { + OP, FIELD, STRING, INT +}; + +union node_value { + enum operation op; + char *fieldname; + char *string_literal; + int int_literal; +}; + +typedef struct node { + struct node *left_child; + struct node *right_child; + enum node_type type; + union node_value value; +} node_t; + +node_t* alloc_node(); + +node_t* make_op_node(enum operation op); + +node_t* make_field_node(char *fieldname); + +node_t* make_string_node(char *literal); + +node_t* make_int_node(int literal); + +int evaluate_expression(node_t *root); + +void print_expression(node_t *root); + +#endif /* ZMAP_TREE_H */ \ No newline at end of file diff --git a/filter_sandbox/y.output b/filter_sandbox/y.output new file mode 100644 index 0000000..3687082 --- /dev/null +++ b/filter_sandbox/y.output @@ -0,0 +1,303 @@ +Grammar + + 0 $accept: filter_expr $end + + 1 filter_expr: filter_expr T_OR filter_expr + 2 | filter_expr T_AND filter_expr + 3 | '(' filter_expr ')' + 4 | filter + + 5 filter: number_filter + 6 | string_filter + + 7 number_filter: T_FIELD '=' T_NUMBER + 8 | T_FIELD '>' T_NUMBER + 9 | T_FIELD '<' T_NUMBER + 10 | T_FIELD T_NOT_EQ T_NUMBER + 11 | T_FIELD T_GT_EQ T_NUMBER + 12 | T_FIELD T_LT_EQ T_NUMBER + + 13 string_filter: T_FIELD '=' T_FIELD + 14 | T_FIELD T_NOT_EQ T_FIELD + + +Terminals, with rules where they appear + +$end (0) 0 +'(' (40) 3 +')' (41) 3 +'<' (60) 9 +'=' (61) 7 13 +'>' (62) 8 +error (256) +T_AND (258) 2 +T_OR (259) 1 +T_NUMBER (260) 7 8 9 10 11 12 +T_FIELD (261) 7 8 9 10 11 12 13 14 +T_NOT_EQ (262) 10 14 +T_GT_EQ (263) 11 +T_LT_EQ (264) 12 + + +Nonterminals, with rules where they appear + +$accept (15) + on left: 0 +filter_expr (16) + on left: 1 2 3 4, on right: 0 1 2 3 +filter (17) + on left: 5 6, on right: 4 +number_filter (18) + on left: 7 8 9 10 11 12, on right: 5 +string_filter (19) + on left: 13 14, on right: 6 + + +state 0 + + 0 $accept: . filter_expr $end + + '(' shift, and go to state 1 + T_FIELD shift, and go to state 2 + + filter_expr go to state 3 + filter go to state 4 + number_filter go to state 5 + string_filter go to state 6 + + +state 1 + + 3 filter_expr: '(' . filter_expr ')' + + '(' shift, and go to state 1 + T_FIELD shift, and go to state 2 + + filter_expr go to state 7 + filter go to state 4 + number_filter go to state 5 + string_filter go to state 6 + + +state 2 + + 7 number_filter: T_FIELD . '=' T_NUMBER + 8 | T_FIELD . '>' T_NUMBER + 9 | T_FIELD . '<' T_NUMBER + 10 | T_FIELD . T_NOT_EQ T_NUMBER + 11 | T_FIELD . T_GT_EQ T_NUMBER + 12 | T_FIELD . T_LT_EQ T_NUMBER + 13 string_filter: T_FIELD . '=' T_FIELD + 14 | T_FIELD . T_NOT_EQ T_FIELD + + T_NOT_EQ shift, and go to state 8 + '>' shift, and go to state 9 + T_GT_EQ shift, and go to state 10 + '<' shift, and go to state 11 + '=' shift, and go to state 12 + T_LT_EQ shift, and go to state 13 + + +state 3 + + 0 $accept: filter_expr . $end + 1 filter_expr: filter_expr . T_OR filter_expr + 2 | filter_expr . T_AND filter_expr + + $end shift, and go to state 14 + T_AND shift, and go to state 15 + T_OR shift, and go to state 16 + + +state 4 + + 4 filter_expr: filter . + + $default reduce using rule 4 (filter_expr) + + +state 5 + + 5 filter: number_filter . + + $default reduce using rule 5 (filter) + + +state 6 + + 6 filter: string_filter . + + $default reduce using rule 6 (filter) + + +state 7 + + 1 filter_expr: filter_expr . T_OR filter_expr + 2 | filter_expr . T_AND filter_expr + 3 | '(' filter_expr . ')' + + ')' shift, and go to state 17 + T_AND shift, and go to state 15 + T_OR shift, and go to state 16 + + +state 8 + + 10 number_filter: T_FIELD T_NOT_EQ . T_NUMBER + 14 string_filter: T_FIELD T_NOT_EQ . T_FIELD + + T_NUMBER shift, and go to state 18 + T_FIELD shift, and go to state 19 + + +state 9 + + 8 number_filter: T_FIELD '>' . T_NUMBER + + T_NUMBER shift, and go to state 20 + + +state 10 + + 11 number_filter: T_FIELD T_GT_EQ . T_NUMBER + + T_NUMBER shift, and go to state 21 + + +state 11 + + 9 number_filter: T_FIELD '<' . T_NUMBER + + T_NUMBER shift, and go to state 22 + + +state 12 + + 7 number_filter: T_FIELD '=' . T_NUMBER + 13 string_filter: T_FIELD '=' . T_FIELD + + T_NUMBER shift, and go to state 23 + T_FIELD shift, and go to state 24 + + +state 13 + + 12 number_filter: T_FIELD T_LT_EQ . T_NUMBER + + T_NUMBER shift, and go to state 25 + + +state 14 + + 0 $accept: filter_expr $end . + + $default accept + + +state 15 + + 2 filter_expr: filter_expr T_AND . filter_expr + + '(' shift, and go to state 1 + T_FIELD shift, and go to state 2 + + filter_expr go to state 26 + filter go to state 4 + number_filter go to state 5 + string_filter go to state 6 + + +state 16 + + 1 filter_expr: filter_expr T_OR . filter_expr + + '(' shift, and go to state 1 + T_FIELD shift, and go to state 2 + + filter_expr go to state 27 + filter go to state 4 + number_filter go to state 5 + string_filter go to state 6 + + +state 17 + + 3 filter_expr: '(' filter_expr ')' . + + $default reduce using rule 3 (filter_expr) + + +state 18 + + 10 number_filter: T_FIELD T_NOT_EQ T_NUMBER . + + $default reduce using rule 10 (number_filter) + + +state 19 + + 14 string_filter: T_FIELD T_NOT_EQ T_FIELD . + + $default reduce using rule 14 (string_filter) + + +state 20 + + 8 number_filter: T_FIELD '>' T_NUMBER . + + $default reduce using rule 8 (number_filter) + + +state 21 + + 11 number_filter: T_FIELD T_GT_EQ T_NUMBER . + + $default reduce using rule 11 (number_filter) + + +state 22 + + 9 number_filter: T_FIELD '<' T_NUMBER . + + $default reduce using rule 9 (number_filter) + + +state 23 + + 7 number_filter: T_FIELD '=' T_NUMBER . + + $default reduce using rule 7 (number_filter) + + +state 24 + + 13 string_filter: T_FIELD '=' T_FIELD . + + $default reduce using rule 13 (string_filter) + + +state 25 + + 12 number_filter: T_FIELD T_LT_EQ T_NUMBER . + + $default reduce using rule 12 (number_filter) + + +state 26 + + 1 filter_expr: filter_expr . T_OR filter_expr + 2 | filter_expr . T_AND filter_expr + 2 | filter_expr T_AND filter_expr . + + $default reduce using rule 2 (filter_expr) + + +state 27 + + 1 filter_expr: filter_expr . T_OR filter_expr + 1 | filter_expr T_OR filter_expr . + 2 | filter_expr . T_AND filter_expr + + T_AND shift, and go to state 15 + + $default reduce using rule 1 (filter_expr) diff --git a/filter_sandbox/y.tab.c b/filter_sandbox/y.tab.c new file mode 100644 index 0000000..3d4097e --- /dev/null +++ b/filter_sandbox/y.tab.c @@ -0,0 +1,1687 @@ +/* A Bison parser, made by GNU Bison 2.3. */ + +/* Skeleton implementation for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "2.3" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Using locations. */ +#define YYLSP_NEEDED 0 + + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + T_AND = 258, + T_OR = 259, + T_NUMBER = 260, + T_FIELD = 261, + T_NOT_EQ = 262, + T_GT_EQ = 263, + T_LT_EQ = 264 + }; +#endif +/* Tokens. */ +#define T_AND 258 +#define T_OR 259 +#define T_NUMBER 260 +#define T_FIELD 261 +#define T_NOT_EQ 262 +#define T_GT_EQ 263 +#define T_LT_EQ 264 + + + + +/* Copy the first part of user declarations. */ +#line 1 "zmap.y" + +#include +#include +#include "tree.h" + +void yyerror(const char *str) +{ + fprintf(stderr,"error: %s\n",str); + fprintf(stderr, "%s\n", "YOLO"); +} + +int yywrap() +{ + return 1; +} + +int main() +{ + yyparse(); +} + + + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 1 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +/* Enabling the token table. */ +#ifndef YYTOKEN_TABLE +# define YYTOKEN_TABLE 0 +#endif + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +#line 24 "zmap.y" +{ + int int_literal; + char *string_literal; + struct node *expr; +} +/* Line 193 of yacc.c. */ +#line 143 "y.tab.c" + YYSTYPE; +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + + + +/* Copy the second part of user declarations. */ + + +/* Line 216 of yacc.c. */ +#line 156 "y.tab.c" + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#elif (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +typedef signed char yytype_int8; +#else +typedef short int yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short int yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short int yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned int +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(msgid) dgettext ("bison-runtime", msgid) +# endif +# endif +# ifndef YY_ +# define YY_(msgid) msgid +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(e) ((void) (e)) +#else +# define YYUSE(e) /* empty */ +#endif + +/* Identity function, used to suppress warnings about constant conditions. */ +#ifndef lint +# define YYID(n) (n) +#else +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static int +YYID (int i) +#else +static int +YYID (i) + int i; +#endif +{ + return i; +} +#endif + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef _STDLIB_H +# define _STDLIB_H 1 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined _STDLIB_H \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef _STDLIB_H +# define _STDLIB_H 1 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss; + YYSTYPE yyvs; + }; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (YYID (0)) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack, Stack, yysize); \ + Stack = &yyptr->Stack; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (YYID (0)) + +#endif + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 14 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 26 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 15 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 5 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 15 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 28 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 264 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 3, 4, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 12, 13, 10, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 5, 6, + 7, 8, 9, 11, 14 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const yytype_uint8 yyprhs[] = +{ + 0, 0, 3, 7, 11, 15, 17, 19, 21, 25, + 29, 33, 37, 41, 45, 49 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yytype_int8 yyrhs[] = +{ + 16, 0, -1, 16, 6, 16, -1, 16, 5, 16, + -1, 3, 16, 4, -1, 17, -1, 18, -1, 19, + -1, 8, 13, 7, -1, 8, 10, 7, -1, 8, + 12, 7, -1, 8, 9, 7, -1, 8, 11, 7, + -1, 8, 14, 7, -1, 8, 13, 8, -1, 8, + 9, 8, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const yytype_uint8 yyrline[] = +{ + 0, 47, 47, 55, 63, 67, 73, 77, 83, 91, + 99, 104, 109, 114, 121, 126 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "'('", "')'", "T_AND", "T_OR", + "T_NUMBER", "T_FIELD", "T_NOT_EQ", "'>'", "T_GT_EQ", "'<'", "'='", + "T_LT_EQ", "$accept", "filter_expr", "filter", "number_filter", + "string_filter", 0 +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 40, 41, 258, 259, 260, 261, 262, + 62, 263, 60, 61, 264 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 15, 16, 16, 16, 16, 17, 17, 18, 18, + 18, 18, 18, 18, 19, 19 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 3, 3, 3, 1, 1, 1, 3, 3, + 3, 3, 3, 3, 3, 3 +}; + +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const yytype_uint8 yydefact[] = +{ + 0, 0, 0, 0, 5, 6, 7, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 4, 11, 15, + 9, 12, 10, 8, 14, 13, 3, 2 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int8 yydefgoto[] = +{ + -1, 3, 4, 5, 6 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -6 +static const yytype_int8 yypact[] = +{ + 0, 0, 7, 1, -6, -6, -6, 5, -3, -5, + 6, 17, 15, 18, -6, 0, 0, -6, -6, -6, + -6, -6, -6, -6, -6, -6, -6, 21 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int8 yypgoto[] = +{ + -6, -1, -6, -6, -6 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -1 +static const yytype_uint8 yytable[] = +{ + 7, 14, 20, 1, 18, 19, 15, 16, 2, 17, + 15, 16, 0, 21, 26, 27, 8, 9, 10, 11, + 12, 13, 23, 24, 22, 25, 15 +}; + +static const yytype_int8 yycheck[] = +{ + 1, 0, 7, 3, 7, 8, 5, 6, 8, 4, + 5, 6, -1, 7, 15, 16, 9, 10, 11, 12, + 13, 14, 7, 8, 7, 7, 5 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint8 yystos[] = +{ + 0, 3, 8, 16, 17, 18, 19, 16, 9, 10, + 11, 12, 13, 14, 0, 5, 6, 4, 7, 8, + 7, 7, 7, 7, 8, 7, 16, 16 +}; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ + +#define YYFAIL goto yyerrlab + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK (1); \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (YYID (0)) + + +#define YYTERROR 1 +#define YYERRCODE 256 + + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (YYID (N)) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (YYID (0)) +#endif + + +/* YY_LOCATION_PRINT -- Print the location on the stream. + This macro was not mandated originally: define only if we know + we won't break user code: when these are the locations we know. */ + +#ifndef YY_LOCATION_PRINT +# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL +# define YY_LOCATION_PRINT(File, Loc) \ + fprintf (File, "%d.%d-%d.%d", \ + (Loc).first_line, (Loc).first_column, \ + (Loc).last_line, (Loc).last_column) +# else +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +# endif +#endif + + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (YYLEX_PARAM) +#else +# define YYLEX yylex () +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (YYID (0)) + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (YYID (0)) + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_value_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif +{ + if (!yyvaluep) + return; +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# else + YYUSE (yyoutput); +# endif + switch (yytype) + { + default: + break; + } +} + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +#else +static void +yy_symbol_print (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; +#endif +{ + if (yytype < YYNTOKENS) + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + yy_symbol_value_print (yyoutput, yytype, yyvaluep); + YYFPRINTF (yyoutput, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) +#else +static void +yy_stack_print (bottom, top) + yytype_int16 *bottom; + yytype_int16 *top; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (; bottom <= top; ++bottom) + YYFPRINTF (stderr, " %d", *bottom); + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (YYID (0)) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_reduce_print (YYSTYPE *yyvsp, int yyrule) +#else +static void +yy_reduce_print (yyvsp, yyrule) + YYSTYPE *yyvsp; + int yyrule; +#endif +{ + int yynrhs = yyr2[yyrule]; + int yyi; + unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + fprintf (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], + &(yyvsp[(yyi + 1) - (yynrhs)]) + ); + fprintf (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyvsp, Rule); \ +} while (YYID (0)) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static YYSIZE_T +yystrlen (const char *yystr) +#else +static YYSIZE_T +yystrlen (yystr) + const char *yystr; +#endif +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static char * +yystpcpy (char *yydest, const char *yysrc) +#else +static char * +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +#endif +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif + +/* Copy into YYRESULT an error message about the unexpected token + YYCHAR while in state YYSTATE. Return the number of bytes copied, + including the terminating null byte. If YYRESULT is null, do not + copy anything; just return the number of bytes that would be + copied. As a special case, return 0 if an ordinary "syntax error" + message will do. Return YYSIZE_MAXIMUM if overflow occurs during + size calculation. */ +static YYSIZE_T +yysyntax_error (char *yyresult, int yystate, int yychar) +{ + int yyn = yypact[yystate]; + + if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) + return 0; + else + { + int yytype = YYTRANSLATE (yychar); + YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); + YYSIZE_T yysize = yysize0; + YYSIZE_T yysize1; + int yysize_overflow = 0; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + int yyx; + +# if 0 + /* This is so xgettext sees the translatable formats that are + constructed on the fly. */ + YY_("syntax error, unexpected %s"); + YY_("syntax error, unexpected %s, expecting %s"); + YY_("syntax error, unexpected %s, expecting %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); +# endif + char *yyfmt; + char const *yyf; + static char const yyunexpected[] = "syntax error, unexpected %s"; + static char const yyexpecting[] = ", expecting %s"; + static char const yyor[] = " or %s"; + char yyformat[sizeof yyunexpected + + sizeof yyexpecting - 1 + + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) + * (sizeof yyor - 1))]; + char const *yyprefix = yyexpecting; + + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yycount = 1; + + yyarg[0] = yytname[yytype]; + yyfmt = yystpcpy (yyformat, yyunexpected); + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + yyformat[sizeof yyunexpected - 1] = '\0'; + break; + } + yyarg[yycount++] = yytname[yyx]; + yysize1 = yysize + yytnamerr (0, yytname[yyx]); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + yyfmt = yystpcpy (yyfmt, yyprefix); + yyprefix = yyor; + } + + yyf = YY_(yyformat); + yysize1 = yysize + yystrlen (yyf); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + + if (yysize_overflow) + return YYSIZE_MAXIMUM; + + if (yyresult) + { + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + char *yyp = yyresult; + int yyi = 0; + while ((*yyp = *yyf) != '\0') + { + if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyf += 2; + } + else + { + yyp++; + yyf++; + } + } + } + return yysize; + } +} +#endif /* YYERROR_VERBOSE */ + + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +#else +static void +yydestruct (yymsg, yytype, yyvaluep) + const char *yymsg; + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + YYUSE (yyvaluep); + + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + switch (yytype) + { + + default: + break; + } +} + + +/* Prevent warnings from -Wmissing-prototypes. */ + +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int yyparse (void *YYPARSE_PARAM); +#else +int yyparse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int yyparse (void); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + + + +/* The look-ahead symbol. */ +int yychar; + +/* The semantic value of the look-ahead symbol. */ +YYSTYPE yylval; + +/* Number of syntax errors so far. */ +int yynerrs; + + + +/*----------. +| yyparse. | +`----------*/ + +#ifdef YYPARSE_PARAM +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void *YYPARSE_PARAM) +#else +int +yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +#endif +#else /* ! YYPARSE_PARAM */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void) +#else +int +yyparse () + +#endif +#endif +{ + + int yystate; + int yyn; + int yyresult; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + /* Look-ahead token as an internal (translated) token number. */ + int yytoken = 0; +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + + /* Three stacks and their tools: + `yyss': related to states, + `yyvs': related to semantic values, + `yyls': related to locations. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss = yyssa; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs = yyvsa; + YYSTYPE *yyvsp; + + + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + YYSIZE_T yystacksize = YYINITDEPTH; + + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + + yyssp = yyss; + yyvsp = yyvs; + + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss); + YYSTACK_RELOCATE (yyvs); + +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + + /* Do appropriate processing given the current state. Read a + look-ahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to look-ahead token. */ + yyn = yypact[yystate]; + if (yyn == YYPACT_NINF) + goto yydefault; + + /* Not known => get a look-ahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == YYTABLE_NINF) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + if (yyn == YYFINAL) + YYACCEPT; + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the look-ahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token unless it is eof. */ + if (yychar != YYEOF) + yychar = YYEMPTY; + + yystate = yyn; + *++yyvsp = yylval; + + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 2: +#line 48 "zmap.y" + { + (yyval.expr) = make_op_node(OR); + (yyval.expr)->left_child = (yyvsp[(1) - (3)].expr); + (yyval.expr)->right_child = (yyvsp[(3) - (3)].expr); + print_expression((yyval.expr)); + printf("%s\n", ""); + } + break; + + case 3: +#line 56 "zmap.y" + { + (yyval.expr) = make_op_node(AND); + (yyval.expr)->left_child = (yyvsp[(1) - (3)].expr); + (yyval.expr)->right_child = (yyvsp[(3) - (3)].expr); + print_expression((yyval.expr)); + printf("%s\n", ""); + } + break; + + case 4: +#line 64 "zmap.y" + { + (yyval.expr) = (yyvsp[(2) - (3)].expr); + } + break; + + case 5: +#line 68 "zmap.y" + { + (yyval.expr) = (yyvsp[(1) - (1)].expr); + } + break; + + case 6: +#line 74 "zmap.y" + { + (yyval.expr) = (yyvsp[(1) - (1)].expr); + } + break; + + case 7: +#line 78 "zmap.y" + { + (yyval.expr) = (yyvsp[(1) - (1)].expr); + } + break; + + case 8: +#line 84 "zmap.y" + { + printf("number_filter: %s = %d\n", (yyvsp[(1) - (3)].string_literal), (yyvsp[(3) - (3)].int_literal)); + (yyval.expr) = make_op_node(EQ); + (yyval.expr)->left_child = make_field_node((yyvsp[(1) - (3)].string_literal)); + (yyval.expr)->right_child = make_int_node((yyvsp[(3) - (3)].int_literal)); + } + break; + + case 9: +#line 92 "zmap.y" + { + printf("number_filter: %s > %d\n", (yyvsp[(1) - (3)].string_literal), (yyvsp[(3) - (3)].int_literal)); + (yyval.expr) = make_op_node(GT); + (yyval.expr)->left_child = make_field_node((yyvsp[(1) - (3)].string_literal)); + (yyval.expr)->right_child = make_int_node((yyvsp[(3) - (3)].int_literal)); + } + break; + + case 10: +#line 100 "zmap.y" + { + printf("number_filter: %s < %d\n", (yyvsp[(1) - (3)].string_literal), (yyvsp[(3) - (3)].int_literal)); + } + break; + + case 11: +#line 105 "zmap.y" + { + printf("number_filter: %s != %d\n", (yyvsp[(1) - (3)].string_literal), (yyvsp[(3) - (3)].int_literal)); + } + break; + + case 12: +#line 110 "zmap.y" + { + printf("number_filter: %s >= %d\n", (yyvsp[(1) - (3)].string_literal), (yyvsp[(3) - (3)].int_literal)); + } + break; + + case 13: +#line 115 "zmap.y" + { + printf("number_filter: %s <= %d\n", (yyvsp[(1) - (3)].string_literal), (yyvsp[(3) - (3)].int_literal)); + } + break; + + case 14: +#line 122 "zmap.y" + { + printf("string_filter %s = %s\n", (yyvsp[(1) - (3)].string_literal), (yyvsp[(3) - (3)].string_literal)); + } + break; + + case 15: +#line 127 "zmap.y" + { + printf("string_filter: %s != %s\n", (yyvsp[(1) - (3)].string_literal), (yyvsp[(3) - (3)].string_literal)); + } + break; + + +/* Line 1267 of yacc.c. */ +#line 1470 "y.tab.c" + default: break; + } + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (YY_("syntax error")); +#else + { + YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); + if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) + { + YYSIZE_T yyalloc = 2 * yysize; + if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) + yyalloc = YYSTACK_ALLOC_MAXIMUM; + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yyalloc); + if (yymsg) + yymsg_alloc = yyalloc; + else + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + } + } + + if (0 < yysize && yysize <= yymsg_alloc) + { + (void) yysyntax_error (yymsg, yystate, yychar); + yyerror (yymsg); + } + else + { + yyerror (YY_("syntax error")); + if (yysize != 0) + goto yyexhaustedlab; + } + } +#endif + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse look-ahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse look-ahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (/*CONSTCOND*/ 0) + goto yyerrorlab; + + /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (yyn != YYPACT_NINF) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + yystos[yystate], yyvsp); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + if (yyn == YYFINAL) + YYACCEPT; + + *++yyvsp = yylval; + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#ifndef yyoverflow +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: + if (yychar != YYEOF && yychar != YYEMPTY) + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); + /* Do not reclaim the symbols of the rule which action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + /* Make sure YYID is used. */ + return YYID (yyresult); +} + + +#line 132 "zmap.y" + + + + diff --git a/filter_sandbox/y.tab.h b/filter_sandbox/y.tab.h new file mode 100644 index 0000000..305eba0 --- /dev/null +++ b/filter_sandbox/y.tab.h @@ -0,0 +1,80 @@ +/* A Bison parser, made by GNU Bison 2.3. */ + +/* Skeleton interface for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + T_AND = 258, + T_OR = 259, + T_NUMBER = 260, + T_FIELD = 261, + T_NOT_EQ = 262, + T_GT_EQ = 263, + T_LT_EQ = 264 + }; +#endif +/* Tokens. */ +#define T_AND 258 +#define T_OR 259 +#define T_NUMBER 260 +#define T_FIELD 261 +#define T_NOT_EQ 262 +#define T_GT_EQ 263 +#define T_LT_EQ 264 + + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE +#line 24 "zmap.y" +{ + int int_literal; + char *string_literal; + struct node *expr; +} +/* Line 1529 of yacc.c. */ +#line 73 "y.tab.h" + YYSTYPE; +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + +extern YYSTYPE yylval; + diff --git a/filter_sandbox/zmap.l b/filter_sandbox/zmap.l new file mode 100644 index 0000000..4de7dff --- /dev/null +++ b/filter_sandbox/zmap.l @@ -0,0 +1,22 @@ +%{ +#include +#include "y.tab.h" +%} + +%% +[0-9]+ yylval.int_literal = atoi(yytext); return T_NUMBER; +\n /* Ignore end of line */ +[ \t]+ /* Ignore whitespace */ +!= return T_NOT_EQ; +>= return T_GT_EQ; +"<=" return T_LT_EQ; +&& return T_AND; +"||" return T_OR; += return '='; +">" return '>'; +"<" return '<'; +"(" return '('; +")" return ')'; +[a-zA-Z][a-zA-Z0-9]+ yylval.string_literal = strdup(yytext); return T_FIELD; + +%% \ No newline at end of file diff --git a/filter_sandbox/zmap.y b/filter_sandbox/zmap.y new file mode 100644 index 0000000..fe196a1 --- /dev/null +++ b/filter_sandbox/zmap.y @@ -0,0 +1,134 @@ +%{ +#include +#include +#include "tree.h" + +void yyerror(const char *str) +{ + fprintf(stderr,"error: %s\n",str); + fprintf(stderr, "%s\n", "YOLO"); +} + +int yywrap() +{ + return 1; +} + +int main() +{ + yyparse(); +} + +%} + +%union { + int int_literal; + char *string_literal; + struct node *expr; +} + +%token '(' ')' T_AND T_OR +%token T_NUMBER +%token T_FIELD +%token T_NOT_EQ T_GT_EQ '>' '<' '=' T_LT_EQ + +%left T_OR +%left T_AND + +%type filter +%type number_filter +%type string_filter +%type filter_expr + + +%% + +filter_expr: + filter_expr T_OR filter_expr + { + $$ = make_op_node(OR); + $$->left_child = $1; + $$->right_child = $3; + print_expression($$); + printf("%s\n", ""); + } + | filter_expr T_AND filter_expr + { + $$ = make_op_node(AND); + $$->left_child = $1; + $$->right_child = $3; + print_expression($$); + printf("%s\n", ""); + } + | '(' filter_expr ')' + { + $$ = $2; + } + | filter + { + $$ = $1; + } + ; + +filter: number_filter + { + $$ = $1; + } + | string_filter + { + $$ = $1; + } + ; + +number_filter: T_FIELD '=' T_NUMBER + { + printf("number_filter: %s = %d\n", $1, $3); + $$ = make_op_node(EQ); + $$->left_child = make_field_node($1); + $$->right_child = make_int_node($3); + } + | + T_FIELD '>' T_NUMBER + { + printf("number_filter: %s > %d\n", $1, $3); + $$ = make_op_node(GT); + $$->left_child = make_field_node($1); + $$->right_child = make_int_node($3); + } + | + T_FIELD '<' T_NUMBER + { + printf("number_filter: %s < %d\n", $1, $3); + } + | + T_FIELD T_NOT_EQ T_NUMBER + { + printf("number_filter: %s != %d\n", $1, $3); + } + | + T_FIELD T_GT_EQ T_NUMBER + { + printf("number_filter: %s >= %d\n", $1, $3); + } + | + T_FIELD T_LT_EQ T_NUMBER + { + printf("number_filter: %s <= %d\n", $1, $3); + } + ; + +string_filter: + T_FIELD '=' T_FIELD + { + printf("string_filter %s = %s\n", $1, $3); + } + | + T_FIELD T_NOT_EQ T_FIELD + { + printf("string_filter: %s != %s\n", $1, $3); + } + ; + +%% + + From 8607c2574b0ea85a4074fab259ead1bc20647440 Mon Sep 17 00:00:00 2001 From: David Adrian Date: Mon, 16 Sep 2013 21:53:13 -0400 Subject: [PATCH 11/53] Move filter files into src/ - Makefile still needs work, is not compiling --- filter_sandbox/.gitignore | 2 - filter_sandbox/Makefile | 8 - filter_sandbox/README | 7 - filter_sandbox/lex.yy.c | 1807 --------------------- filter_sandbox/parser.y | 347 ---- filter_sandbox/scanner.l | 256 --- filter_sandbox/y.output | 303 ---- filter_sandbox/y.tab.c | 1687 ------------------- filter_sandbox/y.tab.h | 80 - filter_sandbox/tree.c => src/expression.c | 0 filter_sandbox/tree.h => src/expression.h | 0 src/zmap.c | 1229 +++++++------- {filter_sandbox => src}/zmap.l | 2 +- {filter_sandbox => src}/zmap.y | 9 +- 14 files changed, 609 insertions(+), 5128 deletions(-) delete mode 100644 filter_sandbox/.gitignore delete mode 100644 filter_sandbox/Makefile delete mode 100644 filter_sandbox/README delete mode 100644 filter_sandbox/lex.yy.c delete mode 100644 filter_sandbox/parser.y delete mode 100644 filter_sandbox/scanner.l delete mode 100644 filter_sandbox/y.output delete mode 100644 filter_sandbox/y.tab.c delete mode 100644 filter_sandbox/y.tab.h rename filter_sandbox/tree.c => src/expression.c (100%) rename filter_sandbox/tree.h => src/expression.h (100%) rename {filter_sandbox => src}/zmap.l (96%) rename {filter_sandbox => src}/zmap.y (97%) diff --git a/filter_sandbox/.gitignore b/filter_sandbox/.gitignore deleted file mode 100644 index 2883a20..0000000 --- a/filter_sandbox/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -.output -test diff --git a/filter_sandbox/Makefile b/filter_sandbox/Makefile deleted file mode 100644 index 243e279..0000000 --- a/filter_sandbox/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -all: - gcc -c tree.c -o tree.o - lex zmap.l - yacc -d --debug --verbose zmap.y - gcc tree.o lex.yy.c y.tab.c -o test - -clean: - rm *.o a.out test diff --git a/filter_sandbox/README b/filter_sandbox/README deleted file mode 100644 index 5f20d79..0000000 --- a/filter_sandbox/README +++ /dev/null @@ -1,7 +0,0 @@ -make - -./text - -Example Input: - -(ipaddr = 8 && herp = 6) || (field = value && yolo = swag) diff --git a/filter_sandbox/lex.yy.c b/filter_sandbox/lex.yy.c deleted file mode 100644 index 8c248d4..0000000 --- a/filter_sandbox/lex.yy.c +++ /dev/null @@ -1,1807 +0,0 @@ - -#line 3 "lex.yy.c" - -#define YY_INT_ALIGNED short int - -/* A lexical scanner generated by flex */ - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 35 -#if YY_FLEX_SUBMINOR_VERSION > 0 -#define FLEX_BETA -#endif - -/* First, we deal with platform-specific or compiler-specific issues. */ - -/* begin standard C headers. */ -#include -#include -#include -#include - -/* end standard C headers. */ - -/* flex integer type definitions */ - -#ifndef FLEXINT_H -#define FLEXINT_H - -/* C99 systems have . Non-C99 systems may or may not. */ - -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - -/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, - * if you want the limit (max/min) macros for int types. - */ -#ifndef __STDC_LIMIT_MACROS -#define __STDC_LIMIT_MACROS 1 -#endif - -#include -typedef int8_t flex_int8_t; -typedef uint8_t flex_uint8_t; -typedef int16_t flex_int16_t; -typedef uint16_t flex_uint16_t; -typedef int32_t flex_int32_t; -typedef uint32_t flex_uint32_t; -typedef uint64_t flex_uint64_t; -#else -typedef signed char flex_int8_t; -typedef short int flex_int16_t; -typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; -typedef unsigned short int flex_uint16_t; -typedef unsigned int flex_uint32_t; -#endif /* ! C99 */ - -/* Limits of integral types. */ -#ifndef INT8_MIN -#define INT8_MIN (-128) -#endif -#ifndef INT16_MIN -#define INT16_MIN (-32767-1) -#endif -#ifndef INT32_MIN -#define INT32_MIN (-2147483647-1) -#endif -#ifndef INT8_MAX -#define INT8_MAX (127) -#endif -#ifndef INT16_MAX -#define INT16_MAX (32767) -#endif -#ifndef INT32_MAX -#define INT32_MAX (2147483647) -#endif -#ifndef UINT8_MAX -#define UINT8_MAX (255U) -#endif -#ifndef UINT16_MAX -#define UINT16_MAX (65535U) -#endif -#ifndef UINT32_MAX -#define UINT32_MAX (4294967295U) -#endif - -#endif /* ! FLEXINT_H */ - -#ifdef __cplusplus - -/* The "const" storage-class-modifier is valid. */ -#define YY_USE_CONST - -#else /* ! __cplusplus */ - -/* C99 requires __STDC__ to be defined as 1. */ -#if defined (__STDC__) - -#define YY_USE_CONST - -#endif /* defined (__STDC__) */ -#endif /* ! __cplusplus */ - -#ifdef YY_USE_CONST -#define yyconst const -#else -#define yyconst -#endif - -/* Returned upon end-of-file. */ -#define YY_NULL 0 - -/* Promotes a possibly negative, possibly signed char to an unsigned - * integer for use as an array index. If the signed char is negative, - * we want to instead treat it as an 8-bit unsigned char, hence the - * double cast. - */ -#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) - -/* Enter a start condition. This macro really ought to take a parameter, - * but we do it the disgusting crufty way forced on us by the ()-less - * definition of BEGIN. - */ -#define BEGIN (yy_start) = 1 + 2 * - -/* Translate the current start state into a value that can be later handed - * to BEGIN to return to the state. The YYSTATE alias is for lex - * compatibility. - */ -#define YY_START (((yy_start) - 1) / 2) -#define YYSTATE YY_START - -/* Action number for EOF rule of a given start state. */ -#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) - -/* Special action meaning "start processing a new file". */ -#define YY_NEW_FILE yyrestart(yyin ) - -#define YY_END_OF_BUFFER_CHAR 0 - -/* Size of default input buffer. */ -#ifndef YY_BUF_SIZE -#define YY_BUF_SIZE 16384 -#endif - -/* The state buf must be large enough to hold one state per character in the main buffer. - */ -#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) - -#ifndef YY_TYPEDEF_YY_BUFFER_STATE -#define YY_TYPEDEF_YY_BUFFER_STATE -typedef struct yy_buffer_state *YY_BUFFER_STATE; -#endif - -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif - -extern yy_size_t yyleng; - -extern FILE *yyin, *yyout; - -#define EOB_ACT_CONTINUE_SCAN 0 -#define EOB_ACT_END_OF_FILE 1 -#define EOB_ACT_LAST_MATCH 2 - - #define YY_LESS_LINENO(n) - -/* Return all but the first "n" matched characters back to the input stream. */ -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - *yy_cp = (yy_hold_char); \ - YY_RESTORE_YY_MORE_OFFSET \ - (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) - -#define unput(c) yyunput( c, (yytext_ptr) ) - -#ifndef YY_STRUCT_YY_BUFFER_STATE -#define YY_STRUCT_YY_BUFFER_STATE -struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - yy_size_t yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - yy_size_t yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - int yy_bs_lineno; /**< The line count. */ - int yy_bs_column; /**< The column count. */ - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; - -#define YY_BUFFER_NEW 0 -#define YY_BUFFER_NORMAL 1 - /* When an EOF's been seen but there's still some text to process - * then we mark the buffer as YY_EOF_PENDING, to indicate that we - * shouldn't try reading from the input source any more. We might - * still have a bunch of tokens to match, though, because of - * possible backing-up. - * - * When we actually see the EOF, we change the status to "new" - * (via yyrestart()), so that the user can continue scanning by - * just pointing yyin at a new input file. - */ -#define YY_BUFFER_EOF_PENDING 2 - - }; -#endif /* !YY_STRUCT_YY_BUFFER_STATE */ - -/* Stack of input buffers. */ -static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ -static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ -static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ - -/* We provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general - * "scanner state". - * - * Returns the top of the stack, or NULL. - */ -#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ - ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ - : NULL) - -/* Same as previous macro, but useful when we know that the buffer stack is not - * NULL or when we need an lvalue. For internal use only. - */ -#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] - -/* yy_hold_char holds the character lost when yytext is formed. */ -static char yy_hold_char; -static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */ -yy_size_t yyleng; - -/* Points to current character in buffer. */ -static char *yy_c_buf_p = (char *) 0; -static int yy_init = 0; /* whether we need to initialize */ -static int yy_start = 0; /* start state number */ - -/* Flag which is used to allow yywrap()'s to do buffer switches - * instead of setting up a fresh yyin. A bit of a hack ... - */ -static int yy_did_buffer_switch_on_eof; - -void yyrestart (FILE *input_file ); -void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); -YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); -void yy_delete_buffer (YY_BUFFER_STATE b ); -void yy_flush_buffer (YY_BUFFER_STATE b ); -void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); -void yypop_buffer_state (void ); - -static void yyensure_buffer_stack (void ); -static void yy_load_buffer_state (void ); -static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); - -#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) - -YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); -YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); -YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ); - -void *yyalloc (yy_size_t ); -void *yyrealloc (void *,yy_size_t ); -void yyfree (void * ); - -#define yy_new_buffer yy_create_buffer - -#define yy_set_interactive(is_interactive) \ - { \ - if ( ! YY_CURRENT_BUFFER ){ \ - yyensure_buffer_stack (); \ - YY_CURRENT_BUFFER_LVALUE = \ - yy_create_buffer(yyin,YY_BUF_SIZE ); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ - } - -#define yy_set_bol(at_bol) \ - { \ - if ( ! YY_CURRENT_BUFFER ){\ - yyensure_buffer_stack (); \ - YY_CURRENT_BUFFER_LVALUE = \ - yy_create_buffer(yyin,YY_BUF_SIZE ); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ - } - -#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) - -/* Begin user sect3 */ - -typedef unsigned char YY_CHAR; - -FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; - -typedef int yy_state_type; - -extern int yylineno; - -int yylineno = 1; - -extern char *yytext; -#define yytext_ptr yytext - -static yy_state_type yy_get_previous_state (void ); -static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); -static int yy_get_next_buffer (void ); -static void yy_fatal_error (yyconst char msg[] ); - -/* Done after the current pattern has been matched and before the - * corresponding action - sets up yytext. - */ -#define YY_DO_BEFORE_ACTION \ - (yytext_ptr) = yy_bp; \ - yyleng = (yy_size_t) (yy_cp - yy_bp); \ - (yy_hold_char) = *yy_cp; \ - *yy_cp = '\0'; \ - (yy_c_buf_p) = yy_cp; - -#define YY_NUM_RULES 15 -#define YY_END_OF_BUFFER 16 -/* This struct is not used in this scanner, - but its presence is necessary. */ -struct yy_trans_info - { - flex_int32_t yy_verify; - flex_int32_t yy_nxt; - }; -static yyconst flex_int16_t yy_accept[26] = - { 0, - 0, 0, 16, 15, 3, 2, 15, 15, 12, 13, - 1, 11, 9, 10, 15, 15, 3, 4, 7, 1, - 6, 5, 14, 8, 0 - } ; - -static yyconst flex_int32_t yy_ec[256] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 4, 1, 1, 1, 1, 5, 1, 6, - 7, 1, 1, 1, 1, 1, 1, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 1, 1, 9, - 10, 11, 1, 1, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 1, 1, 1, 1, 1, 1, 12, 12, 12, 12, - - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 1, 13, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 - } ; - -static yyconst flex_int32_t yy_meta[14] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, - 1, 2, 1 - } ; - -static yyconst flex_int16_t yy_base[27] = - { 0, - 0, 0, 24, 25, 21, 25, 12, 16, 25, 25, - 12, 9, 25, 8, 0, 4, 14, 25, 25, 7, - 25, 25, 0, 25, 25, 12 - } ; - -static yyconst flex_int16_t yy_def[27] = - { 0, - 25, 1, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 26, 25, 25, 25, 25, 25, - 25, 25, 26, 25, 0, 25 - } ; - -static yyconst flex_int16_t yy_nxt[39] = - { 0, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 23, 20, 17, 24, 22, 21, 20, - 19, 18, 17, 25, 3, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25 - } ; - -static yyconst flex_int16_t yy_chk[39] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 26, 20, 17, 16, 14, 12, 11, - 8, 7, 5, 3, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25 - } ; - -static yy_state_type yy_last_accepting_state; -static char *yy_last_accepting_cpos; - -extern int yy_flex_debug; -int yy_flex_debug = 0; - -/* The intent behind this definition is that it'll catch - * any uses of REJECT which flex missed. - */ -#define REJECT reject_used_but_not_detected -#define yymore() yymore_used_but_not_detected -#define YY_MORE_ADJ 0 -#define YY_RESTORE_YY_MORE_OFFSET -char *yytext; -#line 1 "zmap.l" -#line 2 "zmap.l" -#include -#include "y.tab.h" -#line 466 "lex.yy.c" - -#define INITIAL 0 - -#ifndef YY_NO_UNISTD_H -/* Special case for "unistd.h", since it is non-ANSI. We include it way - * down here because we want the user's section 1 to have been scanned first. - * The user has a chance to override it with an option. - */ -#include -#endif - -#ifndef YY_EXTRA_TYPE -#define YY_EXTRA_TYPE void * -#endif - -static int yy_init_globals (void ); - -/* Accessor methods to globals. - These are made visible to non-reentrant scanners for convenience. */ - -int yylex_destroy (void ); - -int yyget_debug (void ); - -void yyset_debug (int debug_flag ); - -YY_EXTRA_TYPE yyget_extra (void ); - -void yyset_extra (YY_EXTRA_TYPE user_defined ); - -FILE *yyget_in (void ); - -void yyset_in (FILE * in_str ); - -FILE *yyget_out (void ); - -void yyset_out (FILE * out_str ); - -yy_size_t yyget_leng (void ); - -char *yyget_text (void ); - -int yyget_lineno (void ); - -void yyset_lineno (int line_number ); - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int yywrap (void ); -#else -extern int yywrap (void ); -#endif -#endif - - static void yyunput (int c,char *buf_ptr ); - -#ifndef yytext_ptr -static void yy_flex_strncpy (char *,yyconst char *,int ); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * ); -#endif - -#ifndef YY_NO_INPUT - -#ifdef __cplusplus -static int yyinput (void ); -#else -static int input (void ); -#endif - -#endif - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#define YY_READ_BUF_SIZE 8192 -#endif - -/* Copy whatever the last rule matched to the standard output. */ -#ifndef ECHO -/* This used to be an fputs(), but since the string might contain NUL's, - * we now use fwrite(). - */ -#define ECHO fwrite( yytext, yyleng, 1, yyout ) -#endif - -/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, - * is returned in "result". - */ -#ifndef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ - { \ - int c = '*'; \ - yy_size_t n; \ - for ( n = 0; n < max_size && \ - (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ - buf[n] = (char) c; \ - if ( c == '\n' ) \ - buf[n++] = (char) c; \ - if ( c == EOF && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - result = n; \ - } \ - else \ - { \ - errno=0; \ - while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ - { \ - if( errno != EINTR) \ - { \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - break; \ - } \ - errno=0; \ - clearerr(yyin); \ - } \ - }\ -\ - -#endif - -/* No semi-colon after return; correct usage is to write "yyterminate();" - - * we don't want an extra ';' after the "return" because that will cause - * some compilers to complain about unreachable statements. - */ -#ifndef yyterminate -#define yyterminate() return YY_NULL -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Report a fatal error. */ -#ifndef YY_FATAL_ERROR -#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) -#endif - -/* end tables serialization structures and prototypes */ - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL_IS_OURS 1 - -extern int yylex (void); - -#define YY_DECL int yylex (void) -#endif /* !YY_DECL */ - -/* Code executed at the beginning of each rule, after yytext and yyleng - * have been set up. - */ -#ifndef YY_USER_ACTION -#define YY_USER_ACTION -#endif - -/* Code executed at the end of each rule. */ -#ifndef YY_BREAK -#define YY_BREAK break; -#endif - -#define YY_RULE_SETUP \ - YY_USER_ACTION - -/** The main scanner function which does all the work. - */ -YY_DECL -{ - register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; - register int yy_act; - -#line 6 "zmap.l" - -#line 650 "lex.yy.c" - - if ( !(yy_init) ) - { - (yy_init) = 1; - -#ifdef YY_USER_INIT - YY_USER_INIT; -#endif - - if ( ! (yy_start) ) - (yy_start) = 1; /* first start state */ - - if ( ! yyin ) - yyin = stdin; - - if ( ! yyout ) - yyout = stdout; - - if ( ! YY_CURRENT_BUFFER ) { - yyensure_buffer_stack (); - YY_CURRENT_BUFFER_LVALUE = - yy_create_buffer(yyin,YY_BUF_SIZE ); - } - - yy_load_buffer_state( ); - } - - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = (yy_c_buf_p); - - /* Support of yytext. */ - *yy_cp = (yy_hold_char); - - /* yy_bp points to the position in yy_ch_buf of the start of - * the current run. - */ - yy_bp = yy_cp; - - yy_current_state = (yy_start); -yy_match: - do - { - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; - (yy_last_accepting_cpos) = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 26 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - ++yy_cp; - } - while ( yy_base[yy_current_state] != 25 ); - -yy_find_action: - yy_act = yy_accept[yy_current_state]; - if ( yy_act == 0 ) - { /* have to back up */ - yy_cp = (yy_last_accepting_cpos); - yy_current_state = (yy_last_accepting_state); - yy_act = yy_accept[yy_current_state]; - } - - YY_DO_BEFORE_ACTION; - -do_action: /* This label is used only to access EOF actions. */ - - switch ( yy_act ) - { /* beginning of action switch */ - case 0: /* must back up */ - /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = (yy_hold_char); - yy_cp = (yy_last_accepting_cpos); - yy_current_state = (yy_last_accepting_state); - goto yy_find_action; - -case 1: -YY_RULE_SETUP -#line 7 "zmap.l" -yylval.int_literal = atoi(yytext); return T_NUMBER; - YY_BREAK -case 2: -/* rule 2 can match eol */ -YY_RULE_SETUP -#line 8 "zmap.l" -/* Ignore end of line */ - YY_BREAK -case 3: -YY_RULE_SETUP -#line 9 "zmap.l" -/* Ignore whitespace */ - YY_BREAK -case 4: -YY_RULE_SETUP -#line 10 "zmap.l" -return T_NOT_EQ; - YY_BREAK -case 5: -YY_RULE_SETUP -#line 11 "zmap.l" -return T_GT_EQ; - YY_BREAK -case 6: -YY_RULE_SETUP -#line 12 "zmap.l" -return T_LT_EQ; - YY_BREAK -case 7: -YY_RULE_SETUP -#line 13 "zmap.l" -return T_AND; - YY_BREAK -case 8: -YY_RULE_SETUP -#line 14 "zmap.l" -return T_OR; - YY_BREAK -case 9: -YY_RULE_SETUP -#line 15 "zmap.l" -return '='; - YY_BREAK -case 10: -YY_RULE_SETUP -#line 16 "zmap.l" -return '>'; - YY_BREAK -case 11: -YY_RULE_SETUP -#line 17 "zmap.l" -return '<'; - YY_BREAK -case 12: -YY_RULE_SETUP -#line 18 "zmap.l" -return '('; - YY_BREAK -case 13: -YY_RULE_SETUP -#line 19 "zmap.l" -return ')'; - YY_BREAK -case 14: -YY_RULE_SETUP -#line 20 "zmap.l" -yylval.string_literal = strdup(yytext); return T_FIELD; - YY_BREAK -case 15: -YY_RULE_SETUP -#line 22 "zmap.l" -ECHO; - YY_BREAK -#line 809 "lex.yy.c" -case YY_STATE_EOF(INITIAL): - yyterminate(); - - case YY_END_OF_BUFFER: - { - /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; - - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = (yy_hold_char); - YY_RESTORE_YY_MORE_OFFSET - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) - { - /* We're scanning a new file or input source. It's - * possible that this happened because the user - * just pointed yyin at a new source and called - * yylex(). If so, then we have to assure - * consistency between YY_CURRENT_BUFFER and our - * globals. Here is the right place to do so, because - * this is the first action (other than possibly a - * back-up) that will match for the new input source. - */ - (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; - } - - /* Note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the - * end-of-buffer state). Contrast this with the test - * in input(). - */ - if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) - { /* This was really a NUL. */ - yy_state_type yy_next_state; - - (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( ); - - /* Okay, we're now positioned to make the NUL - * transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we don't - * want to build jamming into it because then it - * will run more slowly). - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state ); - - yy_bp = (yytext_ptr) + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* Consume the NUL. */ - yy_cp = ++(yy_c_buf_p); - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { - yy_cp = (yy_c_buf_p); - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer( ) ) - { - case EOB_ACT_END_OF_FILE: - { - (yy_did_buffer_switch_on_eof) = 0; - - if ( yywrap( ) ) - { - /* Note: because we've taken care in - * yy_get_next_buffer() to have set up - * yytext, we can now set up - * yy_c_buf_p so that if some total - * hoser (like flex itself) wants to - * call the scanner after we return the - * YY_NULL, it'll still work - another - * YY_NULL will get returned. - */ - (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF(YY_START); - goto do_action; - } - - else - { - if ( ! (yy_did_buffer_switch_on_eof) ) - YY_NEW_FILE; - } - break; - } - - case EOB_ACT_CONTINUE_SCAN: - (yy_c_buf_p) = - (yytext_ptr) + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( ); - - yy_cp = (yy_c_buf_p); - yy_bp = (yytext_ptr) + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - (yy_c_buf_p) = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; - - yy_current_state = yy_get_previous_state( ); - - yy_cp = (yy_c_buf_p); - yy_bp = (yytext_ptr) + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ -} /* end of yylex */ - -/* yy_get_next_buffer - try to read in a new buffer - * - * Returns a code representing an action: - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file - */ -static int yy_get_next_buffer (void) -{ - register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; - register char *source = (yytext_ptr); - register int number_to_move, i; - int ret_val; - - if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ - if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) - { - /* We matched a single character, the EOB, so - * treat this as a final EOF. - */ - return EOB_ACT_END_OF_FILE; - } - - else - { - /* We matched some text prior to the EOB, first - * process it. - */ - return EOB_ACT_LAST_MATCH; - } - } - - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ - number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; - - else - { - yy_size_t num_to_read = - YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ - - /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = YY_CURRENT_BUFFER; - - int yy_c_buf_p_offset = - (int) ((yy_c_buf_p) - b->yy_ch_buf); - - if ( b->yy_is_our_buffer ) - { - yy_size_t new_size = b->yy_buf_size * 2; - - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; - else - b->yy_buf_size *= 2; - - b->yy_ch_buf = (char *) - /* Include room in for 2 EOB chars. */ - yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); - } - else - /* Can't grow it, we don't own it. */ - b->yy_ch_buf = 0; - - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( - "fatal error - scanner input buffer overflow" ); - - (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; - - num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - - number_to_move - 1; - - } - - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; - - /* Read in more data. */ - YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - (yy_n_chars), num_to_read ); - - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } - - if ( (yy_n_chars) == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; - yyrestart(yyin ); - } - - else - { - ret_val = EOB_ACT_LAST_MATCH; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } - } - - else - ret_val = EOB_ACT_CONTINUE_SCAN; - - if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { - /* Extend the array by 50%, plus the number we really need. */ - yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); - if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); - } - - (yy_n_chars) += number_to_move; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; - - (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; - - return ret_val; -} - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - - static yy_state_type yy_get_previous_state (void) -{ - register yy_state_type yy_current_state; - register char *yy_cp; - - yy_current_state = (yy_start); - - for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) - { - register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; - (yy_last_accepting_cpos) = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 26 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - } - - return yy_current_state; -} - -/* yy_try_NUL_trans - try to make a transition on the NUL character - * - * synopsis - * next_state = yy_try_NUL_trans( current_state ); - */ - static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) -{ - register int yy_is_jam; - register char *yy_cp = (yy_c_buf_p); - - register YY_CHAR yy_c = 1; - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; - (yy_last_accepting_cpos) = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 26 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 25); - - return yy_is_jam ? 0 : yy_current_state; -} - - static void yyunput (int c, register char * yy_bp ) -{ - register char *yy_cp; - - yy_cp = (yy_c_buf_p); - - /* undo effects of setting up yytext */ - *yy_cp = (yy_hold_char); - - if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) - { /* need to shift things up to make room */ - /* +2 for EOB chars. */ - register yy_size_t number_to_move = (yy_n_chars) + 2; - register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ - YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; - register char *source = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; - - while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - *--dest = *--source; - - yy_cp += (int) (dest - source); - yy_bp += (int) (dest - source); - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = - (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; - - if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) - YY_FATAL_ERROR( "flex scanner push-back overflow" ); - } - - *--yy_cp = (char) c; - - (yytext_ptr) = yy_bp; - (yy_hold_char) = *yy_cp; - (yy_c_buf_p) = yy_cp; -} - -#ifndef YY_NO_INPUT -#ifdef __cplusplus - static int yyinput (void) -#else - static int input (void) -#endif - -{ - int c; - - *(yy_c_buf_p) = (yy_hold_char); - - if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ - if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) - /* This was really a NUL. */ - *(yy_c_buf_p) = '\0'; - - else - { /* need more input */ - yy_size_t offset = (yy_c_buf_p) - (yytext_ptr); - ++(yy_c_buf_p); - - switch ( yy_get_next_buffer( ) ) - { - case EOB_ACT_LAST_MATCH: - /* This happens because yy_g_n_b() - * sees that we've accumulated a - * token and flags that we need to - * try matching the token before - * proceeding. But for input(), - * there's no matching to consider. - * So convert the EOB_ACT_LAST_MATCH - * to EOB_ACT_END_OF_FILE. - */ - - /* Reset buffer status. */ - yyrestart(yyin ); - - /*FALLTHROUGH*/ - - case EOB_ACT_END_OF_FILE: - { - if ( yywrap( ) ) - return 0; - - if ( ! (yy_did_buffer_switch_on_eof) ) - YY_NEW_FILE; -#ifdef __cplusplus - return yyinput(); -#else - return input(); -#endif - } - - case EOB_ACT_CONTINUE_SCAN: - (yy_c_buf_p) = (yytext_ptr) + offset; - break; - } - } - } - - c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ - *(yy_c_buf_p) = '\0'; /* preserve yytext */ - (yy_hold_char) = *++(yy_c_buf_p); - - return c; -} -#endif /* ifndef YY_NO_INPUT */ - -/** Immediately switch to a different input stream. - * @param input_file A readable stream. - * - * @note This function does not reset the start condition to @c INITIAL . - */ - void yyrestart (FILE * input_file ) -{ - - if ( ! YY_CURRENT_BUFFER ){ - yyensure_buffer_stack (); - YY_CURRENT_BUFFER_LVALUE = - yy_create_buffer(yyin,YY_BUF_SIZE ); - } - - yy_init_buffer(YY_CURRENT_BUFFER,input_file ); - yy_load_buffer_state( ); -} - -/** Switch to a different input buffer. - * @param new_buffer The new input buffer. - * - */ - void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) -{ - - /* TODO. We should be able to replace this entire function body - * with - * yypop_buffer_state(); - * yypush_buffer_state(new_buffer); - */ - yyensure_buffer_stack (); - if ( YY_CURRENT_BUFFER == new_buffer ) - return; - - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *(yy_c_buf_p) = (yy_hold_char); - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } - - YY_CURRENT_BUFFER_LVALUE = new_buffer; - yy_load_buffer_state( ); - - /* We don't actually know whether we did this switch during - * EOF (yywrap()) processing, but the only time this flag - * is looked at is after yywrap() is called, so it's safe - * to go ahead and always set it. - */ - (yy_did_buffer_switch_on_eof) = 1; -} - -static void yy_load_buffer_state (void) -{ - (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; - yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; - (yy_hold_char) = *(yy_c_buf_p); -} - -/** Allocate and initialize an input buffer state. - * @param file A readable stream. - * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. - * - * @return the allocated buffer state. - */ - YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) -{ - YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_buf_size = size; - - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_is_our_buffer = 1; - - yy_init_buffer(b,file ); - - return b; -} - -/** Destroy the buffer. - * @param b a buffer created with yy_create_buffer() - * - */ - void yy_delete_buffer (YY_BUFFER_STATE b ) -{ - - if ( ! b ) - return; - - if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ - YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; - - if ( b->yy_is_our_buffer ) - yyfree((void *) b->yy_ch_buf ); - - yyfree((void *) b ); -} - -#ifndef __cplusplus -extern int isatty (int ); -#endif /* __cplusplus */ - -/* Initializes or reinitializes a buffer. - * This function is sometimes called more than once on the same buffer, - * such as during a yyrestart() or at EOF. - */ - static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) - -{ - int oerrno = errno; - - yy_flush_buffer(b ); - - b->yy_input_file = file; - b->yy_fill_buffer = 1; - - /* If b is the current buffer, then yy_init_buffer was _probably_ - * called from yyrestart() or through yy_get_next_buffer. - * In that case, we don't want to reset the lineno or column. - */ - if (b != YY_CURRENT_BUFFER){ - b->yy_bs_lineno = 1; - b->yy_bs_column = 0; - } - - b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; - - errno = oerrno; -} - -/** Discard all buffered characters. On the next scan, YY_INPUT will be called. - * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. - * - */ - void yy_flush_buffer (YY_BUFFER_STATE b ) -{ - if ( ! b ) - return; - - b->yy_n_chars = 0; - - /* We always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - - b->yy_buf_pos = &b->yy_ch_buf[0]; - - b->yy_at_bol = 1; - b->yy_buffer_status = YY_BUFFER_NEW; - - if ( b == YY_CURRENT_BUFFER ) - yy_load_buffer_state( ); -} - -/** Pushes the new state onto the stack. The new state becomes - * the current state. This function will allocate the stack - * if necessary. - * @param new_buffer The new state. - * - */ -void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) -{ - if (new_buffer == NULL) - return; - - yyensure_buffer_stack(); - - /* This block is copied from yy_switch_to_buffer. */ - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *(yy_c_buf_p) = (yy_hold_char); - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } - - /* Only push if top exists. Otherwise, replace top. */ - if (YY_CURRENT_BUFFER) - (yy_buffer_stack_top)++; - YY_CURRENT_BUFFER_LVALUE = new_buffer; - - /* copied from yy_switch_to_buffer. */ - yy_load_buffer_state( ); - (yy_did_buffer_switch_on_eof) = 1; -} - -/** Removes and deletes the top of the stack, if present. - * The next element becomes the new top. - * - */ -void yypop_buffer_state (void) -{ - if (!YY_CURRENT_BUFFER) - return; - - yy_delete_buffer(YY_CURRENT_BUFFER ); - YY_CURRENT_BUFFER_LVALUE = NULL; - if ((yy_buffer_stack_top) > 0) - --(yy_buffer_stack_top); - - if (YY_CURRENT_BUFFER) { - yy_load_buffer_state( ); - (yy_did_buffer_switch_on_eof) = 1; - } -} - -/* Allocates the stack if it does not exist. - * Guarantees space for at least one push. - */ -static void yyensure_buffer_stack (void) -{ - yy_size_t num_to_alloc; - - if (!(yy_buffer_stack)) { - - /* First allocation is just for 2 elements, since we don't know if this - * scanner will even need a stack. We use 2 instead of 1 to avoid an - * immediate realloc on the next call. - */ - num_to_alloc = 1; - (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc - (num_to_alloc * sizeof(struct yy_buffer_state*) - ); - if ( ! (yy_buffer_stack) ) - YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); - - memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); - - (yy_buffer_stack_max) = num_to_alloc; - (yy_buffer_stack_top) = 0; - return; - } - - if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ - - /* Increase the buffer to prepare for a possible push. */ - int grow_size = 8 /* arbitrary grow size */; - - num_to_alloc = (yy_buffer_stack_max) + grow_size; - (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc - ((yy_buffer_stack), - num_to_alloc * sizeof(struct yy_buffer_state*) - ); - if ( ! (yy_buffer_stack) ) - YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); - - /* zero only the new slots.*/ - memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); - (yy_buffer_stack_max) = num_to_alloc; - } -} - -/** Setup the input buffer state to scan directly from a user-specified character buffer. - * @param base the character buffer - * @param size the size in bytes of the character buffer - * - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) -{ - YY_BUFFER_STATE b; - - if ( size < 2 || - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) - /* They forgot to leave room for the EOB's. */ - return 0; - - b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); - - b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ - b->yy_buf_pos = b->yy_ch_buf = base; - b->yy_is_our_buffer = 0; - b->yy_input_file = 0; - b->yy_n_chars = b->yy_buf_size; - b->yy_is_interactive = 0; - b->yy_at_bol = 1; - b->yy_fill_buffer = 0; - b->yy_buffer_status = YY_BUFFER_NEW; - - yy_switch_to_buffer(b ); - - return b; -} - -/** Setup the input buffer state to scan a string. The next call to yylex() will - * scan from a @e copy of @a str. - * @param yystr a NUL-terminated string to scan - * - * @return the newly allocated buffer state object. - * @note If you want to scan bytes that may contain NUL values, then use - * yy_scan_bytes() instead. - */ -YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) -{ - - return yy_scan_bytes(yystr,strlen(yystr) ); -} - -/** Setup the input buffer state to scan the given bytes. The next call to yylex() will - * scan from a @e copy of @a bytes. - * @param bytes the byte buffer to scan - * @param len the number of bytes in the buffer pointed to by @a bytes. - * - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len ) -{ - YY_BUFFER_STATE b; - char *buf; - yy_size_t n, i; - - /* Get memory for full buffer, including space for trailing EOB's. */ - n = _yybytes_len + 2; - buf = (char *) yyalloc(n ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); - - for ( i = 0; i < _yybytes_len; ++i ) - buf[i] = yybytes[i]; - - buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; - - b = yy_scan_buffer(buf,n ); - if ( ! b ) - YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); - - /* It's okay to grow etc. this buffer, and we should throw it - * away when we're done. - */ - b->yy_is_our_buffer = 1; - - return b; -} - -#ifndef YY_EXIT_FAILURE -#define YY_EXIT_FAILURE 2 -#endif - -static void yy_fatal_error (yyconst char* msg ) -{ - (void) fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); -} - -/* Redefine yyless() so it works in section 3 code. */ - -#undef yyless -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - yytext[yyleng] = (yy_hold_char); \ - (yy_c_buf_p) = yytext + yyless_macro_arg; \ - (yy_hold_char) = *(yy_c_buf_p); \ - *(yy_c_buf_p) = '\0'; \ - yyleng = yyless_macro_arg; \ - } \ - while ( 0 ) - -/* Accessor methods (get/set functions) to struct members. */ - -/** Get the current line number. - * - */ -int yyget_lineno (void) -{ - - return yylineno; -} - -/** Get the input stream. - * - */ -FILE *yyget_in (void) -{ - return yyin; -} - -/** Get the output stream. - * - */ -FILE *yyget_out (void) -{ - return yyout; -} - -/** Get the length of the current token. - * - */ -yy_size_t yyget_leng (void) -{ - return yyleng; -} - -/** Get the current token. - * - */ - -char *yyget_text (void) -{ - return yytext; -} - -/** Set the current line number. - * @param line_number - * - */ -void yyset_lineno (int line_number ) -{ - - yylineno = line_number; -} - -/** Set the input stream. This does not discard the current - * input buffer. - * @param in_str A readable stream. - * - * @see yy_switch_to_buffer - */ -void yyset_in (FILE * in_str ) -{ - yyin = in_str ; -} - -void yyset_out (FILE * out_str ) -{ - yyout = out_str ; -} - -int yyget_debug (void) -{ - return yy_flex_debug; -} - -void yyset_debug (int bdebug ) -{ - yy_flex_debug = bdebug ; -} - -static int yy_init_globals (void) -{ - /* Initialization is the same as for the non-reentrant scanner. - * This function is called from yylex_destroy(), so don't allocate here. - */ - - (yy_buffer_stack) = 0; - (yy_buffer_stack_top) = 0; - (yy_buffer_stack_max) = 0; - (yy_c_buf_p) = (char *) 0; - (yy_init) = 0; - (yy_start) = 0; - -/* Defined in main.c */ -#ifdef YY_STDINIT - yyin = stdin; - yyout = stdout; -#else - yyin = (FILE *) 0; - yyout = (FILE *) 0; -#endif - - /* For future reference: Set errno on error, since we are called by - * yylex_init() - */ - return 0; -} - -/* yylex_destroy is for both reentrant and non-reentrant scanners. */ -int yylex_destroy (void) -{ - - /* Pop the buffer stack, destroying each element. */ - while(YY_CURRENT_BUFFER){ - yy_delete_buffer(YY_CURRENT_BUFFER ); - YY_CURRENT_BUFFER_LVALUE = NULL; - yypop_buffer_state(); - } - - /* Destroy the stack itself. */ - yyfree((yy_buffer_stack) ); - (yy_buffer_stack) = NULL; - - /* Reset the globals. This is important in a non-reentrant scanner so the next time - * yylex() is called, initialization will occur. */ - yy_init_globals( ); - - return 0; -} - -/* - * Internal utility routines. - */ - -#ifndef yytext_ptr -static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) -{ - register int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; -} -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * s ) -{ - register int n; - for ( n = 0; s[n]; ++n ) - ; - - return n; -} -#endif - -void *yyalloc (yy_size_t size ) -{ - return (void *) malloc( size ); -} - -void *yyrealloc (void * ptr, yy_size_t size ) -{ - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter - * because both ANSI C and C++ allow castless assignment from - * any pointer type to void*, and deal with argument conversions - * as though doing an assignment. - */ - return (void *) realloc( (char *) ptr, size ); -} - -void yyfree (void * ptr ) -{ - free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ -} - -#define YYTABLES_NAME "yytables" - -#line 22 "zmap.l" - - diff --git a/filter_sandbox/parser.y b/filter_sandbox/parser.y deleted file mode 100644 index 15cc097..0000000 --- a/filter_sandbox/parser.y +++ /dev/null @@ -1,347 +0,0 @@ -/* File: parser.y - * -------------- - * Yacc input file to generate the parser for the compiler. - * - * pp2: your job is to write a parser that will construct the parse tree - * and if no parse errors were found, print it. The parser should - * accept the language as described in specification, and as augmented - * in the pp2 handout. - */ - -%{ - - /* Just like lex, the text within this first region delimited by %{ and %} - * is assumed to be C/C++ code and will be copied verbatim to the y.tab.c - * file ahead of the definitions of the yyparse() function. Add other header - * file inclusions or C++ variable declarations/prototypes that are needed - * by your code here. - */ -#include "scanner.h" // for yylex -#include "parser.h" -#include "errors.h" -#include - using namespace std; - void yyerror(const char *msg); // standard error-handling routine - -%} - - /* The section before the first %% is the Definitions section of the yacc - * input file. Here is where you declare tokens and types, add precedence - * and associativity options, and so on. - */ - - /* yylval - * ------ - * Here we define the type of the yylval global variable that is used by - * the scanner to store attibute information about the token just scanned - * and thus communicate that information to the parser. - * - * pp2: You will need to add new fields to this union as you add different - * attributes to your non-terminal symbols. - */ - %union { - int integerConstant; - bool boolConstant; - char *stringConstant; - double doubleConstant; - char identifier[MaxIdentLen+1]; // +1 for terminating null - Decl *decl; - VarDecl *varDecl; - Case *caseNode; - Default *defaultNode; - List *declList; - Stmt *stmt; - List *stmtList; - List *varDeclList; -List *caseList; - Expr *expr; - Type *type; - List *exprList; - List *typeList; - } - -/* Tokens - * ------ - * Here we tell yacc about all the token types that we are using. - * Yacc will assign unique numbers to these and export the #define - * in the generated y.tab.h header file. - */ -%token T_Void T_Bool T_Int T_Double T_String T_Class -%token T_LessEqual T_GreaterEqual T_Equal T_NotEqual T_Dims -%token T_And T_Or T_Null T_Extends T_This T_Interface T_Implements -%token T_While T_For T_If T_Else T_Return T_Break -%token T_New T_NewArray T_Print T_ReadInteger T_ReadLine - -%token T_Identifier -%token T_StringConstant -%token T_IntConstant -%token T_DoubleConstant -%token T_BoolConstant - -%token T_Increm T_Decrem T_Switch T_Case T_Default - -%nonassoc NON_ELSE -%nonassoc T_Else -%nonassoc '=' -%left T_Or -%left T_And -%left T_Equal T_NotEqual -%nonassoc '<' T_LessEqual T_GreaterEqual '>' -%left '+' '-' -%left '*' '/' '%' -%left NEG '!' INCRDECR -%left '[' '.' - -/* Non-terminal types - * ------------------ - * In order for yacc to assign/access the correct field of $$, $1, we - * must to declare which field is appropriate for the non-terminal. - * As an example, this first type declaration establishes that the DeclList - * non-terminal uses the field named "declList" in the yylval union. This - * means that when we are setting $$ for a reduction for DeclList ore reading - * $n which corresponds to a DeclList nonterminal we are accessing the field - * of the union named "declList" which is of type List. - * pp2: You'll need to add many of these of your own. - */ -%type DeclList -%type VarDeclList -%type Formals -%type Decl -%type FnDecl -%type VarDecl -%type Variable -%type Stmt -%type WhileStmt -%type IfStmt -%type ForStmt -%type BreakStmt -%type ReturnStmt -%type PrintStmt -%type StmtBlock -%type StmtList -%type Expr -%type EmptyExpr -%type Type -%type Field -%type FieldList -%type ClassDecl -%type InterfaceDecl -%type InterfaceList -%type Prototype -%type PrototypeList -%type ExprList -%type Actuals -%type LValue -%type Constant -%type Call -%type SwitchStmt -%type CaseList -%type Case -%type Default - -%% -/* Rules - * ----- - * All productions and actions should be placed between the start and stop - * %% markers which delimit the Rules section. - - */ -Program : DeclList { - Program *program = new Program($1); - // if no errors, advance to next phase - if (ReportError::NumErrors() == 0) - program->Print(0); - } -; - -DeclList : DeclList Decl { ($$=$1)->Append($2); } -| Decl { ($$ = new List)->Append($1); } -; - -Decl : VarDecl { $$ = $1; } -| FnDecl {$$ = $1;} -| ClassDecl {$$ = $1;} -| InterfaceDecl {$$ = $1;} -; - -VarDeclList : VarDeclList VarDecl { ($$=$1)->Append($2); } -| VarDecl { ($$ = new List)->Append($1); } -; - -VarDecl : Variable ';' {$$ = $1;}; - -Variable : Type T_Identifier {$$ = new VarDecl(new Identifier(@2, $2), $1); }; - -ClassDecl : T_Class T_Identifier '{' FieldList '}' {$$ = new ClassDecl(new Identifier(@2, $2), 0, new List, $4);} -| T_Class T_Identifier T_Extends T_Identifier '{' FieldList '}' {$$ = new ClassDecl(new Identifier(@2, $2), new NamedType(new Identifier(@4, $4)), new List, $6);} - | T_Class T_Identifier T_Extends T_Identifier T_Implements InterfaceList '{' FieldList '}' {$$ = new ClassDecl(new Identifier(@2, $2), new NamedType(new Identifier(@4, $4)), $6, $8);} - | T_Class T_Identifier T_Implements InterfaceList '{' FieldList '}' {$$ = new ClassDecl(new Identifier(@2, $2), 0, $4, $6);} -; - -InterfaceList: T_Identifier ',' InterfaceList {($$=$3)->Append(new NamedType(new Identifier(@1, $1)));} -| T_Identifier {($$=new List)->Append(new NamedType(new Identifier(@1, $1)));} - -FieldList : FieldList Field {($$ = $1)->Append($2);} - | /* empty */ {$$ = new List;} -; - - Type: T_Int {$$ = Type::intType; } - | T_Double {$$ = Type::doubleType; } - |T_Bool {$$ = Type::boolType; } - |T_String {$$ = Type::stringType; } - |T_Identifier {$$ = new NamedType(new Identifier(@1, $1)); } -|Type T_Dims {$$ = new ArrayType(@1, $1); } -; - -FnDecl : Type T_Identifier '(' Formals ')' StmtBlock {$$ = new FnDecl(new Identifier(@2, $2), $1, $4); ((FnDecl *)$$)->SetFunctionBody($6); } -| T_Void T_Identifier '(' Formals ')' StmtBlock {$$ = new FnDecl(new Identifier(@2, $2), Type::voidType, $4); ((FnDecl *)$$)->SetFunctionBody($6); } -; - -Formals : Variable {($$ = new List)->Append($1);} -| Formals ',' Variable {($$ = $1)->Append($3);} -| {$$ = new List;} -; - -Field : VarDecl {$$ = $1;} -| FnDecl {$$ = $1;} -; - -InterfaceDecl : T_Interface T_Identifier '{' PrototypeList '}' {$$ = new InterfaceDecl(new Identifier(@2, $2), $4);}; - -PrototypeList : PrototypeList Prototype {($$=$1)->Append($2);} -| {$$ = new List;} -; -Prototype : Type T_Identifier '(' Formals ')' ';' {$$ = new FnDecl(new Identifier(@2, $2), $1, $4);} - | T_Void T_Identifier '(' Formals ')' ';' {$$ = new FnDecl(new Identifier(@2, $2), Type::voidType, $4);} -; - -StmtBlock : '{' VarDeclList StmtList '}' { $$ = new StmtBlock($2, $3);} - | '{' VarDeclList '}' { $$ = new StmtBlock($2, new List);} - | '{' StmtList '}' { $$ = new StmtBlock(new List, $2);} -| '{' '}' { $$ = new StmtBlock(new List, new List);} -; - -StmtList : StmtList Stmt { ($$=$1)->Append($2);} -| Stmt { ($$ = new List)->Append($1); } -; - -Stmt : EmptyExpr ';' {$$ = $1; } - | IfStmt {$$ = $1; } - | WhileStmt {$$ = $1; } - | ForStmt {$$ = $1; } - | BreakStmt {$$ = $1; } - | ReturnStmt {$$ = $1; } - | PrintStmt {$$ = $1; } - | StmtBlock {$$ = $1; } - | SwitchStmt {$$ = $1; } -; - -IfStmt : T_If '(' Expr ')' Stmt %prec NON_ELSE {$$ = new IfStmt($3, $5, 0); } - | T_If '(' Expr ')' Stmt T_Else Stmt { $$ = new IfStmt($3, $5, $7); } - ; -SwitchStmt : T_Switch '(' Expr ')' '{' CaseList Default '}' { $$ = new SwitchStmt($3, $6, $7);} - | T_Switch '(' Expr ')' '{' CaseList '}' { $$ = new SwitchStmt($3, $6, 0);}; - -CaseList : CaseList Case {($$ = $1)->Append($2);} -| Case {($$ = new List)->Append($1);} -; - -Case : T_Case T_IntConstant ':' StmtList {$$ = new Case(new IntConstant(@2, $2), $4);} -| T_Case T_IntConstant ':' {$$ = new Case(new IntConstant(@2, $2), new List);}; - -Default : T_Default ':' StmtList {$$ = new Default($3);} -| T_Default ':' {$$ = new Default(new List);}; - -WhileStmt : T_While '(' Expr ')' Stmt {$$ = new WhileStmt($3, $5); } -; -ForStmt : T_For '(' EmptyExpr ';' Expr ';' EmptyExpr ')' Stmt {$$ = new ForStmt($3, $5, $7, $9); } -; - -ReturnStmt : T_Return EmptyExpr ';' { $$ = new ReturnStmt(@1, $2); }; - -BreakStmt : T_Break ';' {$$ = new BreakStmt(@1); }; - -PrintStmt : T_Print '(' ExprList ')' ';' {$$ = new PrintStmt($3);}; - -ExprList : Expr {($$ = new List)->Append($1);} - | ExprList ',' Expr {($$ = $1)->Append($3);} -; - - EmptyExpr : Expr {$$ = $1; } - | {$$ = new EmptyExpr; } - ; - -Expr : LValue '=' Expr {$$ = new AssignExpr($1, new Operator(@2, "=") , $3); }; -| Constant {$$ = $1;} -| LValue {$$ = $1; } -| T_This {$$ = new This(@1);} -| Call {$$ = $1;} -|'(' Expr ')' {$$ = $2;} -| Expr '+' Expr {$$ = new ArithmeticExpr($1, new Operator(@2, "+"), $3);} -| Expr '-' Expr {$$ = new ArithmeticExpr($1, new Operator(@2, "-"), $3);} -| Expr '*' Expr {$$ = new ArithmeticExpr($1, new Operator(@2, "*"), $3);} -| Expr '/' Expr {$$ = new ArithmeticExpr($1, new Operator(@2, "/"), $3);} -| Expr '%' Expr {$$ = new ArithmeticExpr($1, new Operator(@2, "%"), $3);} -| '-' Expr %prec NEG {$$ = new ArithmeticExpr(new Operator(@2, "-"), $2);} -| Expr '<' Expr {$$ = new RelationalExpr($1, new Operator(@2, "<"), $3);} -| Expr T_LessEqual Expr {$$ = new RelationalExpr($1, new Operator(@2, "<="), $3);} -| Expr '>' Expr {$$ = new RelationalExpr($1, new Operator(@2, ">"), $3);} -| Expr T_GreaterEqual Expr {$$ = new RelationalExpr($1, new Operator(@2, ">="), $3);} -| Expr T_Equal Expr {$$ = new EqualityExpr($1, new Operator(@2, "=="), $3);} -| Expr T_NotEqual Expr {$$ = new EqualityExpr($1, new Operator(@2, "!="), $3);} -| Expr T_And Expr {$$ = new LogicalExpr($1, new Operator(@2, "&&"), $3);} -| Expr T_Or Expr {$$ = new LogicalExpr($1, new Operator(@2, "||"), $3);} -| '!' Expr {$$ = new LogicalExpr(new Operator(@1, "!"), $2);} -| T_ReadInteger '(' ')' {$$ = new ReadIntegerExpr(@1);} -| T_ReadLine '(' ')' {$$ = new ReadLineExpr(@1);} -| T_New '(' T_Identifier ')' {$$ = new NewExpr(@1, new NamedType(new Identifier(@3, $3)) );} -| T_NewArray '('Expr ',' Type')' {$$ = new NewArrayExpr(@1, $3, $5);} -| LValue T_Increm %prec INCRDECR {$$ = new PostfixExpr($1, new Operator(@2, "++"));} -| LValue T_Decrem %prec INCRDECR {$$ = new PostfixExpr($1, new Operator(@2, "--"));} -; - -LValue : T_Identifier {$$ = new FieldAccess(0, new Identifier(@1, $1)); } -| Expr '.' T_Identifier {$$ = new FieldAccess($1, new Identifier(@3, $3));} -| Expr '[' Expr ']' {$$ = new ArrayAccess(@1, $1, $3);} -; - -Call : T_Identifier '(' Actuals ')' {$$ = new Call(@1, 0, new Identifier(@1, $1), $3);} -| Expr '.' T_Identifier '(' Actuals ')' {$$ = new Call(@1, $1, new Identifier(@3, $3), $5);} -; - -Actuals: ExprList {$$ = $1;} -| {$$ = new List;} -; - -Constant: T_IntConstant {$$ = new IntConstant(@1, $1);} -| T_DoubleConstant {$$ = new DoubleConstant(@1, $1);} -| T_BoolConstant {$$ = new BoolConstant(@1, $1);} -| T_StringConstant {$$ = new StringConstant(@1, $1);} -| T_Null {$$ = new NullConstant(@1); } -; -%% - -/* The closing %% above marks the end of the Rules section and the beginning - * of the User Subroutines section. All text from here to the end of the - * file is copied verbatim to the end of the generated y.tab.c file. - * This section is where you put definitions of helper functions. - */ - -/* Function: InitParser - * -------------------- - * This function will be called before any calls to yyparse(). It is designed - * to give you an opportunity to do anything that must be done to initialize - * the parser (set global variables, configure starting state, etc.). One - * thing it already does for you is assign the value of the global variable - * yydebug that controls whether yacc prints debugging information about - * parser actions (shift/reduce) and contents of state stack during parser. - * If set to false, no information is printed. Setting it to true will give - * you a running trail that might be helpful when debugging your parser. - * Please be sure the variable is set to false when submitting your final - * version. - */ -void InitParser() -{ - PrintDebug("parser", "Initializing parser"); - yydebug = false; -} diff --git a/filter_sandbox/scanner.l b/filter_sandbox/scanner.l deleted file mode 100644 index 6294ee4..0000000 --- a/filter_sandbox/scanner.l +++ /dev/null @@ -1,256 +0,0 @@ -/* File: scanner.l - * ---------------- - * Lex input file to generate the scanner for the compiler. - */ - -%{ -#include -#include "scanner.h" -#include "utility.h" // for PrintDebug() -#include "errors.h" -#include -#include -#include - -using std::string; -using std::cout; -using std::endl; - -/* Global variable: yylval - * ----------------------- - * This global variable is how we get attribute information about the token - * just scanned to the client. The scanner sets the global variable - * appropriately and since it's global the client can just read it. In the - * future, this variable will be declared for us in the y.tab.c file - * produced by Yacc, but for now, we declare it manually. - */ -YYSTYPE yylval; // manually declared for pp1, later Yacc provides - -/* Global variable: yylloc - * ----------------------- - * This global variable is how we get position information about the token - * just scanned to the client. (Operates similarly to yylval above) - */ -struct yyltype yylloc; // manually dclared for pp1, later Yacc provides - -/* Macro: YY_USER_ACTION - * --------------------- - * This flex built-in macro can be defined to provide an action which is - * always executed prior to any matched rule's action. Basically, it is - * a way of having a piece of code common to all actions factored out to - * this routine. We already defined it for you and left the empty - * function DoBeforeEachAction ready for your use as needed. It will - * be called once for each pattern scanned from the file, before - * executing its action. - */ -static void DoBeforeEachAction(); -#define YY_USER_ACTION DoBeforeEachAction(); - -static void set_value(TokenType); - -%} - -ALPHA [a-zA-Z] -ALPHANUM [a-zA-Z0-9] -WORDCHAR [a-zA-Z0-9_] -DIGIT [0-9] -HEX 0(x|X)[0-9a-fA-F]+ -WHITESPACE [ \t\n] - -%% - - /* Keywords */ -void return T_Void; -int return T_Int; -double return T_Double; -bool return T_Bool; -string return T_String; -class return T_Class; -interface return T_Interface; -null return T_Null; -this return T_This; -extends return T_Extends; -implements return T_Implements; -for return T_For; -while return T_While; -if return T_If; -else return T_Else; -return return T_Return; -break return T_Break; -New return T_New; -NewArray return T_NewArray; - - /* Type Constants */ -true|false {set_value(T_BoolConstant); return T_BoolConstant;} -{HEX}|{DIGIT}+ {set_value(T_IntConstant); return T_IntConstant;} -{DIGIT}+\.{DIGIT}*((E|e)(\+|-)?{DIGIT}+)? {set_value(T_DoubleConstant); return T_DoubleConstant;} -\"[^\"\n]*\" {set_value(T_StringConstant); return T_StringConstant;} -\"[^\"\n]* {ReportError::UntermString(&yylloc, yytext);} - - /* Whitespace */ -{WHITESPACE} ; - - /* Identifier */ -{ALPHA}{WORDCHAR}* {set_value(T_Identifier); return T_Identifier;} - - /* Operators */ -"<=" return T_LessEqual; ->= return T_GreaterEqual; -== return T_Equal; -!= return T_NotEqual; -&& return T_And; -"||" return T_Or; -\+ return '+'; -- return '-'; -\* return '*'; -\/ return '/'; -% return '%'; -\< return '<'; -\> return '>'; -= return '='; -! return '!'; -; return ';'; -, return ','; -\. return '.'; -"[" return '['; -"]" return ']'; -"(" return '('; -")" return ')'; -"{" return '{'; -"}" return '}'; - -. ReportError::UnrecogChar(&yylloc, *yytext); - -%% - -static bool text_to_bool(char *yytext) { - if (!strcmp(yytext, "true")) { - return true; - } else if (!strcmp(yytext, "false")) { - return false; - } else { - Failure("Unrecognized value in function text_to_bool()"); - } - - // This will never be called - exit(1); -} - -static int text_to_int(char *yytext) { - if (strlen(yytext) >= 2 && (yytext[1] == 'x' || yytext[1] == 'X')) { - int num; - int decimal = 0; - for (int i = 2; i < yyleng; i++) { - char c = isalpha(yytext[i]) ? toupper(yytext[i]) : yytext[i]; - switch(c) { - case 'A': num = 10; break; - case 'B': num = 11; break; - case 'C': num = 12; break; - case 'D': num = 13; break; - case 'E': num = 14; break; - case 'F': num = 15; break; - default: num = yytext[i] - 48; break; - } - decimal += num * pow(16, yyleng - i - 1); // The exponent is the inverse of the char position - } - return decimal; - } - return atoi(yytext); -} - -static double text_to_double(char *yytext) { - int i = 0; - double ret = 0; - bool decimal = false; - double divisor = 1; - bool pose = true; - bool exponent = false; - std::string num; - while(i < yyleng){ - num = num + yytext[i]; - if(yytext[i] == 'E' || yytext[i] == 'e'){ - exponent = true; - ret = ret + atoi(num.c_str())/divisor; - num.clear(); - if(yytext[i + 1] == '-'){ - pose = false; - i++; - } - else if(yytext[i + 1] == '+') i++; - } - if(decimal) divisor *= 10; - if(yytext[i] == '.'){ - ret = atoi(num.c_str()); - decimal = true; - num.clear(); - } - i++; - } - - if(exponent) return ret * pow(10, atoi(num.c_str())); - else return ret + atoi(num.c_str())/divisor; -} - -static void set_identifier(char *identifier) { - int num_chars = yyleng + 1; // The characters plus the null character - if (yyleng > MaxIdentLen) { - ReportError::LongIdentifier(&yylloc, yytext); - num_chars = MaxIdentLen; - } - - strncpy(identifier, yytext, num_chars); - assert(identifier[MaxIdentLen + 1] == 0); -} - -static void set_value(TokenType t) { - switch(t) { - case T_BoolConstant: yylval.boolConstant = text_to_bool(yytext); break; - case T_IntConstant: yylval.integerConstant = text_to_int(yytext); break; - case T_DoubleConstant: yylval.doubleConstant = text_to_double(yytext); break; - case T_StringConstant: yylval.stringConstant = yytext; break; - case T_Identifier: set_identifier(yylval.identifier); break; - default: Failure("Unrecognized token %d in set_value()", (int) t); - } -} - -/* Function: InitScanner - * --------------------- - * This function will be called before any calls to yylex(). It is designed - * to give you an opportunity to do anything that must be done to initialize - * the scanner (set global variables, configure starting state, etc.). One - * thing it already does for you is assign the value of the global variable - * yy_flex_debug that controls whether flex prints debugging information - * about each token and what rule was matched. If set to false, no information - * is printed. Setting it to true will give you a running trail that might - * be helpful when debugging your scanner. Please be sure the variable is - * set to false when submitting your final version. - */ -void InitScanner() -{ - yy_flex_debug = false; - PrintDebug("lex", "Initializing scanner"); -} - - -/* Function: DoBeforeEachAction() - * ------------------------------ - * This function is installed as the YY_USER_ACTION. This is a place - * to group code common to all actions. - */ -static void DoBeforeEachAction() -{ - // TODO: This section looks hacky to me - static int col_pos = 1; - static int line_pos = 1; - - if (*yytext == '\n') { - line_pos++; - col_pos = 0; - } - - yylloc.first_column = col_pos; - yylloc.last_column = col_pos + yyleng - 1; - yylloc.first_line = line_pos; - - col_pos += yyleng; -} diff --git a/filter_sandbox/y.output b/filter_sandbox/y.output deleted file mode 100644 index 3687082..0000000 --- a/filter_sandbox/y.output +++ /dev/null @@ -1,303 +0,0 @@ -Grammar - - 0 $accept: filter_expr $end - - 1 filter_expr: filter_expr T_OR filter_expr - 2 | filter_expr T_AND filter_expr - 3 | '(' filter_expr ')' - 4 | filter - - 5 filter: number_filter - 6 | string_filter - - 7 number_filter: T_FIELD '=' T_NUMBER - 8 | T_FIELD '>' T_NUMBER - 9 | T_FIELD '<' T_NUMBER - 10 | T_FIELD T_NOT_EQ T_NUMBER - 11 | T_FIELD T_GT_EQ T_NUMBER - 12 | T_FIELD T_LT_EQ T_NUMBER - - 13 string_filter: T_FIELD '=' T_FIELD - 14 | T_FIELD T_NOT_EQ T_FIELD - - -Terminals, with rules where they appear - -$end (0) 0 -'(' (40) 3 -')' (41) 3 -'<' (60) 9 -'=' (61) 7 13 -'>' (62) 8 -error (256) -T_AND (258) 2 -T_OR (259) 1 -T_NUMBER (260) 7 8 9 10 11 12 -T_FIELD (261) 7 8 9 10 11 12 13 14 -T_NOT_EQ (262) 10 14 -T_GT_EQ (263) 11 -T_LT_EQ (264) 12 - - -Nonterminals, with rules where they appear - -$accept (15) - on left: 0 -filter_expr (16) - on left: 1 2 3 4, on right: 0 1 2 3 -filter (17) - on left: 5 6, on right: 4 -number_filter (18) - on left: 7 8 9 10 11 12, on right: 5 -string_filter (19) - on left: 13 14, on right: 6 - - -state 0 - - 0 $accept: . filter_expr $end - - '(' shift, and go to state 1 - T_FIELD shift, and go to state 2 - - filter_expr go to state 3 - filter go to state 4 - number_filter go to state 5 - string_filter go to state 6 - - -state 1 - - 3 filter_expr: '(' . filter_expr ')' - - '(' shift, and go to state 1 - T_FIELD shift, and go to state 2 - - filter_expr go to state 7 - filter go to state 4 - number_filter go to state 5 - string_filter go to state 6 - - -state 2 - - 7 number_filter: T_FIELD . '=' T_NUMBER - 8 | T_FIELD . '>' T_NUMBER - 9 | T_FIELD . '<' T_NUMBER - 10 | T_FIELD . T_NOT_EQ T_NUMBER - 11 | T_FIELD . T_GT_EQ T_NUMBER - 12 | T_FIELD . T_LT_EQ T_NUMBER - 13 string_filter: T_FIELD . '=' T_FIELD - 14 | T_FIELD . T_NOT_EQ T_FIELD - - T_NOT_EQ shift, and go to state 8 - '>' shift, and go to state 9 - T_GT_EQ shift, and go to state 10 - '<' shift, and go to state 11 - '=' shift, and go to state 12 - T_LT_EQ shift, and go to state 13 - - -state 3 - - 0 $accept: filter_expr . $end - 1 filter_expr: filter_expr . T_OR filter_expr - 2 | filter_expr . T_AND filter_expr - - $end shift, and go to state 14 - T_AND shift, and go to state 15 - T_OR shift, and go to state 16 - - -state 4 - - 4 filter_expr: filter . - - $default reduce using rule 4 (filter_expr) - - -state 5 - - 5 filter: number_filter . - - $default reduce using rule 5 (filter) - - -state 6 - - 6 filter: string_filter . - - $default reduce using rule 6 (filter) - - -state 7 - - 1 filter_expr: filter_expr . T_OR filter_expr - 2 | filter_expr . T_AND filter_expr - 3 | '(' filter_expr . ')' - - ')' shift, and go to state 17 - T_AND shift, and go to state 15 - T_OR shift, and go to state 16 - - -state 8 - - 10 number_filter: T_FIELD T_NOT_EQ . T_NUMBER - 14 string_filter: T_FIELD T_NOT_EQ . T_FIELD - - T_NUMBER shift, and go to state 18 - T_FIELD shift, and go to state 19 - - -state 9 - - 8 number_filter: T_FIELD '>' . T_NUMBER - - T_NUMBER shift, and go to state 20 - - -state 10 - - 11 number_filter: T_FIELD T_GT_EQ . T_NUMBER - - T_NUMBER shift, and go to state 21 - - -state 11 - - 9 number_filter: T_FIELD '<' . T_NUMBER - - T_NUMBER shift, and go to state 22 - - -state 12 - - 7 number_filter: T_FIELD '=' . T_NUMBER - 13 string_filter: T_FIELD '=' . T_FIELD - - T_NUMBER shift, and go to state 23 - T_FIELD shift, and go to state 24 - - -state 13 - - 12 number_filter: T_FIELD T_LT_EQ . T_NUMBER - - T_NUMBER shift, and go to state 25 - - -state 14 - - 0 $accept: filter_expr $end . - - $default accept - - -state 15 - - 2 filter_expr: filter_expr T_AND . filter_expr - - '(' shift, and go to state 1 - T_FIELD shift, and go to state 2 - - filter_expr go to state 26 - filter go to state 4 - number_filter go to state 5 - string_filter go to state 6 - - -state 16 - - 1 filter_expr: filter_expr T_OR . filter_expr - - '(' shift, and go to state 1 - T_FIELD shift, and go to state 2 - - filter_expr go to state 27 - filter go to state 4 - number_filter go to state 5 - string_filter go to state 6 - - -state 17 - - 3 filter_expr: '(' filter_expr ')' . - - $default reduce using rule 3 (filter_expr) - - -state 18 - - 10 number_filter: T_FIELD T_NOT_EQ T_NUMBER . - - $default reduce using rule 10 (number_filter) - - -state 19 - - 14 string_filter: T_FIELD T_NOT_EQ T_FIELD . - - $default reduce using rule 14 (string_filter) - - -state 20 - - 8 number_filter: T_FIELD '>' T_NUMBER . - - $default reduce using rule 8 (number_filter) - - -state 21 - - 11 number_filter: T_FIELD T_GT_EQ T_NUMBER . - - $default reduce using rule 11 (number_filter) - - -state 22 - - 9 number_filter: T_FIELD '<' T_NUMBER . - - $default reduce using rule 9 (number_filter) - - -state 23 - - 7 number_filter: T_FIELD '=' T_NUMBER . - - $default reduce using rule 7 (number_filter) - - -state 24 - - 13 string_filter: T_FIELD '=' T_FIELD . - - $default reduce using rule 13 (string_filter) - - -state 25 - - 12 number_filter: T_FIELD T_LT_EQ T_NUMBER . - - $default reduce using rule 12 (number_filter) - - -state 26 - - 1 filter_expr: filter_expr . T_OR filter_expr - 2 | filter_expr . T_AND filter_expr - 2 | filter_expr T_AND filter_expr . - - $default reduce using rule 2 (filter_expr) - - -state 27 - - 1 filter_expr: filter_expr . T_OR filter_expr - 1 | filter_expr T_OR filter_expr . - 2 | filter_expr . T_AND filter_expr - - T_AND shift, and go to state 15 - - $default reduce using rule 1 (filter_expr) diff --git a/filter_sandbox/y.tab.c b/filter_sandbox/y.tab.c deleted file mode 100644 index 3d4097e..0000000 --- a/filter_sandbox/y.tab.c +++ /dev/null @@ -1,1687 +0,0 @@ -/* A Bison parser, made by GNU Bison 2.3. */ - -/* Skeleton implementation for Bison's Yacc-like parsers in C - - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 - Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* C LALR(1) parser skeleton written by Richard Stallman, by - simplifying the original so-called "semantic" parser. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output. */ -#define YYBISON 1 - -/* Bison version. */ -#define YYBISON_VERSION "2.3" - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 0 - -/* Using locations. */ -#define YYLSP_NEEDED 0 - - - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - T_AND = 258, - T_OR = 259, - T_NUMBER = 260, - T_FIELD = 261, - T_NOT_EQ = 262, - T_GT_EQ = 263, - T_LT_EQ = 264 - }; -#endif -/* Tokens. */ -#define T_AND 258 -#define T_OR 259 -#define T_NUMBER 260 -#define T_FIELD 261 -#define T_NOT_EQ 262 -#define T_GT_EQ 263 -#define T_LT_EQ 264 - - - - -/* Copy the first part of user declarations. */ -#line 1 "zmap.y" - -#include -#include -#include "tree.h" - -void yyerror(const char *str) -{ - fprintf(stderr,"error: %s\n",str); - fprintf(stderr, "%s\n", "YOLO"); -} - -int yywrap() -{ - return 1; -} - -int main() -{ - yyparse(); -} - - - -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 1 -#endif - -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 0 -#endif - -/* Enabling the token table. */ -#ifndef YYTOKEN_TABLE -# define YYTOKEN_TABLE 0 -#endif - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE -#line 24 "zmap.y" -{ - int int_literal; - char *string_literal; - struct node *expr; -} -/* Line 193 of yacc.c. */ -#line 143 "y.tab.c" - YYSTYPE; -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 -#endif - - - -/* Copy the second part of user declarations. */ - - -/* Line 216 of yacc.c. */ -#line 156 "y.tab.c" - -#ifdef short -# undef short -#endif - -#ifdef YYTYPE_UINT8 -typedef YYTYPE_UINT8 yytype_uint8; -#else -typedef unsigned char yytype_uint8; -#endif - -#ifdef YYTYPE_INT8 -typedef YYTYPE_INT8 yytype_int8; -#elif (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -typedef signed char yytype_int8; -#else -typedef short int yytype_int8; -#endif - -#ifdef YYTYPE_UINT16 -typedef YYTYPE_UINT16 yytype_uint16; -#else -typedef unsigned short int yytype_uint16; -#endif - -#ifdef YYTYPE_INT16 -typedef YYTYPE_INT16 yytype_int16; -#else -typedef short int yytype_int16; -#endif - -#ifndef YYSIZE_T -# ifdef __SIZE_TYPE__ -# define YYSIZE_T __SIZE_TYPE__ -# elif defined size_t -# define YYSIZE_T size_t -# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# else -# define YYSIZE_T unsigned int -# endif -#endif - -#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) - -#ifndef YY_ -# if defined YYENABLE_NLS && YYENABLE_NLS -# if ENABLE_NLS -# include /* INFRINGES ON USER NAME SPACE */ -# define YY_(msgid) dgettext ("bison-runtime", msgid) -# endif -# endif -# ifndef YY_ -# define YY_(msgid) msgid -# endif -#endif - -/* Suppress unused-variable warnings by "using" E. */ -#if ! defined lint || defined __GNUC__ -# define YYUSE(e) ((void) (e)) -#else -# define YYUSE(e) /* empty */ -#endif - -/* Identity function, used to suppress warnings about constant conditions. */ -#ifndef lint -# define YYID(n) (n) -#else -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static int -YYID (int i) -#else -static int -YYID (i) - int i; -#endif -{ - return i; -} -#endif - -#if ! defined yyoverflow || YYERROR_VERBOSE - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# elif defined __BUILTIN_VA_ARG_INCR -# include /* INFRINGES ON USER NAME SPACE */ -# elif defined _AIX -# define YYSTACK_ALLOC __alloca -# elif defined _MSC_VER -# include /* INFRINGES ON USER NAME SPACE */ -# define alloca _alloca -# else -# define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 -# endif -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) -# ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - invoke alloca (N) if N exceeds 4096. Use a slightly smaller number - to allow for a few compiler-allocated temporary stack slots. */ -# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ -# endif -# else -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# ifndef YYSTACK_ALLOC_MAXIMUM -# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM -# endif -# if (defined __cplusplus && ! defined _STDLIB_H \ - && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 -# endif -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifndef YYFREE -# define YYFREE free -# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void free (void *); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# endif -#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ - - -#if (! defined yyoverflow \ - && (! defined __cplusplus \ - || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - yytype_int16 yyss; - YYSTYPE yyvs; - }; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ - + YYSTACK_GAP_MAXIMUM) - -/* Copy COUNT objects from FROM to TO. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -# else -# define YYCOPY(To, From, Count) \ - do \ - { \ - YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ - while (YYID (0)) -# endif -# endif - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack, Stack, yysize); \ - Stack = &yyptr->Stack; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (YYID (0)) - -#endif - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 14 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 26 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 15 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 5 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 15 -/* YYNRULES -- Number of states. */ -#define YYNSTATES 28 - -/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -#define YYUNDEFTOK 2 -#define YYMAXUTOK 264 - -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - -/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -static const yytype_uint8 yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 3, 4, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 12, 13, 10, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 5, 6, - 7, 8, 9, 11, 14 -}; - -#if YYDEBUG -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in - YYRHS. */ -static const yytype_uint8 yyprhs[] = -{ - 0, 0, 3, 7, 11, 15, 17, 19, 21, 25, - 29, 33, 37, 41, 45, 49 -}; - -/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const yytype_int8 yyrhs[] = -{ - 16, 0, -1, 16, 6, 16, -1, 16, 5, 16, - -1, 3, 16, 4, -1, 17, -1, 18, -1, 19, - -1, 8, 13, 7, -1, 8, 10, 7, -1, 8, - 12, 7, -1, 8, 9, 7, -1, 8, 11, 7, - -1, 8, 14, 7, -1, 8, 13, 8, -1, 8, - 9, 8, -1 -}; - -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const yytype_uint8 yyrline[] = -{ - 0, 47, 47, 55, 63, 67, 73, 77, 83, 91, - 99, 104, 109, 114, 121, 126 -}; -#endif - -#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE -/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "$end", "error", "$undefined", "'('", "')'", "T_AND", "T_OR", - "T_NUMBER", "T_FIELD", "T_NOT_EQ", "'>'", "T_GT_EQ", "'<'", "'='", - "T_LT_EQ", "$accept", "filter_expr", "filter", "number_filter", - "string_filter", 0 -}; -#endif - -# ifdef YYPRINT -/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to - token YYLEX-NUM. */ -static const yytype_uint16 yytoknum[] = -{ - 0, 256, 257, 40, 41, 258, 259, 260, 261, 262, - 62, 263, 60, 61, 264 -}; -# endif - -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint8 yyr1[] = -{ - 0, 15, 16, 16, 16, 16, 17, 17, 18, 18, - 18, 18, 18, 18, 19, 19 -}; - -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = -{ - 0, 2, 3, 3, 3, 1, 1, 1, 3, 3, - 3, 3, 3, 3, 3, 3 -}; - -/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state - STATE-NUM when YYTABLE doesn't specify something else to do. Zero - means the default is an error. */ -static const yytype_uint8 yydefact[] = -{ - 0, 0, 0, 0, 5, 6, 7, 0, 0, 0, - 0, 0, 0, 0, 1, 0, 0, 4, 11, 15, - 9, 12, 10, 8, 14, 13, 3, 2 -}; - -/* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_int8 yydefgoto[] = -{ - -1, 3, 4, 5, 6 -}; - -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -#define YYPACT_NINF -6 -static const yytype_int8 yypact[] = -{ - 0, 0, 7, 1, -6, -6, -6, 5, -3, -5, - 6, 17, 15, 18, -6, 0, 0, -6, -6, -6, - -6, -6, -6, -6, -6, -6, -6, 21 -}; - -/* YYPGOTO[NTERM-NUM]. */ -static const yytype_int8 yypgoto[] = -{ - -6, -1, -6, -6, -6 -}; - -/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule which - number is the opposite. If zero, do what YYDEFACT says. - If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -1 -static const yytype_uint8 yytable[] = -{ - 7, 14, 20, 1, 18, 19, 15, 16, 2, 17, - 15, 16, 0, 21, 26, 27, 8, 9, 10, 11, - 12, 13, 23, 24, 22, 25, 15 -}; - -static const yytype_int8 yycheck[] = -{ - 1, 0, 7, 3, 7, 8, 5, 6, 8, 4, - 5, 6, -1, 7, 15, 16, 9, 10, 11, 12, - 13, 14, 7, 8, 7, 7, 5 -}; - -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const yytype_uint8 yystos[] = -{ - 0, 3, 8, 16, 17, 18, 19, 16, 9, 10, - 11, 12, 13, 14, 0, 5, 6, 4, 7, 8, - 7, 7, 7, 7, 8, 7, 16, 16 -}; - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab - - -/* Like YYERROR except do call yyerror. This remains here temporarily - to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ - -#define YYFAIL goto yyerrlab - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - yytoken = YYTRANSLATE (yychar); \ - YYPOPSTACK (1); \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (YYID (0)) - - -#define YYTERROR 1 -#define YYERRCODE 256 - - -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -#define YYRHSLOC(Rhs, K) ((Rhs)[K]) -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (YYID (N)) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ - while (YYID (0)) -#endif - - -/* YY_LOCATION_PRINT -- Print the location on the stream. - This macro was not mandated originally: define only if we know - we won't break user code: when these are the locations we know. */ - -#ifndef YY_LOCATION_PRINT -# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL -# define YY_LOCATION_PRINT(File, Loc) \ - fprintf (File, "%d.%d-%d.%d", \ - (Loc).first_line, (Loc).first_column, \ - (Loc).last_line, (Loc).last_column) -# else -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -# endif -#endif - - -/* YYLEX -- calling `yylex' with the right arguments. */ - -#ifdef YYLEX_PARAM -# define YYLEX yylex (YYLEX_PARAM) -#else -# define YYLEX yylex () -#endif - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (YYID (0)) - -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Type, Value); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (YYID (0)) - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) -#else -static void -yy_symbol_value_print (yyoutput, yytype, yyvaluep) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; -#endif -{ - if (!yyvaluep) - return; -# ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# else - YYUSE (yyoutput); -# endif - switch (yytype) - { - default: - break; - } -} - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) -#else -static void -yy_symbol_print (yyoutput, yytype, yyvaluep) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; -#endif -{ - if (yytype < YYNTOKENS) - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); - else - YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); - - yy_symbol_value_print (yyoutput, yytype, yyvaluep); - YYFPRINTF (yyoutput, ")"); -} - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) -#else -static void -yy_stack_print (bottom, top) - yytype_int16 *bottom; - yytype_int16 *top; -#endif -{ - YYFPRINTF (stderr, "Stack now"); - for (; bottom <= top; ++bottom) - YYFPRINTF (stderr, " %d", *bottom); - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (YYID (0)) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_reduce_print (YYSTYPE *yyvsp, int yyrule) -#else -static void -yy_reduce_print (yyvsp, yyrule) - YYSTYPE *yyvsp; - int yyrule; -#endif -{ - int yynrhs = yyr2[yyrule]; - int yyi; - unsigned long int yylno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", - yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - fprintf (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], - &(yyvsp[(yyi + 1) - (yynrhs)]) - ); - fprintf (stderr, "\n"); - } -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyvsp, Rule); \ -} while (YYID (0)) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - - -#if YYERROR_VERBOSE - -# ifndef yystrlen -# if defined __GLIBC__ && defined _STRING_H -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static YYSIZE_T -yystrlen (const char *yystr) -#else -static YYSIZE_T -yystrlen (yystr) - const char *yystr; -#endif -{ - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) - continue; - return yylen; -} -# endif -# endif - -# ifndef yystpcpy -# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static char * -yystpcpy (char *yydest, const char *yysrc) -#else -static char * -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; -#endif -{ - char *yyd = yydest; - const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif - -# ifndef yytnamerr -/* Copy to YYRES the contents of YYSTR after stripping away unnecessary - quotes and backslashes, so that it's suitable for yyerror. The - heuristic is that double-quoting is unnecessary unless the string - contains an apostrophe, a comma, or backslash (other than - backslash-backslash). YYSTR is taken from yytname. If YYRES is - null, do not copy; instead, return the length of what the result - would have been. */ -static YYSIZE_T -yytnamerr (char *yyres, const char *yystr) -{ - if (*yystr == '"') - { - YYSIZE_T yyn = 0; - char const *yyp = yystr; - - for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } - do_not_strip_quotes: ; - } - - if (! yyres) - return yystrlen (yystr); - - return yystpcpy (yyres, yystr) - yyres; -} -# endif - -/* Copy into YYRESULT an error message about the unexpected token - YYCHAR while in state YYSTATE. Return the number of bytes copied, - including the terminating null byte. If YYRESULT is null, do not - copy anything; just return the number of bytes that would be - copied. As a special case, return 0 if an ordinary "syntax error" - message will do. Return YYSIZE_MAXIMUM if overflow occurs during - size calculation. */ -static YYSIZE_T -yysyntax_error (char *yyresult, int yystate, int yychar) -{ - int yyn = yypact[yystate]; - - if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) - return 0; - else - { - int yytype = YYTRANSLATE (yychar); - YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); - YYSIZE_T yysize = yysize0; - YYSIZE_T yysize1; - int yysize_overflow = 0; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - int yyx; - -# if 0 - /* This is so xgettext sees the translatable formats that are - constructed on the fly. */ - YY_("syntax error, unexpected %s"); - YY_("syntax error, unexpected %s, expecting %s"); - YY_("syntax error, unexpected %s, expecting %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); -# endif - char *yyfmt; - char const *yyf; - static char const yyunexpected[] = "syntax error, unexpected %s"; - static char const yyexpecting[] = ", expecting %s"; - static char const yyor[] = " or %s"; - char yyformat[sizeof yyunexpected - + sizeof yyexpecting - 1 - + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) - * (sizeof yyor - 1))]; - char const *yyprefix = yyexpecting; - - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn + 1; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yycount = 1; - - yyarg[0] = yytname[yytype]; - yyfmt = yystpcpy (yyformat, yyunexpected); - - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - yyformat[sizeof yyunexpected - 1] = '\0'; - break; - } - yyarg[yycount++] = yytname[yyx]; - yysize1 = yysize + yytnamerr (0, yytname[yyx]); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - yyfmt = yystpcpy (yyfmt, yyprefix); - yyprefix = yyor; - } - - yyf = YY_(yyformat); - yysize1 = yysize + yystrlen (yyf); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - - if (yysize_overflow) - return YYSIZE_MAXIMUM; - - if (yyresult) - { - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - char *yyp = yyresult; - int yyi = 0; - while ((*yyp = *yyf) != '\0') - { - if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyf += 2; - } - else - { - yyp++; - yyf++; - } - } - } - return yysize; - } -} -#endif /* YYERROR_VERBOSE */ - - -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) -#else -static void -yydestruct (yymsg, yytype, yyvaluep) - const char *yymsg; - int yytype; - YYSTYPE *yyvaluep; -#endif -{ - YYUSE (yyvaluep); - - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - - switch (yytype) - { - - default: - break; - } -} - - -/* Prevent warnings from -Wmissing-prototypes. */ - -#ifdef YYPARSE_PARAM -#if defined __STDC__ || defined __cplusplus -int yyparse (void *YYPARSE_PARAM); -#else -int yyparse (); -#endif -#else /* ! YYPARSE_PARAM */ -#if defined __STDC__ || defined __cplusplus -int yyparse (void); -#else -int yyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ - - - -/* The look-ahead symbol. */ -int yychar; - -/* The semantic value of the look-ahead symbol. */ -YYSTYPE yylval; - -/* Number of syntax errors so far. */ -int yynerrs; - - - -/*----------. -| yyparse. | -`----------*/ - -#ifdef YYPARSE_PARAM -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void *YYPARSE_PARAM) -#else -int -yyparse (YYPARSE_PARAM) - void *YYPARSE_PARAM; -#endif -#else /* ! YYPARSE_PARAM */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void) -#else -int -yyparse () - -#endif -#endif -{ - - int yystate; - int yyn; - int yyresult; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - /* Look-ahead token as an internal (translated) token number. */ - int yytoken = 0; -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif - - /* Three stacks and their tools: - `yyss': related to states, - `yyvs': related to semantic values, - `yyls': related to locations. - - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss = yyssa; - yytype_int16 *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs = yyvsa; - YYSTYPE *yyvsp; - - - -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) - - YYSIZE_T yystacksize = YYINITDEPTH; - - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - - - /* The number of symbols on the RHS of the reduced rule. - Keep to zero when no symbol should be popped. */ - int yylen = 0; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - - yyssp = yyss; - yyvsp = yyvs; - - goto yysetstate; - -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. So pushing a state here evens the stacks. */ - yyssp++; - - yysetstate: - *yyssp = yystate; - - if (yyss + yystacksize - 1 <= yyssp) - { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; - -#ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss; - - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - - &yystacksize); - - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - yytype_int16 *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss); - YYSTACK_RELOCATE (yyvs); - -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - - goto yybackup; - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - - /* Do appropriate processing given the current state. Read a - look-ahead token if we need one and don't already have one. */ - - /* First try to decide what to do without reference to look-ahead token. */ - yyn = yypact[yystate]; - if (yyn == YYPACT_NINF) - goto yydefault; - - /* Not known => get a look-ahead token if don't already have one. */ - - /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); - yychar = YYLEX; - } - - if (yychar <= YYEOF) - { - yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yyn == 0 || yyn == YYTABLE_NINF) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - - if (yyn == YYFINAL) - YYACCEPT; - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - /* Shift the look-ahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - - /* Discard the shifted token unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; - - yystate = yyn; - *++yyvsp = yylval; - - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - `$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 2: -#line 48 "zmap.y" - { - (yyval.expr) = make_op_node(OR); - (yyval.expr)->left_child = (yyvsp[(1) - (3)].expr); - (yyval.expr)->right_child = (yyvsp[(3) - (3)].expr); - print_expression((yyval.expr)); - printf("%s\n", ""); - } - break; - - case 3: -#line 56 "zmap.y" - { - (yyval.expr) = make_op_node(AND); - (yyval.expr)->left_child = (yyvsp[(1) - (3)].expr); - (yyval.expr)->right_child = (yyvsp[(3) - (3)].expr); - print_expression((yyval.expr)); - printf("%s\n", ""); - } - break; - - case 4: -#line 64 "zmap.y" - { - (yyval.expr) = (yyvsp[(2) - (3)].expr); - } - break; - - case 5: -#line 68 "zmap.y" - { - (yyval.expr) = (yyvsp[(1) - (1)].expr); - } - break; - - case 6: -#line 74 "zmap.y" - { - (yyval.expr) = (yyvsp[(1) - (1)].expr); - } - break; - - case 7: -#line 78 "zmap.y" - { - (yyval.expr) = (yyvsp[(1) - (1)].expr); - } - break; - - case 8: -#line 84 "zmap.y" - { - printf("number_filter: %s = %d\n", (yyvsp[(1) - (3)].string_literal), (yyvsp[(3) - (3)].int_literal)); - (yyval.expr) = make_op_node(EQ); - (yyval.expr)->left_child = make_field_node((yyvsp[(1) - (3)].string_literal)); - (yyval.expr)->right_child = make_int_node((yyvsp[(3) - (3)].int_literal)); - } - break; - - case 9: -#line 92 "zmap.y" - { - printf("number_filter: %s > %d\n", (yyvsp[(1) - (3)].string_literal), (yyvsp[(3) - (3)].int_literal)); - (yyval.expr) = make_op_node(GT); - (yyval.expr)->left_child = make_field_node((yyvsp[(1) - (3)].string_literal)); - (yyval.expr)->right_child = make_int_node((yyvsp[(3) - (3)].int_literal)); - } - break; - - case 10: -#line 100 "zmap.y" - { - printf("number_filter: %s < %d\n", (yyvsp[(1) - (3)].string_literal), (yyvsp[(3) - (3)].int_literal)); - } - break; - - case 11: -#line 105 "zmap.y" - { - printf("number_filter: %s != %d\n", (yyvsp[(1) - (3)].string_literal), (yyvsp[(3) - (3)].int_literal)); - } - break; - - case 12: -#line 110 "zmap.y" - { - printf("number_filter: %s >= %d\n", (yyvsp[(1) - (3)].string_literal), (yyvsp[(3) - (3)].int_literal)); - } - break; - - case 13: -#line 115 "zmap.y" - { - printf("number_filter: %s <= %d\n", (yyvsp[(1) - (3)].string_literal), (yyvsp[(3) - (3)].int_literal)); - } - break; - - case 14: -#line 122 "zmap.y" - { - printf("string_filter %s = %s\n", (yyvsp[(1) - (3)].string_literal), (yyvsp[(3) - (3)].string_literal)); - } - break; - - case 15: -#line 127 "zmap.y" - { - printf("string_filter: %s != %s\n", (yyvsp[(1) - (3)].string_literal), (yyvsp[(3) - (3)].string_literal)); - } - break; - - -/* Line 1267 of yacc.c. */ -#line 1470 "y.tab.c" - default: break; - } - YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); - - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - - *++yyvsp = yyval; - - - /* Now `shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; - - goto yynewstate; - - -/*------------------------------------. -| yyerrlab -- here on detecting error | -`------------------------------------*/ -yyerrlab: - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; -#if ! YYERROR_VERBOSE - yyerror (YY_("syntax error")); -#else - { - YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); - if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) - { - YYSIZE_T yyalloc = 2 * yysize; - if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) - yyalloc = YYSTACK_ALLOC_MAXIMUM; - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - yymsg = (char *) YYSTACK_ALLOC (yyalloc); - if (yymsg) - yymsg_alloc = yyalloc; - else - { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - } - } - - if (0 < yysize && yysize <= yymsg_alloc) - { - (void) yysyntax_error (yymsg, yystate, yychar); - yyerror (yymsg); - } - else - { - yyerror (YY_("syntax error")); - if (yysize != 0) - goto yyexhaustedlab; - } - } -#endif - } - - - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse look-ahead token after an - error, discard it. */ - - if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } - else - { - yydestruct ("Error: discarding", - yytoken, &yylval); - yychar = YYEMPTY; - } - } - - /* Else will try to reuse look-ahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - - /* Pacify compilers like GCC when the user code never invokes - YYERROR and the label yyerrorlab therefore never appears in user - code. */ - if (/*CONSTCOND*/ 0) - goto yyerrorlab; - - /* Do not reclaim the symbols of the rule which action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (yyn != YYPACT_NINF) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - - yydestruct ("Error: popping", - yystos[yystate], yyvsp); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - - if (yyn == YYFINAL) - YYACCEPT; - - *++yyvsp = yylval; - - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - -#ifndef yyoverflow -/*-------------------------------------------------. -| yyexhaustedlab -- memory exhaustion comes here. | -`-------------------------------------------------*/ -yyexhaustedlab: - yyerror (YY_("memory exhausted")); - yyresult = 2; - /* Fall through. */ -#endif - -yyreturn: - if (yychar != YYEOF && yychar != YYEMPTY) - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval); - /* Do not reclaim the symbols of the rule which action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp); - YYPOPSTACK (1); - } -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif -#if YYERROR_VERBOSE - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); -#endif - /* Make sure YYID is used. */ - return YYID (yyresult); -} - - -#line 132 "zmap.y" - - - - diff --git a/filter_sandbox/y.tab.h b/filter_sandbox/y.tab.h deleted file mode 100644 index 305eba0..0000000 --- a/filter_sandbox/y.tab.h +++ /dev/null @@ -1,80 +0,0 @@ -/* A Bison parser, made by GNU Bison 2.3. */ - -/* Skeleton interface for Bison's Yacc-like parsers in C - - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 - Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - T_AND = 258, - T_OR = 259, - T_NUMBER = 260, - T_FIELD = 261, - T_NOT_EQ = 262, - T_GT_EQ = 263, - T_LT_EQ = 264 - }; -#endif -/* Tokens. */ -#define T_AND 258 -#define T_OR 259 -#define T_NUMBER 260 -#define T_FIELD 261 -#define T_NOT_EQ 262 -#define T_GT_EQ 263 -#define T_LT_EQ 264 - - - - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE -#line 24 "zmap.y" -{ - int int_literal; - char *string_literal; - struct node *expr; -} -/* Line 1529 of yacc.c. */ -#line 73 "y.tab.h" - YYSTYPE; -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 -#endif - -extern YYSTYPE yylval; - diff --git a/filter_sandbox/tree.c b/src/expression.c similarity index 100% rename from filter_sandbox/tree.c rename to src/expression.c diff --git a/filter_sandbox/tree.h b/src/expression.h similarity index 100% rename from filter_sandbox/tree.h rename to src/expression.h diff --git a/src/zmap.c b/src/zmap.c index 083566d..9fe5b2c 100644 --- a/src/zmap.c +++ b/src/zmap.c @@ -1,630 +1,613 @@ -/* - * 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 - */ +#ifndef lint +static const char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93"; +#endif -#define _GNU_SOURCE +#define YYBYACC 1 +#define YYMAJOR 1 +#define YYMINOR 9 +#define YYPATCH 20120115 -#include +#define YYEMPTY (-1) +#define yyclearin (yychar = YYEMPTY) +#define yyerrok (yyerrflag = 0) +#define YYRECOVERING() (yyerrflag != 0) + +#define YYPREFIX "yy" + +#define YYPURE 0 + +#line 2 "zmap.y" #include #include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include "../lib/logger.h" -#include "../lib/random.h" - -#include "zopt.h" -#include "send.h" -#include "recv.h" -#include "state.h" -#include "monitor.h" -#include "get_gateway.h" - -#include "output_modules/output_modules.h" -#include "probe_modules/probe_modules.h" - -pthread_mutex_t cpu_affinity_mutex = PTHREAD_MUTEX_INITIALIZER; -pthread_mutex_t recv_ready_mutex = PTHREAD_MUTEX_INITIALIZER; - -// splits comma delimited string into char*[]. Does not handle -// escaping or complicated setups: designed to process a set -// of fields that the user wants output -static void split_string(char* in, int *len, char***results) +#include "expression.h" + +void yyerror(const char *str) { - char** fields = calloc(MAX_FIELDS, sizeof(char*)); - memset(fields, 0, MAX_FIELDS*sizeof(fields)); - int retvlen = 0; - char *currloc = in; - // parse csv into a set of strings - while (1) { - size_t len = strcspn(currloc, ", "); - if (len == 0) { - currloc++; - } else { - char *new = malloc(len+1); - assert(new); - strncpy(new, currloc, len); - new[len] = '\0'; - fields[retvlen++] = new; - assert(fields[retvlen-1]); - } - if (len == strlen(currloc)) { - break; - } - currloc += len; + fprintf(stderr,"error: %s\n",str); + fprintf(stderr, "%s\n", "YOLO"); +} + +int yywrap() +{ + return 1; +} + +#line 19 "zmap.y" +#ifdef YYSTYPE +#undef YYSTYPE_IS_DECLARED +#define YYSTYPE_IS_DECLARED 1 +#endif +#ifndef YYSTYPE_IS_DECLARED +#define YYSTYPE_IS_DECLARED 1 +typedef union { + int int_literal; + char *string_literal; + struct node *expr; +} YYSTYPE; +#endif /* !YYSTYPE_IS_DECLARED */ +#line 48 "y.tab.c" + +/* compatibility with bison */ +#ifdef YYPARSE_PARAM +/* compatibility with FreeBSD */ +# ifdef YYPARSE_PARAM_TYPE +# define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM) +# else +# define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM) +# endif +#else +# define YYPARSE_DECL() yyparse(void) +#endif + +/* Parameters sent to lex. */ +#ifdef YYLEX_PARAM +# define YYLEX_DECL() yylex(void *YYLEX_PARAM) +# define YYLEX yylex(YYLEX_PARAM) +#else +# define YYLEX_DECL() yylex(void) +# define YYLEX yylex() +#endif + +/* Parameters sent to yyerror. */ +#ifndef YYERROR_DECL +#define YYERROR_DECL() yyerror(const char *s) +#endif +#ifndef YYERROR_CALL +#define YYERROR_CALL(msg) yyerror(msg) +#endif + +extern int YYPARSE_DECL(); + +#define T_AND 257 +#define T_OR 258 +#define T_NUMBER 259 +#define T_FIELD 260 +#define T_NOT_EQ 261 +#define T_GT_EQ 262 +#define T_LT_EQ 263 +#define YYERRCODE 256 +static const short yylhs[] = { -1, + 0, 0, 0, 0, 1, 1, 2, 2, 2, 2, + 2, 2, 3, 3, +}; +static const short yylen[] = { 2, + 3, 3, 3, 1, 1, 1, 3, 3, 3, 3, + 3, 3, 3, 3, +}; +static const short yydefred[] = { 0, + 0, 0, 0, 4, 5, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3, 10, 14, 11, 8, + 9, 7, 13, 12, 2, 0, +}; +static const short yydgoto[] = { 3, + 4, 5, 6, +}; +static const short yysindex[] = { -40, + -40, -57, -250, 0, 0, 0, -39, -249, -245, -244, + -243, -247, -242, -40, -40, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -248, +}; +static const short yyrindex[] = { 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, +}; +static const short yygindex[] = { 5, + 0, 0, 0, +}; +#define YYTABLESIZE 259 +static const short yytable[] = { 1, + 1, 16, 11, 12, 10, 7, 14, 15, 14, 17, + 18, 22, 23, 19, 20, 21, 24, 0, 25, 26, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 8, 9, 13, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 15, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, +}; +static const short yycheck[] = { 40, + 0, 41, 60, 61, 62, 1, 257, 258, 257, 259, + 260, 259, 260, 259, 259, 259, 259, -1, 14, 15, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 41, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 261, 262, 263, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 257, 258, 260, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 258, +}; +#define YYFINAL 3 +#ifndef YYDEBUG +#define YYDEBUG 0 +#endif +#define YYMAXTOKEN 263 +#if YYDEBUG +static const char *yyname[] = { + +"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,"'('","')'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'<'","'='","'>'",0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"T_AND", +"T_OR","T_NUMBER","T_FIELD","T_NOT_EQ","T_GT_EQ","T_LT_EQ", +}; +static const char *yyrule[] = { +"$accept : filter_expr", +"filter_expr : filter_expr T_OR filter_expr", +"filter_expr : filter_expr T_AND filter_expr", +"filter_expr : '(' filter_expr ')'", +"filter_expr : filter", +"filter : number_filter", +"filter : string_filter", +"number_filter : T_FIELD '=' T_NUMBER", +"number_filter : T_FIELD '>' T_NUMBER", +"number_filter : T_FIELD '<' T_NUMBER", +"number_filter : T_FIELD T_NOT_EQ T_NUMBER", +"number_filter : T_FIELD T_GT_EQ T_NUMBER", +"number_filter : T_FIELD T_LT_EQ T_NUMBER", +"string_filter : T_FIELD '=' T_FIELD", +"string_filter : T_FIELD T_NOT_EQ T_FIELD", + +}; +#endif + +int yydebug; +int yynerrs; + +int yyerrflag; +int yychar; +YYSTYPE yyval; +YYSTYPE yylval; + +/* define the initial stack-sizes */ +#ifdef YYSTACKSIZE +#undef YYMAXDEPTH +#define YYMAXDEPTH YYSTACKSIZE +#else +#ifdef YYMAXDEPTH +#define YYSTACKSIZE YYMAXDEPTH +#else +#define YYSTACKSIZE 500 +#define YYMAXDEPTH 500 +#endif +#endif + +#define YYINITSTACKSIZE 500 + +typedef struct { + unsigned stacksize; + short *s_base; + short *s_mark; + short *s_last; + YYSTYPE *l_base; + YYSTYPE *l_mark; +} YYSTACKDATA; +/* variables for the parser stack */ +static YYSTACKDATA yystack; +#line 128 "zmap.y" + + +#line 248 "y.tab.c" + +#if YYDEBUG +#include /* needed for printf */ +#endif + +#include /* needed for malloc, etc */ +#include /* needed for memset */ + +/* allocate initial stack or double stack size, up to YYMAXDEPTH */ +static int yygrowstack(YYSTACKDATA *data) +{ + int i; + unsigned newsize; + short *newss; + YYSTYPE *newvs; + + if ((newsize = data->stacksize) == 0) + newsize = YYINITSTACKSIZE; + else if (newsize >= YYMAXDEPTH) + return -1; + else if ((newsize *= 2) > YYMAXDEPTH) + newsize = YYMAXDEPTH; + + i = data->s_mark - data->s_base; + newss = (short *)realloc(data->s_base, newsize * sizeof(*newss)); + if (newss == 0) + return -1; + + data->s_base = newss; + data->s_mark = newss + i; + + newvs = (YYSTYPE *)realloc(data->l_base, newsize * sizeof(*newvs)); + if (newvs == 0) + return -1; + + data->l_base = newvs; + data->l_mark = newvs + i; + + data->stacksize = newsize; + data->s_last = data->s_base + newsize - 1; + return 0; +} + +#if YYPURE || defined(YY_NO_LEAKS) +static void yyfreestack(YYSTACKDATA *data) +{ + free(data->s_base); + free(data->l_base); + memset(data, 0, sizeof(*data)); +} +#else +#define yyfreestack(data) /* nothing */ +#endif + +#define YYABORT goto yyabort +#define YYREJECT goto yyabort +#define YYACCEPT goto yyaccept +#define YYERROR goto yyerrlab + +int +YYPARSE_DECL() +{ + int yym, yyn, yystate; +#if YYDEBUG + const char *yys; + + if ((yys = getenv("YYDEBUG")) != 0) + { + yyn = *yys; + if (yyn >= '0' && yyn <= '9') + yydebug = yyn - '0'; + } +#endif + + yynerrs = 0; + yyerrflag = 0; + yychar = YYEMPTY; + yystate = 0; + +#if YYPURE + memset(&yystack, 0, sizeof(yystack)); +#endif + + if (yystack.s_base == NULL && yygrowstack(&yystack)) goto yyoverflow; + yystack.s_mark = yystack.s_base; + yystack.l_mark = yystack.l_base; + yystate = 0; + *yystack.s_mark = 0; + +yyloop: + if ((yyn = yydefred[yystate]) != 0) goto yyreduce; + if (yychar < 0) + { + if ((yychar = YYLEX) < 0) yychar = 0; +#if YYDEBUG + if (yydebug) + { + yys = 0; + if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; + if (!yys) yys = "illegal-symbol"; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, yystate, yychar, yys); } - *results = fields; - *len = retvlen; +#endif + } + if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, shifting to state %d\n", + YYPREFIX, yystate, yytable[yyn]); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + yychar = YYEMPTY; + if (yyerrflag > 0) --yyerrflag; + goto yyloop; + } + if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { + yyn = yytable[yyn]; + goto yyreduce; + } + if (yyerrflag) goto yyinrecovery; + + yyerror("syntax error"); + + goto yyerrlab; + +yyerrlab: + ++yynerrs; + +yyinrecovery: + if (yyerrflag < 3) + { + yyerrflag = 3; + for (;;) + { + if ((yyn = yysindex[*yystack.s_mark]) && (yyn += YYERRCODE) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, error recovery shifting\ + to state %d\n", YYPREFIX, *yystack.s_mark, yytable[yyn]); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + goto yyloop; + } + else + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: error recovery discarding state %d\n", + YYPREFIX, *yystack.s_mark); +#endif + if (yystack.s_mark <= yystack.s_base) goto yyabort; + --yystack.s_mark; + --yystack.l_mark; + } + } + } + else + { + if (yychar == 0) goto yyabort; +#if YYDEBUG + if (yydebug) + { + yys = 0; + if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; + if (!yys) yys = "illegal-symbol"; + printf("%sdebug: state %d, error recovery discards token %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + yychar = YYEMPTY; + goto yyloop; + } + +yyreduce: +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, reducing by rule %d (%s)\n", + YYPREFIX, yystate, yyn, yyrule[yyn]); +#endif + yym = yylen[yyn]; + if (yym) + yyval = yystack.l_mark[1-yym]; + else + memset(&yyval, 0, sizeof yyval); + switch (yyn) + { +case 1: +#line 43 "zmap.y" + { + yyval.expr = make_op_node(OR); + yyval.expr->left_child = yystack.l_mark[-2].expr; + yyval.expr->right_child = yystack.l_mark[0].expr; + print_expression(yyval.expr); + printf("%s\n", ""); + } +break; +case 2: +#line 51 "zmap.y" + { + yyval.expr = make_op_node(AND); + yyval.expr->left_child = yystack.l_mark[-2].expr; + yyval.expr->right_child = yystack.l_mark[0].expr; + print_expression(yyval.expr); + printf("%s\n", ""); + } +break; +case 3: +#line 59 "zmap.y" + { + yyval.expr = yystack.l_mark[-1].expr; + } +break; +case 4: +#line 63 "zmap.y" + { + yyval.expr = yystack.l_mark[0].expr; + } +break; +case 5: +#line 69 "zmap.y" + { + yyval.expr = yystack.l_mark[0].expr; + } +break; +case 6: +#line 73 "zmap.y" + { + yyval.expr = yystack.l_mark[0].expr; + } +break; +case 7: +#line 79 "zmap.y" + { + printf("number_filter: %s = %d\n", yystack.l_mark[-2].string_literal, yystack.l_mark[0].int_literal); + yyval.expr = make_op_node(EQ); + yyval.expr->left_child = make_field_node(yystack.l_mark[-2].string_literal); + yyval.expr->right_child = make_int_node(yystack.l_mark[0].int_literal); + } +break; +case 8: +#line 87 "zmap.y" + { + printf("number_filter: %s > %d\n", yystack.l_mark[-2].string_literal, yystack.l_mark[0].int_literal); + yyval.expr = make_op_node(GT); + yyval.expr->left_child = make_field_node(yystack.l_mark[-2].string_literal); + yyval.expr->right_child = make_int_node(yystack.l_mark[0].int_literal); + } +break; +case 9: +#line 95 "zmap.y" + { + printf("number_filter: %s < %d\n", yystack.l_mark[-2].string_literal, yystack.l_mark[0].int_literal); + } +break; +case 10: +#line 100 "zmap.y" + { + printf("number_filter: %s != %d\n", yystack.l_mark[-2].string_literal, yystack.l_mark[0].int_literal); + } +break; +case 11: +#line 105 "zmap.y" + { + printf("number_filter: %s >= %d\n", yystack.l_mark[-2].string_literal, yystack.l_mark[0].int_literal); + } +break; +case 12: +#line 110 "zmap.y" + { + printf("number_filter: %s <= %d\n", yystack.l_mark[-2].string_literal, yystack.l_mark[0].int_literal); + } +break; +case 13: +#line 117 "zmap.y" + { + printf("string_filter %s = %s\n", yystack.l_mark[-2].string_literal, yystack.l_mark[0].string_literal); + } +break; +case 14: +#line 122 "zmap.y" + { + printf("string_filter: %s != %s\n", yystack.l_mark[-2].string_literal, yystack.l_mark[0].string_literal); + } +break; +#line 552 "y.tab.c" + } + yystack.s_mark -= yym; + yystate = *yystack.s_mark; + yystack.l_mark -= yym; + yym = yylhs[yyn]; + if (yystate == 0 && yym == 0) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state 0 to\ + state %d\n", YYPREFIX, YYFINAL); +#endif + yystate = YYFINAL; + *++yystack.s_mark = YYFINAL; + *++yystack.l_mark = yyval; + if (yychar < 0) + { + if ((yychar = YYLEX) < 0) yychar = 0; +#if YYDEBUG + if (yydebug) + { + yys = 0; + if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; + if (!yys) yys = "illegal-symbol"; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, YYFINAL, yychar, yys); + } +#endif + } + if (yychar == 0) goto yyaccept; + goto yyloop; + } + if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yystate) + yystate = yytable[yyn]; + else + yystate = yydgoto[yym]; +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state %d \ +to state %d\n", YYPREFIX, *yystack.s_mark, yystate); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + *++yystack.s_mark = (short) yystate; + *++yystack.l_mark = yyval; + goto yyloop; + +yyoverflow: + yyerror("yacc stack overflow"); + +yyabort: + yyfreestack(&yystack); + return (1); + +yyaccept: + yyfreestack(&yystack); + return (0); } - -static void set_cpu(void) -{ - pthread_mutex_lock(&cpu_affinity_mutex); - static int core=0; - int num_cores = sysconf(_SC_NPROCESSORS_ONLN); - cpu_set_t cpuset; - CPU_ZERO(&cpuset); - CPU_SET(core, &cpuset); - if (pthread_setaffinity_np(pthread_self(), - sizeof(cpu_set_t), &cpuset) != 0) { - log_error("zmap", "can't set thread CPU affinity"); - } - log_trace("zmap", "set thread %u affinity to core %d", - pthread_self(), core); - core = (core + 1) % num_cores; - pthread_mutex_unlock(&cpu_affinity_mutex); -} - -static void* start_send(void *arg) -{ - uintptr_t v = (uintptr_t) arg; - int sock = (int) v & 0xFFFF; - set_cpu(); - send_run(sock); - return NULL; -} - -static void* start_recv(__attribute__((unused)) void *arg) -{ - set_cpu(); - recv_run(&recv_ready_mutex); - return NULL; -} - -static void drop_privs() -{ - struct passwd *pw; - if ((pw = getpwnam("nobody")) != NULL) { - if (setuid(pw->pw_uid) == 0) { - return; // success - } - } - log_fatal("zmap", "Couldn't change UID to 'nobody'"); -} - -static void *start_mon(__attribute__((unused)) void *arg) -{ - set_cpu(); - monitor_run(); - return NULL; -} - -#define SI(w,x,y) printf("%s\t%s\t%i\n", w, x, y); -#define SD(w,x,y) printf("%s\t%s\t%f\n", w, x, y); -#define SU(w,x,y) printf("%s\t%s\t%u\n", w, x, y); -#define SLU(w,x,y) printf("%s\t%s\t%lu\n", w, x, (long unsigned int) y); -#define SS(w,x,y) printf("%s\t%s\t%s\n", w, x, y); -#define STRTIME_LEN 1024 - -static void summary(void) -{ - char send_start_time[STRTIME_LEN+1]; - assert(dstrftime(send_start_time, STRTIME_LEN, "%c", zsend.start)); - char send_end_time[STRTIME_LEN+1]; - assert(dstrftime(send_end_time, STRTIME_LEN, "%c", zsend.finish)); - char recv_start_time[STRTIME_LEN+1]; - assert(dstrftime(recv_start_time, STRTIME_LEN, "%c", zrecv.start)); - char recv_end_time[STRTIME_LEN+1]; - assert(dstrftime(recv_end_time, STRTIME_LEN, "%c", zrecv.finish)); - double hitrate = ((double) 100 * zrecv.success_unique)/((double)zsend.sent); - - SU("cnf", "target-port", zconf.target_port); - SU("cnf", "source-port-range-begin", zconf.source_port_first); - SU("cnf", "source-port-range-end", zconf.source_port_last); - SS("cnf", "source-addr-range-begin", zconf.source_ip_first); - SS("cnf", "source-addr-range-end", zconf.source_ip_last); - SU("cnf", "maximum-targets", zconf.max_targets); - SU("cnf", "maximum-runtime", zconf.max_runtime); - SU("cnf", "maximum-results", zconf.max_results); - SU("cnf", "permutation-seed", zconf.seed); - SI("cnf", "cooldown-period", zconf.cooldown_secs); - SS("cnf", "send-interface", zconf.iface); - SI("cnf", "rate", zconf.rate); - SLU("cnf", "bandwidth", zconf.bandwidth); - SU("env", "nprocessors", (unsigned) sysconf(_SC_NPROCESSORS_ONLN)); - SS("exc", "send-start-time", send_start_time); - SS("exc", "send-end-time", send_end_time); - SS("exc", "recv-start-time", recv_start_time); - SS("exc", "recv-end-time", recv_end_time); - SU("exc", "sent", zsend.sent); - SU("exc", "blacklisted", zsend.blacklisted); - SU("exc", "first-scanned", zsend.first_scanned); - SD("exc", "hit-rate", hitrate); - SU("exc", "success-total", zrecv.success_total); - SU("exc", "success-unique", zrecv.success_unique); - SU("exc", "success-cooldown-total", zrecv.cooldown_total); - SU("exc", "success-cooldown-unique", zrecv.cooldown_unique); - SU("exc", "failure-total", zrecv.failure_total); - SU("exc", "sendto-failures", zsend.sendto_failures); - SU("adv", "permutation-gen", zconf.generator); - SS("exc", "scan-type", zconf.probe_module->name); -} - -static void start_zmap(void) -{ - log_info("zmap", "started"); - - // finish setting up configuration - if (zconf.iface == NULL) { - char errbuf[PCAP_ERRBUF_SIZE]; - char *iface = pcap_lookupdev(errbuf); - if (iface == NULL) { - log_fatal("zmap", "could not detect default network interface " - "(e.g. eth0). Try running as root or setting" - " interface using -i flag."); - } - log_debug("zmap", "no interface provided. will use %s", iface); - zconf.iface = iface; - } - if (zconf.source_ip_first == NULL) { - struct in_addr default_ip; - zconf.source_ip_first = malloc(INET_ADDRSTRLEN); - zconf.source_ip_last = zconf.source_ip_first; - if (get_iface_ip(zconf.iface, &default_ip) < 0) { - log_fatal("zmap", "could not detect default IP address for for %s." - " Try specifying a source address (-S).", zconf.iface); - } - inet_ntop(AF_INET, &default_ip, zconf.source_ip_first, INET_ADDRSTRLEN); - log_debug("zmap", "no source IP address given. will use %s", - zconf.source_ip_first); - } - if (!zconf.gw_mac_set) { - struct in_addr gw_ip; - char iface[IF_NAMESIZE]; - if (get_default_gw(&gw_ip, iface) < 0) { - log_fatal("zmap", "could not detect default gateway address for %i." - " Try setting default gateway mac address (-G)."); - } - log_debug("zmap", "found gateway IP %s on %s", inet_ntoa(gw_ip), iface); - if (get_hw_addr(&gw_ip, iface, zconf.gw_mac) < 0) { - log_fatal("zmap", "could not detect GW MAC address for %s on %s." - " Try setting default gateway mac address (-G).", - inet_ntoa(gw_ip), zconf.iface); - } - zconf.gw_mac_set = 1; - log_debug("zmap", "using default gateway MAC %02x:%02x:%02x:%02x:%02x:%02x", - zconf.gw_mac[0], zconf.gw_mac[1], zconf.gw_mac[2], - zconf.gw_mac[3], zconf.gw_mac[4], zconf.gw_mac[5]); - } - - // initialization - if (zconf.output_module && zconf.output_module->init) { - zconf.output_module->init(&zconf, zconf.output_fields, - zconf.output_fields_len); - } - if (send_init()) { - exit(EXIT_FAILURE); - } - if (zconf.output_module && zconf.output_module->start) { - zconf.output_module->start(&zconf, &zsend, &zrecv); - } - // start threads - pthread_t *tsend, trecv, tmon; - int r = pthread_create(&trecv, NULL, start_recv, NULL); - if (r != 0) { - log_fatal("zmap", "unable to create recv thread"); - exit(EXIT_FAILURE); - } - for (;;) { - pthread_mutex_lock(&recv_ready_mutex); - if (zconf.recv_ready) { - break; - } - pthread_mutex_unlock(&recv_ready_mutex); - } - tsend = malloc(zconf.senders * sizeof(pthread_t)); - assert(tsend); - log_debug("zmap", "using %d sender threads", zconf.senders); - for (int i=0; i < zconf.senders; i++) { - uintptr_t sock; - if (zconf.dryrun) { - sock = get_dryrun_socket(); - } else { - sock = get_socket(); - } - - int r = pthread_create(&tsend[i], NULL, start_send, (void*) sock); - if (r != 0) { - log_fatal("zmap", "unable to create send thread"); - exit(EXIT_FAILURE); - } - } - if (!zconf.quiet) { - int r = pthread_create(&tmon, NULL, start_mon, NULL); - if (r != 0) { - log_fatal("zmap", "unable to create monitor thread"); - exit(EXIT_FAILURE); - } - } - - drop_privs(); - - // wait for completion - for (int i=0; i < zconf.senders; i++) { - int r = pthread_join(tsend[i], NULL); - if (r != 0) { - log_fatal("zmap", "unable to join send thread"); - exit(EXIT_FAILURE); - } - } - log_debug("zmap", "senders finished"); - r = pthread_join(trecv, NULL); - if (r != 0) { - log_fatal("zmap", "unable to join recv thread"); - exit(EXIT_FAILURE); - } - if (!zconf.quiet) { - pthread_join(tmon, NULL); - if (r != 0) { - log_fatal("zmap", "unable to join monitor thread"); - exit(EXIT_FAILURE); - } - } - - // finished - if (zconf.summary) { - summary(); - } - if (zconf.output_module && zconf.output_module->close) { - zconf.output_module->close(&zconf, &zsend, &zrecv); - } - if (zconf.probe_module && zconf.probe_module->close) { - zconf.probe_module->close(&zconf, &zsend, &zrecv); - } - log_info("zmap", "completed"); -} - -static void enforce_range(const char *name, int v, int min, int max) -{ - if (v < min || v > max) { - fprintf(stderr, "%s: argument `%s' must be between %d and %d\n", - CMDLINE_PARSER_PACKAGE, name, min, max); - exit(EXIT_FAILURE); - } -} - -static int file_exists(char *name) -{ - FILE *file = fopen(name, "r"); - if (!file) - return 0; - fclose(file); - return 1; -} - -#define MAC_LEN IFHWADDRLEN -int parse_mac(macaddr_t *out, char *in) -{ - if (strlen(in) < MAC_LEN*3-1) - return 0; - char octet[3]; - octet[2] = '\0'; - for (int i=0; i < MAC_LEN; i++) { - if (i < MAC_LEN-1 && in[i*3+2] != ':') { - return 0; - } - strncpy(octet, &in[i*3], 2); - char *err = NULL; - long b = strtol(octet, &err, 16); - if (err && *err != '\0') { - return 0; - } - out[i] = b & 0xFF; - } - return 1; -} - -#define SET_IF_GIVEN(DST,ARG) \ - { if (args.ARG##_given) { (DST) = args.ARG##_arg; }; } -#define SET_BOOL(DST,ARG) \ - { if (args.ARG##_given) { (DST) = 1; }; } - -int main(int argc, char *argv[]) -{ - struct gengetopt_args_info args; - struct cmdline_parser_params *params; - params = cmdline_parser_params_create(); - params->initialize = 1; - params->override = 0; - params->check_required = 0; - - if (cmdline_parser_ext(argc, argv, &args, params) != 0) { - exit(EXIT_SUCCESS); - } - - zconf.log_level = args.verbosity_arg; - log_init(stderr, zconf.log_level); - log_trace("zmap", "zmap main thread started"); - - if (args.help_given) { - cmdline_parser_print_help(); - exit(EXIT_SUCCESS); - } - if (args.version_given) { - cmdline_parser_print_version(); - exit(EXIT_SUCCESS); - } - if (args.list_output_modules_given) { - print_output_modules(); - exit(EXIT_SUCCESS); - } - if (args.list_probe_modules_given) { - print_probe_modules(); - exit(EXIT_SUCCESS); - } - if (args.config_given || file_exists(args.config_arg)) { - params->initialize = 0; - params->override = 0; - if (cmdline_parser_config_file(args.config_arg, &args, params) - != 0) { - exit(EXIT_FAILURE); - } - } - if (args.vpn_given) { - zconf.send_ip_pkts = 1; - zconf.gw_mac_set = 1; - memset(zconf.gw_mac, 0, IFHWADDRLEN); - } - if (cmdline_parser_required(&args, CMDLINE_PARSER_PACKAGE) != 0) { - exit(EXIT_FAILURE); - } - // parse the provided probe and output module s.t. that we can support - // other command-line helpers (e.g. probe help) - if (!args.output_module_given) { - zconf.output_module = get_output_module_by_name("csv"); - zconf.raw_output_fields = (char*) "saddr"; - zconf.filter_duplicates = 1; - zconf.filter_unsuccessful = 1; - } else if (!strcmp(args.output_module_arg, "simple_file")) { - log_warn("zmap", "the simple_file output interface has been deprecated and " - "will be removed in the future. Users should use the csv " - "output module. Newer scan options such as output-fields " - "are not supported with this output module."); - zconf.output_module = get_output_module_by_name("csv"); - zconf.raw_output_fields = (char*) "saddr"; - zconf.filter_duplicates = 1; - zconf.filter_unsuccessful = 1; - } else if (!strcmp(args.output_module_arg, "extended_file")) { - log_warn("zmap", "the extended_file output interface has been deprecated and " - "will be removed in the future. Users should use the csv " - "output module. Newer scan options such as output-fields " - "are not supported with this output module."); - zconf.output_module = get_output_module_by_name("csv"); - zconf.raw_output_fields = (char*) "classification, saddr, " - "daddr, sport, dport, " - "seqnum, acknum, cooldown, " - "repeat, timestamp-str"; - zconf.filter_duplicates = 0; - } else { - zconf.output_module = get_output_module_by_name(args.output_module_arg); - if (!zconf.output_module) { - fprintf(stderr, "%s: specified output module (%s) does not exist\n", - CMDLINE_PARSER_PACKAGE, args.output_module_arg); - exit(EXIT_FAILURE); - } - } - zconf.probe_module = get_probe_module_by_name(args.probe_module_arg); - if (!zconf.probe_module) { - fprintf(stderr, "%s: specified probe module (%s) does not exist\n", - CMDLINE_PARSER_PACKAGE, args.probe_module_arg); - exit(EXIT_FAILURE); - } - - // now that we know the probe module, let's find what it supports - memset(&zconf.fsconf, 0, sizeof(struct fieldset_conf)); - // the set of fields made available to a user is constructed - // of IP header fields + probe module fields + system fields - fielddefset_t *fds = &(zconf.fsconf.defs); - gen_fielddef_set(fds, (fielddef_t*) &(ip_fields), - 4); - gen_fielddef_set(fds, zconf.probe_module->fields, - zconf.probe_module->numfields); - gen_fielddef_set(fds, (fielddef_t*) &(sys_fields), - 5); - if (args.list_output_fields_given) { - for (int i = 0; i < fds->len; i++) { - printf("%-15s %6s: %s\n", fds->fielddefs[i].name, - fds->fielddefs[i].type, - fds->fielddefs[i].desc); - } - exit(EXIT_SUCCESS); - } - // find the fields we need for the framework - zconf.fsconf.success_index = - fds_get_index_by_name(fds, (char*) "success"); - if (zconf.fsconf.success_index < 0) { - log_fatal("fieldset", "probe module does not supply " - "required success field."); - } - zconf.fsconf.classification_index = - fds_get_index_by_name(fds, (char*) "classification"); - if (zconf.fsconf.classification_index < 0) { - log_fatal("fieldset", "probe module does not supply " - "required packet classification field."); - } - // process the list of requested output fields. - if (args.output_fields_given) { - zconf.raw_output_fields = args.output_fields_arg; - } else if (!zconf.raw_output_fields) { - zconf.raw_output_fields = (char*) "saddr"; - } - split_string(zconf.raw_output_fields, &(zconf.output_fields_len), - &(zconf.output_fields)); - for (int i=0; i < zconf.output_fields_len; i++) { - log_debug("zmap", "requested output field (%i): %s", - i, - zconf.output_fields[i]); - } - // generate a translation that can be used to convert output - // from a probe module to the input for an output module - fs_generate_fieldset_translation(&zconf.fsconf.translation, - &zconf.fsconf.defs, zconf.output_fields, - zconf.output_fields_len); - - SET_BOOL(zconf.dryrun, dryrun); - SET_BOOL(zconf.quiet, quiet); - SET_BOOL(zconf.summary, summary); - zconf.cooldown_secs = args.cooldown_time_arg; - zconf.senders = args.sender_threads_arg; - SET_IF_GIVEN(zconf.output_filename, output_file); - SET_IF_GIVEN(zconf.blacklist_filename, blacklist_file); - SET_IF_GIVEN(zconf.whitelist_filename, whitelist_file); - SET_IF_GIVEN(zconf.probe_args, probe_args); - SET_IF_GIVEN(zconf.output_args, output_args); - SET_IF_GIVEN(zconf.iface, interface); - SET_IF_GIVEN(zconf.max_runtime, max_runtime); - SET_IF_GIVEN(zconf.max_results, max_results); - SET_IF_GIVEN(zconf.rate, rate); - SET_IF_GIVEN(zconf.packet_streams, probes); - - - if (zconf.probe_module->port_args) { - if (args.source_port_given) { - char *dash = strchr(args.source_port_arg, '-'); - if (dash) { // range - *dash = '\0'; - zconf.source_port_first = atoi(args.source_port_arg); - enforce_range("starting source-port", zconf.source_port_first, 0, 0xFFFF); - zconf.source_port_last = atoi(dash+1); - enforce_range("ending source-port", zconf.source_port_last, 0, 0xFFFF); - if (zconf.source_port_first > zconf.source_port_last) { - fprintf(stderr, "%s: invalid source port range: " - "last port is less than first port\n", - CMDLINE_PARSER_PACKAGE); - exit(EXIT_FAILURE); - } - } else { // single port - int port = atoi(args.source_port_arg); - enforce_range("source-port", port, 0, 0xFFFF); - zconf.source_port_first = port; - zconf.source_port_last = port; - } - } - if (!args.target_port_given) { - fprintf(stderr, "%s: target port is required for this type of probe\n", - CMDLINE_PARSER_PACKAGE); - exit(EXIT_FAILURE); - } - enforce_range("target-port", args.target_port_arg, 0, 0xFFFF); - zconf.target_port = args.target_port_arg; - } - if (args.source_ip_given) { - char *dash = strchr(args.source_ip_arg, '-'); - if (dash) { // range - *dash = '\0'; - zconf.source_ip_first = args.source_ip_arg; - zconf.source_ip_last = dash+1; - } else { // single address - zconf.source_ip_first = args.source_ip_arg; - zconf.source_ip_last = args.source_ip_arg; - } - } - if (args.gateway_mac_given) { - if (!parse_mac(zconf.gw_mac, args.gateway_mac_arg)) { - fprintf(stderr, "%s: invalid MAC address `%s'\n", - CMDLINE_PARSER_PACKAGE, args.gateway_mac_arg); - exit(EXIT_FAILURE); - } - zconf.gw_mac_set = 1; - } - if (args.seed_given) { - zconf.seed = args.seed_arg; - zconf.use_seed = 1; - } - if (args.bandwidth_given) { - // Supported: G,g=*1000000000; M,m=*1000000 K,k=*1000 bits per second - zconf.bandwidth = atoi(args.bandwidth_arg); - char *suffix = args.bandwidth_arg; - while (*suffix >= '0' && *suffix <= '9') { - suffix++; - } - if (*suffix) { - switch (*suffix) { - case 'G': case 'g': - zconf.bandwidth *= 1000000000; - break; - case 'M': case 'm': - zconf.bandwidth *= 1000000; - break; - case 'K': case 'k': - zconf.bandwidth *= 1000; - break; - default: - fprintf(stderr, "%s: unknown bandwidth suffix '%s' " - "(supported suffixes are G, M and K)\n", - CMDLINE_PARSER_PACKAGE, suffix); - exit(EXIT_FAILURE); - } - } - } - if (args.max_targets_given) { - errno = 0; - char *end; - double v = strtod(args.max_targets_arg, &end); - if (end == args.max_targets_arg || errno != 0) { - fprintf(stderr, "%s: can't convert max-targets to a number\n", - CMDLINE_PARSER_PACKAGE); - exit(EXIT_FAILURE); - } - if (end[0] == '%' && end[1] == '\0') { - // treat as percentage - v = v * ((unsigned long long int)1 << 32) / 100.; - } else if (end[0] != '\0') { - fprintf(stderr, "%s: extra characters after max-targets\n", - CMDLINE_PARSER_PACKAGE); - exit(EXIT_FAILURE); - } - if (v <= 0) { - zconf.max_targets = 0; - } - else if (v >= ((unsigned long long int)1 << 32)) { - zconf.max_targets = 0xFFFFFFFF; - } else { - zconf.max_targets = v; - } - } - - start_zmap(); - - cmdline_parser_free(&args); - free(params); - return EXIT_SUCCESS; -} - diff --git a/filter_sandbox/zmap.l b/src/zmap.l similarity index 96% rename from filter_sandbox/zmap.l rename to src/zmap.l index 4de7dff..dbae5d0 100644 --- a/filter_sandbox/zmap.l +++ b/src/zmap.l @@ -1,6 +1,6 @@ %{ #include -#include "y.tab.h" +#include "zmap.tab.h" %} %% diff --git a/filter_sandbox/zmap.y b/src/zmap.y similarity index 97% rename from filter_sandbox/zmap.y rename to src/zmap.y index fe196a1..63bb6be 100644 --- a/filter_sandbox/zmap.y +++ b/src/zmap.y @@ -1,7 +1,7 @@ %{ #include #include -#include "tree.h" +#include "expression.h" void yyerror(const char *str) { @@ -12,12 +12,7 @@ void yyerror(const char *str) int yywrap() { return 1; -} - -int main() -{ - yyparse(); -} +} %} From 8db9f260f2947e82861e56887ecb8065e4d36452 Mon Sep 17 00:00:00 2001 From: David Adrian Date: Thu, 19 Sep 2013 17:51:49 -0400 Subject: [PATCH 12/53] Mildly working build process with argument parsing --- lib/xalloc.c | 44 + lib/xalloc.h | 14 + src/expression.c | 7 +- src/filter.c | 25 + src/filter.h | 12 + src/lexer.c | 1784 ++++++++++++++++++++++++++++++++++++++ src/lexer.h | 330 +++++++ src/{zmap.l => lexer.l} | 5 +- src/parser.c | 630 ++++++++++++++ src/{zmap.y => parser.y} | 42 +- src/stack.c | 40 + src/stack.h | 15 + src/state.h | 2 + src/whitelist | 1 + src/y.tab.h | 20 + src/zmap.c | 1217 +++++++++++++------------- src/zopt.ggo | 3 + 17 files changed, 3578 insertions(+), 613 deletions(-) create mode 100644 lib/xalloc.c create mode 100644 lib/xalloc.h create mode 100644 src/filter.c create mode 100644 src/filter.h create mode 100644 src/lexer.c create mode 100644 src/lexer.h rename src/{zmap.l => lexer.l} (91%) create mode 100644 src/parser.c rename src/{zmap.y => parser.y} (65%) create mode 100644 src/stack.c create mode 100644 src/stack.h create mode 100644 src/whitelist create mode 100644 src/y.tab.h diff --git a/lib/xalloc.c b/lib/xalloc.c new file mode 100644 index 0000000..60e73e7 --- /dev/null +++ b/lib/xalloc.c @@ -0,0 +1,44 @@ +#include "xalloc.h" +#include "../lib/logger.h" + +#include + +void die() __attribute__((noreturn)); + +void* xcalloc(size_t count, size_t size) +{ + void* res = calloc(count, size); + if (res == NULL) { + die(); + } + return res; +} + +void xfree(void *ptr) +{ + free(ptr); +} + +void* xmalloc(size_t size) +{ + void* res = malloc(size); + if (res == NULL) { + die(); + } + return res; +} + +void* xrealloc(void *ptr, size_t size) +{ + void* res = realloc(ptr, size); + if (res == NULL) { + die(); + } + return res; +} + +void die() +{ + log_fatal("zmap", "Out of memory"); +} + diff --git a/lib/xalloc.h b/lib/xalloc.h new file mode 100644 index 0000000..78cd278 --- /dev/null +++ b/lib/xalloc.h @@ -0,0 +1,14 @@ +#ifndef ZMAP_ALLOC_H +#define ZMAP_ALLOC_H + +#include + +void* xcalloc(size_t count, size_t size); + +void xfree(void *ptr); + +void* xmalloc(size_t size); + +void* xrealloc(void *ptr, size_t size); + +#endif \ No newline at end of file diff --git a/src/expression.c b/src/expression.c index 76adc99..2536f48 100644 --- a/src/expression.c +++ b/src/expression.c @@ -1,8 +1,10 @@ -#include "tree.h" +#include "expression.h" + +#include "../lib/xalloc.h" node_t* alloc_node() { - node_t *node = (node_t*) malloc(sizeof(node_t)); + node_t *node = xmalloc(sizeof(node_t)); memset(node, 0, sizeof(node_t)); return node; } @@ -40,6 +42,7 @@ node_t* make_int_node(int literal) } int evaluate_expression(node_t *root) { + if (!root) return 0; int result = 1; return result; } diff --git a/src/filter.c b/src/filter.c new file mode 100644 index 0000000..cb500f1 --- /dev/null +++ b/src/filter.c @@ -0,0 +1,25 @@ +#include "filter.h" +#include "state.h" +#include "lexer.h" +#include "y.tab.h" +#include "../lib/logger.h" + +extern int yyparse(); + +node_t *zfilter; + +void 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_fatal("zmap", "Unable to parse filter"); + } + zconf.filter.expression = zfilter; + print_expression(zfilter); + printf("%s\n", ""); + fflush(stdout); + return; +} \ No newline at end of file diff --git a/src/filter.h b/src/filter.h new file mode 100644 index 0000000..14af688 --- /dev/null +++ b/src/filter.h @@ -0,0 +1,12 @@ +#ifndef ZMAP_FILTER_H +#define ZMAP_FILTER_H + +#include "expression.h" + +struct output_filter { + node_t *expression; +}; + +void parse_filter_string(char *filter); + +#endif /* ZMAP_FILTER_H */ \ No newline at end of file diff --git a/src/lexer.c b/src/lexer.c new file mode 100644 index 0000000..7172b5b --- /dev/null +++ b/src/lexer.c @@ -0,0 +1,1784 @@ + +#line 3 "" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 35 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +/* C99 requires __STDC__ to be defined as 1. */ +#if defined (__STDC__) + +#define YY_USE_CONST + +#endif /* defined (__STDC__) */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart(yyin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k. + * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. + * Ditto for the __ia64__ case accordingly. + */ +#define YY_BUF_SIZE 32768 +#else +#define YY_BUF_SIZE 16384 +#endif /* __ia64__ */ +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +extern int yyleng; + +extern FILE *yyin, *yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, (yytext_ptr) ) + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) + +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; +static int yy_n_chars; /* number of characters read into yy_ch_buf */ +int yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 0; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart (FILE *input_file ); +void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); +void yy_delete_buffer (YY_BUFFER_STATE b ); +void yy_flush_buffer (YY_BUFFER_STATE b ); +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); +void yypop_buffer_state (void ); + +static void yyensure_buffer_stack (void ); +static void yy_load_buffer_state (void ); +static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); + +#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) + +YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); +YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); +YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ); + +void *yyalloc (yy_size_t ); +void *yyrealloc (void *,yy_size_t ); +void yyfree (void * ); + +#define yy_new_buffer yy_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer(yyin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer(yyin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ + +typedef unsigned char YY_CHAR; + +FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; + +typedef int yy_state_type; + +extern int yylineno; + +int yylineno = 1; + +extern char *yytext; +#define yytext_ptr yytext + +static yy_state_type yy_get_previous_state (void ); +static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); +static int yy_get_next_buffer (void ); +static void yy_fatal_error (yyconst char msg[] ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ + yyleng = (size_t) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; + +#define YY_NUM_RULES 15 +#define YY_END_OF_BUFFER 16 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static yyconst flex_int16_t yy_accept[26] = + { 0, + 0, 0, 16, 15, 3, 2, 15, 15, 12, 13, + 1, 11, 9, 10, 15, 15, 3, 4, 7, 1, + 6, 5, 14, 8, 0 + } ; + +static yyconst flex_int32_t yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 4, 1, 1, 1, 1, 5, 1, 6, + 7, 1, 1, 1, 1, 1, 1, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 1, 1, 9, + 10, 11, 1, 1, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 1, 1, 1, 1, 1, 1, 12, 12, 12, 12, + + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 1, 13, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst flex_int32_t yy_meta[14] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, + 1, 2, 1 + } ; + +static yyconst flex_int16_t yy_base[27] = + { 0, + 0, 0, 24, 25, 21, 25, 12, 16, 25, 25, + 12, 9, 25, 8, 0, 4, 14, 25, 25, 7, + 25, 25, 0, 25, 25, 12 + } ; + +static yyconst flex_int16_t yy_def[27] = + { 0, + 25, 1, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 26, 25, 25, 25, 25, 25, + 25, 25, 26, 25, 0, 25 + } ; + +static yyconst flex_int16_t yy_nxt[39] = + { 0, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 23, 20, 17, 24, 22, 21, 20, + 19, 18, 17, 25, 3, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25 + } ; + +static yyconst flex_int16_t yy_chk[39] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 26, 20, 17, 16, 14, 12, 11, + 8, 7, 5, 3, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25 + } ; + +static yy_state_type yy_last_accepting_state; +static char *yy_last_accepting_cpos; + +extern int yy_flex_debug; +int yy_flex_debug = 0; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *yytext; +#line 1 "lexer.l" +#line 2 "lexer.l" +#include +#include "y.tab.h" + +#define YY_NO_INPUT 1 +#line 476 "" + +#define INITIAL 0 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +static int yy_init_globals (void ); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int yylex_destroy (void ); + +int yyget_debug (void ); + +void yyset_debug (int debug_flag ); + +YY_EXTRA_TYPE yyget_extra (void ); + +void yyset_extra (YY_EXTRA_TYPE user_defined ); + +FILE *yyget_in (void ); + +void yyset_in (FILE * in_str ); + +FILE *yyget_out (void ); + +void yyset_out (FILE * out_str ); + +int yyget_leng (void ); + +char *yyget_text (void ); + +int yyget_lineno (void ); + +void yyset_lineno (int line_number ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap (void ); +#else +extern int yywrap (void ); +#endif +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ); +#endif + +#ifndef YY_NO_INPUT + +#ifdef __cplusplus +static int yyinput (void ); +#else +static int input (void ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k */ +#define YY_READ_BUF_SIZE 16384 +#else +#define YY_READ_BUF_SIZE 8192 +#endif /* __ia64__ */ +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + size_t n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int yylex (void); + +#define YY_DECL int yylex (void) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + +#line 9 "lexer.l" + +#line 663 "" + + if ( !(yy_init) ) + { + (yy_init) = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer(yyin,YY_BUF_SIZE ); + } + + yy_load_buffer_state( ); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = (yy_c_buf_p); + + /* Support of yytext. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = (yy_start); +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 26 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 25 ); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + yy_act = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = (yy_hold_char); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + +case 1: +YY_RULE_SETUP +#line 10 "lexer.l" +yylval.int_literal = atoi(yytext); return T_NUMBER; + YY_BREAK +case 2: +/* rule 2 can match eol */ +YY_RULE_SETUP +#line 11 "lexer.l" +/* Ignore end of line */ + YY_BREAK +case 3: +YY_RULE_SETUP +#line 12 "lexer.l" +/* Ignore whitespace */ + YY_BREAK +case 4: +YY_RULE_SETUP +#line 13 "lexer.l" +return T_NOT_EQ; + YY_BREAK +case 5: +YY_RULE_SETUP +#line 14 "lexer.l" +return T_GT_EQ; + YY_BREAK +case 6: +YY_RULE_SETUP +#line 15 "lexer.l" +return T_LT_EQ; + YY_BREAK +case 7: +YY_RULE_SETUP +#line 16 "lexer.l" +return T_AND; + YY_BREAK +case 8: +YY_RULE_SETUP +#line 17 "lexer.l" +return T_OR; + YY_BREAK +case 9: +YY_RULE_SETUP +#line 18 "lexer.l" +return '='; + YY_BREAK +case 10: +YY_RULE_SETUP +#line 19 "lexer.l" +return '>'; + YY_BREAK +case 11: +YY_RULE_SETUP +#line 20 "lexer.l" +return '<'; + YY_BREAK +case 12: +YY_RULE_SETUP +#line 21 "lexer.l" +return '('; + YY_BREAK +case 13: +YY_RULE_SETUP +#line 22 "lexer.l" +return ')'; + YY_BREAK +case 14: +YY_RULE_SETUP +#line 23 "lexer.l" +yylval.string_literal = strdup(yytext); return T_FIELD; + YY_BREAK +case 15: +YY_RULE_SETUP +#line 25 "lexer.l" +ECHO; + YY_BREAK +#line 822 "" +case YY_STATE_EOF(INITIAL): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = (yy_c_buf_p); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( yywrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ +} /* end of yylex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (void) +{ + register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + register char *source = (yytext_ptr); + register int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + int num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER; + + int yy_c_buf_p_offset = + (int) ((yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), (size_t) num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart(yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + } + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (void) +{ + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = (yy_start); + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 26 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +{ + register int yy_is_jam; + register char *yy_cp = (yy_c_buf_p); + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 26 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 25); + + return yy_is_jam ? 0 : yy_current_state; +} + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (void) +#else + static int input (void) +#endif + +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + int offset = (yy_c_buf_p) - (yytext_ptr); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart(yyin ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap( ) ) + return EOF; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve yytext */ + (yy_hold_char) = *++(yy_c_buf_p); + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ + void yyrestart (FILE * input_file ) +{ + + if ( ! YY_CURRENT_BUFFER ){ + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer(yyin,YY_BUF_SIZE ); + } + + yy_init_buffer(YY_CURRENT_BUFFER,input_file ); + yy_load_buffer_state( ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ + void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) +{ + + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + yy_load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + +static void yy_load_buffer_state (void) +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer(b,file ); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * + */ + void yy_delete_buffer (YY_BUFFER_STATE b ) +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yyfree((void *) b->yy_ch_buf ); + + yyfree((void *) b ); +} + +#ifndef __cplusplus +extern int isatty (int ); +#endif /* __cplusplus */ + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ + static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) + +{ + int oerrno = errno; + + yy_flush_buffer(b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ + void yy_flush_buffer (YY_BUFFER_STATE b ) +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + yy_load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) +{ + if (new_buffer == NULL) + return; + + yyensure_buffer_stack(); + + /* This block is copied from yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void yypop_buffer_state (void) +{ + if (!YY_CURRENT_BUFFER) + return; + + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void yyensure_buffer_stack (void) +{ + int num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer(b ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to yylex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * yy_scan_bytes() instead. + */ +YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) +{ + + return yy_scan_bytes(yystr,strlen(yystr) ); +} + +/** Setup the input buffer state to scan the given bytes. The next call to yylex() will + * scan from a @e copy of @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len ) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = _yybytes_len + 2; + buf = (char *) yyalloc(n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer(buf,n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yy_fatal_error (yyconst char* msg ) +{ + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = (yy_hold_char); \ + (yy_c_buf_p) = yytext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the current line number. + * + */ +int yyget_lineno (void) +{ + + return yylineno; +} + +/** Get the input stream. + * + */ +FILE *yyget_in (void) +{ + return yyin; +} + +/** Get the output stream. + * + */ +FILE *yyget_out (void) +{ + return yyout; +} + +/** Get the length of the current token. + * + */ +int yyget_leng (void) +{ + return yyleng; +} + +/** Get the current token. + * + */ + +char *yyget_text (void) +{ + return yytext; +} + +/** Set the current line number. + * @param line_number + * + */ +void yyset_lineno (int line_number ) +{ + + yylineno = line_number; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param in_str A readable stream. + * + * @see yy_switch_to_buffer + */ +void yyset_in (FILE * in_str ) +{ + yyin = in_str ; +} + +void yyset_out (FILE * out_str ) +{ + yyout = out_str ; +} + +int yyget_debug (void) +{ + return yy_flex_debug; +} + +void yyset_debug (int bdebug ) +{ + yy_flex_debug = bdebug ; +} + +static int yy_init_globals (void) +{ + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from yylex_destroy(), so don't allocate here. + */ + + (yy_buffer_stack) = 0; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + (yy_c_buf_p) = (char *) 0; + (yy_init) = 0; + (yy_start) = 0; + +/* Defined in main.c */ +#ifdef YY_STDINIT + yyin = stdin; + yyout = stdout; +#else + yyin = (FILE *) 0; + yyout = (FILE *) 0; +#endif + + /* For future reference: Set errno on error, since we are called by + * yylex_init() + */ + return 0; +} + +/* yylex_destroy is for both reentrant and non-reentrant scanners. */ +int yylex_destroy (void) +{ + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + yypop_buffer_state(); + } + + /* Destroy the stack itself. */ + yyfree((yy_buffer_stack) ); + (yy_buffer_stack) = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * yylex() is called, initialization will occur. */ + yy_init_globals( ); + + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) +{ + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * s ) +{ + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *yyalloc (yy_size_t size ) +{ + return (void *) malloc( size ); +} + +void *yyrealloc (void * ptr, yy_size_t size ) +{ + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); +} + +void yyfree (void * ptr ) +{ + free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#line 25 "lexer.l" + + diff --git a/src/lexer.h b/src/lexer.h new file mode 100644 index 0000000..42a19e9 --- /dev/null +++ b/src/lexer.h @@ -0,0 +1,330 @@ +#ifndef yyHEADER_H +#define yyHEADER_H 1 +#define yyIN_HEADER 1 + +#line 6 "lexer.h" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 35 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +/* C99 requires __STDC__ to be defined as 1. */ +#if defined (__STDC__) + +#define YY_USE_CONST + +#endif /* defined (__STDC__) */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k. + * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. + * Ditto for the __ia64__ case accordingly. + */ +#define YY_BUF_SIZE 32768 +#else +#define YY_BUF_SIZE 16384 +#endif /* __ia64__ */ +#endif + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +extern int yyleng; + +extern FILE *yyin, *yyout; + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +void yyrestart (FILE *input_file ); +void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); +void yy_delete_buffer (YY_BUFFER_STATE b ); +void yy_flush_buffer (YY_BUFFER_STATE b ); +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); +void yypop_buffer_state (void ); + +YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); +YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); +YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ); + +void *yyalloc (yy_size_t ); +void *yyrealloc (void *,yy_size_t ); +void yyfree (void * ); + +/* Begin user sect3 */ + +extern int yylineno; + +extern char *yytext; +#define yytext_ptr yytext + +#ifdef YY_HEADER_EXPORT_START_CONDITIONS +#define INITIAL 0 + +#endif + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int yylex_destroy (void ); + +int yyget_debug (void ); + +void yyset_debug (int debug_flag ); + +YY_EXTRA_TYPE yyget_extra (void ); + +void yyset_extra (YY_EXTRA_TYPE user_defined ); + +FILE *yyget_in (void ); + +void yyset_in (FILE * in_str ); + +FILE *yyget_out (void ); + +void yyset_out (FILE * out_str ); + +int yyget_leng (void ); + +char *yyget_text (void ); + +int yyget_lineno (void ); + +void yyset_lineno (int line_number ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap (void ); +#else +extern int yywrap (void ); +#endif +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ); +#endif + +#ifndef YY_NO_INPUT + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k */ +#define YY_READ_BUF_SIZE 16384 +#else +#define YY_READ_BUF_SIZE 8192 +#endif /* __ia64__ */ +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int yylex (void); + +#define YY_DECL int yylex (void) +#endif /* !YY_DECL */ + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + +#undef YY_NEW_FILE +#undef YY_FLUSH_BUFFER +#undef yy_set_bol +#undef yy_new_buffer +#undef yy_set_interactive +#undef YY_DO_BEFORE_ACTION + +#ifdef YY_DECL_IS_OURS +#undef YY_DECL_IS_OURS +#undef YY_DECL +#endif + +#line 25 "lexer.l" + + +#line 329 "lexer.h" +#undef yyIN_HEADER +#endif /* yyHEADER_H */ diff --git a/src/zmap.l b/src/lexer.l similarity index 91% rename from src/zmap.l rename to src/lexer.l index dbae5d0..63696b2 100644 --- a/src/zmap.l +++ b/src/lexer.l @@ -1,8 +1,11 @@ %{ #include -#include "zmap.tab.h" +#include "y.tab.h" + %} +%option noinput +%option nounput %% [0-9]+ yylval.int_literal = atoi(yytext); return T_NUMBER; \n /* Ignore end of line */ diff --git a/src/parser.c b/src/parser.c new file mode 100644 index 0000000..86802d1 --- /dev/null +++ b/src/parser.c @@ -0,0 +1,630 @@ +#ifndef lint +static const char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93"; +#endif + +#define YYBYACC 1 +#define YYMAJOR 1 +#define YYMINOR 9 +#define YYPATCH 20120115 + +#define YYEMPTY (-1) +#define yyclearin (yychar = YYEMPTY) +#define yyerrok (yyerrflag = 0) +#define YYRECOVERING() (yyerrflag != 0) + +#define YYPREFIX "yy" + +#define YYPURE 0 + +#line 2 "parser.y" +#include +#include +#include "expression.h" +#include "lexer.h" +#include "filter.h" + +void yyerror(const char *str) +{ + fprintf(stderr,"error: %s\n",str); + fprintf(stderr, "%s\n", "YOLO"); +} + +int yywrap() +{ + return 1; +} + +extern node_t *zfilter; + +#line 23 "parser.y" +#ifdef YYSTYPE +#undef YYSTYPE_IS_DECLARED +#define YYSTYPE_IS_DECLARED 1 +#endif +#ifndef YYSTYPE_IS_DECLARED +#define YYSTYPE_IS_DECLARED 1 +typedef union { + int int_literal; + char *string_literal; + struct node *expr; +} YYSTYPE; +#endif /* !YYSTYPE_IS_DECLARED */ +#line 52 "y.tab.c" + +/* compatibility with bison */ +#ifdef YYPARSE_PARAM +/* compatibility with FreeBSD */ +# ifdef YYPARSE_PARAM_TYPE +# define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM) +# else +# define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM) +# endif +#else +# define YYPARSE_DECL() yyparse(void) +#endif + +/* Parameters sent to lex. */ +#ifdef YYLEX_PARAM +# define YYLEX_DECL() yylex(void *YYLEX_PARAM) +# define YYLEX yylex(YYLEX_PARAM) +#else +# define YYLEX_DECL() yylex(void) +# define YYLEX yylex() +#endif + +/* Parameters sent to yyerror. */ +#ifndef YYERROR_DECL +#define YYERROR_DECL() yyerror(const char *s) +#endif +#ifndef YYERROR_CALL +#define YYERROR_CALL(msg) yyerror(msg) +#endif + +extern int YYPARSE_DECL(); + +#define T_AND 257 +#define T_OR 258 +#define T_NUMBER 259 +#define T_FIELD 260 +#define T_NOT_EQ 261 +#define T_GT_EQ 262 +#define T_LT_EQ 263 +#define YYERRCODE 256 +static const short yylhs[] = { -1, + 0, 4, 4, 4, 4, 1, 1, 2, 2, 2, + 2, 2, 2, 3, 3, +}; +static const short yylen[] = { 2, + 1, 3, 3, 3, 1, 1, 1, 3, 3, 3, + 3, 3, 3, 3, 3, +}; +static const short yydefred[] = { 0, + 0, 0, 0, 5, 6, 7, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 4, 11, 15, 12, + 9, 10, 8, 14, 13, 3, 0, +}; +static const short yydgoto[] = { 3, + 4, 5, 6, 7, +}; +static const short yysindex[] = { -40, + -40, -57, 0, 0, 0, 0, -250, -39, -249, -245, + -244, -243, -247, -242, -40, -40, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, -248, +}; +static const short yyrindex[] = { 0, + 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, +}; +static const short yygindex[] = { 0, + 0, 0, 0, 5, +}; +#define YYTABLESIZE 259 +static const short yytable[] = { 1, + 2, 17, 12, 13, 11, 8, 15, 16, 15, 18, + 19, 23, 24, 20, 21, 22, 25, 1, 0, 26, + 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 10, 14, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 15, 16, 2, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 2, +}; +static const short yycheck[] = { 40, + 0, 41, 60, 61, 62, 1, 257, 258, 257, 259, + 260, 259, 260, 259, 259, 259, 259, 0, -1, 15, + 16, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 41, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 261, 262, 263, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 257, 258, 260, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 258, +}; +#define YYFINAL 3 +#ifndef YYDEBUG +#define YYDEBUG 0 +#endif +#define YYMAXTOKEN 263 +#if YYDEBUG +static const char *yyname[] = { + +"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,"'('","')'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'<'","'='","'>'",0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"T_AND", +"T_OR","T_NUMBER","T_FIELD","T_NOT_EQ","T_GT_EQ","T_LT_EQ", +}; +static const char *yyrule[] = { +"$accept : expression", +"expression : filter_expr", +"filter_expr : filter_expr T_OR filter_expr", +"filter_expr : filter_expr T_AND filter_expr", +"filter_expr : '(' filter_expr ')'", +"filter_expr : filter", +"filter : number_filter", +"filter : string_filter", +"number_filter : T_FIELD '=' T_NUMBER", +"number_filter : T_FIELD '>' T_NUMBER", +"number_filter : T_FIELD '<' T_NUMBER", +"number_filter : T_FIELD T_NOT_EQ T_NUMBER", +"number_filter : T_FIELD T_GT_EQ T_NUMBER", +"number_filter : T_FIELD T_LT_EQ T_NUMBER", +"string_filter : T_FIELD '=' T_FIELD", +"string_filter : T_FIELD T_NOT_EQ T_FIELD", + +}; +#endif + +int yydebug; +int yynerrs; + +int yyerrflag; +int yychar; +YYSTYPE yyval; +YYSTYPE yylval; + +/* define the initial stack-sizes */ +#ifdef YYSTACKSIZE +#undef YYMAXDEPTH +#define YYMAXDEPTH YYSTACKSIZE +#else +#ifdef YYMAXDEPTH +#define YYSTACKSIZE YYMAXDEPTH +#else +#define YYSTACKSIZE 500 +#define YYMAXDEPTH 500 +#endif +#endif + +#define YYINITSTACKSIZE 500 + +typedef struct { + unsigned stacksize; + short *s_base; + short *s_mark; + short *s_last; + YYSTYPE *l_base; + YYSTYPE *l_mark; +} YYSTACKDATA; +/* variables for the parser stack */ +static YYSTACKDATA yystack; +#line 144 "parser.y" + + +#line 253 "y.tab.c" + +#if YYDEBUG +#include /* needed for printf */ +#endif + +#include /* needed for malloc, etc */ +#include /* needed for memset */ + +/* allocate initial stack or double stack size, up to YYMAXDEPTH */ +static int yygrowstack(YYSTACKDATA *data) +{ + int i; + unsigned newsize; + short *newss; + YYSTYPE *newvs; + + if ((newsize = data->stacksize) == 0) + newsize = YYINITSTACKSIZE; + else if (newsize >= YYMAXDEPTH) + return -1; + else if ((newsize *= 2) > YYMAXDEPTH) + newsize = YYMAXDEPTH; + + i = data->s_mark - data->s_base; + newss = (short *)realloc(data->s_base, newsize * sizeof(*newss)); + if (newss == 0) + return -1; + + data->s_base = newss; + data->s_mark = newss + i; + + newvs = (YYSTYPE *)realloc(data->l_base, newsize * sizeof(*newvs)); + if (newvs == 0) + return -1; + + data->l_base = newvs; + data->l_mark = newvs + i; + + data->stacksize = newsize; + data->s_last = data->s_base + newsize - 1; + return 0; +} + +#if YYPURE || defined(YY_NO_LEAKS) +static void yyfreestack(YYSTACKDATA *data) +{ + free(data->s_base); + free(data->l_base); + memset(data, 0, sizeof(*data)); +} +#else +#define yyfreestack(data) /* nothing */ +#endif + +#define YYABORT goto yyabort +#define YYREJECT goto yyabort +#define YYACCEPT goto yyaccept +#define YYERROR goto yyerrlab + +int +YYPARSE_DECL() +{ + int yym, yyn, yystate; +#if YYDEBUG + const char *yys; + + if ((yys = getenv("YYDEBUG")) != 0) + { + yyn = *yys; + if (yyn >= '0' && yyn <= '9') + yydebug = yyn - '0'; + } +#endif + + yynerrs = 0; + yyerrflag = 0; + yychar = YYEMPTY; + yystate = 0; + +#if YYPURE + memset(&yystack, 0, sizeof(yystack)); +#endif + + if (yystack.s_base == NULL && yygrowstack(&yystack)) goto yyoverflow; + yystack.s_mark = yystack.s_base; + yystack.l_mark = yystack.l_base; + yystate = 0; + *yystack.s_mark = 0; + +yyloop: + if ((yyn = yydefred[yystate]) != 0) goto yyreduce; + if (yychar < 0) + { + if ((yychar = YYLEX) < 0) yychar = 0; +#if YYDEBUG + if (yydebug) + { + yys = 0; + if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; + if (!yys) yys = "illegal-symbol"; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + } + if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, shifting to state %d\n", + YYPREFIX, yystate, yytable[yyn]); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + yychar = YYEMPTY; + if (yyerrflag > 0) --yyerrflag; + goto yyloop; + } + if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { + yyn = yytable[yyn]; + goto yyreduce; + } + if (yyerrflag) goto yyinrecovery; + + yyerror("syntax error"); + + goto yyerrlab; + +yyerrlab: + ++yynerrs; + +yyinrecovery: + if (yyerrflag < 3) + { + yyerrflag = 3; + for (;;) + { + if ((yyn = yysindex[*yystack.s_mark]) && (yyn += YYERRCODE) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, error recovery shifting\ + to state %d\n", YYPREFIX, *yystack.s_mark, yytable[yyn]); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + goto yyloop; + } + else + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: error recovery discarding state %d\n", + YYPREFIX, *yystack.s_mark); +#endif + if (yystack.s_mark <= yystack.s_base) goto yyabort; + --yystack.s_mark; + --yystack.l_mark; + } + } + } + else + { + if (yychar == 0) goto yyabort; +#if YYDEBUG + if (yydebug) + { + yys = 0; + if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; + if (!yys) yys = "illegal-symbol"; + printf("%sdebug: state %d, error recovery discards token %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + yychar = YYEMPTY; + goto yyloop; + } + +yyreduce: +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, reducing by rule %d (%s)\n", + YYPREFIX, yystate, yyn, yyrule[yyn]); +#endif + yym = yylen[yyn]; + if (yym) + yyval = yystack.l_mark[1-yym]; + else + memset(&yyval, 0, sizeof yyval); + switch (yyn) + { +case 1: +#line 46 "parser.y" + { + zfilter = yystack.l_mark[0].expr; + } +break; +case 2: +#line 53 "parser.y" + { + yyval.expr = make_op_node(OR); + yyval.expr->left_child = yystack.l_mark[-2].expr; + yyval.expr->right_child = yystack.l_mark[0].expr; + } +break; +case 3: +#line 59 "parser.y" + { + yyval.expr = make_op_node(AND); + yyval.expr->left_child = yystack.l_mark[-2].expr; + yyval.expr->right_child = yystack.l_mark[0].expr; + } +break; +case 4: +#line 65 "parser.y" + { + yyval.expr = yystack.l_mark[-1].expr; + } +break; +case 5: +#line 69 "parser.y" + { + yyval.expr = yystack.l_mark[0].expr; + } +break; +case 6: +#line 75 "parser.y" + { + yyval.expr = yystack.l_mark[0].expr; + } +break; +case 7: +#line 79 "parser.y" + { + yyval.expr = yystack.l_mark[0].expr; + } +break; +case 8: +#line 85 "parser.y" + { + yyval.expr = make_op_node(EQ); + yyval.expr->left_child = make_field_node(yystack.l_mark[-2].string_literal); + yyval.expr->right_child = make_int_node(yystack.l_mark[0].int_literal); + } +break; +case 9: +#line 92 "parser.y" + { + yyval.expr = make_op_node(GT); + yyval.expr->left_child = make_field_node(yystack.l_mark[-2].string_literal); + yyval.expr->right_child = make_int_node(yystack.l_mark[0].int_literal); + } +break; +case 10: +#line 99 "parser.y" + { + yyval.expr = make_op_node(LT); + yyval.expr->left_child = make_field_node(yystack.l_mark[-2].string_literal); + yyval.expr->right_child = make_int_node(yystack.l_mark[0].int_literal); + } +break; +case 11: +#line 106 "parser.y" + { + yyval.expr = make_op_node(NEQ); + yyval.expr->left_child = make_field_node(yystack.l_mark[-2].string_literal); + yyval.expr->right_child = make_int_node(yystack.l_mark[0].int_literal); + } +break; +case 12: +#line 113 "parser.y" + { + yyval.expr = make_op_node(GT_EQ); + yyval.expr->left_child = make_field_node(yystack.l_mark[-2].string_literal); + yyval.expr->right_child = make_int_node(yystack.l_mark[0].int_literal); + } +break; +case 13: +#line 120 "parser.y" + { + yyval.expr = make_op_node(LT_EQ); + yyval.expr->left_child = make_field_node(yystack.l_mark[-2].string_literal); + yyval.expr->right_child = make_int_node(yystack.l_mark[0].int_literal); + } +break; +case 14: +#line 129 "parser.y" + { + yyval.expr = make_op_node(EQ); + yyval.expr->left_child = make_field_node(yystack.l_mark[-2].string_literal); + yyval.expr->right_child = make_field_node(yystack.l_mark[0].string_literal); + } +break; +case 15: +#line 136 "parser.y" + { + yyval.expr = make_op_node(NEQ); + yyval.expr->left_child = make_field_node(yystack.l_mark[-2].string_literal); + yyval.expr->right_child = make_field_node(yystack.l_mark[0].string_literal); + } +break; +#line 569 "y.tab.c" + } + yystack.s_mark -= yym; + yystate = *yystack.s_mark; + yystack.l_mark -= yym; + yym = yylhs[yyn]; + if (yystate == 0 && yym == 0) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state 0 to\ + state %d\n", YYPREFIX, YYFINAL); +#endif + yystate = YYFINAL; + *++yystack.s_mark = YYFINAL; + *++yystack.l_mark = yyval; + if (yychar < 0) + { + if ((yychar = YYLEX) < 0) yychar = 0; +#if YYDEBUG + if (yydebug) + { + yys = 0; + if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; + if (!yys) yys = "illegal-symbol"; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, YYFINAL, yychar, yys); + } +#endif + } + if (yychar == 0) goto yyaccept; + goto yyloop; + } + if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yystate) + yystate = yytable[yyn]; + else + yystate = yydgoto[yym]; +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state %d \ +to state %d\n", YYPREFIX, *yystack.s_mark, yystate); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + *++yystack.s_mark = (short) yystate; + *++yystack.l_mark = yyval; + goto yyloop; + +yyoverflow: + yyerror("yacc stack overflow"); + +yyabort: + yyfreestack(&yystack); + return (1); + +yyaccept: + yyfreestack(&yystack); + return (0); +} diff --git a/src/zmap.y b/src/parser.y similarity index 65% rename from src/zmap.y rename to src/parser.y index 63bb6be..941992d 100644 --- a/src/zmap.y +++ b/src/parser.y @@ -2,7 +2,9 @@ #include #include #include "expression.h" - +#include "lexer.h" +#include "filter.h" + void yyerror(const char *str) { fprintf(stderr,"error: %s\n",str); @@ -14,6 +16,8 @@ int yywrap() return 1; } +extern node_t *zfilter; + %} %union { @@ -38,22 +42,24 @@ int yywrap() %% +expression: filter_expr + { + zfilter = $1; + } + + filter_expr: filter_expr T_OR filter_expr { $$ = make_op_node(OR); $$->left_child = $1; $$->right_child = $3; - print_expression($$); - printf("%s\n", ""); } | filter_expr T_AND filter_expr { $$ = make_op_node(AND); $$->left_child = $1; $$->right_child = $3; - print_expression($$); - printf("%s\n", ""); } | '(' filter_expr ')' { @@ -77,7 +83,6 @@ filter: number_filter number_filter: T_FIELD '=' T_NUMBER { - printf("number_filter: %s = %d\n", $1, $3); $$ = make_op_node(EQ); $$->left_child = make_field_node($1); $$->right_child = make_int_node($3); @@ -85,7 +90,6 @@ number_filter: T_FIELD '=' T_NUMBER | T_FIELD '>' T_NUMBER { - printf("number_filter: %s > %d\n", $1, $3); $$ = make_op_node(GT); $$->left_child = make_field_node($1); $$->right_child = make_int_node($3); @@ -93,34 +97,46 @@ number_filter: T_FIELD '=' T_NUMBER | T_FIELD '<' T_NUMBER { - printf("number_filter: %s < %d\n", $1, $3); + $$ = make_op_node(LT); + $$->left_child = make_field_node($1); + $$->right_child = make_int_node($3); } | T_FIELD T_NOT_EQ T_NUMBER { - printf("number_filter: %s != %d\n", $1, $3); + $$ = make_op_node(NEQ); + $$->left_child = make_field_node($1); + $$->right_child = make_int_node($3); } | T_FIELD T_GT_EQ T_NUMBER { - printf("number_filter: %s >= %d\n", $1, $3); + $$ = make_op_node(GT_EQ); + $$->left_child = make_field_node($1); + $$->right_child = make_int_node($3); } | T_FIELD T_LT_EQ T_NUMBER { - printf("number_filter: %s <= %d\n", $1, $3); + $$ = make_op_node(LT_EQ); + $$->left_child = make_field_node($1); + $$->right_child = make_int_node($3); } ; string_filter: T_FIELD '=' T_FIELD { - printf("string_filter %s = %s\n", $1, $3); + $$ = make_op_node(EQ); + $$->left_child = make_field_node($1); + $$->right_child = make_field_node($3); } | T_FIELD T_NOT_EQ T_FIELD { - printf("string_filter: %s != %s\n", $1, $3); + $$ = make_op_node(NEQ); + $$->left_child = make_field_node($1); + $$->right_child = make_field_node($3); } ; diff --git a/src/stack.c b/src/stack.c new file mode 100644 index 0000000..dd98876 --- /dev/null +++ b/src/stack.c @@ -0,0 +1,40 @@ +#include "stack.h" +#include "../lib/xalloc.h" + +#include + +struct stack { + size_t max_size; + size_t cur_size; + void** arr; +}; + +stack_t* alloc_stack(size_t size) +{ + stack_t* stack = xmalloc(sizeof(stack_t)); + stack->arr = xcalloc(size, sizeof(void*)); + stack->max_size = size; + stack->cur_size = 0; + return stack; +} + +void free_stack(stack_t* stack) +{ + xfree(stack->arr); + xfree(stack); +} + +void push(stack_t* stack, void* elt) +{ + if (stack->cur_size == stack->max_size) { + stack->max_size *= 2; + xrealloc(stack->arr, stack->max_size);; + } + stack->arr[stack->cur_size++] = elt; +} + +void* pop(stack_t* stack) +{ + void* res = stack->arr[--stack->cur_size]; + return res; +} diff --git a/src/stack.h b/src/stack.h new file mode 100644 index 0000000..9417238 --- /dev/null +++ b/src/stack.h @@ -0,0 +1,15 @@ +#ifndef ZMAP_STACK_H +#define ZMAP_STACK_H + +#include + +struct stack; +typedef struct stack stack_t; + +stack_t* alloc_stack(size_t size); +void free_stack(stack_t* stack); + +void push(stack_t* stack, void* elt); +void* pop(stack_t* stack); + +#endif /* ZMAP_STACK_H */ \ No newline at end of file diff --git a/src/state.h b/src/state.h index 5bd3f75..7cb3492 100644 --- a/src/state.h +++ b/src/state.h @@ -15,6 +15,7 @@ #include "types.h" #include "fieldset.h" +#include "filter.h" #ifndef STATE_H #define STATE_H @@ -79,6 +80,7 @@ struct state_conf { char *whitelist_filename; char *raw_output_fields; char **output_fields; + struct output_filter filter; struct fieldset_conf fsconf; int output_fields_len; int dryrun; diff --git a/src/whitelist b/src/whitelist new file mode 100644 index 0000000..aab8f1d --- /dev/null +++ b/src/whitelist @@ -0,0 +1 @@ +192.168.1.0/24 diff --git a/src/y.tab.h b/src/y.tab.h new file mode 100644 index 0000000..8f8af3a --- /dev/null +++ b/src/y.tab.h @@ -0,0 +1,20 @@ +#define T_AND 257 +#define T_OR 258 +#define T_NUMBER 259 +#define T_FIELD 260 +#define T_NOT_EQ 261 +#define T_GT_EQ 262 +#define T_LT_EQ 263 +#ifdef YYSTYPE +#undef YYSTYPE_IS_DECLARED +#define YYSTYPE_IS_DECLARED 1 +#endif +#ifndef YYSTYPE_IS_DECLARED +#define YYSTYPE_IS_DECLARED 1 +typedef union { + int int_literal; + char *string_literal; + struct node *expr; +} YYSTYPE; +#endif /* !YYSTYPE_IS_DECLARED */ +extern YYSTYPE yylval; diff --git a/src/zmap.c b/src/zmap.c index 9fe5b2c..d424134 100644 --- a/src/zmap.c +++ b/src/zmap.c @@ -1,613 +1,636 @@ -#ifndef lint -static const char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93"; -#endif +/* + * 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 + */ -#define YYBYACC 1 -#define YYMAJOR 1 -#define YYMINOR 9 -#define YYPATCH 20120115 +#define _GNU_SOURCE -#define YYEMPTY (-1) -#define yyclearin (yychar = YYEMPTY) -#define yyerrok (yyerrflag = 0) -#define YYRECOVERING() (yyerrflag != 0) - -#define YYPREFIX "yy" - -#define YYPURE 0 - -#line 2 "zmap.y" +#include #include #include -#include "expression.h" - -void yyerror(const char *str) +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include "../lib/logger.h" +#include "../lib/random.h" + +#include "zopt.h" +#include "send.h" +#include "recv.h" +#include "state.h" +#include "monitor.h" +#include "get_gateway.h" +#include "filter.h" + +#include "output_modules/output_modules.h" +#include "probe_modules/probe_modules.h" + +pthread_mutex_t cpu_affinity_mutex = PTHREAD_MUTEX_INITIALIZER; +pthread_mutex_t recv_ready_mutex = PTHREAD_MUTEX_INITIALIZER; + +// splits comma delimited string into char*[]. Does not handle +// escaping or complicated setups: designed to process a set +// of fields that the user wants output +static void split_string(char* in, int *len, char***results) { - fprintf(stderr,"error: %s\n",str); - fprintf(stderr, "%s\n", "YOLO"); + char** fields = calloc(MAX_FIELDS, sizeof(char*)); + memset(fields, 0, MAX_FIELDS*sizeof(fields)); + int retvlen = 0; + char *currloc = in; + // parse csv into a set of strings + while (1) { + size_t len = strcspn(currloc, ", "); + if (len == 0) { + currloc++; + } else { + char *new = malloc(len+1); + assert(new); + strncpy(new, currloc, len); + new[len] = '\0'; + fields[retvlen++] = new; + assert(fields[retvlen-1]); + } + if (len == strlen(currloc)) { + break; + } + currloc += len; + } + *results = fields; + *len = retvlen; } - -int yywrap() + +static void set_cpu(void) { + pthread_mutex_lock(&cpu_affinity_mutex); + static int core=0; + int num_cores = sysconf(_SC_NPROCESSORS_ONLN); + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + CPU_SET(core, &cpuset); + if (pthread_setaffinity_np(pthread_self(), + sizeof(cpu_set_t), &cpuset) != 0) { + log_error("zmap", "can't set thread CPU affinity"); + } + log_trace("zmap", "set thread %u affinity to core %d", + pthread_self(), core); + core = (core + 1) % num_cores; + pthread_mutex_unlock(&cpu_affinity_mutex); +} + +static void* start_send(void *arg) +{ + uintptr_t v = (uintptr_t) arg; + int sock = (int) v & 0xFFFF; + set_cpu(); + send_run(sock); + return NULL; +} + +static void* start_recv(__attribute__((unused)) void *arg) +{ + set_cpu(); + recv_run(&recv_ready_mutex); + return NULL; +} + +static void drop_privs() +{ + struct passwd *pw; + if ((pw = getpwnam("nobody")) != NULL) { + if (setuid(pw->pw_uid) == 0) { + return; // success + } + } + log_fatal("zmap", "Couldn't change UID to 'nobody'"); +} + +static void *start_mon(__attribute__((unused)) void *arg) +{ + set_cpu(); + monitor_run(); + return NULL; +} + +#define SI(w,x,y) printf("%s\t%s\t%i\n", w, x, y); +#define SD(w,x,y) printf("%s\t%s\t%f\n", w, x, y); +#define SU(w,x,y) printf("%s\t%s\t%u\n", w, x, y); +#define SLU(w,x,y) printf("%s\t%s\t%lu\n", w, x, (long unsigned int) y); +#define SS(w,x,y) printf("%s\t%s\t%s\n", w, x, y); +#define STRTIME_LEN 1024 + +static void summary(void) +{ + char send_start_time[STRTIME_LEN+1]; + assert(dstrftime(send_start_time, STRTIME_LEN, "%c", zsend.start)); + char send_end_time[STRTIME_LEN+1]; + assert(dstrftime(send_end_time, STRTIME_LEN, "%c", zsend.finish)); + char recv_start_time[STRTIME_LEN+1]; + assert(dstrftime(recv_start_time, STRTIME_LEN, "%c", zrecv.start)); + char recv_end_time[STRTIME_LEN+1]; + assert(dstrftime(recv_end_time, STRTIME_LEN, "%c", zrecv.finish)); + double hitrate = ((double) 100 * zrecv.success_unique)/((double)zsend.sent); + + SU("cnf", "target-port", zconf.target_port); + SU("cnf", "source-port-range-begin", zconf.source_port_first); + SU("cnf", "source-port-range-end", zconf.source_port_last); + SS("cnf", "source-addr-range-begin", zconf.source_ip_first); + SS("cnf", "source-addr-range-end", zconf.source_ip_last); + SU("cnf", "maximum-targets", zconf.max_targets); + SU("cnf", "maximum-runtime", zconf.max_runtime); + SU("cnf", "maximum-results", zconf.max_results); + SU("cnf", "permutation-seed", zconf.seed); + SI("cnf", "cooldown-period", zconf.cooldown_secs); + SS("cnf", "send-interface", zconf.iface); + SI("cnf", "rate", zconf.rate); + SLU("cnf", "bandwidth", zconf.bandwidth); + SU("env", "nprocessors", (unsigned) sysconf(_SC_NPROCESSORS_ONLN)); + SS("exc", "send-start-time", send_start_time); + SS("exc", "send-end-time", send_end_time); + SS("exc", "recv-start-time", recv_start_time); + SS("exc", "recv-end-time", recv_end_time); + SU("exc", "sent", zsend.sent); + SU("exc", "blacklisted", zsend.blacklisted); + SU("exc", "first-scanned", zsend.first_scanned); + SD("exc", "hit-rate", hitrate); + SU("exc", "success-total", zrecv.success_total); + SU("exc", "success-unique", zrecv.success_unique); + SU("exc", "success-cooldown-total", zrecv.cooldown_total); + SU("exc", "success-cooldown-unique", zrecv.cooldown_unique); + SU("exc", "failure-total", zrecv.failure_total); + SU("exc", "sendto-failures", zsend.sendto_failures); + SU("adv", "permutation-gen", zconf.generator); + SS("exc", "scan-type", zconf.probe_module->name); +} + +static void start_zmap(void) +{ + log_info("zmap", "started"); + + // finish setting up configuration + if (zconf.iface == NULL) { + char errbuf[PCAP_ERRBUF_SIZE]; + char *iface = pcap_lookupdev(errbuf); + if (iface == NULL) { + log_fatal("zmap", "could not detect default network interface " + "(e.g. eth0). Try running as root or setting" + " interface using -i flag."); + } + log_debug("zmap", "no interface provided. will use %s", iface); + zconf.iface = iface; + } + if (zconf.source_ip_first == NULL) { + struct in_addr default_ip; + zconf.source_ip_first = malloc(INET_ADDRSTRLEN); + zconf.source_ip_last = zconf.source_ip_first; + if (get_iface_ip(zconf.iface, &default_ip) < 0) { + log_fatal("zmap", "could not detect default IP address for for %s." + " Try specifying a source address (-S).", zconf.iface); + } + inet_ntop(AF_INET, &default_ip, zconf.source_ip_first, INET_ADDRSTRLEN); + log_debug("zmap", "no source IP address given. will use %s", + zconf.source_ip_first); + } + if (!zconf.gw_mac_set) { + struct in_addr gw_ip; + char iface[IF_NAMESIZE]; + if (get_default_gw(&gw_ip, iface) < 0) { + log_fatal("zmap", "could not detect default gateway address for %i." + " Try setting default gateway mac address (-G)."); + } + log_debug("zmap", "found gateway IP %s on %s", inet_ntoa(gw_ip), iface); + if (get_hw_addr(&gw_ip, iface, zconf.gw_mac) < 0) { + log_fatal("zmap", "could not detect GW MAC address for %s on %s." + " Try setting default gateway mac address (-G).", + inet_ntoa(gw_ip), zconf.iface); + } + zconf.gw_mac_set = 1; + log_debug("zmap", "using default gateway MAC %02x:%02x:%02x:%02x:%02x:%02x", + zconf.gw_mac[0], zconf.gw_mac[1], zconf.gw_mac[2], + zconf.gw_mac[3], zconf.gw_mac[4], zconf.gw_mac[5]); + } + + // initialization + if (zconf.output_module && zconf.output_module->init) { + zconf.output_module->init(&zconf, zconf.output_fields, + zconf.output_fields_len); + } + if (send_init()) { + exit(EXIT_FAILURE); + } + if (zconf.output_module && zconf.output_module->start) { + zconf.output_module->start(&zconf, &zsend, &zrecv); + } + // start threads + pthread_t *tsend, trecv, tmon; + int r = pthread_create(&trecv, NULL, start_recv, NULL); + if (r != 0) { + log_fatal("zmap", "unable to create recv thread"); + exit(EXIT_FAILURE); + } + for (;;) { + pthread_mutex_lock(&recv_ready_mutex); + if (zconf.recv_ready) { + break; + } + pthread_mutex_unlock(&recv_ready_mutex); + } + tsend = malloc(zconf.senders * sizeof(pthread_t)); + assert(tsend); + log_debug("zmap", "using %d sender threads", zconf.senders); + for (int i=0; i < zconf.senders; i++) { + uintptr_t sock; + if (zconf.dryrun) { + sock = get_dryrun_socket(); + } else { + sock = get_socket(); + } + + int r = pthread_create(&tsend[i], NULL, start_send, (void*) sock); + if (r != 0) { + log_fatal("zmap", "unable to create send thread"); + exit(EXIT_FAILURE); + } + } + if (!zconf.quiet) { + int r = pthread_create(&tmon, NULL, start_mon, NULL); + if (r != 0) { + log_fatal("zmap", "unable to create monitor thread"); + exit(EXIT_FAILURE); + } + } + + drop_privs(); + + // wait for completion + for (int i=0; i < zconf.senders; i++) { + int r = pthread_join(tsend[i], NULL); + if (r != 0) { + log_fatal("zmap", "unable to join send thread"); + exit(EXIT_FAILURE); + } + } + log_debug("zmap", "senders finished"); + r = pthread_join(trecv, NULL); + if (r != 0) { + log_fatal("zmap", "unable to join recv thread"); + exit(EXIT_FAILURE); + } + if (!zconf.quiet) { + pthread_join(tmon, NULL); + if (r != 0) { + log_fatal("zmap", "unable to join monitor thread"); + exit(EXIT_FAILURE); + } + } + + // finished + if (zconf.summary) { + summary(); + } + if (zconf.output_module && zconf.output_module->close) { + zconf.output_module->close(&zconf, &zsend, &zrecv); + } + if (zconf.probe_module && zconf.probe_module->close) { + zconf.probe_module->close(&zconf, &zsend, &zrecv); + } + log_info("zmap", "completed"); +} + +static void enforce_range(const char *name, int v, int min, int max) +{ + if (v < min || v > max) { + fprintf(stderr, "%s: argument `%s' must be between %d and %d\n", + CMDLINE_PARSER_PACKAGE, name, min, max); + exit(EXIT_FAILURE); + } +} + +static int file_exists(char *name) +{ + FILE *file = fopen(name, "r"); + if (!file) + return 0; + fclose(file); return 1; } -#line 19 "zmap.y" -#ifdef YYSTYPE -#undef YYSTYPE_IS_DECLARED -#define YYSTYPE_IS_DECLARED 1 -#endif -#ifndef YYSTYPE_IS_DECLARED -#define YYSTYPE_IS_DECLARED 1 -typedef union { - int int_literal; - char *string_literal; - struct node *expr; -} YYSTYPE; -#endif /* !YYSTYPE_IS_DECLARED */ -#line 48 "y.tab.c" - -/* compatibility with bison */ -#ifdef YYPARSE_PARAM -/* compatibility with FreeBSD */ -# ifdef YYPARSE_PARAM_TYPE -# define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM) -# else -# define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM) -# endif -#else -# define YYPARSE_DECL() yyparse(void) -#endif - -/* Parameters sent to lex. */ -#ifdef YYLEX_PARAM -# define YYLEX_DECL() yylex(void *YYLEX_PARAM) -# define YYLEX yylex(YYLEX_PARAM) -#else -# define YYLEX_DECL() yylex(void) -# define YYLEX yylex() -#endif - -/* Parameters sent to yyerror. */ -#ifndef YYERROR_DECL -#define YYERROR_DECL() yyerror(const char *s) -#endif -#ifndef YYERROR_CALL -#define YYERROR_CALL(msg) yyerror(msg) -#endif - -extern int YYPARSE_DECL(); - -#define T_AND 257 -#define T_OR 258 -#define T_NUMBER 259 -#define T_FIELD 260 -#define T_NOT_EQ 261 -#define T_GT_EQ 262 -#define T_LT_EQ 263 -#define YYERRCODE 256 -static const short yylhs[] = { -1, - 0, 0, 0, 0, 1, 1, 2, 2, 2, 2, - 2, 2, 3, 3, -}; -static const short yylen[] = { 2, - 3, 3, 3, 1, 1, 1, 3, 3, 3, 3, - 3, 3, 3, 3, -}; -static const short yydefred[] = { 0, - 0, 0, 0, 4, 5, 6, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 3, 10, 14, 11, 8, - 9, 7, 13, 12, 2, 0, -}; -static const short yydgoto[] = { 3, - 4, 5, 6, -}; -static const short yysindex[] = { -40, - -40, -57, -250, 0, 0, 0, -39, -249, -245, -244, - -243, -247, -242, -40, -40, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, -248, -}; -static const short yyrindex[] = { 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, -}; -static const short yygindex[] = { 5, - 0, 0, 0, -}; -#define YYTABLESIZE 259 -static const short yytable[] = { 1, - 1, 16, 11, 12, 10, 7, 14, 15, 14, 17, - 18, 22, 23, 19, 20, 21, 24, 0, 25, 26, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 8, 9, 13, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 14, 15, 2, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, -}; -static const short yycheck[] = { 40, - 0, 41, 60, 61, 62, 1, 257, 258, 257, 259, - 260, 259, 260, 259, 259, 259, 259, -1, 14, 15, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 41, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 261, 262, 263, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 257, 258, 260, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 258, -}; -#define YYFINAL 3 -#ifndef YYDEBUG -#define YYDEBUG 0 -#endif -#define YYMAXTOKEN 263 -#if YYDEBUG -static const char *yyname[] = { - -"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,"'('","')'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'<'","'='","'>'",0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"T_AND", -"T_OR","T_NUMBER","T_FIELD","T_NOT_EQ","T_GT_EQ","T_LT_EQ", -}; -static const char *yyrule[] = { -"$accept : filter_expr", -"filter_expr : filter_expr T_OR filter_expr", -"filter_expr : filter_expr T_AND filter_expr", -"filter_expr : '(' filter_expr ')'", -"filter_expr : filter", -"filter : number_filter", -"filter : string_filter", -"number_filter : T_FIELD '=' T_NUMBER", -"number_filter : T_FIELD '>' T_NUMBER", -"number_filter : T_FIELD '<' T_NUMBER", -"number_filter : T_FIELD T_NOT_EQ T_NUMBER", -"number_filter : T_FIELD T_GT_EQ T_NUMBER", -"number_filter : T_FIELD T_LT_EQ T_NUMBER", -"string_filter : T_FIELD '=' T_FIELD", -"string_filter : T_FIELD T_NOT_EQ T_FIELD", - -}; -#endif - -int yydebug; -int yynerrs; - -int yyerrflag; -int yychar; -YYSTYPE yyval; -YYSTYPE yylval; - -/* define the initial stack-sizes */ -#ifdef YYSTACKSIZE -#undef YYMAXDEPTH -#define YYMAXDEPTH YYSTACKSIZE -#else -#ifdef YYMAXDEPTH -#define YYSTACKSIZE YYMAXDEPTH -#else -#define YYSTACKSIZE 500 -#define YYMAXDEPTH 500 -#endif -#endif - -#define YYINITSTACKSIZE 500 - -typedef struct { - unsigned stacksize; - short *s_base; - short *s_mark; - short *s_last; - YYSTYPE *l_base; - YYSTYPE *l_mark; -} YYSTACKDATA; -/* variables for the parser stack */ -static YYSTACKDATA yystack; -#line 128 "zmap.y" - - -#line 248 "y.tab.c" - -#if YYDEBUG -#include /* needed for printf */ -#endif - -#include /* needed for malloc, etc */ -#include /* needed for memset */ - -/* allocate initial stack or double stack size, up to YYMAXDEPTH */ -static int yygrowstack(YYSTACKDATA *data) +#define MAC_LEN IFHWADDRLEN +int parse_mac(macaddr_t *out, char *in) { - int i; - unsigned newsize; - short *newss; - YYSTYPE *newvs; - - if ((newsize = data->stacksize) == 0) - newsize = YYINITSTACKSIZE; - else if (newsize >= YYMAXDEPTH) - return -1; - else if ((newsize *= 2) > YYMAXDEPTH) - newsize = YYMAXDEPTH; - - i = data->s_mark - data->s_base; - newss = (short *)realloc(data->s_base, newsize * sizeof(*newss)); - if (newss == 0) - return -1; - - data->s_base = newss; - data->s_mark = newss + i; - - newvs = (YYSTYPE *)realloc(data->l_base, newsize * sizeof(*newvs)); - if (newvs == 0) - return -1; - - data->l_base = newvs; - data->l_mark = newvs + i; - - data->stacksize = newsize; - data->s_last = data->s_base + newsize - 1; - return 0; + if (strlen(in) < MAC_LEN*3-1) + return 0; + char octet[3]; + octet[2] = '\0'; + for (int i=0; i < MAC_LEN; i++) { + if (i < MAC_LEN-1 && in[i*3+2] != ':') { + return 0; + } + strncpy(octet, &in[i*3], 2); + char *err = NULL; + long b = strtol(octet, &err, 16); + if (err && *err != '\0') { + return 0; + } + out[i] = b & 0xFF; + } + return 1; } -#if YYPURE || defined(YY_NO_LEAKS) -static void yyfreestack(YYSTACKDATA *data) +#define SET_IF_GIVEN(DST,ARG) \ + { if (args.ARG##_given) { (DST) = args.ARG##_arg; }; } +#define SET_BOOL(DST,ARG) \ + { if (args.ARG##_given) { (DST) = 1; }; } + +int main(int argc, char *argv[]) { - free(data->s_base); - free(data->l_base); - memset(data, 0, sizeof(*data)); + struct gengetopt_args_info args; + struct cmdline_parser_params *params; + params = cmdline_parser_params_create(); + params->initialize = 1; + params->override = 0; + params->check_required = 0; + + if (cmdline_parser_ext(argc, argv, &args, params) != 0) { + exit(EXIT_SUCCESS); + } + + zconf.log_level = args.verbosity_arg; + log_init(stderr, zconf.log_level); + log_trace("zmap", "zmap main thread started"); + + if (args.help_given) { + cmdline_parser_print_help(); + exit(EXIT_SUCCESS); + } + if (args.version_given) { + cmdline_parser_print_version(); + exit(EXIT_SUCCESS); + } + if (args.list_output_modules_given) { + print_output_modules(); + exit(EXIT_SUCCESS); + } + if (args.list_probe_modules_given) { + print_probe_modules(); + exit(EXIT_SUCCESS); + } + if (args.config_given || file_exists(args.config_arg)) { + params->initialize = 0; + params->override = 0; + if (cmdline_parser_config_file(args.config_arg, &args, params) + != 0) { + exit(EXIT_FAILURE); + } + } + if (args.vpn_given) { + zconf.send_ip_pkts = 1; + zconf.gw_mac_set = 1; + memset(zconf.gw_mac, 0, IFHWADDRLEN); + } + if (cmdline_parser_required(&args, CMDLINE_PARSER_PACKAGE) != 0) { + exit(EXIT_FAILURE); + } + // parse the provided probe and output module s.t. that we can support + // other command-line helpers (e.g. probe help) + if (!args.output_module_given) { + zconf.output_module = get_output_module_by_name("csv"); + zconf.raw_output_fields = (char*) "saddr"; + zconf.filter_duplicates = 1; + zconf.filter_unsuccessful = 1; + } else if (!strcmp(args.output_module_arg, "simple_file")) { + log_warn("zmap", "the simple_file output interface has been deprecated and " + "will be removed in the future. Users should use the csv " + "output module. Newer scan options such as output-fields " + "are not supported with this output module."); + zconf.output_module = get_output_module_by_name("csv"); + zconf.raw_output_fields = (char*) "saddr"; + zconf.filter_duplicates = 1; + zconf.filter_unsuccessful = 1; + } else if (!strcmp(args.output_module_arg, "extended_file")) { + log_warn("zmap", "the extended_file output interface has been deprecated and " + "will be removed in the future. Users should use the csv " + "output module. Newer scan options such as output-fields " + "are not supported with this output module."); + zconf.output_module = get_output_module_by_name("csv"); + zconf.raw_output_fields = (char*) "classification, saddr, " + "daddr, sport, dport, " + "seqnum, acknum, cooldown, " + "repeat, timestamp-str"; + zconf.filter_duplicates = 0; + } else { + zconf.output_module = get_output_module_by_name(args.output_module_arg); + if (!zconf.output_module) { + fprintf(stderr, "%s: specified output module (%s) does not exist\n", + CMDLINE_PARSER_PACKAGE, args.output_module_arg); + exit(EXIT_FAILURE); + } + } + zconf.probe_module = get_probe_module_by_name(args.probe_module_arg); + if (!zconf.probe_module) { + fprintf(stderr, "%s: specified probe module (%s) does not exist\n", + CMDLINE_PARSER_PACKAGE, args.probe_module_arg); + exit(EXIT_FAILURE); + } + + // now that we know the probe module, let's find what it supports + memset(&zconf.fsconf, 0, sizeof(struct fieldset_conf)); + // the set of fields made available to a user is constructed + // of IP header fields + probe module fields + system fields + fielddefset_t *fds = &(zconf.fsconf.defs); + gen_fielddef_set(fds, (fielddef_t*) &(ip_fields), + 4); + gen_fielddef_set(fds, zconf.probe_module->fields, + zconf.probe_module->numfields); + gen_fielddef_set(fds, (fielddef_t*) &(sys_fields), + 5); + if (args.list_output_fields_given) { + for (int i = 0; i < fds->len; i++) { + printf("%-15s %6s: %s\n", fds->fielddefs[i].name, + fds->fielddefs[i].type, + fds->fielddefs[i].desc); + } + exit(EXIT_SUCCESS); + } + // find the fields we need for the framework + zconf.fsconf.success_index = + fds_get_index_by_name(fds, (char*) "success"); + if (zconf.fsconf.success_index < 0) { + log_fatal("fieldset", "probe module does not supply " + "required success field."); + } + zconf.fsconf.classification_index = + fds_get_index_by_name(fds, (char*) "classification"); + if (zconf.fsconf.classification_index < 0) { + log_fatal("fieldset", "probe module does not supply " + "required packet classification field."); + } + // process the list of requested output fields. + if (args.output_fields_given) { + zconf.raw_output_fields = args.output_fields_arg; + } else if (!zconf.raw_output_fields) { + zconf.raw_output_fields = (char*) "saddr"; + } + split_string(zconf.raw_output_fields, &(zconf.output_fields_len), + &(zconf.output_fields)); + for (int i=0; i < zconf.output_fields_len; i++) { + log_debug("zmap", "requested output field (%i): %s", + i, + zconf.output_fields[i]); + } + // generate a translation that can be used to convert output + // from a probe module to the input for an output module + fs_generate_fieldset_translation(&zconf.fsconf.translation, + &zconf.fsconf.defs, zconf.output_fields, + zconf.output_fields_len); + + // Parse and validate the output filter, if any + if (args.output_filter_arg) { + parse_filter_string(args.output_filter_arg); + } + + SET_BOOL(zconf.dryrun, dryrun); + SET_BOOL(zconf.quiet, quiet); + SET_BOOL(zconf.summary, summary); + zconf.cooldown_secs = args.cooldown_time_arg; + zconf.senders = args.sender_threads_arg; + SET_IF_GIVEN(zconf.output_filename, output_file); + SET_IF_GIVEN(zconf.blacklist_filename, blacklist_file); + SET_IF_GIVEN(zconf.whitelist_filename, whitelist_file); + SET_IF_GIVEN(zconf.probe_args, probe_args); + SET_IF_GIVEN(zconf.output_args, output_args); + SET_IF_GIVEN(zconf.iface, interface); + SET_IF_GIVEN(zconf.max_runtime, max_runtime); + SET_IF_GIVEN(zconf.max_results, max_results); + SET_IF_GIVEN(zconf.rate, rate); + SET_IF_GIVEN(zconf.packet_streams, probes); + + + if (zconf.probe_module->port_args) { + if (args.source_port_given) { + char *dash = strchr(args.source_port_arg, '-'); + if (dash) { // range + *dash = '\0'; + zconf.source_port_first = atoi(args.source_port_arg); + enforce_range("starting source-port", zconf.source_port_first, 0, 0xFFFF); + zconf.source_port_last = atoi(dash+1); + enforce_range("ending source-port", zconf.source_port_last, 0, 0xFFFF); + if (zconf.source_port_first > zconf.source_port_last) { + fprintf(stderr, "%s: invalid source port range: " + "last port is less than first port\n", + CMDLINE_PARSER_PACKAGE); + exit(EXIT_FAILURE); + } + } else { // single port + int port = atoi(args.source_port_arg); + enforce_range("source-port", port, 0, 0xFFFF); + zconf.source_port_first = port; + zconf.source_port_last = port; + } + } + if (!args.target_port_given) { + fprintf(stderr, "%s: target port is required for this type of probe\n", + CMDLINE_PARSER_PACKAGE); + exit(EXIT_FAILURE); + } + enforce_range("target-port", args.target_port_arg, 0, 0xFFFF); + zconf.target_port = args.target_port_arg; + } + if (args.source_ip_given) { + char *dash = strchr(args.source_ip_arg, '-'); + if (dash) { // range + *dash = '\0'; + zconf.source_ip_first = args.source_ip_arg; + zconf.source_ip_last = dash+1; + } else { // single address + zconf.source_ip_first = args.source_ip_arg; + zconf.source_ip_last = args.source_ip_arg; + } + } + if (args.gateway_mac_given) { + if (!parse_mac(zconf.gw_mac, args.gateway_mac_arg)) { + fprintf(stderr, "%s: invalid MAC address `%s'\n", + CMDLINE_PARSER_PACKAGE, args.gateway_mac_arg); + exit(EXIT_FAILURE); + } + zconf.gw_mac_set = 1; + } + if (args.seed_given) { + zconf.seed = args.seed_arg; + zconf.use_seed = 1; + } + if (args.bandwidth_given) { + // Supported: G,g=*1000000000; M,m=*1000000 K,k=*1000 bits per second + zconf.bandwidth = atoi(args.bandwidth_arg); + char *suffix = args.bandwidth_arg; + while (*suffix >= '0' && *suffix <= '9') { + suffix++; + } + if (*suffix) { + switch (*suffix) { + case 'G': case 'g': + zconf.bandwidth *= 1000000000; + break; + case 'M': case 'm': + zconf.bandwidth *= 1000000; + break; + case 'K': case 'k': + zconf.bandwidth *= 1000; + break; + default: + fprintf(stderr, "%s: unknown bandwidth suffix '%s' " + "(supported suffixes are G, M and K)\n", + CMDLINE_PARSER_PACKAGE, suffix); + exit(EXIT_FAILURE); + } + } + } + if (args.max_targets_given) { + errno = 0; + char *end; + double v = strtod(args.max_targets_arg, &end); + if (end == args.max_targets_arg || errno != 0) { + fprintf(stderr, "%s: can't convert max-targets to a number\n", + CMDLINE_PARSER_PACKAGE); + exit(EXIT_FAILURE); + } + if (end[0] == '%' && end[1] == '\0') { + // treat as percentage + v = v * ((unsigned long long int)1 << 32) / 100.; + } else if (end[0] != '\0') { + fprintf(stderr, "%s: extra characters after max-targets\n", + CMDLINE_PARSER_PACKAGE); + exit(EXIT_FAILURE); + } + if (v <= 0) { + zconf.max_targets = 0; + } + else if (v >= ((unsigned long long int)1 << 32)) { + zconf.max_targets = 0xFFFFFFFF; + } else { + zconf.max_targets = v; + } + } + + start_zmap(); + + cmdline_parser_free(&args); + free(params); + return EXIT_SUCCESS; } -#else -#define yyfreestack(data) /* nothing */ -#endif -#define YYABORT goto yyabort -#define YYREJECT goto yyabort -#define YYACCEPT goto yyaccept -#define YYERROR goto yyerrlab - -int -YYPARSE_DECL() -{ - int yym, yyn, yystate; -#if YYDEBUG - const char *yys; - - if ((yys = getenv("YYDEBUG")) != 0) - { - yyn = *yys; - if (yyn >= '0' && yyn <= '9') - yydebug = yyn - '0'; - } -#endif - - yynerrs = 0; - yyerrflag = 0; - yychar = YYEMPTY; - yystate = 0; - -#if YYPURE - memset(&yystack, 0, sizeof(yystack)); -#endif - - if (yystack.s_base == NULL && yygrowstack(&yystack)) goto yyoverflow; - yystack.s_mark = yystack.s_base; - yystack.l_mark = yystack.l_base; - yystate = 0; - *yystack.s_mark = 0; - -yyloop: - if ((yyn = yydefred[yystate]) != 0) goto yyreduce; - if (yychar < 0) - { - if ((yychar = YYLEX) < 0) yychar = 0; -#if YYDEBUG - if (yydebug) - { - yys = 0; - if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; - if (!yys) yys = "illegal-symbol"; - printf("%sdebug: state %d, reading %d (%s)\n", - YYPREFIX, yystate, yychar, yys); - } -#endif - } - if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && - yyn <= YYTABLESIZE && yycheck[yyn] == yychar) - { -#if YYDEBUG - if (yydebug) - printf("%sdebug: state %d, shifting to state %d\n", - YYPREFIX, yystate, yytable[yyn]); -#endif - if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) - { - goto yyoverflow; - } - yystate = yytable[yyn]; - *++yystack.s_mark = yytable[yyn]; - *++yystack.l_mark = yylval; - yychar = YYEMPTY; - if (yyerrflag > 0) --yyerrflag; - goto yyloop; - } - if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && - yyn <= YYTABLESIZE && yycheck[yyn] == yychar) - { - yyn = yytable[yyn]; - goto yyreduce; - } - if (yyerrflag) goto yyinrecovery; - - yyerror("syntax error"); - - goto yyerrlab; - -yyerrlab: - ++yynerrs; - -yyinrecovery: - if (yyerrflag < 3) - { - yyerrflag = 3; - for (;;) - { - if ((yyn = yysindex[*yystack.s_mark]) && (yyn += YYERRCODE) >= 0 && - yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) - { -#if YYDEBUG - if (yydebug) - printf("%sdebug: state %d, error recovery shifting\ - to state %d\n", YYPREFIX, *yystack.s_mark, yytable[yyn]); -#endif - if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) - { - goto yyoverflow; - } - yystate = yytable[yyn]; - *++yystack.s_mark = yytable[yyn]; - *++yystack.l_mark = yylval; - goto yyloop; - } - else - { -#if YYDEBUG - if (yydebug) - printf("%sdebug: error recovery discarding state %d\n", - YYPREFIX, *yystack.s_mark); -#endif - if (yystack.s_mark <= yystack.s_base) goto yyabort; - --yystack.s_mark; - --yystack.l_mark; - } - } - } - else - { - if (yychar == 0) goto yyabort; -#if YYDEBUG - if (yydebug) - { - yys = 0; - if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; - if (!yys) yys = "illegal-symbol"; - printf("%sdebug: state %d, error recovery discards token %d (%s)\n", - YYPREFIX, yystate, yychar, yys); - } -#endif - yychar = YYEMPTY; - goto yyloop; - } - -yyreduce: -#if YYDEBUG - if (yydebug) - printf("%sdebug: state %d, reducing by rule %d (%s)\n", - YYPREFIX, yystate, yyn, yyrule[yyn]); -#endif - yym = yylen[yyn]; - if (yym) - yyval = yystack.l_mark[1-yym]; - else - memset(&yyval, 0, sizeof yyval); - switch (yyn) - { -case 1: -#line 43 "zmap.y" - { - yyval.expr = make_op_node(OR); - yyval.expr->left_child = yystack.l_mark[-2].expr; - yyval.expr->right_child = yystack.l_mark[0].expr; - print_expression(yyval.expr); - printf("%s\n", ""); - } -break; -case 2: -#line 51 "zmap.y" - { - yyval.expr = make_op_node(AND); - yyval.expr->left_child = yystack.l_mark[-2].expr; - yyval.expr->right_child = yystack.l_mark[0].expr; - print_expression(yyval.expr); - printf("%s\n", ""); - } -break; -case 3: -#line 59 "zmap.y" - { - yyval.expr = yystack.l_mark[-1].expr; - } -break; -case 4: -#line 63 "zmap.y" - { - yyval.expr = yystack.l_mark[0].expr; - } -break; -case 5: -#line 69 "zmap.y" - { - yyval.expr = yystack.l_mark[0].expr; - } -break; -case 6: -#line 73 "zmap.y" - { - yyval.expr = yystack.l_mark[0].expr; - } -break; -case 7: -#line 79 "zmap.y" - { - printf("number_filter: %s = %d\n", yystack.l_mark[-2].string_literal, yystack.l_mark[0].int_literal); - yyval.expr = make_op_node(EQ); - yyval.expr->left_child = make_field_node(yystack.l_mark[-2].string_literal); - yyval.expr->right_child = make_int_node(yystack.l_mark[0].int_literal); - } -break; -case 8: -#line 87 "zmap.y" - { - printf("number_filter: %s > %d\n", yystack.l_mark[-2].string_literal, yystack.l_mark[0].int_literal); - yyval.expr = make_op_node(GT); - yyval.expr->left_child = make_field_node(yystack.l_mark[-2].string_literal); - yyval.expr->right_child = make_int_node(yystack.l_mark[0].int_literal); - } -break; -case 9: -#line 95 "zmap.y" - { - printf("number_filter: %s < %d\n", yystack.l_mark[-2].string_literal, yystack.l_mark[0].int_literal); - } -break; -case 10: -#line 100 "zmap.y" - { - printf("number_filter: %s != %d\n", yystack.l_mark[-2].string_literal, yystack.l_mark[0].int_literal); - } -break; -case 11: -#line 105 "zmap.y" - { - printf("number_filter: %s >= %d\n", yystack.l_mark[-2].string_literal, yystack.l_mark[0].int_literal); - } -break; -case 12: -#line 110 "zmap.y" - { - printf("number_filter: %s <= %d\n", yystack.l_mark[-2].string_literal, yystack.l_mark[0].int_literal); - } -break; -case 13: -#line 117 "zmap.y" - { - printf("string_filter %s = %s\n", yystack.l_mark[-2].string_literal, yystack.l_mark[0].string_literal); - } -break; -case 14: -#line 122 "zmap.y" - { - printf("string_filter: %s != %s\n", yystack.l_mark[-2].string_literal, yystack.l_mark[0].string_literal); - } -break; -#line 552 "y.tab.c" - } - yystack.s_mark -= yym; - yystate = *yystack.s_mark; - yystack.l_mark -= yym; - yym = yylhs[yyn]; - if (yystate == 0 && yym == 0) - { -#if YYDEBUG - if (yydebug) - printf("%sdebug: after reduction, shifting from state 0 to\ - state %d\n", YYPREFIX, YYFINAL); -#endif - yystate = YYFINAL; - *++yystack.s_mark = YYFINAL; - *++yystack.l_mark = yyval; - if (yychar < 0) - { - if ((yychar = YYLEX) < 0) yychar = 0; -#if YYDEBUG - if (yydebug) - { - yys = 0; - if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; - if (!yys) yys = "illegal-symbol"; - printf("%sdebug: state %d, reading %d (%s)\n", - YYPREFIX, YYFINAL, yychar, yys); - } -#endif - } - if (yychar == 0) goto yyaccept; - goto yyloop; - } - if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && - yyn <= YYTABLESIZE && yycheck[yyn] == yystate) - yystate = yytable[yyn]; - else - yystate = yydgoto[yym]; -#if YYDEBUG - if (yydebug) - printf("%sdebug: after reduction, shifting from state %d \ -to state %d\n", YYPREFIX, *yystack.s_mark, yystate); -#endif - if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) - { - goto yyoverflow; - } - *++yystack.s_mark = (short) yystate; - *++yystack.l_mark = yyval; - goto yyloop; - -yyoverflow: - yyerror("yacc stack overflow"); - -yyabort: - yyfreestack(&yystack); - return (1); - -yyaccept: - yyfreestack(&yystack); - return (0); -} diff --git a/src/zopt.ggo b/src/zopt.ggo index 71f0aef..4ed15e1 100644 --- a/src/zopt.ggo +++ b/src/zopt.ggo @@ -94,6 +94,9 @@ option "probe-args" - "Arguments to pass to probe module" option "output-args" - "Arguments to pass to output module" typestr="args" optional string +option "output-filter" - "Read a file containing an output filter on the first line" + typestr="filename" + optional string option "list-output-modules" - "List available output modules" optional option "list-probe-modules" - "List available probe modules" From f7939bfbcb400b315aa468c0aba95526ea2d557c Mon Sep 17 00:00:00 2001 From: David Adrian Date: Thu, 19 Sep 2013 18:19:12 -0400 Subject: [PATCH 13/53] Add support for holding an index instead of fieldname --- src/expression.c | 13 ++++++++++--- src/expression.h | 11 +++++++---- src/filter.c | 7 ++++--- src/filter.h | 2 +- src/zmap.c | 4 +++- 5 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/expression.c b/src/expression.c index 2536f48..4f1e87d 100644 --- a/src/expression.c +++ b/src/expression.c @@ -2,13 +2,20 @@ #include "../lib/xalloc.h" -node_t* alloc_node() +/* Static helper functions */ + +static node_t* alloc_node(); +static int eval_single_node(node_t* node); + +static node_t* alloc_node() { node_t *node = xmalloc(sizeof(node_t)); memset(node, 0, sizeof(node_t)); return node; } +/* Exposed functions */ + node_t* make_op_node(enum operation op) { node_t* node = alloc_node(); @@ -21,7 +28,7 @@ node_t* make_field_node(char *fieldname) { node_t *node = alloc_node(); node->type = FIELD; - node->value.fieldname = fieldname; + node->value.field.fieldname = fieldname; return node; } @@ -56,7 +63,7 @@ void print_expression(node_t *root) { printf(" %i ", root->value.op); break; case FIELD: - printf(" (%s", root->value.fieldname); + printf(" (%s", root->value.field.fieldname); break; case STRING: printf("%s) ", root->value.string_literal); diff --git a/src/expression.h b/src/expression.h index 232afef..1c58f68 100644 --- a/src/expression.h +++ b/src/expression.h @@ -13,11 +13,16 @@ enum node_type { OP, FIELD, STRING, INT }; -union node_value { - enum operation op; +struct field_id { + int index; char *fieldname; +}; + +union node_value { + struct field_id field; char *string_literal; int int_literal; + enum operation op; }; typedef struct node { @@ -27,8 +32,6 @@ typedef struct node { union node_value value; } node_t; -node_t* alloc_node(); - node_t* make_op_node(enum operation op); node_t* make_field_node(char *fieldname); diff --git a/src/filter.c b/src/filter.c index cb500f1..19ac3ae 100644 --- a/src/filter.c +++ b/src/filter.c @@ -8,18 +8,19 @@ extern int yyparse(); node_t *zfilter; -void parse_filter_string(char *filter) +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_fatal("zmap", "Unable to parse filter"); + log_error("zmap", "Unable to parse filter string: '%s'", filter); + return 0; } zconf.filter.expression = zfilter; print_expression(zfilter); printf("%s\n", ""); fflush(stdout); - return; + return 1; } \ No newline at end of file diff --git a/src/filter.h b/src/filter.h index 14af688..4de684c 100644 --- a/src/filter.h +++ b/src/filter.h @@ -7,6 +7,6 @@ struct output_filter { node_t *expression; }; -void parse_filter_string(char *filter); +int parse_filter_string(char *filter); #endif /* ZMAP_FILTER_H */ \ No newline at end of file diff --git a/src/zmap.c b/src/zmap.c index d424134..ae30562 100644 --- a/src/zmap.c +++ b/src/zmap.c @@ -501,7 +501,9 @@ int main(int argc, char *argv[]) // Parse and validate the output filter, if any if (args.output_filter_arg) { - parse_filter_string(args.output_filter_arg); + if (!parse_filter_string(args.output_filter_arg)) { + log_fatal("zmap", "Unable to parse filter expression"); + } } SET_BOOL(zconf.dryrun, dryrun); From 29c291c562fe37e5145ce6f3248648be5df9127a Mon Sep 17 00:00:00 2001 From: David Adrian Date: Fri, 20 Sep 2013 14:35:07 -0400 Subject: [PATCH 14/53] Incredibly hacky evaluate implementation --- src/expression.c | 93 ++++++++++++++++++++++++++++++++++++++++++++---- src/expression.h | 9 ++--- src/filter.c | 38 +++++++++++++++++++- src/filter.h | 3 ++ src/lexer.c | 2 +- src/lexer.l | 2 +- src/zmap.c | 6 ++++ 7 files changed, 140 insertions(+), 13 deletions(-) diff --git a/src/expression.c b/src/expression.c index 4f1e87d..354b805 100644 --- a/src/expression.c +++ b/src/expression.c @@ -1,11 +1,17 @@ #include "expression.h" +#include "fieldset.H" #include "../lib/xalloc.h" /* Static helper functions */ 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() { @@ -14,6 +20,54 @@ static node_t* alloc_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 */ node_t* make_op_node(enum operation op) @@ -48,10 +102,37 @@ node_t* make_int_node(int literal) return node; } -int evaluate_expression(node_t *root) { - if (!root) return 0; - int result = 1; - return result; +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) { @@ -69,7 +150,7 @@ void print_expression(node_t *root) { printf("%s) ", root->value.string_literal); break; case INT: - printf(" %d) ", root->value.int_literal); + printf(" %llu) ", (long long unsigned) root->value.int_literal); break; default: break; diff --git a/src/expression.h b/src/expression.h index 1c58f68..7ff5068 100644 --- a/src/expression.h +++ b/src/expression.h @@ -1,9 +1,12 @@ #ifndef ZMAP_TREE_H #define ZMAP_TREE_H +#include "fieldset.h" + #include #include #include +#include enum operation { GT, LT, EQ, NEQ, AND, OR, LT_EQ, GT_EQ @@ -21,7 +24,7 @@ struct field_id { union node_value { struct field_id field; char *string_literal; - int int_literal; + uint64_t int_literal; enum operation op; }; @@ -40,8 +43,6 @@ node_t* make_string_node(char *literal); node_t* make_int_node(int literal); -int evaluate_expression(node_t *root); - -void print_expression(node_t *root); +int evaluate_expression(node_t *root, fieldset_t *fields); #endif /* ZMAP_TREE_H */ \ No newline at end of file diff --git a/src/filter.c b/src/filter.c index 19ac3ae..49165f3 100644 --- a/src/filter.c +++ b/src/filter.c @@ -4,10 +4,32 @@ #include "y.tab.h" #include "../lib/logger.h" +#include + extern int yyparse(); 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) { YY_BUFFER_STATE buffer_state = yy_scan_string(filter); @@ -23,4 +45,18 @@ int parse_filter_string(char *filter) printf("%s\n", ""); fflush(stdout); return 1; -} \ No newline at end of file +} + +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)); + +} diff --git a/src/filter.h b/src/filter.h index 4de684c..f42af6d 100644 --- a/src/filter.h +++ b/src/filter.h @@ -2,6 +2,7 @@ #define ZMAP_FILTER_H #include "expression.h" +#include "fieldset.h" struct output_filter { node_t *expression; @@ -9,4 +10,6 @@ struct output_filter { int parse_filter_string(char *filter); +int validate_filter(node_t *root, fielddefset_t *fields); + #endif /* ZMAP_FILTER_H */ \ No newline at end of file diff --git a/src/lexer.c b/src/lexer.c index 7172b5b..b5be489 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -745,7 +745,7 @@ do_action: /* This label is used only to access EOF actions. */ case 1: YY_RULE_SETUP #line 10 "lexer.l" -yylval.int_literal = atoi(yytext); return T_NUMBER; +yylval.int_literal = (uint64_t) atoll(yytext); return T_NUMBER; YY_BREAK case 2: /* rule 2 can match eol */ diff --git a/src/lexer.l b/src/lexer.l index 63696b2..0fa3b90 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -7,7 +7,7 @@ %option noinput %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 */ [ \t]+ /* Ignore whitespace */ != return T_NOT_EQ; diff --git a/src/zmap.c b/src/zmap.c index ae30562..e61ae65 100644 --- a/src/zmap.c +++ b/src/zmap.c @@ -501,9 +501,15 @@ int main(int argc, char *argv[]) // Parse and validate the output filter, if any if (args.output_filter_arg) { + // Run it through yyparse to build the expression tree if (!parse_filter_string(args.output_filter_arg)) { 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); From 9df8f678a37ad870ae2a74781bcb29e61d0f5787 Mon Sep 17 00:00:00 2001 From: David Adrian Date: Thu, 3 Oct 2013 11:29:11 -0400 Subject: [PATCH 15/53] Drop packets that don't pass the filter in recv --- src/recv.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/recv.c b/src/recv.c index 7f15765..df8211e 100644 --- a/src/recv.c +++ b/src/recv.c @@ -34,6 +34,7 @@ #include "state.h" #include "validate.h" #include "fieldset.h" +#include "expression.h" #include "probe_modules/probe_modules.h" #include "output_modules/output_modules.h" @@ -141,6 +142,10 @@ void packet_cb(u_char __attribute__((__unused__)) *user, if (is_repeat && zconf.filter_duplicates) { goto cleanup; } + if (!evaluate_expression(zconf.filter.expression, fs)) { + goto cleanup; + } + o = translate_fieldset(fs, &zconf.fsconf.translation); if (zconf.output_module && zconf.output_module->process_ip) { zconf.output_module->process_ip(o); From 82a8f402b8c62696ef7dd52449feb575ce31d929 Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 3 Oct 2013 20:40:38 -0400 Subject: [PATCH 16/53] change INSTALL to document cmake --- INSTALL | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/INSTALL b/INSTALL index 442f292..86f3ae2 100644 --- a/INSTALL +++ b/INSTALL @@ -19,8 +19,9 @@ or on RHEL- and Fedora-based systems by running: Once these prerequisites have been installed, ZMap can be installed by running: - cd src + cmake ./ make + sudo make install followed by: From 55b65d697ab7065bbab30077787e5b0b8f4ebb0b Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 3 Oct 2013 21:00:14 -0400 Subject: [PATCH 17/53] I care more about users than attacking governments I'll bet the users would agree with this default as well. Arguably, this shouldn't even be an option??? --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0a403b7..745f3d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ project (ZMAP C) option(WITH_REDIS "Build with support for Redis DB" OFF) option(WITH_JSON "Build with support for JSON" OFF) option(ENABLE_DEVELOPMENT "Enable development specific compiler and linker flags" OFF) -option(ENABLE_HARDENING "Add hardening specific compiler and linker flags" OFF) +option(ENABLE_HARDENING "Add hardening specific compiler and linker flags" ON) if(ENABLE_DEVELOPMENT) # Hardening and warnings for building with gcc From a74f1d877b22ec073f71bb448d3ac5d285c6514d Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 3 Oct 2013 21:35:08 -0400 Subject: [PATCH 18/53] testing on 32-bit system --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 745f3d5..45193ff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,6 +18,7 @@ if(ENABLE_DEVELOPMENT) "-Wmissing-noreturn -Wnormalized=id" "-Wstack-protector" "-Werror" + "-m32" ) # Fix line breaks From ae07374bb9e9be902c3d4650dc3f8fdd9dc71b4f Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 3 Oct 2013 21:53:42 -0400 Subject: [PATCH 19/53] Use a union in fieldset->value Instead of unreliably casting uint64_t's to (void *) --- src/fieldset.c | 46 +++++++++++++++++++-------------- src/fieldset.h | 7 ++++- src/output_modules/module_csv.c | 6 ++--- 3 files changed, 36 insertions(+), 23 deletions(-) diff --git a/src/fieldset.c b/src/fieldset.c index eb5d27e..edab9f9 100644 --- a/src/fieldset.c +++ b/src/fieldset.c @@ -32,11 +32,11 @@ fieldset_t *fs_new_fieldset(void) log_fatal("fieldset", "unable to allocate new fieldset"); } memset(f, 0, sizeof(fieldset_t)); - return f; + return f; } static inline void fs_add_word(fieldset_t *fs, const char *name, int type, - int free_, size_t len, void *value) + int free_, size_t len, field_val_t value) { if (fs->len + 1 >= MAX_FIELDS) { log_fatal("fieldset", "out of room in fieldset"); @@ -46,24 +46,24 @@ static inline void fs_add_word(fieldset_t *fs, const char *name, int type, f->type = type; f->name = name; f->len = len; - f->value = (uint64_t) value; + f->value = value; f->free_ = free_; } static void fs_modify_word(fieldset_t *fs, const char *name, int type, - int free_, size_t len, void *value) + int free_, size_t len, field_val_t value) { int i; for (i=0; ilen; i++) { if (!strcmp(fs->fields[i].name, name)) { if (fs->fields[i].free_) { - free((void*)fs->fields[i].value); - fs->fields[i].value = 0; + free(fs->fields[i].value.ptr); + fs->fields[i].value.ptr = NULL; } fs->fields[i].type = type; fs->fields[i].free_ = free_; fs->fields[i].len = len; - fs->fields[i].value = (uint64_t)value; + fs->fields[i].value = value; return; } } @@ -72,55 +72,63 @@ static void fs_modify_word(fieldset_t *fs, const char *name, int type, void fs_add_null(fieldset_t *fs, const char *name) { - fs_add_word(fs, name, FS_NULL, 0, 0, NULL); + field_val_t val = { .ptr = NULL }; + fs_add_word(fs, name, FS_NULL, 0, 0, val); } void fs_add_string(fieldset_t *fs, const char *name, char *value, int free_) { - fs_add_word(fs, name, FS_STRING, free_, strlen(value), (void*) value); + field_val_t val = { .ptr = value }; + fs_add_word(fs, name, FS_STRING, free_, strlen(value), val); } void fs_add_uint64(fieldset_t *fs, const char *name, uint64_t value) { - fs_add_word(fs, name, FS_UINT64, 0, sizeof(uint64_t), (void*) value); + field_val_t val = { .num = value }; + fs_add_word(fs, name, FS_UINT64, 0, sizeof(uint64_t), val); } void fs_add_binary(fieldset_t *fs, const char *name, size_t len, void *value, int free_) { - fs_add_word(fs, name, FS_BINARY, free_, len, value); + field_val_t val = { .ptr = value }; + fs_add_word(fs, name, FS_BINARY, free_, len, val); } // Modify void fs_modify_null(fieldset_t *fs, const char *name) { - fs_modify_word(fs, name, FS_NULL, 0, 0, NULL); + field_val_t val = { .ptr = NULL }; + fs_modify_word(fs, name, FS_NULL, 0, 0, val); } void fs_modify_string(fieldset_t *fs, const char *name, char *value, int free_) { - fs_modify_word(fs, name, FS_STRING, free_, strlen(value), (void*) value); + field_val_t val = { .ptr = value }; + fs_modify_word(fs, name, FS_STRING, free_, strlen(value), val); } void fs_modify_uint64(fieldset_t *fs, const char *name, uint64_t value) { - fs_modify_word(fs, name, FS_UINT64, 0, sizeof(uint64_t), (void*) value); + field_val_t val = { .num = value }; + fs_modify_word(fs, name, FS_UINT64, 0, sizeof(uint64_t), val); } void fs_modify_binary(fieldset_t *fs, const char *name, size_t len, void *value, int free_) { - fs_modify_word(fs, name, FS_BINARY, free_, len, value); + field_val_t val = { .ptr = value }; + fs_modify_word(fs, name, FS_BINARY, free_, len, val); } uint64_t fs_get_uint64_by_index(fieldset_t *fs, int index) { - return (uint64_t) fs->fields[index].value; + return (uint64_t) fs->fields[index].value.num; } char* fs_get_string_by_index(fieldset_t *fs, int index) { - return (char*) fs->fields[index].value; + return (char*) fs->fields[index].value.ptr; } int fds_get_index_by_name(fielddefset_t *fds, char *name) @@ -141,7 +149,7 @@ void fs_free(fieldset_t *fs) for (int i=0; i < fs->len; i++) { field_t *f = &(fs->fields[i]); if (f->free_) { - free((void*) f->value); + free(f->value.ptr); } } free(fs); @@ -160,7 +168,7 @@ void fs_generate_fieldset_translation(translation_t *t, log_fatal("fieldset", "specified field (%s) not " "available in selected " "probe module.", req[i]); - } + } t->translation[t->len++] = l; } } diff --git a/src/fieldset.h b/src/fieldset.h index 66de892..4f288ce 100644 --- a/src/fieldset.h +++ b/src/fieldset.h @@ -36,13 +36,18 @@ typedef struct fielddef_set { int len; } fielddefset_t; +typedef union field_val { + void *ptr; + uint64_t num; +} field_val_t; + // the internal field type used by fieldset typedef struct field { const char *name; int type; int free_; size_t len; - uint64_t value; + union field_val value; } field_t; // data structure that is populated by the probe module diff --git a/src/output_modules/module_csv.c b/src/output_modules/module_csv.c index 985be91..0377ba3 100644 --- a/src/output_modules/module_csv.c +++ b/src/output_modules/module_csv.c @@ -79,11 +79,11 @@ int csv_process(fieldset_t *fs) fprintf(file, ", "); } if (f->type == FS_STRING) { - fprintf(file, "%s", (char*) f->value); + fprintf(file, "%s", (char*) f->value.ptr); } else if (f->type == FS_UINT64) { - fprintf(file, "%lu", (uint64_t) f->value); + fprintf(file, "%llu", (uint64_t) f->value.num); } else if (f->type == FS_BINARY) { - hex_encode(file, (unsigned char*) f->value, f->len); + hex_encode(file, (unsigned char*) f->value.ptr, f->len); } else if (f->type == FS_NULL) { // do nothing } else { From 113d684fe8bc54f704215f96023aecdaa04e18b2 Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 3 Oct 2013 22:03:40 -0400 Subject: [PATCH 20/53] done testing m32 --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 45193ff..745f3d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,7 +18,6 @@ if(ENABLE_DEVELOPMENT) "-Wmissing-noreturn -Wnormalized=id" "-Wstack-protector" "-Werror" - "-m32" ) # Fix line breaks From 6cf931b541860ec1f14f135b56478e5269dcd4ce Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 3 Oct 2013 22:03:55 -0400 Subject: [PATCH 21/53] portable 64-bit output type --- src/output_modules/module_csv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/output_modules/module_csv.c b/src/output_modules/module_csv.c index 0377ba3..1d4de7b 100644 --- a/src/output_modules/module_csv.c +++ b/src/output_modules/module_csv.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "../../lib/logger.h" #include "../fieldset.h" @@ -81,7 +82,7 @@ int csv_process(fieldset_t *fs) if (f->type == FS_STRING) { fprintf(file, "%s", (char*) f->value.ptr); } else if (f->type == FS_UINT64) { - fprintf(file, "%llu", (uint64_t) f->value.num); + fprintf(file, "%" PRIu64, (uint64_t) f->value.num); } else if (f->type == FS_BINARY) { hex_encode(file, (unsigned char*) f->value.ptr, f->len); } else if (f->type == FS_NULL) { From f6ea0a79a8742c34400886ec8ab851408a2c43a8 Mon Sep 17 00:00:00 2001 From: David Adrian Date: Fri, 4 Oct 2013 10:53:03 -0400 Subject: [PATCH 22/53] Build filter using CMake --- CMakeLists.txt | 2 +- src/.gitignore | 4 ++++ src/CMakeLists.txt | 14 ++++++++++++++ src/expression.h | 2 ++ src/filter.c | 3 ++- src/lexer.c | 11 ++++++----- src/lexer.h | 6 ++++-- src/lexer.l | 2 +- src/parser.c | 6 +++--- src/y.tab.h | 20 -------------------- 10 files changed, 37 insertions(+), 33 deletions(-) create mode 100644 src/.gitignore delete mode 100644 src/y.tab.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 0a403b7..e27443e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ if(ENABLE_DEVELOPMENT) "-Wnested-externs -Wbad-function-cast -Winit-self" "-Wmissing-noreturn -Wnormalized=id" "-Wstack-protector" - "-Werror" + #"-Werror" ) # Fix line breaks diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 0000000..87de78c --- /dev/null +++ b/src/.gitignore @@ -0,0 +1,4 @@ +lexer.c +lexer.h +parser.c +parser.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 50bf1ee..44ce551 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -11,6 +11,7 @@ SET(LIB_SOURCES ${PROJECT_SOURCE_DIR}/lib/logger.c ${PROJECT_SOURCE_DIR}/lib/random.c ${PROJECT_SOURCE_DIR}/lib/rijndael-alg-fst.c + ${PROJECT_SOURCE_DIR}/lib/xalloc.c ) # ADD YOUR PROBE MODULE HERE @@ -41,16 +42,21 @@ SET(PROBE_MODULE_SOURCES SET(SOURCES aesrand.c cyclic.c + expression.c fieldset.c + filter.c get_gateway.c monitor.c recv.c send.c + stack.c state.c validate.c zmap.c zopt_compat.c "${CMAKE_CURRENT_BINARY_DIR}/zopt.h" + "${CMAKE_CURRENT_BINARY_DIR}/lexer.c" + "${CMAKE_CURRENT_BINARY_DIR}/parser.c" ${EXTRA_PROBE_MODULES} ${EXTRA_OUTPUT_MODULES} ${PROBE_MODULE_SOURCES} @@ -70,6 +76,14 @@ add_custom_command(OUTPUT zopt.h COMMAND gengetopt -C --no-help --no-version -i "${CMAKE_CURRENT_SOURCE_DIR}/zopt.ggo" -F "${CMAKE_CURRENT_BINARY_DIR}/zopt" ) +add_custom_command(OUTPUT lexer.c + COMMAND flex -o "${CMAKE_CURRENT_BINARY_DIR}/lexer.c" --header-file="${CMAKE_CURRENT_BINARY_DIR}/lexer.h" lexer.l + ) + +add_custom_command(OUTPUT parser.c + COMMAND byacc -d -o parser.c parser.y + ) + add_executable(zmap ${SOURCES}) target_link_libraries( diff --git a/src/expression.h b/src/expression.h index 7ff5068..d65668d 100644 --- a/src/expression.h +++ b/src/expression.h @@ -45,4 +45,6 @@ node_t* make_int_node(int literal); int evaluate_expression(node_t *root, fieldset_t *fields); +void print_expression(node_t *root); + #endif /* ZMAP_TREE_H */ \ No newline at end of file diff --git a/src/filter.c b/src/filter.c index 49165f3..7bc4c8d 100644 --- a/src/filter.c +++ b/src/filter.c @@ -1,7 +1,8 @@ #include "filter.h" #include "state.h" #include "lexer.h" -#include "y.tab.h" +#include "parser.h" +#include "expression.h" #include "../lib/logger.h" #include diff --git a/src/lexer.c b/src/lexer.c index b5be489..52a5b1c 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -1,5 +1,6 @@ +#line 2 "/home/david/mac/SourceCode/zmap/src/lexer.c" -#line 3 "" +#line 4 "/home/david/mac/SourceCode/zmap/src/lexer.c" #define YY_INT_ALIGNED short int @@ -469,10 +470,10 @@ char *yytext; #line 1 "lexer.l" #line 2 "lexer.l" #include -#include "y.tab.h" +#include "parser.h" #define YY_NO_INPUT 1 -#line 476 "" +#line 477 "/home/david/mac/SourceCode/zmap/src/lexer.c" #define INITIAL 0 @@ -659,7 +660,7 @@ YY_DECL #line 9 "lexer.l" -#line 663 "" +#line 664 "/home/david/mac/SourceCode/zmap/src/lexer.c" if ( !(yy_init) ) { @@ -818,7 +819,7 @@ YY_RULE_SETUP #line 25 "lexer.l" ECHO; YY_BREAK -#line 822 "" +#line 823 "/home/david/mac/SourceCode/zmap/src/lexer.c" case YY_STATE_EOF(INITIAL): yyterminate(); diff --git a/src/lexer.h b/src/lexer.h index 42a19e9..fe793da 100644 --- a/src/lexer.h +++ b/src/lexer.h @@ -2,7 +2,9 @@ #define yyHEADER_H 1 #define yyIN_HEADER 1 -#line 6 "lexer.h" +#line 6 "/home/david/mac/SourceCode/zmap/src/lexer.h" + +#line 8 "/home/david/mac/SourceCode/zmap/src/lexer.h" #define YY_INT_ALIGNED short int @@ -325,6 +327,6 @@ extern int yylex (void); #line 25 "lexer.l" -#line 329 "lexer.h" +#line 331 "/home/david/mac/SourceCode/zmap/src/lexer.h" #undef yyIN_HEADER #endif /* yyHEADER_H */ diff --git a/src/lexer.l b/src/lexer.l index 0fa3b90..f1ee546 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -1,6 +1,6 @@ %{ #include -#include "y.tab.h" +#include "parser.h" %} diff --git a/src/parser.c b/src/parser.c index 86802d1..43047ca 100644 --- a/src/parser.c +++ b/src/parser.c @@ -49,7 +49,7 @@ typedef union { struct node *expr; } YYSTYPE; #endif /* !YYSTYPE_IS_DECLARED */ -#line 52 "y.tab.c" +#line 52 "parser.c" /* compatibility with bison */ #ifdef YYPARSE_PARAM @@ -250,7 +250,7 @@ static YYSTACKDATA yystack; #line 144 "parser.y" -#line 253 "y.tab.c" +#line 253 "parser.c" #if YYDEBUG #include /* needed for printf */ @@ -566,7 +566,7 @@ case 15: yyval.expr->right_child = make_field_node(yystack.l_mark[0].string_literal); } break; -#line 569 "y.tab.c" +#line 569 "parser.c" } yystack.s_mark -= yym; yystate = *yystack.s_mark; diff --git a/src/y.tab.h b/src/y.tab.h deleted file mode 100644 index 8f8af3a..0000000 --- a/src/y.tab.h +++ /dev/null @@ -1,20 +0,0 @@ -#define T_AND 257 -#define T_OR 258 -#define T_NUMBER 259 -#define T_FIELD 260 -#define T_NOT_EQ 261 -#define T_GT_EQ 262 -#define T_LT_EQ 263 -#ifdef YYSTYPE -#undef YYSTYPE_IS_DECLARED -#define YYSTYPE_IS_DECLARED 1 -#endif -#ifndef YYSTYPE_IS_DECLARED -#define YYSTYPE_IS_DECLARED 1 -typedef union { - int int_literal; - char *string_literal; - struct node *expr; -} YYSTYPE; -#endif /* !YYSTYPE_IS_DECLARED */ -extern YYSTYPE yylval; From 45918fecede9b1f6185e956ff9b72ec2db6043b5 Mon Sep 17 00:00:00 2001 From: David Adrian Date: Fri, 4 Oct 2013 11:59:41 -0400 Subject: [PATCH 23/53] Fix JSON build errors Updated module_json.c to use field_t.value as a union, not as a pointer. --- src/output_modules/module_json.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/output_modules/module_json.c b/src/output_modules/module_json.c index 096540c..594b54c 100644 --- a/src/output_modules/module_json.c +++ b/src/output_modules/module_json.c @@ -149,13 +149,13 @@ int json_output_file_ip(fieldset_t *fs) field_t *f = &(fs->fields[i]); if (f->type == FS_STRING) { json_object_object_add(obj, f->name, - json_object_new_string((char*) f->value)); + json_object_new_string((char *) f->value.ptr)); } else if (f->type == FS_UINT64) { json_object_object_add(obj, f->name, - json_object_new_int((int) f->value)); + json_object_new_int((int) f->value.num)); } else if (f->type == FS_BINARY) { json_output_file_store_data(obj, - (const u_char*) f->value, f->len); + (const u_char*) f->value.ptr, f->len); } else if (f->type == FS_NULL) { // do nothing } else { From df68f4e57dd215c9d696b672e9503c3c6d46fd1d Mon Sep 17 00:00:00 2001 From: Zakir Durumeric Date: Mon, 7 Oct 2013 17:08:23 -0400 Subject: [PATCH 24/53] adding ability to scan specific CIDR blocks or addresses. --- lib/blacklist.c | 103 +++++++++++++++++++++++++++------------------ lib/blacklist.h | 7 ++- src/CMakeLists.txt | 2 +- src/cyclic.c | 18 +++++--- src/state.h | 2 + src/zmap.c | 20 ++++++--- 6 files changed, 99 insertions(+), 53 deletions(-) diff --git a/lib/blacklist.c b/lib/blacklist.c index a33860a..e5d5919 100644 --- a/lib/blacklist.c +++ b/lib/blacklist.c @@ -51,7 +51,38 @@ void whitelist_prefix(char *ip, int prefix_len) constraint_set(constraint, ntohl(inet_addr(ip)), prefix_len, ADDR_ALLOWED); } -static int init(char *file, const char *name, int value) +static int init_from_string(char *ip, int value) +{ + int prefix_len = 32; + char *slash = strchr(ip, '/'); + if (slash) { // split apart network and prefix length + *slash = '\0'; + char *end; + char *len = slash+1; + errno = 0; + prefix_len = strtol(len, &end, 10); + if (end == len || errno != 0 || prefix_len < 0 || prefix_len > 32) { + log_fatal("constraint", "'%s' is not a valid prefix length", len); + return -1; + } + } + struct in_addr addr; + if (inet_aton(ip, &addr) == 0) { + log_error("constraint", "'%s' is not a valid IP address", ip); + return -1; + } + constraint_set(constraint, ntohl(addr.s_addr), prefix_len, value); + char *name; + if (value == ADDR_DISALLOWED) + name = "blacklisting"; + else + name = "whitelisting"; + log_trace(name, "%s %s/%i", + name, ip, prefix_len); +} + + +static int init_from_file(char *file, const char *name, int value) { FILE *fp; char line[1000]; @@ -70,31 +101,22 @@ static int init(char *file, const char *name, int value) if ((sscanf(line, "%32s", ip)) == EOF) { continue; } - int prefix_len = 32; - char *slash = strchr(ip, '/'); - if (slash) { // split apart network and prefix length - *slash = '\0'; - char *end; - char *len = slash+1; - errno = 0; - prefix_len = strtol(len, &end, 10); - if (end == len || errno != 0 || prefix_len < 0 || prefix_len > 32) { - log_fatal(name, "Unable to parse %s file: %s ('%s' is not a valid prefix length)", name, file, len); - } + if (init_from_string(ip, value)) { + log_fatal(name, "unable to parse %s file: %s", name, file); } - struct in_addr addr; - if (inet_aton(ip, &addr) == 0) { - log_fatal(name, "Unable to parse %s file: %s ('%s' is not a valid IP address)", name, file, ip); - } - constraint_set(constraint, ntohl(addr.s_addr), prefix_len, value); - log_trace(name, "%sing %s/%i", - name, ip, prefix_len); } fclose(fp); return 0; } +void static init_from_array(char **cidrs, size_t len, int value) +{ + for (int i=0; i < (int) len; i++) { + init_from_string(cidrs[i], value); + } +} + uint64_t blacklist_count_allowed() { assert(constraint); @@ -107,42 +129,43 @@ uint64_t blacklist_count_not_allowed() return constraint_count_ips(constraint, ADDR_DISALLOWED); } - // Initialize address constraints from whitelist and blacklist files. // Either can be set to NULL to omit. -int blacklist_init_from_files(char *whitelist_filename, char *blacklist_filename) +int blacklist_init(char *whitelist_filename, char *blacklist_filename, + char **whitelist_entries, size_t whitelist_entries_len, + char **blacklist_entries, size_t blacklist_entries_len) { assert(!constraint); - if (whitelist_filename) { + if (whitelist_filename && whitelist_entries) { + log_warn("whitelist", "both a whitelist file and destination addresses " + "were specified. The union of these two sources " + "will be utilized."); + } + if (whitelist_filename || whitelist_entries) { // using a whitelist, so default to allowing nothing constraint = constraint_init(ADDR_DISALLOWED); log_trace("whitelist", "blacklisting 0.0.0.0/0"); - init(whitelist_filename, "whitelist", ADDR_ALLOWED); + if (whitelist_filename) { + init_from_file(whitelist_filename, "whitelist", ADDR_ALLOWED); + } + if (whitelist_entries) { + init_from_array(whitelist_entries, + whitelist_entries_len, ADDR_ALLOWED); + } } else { // no whitelist, so default to allowing everything constraint = constraint_init(ADDR_ALLOWED); } if (blacklist_filename) { - init(blacklist_filename, "blacklist", ADDR_DISALLOWED); + init_from_file(blacklist_filename, "blacklist", ADDR_DISALLOWED); + } + if (blacklist_entries) { + init_from_array(blacklist_entries, blacklist_entries_len, ADDR_DISALLOWED); } constraint_paint_value(constraint, ADDR_ALLOWED); uint64_t allowed = blacklist_count_allowed(); log_debug("blacklist", "%lu addresses allowed to be scanned (%0.0f%% of address space)", allowed, allowed*100./((long long int)1 << 32)); - - /* - // test - log_debug("blacklist", "testing started"); - uint64_t count = constraint_count_ips(constraint, ADDR_ALLOWED); - for (unsigned int i=0; i < count; i++) { - int ip = constraint_lookup_index(constraint, i, ADDR_ALLOWED); - if ((i & 0xFFFFFF) == 0) - log_info("blacklist", "%x", i & 0xFF000000); - if (constraint_lookup_ip(constraint, ip) != ADDR_ALLOWED) { - log_error("blacklist", "test failed for index %d", i); - } - } - log_debug("blacklist", "testing complete"); - */ - return 0; + return EXIT_SUCCESS; } + diff --git a/lib/blacklist.h b/lib/blacklist.h index 98d77b4..ce5f136 100644 --- a/lib/blacklist.h +++ b/lib/blacklist.h @@ -1,3 +1,4 @@ +#include #include #ifndef BLACKLIST_H @@ -7,7 +8,11 @@ uint32_t blacklist_lookup_index(uint64_t index); int blacklist_is_allowed(uint32_t s_addr); void blacklist_prefix(char *ip, int prefix_len); void whitelist_prefix(char *ip, int prefix_len); -int blacklist_init_from_files(char *whitelist, char*blacklist); +int blacklist_init(char *whitelist, char *blacklist, + char **whitelist_entries, + size_t whitelist_entries_len, + char **blacklist_entries, + size_t blacklist_entries_len); uint64_t blacklist_count_allowed(); uint64_t blacklist_count_not_allowed(); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 50bf1ee..13fffbd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -67,7 +67,7 @@ if (WITH_REDIS) endif() add_custom_command(OUTPUT zopt.h - COMMAND gengetopt -C --no-help --no-version -i "${CMAKE_CURRENT_SOURCE_DIR}/zopt.ggo" -F "${CMAKE_CURRENT_BINARY_DIR}/zopt" + COMMAND gengetopt -C --no-help --no-version --unamed-opts=SUBNETS -i "${CMAKE_CURRENT_SOURCE_DIR}/zopt.ggo" -F "${CMAKE_CURRENT_BINARY_DIR}/zopt" ) add_executable(zmap ${SOURCES}) diff --git a/src/cyclic.c b/src/cyclic.c index 7d2eeee..9f53690 100644 --- a/src/cyclic.c +++ b/src/cyclic.c @@ -148,17 +148,25 @@ static uint64_t find_primroot(const cyclic_group_t *group) int cyclic_init(uint32_t primroot_, uint32_t current_) { assert(!(!primroot_ && current_)); - // Initialize blacklist - if (blacklist_init_from_files(zconf.whitelist_filename, - zconf.blacklist_filename)) { + if (blacklist_init(zconf.whitelist_filename, zconf.blacklist_filename, + zconf.destination_cidrs, zconf.destination_cidrs_len, + NULL, 0)) { return -1; } num_addrs = blacklist_count_allowed(); + if (!num_addrs) { + log_error("blacklist", "no addresses are eligible to be scanned in the " + "current configuration. This may be because the " + "blacklist being used by ZMap (%s) prevents " + "any addresses from receiving probe packets.", + zconf.blacklist_filename + ); + exit(EXIT_FAILURE); + } - uint32_t i; const cyclic_group_t *cur_group = NULL; - for (i=0; i num_addrs) { cur_group = &groups[i]; log_debug("cyclic", "using prime %lu, known_primroot %lu", cur_group->prime, cur_group->known_primroot); diff --git a/src/state.h b/src/state.h index 5bd3f75..bb4181a 100644 --- a/src/state.h +++ b/src/state.h @@ -77,6 +77,8 @@ struct state_conf { char *output_filename; char *blacklist_filename; char *whitelist_filename; + char **destination_cidrs; + int destination_cidrs_len; char *raw_output_fields; char **output_fields; struct fieldset_conf fsconf; diff --git a/src/zmap.c b/src/zmap.c index 083566d..1356489 100644 --- a/src/zmap.c +++ b/src/zmap.c @@ -180,8 +180,6 @@ static void summary(void) static void start_zmap(void) { log_info("zmap", "started"); - - // finish setting up configuration if (zconf.iface == NULL) { char errbuf[PCAP_ERRBUF_SIZE]; char *iface = pcap_lookupdev(errbuf); @@ -223,7 +221,6 @@ static void start_zmap(void) zconf.gw_mac[0], zconf.gw_mac[1], zconf.gw_mac[2], zconf.gw_mac[3], zconf.gw_mac[4], zconf.gw_mac[5]); } - // initialization if (zconf.output_module && zconf.output_module->init) { zconf.output_module->init(&zconf, zconf.output_fields, @@ -446,7 +443,6 @@ int main(int argc, char *argv[]) CMDLINE_PARSER_PACKAGE, args.probe_module_arg); exit(EXIT_FAILURE); } - // now that we know the probe module, let's find what it supports memset(&zconf.fsconf, 0, sizeof(struct fieldset_conf)); // the set of fields made available to a user is constructed @@ -498,6 +494,7 @@ int main(int argc, char *argv[]) &zconf.fsconf.defs, zconf.output_fields, zconf.output_fields_len); + SET_BOOL(zconf.dryrun, dryrun); SET_BOOL(zconf.quiet, quiet); SET_BOOL(zconf.summary, summary); @@ -505,7 +502,6 @@ int main(int argc, char *argv[]) zconf.senders = args.sender_threads_arg; SET_IF_GIVEN(zconf.output_filename, output_file); SET_IF_GIVEN(zconf.blacklist_filename, blacklist_file); - SET_IF_GIVEN(zconf.whitelist_filename, whitelist_file); SET_IF_GIVEN(zconf.probe_args, probe_args); SET_IF_GIVEN(zconf.output_args, output_args); SET_IF_GIVEN(zconf.iface, interface); @@ -513,8 +509,20 @@ int main(int argc, char *argv[]) SET_IF_GIVEN(zconf.max_results, max_results); SET_IF_GIVEN(zconf.rate, rate); SET_IF_GIVEN(zconf.packet_streams, probes); - + // find if zmap wants any specific cidrs scanned instead + // of the entire Internet + zconf.destination_cidrs = args.inputs; + zconf.destination_cidrs_len = args.inputs_num; + if (zconf.destination_cidrs && zconf.blacklist_filename + && !strcmp(zconf.blacklist_filename, "/etc/zmap/blacklist.conf")) { + log_warn("blacklist", "ZMap is currently using the default blacklist located " + "at /etc/zmap/blacklist.conf. By default, this blacklist excludes locally " + "scoped networks (e.g. 10.0.0.0/8, 127.0.0.1/8, and 192.168.0.0/16). If you are" + " trying to scan local networks, you can change the default blacklist by " + "editing the default ZMap configuration at /etc/zmap/zmap.conf."); + } + if (zconf.probe_module->port_args) { if (args.source_port_given) { char *dash = strchr(args.source_port_arg, '-'); From 277f49457d1bc5aa1de8ac73ffc34dae68d8cd6f Mon Sep 17 00:00:00 2001 From: Zakir Durumeric Date: Mon, 7 Oct 2013 17:08:23 -0400 Subject: [PATCH 25/53] adding ability to scan specific CIDR blocks or addresses. --- lib/blacklist.c | 103 +++++++++++++++++++++++++++------------------ lib/blacklist.h | 7 ++- lib/pbm.c | 54 ++++++++++++++++++++++++ lib/pbm.h | 5 +++ src/CMakeLists.txt | 3 +- src/cyclic.c | 18 +++++--- src/recv.c | 26 +++--------- src/state.h | 2 + src/zmap.c | 20 ++++++--- src/zopt.ggo | 5 ++- 10 files changed, 168 insertions(+), 75 deletions(-) create mode 100644 lib/pbm.c create mode 100644 lib/pbm.h diff --git a/lib/blacklist.c b/lib/blacklist.c index a33860a..e5d5919 100644 --- a/lib/blacklist.c +++ b/lib/blacklist.c @@ -51,7 +51,38 @@ void whitelist_prefix(char *ip, int prefix_len) constraint_set(constraint, ntohl(inet_addr(ip)), prefix_len, ADDR_ALLOWED); } -static int init(char *file, const char *name, int value) +static int init_from_string(char *ip, int value) +{ + int prefix_len = 32; + char *slash = strchr(ip, '/'); + if (slash) { // split apart network and prefix length + *slash = '\0'; + char *end; + char *len = slash+1; + errno = 0; + prefix_len = strtol(len, &end, 10); + if (end == len || errno != 0 || prefix_len < 0 || prefix_len > 32) { + log_fatal("constraint", "'%s' is not a valid prefix length", len); + return -1; + } + } + struct in_addr addr; + if (inet_aton(ip, &addr) == 0) { + log_error("constraint", "'%s' is not a valid IP address", ip); + return -1; + } + constraint_set(constraint, ntohl(addr.s_addr), prefix_len, value); + char *name; + if (value == ADDR_DISALLOWED) + name = "blacklisting"; + else + name = "whitelisting"; + log_trace(name, "%s %s/%i", + name, ip, prefix_len); +} + + +static int init_from_file(char *file, const char *name, int value) { FILE *fp; char line[1000]; @@ -70,31 +101,22 @@ static int init(char *file, const char *name, int value) if ((sscanf(line, "%32s", ip)) == EOF) { continue; } - int prefix_len = 32; - char *slash = strchr(ip, '/'); - if (slash) { // split apart network and prefix length - *slash = '\0'; - char *end; - char *len = slash+1; - errno = 0; - prefix_len = strtol(len, &end, 10); - if (end == len || errno != 0 || prefix_len < 0 || prefix_len > 32) { - log_fatal(name, "Unable to parse %s file: %s ('%s' is not a valid prefix length)", name, file, len); - } + if (init_from_string(ip, value)) { + log_fatal(name, "unable to parse %s file: %s", name, file); } - struct in_addr addr; - if (inet_aton(ip, &addr) == 0) { - log_fatal(name, "Unable to parse %s file: %s ('%s' is not a valid IP address)", name, file, ip); - } - constraint_set(constraint, ntohl(addr.s_addr), prefix_len, value); - log_trace(name, "%sing %s/%i", - name, ip, prefix_len); } fclose(fp); return 0; } +void static init_from_array(char **cidrs, size_t len, int value) +{ + for (int i=0; i < (int) len; i++) { + init_from_string(cidrs[i], value); + } +} + uint64_t blacklist_count_allowed() { assert(constraint); @@ -107,42 +129,43 @@ uint64_t blacklist_count_not_allowed() return constraint_count_ips(constraint, ADDR_DISALLOWED); } - // Initialize address constraints from whitelist and blacklist files. // Either can be set to NULL to omit. -int blacklist_init_from_files(char *whitelist_filename, char *blacklist_filename) +int blacklist_init(char *whitelist_filename, char *blacklist_filename, + char **whitelist_entries, size_t whitelist_entries_len, + char **blacklist_entries, size_t blacklist_entries_len) { assert(!constraint); - if (whitelist_filename) { + if (whitelist_filename && whitelist_entries) { + log_warn("whitelist", "both a whitelist file and destination addresses " + "were specified. The union of these two sources " + "will be utilized."); + } + if (whitelist_filename || whitelist_entries) { // using a whitelist, so default to allowing nothing constraint = constraint_init(ADDR_DISALLOWED); log_trace("whitelist", "blacklisting 0.0.0.0/0"); - init(whitelist_filename, "whitelist", ADDR_ALLOWED); + if (whitelist_filename) { + init_from_file(whitelist_filename, "whitelist", ADDR_ALLOWED); + } + if (whitelist_entries) { + init_from_array(whitelist_entries, + whitelist_entries_len, ADDR_ALLOWED); + } } else { // no whitelist, so default to allowing everything constraint = constraint_init(ADDR_ALLOWED); } if (blacklist_filename) { - init(blacklist_filename, "blacklist", ADDR_DISALLOWED); + init_from_file(blacklist_filename, "blacklist", ADDR_DISALLOWED); + } + if (blacklist_entries) { + init_from_array(blacklist_entries, blacklist_entries_len, ADDR_DISALLOWED); } constraint_paint_value(constraint, ADDR_ALLOWED); uint64_t allowed = blacklist_count_allowed(); log_debug("blacklist", "%lu addresses allowed to be scanned (%0.0f%% of address space)", allowed, allowed*100./((long long int)1 << 32)); - - /* - // test - log_debug("blacklist", "testing started"); - uint64_t count = constraint_count_ips(constraint, ADDR_ALLOWED); - for (unsigned int i=0; i < count; i++) { - int ip = constraint_lookup_index(constraint, i, ADDR_ALLOWED); - if ((i & 0xFFFFFF) == 0) - log_info("blacklist", "%x", i & 0xFF000000); - if (constraint_lookup_ip(constraint, ip) != ADDR_ALLOWED) { - log_error("blacklist", "test failed for index %d", i); - } - } - log_debug("blacklist", "testing complete"); - */ - return 0; + return EXIT_SUCCESS; } + diff --git a/lib/blacklist.h b/lib/blacklist.h index 98d77b4..ce5f136 100644 --- a/lib/blacklist.h +++ b/lib/blacklist.h @@ -1,3 +1,4 @@ +#include #include #ifndef BLACKLIST_H @@ -7,7 +8,11 @@ uint32_t blacklist_lookup_index(uint64_t index); int blacklist_is_allowed(uint32_t s_addr); void blacklist_prefix(char *ip, int prefix_len); void whitelist_prefix(char *ip, int prefix_len); -int blacklist_init_from_files(char *whitelist, char*blacklist); +int blacklist_init(char *whitelist, char *blacklist, + char **whitelist_entries, + size_t whitelist_entries_len, + char **blacklist_entries, + size_t blacklist_entries_len); uint64_t blacklist_count_allowed(); uint64_t blacklist_count_not_allowed(); diff --git a/lib/pbm.c b/lib/pbm.c new file mode 100644 index 0000000..154a535 --- /dev/null +++ b/lib/pbm.c @@ -0,0 +1,54 @@ +#include +#include +#include +#include +#include + +#include "logger.h" + +#define NUM_VALUES 0xFFFFFFFF +#define PAGE_SIZE 0xFFFF +#define NUM_PAGES (NUM_VALUES / PAGE_SIZE) +#define SIZE (8*sizeof(uint64_t)) + +uint64_t** pbm_init(void) +{ + uint64_t** retv = calloc(NUM_PAGES, sizeof(void*)); + if (!retv) { + log_fatal("pbm", "unable to allocate memory for base page table"); + } + return retv; +} + +static int bm_check(uint64_t *bm, uint32_t v) +{ + return bm[v/SIZE] & (1<< (v % SIZE)); +} + +static void bm_set(uint64_t *bm, uint32_t v) +{ + bm[v/SIZE] |= (1 << (v % SIZE)); +} + +int pbm_check(uint64_t **b, uint32_t v) +{ + uint32_t top = v >> 16; + uint32_t bottom = v & PAGE_SIZE; + return b[top] && bm_check(b[top], bottom); +} + +void pbm_set(uint64_t **b, uint32_t v) +{ + uint32_t top = v >> 16; + uint32_t bottom = v & PAGE_SIZE; + if (!b[top]) { + uint64_t *bm = malloc(PAGE_SIZE); + if (!bm) { + log_fatal("bpm", "unable to allocate memory for new bitmap page"); + } + memset(bm, 0, PAGE_SIZE); + b[top] = bm; + } + bm_set(b[top], bottom); +} + diff --git a/lib/pbm.h b/lib/pbm.h new file mode 100644 index 0000000..df3b6fd --- /dev/null +++ b/lib/pbm.h @@ -0,0 +1,5 @@ +#include + +uint64_t** pbm_init(void); +int pbm_check(uint64_t **b, uint32_t v); +void pbm_set(uint64_t **b, uint32_t v); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 50bf1ee..05177a9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -9,6 +9,7 @@ SET(LIB_SOURCES ${PROJECT_SOURCE_DIR}/lib/blacklist.c ${PROJECT_SOURCE_DIR}/lib/constraint.c ${PROJECT_SOURCE_DIR}/lib/logger.c + ${PROJECT_SOURCE_DIR}/lib/pbm.c ${PROJECT_SOURCE_DIR}/lib/random.c ${PROJECT_SOURCE_DIR}/lib/rijndael-alg-fst.c ) @@ -67,7 +68,7 @@ if (WITH_REDIS) endif() add_custom_command(OUTPUT zopt.h - COMMAND gengetopt -C --no-help --no-version -i "${CMAKE_CURRENT_SOURCE_DIR}/zopt.ggo" -F "${CMAKE_CURRENT_BINARY_DIR}/zopt" + COMMAND gengetopt -C --no-help --no-version --unamed-opts=SUBNETS -i "${CMAKE_CURRENT_SOURCE_DIR}/zopt.ggo" -F "${CMAKE_CURRENT_BINARY_DIR}/zopt" ) add_executable(zmap ${SOURCES}) diff --git a/src/cyclic.c b/src/cyclic.c index 7d2eeee..9f53690 100644 --- a/src/cyclic.c +++ b/src/cyclic.c @@ -148,17 +148,25 @@ static uint64_t find_primroot(const cyclic_group_t *group) int cyclic_init(uint32_t primroot_, uint32_t current_) { assert(!(!primroot_ && current_)); - // Initialize blacklist - if (blacklist_init_from_files(zconf.whitelist_filename, - zconf.blacklist_filename)) { + if (blacklist_init(zconf.whitelist_filename, zconf.blacklist_filename, + zconf.destination_cidrs, zconf.destination_cidrs_len, + NULL, 0)) { return -1; } num_addrs = blacklist_count_allowed(); + if (!num_addrs) { + log_error("blacklist", "no addresses are eligible to be scanned in the " + "current configuration. This may be because the " + "blacklist being used by ZMap (%s) prevents " + "any addresses from receiving probe packets.", + zconf.blacklist_filename + ); + exit(EXIT_FAILURE); + } - uint32_t i; const cyclic_group_t *cur_group = NULL; - for (i=0; i num_addrs) { cur_group = &groups[i]; log_debug("cyclic", "using prime %lu, known_primroot %lu", cur_group->prime, cur_group->known_primroot); diff --git a/src/recv.c b/src/recv.c index 7f15765..bb52fcd 100644 --- a/src/recv.c +++ b/src/recv.c @@ -30,6 +30,7 @@ #include #include "../lib/logger.h" +#include "../lib/pbm.h" #include "state.h" #include "validate.h" @@ -44,20 +45,7 @@ static uint32_t num_src_ports; static pcap_t *pc = NULL; // bitmap of observed IP addresses -static uint64_t *ip_seen = NULL; -static const int IP_SEEN_SIZE = 0x4000000; // == 2^32/64 - -// check if we've received a response from this address previously -static inline int check_ip(uint32_t ip) -{ - return (ip_seen[ip >> 6] >> (ip & 0x3F)) & 1; -} - -// set that we've received a response from the address -static inline void set_ip(uint32_t ip) -{ - ip_seen[ip >> 6] |= (uint64_t)1 << (ip & 0x3F); -} +static uint64_t **seen = NULL; static u_char fake_eth_hdr[65535]; @@ -95,7 +83,7 @@ void packet_cb(u_char __attribute__((__unused__)) *user, return; } - int is_repeat = check_ip(src_ip); + int is_repeat = pbm_check(seen, ntohl(src_ip)); fieldset_t *fs = fs_new_fieldset(); fs_add_ip_fields(fs, ip_hdr); @@ -121,7 +109,7 @@ void packet_cb(u_char __attribute__((__unused__)) *user, zrecv.success_total++; if (!is_repeat) { zrecv.success_unique++; - set_ip(src_ip); + pbm_set(seen, ntohl(src_ip)); } if (zsend.complete) { zrecv.cooldown_total++; @@ -176,10 +164,6 @@ int recv_run(pthread_mutex_t *recv_ready_mutex) { log_debug("recv", "thread started"); num_src_ports = zconf.source_port_last - zconf.source_port_first + 1; - ip_seen = calloc(IP_SEEN_SIZE, sizeof(uint64_t)); - if (!ip_seen) { - log_fatal("recv", "could not allocate address bitmap"); - } log_debug("recv", "using dev %s", zconf.iface); if (!zconf.dryrun) { char errbuf[PCAP_ERRBUF_SIZE]; @@ -202,6 +186,8 @@ int recv_run(pthread_mutex_t *recv_ready_mutex) memset(fake_eth_hdr, 0, sizeof(fake_eth_hdr)); eth->h_proto = htons(ETH_P_IP); } + // initialize paged bitmap + seen = pbm_init(); log_debug("recv", "receiver ready"); if (zconf.filter_duplicates) { log_debug("recv", "duplicate responses will be excluded from output"); diff --git a/src/state.h b/src/state.h index 5bd3f75..bb4181a 100644 --- a/src/state.h +++ b/src/state.h @@ -77,6 +77,8 @@ struct state_conf { char *output_filename; char *blacklist_filename; char *whitelist_filename; + char **destination_cidrs; + int destination_cidrs_len; char *raw_output_fields; char **output_fields; struct fieldset_conf fsconf; diff --git a/src/zmap.c b/src/zmap.c index 083566d..1356489 100644 --- a/src/zmap.c +++ b/src/zmap.c @@ -180,8 +180,6 @@ static void summary(void) static void start_zmap(void) { log_info("zmap", "started"); - - // finish setting up configuration if (zconf.iface == NULL) { char errbuf[PCAP_ERRBUF_SIZE]; char *iface = pcap_lookupdev(errbuf); @@ -223,7 +221,6 @@ static void start_zmap(void) zconf.gw_mac[0], zconf.gw_mac[1], zconf.gw_mac[2], zconf.gw_mac[3], zconf.gw_mac[4], zconf.gw_mac[5]); } - // initialization if (zconf.output_module && zconf.output_module->init) { zconf.output_module->init(&zconf, zconf.output_fields, @@ -446,7 +443,6 @@ int main(int argc, char *argv[]) CMDLINE_PARSER_PACKAGE, args.probe_module_arg); exit(EXIT_FAILURE); } - // now that we know the probe module, let's find what it supports memset(&zconf.fsconf, 0, sizeof(struct fieldset_conf)); // the set of fields made available to a user is constructed @@ -498,6 +494,7 @@ int main(int argc, char *argv[]) &zconf.fsconf.defs, zconf.output_fields, zconf.output_fields_len); + SET_BOOL(zconf.dryrun, dryrun); SET_BOOL(zconf.quiet, quiet); SET_BOOL(zconf.summary, summary); @@ -505,7 +502,6 @@ int main(int argc, char *argv[]) zconf.senders = args.sender_threads_arg; SET_IF_GIVEN(zconf.output_filename, output_file); SET_IF_GIVEN(zconf.blacklist_filename, blacklist_file); - SET_IF_GIVEN(zconf.whitelist_filename, whitelist_file); SET_IF_GIVEN(zconf.probe_args, probe_args); SET_IF_GIVEN(zconf.output_args, output_args); SET_IF_GIVEN(zconf.iface, interface); @@ -513,8 +509,20 @@ int main(int argc, char *argv[]) SET_IF_GIVEN(zconf.max_results, max_results); SET_IF_GIVEN(zconf.rate, rate); SET_IF_GIVEN(zconf.packet_streams, probes); - + // find if zmap wants any specific cidrs scanned instead + // of the entire Internet + zconf.destination_cidrs = args.inputs; + zconf.destination_cidrs_len = args.inputs_num; + if (zconf.destination_cidrs && zconf.blacklist_filename + && !strcmp(zconf.blacklist_filename, "/etc/zmap/blacklist.conf")) { + log_warn("blacklist", "ZMap is currently using the default blacklist located " + "at /etc/zmap/blacklist.conf. By default, this blacklist excludes locally " + "scoped networks (e.g. 10.0.0.0/8, 127.0.0.1/8, and 192.168.0.0/16). If you are" + " trying to scan local networks, you can change the default blacklist by " + "editing the default ZMap configuration at /etc/zmap/zmap.conf."); + } + if (zconf.probe_module->port_args) { if (args.source_port_given) { char *dash = strchr(args.source_port_arg, '-'); diff --git a/src/zopt.ggo b/src/zopt.ggo index 71f0aef..48844b6 100644 --- a/src/zopt.ggo +++ b/src/zopt.ggo @@ -122,5 +122,6 @@ option "version" V "Print version and exit" text "\nExamples:\n\ zmap -p 443 (scans the whole Internet for hosts with port 443 open)\n\ - zmap -N 5 -B 10M -p 80 -o - (find 5 HTTP servers, scanning at 10 Mb/s)" - + zmap -N 5 -B 10M -p 80 -o - (find 5 HTTP servers, scanning at 10 Mb/s)\n + zmap -p 80 10.0.0.0/8 192.168.0.0/16 -o (scan 10.0.0.0/8 and 192.168.0.0/16 on port 80)\n + zmap -p 80 192.168.1.2 192.168.1.3 (scan 192.168.1.2 and 192.168.1.3 on port 80)" From af834fe2e24d7dfabd5a42792107de21bcd289d7 Mon Sep 17 00:00:00 2001 From: David Adrian Date: Wed, 9 Oct 2013 12:49:58 -0400 Subject: [PATCH 26/53] Update build to -Werror, #pragma to ignore in lexer.l --- .gitignore | 4 + CMakeLists.txt | 2 +- src/lexer.c | 1785 ------------------------------------------------ src/lexer.h | 332 --------- src/lexer.l | 1 + 5 files changed, 6 insertions(+), 2118 deletions(-) delete mode 100644 src/lexer.c delete mode 100644 src/lexer.h diff --git a/.gitignore b/.gitignore index 889d9e6..2c2e6ad 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,7 @@ Makefile CMakeCache.txt src/zopt.h src/zopt.c +lexer.c +lexer.h +parser.c +parser.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e27443e..0a403b7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ if(ENABLE_DEVELOPMENT) "-Wnested-externs -Wbad-function-cast -Winit-self" "-Wmissing-noreturn -Wnormalized=id" "-Wstack-protector" - #"-Werror" + "-Werror" ) # Fix line breaks diff --git a/src/lexer.c b/src/lexer.c deleted file mode 100644 index 52a5b1c..0000000 --- a/src/lexer.c +++ /dev/null @@ -1,1785 +0,0 @@ -#line 2 "/home/david/mac/SourceCode/zmap/src/lexer.c" - -#line 4 "/home/david/mac/SourceCode/zmap/src/lexer.c" - -#define YY_INT_ALIGNED short int - -/* A lexical scanner generated by flex */ - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 35 -#if YY_FLEX_SUBMINOR_VERSION > 0 -#define FLEX_BETA -#endif - -/* First, we deal with platform-specific or compiler-specific issues. */ - -/* begin standard C headers. */ -#include -#include -#include -#include - -/* end standard C headers. */ - -/* flex integer type definitions */ - -#ifndef FLEXINT_H -#define FLEXINT_H - -/* C99 systems have . Non-C99 systems may or may not. */ - -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - -/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, - * if you want the limit (max/min) macros for int types. - */ -#ifndef __STDC_LIMIT_MACROS -#define __STDC_LIMIT_MACROS 1 -#endif - -#include -typedef int8_t flex_int8_t; -typedef uint8_t flex_uint8_t; -typedef int16_t flex_int16_t; -typedef uint16_t flex_uint16_t; -typedef int32_t flex_int32_t; -typedef uint32_t flex_uint32_t; -#else -typedef signed char flex_int8_t; -typedef short int flex_int16_t; -typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; -typedef unsigned short int flex_uint16_t; -typedef unsigned int flex_uint32_t; - -/* Limits of integral types. */ -#ifndef INT8_MIN -#define INT8_MIN (-128) -#endif -#ifndef INT16_MIN -#define INT16_MIN (-32767-1) -#endif -#ifndef INT32_MIN -#define INT32_MIN (-2147483647-1) -#endif -#ifndef INT8_MAX -#define INT8_MAX (127) -#endif -#ifndef INT16_MAX -#define INT16_MAX (32767) -#endif -#ifndef INT32_MAX -#define INT32_MAX (2147483647) -#endif -#ifndef UINT8_MAX -#define UINT8_MAX (255U) -#endif -#ifndef UINT16_MAX -#define UINT16_MAX (65535U) -#endif -#ifndef UINT32_MAX -#define UINT32_MAX (4294967295U) -#endif - -#endif /* ! C99 */ - -#endif /* ! FLEXINT_H */ - -#ifdef __cplusplus - -/* The "const" storage-class-modifier is valid. */ -#define YY_USE_CONST - -#else /* ! __cplusplus */ - -/* C99 requires __STDC__ to be defined as 1. */ -#if defined (__STDC__) - -#define YY_USE_CONST - -#endif /* defined (__STDC__) */ -#endif /* ! __cplusplus */ - -#ifdef YY_USE_CONST -#define yyconst const -#else -#define yyconst -#endif - -/* Returned upon end-of-file. */ -#define YY_NULL 0 - -/* Promotes a possibly negative, possibly signed char to an unsigned - * integer for use as an array index. If the signed char is negative, - * we want to instead treat it as an 8-bit unsigned char, hence the - * double cast. - */ -#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) - -/* Enter a start condition. This macro really ought to take a parameter, - * but we do it the disgusting crufty way forced on us by the ()-less - * definition of BEGIN. - */ -#define BEGIN (yy_start) = 1 + 2 * - -/* Translate the current start state into a value that can be later handed - * to BEGIN to return to the state. The YYSTATE alias is for lex - * compatibility. - */ -#define YY_START (((yy_start) - 1) / 2) -#define YYSTATE YY_START - -/* Action number for EOF rule of a given start state. */ -#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) - -/* Special action meaning "start processing a new file". */ -#define YY_NEW_FILE yyrestart(yyin ) - -#define YY_END_OF_BUFFER_CHAR 0 - -/* Size of default input buffer. */ -#ifndef YY_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k. - * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. - * Ditto for the __ia64__ case accordingly. - */ -#define YY_BUF_SIZE 32768 -#else -#define YY_BUF_SIZE 16384 -#endif /* __ia64__ */ -#endif - -/* The state buf must be large enough to hold one state per character in the main buffer. - */ -#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) - -#ifndef YY_TYPEDEF_YY_BUFFER_STATE -#define YY_TYPEDEF_YY_BUFFER_STATE -typedef struct yy_buffer_state *YY_BUFFER_STATE; -#endif - -extern int yyleng; - -extern FILE *yyin, *yyout; - -#define EOB_ACT_CONTINUE_SCAN 0 -#define EOB_ACT_END_OF_FILE 1 -#define EOB_ACT_LAST_MATCH 2 - - #define YY_LESS_LINENO(n) - -/* Return all but the first "n" matched characters back to the input stream. */ -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - *yy_cp = (yy_hold_char); \ - YY_RESTORE_YY_MORE_OFFSET \ - (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) - -#define unput(c) yyunput( c, (yytext_ptr) ) - -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif - -#ifndef YY_STRUCT_YY_BUFFER_STATE -#define YY_STRUCT_YY_BUFFER_STATE -struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - yy_size_t yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - int yy_bs_lineno; /**< The line count. */ - int yy_bs_column; /**< The column count. */ - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; - -#define YY_BUFFER_NEW 0 -#define YY_BUFFER_NORMAL 1 - /* When an EOF's been seen but there's still some text to process - * then we mark the buffer as YY_EOF_PENDING, to indicate that we - * shouldn't try reading from the input source any more. We might - * still have a bunch of tokens to match, though, because of - * possible backing-up. - * - * When we actually see the EOF, we change the status to "new" - * (via yyrestart()), so that the user can continue scanning by - * just pointing yyin at a new input file. - */ -#define YY_BUFFER_EOF_PENDING 2 - - }; -#endif /* !YY_STRUCT_YY_BUFFER_STATE */ - -/* Stack of input buffers. */ -static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ -static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ -static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ - -/* We provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general - * "scanner state". - * - * Returns the top of the stack, or NULL. - */ -#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ - ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ - : NULL) - -/* Same as previous macro, but useful when we know that the buffer stack is not - * NULL or when we need an lvalue. For internal use only. - */ -#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] - -/* yy_hold_char holds the character lost when yytext is formed. */ -static char yy_hold_char; -static int yy_n_chars; /* number of characters read into yy_ch_buf */ -int yyleng; - -/* Points to current character in buffer. */ -static char *yy_c_buf_p = (char *) 0; -static int yy_init = 0; /* whether we need to initialize */ -static int yy_start = 0; /* start state number */ - -/* Flag which is used to allow yywrap()'s to do buffer switches - * instead of setting up a fresh yyin. A bit of a hack ... - */ -static int yy_did_buffer_switch_on_eof; - -void yyrestart (FILE *input_file ); -void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); -YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); -void yy_delete_buffer (YY_BUFFER_STATE b ); -void yy_flush_buffer (YY_BUFFER_STATE b ); -void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); -void yypop_buffer_state (void ); - -static void yyensure_buffer_stack (void ); -static void yy_load_buffer_state (void ); -static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); - -#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) - -YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); -YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); -YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ); - -void *yyalloc (yy_size_t ); -void *yyrealloc (void *,yy_size_t ); -void yyfree (void * ); - -#define yy_new_buffer yy_create_buffer - -#define yy_set_interactive(is_interactive) \ - { \ - if ( ! YY_CURRENT_BUFFER ){ \ - yyensure_buffer_stack (); \ - YY_CURRENT_BUFFER_LVALUE = \ - yy_create_buffer(yyin,YY_BUF_SIZE ); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ - } - -#define yy_set_bol(at_bol) \ - { \ - if ( ! YY_CURRENT_BUFFER ){\ - yyensure_buffer_stack (); \ - YY_CURRENT_BUFFER_LVALUE = \ - yy_create_buffer(yyin,YY_BUF_SIZE ); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ - } - -#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) - -/* Begin user sect3 */ - -typedef unsigned char YY_CHAR; - -FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; - -typedef int yy_state_type; - -extern int yylineno; - -int yylineno = 1; - -extern char *yytext; -#define yytext_ptr yytext - -static yy_state_type yy_get_previous_state (void ); -static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); -static int yy_get_next_buffer (void ); -static void yy_fatal_error (yyconst char msg[] ); - -/* Done after the current pattern has been matched and before the - * corresponding action - sets up yytext. - */ -#define YY_DO_BEFORE_ACTION \ - (yytext_ptr) = yy_bp; \ - yyleng = (size_t) (yy_cp - yy_bp); \ - (yy_hold_char) = *yy_cp; \ - *yy_cp = '\0'; \ - (yy_c_buf_p) = yy_cp; - -#define YY_NUM_RULES 15 -#define YY_END_OF_BUFFER 16 -/* This struct is not used in this scanner, - but its presence is necessary. */ -struct yy_trans_info - { - flex_int32_t yy_verify; - flex_int32_t yy_nxt; - }; -static yyconst flex_int16_t yy_accept[26] = - { 0, - 0, 0, 16, 15, 3, 2, 15, 15, 12, 13, - 1, 11, 9, 10, 15, 15, 3, 4, 7, 1, - 6, 5, 14, 8, 0 - } ; - -static yyconst flex_int32_t yy_ec[256] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 4, 1, 1, 1, 1, 5, 1, 6, - 7, 1, 1, 1, 1, 1, 1, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 1, 1, 9, - 10, 11, 1, 1, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 1, 1, 1, 1, 1, 1, 12, 12, 12, 12, - - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 1, 13, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 - } ; - -static yyconst flex_int32_t yy_meta[14] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, - 1, 2, 1 - } ; - -static yyconst flex_int16_t yy_base[27] = - { 0, - 0, 0, 24, 25, 21, 25, 12, 16, 25, 25, - 12, 9, 25, 8, 0, 4, 14, 25, 25, 7, - 25, 25, 0, 25, 25, 12 - } ; - -static yyconst flex_int16_t yy_def[27] = - { 0, - 25, 1, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 26, 25, 25, 25, 25, 25, - 25, 25, 26, 25, 0, 25 - } ; - -static yyconst flex_int16_t yy_nxt[39] = - { 0, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 23, 20, 17, 24, 22, 21, 20, - 19, 18, 17, 25, 3, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25 - } ; - -static yyconst flex_int16_t yy_chk[39] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 26, 20, 17, 16, 14, 12, 11, - 8, 7, 5, 3, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25 - } ; - -static yy_state_type yy_last_accepting_state; -static char *yy_last_accepting_cpos; - -extern int yy_flex_debug; -int yy_flex_debug = 0; - -/* The intent behind this definition is that it'll catch - * any uses of REJECT which flex missed. - */ -#define REJECT reject_used_but_not_detected -#define yymore() yymore_used_but_not_detected -#define YY_MORE_ADJ 0 -#define YY_RESTORE_YY_MORE_OFFSET -char *yytext; -#line 1 "lexer.l" -#line 2 "lexer.l" -#include -#include "parser.h" - -#define YY_NO_INPUT 1 -#line 477 "/home/david/mac/SourceCode/zmap/src/lexer.c" - -#define INITIAL 0 - -#ifndef YY_NO_UNISTD_H -/* Special case for "unistd.h", since it is non-ANSI. We include it way - * down here because we want the user's section 1 to have been scanned first. - * The user has a chance to override it with an option. - */ -#include -#endif - -#ifndef YY_EXTRA_TYPE -#define YY_EXTRA_TYPE void * -#endif - -static int yy_init_globals (void ); - -/* Accessor methods to globals. - These are made visible to non-reentrant scanners for convenience. */ - -int yylex_destroy (void ); - -int yyget_debug (void ); - -void yyset_debug (int debug_flag ); - -YY_EXTRA_TYPE yyget_extra (void ); - -void yyset_extra (YY_EXTRA_TYPE user_defined ); - -FILE *yyget_in (void ); - -void yyset_in (FILE * in_str ); - -FILE *yyget_out (void ); - -void yyset_out (FILE * out_str ); - -int yyget_leng (void ); - -char *yyget_text (void ); - -int yyget_lineno (void ); - -void yyset_lineno (int line_number ); - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int yywrap (void ); -#else -extern int yywrap (void ); -#endif -#endif - -#ifndef yytext_ptr -static void yy_flex_strncpy (char *,yyconst char *,int ); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * ); -#endif - -#ifndef YY_NO_INPUT - -#ifdef __cplusplus -static int yyinput (void ); -#else -static int input (void ); -#endif - -#endif - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k */ -#define YY_READ_BUF_SIZE 16384 -#else -#define YY_READ_BUF_SIZE 8192 -#endif /* __ia64__ */ -#endif - -/* Copy whatever the last rule matched to the standard output. */ -#ifndef ECHO -/* This used to be an fputs(), but since the string might contain NUL's, - * we now use fwrite(). - */ -#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) -#endif - -/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, - * is returned in "result". - */ -#ifndef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ - { \ - int c = '*'; \ - size_t n; \ - for ( n = 0; n < max_size && \ - (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ - buf[n] = (char) c; \ - if ( c == '\n' ) \ - buf[n++] = (char) c; \ - if ( c == EOF && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - result = n; \ - } \ - else \ - { \ - errno=0; \ - while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ - { \ - if( errno != EINTR) \ - { \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - break; \ - } \ - errno=0; \ - clearerr(yyin); \ - } \ - }\ -\ - -#endif - -/* No semi-colon after return; correct usage is to write "yyterminate();" - - * we don't want an extra ';' after the "return" because that will cause - * some compilers to complain about unreachable statements. - */ -#ifndef yyterminate -#define yyterminate() return YY_NULL -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Report a fatal error. */ -#ifndef YY_FATAL_ERROR -#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) -#endif - -/* end tables serialization structures and prototypes */ - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL_IS_OURS 1 - -extern int yylex (void); - -#define YY_DECL int yylex (void) -#endif /* !YY_DECL */ - -/* Code executed at the beginning of each rule, after yytext and yyleng - * have been set up. - */ -#ifndef YY_USER_ACTION -#define YY_USER_ACTION -#endif - -/* Code executed at the end of each rule. */ -#ifndef YY_BREAK -#define YY_BREAK break; -#endif - -#define YY_RULE_SETUP \ - YY_USER_ACTION - -/** The main scanner function which does all the work. - */ -YY_DECL -{ - register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; - register int yy_act; - -#line 9 "lexer.l" - -#line 664 "/home/david/mac/SourceCode/zmap/src/lexer.c" - - if ( !(yy_init) ) - { - (yy_init) = 1; - -#ifdef YY_USER_INIT - YY_USER_INIT; -#endif - - if ( ! (yy_start) ) - (yy_start) = 1; /* first start state */ - - if ( ! yyin ) - yyin = stdin; - - if ( ! yyout ) - yyout = stdout; - - if ( ! YY_CURRENT_BUFFER ) { - yyensure_buffer_stack (); - YY_CURRENT_BUFFER_LVALUE = - yy_create_buffer(yyin,YY_BUF_SIZE ); - } - - yy_load_buffer_state( ); - } - - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = (yy_c_buf_p); - - /* Support of yytext. */ - *yy_cp = (yy_hold_char); - - /* yy_bp points to the position in yy_ch_buf of the start of - * the current run. - */ - yy_bp = yy_cp; - - yy_current_state = (yy_start); -yy_match: - do - { - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; - (yy_last_accepting_cpos) = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 26 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - ++yy_cp; - } - while ( yy_base[yy_current_state] != 25 ); - -yy_find_action: - yy_act = yy_accept[yy_current_state]; - if ( yy_act == 0 ) - { /* have to back up */ - yy_cp = (yy_last_accepting_cpos); - yy_current_state = (yy_last_accepting_state); - yy_act = yy_accept[yy_current_state]; - } - - YY_DO_BEFORE_ACTION; - -do_action: /* This label is used only to access EOF actions. */ - - switch ( yy_act ) - { /* beginning of action switch */ - case 0: /* must back up */ - /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = (yy_hold_char); - yy_cp = (yy_last_accepting_cpos); - yy_current_state = (yy_last_accepting_state); - goto yy_find_action; - -case 1: -YY_RULE_SETUP -#line 10 "lexer.l" -yylval.int_literal = (uint64_t) atoll(yytext); return T_NUMBER; - YY_BREAK -case 2: -/* rule 2 can match eol */ -YY_RULE_SETUP -#line 11 "lexer.l" -/* Ignore end of line */ - YY_BREAK -case 3: -YY_RULE_SETUP -#line 12 "lexer.l" -/* Ignore whitespace */ - YY_BREAK -case 4: -YY_RULE_SETUP -#line 13 "lexer.l" -return T_NOT_EQ; - YY_BREAK -case 5: -YY_RULE_SETUP -#line 14 "lexer.l" -return T_GT_EQ; - YY_BREAK -case 6: -YY_RULE_SETUP -#line 15 "lexer.l" -return T_LT_EQ; - YY_BREAK -case 7: -YY_RULE_SETUP -#line 16 "lexer.l" -return T_AND; - YY_BREAK -case 8: -YY_RULE_SETUP -#line 17 "lexer.l" -return T_OR; - YY_BREAK -case 9: -YY_RULE_SETUP -#line 18 "lexer.l" -return '='; - YY_BREAK -case 10: -YY_RULE_SETUP -#line 19 "lexer.l" -return '>'; - YY_BREAK -case 11: -YY_RULE_SETUP -#line 20 "lexer.l" -return '<'; - YY_BREAK -case 12: -YY_RULE_SETUP -#line 21 "lexer.l" -return '('; - YY_BREAK -case 13: -YY_RULE_SETUP -#line 22 "lexer.l" -return ')'; - YY_BREAK -case 14: -YY_RULE_SETUP -#line 23 "lexer.l" -yylval.string_literal = strdup(yytext); return T_FIELD; - YY_BREAK -case 15: -YY_RULE_SETUP -#line 25 "lexer.l" -ECHO; - YY_BREAK -#line 823 "/home/david/mac/SourceCode/zmap/src/lexer.c" -case YY_STATE_EOF(INITIAL): - yyterminate(); - - case YY_END_OF_BUFFER: - { - /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; - - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = (yy_hold_char); - YY_RESTORE_YY_MORE_OFFSET - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) - { - /* We're scanning a new file or input source. It's - * possible that this happened because the user - * just pointed yyin at a new source and called - * yylex(). If so, then we have to assure - * consistency between YY_CURRENT_BUFFER and our - * globals. Here is the right place to do so, because - * this is the first action (other than possibly a - * back-up) that will match for the new input source. - */ - (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; - } - - /* Note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the - * end-of-buffer state). Contrast this with the test - * in input(). - */ - if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) - { /* This was really a NUL. */ - yy_state_type yy_next_state; - - (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( ); - - /* Okay, we're now positioned to make the NUL - * transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we don't - * want to build jamming into it because then it - * will run more slowly). - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state ); - - yy_bp = (yytext_ptr) + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* Consume the NUL. */ - yy_cp = ++(yy_c_buf_p); - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { - yy_cp = (yy_c_buf_p); - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer( ) ) - { - case EOB_ACT_END_OF_FILE: - { - (yy_did_buffer_switch_on_eof) = 0; - - if ( yywrap( ) ) - { - /* Note: because we've taken care in - * yy_get_next_buffer() to have set up - * yytext, we can now set up - * yy_c_buf_p so that if some total - * hoser (like flex itself) wants to - * call the scanner after we return the - * YY_NULL, it'll still work - another - * YY_NULL will get returned. - */ - (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF(YY_START); - goto do_action; - } - - else - { - if ( ! (yy_did_buffer_switch_on_eof) ) - YY_NEW_FILE; - } - break; - } - - case EOB_ACT_CONTINUE_SCAN: - (yy_c_buf_p) = - (yytext_ptr) + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( ); - - yy_cp = (yy_c_buf_p); - yy_bp = (yytext_ptr) + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - (yy_c_buf_p) = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; - - yy_current_state = yy_get_previous_state( ); - - yy_cp = (yy_c_buf_p); - yy_bp = (yytext_ptr) + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ -} /* end of yylex */ - -/* yy_get_next_buffer - try to read in a new buffer - * - * Returns a code representing an action: - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file - */ -static int yy_get_next_buffer (void) -{ - register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; - register char *source = (yytext_ptr); - register int number_to_move, i; - int ret_val; - - if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ - if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) - { - /* We matched a single character, the EOB, so - * treat this as a final EOF. - */ - return EOB_ACT_END_OF_FILE; - } - - else - { - /* We matched some text prior to the EOB, first - * process it. - */ - return EOB_ACT_LAST_MATCH; - } - } - - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ - number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; - - else - { - int num_to_read = - YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ - - /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = YY_CURRENT_BUFFER; - - int yy_c_buf_p_offset = - (int) ((yy_c_buf_p) - b->yy_ch_buf); - - if ( b->yy_is_our_buffer ) - { - int new_size = b->yy_buf_size * 2; - - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; - else - b->yy_buf_size *= 2; - - b->yy_ch_buf = (char *) - /* Include room in for 2 EOB chars. */ - yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); - } - else - /* Can't grow it, we don't own it. */ - b->yy_ch_buf = 0; - - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( - "fatal error - scanner input buffer overflow" ); - - (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; - - num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - - number_to_move - 1; - - } - - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; - - /* Read in more data. */ - YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - (yy_n_chars), (size_t) num_to_read ); - - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } - - if ( (yy_n_chars) == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; - yyrestart(yyin ); - } - - else - { - ret_val = EOB_ACT_LAST_MATCH; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } - } - - else - ret_val = EOB_ACT_CONTINUE_SCAN; - - if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { - /* Extend the array by 50%, plus the number we really need. */ - yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); - if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); - } - - (yy_n_chars) += number_to_move; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; - - (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; - - return ret_val; -} - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - - static yy_state_type yy_get_previous_state (void) -{ - register yy_state_type yy_current_state; - register char *yy_cp; - - yy_current_state = (yy_start); - - for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) - { - register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; - (yy_last_accepting_cpos) = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 26 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - } - - return yy_current_state; -} - -/* yy_try_NUL_trans - try to make a transition on the NUL character - * - * synopsis - * next_state = yy_try_NUL_trans( current_state ); - */ - static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) -{ - register int yy_is_jam; - register char *yy_cp = (yy_c_buf_p); - - register YY_CHAR yy_c = 1; - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; - (yy_last_accepting_cpos) = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 26 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 25); - - return yy_is_jam ? 0 : yy_current_state; -} - -#ifndef YY_NO_INPUT -#ifdef __cplusplus - static int yyinput (void) -#else - static int input (void) -#endif - -{ - int c; - - *(yy_c_buf_p) = (yy_hold_char); - - if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ - if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) - /* This was really a NUL. */ - *(yy_c_buf_p) = '\0'; - - else - { /* need more input */ - int offset = (yy_c_buf_p) - (yytext_ptr); - ++(yy_c_buf_p); - - switch ( yy_get_next_buffer( ) ) - { - case EOB_ACT_LAST_MATCH: - /* This happens because yy_g_n_b() - * sees that we've accumulated a - * token and flags that we need to - * try matching the token before - * proceeding. But for input(), - * there's no matching to consider. - * So convert the EOB_ACT_LAST_MATCH - * to EOB_ACT_END_OF_FILE. - */ - - /* Reset buffer status. */ - yyrestart(yyin ); - - /*FALLTHROUGH*/ - - case EOB_ACT_END_OF_FILE: - { - if ( yywrap( ) ) - return EOF; - - if ( ! (yy_did_buffer_switch_on_eof) ) - YY_NEW_FILE; -#ifdef __cplusplus - return yyinput(); -#else - return input(); -#endif - } - - case EOB_ACT_CONTINUE_SCAN: - (yy_c_buf_p) = (yytext_ptr) + offset; - break; - } - } - } - - c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ - *(yy_c_buf_p) = '\0'; /* preserve yytext */ - (yy_hold_char) = *++(yy_c_buf_p); - - return c; -} -#endif /* ifndef YY_NO_INPUT */ - -/** Immediately switch to a different input stream. - * @param input_file A readable stream. - * - * @note This function does not reset the start condition to @c INITIAL . - */ - void yyrestart (FILE * input_file ) -{ - - if ( ! YY_CURRENT_BUFFER ){ - yyensure_buffer_stack (); - YY_CURRENT_BUFFER_LVALUE = - yy_create_buffer(yyin,YY_BUF_SIZE ); - } - - yy_init_buffer(YY_CURRENT_BUFFER,input_file ); - yy_load_buffer_state( ); -} - -/** Switch to a different input buffer. - * @param new_buffer The new input buffer. - * - */ - void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) -{ - - /* TODO. We should be able to replace this entire function body - * with - * yypop_buffer_state(); - * yypush_buffer_state(new_buffer); - */ - yyensure_buffer_stack (); - if ( YY_CURRENT_BUFFER == new_buffer ) - return; - - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *(yy_c_buf_p) = (yy_hold_char); - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } - - YY_CURRENT_BUFFER_LVALUE = new_buffer; - yy_load_buffer_state( ); - - /* We don't actually know whether we did this switch during - * EOF (yywrap()) processing, but the only time this flag - * is looked at is after yywrap() is called, so it's safe - * to go ahead and always set it. - */ - (yy_did_buffer_switch_on_eof) = 1; -} - -static void yy_load_buffer_state (void) -{ - (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; - yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; - (yy_hold_char) = *(yy_c_buf_p); -} - -/** Allocate and initialize an input buffer state. - * @param file A readable stream. - * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. - * - * @return the allocated buffer state. - */ - YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) -{ - YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_buf_size = size; - - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_is_our_buffer = 1; - - yy_init_buffer(b,file ); - - return b; -} - -/** Destroy the buffer. - * @param b a buffer created with yy_create_buffer() - * - */ - void yy_delete_buffer (YY_BUFFER_STATE b ) -{ - - if ( ! b ) - return; - - if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ - YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; - - if ( b->yy_is_our_buffer ) - yyfree((void *) b->yy_ch_buf ); - - yyfree((void *) b ); -} - -#ifndef __cplusplus -extern int isatty (int ); -#endif /* __cplusplus */ - -/* Initializes or reinitializes a buffer. - * This function is sometimes called more than once on the same buffer, - * such as during a yyrestart() or at EOF. - */ - static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) - -{ - int oerrno = errno; - - yy_flush_buffer(b ); - - b->yy_input_file = file; - b->yy_fill_buffer = 1; - - /* If b is the current buffer, then yy_init_buffer was _probably_ - * called from yyrestart() or through yy_get_next_buffer. - * In that case, we don't want to reset the lineno or column. - */ - if (b != YY_CURRENT_BUFFER){ - b->yy_bs_lineno = 1; - b->yy_bs_column = 0; - } - - b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; - - errno = oerrno; -} - -/** Discard all buffered characters. On the next scan, YY_INPUT will be called. - * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. - * - */ - void yy_flush_buffer (YY_BUFFER_STATE b ) -{ - if ( ! b ) - return; - - b->yy_n_chars = 0; - - /* We always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - - b->yy_buf_pos = &b->yy_ch_buf[0]; - - b->yy_at_bol = 1; - b->yy_buffer_status = YY_BUFFER_NEW; - - if ( b == YY_CURRENT_BUFFER ) - yy_load_buffer_state( ); -} - -/** Pushes the new state onto the stack. The new state becomes - * the current state. This function will allocate the stack - * if necessary. - * @param new_buffer The new state. - * - */ -void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) -{ - if (new_buffer == NULL) - return; - - yyensure_buffer_stack(); - - /* This block is copied from yy_switch_to_buffer. */ - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *(yy_c_buf_p) = (yy_hold_char); - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } - - /* Only push if top exists. Otherwise, replace top. */ - if (YY_CURRENT_BUFFER) - (yy_buffer_stack_top)++; - YY_CURRENT_BUFFER_LVALUE = new_buffer; - - /* copied from yy_switch_to_buffer. */ - yy_load_buffer_state( ); - (yy_did_buffer_switch_on_eof) = 1; -} - -/** Removes and deletes the top of the stack, if present. - * The next element becomes the new top. - * - */ -void yypop_buffer_state (void) -{ - if (!YY_CURRENT_BUFFER) - return; - - yy_delete_buffer(YY_CURRENT_BUFFER ); - YY_CURRENT_BUFFER_LVALUE = NULL; - if ((yy_buffer_stack_top) > 0) - --(yy_buffer_stack_top); - - if (YY_CURRENT_BUFFER) { - yy_load_buffer_state( ); - (yy_did_buffer_switch_on_eof) = 1; - } -} - -/* Allocates the stack if it does not exist. - * Guarantees space for at least one push. - */ -static void yyensure_buffer_stack (void) -{ - int num_to_alloc; - - if (!(yy_buffer_stack)) { - - /* First allocation is just for 2 elements, since we don't know if this - * scanner will even need a stack. We use 2 instead of 1 to avoid an - * immediate realloc on the next call. - */ - num_to_alloc = 1; - (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc - (num_to_alloc * sizeof(struct yy_buffer_state*) - ); - if ( ! (yy_buffer_stack) ) - YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); - - memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); - - (yy_buffer_stack_max) = num_to_alloc; - (yy_buffer_stack_top) = 0; - return; - } - - if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ - - /* Increase the buffer to prepare for a possible push. */ - int grow_size = 8 /* arbitrary grow size */; - - num_to_alloc = (yy_buffer_stack_max) + grow_size; - (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc - ((yy_buffer_stack), - num_to_alloc * sizeof(struct yy_buffer_state*) - ); - if ( ! (yy_buffer_stack) ) - YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); - - /* zero only the new slots.*/ - memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); - (yy_buffer_stack_max) = num_to_alloc; - } -} - -/** Setup the input buffer state to scan directly from a user-specified character buffer. - * @param base the character buffer - * @param size the size in bytes of the character buffer - * - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) -{ - YY_BUFFER_STATE b; - - if ( size < 2 || - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) - /* They forgot to leave room for the EOB's. */ - return 0; - - b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); - - b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ - b->yy_buf_pos = b->yy_ch_buf = base; - b->yy_is_our_buffer = 0; - b->yy_input_file = 0; - b->yy_n_chars = b->yy_buf_size; - b->yy_is_interactive = 0; - b->yy_at_bol = 1; - b->yy_fill_buffer = 0; - b->yy_buffer_status = YY_BUFFER_NEW; - - yy_switch_to_buffer(b ); - - return b; -} - -/** Setup the input buffer state to scan a string. The next call to yylex() will - * scan from a @e copy of @a str. - * @param yystr a NUL-terminated string to scan - * - * @return the newly allocated buffer state object. - * @note If you want to scan bytes that may contain NUL values, then use - * yy_scan_bytes() instead. - */ -YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) -{ - - return yy_scan_bytes(yystr,strlen(yystr) ); -} - -/** Setup the input buffer state to scan the given bytes. The next call to yylex() will - * scan from a @e copy of @a bytes. - * @param yybytes the byte buffer to scan - * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. - * - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len ) -{ - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; - int i; - - /* Get memory for full buffer, including space for trailing EOB's. */ - n = _yybytes_len + 2; - buf = (char *) yyalloc(n ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); - - for ( i = 0; i < _yybytes_len; ++i ) - buf[i] = yybytes[i]; - - buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; - - b = yy_scan_buffer(buf,n ); - if ( ! b ) - YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); - - /* It's okay to grow etc. this buffer, and we should throw it - * away when we're done. - */ - b->yy_is_our_buffer = 1; - - return b; -} - -#ifndef YY_EXIT_FAILURE -#define YY_EXIT_FAILURE 2 -#endif - -static void yy_fatal_error (yyconst char* msg ) -{ - (void) fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); -} - -/* Redefine yyless() so it works in section 3 code. */ - -#undef yyless -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - yytext[yyleng] = (yy_hold_char); \ - (yy_c_buf_p) = yytext + yyless_macro_arg; \ - (yy_hold_char) = *(yy_c_buf_p); \ - *(yy_c_buf_p) = '\0'; \ - yyleng = yyless_macro_arg; \ - } \ - while ( 0 ) - -/* Accessor methods (get/set functions) to struct members. */ - -/** Get the current line number. - * - */ -int yyget_lineno (void) -{ - - return yylineno; -} - -/** Get the input stream. - * - */ -FILE *yyget_in (void) -{ - return yyin; -} - -/** Get the output stream. - * - */ -FILE *yyget_out (void) -{ - return yyout; -} - -/** Get the length of the current token. - * - */ -int yyget_leng (void) -{ - return yyleng; -} - -/** Get the current token. - * - */ - -char *yyget_text (void) -{ - return yytext; -} - -/** Set the current line number. - * @param line_number - * - */ -void yyset_lineno (int line_number ) -{ - - yylineno = line_number; -} - -/** Set the input stream. This does not discard the current - * input buffer. - * @param in_str A readable stream. - * - * @see yy_switch_to_buffer - */ -void yyset_in (FILE * in_str ) -{ - yyin = in_str ; -} - -void yyset_out (FILE * out_str ) -{ - yyout = out_str ; -} - -int yyget_debug (void) -{ - return yy_flex_debug; -} - -void yyset_debug (int bdebug ) -{ - yy_flex_debug = bdebug ; -} - -static int yy_init_globals (void) -{ - /* Initialization is the same as for the non-reentrant scanner. - * This function is called from yylex_destroy(), so don't allocate here. - */ - - (yy_buffer_stack) = 0; - (yy_buffer_stack_top) = 0; - (yy_buffer_stack_max) = 0; - (yy_c_buf_p) = (char *) 0; - (yy_init) = 0; - (yy_start) = 0; - -/* Defined in main.c */ -#ifdef YY_STDINIT - yyin = stdin; - yyout = stdout; -#else - yyin = (FILE *) 0; - yyout = (FILE *) 0; -#endif - - /* For future reference: Set errno on error, since we are called by - * yylex_init() - */ - return 0; -} - -/* yylex_destroy is for both reentrant and non-reentrant scanners. */ -int yylex_destroy (void) -{ - - /* Pop the buffer stack, destroying each element. */ - while(YY_CURRENT_BUFFER){ - yy_delete_buffer(YY_CURRENT_BUFFER ); - YY_CURRENT_BUFFER_LVALUE = NULL; - yypop_buffer_state(); - } - - /* Destroy the stack itself. */ - yyfree((yy_buffer_stack) ); - (yy_buffer_stack) = NULL; - - /* Reset the globals. This is important in a non-reentrant scanner so the next time - * yylex() is called, initialization will occur. */ - yy_init_globals( ); - - return 0; -} - -/* - * Internal utility routines. - */ - -#ifndef yytext_ptr -static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) -{ - register int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; -} -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * s ) -{ - register int n; - for ( n = 0; s[n]; ++n ) - ; - - return n; -} -#endif - -void *yyalloc (yy_size_t size ) -{ - return (void *) malloc( size ); -} - -void *yyrealloc (void * ptr, yy_size_t size ) -{ - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter - * because both ANSI C and C++ allow castless assignment from - * any pointer type to void*, and deal with argument conversions - * as though doing an assignment. - */ - return (void *) realloc( (char *) ptr, size ); -} - -void yyfree (void * ptr ) -{ - free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ -} - -#define YYTABLES_NAME "yytables" - -#line 25 "lexer.l" - - diff --git a/src/lexer.h b/src/lexer.h deleted file mode 100644 index fe793da..0000000 --- a/src/lexer.h +++ /dev/null @@ -1,332 +0,0 @@ -#ifndef yyHEADER_H -#define yyHEADER_H 1 -#define yyIN_HEADER 1 - -#line 6 "/home/david/mac/SourceCode/zmap/src/lexer.h" - -#line 8 "/home/david/mac/SourceCode/zmap/src/lexer.h" - -#define YY_INT_ALIGNED short int - -/* A lexical scanner generated by flex */ - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 35 -#if YY_FLEX_SUBMINOR_VERSION > 0 -#define FLEX_BETA -#endif - -/* First, we deal with platform-specific or compiler-specific issues. */ - -/* begin standard C headers. */ -#include -#include -#include -#include - -/* end standard C headers. */ - -/* flex integer type definitions */ - -#ifndef FLEXINT_H -#define FLEXINT_H - -/* C99 systems have . Non-C99 systems may or may not. */ - -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - -/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, - * if you want the limit (max/min) macros for int types. - */ -#ifndef __STDC_LIMIT_MACROS -#define __STDC_LIMIT_MACROS 1 -#endif - -#include -typedef int8_t flex_int8_t; -typedef uint8_t flex_uint8_t; -typedef int16_t flex_int16_t; -typedef uint16_t flex_uint16_t; -typedef int32_t flex_int32_t; -typedef uint32_t flex_uint32_t; -#else -typedef signed char flex_int8_t; -typedef short int flex_int16_t; -typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; -typedef unsigned short int flex_uint16_t; -typedef unsigned int flex_uint32_t; - -/* Limits of integral types. */ -#ifndef INT8_MIN -#define INT8_MIN (-128) -#endif -#ifndef INT16_MIN -#define INT16_MIN (-32767-1) -#endif -#ifndef INT32_MIN -#define INT32_MIN (-2147483647-1) -#endif -#ifndef INT8_MAX -#define INT8_MAX (127) -#endif -#ifndef INT16_MAX -#define INT16_MAX (32767) -#endif -#ifndef INT32_MAX -#define INT32_MAX (2147483647) -#endif -#ifndef UINT8_MAX -#define UINT8_MAX (255U) -#endif -#ifndef UINT16_MAX -#define UINT16_MAX (65535U) -#endif -#ifndef UINT32_MAX -#define UINT32_MAX (4294967295U) -#endif - -#endif /* ! C99 */ - -#endif /* ! FLEXINT_H */ - -#ifdef __cplusplus - -/* The "const" storage-class-modifier is valid. */ -#define YY_USE_CONST - -#else /* ! __cplusplus */ - -/* C99 requires __STDC__ to be defined as 1. */ -#if defined (__STDC__) - -#define YY_USE_CONST - -#endif /* defined (__STDC__) */ -#endif /* ! __cplusplus */ - -#ifdef YY_USE_CONST -#define yyconst const -#else -#define yyconst -#endif - -/* Size of default input buffer. */ -#ifndef YY_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k. - * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. - * Ditto for the __ia64__ case accordingly. - */ -#define YY_BUF_SIZE 32768 -#else -#define YY_BUF_SIZE 16384 -#endif /* __ia64__ */ -#endif - -#ifndef YY_TYPEDEF_YY_BUFFER_STATE -#define YY_TYPEDEF_YY_BUFFER_STATE -typedef struct yy_buffer_state *YY_BUFFER_STATE; -#endif - -extern int yyleng; - -extern FILE *yyin, *yyout; - -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif - -#ifndef YY_STRUCT_YY_BUFFER_STATE -#define YY_STRUCT_YY_BUFFER_STATE -struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - yy_size_t yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - int yy_bs_lineno; /**< The line count. */ - int yy_bs_column; /**< The column count. */ - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; - - }; -#endif /* !YY_STRUCT_YY_BUFFER_STATE */ - -void yyrestart (FILE *input_file ); -void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); -YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); -void yy_delete_buffer (YY_BUFFER_STATE b ); -void yy_flush_buffer (YY_BUFFER_STATE b ); -void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); -void yypop_buffer_state (void ); - -YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); -YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); -YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ); - -void *yyalloc (yy_size_t ); -void *yyrealloc (void *,yy_size_t ); -void yyfree (void * ); - -/* Begin user sect3 */ - -extern int yylineno; - -extern char *yytext; -#define yytext_ptr yytext - -#ifdef YY_HEADER_EXPORT_START_CONDITIONS -#define INITIAL 0 - -#endif - -#ifndef YY_NO_UNISTD_H -/* Special case for "unistd.h", since it is non-ANSI. We include it way - * down here because we want the user's section 1 to have been scanned first. - * The user has a chance to override it with an option. - */ -#include -#endif - -#ifndef YY_EXTRA_TYPE -#define YY_EXTRA_TYPE void * -#endif - -/* Accessor methods to globals. - These are made visible to non-reentrant scanners for convenience. */ - -int yylex_destroy (void ); - -int yyget_debug (void ); - -void yyset_debug (int debug_flag ); - -YY_EXTRA_TYPE yyget_extra (void ); - -void yyset_extra (YY_EXTRA_TYPE user_defined ); - -FILE *yyget_in (void ); - -void yyset_in (FILE * in_str ); - -FILE *yyget_out (void ); - -void yyset_out (FILE * out_str ); - -int yyget_leng (void ); - -char *yyget_text (void ); - -int yyget_lineno (void ); - -void yyset_lineno (int line_number ); - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int yywrap (void ); -#else -extern int yywrap (void ); -#endif -#endif - -#ifndef yytext_ptr -static void yy_flex_strncpy (char *,yyconst char *,int ); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * ); -#endif - -#ifndef YY_NO_INPUT - -#endif - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k */ -#define YY_READ_BUF_SIZE 16384 -#else -#define YY_READ_BUF_SIZE 8192 -#endif /* __ia64__ */ -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL_IS_OURS 1 - -extern int yylex (void); - -#define YY_DECL int yylex (void) -#endif /* !YY_DECL */ - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - -#undef YY_NEW_FILE -#undef YY_FLUSH_BUFFER -#undef yy_set_bol -#undef yy_new_buffer -#undef yy_set_interactive -#undef YY_DO_BEFORE_ACTION - -#ifdef YY_DECL_IS_OURS -#undef YY_DECL_IS_OURS -#undef YY_DECL -#endif - -#line 25 "lexer.l" - - -#line 331 "/home/david/mac/SourceCode/zmap/src/lexer.h" -#undef yyIN_HEADER -#endif /* yyHEADER_H */ diff --git a/src/lexer.l b/src/lexer.l index f1ee546..cd884fa 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -1,4 +1,5 @@ %{ +#pragma GCC diagnostic ignored "-Wredundant-decls" #include #include "parser.h" From 13ca18479ae01381739b1fbfffde25d6006df904 Mon Sep 17 00:00:00 2001 From: Zakir Durumeric Date: Wed, 9 Oct 2013 15:11:23 -0400 Subject: [PATCH 27/53] compiling redis support --- lib/redis.c | 88 ++++++++++++++++++++++++++++--- lib/redis.h | 2 +- src/cyclic.c | 3 +- src/output_modules/module_redis.c | 48 +++++++---------- src/zmap.c | 8 +++ 5 files changed, 110 insertions(+), 39 deletions(-) diff --git a/lib/redis.c b/lib/redis.c index 20bf4e7..aeacf08 100644 --- a/lib/redis.c +++ b/lib/redis.c @@ -6,16 +6,18 @@ * of the License at http://www.apache.org/licenses/LICENSE-2.0 */ -#include #include "redis.h" + +#include #include #include -#include "assert.h" -#include "logger.h" #include +#include + #include -#define REDIS_UNIX_PATH "/tmp/redis.sock" +#include "logger.h" + #define REDIS_TIMEOUT 2 #undef MIN @@ -23,13 +25,83 @@ static redisContext *rctx; -static redisContext* redis_connect(void) +#define T_TCP 0 +#define T_LOCAL 1 + +typedef struct redisconf { + int type; + char *path; + char *server; + uint16_t port; + char *list_name; +} redisconf_t; + +static redisconf_t *redis_parse_connstr(char *connstr) { + redisconf_t *retv = malloc(sizeof(redisconf_t)); + if (strcmp("tcp://", connstr) == 6) { + char *servername = malloc(strlen(connstr)); + assert(servername); + char *list_name = malloc(strlen(connstr)); + assert(list_name); + uint16_t port; + if (scanf(connstr, "tcp://%s:%u/%s", servername, + port, list_name) != 3) { + log_fatal("redis", "unable to parse redis connection string. This " + "should be of the form tcp://server:port/list-name " + "for TCP connections. All fields are required."); + } + retv->type = T_TCP; + retv->server = servername; + retv->port = port; + retv->list_name = list_name; + retv->path = NULL; + } else if (strcmp("local://", connstr) == 8) { + char *path = malloc(strlen(connstr)); + assert(path); + char *list_name = malloc(strlen(connstr)); + assert(list_name); + if (scanf(connstr, "local://%s/%s", path, + list_name) != 3) { + log_fatal("redis", "unable to parse redis connection string. This " + "should be of the form tcp://server:port/list-name " + "for TCP connections. All fields are required."); + } + retv->type = T_LOCAL; + retv->list_name = list_name; + retv->path = path; + retv->server = NULL; + retv->port = 0; + } else { + log_fatal("redis", "unable to parse connection string. does not begin with " + "unix:// or tcp:// as expected"); + } +} + +static redisContext* redis_connect(char *connstr) +{ + redisconf_t *c; + // handle old behavior where we only connected to a specific + // socket that we #defined. + if (!connstr) { + c = malloc(sizeof(redisconf_t)); + assert(c); + c->type = T_LOCAL; + c->path = "/tmp/redis.sock"; + } else { + c = redis_parse_connstr(connstr); + assert(c); + } struct timeval timeout; timeout.tv_sec = REDIS_TIMEOUT; timeout.tv_usec = 0; - return (redisContext*) redisConnectUnixWithTimeout(REDIS_UNIX_PATH, + if (c->type == T_LOCAL) { + return (redisContext*) redisConnectUnixWithTimeout(c->path, timeout); + } else { + return (redisContext*) redisConnectWithTimeout(c->server, + c->port, timeout); + } } static int chkerr(redisReply *reply) @@ -47,9 +119,9 @@ static int chkerr(redisReply *reply) return 0; } -int redis_init(void) +int redis_init(char *connstr) { - rctx = redis_connect(); + rctx = redis_connect(connstr); if (!rctx) { return -1; } diff --git a/lib/redis.h b/lib/redis.h index 229136c..e382375 100644 --- a/lib/redis.h +++ b/lib/redis.h @@ -5,7 +5,7 @@ #ifndef REDIS_ZHELPERS_H #define REDIS_ZHELPERS_H -int redis_init(void); +int redis_init(char*); int redis_close(void); diff --git a/src/cyclic.c b/src/cyclic.c index 9f53690..814a49c 100644 --- a/src/cyclic.c +++ b/src/cyclic.c @@ -169,7 +169,8 @@ int cyclic_init(uint32_t primroot_, uint32_t current_) for (uint32_t i=0; i num_addrs) { cur_group = &groups[i]; - log_debug("cyclic", "using prime %lu, known_primroot %lu", cur_group->prime, cur_group->known_primroot); + log_debug("cyclic", "using prime %lu, known_primroot %lu", + cur_group->prime, cur_group->known_primroot); prime = groups[i].prime; break; } diff --git a/src/output_modules/module_redis.c b/src/output_modules/module_redis.c index a6dc8f8..703ad55 100644 --- a/src/output_modules/module_redis.c +++ b/src/output_modules/module_redis.c @@ -22,55 +22,46 @@ #define UNUSED __attribute__((unused)) -typedef struct scannable_t { - in_addr_t ip_address; - uint8_t source; -} scannable_t; - -#define QUEUE_NAME "zmap_results" #define BUFFER_SIZE 500 #define SOURCE_ZMAP 0 -static scannable_t* buffer; +static uint32_t *buffer; static int buffer_fill = 0; +static char *queue_name = NULL; -int redismodule_init(UNUSED struct state_conf *conf) +static int redismodule_init(struct state_conf *conf, char **fields, int fieldlens) { - buffer = calloc(BUFFER_SIZE, sizeof(scannable_t)); + assert(fieldlens == 1); + buffer = calloc(BUFFER_SIZE, sizeof(uint32_t)); assert(buffer); buffer_fill = 0; - return redis_init(); + return redis_init(conf->output_args); } -int redismodule_flush(void) +static int redismodule_flush(void) { - if (redis_lpush((char *)QUEUE_NAME, buffer, - buffer_fill, sizeof(scannable_t))) { + if (redis_lpush((char *)queue_name, buffer, + buffer_fill, sizeof(uint32_t))) { return EXIT_FAILURE; } buffer_fill = 0; return EXIT_SUCCESS; } -int redismodule_newip(ipaddr_n_t saddr, UNUSED ipaddr_n_t daddr, - UNUSED const char *response_type, int is_repeat, - UNUSED int in_cooldown, UNUSED const u_char *packet, UNUSED size_t len) +static int redismodule_process(fieldset_t *fs) { - if (!is_repeat) { - buffer[buffer_fill].ip_address = saddr; - buffer[buffer_fill].source = SOURCE_ZMAP; - - if (++buffer_fill == BUFFER_SIZE) { - if (redismodule_flush()) { - return EXIT_FAILURE; - } + field_t *f = &(fs->fields[0]); + buffer[buffer_fill] = (uint32_t) f->value.num; + if (++buffer_fill == BUFFER_SIZE) { + if (redismodule_flush()) { + return EXIT_FAILURE; } } return EXIT_SUCCESS; } -int redismodule_close(UNUSED struct state_conf* c, - UNUSED struct state_send* s, +static int redismodule_close(UNUSED struct state_conf* c, + UNUSED struct state_send* s, UNUSED struct state_recv* r) { if (redismodule_flush()) { @@ -83,13 +74,12 @@ int redismodule_close(UNUSED struct state_conf* c, } output_module_t module_redis = { - .name = "redis", + .name = "redis-packed", .init = &redismodule_init, .start = NULL, .update = NULL, .update_interval = 0, .close = &redismodule_close, - .success_ip = &redismodule_newip, - .other_ip = NULL + .process_ip = &redismodule_process }; diff --git a/src/zmap.c b/src/zmap.c index 1356489..dee0b9e 100644 --- a/src/zmap.c +++ b/src/zmap.c @@ -429,6 +429,14 @@ int main(int argc, char *argv[]) "seqnum, acknum, cooldown, " "repeat, timestamp-str"; zconf.filter_duplicates = 0; + } else if (!strcmp(args.output_module_arg, "redis")) { + log_warn("zmap", "the redis output interface has been deprecated and " + "will be removed in the future. Users should " + "either use redis-packed or redis-json in the " + "future."); + zconf.output_module = get_output_module_by_name("redis-packed"); + zconf.raw_output_fields = (char*) "saddr"; + zconf.filter_duplicates = 1; } else { zconf.output_module = get_output_module_by_name(args.output_module_arg); if (!zconf.output_module) { From 0410a99d18d96e37512549244d52f4c7e7f02717 Mon Sep 17 00:00:00 2001 From: Zakir Durumeric Date: Wed, 9 Oct 2013 17:05:44 -0400 Subject: [PATCH 28/53] adding support for help text to output modules --- src/output_modules/output_modules.c | 5 +- src/output_modules/output_modules.h | 2 +- src/zmap.c | 78 +++++++++++++++++------------ 3 files changed, 47 insertions(+), 38 deletions(-) diff --git a/src/output_modules/output_modules.c b/src/output_modules/output_modules.c index c0c5aed..60fd9f7 100644 --- a/src/output_modules/output_modules.c +++ b/src/output_modules/output_modules.c @@ -6,7 +6,6 @@ * of the License at http://www.apache.org/licenses/LICENSE-2.0 */ - #include #include @@ -25,7 +24,7 @@ extern output_module_t module_json_file; output_module_t* output_modules[] = { &module_csv_file, #ifdef REDIS - //&module_redis, + &module_redis, #endif #ifdef JSON &module_json_file @@ -33,8 +32,6 @@ output_module_t* output_modules[] = { // ADD YOUR MODULE HERE }; - - output_module_t* get_output_module_by_name(const char* name) { int num_modules = (int) (sizeof(output_modules)/sizeof(output_modules[0])); diff --git a/src/output_modules/output_modules.h b/src/output_modules/output_modules.h index 8da6399..8b236a4 100644 --- a/src/output_modules/output_modules.h +++ b/src/output_modules/output_modules.h @@ -30,9 +30,9 @@ typedef struct output_module { output_update_cb update; output_update_cb close; output_packet_cb process_ip; + const char *helptext; } output_module_t; - output_module_t* get_output_module_by_name(const char*); void print_output_modules(void); diff --git a/src/zmap.c b/src/zmap.c index dee0b9e..69b6241 100644 --- a/src/zmap.c +++ b/src/zmap.c @@ -369,39 +369,6 @@ int main(int argc, char *argv[]) zconf.log_level = args.verbosity_arg; log_init(stderr, zconf.log_level); log_trace("zmap", "zmap main thread started"); - - if (args.help_given) { - cmdline_parser_print_help(); - exit(EXIT_SUCCESS); - } - if (args.version_given) { - cmdline_parser_print_version(); - exit(EXIT_SUCCESS); - } - if (args.list_output_modules_given) { - print_output_modules(); - exit(EXIT_SUCCESS); - } - if (args.list_probe_modules_given) { - print_probe_modules(); - exit(EXIT_SUCCESS); - } - if (args.config_given || file_exists(args.config_arg)) { - params->initialize = 0; - params->override = 0; - if (cmdline_parser_config_file(args.config_arg, &args, params) - != 0) { - exit(EXIT_FAILURE); - } - } - if (args.vpn_given) { - zconf.send_ip_pkts = 1; - zconf.gw_mac_set = 1; - memset(zconf.gw_mac, 0, IFHWADDRLEN); - } - if (cmdline_parser_required(&args, CMDLINE_PARSER_PACKAGE) != 0) { - exit(EXIT_FAILURE); - } // parse the provided probe and output module s.t. that we can support // other command-line helpers (e.g. probe help) if (!args.output_module_given) { @@ -451,6 +418,51 @@ int main(int argc, char *argv[]) CMDLINE_PARSER_PACKAGE, args.probe_module_arg); exit(EXIT_FAILURE); } + if (args.help_given) { + cmdline_parser_print_help(); + printf("\nselected probe-module (%s) help\n", zconf.probe_module->name); + if (zconf.probe_module->helptext) { + printf("%s\n", zconf.probe_module->helptext); + } else { + printf("no help text available\n"); + } + printf("\nselected output-module help\n"); + if (zconf.output_module->helptext) { + printf("%s\n", zconf.output_module->helptext); + } else { + printf("no help text available\n"); + } + exit(EXIT_SUCCESS); + } + if (args.version_given) { + cmdline_parser_print_version(); + exit(EXIT_SUCCESS); + } + if (args.list_output_modules_given) { + print_output_modules(); + exit(EXIT_SUCCESS); + } + if (args.list_probe_modules_given) { + print_probe_modules(); + exit(EXIT_SUCCESS); + } + if (args.config_given || file_exists(args.config_arg)) { + params->initialize = 0; + params->override = 0; + if (cmdline_parser_config_file(args.config_arg, &args, params) + != 0) { + exit(EXIT_FAILURE); + } + } + if (args.vpn_given) { + zconf.send_ip_pkts = 1; + zconf.gw_mac_set = 1; + memset(zconf.gw_mac, 0, IFHWADDRLEN); + } + if (cmdline_parser_required(&args, CMDLINE_PARSER_PACKAGE) != 0) { + exit(EXIT_FAILURE); + } + // now that we know the probe module, let's find what it supports memset(&zconf.fsconf, 0, sizeof(struct fieldset_conf)); // the set of fields made available to a user is constructed From 8fd14916808a384ec978d87af39178f40bdaf6c9 Mon Sep 17 00:00:00 2001 From: Zakir Durumeric Date: Wed, 9 Oct 2013 17:06:15 -0400 Subject: [PATCH 29/53] adding null help text place holders --- src/output_modules/module_csv.c | 1 + src/output_modules/module_json.c | 1 + src/output_modules/module_redis.c | 14 +++++++++++++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/output_modules/module_csv.c b/src/output_modules/module_csv.c index 1d4de7b..51c9278 100644 --- a/src/output_modules/module_csv.c +++ b/src/output_modules/module_csv.c @@ -103,5 +103,6 @@ output_module_t module_csv_file = { .update_interval = 0, .close = &csv_close, .process_ip = &csv_process, + .helptext = NULL }; diff --git a/src/output_modules/module_json.c b/src/output_modules/module_json.c index 594b54c..bb0ed9e 100644 --- a/src/output_modules/module_json.c +++ b/src/output_modules/module_json.c @@ -188,5 +188,6 @@ output_module_t module_json_file = { .update_interval = 0, .close = &json_output_file_close, .process_ip = &json_output_file_ip, + .helptext = NULL }; diff --git a/src/output_modules/module_redis.c b/src/output_modules/module_redis.c index 703ad55..a2ad693 100644 --- a/src/output_modules/module_redis.c +++ b/src/output_modules/module_redis.c @@ -35,6 +35,17 @@ static int redismodule_init(struct state_conf *conf, char **fields, int fieldlen buffer = calloc(BUFFER_SIZE, sizeof(uint32_t)); assert(buffer); buffer_fill = 0; + + redisconf_t *rconf = redis_parse_connstr(conf->output_args); + if (rconf->type == T_TCP) { + log_info("redis-module", "{type: TCP, server: %s, " + "port %u, list %s", rconf->server, + rconf->port, rconf->list_name); + } else { + log_info("redis-module", "{type: LOCAL, path: %s, " + "list %s", rconf->path, rconf->list_name); + } + queue_name = rconf->list_name; return redis_init(conf->output_args); } @@ -80,6 +91,7 @@ output_module_t module_redis = { .update = NULL, .update_interval = 0, .close = &redismodule_close, - .process_ip = &redismodule_process + .process_ip = &redismodule_process, + .helptext = NULL }; From b5f6a278bb1462f3d5532f2a900ecd19db049f99 Mon Sep 17 00:00:00 2001 From: Zakir Durumeric Date: Wed, 9 Oct 2013 17:07:00 -0400 Subject: [PATCH 30/53] help to show selected output module name before printing help text --- src/zmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zmap.c b/src/zmap.c index 69b6241..b4f564e 100644 --- a/src/zmap.c +++ b/src/zmap.c @@ -426,7 +426,7 @@ int main(int argc, char *argv[]) } else { printf("no help text available\n"); } - printf("\nselected output-module help\n"); + printf("\nselected output-module (%s) help\n", zconf.output_module->name); if (zconf.output_module->helptext) { printf("%s\n", zconf.output_module->helptext); } else { From 76f848bf79ad26795a72d996b4a956d3825ab461 Mon Sep 17 00:00:00 2001 From: Zakir Durumeric Date: Wed, 9 Oct 2013 17:07:29 -0400 Subject: [PATCH 31/53] removing deprecated references to extended_file and simple_file. --- src/CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 05177a9..a5c6346 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -25,8 +25,6 @@ SET(EXTRA_OUTPUT_MODULES ) SET(OUTPUT_MODULE_SOURCES -# output_modules/module_extended_file.c -# output_modules/module_simple_file.c output_modules/module_csv.c output_modules/output_modules.c ) From 3eb7630f28e40f884af76afeb4b20443ab08f5d3 Mon Sep 17 00:00:00 2001 From: Zakir Durumeric Date: Wed, 9 Oct 2013 17:07:52 -0400 Subject: [PATCH 32/53] making parse redis connstr externally available --- lib/redis.c | 13 +------------ lib/redis.h | 13 +++++++++++++ 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/lib/redis.c b/lib/redis.c index aeacf08..9383a39 100644 --- a/lib/redis.c +++ b/lib/redis.c @@ -25,18 +25,7 @@ static redisContext *rctx; -#define T_TCP 0 -#define T_LOCAL 1 - -typedef struct redisconf { - int type; - char *path; - char *server; - uint16_t port; - char *list_name; -} redisconf_t; - -static redisconf_t *redis_parse_connstr(char *connstr) +redisconf_t *redis_parse_connstr(char *connstr) { redisconf_t *retv = malloc(sizeof(redisconf_t)); if (strcmp("tcp://", connstr) == 6) { diff --git a/lib/redis.h b/lib/redis.h index e382375..ca636bf 100644 --- a/lib/redis.h +++ b/lib/redis.h @@ -5,6 +5,19 @@ #ifndef REDIS_ZHELPERS_H #define REDIS_ZHELPERS_H +#define T_TCP 0 +#define T_LOCAL 1 + +typedef struct redisconf { + int type; + char *path; + char *server; + uint16_t port; + char *list_name; +} redisconf_t; + +redisconf_t *redis_parse_connstr(char *connstr); + int redis_init(char*); int redis_close(void); From 4af98e99512464cadc1371e58e6d2a109f99a35d Mon Sep 17 00:00:00 2001 From: David Adrian Date: Fri, 11 Oct 2013 10:19:53 -0400 Subject: [PATCH 33/53] Working filtering, still needs cleanup and optimization --- src/filter.c | 5 +- src/parser.c | 630 --------------------------------------------------- src/parser.y | 4 +- 3 files changed, 5 insertions(+), 634 deletions(-) delete mode 100644 src/parser.c diff --git a/src/filter.c b/src/filter.c index 7bc4c8d..7cb78e7 100644 --- a/src/filter.c +++ b/src/filter.c @@ -18,8 +18,9 @@ static int validate_node(node_t *node, fielddefset_t *fields) return 1; } - for (i = 0; i < MAX_FIELDS; i++) { + for (i = 0; i < fields->len; i++) { if (fields->fielddefs[i].name) { + printf("Fields: %s, Looking for: %s\n", fields->fielddefs[i].name, node->value.field.fieldname); if (strcmp(fields->fielddefs[i].name, node->value.field.fieldname) == 0) { node->value.field.index = i; return 1; @@ -58,6 +59,6 @@ int validate_filter(node_t *root, fielddefset_t *fields) if (!valid) { return 0; } + return (validate_filter(root->left_child, fields) && validate_filter(root->right_child, fields)); - } diff --git a/src/parser.c b/src/parser.c deleted file mode 100644 index 43047ca..0000000 --- a/src/parser.c +++ /dev/null @@ -1,630 +0,0 @@ -#ifndef lint -static const char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93"; -#endif - -#define YYBYACC 1 -#define YYMAJOR 1 -#define YYMINOR 9 -#define YYPATCH 20120115 - -#define YYEMPTY (-1) -#define yyclearin (yychar = YYEMPTY) -#define yyerrok (yyerrflag = 0) -#define YYRECOVERING() (yyerrflag != 0) - -#define YYPREFIX "yy" - -#define YYPURE 0 - -#line 2 "parser.y" -#include -#include -#include "expression.h" -#include "lexer.h" -#include "filter.h" - -void yyerror(const char *str) -{ - fprintf(stderr,"error: %s\n",str); - fprintf(stderr, "%s\n", "YOLO"); -} - -int yywrap() -{ - return 1; -} - -extern node_t *zfilter; - -#line 23 "parser.y" -#ifdef YYSTYPE -#undef YYSTYPE_IS_DECLARED -#define YYSTYPE_IS_DECLARED 1 -#endif -#ifndef YYSTYPE_IS_DECLARED -#define YYSTYPE_IS_DECLARED 1 -typedef union { - int int_literal; - char *string_literal; - struct node *expr; -} YYSTYPE; -#endif /* !YYSTYPE_IS_DECLARED */ -#line 52 "parser.c" - -/* compatibility with bison */ -#ifdef YYPARSE_PARAM -/* compatibility with FreeBSD */ -# ifdef YYPARSE_PARAM_TYPE -# define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM) -# else -# define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM) -# endif -#else -# define YYPARSE_DECL() yyparse(void) -#endif - -/* Parameters sent to lex. */ -#ifdef YYLEX_PARAM -# define YYLEX_DECL() yylex(void *YYLEX_PARAM) -# define YYLEX yylex(YYLEX_PARAM) -#else -# define YYLEX_DECL() yylex(void) -# define YYLEX yylex() -#endif - -/* Parameters sent to yyerror. */ -#ifndef YYERROR_DECL -#define YYERROR_DECL() yyerror(const char *s) -#endif -#ifndef YYERROR_CALL -#define YYERROR_CALL(msg) yyerror(msg) -#endif - -extern int YYPARSE_DECL(); - -#define T_AND 257 -#define T_OR 258 -#define T_NUMBER 259 -#define T_FIELD 260 -#define T_NOT_EQ 261 -#define T_GT_EQ 262 -#define T_LT_EQ 263 -#define YYERRCODE 256 -static const short yylhs[] = { -1, - 0, 4, 4, 4, 4, 1, 1, 2, 2, 2, - 2, 2, 2, 3, 3, -}; -static const short yylen[] = { 2, - 1, 3, 3, 3, 1, 1, 1, 3, 3, 3, - 3, 3, 3, 3, 3, -}; -static const short yydefred[] = { 0, - 0, 0, 0, 5, 6, 7, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 4, 11, 15, 12, - 9, 10, 8, 14, 13, 3, 0, -}; -static const short yydgoto[] = { 3, - 4, 5, 6, 7, -}; -static const short yysindex[] = { -40, - -40, -57, 0, 0, 0, 0, -250, -39, -249, -245, - -244, -243, -247, -242, -40, -40, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, -248, -}; -static const short yyrindex[] = { 0, - 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, -}; -static const short yygindex[] = { 0, - 0, 0, 0, 5, -}; -#define YYTABLESIZE 259 -static const short yytable[] = { 1, - 2, 17, 12, 13, 11, 8, 15, 16, 15, 18, - 19, 23, 24, 20, 21, 22, 25, 1, 0, 26, - 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 9, 10, 14, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 15, 16, 2, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 2, -}; -static const short yycheck[] = { 40, - 0, 41, 60, 61, 62, 1, 257, 258, 257, 259, - 260, 259, 260, 259, 259, 259, 259, 0, -1, 15, - 16, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 41, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 261, 262, 263, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 257, 258, 260, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 258, -}; -#define YYFINAL 3 -#ifndef YYDEBUG -#define YYDEBUG 0 -#endif -#define YYMAXTOKEN 263 -#if YYDEBUG -static const char *yyname[] = { - -"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,"'('","')'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'<'","'='","'>'",0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"T_AND", -"T_OR","T_NUMBER","T_FIELD","T_NOT_EQ","T_GT_EQ","T_LT_EQ", -}; -static const char *yyrule[] = { -"$accept : expression", -"expression : filter_expr", -"filter_expr : filter_expr T_OR filter_expr", -"filter_expr : filter_expr T_AND filter_expr", -"filter_expr : '(' filter_expr ')'", -"filter_expr : filter", -"filter : number_filter", -"filter : string_filter", -"number_filter : T_FIELD '=' T_NUMBER", -"number_filter : T_FIELD '>' T_NUMBER", -"number_filter : T_FIELD '<' T_NUMBER", -"number_filter : T_FIELD T_NOT_EQ T_NUMBER", -"number_filter : T_FIELD T_GT_EQ T_NUMBER", -"number_filter : T_FIELD T_LT_EQ T_NUMBER", -"string_filter : T_FIELD '=' T_FIELD", -"string_filter : T_FIELD T_NOT_EQ T_FIELD", - -}; -#endif - -int yydebug; -int yynerrs; - -int yyerrflag; -int yychar; -YYSTYPE yyval; -YYSTYPE yylval; - -/* define the initial stack-sizes */ -#ifdef YYSTACKSIZE -#undef YYMAXDEPTH -#define YYMAXDEPTH YYSTACKSIZE -#else -#ifdef YYMAXDEPTH -#define YYSTACKSIZE YYMAXDEPTH -#else -#define YYSTACKSIZE 500 -#define YYMAXDEPTH 500 -#endif -#endif - -#define YYINITSTACKSIZE 500 - -typedef struct { - unsigned stacksize; - short *s_base; - short *s_mark; - short *s_last; - YYSTYPE *l_base; - YYSTYPE *l_mark; -} YYSTACKDATA; -/* variables for the parser stack */ -static YYSTACKDATA yystack; -#line 144 "parser.y" - - -#line 253 "parser.c" - -#if YYDEBUG -#include /* needed for printf */ -#endif - -#include /* needed for malloc, etc */ -#include /* needed for memset */ - -/* allocate initial stack or double stack size, up to YYMAXDEPTH */ -static int yygrowstack(YYSTACKDATA *data) -{ - int i; - unsigned newsize; - short *newss; - YYSTYPE *newvs; - - if ((newsize = data->stacksize) == 0) - newsize = YYINITSTACKSIZE; - else if (newsize >= YYMAXDEPTH) - return -1; - else if ((newsize *= 2) > YYMAXDEPTH) - newsize = YYMAXDEPTH; - - i = data->s_mark - data->s_base; - newss = (short *)realloc(data->s_base, newsize * sizeof(*newss)); - if (newss == 0) - return -1; - - data->s_base = newss; - data->s_mark = newss + i; - - newvs = (YYSTYPE *)realloc(data->l_base, newsize * sizeof(*newvs)); - if (newvs == 0) - return -1; - - data->l_base = newvs; - data->l_mark = newvs + i; - - data->stacksize = newsize; - data->s_last = data->s_base + newsize - 1; - return 0; -} - -#if YYPURE || defined(YY_NO_LEAKS) -static void yyfreestack(YYSTACKDATA *data) -{ - free(data->s_base); - free(data->l_base); - memset(data, 0, sizeof(*data)); -} -#else -#define yyfreestack(data) /* nothing */ -#endif - -#define YYABORT goto yyabort -#define YYREJECT goto yyabort -#define YYACCEPT goto yyaccept -#define YYERROR goto yyerrlab - -int -YYPARSE_DECL() -{ - int yym, yyn, yystate; -#if YYDEBUG - const char *yys; - - if ((yys = getenv("YYDEBUG")) != 0) - { - yyn = *yys; - if (yyn >= '0' && yyn <= '9') - yydebug = yyn - '0'; - } -#endif - - yynerrs = 0; - yyerrflag = 0; - yychar = YYEMPTY; - yystate = 0; - -#if YYPURE - memset(&yystack, 0, sizeof(yystack)); -#endif - - if (yystack.s_base == NULL && yygrowstack(&yystack)) goto yyoverflow; - yystack.s_mark = yystack.s_base; - yystack.l_mark = yystack.l_base; - yystate = 0; - *yystack.s_mark = 0; - -yyloop: - if ((yyn = yydefred[yystate]) != 0) goto yyreduce; - if (yychar < 0) - { - if ((yychar = YYLEX) < 0) yychar = 0; -#if YYDEBUG - if (yydebug) - { - yys = 0; - if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; - if (!yys) yys = "illegal-symbol"; - printf("%sdebug: state %d, reading %d (%s)\n", - YYPREFIX, yystate, yychar, yys); - } -#endif - } - if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && - yyn <= YYTABLESIZE && yycheck[yyn] == yychar) - { -#if YYDEBUG - if (yydebug) - printf("%sdebug: state %d, shifting to state %d\n", - YYPREFIX, yystate, yytable[yyn]); -#endif - if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) - { - goto yyoverflow; - } - yystate = yytable[yyn]; - *++yystack.s_mark = yytable[yyn]; - *++yystack.l_mark = yylval; - yychar = YYEMPTY; - if (yyerrflag > 0) --yyerrflag; - goto yyloop; - } - if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && - yyn <= YYTABLESIZE && yycheck[yyn] == yychar) - { - yyn = yytable[yyn]; - goto yyreduce; - } - if (yyerrflag) goto yyinrecovery; - - yyerror("syntax error"); - - goto yyerrlab; - -yyerrlab: - ++yynerrs; - -yyinrecovery: - if (yyerrflag < 3) - { - yyerrflag = 3; - for (;;) - { - if ((yyn = yysindex[*yystack.s_mark]) && (yyn += YYERRCODE) >= 0 && - yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) - { -#if YYDEBUG - if (yydebug) - printf("%sdebug: state %d, error recovery shifting\ - to state %d\n", YYPREFIX, *yystack.s_mark, yytable[yyn]); -#endif - if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) - { - goto yyoverflow; - } - yystate = yytable[yyn]; - *++yystack.s_mark = yytable[yyn]; - *++yystack.l_mark = yylval; - goto yyloop; - } - else - { -#if YYDEBUG - if (yydebug) - printf("%sdebug: error recovery discarding state %d\n", - YYPREFIX, *yystack.s_mark); -#endif - if (yystack.s_mark <= yystack.s_base) goto yyabort; - --yystack.s_mark; - --yystack.l_mark; - } - } - } - else - { - if (yychar == 0) goto yyabort; -#if YYDEBUG - if (yydebug) - { - yys = 0; - if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; - if (!yys) yys = "illegal-symbol"; - printf("%sdebug: state %d, error recovery discards token %d (%s)\n", - YYPREFIX, yystate, yychar, yys); - } -#endif - yychar = YYEMPTY; - goto yyloop; - } - -yyreduce: -#if YYDEBUG - if (yydebug) - printf("%sdebug: state %d, reducing by rule %d (%s)\n", - YYPREFIX, yystate, yyn, yyrule[yyn]); -#endif - yym = yylen[yyn]; - if (yym) - yyval = yystack.l_mark[1-yym]; - else - memset(&yyval, 0, sizeof yyval); - switch (yyn) - { -case 1: -#line 46 "parser.y" - { - zfilter = yystack.l_mark[0].expr; - } -break; -case 2: -#line 53 "parser.y" - { - yyval.expr = make_op_node(OR); - yyval.expr->left_child = yystack.l_mark[-2].expr; - yyval.expr->right_child = yystack.l_mark[0].expr; - } -break; -case 3: -#line 59 "parser.y" - { - yyval.expr = make_op_node(AND); - yyval.expr->left_child = yystack.l_mark[-2].expr; - yyval.expr->right_child = yystack.l_mark[0].expr; - } -break; -case 4: -#line 65 "parser.y" - { - yyval.expr = yystack.l_mark[-1].expr; - } -break; -case 5: -#line 69 "parser.y" - { - yyval.expr = yystack.l_mark[0].expr; - } -break; -case 6: -#line 75 "parser.y" - { - yyval.expr = yystack.l_mark[0].expr; - } -break; -case 7: -#line 79 "parser.y" - { - yyval.expr = yystack.l_mark[0].expr; - } -break; -case 8: -#line 85 "parser.y" - { - yyval.expr = make_op_node(EQ); - yyval.expr->left_child = make_field_node(yystack.l_mark[-2].string_literal); - yyval.expr->right_child = make_int_node(yystack.l_mark[0].int_literal); - } -break; -case 9: -#line 92 "parser.y" - { - yyval.expr = make_op_node(GT); - yyval.expr->left_child = make_field_node(yystack.l_mark[-2].string_literal); - yyval.expr->right_child = make_int_node(yystack.l_mark[0].int_literal); - } -break; -case 10: -#line 99 "parser.y" - { - yyval.expr = make_op_node(LT); - yyval.expr->left_child = make_field_node(yystack.l_mark[-2].string_literal); - yyval.expr->right_child = make_int_node(yystack.l_mark[0].int_literal); - } -break; -case 11: -#line 106 "parser.y" - { - yyval.expr = make_op_node(NEQ); - yyval.expr->left_child = make_field_node(yystack.l_mark[-2].string_literal); - yyval.expr->right_child = make_int_node(yystack.l_mark[0].int_literal); - } -break; -case 12: -#line 113 "parser.y" - { - yyval.expr = make_op_node(GT_EQ); - yyval.expr->left_child = make_field_node(yystack.l_mark[-2].string_literal); - yyval.expr->right_child = make_int_node(yystack.l_mark[0].int_literal); - } -break; -case 13: -#line 120 "parser.y" - { - yyval.expr = make_op_node(LT_EQ); - yyval.expr->left_child = make_field_node(yystack.l_mark[-2].string_literal); - yyval.expr->right_child = make_int_node(yystack.l_mark[0].int_literal); - } -break; -case 14: -#line 129 "parser.y" - { - yyval.expr = make_op_node(EQ); - yyval.expr->left_child = make_field_node(yystack.l_mark[-2].string_literal); - yyval.expr->right_child = make_field_node(yystack.l_mark[0].string_literal); - } -break; -case 15: -#line 136 "parser.y" - { - yyval.expr = make_op_node(NEQ); - yyval.expr->left_child = make_field_node(yystack.l_mark[-2].string_literal); - yyval.expr->right_child = make_field_node(yystack.l_mark[0].string_literal); - } -break; -#line 569 "parser.c" - } - yystack.s_mark -= yym; - yystate = *yystack.s_mark; - yystack.l_mark -= yym; - yym = yylhs[yyn]; - if (yystate == 0 && yym == 0) - { -#if YYDEBUG - if (yydebug) - printf("%sdebug: after reduction, shifting from state 0 to\ - state %d\n", YYPREFIX, YYFINAL); -#endif - yystate = YYFINAL; - *++yystack.s_mark = YYFINAL; - *++yystack.l_mark = yyval; - if (yychar < 0) - { - if ((yychar = YYLEX) < 0) yychar = 0; -#if YYDEBUG - if (yydebug) - { - yys = 0; - if (yychar <= YYMAXTOKEN) yys = yyname[yychar]; - if (!yys) yys = "illegal-symbol"; - printf("%sdebug: state %d, reading %d (%s)\n", - YYPREFIX, YYFINAL, yychar, yys); - } -#endif - } - if (yychar == 0) goto yyaccept; - goto yyloop; - } - if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && - yyn <= YYTABLESIZE && yycheck[yyn] == yystate) - yystate = yytable[yyn]; - else - yystate = yydgoto[yym]; -#if YYDEBUG - if (yydebug) - printf("%sdebug: after reduction, shifting from state %d \ -to state %d\n", YYPREFIX, *yystack.s_mark, yystate); -#endif - if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) - { - goto yyoverflow; - } - *++yystack.s_mark = (short) yystate; - *++yystack.l_mark = yyval; - goto yyloop; - -yyoverflow: - yyerror("yacc stack overflow"); - -yyabort: - yyfreestack(&yystack); - return (1); - -yyaccept: - yyfreestack(&yystack); - return (0); -} diff --git a/src/parser.y b/src/parser.y index 941992d..f749d61 100644 --- a/src/parser.y +++ b/src/parser.y @@ -129,14 +129,14 @@ string_filter: { $$ = make_op_node(EQ); $$->left_child = make_field_node($1); - $$->right_child = make_field_node($3); + $$->right_child = make_string_node($3); } | T_FIELD T_NOT_EQ T_FIELD { $$ = make_op_node(NEQ); $$->left_child = make_field_node($1); - $$->right_child = make_field_node($3); + $$->right_child = make_string_node($3); } ; From bc516445ef75d6e3335f2d6cc0c24bfa797c9c8c Mon Sep 17 00:00:00 2001 From: David Adrian Date: Fri, 11 Oct 2013 10:25:45 -0400 Subject: [PATCH 34/53] Remove debug printf calls --- src/filter.c | 6 +----- src/parser.y | 3 +-- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/filter.c b/src/filter.c index 7cb78e7..f0a19e8 100644 --- a/src/filter.c +++ b/src/filter.c @@ -20,7 +20,6 @@ static int validate_node(node_t *node, fielddefset_t *fields) for (i = 0; i < fields->len; i++) { if (fields->fielddefs[i].name) { - printf("Fields: %s, Looking for: %s\n", fields->fielddefs[i].name, node->value.field.fieldname); if (strcmp(fields->fielddefs[i].name, node->value.field.fieldname) == 0) { node->value.field.index = i; return 1; @@ -43,9 +42,6 @@ int parse_filter_string(char *filter) return 0; } zconf.filter.expression = zfilter; - print_expression(zfilter); - printf("%s\n", ""); - fflush(stdout); return 1; } @@ -59,6 +55,6 @@ int validate_filter(node_t *root, fielddefset_t *fields) if (!valid) { return 0; } - + return (validate_filter(root->left_child, fields) && validate_filter(root->right_child, fields)); } diff --git a/src/parser.y b/src/parser.y index f749d61..6c44e17 100644 --- a/src/parser.y +++ b/src/parser.y @@ -7,8 +7,7 @@ void yyerror(const char *str) { - fprintf(stderr,"error: %s\n",str); - fprintf(stderr, "%s\n", "YOLO"); + fprintf(stderr,"Parse error: %s\n",str); } int yywrap() From 24534046042469fac24c3536575bbee1691ad6ea Mon Sep 17 00:00:00 2001 From: David Adrian Date: Fri, 11 Oct 2013 11:04:04 -0400 Subject: [PATCH 35/53] Move stack.h and stack.c to lib --- {src => lib}/stack.c | 2 +- {src => lib}/stack.h | 0 src/CMakeLists.txt | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename {src => lib}/stack.c (93%) rename {src => lib}/stack.h (100%) diff --git a/src/stack.c b/lib/stack.c similarity index 93% rename from src/stack.c rename to lib/stack.c index dd98876..8dfe0db 100644 --- a/src/stack.c +++ b/lib/stack.c @@ -28,7 +28,7 @@ void push(stack_t* stack, void* elt) { if (stack->cur_size == stack->max_size) { stack->max_size *= 2; - xrealloc(stack->arr, stack->max_size);; + xrealloc(stack->arr, stack->max_size); } stack->arr[stack->cur_size++] = elt; } diff --git a/src/stack.h b/lib/stack.h similarity index 100% rename from src/stack.h rename to lib/stack.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 44ce551..c75c457 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -11,6 +11,7 @@ SET(LIB_SOURCES ${PROJECT_SOURCE_DIR}/lib/logger.c ${PROJECT_SOURCE_DIR}/lib/random.c ${PROJECT_SOURCE_DIR}/lib/rijndael-alg-fst.c + ${PROJECT_SOURCE_DIR}/lib/stack.c ${PROJECT_SOURCE_DIR}/lib/xalloc.c ) @@ -49,7 +50,6 @@ SET(SOURCES monitor.c recv.c send.c - stack.c state.c validate.c zmap.c From f2ba9d76215f2bb22fde0f71850cdd541ee59eeb Mon Sep 17 00:00:00 2001 From: David Adrian Date: Fri, 11 Oct 2013 12:13:42 -0400 Subject: [PATCH 36/53] Untested iterative implementation of evaluate --- lib/stack.c | 17 ++++++--- lib/stack.h | 7 ++-- src/expression.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++- src/expression.h | 6 +++- 4 files changed, 111 insertions(+), 8 deletions(-) diff --git a/lib/stack.c b/lib/stack.c index 8dfe0db..3ebe921 100644 --- a/lib/stack.c +++ b/lib/stack.c @@ -24,7 +24,7 @@ void free_stack(stack_t* stack) xfree(stack); } -void push(stack_t* stack, void* elt) +void stack_push(stack_t* stack, void* elt) { if (stack->cur_size == stack->max_size) { stack->max_size *= 2; @@ -33,8 +33,17 @@ void push(stack_t* stack, void* elt) stack->arr[stack->cur_size++] = elt; } -void* pop(stack_t* stack) +void stack_pop(stack_t* stack) { - void* res = stack->arr[--stack->cur_size]; - return res; + --stack->cur_size; +} + +void* stack_peek(stack_t* stack) +{ + return stack->arr[stack->cur_size - 1]; +} + +int stack_is_empty(stack_t* stack) +{ + return (stack->cur_size == 0); } diff --git a/lib/stack.h b/lib/stack.h index 9417238..c3dec83 100644 --- a/lib/stack.h +++ b/lib/stack.h @@ -9,7 +9,10 @@ typedef struct stack stack_t; stack_t* alloc_stack(size_t size); void free_stack(stack_t* stack); -void push(stack_t* stack, void* elt); -void* pop(stack_t* stack); +void stack_push(stack_t* stack, void* elt); +void stack_pop(stack_t* stack); +void* stack_peek(stack_t* stack); + +int stack_is_empty(stack_t* stack); #endif /* ZMAP_STACK_H */ \ No newline at end of file diff --git a/src/expression.c b/src/expression.c index 354b805..352c925 100644 --- a/src/expression.c +++ b/src/expression.c @@ -1,6 +1,8 @@ #include "expression.h" -#include "fieldset.H" +#include "fieldset.h" + +#include "../lib/stack.h" #include "../lib/xalloc.h" /* Static helper functions */ @@ -83,6 +85,7 @@ node_t* make_field_node(char *fieldname) node_t *node = alloc_node(); node->type = FIELD; node->value.field.fieldname = fieldname; + node->result = 1; return node; } @@ -91,6 +94,7 @@ node_t* make_string_node(char *literal) node_t *node = alloc_node(); node->type = STRING; node->value.string_literal = literal; + node->result = 1; return node; } @@ -99,6 +103,7 @@ node_t* make_int_node(int literal) node_t *node = alloc_node(); node->type = INT; node->value.int_literal = literal; + node->result = 1; return node; } @@ -135,6 +140,88 @@ int evaluate_expression(node_t *root, fieldset_t *fields) { return 0; } +int evaluate_expression_fast(node_t *root, fieldset_t *fields) { + stack_t* s; + node_t* node; + if (!root) return 1; + s = alloc_stack(16); /* XXX Find a way to guess/know this better */ + root->evaluated = 0; + stack_push(s, root); + int result = 1; + while (!stack_is_empty(s) && result) { + node = (node_t *) stack_peek(s); + if (node->type != OP) { + continue; + } + if (node->value.op == AND) { + if (!node->right_child->evaluated) { + stack_push(s, node->right_child); + } + if (!node->left_child->evaluated) { + stack_push(s, node->left_child); + continue; + } + + stack_pop(s); + if (!(node->left_child->result && node->right_child->result)) { + node->evaluated = 1; + result = 0; + } + node->left_child->evaluated = 0; + node->right_child->evaluated = 0; + } else if (node->value.op == OR) { + if (!node->right_child->evaluated) { + stack_push(s, node->right_child); + } + if (!node->left_child->evaluated) { + stack_push(s, node->left_child); + continue; + } + + stack_pop(s); + if (!(node->left_child->result || node->right_child->result)) { + node->evaluated = 1; + result = 0; + } + node->left_child->evaluated = 0; + node->right_child->evaluated = 0; + + } else { + stack_pop(s); + switch (node->value.op) { + case GT: + node->result = eval_gt_node(node, fields); + break; + case LT: + node->result = eval_lt_node(node, fields); + break; + case EQ: + node->result = eval_eq_node(node, fields); + break; + case NEQ: + node->result = !(eval_eq_node(node, fields)); + break; + case LT_EQ: + node->result = eval_lt_eq_node(node, fields); + break; + case GT_EQ: + node->result = eval_gt_eq_node(node, fields); + break; + default: + exit(-1); + break; + } + node->evaluated = 1; + if (stack_is_empty(s)) { + result = node->result; + node->evaluated = 0; + } + } + } + free_stack(s); + return result; +} + void print_expression(node_t *root) { if (!root) return; printf("%s", "( "); diff --git a/src/expression.h b/src/expression.h index d65668d..e44ee2f 100644 --- a/src/expression.h +++ b/src/expression.h @@ -23,8 +23,8 @@ struct field_id { union node_value { struct field_id field; - char *string_literal; uint64_t int_literal; + char *string_literal; enum operation op; }; @@ -33,6 +33,8 @@ typedef struct node { struct node *right_child; enum node_type type; union node_value value; + int evaluated; + int result; } node_t; node_t* make_op_node(enum operation op); @@ -45,6 +47,8 @@ node_t* make_int_node(int literal); int evaluate_expression(node_t *root, fieldset_t *fields); +int evaluate_expression_fast(node_t *root, fieldset_t *fields); + void print_expression(node_t *root); #endif /* ZMAP_TREE_H */ \ No newline at end of file From eeb5ddcf0cffd78762b7b223354736f076b21e05 Mon Sep 17 00:00:00 2001 From: David Adrian Date: Fri, 11 Oct 2013 12:38:22 -0400 Subject: [PATCH 37/53] Switch to the iterative evaluator --- src/recv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/recv.c b/src/recv.c index df8211e..97a7dd8 100644 --- a/src/recv.c +++ b/src/recv.c @@ -142,7 +142,7 @@ void packet_cb(u_char __attribute__((__unused__)) *user, if (is_repeat && zconf.filter_duplicates) { goto cleanup; } - if (!evaluate_expression(zconf.filter.expression, fs)) { + if (!evaluate_expression_fast(zconf.filter.expression, fs)) { goto cleanup; } From 8f19fb2cac337d6692ecb6036bb7097b0a15ba3e Mon Sep 17 00:00:00 2001 From: David Adrian Date: Fri, 11 Oct 2013 17:10:05 -0400 Subject: [PATCH 38/53] Revert "Switch to the iterative evaluator" This reverts commit eeb5ddcf0cffd78762b7b223354736f076b21e05. --- src/recv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/recv.c b/src/recv.c index 97a7dd8..df8211e 100644 --- a/src/recv.c +++ b/src/recv.c @@ -142,7 +142,7 @@ void packet_cb(u_char __attribute__((__unused__)) *user, if (is_repeat && zconf.filter_duplicates) { goto cleanup; } - if (!evaluate_expression_fast(zconf.filter.expression, fs)) { + if (!evaluate_expression(zconf.filter.expression, fs)) { goto cleanup; } From 84318c2cf0c5544adfbaf27366f131f39f2fc8dc Mon Sep 17 00:00:00 2001 From: David Adrian Date: Fri, 11 Oct 2013 17:10:20 -0400 Subject: [PATCH 39/53] Revert "Untested iterative implementation of evaluate" This reverts commit f2ba9d76215f2bb22fde0f71850cdd541ee59eeb. --- lib/stack.c | 17 +++------ lib/stack.h | 7 ++-- src/expression.c | 89 +----------------------------------------------- src/expression.h | 6 +--- 4 files changed, 8 insertions(+), 111 deletions(-) diff --git a/lib/stack.c b/lib/stack.c index 3ebe921..8dfe0db 100644 --- a/lib/stack.c +++ b/lib/stack.c @@ -24,7 +24,7 @@ void free_stack(stack_t* stack) xfree(stack); } -void stack_push(stack_t* stack, void* elt) +void push(stack_t* stack, void* elt) { if (stack->cur_size == stack->max_size) { stack->max_size *= 2; @@ -33,17 +33,8 @@ void stack_push(stack_t* stack, void* elt) stack->arr[stack->cur_size++] = elt; } -void stack_pop(stack_t* stack) +void* pop(stack_t* stack) { - --stack->cur_size; -} - -void* stack_peek(stack_t* stack) -{ - return stack->arr[stack->cur_size - 1]; -} - -int stack_is_empty(stack_t* stack) -{ - return (stack->cur_size == 0); + void* res = stack->arr[--stack->cur_size]; + return res; } diff --git a/lib/stack.h b/lib/stack.h index c3dec83..9417238 100644 --- a/lib/stack.h +++ b/lib/stack.h @@ -9,10 +9,7 @@ typedef struct stack stack_t; stack_t* alloc_stack(size_t size); void free_stack(stack_t* stack); -void stack_push(stack_t* stack, void* elt); -void stack_pop(stack_t* stack); -void* stack_peek(stack_t* stack); - -int stack_is_empty(stack_t* stack); +void push(stack_t* stack, void* elt); +void* pop(stack_t* stack); #endif /* ZMAP_STACK_H */ \ No newline at end of file diff --git a/src/expression.c b/src/expression.c index 352c925..354b805 100644 --- a/src/expression.c +++ b/src/expression.c @@ -1,8 +1,6 @@ #include "expression.h" -#include "fieldset.h" +#include "fieldset.H" - -#include "../lib/stack.h" #include "../lib/xalloc.h" /* Static helper functions */ @@ -85,7 +83,6 @@ node_t* make_field_node(char *fieldname) node_t *node = alloc_node(); node->type = FIELD; node->value.field.fieldname = fieldname; - node->result = 1; return node; } @@ -94,7 +91,6 @@ node_t* make_string_node(char *literal) node_t *node = alloc_node(); node->type = STRING; node->value.string_literal = literal; - node->result = 1; return node; } @@ -103,7 +99,6 @@ node_t* make_int_node(int literal) node_t *node = alloc_node(); node->type = INT; node->value.int_literal = literal; - node->result = 1; return node; } @@ -140,88 +135,6 @@ int evaluate_expression(node_t *root, fieldset_t *fields) { return 0; } -int evaluate_expression_fast(node_t *root, fieldset_t *fields) { - stack_t* s; - node_t* node; - if (!root) return 1; - s = alloc_stack(16); /* XXX Find a way to guess/know this better */ - root->evaluated = 0; - stack_push(s, root); - int result = 1; - while (!stack_is_empty(s) && result) { - node = (node_t *) stack_peek(s); - if (node->type != OP) { - continue; - } - if (node->value.op == AND) { - if (!node->right_child->evaluated) { - stack_push(s, node->right_child); - } - if (!node->left_child->evaluated) { - stack_push(s, node->left_child); - continue; - } - - stack_pop(s); - if (!(node->left_child->result && node->right_child->result)) { - node->evaluated = 1; - result = 0; - } - node->left_child->evaluated = 0; - node->right_child->evaluated = 0; - } else if (node->value.op == OR) { - if (!node->right_child->evaluated) { - stack_push(s, node->right_child); - } - if (!node->left_child->evaluated) { - stack_push(s, node->left_child); - continue; - } - - stack_pop(s); - if (!(node->left_child->result || node->right_child->result)) { - node->evaluated = 1; - result = 0; - } - node->left_child->evaluated = 0; - node->right_child->evaluated = 0; - - } else { - stack_pop(s); - switch (node->value.op) { - case GT: - node->result = eval_gt_node(node, fields); - break; - case LT: - node->result = eval_lt_node(node, fields); - break; - case EQ: - node->result = eval_eq_node(node, fields); - break; - case NEQ: - node->result = !(eval_eq_node(node, fields)); - break; - case LT_EQ: - node->result = eval_lt_eq_node(node, fields); - break; - case GT_EQ: - node->result = eval_gt_eq_node(node, fields); - break; - default: - exit(-1); - break; - } - node->evaluated = 1; - if (stack_is_empty(s)) { - result = node->result; - node->evaluated = 0; - } - } - } - free_stack(s); - return result; -} - void print_expression(node_t *root) { if (!root) return; printf("%s", "( "); diff --git a/src/expression.h b/src/expression.h index e44ee2f..d65668d 100644 --- a/src/expression.h +++ b/src/expression.h @@ -23,8 +23,8 @@ struct field_id { union node_value { struct field_id field; - uint64_t int_literal; char *string_literal; + uint64_t int_literal; enum operation op; }; @@ -33,8 +33,6 @@ typedef struct node { struct node *right_child; enum node_type type; union node_value value; - int evaluated; - int result; } node_t; node_t* make_op_node(enum operation op); @@ -47,8 +45,6 @@ node_t* make_int_node(int literal); int evaluate_expression(node_t *root, fieldset_t *fields); -int evaluate_expression_fast(node_t *root, fieldset_t *fields); - void print_expression(node_t *root); #endif /* ZMAP_TREE_H */ \ No newline at end of file From e49e4425359ff33ea7d2802d054e49f8e621b304 Mon Sep 17 00:00:00 2001 From: Zakir Durumeric Date: Fri, 11 Oct 2013 23:15:59 -0400 Subject: [PATCH 40/53] working redis string connections --- lib/redis.c | 25 +++++++++++++------------ src/output_modules/module_redis.c | 21 ++++++++++++--------- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/lib/redis.c b/lib/redis.c index 9383a39..1bad06b 100644 --- a/lib/redis.c +++ b/lib/redis.c @@ -28,14 +28,14 @@ static redisContext *rctx; redisconf_t *redis_parse_connstr(char *connstr) { redisconf_t *retv = malloc(sizeof(redisconf_t)); - if (strcmp("tcp://", connstr) == 6) { + if (!strncmp("tcp://", connstr, 6)) { char *servername = malloc(strlen(connstr)); assert(servername); char *list_name = malloc(strlen(connstr)); assert(list_name); - uint16_t port; - if (scanf(connstr, "tcp://%s:%u/%s", servername, - port, list_name) != 3) { + uint32_t port; + if (sscanf(connstr, "tcp://%[^:]:%u/%s", servername, + &port, list_name) != 3) { log_fatal("redis", "unable to parse redis connection string. This " "should be of the form tcp://server:port/list-name " "for TCP connections. All fields are required."); @@ -45,17 +45,18 @@ redisconf_t *redis_parse_connstr(char *connstr) retv->port = port; retv->list_name = list_name; retv->path = NULL; - } else if (strcmp("local://", connstr) == 8) { + } else if (!strncmp("local://", connstr, 8)) { + // looking for something along the lines of + // local:///tmp/redis.sock/list-name char *path = malloc(strlen(connstr)); assert(path); char *list_name = malloc(strlen(connstr)); assert(list_name); - if (scanf(connstr, "local://%s/%s", path, - list_name) != 3) { - log_fatal("redis", "unable to parse redis connection string. This " - "should be of the form tcp://server:port/list-name " - "for TCP connections. All fields are required."); - } + connstr = connstr + (size_t) 8; + char *listname = strrchr(connstr, '/') + (size_t) 1; + connstr[strrchr(connstr, '/') - connstr] = '\0'; + strcpy(path, connstr); + strcpy(list_name, listname); retv->type = T_LOCAL; retv->list_name = list_name; retv->path = path; @@ -63,7 +64,7 @@ redisconf_t *redis_parse_connstr(char *connstr) retv->port = 0; } else { log_fatal("redis", "unable to parse connection string. does not begin with " - "unix:// or tcp:// as expected"); + "local:// or tcp:// as expected"); } } diff --git a/src/output_modules/module_redis.c b/src/output_modules/module_redis.c index a2ad693..f766693 100644 --- a/src/output_modules/module_redis.c +++ b/src/output_modules/module_redis.c @@ -23,7 +23,6 @@ #define UNUSED __attribute__((unused)) #define BUFFER_SIZE 500 -#define SOURCE_ZMAP 0 static uint32_t *buffer; static int buffer_fill = 0; @@ -36,16 +35,20 @@ static int redismodule_init(struct state_conf *conf, char **fields, int fieldlen assert(buffer); buffer_fill = 0; - redisconf_t *rconf = redis_parse_connstr(conf->output_args); - if (rconf->type == T_TCP) { - log_info("redis-module", "{type: TCP, server: %s, " - "port %u, list %s", rconf->server, - rconf->port, rconf->list_name); + if (conf->output_args) { + redisconf_t *rconf = redis_parse_connstr(conf->output_args); + if (rconf->type == T_TCP) { + log_info("redis-module", "{type: TCP, server: %s, " + "port: %u, list: %s}", rconf->server, + rconf->port, rconf->list_name); + } else { + log_info("redis-module", "{type: LOCAL, path: %s, " + "list: %s}", rconf->path, rconf->list_name); + } + queue_name = rconf->list_name; } else { - log_info("redis-module", "{type: LOCAL, path: %s, " - "list %s", rconf->path, rconf->list_name); + queue_name = "zmap_output"; } - queue_name = rconf->list_name; return redis_init(conf->output_args); } From 8389362a012fa4880ebd265e66d49d0c52e16d51 Mon Sep 17 00:00:00 2001 From: Zakir Durumeric Date: Fri, 11 Oct 2013 23:31:48 -0400 Subject: [PATCH 41/53] return parsed data from redis parse conn str --- lib/redis.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/redis.c b/lib/redis.c index 1bad06b..4e11743 100644 --- a/lib/redis.c +++ b/lib/redis.c @@ -66,6 +66,7 @@ redisconf_t *redis_parse_connstr(char *connstr) log_fatal("redis", "unable to parse connection string. does not begin with " "local:// or tcp:// as expected"); } + return retv; } static redisContext* redis_connect(char *connstr) From a01a99e2398071f8ffb0cc23a75a8d6328835f6b Mon Sep 17 00:00:00 2001 From: David Adrian Date: Sat, 12 Oct 2013 12:05:30 -0400 Subject: [PATCH 42/53] Fix casing error in #include --- src/expression.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/expression.c b/src/expression.c index 354b805..0e4e2a1 100644 --- a/src/expression.c +++ b/src/expression.c @@ -1,5 +1,5 @@ #include "expression.h" -#include "fieldset.H" +#include "fieldset.h" #include "../lib/xalloc.h" From f483288e5a93b98940839c9345786b7644dd1b9a Mon Sep 17 00:00:00 2001 From: David Adrian Date: Sat, 12 Oct 2013 12:47:23 -0400 Subject: [PATCH 43/53] Improved filter validator - Can no longer do "stringfield = INTEGER" or "intfield = string" - Print slightly more sane error messages --- src/filter.c | 63 ++++++++++++++++++++++++++++++++++++++++++---------- src/zmap.c | 2 +- 2 files changed, 52 insertions(+), 13 deletions(-) diff --git a/src/filter.c b/src/filter.c index f0a19e8..83bee43 100644 --- a/src/filter.c +++ b/src/filter.c @@ -13,20 +13,55 @@ 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 < fields->len; i++) { - if (fields->fielddefs[i].name) { - if (strcmp(fields->fielddefs[i].name, node->value.field.fieldname) == 0) { - node->value.field.index = i; - return 1; + 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) { + 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 find it + // Didn't validate return 0; } @@ -45,6 +80,11 @@ int parse_filter_string(char *filter) return 1; } +/* + * 0 Valid + * -1 Invalid Field Name + * -2 Type Mismatch + */ int validate_filter(node_t *root, fielddefset_t *fields) { int valid; @@ -55,6 +95,5 @@ int validate_filter(node_t *root, fielddefset_t *fields) if (!valid) { return 0; } - return (validate_filter(root->left_child, fields) && validate_filter(root->right_child, fields)); } diff --git a/src/zmap.c b/src/zmap.c index e61ae65..dd15fd4 100644 --- a/src/zmap.c +++ b/src/zmap.c @@ -508,7 +508,7 @@ int main(int argc, char *argv[]) // 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"); + log_fatal("zmap", "Invalid filter"); } } From d1f6d4c1822a9c7e7f511838d6a02f5c0d3253ef Mon Sep 17 00:00:00 2001 From: David Adrian Date: Sat, 12 Oct 2013 12:52:15 -0400 Subject: [PATCH 44/53] Fix minor styling errors --- src/expression.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/expression.c b/src/expression.c index 0e4e2a1..537be78 100644 --- a/src/expression.c +++ b/src/expression.c @@ -102,7 +102,8 @@ node_t* make_int_node(int literal) return node; } -int evaluate_expression(node_t *root, fieldset_t *fields) { +int evaluate_expression(node_t *root, fieldset_t *fields) +{ if (!root) return 1; switch (root->type) { /* XXX Not sure if runs */ case FIELD: @@ -135,7 +136,8 @@ int evaluate_expression(node_t *root, fieldset_t *fields) { return 0; } -void print_expression(node_t *root) { +void print_expression(node_t *root) +{ if (!root) return; printf("%s", "( "); print_expression(root->left_child); From bc28a5a576c2a1c1cc495d6e97ad9c121ab998ac Mon Sep 17 00:00:00 2001 From: David Adrian Date: Sat, 12 Oct 2013 13:04:02 -0400 Subject: [PATCH 45/53] Fix compile warnings in blacklist.c --- lib/blacklist.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/blacklist.c b/lib/blacklist.c index e5d5919..9319d9f 100644 --- a/lib/blacklist.c +++ b/lib/blacklist.c @@ -72,13 +72,14 @@ static int init_from_string(char *ip, int value) return -1; } constraint_set(constraint, ntohl(addr.s_addr), prefix_len, value); - char *name; + const char *name; if (value == ADDR_DISALLOWED) name = "blacklisting"; else name = "whitelisting"; log_trace(name, "%s %s/%i", name, ip, prefix_len); + return 0; } @@ -110,7 +111,7 @@ static int init_from_file(char *file, const char *name, int value) return 0; } -void static init_from_array(char **cidrs, size_t len, int value) +static void init_from_array(char **cidrs, size_t len, int value) { for (int i=0; i < (int) len; i++) { init_from_string(cidrs[i], value); From f6609beb2c5c2394778e1069193af69f9c2b2d77 Mon Sep 17 00:00:00 2001 From: David Adrian Date: Sat, 12 Oct 2013 13:44:33 -0400 Subject: [PATCH 46/53] Don't overwrite conf files on install --- .gitignore | 1 + CMakeLists.txt | 10 ++++------ zmap_conf_install.cmake.in | 6 ++++++ 3 files changed, 11 insertions(+), 6 deletions(-) create mode 100644 zmap_conf_install.cmake.in diff --git a/.gitignore b/.gitignore index 2c2e6ad..d1656df 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ lexer.c lexer.h parser.c parser.h +install_manifest.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 745f3d5..bea62ab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,9 +64,7 @@ set(CMAKE_C_FLAGS_RELEASE "-O2") add_subdirectory(src) # Install conf files -FILE(GLOB CONF_FILES "conf/*") -install( - FILES - ${CONF_FILES} - DESTINATION "/etc/zmap/" - ) +FILE(GLOB CONF_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/conf" "conf/*") +message(STATUS "${CONF_FILES}") +configure_file(zmap_conf_install.cmake.in zmap_conf_install.cmake) +install(SCRIPT zmap_conf_install.cmake) diff --git a/zmap_conf_install.cmake.in b/zmap_conf_install.cmake.in new file mode 100644 index 0000000..358a97d --- /dev/null +++ b/zmap_conf_install.cmake.in @@ -0,0 +1,6 @@ +foreach(conf_file ${CONF_FILES}) + message(STATUS "${conf_file}") + if(NOT EXISTS "/etc/zmap/${conf_file}") + file(INSTALL "conf/${conf_file}" DESTINATION "/etc/zmap") + endif() +endforeach() From 48154339e0c79a832b5adc65f130f895b2b073d8 Mon Sep 17 00:00:00 2001 From: David Adrian Date: Mon, 14 Oct 2013 18:21:17 -0400 Subject: [PATCH 47/53] Delete whitelist File from testing snuck into version control. --- src/whitelist | 1 - 1 file changed, 1 deletion(-) delete mode 100644 src/whitelist diff --git a/src/whitelist b/src/whitelist deleted file mode 100644 index aab8f1d..0000000 --- a/src/whitelist +++ /dev/null @@ -1 +0,0 @@ -192.168.1.0/24 From d8a592a40158cbc7ab4d7eff858380050b336f2d Mon Sep 17 00:00:00 2001 From: Zakir Durumeric Date: Tue, 15 Oct 2013 10:22:23 -0400 Subject: [PATCH 48/53] use whitelist --- src/recv.c | 1 - src/zmap.c | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/recv.c b/src/recv.c index 6dff8c6..982d0e0 100644 --- a/src/recv.c +++ b/src/recv.c @@ -133,7 +133,6 @@ void packet_cb(u_char __attribute__((__unused__)) *user, if (!evaluate_expression(zconf.filter.expression, fs)) { goto cleanup; } - o = translate_fieldset(fs, &zconf.fsconf.translation); if (zconf.output_module && zconf.output_module->process_ip) { zconf.output_module->process_ip(o); diff --git a/src/zmap.c b/src/zmap.c index 7cf1079..136de99 100644 --- a/src/zmap.c +++ b/src/zmap.c @@ -555,6 +555,7 @@ int main(int argc, char *argv[]) " trying to scan local networks, you can change the default blacklist by " "editing the default ZMap configuration at /etc/zmap/zmap.conf."); } + SET_IF_GIVEN(zconf.whitelist_filename, whitelist_file); if (zconf.probe_module->port_args) { if (args.source_port_given) { From 002379f092382b1ee702b7d773edada3d4af08d5 Mon Sep 17 00:00:00 2001 From: Zakir Durumeric Date: Tue, 15 Oct 2013 10:39:14 -0400 Subject: [PATCH 49/53] updated install instructions from cmake --- INSTALL | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/INSTALL b/INSTALL index 86f3ae2..31e8af0 100644 --- a/INSTALL +++ b/INSTALL @@ -1,25 +1,25 @@ SYSTEM REQUIREMENTS ZMap is designed to run on GNU/Linux systems and can be built with -most recent versions of gcc. Currently, ZMap only supports 64-bit -systems. Running it requires at least 600 MB of free memory. +most recent versions of gcc. Currently, ZMap only supports 64-bit +systems. Running it requires at least 600 MB of free memory. BUILDING AND INSTALLING ZMAP ZMap requires GMP, a free library for arbitrary precision arithmetic, -gengetopt, and libpcap. These packages can be installed on +gengetopt, and libpcap. These packages can be installed on Debian-based systems by running: - sudo apt-get install libgmp3-dev gengetopt libpcap-dev + sudo apt-get install libgmp3-dev gengetopt libpcap-dev bison or on RHEL- and Fedora-based systems by running: - sudo yum install gmp gmp-devel gengetopt libpcap-devel + sudo yum install gmp gmp-devel gengetopt libpcap-devel bison Once these prerequisites have been installed, ZMap can be installed by running: - cmake ./ + cmake ./ [-DWITH_REDIS=ON] [-DWITH_JSON=ON] [-DENABLE_DEVELOPMENT=ON] [-DENABLE_HARDENING=ON] make sudo make install @@ -27,13 +27,13 @@ followed by: sudo make install -Redis support is not enabled by default. If you are want to use ZMap -with Redis, you will first need to install Hiredis. Then, rebuild -ZMap with the command "make REDIS=true". - -JSON support is not enabled by default. If you are want to use ZMap -with JSON output, you will first need to install json-c. Then, rebuild -ZMap with the command "make JSON=true". +Redis support is not enabled by default. If you are want to use ZMap +with Redis, you will first need to install Hiredis. Then run cmake with +"-DWITH_REDIS=ON". +JSON support is not enabled by default. If you are want to use ZMap +with JSON output, you will first need to install json-c. Then, run cmake with +"-DWITH_JSON=ON" + Installing json-c requires git and autotools to be available. For more information on how to install json-c, please see http://github.com/json-c/json-c From 7d04b50e4bda1e281922e4071ae482121929f1a5 Mon Sep 17 00:00:00 2001 From: Zakir Durumeric Date: Tue, 15 Oct 2013 10:42:02 -0400 Subject: [PATCH 50/53] adding david and hd to the authors list --- AUTHORS | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index e5a0436..766fec7 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,3 +1,7 @@ Zakir Durumeric J. Alex Halderman -Eric Wustrow \ No newline at end of file +Eric Wustrow + +David Adrian +HD Moore + From 69fe56864bd7dab544aad89a1de766dfd3b193f7 Mon Sep 17 00:00:00 2001 From: David Adrian Date: Wed, 16 Oct 2013 11:43:14 -0400 Subject: [PATCH 51/53] Update install to use flex and byacc, not Bison --- INSTALL | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/INSTALL b/INSTALL index 31e8af0..9ca68df 100644 --- a/INSTALL +++ b/INSTALL @@ -10,18 +10,17 @@ ZMap requires GMP, a free library for arbitrary precision arithmetic, gengetopt, and libpcap. These packages can be installed on Debian-based systems by running: - sudo apt-get install libgmp3-dev gengetopt libpcap-dev bison + sudo apt-get install libgmp3-dev gengetopt libpcap-dev flex byacc or on RHEL- and Fedora-based systems by running: - sudo yum install gmp gmp-devel gengetopt libpcap-devel bison + sudo yum install gmp gmp-devel gengetopt libpcap-devel flex byacc Once these prerequisites have been installed, ZMap can be installed by running: - cmake ./ [-DWITH_REDIS=ON] [-DWITH_JSON=ON] [-DENABLE_DEVELOPMENT=ON] [-DENABLE_HARDENING=ON] + cmake [-DWITH_REDIS=ON] [-DWITH_JSON=ON] [-DENABLE_DEVELOPMENT=ON] [-DENABLE_HARDENING=ON] ./ make - sudo make install followed by: From 0e03d170e62110441d5d59e47b8e2bccaa02c8f4 Mon Sep 17 00:00:00 2001 From: David Adrian Date: Wed, 16 Oct 2013 17:22:22 -0400 Subject: [PATCH 52/53] Fix bug where only 16 bits of entropy was used Always use aesrand_getword() & 0xFFFFFFFF not 0xFFFF. This was causing the groups used over multiple runs of ZMap to have identical generators too often. --- src/cyclic.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/cyclic.c b/src/cyclic.c index 814a49c..912c958 100644 --- a/src/cyclic.c +++ b/src/cyclic.c @@ -126,7 +126,8 @@ static int check_coprime(uint64_t check, const cyclic_group_t *group) static uint64_t find_primroot(const cyclic_group_t *group) { // what luck, rand() returns a uint32_t! - uint32_t candidate = (uint32_t) aesrand_getword() & 0xFFFF; + uint32_t candidate = (uint32_t) aesrand_getword() & 0xFFFFFFFF; + printf("Candidate: %u\n", (unsigned) candidate); while(check_coprime(candidate, group) != COPRIME) { ++candidate; } @@ -186,14 +187,14 @@ int cyclic_init(uint32_t primroot_, uint32_t current_) primroot = find_primroot(cur_group); } while (primroot >= (1LL << 32)); log_debug(LSRC, "primitive root: %lld", primroot); - current = (uint32_t) aesrand_getword() & 0xFFFF; + current = (uint32_t) aesrand_getword() & 0xFFFFFFFF; log_debug(LSRC, "starting point: %lld", current); } else { primroot = primroot_; log_debug(LSRC, "primitive root %lld specified by caller", primroot); if (!current_) { - current = (uint32_t) aesrand_getword() & 0xFFFF; + current = (uint32_t) aesrand_getword() & 0xFFFFFFFF; log_debug(LSRC, "no cyclic starting point, " "selected random startpoint: %lld", current); From f30c8df9e558ad96765573d50ff63ba396fe7b96 Mon Sep 17 00:00:00 2001 From: David Adrian Date: Wed, 16 Oct 2013 17:36:40 -0400 Subject: [PATCH 53/53] Remove extranneous printf --- src/cyclic.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cyclic.c b/src/cyclic.c index 912c958..76873c9 100644 --- a/src/cyclic.c +++ b/src/cyclic.c @@ -127,7 +127,6 @@ static uint64_t find_primroot(const cyclic_group_t *group) { // what luck, rand() returns a uint32_t! uint32_t candidate = (uint32_t) aesrand_getword() & 0xFFFFFFFF; - printf("Candidate: %u\n", (unsigned) candidate); while(check_coprime(candidate, group) != COPRIME) { ++candidate; }