From c5d6c1a644ea3710d31d6ccb75dbea93c74a7ffa Mon Sep 17 00:00:00 2001 From: Francis Dupont Date: Wed, 23 Mar 2016 14:50:23 +0100 Subject: [PATCH 1/9] [4268a] Updated rebased doc --- doc/guide/classify.xml | 118 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 104 insertions(+), 14 deletions(-) diff --git a/doc/guide/classify.xml b/doc/guide/classify.xml index fef363ed9b..50a66ee37a 100644 --- a/doc/guide/classify.xml +++ b/doc/guide/classify.xml @@ -152,24 +152,110 @@ Name - Example + Example expression + Example value Description + -String'example'A string -Hex String0XABCDA hexadecimal string -IP Address10.0.0.1An IP address -Integer123An integer value + + String literal + 'example' + 'example' + A string + + + Hexadecimal string literal + 0x5a7d + 'Z}' + A hexadecimal string + + + IP address literal + 10.0.0.1 + 0x0a000001 + An IP address + + + Integer literal + 123 + '123' + An integer value + + + + Binary content of the option + option[123].hex + '(content of the option)' + The value of the option with given code from the + packet as hex + -Option Hexoption[code].hexThe value of the option with code "code" from the packet as hex -Option Existoption[code].existIf the option with code "code" is present in the packet "true" else "false" -DHCPv4 Relay Agent -sub-optionrelay4[code].hexThe value of -sub-option with code "code" from the DHCPv4 Relay Agent Information option -(option 82) + + Option existence + option[123].exist + 'true' + If the option with given code is present in the + packet "true" else "false" + + + DHCPv4 relay agent sub-option + relay4[123].hex + '(content of the RAI sub-option)' + The value of sub-option with given code from the + DHCPv4 Relay Agent Information option (option 82) + + + Hardware address in DHCPv4 packet + pkt4.mac + 0x010203040506 + The value of the chaddr field of the DHCPv4 packet. + + + Hardware length in DHCPv4 packet + pkt4.hlen + 0x06 + The value of the hlen field of the DHCPv4 packet. + + + Hardware type in DHCPv4 packet + pkt4.htype + 0x7b + The value of the htype field of the DHCPv4 packet. + + + ciaddr field in DHCPv4 packet + pkt4.ciaddr + 192.0.2.1 + The value of the ciaddr field of the DHCPv4 packet. + + + giaddr field in DHCPv4 packet + pkt4.giaddr + 192.0.2.1 + The value of the giaddr field of the DHCPv4 packet. + + + yiaddr field in DHCPv4 packet + pkt4.yiaddr + 192.0.2.1 + The value of the yiaddr field of the DHCPv4 packet. + + + siaddr field in DHCPv4 packet + pkt4.siaddr + 192.0.2.1 + The value of the siaddr field of the DHCPv4 packet. + @@ -189,14 +275,14 @@ sub-option with code "code" from the DHCPv4 Relay Agent Information option - "option[code].hex" extracts the value of the option with the given code + "option[code].hex" extracts the value of the option with the code "code" from the incoming packet. If the packet doesn't contain the option, it returns the empty string. The string is presented as a byte string of the option payload without the type code or length fields. - "option[code].exist" checks if an option with the given code is present + "option[code].exist" checks if an option with the code "code" is present in the incoming packet. It can be used with empty options. @@ -215,6 +301,10 @@ sub-option with code "code" from the DHCPv4 Relay Agent Information option instance "relay4[code].exists" is supported. + + Expressions starting with pkt4 can be used only in DHCPv4. + + List of Classification Expressions From 3b5f6d6322a2a881ff60d5ea8ec2015c2ab88b18 Mon Sep 17 00:00:00 2001 From: Francis Dupont Date: Wed, 23 Mar 2016 15:00:20 +0100 Subject: [PATCH 2/9] [4268a] Updated and regenerated rebased parser files --- src/lib/eval/lexer.cc | 514 +++++++++++++++++++++-------------------- src/lib/eval/lexer.ll | 8 + src/lib/eval/parser.cc | 390 +++++++++++++++++++------------ src/lib/eval/parser.h | 225 +++++++++++++----- src/lib/eval/parser.yy | 44 ++++ 5 files changed, 733 insertions(+), 448 deletions(-) diff --git a/src/lib/eval/lexer.cc b/src/lib/eval/lexer.cc index 7cc13ac9a3..85516345a4 100644 --- a/src/lib/eval/lexer.cc +++ b/src/lib/eval/lexer.cc @@ -17,8 +17,8 @@ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 6 -#define YY_FLEX_SUBMINOR_VERSION 0 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 35 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif @@ -72,6 +72,7 @@ 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; @@ -79,6 +80,7 @@ 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 @@ -109,8 +111,6 @@ typedef unsigned int flex_uint32_t; #define UINT32_MAX (4294967295U) #endif -#endif /* ! C99 */ - #endif /* ! FLEXINT_H */ /* %endif */ @@ -185,15 +185,7 @@ typedef unsigned int flex_uint32_t; /* 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. @@ -233,18 +225,11 @@ extern FILE *yyin, *yyout; */ #define YY_LESS_LINENO(n) \ do { \ - int yyl;\ + yy_size_t yyl;\ for ( yyl = n; yyl < yyleng; ++yyl )\ if ( yytext[yyl] == '\n' )\ --yylineno;\ }while(0) - #define YY_LINENO_REWIND_TO(dst) \ - do {\ - const char *p;\ - for ( p = yy_cp-1; p >= (dst); --p)\ - if ( *p == '\n' )\ - --yylineno;\ - }while(0) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ @@ -435,7 +420,7 @@ void yyfree (void * ); /* %% [1.0] yytext/yyin/yyout/yy_state_type/yylineno etc. def's & init go here */ /* Begin user sect3 */ -#define yywrap() (/*CONSTCOND*/1) +#define yywrap(n) 1 #define YY_SKIP_YYWRAP #define FLEX_DEBUG @@ -451,21 +436,13 @@ extern int yylineno; int yylineno = 1; extern char *yytext; -#ifdef yytext_ptr -#undef yytext_ptr -#endif #define yytext_ptr yytext -/* %% [1.5] DFA */ - /* %if-c-only Standard (non-C++) definition */ 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 ); -#if defined(__GNUC__) && __GNUC__ >= 3 -__attribute__((__noreturn__)) -#endif static void yy_fatal_error (yyconst char msg[] ); /* %endif */ @@ -476,15 +453,15 @@ static void yy_fatal_error (yyconst char msg[] ); #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ /* %% [2.0] code to fiddle yytext and yyleng for yymore() goes here \ */\ - yyleng = (size_t) (yy_cp - yy_bp); \ + yyleng = (yy_size_t) (yy_cp - yy_bp); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ /* %% [3.0] code to copy yytext_ptr to yytext[] goes here, if %array \ */\ (yy_c_buf_p) = yy_cp; /* %% [4.0] data tables for the DFA and the user's section 1 definitions go here */ -#define YY_NUM_RULES 27 -#define YY_END_OF_BUFFER 28 +#define YY_NUM_RULES 35 +#define YY_END_OF_BUFFER 36 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -492,41 +469,50 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_acclist[138] = +static yyconst flex_int16_t yy_acclist[190] = { 0, - 28, 26, 27, 1, 26, 27, 2, 27, 26, 27, - 21, 26, 27, 22, 26, 27, 25, 26, 27, 26, - 27, 20, 26, 27, 5, 26, 27, 5, 26, 27, - 26, 27, 26, 27, 26, 27,16390, 26, 27,16390, - 23, 26, 27, 24, 26, 27, 26, 27,16390, 26, - 27,16390, 26, 27,16390, 26, 27,16390, 26, 27, - 16390, 26, 27,16390, 26, 27,16390, 26, 27,16390, - 26, 27,16390, 1, 2, 3, 5, 5, 7, 8, - 16390,16390, 8198,16390,16390,16390,16390,16390,16390,16390, - 19,16390,16390,16390,16390, 4, 7, 15,16390, 18, + 36, 34, 35, 1, 34, 35, 2, 35, 34, 35, + 29, 34, 35, 30, 34, 35, 33, 34, 35, 34, + 35, 28, 34, 35, 5, 34, 35, 5, 34, 35, + 34, 35, 34, 35, 34, 35,16390, 34, 35,16390, + 31, 34, 35, 32, 34, 35, 34, 35,16390, 34, + 35,16390, 34, 35,16390, 34, 35,16390, 34, 35, + 16390, 34, 35,16390, 34, 35,16390, 34, 35,16390, + 34, 35,16390, 34, 35,16390, 34, 35,16390, 34, + 35,16390, 34, 35,16390, 1, 2, 3, 5, 5, + 7, 8,16390,16390, 8198,16390,16390,16390,16390,16390, - 16390,16390,16390, 12,16390, 17,16390,16390,16390,16390, - 16390,16390,16390,16390,16390,16390, 11,16390,16390,16390, - 16390,16390,16390, 16,16390, 13,16390, 9,16390, 10, - 16390,16390, 7,16390,16390, 14,16390 + 16390,16390,16390,16390,16390,16390,16390, 27,16390,16390, + 16390,16390,16390,16390,16390, 4, 7, 23,16390, 26, + 16390,16390,16390,16390,16390, 12,16390,16390,16390, 15, + 16390, 25,16390,16390,16390,16390,16390,16390,16390,16390, + 16390,16390,16390,16390, 16,16390,16390,16390, 14,16390, + 16390,16390,16390, 11,16390,16390,16390,16390,16390,16390, + 17,16390,16390,16390,16390,16390,16390, 18,16390, 24, + 16390, 13,16390, 19,16390, 9,16390, 10,16390, 21, + 16390,16390, 20,16390, 7,16390,16390, 22,16390 } ; -static yyconst flex_int16_t yy_accept[97] = +static yyconst flex_int16_t yy_accept[133] = { 0, 1, 1, 1, 2, 4, 7, 9, 11, 14, 17, 20, 22, 25, 28, 31, 33, 35, 38, 41, 44, 47, 50, 53, 56, 59, 62, 65, 68, 71, 74, - 75, 76, 76, 77, 78, 78, 79, 79, 79, 79, - 79, 80, 81, 81, 81, 82, 83, 84, 85, 86, - 87, 88, 89, 90, 91, 93, 94, 95, 96, 96, - 97, 98, 100, 102, 103, 104, 106, 108, 109, 110, - 111, 112, 112, 113, 114, 115, 116, 117, 119, 119, - 120, 121, 122, 123, 124, 124, 126, 128, 130, 132, - 133, 134, 135, 136, 138, 138 + 77, 80, 83, 86, 87, 88, 88, 89, 90, 90, + 91, 91, 91, 91, 91, 92, 93, 93, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 110, 111, 112, 113, 114, 115, + 116, 116, 117, 118, 120, 122, 123, 124, 125, 126, + 128, 129, 130, 132, 134, 135, 136, 137, 138, 139, + 140, 141, 141, 142, 143, 144, 145, 147, 148, 149, + 151, 152, 153, 154, 156, 157, 157, 158, 159, 160, + 161, 163, 164, 165, 166, 167, 168, 168, 170, 172, + 174, 176, 178, 180, 182, 183, 185, 186, 187, 188, + 190, 190 } ; -static yyconst YY_CHAR yy_ec[256] = +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, @@ -539,9 +525,9 @@ static yyconst YY_CHAR yy_ec[256] = 16, 16, 16, 16, 16, 16, 16, 17, 16, 16, 18, 1, 19, 1, 20, 1, 21, 22, 23, 24, - 25, 15, 26, 27, 28, 16, 16, 29, 16, 30, - 31, 32, 16, 33, 34, 35, 36, 16, 16, 37, - 38, 16, 1, 1, 1, 1, 1, 1, 1, 1, + 25, 15, 26, 27, 28, 16, 29, 30, 31, 32, + 33, 34, 16, 35, 36, 37, 38, 16, 16, 39, + 40, 16, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -558,116 +544,133 @@ static yyconst YY_CHAR yy_ec[256] = 1, 1, 1, 1, 1 } ; -static yyconst YY_CHAR yy_meta[39] = +static yyconst flex_int32_t yy_meta[41] = { 0, 1, 1, 2, 1, 1, 1, 1, 1, 3, 4, 4, 4, 5, 1, 4, 1, 1, 1, 1, 1, 4, 4, 4, 4, 4, 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_uint16_t yy_base[101] = +static yyconst flex_int16_t yy_base[137] = { 0, - 0, 0, 191, 192, 188, 186, 184, 192, 192, 192, - 29, 192, 33, 30, 174, 172, 69, 98, 192, 192, - 22, 154, 147, 158, 151, 27, 156, 144, 154, 176, - 174, 172, 192, 51, 54, 32, 162, 161, 0, 160, - 0, 192, 112, 114, 0, 0, 192, 143, 147, 140, - 141, 131, 132, 131, 0, 136, 142, 126, 64, 0, - 0, 0, 0, 139, 127, 0, 0, 132, 138, 124, - 122, 114, 135, 120, 123, 115, 117, 0, 118, 106, - 98, 88, 100, 54, 124, 0, 0, 0, 0, 55, - 127, 48, 42, 0, 192, 139, 141, 143, 49, 146 + 0, 0, 227, 228, 224, 222, 220, 228, 228, 228, + 31, 228, 35, 32, 210, 208, 73, 104, 228, 228, + 21, 33, 182, 192, 40, 198, 185, 20, 188, 191, + 34, 190, 186, 211, 209, 207, 228, 57, 68, 101, + 197, 196, 0, 195, 0, 228, 118, 120, 0, 0, + 228, 177, 182, 184, 172, 175, 181, 162, 175, 159, + 175, 160, 159, 0, 158, 164, 172, 170, 152, 169, + 121, 0, 0, 0, 0, 165, 165, 151, 162, 0, + 153, 150, 0, 0, 155, 170, 160, 156, 143, 141, + 153, 124, 152, 154, 137, 149, 0, 147, 138, 0, + 130, 145, 131, 0, 143, 132, 131, 128, 128, 128, + 0, 120, 126, 89, 56, 52, 135, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 138, 41, 38, 0, + 228, 150, 152, 154, 59, 157 } ; -static yyconst flex_int16_t yy_def[101] = +static yyconst flex_int16_t yy_def[137] = { 0, - 95, 1, 95, 95, 95, 95, 96, 95, 95, 95, - 95, 95, 95, 13, 97, 95, 95, 17, 95, 95, - 17, 17, 17, 18, 18, 18, 18, 18, 18, 95, - 95, 96, 95, 95, 95, 13, 97, 98, 99, 97, - 100, 95, 95, 18, 17, 18, 95, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 95, 99, - 100, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 95, 18, 18, 18, 18, 18, 18, 95, 18, - 18, 18, 18, 18, 95, 18, 18, 18, 18, 18, - 95, 18, 18, 18, 0, 95, 95, 95, 95, 95 + 131, 1, 131, 131, 131, 131, 132, 131, 131, 131, + 131, 131, 131, 13, 133, 131, 131, 17, 131, 131, + 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 131, 131, 132, 131, 131, 131, 13, + 133, 134, 135, 133, 136, 131, 131, 18, 17, 18, + 131, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 131, 135, 136, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 131, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 131, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 131, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 131, 18, 18, 18, + 0, 131, 131, 131, 131, 131 } ; -static yyconst flex_uint16_t yy_nxt[231] = +static yyconst flex_int16_t yy_nxt[269] = { 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14, 15, 16, 17, 18, 18, 19, 20, 4, - 21, 17, 22, 17, 23, 18, 24, 18, 18, 25, - 26, 18, 27, 28, 29, 18, 18, 18, 34, 34, - 34, 35, 36, 36, 36, 37, 95, 38, 95, 39, - 48, 49, 60, 38, 38, 38, 38, 38, 54, 55, - 34, 34, 34, 59, 59, 59, 95, 94, 95, 39, - 43, 43, 72, 59, 59, 59, 44, 93, 45, 45, - 45, 37, 92, 45, 46, 46, 90, 47, 44, 45, - 45, 45, 45, 45, 46, 46, 46, 46, 46, 46, + 21, 17, 22, 17, 23, 24, 25, 18, 18, 18, + 26, 27, 28, 29, 30, 31, 32, 18, 18, 33, + 38, 38, 38, 39, 40, 40, 40, 41, 131, 42, + 52, 43, 53, 63, 64, 42, 42, 42, 42, 42, + 54, 67, 72, 130, 58, 55, 38, 38, 38, 59, + 131, 68, 129, 43, 47, 47, 60, 71, 71, 71, + 48, 128, 49, 49, 49, 41, 126, 49, 50, 50, + 125, 51, 48, 49, 49, 49, 49, 49, 50, 50, - 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 95, 89, 46, 43, 43, 95, 95, 88, 46, 46, - 46, 46, 46, 79, 79, 79, 85, 79, 79, 79, - 47, 87, 95, 91, 91, 91, 91, 91, 91, 32, - 86, 32, 32, 32, 40, 40, 38, 38, 61, 61, - 61, 84, 83, 82, 81, 80, 78, 77, 76, 75, - 74, 73, 71, 70, 69, 68, 67, 66, 65, 64, - 63, 62, 41, 37, 41, 33, 31, 30, 58, 57, - 56, 53, 52, 51, 50, 42, 41, 33, 31, 30, - 95, 3, 95, 95, 95, 95, 95, 95, 95, 95, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 131, 131, 50, 47, + 47, 131, 131, 124, 50, 50, 50, 50, 50, 92, + 71, 71, 71, 106, 106, 106, 51, 123, 131, 131, + 117, 106, 106, 106, 127, 127, 127, 127, 127, 127, + 36, 122, 36, 36, 36, 44, 44, 42, 42, 73, + 73, 73, 121, 120, 119, 118, 116, 115, 114, 113, + 112, 111, 110, 109, 108, 107, 105, 104, 103, 102, + 101, 100, 99, 98, 97, 96, 95, 94, 93, 91, + 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95 + 80, 79, 78, 77, 76, 75, 74, 45, 41, 45, + 37, 35, 34, 70, 69, 66, 65, 62, 61, 57, + 56, 46, 45, 37, 35, 34, 131, 3, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131 } ; -static yyconst flex_int16_t yy_chk[231] = +static yyconst flex_int16_t yy_chk[269] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 11, 11, - 11, 13, 13, 13, 13, 13, 14, 13, 36, 13, - 21, 21, 99, 13, 13, 13, 13, 13, 26, 26, - 34, 34, 34, 35, 35, 35, 14, 93, 36, 13, - 17, 17, 59, 59, 59, 59, 17, 92, 17, 17, - 17, 17, 90, 17, 17, 17, 84, 17, 17, 17, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 11, 11, 11, 13, 13, 13, 13, 13, 14, 13, + 21, 13, 21, 28, 28, 13, 13, 13, 13, 13, + 22, 31, 135, 129, 25, 22, 38, 38, 38, 25, + 14, 31, 128, 13, 17, 17, 25, 39, 39, 39, + 17, 125, 17, 17, 17, 17, 116, 17, 17, 17, + 115, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 18, 18, 18, 18, 40, 18, 47, + 47, 48, 48, 114, 18, 18, 18, 18, 18, 71, + 71, 71, 71, 92, 92, 92, 47, 113, 48, 40, + 106, 106, 106, 106, 117, 117, 117, 127, 127, 127, + 132, 112, 132, 132, 132, 133, 133, 134, 134, 136, + 136, 136, 110, 109, 108, 107, 105, 103, 102, 101, + 99, 98, 96, 95, 94, 93, 91, 90, 89, 88, + 87, 86, 85, 82, 81, 79, 78, 77, 76, 70, + 69, 68, 67, 66, 65, 63, 62, 61, 60, 59, - 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, - 18, 83, 18, 43, 43, 44, 44, 82, 18, 18, - 18, 18, 18, 72, 72, 72, 79, 79, 79, 79, - 43, 81, 44, 85, 85, 85, 91, 91, 91, 96, - 80, 96, 96, 96, 97, 97, 98, 98, 100, 100, - 100, 77, 76, 75, 74, 73, 71, 70, 69, 68, - 65, 64, 58, 57, 56, 54, 53, 52, 51, 50, - 49, 48, 40, 38, 37, 32, 31, 30, 29, 28, - 27, 25, 24, 23, 22, 16, 15, 7, 6, 5, - 3, 95, 95, 95, 95, 95, 95, 95, 95, 95, - - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95 + 58, 57, 56, 55, 54, 53, 52, 44, 42, 41, + 36, 35, 34, 33, 32, 30, 29, 27, 26, 24, + 23, 16, 15, 7, 6, 5, 3, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131, 131, 131, + 131, 131, 131, 131, 131, 131, 131, 131 } ; /* Table of booleans, true if rule could match eol. */ -static yyconst flex_int32_t yy_rule_can_match_eol[28] = +static yyconst flex_int32_t yy_rule_can_match_eol[36] = { 0, 0, 1, 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, }; extern int yy_flex_debug; int yy_flex_debug = 1; -static yyconst flex_int16_t yy_rule_linenum[27] = +static yyconst flex_int16_t yy_rule_linenum[35] = { 0, 82, 86, 92, 102, 108, 122, 129, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, 159, 160, 162 + 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, + 166, 167, 168, 170 } ; static yy_state_type *yy_state_buf=0, *yy_state_ptr=0; @@ -746,7 +749,7 @@ static isc::eval::location loc; // by moving it ahead by yyleng bytes. yyleng specifies the length of the // currently matched token. #define YY_USER_ACTION loc.columns(yyleng); -#line 750 "lexer.cc" +#line 753 "lexer.cc" #define INITIAL 0 @@ -792,11 +795,11 @@ void yyset_extra (YY_EXTRA_TYPE user_defined ); FILE *yyget_in (void ); -void yyset_in (FILE * _in_str ); +void yyset_in (FILE * in_str ); FILE *yyget_out (void ); -void yyset_out (FILE * _out_str ); +void yyset_out (FILE * out_str ); yy_size_t yyget_leng (void ); @@ -804,7 +807,7 @@ char *yyget_text (void ); int yyget_lineno (void ); -void yyset_lineno (int _line_number ); +void yyset_lineno (int line_number ); /* %if-bison-bridge */ /* %endif */ @@ -823,9 +826,6 @@ extern int yywrap (void ); /* %not-for-header */ -#ifndef YY_NO_UNPUT - -#endif /* %ok-for-header */ /* %endif */ @@ -858,12 +858,7 @@ static int input (void ); /* 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. */ @@ -872,7 +867,7 @@ static int input (void ); /* 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) +#define ECHO fwrite( yytext, yyleng, 1, yyout ) /* %endif */ /* %if-c++-only C++ definition */ /* %endif */ @@ -887,7 +882,7 @@ static int input (void ); if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ - size_t n; \ + yy_size_t n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ @@ -976,7 +971,7 @@ extern int yylex (void); /* Code executed at the end of each rule. */ #ifndef YY_BREAK -#define YY_BREAK /*LINTED*/break; +#define YY_BREAK break; #endif /* %% [6.0] YY_RULE_SETUP definition goes here */ @@ -989,10 +984,21 @@ extern int yylex (void); */ YY_DECL { - yy_state_type yy_current_state; - char *yy_cp, *yy_bp; - int yy_act; + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; +/* %% [7.0] user's declarations go here */ +#line 75 "lexer.ll" + + + + // Code run each time yylex is called. + loc.step(); + + +#line 1001 "lexer.cc" + if ( !(yy_init) ) { (yy_init) = 1; @@ -1033,19 +1039,7 @@ YY_DECL yy_load_buffer_state( ); } - { -/* %% [7.0] user's declarations go here */ -#line 75 "lexer.ll" - - - - // Code run each time yylex is called. - loc.step(); - - -#line 1047 "lexer.cc" - - while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ + while ( 1 ) /* loops until end-of-file is reached */ { /* %% [8.0] yymore()-related code goes here */ yy_cp = (yy_c_buf_p); @@ -1067,23 +1061,24 @@ YY_DECL yy_match: do { - YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*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 >= 96 ) + if ( yy_current_state >= 132 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; *(yy_state_ptr)++ = yy_current_state; ++yy_cp; } - while ( yy_current_state != 95 ); + while ( yy_current_state != 131 ); yy_find_action: /* %% [10.0] code to find the action number goes here */ yy_current_state = *--(yy_state_ptr); (yy_lp) = yy_accept[yy_current_state]; +goto find_rule; /* Shut up GCC warning -Wall */ find_rule: /* we branch to this label when backing up */ for ( ; ; ) /* until we find what rule we matched */ { @@ -1141,13 +1136,13 @@ do_action: /* This label is used only to access EOF actions. */ { if ( yy_act == 0 ) fprintf( stderr, "--scanner backing up\n" ); - else if ( yy_act < 27 ) + else if ( yy_act < 35 ) fprintf( stderr, "--accepting rule at line %ld (\"%s\")\n", (long)yy_rule_linenum[yy_act], yytext ); - else if ( yy_act == 27 ) + else if ( yy_act == 35 ) fprintf( stderr, "--accepting default rule (\"%s\")\n", yytext ); - else if ( yy_act == 28 ) + else if ( yy_act == 36 ) fprintf( stderr, "--(end of buffer or a NUL)\n" ); else fprintf( stderr, "--EOF (start condition %d)\n", YY_START ); @@ -1274,78 +1269,118 @@ return isc::eval::EvalParser::make_EXISTS(loc); case 14: YY_RULE_SETUP #line 149 "lexer.ll" -return isc::eval::EvalParser::make_SUBSTRING(loc); +return isc::eval::EvalParser::make_PKT4(loc); YY_BREAK case 15: YY_RULE_SETUP #line 150 "lexer.ll" -return isc::eval::EvalParser::make_ALL(loc); +return isc::eval::EvalParser::make_CHADDR(loc); YY_BREAK case 16: YY_RULE_SETUP #line 151 "lexer.ll" -return isc::eval::EvalParser::make_CONCAT(loc); +return isc::eval::EvalParser::make_HLEN(loc); YY_BREAK case 17: YY_RULE_SETUP #line 152 "lexer.ll" -return isc::eval::EvalParser::make_NOT(loc); +return isc::eval::EvalParser::make_HTYPE(loc); YY_BREAK case 18: YY_RULE_SETUP #line 153 "lexer.ll" -return isc::eval::EvalParser::make_AND(loc); +return isc::eval::EvalParser::make_CIADDR(loc); YY_BREAK case 19: YY_RULE_SETUP #line 154 "lexer.ll" -return isc::eval::EvalParser::make_OR(loc); +return isc::eval::EvalParser::make_GIADDR(loc); YY_BREAK case 20: YY_RULE_SETUP #line 155 "lexer.ll" -return isc::eval::EvalParser::make_DOT(loc); +return isc::eval::EvalParser::make_YIADDR(loc); YY_BREAK case 21: YY_RULE_SETUP #line 156 "lexer.ll" -return isc::eval::EvalParser::make_LPAREN(loc); +return isc::eval::EvalParser::make_SIADDR(loc); YY_BREAK case 22: YY_RULE_SETUP #line 157 "lexer.ll" -return isc::eval::EvalParser::make_RPAREN(loc); +return isc::eval::EvalParser::make_SUBSTRING(loc); YY_BREAK case 23: YY_RULE_SETUP #line 158 "lexer.ll" -return isc::eval::EvalParser::make_LBRACKET(loc); +return isc::eval::EvalParser::make_ALL(loc); YY_BREAK case 24: YY_RULE_SETUP #line 159 "lexer.ll" -return isc::eval::EvalParser::make_RBRACKET(loc); +return isc::eval::EvalParser::make_CONCAT(loc); YY_BREAK case 25: YY_RULE_SETUP #line 160 "lexer.ll" -return isc::eval::EvalParser::make_COMA(loc); +return isc::eval::EvalParser::make_NOT(loc); YY_BREAK case 26: YY_RULE_SETUP -#line 162 "lexer.ll" -driver.error (loc, "Invalid character: " + std::string(yytext)); - YY_BREAK -case YY_STATE_EOF(INITIAL): -#line 163 "lexer.ll" -return isc::eval::EvalParser::make_END(loc); +#line 161 "lexer.ll" +return isc::eval::EvalParser::make_AND(loc); YY_BREAK case 27: YY_RULE_SETUP +#line 162 "lexer.ll" +return isc::eval::EvalParser::make_OR(loc); + YY_BREAK +case 28: +YY_RULE_SETUP +#line 163 "lexer.ll" +return isc::eval::EvalParser::make_DOT(loc); + YY_BREAK +case 29: +YY_RULE_SETUP #line 164 "lexer.ll" +return isc::eval::EvalParser::make_LPAREN(loc); + YY_BREAK +case 30: +YY_RULE_SETUP +#line 165 "lexer.ll" +return isc::eval::EvalParser::make_RPAREN(loc); + YY_BREAK +case 31: +YY_RULE_SETUP +#line 166 "lexer.ll" +return isc::eval::EvalParser::make_LBRACKET(loc); + YY_BREAK +case 32: +YY_RULE_SETUP +#line 167 "lexer.ll" +return isc::eval::EvalParser::make_RBRACKET(loc); + YY_BREAK +case 33: +YY_RULE_SETUP +#line 168 "lexer.ll" +return isc::eval::EvalParser::make_COMA(loc); + YY_BREAK +case 34: +YY_RULE_SETUP +#line 170 "lexer.ll" +driver.error (loc, "Invalid character: " + std::string(yytext)); + YY_BREAK +case YY_STATE_EOF(INITIAL): +#line 171 "lexer.ll" +return isc::eval::EvalParser::make_END(loc); + YY_BREAK +case 35: +YY_RULE_SETUP +#line 172 "lexer.ll" ECHO; YY_BREAK -#line 1349 "lexer.cc" +#line 1384 "lexer.cc" case YY_END_OF_BUFFER: { @@ -1368,11 +1403,7 @@ ECHO; * back-up) that will match for the new input source. */ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; -/* %if-c-only */ YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; -/* %endif */ -/* %if-c++-only */ -/* %endif */ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } @@ -1479,7 +1510,6 @@ ECHO; "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ - } /* end of user's declarations */ } /* end of yylex */ /* %ok-for-header */ @@ -1503,9 +1533,9 @@ static int yy_get_next_buffer (void) /* %if-c++-only */ /* %endif */ { - char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; - char *source = (yytext_ptr); - yy_size_t number_to_move, i; + 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] ) @@ -1534,7 +1564,7 @@ static int yy_get_next_buffer (void) /* Try to read more data. */ /* First move last chars to start of buffer. */ - number_to_move = (yy_size_t) ((yy_c_buf_p) - (yytext_ptr)) - 1; + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); @@ -1614,8 +1644,8 @@ static int yy_get_next_buffer (void) /* %if-c++-only */ /* %endif */ { - yy_state_type yy_current_state; - char *yy_cp; + register yy_state_type yy_current_state; + register char *yy_cp; /* %% [15.0] code to get the start state into yy_current_state goes here */ yy_current_state = (yy_start); @@ -1626,11 +1656,11 @@ static int yy_get_next_buffer (void) for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) { /* %% [16.0] code to find the next state goes here */ - YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); 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 >= 96 ) + if ( yy_current_state >= 132 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -1651,29 +1681,27 @@ static int yy_get_next_buffer (void) /* %if-c++-only */ /* %endif */ { - int yy_is_jam; + register int yy_is_jam; /* %% [17.0] code to find the next state, and perhaps do backing up, goes here */ - YY_CHAR yy_c = 1; + register YY_CHAR yy_c = 1; 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 >= 96 ) + if ( yy_current_state >= 132 ) 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 == 95); + yy_is_jam = (yy_current_state == 131); if ( ! yy_is_jam ) *(yy_state_ptr)++ = yy_current_state; - return yy_is_jam ? 0 : yy_current_state; + return yy_is_jam ? 0 : yy_current_state; } -#ifndef YY_NO_UNPUT /* %if-c-only */ /* %endif */ -#endif /* %if-c-only */ #ifndef YY_NO_INPUT @@ -1727,7 +1755,7 @@ static int yy_get_next_buffer (void) case EOB_ACT_END_OF_FILE: { if ( yywrap( ) ) - return EOF; + return 0; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; @@ -1783,9 +1811,6 @@ static int yy_get_next_buffer (void) yy_load_buffer_state( ); } -/* %if-c++-only */ -/* %endif */ - /** Switch to a different input buffer. * @param new_buffer The new input buffer. * @@ -1833,11 +1858,7 @@ 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; -/* %if-c-only */ yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; -/* %endif */ -/* %if-c++-only */ -/* %endif */ (yy_hold_char) = *(yy_c_buf_p); } @@ -1859,7 +1880,7 @@ static void yy_load_buffer_state (void) if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - b->yy_buf_size = (yy_size_t)size; + 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. @@ -1875,9 +1896,6 @@ static void yy_load_buffer_state (void) return b; } -/* %if-c++-only */ -/* %endif */ - /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * @@ -1901,6 +1919,17 @@ static void yy_load_buffer_state (void) yyfree((void *) b ); } +/* %if-c-only */ + +#ifndef __cplusplus +extern int isatty (int ); +#endif /* __cplusplus */ + +/* %endif */ + +/* %if-c++-only */ +/* %endif */ + /* 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. @@ -1916,11 +1945,7 @@ static void yy_load_buffer_state (void) yy_flush_buffer(b ); -/* %if-c-only */ b->yy_input_file = file; -/* %endif */ -/* %if-c++-only */ -/* %endif */ b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ @@ -2055,7 +2080,7 @@ static void yyensure_buffer_stack (void) * 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; // After all that talk, this was set to 1 anyways... + num_to_alloc = 1; (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) ); @@ -2072,7 +2097,7 @@ static void yyensure_buffer_stack (void) if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ /* Increase the buffer to prepare for a possible push. */ - yy_size_t grow_size = 8 /* arbitrary grow size */; + int grow_size = 8 /* arbitrary grow size */; num_to_alloc = (yy_buffer_stack_max) + grow_size; (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc @@ -2145,8 +2170,8 @@ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) /* %if-c-only */ /** 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. + * @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. */ @@ -2154,8 +2179,7 @@ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len { YY_BUFFER_STATE b; char *buf; - yy_size_t n; - yy_size_t i; + yy_size_t n, i; /* Get memory for full buffer, including space for trailing EOB's. */ n = _yybytes_len + 2; @@ -2188,7 +2212,7 @@ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len /* %if-c-only */ static void yy_fatal_error (yyconst char* msg ) { - (void) fprintf( stderr, "%s\n", msg ); + (void) fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); } /* %endif */ @@ -2264,29 +2288,29 @@ char *yyget_text (void) /* %endif */ /** Set the current line number. - * @param _line_number line number + * @param line_number * */ -void yyset_lineno (int _line_number ) +void yyset_lineno (int line_number ) { - yylineno = _line_number; + yylineno = line_number; } /** Set the input stream. This does not discard the current * input buffer. - * @param _in_str A readable stream. + * @param in_str A readable stream. * * @see yy_switch_to_buffer */ -void yyset_in (FILE * _in_str ) +void yyset_in (FILE * in_str ) { - yyin = _in_str ; + yyin = in_str ; } -void yyset_out (FILE * _out_str ) +void yyset_out (FILE * out_str ) { - yyout = _out_str ; + yyout = out_str ; } int yyget_debug (void) @@ -2294,9 +2318,9 @@ int yyget_debug (void) return yy_flex_debug; } -void yyset_debug (int _bdebug ) +void yyset_debug (int bdebug ) { - yy_flex_debug = _bdebug ; + yy_flex_debug = bdebug ; } /* %endif */ @@ -2380,8 +2404,7 @@ int yylex_destroy (void) #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) { - - int i; + register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } @@ -2390,7 +2413,7 @@ static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * s ) { - int n; + register int n; for ( n = 0; s[n]; ++n ) ; @@ -2400,12 +2423,11 @@ static int yy_flex_strlen (yyconst char * s ) void *yyalloc (yy_size_t size ) { - return (void *) malloc( 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 @@ -2418,7 +2440,7 @@ void *yyrealloc (void * ptr, yy_size_t size ) void yyfree (void * ptr ) { - free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ + free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ } /* %if-tables-serialization definitions */ @@ -2428,7 +2450,7 @@ void yyfree (void * ptr ) /* %ok-for-header */ -#line 164 "lexer.ll" +#line 172 "lexer.ll" diff --git a/src/lib/eval/lexer.ll b/src/lib/eval/lexer.ll index 18a4b87591..f367d4fbe4 100644 --- a/src/lib/eval/lexer.ll +++ b/src/lib/eval/lexer.ll @@ -146,6 +146,14 @@ addr6 [0-9a-fA-F]*\:[0-9a-fA-F]*\:[0-9a-fA-F:.]* "text" return isc::eval::EvalParser::make_TEXT(loc); "hex" return isc::eval::EvalParser::make_HEX(loc); "exists" return isc::eval::EvalParser::make_EXISTS(loc); +"pkt4" return isc::eval::EvalParser::make_PKT4(loc); +"mac" return isc::eval::EvalParser::make_CHADDR(loc); +"hlen" return isc::eval::EvalParser::make_HLEN(loc); +"htype" return isc::eval::EvalParser::make_HTYPE(loc); +"ciaddr" return isc::eval::EvalParser::make_CIADDR(loc); +"giaddr" return isc::eval::EvalParser::make_GIADDR(loc); +"yiaddr" return isc::eval::EvalParser::make_YIADDR(loc); +"siaddr" return isc::eval::EvalParser::make_SIADDR(loc); "substring" return isc::eval::EvalParser::make_SUBSTRING(loc); "all" return isc::eval::EvalParser::make_ALL(loc); "concat" return isc::eval::EvalParser::make_CONCAT(loc); diff --git a/src/lib/eval/parser.cc b/src/lib/eval/parser.cc index 2887ba9461..520ea3711b 100644 --- a/src/lib/eval/parser.cc +++ b/src/lib/eval/parser.cc @@ -251,19 +251,23 @@ namespace isc { namespace eval { { switch (that.type_get ()) { - case 31: // option_repr_type + case 39: // option_repr_type value.move< TokenOption::RepresentationType > (that.value); break; - case 21: // "constant string" - case 22: // "integer" - case 23: // "constant hexstring" - case 24: // "option name" - case 25: // "ip address" + case 40: // pkt4_field + value.move< TokenPkt4::FieldType > (that.value); + break; + + case 29: // "constant string" + case 30: // "integer" + case 31: // "constant hexstring" + case 32: // "option name" + case 33: // "ip address" value.move< std::string > (that.value); break; - case 30: // option_code + case 38: // option_code value.move< uint16_t > (that.value); break; @@ -282,19 +286,23 @@ namespace isc { namespace eval { state = that.state; switch (that.type_get ()) { - case 31: // option_repr_type + case 39: // option_repr_type value.copy< TokenOption::RepresentationType > (that.value); break; - case 21: // "constant string" - case 22: // "integer" - case 23: // "constant hexstring" - case 24: // "option name" - case 25: // "ip address" + case 40: // pkt4_field + value.copy< TokenPkt4::FieldType > (that.value); + break; + + case 29: // "constant string" + case 30: // "integer" + case 31: // "constant hexstring" + case 32: // "option name" + case 33: // "ip address" value.copy< std::string > (that.value); break; - case 30: // option_code + case 38: // option_code value.copy< uint16_t > (that.value); break; @@ -334,53 +342,60 @@ namespace isc { namespace eval { << yysym.location << ": "; switch (yytype) { - case 21: // "constant string" + case 29: // "constant string" -#line 73 "parser.yy" // lalr1.cc:636 +#line 82 "parser.yy" // lalr1.cc:636 { yyoutput << yysym.value.template as< std::string > (); } -#line 342 "parser.cc" // lalr1.cc:636 +#line 350 "parser.cc" // lalr1.cc:636 break; - case 22: // "integer" + case 30: // "integer" -#line 73 "parser.yy" // lalr1.cc:636 +#line 82 "parser.yy" // lalr1.cc:636 { yyoutput << yysym.value.template as< std::string > (); } -#line 349 "parser.cc" // lalr1.cc:636 +#line 357 "parser.cc" // lalr1.cc:636 break; - case 23: // "constant hexstring" + case 31: // "constant hexstring" -#line 73 "parser.yy" // lalr1.cc:636 +#line 82 "parser.yy" // lalr1.cc:636 { yyoutput << yysym.value.template as< std::string > (); } -#line 356 "parser.cc" // lalr1.cc:636 +#line 364 "parser.cc" // lalr1.cc:636 break; - case 24: // "option name" + case 32: // "option name" -#line 73 "parser.yy" // lalr1.cc:636 +#line 82 "parser.yy" // lalr1.cc:636 { yyoutput << yysym.value.template as< std::string > (); } -#line 363 "parser.cc" // lalr1.cc:636 +#line 371 "parser.cc" // lalr1.cc:636 break; - case 25: // "ip address" + case 33: // "ip address" -#line 73 "parser.yy" // lalr1.cc:636 +#line 82 "parser.yy" // lalr1.cc:636 { yyoutput << yysym.value.template as< std::string > (); } -#line 370 "parser.cc" // lalr1.cc:636 +#line 378 "parser.cc" // lalr1.cc:636 break; - case 30: // option_code + case 38: // option_code -#line 73 "parser.yy" // lalr1.cc:636 +#line 82 "parser.yy" // lalr1.cc:636 { yyoutput << yysym.value.template as< uint16_t > (); } -#line 377 "parser.cc" // lalr1.cc:636 +#line 385 "parser.cc" // lalr1.cc:636 break; - case 31: // option_repr_type + case 39: // option_repr_type -#line 73 "parser.yy" // lalr1.cc:636 +#line 82 "parser.yy" // lalr1.cc:636 { yyoutput << yysym.value.template as< TokenOption::RepresentationType > (); } -#line 384 "parser.cc" // lalr1.cc:636 +#line 392 "parser.cc" // lalr1.cc:636 + break; + + case 40: // pkt4_field + +#line 82 "parser.yy" // lalr1.cc:636 + { yyoutput << yysym.value.template as< TokenPkt4::FieldType > (); } +#line 399 "parser.cc" // lalr1.cc:636 break; @@ -580,19 +595,23 @@ namespace isc { namespace eval { when using variants. */ switch (yyr1_[yyn]) { - case 31: // option_repr_type + case 39: // option_repr_type yylhs.value.build< TokenOption::RepresentationType > (); break; - case 21: // "constant string" - case 22: // "integer" - case 23: // "constant hexstring" - case 24: // "option name" - case 25: // "ip address" + case 40: // pkt4_field + yylhs.value.build< TokenPkt4::FieldType > (); + break; + + case 29: // "constant string" + case 30: // "integer" + case 31: // "constant hexstring" + case 32: // "option name" + case 33: // "ip address" yylhs.value.build< std::string > (); break; - case 30: // option_code + case 38: // option_code yylhs.value.build< uint16_t > (); break; @@ -614,52 +633,52 @@ namespace isc { namespace eval { switch (yyn) { case 4: -#line 87 "parser.yy" // lalr1.cc:859 +#line 96 "parser.yy" // lalr1.cc:859 { TokenPtr neg(new TokenNot()); ctx.expression.push_back(neg); } -#line 623 "parser.cc" // lalr1.cc:859 +#line 642 "parser.cc" // lalr1.cc:859 break; case 5: -#line 92 "parser.yy" // lalr1.cc:859 +#line 101 "parser.yy" // lalr1.cc:859 { TokenPtr neg(new TokenAnd()); ctx.expression.push_back(neg); } -#line 632 "parser.cc" // lalr1.cc:859 +#line 651 "parser.cc" // lalr1.cc:859 break; case 6: -#line 97 "parser.yy" // lalr1.cc:859 +#line 106 "parser.yy" // lalr1.cc:859 { TokenPtr neg(new TokenOr()); ctx.expression.push_back(neg); } -#line 641 "parser.cc" // lalr1.cc:859 +#line 660 "parser.cc" // lalr1.cc:859 break; case 7: -#line 102 "parser.yy" // lalr1.cc:859 +#line 111 "parser.yy" // lalr1.cc:859 { TokenPtr eq(new TokenEqual()); ctx.expression.push_back(eq); } -#line 650 "parser.cc" // lalr1.cc:859 +#line 669 "parser.cc" // lalr1.cc:859 break; case 8: -#line 107 "parser.yy" // lalr1.cc:859 +#line 116 "parser.yy" // lalr1.cc:859 { TokenPtr opt(new TokenOption(yystack_[3].value.as< uint16_t > (), TokenOption::EXISTS)); ctx.expression.push_back(opt); } -#line 659 "parser.cc" // lalr1.cc:859 +#line 678 "parser.cc" // lalr1.cc:859 break; case 9: -#line 112 "parser.yy" // lalr1.cc:859 +#line 121 "parser.yy" // lalr1.cc:859 { switch (ctx.getUniverse()) { case Option::V4: @@ -679,47 +698,47 @@ namespace isc { namespace eval { error(yystack_[5].location, "relay4 can only be used in DHCPv4."); } } -#line 683 "parser.cc" // lalr1.cc:859 +#line 702 "parser.cc" // lalr1.cc:859 break; case 10: -#line 134 "parser.yy" // lalr1.cc:859 +#line 143 "parser.yy" // lalr1.cc:859 { TokenPtr str(new TokenString(yystack_[0].value.as< std::string > ())); ctx.expression.push_back(str); } -#line 692 "parser.cc" // lalr1.cc:859 +#line 711 "parser.cc" // lalr1.cc:859 break; case 11: -#line 139 "parser.yy" // lalr1.cc:859 +#line 148 "parser.yy" // lalr1.cc:859 { TokenPtr hex(new TokenHexString(yystack_[0].value.as< std::string > ())); ctx.expression.push_back(hex); } -#line 701 "parser.cc" // lalr1.cc:859 +#line 720 "parser.cc" // lalr1.cc:859 break; case 12: -#line 144 "parser.yy" // lalr1.cc:859 +#line 153 "parser.yy" // lalr1.cc:859 { TokenPtr ip(new TokenIpAddress(yystack_[0].value.as< std::string > ())); ctx.expression.push_back(ip); } -#line 710 "parser.cc" // lalr1.cc:859 +#line 729 "parser.cc" // lalr1.cc:859 break; case 13: -#line 149 "parser.yy" // lalr1.cc:859 +#line 158 "parser.yy" // lalr1.cc:859 { TokenPtr opt(new TokenOption(yystack_[3].value.as< uint16_t > (), yystack_[0].value.as< TokenOption::RepresentationType > ())); ctx.expression.push_back(opt); } -#line 719 "parser.cc" // lalr1.cc:859 +#line 738 "parser.cc" // lalr1.cc:859 break; case 14: -#line 154 "parser.yy" // lalr1.cc:859 +#line 163 "parser.yy" // lalr1.cc:859 { switch (ctx.getUniverse()) { case Option::V4: @@ -739,88 +758,153 @@ namespace isc { namespace eval { error(yystack_[5].location, "relay4 can only be used in DHCPv4."); } } -#line 743 "parser.cc" // lalr1.cc:859 +#line 762 "parser.cc" // lalr1.cc:859 break; case 15: -#line 174 "parser.yy" // lalr1.cc:859 +#line 183 "parser.yy" // lalr1.cc:859 + { + TokenPtr pkt4field(new TokenPkt4(yystack_[0].value.as< TokenPkt4::FieldType > ())); + ctx.expression.push_back(pkt4field); + } +#line 771 "parser.cc" // lalr1.cc:859 + break; + + case 16: +#line 188 "parser.yy" // lalr1.cc:859 { TokenPtr sub(new TokenSubstring()); ctx.expression.push_back(sub); } -#line 752 "parser.cc" // lalr1.cc:859 +#line 780 "parser.cc" // lalr1.cc:859 break; - case 16: -#line 179 "parser.yy" // lalr1.cc:859 + case 17: +#line 193 "parser.yy" // lalr1.cc:859 { TokenPtr conc(new TokenConcat()); ctx.expression.push_back(conc); } -#line 761 "parser.cc" // lalr1.cc:859 - break; - - case 17: -#line 186 "parser.yy" // lalr1.cc:859 - { - yylhs.value.as< uint16_t > () = ctx.convertOptionCode(yystack_[0].value.as< std::string > (), yystack_[0].location); - } -#line 769 "parser.cc" // lalr1.cc:859 +#line 789 "parser.cc" // lalr1.cc:859 break; case 18: -#line 190 "parser.yy" // lalr1.cc:859 +#line 200 "parser.yy" // lalr1.cc:859 { - yylhs.value.as< uint16_t > () = ctx.convertOptionName(yystack_[0].value.as< std::string > (), yystack_[0].location); + yylhs.value.as< uint16_t > () = ctx.convertOptionCode(yystack_[0].value.as< std::string > (), yystack_[0].location); } -#line 777 "parser.cc" // lalr1.cc:859 +#line 797 "parser.cc" // lalr1.cc:859 break; case 19: -#line 196 "parser.yy" // lalr1.cc:859 +#line 204 "parser.yy" // lalr1.cc:859 { - yylhs.value.as< TokenOption::RepresentationType > () = TokenOption::TEXTUAL; - } -#line 785 "parser.cc" // lalr1.cc:859 + yylhs.value.as< uint16_t > () = ctx.convertOptionName(yystack_[0].value.as< std::string > (), yystack_[0].location); + } +#line 805 "parser.cc" // lalr1.cc:859 break; case 20: -#line 200 "parser.yy" // lalr1.cc:859 +#line 210 "parser.yy" // lalr1.cc:859 { - yylhs.value.as< TokenOption::RepresentationType > () = TokenOption::HEXADECIMAL; + yylhs.value.as< TokenOption::RepresentationType > () = TokenOption::TEXTUAL; } -#line 793 "parser.cc" // lalr1.cc:859 +#line 813 "parser.cc" // lalr1.cc:859 break; case 21: -#line 206 "parser.yy" // lalr1.cc:859 +#line 214 "parser.yy" // lalr1.cc:859 + { + yylhs.value.as< TokenOption::RepresentationType > () = TokenOption::HEXADECIMAL; + } +#line 821 "parser.cc" // lalr1.cc:859 + break; + + case 22: +#line 220 "parser.yy" // lalr1.cc:859 + { + yylhs.value.as< TokenPkt4::FieldType > () = TokenPkt4::CHADDR; + } +#line 829 "parser.cc" // lalr1.cc:859 + break; + + case 23: +#line 224 "parser.yy" // lalr1.cc:859 + { + yylhs.value.as< TokenPkt4::FieldType > () = TokenPkt4::HLEN; + } +#line 837 "parser.cc" // lalr1.cc:859 + break; + + case 24: +#line 228 "parser.yy" // lalr1.cc:859 + { + yylhs.value.as< TokenPkt4::FieldType > () = TokenPkt4::HTYPE; + } +#line 845 "parser.cc" // lalr1.cc:859 + break; + + case 25: +#line 232 "parser.yy" // lalr1.cc:859 + { + yylhs.value.as< TokenPkt4::FieldType > () = TokenPkt4::CIADDR; + } +#line 853 "parser.cc" // lalr1.cc:859 + break; + + case 26: +#line 236 "parser.yy" // lalr1.cc:859 + { + yylhs.value.as< TokenPkt4::FieldType > () = TokenPkt4::GIADDR; + } +#line 861 "parser.cc" // lalr1.cc:859 + break; + + case 27: +#line 240 "parser.yy" // lalr1.cc:859 + { + yylhs.value.as< TokenPkt4::FieldType > () = TokenPkt4::YIADDR; + } +#line 869 "parser.cc" // lalr1.cc:859 + break; + + case 28: +#line 244 "parser.yy" // lalr1.cc:859 + { + yylhs.value.as< TokenPkt4::FieldType > () = TokenPkt4::SIADDR; + } +#line 877 "parser.cc" // lalr1.cc:859 + break; + + case 29: +#line 250 "parser.yy" // lalr1.cc:859 { TokenPtr str(new TokenString(yystack_[0].value.as< std::string > ())); ctx.expression.push_back(str); } -#line 802 "parser.cc" // lalr1.cc:859 +#line 886 "parser.cc" // lalr1.cc:859 break; - case 22: -#line 213 "parser.yy" // lalr1.cc:859 + case 30: +#line 257 "parser.yy" // lalr1.cc:859 { TokenPtr str(new TokenString(yystack_[0].value.as< std::string > ())); ctx.expression.push_back(str); } -#line 811 "parser.cc" // lalr1.cc:859 +#line 895 "parser.cc" // lalr1.cc:859 break; - case 23: -#line 218 "parser.yy" // lalr1.cc:859 + case 31: +#line 262 "parser.yy" // lalr1.cc:859 { TokenPtr str(new TokenString("all")); ctx.expression.push_back(str); } -#line 820 "parser.cc" // lalr1.cc:859 +#line 904 "parser.cc" // lalr1.cc:859 break; -#line 824 "parser.cc" // lalr1.cc:859 +#line 908 "parser.cc" // lalr1.cc:859 default: break; } @@ -1075,96 +1159,103 @@ namespace isc { namespace eval { } - const signed char EvalParser::yypact_ninf_ = -29; + const signed char EvalParser::yypact_ninf_ = -47; const signed char EvalParser::yytable_ninf_ = -1; const signed char EvalParser::yypact_[] = { - -1, -1, -1, 24, 27, 18, 37, -29, -29, -29, - 50, 6, 43, 11, -29, 10, 10, 16, 16, -29, - -1, -1, 16, -29, -29, -29, 40, 41, 44, 45, - 35, 38, -29, 52, -29, 46, 47, 10, 10, 39, - 16, 28, 31, 51, 53, -29, 48, 58, -29, -29, - -29, -29, -29, -29, 55, 56, -15, -29, 34, 34, - -29, -29, 60, -29 + 9, 9, 9, -4, 25, 26, 38, 45, -47, -47, + -47, 50, 23, 52, 4, -47, 29, 29, 34, 18, + 18, -47, 9, 9, 18, -47, -47, -47, 51, 53, + -47, -47, -47, -47, -47, -47, -47, -47, 55, 56, + 35, 37, -47, 62, -47, 57, 58, 29, 29, 39, + 18, 1, 6, 60, 61, -47, 47, 71, -47, -47, + -47, -47, -47, -47, 63, 64, -17, -47, 30, 30, + -47, -47, 74, -47 }; const unsigned char EvalParser::yydefact_[] = { - 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, - 0, 2, 0, 0, 4, 0, 0, 0, 0, 1, - 0, 0, 0, 3, 17, 18, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 10, 11, + 12, 0, 2, 0, 0, 4, 0, 0, 0, 0, + 0, 1, 0, 0, 0, 3, 18, 19, 0, 0, + 22, 23, 24, 25, 26, 27, 28, 15, 0, 0, 0, 0, 5, 6, 7, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 21, 0, 0, 19, 20, - 8, 13, 9, 14, 0, 0, 0, 16, 0, 0, - 23, 22, 0, 15 + 0, 0, 0, 0, 0, 29, 0, 0, 20, 21, + 8, 13, 9, 14, 0, 0, 0, 17, 0, 0, + 31, 30, 0, 16 }; const signed char EvalParser::yypgoto_[] = { - -29, -29, 9, -17, -10, -28, -29, -29 + -47, -47, 2, -19, -15, -46, -47, -47, -47 }; const signed char EvalParser::yydefgoto_[] = { - -1, 10, 11, 12, 26, 51, 46, 62 + -1, 11, 12, 13, 28, 61, 37, 56, 72 }; const unsigned char EvalParser::yytable_[] = { - 30, 31, 1, 60, 2, 34, 27, 61, 3, 4, - 13, 14, 20, 21, 53, 23, 5, 20, 21, 6, - 7, 17, 8, 47, 9, 28, 29, 43, 44, 32, - 33, 53, 24, 5, 25, 15, 6, 7, 16, 8, - 18, 9, 48, 49, 50, 48, 49, 52, 48, 49, - 19, 22, 35, 36, 39, 37, 38, 40, 20, 41, - 42, 45, 57, 54, 63, 55, 0, 56, 58, 59 + 40, 41, 29, 14, 15, 44, 63, 16, 25, 70, + 22, 23, 1, 71, 2, 58, 59, 60, 3, 4, + 58, 59, 62, 63, 42, 43, 5, 38, 39, 22, + 23, 57, 53, 54, 6, 5, 17, 7, 8, 18, + 9, 19, 10, 6, 58, 59, 7, 8, 20, 9, + 21, 10, 30, 31, 32, 33, 34, 35, 36, 26, + 24, 27, 49, 45, 50, 46, 47, 48, 22, 55, + 51, 52, 64, 65, 66, 67, 68, 69, 73 }; - const signed char + const unsigned char EvalParser::yycheck_[] = { - 17, 18, 3, 18, 5, 22, 16, 22, 9, 10, - 1, 2, 6, 7, 42, 4, 17, 6, 7, 20, - 21, 3, 23, 40, 25, 9, 10, 37, 38, 20, - 21, 59, 22, 17, 24, 11, 20, 21, 11, 23, - 3, 25, 14, 15, 16, 14, 15, 16, 14, 15, - 0, 8, 12, 12, 19, 11, 11, 19, 6, 13, - 13, 22, 4, 12, 4, 12, -1, 19, 13, 13 + 19, 20, 17, 1, 2, 24, 52, 11, 4, 26, + 6, 7, 3, 30, 5, 14, 15, 16, 9, 10, + 14, 15, 16, 69, 22, 23, 17, 9, 10, 6, + 7, 50, 47, 48, 25, 17, 11, 28, 29, 13, + 31, 3, 33, 25, 14, 15, 28, 29, 3, 31, + 0, 33, 18, 19, 20, 21, 22, 23, 24, 30, + 8, 32, 27, 12, 27, 12, 11, 11, 6, 30, + 13, 13, 12, 12, 27, 4, 13, 13, 4 }; const unsigned char EvalParser::yystos_[] = { - 0, 3, 5, 9, 10, 17, 20, 21, 23, 25, - 27, 28, 29, 28, 28, 11, 11, 3, 3, 0, - 6, 7, 8, 4, 22, 24, 30, 30, 9, 10, - 29, 29, 28, 28, 29, 12, 12, 11, 11, 19, - 19, 13, 13, 30, 30, 22, 32, 29, 14, 15, - 16, 31, 16, 31, 12, 12, 19, 4, 13, 13, - 18, 22, 33, 4 + 0, 3, 5, 9, 10, 17, 25, 28, 29, 31, + 33, 35, 36, 37, 36, 36, 11, 11, 13, 3, + 3, 0, 6, 7, 8, 4, 30, 32, 38, 38, + 18, 19, 20, 21, 22, 23, 24, 40, 9, 10, + 37, 37, 36, 36, 37, 12, 12, 11, 11, 27, + 27, 13, 13, 38, 38, 30, 41, 37, 14, 15, + 16, 39, 16, 39, 12, 12, 27, 4, 13, 13, + 26, 30, 42, 4 }; const unsigned char EvalParser::yyr1_[] = { - 0, 26, 27, 28, 28, 28, 28, 28, 28, 28, - 29, 29, 29, 29, 29, 29, 29, 30, 30, 31, - 31, 32, 33, 33 + 0, 34, 35, 36, 36, 36, 36, 36, 36, 36, + 37, 37, 37, 37, 37, 37, 37, 37, 38, 38, + 39, 39, 40, 40, 40, 40, 40, 40, 40, 41, + 42, 42 }; const unsigned char EvalParser::yyr2_[] = { 0, 2, 1, 3, 2, 3, 3, 3, 6, 6, - 1, 1, 1, 6, 6, 8, 6, 1, 1, 1, - 1, 1, 1, 1 + 1, 1, 1, 6, 6, 3, 8, 6, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1 }; @@ -1176,20 +1267,23 @@ namespace isc { namespace eval { { "\"end of file\"", "error", "$undefined", "\"(\"", "\")\"", "\"not\"", "\"and\"", "\"or\"", "\"==\"", "\"option\"", "\"relay4\"", "\"[\"", - "\"]\"", "\".\"", "\"text\"", "\"hex\"", "\"exists\"", "\"substring\"", - "\"all\"", "\",\"", "\"concat\"", "\"constant string\"", "\"integer\"", + "\"]\"", "\".\"", "\"text\"", "\"hex\"", "\"exists\"", "\"pkt4\"", + "\"mac\"", "\"hlen\"", "\"htype\"", "\"ciaddr\"", "\"giaddr\"", + "\"yiaddr\"", "\"siaddr\"", "\"substring\"", "\"all\"", "\",\"", + "\"concat\"", "\"constant string\"", "\"integer\"", "\"constant hexstring\"", "\"option name\"", "\"ip address\"", "$accept", "expression", "bool_expr", "string_expr", "option_code", - "option_repr_type", "start_expr", "length_expr", YY_NULLPTR + "option_repr_type", "pkt4_field", "start_expr", "length_expr", YY_NULLPTR }; #if YYDEBUG - const unsigned char + const unsigned short int EvalParser::yyrline_[] = { - 0, 82, 82, 85, 86, 91, 96, 101, 106, 111, - 133, 138, 143, 148, 153, 173, 178, 185, 189, 195, - 199, 205, 212, 217 + 0, 91, 91, 94, 95, 100, 105, 110, 115, 120, + 142, 147, 152, 157, 162, 182, 187, 192, 199, 203, + 209, 213, 219, 223, 227, 231, 235, 239, 243, 249, + 256, 261 }; // Print the state stack on the debug stream. @@ -1224,8 +1318,8 @@ namespace isc { namespace eval { #line 13 "parser.yy" // lalr1.cc:1167 } } // isc::eval -#line 1228 "parser.cc" // lalr1.cc:1167 -#line 224 "parser.yy" // lalr1.cc:1168 +#line 1322 "parser.cc" // lalr1.cc:1167 +#line 268 "parser.yy" // lalr1.cc:1168 void isc::eval::EvalParser::error(const location_type& loc, diff --git a/src/lib/eval/parser.h b/src/lib/eval/parser.h index 0678aeac29..9728780db3 100644 --- a/src/lib/eval/parser.h +++ b/src/lib/eval/parser.h @@ -40,7 +40,7 @@ #ifndef YY_YY_PARSER_H_INCLUDED # define YY_YY_PARSER_H_INCLUDED // // "%code requires" blocks. -#line 16 "parser.yy" // lalr1.cc:377 +#line 16 "parser.yy" // lalr1.cc:392 #include #include @@ -51,7 +51,7 @@ using namespace isc::dhcp; using namespace isc::eval; -#line 55 "parser.h" // lalr1.cc:377 +#line 55 "parser.h" // lalr1.cc:392 # include # include // std::abort @@ -126,9 +126,9 @@ using namespace isc::eval; # define YYDEBUG 1 #endif -#line 13 "parser.yy" // lalr1.cc:377 +#line 13 "parser.yy" // lalr1.cc:392 namespace isc { namespace eval { -#line 132 "parser.h" // lalr1.cc:377 +#line 132 "parser.h" // lalr1.cc:392 @@ -298,15 +298,18 @@ namespace isc { namespace eval { // option_repr_type char dummy1[sizeof(TokenOption::RepresentationType)]; + // pkt4_field + char dummy2[sizeof(TokenPkt4::FieldType)]; + // "constant string" // "integer" // "constant hexstring" // "option name" // "ip address" - char dummy2[sizeof(std::string)]; + char dummy3[sizeof(std::string)]; // option_code - char dummy3[sizeof(uint16_t)]; + char dummy4[sizeof(uint16_t)]; }; /// Symbol semantic values. @@ -344,15 +347,23 @@ namespace isc { namespace eval { TOKEN_TEXT = 269, TOKEN_HEX = 270, TOKEN_EXISTS = 271, - TOKEN_SUBSTRING = 272, - TOKEN_ALL = 273, - TOKEN_COMA = 274, - TOKEN_CONCAT = 275, - TOKEN_STRING = 276, - TOKEN_INTEGER = 277, - TOKEN_HEXSTRING = 278, - TOKEN_OPTION_NAME = 279, - TOKEN_IP_ADDRESS = 280 + TOKEN_PKT4 = 272, + TOKEN_CHADDR = 273, + TOKEN_HLEN = 274, + TOKEN_HTYPE = 275, + TOKEN_CIADDR = 276, + TOKEN_GIADDR = 277, + TOKEN_YIADDR = 278, + TOKEN_SIADDR = 279, + TOKEN_SUBSTRING = 280, + TOKEN_ALL = 281, + TOKEN_COMA = 282, + TOKEN_CONCAT = 283, + TOKEN_STRING = 284, + TOKEN_INTEGER = 285, + TOKEN_HEXSTRING = 286, + TOKEN_OPTION_NAME = 287, + TOKEN_IP_ADDRESS = 288 }; }; @@ -392,6 +403,8 @@ namespace isc { namespace eval { basic_symbol (typename Base::kind_type t, const TokenOption::RepresentationType v, const location_type& l); + basic_symbol (typename Base::kind_type t, const TokenPkt4::FieldType v, const location_type& l); + basic_symbol (typename Base::kind_type t, const std::string v, const location_type& l); basic_symbol (typename Base::kind_type t, const uint16_t v, const location_type& l); @@ -523,6 +536,38 @@ namespace isc { namespace eval { symbol_type make_EXISTS (const location_type& l); + static inline + symbol_type + make_PKT4 (const location_type& l); + + static inline + symbol_type + make_CHADDR (const location_type& l); + + static inline + symbol_type + make_HLEN (const location_type& l); + + static inline + symbol_type + make_HTYPE (const location_type& l); + + static inline + symbol_type + make_CIADDR (const location_type& l); + + static inline + symbol_type + make_GIADDR (const location_type& l); + + static inline + symbol_type + make_YIADDR (const location_type& l); + + static inline + symbol_type + make_SIADDR (const location_type& l); + static inline symbol_type make_SUBSTRING (const location_type& l); @@ -644,7 +689,7 @@ namespace isc { namespace eval { // number is the opposite. If YYTABLE_NINF, syntax error. static const unsigned char yytable_[]; - static const signed char yycheck_[]; + static const unsigned char yycheck_[]; // YYSTOS[STATE-NUM] -- The (internal number of the) accessing // symbol of state STATE-NUM. @@ -665,7 +710,7 @@ namespace isc { namespace eval { static const char* const yytname_[]; #if YYDEBUG // YYRLINE[YYN] -- Source line where rule number YYN was defined. - static const unsigned char yyrline_[]; + static const unsigned short int yyrline_[]; /// Report on the debug stream that the rule \a r is going to be reduced. virtual void yy_reduce_print_ (int r); /// Print the state stack on the debug stream. @@ -764,12 +809,12 @@ namespace isc { namespace eval { enum { yyeof_ = 0, - yylast_ = 69, ///< Last index in yytable_. - yynnts_ = 8, ///< Number of nonterminal symbols. - yyfinal_ = 19, ///< Termination state number. + yylast_ = 78, ///< Last index in yytable_. + yynnts_ = 9, ///< Number of nonterminal symbols. + yyfinal_ = 21, ///< Termination state number. yyterror_ = 1, yyerrcode_ = 256, - yyntokens_ = 26 ///< Number of tokens. + yyntokens_ = 34 ///< Number of tokens. }; @@ -814,9 +859,9 @@ namespace isc { namespace eval { 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25 + 25, 26, 27, 28, 29, 30, 31, 32, 33 }; - const unsigned int user_token_number_max_ = 280; + const unsigned int user_token_number_max_ = 288; const token_number_type undef_token_ = 2; if (static_cast(t) <= yyeof_) @@ -849,19 +894,23 @@ namespace isc { namespace eval { { switch (other.type_get ()) { - case 31: // option_repr_type + case 39: // option_repr_type value.copy< TokenOption::RepresentationType > (other.value); break; - case 21: // "constant string" - case 22: // "integer" - case 23: // "constant hexstring" - case 24: // "option name" - case 25: // "ip address" + case 40: // pkt4_field + value.copy< TokenPkt4::FieldType > (other.value); + break; + + case 29: // "constant string" + case 30: // "integer" + case 31: // "constant hexstring" + case 32: // "option name" + case 33: // "ip address" value.copy< std::string > (other.value); break; - case 30: // option_code + case 38: // option_code value.copy< uint16_t > (other.value); break; @@ -882,19 +931,23 @@ namespace isc { namespace eval { (void) v; switch (this->type_get ()) { - case 31: // option_repr_type + case 39: // option_repr_type value.copy< TokenOption::RepresentationType > (v); break; - case 21: // "constant string" - case 22: // "integer" - case 23: // "constant hexstring" - case 24: // "option name" - case 25: // "ip address" + case 40: // pkt4_field + value.copy< TokenPkt4::FieldType > (v); + break; + + case 29: // "constant string" + case 30: // "integer" + case 31: // "constant hexstring" + case 32: // "option name" + case 33: // "ip address" value.copy< std::string > (v); break; - case 30: // option_code + case 38: // option_code value.copy< uint16_t > (v); break; @@ -920,6 +973,13 @@ namespace isc { namespace eval { , location (l) {} + template + EvalParser::basic_symbol::basic_symbol (typename Base::kind_type t, const TokenPkt4::FieldType v, const location_type& l) + : Base (t) + , value (v) + , location (l) + {} + template EvalParser::basic_symbol::basic_symbol (typename Base::kind_type t, const std::string v, const location_type& l) : Base (t) @@ -960,19 +1020,23 @@ namespace isc { namespace eval { // Type destructor. switch (yytype) { - case 31: // option_repr_type + case 39: // option_repr_type value.template destroy< TokenOption::RepresentationType > (); break; - case 21: // "constant string" - case 22: // "integer" - case 23: // "constant hexstring" - case 24: // "option name" - case 25: // "ip address" + case 40: // pkt4_field + value.template destroy< TokenPkt4::FieldType > (); + break; + + case 29: // "constant string" + case 30: // "integer" + case 31: // "constant hexstring" + case 32: // "option name" + case 33: // "ip address" value.template destroy< std::string > (); break; - case 30: // option_code + case 38: // option_code value.template destroy< uint16_t > (); break; @@ -999,19 +1063,23 @@ namespace isc { namespace eval { super_type::move(s); switch (this->type_get ()) { - case 31: // option_repr_type + case 39: // option_repr_type value.move< TokenOption::RepresentationType > (s.value); break; - case 21: // "constant string" - case 22: // "integer" - case 23: // "constant hexstring" - case 24: // "option name" - case 25: // "ip address" + case 40: // pkt4_field + value.move< TokenPkt4::FieldType > (s.value); + break; + + case 29: // "constant string" + case 30: // "integer" + case 31: // "constant hexstring" + case 32: // "option name" + case 33: // "ip address" value.move< std::string > (s.value); break; - case 30: // option_code + case 38: // option_code value.move< uint16_t > (s.value); break; @@ -1072,7 +1140,8 @@ namespace isc { namespace eval { { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280 + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288 }; return static_cast (yytoken_number_[type]); } @@ -1167,6 +1236,54 @@ namespace isc { namespace eval { return symbol_type (token::TOKEN_EXISTS, l); } + EvalParser::symbol_type + EvalParser::make_PKT4 (const location_type& l) + { + return symbol_type (token::TOKEN_PKT4, l); + } + + EvalParser::symbol_type + EvalParser::make_CHADDR (const location_type& l) + { + return symbol_type (token::TOKEN_CHADDR, l); + } + + EvalParser::symbol_type + EvalParser::make_HLEN (const location_type& l) + { + return symbol_type (token::TOKEN_HLEN, l); + } + + EvalParser::symbol_type + EvalParser::make_HTYPE (const location_type& l) + { + return symbol_type (token::TOKEN_HTYPE, l); + } + + EvalParser::symbol_type + EvalParser::make_CIADDR (const location_type& l) + { + return symbol_type (token::TOKEN_CIADDR, l); + } + + EvalParser::symbol_type + EvalParser::make_GIADDR (const location_type& l) + { + return symbol_type (token::TOKEN_GIADDR, l); + } + + EvalParser::symbol_type + EvalParser::make_YIADDR (const location_type& l) + { + return symbol_type (token::TOKEN_YIADDR, l); + } + + EvalParser::symbol_type + EvalParser::make_SIADDR (const location_type& l) + { + return symbol_type (token::TOKEN_SIADDR, l); + } + EvalParser::symbol_type EvalParser::make_SUBSTRING (const location_type& l) { @@ -1222,9 +1339,9 @@ namespace isc { namespace eval { } -#line 13 "parser.yy" // lalr1.cc:377 +#line 13 "parser.yy" // lalr1.cc:392 } } // isc::eval -#line 1228 "parser.h" // lalr1.cc:377 +#line 1345 "parser.h" // lalr1.cc:392 diff --git a/src/lib/eval/parser.yy b/src/lib/eval/parser.yy index d02002e202..83ab9f148b 100644 --- a/src/lib/eval/parser.yy +++ b/src/lib/eval/parser.yy @@ -51,6 +51,14 @@ using namespace isc::eval; TEXT "text" HEX "hex" EXISTS "exists" + PKT4 "pkt4" + CHADDR "mac" + HLEN "hlen" + HTYPE "htype" + CIADDR "ciaddr" + GIADDR "giaddr" + YIADDR "yiaddr" + SIADDR "siaddr" SUBSTRING "substring" ALL "all" COMA "," @@ -65,6 +73,7 @@ using namespace isc::eval; %type option_code %type option_repr_type +%type pkt4_field %left OR %left AND @@ -170,6 +179,11 @@ string_expr : STRING error(@1, "relay4 can only be used in DHCPv4."); } } + | PKT4 "." pkt4_field + { + TokenPtr pkt4field(new TokenPkt4($3)); + ctx.expression.push_back(pkt4field); + } | SUBSTRING "(" string_expr "," start_expr "," length_expr ")" { TokenPtr sub(new TokenSubstring()); @@ -202,6 +216,36 @@ option_repr_type : TEXT } ; +pkt4_field : CHADDR + { + $$ = TokenPkt4::CHADDR; + } + | HLEN + { + $$ = TokenPkt4::HLEN; + } + | HTYPE + { + $$ = TokenPkt4::HTYPE; + } + | CIADDR + { + $$ = TokenPkt4::CIADDR; + } + | GIADDR + { + $$ = TokenPkt4::GIADDR; + } + | YIADDR + { + $$ = TokenPkt4::YIADDR; + } + | SIADDR + { + $$ = TokenPkt4::SIADDR; + } + ; + start_expr : INTEGER { TokenPtr str(new TokenString($1)); From d92767e4f68a670fae1190061c4af34105733277 Mon Sep 17 00:00:00 2001 From: Francis Dupont Date: Wed, 23 Mar 2016 15:21:42 +0100 Subject: [PATCH 3/9] [4268a] Rebased TokenPkt4 code --- src/lib/eval/tests/context_unittest.cc | 81 ++++++++++++++++++++++++++ src/lib/eval/tests/token_unittest.cc | 79 +++++++++++++++++++++++++ src/lib/eval/token.cc | 64 ++++++++++++++++++++ src/lib/eval/token.h | 55 +++++++++++++++++ 4 files changed, 279 insertions(+) diff --git a/src/lib/eval/tests/context_unittest.cc b/src/lib/eval/tests/context_unittest.cc index 7465bb2df1..7e4ef26f2c 100644 --- a/src/lib/eval/tests/context_unittest.cc +++ b/src/lib/eval/tests/context_unittest.cc @@ -132,6 +132,51 @@ public: } } + /// @brief checks if the given token is Pkt4 of specified type + /// @param token token to be checked + /// @param type expected type of the Pkt4 field + void checkTokenPkt4(const TokenPtr& token, TokenPkt4::FieldType type) { + ASSERT_TRUE(token); + boost::shared_ptr pkt = + boost::dynamic_pointer_cast(token); + ASSERT_TRUE(pkt); + + EXPECT_EQ(type, pkt->getType()); + } + + /// @brief Test that verifies access to the DHCPv4 packet fields. + /// + /// This test attempts to parse the expression, will check if the number + /// of tokens is exactly as expected and then will try to verify if the + /// first token represents the expected field in DHCPv4 packet. + /// + /// @param expr expression to be parsed + /// @param exp_type expected field type to be parsed + /// @param exp_tokens expected number of tokens + void testPkt4Field(std::string expr, + TokenPkt4::FieldType exp_type, + int exp_tokens) { + EvalContext eval(Option::V4); + + // Parse the expression. + try { + parsed_ = eval.parseString(expr); + } + catch (const EvalParseError& ex) { + FAIL() << "Exception thrown: " << ex.what(); + return; + } + + // Parsing should succeed and return a token. + EXPECT_TRUE(parsed_); + + // There should be exactly the expected number of tokens. + ASSERT_EQ(exp_tokens, eval.expression.size()); + + // Check that the first token is TokenPkt4 instance and has correct type. + checkTokenPkt4(eval.expression.at(0), exp_type); + } + /// @brief checks if the given token is a substring operator void checkTokenSubstring(const TokenPtr& token) { ASSERT_TRUE(token); @@ -430,6 +475,41 @@ TEST_F(EvalContextTest, relay4Error) { ":1.1-6: relay4 can only be used in DHCPv4."); } +// Tests whether chaddr field in DHCPv4 can be accessed. +TEST_F(EvalContextTest, pkt4FieldChaddr) { + testPkt4Field("pkt4.mac == 0x000102030405", TokenPkt4::CHADDR, 3); +} + +// Tests whether hlen field in DHCPv4 can be accessed. +TEST_F(EvalContextTest, pkt4FieldHlen) { + testPkt4Field("pkt4.hlen == 0x6", TokenPkt4::HLEN, 3); +} + +// Tests whether htype field in DHCPv4 can be accessed. +TEST_F(EvalContextTest, pkt4FieldHtype) { + testPkt4Field("pkt4.htype == 0x1", TokenPkt4::HTYPE, 3); +} + +// Tests whether ciaddr field in DHCPv4 can be accessed. +TEST_F(EvalContextTest, pkt4FieldCiaddr) { + testPkt4Field("pkt4.ciaddr == 192.0.2.1", TokenPkt4::CIADDR, 3); +} + +// Tests whether giaddr field in DHCPv4 can be accessed. +TEST_F(EvalContextTest, pkt4FieldGiaddr) { + testPkt4Field("pkt4.giaddr == 192.0.2.1", TokenPkt4::GIADDR, 3); +} + +// Tests whether yiaddr field in DHCPv4 can be accessed. +TEST_F(EvalContextTest, pkt4FieldYiaddr) { + testPkt4Field("pkt4.yiaddr == 192.0.2.1", TokenPkt4::YIADDR, 3); +} + +// Tests whether siaddr field in DHCPv4 can be accessed. +TEST_F(EvalContextTest, pkt4FieldSiaddr) { + testPkt4Field("pkt4.siaddr == 192.0.2.1", TokenPkt4::SIADDR, 3); +} + // Test parsing of logical operators TEST_F(EvalContextTest, logicalOps) { // option.exists @@ -588,6 +668,7 @@ TEST_F(EvalContextTest, scanErrors) { checkError("foo", ":1.1: Invalid character: f"); checkError(" bar", ":1.2: Invalid character: b"); checkError("relay[12].hex == 'foo'", ":1.1: Invalid character: r"); + checkError("pkt4.ziaddr", ":1.6: Invalid character: z"); } // Tests some scanner/parser error cases diff --git a/src/lib/eval/tests/token_unittest.cc b/src/lib/eval/tests/token_unittest.cc index 3449281dbd..85a3811ba2 100644 --- a/src/lib/eval/tests/token_unittest.cc +++ b/src/lib/eval/tests/token_unittest.cc @@ -20,6 +20,7 @@ using namespace std; using namespace isc::dhcp; +using namespace isc::asiolink; namespace { @@ -603,6 +604,84 @@ TEST_F(TokenTest, relay4RAIOnly) { EXPECT_EQ("false", values_.top()); } +// Verifies if the DHCPv4 packet fields can be extracted. +TEST_F(TokenTest, pkt4Fields) { + pkt4_->setGiaddr(IOAddress("192.0.2.1")); + pkt4_->setCiaddr(IOAddress("192.0.2.2")); + pkt4_->setYiaddr(IOAddress("192.0.2.3")); + pkt4_->setSiaddr(IOAddress("192.0.2.4")); + + // We're setting hardware address to uncommon (7 bytes rather than 6 and + // hardware type 123) HW address. We'll use it in hlen and htype checks. + HWAddrPtr hw(new HWAddr(HWAddr::fromText("01:02:03:04:05:06:07", 123))); + pkt4_->setHWAddr(hw); + + // Check hardware address field. + ASSERT_NO_THROW(t_.reset(new TokenPkt4(TokenPkt4::CHADDR))); + EXPECT_NO_THROW(t_->evaluate(*pkt4_, values_)); + ASSERT_EQ(1, values_.size()); + uint8_t expected_hw[] = { 1, 2, 3, 4, 5, 6, 7 }; + ASSERT_EQ(7, values_.top().size()); + EXPECT_EQ(0, memcmp(expected_hw, &values_.top()[0], 7)); + + // Check hlen value field. + clearStack(); + ASSERT_NO_THROW(t_.reset(new TokenPkt4(TokenPkt4::HLEN))); + EXPECT_NO_THROW(t_->evaluate(*pkt4_, values_)); + ASSERT_EQ(1, values_.size()); + ASSERT_EQ(1, values_.top().size()); + EXPECT_EQ(7, static_cast(values_.top()[0])); + + // Check htype value. + clearStack(); + ASSERT_NO_THROW(t_.reset(new TokenPkt4(TokenPkt4::HTYPE))); + EXPECT_NO_THROW(t_->evaluate(*pkt4_, values_)); + ASSERT_EQ(1, values_.size()); + ASSERT_EQ(1, values_.top().size()); + EXPECT_EQ(123, static_cast(values_.top()[0])); + + // Check giaddr value. + clearStack(); + ASSERT_NO_THROW(t_.reset(new TokenPkt4(TokenPkt4::GIADDR))); + EXPECT_NO_THROW(t_->evaluate(*pkt4_, values_)); + ASSERT_EQ(1, values_.size()); + uint8_t expected_addr[] = { 192, 0, 2, 1 }; + ASSERT_EQ(4, values_.top().size()); + EXPECT_EQ(0, memcmp(expected_addr, &values_.top()[0], 4)); + + // Check ciaddr value. + clearStack(); + ASSERT_NO_THROW(t_.reset(new TokenPkt4(TokenPkt4::CIADDR))); + EXPECT_NO_THROW(t_->evaluate(*pkt4_, values_)); + ASSERT_EQ(1, values_.size()); + expected_addr[3] = 2; + ASSERT_EQ(4, values_.top().size()); + EXPECT_EQ(0, memcmp(expected_addr, &values_.top()[0], 4)); + + // Check yiaddr value. + clearStack(); + ASSERT_NO_THROW(t_.reset(new TokenPkt4(TokenPkt4::YIADDR))); + EXPECT_NO_THROW(t_->evaluate(*pkt4_, values_)); + ASSERT_EQ(1, values_.size()); + expected_addr[3] = 3; + ASSERT_EQ(4, values_.top().size()); + EXPECT_EQ(0, memcmp(expected_addr, &values_.top()[0], 4)); + + // Check siaddr value. + clearStack(); + ASSERT_NO_THROW(t_.reset(new TokenPkt4(TokenPkt4::SIADDR))); + EXPECT_NO_THROW(t_->evaluate(*pkt4_, values_)); + ASSERT_EQ(1, values_.size()); + expected_addr[3] = 4; + ASSERT_EQ(4, values_.top().size()); + EXPECT_EQ(0, memcmp(expected_addr, &values_.top()[0], 4)); + + // Check a DHCPv6 packet throws. + clearStack(); + ASSERT_NO_THROW(t_.reset(new TokenPkt4(TokenPkt4::HLEN))); + EXPECT_THROW(t_->evaluate(*pkt6_, values_), EvalTypeError); +} + // This test checks if a token representing an == operator is able to // compare two values (with incorrectly built stack). TEST_F(TokenTest, optionEqualInvalid) { diff --git a/src/lib/eval/token.cc b/src/lib/eval/token.cc index fcbdc91057..095fd52380 100644 --- a/src/lib/eval/token.cc +++ b/src/lib/eval/token.cc @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -123,6 +124,69 @@ OptionPtr TokenRelay4Option::getOption(const Pkt& pkt) { return (rai->getOption(option_code_)); } +void +TokenPkt4::evaluate(const Pkt& pkt, ValueStack& values) { + + vector binary; + try { + // Check if it's a Pkt4. If it's not, the dynamic_cast will throw + // std::bad_cast (failed dynamic_cast returns NULL for pointers and + // throws for references). + const Pkt4& pkt4 = dynamic_cast(pkt); + + switch (type_) { + case CHADDR: { + HWAddrPtr hwaddr = pkt4.getHWAddr(); + if (!hwaddr) { + // This should never happen. Every Pkt4 should always have + // a hardware address. + isc_throw(EvalTypeError, + "Packet does not have hardware address"); + } + binary = hwaddr->hwaddr_; + break; + } + case GIADDR: + binary = pkt4.getGiaddr().toBytes(); + break; + + case CIADDR: + binary = pkt4.getCiaddr().toBytes(); + break; + + case YIADDR: + binary = pkt4.getYiaddr().toBytes(); + break; + + case SIADDR: + binary = pkt4.getSiaddr().toBytes(); + break; + + case HLEN: + binary.assign(1, pkt4.getHlen()); + break; + + case HTYPE: + binary.assign(1, pkt4.getHtype()); + break; + + default: + isc_throw(EvalTypeError, "Bad field specified: " + << static_cast(type_) ); + } + + } catch (const std::bad_cast&) { + isc_throw(EvalTypeError, "Specified packet is not a Pkt4"); + } + + string value; + value.resize(binary.size()); + if (!binary.empty()) { + memmove(&value[0], &binary[0], binary.size()); + } + values.push(value); +} + void TokenEqual::evaluate(const Pkt& /*pkt*/, ValueStack& values) { diff --git a/src/lib/eval/token.h b/src/lib/eval/token.h index 4d4ab7a41b..b3c4cedd62 100644 --- a/src/lib/eval/token.h +++ b/src/lib/eval/token.h @@ -288,6 +288,61 @@ protected: virtual OptionPtr getOption(const Pkt& pkt); }; +/// @brief Token that represents fields of a DHCPv4 packet. +/// +/// For example in the expression pkt4.chaddr == 0x0102030405 +/// this token represents the pkt4.chaddr expression. +/// +/// Currently supported fields are: +/// - chaddr (client hardware address, hlen [0..16] octets) +/// - giaddr (relay agent IP address, 4 octets) +/// - ciaddr (client IP address, 4 octets) +/// - yiaddr ('your' (client) IP address, 4 octets) +/// - siaddr (next server IP address, 4 octets) +/// - hlen (hardware address length, 1 octet) +/// - htype (hardware address type, 1 octet) +class TokenPkt4 : public Token { +public: + + /// @brief enum value that determines the field. + enum FieldType { + CHADDR, ///< chaddr field (up to 16 bytes link-layer address) + GIADDR, ///< giaddr (IPv4 address) + CIADDR, ///< ciaddr (IPv4 address) + YIADDR, ///< yiaddr (IPv4 address) + SIADDR, ///< siaddr (IPv4 address) + HLEN, ///< hlen (hardware address length) + HTYPE ///< htype (hardware address type) + }; + + /// @brief Constructor (does nothing) + TokenPkt4(const FieldType type) + : type_(type) {} + + /// @brief Gets a value from the specified packet. + /// + /// Evaluation uses fields available in the packet. It does not require + /// any values to be present on the stack. + /// + /// @throw EvalTypeError when called for DHCPv6 packet + /// + /// @param pkt - fields will be extracted from here + /// @param values - stack of values (1 result will be pushed) + void evaluate(const Pkt& pkt, ValueStack& values); + + /// @brief Returns field type + /// + /// This method is used only in tests. + /// @return type of the field. + FieldType getType() { + return (type_); + } + +private: + /// @brief Specifies field of the DHCPv4 packet + FieldType type_; +}; + /// @brief Token that represents equality operator (compares two other tokens) /// /// For example in the expression option[vendor-class].text == "MSFT" From 18542d6e6e4a6f125945623f3a1db0f3a3094773 Mon Sep 17 00:00:00 2001 From: Francis Dupont Date: Mon, 25 Apr 2016 16:28:20 +0200 Subject: [PATCH 4/9] [4268a] Added extracted field lengthes --- doc/guide/classify.xml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/doc/guide/classify.xml b/doc/guide/classify.xml index 50a66ee37a..291caba0ad 100644 --- a/doc/guide/classify.xml +++ b/doc/guide/classify.xml @@ -218,43 +218,43 @@ Hardware address in DHCPv4 packet pkt4.mac 0x010203040506 - The value of the chaddr field of the DHCPv4 packet. + The value of the chaddr field of the DHCPv4 packet on hlen bytes Hardware length in DHCPv4 packet pkt4.hlen - 0x06 - The value of the hlen field of the DHCPv4 packet. + 0x00000006 + The value of the hlen field of the DHCPv4 packet padded to 4 bytes. Hardware type in DHCPv4 packet pkt4.htype - 0x7b - The value of the htype field of the DHCPv4 packet. + 0x0000007b + The value of the htype field of the DHCPv4 packet padded to 4 bytes. ciaddr field in DHCPv4 packet pkt4.ciaddr 192.0.2.1 - The value of the ciaddr field of the DHCPv4 packet. + The value of the ciaddr field of the DHCPv4 packet (IPv4 address on 4 bytes). giaddr field in DHCPv4 packet pkt4.giaddr 192.0.2.1 - The value of the giaddr field of the DHCPv4 packet. + The value of the giaddr field of the DHCPv4 packet (IPv4 address on 4 bytes). yiaddr field in DHCPv4 packet pkt4.yiaddr 192.0.2.1 - The value of the yiaddr field of the DHCPv4 packet. + The value of the yiaddr field of the DHCPv4 packet (IPv4 address on 4 bytes). siaddr field in DHCPv4 packet pkt4.siaddr 192.0.2.1 - The value of the siaddr field of the DHCPv4 packet. + The value of the siaddr field of the DHCPv4 packet (IPv4 address on 4 bytes). From bc80ce57a5af00ec5a9eaa8e11acdacbafa9f36e Mon Sep 17 00:00:00 2001 From: Francis Dupont Date: Mon, 25 Apr 2016 16:36:10 +0200 Subject: [PATCH 5/9] [4268a] Padded hlen/htype pkt4 --- src/lib/eval/token.cc | 12 ++++++++++-- src/lib/eval/token.h | 4 ++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/lib/eval/token.cc b/src/lib/eval/token.cc index 095fd52380..7745a3da06 100644 --- a/src/lib/eval/token.cc +++ b/src/lib/eval/token.cc @@ -163,11 +163,19 @@ TokenPkt4::evaluate(const Pkt& pkt, ValueStack& values) { break; case HLEN: - binary.assign(1, pkt4.getHlen()); + // Pad the uint8_t field to 4 bytes. + binary.push_back(0); + binary.push_back(0); + binary.push_back(0); + binary.push_back(pkt4.getHlen()); break; case HTYPE: - binary.assign(1, pkt4.getHtype()); + // Pad the uint8_t field to 4 bytes. + binary.push_back(0); + binary.push_back(0); + binary.push_back(0); + binary.push_back(pkt4.getHtype()); break; default: diff --git a/src/lib/eval/token.h b/src/lib/eval/token.h index b3c4cedd62..1df143fe35 100644 --- a/src/lib/eval/token.h +++ b/src/lib/eval/token.h @@ -299,8 +299,8 @@ protected: /// - ciaddr (client IP address, 4 octets) /// - yiaddr ('your' (client) IP address, 4 octets) /// - siaddr (next server IP address, 4 octets) -/// - hlen (hardware address length, 1 octet) -/// - htype (hardware address type, 1 octet) +/// - hlen (hardware address length, padded to 4 octets) +/// - htype (hardware address type, padded to 4 octets) class TokenPkt4 : public Token { public: From f093418dd94701adb6e8049e794b424ca62d80d0 Mon Sep 17 00:00:00 2001 From: Francis Dupont Date: Mon, 25 Apr 2016 16:43:08 +0200 Subject: [PATCH 6/9] [4268a] untabify --- doc/guide/classify.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/guide/classify.xml b/doc/guide/classify.xml index 291caba0ad..f8cd5f7a37 100644 --- a/doc/guide/classify.xml +++ b/doc/guide/classify.xml @@ -183,7 +183,7 @@ '123' An integer value - + Binary content of the option option[123].hex From c8ab56f272726e5130b3a74d76ec8c044631a90a Mon Sep 17 00:00:00 2001 From: Francis Dupont Date: Mon, 25 Apr 2016 16:43:28 +0200 Subject: [PATCH 7/9] [4268a] Updated tests for 4 byte padding --- src/lib/eval/tests/token_unittest.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/lib/eval/tests/token_unittest.cc b/src/lib/eval/tests/token_unittest.cc index 85a3811ba2..c26d2e7025 100644 --- a/src/lib/eval/tests/token_unittest.cc +++ b/src/lib/eval/tests/token_unittest.cc @@ -629,16 +629,18 @@ TEST_F(TokenTest, pkt4Fields) { ASSERT_NO_THROW(t_.reset(new TokenPkt4(TokenPkt4::HLEN))); EXPECT_NO_THROW(t_->evaluate(*pkt4_, values_)); ASSERT_EQ(1, values_.size()); - ASSERT_EQ(1, values_.top().size()); - EXPECT_EQ(7, static_cast(values_.top()[0])); + ASSERT_EQ(4, values_.top().size()); + uint32_t expected_hlen = htonl(7); + EXPECT_EQ(0, memcmp(&expected, &values_.top()[0], 4)); // Check htype value. clearStack(); ASSERT_NO_THROW(t_.reset(new TokenPkt4(TokenPkt4::HTYPE))); EXPECT_NO_THROW(t_->evaluate(*pkt4_, values_)); ASSERT_EQ(1, values_.size()); - ASSERT_EQ(1, values_.top().size()); - EXPECT_EQ(123, static_cast(values_.top()[0])); + ASSERT_EQ(4, values_.top().size()); + uint32_t expected_htype = htonl(123); + EXPECT_EQ(0, memcmp(&expected, &values_.top()[0], 4)); // Check giaddr value. clearStack(); From 777a9979a214196068e8f10a55721814299bc95b Mon Sep 17 00:00:00 2001 From: Francis Dupont Date: Mon, 25 Apr 2016 16:57:39 +0200 Subject: [PATCH 8/9] [4268a] Fixes and cleanups --- doc/guide/classify.xml | 12 ++++++------ src/lib/eval/tests/token_unittest.cc | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/guide/classify.xml b/doc/guide/classify.xml index f8cd5f7a37..e482614f96 100644 --- a/doc/guide/classify.xml +++ b/doc/guide/classify.xml @@ -224,37 +224,37 @@ Hardware length in DHCPv4 packet pkt4.hlen 0x00000006 - The value of the hlen field of the DHCPv4 packet padded to 4 bytes. + The value of the hlen field of the DHCPv4 packet padded to 4 bytes Hardware type in DHCPv4 packet pkt4.htype 0x0000007b - The value of the htype field of the DHCPv4 packet padded to 4 bytes. + The value of the htype field of the DHCPv4 packet padded to 4 bytes ciaddr field in DHCPv4 packet pkt4.ciaddr 192.0.2.1 - The value of the ciaddr field of the DHCPv4 packet (IPv4 address on 4 bytes). + The value of the ciaddr field of the DHCPv4 packet (IPv4 address on 4 bytes) giaddr field in DHCPv4 packet pkt4.giaddr 192.0.2.1 - The value of the giaddr field of the DHCPv4 packet (IPv4 address on 4 bytes). + The value of the giaddr field of the DHCPv4 packet (IPv4 address on 4 bytes) yiaddr field in DHCPv4 packet pkt4.yiaddr 192.0.2.1 - The value of the yiaddr field of the DHCPv4 packet (IPv4 address on 4 bytes). + The value of the yiaddr field of the DHCPv4 packet (IPv4 address on 4 bytes) siaddr field in DHCPv4 packet pkt4.siaddr 192.0.2.1 - The value of the siaddr field of the DHCPv4 packet (IPv4 address on 4 bytes). + The value of the siaddr field of the DHCPv4 packet (IPv4 address on 4 bytes) diff --git a/src/lib/eval/tests/token_unittest.cc b/src/lib/eval/tests/token_unittest.cc index c26d2e7025..2143a015bb 100644 --- a/src/lib/eval/tests/token_unittest.cc +++ b/src/lib/eval/tests/token_unittest.cc @@ -631,7 +631,7 @@ TEST_F(TokenTest, pkt4Fields) { ASSERT_EQ(1, values_.size()); ASSERT_EQ(4, values_.top().size()); uint32_t expected_hlen = htonl(7); - EXPECT_EQ(0, memcmp(&expected, &values_.top()[0], 4)); + EXPECT_EQ(0, memcmp(&expected_hlen, &values_.top()[0], 4)); // Check htype value. clearStack(); @@ -640,7 +640,7 @@ TEST_F(TokenTest, pkt4Fields) { ASSERT_EQ(1, values_.size()); ASSERT_EQ(4, values_.top().size()); uint32_t expected_htype = htonl(123); - EXPECT_EQ(0, memcmp(&expected, &values_.top()[0], 4)); + EXPECT_EQ(0, memcmp(&expected_htype, &values_.top()[0], 4)); // Check giaddr value. clearStack(); From 0b30f90dd6ccfbdf350cbce239e38e30bca4a2b8 Mon Sep 17 00:00:00 2001 From: Shawn Routhier Date: Mon, 25 Apr 2016 22:39:03 -0700 Subject: [PATCH 9/9] [trac4268] Tidy up some documentation strings --- doc/guide/classify.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/guide/classify.xml b/doc/guide/classify.xml index e482614f96..acd208fb36 100644 --- a/doc/guide/classify.xml +++ b/doc/guide/classify.xml @@ -218,7 +218,7 @@ Hardware address in DHCPv4 packet pkt4.mac 0x010203040506 - The value of the chaddr field of the DHCPv4 packet on hlen bytes + The value of the chaddr field of the DHCPv4 packet, hlen (0 to 16) bytes Hardware length in DHCPv4 packet @@ -236,25 +236,25 @@ ciaddr field in DHCPv4 packet pkt4.ciaddr 192.0.2.1 - The value of the ciaddr field of the DHCPv4 packet (IPv4 address on 4 bytes) + The value of the ciaddr field of the DHCPv4 packet (IPv4 address, 4 bytes) giaddr field in DHCPv4 packet pkt4.giaddr 192.0.2.1 - The value of the giaddr field of the DHCPv4 packet (IPv4 address on 4 bytes) + The value of the giaddr field of the DHCPv4 packet (IPv4 address, 4 bytes) yiaddr field in DHCPv4 packet pkt4.yiaddr 192.0.2.1 - The value of the yiaddr field of the DHCPv4 packet (IPv4 address on 4 bytes) + The value of the yiaddr field of the DHCPv4 packet (IPv4 address, 4 bytes) siaddr field in DHCPv4 packet pkt4.siaddr 192.0.2.1 - The value of the siaddr field of the DHCPv4 packet (IPv4 address on 4 bytes) + The value of the siaddr field of the DHCPv4 packet (IPv4 address, 4 bytes)