diff --git a/ChangeLog b/ChangeLog index 7c2341d9c8..5f926a817d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +1107. [func] fdupont + Added support for extracting constant length fields from a DHCPv4 + packet. + (Trac #4268, git xxx) + 1106. [func] sar Added support for accessing DHCPv6 packet fields message type and transaction id in a classification expression. diff --git a/doc/guide/classify.xml b/doc/guide/classify.xml index 76c310641b..ba746272f5 100644 --- a/doc/guide/classify.xml +++ b/doc/guide/classify.xml @@ -152,56 +152,145 @@ 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) - - DHCPv6 Relay Options - relay6[nest].option[code].hex - - The value of the option with code "code" from the relay encapsulation "nest" - - - DHCPv6 Relay Peer Address - relay6[nest].peeraddr -n - The value of the peer address field from the relay encapsulation "nest" - - - DHCPv6 Relay Link Address - relay6[nest].linkaddr -n - The value of the link address field from the relay encapsulation "nest" - - - Message Type in DHCPv6 packet - pkt6.msgtype - - The value of the message type field in the DHCPv6 packet. - - - Transaction ID in DHCPv6 packet - pkt6.transid - - The value of the transaction id in the DHCPv6 packet. - + + 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) + + + DHCPv6 Relay Options + relay6[nest].option[code].hex + + The value of the option with code "code" from the + relay encapsulation "nest" + + + DHCPv6 Relay Peer Address + relay6[nest].peeraddr + n + The value of the peer address field from the + relay encapsulation "nest" + + + DHCPv6 Relay Link Address + relay6[nest].linkaddr + n + The value of the link address field from the + relay encapsulation "nest" + + + Hardware address in DHCPv4 packet + pkt4.mac + 0x010203040506 + The value of the chaddr field of the DHCPv4 packet, hlen (0 to 16) bytes + + + Hardware length in DHCPv4 packet + pkt4.hlen + 0x00000006 + 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 + + + ciaddr field in DHCPv4 packet + pkt4.ciaddr + 192.0.2.1 + 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, 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, 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, 4 bytes) + + + Message Type in DHCPv6 packet + pkt6.msgtype + + The value of the message type field in the DHCPv6 + packet. + + + Transaction ID in DHCPv6 packet + pkt6.transid + + The value of the transaction id in the DHCPv6 + packet. + @@ -221,14 +310,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. @@ -261,6 +350,10 @@ sub-option with code "code" from the DHCPv4 Relay Agent Information option "option", for instance "relay6[nest].option[code].exists" is supported. + + Expressions starting with pkt4 can be used only in DHCPv4. + + "pkt6" refers to information from the client request. To access any information from an intermediate relay use "relay6". "pkt6.msgtype" diff --git a/src/lib/eval/lexer.cc b/src/lib/eval/lexer.cc index 02ea9fa388..20bdad15b9 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 33 -#define YY_END_OF_BUFFER 34 +#define YY_NUM_RULES 41 +#define YY_END_OF_BUFFER 42 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -492,49 +469,58 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_acclist[183] = +static yyconst flex_int16_t yy_acclist[227] = { 0, - 34, 32, 33, 1, 32, 33, 2, 33, 32, 33, - 24, 32, 33, 25, 32, 33, 28, 32, 33, 32, - 33, 23, 32, 33, 5, 32, 33, 5, 32, 33, - 32, 33, 32, 33, 32, 33,16390, 32, 33,16390, - 26, 32, 33, 27, 32, 33, 32, 33,16390, 32, - 33,16390, 32, 33,16390, 32, 33,16390, 32, 33, - 16390, 32, 33,16390, 32, 33,16390, 32, 33,16390, - 32, 33,16390, 32, 33,16390, 32, 33,16390, 32, - 33,16390, 1, 2, 3, 5, 5, 7, 8,16390, - 16390, 8198,16390,16390,16390,16390,16390,16390,16390,16390, + 42, 40, 41, 1, 40, 41, 2, 41, 40, 41, + 32, 40, 41, 33, 40, 41, 36, 40, 41, 40, + 41, 31, 40, 41, 5, 40, 41, 5, 40, 41, + 40, 41, 40, 41, 40, 41,16390, 40, 41,16390, + 34, 40, 41, 35, 40, 41, 40, 41,16390, 40, + 41,16390, 40, 41,16390, 40, 41,16390, 40, 41, + 16390, 40, 41,16390, 40, 41,16390, 40, 41,16390, + 40, 41,16390, 40, 41,16390, 40, 41,16390, 40, + 41,16390, 40, 41,16390, 40, 41,16390, 1, 2, + 3, 5, 5, 7, 8,16390,16390, 8198,16390,16390, - 16390, 22,16390,16390,16390,16390,16390,16390,16390, 4, - 7, 18,16390, 21,16390,16390,16390, 15,16390,16390, - 16390, 20,16390,16390,16390,16390,16390,16390,16390,16390, - 16390,16390,16390,16390,16390,16390, 29,16390,16390,16390, - 14,16390,16390,16390,16390,16390,16390,16390,16390,16390, - 16390,16390, 19,16390, 16,16390,16390,16390, 9,16390, - 16390, 10,16390, 11,16390,16390,16390, 7,16390, 30, - 16390,16390,16390, 31,16390, 13,16390, 12,16390,16390, - 17,16390 + 16390,16390,16390,16390,16390,16390,16390,16390,16390,16390, + 16390,16390, 30,16390,16390,16390,16390,16390,16390,16390, + 16390,16390, 4, 7, 26,16390, 29,16390,16390,16390, + 16390,16390, 15,16390,16390,16390,16390, 18,16390,16390, + 28,16390,16390,16390,16390,16390,16390,16390,16390,16390, + 16390,16390,16390,16390,16390, 19,16390,16390,16390,16390, + 16390,16390, 17,16390, 37,16390,16390,16390,16390, 14, + 16390,16390,16390,16390,16390,16390,16390, 20,16390,16390, + 16390,16390,16390,16390,16390,16390,16390,16390, 21,16390, + 27,16390, 16,16390, 22,16390,16390,16390, 9,16390, + + 16390, 10,16390, 11,16390, 24,16390,16390,16390, 23, + 16390, 7,16390, 38,16390,16390,16390, 39,16390, 13, + 16390, 12,16390,16390, 25,16390 } ; -static yyconst flex_int16_t yy_accept[130] = +static yyconst flex_int16_t yy_accept[162] = { 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, - 77, 80, 83, 84, 85, 85, 86, 87, 87, 88, - 88, 88, 88, 88, 89, 90, 90, 90, 91, 92, - 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, - 104, 105, 106, 107, 108, 109, 110, 110, 111, 112, - 114, 116, 117, 118, 120, 121, 122, 124, 125, 126, - 127, 128, 129, 130, 131, 131, 132, 133, 134, 135, - 136, 137, 139, 140, 141, 143, 144, 144, 145, 146, + 77, 80, 83, 86, 89, 90, 91, 91, 92, 93, + 93, 94, 94, 94, 94, 94, 95, 96, 96, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 115, 116, 117, + 118, 119, 120, 121, 122, 123, 123, 124, 125, 127, + 129, 130, 131, 132, 133, 135, 136, 137, 138, 140, + 141, 143, 144, 145, 146, 147, 148, 149, 150, 151, - 147, 148, 149, 150, 151, 152, 153, 153, 155, 157, - 158, 159, 161, 162, 164, 166, 167, 168, 169, 170, - 172, 173, 174, 176, 178, 180, 181, 183, 183 + 152, 152, 153, 154, 155, 156, 158, 159, 160, 161, + 162, 163, 165, 167, 168, 169, 170, 172, 173, 174, + 174, 175, 176, 177, 178, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 189, 191, 193, 195, 197, + 198, 199, 201, 202, 204, 206, 208, 209, 210, 212, + 213, 214, 216, 217, 218, 220, 222, 224, 225, 227, + 227 } ; -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, @@ -566,7 +552,7 @@ static yyconst YY_CHAR yy_ec[256] = 1, 1, 1, 1, 1 } ; -static yyconst YY_CHAR yy_meta[42] = +static yyconst flex_int32_t yy_meta[42] = { 0, 1, 1, 2, 1, 1, 1, 1, 1, 3, 4, 4, 4, 4, 5, 1, 4, 1, 1, 1, 1, @@ -575,127 +561,142 @@ static yyconst YY_CHAR yy_meta[42] = 1 } ; -static yyconst flex_uint16_t yy_base[134] = +static yyconst flex_int16_t yy_base[166] = { 0, - 0, 0, 237, 238, 234, 232, 230, 238, 238, 238, - 32, 238, 37, 34, 219, 217, 76, 108, 238, 238, - 23, 197, 190, 203, 199, 190, 192, 22, 38, 199, - 185, 39, 221, 219, 217, 238, 59, 70, 55, 206, - 205, 0, 204, 0, 238, 123, 125, 0, 0, 238, - 186, 191, 182, 185, 173, 179, 184, 172, 171, 0, - 182, 169, 175, 182, 164, 181, 126, 0, 0, 0, - 0, 178, 164, 0, 170, 161, 0, 169, 161, 183, - 173, 157, 155, 159, 136, 169, 152, 167, 147, 153, - 164, 0, 144, 146, 0, 146, 141, 144, 144, 155, + 0, 0, 267, 268, 264, 262, 260, 268, 268, 268, + 32, 268, 37, 34, 249, 247, 76, 108, 268, 268, + 23, 35, 221, 231, 42, 230, 35, 224, 30, 41, + 231, 46, 55, 227, 253, 251, 249, 268, 115, 125, + 105, 238, 237, 0, 236, 0, 268, 137, 139, 0, + 0, 268, 218, 223, 225, 213, 216, 222, 203, 216, + 200, 207, 215, 211, 199, 198, 0, 209, 196, 202, + 210, 208, 190, 207, 206, 137, 0, 0, 0, 0, + 202, 202, 188, 199, 0, 190, 187, 191, 0, 182, + 0, 190, 182, 70, 195, 191, 178, 176, 180, 187, - 144, 145, 152, 54, 140, 146, 145, 0, 0, 139, - 118, 0, 117, 0, 0, 112, 115, 149, 93, 0, - 87, 58, 0, 0, 0, 58, 0, 238, 162, 164, - 166, 72, 169 + 141, 186, 188, 171, 183, 0, 181, 184, 164, 170, + 181, 0, 0, 161, 176, 162, 0, 162, 173, 151, + 161, 158, 158, 158, 0, 168, 157, 158, 165, 131, + 153, 152, 158, 150, 155, 0, 0, 0, 0, 160, + 148, 0, 133, 0, 0, 0, 127, 130, 0, 159, + 93, 0, 59, 43, 0, 0, 0, 43, 0, 268, + 172, 174, 176, 54, 179 } ; -static yyconst flex_int16_t yy_def[134] = +static yyconst flex_int16_t yy_def[166] = { 0, - 128, 1, 128, 128, 128, 128, 129, 128, 128, 128, - 128, 128, 128, 13, 130, 128, 128, 17, 128, 128, + 160, 1, 160, 160, 160, 160, 161, 160, 160, 160, + 160, 160, 160, 13, 162, 160, 160, 17, 160, 160, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 128, 128, 129, 128, 128, 128, 13, 130, - 131, 132, 130, 133, 128, 128, 18, 17, 18, 128, + 18, 18, 18, 18, 160, 160, 161, 160, 160, 160, + 13, 162, 163, 164, 162, 165, 160, 160, 18, 17, + 18, 160, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 160, 164, 165, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 128, 132, 133, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 128, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 128, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 128, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 128, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 0, 128, 128, - 128, 128, 128 + 160, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 160, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 160, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 160, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, + 160, 160, 160, 160, 160 } ; -static yyconst flex_uint16_t yy_nxt[280] = +static yyconst flex_int16_t yy_nxt[310] = { 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14, 14, 15, 16, 17, 18, 18, 19, 20, - 4, 21, 17, 22, 17, 23, 18, 24, 18, 18, - 25, 26, 27, 28, 29, 30, 31, 32, 18, 18, - 18, 37, 37, 37, 37, 38, 39, 39, 39, 39, - 40, 128, 41, 51, 42, 52, 59, 60, 41, 41, - 41, 41, 41, 61, 65, 114, 115, 62, 37, 37, - 37, 37, 128, 128, 66, 68, 42, 46, 46, 67, - 67, 67, 67, 47, 127, 48, 48, 48, 48, 40, - 126, 48, 49, 49, 128, 50, 47, 48, 48, 48, + 4, 21, 17, 22, 17, 23, 24, 25, 18, 18, + 26, 27, 28, 29, 30, 31, 32, 33, 18, 18, + 34, 39, 39, 39, 39, 40, 41, 41, 41, 41, + 42, 160, 43, 53, 44, 54, 63, 77, 43, 43, + 43, 43, 43, 55, 66, 67, 68, 59, 56, 159, + 69, 64, 60, 160, 71, 158, 44, 48, 48, 61, + 73, 112, 113, 49, 72, 50, 50, 50, 50, 42, + 74, 50, 51, 51, 157, 52, 49, 50, 50, 50, - 48, 48, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, - 49, 128, 125, 49, 46, 46, 128, 128, 124, 49, - 49, 49, 49, 49, 85, 67, 67, 67, 67, 123, - 122, 121, 50, 120, 128, 97, 97, 97, 97, 107, - 97, 97, 97, 97, 118, 118, 118, 118, 118, 118, - 118, 118, 35, 119, 35, 35, 35, 43, 43, 41, - 41, 69, 69, 69, 117, 116, 113, 112, 111, 110, - 109, 108, 106, 105, 104, 103, 102, 101, 100, 99, - 98, 96, 95, 94, 93, 92, 91, 90, 89, 88, + 50, 50, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 160, 160, 51, 39, 39, 39, 39, 156, 51, + 51, 51, 51, 51, 76, 76, 76, 76, 48, 48, + 160, 160, 144, 145, 160, 101, 76, 76, 76, 76, + 120, 120, 120, 120, 155, 154, 52, 153, 160, 135, + 120, 120, 120, 120, 150, 150, 150, 150, 150, 150, + 150, 150, 37, 152, 37, 37, 37, 45, 45, 43, + 43, 78, 78, 78, 151, 149, 148, 147, 146, 143, + 142, 141, 140, 139, 138, 137, 136, 134, 133, 132, - 87, 86, 84, 83, 82, 81, 80, 79, 78, 77, - 76, 75, 74, 73, 72, 71, 70, 44, 40, 44, - 36, 34, 33, 64, 63, 58, 57, 56, 55, 54, - 53, 45, 44, 36, 34, 33, 128, 3, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128 + 131, 130, 129, 128, 127, 126, 125, 124, 123, 122, + 121, 119, 118, 117, 116, 115, 114, 111, 110, 109, + 108, 107, 106, 105, 104, 103, 102, 100, 99, 98, + 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, + 87, 86, 85, 84, 83, 82, 81, 80, 79, 46, + 42, 46, 38, 36, 35, 75, 70, 65, 62, 58, + 57, 47, 46, 38, 36, 35, 160, 3, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, + + 160, 160, 160, 160, 160, 160, 160, 160, 160 } ; -static yyconst flex_int16_t yy_chk[280] = +static yyconst flex_int16_t yy_chk[310] = { 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, 1, 1, 1, 11, 11, 11, 11, 13, 13, 13, 13, 13, - 13, 14, 13, 21, 13, 21, 28, 28, 13, 13, - 13, 13, 13, 29, 32, 104, 104, 29, 37, 37, - 37, 37, 39, 14, 32, 132, 13, 17, 17, 38, - 38, 38, 38, 17, 126, 17, 17, 17, 17, 17, - 122, 17, 17, 17, 39, 17, 17, 17, 17, 17, + 13, 14, 13, 21, 13, 21, 27, 164, 13, 13, + 13, 13, 13, 22, 29, 29, 30, 25, 22, 158, + 30, 27, 25, 14, 32, 154, 13, 17, 17, 25, + 33, 94, 94, 17, 32, 17, 17, 17, 17, 17, + 33, 17, 17, 17, 153, 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, 18, 121, 18, 46, 46, 47, 47, 119, 18, - 18, 18, 18, 18, 67, 67, 67, 67, 67, 117, - 116, 113, 46, 111, 47, 85, 85, 85, 85, 97, - 97, 97, 97, 97, 107, 107, 107, 107, 118, 118, - 118, 118, 129, 110, 129, 129, 129, 130, 130, 131, - 131, 133, 133, 133, 106, 105, 103, 102, 101, 100, - 99, 98, 96, 94, 93, 91, 90, 89, 88, 87, - 86, 84, 83, 82, 81, 80, 79, 78, 76, 75, + 18, 18, 41, 18, 39, 39, 39, 39, 151, 18, + 18, 18, 18, 18, 40, 40, 40, 40, 48, 48, + 49, 49, 130, 130, 41, 76, 76, 76, 76, 76, + 101, 101, 101, 101, 148, 147, 48, 143, 49, 120, + 120, 120, 120, 120, 135, 135, 135, 135, 150, 150, + 150, 150, 161, 141, 161, 161, 161, 162, 162, 163, + 163, 165, 165, 165, 140, 134, 133, 132, 131, 129, + 128, 127, 126, 124, 123, 122, 121, 119, 118, 116, - 73, 72, 66, 65, 64, 63, 62, 61, 59, 58, - 57, 56, 55, 54, 53, 52, 51, 43, 41, 40, - 35, 34, 33, 31, 30, 27, 26, 25, 24, 23, - 22, 16, 15, 7, 6, 5, 3, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, 128 + 115, 114, 111, 110, 109, 108, 107, 105, 104, 103, + 102, 100, 99, 98, 97, 96, 95, 93, 92, 90, + 88, 87, 86, 84, 83, 82, 81, 75, 74, 73, + 72, 71, 70, 69, 68, 66, 65, 64, 63, 62, + 61, 60, 59, 58, 57, 56, 55, 54, 53, 45, + 43, 42, 37, 36, 35, 34, 31, 28, 26, 24, + 23, 16, 15, 7, 6, 5, 3, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, + + 160, 160, 160, 160, 160, 160, 160, 160, 160 } ; /* Table of booleans, true if rule could match eol. */ -static yyconst flex_int32_t yy_rule_can_match_eol[34] = +static yyconst flex_int32_t yy_rule_can_match_eol[42] = { 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, 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[33] = +static yyconst flex_int16_t yy_rule_linenum[41] = { 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, 161, 162, 163, 165, 166, - 167, 169 + 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, + 166, 167, 168, 169, 170, 171, 173, 174, 175, 177 } ; static yy_state_type *yy_state_buf=0, *yy_state_ptr=0; @@ -774,7 +775,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 778 "lexer.cc" +#line 779 "lexer.cc" #define INITIAL 0 @@ -820,11 +821,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 ); @@ -832,7 +833,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 */ @@ -851,9 +852,6 @@ extern int yywrap (void ); /* %not-for-header */ -#ifndef YY_NO_UNPUT - -#endif /* %ok-for-header */ /* %endif */ @@ -886,12 +884,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. */ @@ -900,7 +893,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 */ @@ -915,7 +908,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; \ @@ -1004,7 +997,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 */ @@ -1017,10 +1010,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 1027 "lexer.cc" + if ( !(yy_init) ) { (yy_init) = 1; @@ -1061,19 +1065,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 1075 "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); @@ -1095,23 +1087,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 >= 129 ) + if ( yy_current_state >= 161 ) 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 != 128 ); + while ( yy_current_state != 160 ); 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 */ { @@ -1169,13 +1162,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 < 33 ) + else if ( yy_act < 41 ) fprintf( stderr, "--accepting rule at line %ld (\"%s\")\n", (long)yy_rule_linenum[yy_act], yytext ); - else if ( yy_act == 33 ) + else if ( yy_act == 41 ) fprintf( stderr, "--accepting default rule (\"%s\")\n", yytext ); - else if ( yy_act == 34 ) + else if ( yy_act == 42 ) fprintf( stderr, "--(end of buffer or a NUL)\n" ); else fprintf( stderr, "--EOF (start condition %d)\n", YY_START ); @@ -1317,93 +1310,133 @@ return isc::eval::EvalParser::make_EXISTS(loc); case 17: YY_RULE_SETUP #line 152 "lexer.ll" -return isc::eval::EvalParser::make_SUBSTRING(loc); +return isc::eval::EvalParser::make_PKT4(loc); YY_BREAK case 18: YY_RULE_SETUP #line 153 "lexer.ll" -return isc::eval::EvalParser::make_ALL(loc); +return isc::eval::EvalParser::make_CHADDR(loc); YY_BREAK case 19: YY_RULE_SETUP #line 154 "lexer.ll" -return isc::eval::EvalParser::make_CONCAT(loc); +return isc::eval::EvalParser::make_HLEN(loc); YY_BREAK case 20: YY_RULE_SETUP #line 155 "lexer.ll" -return isc::eval::EvalParser::make_NOT(loc); +return isc::eval::EvalParser::make_HTYPE(loc); YY_BREAK case 21: YY_RULE_SETUP #line 156 "lexer.ll" -return isc::eval::EvalParser::make_AND(loc); +return isc::eval::EvalParser::make_CIADDR(loc); YY_BREAK case 22: YY_RULE_SETUP #line 157 "lexer.ll" -return isc::eval::EvalParser::make_OR(loc); +return isc::eval::EvalParser::make_GIADDR(loc); YY_BREAK case 23: YY_RULE_SETUP #line 158 "lexer.ll" -return isc::eval::EvalParser::make_DOT(loc); +return isc::eval::EvalParser::make_YIADDR(loc); YY_BREAK case 24: YY_RULE_SETUP #line 159 "lexer.ll" -return isc::eval::EvalParser::make_LPAREN(loc); +return isc::eval::EvalParser::make_SIADDR(loc); YY_BREAK case 25: YY_RULE_SETUP #line 160 "lexer.ll" -return isc::eval::EvalParser::make_RPAREN(loc); +return isc::eval::EvalParser::make_SUBSTRING(loc); YY_BREAK case 26: YY_RULE_SETUP #line 161 "lexer.ll" -return isc::eval::EvalParser::make_LBRACKET(loc); +return isc::eval::EvalParser::make_ALL(loc); YY_BREAK case 27: YY_RULE_SETUP #line 162 "lexer.ll" -return isc::eval::EvalParser::make_RBRACKET(loc); +return isc::eval::EvalParser::make_CONCAT(loc); YY_BREAK case 28: YY_RULE_SETUP #line 163 "lexer.ll" -return isc::eval::EvalParser::make_COMA(loc); +return isc::eval::EvalParser::make_NOT(loc); YY_BREAK case 29: YY_RULE_SETUP -#line 165 "lexer.ll" -return isc::eval::EvalParser::make_PKT6(loc); +#line 164 "lexer.ll" +return isc::eval::EvalParser::make_AND(loc); YY_BREAK case 30: YY_RULE_SETUP -#line 166 "lexer.ll" -return isc::eval::EvalParser::make_MSGTYPE(loc); +#line 165 "lexer.ll" +return isc::eval::EvalParser::make_OR(loc); YY_BREAK case 31: YY_RULE_SETUP -#line 167 "lexer.ll" -return isc::eval::EvalParser::make_TRANSID(loc); +#line 166 "lexer.ll" +return isc::eval::EvalParser::make_DOT(loc); YY_BREAK case 32: YY_RULE_SETUP -#line 169 "lexer.ll" -driver.error (loc, "Invalid character: " + std::string(yytext)); - YY_BREAK -case YY_STATE_EOF(INITIAL): -#line 170 "lexer.ll" -return isc::eval::EvalParser::make_END(loc); +#line 167 "lexer.ll" +return isc::eval::EvalParser::make_LPAREN(loc); YY_BREAK case 33: YY_RULE_SETUP +#line 168 "lexer.ll" +return isc::eval::EvalParser::make_RPAREN(loc); + YY_BREAK +case 34: +YY_RULE_SETUP +#line 169 "lexer.ll" +return isc::eval::EvalParser::make_LBRACKET(loc); + YY_BREAK +case 35: +YY_RULE_SETUP +#line 170 "lexer.ll" +return isc::eval::EvalParser::make_RBRACKET(loc); + YY_BREAK +case 36: +YY_RULE_SETUP #line 171 "lexer.ll" +return isc::eval::EvalParser::make_COMA(loc); + YY_BREAK +case 37: +YY_RULE_SETUP +#line 173 "lexer.ll" +return isc::eval::EvalParser::make_PKT6(loc); + YY_BREAK +case 38: +YY_RULE_SETUP +#line 174 "lexer.ll" +return isc::eval::EvalParser::make_MSGTYPE(loc); + YY_BREAK +case 39: +YY_RULE_SETUP +#line 175 "lexer.ll" +return isc::eval::EvalParser::make_TRANSID(loc); + YY_BREAK +case 40: +YY_RULE_SETUP +#line 177 "lexer.ll" +driver.error (loc, "Invalid character: " + std::string(yytext)); + YY_BREAK +case YY_STATE_EOF(INITIAL): +#line 178 "lexer.ll" +return isc::eval::EvalParser::make_END(loc); + YY_BREAK +case 41: +YY_RULE_SETUP +#line 179 "lexer.ll" ECHO; YY_BREAK -#line 1407 "lexer.cc" +#line 1440 "lexer.cc" case YY_END_OF_BUFFER: { @@ -1426,11 +1459,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; } @@ -1537,7 +1566,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 */ @@ -1561,9 +1589,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] ) @@ -1592,7 +1620,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++); @@ -1672,8 +1700,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); @@ -1684,11 +1712,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 >= 129 ) + if ( yy_current_state >= 161 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -1709,29 +1737,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 >= 129 ) + if ( yy_current_state >= 161 ) 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 == 128); + yy_is_jam = (yy_current_state == 160); 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 @@ -1785,7 +1811,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; @@ -1841,9 +1867,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. * @@ -1891,11 +1914,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); } @@ -1917,7 +1936,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. @@ -1933,9 +1952,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() * @@ -1959,6 +1975,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. @@ -1974,11 +2001,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_ @@ -2113,7 +2136,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*) ); @@ -2130,7 +2153,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 @@ -2203,8 +2226,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. */ @@ -2212,8 +2235,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; @@ -2246,7 +2268,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 */ @@ -2322,29 +2344,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) @@ -2352,9 +2374,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 */ @@ -2438,8 +2460,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]; } @@ -2448,7 +2469,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 ) ; @@ -2458,12 +2479,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 @@ -2476,7 +2496,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 */ @@ -2486,7 +2506,7 @@ void yyfree (void * ptr ) /* %ok-for-header */ -#line 171 "lexer.ll" +#line 179 "lexer.ll" diff --git a/src/lib/eval/lexer.ll b/src/lib/eval/lexer.ll index 6fadc94a3e..ef2c460396 100644 --- a/src/lib/eval/lexer.ll +++ b/src/lib/eval/lexer.ll @@ -149,6 +149,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 fa8038cfc6..c14a54942f 100644 --- a/src/lib/eval/parser.cc +++ b/src/lib/eval/parser.cc @@ -251,31 +251,35 @@ namespace isc { namespace eval { { switch (that.type_get ()) { - case 37: // option_repr_type + case 45: // option_repr_type value.move< TokenOption::RepresentationType > (that.value); break; - case 42: // pkt6_field + case 46: // pkt4_field + value.move< TokenPkt4::FieldType > (that.value); + break; + + case 51: // pkt6_field value.move< TokenPkt6::FieldType > (that.value); break; - case 40: // relay6_field + case 49: // relay6_field value.move< TokenRelay6Field::FieldType > (that.value); break; - case 27: // "constant string" - case 28: // "integer" - case 29: // "constant hexstring" - case 30: // "option name" - case 31: // "ip address" + case 35: // "constant string" + case 36: // "integer" + case 37: // "constant hexstring" + case 38: // "option name" + case 39: // "ip address" value.move< std::string > (that.value); break; - case 36: // option_code + case 44: // option_code value.move< uint16_t > (that.value); break; - case 41: // nest_level + case 50: // nest_level value.move< uint8_t > (that.value); break; @@ -294,31 +298,35 @@ namespace isc { namespace eval { state = that.state; switch (that.type_get ()) { - case 37: // option_repr_type + case 45: // option_repr_type value.copy< TokenOption::RepresentationType > (that.value); break; - case 42: // pkt6_field + case 46: // pkt4_field + value.copy< TokenPkt4::FieldType > (that.value); + break; + + case 51: // pkt6_field value.copy< TokenPkt6::FieldType > (that.value); break; - case 40: // relay6_field + case 49: // relay6_field value.copy< TokenRelay6Field::FieldType > (that.value); break; - case 27: // "constant string" - case 28: // "integer" - case 29: // "constant hexstring" - case 30: // "option name" - case 31: // "ip address" + case 35: // "constant string" + case 36: // "integer" + case 37: // "constant hexstring" + case 38: // "option name" + case 39: // "ip address" value.copy< std::string > (that.value); break; - case 36: // option_code + case 44: // option_code value.copy< uint16_t > (that.value); break; - case 41: // nest_level + case 50: // nest_level value.copy< uint8_t > (that.value); break; @@ -358,74 +366,81 @@ namespace isc { namespace eval { << yysym.location << ": "; switch (yytype) { - case 27: // "constant string" + case 35: // "constant string" -#line 82 "parser.yy" // lalr1.cc:636 +#line 91 "parser.yy" // lalr1.cc:636 { yyoutput << yysym.value.template as< std::string > (); } -#line 366 "parser.cc" // lalr1.cc:636 +#line 374 "parser.cc" // lalr1.cc:636 break; - case 28: // "integer" + case 36: // "integer" -#line 82 "parser.yy" // lalr1.cc:636 +#line 91 "parser.yy" // lalr1.cc:636 { yyoutput << yysym.value.template as< std::string > (); } -#line 373 "parser.cc" // lalr1.cc:636 +#line 381 "parser.cc" // lalr1.cc:636 break; - case 29: // "constant hexstring" + case 37: // "constant hexstring" -#line 82 "parser.yy" // lalr1.cc:636 +#line 91 "parser.yy" // lalr1.cc:636 { yyoutput << yysym.value.template as< std::string > (); } -#line 380 "parser.cc" // lalr1.cc:636 +#line 388 "parser.cc" // lalr1.cc:636 break; - case 30: // "option name" + case 38: // "option name" -#line 82 "parser.yy" // lalr1.cc:636 +#line 91 "parser.yy" // lalr1.cc:636 { yyoutput << yysym.value.template as< std::string > (); } -#line 387 "parser.cc" // lalr1.cc:636 +#line 395 "parser.cc" // lalr1.cc:636 break; - case 31: // "ip address" + case 39: // "ip address" -#line 82 "parser.yy" // lalr1.cc:636 +#line 91 "parser.yy" // lalr1.cc:636 { yyoutput << yysym.value.template as< std::string > (); } -#line 394 "parser.cc" // lalr1.cc:636 +#line 402 "parser.cc" // lalr1.cc:636 break; - case 36: // option_code + case 44: // option_code -#line 82 "parser.yy" // lalr1.cc:636 +#line 91 "parser.yy" // lalr1.cc:636 { yyoutput << yysym.value.template as< uint16_t > (); } -#line 401 "parser.cc" // lalr1.cc:636 +#line 409 "parser.cc" // lalr1.cc:636 break; - case 37: // option_repr_type + case 45: // option_repr_type -#line 82 "parser.yy" // lalr1.cc:636 +#line 91 "parser.yy" // lalr1.cc:636 { yyoutput << yysym.value.template as< TokenOption::RepresentationType > (); } -#line 408 "parser.cc" // lalr1.cc:636 +#line 416 "parser.cc" // lalr1.cc:636 break; - case 40: // relay6_field + case 46: // pkt4_field -#line 82 "parser.yy" // lalr1.cc:636 +#line 91 "parser.yy" // lalr1.cc:636 + { yyoutput << yysym.value.template as< TokenPkt4::FieldType > (); } +#line 423 "parser.cc" // lalr1.cc:636 + break; + + case 49: // relay6_field + +#line 91 "parser.yy" // lalr1.cc:636 { yyoutput << yysym.value.template as< TokenRelay6Field::FieldType > (); } -#line 415 "parser.cc" // lalr1.cc:636 +#line 430 "parser.cc" // lalr1.cc:636 break; - case 41: // nest_level + case 50: // nest_level -#line 82 "parser.yy" // lalr1.cc:636 +#line 91 "parser.yy" // lalr1.cc:636 { yyoutput << yysym.value.template as< uint8_t > (); } -#line 422 "parser.cc" // lalr1.cc:636 +#line 437 "parser.cc" // lalr1.cc:636 break; - case 42: // pkt6_field + case 51: // pkt6_field -#line 82 "parser.yy" // lalr1.cc:636 +#line 91 "parser.yy" // lalr1.cc:636 { yyoutput << yysym.value.template as< TokenPkt6::FieldType > (); } -#line 429 "parser.cc" // lalr1.cc:636 +#line 444 "parser.cc" // lalr1.cc:636 break; @@ -625,31 +640,35 @@ namespace isc { namespace eval { when using variants. */ switch (yyr1_[yyn]) { - case 37: // option_repr_type + case 45: // option_repr_type yylhs.value.build< TokenOption::RepresentationType > (); break; - case 42: // pkt6_field + case 46: // pkt4_field + yylhs.value.build< TokenPkt4::FieldType > (); + break; + + case 51: // pkt6_field yylhs.value.build< TokenPkt6::FieldType > (); break; - case 40: // relay6_field + case 49: // relay6_field yylhs.value.build< TokenRelay6Field::FieldType > (); break; - case 27: // "constant string" - case 28: // "integer" - case 29: // "constant hexstring" - case 30: // "option name" - case 31: // "ip address" + case 35: // "constant string" + case 36: // "integer" + case 37: // "constant hexstring" + case 38: // "option name" + case 39: // "ip address" yylhs.value.build< std::string > (); break; - case 36: // option_code + case 44: // option_code yylhs.value.build< uint16_t > (); break; - case 41: // nest_level + case 50: // nest_level yylhs.value.build< uint8_t > (); break; @@ -671,52 +690,52 @@ namespace isc { namespace eval { switch (yyn) { case 4: -#line 96 "parser.yy" // lalr1.cc:859 +#line 105 "parser.yy" // lalr1.cc:859 { TokenPtr neg(new TokenNot()); ctx.expression.push_back(neg); } -#line 680 "parser.cc" // lalr1.cc:859 +#line 699 "parser.cc" // lalr1.cc:859 break; case 5: -#line 101 "parser.yy" // lalr1.cc:859 +#line 110 "parser.yy" // lalr1.cc:859 { TokenPtr neg(new TokenAnd()); ctx.expression.push_back(neg); } -#line 689 "parser.cc" // lalr1.cc:859 +#line 708 "parser.cc" // lalr1.cc:859 break; case 6: -#line 106 "parser.yy" // lalr1.cc:859 +#line 115 "parser.yy" // lalr1.cc:859 { TokenPtr neg(new TokenOr()); ctx.expression.push_back(neg); } -#line 698 "parser.cc" // lalr1.cc:859 +#line 717 "parser.cc" // lalr1.cc:859 break; case 7: -#line 111 "parser.yy" // lalr1.cc:859 +#line 120 "parser.yy" // lalr1.cc:859 { TokenPtr eq(new TokenEqual()); ctx.expression.push_back(eq); } -#line 707 "parser.cc" // lalr1.cc:859 +#line 726 "parser.cc" // lalr1.cc:859 break; case 8: -#line 116 "parser.yy" // lalr1.cc:859 +#line 125 "parser.yy" // lalr1.cc:859 { TokenPtr opt(new TokenOption(yystack_[3].value.as< uint16_t > (), TokenOption::EXISTS)); ctx.expression.push_back(opt); } -#line 716 "parser.cc" // lalr1.cc:859 +#line 735 "parser.cc" // lalr1.cc:859 break; case 9: -#line 121 "parser.yy" // lalr1.cc:859 +#line 130 "parser.yy" // lalr1.cc:859 { switch (ctx.getUniverse()) { case Option::V4: @@ -736,11 +755,11 @@ namespace isc { namespace eval { error(yystack_[5].location, "relay4 can only be used in DHCPv4."); } } -#line 740 "parser.cc" // lalr1.cc:859 +#line 759 "parser.cc" // lalr1.cc:859 break; case 10: -#line 141 "parser.yy" // lalr1.cc:859 +#line 150 "parser.yy" // lalr1.cc:859 { switch (ctx.getUniverse()) { case Option::V6: @@ -754,47 +773,47 @@ namespace isc { namespace eval { error(yystack_[10].location, "relay6 can only be used in DHCPv6."); } } -#line 758 "parser.cc" // lalr1.cc:859 +#line 777 "parser.cc" // lalr1.cc:859 break; case 11: -#line 157 "parser.yy" // lalr1.cc:859 +#line 166 "parser.yy" // lalr1.cc:859 { TokenPtr str(new TokenString(yystack_[0].value.as< std::string > ())); ctx.expression.push_back(str); } -#line 767 "parser.cc" // lalr1.cc:859 +#line 786 "parser.cc" // lalr1.cc:859 break; case 12: -#line 162 "parser.yy" // lalr1.cc:859 +#line 171 "parser.yy" // lalr1.cc:859 { TokenPtr hex(new TokenHexString(yystack_[0].value.as< std::string > ())); ctx.expression.push_back(hex); } -#line 776 "parser.cc" // lalr1.cc:859 +#line 795 "parser.cc" // lalr1.cc:859 break; case 13: -#line 167 "parser.yy" // lalr1.cc:859 +#line 176 "parser.yy" // lalr1.cc:859 { TokenPtr ip(new TokenIpAddress(yystack_[0].value.as< std::string > ())); ctx.expression.push_back(ip); } -#line 785 "parser.cc" // lalr1.cc:859 +#line 804 "parser.cc" // lalr1.cc:859 break; case 14: -#line 172 "parser.yy" // lalr1.cc:859 +#line 181 "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 794 "parser.cc" // lalr1.cc:859 +#line 813 "parser.cc" // lalr1.cc:859 break; case 15: -#line 177 "parser.yy" // lalr1.cc:859 +#line 186 "parser.yy" // lalr1.cc:859 { switch (ctx.getUniverse()) { case Option::V4: @@ -814,11 +833,11 @@ namespace isc { namespace eval { error(yystack_[5].location, "relay4 can only be used in DHCPv4."); } } -#line 818 "parser.cc" // lalr1.cc:859 +#line 837 "parser.cc" // lalr1.cc:859 break; case 16: -#line 198 "parser.yy" // lalr1.cc:859 +#line 207 "parser.yy" // lalr1.cc:859 { switch (ctx.getUniverse()) { case Option::V6: @@ -832,11 +851,11 @@ namespace isc { namespace eval { error(yystack_[10].location, "relay6 can only be used in DHCPv6."); } } -#line 836 "parser.cc" // lalr1.cc:859 +#line 855 "parser.cc" // lalr1.cc:859 break; case 17: -#line 213 "parser.yy" // lalr1.cc:859 +#line 222 "parser.yy" // lalr1.cc:859 { switch (ctx.getUniverse()) { case Option::V6: @@ -850,129 +869,194 @@ namespace isc { namespace eval { error(yystack_[5].location, "relay6 can only be used in DHCPv6."); } } -#line 854 "parser.cc" // lalr1.cc:859 +#line 873 "parser.cc" // lalr1.cc:859 break; case 18: -#line 229 "parser.yy" // lalr1.cc:859 +#line 237 "parser.yy" // lalr1.cc:859 { - TokenPtr sub(new TokenSubstring()); - ctx.expression.push_back(sub); + TokenPtr pkt4_field(new TokenPkt4(yystack_[0].value.as< TokenPkt4::FieldType > ())); + ctx.expression.push_back(pkt4_field); } -#line 863 "parser.cc" // lalr1.cc:859 +#line 882 "parser.cc" // lalr1.cc:859 break; case 19: -#line 234 "parser.yy" // lalr1.cc:859 - { - TokenPtr conc(new TokenConcat()); - ctx.expression.push_back(conc); - } -#line 872 "parser.cc" // lalr1.cc:859 - break; - - case 20: -#line 239 "parser.yy" // lalr1.cc:859 +#line 242 "parser.yy" // lalr1.cc:859 { TokenPtr pkt6_field(new TokenPkt6(yystack_[0].value.as< TokenPkt6::FieldType > ())); ctx.expression.push_back(pkt6_field); } -#line 881 "parser.cc" // lalr1.cc:859 +#line 891 "parser.cc" // lalr1.cc:859 + break; + + case 20: +#line 247 "parser.yy" // lalr1.cc:859 + { + TokenPtr sub(new TokenSubstring()); + ctx.expression.push_back(sub); + } +#line 900 "parser.cc" // lalr1.cc:859 break; case 21: -#line 246 "parser.yy" // lalr1.cc:859 +#line 252 "parser.yy" // lalr1.cc:859 { - yylhs.value.as< uint16_t > () = ctx.convertOptionCode(yystack_[0].value.as< std::string > (), yystack_[0].location); - } -#line 889 "parser.cc" // lalr1.cc:859 + TokenPtr conc(new TokenConcat()); + ctx.expression.push_back(conc); + } +#line 909 "parser.cc" // lalr1.cc:859 break; case 22: -#line 250 "parser.yy" // lalr1.cc:859 +#line 259 "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 897 "parser.cc" // lalr1.cc:859 +#line 917 "parser.cc" // lalr1.cc:859 break; case 23: -#line 256 "parser.yy" // lalr1.cc:859 +#line 263 "parser.yy" // lalr1.cc:859 { - yylhs.value.as< TokenOption::RepresentationType > () = TokenOption::TEXTUAL; - } -#line 905 "parser.cc" // lalr1.cc:859 + yylhs.value.as< uint16_t > () = ctx.convertOptionName(yystack_[0].value.as< std::string > (), yystack_[0].location); + } +#line 925 "parser.cc" // lalr1.cc:859 break; case 24: -#line 260 "parser.yy" // lalr1.cc:859 +#line 269 "parser.yy" // lalr1.cc:859 { - yylhs.value.as< TokenOption::RepresentationType > () = TokenOption::HEXADECIMAL; + yylhs.value.as< TokenOption::RepresentationType > () = TokenOption::TEXTUAL; } -#line 913 "parser.cc" // lalr1.cc:859 +#line 933 "parser.cc" // lalr1.cc:859 break; case 25: -#line 266 "parser.yy" // lalr1.cc:859 +#line 273 "parser.yy" // lalr1.cc:859 + { + yylhs.value.as< TokenOption::RepresentationType > () = TokenOption::HEXADECIMAL; + } +#line 941 "parser.cc" // lalr1.cc:859 + break; + + case 26: +#line 279 "parser.yy" // lalr1.cc:859 + { + yylhs.value.as< TokenPkt4::FieldType > () = TokenPkt4::CHADDR; + } +#line 949 "parser.cc" // lalr1.cc:859 + break; + + case 27: +#line 283 "parser.yy" // lalr1.cc:859 + { + yylhs.value.as< TokenPkt4::FieldType > () = TokenPkt4::HLEN; + } +#line 957 "parser.cc" // lalr1.cc:859 + break; + + case 28: +#line 287 "parser.yy" // lalr1.cc:859 + { + yylhs.value.as< TokenPkt4::FieldType > () = TokenPkt4::HTYPE; + } +#line 965 "parser.cc" // lalr1.cc:859 + break; + + case 29: +#line 291 "parser.yy" // lalr1.cc:859 + { + yylhs.value.as< TokenPkt4::FieldType > () = TokenPkt4::CIADDR; + } +#line 973 "parser.cc" // lalr1.cc:859 + break; + + case 30: +#line 295 "parser.yy" // lalr1.cc:859 + { + yylhs.value.as< TokenPkt4::FieldType > () = TokenPkt4::GIADDR; + } +#line 981 "parser.cc" // lalr1.cc:859 + break; + + case 31: +#line 299 "parser.yy" // lalr1.cc:859 + { + yylhs.value.as< TokenPkt4::FieldType > () = TokenPkt4::YIADDR; + } +#line 989 "parser.cc" // lalr1.cc:859 + break; + + case 32: +#line 303 "parser.yy" // lalr1.cc:859 + { + yylhs.value.as< TokenPkt4::FieldType > () = TokenPkt4::SIADDR; + } +#line 997 "parser.cc" // lalr1.cc:859 + break; + + case 33: +#line 309 "parser.yy" // lalr1.cc:859 { TokenPtr str(new TokenString(yystack_[0].value.as< std::string > ())); ctx.expression.push_back(str); } -#line 922 "parser.cc" // lalr1.cc:859 +#line 1006 "parser.cc" // lalr1.cc:859 break; - case 26: -#line 273 "parser.yy" // lalr1.cc:859 + case 34: +#line 316 "parser.yy" // lalr1.cc:859 { TokenPtr str(new TokenString(yystack_[0].value.as< std::string > ())); ctx.expression.push_back(str); } -#line 931 "parser.cc" // lalr1.cc:859 +#line 1015 "parser.cc" // lalr1.cc:859 break; - case 27: -#line 278 "parser.yy" // lalr1.cc:859 + case 35: +#line 321 "parser.yy" // lalr1.cc:859 { TokenPtr str(new TokenString("all")); ctx.expression.push_back(str); } -#line 940 "parser.cc" // lalr1.cc:859 +#line 1024 "parser.cc" // lalr1.cc:859 break; - case 28: -#line 284 "parser.yy" // lalr1.cc:859 + case 36: +#line 327 "parser.yy" // lalr1.cc:859 { yylhs.value.as< TokenRelay6Field::FieldType > () = TokenRelay6Field::PEERADDR; } -#line 946 "parser.cc" // lalr1.cc:859 +#line 1030 "parser.cc" // lalr1.cc:859 break; - case 29: -#line 285 "parser.yy" // lalr1.cc:859 + case 37: +#line 328 "parser.yy" // lalr1.cc:859 { yylhs.value.as< TokenRelay6Field::FieldType > () = TokenRelay6Field::LINKADDR; } -#line 952 "parser.cc" // lalr1.cc:859 +#line 1036 "parser.cc" // lalr1.cc:859 break; - case 30: -#line 289 "parser.yy" // lalr1.cc:859 + case 38: +#line 332 "parser.yy" // lalr1.cc:859 { yylhs.value.as< uint8_t > () = ctx.convertNestLevelNumber(yystack_[0].value.as< std::string > (), yystack_[0].location); } -#line 960 "parser.cc" // lalr1.cc:859 +#line 1044 "parser.cc" // lalr1.cc:859 break; - case 31: -#line 297 "parser.yy" // lalr1.cc:859 + case 39: +#line 340 "parser.yy" // lalr1.cc:859 { yylhs.value.as< TokenPkt6::FieldType > () = TokenPkt6::MSGTYPE; } -#line 966 "parser.cc" // lalr1.cc:859 +#line 1050 "parser.cc" // lalr1.cc:859 break; - case 32: -#line 298 "parser.yy" // lalr1.cc:859 + case 40: +#line 341 "parser.yy" // lalr1.cc:859 { yylhs.value.as< TokenPkt6::FieldType > () = TokenPkt6::TRANSID; } -#line 972 "parser.cc" // lalr1.cc:859 +#line 1056 "parser.cc" // lalr1.cc:859 break; -#line 976 "parser.cc" // lalr1.cc:859 +#line 1060 "parser.cc" // lalr1.cc:859 default: break; } @@ -1227,117 +1311,124 @@ namespace isc { namespace eval { } - const signed char EvalParser::yypact_ninf_ = -54; + const signed char EvalParser::yypact_ninf_ = -62; const signed char EvalParser::yytable_ninf_ = -1; const signed char EvalParser::yypact_[] = { - 29, 29, 29, -12, -4, 7, 21, 30, 32, -54, - -54, -54, 13, 10, 46, 16, -54, -3, -3, 9, - 52, 52, 42, -54, 29, 29, 52, -54, -54, -54, - 40, 54, -54, 56, 43, 59, 60, 55, 58, -54, - -54, -54, -54, 72, -54, 66, 68, 69, -3, -3, - 9, 61, 52, 25, 28, -1, 71, 73, 75, -54, - 65, 87, -54, -54, -54, -54, -54, -54, 78, -54, - -54, -54, 77, 79, 80, -14, -54, -3, 33, 33, - 6, -54, -54, 90, 82, 84, -54, 83, -3, 47, - 85, -54, -54, 86, 33 + 14, 14, 14, 6, 17, 18, 21, 41, 44, 48, + -62, -62, -62, 72, 20, 66, 29, -62, 12, 12, + 16, 36, 45, 45, -24, -62, 14, 14, 45, -62, + -62, -62, 60, 63, -62, 73, -62, -62, -62, -62, + -62, -62, -62, -62, 67, 69, 75, 61, 62, -62, + -62, -62, -62, 84, -62, 77, 78, 79, 12, 12, + 16, 64, 45, -3, 52, -1, 81, 82, 83, -62, + 71, 95, -62, -62, -62, -62, -62, -62, 88, -62, + -62, -62, 87, 89, 90, -23, -62, 12, 49, 49, + 9, -62, -62, 100, 92, 94, -62, 93, 12, 68, + 96, -62, -62, 97, 49 }; const unsigned char EvalParser::yydefact_[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, - 12, 13, 0, 2, 0, 0, 4, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 0, 3, 21, 22, - 0, 0, 30, 0, 0, 0, 0, 0, 0, 31, - 32, 20, 5, 6, 7, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, - 0, 0, 23, 24, 8, 14, 9, 15, 0, 28, - 29, 17, 0, 0, 0, 0, 19, 0, 0, 0, - 0, 27, 26, 0, 0, 0, 18, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 11, 12, 13, 0, 2, 0, 0, 4, 0, 0, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, + 22, 23, 0, 0, 38, 0, 26, 27, 28, 29, + 30, 31, 32, 18, 0, 0, 0, 0, 0, 39, + 40, 19, 5, 6, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, + 0, 0, 24, 25, 8, 14, 9, 15, 0, 36, + 37, 17, 0, 0, 0, 0, 21, 0, 0, 0, + 0, 35, 34, 0, 0, 0, 20, 0, 0, 0, 0, 10, 16, 0, 0 }; const signed char EvalParser::yypgoto_[] = { - -54, -54, 4, -17, -18, -53, -54, -54, -54, 51, - -54 + -62, -62, 3, -21, -19, -61, -62, -62, -62, -62, + 50, -62 }; const signed char EvalParser::yydefgoto_[] = { - -1, 12, 13, 14, 30, 65, 60, 83, 71, 33, - 41 + -1, 13, 14, 15, 32, 75, 43, 70, 93, 81, + 35, 51 }; const unsigned char EvalParser::yytable_[] = { - 31, 67, 17, 37, 38, 15, 16, 81, 68, 44, - 18, 69, 70, 23, 82, 85, 24, 25, 69, 70, - 27, 19, 24, 25, 20, 28, 67, 29, 42, 43, - 56, 57, 1, 21, 2, 61, 92, 32, 3, 4, - 5, 92, 62, 63, 64, 62, 63, 66, 22, 6, - 62, 63, 7, 8, 26, 45, 9, 48, 10, 84, - 11, 34, 35, 36, 62, 63, 91, 39, 40, 46, - 90, 47, 6, 49, 50, 7, 8, 51, 24, 9, - 52, 10, 53, 11, 54, 55, 72, 75, 73, 59, - 74, 76, 77, 78, 86, 79, 80, 87, 88, 89, - 93, 58, 94 + 33, 47, 48, 77, 16, 17, 91, 54, 78, 49, + 50, 79, 80, 92, 72, 73, 74, 1, 95, 2, + 18, 79, 80, 3, 4, 5, 26, 27, 77, 52, + 53, 19, 20, 29, 6, 26, 27, 21, 102, 66, + 67, 71, 7, 102, 22, 8, 9, 23, 30, 10, + 31, 11, 34, 12, 44, 45, 46, 36, 37, 38, + 39, 40, 41, 42, 24, 6, 72, 73, 94, 72, + 73, 76, 25, 7, 28, 55, 8, 9, 56, 100, + 10, 58, 11, 59, 12, 72, 73, 101, 57, 60, + 26, 61, 62, 63, 64, 65, 82, 83, 84, 86, + 69, 85, 87, 88, 96, 89, 90, 97, 98, 99, + 68, 103, 0, 104 }; - const unsigned char + const signed char EvalParser::yycheck_[] = { - 18, 54, 14, 20, 21, 1, 2, 21, 9, 26, - 14, 12, 13, 0, 28, 9, 6, 7, 12, 13, - 4, 14, 6, 7, 3, 28, 79, 30, 24, 25, - 48, 49, 3, 3, 5, 52, 89, 28, 9, 10, - 11, 94, 17, 18, 19, 17, 18, 19, 16, 20, - 17, 18, 23, 24, 8, 15, 27, 14, 29, 77, - 31, 9, 10, 11, 17, 18, 19, 25, 26, 15, - 88, 15, 20, 14, 14, 23, 24, 22, 6, 27, - 22, 29, 16, 31, 16, 16, 15, 22, 15, 28, - 15, 4, 14, 16, 4, 16, 16, 15, 14, 16, - 15, 50, 16 + 19, 22, 23, 64, 1, 2, 29, 28, 9, 33, + 34, 12, 13, 36, 17, 18, 19, 3, 9, 5, + 14, 12, 13, 9, 10, 11, 6, 7, 89, 26, + 27, 14, 14, 4, 20, 6, 7, 16, 99, 58, + 59, 62, 28, 104, 3, 31, 32, 3, 36, 35, + 38, 37, 36, 39, 9, 10, 11, 21, 22, 23, + 24, 25, 26, 27, 16, 20, 17, 18, 87, 17, + 18, 19, 0, 28, 8, 15, 31, 32, 15, 98, + 35, 14, 37, 14, 39, 17, 18, 19, 15, 14, + 6, 30, 30, 16, 16, 16, 15, 15, 15, 4, + 36, 30, 14, 16, 4, 16, 16, 15, 14, 16, + 60, 15, -1, 16 }; const unsigned char EvalParser::yystos_[] = { - 0, 3, 5, 9, 10, 11, 20, 23, 24, 27, - 29, 31, 33, 34, 35, 34, 34, 14, 14, 14, - 3, 3, 16, 0, 6, 7, 8, 4, 28, 30, - 36, 36, 28, 41, 9, 10, 11, 35, 35, 25, - 26, 42, 34, 34, 35, 15, 15, 15, 14, 14, - 14, 22, 22, 16, 16, 16, 36, 36, 41, 28, - 38, 35, 17, 18, 19, 37, 19, 37, 9, 12, - 13, 40, 15, 15, 15, 22, 4, 14, 16, 16, - 16, 21, 28, 39, 36, 9, 4, 15, 14, 16, - 36, 19, 37, 15, 16 + 0, 3, 5, 9, 10, 11, 20, 28, 31, 32, + 35, 37, 39, 41, 42, 43, 42, 42, 14, 14, + 14, 16, 3, 3, 16, 0, 6, 7, 8, 4, + 36, 38, 44, 44, 36, 50, 21, 22, 23, 24, + 25, 26, 27, 46, 9, 10, 11, 43, 43, 33, + 34, 51, 42, 42, 43, 15, 15, 15, 14, 14, + 14, 30, 30, 16, 16, 16, 44, 44, 50, 36, + 47, 43, 17, 18, 19, 45, 19, 45, 9, 12, + 13, 49, 15, 15, 15, 30, 4, 14, 16, 16, + 16, 29, 36, 48, 44, 9, 4, 15, 14, 16, + 44, 19, 45, 15, 16 }; const unsigned char EvalParser::yyr1_[] = { - 0, 32, 33, 34, 34, 34, 34, 34, 34, 34, - 34, 35, 35, 35, 35, 35, 35, 35, 35, 35, - 35, 36, 36, 37, 37, 38, 39, 39, 40, 40, - 41, 42, 42 + 0, 40, 41, 42, 42, 42, 42, 42, 42, 42, + 42, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 44, 44, 45, 45, 46, 46, 46, 46, + 46, 46, 46, 47, 48, 48, 49, 49, 50, 51, + 51 }; const unsigned char EvalParser::yyr2_[] = { 0, 2, 1, 3, 2, 3, 3, 3, 6, 6, - 11, 1, 1, 1, 6, 6, 11, 6, 8, 6, - 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1 + 11, 1, 1, 1, 6, 6, 11, 6, 3, 3, + 8, 6, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1 }; @@ -1350,22 +1441,25 @@ namespace isc { namespace eval { "\"end of file\"", "error", "$undefined", "\"(\"", "\")\"", "\"not\"", "\"and\"", "\"or\"", "\"==\"", "\"option\"", "\"relay4\"", "\"relay6\"", "\"peeraddr\"", "\"linkaddr\"", "\"[\"", "\"]\"", "\".\"", "\"text\"", - "\"hex\"", "\"exists\"", "\"substring\"", "\"all\"", "\",\"", - "\"concat\"", "\"pkt6\"", "\"msgtype\"", "\"transid\"", - "\"constant string\"", "\"integer\"", "\"constant hexstring\"", - "\"option name\"", "\"ip address\"", "$accept", "expression", - "bool_expr", "string_expr", "option_code", "option_repr_type", - "start_expr", "length_expr", "relay6_field", "nest_level", "pkt6_field", YY_NULLPTR + "\"hex\"", "\"exists\"", "\"pkt4\"", "\"mac\"", "\"hlen\"", "\"htype\"", + "\"ciaddr\"", "\"giaddr\"", "\"yiaddr\"", "\"siaddr\"", "\"substring\"", + "\"all\"", "\",\"", "\"concat\"", "\"pkt6\"", "\"msgtype\"", + "\"transid\"", "\"constant string\"", "\"integer\"", + "\"constant hexstring\"", "\"option name\"", "\"ip address\"", "$accept", + "expression", "bool_expr", "string_expr", "option_code", + "option_repr_type", "pkt4_field", "start_expr", "length_expr", + "relay6_field", "nest_level", "pkt6_field", YY_NULLPTR }; #if YYDEBUG const unsigned short int EvalParser::yyrline_[] = { - 0, 91, 91, 94, 95, 100, 105, 110, 115, 120, - 140, 156, 161, 166, 171, 176, 197, 212, 228, 233, - 238, 245, 249, 255, 259, 265, 272, 277, 284, 285, - 288, 297, 298 + 0, 100, 100, 103, 104, 109, 114, 119, 124, 129, + 149, 165, 170, 175, 180, 185, 206, 221, 236, 241, + 246, 251, 258, 262, 268, 272, 278, 282, 286, 290, + 294, 298, 302, 308, 315, 320, 327, 328, 331, 340, + 341 }; // Print the state stack on the debug stream. @@ -1400,8 +1494,8 @@ namespace isc { namespace eval { #line 13 "parser.yy" // lalr1.cc:1167 } } // isc::eval -#line 1404 "parser.cc" // lalr1.cc:1167 -#line 301 "parser.yy" // lalr1.cc:1168 +#line 1498 "parser.cc" // lalr1.cc:1167 +#line 344 "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 7727cffa8b..2cb61b5e4f 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,24 +298,27 @@ namespace isc { namespace eval { // option_repr_type char dummy1[sizeof(TokenOption::RepresentationType)]; + // pkt4_field + char dummy2[sizeof(TokenPkt4::FieldType)]; + // pkt6_field - char dummy2[sizeof(TokenPkt6::FieldType)]; + char dummy3[sizeof(TokenPkt6::FieldType)]; // relay6_field - char dummy3[sizeof(TokenRelay6Field::FieldType)]; + char dummy4[sizeof(TokenRelay6Field::FieldType)]; // "constant string" // "integer" // "constant hexstring" // "option name" // "ip address" - char dummy4[sizeof(std::string)]; + char dummy5[sizeof(std::string)]; // option_code - char dummy5[sizeof(uint16_t)]; + char dummy6[sizeof(uint16_t)]; // nest_level - char dummy6[sizeof(uint8_t)]; + char dummy7[sizeof(uint8_t)]; }; /// Symbol semantic values. @@ -356,18 +359,26 @@ namespace isc { namespace eval { TOKEN_TEXT = 272, TOKEN_HEX = 273, TOKEN_EXISTS = 274, - TOKEN_SUBSTRING = 275, - TOKEN_ALL = 276, - TOKEN_COMA = 277, - TOKEN_CONCAT = 278, - TOKEN_PKT6 = 279, - TOKEN_MSGTYPE = 280, - TOKEN_TRANSID = 281, - TOKEN_STRING = 282, - TOKEN_INTEGER = 283, - TOKEN_HEXSTRING = 284, - TOKEN_OPTION_NAME = 285, - TOKEN_IP_ADDRESS = 286 + TOKEN_PKT4 = 275, + TOKEN_CHADDR = 276, + TOKEN_HLEN = 277, + TOKEN_HTYPE = 278, + TOKEN_CIADDR = 279, + TOKEN_GIADDR = 280, + TOKEN_YIADDR = 281, + TOKEN_SIADDR = 282, + TOKEN_SUBSTRING = 283, + TOKEN_ALL = 284, + TOKEN_COMA = 285, + TOKEN_CONCAT = 286, + TOKEN_PKT6 = 287, + TOKEN_MSGTYPE = 288, + TOKEN_TRANSID = 289, + TOKEN_STRING = 290, + TOKEN_INTEGER = 291, + TOKEN_HEXSTRING = 292, + TOKEN_OPTION_NAME = 293, + TOKEN_IP_ADDRESS = 294 }; }; @@ -407,6 +418,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 TokenPkt6::FieldType v, const location_type& l); basic_symbol (typename Base::kind_type t, const TokenRelay6Field::FieldType v, const location_type& l); @@ -556,6 +569,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); @@ -689,7 +734,7 @@ namespace isc { namespace eval { // number is the opposite. If YYTABLE_NINF, syntax error. static const unsigned char yytable_[]; - static const unsigned char yycheck_[]; + static const signed char yycheck_[]; // YYSTOS[STATE-NUM] -- The (internal number of the) accessing // symbol of state STATE-NUM. @@ -809,12 +854,12 @@ namespace isc { namespace eval { enum { yyeof_ = 0, - yylast_ = 102, ///< Last index in yytable_. - yynnts_ = 11, ///< Number of nonterminal symbols. - yyfinal_ = 23, ///< Termination state number. + yylast_ = 113, ///< Last index in yytable_. + yynnts_ = 12, ///< Number of nonterminal symbols. + yyfinal_ = 25, ///< Termination state number. yyterror_ = 1, yyerrcode_ = 256, - yyntokens_ = 32 ///< Number of tokens. + yyntokens_ = 40 ///< Number of tokens. }; @@ -859,9 +904,10 @@ 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, 26, 27, 28, 29, 30, 31 + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39 }; - const unsigned int user_token_number_max_ = 286; + const unsigned int user_token_number_max_ = 294; const token_number_type undef_token_ = 2; if (static_cast(t) <= yyeof_) @@ -894,31 +940,35 @@ namespace isc { namespace eval { { switch (other.type_get ()) { - case 37: // option_repr_type + case 45: // option_repr_type value.copy< TokenOption::RepresentationType > (other.value); break; - case 42: // pkt6_field + case 46: // pkt4_field + value.copy< TokenPkt4::FieldType > (other.value); + break; + + case 51: // pkt6_field value.copy< TokenPkt6::FieldType > (other.value); break; - case 40: // relay6_field + case 49: // relay6_field value.copy< TokenRelay6Field::FieldType > (other.value); break; - case 27: // "constant string" - case 28: // "integer" - case 29: // "constant hexstring" - case 30: // "option name" - case 31: // "ip address" + case 35: // "constant string" + case 36: // "integer" + case 37: // "constant hexstring" + case 38: // "option name" + case 39: // "ip address" value.copy< std::string > (other.value); break; - case 36: // option_code + case 44: // option_code value.copy< uint16_t > (other.value); break; - case 41: // nest_level + case 50: // nest_level value.copy< uint8_t > (other.value); break; @@ -939,31 +989,35 @@ namespace isc { namespace eval { (void) v; switch (this->type_get ()) { - case 37: // option_repr_type + case 45: // option_repr_type value.copy< TokenOption::RepresentationType > (v); break; - case 42: // pkt6_field + case 46: // pkt4_field + value.copy< TokenPkt4::FieldType > (v); + break; + + case 51: // pkt6_field value.copy< TokenPkt6::FieldType > (v); break; - case 40: // relay6_field + case 49: // relay6_field value.copy< TokenRelay6Field::FieldType > (v); break; - case 27: // "constant string" - case 28: // "integer" - case 29: // "constant hexstring" - case 30: // "option name" - case 31: // "ip address" + case 35: // "constant string" + case 36: // "integer" + case 37: // "constant hexstring" + case 38: // "option name" + case 39: // "ip address" value.copy< std::string > (v); break; - case 36: // option_code + case 44: // option_code value.copy< uint16_t > (v); break; - case 41: // nest_level + case 50: // nest_level value.copy< uint8_t > (v); break; @@ -989,6 +1043,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 TokenPkt6::FieldType v, const location_type& l) : Base (t) @@ -1050,31 +1111,35 @@ namespace isc { namespace eval { // Type destructor. switch (yytype) { - case 37: // option_repr_type + case 45: // option_repr_type value.template destroy< TokenOption::RepresentationType > (); break; - case 42: // pkt6_field + case 46: // pkt4_field + value.template destroy< TokenPkt4::FieldType > (); + break; + + case 51: // pkt6_field value.template destroy< TokenPkt6::FieldType > (); break; - case 40: // relay6_field + case 49: // relay6_field value.template destroy< TokenRelay6Field::FieldType > (); break; - case 27: // "constant string" - case 28: // "integer" - case 29: // "constant hexstring" - case 30: // "option name" - case 31: // "ip address" + case 35: // "constant string" + case 36: // "integer" + case 37: // "constant hexstring" + case 38: // "option name" + case 39: // "ip address" value.template destroy< std::string > (); break; - case 36: // option_code + case 44: // option_code value.template destroy< uint16_t > (); break; - case 41: // nest_level + case 50: // nest_level value.template destroy< uint8_t > (); break; @@ -1101,31 +1166,35 @@ namespace isc { namespace eval { super_type::move(s); switch (this->type_get ()) { - case 37: // option_repr_type + case 45: // option_repr_type value.move< TokenOption::RepresentationType > (s.value); break; - case 42: // pkt6_field + case 46: // pkt4_field + value.move< TokenPkt4::FieldType > (s.value); + break; + + case 51: // pkt6_field value.move< TokenPkt6::FieldType > (s.value); break; - case 40: // relay6_field + case 49: // relay6_field value.move< TokenRelay6Field::FieldType > (s.value); break; - case 27: // "constant string" - case 28: // "integer" - case 29: // "constant hexstring" - case 30: // "option name" - case 31: // "ip address" + case 35: // "constant string" + case 36: // "integer" + case 37: // "constant hexstring" + case 38: // "option name" + case 39: // "ip address" value.move< std::string > (s.value); break; - case 36: // option_code + case 44: // option_code value.move< uint16_t > (s.value); break; - case 41: // nest_level + case 50: // nest_level value.move< uint8_t > (s.value); break; @@ -1187,7 +1256,7 @@ 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, 281, 282, 283, 284, - 285, 286 + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294 }; return static_cast (yytoken_number_[type]); } @@ -1300,6 +1369,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) { @@ -1373,9 +1490,9 @@ namespace isc { namespace eval { } -#line 13 "parser.yy" // lalr1.cc:377 +#line 13 "parser.yy" // lalr1.cc:392 } } // isc::eval -#line 1379 "parser.h" // lalr1.cc:377 +#line 1496 "parser.h" // lalr1.cc:392 diff --git a/src/lib/eval/parser.yy b/src/lib/eval/parser.yy index 1fd28a66f3..52e69c0668 100644 --- a/src/lib/eval/parser.yy +++ b/src/lib/eval/parser.yy @@ -54,6 +54,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 "," @@ -73,6 +81,7 @@ using namespace isc::eval; %type option_repr_type %type relay6_field %type nest_level +%type pkt4_field %type pkt6_field %left OR @@ -224,7 +233,16 @@ string_expr : STRING } } - + | PKT4 "." pkt4_field + { + TokenPtr pkt4_field(new TokenPkt4($3)); + ctx.expression.push_back(pkt4_field); + } + | PKT6 "." pkt6_field + { + TokenPtr pkt6_field(new TokenPkt6($3)); + ctx.expression.push_back(pkt6_field); + } | SUBSTRING "(" string_expr "," start_expr "," length_expr ")" { TokenPtr sub(new TokenSubstring()); @@ -235,11 +253,6 @@ string_expr : STRING TokenPtr conc(new TokenConcat()); ctx.expression.push_back(conc); } - | PKT6 "." pkt6_field - { - TokenPtr pkt6_field(new TokenPkt6($3)); - ctx.expression.push_back(pkt6_field); - } ; option_code : INTEGER @@ -262,6 +275,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)); diff --git a/src/lib/eval/tests/context_unittest.cc b/src/lib/eval/tests/context_unittest.cc index eab31f9ac0..9d757d6690 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); @@ -585,6 +630,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); +} + // Tests whether message type field in DHCPv6 can be accessed. TEST_F(EvalContextTest, pkt6FieldMsgtype) { testPkt6Field("pkt6.msgtype == '1'", TokenPkt6::MSGTYPE, 3); @@ -790,6 +870,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 d81f078bb2..80af7c3c12 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 { @@ -708,6 +709,86 @@ 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(4, values_.top().size()); + uint32_t expected_hlen = htonl(7); + EXPECT_EQ(0, memcmp(&expected_hlen, &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(4, values_.top().size()); + uint32_t expected_htype = htonl(123); + EXPECT_EQ(0, memcmp(&expected_htype, &values_.top()[0], 4)); + + // 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 30b4dbc7a8..7fbe6f2d22 100644 --- a/src/lib/eval/token.cc +++ b/src/lib/eval/token.cc @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -124,6 +125,77 @@ 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: + // 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: + // 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: + 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 92591c7f20..316106e43e 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, padded to 4 octets) +/// - htype (hardware address type, padded to 4 octets) +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"