From: Shawn Routhier Date: Fri, 15 Apr 2016 03:45:08 +0000 (+0000) Subject: Merge branch 'trac4269' Merge 4269 after updates to fix conflicts X-Git-Tag: trac4106_update_base~43 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=48be5f5ceaba6b0d0a2b31465e8a5904524e894c;p=thirdparty%2Fkea.git Merge branch 'trac4269' Merge 4269 after updates to fix conflicts --- 48be5f5ceaba6b0d0a2b31465e8a5904524e894c diff --cc ChangeLog index 93756ef67a,1b6f5b8485..7d9ddcb18b --- a/ChangeLog +++ b/ChangeLog @@@ -1,90 -1,8 +1,95 @@@ -10xx. [func] sar ++1106. [func] sar + Added support for accessing DHCPv6 packet fields message type + and transaction id in a classification expression. + (Trac #4269, git ) + +1105. [bug] pallotron + perfdhcp uses the same transaction id throughout the DORA + exchange to adhere with RFC 2131. + (github #19, git d260a70d6aa0baecd68131bc35f58f097aa77bcc) + +1104. [func] tmark + The DDNS parameter, replace-client-name, has been changed from a boolean - to list of modes, which provides greater flexibility in when the Kea ++ to list of modes, which provides greater flexibility in when the Kea + servers replace or supply DNS names for clients. This is supported both + kea-dhcp4 and kea-dhcp6. + (Trac #4529, git 45e56d7aa0d4a6224a1a28941f6cb11575391222) + +1103. [func] marcin + "circuit-id" can be specified as host identifier in host + host reservations. However, the server ignores the reservations + by "circuit-id" at this point. + (Trac #4301, git cf56fc2a2e0e821a17dd95de49a43755745682fb) + +1102. [func] sar + Added access to the peer address, link address and option + information added by relays in a DHCPv6 message. - (Trac $4269, git bb00d9d205ee047961ba70417d7ce02c37d80ce7) ++ (Trac $4265, git bb00d9d205ee047961ba70417d7ce02c37d80ce7) + +1101. [bug] stephen + Made DHCPSRV_MEMFILE_LFC_UNREGISTER_TIMER_FAILED a debug message as the + condition leading to it (trying to unregister a timer that is not + registered) does not have an adverse effect on the operation of Kea. + (Trac #4293, git 06204c5d347d0df359af69974c155d0fa9725b44) + +1100. [bug] tmark + Wrapped asio/asio.hpp with logic to suppress optimization when building + under GCC 5.2.0 through 5.3.1 and BOOST_ERROR_CODE_HEADER only is defined. + This avoids an issue in the asio socket layer that was incorrectly + reporting socket read errors causing unit tests to fail and kea-dhcp-ddns + to loop logger calls in the error handler (aka double errors). + (Trac #4243, git 082f846f37cb32964c876b2bff5fcac82d1eaaf0) + +1099. [func] marcin + Updated Host Manager API to allow for retrieving host reservations + by any type of host identifier. Previously it was only possible + to retrieve host reservations by hardware address or DUID. + (Trac #4302, git 3979656c918164e3c39e0e8fb78b2862a2b5e95a) + +1098. [func] kalmus, marcin + Implemented IPv6 address/prefix reservations in MySQL. + (Trac #4212, git 79481043935789fc6898d4743bede1606f82eb75) + +1097. [func] fdupont + Reorganized the DHCPv4 and DHCPv6 services into run() (service + loop), run_one() (receive, call next routine and send) and + processPacket() (internal core processing of an incoming packet). + (Trac #4108,#4266,#4267, git ba24bd770d1a1791f8fdc3df7f2e41f9f0c851ec) + +1096. [func] tmark + Both kea-dhcp4 and kea-dhcp6, now log the primary lease events (e.g. + grants, renewals, releases, declines) at the INFO log level to the + lease4_logger and lease6_logger repsectively. Prior to this these + events were logged at the DEBUG log level. + (Trac #4316, git 9beca27e3d76d0ccec925125f23074227db08869) + +1095. [bug] fdupont + Fixed some minor Coverity-detected issues. + (Trac #4326, git ad1f442ee4382b354dc8be84ba77785e565aa86b) + +1094. [bug] marcin + libdhcpsrv: Fixed issues with lease indexing in Memfile + database backend. + (Trac #4339, git a065144663ac716b1fa1c8c224a88aa176da9630) + +1093. [bug] fdupont + Fixed Coverity-detected overflows in pkt4::setFile() and setName(). + (Trac #4306, git 0b7388891eaab39fe727b076468d672551126796) + +1092. [func] marcin + DHCP option values can be specified within host reservations + in the configuration file. + (Trac #4319, git 069dd7c248afcfcb7e4d958f20faa32e946e74ce) + +1091. [bug] fdupont + Fixed Coverity-detected exception-handling issues. + (Trac #4307, git 3e1050749d9684144e1bd17552af7e4abf3c0d17) + +1090. [func] fdupont + Added support for IP address (IPv4 and IPv6) literals in + classification expressions. + (Trac #4232, git b98cc019b172a4903a2121e910f3cee4eaca2d51) + 1089. [func] fdupont Added relay4[X].exists method in classifications that checks whether a sub-option is present in theDHCPv4 RAI (Relay Agent diff --cc doc/guide/classify.xml index 77c4981e32,bb9f7a06ae..76c310641b --- a/doc/guide/classify.xml +++ b/doc/guide/classify.xml @@@ -170,23 -169,19 +170,37 @@@ sub-optionrelay4[code].hexThe value of sub-option with code "code" from the DHCPv4 Relay Agent Information option (option 82) + + DHCPv6 Relay Options + relay6[nest].option[code].hex + + The value of the option with code "code" from the relay encapsulation "nest" + + + DHCPv6 Relay Peer Address + relay6[nest].peeraddr +n + The value of the peer address field from the relay encapsulation "nest" + + + DHCPv6 Relay Link Address + relay6[nest].linkaddr +n + The value of the link address field from the relay encapsulation "nest" ++ + + Message Type in DHCPv6 packet + pkt6.msgtype + + The value of the message type field in the DHCPv6 packet. + + + Transaction ID in DHCPv6 packet + pkt6.transid + + The value of the transaction id in the DHCPv6 packet. @@@ -233,20 -223,14 +247,28 @@@ instance "relay4[code].exists" is supported. + + "relay6[nest]" allows access to the encapsulations used by any DHCPv6 + relays that forwarded the packet. The "nest" level specifies the relay + from which to extract the information, with a value of 0 indicating + the relay closest to the DHCPv6 server. If the requested encapsulation + doesn't exist an empty string "" is returned. This expression is + allowed in DHCPv6 only. + + + + "relay6[nest].option[code]" shares the same representation types as + "option", for instance "relay6[nest].option[code].exists" is supported. + + + + "pkt6" refers to information from the client request. To access any + information from an intermediate relay use "relay6". "pkt6.msgtype" + and "pkt6.transid" output a 4 byte binary string for the message type + or transaction id. For example the message type SOLICIT will be + "0x00000001" or simply 1 as in "pkt6.msgtype == 1". + + List of Classification Expressions diff --cc src/lib/eval/lexer.cc index 25ba5f1f2c,7a99903c39..02ea9fa388 --- 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 30 - #define YY_END_OF_BUFFER 31 -#define YY_NUM_RULES 29 -#define YY_END_OF_BUFFER 30 ++#define YY_NUM_RULES 33 ++#define YY_END_OF_BUFFER 34 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@@ -492,43 -492,40 +492,46 @@@ flex_int32_t yy_verify; flex_int32_t yy_nxt; }; - static yyconst flex_int16_t yy_acclist[162] = -static yyconst flex_int16_t yy_acclist[152] = ++static yyconst flex_int16_t yy_acclist[183] = { 0, - 31, 29, 30, 1, 29, 30, 2, 30, 29, 30, - 24, 29, 30, 25, 29, 30, 28, 29, 30, 29, - 30, 23, 29, 30, 5, 29, 30, 5, 29, 30, - 29, 30, 29, 30, 29, 30,16390, 29, 30,16390, - 26, 29, 30, 27, 29, 30, 29, 30,16390, 29, - 30,16390, 29, 30,16390, 29, 30,16390, 29, 30, - 16390, 29, 30,16390, 29, 30,16390, 29, 30,16390, - 29, 30,16390, 29, 30,16390, 29, 30,16390, 1, - 2, 3, 5, 5, 7, 8,16390,16390, 8198,16390, - 16390,16390,16390,16390,16390,16390,16390, 22,16390,16390, - 30, 28, 29, 1, 28, 29, 2, 29, 28, 29, - 20, 28, 29, 21, 28, 29, 24, 28, 29, 28, - 29, 19, 28, 29, 5, 28, 29, 5, 28, 29, - 28, 29, 28, 29,16390, 22, 28, 29, 23, 28, - 29, 28, 29,16390, 28, 29,16390, 28, 29,16390, - 28, 29,16390, 28, 29,16390, 28, 29,16390, 28, - 29,16390, 28, 29,16390, 28, 29,16390, 28, 29, - 16390, 28, 29,16390, 1, 2, 3, 5, 7,16390, - 8198,16390,16390,16390,16390,16390,16390,16390,16390, 18, - 16390,16390,16390,16390,16390,16390, 4, 14,16390, 17, -- - 16390,16390,16390, 4, 7, 18,16390, 21,16390,16390, - 16390, 15,16390,16390, 20,16390,16390,16390,16390,16390, - 16390,16390,16390,16390,16390,16390,16390,16390, 14,16390, - 16390,16390,16390,16390,16390,16390,16390, 19,16390, 16, - 16390,16390, 9,16390,16390, 10,16390, 11,16390,16390, - 7,16390,16390,16390, 13,16390, 12,16390,16390, 17, - 16390,16390,16390, 11,16390,16390, 16,16390,16390,16390, - 16390,16390,16390,16390,16390,16390,16390,16390, 25,16390, - 16390,16390, 10,16390,16390,16390,16390,16390,16390,16390, - 16390,16390, 15,16390, 12,16390,16390, 8,16390, 9, - 16390,16390,16390, 26,16390,16390, 27,16390,16390, 13, -- 16390 ++ 34, 32, 33, 1, 32, 33, 2, 33, 32, 33, ++ 24, 32, 33, 25, 32, 33, 28, 32, 33, 32, ++ 33, 23, 32, 33, 5, 32, 33, 5, 32, 33, ++ 32, 33, 32, 33, 32, 33,16390, 32, 33,16390, ++ 26, 32, 33, 27, 32, 33, 32, 33,16390, 32, ++ 33,16390, 32, 33,16390, 32, 33,16390, 32, 33, ++ 16390, 32, 33,16390, 32, 33,16390, 32, 33,16390, ++ 32, 33,16390, 32, 33,16390, 32, 33,16390, 32, ++ 33,16390, 1, 2, 3, 5, 5, 7, 8,16390, ++ 16390, 8198,16390,16390,16390,16390,16390,16390,16390,16390, ++ ++ 16390, 22,16390,16390,16390,16390,16390,16390,16390, 4, ++ 7, 18,16390, 21,16390,16390,16390, 15,16390,16390, ++ 16390, 20,16390,16390,16390,16390,16390,16390,16390,16390, ++ 16390,16390,16390,16390,16390,16390, 29,16390,16390,16390, ++ 14,16390,16390,16390,16390,16390,16390,16390,16390,16390, ++ 16390,16390, 19,16390, 16,16390,16390,16390, 9,16390, ++ 16390, 10,16390, 11,16390,16390,16390, 7,16390, 30, ++ 16390,16390,16390, 31,16390, 13,16390, 12,16390,16390, ++ 17,16390 } ; - static yyconst flex_int16_t yy_accept[114] = -static yyconst flex_int16_t yy_accept[99] = ++static yyconst flex_int16_t yy_accept[130] = { 0, 1, 1, 1, 2, 4, 7, 9, 11, 14, 17, - 20, 22, 25, 28, 31, 33, 36, 39, 42, 45, - 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, - 76, 77, 77, 78, 79, 79, 80, 80, 80, 81, - 82, 83, 84, 85, 86, 87, 88, 89, 90, 92, - 93, 94, 95, 96, 97, 98, 100, 102, 103, 104, - 106, 107, 109, 110, 111, 112, 113, 114, 115, 116, - 117, 118, 119, 121, 122, 123, 125, 126, 127, 128, - 129, 130, 131, 132, 133, 135, 137, 138, 140, 142, - 143, 144, 146, 147, 149, 150, 152, 152 - + 20, 22, 25, 28, 31, 33, 35, 38, 41, 44, + 47, 50, 53, 56, 59, 62, 65, 68, 71, 74, - 77, 80, 81, 82, 82, 83, 84, 84, 85, 85, - 85, 85, 85, 86, 87, 87, 87, 88, 89, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 100, 101, - 102, 103, 104, 104, 105, 106, 108, 110, 111, 112, - 114, 115, 117, 118, 119, 120, 121, 122, 122, 123, - 124, 125, 126, 127, 128, 129, 131, 131, 132, 133, - 134, 135, 136, 137, 138, 138, 140, 142, 143, 145, - - 146, 148, 150, 151, 152, 153, 154, 155, 157, 159, - 160, 162, 162 ++ 77, 80, 83, 84, 85, 85, 86, 87, 87, 88, ++ 88, 88, 88, 88, 89, 90, 90, 90, 91, 92, ++ 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, ++ 104, 105, 106, 107, 108, 109, 110, 110, 111, 112, ++ 114, 116, 117, 118, 120, 121, 122, 124, 125, 126, ++ 127, 128, 129, 130, 131, 131, 132, 133, 134, 135, ++ 136, 137, 139, 140, 141, 143, 144, 144, 145, 146, ++ ++ 147, 148, 149, 150, 151, 152, 153, 153, 155, 157, ++ 158, 159, 161, 162, 164, 166, 167, 168, 169, 170, ++ 172, 173, 174, 176, 178, 180, 181, 183, 183 } ; static yyconst YY_CHAR yy_ec[256] = @@@ -538,15 -535,15 +541,15 @@@ 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, 1, 1, 1, - 14, 1, 1, 1, 15, 15, 15, 15, 15, 15, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 17, 16, 16, - 18, 1, 19, 1, 20, 1, 21, 22, 23, 24, - - 25, 15, 26, 27, 28, 16, 29, 30, 31, 32, - 33, 34, 16, 35, 36, 37, 38, 16, 16, 39, - 40, 16, 1, 1, 1, 1, 1, 1, 1, 1, + 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, 16, 27, 28, 29, 17, 30, 31, 17, 32, - 33, 34, 17, 35, 36, 37, 38, 17, 17, 39, - 40, 17, 1, 1, 1, 1, 1, 1, 1, 1, ++ 26, 16, 27, 28, 29, 17, 30, 31, 32, 33, ++ 34, 35, 17, 36, 37, 38, 39, 17, 17, 40, ++ 41, 17, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@@ -563,128 -560,140 +566,136 @@@ 1, 1, 1, 1, 1 } ; --static yyconst YY_CHAR yy_meta[41] = ++static yyconst YY_CHAR yy_meta[42] = { 0, - 1, 2, 3, 1, 1, 1, 1, 2, 1, 4, - 4, 4, 4, 1, 5, 2, 6, 1, 2, 2, - 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 6, 2 + 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, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ++ 1 } ; - static yyconst flex_uint16_t yy_base[118] = -static yyconst flex_uint16_t yy_base[102] = ++static yyconst flex_uint16_t yy_base[134] = { 0, - 0, 0, 220, 221, 217, 215, 213, 221, 221, 221, - 31, 221, 36, 33, 202, 200, 74, 105, 221, 221, - 24, 181, 174, 186, 182, 177, 29, 183, 182, 169, - 180, 203, 201, 199, 221, 55, 68, 35, 188, 187, - 0, 186, 0, 221, 120, 122, 0, 0, 221, 168, - 173, 165, 167, 156, 162, 156, 155, 0, 165, 159, - 166, 149, 123, 0, 0, 0, 0, 163, 150, 0, - 155, 0, 155, 148, 160, 145, 143, 133, 157, 141, - 155, 143, 153, 134, 136, 0, 138, 135, 125, 116, - 107, 113, 57, 102, 142, 0, 0, 101, 0, 95, - 0, 0, 122, 289, 103, 82, 70, 289, 289, 289, - 31, 289, 28, 36, 59, 49, 289, 289, 68, 23, - 33, 29, 28, 45, 49, 60, 61, 64, 74, 64, - 59, 46, 289, 100, 0, 289, 105, 112, 50, 289, - 65, 93, 71, 88, 89, 100, 97, 103, 106, 109, - 113, 125, 119, 129, 0, 122, 130, 133, 134, 137, - 141, 142, 147, 155, 159, 152, 160, 151, 172, 164, - 168, 173, 177, 180, 181, 184, 185, 192, 195, 196, - 202, 207, 203, 212, 211, 215, 221, 218, 222, 227, - 232, 228, 231, 235, 240, 239, 289, 272, 275, 280, -- - 0, 0, 64, 146, 54, 48, 41, 0, 0, 44, - 0, 221, 159, 161, 163, 53, 166 - 283 ++ 0, 0, 237, 238, 234, 232, 230, 238, 238, 238, ++ 32, 238, 37, 34, 219, 217, 76, 108, 238, 238, ++ 23, 197, 190, 203, 199, 190, 192, 22, 38, 199, ++ 185, 39, 221, 219, 217, 238, 59, 70, 55, 206, ++ 205, 0, 204, 0, 238, 123, 125, 0, 0, 238, ++ 186, 191, 182, 185, 173, 179, 184, 172, 171, 0, ++ 182, 169, 175, 182, 164, 181, 126, 0, 0, 0, ++ 0, 178, 164, 0, 170, 161, 0, 169, 161, 183, ++ 173, 157, 155, 159, 136, 169, 152, 167, 147, 153, ++ 164, 0, 144, 146, 0, 146, 141, 144, 144, 155, ++ ++ 144, 145, 152, 54, 140, 146, 145, 0, 0, 139, ++ 118, 0, 117, 0, 0, 112, 115, 149, 93, 0, ++ 87, 58, 0, 0, 0, 58, 0, 238, 162, 164, ++ 166, 72, 169 } ; - static yyconst flex_int16_t yy_def[118] = -static yyconst flex_int16_t yy_def[102] = ++static yyconst flex_int16_t yy_def[134] = { 0, - 112, 1, 112, 112, 112, 112, 113, 112, 112, 112, - 112, 112, 112, 13, 114, 112, 112, 17, 112, 112, - 97, 1, 97, 97, 97, 97, 98, 97, 97, 97, - 97, 97, 99, 97, 97, 100, 97, 97, 100, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 97, - 97, 98, 97, 97, 101, 97, 97, 19, 19, 97, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 101, 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, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 0, 97, 97, 97, - - 97 ++ 128, 1, 128, 128, 128, 128, 129, 128, 128, 128, ++ 128, 128, 128, 13, 130, 128, 128, 17, 128, 128, + 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, - 18, 112, 112, 113, 112, 112, 112, 13, 114, 115, - 116, 114, 117, 112, 112, 18, 17, 18, 112, 18, ++ 18, 18, 128, 128, 129, 128, 128, 128, 13, 130, ++ 131, 132, 130, 133, 128, 128, 18, 17, 18, 128, ++ 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, ++ 18, 18, 18, 18, 18, 18, 128, 132, 133, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 112, 116, 117, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 112, 18, 18, - 18, 18, 18, 18, 18, 18, 112, 18, 18, 18, - 18, 18, 18, 18, 112, 18, 18, 18, 18, 18, ++ 18, 18, 18, 18, 128, 18, 18, 18, 18, 18, ++ 18, 18, 18, 18, 18, 18, 128, 18, 18, 18, + - 18, 18, 18, 112, 18, 18, 18, 18, 18, 18, - 18, 0, 112, 112, 112, 112, 112 ++ 18, 18, 18, 18, 18, 18, 128, 18, 18, 18, ++ 18, 18, 18, 18, 18, 18, 18, 128, 18, 18, ++ 18, 18, 18, 18, 18, 18, 18, 0, 128, 128, ++ 128, 128, 128 } ; - static yyconst flex_uint16_t yy_nxt[262] = -static yyconst flex_uint16_t yy_nxt[330] = ++static yyconst flex_uint16_t yy_nxt[280] = { 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 14, 14, 15, 16, 16, 16, 17, 18, 4, - 19, 16, 20, 16, 21, 16, 22, 16, 16, 16, - 23, 24, 25, 26, 27, 28, 29, 16, 16, 16, - 34, 34, 34, 34, 35, 34, 34, 34, 34, 33, - 37, 37, 39, 45, 39, 43, 38, 39, 39, 39, - 39, 31, 39, 46, 39, 30, 35, 40, 38, 37, - 37, 44, 36, 33, 39, 38, 39, 47, 39, 39, - 39, 39, 48, 49, 31, 51, 40, 38, 50, 39, - 39, 39, 39, 39, 56, 39, 39, 41, 53, 42, - - 39, 52, 58, 39, 30, 39, 37, 37, 54, 34, - 34, 34, 34, 97, 97, 59, 57, 39, 39, 39, - 39, 97, 39, 40, 39, 61, 39, 60, 39, 39, - 97, 39, 39, 62, 39, 39, 97, 39, 39, 63, - 39, 39, 65, 39, 39, 64, 66, 97, 39, 68, - 39, 39, 97, 39, 39, 69, 39, 67, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 73, 39, 70, - 39, 39, 39, 39, 72, 97, 39, 71, 39, 74, - 39, 39, 77, 39, 39, 97, 39, 75, 39, 39, - 39, 39, 78, 39, 97, 39, 76, 39, 97, 39, - - 79, 39, 39, 39, 39, 81, 39, 80, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 83, 89, 82, - 84, 39, 97, 39, 39, 39, 39, 39, 85, 87, - 86, 39, 39, 88, 39, 97, 39, 90, 39, 91, - 39, 39, 39, 39, 39, 92, 39, 39, 97, 39, - 39, 39, 39, 39, 93, 94, 39, 39, 39, 39, - 39, 39, 95, 39, 39, 96, 39, 97, 39, 39, - 39, 39, 32, 32, 97, 32, 32, 32, 34, 97, - 34, 39, 39, 39, 39, 39, 55, 55, 3, 97, - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, - - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, - 97, 97, 97, 97, 97, 97, 97, 97, 97 + 14, 14, 14, 15, 16, 17, 18, 18, 19, 20, + 4, 21, 17, 22, 17, 23, 18, 24, 18, 18, - 25, 26, 27, 28, 29, 30, 31, 18, 18, 18, - 36, 36, 36, 36, 37, 38, 38, 38, 38, 39, - 112, 40, 112, 41, 50, 51, 64, 40, 40, 40, - 40, 40, 57, 58, 36, 36, 36, 36, 101, 102, - 111, 112, 110, 112, 41, 45, 45, 63, 63, 63, - 63, 46, 109, 47, 47, 47, 47, 39, 108, 47, - 48, 48, 107, 49, 46, 47, 47, 47, 47, 47, - - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 112, 106, - 48, 45, 45, 112, 112, 105, 48, 48, 48, 48, - 48, 78, 63, 63, 63, 63, 103, 100, 99, 49, - 98, 112, 87, 87, 87, 87, 95, 87, 87, 87, - 87, 104, 104, 104, 104, 104, 104, 104, 104, 34, - 97, 34, 34, 34, 42, 42, 40, 40, 65, 65, - 65, 96, 94, 93, 92, 91, 90, 89, 88, 86, - 85, 84, 83, 82, 81, 80, 79, 77, 76, 75, - 74, 73, 72, 71, 70, 69, 68, 67, 66, 43, - - 39, 43, 35, 33, 32, 62, 61, 60, 59, 56, - 55, 54, 53, 52, 44, 43, 35, 33, 32, 112, - 3, 112, 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, - 112 ++ 25, 26, 27, 28, 29, 30, 31, 32, 18, 18, ++ 18, 37, 37, 37, 37, 38, 39, 39, 39, 39, ++ 40, 128, 41, 51, 42, 52, 59, 60, 41, 41, ++ 41, 41, 41, 61, 65, 114, 115, 62, 37, 37, ++ 37, 37, 128, 128, 66, 68, 42, 46, 46, 67, ++ 67, 67, 67, 47, 127, 48, 48, 48, 48, 40, ++ 126, 48, 49, 49, 128, 50, 47, 48, 48, 48, ++ ++ 48, 48, 49, 49, 49, 49, 49, 49, 49, 49, ++ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, ++ 49, 128, 125, 49, 46, 46, 128, 128, 124, 49, ++ 49, 49, 49, 49, 85, 67, 67, 67, 67, 123, ++ 122, 121, 50, 120, 128, 97, 97, 97, 97, 107, ++ 97, 97, 97, 97, 118, 118, 118, 118, 118, 118, ++ 118, 118, 35, 119, 35, 35, 35, 43, 43, 41, ++ 41, 69, 69, 69, 117, 116, 113, 112, 111, 110, ++ 109, 108, 106, 105, 104, 103, 102, 101, 100, 99, ++ 98, 96, 95, 94, 93, 92, 91, 90, 89, 88, ++ ++ 87, 86, 84, 83, 82, 81, 80, 79, 78, 77, ++ 76, 75, 74, 73, 72, 71, 70, 44, 40, 44, ++ 36, 34, 33, 64, 63, 58, 57, 56, 55, 54, ++ 53, 45, 44, 36, 34, 33, 128, 3, 128, 128, ++ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, ++ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, ++ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, ++ 128, 128, 128, 128, 128, 128, 128, 128, 128 } ; - static yyconst flex_int16_t yy_chk[262] = -static yyconst flex_int16_t yy_chk[330] = ++static yyconst flex_int16_t yy_chk[280] = { 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, - 11, 11, 11, 11, 13, 13, 13, 13, 13, 13, - 14, 13, 38, 13, 21, 21, 116, 13, 13, 13, - 13, 13, 27, 27, 36, 36, 36, 36, 93, 93, - 110, 14, 107, 38, 13, 17, 17, 37, 37, 37, - 37, 17, 106, 17, 17, 17, 17, 17, 105, 17, - 17, 17, 103, 17, 17, 17, 17, 17, 17, 17, - 11, 11, 11, 11, 13, 14, 14, 14, 14, 32, - 16, 16, 20, 22, 20, 20, 16, 23, 22, 23, - 22, 31, 21, 23, 21, 30, 13, 16, 16, 19, - 19, 21, 15, 7, 24, 19, 24, 24, 25, 39, - 25, 39, 25, 25, 6, 27, 19, 19, 26, 26, - 27, 26, 27, 28, 41, 28, 41, 19, 29, 19, - - 43, 28, 43, 29, 5, 29, 37, 37, 29, 34, - 34, 34, 34, 38, 38, 44, 42, 44, 45, 44, - 45, 3, 42, 37, 42, 46, 47, 45, 47, 46, - 38, 46, 48, 47, 48, 49, 0, 49, 50, 48, - 50, 38, 51, 38, 51, 50, 52, 0, 53, 54, - 53, 56, 0, 56, 52, 58, 52, 53, 54, 57, - 54, 57, 58, 59, 58, 59, 60, 64, 60, 59, - 61, 62, 61, 62, 63, 0, 63, 61, 63, 65, - 68, 66, 68, 66, 64, 0, 64, 66, 65, 67, - 65, 67, 69, 70, 0, 70, 67, 71, 0, 71, - - 70, 69, 72, 69, 72, 72, 73, 71, 73, 74, - 75, 74, 75, 76, 77, 76, 77, 75, 82, 74, - 77, 78, 0, 78, 79, 80, 79, 80, 78, 80, - 79, 81, 83, 81, 83, 0, 82, 83, 82, 84, - 85, 84, 85, 84, 86, 87, 86, 88, 0, 88, - 87, 89, 87, 89, 90, 91, 90, 92, 90, 92, - 93, 91, 93, 91, 94, 95, 94, 0, 96, 95, - 96, 95, 98, 98, 0, 98, 98, 98, 99, 0, - 99, 100, 100, 100, 100, 100, 101, 101, 97, 97, - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, - - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, - 97, 97, 97, 97, 97, 97, 97, 97, 97 ++ 1, 11, 11, 11, 11, 13, 13, 13, 13, 13, ++ 13, 14, 13, 21, 13, 21, 28, 28, 13, 13, ++ 13, 13, 13, 29, 32, 104, 104, 29, 37, 37, ++ 37, 37, 39, 14, 32, 132, 13, 17, 17, 38, ++ 38, 38, 38, 17, 126, 17, 17, 17, 17, 17, ++ 122, 17, 17, 17, 39, 17, 17, 17, 17, 17, + + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 18, 18, 18, 18, 18, 100, - 18, 45, 45, 46, 46, 98, 18, 18, 18, 18, - 18, 63, 63, 63, 63, 63, 94, 92, 91, 45, - 90, 46, 78, 78, 78, 78, 87, 87, 87, 87, - 87, 95, 95, 95, 95, 104, 104, 104, 104, 113, - 89, 113, 113, 113, 114, 114, 115, 115, 117, 117, - 117, 88, 85, 84, 83, 82, 81, 80, 79, 77, - 76, 75, 74, 73, 71, 69, 68, 62, 61, 60, - 59, 57, 56, 55, 54, 53, 52, 51, 50, 42, - - 40, 39, 34, 33, 32, 31, 30, 29, 28, 26, - 25, 24, 23, 22, 16, 15, 7, 6, 5, 3, - 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, - 112 ++ 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, ++ 18, 18, 121, 18, 46, 46, 47, 47, 119, 18, ++ 18, 18, 18, 18, 67, 67, 67, 67, 67, 117, ++ 116, 113, 46, 111, 47, 85, 85, 85, 85, 97, ++ 97, 97, 97, 97, 107, 107, 107, 107, 118, 118, ++ 118, 118, 129, 110, 129, 129, 129, 130, 130, 131, ++ 131, 133, 133, 133, 106, 105, 103, 102, 101, 100, ++ 99, 98, 96, 94, 93, 91, 90, 89, 88, 87, ++ 86, 84, 83, 82, 81, 80, 79, 78, 76, 75, ++ ++ 73, 72, 66, 65, 64, 63, 62, 61, 59, 58, ++ 57, 56, 55, 54, 53, 52, 51, 43, 41, 40, ++ 35, 34, 33, 31, 30, 27, 26, 25, 24, 23, ++ 22, 16, 15, 7, 6, 5, 3, 128, 128, 128, ++ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, ++ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, ++ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, ++ 128, 128, 128, 128, 128, 128, 128, 128, 128 } ; /* Table of booleans, true if rule could match eol. */ - static yyconst flex_int32_t yy_rule_can_match_eol[31] = -static yyconst flex_int32_t yy_rule_can_match_eol[30] = ++static yyconst flex_int32_t yy_rule_can_match_eol[34] = { 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, }; extern int yy_flex_debug; int yy_flex_debug = 1; - static yyconst flex_int16_t yy_rule_linenum[30] = -static yyconst flex_int16_t yy_rule_linenum[29] = ++static yyconst flex_int16_t yy_rule_linenum[33] = { 0, - 78, 82, 88, 98, 104, 118, 125, 126, 127, 128, - 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, - 139, 140, 141, 142, 144, 145, 146, 148 + 82, 86, 92, 102, 108, 122, 129, 143, 144, 145, + 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, 159, 160, 161, 162, 163, 165 ++ 156, 157, 158, 159, 160, 161, 162, 163, 165, 166, ++ 167, 169 } ; static yy_state_type *yy_state_buf=0, *yy_state_ptr=0; @@@ -763,7 -770,7 +774,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 767 "lexer.cc" -#line 774 "lexer.cc" ++#line 778 "lexer.cc" #define INITIAL 0 @@@ -1060,7 -1067,7 +1071,7 @@@ YY_DEC loc.step(); - #line 1064 "lexer.cc" -#line 1071 "lexer.cc" ++#line 1075 "lexer.cc" while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { @@@ -1088,14 -1095,14 +1099,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 >= 113 ) - if ( yy_current_state >= 98 ) ++ if ( yy_current_state >= 129 ) 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 != 112 ); - while ( yy_current_state != 97 ); ++ while ( yy_current_state != 128 ); yy_find_action: /* %% [10.0] code to find the action number goes here */ @@@ -1158,13 -1165,13 +1169,13 @@@ do_action: /* This label is used only t { if ( yy_act == 0 ) fprintf( stderr, "--scanner backing up\n" ); - else if ( yy_act < 30 ) - else if ( yy_act < 29 ) ++ else if ( yy_act < 33 ) fprintf( stderr, "--accepting rule at line %ld (\"%s\")\n", (long)yy_rule_linenum[yy_act], yytext ); - else if ( yy_act == 30 ) - else if ( yy_act == 29 ) ++ else if ( yy_act == 33 ) fprintf( stderr, "--accepting default rule (\"%s\")\n", yytext ); - else if ( yy_act == 31 ) - else if ( yy_act == 30 ) ++ else if ( yy_act == 34 ) fprintf( stderr, "--(end of buffer or a NUL)\n" ); else fprintf( stderr, "--EOF (start condition %d)\n", YY_START ); @@@ -1360,24 -1355,19 +1371,39 @@@ return isc::eval::EvalParser::make_RBRA YY_BREAK case 28: YY_RULE_SETUP -#line 148 "lexer.ll" +#line 163 "lexer.ll" +return isc::eval::EvalParser::make_COMA(loc); + YY_BREAK +case 29: +YY_RULE_SETUP +#line 165 "lexer.ll" ++return isc::eval::EvalParser::make_PKT6(loc); ++ YY_BREAK ++case 30: ++YY_RULE_SETUP ++#line 166 "lexer.ll" ++return isc::eval::EvalParser::make_MSGTYPE(loc); ++ YY_BREAK ++case 31: ++YY_RULE_SETUP ++#line 167 "lexer.ll" ++return isc::eval::EvalParser::make_TRANSID(loc); ++ YY_BREAK ++case 32: ++YY_RULE_SETUP ++#line 169 "lexer.ll" driver.error (loc, "Invalid character: " + std::string(yytext)); YY_BREAK case YY_STATE_EOF(INITIAL): - #line 166 "lexer.ll" -#line 149 "lexer.ll" ++#line 170 "lexer.ll" return isc::eval::EvalParser::make_END(loc); YY_BREAK - case 30: -case 29: ++case 33: YY_RULE_SETUP - #line 167 "lexer.ll" -#line 150 "lexer.ll" ++#line 171 "lexer.ll" ECHO; YY_BREAK - #line 1381 "lexer.cc" -#line 1371 "lexer.cc" ++#line 1407 "lexer.cc" case YY_END_OF_BUFFER: { @@@ -1662,7 -1652,7 +1688,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 >= 113 ) - if ( yy_current_state >= 98 ) ++ if ( yy_current_state >= 129 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@@ -1690,11 -1680,11 +1716,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 >= 113 ) - if ( yy_current_state >= 98 ) ++ if ( yy_current_state >= 129 ) 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 == 112); - yy_is_jam = (yy_current_state == 97); ++ yy_is_jam = (yy_current_state == 128); if ( ! yy_is_jam ) *(yy_state_ptr)++ = yy_current_state; @@@ -2460,7 -2450,7 +2486,7 @@@ void yyfree (void * ptr /* %ok-for-header */ - #line 167 "lexer.ll" -#line 150 "lexer.ll" ++#line 171 "lexer.ll" diff --cc src/lib/eval/parser.cc index 3231b15b78,009fe69348..fa8038cfc6 --- a/src/lib/eval/parser.cc +++ b/src/lib/eval/parser.cc @@@ -251,30 -251,25 +251,34 @@@ namespace isc { namespace eval { switch (that.type_get ()) { - case 34: // option_repr_type - case 33: // option_repr_type ++ case 37: // option_repr_type value.move< TokenOption::RepresentationType > (that.value); break; - case 37: // relay6_field - case 36: // pkt6_field ++ case 42: // pkt6_field + value.move< TokenPkt6::FieldType > (that.value); + break; + - case 24: // "constant string" - case 25: // "integer" - case 26: // "constant hexstring" - case 27: // "option name" ++ case 40: // relay6_field + value.move< TokenRelay6Field::FieldType > (that.value); + break; + - case 24: // "constant string" - case 25: // "integer" - case 26: // "constant hexstring" - case 27: // "option name" - case 28: // "ip address" ++ case 27: // "constant string" ++ case 28: // "integer" ++ case 29: // "constant hexstring" ++ case 30: // "option name" ++ case 31: // "ip address" value.move< std::string > (that.value); break; - case 33: // option_code - case 32: // option_code ++ case 36: // option_code value.move< uint16_t > (that.value); break; - case 38: // nest_level ++ case 41: // nest_level + value.move< uint8_t > (that.value); + break; + default: break; } @@@ -290,30 -285,25 +294,34 @@@ state = that.state; switch (that.type_get ()) { - case 34: // option_repr_type - case 33: // option_repr_type ++ case 37: // option_repr_type value.copy< TokenOption::RepresentationType > (that.value); break; - case 37: // relay6_field - case 36: // pkt6_field ++ case 42: // pkt6_field + value.copy< TokenPkt6::FieldType > (that.value); + break; + - case 24: // "constant string" - case 25: // "integer" - case 26: // "constant hexstring" - case 27: // "option name" ++ case 40: // relay6_field + value.copy< TokenRelay6Field::FieldType > (that.value); + break; + - case 24: // "constant string" - case 25: // "integer" - case 26: // "constant hexstring" - case 27: // "option name" - case 28: // "ip address" ++ case 27: // "constant string" ++ case 28: // "integer" ++ case 29: // "constant hexstring" ++ case 30: // "option name" ++ case 31: // "ip address" value.copy< std::string > (that.value); break; - case 33: // option_code - case 32: // option_code ++ case 36: // option_code value.copy< uint16_t > (that.value); break; - case 38: // nest_level ++ case 41: // nest_level + value.copy< uint8_t > (that.value); + break; + default: break; } @@@ -350,67 -340,53 +358,74 @@@ << yysym.location << ": "; switch (yytype) { -- case 24: // "constant string" ++ case 27: // "constant string" + - #line 78 "parser.yy" // lalr1.cc:636 ++#line 82 "parser.yy" // lalr1.cc:636 + { yyoutput << yysym.value.template as< std::string > (); } - #line 358 "parser.cc" // lalr1.cc:636 ++#line 366 "parser.cc" // lalr1.cc:636 + break; + - case 25: // "integer" ++ case 28: // "integer" - #line 78 "parser.yy" // lalr1.cc:636 -#line 76 "parser.yy" // lalr1.cc:636 ++#line 82 "parser.yy" // lalr1.cc:636 { yyoutput << yysym.value.template as< std::string > (); } - #line 365 "parser.cc" // lalr1.cc:636 -#line 348 "parser.cc" // lalr1.cc:636 ++#line 373 "parser.cc" // lalr1.cc:636 break; - case 26: // "constant hexstring" - case 25: // "integer" ++ case 29: // "constant hexstring" - #line 78 "parser.yy" // lalr1.cc:636 -#line 76 "parser.yy" // lalr1.cc:636 ++#line 82 "parser.yy" // lalr1.cc:636 { yyoutput << yysym.value.template as< std::string > (); } - #line 372 "parser.cc" // lalr1.cc:636 -#line 355 "parser.cc" // lalr1.cc:636 ++#line 380 "parser.cc" // lalr1.cc:636 break; - case 27: // "option name" - case 26: // "constant hexstring" ++ case 30: // "option name" - #line 78 "parser.yy" // lalr1.cc:636 -#line 76 "parser.yy" // lalr1.cc:636 ++#line 82 "parser.yy" // lalr1.cc:636 { yyoutput << yysym.value.template as< std::string > (); } - #line 379 "parser.cc" // lalr1.cc:636 -#line 362 "parser.cc" // lalr1.cc:636 ++#line 387 "parser.cc" // lalr1.cc:636 break; - case 28: // "ip address" - case 27: // "option name" ++ case 31: // "ip address" - #line 78 "parser.yy" // lalr1.cc:636 -#line 76 "parser.yy" // lalr1.cc:636 ++#line 82 "parser.yy" // lalr1.cc:636 { yyoutput << yysym.value.template as< std::string > (); } - #line 386 "parser.cc" // lalr1.cc:636 -#line 369 "parser.cc" // lalr1.cc:636 ++#line 394 "parser.cc" // lalr1.cc:636 break; - case 33: // option_code - case 32: // option_code ++ case 36: // option_code - #line 78 "parser.yy" // lalr1.cc:636 -#line 76 "parser.yy" // lalr1.cc:636 ++#line 82 "parser.yy" // lalr1.cc:636 { yyoutput << yysym.value.template as< uint16_t > (); } - #line 393 "parser.cc" // lalr1.cc:636 -#line 376 "parser.cc" // lalr1.cc:636 ++#line 401 "parser.cc" // lalr1.cc:636 break; - case 34: // option_repr_type - case 33: // option_repr_type ++ case 37: // option_repr_type - #line 78 "parser.yy" // lalr1.cc:636 -#line 76 "parser.yy" // lalr1.cc:636 ++#line 82 "parser.yy" // lalr1.cc:636 { yyoutput << yysym.value.template as< TokenOption::RepresentationType > (); } - #line 400 "parser.cc" // lalr1.cc:636 -#line 383 "parser.cc" // lalr1.cc:636 ++#line 408 "parser.cc" // lalr1.cc:636 + break; + - case 37: // relay6_field ++ case 40: // relay6_field + - #line 78 "parser.yy" // lalr1.cc:636 ++#line 82 "parser.yy" // lalr1.cc:636 + { yyoutput << yysym.value.template as< TokenRelay6Field::FieldType > (); } - #line 407 "parser.cc" // lalr1.cc:636 ++#line 415 "parser.cc" // lalr1.cc:636 break; - case 38: // nest_level - case 36: // pkt6_field ++ case 41: // nest_level + - #line 78 "parser.yy" // lalr1.cc:636 ++#line 82 "parser.yy" // lalr1.cc:636 + { yyoutput << yysym.value.template as< uint8_t > (); } - #line 414 "parser.cc" // lalr1.cc:636 ++#line 422 "parser.cc" // lalr1.cc:636 ++ break; + -#line 76 "parser.yy" // lalr1.cc:636 ++ case 42: // pkt6_field ++ ++#line 82 "parser.yy" // lalr1.cc:636 + { yyoutput << yysym.value.template as< TokenPkt6::FieldType > (); } -#line 390 "parser.cc" // lalr1.cc:636 ++#line 429 "parser.cc" // lalr1.cc:636 break; @@@ -610,30 -586,25 +625,34 @@@ when using variants. */ switch (yyr1_[yyn]) { - case 34: // option_repr_type - case 33: // option_repr_type ++ case 37: // option_repr_type yylhs.value.build< TokenOption::RepresentationType > (); break; - case 37: // relay6_field - case 36: // pkt6_field ++ case 42: // pkt6_field + yylhs.value.build< TokenPkt6::FieldType > (); + break; + - case 24: // "constant string" - case 25: // "integer" - case 26: // "constant hexstring" - case 27: // "option name" ++ case 40: // relay6_field + yylhs.value.build< TokenRelay6Field::FieldType > (); + break; + - case 24: // "constant string" - case 25: // "integer" - case 26: // "constant hexstring" - case 27: // "option name" - case 28: // "ip address" ++ case 27: // "constant string" ++ case 28: // "integer" ++ case 29: // "constant hexstring" ++ case 30: // "option name" ++ case 31: // "ip address" yylhs.value.build< std::string > (); break; - case 33: // option_code - case 32: // option_code ++ case 36: // option_code yylhs.value.build< uint16_t > (); break; - case 38: // nest_level ++ case 41: // nest_level + yylhs.value.build< uint8_t > (); + break; + default: break; } @@@ -652,52 -623,52 +671,52 @@@ switch (yyn) { case 4: - #line 92 "parser.yy" // lalr1.cc:859 -#line 90 "parser.yy" // lalr1.cc:859 ++#line 96 "parser.yy" // lalr1.cc:859 { TokenPtr neg(new TokenNot()); ctx.expression.push_back(neg); } - #line 661 "parser.cc" // lalr1.cc:859 -#line 632 "parser.cc" // lalr1.cc:859 ++#line 680 "parser.cc" // lalr1.cc:859 break; case 5: - #line 97 "parser.yy" // lalr1.cc:859 -#line 95 "parser.yy" // lalr1.cc:859 ++#line 101 "parser.yy" // lalr1.cc:859 { TokenPtr neg(new TokenAnd()); ctx.expression.push_back(neg); } - #line 670 "parser.cc" // lalr1.cc:859 -#line 641 "parser.cc" // lalr1.cc:859 ++#line 689 "parser.cc" // lalr1.cc:859 break; case 6: - #line 102 "parser.yy" // lalr1.cc:859 -#line 100 "parser.yy" // lalr1.cc:859 ++#line 106 "parser.yy" // lalr1.cc:859 { TokenPtr neg(new TokenOr()); ctx.expression.push_back(neg); } - #line 679 "parser.cc" // lalr1.cc:859 -#line 650 "parser.cc" // lalr1.cc:859 ++#line 698 "parser.cc" // lalr1.cc:859 break; case 7: - #line 107 "parser.yy" // lalr1.cc:859 -#line 105 "parser.yy" // lalr1.cc:859 ++#line 111 "parser.yy" // lalr1.cc:859 { TokenPtr eq(new TokenEqual()); ctx.expression.push_back(eq); } - #line 688 "parser.cc" // lalr1.cc:859 -#line 659 "parser.cc" // lalr1.cc:859 ++#line 707 "parser.cc" // lalr1.cc:859 break; case 8: - #line 112 "parser.yy" // lalr1.cc:859 -#line 110 "parser.yy" // lalr1.cc:859 ++#line 116 "parser.yy" // lalr1.cc:859 { TokenPtr opt(new TokenOption(yystack_[3].value.as< uint16_t > (), TokenOption::EXISTS)); ctx.expression.push_back(opt); } - #line 697 "parser.cc" // lalr1.cc:859 -#line 668 "parser.cc" // lalr1.cc:859 ++#line 716 "parser.cc" // lalr1.cc:859 break; case 9: - #line 117 "parser.yy" // lalr1.cc:859 -#line 115 "parser.yy" // lalr1.cc:859 ++#line 121 "parser.yy" // lalr1.cc:859 { switch (ctx.getUniverse()) { case Option::V4: @@@ -717,65 -688,38 +736,65 @@@ error(yystack_[5].location, "relay4 can only be used in DHCPv4."); } } - #line 721 "parser.cc" // lalr1.cc:859 -#line 692 "parser.cc" // lalr1.cc:859 ++#line 740 "parser.cc" // lalr1.cc:859 break; case 10: --#line 137 "parser.yy" // lalr1.cc:859 ++#line 141 "parser.yy" // lalr1.cc:859 + { + switch (ctx.getUniverse()) { + case Option::V6: + { + TokenPtr opt(new TokenRelay6Option(yystack_[8].value.as< uint8_t > (), yystack_[3].value.as< uint16_t > (), TokenOption::EXISTS)); + ctx.expression.push_back(opt); + break; + } + case Option::V4: + // For now we only use relay6 in DHCPv6. + error(yystack_[10].location, "relay6 can only be used in DHCPv6."); + } + } - #line 739 "parser.cc" // lalr1.cc:859 ++#line 758 "parser.cc" // lalr1.cc:859 + break; + + case 11: - #line 153 "parser.yy" // lalr1.cc:859 ++#line 157 "parser.yy" // lalr1.cc:859 { TokenPtr str(new TokenString(yystack_[0].value.as< std::string > ())); ctx.expression.push_back(str); } - #line 748 "parser.cc" // lalr1.cc:859 -#line 701 "parser.cc" // lalr1.cc:859 ++#line 767 "parser.cc" // lalr1.cc:859 break; - case 11: -#line 142 "parser.yy" // lalr1.cc:859 + case 12: - #line 158 "parser.yy" // lalr1.cc:859 ++#line 162 "parser.yy" // lalr1.cc:859 { TokenPtr hex(new TokenHexString(yystack_[0].value.as< std::string > ())); ctx.expression.push_back(hex); } - #line 757 "parser.cc" // lalr1.cc:859 -#line 710 "parser.cc" // lalr1.cc:859 ++#line 776 "parser.cc" // lalr1.cc:859 break; - case 12: -#line 147 "parser.yy" // lalr1.cc:859 + case 13: - #line 163 "parser.yy" // lalr1.cc:859 ++#line 167 "parser.yy" // lalr1.cc:859 + { + TokenPtr ip(new TokenIpAddress(yystack_[0].value.as< std::string > ())); + ctx.expression.push_back(ip); + } - #line 766 "parser.cc" // lalr1.cc:859 ++#line 785 "parser.cc" // lalr1.cc:859 + break; + + case 14: - #line 168 "parser.yy" // lalr1.cc:859 ++#line 172 "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 775 "parser.cc" // lalr1.cc:859 -#line 719 "parser.cc" // lalr1.cc:859 ++#line 794 "parser.cc" // lalr1.cc:859 break; - case 13: -#line 152 "parser.yy" // lalr1.cc:859 + case 15: - #line 173 "parser.yy" // lalr1.cc:859 ++#line 177 "parser.yy" // lalr1.cc:859 { switch (ctx.getUniverse()) { case Option::V4: @@@ -795,144 -739,109 +814,165 @@@ error(yystack_[5].location, "relay4 can only be used in DHCPv4."); } } - #line 799 "parser.cc" // lalr1.cc:859 -#line 743 "parser.cc" // lalr1.cc:859 ++#line 818 "parser.cc" // lalr1.cc:859 break; - case 14: -#line 172 "parser.yy" // lalr1.cc:859 + case 16: - #line 194 "parser.yy" // lalr1.cc:859 ++#line 198 "parser.yy" // lalr1.cc:859 + { + switch (ctx.getUniverse()) { + case Option::V6: + { + TokenPtr opt(new TokenRelay6Option(yystack_[8].value.as< uint8_t > (), yystack_[3].value.as< uint16_t > (), yystack_[0].value.as< TokenOption::RepresentationType > ())); + ctx.expression.push_back(opt); + break; + } + case Option::V4: + // For now we only use relay6 in DHCPv6. + error(yystack_[10].location, "relay6 can only be used in DHCPv6."); + } + } - #line 817 "parser.cc" // lalr1.cc:859 ++#line 836 "parser.cc" // lalr1.cc:859 + break; + + case 17: - #line 209 "parser.yy" // lalr1.cc:859 ++#line 213 "parser.yy" // lalr1.cc:859 + { + 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 835 "parser.cc" // lalr1.cc:859 ++#line 854 "parser.cc" // lalr1.cc:859 + break; + + case 18: - #line 225 "parser.yy" // lalr1.cc:859 ++#line 229 "parser.yy" // lalr1.cc:859 { TokenPtr sub(new TokenSubstring()); ctx.expression.push_back(sub); } - #line 844 "parser.cc" // lalr1.cc:859 -#line 752 "parser.cc" // lalr1.cc:859 ++#line 863 "parser.cc" // lalr1.cc:859 break; - case 15: -#line 177 "parser.yy" // lalr1.cc:859 + case 19: - #line 230 "parser.yy" // lalr1.cc:859 ++#line 234 "parser.yy" // lalr1.cc:859 { TokenPtr conc(new TokenConcat()); ctx.expression.push_back(conc); } - #line 853 "parser.cc" // lalr1.cc:859 -#line 761 "parser.cc" // lalr1.cc:859 ++#line 872 "parser.cc" // lalr1.cc:859 break; - case 16: -#line 182 "parser.yy" // lalr1.cc:859 + case 20: - #line 237 "parser.yy" // lalr1.cc:859 ++#line 239 "parser.yy" // lalr1.cc:859 + { + TokenPtr pkt6_field(new TokenPkt6(yystack_[0].value.as< TokenPkt6::FieldType > ())); + ctx.expression.push_back(pkt6_field); + } -#line 770 "parser.cc" // lalr1.cc:859 ++#line 881 "parser.cc" // lalr1.cc:859 + break; + - case 17: -#line 189 "parser.yy" // lalr1.cc:859 ++ case 21: ++#line 246 "parser.yy" // lalr1.cc:859 { yylhs.value.as< uint16_t > () = ctx.convertOptionCode(yystack_[0].value.as< std::string > (), yystack_[0].location); } - #line 861 "parser.cc" // lalr1.cc:859 -#line 778 "parser.cc" // lalr1.cc:859 ++#line 889 "parser.cc" // lalr1.cc:859 break; - case 21: - #line 241 "parser.yy" // lalr1.cc:859 - case 18: -#line 193 "parser.yy" // lalr1.cc:859 ++ case 22: ++#line 250 "parser.yy" // lalr1.cc:859 { yylhs.value.as< uint16_t > () = ctx.convertOptionName(yystack_[0].value.as< std::string > (), yystack_[0].location); } - #line 869 "parser.cc" // lalr1.cc:859 -#line 786 "parser.cc" // lalr1.cc:859 ++#line 897 "parser.cc" // lalr1.cc:859 break; - case 22: - #line 247 "parser.yy" // lalr1.cc:859 - case 19: -#line 199 "parser.yy" // lalr1.cc:859 ++ case 23: ++#line 256 "parser.yy" // lalr1.cc:859 { yylhs.value.as< TokenOption::RepresentationType > () = TokenOption::TEXTUAL; } - #line 877 "parser.cc" // lalr1.cc:859 -#line 794 "parser.cc" // lalr1.cc:859 ++#line 905 "parser.cc" // lalr1.cc:859 break; - case 23: - #line 251 "parser.yy" // lalr1.cc:859 - case 20: -#line 203 "parser.yy" // lalr1.cc:859 ++ case 24: ++#line 260 "parser.yy" // lalr1.cc:859 { yylhs.value.as< TokenOption::RepresentationType > () = TokenOption::HEXADECIMAL; } - #line 885 "parser.cc" // lalr1.cc:859 -#line 802 "parser.cc" // lalr1.cc:859 ++#line 913 "parser.cc" // lalr1.cc:859 break; - case 24: - #line 257 "parser.yy" // lalr1.cc:859 - case 21: -#line 209 "parser.yy" // lalr1.cc:859 ++ case 25: ++#line 266 "parser.yy" // lalr1.cc:859 { TokenPtr str(new TokenString(yystack_[0].value.as< std::string > ())); ctx.expression.push_back(str); } - #line 894 "parser.cc" // lalr1.cc:859 -#line 811 "parser.cc" // lalr1.cc:859 ++#line 922 "parser.cc" // lalr1.cc:859 break; - case 25: - #line 264 "parser.yy" // lalr1.cc:859 - case 22: -#line 216 "parser.yy" // lalr1.cc:859 ++ case 26: ++#line 273 "parser.yy" // lalr1.cc:859 { TokenPtr str(new TokenString(yystack_[0].value.as< std::string > ())); ctx.expression.push_back(str); } - #line 903 "parser.cc" // lalr1.cc:859 -#line 820 "parser.cc" // lalr1.cc:859 ++#line 931 "parser.cc" // lalr1.cc:859 break; - case 26: - #line 269 "parser.yy" // lalr1.cc:859 - case 23: -#line 221 "parser.yy" // lalr1.cc:859 ++ case 27: ++#line 278 "parser.yy" // lalr1.cc:859 { TokenPtr str(new TokenString("all")); ctx.expression.push_back(str); } - #line 912 "parser.cc" // lalr1.cc:859 -#line 829 "parser.cc" // lalr1.cc:859 ++#line 940 "parser.cc" // lalr1.cc:859 break; - case 27: - #line 275 "parser.yy" // lalr1.cc:859 - case 24: -#line 227 "parser.yy" // lalr1.cc:859 ++ case 28: ++#line 284 "parser.yy" // lalr1.cc:859 + { yylhs.value.as< TokenRelay6Field::FieldType > () = TokenRelay6Field::PEERADDR; } - #line 918 "parser.cc" // lalr1.cc:859 ++#line 946 "parser.cc" // lalr1.cc:859 + break; + - case 28: - #line 276 "parser.yy" // lalr1.cc:859 ++ case 29: ++#line 285 "parser.yy" // lalr1.cc:859 + { yylhs.value.as< TokenRelay6Field::FieldType > () = TokenRelay6Field::LINKADDR; } - #line 924 "parser.cc" // lalr1.cc:859 ++#line 952 "parser.cc" // lalr1.cc:859 + break; + - case 29: - #line 280 "parser.yy" // lalr1.cc:859 ++ case 30: ++#line 289 "parser.yy" // lalr1.cc:859 + { + yylhs.value.as< uint8_t > () = ctx.convertNestLevelNumber(yystack_[0].value.as< std::string > (), yystack_[0].location); + } - #line 932 "parser.cc" // lalr1.cc:859 ++#line 960 "parser.cc" // lalr1.cc:859 + break; + ++ case 31: ++#line 297 "parser.yy" // lalr1.cc:859 + { yylhs.value.as< TokenPkt6::FieldType > () = TokenPkt6::MSGTYPE; } -#line 835 "parser.cc" // lalr1.cc:859 ++#line 966 "parser.cc" // lalr1.cc:859 + break; - #line 936 "parser.cc" // lalr1.cc:859 - case 25: -#line 228 "parser.yy" // lalr1.cc:859 ++ case 32: ++#line 298 "parser.yy" // lalr1.cc:859 + { yylhs.value.as< TokenPkt6::FieldType > () = TokenPkt6::TRANSID; } -#line 841 "parser.cc" // lalr1.cc:859 ++#line 972 "parser.cc" // lalr1.cc:859 + break; + + -#line 845 "parser.cc" // lalr1.cc:859 ++#line 976 "parser.cc" // lalr1.cc:859 default: break; } @@@ -1187,108 -1096,98 +1227,117 @@@ } - const signed char EvalParser::yypact_ninf_ = -47; - const signed char EvalParser::yypact_ninf_ = -42; ++ const signed char EvalParser::yypact_ninf_ = -54; const signed char EvalParser::yytable_ninf_ = -1; const signed char EvalParser::yypact_[] = { - 11, 11, 11, -4, -1, 3, 21, 27, -47, -47, - -47, 49, 51, 28, 44, -47, -2, -2, 19, 36, - 36, -47, 11, 11, 36, -47, -47, -47, 46, 48, - -47, 57, 59, 60, 61, 43, 54, -47, 71, -47, - 62, 63, 64, -2, -2, 19, 56, 36, 23, 35, - -5, 67, 68, 69, -47, 65, 81, -47, -47, -47, - -47, -47, -47, 72, -47, -47, -47, 73, 74, 75, - -16, -47, -2, 53, 53, 6, -47, -47, 84, 77, - 79, -47, 78, -2, 50, 80, -47, -47, 82, 53 - -1, -1, -1, 10, 13, 35, 45, 40, -42, -42, - 26, 6, 46, 11, -42, 12, 12, 23, 23, 19, - -42, -1, -1, 23, -42, -42, -42, 43, 44, 47, - 48, 38, 41, -42, -42, -42, -42, 55, -42, 49, - 50, 12, 12, 39, 23, 20, 36, 53, 54, -42, - 51, 63, -42, -42, -42, -42, -42, -42, 56, 58, - -11, -42, 31, 31, -42, -42, 64, -42 ++ 29, 29, 29, -12, -4, 7, 21, 30, 32, -54, ++ -54, -54, 13, 10, 46, 16, -54, -3, -3, 9, ++ 52, 52, 42, -54, 29, 29, 52, -54, -54, -54, ++ 40, 54, -54, 56, 43, 59, 60, 55, 58, -54, ++ -54, -54, -54, 72, -54, 66, 68, 69, -3, -3, ++ 9, 61, 52, 25, 28, -1, 71, 73, 75, -54, ++ 65, 87, -54, -54, -54, -54, -54, -54, 78, -54, ++ -54, -54, 77, 79, 80, -14, -54, -3, 33, 33, ++ 6, -54, -54, 90, 82, 84, -54, 83, -3, 47, ++ 85, -54, -54, 86, 33 }; const unsigned char EvalParser::yydefact_[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, - 13, 0, 2, 0, 0, 4, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 3, 20, 21, 0, 0, - 29, 0, 0, 0, 0, 0, 0, 5, 6, 7, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 24, 0, 0, 22, 23, 8, - 14, 9, 15, 0, 27, 28, 17, 0, 0, 0, - 0, 19, 0, 0, 0, 0, 26, 25, 0, 0, - 0, 18, 0, 0, 0, 0, 10, 16, 0, 0 - 0, 0, 0, 0, 0, 0, 0, 0, 10, 11, - 0, 2, 0, 0, 4, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 3, 17, 18, 0, 0, 0, - 0, 0, 0, 24, 25, 16, 5, 6, 7, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, - 0, 0, 19, 20, 8, 12, 9, 13, 0, 0, - 0, 15, 0, 0, 23, 22, 0, 14 ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, ++ 12, 13, 0, 2, 0, 0, 4, 0, 0, 0, ++ 0, 0, 0, 1, 0, 0, 0, 3, 21, 22, ++ 0, 0, 30, 0, 0, 0, 0, 0, 0, 31, ++ 32, 20, 5, 6, 7, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, ++ 0, 0, 23, 24, 8, 14, 9, 15, 0, 28, ++ 29, 17, 0, 0, 0, 0, 19, 0, 0, 0, ++ 0, 27, 26, 0, 0, 0, 18, 0, 0, 0, ++ 0, 10, 16, 0, 0 }; const signed char EvalParser::yypgoto_[] = { - -47, -47, 10, -18, -17, -46, -47, -47, -47, 52 - -42, -42, 9, -17, -13, -41, -42, -42, -42 ++ -54, -54, 4, -17, -18, -53, -54, -54, -54, 51, ++ -54 }; const signed char EvalParser::yydefgoto_[] = { - -1, 11, 12, 13, 28, 60, 55, 78, 66, 31 - -1, 10, 11, 12, 27, 55, 50, 66, 35 ++ -1, 12, 13, 14, 30, 65, 60, 83, 71, 33, ++ 41 }; const unsigned char EvalParser::yytable_[] = { - 29, 35, 36, 62, 63, 76, 39, 64, 65, 77, - 16, 14, 15, 17, 1, 80, 2, 18, 64, 65, - 3, 4, 5, 26, 19, 27, 51, 52, 62, 56, - 20, 6, 37, 38, 7, 8, 24, 9, 87, 10, - 57, 58, 59, 87, 30, 32, 33, 34, 25, 21, - 22, 23, 57, 58, 61, 79, 6, 22, 23, 7, - 8, 40, 9, 41, 10, 46, 85, 57, 58, 86, - 57, 58, 42, 43, 44, 45, 47, 22, 48, 49, - 50, 54, 67, 68, 69, 71, 72, 70, 81, 73, - 74, 75, 82, 83, 84, 88, 0, 53, 89 - 31, 32, 1, 28, 2, 57, 38, 64, 3, 4, - 13, 14, 21, 22, 65, 24, 5, 21, 22, 6, - 7, 15, 57, 8, 16, 9, 20, 51, 47, 48, - 36, 37, 29, 30, 52, 53, 54, 25, 17, 26, - 5, 33, 34, 6, 7, 52, 53, 8, 18, 9, - 52, 53, 56, 19, 23, 39, 40, 43, 41, 42, - 44, 21, 45, 46, 49, 58, 59, 61, 67, 62, - 60, 63 ++ 31, 67, 17, 37, 38, 15, 16, 81, 68, 44, ++ 18, 69, 70, 23, 82, 85, 24, 25, 69, 70, ++ 27, 19, 24, 25, 20, 28, 67, 29, 42, 43, ++ 56, 57, 1, 21, 2, 61, 92, 32, 3, 4, ++ 5, 92, 62, 63, 64, 62, 63, 66, 22, 6, ++ 62, 63, 7, 8, 26, 45, 9, 48, 10, 84, ++ 11, 34, 35, 36, 62, 63, 91, 39, 40, 46, ++ 90, 47, 6, 49, 50, 7, 8, 51, 24, 9, ++ 52, 10, 53, 11, 54, 55, 72, 75, 73, 59, ++ 74, 76, 77, 78, 86, 79, 80, 87, 88, 89, ++ 93, 58, 94 }; - const signed char + const unsigned char EvalParser::yycheck_[] = { - 17, 19, 20, 49, 9, 21, 24, 12, 13, 25, - 14, 1, 2, 14, 3, 9, 5, 14, 12, 13, - 9, 10, 11, 25, 3, 27, 43, 44, 74, 47, - 3, 20, 22, 23, 23, 24, 8, 26, 84, 28, - 17, 18, 19, 89, 25, 9, 10, 11, 4, 0, - 6, 7, 17, 18, 19, 72, 20, 6, 7, 23, - 24, 15, 26, 15, 28, 22, 83, 17, 18, 19, - 17, 18, 15, 14, 14, 14, 22, 6, 16, 16, - 16, 25, 15, 15, 15, 4, 14, 22, 4, 16, - 16, 16, 15, 14, 16, 15, -1, 45, 16 - 17, 18, 3, 16, 5, 46, 23, 18, 9, 10, - 1, 2, 6, 7, 25, 4, 17, 6, 7, 20, - 21, 11, 63, 24, 11, 26, 0, 44, 41, 42, - 21, 22, 9, 10, 14, 15, 16, 25, 3, 27, - 17, 22, 23, 20, 21, 14, 15, 24, 3, 26, - 14, 15, 16, 13, 8, 12, 12, 19, 11, 11, - 19, 6, 13, 13, 25, 12, 12, 4, 4, 13, - 19, 13 ++ 18, 54, 14, 20, 21, 1, 2, 21, 9, 26, ++ 14, 12, 13, 0, 28, 9, 6, 7, 12, 13, ++ 4, 14, 6, 7, 3, 28, 79, 30, 24, 25, ++ 48, 49, 3, 3, 5, 52, 89, 28, 9, 10, ++ 11, 94, 17, 18, 19, 17, 18, 19, 16, 20, ++ 17, 18, 23, 24, 8, 15, 27, 14, 29, 77, ++ 31, 9, 10, 11, 17, 18, 19, 25, 26, 15, ++ 88, 15, 20, 14, 14, 23, 24, 22, 6, 27, ++ 22, 29, 16, 31, 16, 16, 15, 22, 15, 28, ++ 15, 4, 14, 16, 4, 16, 16, 15, 14, 16, ++ 15, 50, 16 }; const unsigned char EvalParser::yystos_[] = { - 0, 3, 5, 9, 10, 11, 20, 23, 24, 26, - 28, 30, 31, 32, 31, 31, 14, 14, 14, 3, - 3, 0, 6, 7, 8, 4, 25, 27, 33, 33, - 25, 38, 9, 10, 11, 32, 32, 31, 31, 32, - 15, 15, 15, 14, 14, 14, 22, 22, 16, 16, - 16, 33, 33, 38, 25, 35, 32, 17, 18, 19, - 34, 19, 34, 9, 12, 13, 37, 15, 15, 15, - 22, 4, 14, 16, 16, 16, 21, 25, 36, 33, - 9, 4, 15, 14, 16, 33, 19, 34, 15, 16 - 0, 3, 5, 9, 10, 17, 20, 21, 24, 26, - 29, 30, 31, 30, 30, 11, 11, 3, 3, 13, - 0, 6, 7, 8, 4, 25, 27, 32, 32, 9, - 10, 31, 31, 22, 23, 36, 30, 30, 31, 12, - 12, 11, 11, 19, 19, 13, 13, 32, 32, 25, - 34, 31, 14, 15, 16, 33, 16, 33, 12, 12, - 19, 4, 13, 13, 18, 25, 35, 4 ++ 0, 3, 5, 9, 10, 11, 20, 23, 24, 27, ++ 29, 31, 33, 34, 35, 34, 34, 14, 14, 14, ++ 3, 3, 16, 0, 6, 7, 8, 4, 28, 30, ++ 36, 36, 28, 41, 9, 10, 11, 35, 35, 25, ++ 26, 42, 34, 34, 35, 15, 15, 15, 14, 14, ++ 14, 22, 22, 16, 16, 16, 36, 36, 41, 28, ++ 38, 35, 17, 18, 19, 37, 19, 37, 9, 12, ++ 13, 40, 15, 15, 15, 22, 4, 14, 16, 16, ++ 16, 21, 28, 39, 36, 9, 4, 15, 14, 16, ++ 36, 19, 37, 15, 16 }; const unsigned char EvalParser::yyr1_[] = { - 0, 29, 30, 31, 31, 31, 31, 31, 31, 31, - 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 33, 33, 34, 34, 35, 36, 36, 37, 37, 38 - 0, 28, 29, 30, 30, 30, 30, 30, 30, 30, - 31, 31, 31, 31, 31, 31, 31, 32, 32, 33, - 33, 34, 35, 35, 36, 36 ++ 0, 32, 33, 34, 34, 34, 34, 34, 34, 34, ++ 34, 35, 35, 35, 35, 35, 35, 35, 35, 35, ++ 35, 36, 36, 37, 37, 38, 39, 39, 40, 40, ++ 41, 42, 42 }; const unsigned char EvalParser::yyr2_[] = { 0, 2, 1, 3, 2, 3, 3, 3, 6, 6, - 1, 1, 6, 6, 8, 6, 3, 1, 1, 1, - 1, 1, 1, 1, 1, 1 + 11, 1, 1, 1, 6, 6, 11, 6, 8, 6, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ++ 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, ++ 1, 1, 1 }; @@@ -1299,23 -1198,22 +1348,24 @@@ const EvalParser::yytname_[] = { "\"end of file\"", "error", "$undefined", "\"(\"", "\")\"", "\"not\"", - "\"and\"", "\"or\"", "\"==\"", "\"option\"", "\"relay4\"", "\"[\"", - "\"]\"", "\".\"", "\"text\"", "\"hex\"", "\"exists\"", "\"substring\"", - "\"all\"", "\",\"", "\"concat\"", "\"pkt6\"", "\"msgtype\"", - "\"transid\"", "\"constant string\"", "\"integer\"", - "\"constant hexstring\"", "\"option name\"", "$accept", "expression", + "\"and\"", "\"or\"", "\"==\"", "\"option\"", "\"relay4\"", "\"relay6\"", + "\"peeraddr\"", "\"linkaddr\"", "\"[\"", "\"]\"", "\".\"", "\"text\"", + "\"hex\"", "\"exists\"", "\"substring\"", "\"all\"", "\",\"", - "\"concat\"", "\"constant string\"", "\"integer\"", - "\"constant hexstring\"", "\"option name\"", "\"ip address\"", "$accept", - "expression", "bool_expr", "string_expr", "option_code", - "option_repr_type", "start_expr", "length_expr", "relay6_field", - "nest_level", YY_NULLPTR ++ "\"concat\"", "\"pkt6\"", "\"msgtype\"", "\"transid\"", ++ "\"constant string\"", "\"integer\"", "\"constant hexstring\"", ++ "\"option name\"", "\"ip address\"", "$accept", "expression", + "bool_expr", "string_expr", "option_code", "option_repr_type", - "start_expr", "length_expr", "pkt6_field", YY_NULLPTR ++ "start_expr", "length_expr", "relay6_field", "nest_level", "pkt6_field", YY_NULLPTR }; #if YYDEBUG - const unsigned char + const unsigned short int EvalParser::yyrline_[] = { - 0, 87, 87, 90, 91, 96, 101, 106, 111, 116, - 136, 152, 157, 162, 167, 172, 193, 208, 224, 229, - 236, 240, 246, 250, 256, 263, 268, 275, 276, 279 - 0, 85, 85, 88, 89, 94, 99, 104, 109, 114, - 136, 141, 146, 151, 171, 176, 181, 188, 192, 198, - 202, 208, 215, 220, 227, 228 ++ 0, 91, 91, 94, 95, 100, 105, 110, 115, 120, ++ 140, 156, 161, 166, 171, 176, 197, 212, 228, 233, ++ 238, 245, 249, 255, 259, 265, 272, 277, 284, 285, ++ 288, 297, 298 }; // Print the state stack on the debug stream. @@@ -1350,8 -1248,8 +1400,8 @@@ #line 13 "parser.yy" // lalr1.cc:1167 } } // isc::eval - #line 1354 "parser.cc" // lalr1.cc:1167 - #line 288 "parser.yy" // lalr1.cc:1168 -#line 1252 "parser.cc" // lalr1.cc:1167 -#line 231 "parser.yy" // lalr1.cc:1168 ++#line 1404 "parser.cc" // lalr1.cc:1167 ++#line 301 "parser.yy" // lalr1.cc:1168 void isc::eval::EvalParser::error(const location_type& loc, diff --cc src/lib/eval/parser.h index c22092b985,ce3adb04bb..7727cffa8b --- a/src/lib/eval/parser.h +++ b/src/lib/eval/parser.h @@@ -298,21 -298,17 +298,24 @@@ namespace isc { namespace eval // option_repr_type char dummy1[sizeof(TokenOption::RepresentationType)]; + // pkt6_field + char dummy2[sizeof(TokenPkt6::FieldType)]; + + // relay6_field - char dummy2[sizeof(TokenRelay6Field::FieldType)]; ++ char dummy3[sizeof(TokenRelay6Field::FieldType)]; + // "constant string" // "integer" // "constant hexstring" // "option name" - char dummy3[sizeof(std::string)]; + // "ip address" - char dummy3[sizeof(std::string)]; ++ char dummy4[sizeof(std::string)]; // option_code -- char dummy4[sizeof(uint16_t)]; ++ char dummy5[sizeof(uint16_t)]; + + // nest_level - char dummy5[sizeof(uint8_t)]; ++ char dummy6[sizeof(uint8_t)]; }; /// Symbol semantic values. @@@ -344,24 -340,23 +347,27 @@@ TOKEN_EQUAL = 263, TOKEN_OPTION = 264, TOKEN_RELAY4 = 265, - TOKEN_LBRACKET = 266, - TOKEN_RBRACKET = 267, - TOKEN_DOT = 268, - TOKEN_TEXT = 269, - TOKEN_HEX = 270, - TOKEN_EXISTS = 271, - TOKEN_SUBSTRING = 272, - TOKEN_ALL = 273, - TOKEN_COMA = 274, - TOKEN_CONCAT = 275, - TOKEN_PKT6 = 276, - TOKEN_MSGTYPE = 277, - TOKEN_TRANSID = 278, - TOKEN_STRING = 279, - TOKEN_INTEGER = 280, - TOKEN_HEXSTRING = 281, - TOKEN_OPTION_NAME = 282 + TOKEN_RELAY6 = 266, + TOKEN_PEERADDR = 267, + TOKEN_LINKADDR = 268, + TOKEN_LBRACKET = 269, + TOKEN_RBRACKET = 270, + TOKEN_DOT = 271, + TOKEN_TEXT = 272, + TOKEN_HEX = 273, + TOKEN_EXISTS = 274, + TOKEN_SUBSTRING = 275, + TOKEN_ALL = 276, + TOKEN_COMA = 277, + TOKEN_CONCAT = 278, - TOKEN_STRING = 279, - TOKEN_INTEGER = 280, - TOKEN_HEXSTRING = 281, - TOKEN_OPTION_NAME = 282, - TOKEN_IP_ADDRESS = 283 ++ TOKEN_PKT6 = 279, ++ TOKEN_MSGTYPE = 280, ++ TOKEN_TRANSID = 281, ++ TOKEN_STRING = 282, ++ TOKEN_INTEGER = 283, ++ TOKEN_HEXSTRING = 284, ++ TOKEN_OPTION_NAME = 285, ++ TOKEN_IP_ADDRESS = 286 }; }; @@@ -401,8 -396,8 +407,10 @@@ basic_symbol (typename Base::kind_type t, const TokenOption::RepresentationType v, const location_type& l); + basic_symbol (typename Base::kind_type t, const TokenPkt6::FieldType v, const location_type& l); + + basic_symbol (typename Base::kind_type t, const TokenRelay6Field::FieldType v, const location_type& l); + basic_symbol (typename Base::kind_type t, const std::string v, const location_type& l); basic_symbol (typename Base::kind_type t, const uint16_t v, const location_type& l); @@@ -789,12 -778,12 +809,12 @@@ enum { yyeof_ = 0, - yylast_ = 98, ///< Last index in yytable_. - yynnts_ = 10, ///< Number of nonterminal symbols. - yyfinal_ = 21, ///< Termination state number. - yylast_ = 71, ///< Last index in yytable_. - yynnts_ = 9, ///< Number of nonterminal symbols. - yyfinal_ = 20, ///< Termination state number. ++ yylast_ = 102, ///< Last index in yytable_. ++ yynnts_ = 11, ///< Number of nonterminal symbols. ++ yyfinal_ = 23, ///< Termination state number. yyterror_ = 1, yyerrcode_ = 256, - yyntokens_ = 29 ///< Number of tokens. - yyntokens_ = 28 ///< Number of tokens. ++ yyntokens_ = 32 ///< Number of tokens. }; @@@ -839,9 -828,9 +859,9 @@@ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28 - 25, 26, 27 ++ 25, 26, 27, 28, 29, 30, 31 }; - const unsigned int user_token_number_max_ = 283; - const unsigned int user_token_number_max_ = 282; ++ const unsigned int user_token_number_max_ = 286; const token_number_type undef_token_ = 2; if (static_cast(t) <= yyeof_) @@@ -874,30 -863,25 +894,34 @@@ { switch (other.type_get ()) { - case 34: // option_repr_type - case 33: // option_repr_type ++ case 37: // option_repr_type value.copy< TokenOption::RepresentationType > (other.value); break; - case 37: // relay6_field - case 36: // pkt6_field ++ case 42: // pkt6_field + value.copy< TokenPkt6::FieldType > (other.value); + break; + - case 24: // "constant string" - case 25: // "integer" - case 26: // "constant hexstring" - case 27: // "option name" ++ case 40: // relay6_field + value.copy< TokenRelay6Field::FieldType > (other.value); + break; + - case 24: // "constant string" - case 25: // "integer" - case 26: // "constant hexstring" - case 27: // "option name" - case 28: // "ip address" ++ case 27: // "constant string" ++ case 28: // "integer" ++ case 29: // "constant hexstring" ++ case 30: // "option name" ++ case 31: // "ip address" value.copy< std::string > (other.value); break; - case 33: // option_code - case 32: // option_code ++ case 36: // option_code value.copy< uint16_t > (other.value); break; - case 38: // nest_level ++ case 41: // nest_level + value.copy< uint8_t > (other.value); + break; + default: break; } @@@ -915,30 -899,25 +939,34 @@@ (void) v; switch (this->type_get ()) { - case 34: // option_repr_type - case 33: // option_repr_type ++ case 37: // option_repr_type value.copy< TokenOption::RepresentationType > (v); break; - case 37: // relay6_field - case 36: // pkt6_field ++ case 42: // pkt6_field + value.copy< TokenPkt6::FieldType > (v); + break; + - case 24: // "constant string" - case 25: // "integer" - case 26: // "constant hexstring" - case 27: // "option name" ++ case 40: // relay6_field + value.copy< TokenRelay6Field::FieldType > (v); + break; + - case 24: // "constant string" - case 25: // "integer" - case 26: // "constant hexstring" - case 27: // "option name" - case 28: // "ip address" ++ case 27: // "constant string" ++ case 28: // "integer" ++ case 29: // "constant hexstring" ++ case 30: // "option name" ++ case 31: // "ip address" value.copy< std::string > (v); break; - case 33: // option_code - case 32: // option_code ++ case 36: // option_code value.copy< uint16_t > (v); break; - case 38: // nest_level ++ case 41: // nest_level + value.copy< uint8_t > (v); + break; + default: break; } @@@ -961,13 -940,13 +989,20 @@@ , location (l) {} + template + EvalParser::basic_symbol::basic_symbol (typename Base::kind_type t, const TokenPkt6::FieldType v, const location_type& l) + : Base (t) + , value (v) + , location (l) + {} + + template + EvalParser::basic_symbol::basic_symbol (typename Base::kind_type t, const TokenRelay6Field::FieldType v, const location_type& l) + : Base (t) + , value (v) + , location (l) + {} + template EvalParser::basic_symbol::basic_symbol (typename Base::kind_type t, const std::string v, const location_type& l) : Base (t) @@@ -1015,30 -987,25 +1050,34 @@@ // Type destructor. switch (yytype) { - case 34: // option_repr_type - case 33: // option_repr_type ++ case 37: // option_repr_type value.template destroy< TokenOption::RepresentationType > (); break; - case 37: // relay6_field - case 36: // pkt6_field ++ case 42: // pkt6_field + value.template destroy< TokenPkt6::FieldType > (); + break; + - case 24: // "constant string" - case 25: // "integer" - case 26: // "constant hexstring" - case 27: // "option name" ++ case 40: // relay6_field + value.template destroy< TokenRelay6Field::FieldType > (); + break; + - case 24: // "constant string" - case 25: // "integer" - case 26: // "constant hexstring" - case 27: // "option name" - case 28: // "ip address" ++ case 27: // "constant string" ++ case 28: // "integer" ++ case 29: // "constant hexstring" ++ case 30: // "option name" ++ case 31: // "ip address" value.template destroy< std::string > (); break; - case 33: // option_code - case 32: // option_code ++ case 36: // option_code value.template destroy< uint16_t > (); break; - case 38: // nest_level ++ case 41: // nest_level + value.template destroy< uint8_t > (); + break; + default: break; } @@@ -1062,30 -1029,25 +1101,34 @@@ super_type::move(s); switch (this->type_get ()) { - case 34: // option_repr_type - case 33: // option_repr_type ++ case 37: // option_repr_type value.move< TokenOption::RepresentationType > (s.value); break; - case 37: // relay6_field - case 36: // pkt6_field ++ case 42: // pkt6_field + value.move< TokenPkt6::FieldType > (s.value); + break; + - case 24: // "constant string" - case 25: // "integer" - case 26: // "constant hexstring" - case 27: // "option name" ++ case 40: // relay6_field + value.move< TokenRelay6Field::FieldType > (s.value); + break; + - case 24: // "constant string" - case 25: // "integer" - case 26: // "constant hexstring" - case 27: // "option name" - case 28: // "ip address" ++ case 27: // "constant string" ++ case 28: // "integer" ++ case 29: // "constant hexstring" ++ case 30: // "option name" ++ case 31: // "ip address" value.move< std::string > (s.value); break; - case 33: // option_code - case 32: // option_code ++ case 36: // option_code value.move< uint16_t > (s.value); break; - case 38: // nest_level ++ case 41: // nest_level + value.move< uint8_t > (s.value); + break; + default: break; } @@@ -1143,7 -1105,7 +1186,8 @@@ { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282, 283 - 275, 276, 277, 278, 279, 280, 281, 282 ++ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, ++ 285, 286 }; return static_cast (yytoken_number_[type]); } @@@ -1313,7 -1269,7 +1375,7 @@@ #line 13 "parser.yy" // lalr1.cc:377 } } // isc::eval - #line 1317 "parser.h" // lalr1.cc:377 -#line 1273 "parser.h" // lalr1.cc:377 ++#line 1379 "parser.h" // lalr1.cc:377 diff --cc src/lib/eval/parser.yy index cc7ed8fd50,67d190b6c0..1fd28a66f3 --- a/src/lib/eval/parser.yy +++ b/src/lib/eval/parser.yy @@@ -68,8 -67,7 +71,9 @@@ using namespace isc::eval %type option_code %type option_repr_type +%type relay6_field +%type nest_level + %type pkt6_field %left OR %left AND @@@ -272,19 -224,10 +281,23 @@@ length_expr : INTEGE } ; +relay6_field : PEERADDR { $$ = TokenRelay6Field::PEERADDR; } + | LINKADDR { $$ = TokenRelay6Field::LINKADDR; } + ; + +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. + ; + + pkt6_field:MSGTYPE { $$ = TokenPkt6::MSGTYPE; } + | TRANSID { $$ = TokenPkt6::TRANSID; } + ; + %% void isc::eval::EvalParser::error(const location_type& loc, diff --cc src/lib/eval/tests/context_unittest.cc index d086b3da46,e4ae0c3dcd..eab31f9ac0 --- a/src/lib/eval/tests/context_unittest.cc +++ b/src/lib/eval/tests/context_unittest.cc @@@ -148,114 -123,21 +148,129 @@@ public EXPECT_TRUE(conc); } + /// @brief checks if the given token is a TokenRelay6Option with + /// the correct nesting level, option code and representation. + /// @param token token to be checked + /// @param expected_level expected nesting level + /// @param expected_code expected option code + /// @param expected_repr expected representation (text, hex, exists) + void checkTokenRelay6Option(const TokenPtr& token, + uint8_t expected_level, + uint16_t expected_code, + TokenOption::RepresentationType expected_repr) { + ASSERT_TRUE(token); + boost::shared_ptr opt = + boost::dynamic_pointer_cast(token); + ASSERT_TRUE(opt); + + EXPECT_EQ(expected_level, opt->getNest()); + EXPECT_EQ(expected_code, opt->getCode()); + EXPECT_EQ(expected_repr, opt->getRepresentation()); + } + + /// @brief This tests attempts to parse the expression then checks + /// if the number of tokens is correct and the TokenRelay6Option + /// is as expected. + /// + /// @param expr expression to be parsed + /// @param exp_level expected level to be parsed + /// @param exp_code expected option code to be parsed + /// @param exp_repr expected representation to be parsed + /// @param exp_tokens expected number of tokens + void testRelay6Option(std::string expr, + uint8_t exp_level, + uint16_t exp_code, + TokenOption::RepresentationType exp_repr, + 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 succed and return a token. + EXPECT_TRUE(parsed_); + + // There should be the expected number of tokens. + ASSERT_EQ(exp_tokens, eval.expression.size()); + + // checkt that the first token is TokenRelay6Option and that + // is has the correct attributes + checkTokenRelay6Option(eval.expression.at(0), exp_level, exp_code, exp_repr); + } + + /// @brief checks if the given token is a TokenRelay with the + /// correct nesting level and field type. + /// @param token token to be checked + /// @param expected_level expected nesting level + /// @param expected_code expected option code + /// @param expected_repr expected representation (text, hex, exists) + void checkTokenRelay6Field(const TokenPtr& token, + uint8_t expected_level, + TokenRelay6Field::FieldType expected_type) { + ASSERT_TRUE(token); + boost::shared_ptr opt = + boost::dynamic_pointer_cast(token); + ASSERT_TRUE(opt); + + EXPECT_EQ(expected_level, opt->getNest()); + EXPECT_EQ(expected_type, opt->getType()); + } + + /// @brief This tests attempts to parse the expression then checks + /// if the number of tokens is correct and the TokenRelay6Field is as + /// expected. + /// + /// @param expr expression to be parsed + /// @param exp_level expected level to be parsed + /// @param exp_type expected field type to be parsed + /// @param exp_tokens expected number of tokens + void testRelay6Field(std::string expr, + uint8_t exp_level, + TokenRelay6Field::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 succed and return a token. + EXPECT_TRUE(parsed_); + + // There should be the expected number of tokens. + ASSERT_EQ(exp_tokens, eval.expression.size()); + + // checkt that the first token is TokenRelay6Field and that + // is has the correct attributes + checkTokenRelay6Field(eval.expression.at(0), exp_level, exp_type); + } + + /// @brief checks if the given token is Pkt6 of specified type + /// @param token token to be checked + /// @param exp_type expected type of the Pkt6 field + void checkTokenPkt6(const TokenPtr& token, + TokenPkt6::FieldType exp_type) { + ASSERT_TRUE(token); + + boost::shared_ptr pkt = + boost::dynamic_pointer_cast(token); + + ASSERT_TRUE(pkt); + + EXPECT_EQ(exp_type, pkt->getType()); + } + /// @brief checks if the given expression raises the expected message /// when it is parsed. void checkError(const string& expr, const string& msg) { diff --cc src/lib/eval/tests/token_unittest.cc index c9276bed4f,c47d9e8096..d81f078bb2 --- a/src/lib/eval/tests/token_unittest.cc +++ b/src/lib/eval/tests/token_unittest.cc @@@ -1118,88 -968,28 +1118,114 @@@ TEST_F(TokenTest, concat) EXPECT_EQ("foobar", values_.top()); } +// This test checks if we can properly extract the link and peer +// address fields from relay encapsulations. Our packet has +// two relay encapsulations. We attempt to extract the two +// fields from both of the encapsulations and compare them. +// We also try to extract one of the fields from an encapsulation +// that doesn't exist (level 2), this should result in an empty +// string. +TEST_F(TokenTest, relay6Field) { + // Values for the address results + uint8_t zeroaddr[] = { 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 }; + uint8_t linkaddr[] = { 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1 }; + uint8_t peeraddr[] = { 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2 }; + + // We start by adding a set of relay encapsulations to the + // basic v6 packet. + addRelay6Encapsulations(); + + // Then we work our way through the set of choices + // Level 0 both link and peer address should be 0::0 + verifyRelay6Eval(0, TokenRelay6Field::LINKADDR, 16, zeroaddr); + verifyRelay6Eval(0, TokenRelay6Field::PEERADDR, 16, zeroaddr); + + // Level 1 link and peer should have different non-zero addresses + verifyRelay6Eval(1, TokenRelay6Field::LINKADDR, 16, linkaddr); + verifyRelay6Eval(1, TokenRelay6Field::PEERADDR, 16, peeraddr); + + // Level 2 has no encapsulation so the address should be zero length + verifyRelay6Eval(2, TokenRelay6Field::LINKADDR, 0, zeroaddr); + + // Lets check that the layout of the address returned by the + // token matches that of the TokenIpAddress + TokenPtr trelay; + TokenPtr taddr; + TokenPtr tequal; + ASSERT_NO_THROW(trelay.reset(new TokenRelay6Field(1, TokenRelay6Field::LINKADDR))); + ASSERT_NO_THROW(taddr.reset(new TokenIpAddress("1::1"))); + ASSERT_NO_THROW(tequal.reset(new TokenEqual())); + + EXPECT_NO_THROW(trelay->evaluate(*pkt6_, values_)); + EXPECT_NO_THROW(taddr->evaluate(*pkt6_, values_)); + EXPECT_NO_THROW(tequal->evaluate(*pkt6_, values_)); + + // We should have a single value on the stack and it should be "true" + ASSERT_EQ(1, values_.size()); + EXPECT_EQ("true", values_.top()); + + // be tidy + clearStack(); +} + +// This test checks if we can properly extract an option +// from relay encapsulations. Our packet has two relay +// encapsulations. Both include a common option with the +// original message (option 100) and both include their +// own option (101 and 102). We attempt to extract the +// options and compare them to expected values. We also +// try to extract an option from an encapsulation +// that doesn't exist (level 2), this should result in an empty +// string. +TEST_F(TokenTest, relay6Option) { + // We start by adding a set of relay encapsulations to the + // basic v6 packet. + addRelay6Encapsulations(); + + // Then we work our way through the set of choices + // Level 0 both options it has and the check that + // the checking for an option it doesn't have results + // in an empty string. + verifyRelay6Option(0, 100, TokenOption::TEXTUAL, "hundred.zero"); + verifyRelay6Option(0, 100, TokenOption::EXISTS, "true"); + verifyRelay6Option(0, 101, TokenOption::TEXTUAL, "hundredone.zero"); + verifyRelay6Option(0, 102, TokenOption::TEXTUAL, ""); + verifyRelay6Option(0, 102, TokenOption::EXISTS, "false"); + + // Level 1, again both options it has and the one for level 0 + verifyRelay6Option(1, 100, TokenOption::TEXTUAL, "hundred.one"); + verifyRelay6Option(1, 101, TokenOption::TEXTUAL, ""); + verifyRelay6Option(1, 102, TokenOption::TEXTUAL, "hundredtwo.one"); + + // Level 2, no encapsulation so no options + verifyRelay6Option(2, 100, TokenOption::TEXTUAL, ""); +} ++ + // Verifies if the DHCPv6 packet fields can be extracted. + TEST_F(TokenTest, pkt6Fields) { + // The default test creates a v6 DHCPV6_SOLICIT packet with a + // transaction id of 12345. + + // Check the message type + ASSERT_NO_THROW(t_.reset(new TokenPkt6(TokenPkt6::MSGTYPE))); + EXPECT_NO_THROW(t_->evaluate(*pkt6_, values_)); + ASSERT_EQ(1, values_.size()); + uint32_t expected = htonl(1); + EXPECT_EQ(0, memcmp(&expected, &values_.top()[0], 4)); + + // Check the transaction id field + clearStack(); + ASSERT_NO_THROW(t_.reset(new TokenPkt6(TokenPkt6::TRANSID))); + EXPECT_NO_THROW(t_->evaluate(*pkt6_, values_)); + ASSERT_EQ(1, values_.size()); + expected = htonl(12345); + EXPECT_EQ(0, memcmp(&expected, &values_.top()[0], 4)); + + // Check that working with a v4 packet generates an error + clearStack(); + ASSERT_NO_THROW(t_.reset(new TokenPkt6(TokenPkt6::TRANSID))); + EXPECT_THROW(t_->evaluate(*pkt4_, values_), EvalTypeError); + } diff --cc src/lib/eval/token.cc index b3e52ba924,9610f4af66..30b4dbc7a8 --- a/src/lib/eval/token.cc +++ b/src/lib/eval/token.cc @@@ -297,66 -275,44 +297,109 @@@ TokenOr::evaluate(const Pkt& /*pkt*/, V } } +OptionPtr TokenRelay6Option::getOption(const Pkt& pkt) { + + 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 { + // 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(const Pkt& pkt, ValueStack& values) { + + vector binary; + 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: + binary = pkt6.getRelay6LinkAddress(nest_level_).toBytes(); + break; + case 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(""); + 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); +} ++ + void + TokenPkt6::evaluate(const Pkt& pkt, ValueStack& values) { + + vector binary; + 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()); + 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); + 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); -}; ++} diff --cc src/lib/eval/token.h index e603192490,e3a1854e56..92591c7f20 --- a/src/lib/eval/token.h +++ b/src/lib/eval/token.h @@@ -467,119 -444,52 +467,165 @@@ public void evaluate(const 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(const Pkt& pkt); + + uint8_t nest_level_; ///< nesting level of the relay block to use +}; + +/// @breif 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(const 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 determins the field. ++ /// @brief enum value that determines the field. + enum FieldType { + MSGTYPE, ///< msg type + TRANSID ///< transaction id (integer but manipulated as as 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(const Pkt& pkt, ValueStack& values); + - /// @breif Returns field type ++ /// @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_; + }; + }; // end of isc::dhcp namespace }; // end of isc namespace