From: Tomek Mrugalski Date: Thu, 18 Aug 2016 21:40:27 +0000 (+0200) Subject: [master] Merge branch 'trac4271' (vendor options support in classification) X-Git-Tag: trac4631_base~25 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ef676368f9036625d73f7f34e3fe9b5eeeaee7f1;p=thirdparty%2Fkea.git [master] Merge branch 'trac4271' (vendor options support in classification) # Conflicts: # src/lib/eval/lexer.cc # src/lib/eval/lexer.ll # src/lib/eval/location.hh # src/lib/eval/parser.cc # src/lib/eval/parser.h # src/lib/eval/parser.yy # src/lib/eval/position.hh # src/lib/eval/stack.hh # src/lib/eval/tests/context_unittest.cc # src/lib/eval/tests/token_unittest.cc # src/lib/eval/token.cc # src/lib/eval/token.h --- ef676368f9036625d73f7f34e3fe9b5eeeaee7f1 diff --cc src/lib/eval/eval_context.cc index ca27893092,b1f4dbf443..4ede1dbc42 --- a/src/lib/eval/eval_context.cc +++ b/src/lib/eval/eval_context.cc @@@ -97,17 -98,12 +98,12 @@@ uint8_ EvalContext::convertNestLevelNumber(const std::string& nest_level, const isc::eval::location& loc) { - int n = 0; - try { - n = boost::lexical_cast(nest_level); - } catch (const boost::bad_lexical_cast &) { - error(loc, "Nest level has invalid value in " + nest_level); - } + uint8_t n = convertUint8(nest_level, loc); if (option_universe_ == Option::V6) { - if (n < 0 || n >= HOP_COUNT_LIMIT) { + if (n >= HOP_COUNT_LIMIT) { error(loc, "Nest level has invalid value in " + nest_level + ". Allowed range: 0..31"); - } + } } else { error(loc, "Nest level invalid for DHCPv4 packets"); } diff --cc src/lib/eval/lexer.cc index 6ba140daf2,6b6a1e32f6..69757ba1b3 --- a/src/lib/eval/lexer.cc +++ b/src/lib/eval/lexer.cc @@@ -483,8 -483,8 +483,8 @@@ static void yy_fatal_error (yyconst cha (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 46 --#define YY_END_OF_BUFFER 47 ++#define YY_NUM_RULES 51 ++#define YY_END_OF_BUFFER 52 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@@ -492,58 -492,61 +492,64 @@@ flex_int32_t yy_verify; flex_int32_t yy_nxt; }; - static yyconst flex_int16_t yy_acclist[248] = -static yyconst flex_int16_t yy_acclist[262] = ++static yyconst flex_int16_t yy_acclist[280] = { 0, -- 47, 45, 46, 1, 45, 46, 2, 46, 45, 46, - 40, 45, 46, 41, 45, 46, 44, 45, 46, 45, - 46, 39, 45, 46, 5, 45, 46, 5, 45, 46, - 45, 46, 45, 46, 45, 46,16390, 45, 46,16390, - 42, 45, 46, 43, 45, 46, 45, 46,16390, 45, - 32, 45, 46, 33, 45, 46, 37, 45, 46, 36, - 45, 46, 45, 46, 31, 45, 46, 5, 45, 46, - 5, 45, 46, 45, 46, 45, 46, 45, 46,16390, - 45, 46,16390, 34, 45, 46, 35, 45, 46, 45, -- 46,16390, 45, 46,16390, 45, 46,16390, 45, 46, -- 16390, 45, 46,16390, 45, 46,16390, 45, 46,16390, -- 45, 46,16390, 45, 46,16390, 45, 46,16390, 45, -- 46,16390, 45, 46,16390, 45, 46,16390, 45, 46, - 16390, 45, 46,16390, 1, 2, 3, 5, 5, 7, - 16390, 45, 46,16390, 45, 46,16390, 1, 2, 3, -- - 8,16390,16390, 8198,16390,16390,16390,16390,16390,16390, - 5, 5, 7, 8,16390,16390, 8198,16390,16390,16390, ++ 52, 50, 51, 1, 50, 51, 2, 51, 50, 51, ++ 44, 50, 51, 45, 50, 51, 49, 50, 51, 48, ++ 50, 51, 50, 51, 43, 50, 51, 5, 50, 51, ++ 5, 50, 51, 50, 51, 50, 51, 50, 51,16390, ++ 50, 51,16390, 46, 50, 51, 47, 50, 51, 50, ++ 51,16390, 50, 51,16390, 50, 51,16390, 50, 51, ++ 16390, 50, 51,16390, 50, 51,16390, 50, 51,16390, ++ 50, 51,16390, 50, 51,16390, 50, 51,16390, 50, ++ 51,16390, 50, 51,16390, 50, 51,16390, 50, 51, ++ 16390, 50, 51,16390, 50, 51,16390, 50, 51,16390, ++ ++ 1, 2, 3, 5, 5, 7, 8,16390,16390, 8198, 16390,16390,16390,16390,16390,16390,16390,16390,16390,16390, - 16390, 38,16390,16390,16390,16390,16390,16390,16390,16390, - 16390,16390, 4, 7, 34,16390, 37,16390,16390,16390, - 20,16390,16390,16390, 15,16390,16390,16390,16390, 21, - 16390,16390, 23,16390,16390, 36,16390,16390,16390, 17, - 16390,16390,16390, 30,16390,16390,16390,16390,16390,16390, - 16390,16390,16390,16390, 4, 7, 26,16390, 29,16390, - 16390,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, 43,16390, -- 16390,16390,16390, 19,16390,16390,16390,16390,16390,16390, - 16390,16390,16390, 24,16390,16390,16390,16390,16390,16390, - 16390, 22,16390, 30,16390,16390,16390,16390, 14,16390, - 16390,16390,16390,16390,16390,16390, 25,16390, 18,16390, - 17,16390, 38,16390,16390,16390,16390, 14,16390,16390, - 16390,16390,16390,16390,16390,16390,16390, 20,16390,16390, -- - 16390,16390,16390,16390,16390,16390,16390,16390,16390, 26, - 16390, 35,16390, 16,16390, 27,16390,16390,16390, 9, - 16390,16390, 10,16390, 11,16390, 29,16390,16390,16390, - 28,16390, 7,16390, 31,16390,16390,16390, 32,16390, - 13,16390, 12,16390,16390, 33,16390 - 16390,16390,16390,16390,16390,16390,16390,16390,16390, 21, - 16390, 27,16390,16390, 16,16390, 22,16390,16390,16390, - 9,16390,16390, 10,16390, 11,16390, 24,16390,16390, - 16390, 41,16390, 23,16390, 7,16390,16390, 39,16390, - 16390,16390, 40,16390,16390, 13,16390, 12,16390,16390, - 16390,16390, 25,16390,16390, 44,16390,16390,16390, 42, - 16390 ++ 16390,16390,16390,16390,16390,16390,16390,16390,16390, 42, ++ 16390,16390,16390,16390,16390,16390,16390,16390,16390,16390, ++ 16390, 4, 7, 38,16390, 41,16390,16390,16390,16390, ++ 20,16390,16390,16390,16390, 15,16390,16390,16390,16390, ++ 21,16390,16390, 23,16390,16390, 40,16390,16390,16390, ++ 17,16390,16390,16390, 19,16390,16390,16390,16390,16390, ++ 16390,16390,16390, 35,16390,16390,16390,16390, 24,16390, ++ 16390,16390,16390,16390,16390,16390, 22,16390, 30,16390, ++ ++ 16390,16390,16390, 14,16390,16390,16390,16390,16390,16390, ++ 16390,16390,16390, 25,16390, 18,16390,16390,16390,16390, ++ 16390,16390,16390,16390,16390,16390,16390, 26,16390, 39, ++ 16390,16390, 16,16390, 27,16390,16390,16390, 9,16390, ++ 16390, 10,16390, 11,16390, 29,16390,16390,16390, 33, ++ 16390, 28,16390, 7,16390,16390, 31,16390,16390,16390, ++ 32,16390,16390, 13,16390, 12,16390,16390,16390,16390, ++ 37,16390,16390, 36,16390,16390,16390, 34,16390 } ; - static yyconst flex_int16_t yy_accept[174] = -static yyconst flex_int16_t yy_accept[188] = ++static yyconst flex_int16_t yy_accept[199] = { 0, 1, 1, 1, 2, 4, 7, 9, 11, 14, 17, - 20, 22, 25, 28, 31, 33, 35, 38, 41, 44, + 20, 23, 25, 28, 31, 34, 36, 38, 41, 44, 47, 50, 53, 56, 59, 62, 65, 68, 71, 74, - 77, 80, 83, 86, 89, 92, 95, 96, 97, 97, - 98, 99, 99, 100, 100, 100, 100, 100, 101, 102, - 102, 102, 103, 104, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, - 121, 122, 124, 125, 126, 127, 128, 129, 130, 131, - 132, 133, 133, 134, 135, 137, 139, 140, 141, 143, - 144, 145, 147, 148, 149, 150, 152, 153, 155, 156, - 77, 80, 83, 86, 89, 92, 95, 98, 99, 100, - 100, 101, 102, 102, 103, 103, 103, 103, 103, 104, - 105, 105, 105, 106, 107, 108, 109, 110, 111, 112, - 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, - 123, 124, 126, 127, 128, 129, 130, 131, 132, 133, - 134, 135, 135, 136, 137, 139, 141, 142, 143, 144, - 145, 146, 147, 149, 150, 151, 152, 154, 155, 157, -- - 158, 159, 160, 162, 163, 164, 166, 167, 168, 169, - 170, 170, 171, 172, 173, 174, 176, 177, 178, 179, - 180, 181, 182, 184, 186, 187, 188, 189, 191, 192, - 193, 193, 194, 195, 196, 197, 199, 201, 202, 203, - 204, 205, 206, 207, 208, 209, 210, 210, 212, 214, - 216, 218, 219, 220, 222, 223, 225, 227, 229, 230, - 231, 233, 234, 235, 237, 238, 239, 241, 243, 245, - 246, 248, 248 - 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, - 167, 168, 169, 171, 172, 173, 174, 176, 177, 178, - 179, 180, 181, 183, 185, 186, 187, 188, 190, 191, - 192, 193, 193, 194, 195, 196, 197, 198, 200, 201, - 202, 203, 204, 205, 206, 207, 208, 209, 210, 210, - 212, 214, 215, 217, 219, 220, 221, 223, 224, 226, - 228, 230, 231, 232, 234, 236, 237, 238, 239, 241, - 242, 243, 245, 245, 246, 248, 250, 251, 252, 253, - 255, 256, 258, 259, 260, 262, 262 ++ 77, 80, 83, 86, 89, 92, 95, 98, 101, 102, ++ 103, 103, 104, 105, 105, 106, 106, 106, 106, 106, ++ 107, 108, 108, 108, 109, 110, 111, 112, 113, 114, ++ 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, ++ 125, 126, 127, 128, 129, 130, 132, 133, 134, 135, ++ 136, 137, 138, 139, 140, 141, 142, 142, 143, 144, ++ 146, 148, 149, 150, 151, 153, 154, 155, 156, 158, ++ ++ 159, 160, 161, 163, 164, 166, 167, 169, 170, 171, ++ 173, 174, 175, 177, 178, 179, 180, 181, 182, 182, ++ 183, 184, 186, 187, 188, 189, 191, 192, 193, 194, ++ 195, 196, 197, 199, 201, 202, 203, 204, 206, 207, ++ 208, 209, 209, 210, 211, 212, 213, 214, 216, 218, ++ 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, ++ 228, 230, 232, 233, 235, 237, 238, 239, 241, 242, ++ 244, 246, 248, 249, 250, 252, 254, 255, 256, 257, ++ 259, 260, 261, 263, 263, 264, 266, 268, 269, 270, ++ 271, 273, 274, 276, 277, 278, 280, 280 ++ } ; static yyconst YY_CHAR yy_ec[256] = @@@ -552,16 -555,16 +558,16 @@@ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 4, 5, - 6, 1, 1, 7, 8, 9, 1, 10, 11, 11, - 11, 12, 11, 13, 11, 11, 11, 14, 1, 1, - 15, 1, 1, 1, 16, 16, 16, 16, 16, 16, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 18, 17, 17, - 19, 1, 20, 1, 21, 1, 22, 23, 24, 25, - - 26, 27, 28, 29, 30, 17, 31, 32, 33, 34, - 35, 36, 17, 37, 38, 39, 40, 17, 17, 41, - 42, 17, 1, 1, 1, 1, 1, 1, 1, 1, + 6, 7, 1, 8, 9, 10, 1, 11, 12, 12, + 12, 13, 12, 14, 12, 12, 12, 15, 1, 1, + 16, 1, 1, 1, 17, 17, 17, 17, 17, 17, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 19, 18, 18, + 20, 1, 21, 1, 22, 1, 23, 24, 25, 26, + - 27, 17, 28, 29, 30, 18, 31, 32, 33, 34, - 35, 36, 18, 37, 38, 39, 40, 41, 18, 42, - 43, 18, 1, 1, 1, 1, 1, 1, 1, 1, ++ 27, 28, 29, 30, 31, 18, 32, 33, 34, 35, ++ 36, 37, 18, 38, 39, 40, 41, 42, 18, 43, ++ 44, 18, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@@ -578,158 -581,166 +584,172 @@@ 1, 1, 1, 1, 1 } ; - static yyconst YY_CHAR yy_meta[43] = -static yyconst YY_CHAR yy_meta[44] = ++static yyconst YY_CHAR yy_meta[45] = { 0, - 1, 1, 2, 1, 1, 1, 1, 1, 3, 4, - 4, 4, 4, 5, 1, 4, 1, 1, 1, 1, - 1, 4, 4, 4, 4, 4, 4, 1, 1, 1, + 1, 1, 2, 1, 1, 1, 1, 1, 1, 3, + 4, 4, 4, 4, 5, 1, 4, 1, 1, 1, - 1, 1, 4, 4, 4, 4, 4, 1, 1, 1, ++ 1, 1, 4, 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 } ; - static yyconst flex_uint16_t yy_base[178] = -static yyconst flex_uint16_t yy_base[192] = ++static yyconst flex_uint16_t yy_base[203] = { 0, - 0, 0, 281, 282, 278, 276, 274, 282, 282, 282, - 33, 282, 38, 35, 263, 261, 78, 111, 282, 282, - 23, 36, 237, 233, 243, 43, 245, 42, 36, 236, - 41, 100, 244, 102, 33, 239, 266, 264, 262, 282, - 133, 137, 110, 251, 250, 0, 249, 0, 282, 138, - 150, 0, 0, 282, 230, 236, 238, 225, 219, 227, - 234, 214, 228, 211, 230, 217, 216, 225, 220, 208, - 207, 0, 219, 205, 211, 220, 217, 217, 198, 216, - 215, 150, 0, 0, 0, 0, 211, 211, 0, 196, - 208, 0, 198, 195, 206, 0, 198, 0, 189, 0, - 0, 0, 296, 297, 293, 291, 289, 297, 297, 297, - 297, 33, 297, 38, 35, 277, 275, 79, 112, 297, - 297, 24, 36, 267, 25, 259, 46, 258, 37, 252, - 32, 43, 259, 46, 52, 258, 254, 281, 279, 277, - 297, 119, 129, 53, 265, 264, 0, 263, 0, 297, - 142, 144, 0, 0, 297, 245, 250, 252, 240, 234, - 233, 241, 247, 227, 241, 224, 232, 240, 236, 224, - 223, 0, 234, 221, 227, 235, 233, 214, 232, 220, - 230, 138, 0, 0, 0, 0, 226, 226, 227, 222, - 210, 221, 0, 212, 209, 213, 0, 204, 0, 212, -- - 197, 189, 71, 203, 199, 0, 185, 183, 187, 195, - 144, 194, 196, 178, 191, 0, 189, 188, 191, 170, - 176, 188, 0, 0, 167, 183, 168, 0, 168, 180, - 155, 167, 164, 164, 164, 0, 0, 175, 163, 164, - 172, 117, 159, 158, 164, 156, 161, 0, 0, 0, - 0, 167, 165, 0, 155, 0, 0, 0, 139, 72, - 0, 165, 56, 0, 50, 51, 0, 0, 0, 45, - 0, 282, 178, 180, 182, 63, 185 - 204, 70, 217, 213, 200, 198, 202, 209, 208, 142, - 207, 209, 0, 194, 191, 203, 0, 201, 204, 183, - 190, 201, 0, 0, 180, 196, 182, 0, 182, 184, - 192, 147, 180, 177, 179, 176, 176, 0, 186, 165, - 164, 171, 153, 159, 157, 163, 155, 154, 157, 0, - 0, 153, 0, 0, 163, 161, 0, 161, 0, 0, - 0, 156, 159, 175, 0, 161, 153, 145, 0, 144, - 146, 0, 174, 141, 0, 0, 150, 132, 135, 0, - 111, 0, 90, 61, 0, 297, 199, 201, 203, 83, - 206 - ++ 0, 0, 310, 311, 307, 305, 303, 311, 311, 311, ++ 311, 34, 311, 39, 36, 291, 289, 81, 115, 311, ++ 311, 24, 37, 37, 26, 273, 45, 275, 43, 48, ++ 266, 43, 59, 274, 106, 50, 273, 268, 296, 294, ++ 292, 311, 122, 137, 112, 280, 279, 0, 278, 0, ++ 311, 143, 150, 0, 0, 311, 259, 265, 267, 254, ++ 248, 247, 246, 254, 261, 240, 255, 237, 257, 244, ++ 243, 252, 247, 235, 234, 0, 246, 232, 238, 247, ++ 244, 244, 224, 243, 230, 241, 146, 0, 0, 0, ++ 0, 237, 237, 238, 0, 233, 220, 232, 0, 222, ++ ++ 219, 230, 0, 222, 0, 213, 0, 221, 213, 148, ++ 227, 223, 0, 209, 207, 211, 219, 218, 154, 217, ++ 219, 0, 203, 200, 213, 0, 211, 210, 213, 191, ++ 198, 210, 0, 0, 188, 205, 190, 0, 190, 192, ++ 201, 162, 188, 185, 187, 184, 184, 0, 0, 195, ++ 173, 172, 180, 156, 167, 165, 171, 163, 162, 166, ++ 0, 0, 161, 0, 0, 172, 170, 0, 170, 0, ++ 0, 0, 164, 168, 184, 0, 170, 161, 153, 0, ++ 152, 154, 0, 183, 149, 0, 0, 158, 130, 127, ++ 0, 78, 0, 58, 50, 0, 311, 208, 210, 212, ++ ++ 71, 215 } ; - static yyconst flex_int16_t yy_def[178] = -static yyconst flex_int16_t yy_def[192] = ++static yyconst flex_int16_t yy_def[203] = { 0, - 172, 1, 172, 172, 172, 172, 173, 172, 172, 172, - 172, 172, 172, 13, 174, 172, 172, 17, 172, 172, - 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 172, 172, 173, 172, - 172, 172, 13, 174, 175, 176, 174, 177, 172, 172, - 18, 17, 18, 172, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 172, 176, 177, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 172, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 172, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 172, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 172, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 0, 172, 172, 172, 172, 172 - 186, 1, 186, 186, 186, 186, 187, 186, 186, 186, - 186, 186, 186, 186, 14, 188, 186, 186, 18, 186, - 186, 18, 18, 18, 18, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 186, 186, 187, - 186, 186, 186, 14, 188, 189, 190, 188, 191, 186, - 186, 19, 18, 19, 186, 19, 19, 19, 19, 18, ++ 197, 1, 197, 197, 197, 197, 198, 197, 197, 197, ++ 197, 197, 197, 197, 14, 199, 197, 197, 18, 197, ++ 197, 18, 18, 18, 18, 19, 19, 19, 19, 19, ++ 19, 19, 19, 19, 19, 19, 19, 19, 197, 197, ++ 198, 197, 197, 197, 14, 199, 200, 201, 199, 202, ++ 197, 197, 19, 18, 19, 197, 19, 19, 19, 19, ++ 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 186, 190, 191, 19, 19, 19, 19, 19, 19, ++ 19, 19, 19, 19, 19, 19, 197, 201, 202, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + - 19, 19, 19, 19, 19, 19, 19, 19, 19, 186, ++ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, ++ 19, 19, 19, 19, 19, 19, 19, 19, 197, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 186, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 186, 19, ++ 19, 197, 19, 19, 19, 19, 19, 19, 19, 19, ++ 19, 19, 19, 19, 19, 19, 19, 19, 19, 197, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 186, 19, 19, 19, 19, ++ 19, 19, 19, 19, 19, 19, 197, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 0, 186, 186, 186, 186, - 186 ++ 19, 19, 19, 19, 19, 19, 0, 197, 197, 197, + ++ 197, 197 } ; - static yyconst flex_uint16_t yy_nxt[325] = -static yyconst flex_uint16_t yy_nxt[341] = ++static yyconst flex_uint16_t yy_nxt[356] = { 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, 23, 24, 17, 25, 26, 27, - 18, 28, 29, 30, 31, 32, 33, 34, 35, 18, - 18, 36, 41, 41, 41, 41, 42, 43, 43, 43, - 43, 44, 172, 45, 55, 46, 56, 68, 79, 45, - 45, 45, 45, 45, 45, 57, 83, 66, 62, 80, - 58, 67, 171, 69, 63, 172, 71, 72, 46, 50, - 50, 64, 123, 124, 170, 51, 169, 52, 52, 52, - 52, 44, 168, 52, 53, 53, 167, 54, 51, 52, - - 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 172, 73, 53, 172, 156, 157, - 74, 76, 53, 53, 53, 53, 53, 53, 77, 50, - 50, 78, 41, 41, 41, 41, 82, 82, 82, 82, - 172, 172, 172, 131, 131, 131, 131, 54, 111, 82, - 82, 82, 82, 147, 131, 131, 131, 131, 166, 172, - 162, 162, 162, 162, 162, 162, 162, 162, 39, 165, - 39, 39, 39, 47, 47, 45, 45, 84, 84, 84, - 164, 163, 161, 160, 159, 158, 155, 154, 153, 152, - - 151, 150, 149, 148, 146, 145, 144, 143, 142, 141, - 140, 139, 138, 137, 136, 135, 134, 133, 132, 130, - 129, 128, 127, 126, 125, 122, 121, 120, 119, 118, - 117, 116, 115, 114, 113, 112, 110, 109, 108, 107, - 106, 105, 104, 103, 102, 101, 100, 99, 98, 97, - 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, - 86, 85, 48, 44, 48, 40, 38, 37, 81, 75, - 70, 65, 61, 60, 59, 49, 48, 40, 38, 37, - 172, 3, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172 + 14, 15, 15, 15, 16, 17, 18, 19, 19, 20, - 21, 4, 22, 18, 23, 24, 25, 26, 27, 19, - 19, 28, 29, 30, 31, 32, 33, 34, 35, 19, - 36, 19, 37, 42, 42, 42, 42, 43, 44, 44, - 44, 44, 45, 186, 46, 56, 47, 57, 61, 68, - 46, 46, 46, 46, 46, 58, 62, 71, 72, 73, - 59, 186, 64, 74, 69, 76, 186, 65, 78, 47, - 51, 51, 123, 124, 66, 77, 83, 52, 79, 53, - 53, 53, 53, 45, 186, 53, 54, 54, 185, 55, - - 52, 53, 53, 53, 53, 53, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 186, 184, 54, 42, - 42, 42, 42, 183, 54, 54, 54, 54, 54, 82, - 82, 82, 82, 51, 51, 186, 186, 110, 82, 82, - 82, 82, 132, 132, 132, 132, 149, 132, 132, 132, - 132, 182, 55, 181, 186, 159, 160, 166, 166, 166, - 166, 166, 166, 166, 166, 186, 186, 180, 179, 177, - 176, 175, 174, 173, 172, 171, 170, 169, 168, 167, - 165, 164, 163, 162, 186, 161, 158, 157, 178, 40, - - 156, 40, 40, 40, 48, 48, 46, 46, 84, 84, - 84, 155, 154, 153, 152, 151, 150, 148, 147, 146, - 145, 144, 143, 142, 141, 140, 139, 138, 137, 136, - 135, 134, 133, 131, 130, 129, 128, 127, 126, 125, - 122, 121, 120, 119, 118, 117, 116, 115, 114, 113, - 112, 111, 109, 108, 107, 106, 105, 104, 103, 102, ++ 21, 4, 22, 18, 23, 24, 25, 18, 26, 27, ++ 28, 19, 29, 30, 31, 32, 33, 34, 35, 36, ++ 19, 37, 19, 38, 43, 43, 43, 43, 44, 45, ++ 45, 45, 45, 46, 197, 47, 57, 48, 58, 61, ++ 63, 47, 47, 47, 47, 47, 47, 59, 64, 70, ++ 72, 66, 60, 71, 88, 62, 83, 67, 197, 75, ++ 76, 48, 52, 52, 68, 77, 73, 84, 196, 53, ++ 78, 54, 54, 54, 54, 46, 195, 54, 55, 55, ++ ++ 194, 56, 53, 54, 54, 54, 54, 54, 54, 55, ++ 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, ++ 55, 55, 55, 55, 55, 55, 55, 55, 55, 197, ++ 197, 55, 43, 43, 43, 43, 80, 55, 55, 55, ++ 55, 55, 55, 81, 52, 52, 82, 87, 87, 87, ++ 87, 197, 197, 193, 197, 119, 87, 87, 87, 87, ++ 133, 134, 192, 56, 142, 142, 142, 142, 170, 171, ++ 197, 160, 142, 142, 142, 142, 177, 177, 177, 177, ++ 177, 177, 177, 177, 197, 197, 191, 190, 188, 187, ++ 186, 185, 184, 183, 182, 181, 180, 179, 178, 176, ++ ++ 175, 174, 173, 197, 172, 169, 168, 189, 41, 167, ++ 41, 41, 41, 49, 49, 47, 47, 89, 89, 89, ++ 166, 165, 164, 163, 162, 161, 159, 158, 157, 156, ++ 155, 154, 153, 152, 151, 150, 149, 148, 147, 146, ++ 145, 144, 143, 141, 140, 139, 138, 137, 136, 135, ++ 132, 131, 130, 129, 128, 127, 126, 125, 124, 123, ++ 122, 121, 120, 118, 117, 116, 115, 114, 113, 112, ++ 111, 110, 109, 108, 107, 106, 105, 104, 103, 102, + 101, 100, 99, 98, 97, 96, 95, 94, 93, 92, - 91, 90, 89, 88, 87, 86, 85, 49, 45, 49, - 41, 39, 38, 81, 80, 75, 70, 67, 63, 60, - 50, 49, 41, 39, 38, 186, 3, 186, 186, 186, - - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186 ++ 91, 90, 50, 46, 50, 42, 40, 39, 86, 85, ++ ++ 79, 74, 69, 65, 51, 50, 42, 40, 39, 197, ++ 3, 197, 197, 197, 197, 197, 197, 197, 197, 197, ++ 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, ++ 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, ++ 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, ++ 197, 197, 197, 197, 197 } ; - static yyconst flex_int16_t yy_chk[325] = -static yyconst flex_int16_t yy_chk[341] = ++static yyconst flex_int16_t yy_chk[356] = { 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, 1, 11, 11, 11, 11, 13, 13, 13, 13, - 13, 13, 14, 13, 21, 13, 21, 29, 35, 13, - 13, 13, 13, 13, 13, 22, 176, 28, 26, 35, - 22, 28, 170, 29, 26, 14, 31, 31, 13, 17, - 17, 26, 103, 103, 166, 17, 165, 17, 17, 17, - 17, 17, 163, 17, 17, 17, 160, 17, 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, 32, 18, 43, 142, 142, - 32, 34, 18, 18, 18, 18, 18, 18, 34, 50, - 50, 34, 41, 41, 41, 41, 42, 42, 42, 42, - 43, 51, 51, 111, 111, 111, 111, 50, 82, 82, - 82, 82, 82, 131, 131, 131, 131, 131, 159, 51, - 147, 147, 147, 147, 162, 162, 162, 162, 173, 155, - 173, 173, 173, 174, 174, 175, 175, 177, 177, 177, - 153, 152, 146, 145, 144, 143, 141, 140, 139, 138, - - 135, 134, 133, 132, 130, 129, 127, 126, 125, 122, - 121, 120, 119, 118, 117, 115, 114, 113, 112, 110, - 109, 108, 107, 105, 104, 102, 101, 99, 97, 95, - 94, 93, 91, 90, 88, 87, 81, 80, 79, 78, - 77, 76, 75, 74, 73, 71, 70, 69, 68, 67, - 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, - 56, 55, 47, 45, 44, 39, 38, 37, 36, 33, - 30, 27, 25, 24, 23, 16, 15, 7, 6, 5, - 3, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 1, 1, 1, 12, 12, 12, 12, 14, 14, 14, - 14, 14, 14, 15, 14, 22, 14, 22, 25, 29, - 14, 14, 14, 14, 14, 23, 25, 31, 31, 32, - 23, 44, 27, 32, 29, 34, 15, 27, 35, 14, - 18, 18, 102, 102, 27, 34, 190, 18, 35, 18, - 18, 18, 18, 18, 44, 18, 18, 18, 184, 18, -- - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, - 172, 172, 172, 172 ++ 1, 1, 1, 1, 12, 12, 12, 12, 14, 14, ++ 14, 14, 14, 14, 15, 14, 22, 14, 22, 24, ++ 25, 14, 14, 14, 14, 14, 14, 23, 25, 29, ++ 30, 27, 23, 29, 201, 24, 36, 27, 15, 32, ++ 32, 14, 18, 18, 27, 33, 30, 36, 195, 18, ++ 33, 18, 18, 18, 18, 18, 194, 18, 18, 18, ++ ++ 192, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 19, 19, 19, 19, 19, 183, 19, 42, - 42, 42, 42, 181, 19, 19, 19, 19, 19, 43, - 43, 43, 43, 51, 51, 52, 52, 82, 82, 82, - 82, 82, 110, 110, 110, 110, 132, 132, 132, 132, - 132, 179, 51, 178, 52, 143, 143, 149, 149, 149, - 149, 166, 166, 166, 166, 173, 173, 177, 174, 171, - 170, 168, 167, 164, 163, 162, 158, 156, 155, 152, - 148, 147, 146, 145, 173, 144, 142, 141, 173, 187, - - 140, 187, 187, 187, 188, 188, 189, 189, 191, 191, - 191, 139, 137, 136, 135, 134, 133, 131, 130, 129, - 127, 126, 125, 122, 121, 120, 119, 118, 116, 115, - 114, 112, 111, 109, 108, 107, 106, 105, 104, 103, - 101, 100, 98, 96, 95, 94, 92, 91, 90, 89, - 88, 87, 81, 80, 79, 78, 77, 76, 75, 74, - 73, 71, 70, 69, 68, 67, 66, 65, 64, 63, - 62, 61, 60, 59, 58, 57, 56, 48, 46, 45, - 40, 39, 38, 37, 36, 33, 30, 28, 26, 24, - 17, 16, 7, 6, 5, 3, 186, 186, 186, 186, - - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186, - 186, 186, 186, 186, 186, 186, 186, 186, 186, 186 ++ 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, ++ 45, 19, 43, 43, 43, 43, 35, 19, 19, 19, ++ 19, 19, 19, 35, 52, 52, 35, 44, 44, 44, ++ 44, 53, 53, 190, 45, 87, 87, 87, 87, 87, ++ 110, 110, 189, 52, 119, 119, 119, 119, 154, 154, ++ 53, 142, 142, 142, 142, 142, 160, 160, 160, 160, ++ 177, 177, 177, 177, 184, 184, 188, 185, 182, 181, ++ 179, 178, 175, 174, 173, 169, 167, 166, 163, 159, ++ ++ 158, 157, 156, 184, 155, 153, 152, 184, 198, 151, ++ 198, 198, 198, 199, 199, 200, 200, 202, 202, 202, ++ 150, 147, 146, 145, 144, 143, 141, 140, 139, 137, ++ 136, 135, 132, 131, 130, 129, 128, 127, 125, 124, ++ 123, 121, 120, 118, 117, 116, 115, 114, 112, 111, ++ 109, 108, 106, 104, 102, 101, 100, 98, 97, 96, ++ 94, 93, 92, 86, 85, 84, 83, 82, 81, 80, ++ 79, 78, 77, 75, 74, 73, 72, 71, 70, 69, ++ 68, 67, 66, 65, 64, 63, 62, 61, 60, 59, ++ 58, 57, 49, 47, 46, 41, 40, 39, 38, 37, ++ ++ 34, 31, 28, 26, 17, 16, 7, 6, 5, 3, ++ 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, ++ 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, ++ 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, ++ 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, ++ 197, 197, 197, 197, 197 } ; /* Table of booleans, true if rule could match eol. */ --static yyconst flex_int32_t yy_rule_can_match_eol[47] = ++static yyconst flex_int32_t yy_rule_can_match_eol[52] = { 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, 0, 0, 0, }; extern int yy_flex_debug; int yy_flex_debug = 1; --static yyconst flex_int16_t yy_rule_linenum[46] = ++static yyconst flex_int16_t yy_rule_linenum[51] = { 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, 164, 165, - 166, 167, 168, 169, 170, 171, 172, 174, 175, 176, - 177, 178, 179, 180, 182 + 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, - 176, 177, 178, 179, 181 ++ 176, 177, 178, 179, 180, 181, 182, 183, 184, 185 } ; static yy_state_type *yy_state_buf=0, *yy_state_ptr=0; @@@ -808,7 -819,7 +828,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 812 "lexer.cc" -#line 823 "lexer.cc" ++#line 832 "lexer.cc" #define INITIAL 0 @@@ -1105,7 -1116,7 +1125,7 @@@ YY_DEC loc.step(); - #line 1109 "lexer.cc" -#line 1120 "lexer.cc" ++#line 1129 "lexer.cc" while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { @@@ -1133,14 -1144,14 +1153,14 @@@ yy_match 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 >= 173 ) - if ( yy_current_state >= 187 ) ++ if ( yy_current_state >= 198 ) 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 != 172 ); - while ( yy_current_state != 186 ); ++ while ( yy_current_state != 197 ); yy_find_action: /* %% [10.0] code to find the action number goes here */ @@@ -1203,13 -1214,13 +1223,13 @@@ do_action: /* This label is used only t { if ( yy_act == 0 ) fprintf( stderr, "--scanner backing up\n" ); -- else if ( yy_act < 46 ) ++ else if ( yy_act < 51 ) fprintf( stderr, "--accepting rule at line %ld (\"%s\")\n", (long)yy_rule_linenum[yy_act], yytext ); -- else if ( yy_act == 46 ) ++ else if ( yy_act == 51 ) fprintf( stderr, "--accepting default rule (\"%s\")\n", yytext ); -- else if ( yy_act == 47 ) ++ else if ( yy_act == 52 ) fprintf( stderr, "--(end of buffer or a NUL)\n" ); else fprintf( stderr, "--EOF (start condition %d)\n", YY_START ); @@@ -1431,78 -1442,78 +1451,103 @@@ return isc::eval::EvalParser::make_TRAN case 33: YY_RULE_SETUP #line 168 "lexer.ll" - return isc::eval::EvalParser::make_SUBSTRING(loc); -return isc::eval::EvalParser::make_RPAREN(loc); ++return isc::eval::EvalParser::make_VENDOR(loc); YY_BREAK case 34: YY_RULE_SETUP #line 169 "lexer.ll" - return isc::eval::EvalParser::make_ALL(loc); -return isc::eval::EvalParser::make_LBRACKET(loc); ++return isc::eval::EvalParser::make_VENDOR_CLASS(loc); YY_BREAK case 35: YY_RULE_SETUP #line 170 "lexer.ll" - return isc::eval::EvalParser::make_CONCAT(loc); -return isc::eval::EvalParser::make_RBRACKET(loc); ++return isc::eval::EvalParser::make_DATA(loc); YY_BREAK case 36: YY_RULE_SETUP #line 171 "lexer.ll" - return isc::eval::EvalParser::make_NOT(loc); -return isc::eval::EvalParser::make_COMA(loc); ++return isc::eval::EvalParser::make_ENTERPRISE(loc); YY_BREAK case 37: YY_RULE_SETUP #line 172 "lexer.ll" - return isc::eval::EvalParser::make_AND(loc); -return isc::eval::EvalParser::make_ANY(loc); ++return isc::eval::EvalParser::make_SUBSTRING(loc); YY_BREAK case 38: YY_RULE_SETUP -#line 174 "lexer.ll" -return isc::eval::EvalParser::make_PKT6(loc); +#line 173 "lexer.ll" - return isc::eval::EvalParser::make_OR(loc); ++return isc::eval::EvalParser::make_ALL(loc); YY_BREAK case 39: YY_RULE_SETUP -#line 175 "lexer.ll" -return isc::eval::EvalParser::make_MSGTYPE(loc); +#line 174 "lexer.ll" - return isc::eval::EvalParser::make_DOT(loc); ++return isc::eval::EvalParser::make_CONCAT(loc); YY_BREAK case 40: YY_RULE_SETUP -#line 176 "lexer.ll" -return isc::eval::EvalParser::make_TRANSID(loc); +#line 175 "lexer.ll" - return isc::eval::EvalParser::make_LPAREN(loc); ++return isc::eval::EvalParser::make_NOT(loc); YY_BREAK case 41: YY_RULE_SETUP -#line 177 "lexer.ll" -return isc::eval::EvalParser::make_VENDOR(loc); +#line 176 "lexer.ll" - return isc::eval::EvalParser::make_RPAREN(loc); ++return isc::eval::EvalParser::make_AND(loc); YY_BREAK case 42: YY_RULE_SETUP -#line 178 "lexer.ll" -return isc::eval::EvalParser::make_VENDOR_CLASS(loc); +#line 177 "lexer.ll" - return isc::eval::EvalParser::make_LBRACKET(loc); ++return isc::eval::EvalParser::make_OR(loc); YY_BREAK case 43: YY_RULE_SETUP -#line 179 "lexer.ll" -return isc::eval::EvalParser::make_DATA(loc); +#line 178 "lexer.ll" - return isc::eval::EvalParser::make_RBRACKET(loc); ++return isc::eval::EvalParser::make_DOT(loc); YY_BREAK case 44: YY_RULE_SETUP -#line 180 "lexer.ll" -return isc::eval::EvalParser::make_ENTERPRISE(loc); +#line 179 "lexer.ll" - return isc::eval::EvalParser::make_COMA(loc); ++return isc::eval::EvalParser::make_LPAREN(loc); YY_BREAK case 45: YY_RULE_SETUP ++#line 180 "lexer.ll" ++return isc::eval::EvalParser::make_RPAREN(loc); ++ YY_BREAK ++case 46: ++YY_RULE_SETUP +#line 181 "lexer.ll" ++return isc::eval::EvalParser::make_LBRACKET(loc); ++ YY_BREAK ++case 47: ++YY_RULE_SETUP + #line 182 "lexer.ll" ++return isc::eval::EvalParser::make_RBRACKET(loc); ++ YY_BREAK ++case 48: ++YY_RULE_SETUP ++#line 183 "lexer.ll" ++return isc::eval::EvalParser::make_COMA(loc); ++ YY_BREAK ++case 49: ++YY_RULE_SETUP ++#line 184 "lexer.ll" ++return isc::eval::EvalParser::make_ANY(loc); ++ YY_BREAK ++case 50: ++YY_RULE_SETUP ++#line 185 "lexer.ll" driver.error (loc, "Invalid character: " + std::string(yytext)); YY_BREAK case YY_STATE_EOF(INITIAL): - #line 182 "lexer.ll" -#line 183 "lexer.ll" ++#line 186 "lexer.ll" return isc::eval::EvalParser::make_END(loc); YY_BREAK --case 46: ++case 51: YY_RULE_SETUP - #line 183 "lexer.ll" -#line 184 "lexer.ll" ++#line 187 "lexer.ll" ECHO; YY_BREAK - #line 1506 "lexer.cc" -#line 1517 "lexer.cc" ++#line 1551 "lexer.cc" case YY_END_OF_BUFFER: { @@@ -1787,7 -1798,7 +1832,7 @@@ static int yy_get_next_buffer (void 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 >= 173 ) - if ( yy_current_state >= 187 ) ++ if ( yy_current_state >= 198 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@@ -1815,11 -1826,11 +1860,11 @@@ 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 >= 173 ) - if ( yy_current_state >= 187 ) ++ if ( yy_current_state >= 198 ) 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 == 172); - yy_is_jam = (yy_current_state == 186); ++ yy_is_jam = (yy_current_state == 197); if ( ! yy_is_jam ) *(yy_state_ptr)++ = yy_current_state; @@@ -2585,7 -2596,7 +2630,7 @@@ void yyfree (void * ptr /* %ok-for-header */ - #line 183 "lexer.ll" -#line 184 "lexer.ll" ++#line 187 "lexer.ll" diff --cc src/lib/eval/lexer.ll index f7e489b339,7cb52ee349..fdefcecd63 --- a/src/lib/eval/lexer.ll +++ b/src/lib/eval/lexer.ll @@@ -140,46 -140,47 +140,50 @@@ addr6 [0-9a-fA-F]*\:[0-9a-fA-F]*\:[0-9a return isc::eval::EvalParser::make_IP_ADDRESS(yytext, loc); } - "==" return isc::eval::EvalParser::make_EQUAL(loc); - "option" return isc::eval::EvalParser::make_OPTION(loc); - "relay4" return isc::eval::EvalParser::make_RELAY4(loc); - "relay6" return isc::eval::EvalParser::make_RELAY6(loc); - "peeraddr" return isc::eval::EvalParser::make_PEERADDR(loc); - "linkaddr" return isc::eval::EvalParser::make_LINKADDR(loc); - "text" return isc::eval::EvalParser::make_TEXT(loc); - "hex" return isc::eval::EvalParser::make_HEX(loc); - "exists" return isc::eval::EvalParser::make_EXISTS(loc); - "pkt" return isc::eval::EvalParser::make_PKT(loc); - "iface" return isc::eval::EvalParser::make_IFACE(loc); - "src" return isc::eval::EvalParser::make_SRC(loc); - "dst" return isc::eval::EvalParser::make_DST(loc); - "len" return isc::eval::EvalParser::make_LEN(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); - "pkt6" return isc::eval::EvalParser::make_PKT6(loc); - "msgtype" return isc::eval::EvalParser::make_MSGTYPE(loc); - "transid" return isc::eval::EvalParser::make_TRANSID(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); - "not" return isc::eval::EvalParser::make_NOT(loc); - "and" return isc::eval::EvalParser::make_AND(loc); - "or" return isc::eval::EvalParser::make_OR(loc); - "." return isc::eval::EvalParser::make_DOT(loc); - "(" return isc::eval::EvalParser::make_LPAREN(loc); - ")" return isc::eval::EvalParser::make_RPAREN(loc); - "[" return isc::eval::EvalParser::make_LBRACKET(loc); - "]" return isc::eval::EvalParser::make_RBRACKET(loc); - "," return isc::eval::EvalParser::make_COMA(loc); - + "==" return isc::eval::EvalParser::make_EQUAL(loc); + "option" return isc::eval::EvalParser::make_OPTION(loc); + "relay4" return isc::eval::EvalParser::make_RELAY4(loc); + "relay6" return isc::eval::EvalParser::make_RELAY6(loc); + "peeraddr" return isc::eval::EvalParser::make_PEERADDR(loc); + "linkaddr" return isc::eval::EvalParser::make_LINKADDR(loc); + "text" return isc::eval::EvalParser::make_TEXT(loc); + "hex" return isc::eval::EvalParser::make_HEX(loc); + "exists" return isc::eval::EvalParser::make_EXISTS(loc); ++"pkt" return isc::eval::EvalParser::make_PKT(loc); ++"iface" return isc::eval::EvalParser::make_IFACE(loc); ++"src" return isc::eval::EvalParser::make_SRC(loc); ++"dst" return isc::eval::EvalParser::make_DST(loc); ++"len" return isc::eval::EvalParser::make_LEN(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); ++"pkt6" return isc::eval::EvalParser::make_PKT6(loc); ++"msgtype" return isc::eval::EvalParser::make_MSGTYPE(loc); ++"transid" return isc::eval::EvalParser::make_TRANSID(loc); ++"vendor" return isc::eval::EvalParser::make_VENDOR(loc); ++"vendor-class" return isc::eval::EvalParser::make_VENDOR_CLASS(loc); ++"data" return isc::eval::EvalParser::make_DATA(loc); ++"enterprise" return isc::eval::EvalParser::make_ENTERPRISE(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); + "not" return isc::eval::EvalParser::make_NOT(loc); + "and" return isc::eval::EvalParser::make_AND(loc); + "or" return isc::eval::EvalParser::make_OR(loc); + "." return isc::eval::EvalParser::make_DOT(loc); + "(" return isc::eval::EvalParser::make_LPAREN(loc); + ")" return isc::eval::EvalParser::make_RPAREN(loc); + "[" return isc::eval::EvalParser::make_LBRACKET(loc); + "]" return isc::eval::EvalParser::make_RBRACKET(loc); + "," return isc::eval::EvalParser::make_COMA(loc); + "*" return isc::eval::EvalParser::make_ANY(loc); - -"pkt6" return isc::eval::EvalParser::make_PKT6(loc); -"msgtype" return isc::eval::EvalParser::make_MSGTYPE(loc); -"transid" return isc::eval::EvalParser::make_TRANSID(loc); -"vendor" return isc::eval::EvalParser::make_VENDOR(loc); -"vendor-class" return isc::eval::EvalParser::make_VENDOR_CLASS(loc); -"data" return isc::eval::EvalParser::make_DATA(loc); -"enterprise" return isc::eval::EvalParser::make_ENTERPRISE(loc); - -. driver.error (loc, "Invalid character: " + std::string(yytext)); -<> return isc::eval::EvalParser::make_END(loc); +. driver.error (loc, "Invalid character: " + std::string(yytext)); +<> return isc::eval::EvalParser::make_END(loc); %% using namespace isc::eval; diff --cc src/lib/eval/parser.cc index fdcbab31c9,542df82394..8504c3d485 --- a/src/lib/eval/parser.cc +++ b/src/lib/eval/parser.cc @@@ -251,39 -251,39 +251,43 @@@ namespace isc { namespace eval { switch (that.type_get ()) { -- case 50: // option_repr_type ++ case 55: // option_repr_type value.move< TokenOption::RepresentationType > (that.value); break; - case 53: // pkt4_field - case 52: // pkt4_field ++ case 59: // pkt4_field value.move< TokenPkt4::FieldType > (that.value); break; - case 54: // pkt6_field - case 57: // pkt6_field ++ case 60: // pkt6_field value.move< TokenPkt6::FieldType > (that.value); break; - case 52: // pkt_metadata - case 55: // relay6_field ++ case 57: // pkt_metadata + value.move< TokenPkt::MetadataType > (that.value); + break; + - case 55: // relay6_field ++ case 61: // relay6_field value.move< TokenRelay6Field::FieldType > (that.value); break; -- case 40: // "constant string" -- case 41: // "integer" -- case 42: // "constant hexstring" -- case 43: // "option name" -- case 44: // "ip address" ++ case 45: // "constant string" ++ case 46: // "integer" ++ case 47: // "constant hexstring" ++ case 48: // "option name" ++ case 49: // "ip address" value.move< std::string > (that.value); break; -- case 49: // option_code ++ case 54: // option_code value.move< uint16_t > (that.value); break; - case 51: // nest_level - case 51: // enterprise_id ++ case 58: // enterprise_id + value.move< uint32_t > (that.value); + break; + + case 56: // nest_level value.move< uint8_t > (that.value); break; @@@ -302,39 -302,39 +306,43 @@@ state = that.state; switch (that.type_get ()) { -- case 50: // option_repr_type ++ case 55: // option_repr_type value.copy< TokenOption::RepresentationType > (that.value); break; - case 53: // pkt4_field - case 52: // pkt4_field ++ case 59: // pkt4_field value.copy< TokenPkt4::FieldType > (that.value); break; - case 54: // pkt6_field - case 57: // pkt6_field ++ case 60: // pkt6_field value.copy< TokenPkt6::FieldType > (that.value); break; - case 52: // pkt_metadata - case 55: // relay6_field ++ case 57: // pkt_metadata + value.copy< TokenPkt::MetadataType > (that.value); + break; + - case 55: // relay6_field ++ case 61: // relay6_field value.copy< TokenRelay6Field::FieldType > (that.value); break; -- case 40: // "constant string" -- case 41: // "integer" -- case 42: // "constant hexstring" -- case 43: // "option name" -- case 44: // "ip address" ++ case 45: // "constant string" ++ case 46: // "integer" ++ case 47: // "constant hexstring" ++ case 48: // "option name" ++ case 49: // "ip address" value.copy< std::string > (that.value); break; -- case 49: // option_code ++ case 54: // option_code value.copy< uint16_t > (that.value); break; - case 51: // nest_level - case 51: // enterprise_id ++ case 58: // enterprise_id + value.copy< uint32_t > (that.value); + break; + + case 56: // nest_level value.copy< uint8_t > (that.value); break; @@@ -374,88 -374,88 +382,95 @@@ << yysym.location << ": "; switch (yytype) { -- case 40: // "constant string" ++ case 45: // "constant string" --#line 97 "parser.yy" // lalr1.cc:636 ++#line 103 "parser.yy" // lalr1.cc:636 { yyoutput << yysym.value.template as< std::string > (); } --#line 382 "parser.cc" // lalr1.cc:636 ++#line 390 "parser.cc" // lalr1.cc:636 break; -- case 41: // "integer" ++ case 46: // "integer" --#line 97 "parser.yy" // lalr1.cc:636 ++#line 103 "parser.yy" // lalr1.cc:636 { yyoutput << yysym.value.template as< std::string > (); } --#line 389 "parser.cc" // lalr1.cc:636 ++#line 397 "parser.cc" // lalr1.cc:636 break; -- case 42: // "constant hexstring" ++ case 47: // "constant hexstring" --#line 97 "parser.yy" // lalr1.cc:636 ++#line 103 "parser.yy" // lalr1.cc:636 { yyoutput << yysym.value.template as< std::string > (); } --#line 396 "parser.cc" // lalr1.cc:636 ++#line 404 "parser.cc" // lalr1.cc:636 break; -- case 43: // "option name" ++ case 48: // "option name" --#line 97 "parser.yy" // lalr1.cc:636 ++#line 103 "parser.yy" // lalr1.cc:636 { yyoutput << yysym.value.template as< std::string > (); } --#line 403 "parser.cc" // lalr1.cc:636 ++#line 411 "parser.cc" // lalr1.cc:636 break; -- case 44: // "ip address" ++ case 49: // "ip address" --#line 97 "parser.yy" // lalr1.cc:636 ++#line 103 "parser.yy" // lalr1.cc:636 { yyoutput << yysym.value.template as< std::string > (); } --#line 410 "parser.cc" // lalr1.cc:636 ++#line 418 "parser.cc" // lalr1.cc:636 break; -- case 49: // option_code ++ case 54: // option_code --#line 97 "parser.yy" // lalr1.cc:636 ++#line 103 "parser.yy" // lalr1.cc:636 { yyoutput << yysym.value.template as< uint16_t > (); } --#line 417 "parser.cc" // lalr1.cc:636 ++#line 425 "parser.cc" // lalr1.cc:636 break; -- case 50: // option_repr_type ++ case 55: // option_repr_type --#line 97 "parser.yy" // lalr1.cc:636 ++#line 103 "parser.yy" // lalr1.cc:636 { yyoutput << yysym.value.template as< TokenOption::RepresentationType > (); } --#line 424 "parser.cc" // lalr1.cc:636 ++#line 432 "parser.cc" // lalr1.cc:636 break; - case 51: // nest_level - case 51: // enterprise_id ++ case 56: // nest_level --#line 97 "parser.yy" // lalr1.cc:636 - { yyoutput << yysym.value.template as< uint32_t > (); } -#line 431 "parser.cc" // lalr1.cc:636 ++#line 103 "parser.yy" // lalr1.cc:636 + { yyoutput << yysym.value.template as< uint8_t > (); } - #line 431 "parser.cc" // lalr1.cc:636 ++#line 439 "parser.cc" // lalr1.cc:636 break; - case 52: // pkt_metadata - case 52: // pkt4_field ++ case 57: // pkt_metadata --#line 97 "parser.yy" // lalr1.cc:636 - { yyoutput << yysym.value.template as< TokenPkt4::FieldType > (); } -#line 438 "parser.cc" // lalr1.cc:636 ++#line 103 "parser.yy" // lalr1.cc:636 + { yyoutput << yysym.value.template as< TokenPkt::MetadataType > (); } - #line 438 "parser.cc" // lalr1.cc:636 ++#line 446 "parser.cc" // lalr1.cc:636 break; - case 53: // pkt4_field - case 55: // relay6_field ++ case 58: // enterprise_id --#line 97 "parser.yy" // lalr1.cc:636 - { yyoutput << yysym.value.template as< TokenRelay6Field::FieldType > (); } -#line 445 "parser.cc" // lalr1.cc:636 ++#line 103 "parser.yy" // lalr1.cc:636 ++ { yyoutput << yysym.value.template as< uint32_t > (); } ++#line 453 "parser.cc" // lalr1.cc:636 + break; + - case 56: // nest_level ++ case 59: // pkt4_field + -#line 97 "parser.yy" // lalr1.cc:636 - { yyoutput << yysym.value.template as< uint8_t > (); } -#line 452 "parser.cc" // lalr1.cc:636 ++#line 103 "parser.yy" // lalr1.cc:636 + { yyoutput << yysym.value.template as< TokenPkt4::FieldType > (); } - #line 445 "parser.cc" // lalr1.cc:636 ++#line 460 "parser.cc" // lalr1.cc:636 break; - case 54: // pkt6_field - case 57: // pkt6_field ++ case 60: // pkt6_field --#line 97 "parser.yy" // lalr1.cc:636 ++#line 103 "parser.yy" // lalr1.cc:636 { yyoutput << yysym.value.template as< TokenPkt6::FieldType > (); } - #line 452 "parser.cc" // lalr1.cc:636 -#line 459 "parser.cc" // lalr1.cc:636 ++#line 467 "parser.cc" // lalr1.cc:636 + break; + - case 55: // relay6_field ++ case 61: // relay6_field + - #line 97 "parser.yy" // lalr1.cc:636 ++#line 103 "parser.yy" // lalr1.cc:636 + { yyoutput << yysym.value.template as< TokenRelay6Field::FieldType > (); } - #line 459 "parser.cc" // lalr1.cc:636 ++#line 474 "parser.cc" // lalr1.cc:636 break; @@@ -655,39 -655,39 +670,43 @@@ when using variants. */ switch (yyr1_[yyn]) { -- case 50: // option_repr_type ++ case 55: // option_repr_type yylhs.value.build< TokenOption::RepresentationType > (); break; - case 53: // pkt4_field - case 52: // pkt4_field ++ case 59: // pkt4_field yylhs.value.build< TokenPkt4::FieldType > (); break; - case 54: // pkt6_field - case 57: // pkt6_field ++ case 60: // pkt6_field yylhs.value.build< TokenPkt6::FieldType > (); break; - case 52: // pkt_metadata - case 55: // relay6_field ++ case 57: // pkt_metadata + yylhs.value.build< TokenPkt::MetadataType > (); + break; + - case 55: // relay6_field ++ case 61: // relay6_field yylhs.value.build< TokenRelay6Field::FieldType > (); break; -- case 40: // "constant string" -- case 41: // "integer" -- case 42: // "constant hexstring" -- case 43: // "option name" -- case 44: // "ip address" ++ case 45: // "constant string" ++ case 46: // "integer" ++ case 47: // "constant hexstring" ++ case 48: // "option name" ++ case 49: // "ip address" yylhs.value.build< std::string > (); break; -- case 49: // option_code ++ case 54: // option_code yylhs.value.build< uint16_t > (); break; - case 51: // nest_level - case 51: // enterprise_id ++ case 58: // enterprise_id + yylhs.value.build< uint32_t > (); + break; + + case 56: // nest_level yylhs.value.build< uint8_t > (); break; @@@ -709,52 -709,52 +728,52 @@@ switch (yyn) { case 4: --#line 111 "parser.yy" // lalr1.cc:859 ++#line 117 "parser.yy" // lalr1.cc:859 { TokenPtr neg(new TokenNot()); ctx.expression.push_back(neg); } --#line 718 "parser.cc" // lalr1.cc:859 ++#line 737 "parser.cc" // lalr1.cc:859 break; case 5: --#line 116 "parser.yy" // lalr1.cc:859 ++#line 122 "parser.yy" // lalr1.cc:859 { TokenPtr neg(new TokenAnd()); ctx.expression.push_back(neg); } --#line 727 "parser.cc" // lalr1.cc:859 ++#line 746 "parser.cc" // lalr1.cc:859 break; case 6: --#line 121 "parser.yy" // lalr1.cc:859 ++#line 127 "parser.yy" // lalr1.cc:859 { TokenPtr neg(new TokenOr()); ctx.expression.push_back(neg); } --#line 736 "parser.cc" // lalr1.cc:859 ++#line 755 "parser.cc" // lalr1.cc:859 break; case 7: --#line 126 "parser.yy" // lalr1.cc:859 ++#line 132 "parser.yy" // lalr1.cc:859 { TokenPtr eq(new TokenEqual()); ctx.expression.push_back(eq); } --#line 745 "parser.cc" // lalr1.cc:859 ++#line 764 "parser.cc" // lalr1.cc:859 break; case 8: --#line 131 "parser.yy" // lalr1.cc:859 ++#line 137 "parser.yy" // lalr1.cc:859 { TokenPtr opt(new TokenOption(yystack_[3].value.as< uint16_t > (), TokenOption::EXISTS)); ctx.expression.push_back(opt); } --#line 754 "parser.cc" // lalr1.cc:859 ++#line 773 "parser.cc" // lalr1.cc:859 break; case 9: --#line 136 "parser.yy" // lalr1.cc:859 ++#line 142 "parser.yy" // lalr1.cc:859 { switch (ctx.getUniverse()) { case Option::V4: @@@ -774,11 -774,11 +793,11 @@@ error(yystack_[5].location, "relay4 can only be used in DHCPv4."); } } --#line 778 "parser.cc" // lalr1.cc:859 ++#line 797 "parser.cc" // lalr1.cc:859 break; case 10: --#line 156 "parser.yy" // lalr1.cc:859 ++#line 162 "parser.yy" // lalr1.cc:859 { switch (ctx.getUniverse()) { case Option::V6: @@@ -792,47 -792,87 +811,87 @@@ error(yystack_[10].location, "relay6 can only be used in DHCPv6."); } } --#line 796 "parser.cc" // lalr1.cc:859 ++#line 815 "parser.cc" // lalr1.cc:859 break; case 11: - #line 172 "parser.yy" // lalr1.cc:859 -#line 170 "parser.yy" // lalr1.cc:859 ++#line 176 "parser.yy" // lalr1.cc:859 + { - // Expression: vendor-class[1234].exists - // - // This token will find option 124 (DHCPv4) or 16 (DHCPv6), and will check - // if enterprise-id equals specified value. - TokenPtr exist(new TokenVendorClass(ctx.getUniverse(), yystack_[3].value.as< uint32_t > (), TokenOption::EXISTS)); - ctx.expression.push_back(exist); - } -#line 809 "parser.cc" // lalr1.cc:859 ++ // Expression: vendor-class[1234].exists ++ // ++ // This token will find option 124 (DHCPv4) or 16 (DHCPv6), ++ // and will check if enterprise-id equals specified value. ++ TokenPtr exist(new TokenVendorClass(ctx.getUniverse(), yystack_[3].value.as< uint32_t > (), TokenOption::EXISTS)); ++ ctx.expression.push_back(exist); ++ } ++#line 828 "parser.cc" // lalr1.cc:859 + break; + + case 12: -#line 179 "parser.yy" // lalr1.cc:859 ++#line 185 "parser.yy" // lalr1.cc:859 + { - // Expression: vendor[1234].exists - // - // This token will find option 125 (DHCPv4) or 17 (DHCPv6), and will check - // if enterprise-id equals specified value. - TokenPtr exist(new TokenVendor(ctx.getUniverse(), yystack_[3].value.as< uint32_t > (), TokenOption::EXISTS)); - ctx.expression.push_back(exist); - - } -#line 823 "parser.cc" // lalr1.cc:859 ++ // Expression: vendor[1234].exists ++ // ++ // This token will find option 125 (DHCPv4) or 17 (DHCPv6), ++ // and will check if enterprise-id equals specified value. ++ TokenPtr exist(new TokenVendor(ctx.getUniverse(), yystack_[3].value.as< uint32_t > (), TokenOption::EXISTS)); ++ ctx.expression.push_back(exist); ++ } ++#line 841 "parser.cc" // lalr1.cc:859 + break; + + case 13: -#line 189 "parser.yy" // lalr1.cc:859 ++#line 194 "parser.yy" // lalr1.cc:859 + { - // Expression vendor[1234].option[123].exists - // - // This token will check if specified vendor option exists, has specified - // enterprise-id and if has specified suboption. - TokenPtr exist(new TokenVendor(ctx.getUniverse(), yystack_[8].value.as< uint32_t > (), TokenOption::EXISTS, yystack_[3].value.as< uint16_t > ())); - ctx.expression.push_back(exist); - } -#line 836 "parser.cc" // lalr1.cc:859 ++ // Expression vendor[1234].option[123].exists ++ // ++ // This token will check if specified vendor option ++ // exists, has specified enterprise-id and if has ++ // specified suboption. ++ TokenPtr exist(new TokenVendor(ctx.getUniverse(), yystack_[8].value.as< uint32_t > (), TokenOption::EXISTS, yystack_[3].value.as< uint16_t > ())); ++ ctx.expression.push_back(exist); ++ } ++#line 855 "parser.cc" // lalr1.cc:859 + break; + + case 14: -#line 200 "parser.yy" // lalr1.cc:859 ++#line 206 "parser.yy" // lalr1.cc:859 { TokenPtr str(new TokenString(yystack_[0].value.as< std::string > ())); ctx.expression.push_back(str); } - #line 805 "parser.cc" // lalr1.cc:859 -#line 845 "parser.cc" // lalr1.cc:859 ++#line 864 "parser.cc" // lalr1.cc:859 break; - case 12: - #line 177 "parser.yy" // lalr1.cc:859 + case 15: -#line 205 "parser.yy" // lalr1.cc:859 ++#line 211 "parser.yy" // lalr1.cc:859 { TokenPtr hex(new TokenHexString(yystack_[0].value.as< std::string > ())); ctx.expression.push_back(hex); } - #line 814 "parser.cc" // lalr1.cc:859 -#line 854 "parser.cc" // lalr1.cc:859 ++#line 873 "parser.cc" // lalr1.cc:859 break; - case 13: - #line 182 "parser.yy" // lalr1.cc:859 + case 16: -#line 210 "parser.yy" // lalr1.cc:859 ++#line 216 "parser.yy" // lalr1.cc:859 { TokenPtr ip(new TokenIpAddress(yystack_[0].value.as< std::string > ())); ctx.expression.push_back(ip); } - #line 823 "parser.cc" // lalr1.cc:859 -#line 863 "parser.cc" // lalr1.cc:859 ++#line 882 "parser.cc" // lalr1.cc:859 break; - case 14: - #line 187 "parser.yy" // lalr1.cc:859 + case 17: -#line 215 "parser.yy" // lalr1.cc:859 ++#line 221 "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 832 "parser.cc" // lalr1.cc:859 -#line 872 "parser.cc" // lalr1.cc:859 ++#line 891 "parser.cc" // lalr1.cc:859 break; - case 15: - #line 192 "parser.yy" // lalr1.cc:859 + case 18: -#line 220 "parser.yy" // lalr1.cc:859 ++#line 226 "parser.yy" // lalr1.cc:859 { switch (ctx.getUniverse()) { case Option::V4: @@@ -852,11 -892,11 +911,11 @@@ error(yystack_[5].location, "relay4 can only be used in DHCPv4."); } } - #line 856 "parser.cc" // lalr1.cc:859 -#line 896 "parser.cc" // lalr1.cc:859 ++#line 915 "parser.cc" // lalr1.cc:859 break; - case 16: - #line 213 "parser.yy" // lalr1.cc:859 + case 19: -#line 241 "parser.yy" // lalr1.cc:859 ++#line 247 "parser.yy" // lalr1.cc:859 { switch (ctx.getUniverse()) { case Option::V6: @@@ -870,279 -910,299 +929,369 @@@ error(yystack_[10].location, "relay6 can only be used in DHCPv6."); } } - #line 874 "parser.cc" // lalr1.cc:859 -#line 914 "parser.cc" // lalr1.cc:859 ++#line 933 "parser.cc" // lalr1.cc:859 break; - case 17: - #line 228 "parser.yy" // lalr1.cc:859 + case 20: -#line 256 "parser.yy" // lalr1.cc:859 ++#line 262 "parser.yy" // lalr1.cc:859 + { + TokenPtr pkt_metadata(new TokenPkt(yystack_[0].value.as< TokenPkt::MetadataType > ())); + ctx.expression.push_back(pkt_metadata); + } - #line 883 "parser.cc" // lalr1.cc:859 ++#line 942 "parser.cc" // lalr1.cc:859 + break; + - case 18: - #line 233 "parser.yy" // lalr1.cc:859 ++ case 21: ++#line 267 "parser.yy" // lalr1.cc:859 { switch (ctx.getUniverse()) { - case Option::V6: + case Option::V4: { - TokenPtr relay6field(new TokenRelay6Field(yystack_[3].value.as< uint8_t > (), yystack_[0].value.as< TokenRelay6Field::FieldType > ())); - ctx.expression.push_back(relay6field); + TokenPtr pkt4_field(new TokenPkt4(yystack_[0].value.as< TokenPkt4::FieldType > ())); + ctx.expression.push_back(pkt4_field); break; } - case Option::V4: - // For now we only use relay6 in DHCPv6. - error(yystack_[5].location, "relay6 can only be used in DHCPv6."); + case Option::V6: + // For now we only use pkt4 in DHCPv4. + error(yystack_[2].location, "pkt4 can only be used in DHCPv4."); } } - #line 901 "parser.cc" // lalr1.cc:859 -#line 932 "parser.cc" // lalr1.cc:859 ++#line 960 "parser.cc" // lalr1.cc:859 break; - case 19: - #line 247 "parser.yy" // lalr1.cc:859 - case 21: -#line 271 "parser.yy" // lalr1.cc:859 ++ case 22: ++#line 281 "parser.yy" // lalr1.cc:859 { - TokenPtr pkt4_field(new TokenPkt4(yystack_[0].value.as< TokenPkt4::FieldType > ())); - ctx.expression.push_back(pkt4_field); + switch (ctx.getUniverse()) { + case Option::V6: + { + TokenPtr pkt6_field(new TokenPkt6(yystack_[0].value.as< TokenPkt6::FieldType > ())); + ctx.expression.push_back(pkt6_field); + break; + } + case Option::V4: + // For now we only use pkt6 in DHCPv6. + error(yystack_[2].location, "pkt6 can only be used in DHCPv6."); + } } - #line 919 "parser.cc" // lalr1.cc:859 -#line 941 "parser.cc" // lalr1.cc:859 ++#line 978 "parser.cc" // lalr1.cc:859 break; - case 20: - #line 261 "parser.yy" // lalr1.cc:859 - case 22: -#line 276 "parser.yy" // lalr1.cc:859 ++ case 23: ++#line 295 "parser.yy" // lalr1.cc:859 { - TokenPtr pkt6_field(new TokenPkt6(yystack_[0].value.as< TokenPkt6::FieldType > ())); - ctx.expression.push_back(pkt6_field); + switch (ctx.getUniverse()) { + case Option::V6: + { + TokenPtr relay6field(new TokenRelay6Field(yystack_[3].value.as< uint8_t > (), yystack_[0].value.as< TokenRelay6Field::FieldType > ())); + ctx.expression.push_back(relay6field); + break; + } + case Option::V4: + // For now we only use relay6 in DHCPv6. + error(yystack_[5].location, "relay6 can only be used in DHCPv6."); + } } - #line 937 "parser.cc" // lalr1.cc:859 -#line 950 "parser.cc" // lalr1.cc:859 ++#line 996 "parser.cc" // lalr1.cc:859 break; - case 21: - #line 276 "parser.yy" // lalr1.cc:859 - case 23: -#line 281 "parser.yy" // lalr1.cc:859 ++ case 24: ++#line 310 "parser.yy" // lalr1.cc:859 { TokenPtr sub(new TokenSubstring()); ctx.expression.push_back(sub); } - #line 946 "parser.cc" // lalr1.cc:859 -#line 959 "parser.cc" // lalr1.cc:859 ++#line 1005 "parser.cc" // lalr1.cc:859 break; - case 22: - #line 281 "parser.yy" // lalr1.cc:859 - case 24: -#line 286 "parser.yy" // lalr1.cc:859 ++ case 25: ++#line 315 "parser.yy" // lalr1.cc:859 { TokenPtr conc(new TokenConcat()); ctx.expression.push_back(conc); } - #line 955 "parser.cc" // lalr1.cc:859 -#line 968 "parser.cc" // lalr1.cc:859 - break; - - case 25: -#line 291 "parser.yy" // lalr1.cc:859 - { - // expression: vendor.enterprise - // - // This token will return enterprise-id number of received vendor option. - TokenPtr vendor(new TokenVendor(ctx.getUniverse(), 0, TokenVendor::ENTERPRISE_ID)); - ctx.expression.push_back(vendor); - } -#line 980 "parser.cc" // lalr1.cc:859 ++#line 1014 "parser.cc" // lalr1.cc:859 break; - case 23: - #line 288 "parser.yy" // lalr1.cc:859 + case 26: -#line 299 "parser.yy" // lalr1.cc:859 ++#line 320 "parser.yy" // lalr1.cc:859 + { - // expression: vendor-class.enterprise - // - // This token will return enterprise-id number of received vendor class option. - TokenPtr vendor(new TokenVendorClass(ctx.getUniverse(), 0, - TokenVendor::ENTERPRISE_ID)); - ctx.expression.push_back(vendor); - } -#line 993 "parser.cc" // lalr1.cc:859 ++ // expression: vendor.enterprise ++ // ++ // This token will return enterprise-id number of ++ // received vendor option. ++ TokenPtr vendor(new TokenVendor(ctx.getUniverse(), 0, TokenVendor::ENTERPRISE_ID)); ++ ctx.expression.push_back(vendor); ++ } ++#line 1027 "parser.cc" // lalr1.cc:859 + break; + + case 27: -#line 308 "parser.yy" // lalr1.cc:859 ++#line 329 "parser.yy" // lalr1.cc:859 + { - // expression: vendor[1234].option[56].exists - // expression: vendor[1234].option[56].hex - // - // This token will search for vendor option with specified enterprise-id. - // If found, will search for specified suboption and finally will return - // if it exists ('exists') or its content ('hex') - TokenPtr opt(new TokenVendor(ctx.getUniverse(), yystack_[8].value.as< uint32_t > (), yystack_[0].value.as< TokenOption::RepresentationType > (), yystack_[3].value.as< uint16_t > ())); - ctx.expression.push_back(opt); - } -#line 1008 "parser.cc" // lalr1.cc:859 ++ // expression: vendor-class.enterprise ++ // ++ // This token will return enterprise-id number of ++ // received vendor class option. ++ TokenPtr vendor(new TokenVendorClass(ctx.getUniverse(), 0, ++ TokenVendor::ENTERPRISE_ID)); ++ ctx.expression.push_back(vendor); ++ } ++#line 1041 "parser.cc" // lalr1.cc:859 + break; + + case 28: -#line 319 "parser.yy" // lalr1.cc:859 ++#line 339 "parser.yy" // lalr1.cc:859 + { - // expression: vendor-class[1234].data - // - // Vendor class option does not have suboptions, but chunks of data (typically 1, - // but the option structure allows multiple of them). If chunk offset is not - // specified, we assume the first (0th) is requested. - TokenPtr vendor_class(new TokenVendorClass(ctx.getUniverse(), yystack_[3].value.as< uint32_t > (), - TokenVendor::DATA, 0)); - ctx.expression.push_back(vendor_class); - } -#line 1023 "parser.cc" // lalr1.cc:859 ++ // This token will search for vendor option with ++ // specified enterprise-id. If found, will search ++ // for specified suboption and finally will return ++ // its content. ++ TokenPtr opt(new TokenVendor(ctx.getUniverse(), yystack_[8].value.as< uint32_t > (), yystack_[0].value.as< TokenOption::RepresentationType > (), yystack_[3].value.as< uint16_t > ())); ++ ctx.expression.push_back(opt); ++ } ++#line 1054 "parser.cc" // lalr1.cc:859 + break; + + case 29: -#line 330 "parser.yy" // lalr1.cc:859 ++#line 348 "parser.yy" // lalr1.cc:859 + { - // expression: vendor-class[1234].data[5] - // - // Vendor class option does not have suboptions, but chunks of data (typically 1, - // but the option structure allows multiple of them). This syntax specifies - // which data chunk (tuple) we want. - uint8_t index = ctx.convertUint8(yystack_[1].value.as< std::string > (), yystack_[1].location); - TokenPtr vendor_class(new TokenVendorClass(ctx.getUniverse(), yystack_[6].value.as< uint32_t > (), - TokenVendor::DATA, index)); - ctx.expression.push_back(vendor_class); - } -#line 1039 "parser.cc" // lalr1.cc:859 ++ // expression: vendor-class[1234].data ++ // ++ // Vendor class option does not have suboptions, ++ // but chunks of data (typically 1, but the option ++ // structure allows multiple of them). If chunk ++ // offset is not specified, we assume the first (0th) ++ // is requested. ++ TokenPtr vendor_class(new TokenVendorClass(ctx.getUniverse(), yystack_[3].value.as< uint32_t > (), ++ TokenVendor::DATA, 0)); ++ ctx.expression.push_back(vendor_class); ++ } ++#line 1071 "parser.cc" // lalr1.cc:859 + break; + + case 30: -#line 344 "parser.yy" // lalr1.cc:859 ++#line 361 "parser.yy" // lalr1.cc:859 + { - yylhs.value.as< uint16_t > () = ctx.convertOptionCode(yystack_[0].value.as< std::string > (), yystack_[0].location); - } -#line 1047 "parser.cc" // lalr1.cc:859 ++ // expression: vendor-class[1234].data[5] ++ // ++ // Vendor class option does not have suboptions, ++ // but chunks of data (typically 1, but the option ++ // structure allows multiple of them). This syntax ++ // specifies which data chunk (tuple) we want. ++ uint8_t index = ctx.convertUint8(yystack_[1].value.as< std::string > (), yystack_[1].location); ++ TokenPtr vendor_class(new TokenVendorClass(ctx.getUniverse(), yystack_[6].value.as< uint32_t > (), ++ TokenVendor::DATA, index)); ++ ctx.expression.push_back(vendor_class); ++ } ++#line 1088 "parser.cc" // lalr1.cc:859 + break; + + case 31: -#line 348 "parser.yy" // lalr1.cc:859 ++#line 376 "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 963 "parser.cc" // lalr1.cc:859 -#line 1055 "parser.cc" // lalr1.cc:859 ++#line 1096 "parser.cc" // lalr1.cc:859 break; - case 24: - #line 292 "parser.yy" // lalr1.cc:859 + case 32: -#line 354 "parser.yy" // lalr1.cc:859 ++#line 380 "parser.yy" // lalr1.cc:859 { - yylhs.value.as< TokenOption::RepresentationType > () = TokenOption::TEXTUAL; - } -#line 1063 "parser.cc" // lalr1.cc:859 + yylhs.value.as< uint16_t > () = ctx.convertOptionName(yystack_[0].value.as< std::string > (), yystack_[0].location); + } - #line 971 "parser.cc" // lalr1.cc:859 ++#line 1104 "parser.cc" // lalr1.cc:859 break; - case 25: - #line 298 "parser.yy" // lalr1.cc:859 + case 33: -#line 358 "parser.yy" // lalr1.cc:859 ++#line 386 "parser.yy" // lalr1.cc:859 { - yylhs.value.as< TokenOption::RepresentationType > () = TokenOption::HEXADECIMAL; + yylhs.value.as< TokenOption::RepresentationType > () = TokenOption::TEXTUAL; } - #line 979 "parser.cc" // lalr1.cc:859 -#line 1071 "parser.cc" // lalr1.cc:859 ++#line 1112 "parser.cc" // lalr1.cc:859 break; - case 26: - #line 302 "parser.yy" // lalr1.cc:859 + case 34: -#line 364 "parser.yy" // lalr1.cc:859 ++#line 390 "parser.yy" // lalr1.cc:859 { - yylhs.value.as< uint32_t > () = ctx.convertUint32(yystack_[0].value.as< std::string > (), yystack_[0].location); -} -#line 1079 "parser.cc" // lalr1.cc:859 + yylhs.value.as< TokenOption::RepresentationType > () = TokenOption::HEXADECIMAL; + } - #line 987 "parser.cc" // lalr1.cc:859 ++#line 1120 "parser.cc" // lalr1.cc:859 break; - case 27: - #line 308 "parser.yy" // lalr1.cc:859 + case 35: -#line 368 "parser.yy" // lalr1.cc:859 ++#line 396 "parser.yy" // lalr1.cc:859 { - yylhs.value.as< uint32_t > () = 0; -} -#line 1087 "parser.cc" // lalr1.cc:859 + yylhs.value.as< uint8_t > () = ctx.convertNestLevelNumber(yystack_[0].value.as< std::string > (), yystack_[0].location); + } - #line 995 "parser.cc" // lalr1.cc:859 ++#line 1128 "parser.cc" // lalr1.cc:859 break; - case 28: - #line 317 "parser.yy" // lalr1.cc:859 + case 36: -#line 373 "parser.yy" // lalr1.cc:859 ++#line 405 "parser.yy" // lalr1.cc:859 { - yylhs.value.as< TokenPkt4::FieldType > () = TokenPkt4::CHADDR; - } -#line 1095 "parser.cc" // lalr1.cc:859 + yylhs.value.as< TokenPkt::MetadataType > () = TokenPkt::IFACE; + } - #line 1003 "parser.cc" // lalr1.cc:859 ++#line 1136 "parser.cc" // lalr1.cc:859 break; - case 29: - #line 321 "parser.yy" // lalr1.cc:859 + case 37: -#line 377 "parser.yy" // lalr1.cc:859 ++#line 409 "parser.yy" // lalr1.cc:859 { - yylhs.value.as< TokenPkt4::FieldType > () = TokenPkt4::HLEN; - } -#line 1103 "parser.cc" // lalr1.cc:859 + yylhs.value.as< TokenPkt::MetadataType > () = TokenPkt::SRC; + } - #line 1011 "parser.cc" // lalr1.cc:859 ++#line 1144 "parser.cc" // lalr1.cc:859 break; - case 30: - #line 325 "parser.yy" // lalr1.cc:859 + case 38: -#line 381 "parser.yy" // lalr1.cc:859 ++#line 413 "parser.yy" // lalr1.cc:859 { - yylhs.value.as< TokenPkt4::FieldType > () = TokenPkt4::HTYPE; - } -#line 1111 "parser.cc" // lalr1.cc:859 + yylhs.value.as< TokenPkt::MetadataType > () = TokenPkt::DST; + } - #line 1019 "parser.cc" // lalr1.cc:859 ++#line 1152 "parser.cc" // lalr1.cc:859 break; - case 31: - #line 329 "parser.yy" // lalr1.cc:859 + case 39: -#line 385 "parser.yy" // lalr1.cc:859 ++#line 417 "parser.yy" // lalr1.cc:859 { - yylhs.value.as< TokenPkt4::FieldType > () = TokenPkt4::CIADDR; - } -#line 1119 "parser.cc" // lalr1.cc:859 + yylhs.value.as< TokenPkt::MetadataType > () = TokenPkt::LEN; + } - #line 1027 "parser.cc" // lalr1.cc:859 ++#line 1160 "parser.cc" // lalr1.cc:859 break; - case 32: - #line 335 "parser.yy" // lalr1.cc:859 + case 40: -#line 389 "parser.yy" // lalr1.cc:859 ++#line 423 "parser.yy" // lalr1.cc:859 + { - yylhs.value.as< TokenPkt4::FieldType > () = TokenPkt4::GIADDR; - } -#line 1127 "parser.cc" // lalr1.cc:859 ++ yylhs.value.as< uint32_t > () = ctx.convertUint32(yystack_[0].value.as< std::string > (), yystack_[0].location); ++ } ++#line 1168 "parser.cc" // lalr1.cc:859 + break; + + case 41: -#line 393 "parser.yy" // lalr1.cc:859 ++#line 427 "parser.yy" // lalr1.cc:859 + { - yylhs.value.as< TokenPkt4::FieldType > () = TokenPkt4::YIADDR; - } -#line 1135 "parser.cc" // lalr1.cc:859 ++ yylhs.value.as< uint32_t > () = 0; ++ } ++#line 1176 "parser.cc" // lalr1.cc:859 + break; + + case 42: -#line 397 "parser.yy" // lalr1.cc:859 ++#line 433 "parser.yy" // lalr1.cc:859 { - yylhs.value.as< TokenPkt4::FieldType > () = TokenPkt4::SIADDR; + yylhs.value.as< TokenPkt4::FieldType > () = TokenPkt4::CHADDR; } - #line 1035 "parser.cc" // lalr1.cc:859 -#line 1143 "parser.cc" // lalr1.cc:859 ++#line 1184 "parser.cc" // lalr1.cc:859 break; - case 33: - #line 339 "parser.yy" // lalr1.cc:859 + case 43: -#line 403 "parser.yy" // lalr1.cc:859 ++#line 437 "parser.yy" // lalr1.cc:859 { - TokenPtr str(new TokenString(yystack_[0].value.as< std::string > ())); - ctx.expression.push_back(str); - } -#line 1152 "parser.cc" // lalr1.cc:859 + yylhs.value.as< TokenPkt4::FieldType > () = TokenPkt4::HLEN; + } - #line 1043 "parser.cc" // lalr1.cc:859 ++#line 1192 "parser.cc" // lalr1.cc:859 break; - case 34: - #line 343 "parser.yy" // lalr1.cc:859 + case 44: -#line 410 "parser.yy" // lalr1.cc:859 ++#line 441 "parser.yy" // lalr1.cc:859 { - TokenPtr str(new TokenString(yystack_[0].value.as< std::string > ())); - ctx.expression.push_back(str); - } -#line 1161 "parser.cc" // lalr1.cc:859 + yylhs.value.as< TokenPkt4::FieldType > () = TokenPkt4::HTYPE; + } - #line 1051 "parser.cc" // lalr1.cc:859 ++#line 1200 "parser.cc" // lalr1.cc:859 break; - case 35: - #line 347 "parser.yy" // lalr1.cc:859 + case 45: -#line 415 "parser.yy" // lalr1.cc:859 ++#line 445 "parser.yy" // lalr1.cc:859 { - TokenPtr str(new TokenString("all")); - ctx.expression.push_back(str); - } -#line 1170 "parser.cc" // lalr1.cc:859 + yylhs.value.as< TokenPkt4::FieldType > () = TokenPkt4::CIADDR; + } - #line 1059 "parser.cc" // lalr1.cc:859 ++#line 1208 "parser.cc" // lalr1.cc:859 break; - case 36: - #line 351 "parser.yy" // lalr1.cc:859 + case 46: -#line 421 "parser.yy" // lalr1.cc:859 - { yylhs.value.as< TokenRelay6Field::FieldType > () = TokenRelay6Field::PEERADDR; } -#line 1176 "parser.cc" // lalr1.cc:859 ++#line 449 "parser.yy" // lalr1.cc:859 + { + yylhs.value.as< TokenPkt4::FieldType > () = TokenPkt4::GIADDR; + } - #line 1067 "parser.cc" // lalr1.cc:859 ++#line 1216 "parser.cc" // lalr1.cc:859 break; - case 37: - #line 355 "parser.yy" // lalr1.cc:859 + case 47: -#line 422 "parser.yy" // lalr1.cc:859 - { yylhs.value.as< TokenRelay6Field::FieldType > () = TokenRelay6Field::LINKADDR; } -#line 1182 "parser.cc" // lalr1.cc:859 ++#line 453 "parser.yy" // lalr1.cc:859 + { + yylhs.value.as< TokenPkt4::FieldType > () = TokenPkt4::YIADDR; + } - #line 1075 "parser.cc" // lalr1.cc:859 ++#line 1224 "parser.cc" // lalr1.cc:859 break; - case 38: - #line 359 "parser.yy" // lalr1.cc:859 + case 48: -#line 426 "parser.yy" // lalr1.cc:859 ++#line 457 "parser.yy" // lalr1.cc:859 { - yylhs.value.as< uint8_t > () = ctx.convertNestLevelNumber(yystack_[0].value.as< std::string > (), yystack_[0].location); - } -#line 1190 "parser.cc" // lalr1.cc:859 + yylhs.value.as< TokenPkt4::FieldType > () = TokenPkt4::SIADDR; + } - #line 1083 "parser.cc" // lalr1.cc:859 ++#line 1232 "parser.cc" // lalr1.cc:859 break; - case 39: - #line 365 "parser.yy" // lalr1.cc:859 + case 49: -#line 434 "parser.yy" // lalr1.cc:859 - { yylhs.value.as< TokenPkt6::FieldType > () = TokenPkt6::MSGTYPE; } -#line 1196 "parser.cc" // lalr1.cc:859 ++#line 463 "parser.yy" // lalr1.cc:859 + { + yylhs.value.as< TokenPkt6::FieldType > () = TokenPkt6::MSGTYPE; + } - #line 1091 "parser.cc" // lalr1.cc:859 ++#line 1240 "parser.cc" // lalr1.cc:859 break; - case 40: - #line 369 "parser.yy" // lalr1.cc:859 + case 50: -#line 435 "parser.yy" // lalr1.cc:859 - { yylhs.value.as< TokenPkt6::FieldType > () = TokenPkt6::TRANSID; } -#line 1202 "parser.cc" // lalr1.cc:859 ++#line 467 "parser.yy" // lalr1.cc:859 + { + yylhs.value.as< TokenPkt6::FieldType > () = TokenPkt6::TRANSID; + } - #line 1099 "parser.cc" // lalr1.cc:859 ++#line 1248 "parser.cc" // lalr1.cc:859 + break; + - case 41: - #line 375 "parser.yy" // lalr1.cc:859 ++ case 51: ++#line 473 "parser.yy" // lalr1.cc:859 + { + yylhs.value.as< TokenRelay6Field::FieldType > () = TokenRelay6Field::PEERADDR; + } - #line 1107 "parser.cc" // lalr1.cc:859 ++#line 1256 "parser.cc" // lalr1.cc:859 + break; + - case 42: - #line 379 "parser.yy" // lalr1.cc:859 ++ case 52: ++#line 477 "parser.yy" // lalr1.cc:859 + { + yylhs.value.as< TokenRelay6Field::FieldType > () = TokenRelay6Field::LINKADDR; + } - #line 1115 "parser.cc" // lalr1.cc:859 ++#line 1264 "parser.cc" // lalr1.cc:859 + break; + - case 43: - #line 385 "parser.yy" // lalr1.cc:859 ++ case 53: ++#line 483 "parser.yy" // lalr1.cc:859 + { - TokenPtr str(new TokenString(yystack_[0].value.as< std::string > ())); - ctx.expression.push_back(str); - } - #line 1124 "parser.cc" // lalr1.cc:859 ++ TokenPtr str(new TokenString(yystack_[0].value.as< std::string > ())); ++ ctx.expression.push_back(str); ++ } ++#line 1273 "parser.cc" // lalr1.cc:859 + break; + - case 44: - #line 392 "parser.yy" // lalr1.cc:859 ++ case 54: ++#line 490 "parser.yy" // lalr1.cc:859 + { - TokenPtr str(new TokenString(yystack_[0].value.as< std::string > ())); - ctx.expression.push_back(str); - } - #line 1133 "parser.cc" // lalr1.cc:859 ++ TokenPtr str(new TokenString(yystack_[0].value.as< std::string > ())); ++ ctx.expression.push_back(str); ++ } ++#line 1282 "parser.cc" // lalr1.cc:859 break; - case 45: - #line 397 "parser.yy" // lalr1.cc:859 ++ case 55: ++#line 495 "parser.yy" // lalr1.cc:859 + { + TokenPtr str(new TokenString("all")); + ctx.expression.push_back(str); + } - #line 1142 "parser.cc" // lalr1.cc:859 ++#line 1291 "parser.cc" // lalr1.cc:859 + break; -#line 1206 "parser.cc" // lalr1.cc:859 + - #line 1146 "parser.cc" // lalr1.cc:859 ++#line 1295 "parser.cc" // lalr1.cc:859 default: break; } @@@ -1397,129 -1457,148 +1546,153 @@@ } - const signed char EvalParser::yypact_ninf_ = -70; - const signed char EvalParser::yypact_ninf_ = -82; ++ const signed char EvalParser::yypact_ninf_ = -89; const signed char EvalParser::yytable_ninf_ = -1; - const signed char + const short int EvalParser::yypact_[] = { - 15, 15, 15, -13, 7, 14, -9, 25, 34, 53, - 67, -70, -70, -70, 58, 37, 75, 32, -70, -12, - -12, 45, 42, -17, -18, 51, 51, -70, 15, 15, - 51, -70, -70, -70, 73, 74, -70, 77, -70, -70, - -70, -70, -70, -70, -70, -70, -70, -70, -70, -70, - -70, -70, -70, -70, 61, 80, 82, 59, 62, -70, - 92, -70, 83, 85, 86, -12, -12, 45, 64, 51, - 50, 60, 10, 88, 89, 91, -70, 69, 104, -70, - -70, -70, -70, -70, -70, 95, -70, -70, -70, 94, - 96, 97, -7, -70, -12, 55, 55, 40, -70, -70, - 107, 99, 101, -70, 100, -12, 63, 102, -70, -70, - 103, 55 - 65, 65, 65, -4, -1, 7, 29, 47, 66, 41, - 2, 24, -82, -82, -82, 84, 92, 83, 40, -82, - 45, 45, 67, 56, -3, -3, 69, -11, 75, -11, - 77, -82, 65, 65, -3, -82, -82, -82, 80, 91, - -82, 100, -82, -82, -82, -82, -82, -82, -82, -82, - 103, 104, 105, 73, 76, 90, 94, -82, -82, -82, - -82, -82, 106, -82, 107, -82, -82, 117, -82, 109, - 110, 111, 45, 45, 67, -11, -11, 87, -3, 113, - 114, 36, 43, 11, 116, 118, 119, 120, 121, -82, - 102, 133, -16, 0, -82, -82, -82, -82, -82, -82, - 124, -82, -82, -82, 123, 125, 126, 127, 128, -14, - -82, -82, 131, 132, -82, 45, 93, 93, 22, 112, - 138, -82, -82, 136, 108, 45, 137, 134, 139, -82, - 140, 141, 135, 45, 45, -82, 142, 46, 144, 145, - 54, -82, -82, 146, 147, -82, -82, 93, 93 ++ 4, 4, 4, 11, 18, 46, 69, 70, 93, 94, ++ 85, -6, 36, -89, -89, -89, 105, 32, 100, 77, ++ -89, 58, 58, 71, 67, 48, 62, 62, 26, -11, ++ 72, -11, 76, -89, 4, 4, 62, -89, -89, -89, ++ 106, 107, -89, 108, -89, -89, -89, -89, -89, -89, ++ -89, -89, -89, -89, -89, -89, -89, 110, 111, 112, ++ 98, 99, 92, 95, -89, -89, -89, -89, -89, 113, ++ -89, 114, -89, -89, 125, -89, 116, 117, 118, 58, ++ 58, 71, -11, -11, 89, 62, 120, 121, 1, 29, ++ 14, 123, 124, 126, 127, 128, -89, 109, 136, -15, ++ -3, -89, -89, -89, -89, -89, -89, 131, -89, -89, ++ -89, 130, 132, 133, 134, 135, -29, -89, -89, 138, ++ 139, -89, 58, 25, 25, 21, 104, 145, -89, -89, ++ 151, 115, 58, 141, 143, 144, -89, 147, 148, 149, ++ 58, 58, -89, 150, 51, 152, 153, 75, -89, -89, ++ 154, 155, -89, -89, 25, 25 }; const unsigned char EvalParser::yydefact_[] = { 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, 0, 1, 0, 0, - 0, 3, 23, 24, 0, 0, 27, 0, 28, 29, - 30, 31, 17, 32, 33, 34, 35, 36, 37, 38, - 18, 39, 40, 19, 0, 0, 0, 0, 0, 5, - 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 43, 0, 0, 25, - 26, 8, 14, 9, 15, 0, 41, 42, 20, 0, - 0, 0, 0, 22, 0, 0, 0, 0, 45, 44, - 0, 0, 0, 21, 0, 0, 0, 0, 10, 16, - 0, 0 - 0, 0, 14, 15, 16, 0, 2, 0, 0, 4, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 3, 30, 31, 0, 0, - 48, 0, 36, 37, 38, 39, 40, 41, 42, 21, - 0, 0, 0, 0, 0, 0, 0, 49, 50, 22, - 35, 34, 0, 26, 0, 25, 5, 6, 7, 0, ++ 0, 0, 0, 14, 15, 16, 0, 2, 0, 0, ++ 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 1, 0, 0, 0, 3, 31, 32, ++ 0, 0, 35, 0, 36, 37, 38, 39, 20, 42, ++ 43, 44, 45, 46, 47, 48, 21, 0, 0, 0, ++ 0, 0, 0, 0, 49, 50, 22, 41, 40, 0, ++ 27, 0, 26, 5, 6, 7, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, - 0, 0, 0, 0, 32, 33, 8, 17, 9, 18, - 0, 46, 47, 20, 0, 0, 0, 0, 0, 0, - 24, 11, 28, 0, 12, 0, 0, 0, 0, 0, - 0, 45, 44, 0, 0, 0, 0, 0, 0, 23, - 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, - 0, 10, 19, 0, 0, 13, 27, 0, 0 ++ 0, 0, 0, 0, 0, 0, 53, 0, 0, 0, ++ 0, 33, 34, 8, 17, 9, 18, 0, 51, 52, ++ 23, 0, 0, 0, 0, 0, 0, 25, 11, 29, ++ 0, 12, 0, 0, 0, 0, 0, 0, 55, 54, ++ 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, ++ 0, 0, 30, 0, 0, 0, 0, 0, 10, 19, ++ 0, 0, 13, 28, 0, 0 }; const signed char EvalParser::yypgoto_[] = { - -70, -70, 4, -22, -20, -69, 54, -70, -70, -70, - -70, -70, -70 - -82, -82, 10, -20, -21, -81, -27, -82, -82, -82, - -82, 95, -82 ++ -89, -89, 20, -24, -22, -88, 78, -89, -20, -89, ++ -89, -89, -89, -89 }; -- const signed char ++ const short int EvalParser::yydefgoto_[] = { - -1, 14, 15, 16, 34, 82, 37, 42, 50, 53, - 88, 77, 100 - -1, 15, 16, 17, 38, 97, 62, 49, 90, 123, - 103, 41, 59 ++ -1, 16, 17, 18, 40, 104, 43, 48, 69, 56, ++ 66, 110, 97, 130 }; const unsigned char EvalParser::yytable_[] = { - 35, 19, 84, 57, 58, 17, 18, 22, 61, 43, - 44, 45, 46, 47, 48, 49, 51, 52, 1, 85, - 2, 20, 86, 87, 3, 4, 5, 84, 21, 32, - 98, 33, 59, 60, 99, 6, 31, 109, 28, 29, - 7, 23, 109, 28, 29, 73, 74, 78, 8, 102, - 24, 9, 86, 87, 10, 11, 25, 12, 27, 13, - 54, 55, 56, 38, 39, 40, 41, 79, 80, 81, - 26, 6, 79, 80, 101, 65, 7, 79, 80, 83, - 79, 80, 108, 30, 8, 107, 36, 9, 62, 63, - 10, 11, 64, 12, 66, 13, 67, 68, 28, 70, - 69, 71, 72, 89, 90, 76, 91, 92, 93, 94, - 95, 103, 96, 97, 104, 105, 106, 110, 0, 111, - 0, 75 - 39, 99, 64, 111, 55, 56, 50, 51, 52, 113, - 20, 18, 19, 21, 68, 121, 27, 6, 28, 114, - 100, 22, 112, 101, 102, 7, 60, 122, 8, 9, - 61, 127, 53, 54, 101, 102, 99, 12, 29, 13, - 30, 14, 66, 67, 35, 23, 32, 33, 87, 88, - 24, 84, 85, 94, 95, 96, 142, 26, 91, 146, - 94, 95, 98, 94, 95, 141, 142, 146, 1, 25, - 2, 94, 95, 145, 3, 4, 5, 42, 43, 44, - 45, 46, 47, 48, 31, 6, 36, 75, 37, 28, - 76, 34, 30, 7, 126, 69, 8, 9, 32, 33, - 10, 11, 57, 58, 131, 12, 70, 13, 40, 14, - 94, 95, 138, 139, 63, 71, 65, 72, 73, 74, - 77, 79, 80, 32, 78, 81, 82, 83, 89, 92, - 93, 104, 109, 105, 106, 107, 108, 110, 115, 116, - 129, 117, 118, 119, 120, 124, 125, 128, 133, 130, - 112, 137, 132, 134, 0, 135, 136, 0, 140, 143, - 144, 0, 147, 148, 0, 0, 0, 0, 0, 86 ++ 41, 106, 62, 63, 118, 128, 120, 1, 29, 2, ++ 30, 71, 75, 3, 4, 5, 121, 129, 101, 102, ++ 103, 19, 20, 107, 6, 21, 108, 109, 119, 7, ++ 134, 67, 22, 108, 109, 68, 106, 8, 34, 35, ++ 9, 10, 101, 102, 11, 12, 101, 102, 105, 13, ++ 31, 14, 32, 15, 73, 74, 149, 91, 92, 153, ++ 23, 98, 94, 95, 64, 65, 149, 153, 101, 102, ++ 148, 57, 58, 59, 49, 50, 51, 52, 53, 54, ++ 55, 37, 6, 34, 35, 24, 25, 7, 44, 45, ++ 46, 47, 101, 102, 152, 8, 26, 27, 9, 10, ++ 133, 28, 60, 61, 38, 33, 39, 13, 36, 14, ++ 138, 15, 82, 83, 30, 32, 70, 42, 145, 146, ++ 72, 76, 77, 78, 79, 80, 81, 84, 86, 87, ++ 85, 34, 88, 89, 90, 96, 99, 100, 111, 112, ++ 117, 113, 114, 115, 116, 122, 123, 119, 124, 125, ++ 126, 127, 131, 132, 135, 136, 139, 140, 141, 93, ++ 0, 137, 142, 143, 0, 144, 147, 150, 151, 0, ++ 154, 155 }; - const signed char + const short int EvalParser::yycheck_[] = { - 20, 14, 71, 25, 26, 1, 2, 16, 30, 26, - 27, 28, 29, 30, 31, 32, 34, 35, 3, 9, - 5, 14, 12, 13, 9, 10, 11, 96, 14, 41, - 37, 43, 28, 29, 41, 20, 4, 106, 6, 7, - 25, 16, 111, 6, 7, 65, 66, 69, 33, 9, - 16, 36, 12, 13, 39, 40, 3, 42, 0, 44, - 9, 10, 11, 21, 22, 23, 24, 17, 18, 19, - 3, 20, 17, 18, 94, 14, 25, 17, 18, 19, - 17, 18, 19, 8, 33, 105, 41, 36, 15, 15, - 39, 40, 15, 42, 14, 44, 14, 38, 6, 16, - 38, 16, 16, 15, 15, 41, 15, 38, 4, 14, - 16, 4, 16, 16, 15, 14, 16, 15, -1, 16, - -1, 67 - 21, 82, 29, 19, 24, 25, 9, 10, 11, 9, - 14, 1, 2, 14, 34, 29, 14, 20, 16, 19, - 9, 14, 38, 12, 13, 28, 37, 41, 31, 32, - 41, 9, 35, 36, 12, 13, 117, 40, 14, 42, - 16, 44, 32, 33, 4, 16, 6, 7, 75, 76, - 3, 72, 73, 17, 18, 19, 137, 16, 78, 140, - 17, 18, 19, 17, 18, 19, 147, 148, 3, 3, - 5, 17, 18, 19, 9, 10, 11, 21, 22, 23, - 24, 25, 26, 27, 0, 20, 41, 14, 43, 16, - 14, 8, 16, 28, 115, 15, 31, 32, 6, 7, - 35, 36, 33, 34, 125, 40, 15, 42, 41, 44, - 17, 18, 133, 134, 39, 15, 39, 14, 14, 14, - 30, 15, 15, 6, 30, 16, 16, 16, 41, 16, - 16, 15, 30, 15, 15, 15, 15, 4, 14, 16, - 4, 16, 16, 16, 16, 14, 14, 9, 14, 41, - 38, 16, 15, 14, -1, 15, 15, -1, 16, 15, - 15, -1, 16, 16, -1, -1, -1, -1, -1, 74 ++ 22, 89, 26, 27, 19, 34, 9, 3, 14, 5, ++ 16, 31, 36, 9, 10, 11, 19, 46, 17, 18, ++ 19, 1, 2, 9, 20, 14, 12, 13, 43, 25, ++ 9, 42, 14, 12, 13, 46, 124, 33, 6, 7, ++ 36, 37, 17, 18, 40, 41, 17, 18, 19, 45, ++ 14, 47, 16, 49, 34, 35, 144, 79, 80, 147, ++ 14, 85, 82, 83, 38, 39, 154, 155, 17, 18, ++ 19, 9, 10, 11, 26, 27, 28, 29, 30, 31, ++ 32, 4, 20, 6, 7, 16, 16, 25, 21, 22, ++ 23, 24, 17, 18, 19, 33, 3, 3, 36, 37, ++ 122, 16, 40, 41, 46, 0, 48, 45, 8, 47, ++ 132, 49, 14, 14, 16, 16, 44, 46, 140, 141, ++ 44, 15, 15, 15, 14, 14, 14, 35, 15, 15, ++ 35, 6, 16, 16, 16, 46, 16, 16, 15, 15, ++ 4, 15, 15, 15, 35, 14, 16, 43, 16, 16, ++ 16, 16, 14, 14, 9, 4, 15, 14, 14, 81, ++ -1, 46, 15, 15, -1, 16, 16, 15, 15, -1, ++ 16, 16 }; const unsigned char EvalParser::yystos_[] = { - 0, 3, 5, 9, 10, 11, 20, 28, 31, 32, - 35, 36, 40, 42, 44, 46, 47, 48, 47, 47, - 14, 14, 14, 16, 3, 3, 16, 14, 16, 14, - 16, 0, 6, 7, 8, 4, 41, 43, 49, 49, - 41, 56, 21, 22, 23, 24, 25, 26, 27, 52, - 9, 10, 11, 35, 36, 48, 48, 33, 34, 57, - 37, 41, 51, 39, 51, 39, 47, 47, 48, 15, - 15, 15, 14, 14, 14, 14, 14, 30, 30, 15, - 15, 16, 16, 16, 49, 49, 56, 51, 51, 41, - 53, 48, 16, 16, 17, 18, 19, 50, 19, 50, - 9, 12, 13, 55, 15, 15, 15, 15, 15, 30, - 4, 19, 38, 9, 19, 14, 16, 16, 16, 16, - 16, 29, 41, 54, 14, 14, 49, 9, 9, 4, - 41, 49, 15, 14, 14, 15, 15, 16, 49, 49, - 16, 19, 50, 15, 15, 19, 50, 16, 16 + 0, 3, 5, 9, 10, 11, 20, 25, 33, 36, - 39, 40, 42, 44, 46, 47, 48, 47, 47, 14, - 14, 14, 16, 16, 16, 3, 3, 0, 6, 7, - 8, 4, 41, 43, 49, 49, 41, 51, 21, 22, - 23, 24, 52, 26, 27, 28, 29, 30, 31, 32, - 53, 34, 35, 54, 9, 10, 11, 48, 48, 47, - 47, 48, 15, 15, 15, 14, 14, 14, 38, 38, - 16, 16, 16, 49, 49, 51, 41, 56, 48, 17, - 18, 19, 50, 19, 50, 9, 12, 13, 55, 15, - 15, 15, 38, 4, 14, 16, 16, 16, 37, 41, - 57, 49, 9, 4, 15, 14, 16, 49, 19, 50, - 15, 16 ++ 37, 40, 41, 45, 47, 49, 51, 52, 53, 52, ++ 52, 14, 14, 14, 16, 16, 3, 3, 16, 14, ++ 16, 14, 16, 0, 6, 7, 8, 4, 46, 48, ++ 54, 54, 46, 56, 21, 22, 23, 24, 57, 26, ++ 27, 28, 29, 30, 31, 32, 59, 9, 10, 11, ++ 40, 41, 53, 53, 38, 39, 60, 42, 46, 58, ++ 44, 58, 44, 52, 52, 53, 15, 15, 15, 14, ++ 14, 14, 14, 14, 35, 35, 15, 15, 16, 16, ++ 16, 54, 54, 56, 58, 58, 46, 62, 53, 16, ++ 16, 17, 18, 19, 55, 19, 55, 9, 12, 13, ++ 61, 15, 15, 15, 15, 15, 35, 4, 19, 43, ++ 9, 19, 14, 16, 16, 16, 16, 16, 34, 46, ++ 63, 14, 14, 54, 9, 9, 4, 46, 54, 15, ++ 14, 14, 15, 15, 16, 54, 54, 16, 19, 55, ++ 15, 15, 19, 55, 16, 16 }; const unsigned char EvalParser::yyr1_[] = { -- 0, 45, 46, 47, 47, 47, 47, 47, 47, 47, - 47, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 49, 49, 50, 50, 51, 52, 52, - 52, 52, 53, 53, 53, 53, 53, 53, 53, 54, - 54, 55, 55, 56, 57, 57 - 47, 47, 47, 47, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 49, 49, 50, 50, 51, 51, 52, 52, 52, 52, - 52, 52, 52, 53, 54, 54, 55, 55, 56, 57, - 57 ++ 0, 50, 51, 52, 52, 52, 52, 52, 52, 52, ++ 52, 52, 52, 52, 53, 53, 53, 53, 53, 53, ++ 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, ++ 53, 54, 54, 55, 55, 56, 57, 57, 57, 57, ++ 58, 58, 59, 59, 59, 59, 59, 59, 59, 60, ++ 60, 61, 61, 62, 63, 63 }; const unsigned char EvalParser::yyr2_[] = { 0, 2, 1, 3, 2, 3, 3, 3, 6, 6, - 11, 1, 1, 1, 6, 6, 11, 3, 3, 3, - 6, 8, 6, 1, 1, 1, 1, 1, 1, 1, + 11, 6, 6, 11, 1, 1, 1, 6, 6, 11, - 6, 3, 3, 8, 6, 3, 3, 11, 6, 9, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ++ 3, 3, 3, 6, 8, 6, 3, 3, 11, 6, ++ 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1 + 1, 1, 1, 1, 1, 1 }; @@@ -1532,26 -1611,27 +1705,28 @@@ "\"end of file\"", "error", "$undefined", "\"(\"", "\")\"", "\"not\"", "\"and\"", "\"or\"", "\"==\"", "\"option\"", "\"relay4\"", "\"relay6\"", "\"peeraddr\"", "\"linkaddr\"", "\"[\"", "\"]\"", "\".\"", "\"text\"", - "\"hex\"", "\"exists\"", "\"pkt4\"", "\"mac\"", "\"hlen\"", "\"htype\"", - "\"ciaddr\"", "\"giaddr\"", "\"yiaddr\"", "\"siaddr\"", "\"substring\"", - "\"all\"", "\",\"", "\"concat\"", "\"pkt6\"", "\"msgtype\"", - "\"transid\"", "\"vendor-class\"", "\"vendor\"", "\"*\"", "\"data\"", - "\"enterprise\"", "\"constant string\"", "\"integer\"", - "\"constant hexstring\"", "\"option name\"", "\"ip address\"", "$accept", - "expression", "bool_expr", "string_expr", "option_code", - "option_repr_type", "enterprise_id", "pkt4_field", "start_expr", - "length_expr", "relay6_field", "nest_level", "pkt6_field", YY_NULLPTR + "\"hex\"", "\"exists\"", "\"pkt\"", "\"iface\"", "\"src\"", "\"dst\"", + "\"len\"", "\"pkt4\"", "\"mac\"", "\"hlen\"", "\"htype\"", "\"ciaddr\"", - "\"giaddr\"", "\"yiaddr\"", "\"siaddr\"", "\"pkt6\"", "\"msgtype\"", - "\"transid\"", "\"substring\"", "\"all\"", "\",\"", "\"concat\"", ++ "\"giaddr\"", "\"yiaddr\"", "\"siaddr\"", "\"substring\"", "\"all\"", ++ "\",\"", "\"concat\"", "\"pkt6\"", "\"msgtype\"", "\"transid\"", ++ "\"vendor-class\"", "\"vendor\"", "\"*\"", "\"data\"", "\"enterprise\"", + "\"constant string\"", "\"integer\"", "\"constant hexstring\"", + "\"option name\"", "\"ip address\"", "$accept", "expression", + "bool_expr", "string_expr", "option_code", "option_repr_type", - "nest_level", "pkt_metadata", "pkt4_field", "pkt6_field", "relay6_field", - "start_expr", "length_expr", YY_NULLPTR ++ "nest_level", "pkt_metadata", "enterprise_id", "pkt4_field", ++ "pkt6_field", "relay6_field", "start_expr", "length_expr", YY_NULLPTR }; #if YYDEBUG const unsigned short int EvalParser::yyrline_[] = { -- 0, 106, 106, 109, 110, 115, 120, 125, 130, 135, - 155, 171, 176, 181, 186, 191, 212, 227, 232, 246, - 260, 275, 280, 287, 291, 297, 301, 307, 316, 320, - 324, 328, 334, 338, 342, 346, 350, 354, 358, 364, - 368, 374, 378, 384, 391, 396 - 155, 169, 178, 188, 199, 204, 209, 214, 219, 240, - 255, 270, 275, 280, 285, 290, 298, 307, 318, 329, - 343, 347, 353, 357, 363, 367, 372, 376, 380, 384, - 388, 392, 396, 402, 409, 414, 421, 422, 425, 434, - 435 ++ 0, 112, 112, 115, 116, 121, 126, 131, 136, 141, ++ 161, 175, 184, 193, 205, 210, 215, 220, 225, 246, ++ 261, 266, 280, 294, 309, 314, 319, 328, 338, 347, ++ 360, 375, 379, 385, 389, 395, 404, 408, 412, 416, ++ 422, 426, 432, 436, 440, 444, 448, 452, 456, 462, ++ 466, 472, 476, 482, 489, 494 }; // Print the state stack on the debug stream. @@@ -1586,8 -1666,8 +1761,8 @@@ #line 13 "parser.yy" // lalr1.cc:1167 } } // isc::eval - #line 1590 "parser.cc" // lalr1.cc:1167 - #line 403 "parser.yy" // lalr1.cc:1168 -#line 1670 "parser.cc" // lalr1.cc:1167 -#line 438 "parser.yy" // lalr1.cc:1168 ++#line 1765 "parser.cc" // lalr1.cc:1167 ++#line 501 "parser.yy" // lalr1.cc:1168 void isc::eval::EvalParser::error(const location_type& loc, diff --cc src/lib/eval/parser.h index fe72128758,a4883dcfbf..f61db8fff2 --- a/src/lib/eval/parser.h +++ b/src/lib/eval/parser.h @@@ -315,13 -312,16 +315,16 @@@ namespace isc { namespace eval // "constant hexstring" // "option name" // "ip address" - char dummy5[sizeof(std::string)]; + char dummy6[sizeof(std::string)]; // option_code - char dummy6[sizeof(uint16_t)]; + char dummy7[sizeof(uint16_t)]; + // enterprise_id - char dummy7[sizeof(uint32_t)]; ++ char dummy8[sizeof(uint32_t)]; + // nest_level -- char dummy8[sizeof(uint8_t)]; ++ char dummy9[sizeof(uint8_t)]; }; /// Symbol semantic values. @@@ -362,31 -362,31 +365,36 @@@ TOKEN_TEXT = 272, TOKEN_HEX = 273, TOKEN_EXISTS = 274, - 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_VENDOR_CLASS = 290, - TOKEN_VENDOR = 291, - TOKEN_ANY = 292, - TOKEN_DATA = 293, - TOKEN_ENTERPRISE = 294, - TOKEN_STRING = 295, - TOKEN_INTEGER = 296, - TOKEN_HEXSTRING = 297, - TOKEN_OPTION_NAME = 298, - TOKEN_IP_ADDRESS = 299 + TOKEN_PKT = 275, + TOKEN_IFACE = 276, + TOKEN_SRC = 277, + TOKEN_DST = 278, + TOKEN_LEN = 279, + TOKEN_PKT4 = 280, + TOKEN_CHADDR = 281, + TOKEN_HLEN = 282, + TOKEN_HTYPE = 283, + TOKEN_CIADDR = 284, + TOKEN_GIADDR = 285, + TOKEN_YIADDR = 286, + TOKEN_SIADDR = 287, - TOKEN_PKT6 = 288, - TOKEN_MSGTYPE = 289, - TOKEN_TRANSID = 290, - TOKEN_SUBSTRING = 291, - TOKEN_ALL = 292, - TOKEN_COMA = 293, - TOKEN_CONCAT = 294, - TOKEN_STRING = 295, - TOKEN_INTEGER = 296, - TOKEN_HEXSTRING = 297, - TOKEN_OPTION_NAME = 298, - TOKEN_IP_ADDRESS = 299 ++ TOKEN_SUBSTRING = 288, ++ TOKEN_ALL = 289, ++ TOKEN_COMA = 290, ++ TOKEN_CONCAT = 291, ++ TOKEN_PKT6 = 292, ++ TOKEN_MSGTYPE = 293, ++ TOKEN_TRANSID = 294, ++ TOKEN_VENDOR_CLASS = 295, ++ TOKEN_VENDOR = 296, ++ TOKEN_ANY = 297, ++ TOKEN_DATA = 298, ++ TOKEN_ENTERPRISE = 299, ++ TOKEN_STRING = 300, ++ TOKEN_INTEGER = 301, ++ TOKEN_HEXSTRING = 302, ++ TOKEN_OPTION_NAME = 303, ++ TOKEN_IP_ADDRESS = 304 }; }; @@@ -757,7 -757,7 +787,7 @@@ static const signed char yypgoto_[]; // YYDEFGOTO[NTERM-NUM]. -- static const signed char yydefgoto_[]; ++ static const short int yydefgoto_[]; // YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If // positive, shift that token. If negative, reduce the rule whose @@@ -884,12 -884,12 +914,12 @@@ enum { yyeof_ = 0, - yylast_ = 121, ///< Last index in yytable_. - yylast_ = 169, ///< Last index in yytable_. -- yynnts_ = 13, ///< Number of nonterminal symbols. - yyfinal_ = 27, ///< Termination state number. - yyfinal_ = 31, ///< Termination state number. ++ yylast_ = 171, ///< Last index in yytable_. ++ yynnts_ = 14, ///< Number of nonterminal symbols. ++ yyfinal_ = 33, ///< Termination state number. yyterror_ = 1, yyerrcode_ = 256, -- yyntokens_ = 45 ///< Number of tokens. ++ yyntokens_ = 50 ///< Number of tokens. }; @@@ -935,9 -935,9 +965,10 @@@ 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, 32, 33, 34, -- 35, 36, 37, 38, 39, 40, 41, 42, 43, 44 ++ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, ++ 45, 46, 47, 48, 49 }; -- const unsigned int user_token_number_max_ = 299; ++ const unsigned int user_token_number_max_ = 304; const token_number_type undef_token_ = 2; if (static_cast(t) <= yyeof_) @@@ -970,39 -970,39 +1001,43 @@@ { switch (other.type_get ()) { -- case 50: // option_repr_type ++ case 55: // option_repr_type value.copy< TokenOption::RepresentationType > (other.value); break; - case 53: // pkt4_field - case 52: // pkt4_field ++ case 59: // pkt4_field value.copy< TokenPkt4::FieldType > (other.value); break; - case 54: // pkt6_field - case 57: // pkt6_field ++ case 60: // pkt6_field value.copy< TokenPkt6::FieldType > (other.value); break; - case 52: // pkt_metadata - case 55: // relay6_field ++ case 57: // pkt_metadata + value.copy< TokenPkt::MetadataType > (other.value); + break; + - case 55: // relay6_field ++ case 61: // relay6_field value.copy< TokenRelay6Field::FieldType > (other.value); break; -- case 40: // "constant string" -- case 41: // "integer" -- case 42: // "constant hexstring" -- case 43: // "option name" -- case 44: // "ip address" ++ case 45: // "constant string" ++ case 46: // "integer" ++ case 47: // "constant hexstring" ++ case 48: // "option name" ++ case 49: // "ip address" value.copy< std::string > (other.value); break; -- case 49: // option_code ++ case 54: // option_code value.copy< uint16_t > (other.value); break; - case 51: // nest_level - case 51: // enterprise_id ++ case 58: // enterprise_id + value.copy< uint32_t > (other.value); + break; + + case 56: // nest_level value.copy< uint8_t > (other.value); break; @@@ -1023,39 -1023,39 +1058,43 @@@ (void) v; switch (this->type_get ()) { -- case 50: // option_repr_type ++ case 55: // option_repr_type value.copy< TokenOption::RepresentationType > (v); break; - case 53: // pkt4_field - case 52: // pkt4_field ++ case 59: // pkt4_field value.copy< TokenPkt4::FieldType > (v); break; - case 54: // pkt6_field - case 57: // pkt6_field ++ case 60: // pkt6_field value.copy< TokenPkt6::FieldType > (v); break; - case 52: // pkt_metadata - case 55: // relay6_field ++ case 57: // pkt_metadata + value.copy< TokenPkt::MetadataType > (v); + break; + - case 55: // relay6_field ++ case 61: // relay6_field value.copy< TokenRelay6Field::FieldType > (v); break; -- case 40: // "constant string" -- case 41: // "integer" -- case 42: // "constant hexstring" -- case 43: // "option name" -- case 44: // "ip address" ++ case 45: // "constant string" ++ case 46: // "integer" ++ case 47: // "constant hexstring" ++ case 48: // "option name" ++ case 49: // "ip address" value.copy< std::string > (v); break; -- case 49: // option_code ++ case 54: // option_code value.copy< uint16_t > (v); break; - case 51: // nest_level - case 51: // enterprise_id ++ case 58: // enterprise_id + value.copy< uint32_t > (v); + break; + + case 56: // nest_level value.copy< uint8_t > (v); break; @@@ -1156,39 -1156,39 +1202,43 @@@ // Type destructor. switch (yytype) { -- case 50: // option_repr_type ++ case 55: // option_repr_type value.template destroy< TokenOption::RepresentationType > (); break; - case 53: // pkt4_field - case 52: // pkt4_field ++ case 59: // pkt4_field value.template destroy< TokenPkt4::FieldType > (); break; - case 54: // pkt6_field - case 57: // pkt6_field ++ case 60: // pkt6_field value.template destroy< TokenPkt6::FieldType > (); break; - case 52: // pkt_metadata - case 55: // relay6_field ++ case 57: // pkt_metadata + value.template destroy< TokenPkt::MetadataType > (); + break; + - case 55: // relay6_field ++ case 61: // relay6_field value.template destroy< TokenRelay6Field::FieldType > (); break; -- case 40: // "constant string" -- case 41: // "integer" -- case 42: // "constant hexstring" -- case 43: // "option name" -- case 44: // "ip address" ++ case 45: // "constant string" ++ case 46: // "integer" ++ case 47: // "constant hexstring" ++ case 48: // "option name" ++ case 49: // "ip address" value.template destroy< std::string > (); break; -- case 49: // option_code ++ case 54: // option_code value.template destroy< uint16_t > (); break; - case 51: // nest_level - case 51: // enterprise_id ++ case 58: // enterprise_id + value.template destroy< uint32_t > (); + break; + + case 56: // nest_level value.template destroy< uint8_t > (); break; @@@ -1215,39 -1215,39 +1265,43 @@@ super_type::move(s); switch (this->type_get ()) { -- case 50: // option_repr_type ++ case 55: // option_repr_type value.move< TokenOption::RepresentationType > (s.value); break; - case 53: // pkt4_field - case 52: // pkt4_field ++ case 59: // pkt4_field value.move< TokenPkt4::FieldType > (s.value); break; - case 54: // pkt6_field - case 57: // pkt6_field ++ case 60: // pkt6_field value.move< TokenPkt6::FieldType > (s.value); break; - case 52: // pkt_metadata - case 55: // relay6_field ++ case 57: // pkt_metadata + value.move< TokenPkt::MetadataType > (s.value); + break; + - case 55: // relay6_field ++ case 61: // relay6_field value.move< TokenRelay6Field::FieldType > (s.value); break; -- case 40: // "constant string" -- case 41: // "integer" -- case 42: // "constant hexstring" -- case 43: // "option name" -- case 44: // "ip address" ++ case 45: // "constant string" ++ case 46: // "integer" ++ case 47: // "constant hexstring" ++ case 48: // "option name" ++ case 49: // "ip address" value.move< std::string > (s.value); break; -- case 49: // option_code ++ case 54: // option_code value.move< uint16_t > (s.value); break; - case 51: // nest_level - case 51: // enterprise_id ++ case 58: // enterprise_id + value.move< uint32_t > (s.value); + break; + + case 56: // nest_level value.move< uint8_t > (s.value); break; @@@ -1310,7 -1310,7 +1364,7 @@@ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, -- 295, 296, 297, 298, 299 ++ 295, 296, 297, 298, 299, 300, 301, 302, 303, 304 }; return static_cast (yytoken_number_[type]); } @@@ -1576,7 -1576,7 +1660,7 @@@ #line 13 "parser.yy" // lalr1.cc:377 } } // isc::eval --#line 1580 "parser.h" // lalr1.cc:377 ++#line 1664 "parser.h" // lalr1.cc:377 diff --cc src/lib/eval/parser.yy index 92bdbbc865,d27ab66c12..62a6bd270c --- a/src/lib/eval/parser.yy +++ b/src/lib/eval/parser.yy @@@ -304,33 -363,16 +392,43 @@@ option_repr_type : TEX } ; +nest_level : INTEGER + { + $$ = ctx.convertNestLevelNumber($1, @1); + } + // Eventually we may add strings to handle different + // ways of choosing from which relay we want to extract + // an option or field. + ; + +pkt_metadata : IFACE + { + $$ = TokenPkt::IFACE; + } + | SRC + { + $$ = TokenPkt::SRC; + } + | DST + { + $$ = TokenPkt::DST; + } + | LEN + { + $$ = TokenPkt::LEN; + } + ; + + enterprise_id : INTEGER + { + $$ = ctx.convertUint32($1, @1); + } + | "*" + { + $$ = 0; + } + ; + pkt4_field : CHADDR { $$ = TokenPkt4::CHADDR; @@@ -361,27 -403,14 +459,34 @@@ } ; +pkt6_field : MSGTYPE + { + $$ = TokenPkt6::MSGTYPE; + } + | TRANSID + { + $$ = TokenPkt6::TRANSID; + } + ; + +relay6_field : PEERADDR + { + $$ = TokenRelay6Field::PEERADDR; + } + | LINKADDR + { + $$ = TokenRelay6Field::LINKADDR; + } + ; + start_expr : INTEGER + { + TokenPtr str(new TokenString($1)); + ctx.expression.push_back(str); + } + ; + + length_expr : INTEGER { TokenPtr str(new TokenString($1)); ctx.expression.push_back(str); diff --cc src/lib/eval/tests/context_unittest.cc index b278ed9a81,b8a6954c96..d8811d1ffe --- a/src/lib/eval/tests/context_unittest.cc +++ b/src/lib/eval/tests/context_unittest.cc @@@ -417,46 -340,223 +417,227 @@@ public universe_ = universe; } - Option::Universe universe_; - /// @brief Test that verifies access to the DHCPv6 packet fields. - /// - /// This test attempts to parse the expression, will check if the number - /// of tokens is exactly as planned and then will try to verify if the - /// first token represents expected the field in DHCPv6 packet. - /// - /// @param expr expression to be parsed - /// @param exp_type expected field type to be parsed - /// @param exp_tokens expected number of tokens - void testPkt6Field(std::string expr, TokenPkt6::FieldType exp_type, - int exp_tokens) { - EvalContext eval(Option::V6); - - // 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 the requested number of tokens - ASSERT_EQ(exp_tokens, eval.expression.size()); - - // Check that the first token is TokenPkt6 instance and has correct type. - checkTokenPkt6(eval.expression.at(0), exp_type); - } - - + /// @brief Checks if the given token is TokenVendor and has expected characteristics + /// @param token token to be checked + /// @param exp_vendor_id expected vendor-id (aka enterprise number) + /// @param exp_repr expected representation (either 'exists' or 'hex') + /// @param exp_option_code expected option code (ignored if 0) + void checkTokenVendor(const TokenPtr& token, uint32_t exp_vendor_id, + uint16_t exp_option_code, + TokenOption::RepresentationType exp_repr) { + ASSERT_TRUE(token); + + boost::shared_ptr vendor = + boost::dynamic_pointer_cast(token); + + ASSERT_TRUE(vendor); + + EXPECT_EQ(exp_vendor_id, vendor->getVendorId()); + EXPECT_EQ(exp_repr, vendor->getRepresentation()); + EXPECT_EQ(exp_option_code, vendor->getCode()); + } + + /// @brief Tests if specified token vendor expression can be parsed + /// + /// This test assumes the first token will be token vendor. Any additional + /// tokens are ignored. Tests expressions: + /// vendor[1234].option[234].hex + /// vendor[1234].option[234].exists + /// + /// @param expr expression to be parsed + /// @param u universe (V4 or V6) + /// @param vendor_id expected vendor-id (aka enterprise number) + /// @param option_code expected option code (ignored if 0) + /// @param expected_repr expected representation (either 'exists' or 'hex') + void testVendor(std::string expr, Option::Universe u, uint32_t vendor_id, + uint16_t option_code, TokenOption::RepresentationType expected_repr) { + EvalContext eval(u); + + EXPECT_NO_THROW(parsed_ = eval.parseString(expr)); + EXPECT_TRUE(parsed_); + + // We need at least one token, we will evaluate the first one. + ASSERT_FALSE(eval.expression.empty()); + + checkTokenVendor(eval.expression.at(0), vendor_id, option_code, expected_repr); + } + + /// @brief Checks if token is really a TokenVendor, that the vendor_id was + /// stored properly and that it has expected representation + /// + /// This test is able to handle expressions similar to: + /// vendor[4491].option[1].hex + /// vendor[4491].option[1].exists + /// vendor[4491].exists + /// vendor[*].exists + /// + /// @param expr expression to be parsed + /// @param u universe (V4 or V6) + /// @param vendor_id expected vendor-id (aka enterprise number) + /// @param expected_repr expected representation (either 'exists' or 'hex') + void testVendor(std::string expr, Option::Universe u, uint32_t vendor_id, + TokenOption::RepresentationType expected_repr) { + testVendor(expr, u, vendor_id, 0, expected_repr); + } + + /// @brief Tests if the expression parses into token vendor that returns enterprise-id + /// + /// This test is able to handle expressions similar to: + /// vendor.enterprise + /// + /// @param expr expression to be parsed + /// @param u universe (V4 or V6) + void testVendorEnterprise(std::string expr, Option::Universe u) { + EvalContext eval(u); + + EXPECT_NO_THROW(parsed_ = eval.parseString(expr)); + EXPECT_TRUE(parsed_); + + ASSERT_FALSE(eval.expression.empty()); + + boost::shared_ptr vendor = + boost::dynamic_pointer_cast(eval.expression.at(0)); + + ASSERT_TRUE(vendor); + EXPECT_EQ(TokenVendor::ENTERPRISE_ID, vendor->getField()); + } + + /// @brief This test checks if vendor-class token is correct + /// + /// This test checks if EXISTS representation is set correctly. + /// It covers cases like: + /// - vendor-class[4491].exists + /// - vendor-class[*].exists + /// + /// @param expr expression to be parsed + /// @param u universe (V4 or V6) + /// @param vendor_id expected vendor-id (aka enterprise number) + void testVendorClass(std::string expr, Option::Universe u, uint32_t vendor_id) { + EvalContext eval(u); + + EXPECT_NO_THROW(parsed_ = eval.parseString(expr)); + EXPECT_TRUE(parsed_); + + ASSERT_EQ(1, eval.expression.size()); + checkTokenVendorClass(eval.expression.at(0), vendor_id, 0, TokenOption::EXISTS, + TokenVendor::EXISTS); + } + + /// @brief Tests if specified token vendor class expression can be parsed + /// + /// This test assumes the first token will be token vendor-class. + /// Any additional tokens are ignored. Tests expressions: + /// - vendor-class[4491].exists + /// - vendor-class[*].exists + /// - vendor-class[4491].data + /// - vendor-class[4491].data[3] + /// + /// @param expr expression to be parsed + /// @param u universe (V4 or V6) + /// @param vendor_id expected vendor-id (aka enterprise number) + /// @param index expected data index + void testVendorClass(std::string expr, Option::Universe u, uint32_t vendor_id, + uint16_t index) { + EvalContext eval(u); + + EXPECT_NO_THROW(parsed_ = eval.parseString(expr)); + EXPECT_TRUE(parsed_); + + // Make sure there's at least one token + ASSERT_FALSE(eval.expression.empty()); + + // The first token should be TokenVendorClass, let's take a closer look. + checkTokenVendorClass(eval.expression.at(0), vendor_id, index, + TokenOption::HEXADECIMAL, TokenVendor::DATA); + + } + + /// @brief Tests if the expression parses into vendor class token that + /// returns enterprise-id. + /// + /// This test is able to handle expressions similar to: + /// - vendor-class.enterprise + /// + /// @param expr expression to be parsed + /// @param u universe (V4 or V6) + void testVendorClassEnterprise(std::string expr, Option::Universe u) { + EvalContext eval(u); + + EXPECT_NO_THROW(parsed_ = eval.parseString(expr)); + EXPECT_TRUE(parsed_); + + // Make sure there's at least one token + ASSERT_FALSE(eval.expression.empty()); + + // The first token should be TokenVendorClass, let's take a closer look. + checkTokenVendorClass(eval.expression.at(0), 0, 0, TokenOption::HEXADECIMAL, + TokenVendor::ENTERPRISE_ID); + } + + /// @brief Checks if the given token is TokenVendorClass and has expected characteristics + /// + /// @param token token to be checked + /// @param vendor_id expected vendor-id (aka enterprise number) + /// @param index expected index (used for data field only) + /// @param repr expected representation (either 'exists' or 'hex') + /// @param field expected field (none, enterprise or data) + void checkTokenVendorClass(const TokenPtr& token, uint32_t vendor_id, + uint16_t index, TokenOption::RepresentationType repr, + TokenVendor::FieldType field) { + ASSERT_TRUE(token); + + boost::shared_ptr vendor = + boost::dynamic_pointer_cast(token); + + ASSERT_TRUE(vendor); + + EXPECT_EQ(vendor_id, vendor->getVendorId()); + EXPECT_EQ(index, vendor->getDataIndex()); + EXPECT_EQ(repr, vendor->getRepresentation()); + EXPECT_EQ(field, vendor->getField()); + } + + Option::Universe universe_; ///< Universe (V4 or V6) bool parsed_; ///< Parsing status ++ }; +// Test the error method without location +TEST_F(EvalContextTest, error) { + + EvalContext eval(Option::V4); + + EXPECT_THROW(eval.error("an error"), EvalParseError); +} + +// Test the fatal method +TEST_F(EvalContextTest, fatal) { + + EvalContext eval(Option::V4); + + EXPECT_THROW(eval.fatal("a fatal error"), isc::Unexpected); +} + +// Test the convertOptionCode method with an illegal input +TEST_F(EvalContextTest, badOptionCode) { + + EvalContext eval(Option::V4); + + // the option code must be a number + EXPECT_THROW(eval.convertOptionCode("bad", location(position())), + EvalParseError); +} + +// Test the convertNestLevelNumber method with an illegal input +TEST_F(EvalContextTest, badNestLevelNumber) { + + EvalContext eval(Option::V4); + + // the nest level number must be a number + EXPECT_THROW(eval.convertNestLevelNumber("bad", location(position())), + EvalParseError); +} + // Test the parsing of a basic expression TEST_F(EvalContextTest, basic) { @@@ -711,81 -811,6 +892,80 @@@ TEST_F(EvalContextTest, relay4Error) ":1.1-6: relay4 can only be used in DHCPv4."); } +// Test the parsing of a relay6 option +TEST_F(EvalContextTest, relay6Option) { + EvalContext eval(Option::V6); + + testRelay6Option("relay6[0].option[123].text == 'foo'", + 0, 123, TokenOption::TEXTUAL, 3); +} + +// Test the parsing of existence for a relay6 option +TEST_F(EvalContextTest, relay6OptionExists) { + EvalContext eval(Option::V6); + + testRelay6Option("relay6[1].option[75].exists", + 1, 75, TokenOption::EXISTS, 1); +} + +// Test the parsing of hex for a relay6 option +TEST_F(EvalContextTest, relay6OptionHex) { + EvalContext eval(Option::V6); + + testRelay6Option("relay6[2].option[85].hex == 'foo'", + 2, 85, TokenOption::HEXADECIMAL, 3); +} + +// Test the nest level of a relay6 option should be in [0..32[ +TEST_F(EvalContextTest, relay6OptionLimits) { + EvalContext eval(Option::V6); + + // max nest level is hop count limit minus one so 31 + testRelay6Option("relay6[31].option[123].text == 'foo'", + 31, 123, TokenOption::TEXTUAL, 3); + + universe_ = Option::V6; + + checkError("relay6[32].option[123].text == 'foo'", + ":1.8-9: Nest level has invalid value in 32. " + "Allowed range: 0..31"); + + // next level must be a positive number + checkError("relay6[-1].option[123].text == 'foo'", - ":1.8-9: Nest level has invalid value in -1. " - "Allowed range: 0..31"); ++ ":1.8-9: Invalid value in -1. Allowed range: 0..255"); +} + +// Verify that relay6[13].option is not usable in v4 +TEST_F(EvalContextTest, relay6OptionError) { + universe_ = Option::V4; + + // nest_level is reduced first so raises the error + // (if we'd like to get a relay6 error we have to insert an + // intermediate action to check the universe) + checkError("relay6[0].option[123].text == 'foo'", + ":1.8: Nest level invalid for DHCPv4 packets"); +} + +// Tests whether iface metadata in DHCP can be accessed. +TEST_F(EvalContextTest, pktMetadataIface) { + testPktMetadata("pkt.iface == 'eth0'", TokenPkt::IFACE, 3); +} + +// Tests whether src metadata in DHCP can be accessed. +TEST_F(EvalContextTest, pktMetadataSrc) { + testPktMetadata("pkt.src == fe80::1", TokenPkt::SRC, 3); +} + +// Tests whether dst metadata in DHCP can be accessed. +TEST_F(EvalContextTest, pktMetadataDst) { + testPktMetadata("pkt.dst == fe80::2", TokenPkt::DST, 3); +} + +// Tests whether len metadata in DHCP can be accessed. +TEST_F(EvalContextTest, pktMetadataLen) { + testPktMetadata("pkt.len == 0x00000100", TokenPkt::LEN, 3); +} + // Tests whether chaddr field in DHCPv4 can be accessed. TEST_F(EvalContextTest, pkt4FieldChaddr) { testPkt4Field("pkt4.mac == 0x000102030405", TokenPkt4::CHADDR, 3); diff --cc src/lib/eval/token.cc index 918e4e9ae7,a130c35715..7ef16a0348 --- a/src/lib/eval/token.cc +++ b/src/lib/eval/token.cc @@@ -7,11 -7,14 +7,15 @@@ #include #include #include +#include #include #include -#include #include +#include + #include + #include + #include + #include #include #include @@@ -641,3 -482,358 +655,227 @@@ TokenOr::evaluate(Pkt& /*pkt*/, ValueSt .arg('\'' + op2 + '\'') .arg('\'' + values.top() + '\''); } + -OptionPtr TokenRelay6Option::getOption(Pkt& pkt) { - - try { - // Check if it's a Pkt6. If it's not the dynamic_cast will - // throw std::bad_cast. - Pkt6& pkt6 = dynamic_cast(pkt); - - try { - // Now that we have the right type of packet we can - // get the option and return it. - return(pkt6.getRelayOption(option_code_, nest_level_)); - } - catch (const isc::OutOfRange&) { - // The only exception we expect is OutOfRange if the nest - // level is out of range of the encapsulations, for example - // if nest_level_ is 4 and there are only 2 encapsulations. - // We return a NULL in that case. - return (OptionPtr()); - } - - } catch (const std::bad_cast&) { - isc_throw(EvalTypeError, "Specified packet is not Pkt6"); - } - -} - -void -TokenRelay6Field::evaluate(Pkt& pkt, ValueStack& values) { - - vector binary; - string type_str; - try { - // Check if it's a Pkt6. If it's not the dynamic_cast will - // throw std::bad_cast. - const Pkt6& pkt6 = dynamic_cast(pkt); - - try { - switch (type_) { - // Now that we have the right type of packet we can - // get the option and return it. - case LINKADDR: - type_str = "linkaddr"; - binary = pkt6.getRelay6LinkAddress(nest_level_).toBytes(); - break; - case PEERADDR: - type_str = "peeraddr"; - binary = pkt6.getRelay6PeerAddress(nest_level_).toBytes(); - break; - } - } catch (const isc::OutOfRange&) { - // The only exception we expect is OutOfRange if the nest - // level is invalid. We push "" in that case. - values.push(""); - // Log what we pushed - LOG_DEBUG(eval_logger, EVAL_DBG_STACK, EVAL_DEBUG_RELAY6_RANGE) - .arg(type_str) - .arg(unsigned(nest_level_)) - .arg("0x"); - return; - } - } catch (const std::bad_cast&) { - isc_throw(EvalTypeError, "Specified packet is not Pkt6"); - } - - string value; - value.resize(binary.size()); - if (!binary.empty()) { - memmove(&value[0], &binary[0], binary.size()); - } - values.push(value); - - // Log what we pushed - LOG_DEBUG(eval_logger, EVAL_DBG_STACK, EVAL_DEBUG_RELAY6) - .arg(type_str) - .arg(unsigned(nest_level_)) - .arg("0x" + util::encode::encodeHex(std::vector(value.begin(), - value.end()))); -} - -void -TokenPkt6::evaluate(Pkt& pkt, ValueStack& values) { - - vector binary; - string type_str; - try { - // Check if it's a Pkt6. If it's not the dynamic_cast will throw - // std::bad_cast (failed dynamic_cast returns NULL for pointers and - // throws for references). - const Pkt6& pkt6 = dynamic_cast(pkt); - - switch (type_) { - case MSGTYPE: { - // msg type is an uint8_t integer. We want a 4 byte string so 0 pad. - binary.push_back(0); - binary.push_back(0); - binary.push_back(0); - binary.push_back(pkt6.getType()); - type_str = "msgtype"; - break; - } - case TRANSID: { - // transaction id is an uint32_t integer. We want a 4 byte string so copy - uint32_t transid = pkt6.getTransid(); - binary.push_back(transid >> 24); - binary.push_back((transid >> 16) & 0xFF); - binary.push_back((transid >> 8) & 0xFF); - binary.push_back(transid & 0xFF); - type_str = "transid"; - break; - } - default: - isc_throw(EvalTypeError, "Bad field specified: " - << static_cast(type_) ); - } - - } catch (const std::bad_cast&) { - isc_throw(EvalTypeError, "Specified packet is not Pkt6"); - } - - string value; - value.resize(binary.size()); - memmove(&value[0], &binary[0], binary.size()); - values.push(value); - - // Log what we pushed - LOG_DEBUG(eval_logger, EVAL_DBG_STACK, EVAL_DEBUG_PKT6) - .arg(type_str) - .arg("0x" + util::encode::encodeHex(std::vector(value.begin(), - value.end()))); -} - + TokenVendor::TokenVendor(Option::Universe u, uint32_t vendor_id, RepresentationType repr, + uint16_t option_code) + :TokenOption(option_code, repr), universe_(u), vendor_id_(vendor_id), + field_(option_code ? SUBOPTION : EXISTS) + { + } + + TokenVendor::TokenVendor(Option::Universe u, uint32_t vendor_id, FieldType field) + :TokenOption(0, TokenOption::HEXADECIMAL), universe_(u), vendor_id_(vendor_id), + field_(field) + { + if (field_ == EXISTS) { + representation_type_ = TokenOption::EXISTS; + } + } + + uint32_t TokenVendor::getVendorId() const { + return (vendor_id_); + } + + TokenVendor::FieldType TokenVendor::getField() const { + return (field_); + } + + void TokenVendor::evaluate(Pkt& pkt, ValueStack& values) { + + // Get the option first. + uint16_t code = 0; + switch (universe_) { + case Option::V4: + code = DHO_VIVSO_SUBOPTIONS; + break; + case Option::V6: + code = D6O_VENDOR_OPTS; + break; + } + + OptionPtr opt = pkt.getOption(code); + OptionVendorPtr vendor = boost::dynamic_pointer_cast(opt); + if (!vendor) { + // There's no vendor option, give up. + std::string txt = pushFailure(values); + LOG_DEBUG(eval_logger, EVAL_DBG_STACK, EVAL_DEBUG_VENDOR_NO_OPTION) + .arg(code) + .arg(txt); + return; + } + + if (vendor_id_ && (vendor_id_ != vendor->getVendorId())) { + // There is vendor option, but it has other vendor-id value + // than we're looking for. (0 means accept any vendor-id) + std::string txt = pushFailure(values); + LOG_DEBUG(eval_logger, EVAL_DBG_STACK, EVAL_DEBUG_VENDOR_ENTERPRISE_ID_MISMATCH) + .arg(vendor_id_) + .arg(vendor->getVendorId()) + .arg(txt); + return; + } + + switch (field_) { + case ENTERPRISE_ID: + { + // Extract enterprise-id + string txt(sizeof(uint32_t), 0); + uint32_t value = htonl(vendor->getVendorId()); + memcpy(&txt[0], &value, sizeof(uint32_t)); + values.push(txt); + LOG_DEBUG(eval_logger, EVAL_DBG_STACK, EVAL_DEBUG_VENDOR_ENTERPRISE_ID) + .arg(vendor->getVendorId()) + .arg(util::encode::encodeHex(std::vector(txt.begin(), + txt.end()))); + return; + } + case SUBOPTION: + /// This is vendor[X].option[Y].exists, let's try to + /// extract the option + TokenOption::evaluate(pkt, values); + return; + case EXISTS: + // We already passed all the checks: the option is there and has specified + // enterprise-id. + LOG_DEBUG(eval_logger, EVAL_DBG_STACK, EVAL_DEBUG_VENDOR_EXISTS) + .arg(vendor->getVendorId()) + .arg("true"); + values.push("true"); + return; + case DATA: + // This is for vendor-class option, we can skip it here. + isc_throw(EvalTypeError, "Field None is not valid for vendor-class"); + return; + } + } + + OptionPtr TokenVendor::getOption(Pkt& pkt) { + uint16_t code = 0; + switch (universe_) { + case Option::V4: + code = DHO_VIVSO_SUBOPTIONS; + break; + case Option::V6: + code = D6O_VENDOR_OPTS; + break; + } + + OptionPtr opt = pkt.getOption(code); + if (!opt) { + // If vendor option is not found, return NULL + return (opt); + } + + // If vendor option is found, try to return its + // encapsulated option. + return (opt->getOption(option_code_)); + } + + TokenVendorClass::TokenVendorClass(Option::Universe u, uint32_t vendor_id, + RepresentationType repr) + :TokenVendor(u, vendor_id, repr, 0), index_(0) { + } + + TokenVendorClass::TokenVendorClass(Option::Universe u, uint32_t vendor_id, + FieldType field, uint16_t index) + :TokenVendor(u, vendor_id, TokenOption::HEXADECIMAL, 0), index_(index) + { + field_ = field; + } + + uint16_t TokenVendorClass::getDataIndex() const { + return (index_); + } + + void TokenVendorClass::evaluate(Pkt& pkt, ValueStack& values) { + + // Get the option first. + uint16_t code = 0; + switch (universe_) { + case Option::V4: + code = DHO_VIVCO_SUBOPTIONS; + break; + case Option::V6: + code = D6O_VENDOR_CLASS; + break; + } + + OptionPtr opt = pkt.getOption(code); + OptionVendorClassPtr vendor = boost::dynamic_pointer_cast(opt); + if (!vendor) { + // There's no vendor class option, give up. + std::string txt = pushFailure(values); + LOG_DEBUG(eval_logger, EVAL_DBG_STACK, EVAL_DEBUG_VENDOR_CLASS_NO_OPTION) + .arg(code) + .arg(txt); + return; + } + + if (vendor_id_ && (vendor_id_ != vendor->getVendorId())) { + // There is vendor option, but it has other vendor-id value + // than we're looking for. (0 means accept any vendor-id) + std::string txt = pushFailure(values); + LOG_DEBUG(eval_logger, EVAL_DBG_STACK, EVAL_DEBUG_VENDOR_CLASS_ENTERPRISE_ID_MISMATCH) + .arg(vendor_id_) + .arg(vendor->getVendorId()) + .arg(txt); + return; + } + + switch (field_) { + case ENTERPRISE_ID: + { + // Extract enterprise-id + string txt(sizeof(uint32_t), 0); + uint32_t value = htonl(vendor->getVendorId()); + memcpy(&txt[0], &value, sizeof(uint32_t)); + values.push(txt); + LOG_DEBUG(eval_logger, EVAL_DBG_STACK, EVAL_DEBUG_VENDOR_CLASS_ENTERPRISE_ID) + .arg(vendor->getVendorId()) + .arg(util::encode::encodeHex(std::vector(txt.begin(), + txt.end()))); + return; + } + case SUBOPTION: + // Extract sub-options + isc_throw(EvalTypeError, "Field None is not valid for vendor-class"); + return; + case EXISTS: + // We already passed all the checks: the option is there and has specified + // enterprise-id. + LOG_DEBUG(eval_logger, EVAL_DBG_STACK, EVAL_DEBUG_VENDOR_CLASS_EXISTS) + .arg(vendor->getVendorId()) + .arg("true"); + values.push("true"); + return; + case DATA: + { + size_t max = vendor->getTuplesNum(); + if (index_ + 1 > max) { + // The index specified is out of bounds, e.g. there are only + // 2 tuples and index specified is 5. + LOG_DEBUG(eval_logger, EVAL_DBG_STACK, EVAL_DEBUG_VENDOR_CLASS_DATA_NOT_FOUND) + .arg(index_) + .arg(vendor->getVendorId()) + .arg(max) + .arg(""); + values.push(""); + return; + } + + OpaqueDataTuple tuple = vendor->getTuple(index_); + OpaqueDataTuple::Buffer buf = tuple.getData(); + string txt(buf.begin(), buf.end()); + + LOG_DEBUG(eval_logger, EVAL_DBG_STACK, EVAL_DEBUG_VENDOR_CLASS_DATA) + .arg(index_) + .arg(max) + .arg(txt); + + values.push(txt); + return; + } + default: + isc_throw(EvalTypeError, "Invalid field specified." << field_); + } + } diff --cc src/lib/eval/token.h index ff2e78c2cd,ea6c9cbdf7..aabca84397 --- a/src/lib/eval/token.h +++ b/src/lib/eval/token.h @@@ -728,6 -530,350 +736,191 @@@ public void evaluate(Pkt& pkt, ValueStack& values); }; -/// @brief Token that represents a value of an option within a DHCPv6 relay -/// encapsulation -/// -/// This represents a reference to a given option similar to TokenOption -/// but from within the information from a relay. In the expresssion -/// relay6[nest-level].option[option-code], nest-level indicates which -/// of the relays to examine and option-code which option to extract. -/// -/// During the evaluation it tries to extract the value of the specified -/// option from the requested relay block. If the relay block doesn't -/// exist or the option is not found an empty string ("") is returned -/// (or "false" when the representation is EXISTS). -/// -/// The nesting level can go from 0 (closest to the server) to 31 -class TokenRelay6Option : public TokenOption { -public: - /// @brief Constructor that takes a nesting level and an option - /// code as paramaters. - /// - /// @param nest_level the nesting for which relay to examine. - /// @param option_code code of the option. - /// @param rep_type Token representation type. - TokenRelay6Option(const uint8_t nest_level, const uint16_t option_code, - const RepresentationType& rep_type) - :TokenOption(option_code, rep_type), nest_level_(nest_level) {} - - /// @brief Returns nest-level - /// - /// This method is used in testing to determine if the parser has - /// instantiated TokenRelay6Option with correct parameters. - /// - /// @return nest-level of the relay block this token expects to use - /// for extraction. - uint8_t getNest() const { - return (nest_level_); - } - -protected: - /// @brief Attempts to obtain specified option from the specified relay block - /// @param pkt DHCPv6 packet that hopefully contains the proper relay block - /// @return option instance if available - virtual OptionPtr getOption(Pkt& pkt); - - uint8_t nest_level_; ///< nesting level of the relay block to use -}; - -/// @brief Token that represents a value of a field within a DHCPv6 relay -/// encapsulation -/// -/// This represents a reference to a field with a given DHCPv6 relay encapsulation. -/// In the expression relay6[nest-level].field-name, nest-level indicates which of -/// the relays to examine and field-name which of the fields to extract. -/// -/// During the evaluation it tries to extract the value of the specified -/// field from the requested relay block. If the relay block doesn't exist -/// an empty string ("") is returned. If the relay block does exist the field -/// is always returned as a 16 byte IPv6 address. As the relay may not have -/// set the field it may be 0s. -/// -/// The nesting level can go from 0 (closest to the server) to 31. -class TokenRelay6Field : public Token { -public: - - /// @brief enum value that determines the field. - enum FieldType { - PEERADDR, ///< Peer address field (IPv6 address) - LINKADDR ///< Link address field (IPv6 address) - }; - - /// @brief Constructor that takes a nesting level and field type - /// as parameters. - /// - /// @param nest_level the nesting level for which relay to examine. - /// @param type which field to extract. - TokenRelay6Field(const uint8_t nest_level, const FieldType type) - : nest_level_(nest_level), type_(type) {} - - /// @brief Extracts the specified field from the requested relay - /// - /// Evaluation uses fields available in the packet. It does not require - /// any values to be present on the stack. - /// - /// @param pkt fields will be extracted from here - /// @param values - stack of values (1 result will be pushed) - void evaluate(Pkt& pkt, ValueStack& values); - - /// @brief Returns nest-level - /// - /// This method is used in testing to determine if the parser has - /// instantiated TokenRelay6Field with correct parameters. - /// - /// @return nest-level of the relay block this token expects to use - /// for extraction. - uint8_t getNest() const { - return (nest_level_); - } - - /// @brief Returns field type - /// - /// This method is used only in testing to determine if the parser has - /// instantiated TokenRelay6Field with correct parameters. - /// - /// @return type of the field. - FieldType getType() { - return (type_); - } - -protected: - /// @brief Specifies field of the DHCPv6 relay option to get - uint8_t nest_level_; ///< nesting level of the relay block to use - FieldType type_; ///< field to get -}; - -/// @brief Token that represents fields of DHCPv6 packet. -/// -/// For example in the expression pkt6.msgtype == 1 -/// this token represents the message type of the DHCPv6 packet. -/// The integer values are placed on the value stack as 4 byte -/// strings. -/// -/// Currently supported fields are: -/// - msgtype -/// - transid -class TokenPkt6 : public Token { -public: - /// @brief enum value that determines the field. - enum FieldType { - MSGTYPE, ///< msg type - TRANSID ///< transaction id (integer but manipulated as a string) - }; - - /// @brief Constructor (does nothing) - TokenPkt6(const FieldType type) - : type_(type) {} - - /// @brief Gets a value of the specified packet. - /// - /// The evaluation uses fields that are availabe in the packet. It does not - /// require any values to be present on the stack. - /// - /// @throw EvalTypeError when called for a DHCPv4 packet - /// - /// @param pkt - packet from which to extract the fields - /// @param values - stack of values, 1 result will be pushed - void evaluate(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 DHCPv6 packet to get - FieldType type_; -}; - + /// @brief Token that represents vendor options in DHCPv4 and DHCPv6. + /// + /// It covers vendor independent vendor information option (125, DHCPv4) + /// and vendor option (17, DHCPv6). Since both of those options may have + /// suboptions, this class is derived from TokenOption and leverages its + /// ability to operate on sub-options. It also adds additional capabilities. + /// In particular, it allows retrieving enterprise-id. + /// + /// It can represent the following expressions: + /// vendor[4491].exists - if vendor option with enterprise-id = 4491 exists + /// vendor[*].exists - if any vendor option exists + /// vendor.enterprise - returns enterprise-id from vendor option + /// vendor[4491].option[1].exists - check if suboption 1 exists for vendor 4491 + /// vendor[4491].option[1].hex - return content of suboption 1 for vendor 4491 + class TokenVendor : public TokenOption { + public: + + /// @brief Specifies a field of the vendor option + enum FieldType { + SUBOPTION, ///< If this token fetches a suboption, not a field. + ENTERPRISE_ID, ///< enterprise-id field (vendor-info, vendor-class) + EXISTS, ///< vendor[123].exists + DATA ///< data chunk, used in derived vendor-class only + }; + + /// @brief Constructor used for accessing a field + /// + /// @param u universe (either V4 or V6) + /// @param vendor_id specifies enterprise-id (0 means any) + /// @param field specifies which field should be returned + TokenVendor(Option::Universe u, uint32_t vendor_id, FieldType field); + + + /// @brief Constructor used for accessing an option + /// + /// This constructor is used for accessing suboptions. In general + /// option_code is mandatory, except when repr is EXISTS. For + /// option_code = 0 and repr = EXISTS, the token will return true + /// if the whole option exists, not suboptions. + /// + /// @param u universe (either V4 or V6) + /// @param vendor_id specifies enterprise-id (0 means any) + /// @param repr representation type (hex or exists) + /// @param option_code sub-option code + TokenVendor(Option::Universe u, uint32_t vendor_id, RepresentationType repr, + uint16_t option_code = 0); + + /// @brief Returns enterprise-id + /// + /// Used in tests only. + /// + /// @return enterprise-id + uint32_t getVendorId() const; + + /// @brief Returns field. + /// + /// Used in tests only. + /// + /// @return field type. + FieldType getField() const; + + /// @brief This is a method for evaluating a packet. + /// + /// Depending on the value of vendor_id, field type, representation and + /// option code, it will attempt to return specified characteristic of the + /// vendor option + /// + /// If vendor-id is specified, check only option with that particular + /// enterprise-id. If vendor-id is 0, check any vendor option, regardless + /// of its enterprise-id value. + /// + /// If FieldType is NONE, get specified suboption represented by option_code + /// and represent it as specified by repr. + /// + /// If FieldType is ENTERPRISE_ID, return value of the enterprise-id field + /// or "" if there's no vendor option. + /// + /// @throw EvalTypeError for any other FieldType values. + /// + /// The parameters passed are: + /// + /// @param pkt - vendor options will be searched for here. + /// @param values - the evaluated value will be pushed here. + virtual void evaluate(Pkt& pkt, ValueStack& values); + + protected: + /// @brief Attempts to get a suboption. + /// + /// This method overrides behavior of TokenOption method. It attempts to retrieve + /// the sub-option of the vendor option. Using derived method allows usage of + /// TokenOption routines. + /// + /// @param pkt vendor option will be searched here. + /// @return suboption of the vendor option (if exists) + virtual OptionPtr getOption(Pkt& pkt); + + /// @brief Universe (V4 or V6) + /// + /// We need to remember it, because depending on the universe, the code needs + /// to retrieve either option 125 (DHCPv4) or 17 (DHCPv6). + Option::Universe universe_; + + /// @brief Enterprise-id value + /// + /// Yeah, I know it technically should be called enterprise-id, but that's + /// too long and everyone calls it vendor-id. + uint32_t vendor_id_; + + /// @brief Specifies which field should be accessed. + FieldType field_; + }; + + /// @brief Token that represents vendor class options in DHCPv4 and DHCPv6. + /// + /// It covers vendor independent vendor information option (124, DHCPv4) + /// and vendor option (16, DHCPv6). Contrary to vendor options, vendor class + /// options don't have suboptions, but have data chunks (tuples) instead. + /// Therefore they're not referenced by option codes, but by indexes. + /// The first data chunk is data[0], the second is data[1] etc. + /// + /// This class is derived from OptionVendor to take advantage of the + /// enterprise handling field and field type. + /// + /// It can represent the following expressions: + /// vendor-class[4491].exists + /// vendor-class[*].exists + /// vendor-class[*].enterprise + /// vendor-class[4491].data - content of the opaque-data of the first tuple + /// vendor-class[4491].data[3] - content of the opaque-data of the 4th tuple + class TokenVendorClass : public TokenVendor { + public: + + /// @brief This constructor is used to access fields. + /// + /// @param u universe (V4 or V6) + /// @param vendor_id value of enterprise-id field (0 means any) + /// @param repr representation type (EXISTS or HEX) + TokenVendorClass(Option::Universe u, uint32_t vendor_id, RepresentationType repr); + + /// @brief This constructor is used to access data chunks. + /// + /// @param u universe (V4 or V6) + /// @param vendor_id value of enterprise-id field (0 means any) + /// @param field type of the field (usually DATA or ENTERPRISE) + /// @param index specifies which data chunk to retrieve + TokenVendorClass(Option::Universe u, uint32_t vendor_id, FieldType field, + uint16_t index = 0); + + /// @brief Returns data index. + /// + /// Used in testing. + /// @return data index (specifies which data chunk to retrieve) + uint16_t getDataIndex() const; + + protected: + + /// @brief This is a method for evaluating a packet. + /// + /// Depending on the value of vendor_id, field type, representation and + /// option code, it will attempt to return specified characteristic of the + /// vendor option + /// + /// If vendor-id is specified, check only option with that particular + /// enterprise-id. If vendor-id is 0, check any vendor option, regardless + /// of its enterprise-id value. + /// + /// If FieldType is ENTERPRISE_ID, return value of the enterprise-id field + /// or "" if there's no vendor option. + /// + /// If FieldType is DATA, get specified data chunk represented by index_. + /// + /// If FieldType is EXISTS, return true if vendor-id matches. + /// + /// @throw EvalTypeError for any other FieldType values. + /// + /// The parameters passed are: + /// + /// @param pkt - vendor options will be searched for here. + /// @param values - the evaluated value will be pushed here. + void evaluate(Pkt& pkt, ValueStack& values); + + /// @brief Data chunk index. + uint16_t index_; + }; + }; // end of isc::dhcp namespace }; // end of isc namespace