diff options
author | Shawn Routhier <sar@isc.org> | 2016-04-15 05:45:08 +0200 |
---|---|---|
committer | Shawn Routhier <sar@isc.org> | 2016-04-15 05:45:08 +0200 |
commit | 48be5f5ceaba6b0d0a2b31465e8a5904524e894c (patch) | |
tree | a9bf42365d0ffd0f89160cefd03c353d4a484a90 | |
parent | [master] Added ChangeLog entry for pull request #19. (diff) | |
parent | [trac4269] Updates per review comments, basically change some variable names (diff) | |
download | kea-48be5f5ceaba6b0d0a2b31465e8a5904524e894c.tar.xz kea-48be5f5ceaba6b0d0a2b31465e8a5904524e894c.zip |
Merge branch 'trac4269' Merge 4269 after updates to fix conflicts
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | doc/guide/classify.xml | 22 | ||||
-rw-r--r-- | src/lib/eval/lexer.cc | 290 | ||||
-rw-r--r-- | src/lib/eval/lexer.ll | 4 | ||||
-rw-r--r-- | src/lib/eval/parser.cc | 412 | ||||
-rw-r--r-- | src/lib/eval/parser.h | 170 | ||||
-rw-r--r-- | src/lib/eval/parser.yy | 13 | ||||
-rw-r--r-- | src/lib/eval/tests/context_unittest.cc | 57 | ||||
-rw-r--r-- | src/lib/eval/tests/token_unittest.cc | 26 | ||||
-rw-r--r-- | src/lib/eval/token.cc | 43 | ||||
-rw-r--r-- | src/lib/eval/token.h | 46 |
11 files changed, 723 insertions, 369 deletions
@@ -1,3 +1,8 @@ +1106. [func] sar + Added support for accessing DHCPv6 packet fields message type + and transaction id in a classification expression. + (Trac #4269, git <tbd>) + 1105. [bug] pallotron perfdhcp uses the same transaction id throughout the DORA exchange to adhere with RFC 2131. @@ -5,7 +10,7 @@ 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) @@ -19,7 +24,7 @@ 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 diff --git a/doc/guide/classify.xml b/doc/guide/classify.xml index 77c4981e32..76c310641b 100644 --- a/doc/guide/classify.xml +++ b/doc/guide/classify.xml @@ -188,6 +188,20 @@ sub-option with code "code" from the DHCPv4 Relay Agent Information option <!-- <entry>2001:DB8::1</entry> -->n <entry>The value of the link address field from the relay encapsulation "nest"</entry> </row> +<row> + <entry>Message Type in DHCPv6 packet</entry> + <entry>pkt6.msgtype</entry> +<!-- <entry>1</entry> +--> + <entry>The value of the message type field in the DHCPv6 packet.</entry> +</row> +<row> + <entry>Transaction ID in DHCPv6 packet</entry> + <entry>pkt6.transid</entry> +<!-- <entry>12345</entry> +--> + <entry>The value of the transaction id in the DHCPv6 packet.</entry> +</row> </tbody> </tgroup> </table> @@ -248,6 +262,14 @@ sub-option with code "code" from the DHCPv4 Relay Agent Information option </para> <para> + "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". + </para> + + <para> <table frame="all" id="classification-expressions-list"> <title>List of Classification Expressions</title> <tgroup cols='3'> diff --git a/src/lib/eval/lexer.cc b/src/lib/eval/lexer.cc index 25ba5f1f2c..02ea9fa388 100644 --- a/src/lib/eval/lexer.cc +++ b/src/lib/eval/lexer.cc @@ -483,8 +483,8 @@ static void yy_fatal_error (yyconst char msg[] ); (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 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,46 @@ struct yy_trans_info 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[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, - - 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 + 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[130] = { 0, 1, 1, 1, 2, 4, 7, 9, 11, 14, 17, 20, 22, 25, 28, 31, 33, 35, 38, 41, 44, 47, 50, 53, 56, 59, 62, 65, 68, 71, 74, - 77, 80, 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] = @@ -544,9 +547,9 @@ static yyconst YY_CHAR yy_ec[256] = 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 +566,136 @@ static yyconst YY_CHAR yy_ec[256] = 1, 1, 1, 1, 1 } ; -static yyconst YY_CHAR yy_meta[41] = +static yyconst YY_CHAR yy_meta[42] = { 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, 1, 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[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, 64, 146, 54, 48, 41, 0, 0, 44, - 0, 221, 159, 161, 163, 53, 166 + 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[134] = { 0, - 112, 1, 112, 112, 112, 112, 113, 112, 112, 112, - 112, 112, 112, 13, 114, 112, 112, 17, 112, 112, + 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[280] = { 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14, 14, 15, 16, 17, 18, 18, 19, 20, 4, 21, 17, 22, 17, 23, 18, 24, 18, 18, - 25, 26, 27, 28, 29, 30, 31, 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[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, + 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[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, }; 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[33] = { 0, 82, 86, 92, 102, 108, 122, 129, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, 159, 160, 161, 162, 163, 165 + 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 +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 778 "lexer.cc" #define INITIAL 0 @@ -1060,7 +1071,7 @@ YY_DECL loc.step(); -#line 1064 "lexer.cc" +#line 1075 "lexer.cc" while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { @@ -1088,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 >= 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 != 128 ); yy_find_action: /* %% [10.0] code to find the action number goes here */ @@ -1158,13 +1169,13 @@ do_action: /* This label is used only to access EOF actions. */ { if ( yy_act == 0 ) fprintf( stderr, "--scanner backing up\n" ); - else if ( yy_act < 30 ) + 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 == 33 ) fprintf( stderr, "--accepting default rule (\"%s\")\n", yytext ); - else if ( yy_act == 31 ) + else if ( yy_act == 34 ) fprintf( stderr, "--(end of buffer or a NUL)\n" ); else fprintf( stderr, "--EOF (start condition %d)\n", YY_START ); @@ -1366,18 +1377,33 @@ return isc::eval::EvalParser::make_COMA(loc); 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 170 "lexer.ll" return isc::eval::EvalParser::make_END(loc); YY_BREAK -case 30: +case 33: YY_RULE_SETUP -#line 167 "lexer.ll" +#line 171 "lexer.ll" ECHO; YY_BREAK -#line 1381 "lexer.cc" +#line 1407 "lexer.cc" case YY_END_OF_BUFFER: { @@ -1662,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 >= 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 +1716,11 @@ 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 >= 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 == 128); if ( ! yy_is_jam ) *(yy_state_ptr)++ = yy_current_state; @@ -2460,7 +2486,7 @@ void yyfree (void * ptr ) /* %ok-for-header */ -#line 167 "lexer.ll" +#line 171 "lexer.ll" diff --git a/src/lib/eval/lexer.ll b/src/lib/eval/lexer.ll index 9e44407c70..6fadc94a3e 100644 --- a/src/lib/eval/lexer.ll +++ b/src/lib/eval/lexer.ll @@ -162,6 +162,10 @@ addr6 [0-9a-fA-F]*\:[0-9a-fA-F]*\:[0-9a-fA-F:.]* "]" return isc::eval::EvalParser::make_RBRACKET(loc); "," return isc::eval::EvalParser::make_COMA(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); + . driver.error (loc, "Invalid character: " + std::string(yytext)); <<EOF>> return isc::eval::EvalParser::make_END(loc); %% diff --git a/src/lib/eval/parser.cc b/src/lib/eval/parser.cc index 3231b15b78..fa8038cfc6 100644 --- a/src/lib/eval/parser.cc +++ b/src/lib/eval/parser.cc @@ -251,27 +251,31 @@ namespace isc { namespace eval { { switch (that.type_get ()) { - case 34: // option_repr_type + case 37: // option_repr_type value.move< TokenOption::RepresentationType > (that.value); break; - case 37: // relay6_field + case 42: // pkt6_field + value.move< TokenPkt6::FieldType > (that.value); + break; + + 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 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; @@ -290,27 +294,31 @@ namespace isc { namespace eval { state = that.state; switch (that.type_get ()) { - case 34: // option_repr_type + case 37: // option_repr_type value.copy< TokenOption::RepresentationType > (that.value); break; - case 37: // relay6_field + case 42: // pkt6_field + value.copy< TokenPkt6::FieldType > (that.value); + break; + + 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 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; @@ -350,67 +358,74 @@ namespace isc { namespace eval { << 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 82 "parser.yy" // lalr1.cc:636 { yyoutput << yysym.value.template as< std::string > (); } -#line 365 "parser.cc" // lalr1.cc:636 +#line 373 "parser.cc" // lalr1.cc:636 break; - case 26: // "constant hexstring" + case 29: // "constant hexstring" -#line 78 "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 380 "parser.cc" // lalr1.cc:636 break; - case 27: // "option name" + case 30: // "option name" -#line 78 "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 387 "parser.cc" // lalr1.cc:636 break; - case 28: // "ip address" + case 31: // "ip address" -#line 78 "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 394 "parser.cc" // lalr1.cc:636 break; - case 33: // option_code + case 36: // option_code -#line 78 "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 401 "parser.cc" // lalr1.cc:636 break; - case 34: // option_repr_type + case 37: // option_repr_type -#line 78 "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 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 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; + + case 42: // pkt6_field + +#line 82 "parser.yy" // lalr1.cc:636 + { yyoutput << yysym.value.template as< TokenPkt6::FieldType > (); } +#line 429 "parser.cc" // lalr1.cc:636 break; @@ -610,27 +625,31 @@ namespace isc { namespace eval { when using variants. */ switch (yyr1_[yyn]) { - case 34: // option_repr_type + case 37: // option_repr_type yylhs.value.build< TokenOption::RepresentationType > (); break; - case 37: // relay6_field + case 42: // pkt6_field + yylhs.value.build< TokenPkt6::FieldType > (); + break; + + 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 36: // option_code yylhs.value.build< uint16_t > (); break; - case 38: // nest_level + case 41: // nest_level yylhs.value.build< uint8_t > (); break; @@ -652,52 +671,52 @@ namespace isc { namespace eval { switch (yyn) { case 4: -#line 92 "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 680 "parser.cc" // lalr1.cc:859 break; case 5: -#line 97 "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 689 "parser.cc" // lalr1.cc:859 break; case 6: -#line 102 "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 698 "parser.cc" // lalr1.cc:859 break; case 7: -#line 107 "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 707 "parser.cc" // lalr1.cc:859 break; case 8: -#line 112 "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 716 "parser.cc" // lalr1.cc:859 break; case 9: -#line 117 "parser.yy" // lalr1.cc:859 +#line 121 "parser.yy" // lalr1.cc:859 { switch (ctx.getUniverse()) { case Option::V4: @@ -717,11 +736,11 @@ namespace isc { namespace eval { error(yystack_[5].location, "relay4 can only be used in DHCPv4."); } } -#line 721 "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: @@ -735,47 +754,47 @@ namespace isc { namespace eval { 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 767 "parser.cc" // lalr1.cc:859 break; 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 776 "parser.cc" // lalr1.cc:859 break; 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 794 "parser.cc" // lalr1.cc:859 break; case 15: -#line 173 "parser.yy" // lalr1.cc:859 +#line 177 "parser.yy" // lalr1.cc:859 { switch (ctx.getUniverse()) { case Option::V4: @@ -795,11 +814,11 @@ namespace isc { namespace eval { error(yystack_[5].location, "relay4 can only be used in DHCPv4."); } } -#line 799 "parser.cc" // lalr1.cc:859 +#line 818 "parser.cc" // lalr1.cc:859 break; case 16: -#line 194 "parser.yy" // lalr1.cc:859 +#line 198 "parser.yy" // lalr1.cc:859 { switch (ctx.getUniverse()) { case Option::V6: @@ -813,11 +832,11 @@ namespace isc { namespace eval { 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: @@ -831,108 +850,129 @@ namespace isc { namespace eval { 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 863 "parser.cc" // lalr1.cc:859 break; 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 872 "parser.cc" // lalr1.cc:859 break; 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 881 "parser.cc" // lalr1.cc:859 + break; + + 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 889 "parser.cc" // lalr1.cc:859 break; - case 21: -#line 241 "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 897 "parser.cc" // lalr1.cc:859 break; - case 22: -#line 247 "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 905 "parser.cc" // lalr1.cc:859 break; - case 23: -#line 251 "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 913 "parser.cc" // lalr1.cc:859 break; - case 24: -#line 257 "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 922 "parser.cc" // lalr1.cc:859 break; - case 25: -#line 264 "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 931 "parser.cc" // lalr1.cc:859 break; - case 26: -#line 269 "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 940 "parser.cc" // lalr1.cc:859 break; - case 27: -#line 275 "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 966 "parser.cc" // lalr1.cc:859 + break; -#line 936 "parser.cc" // lalr1.cc:859 + case 32: +#line 298 "parser.yy" // lalr1.cc:859 + { yylhs.value.as< TokenPkt6::FieldType > () = TokenPkt6::TRANSID; } +#line 972 "parser.cc" // lalr1.cc:859 + break; + + +#line 976 "parser.cc" // lalr1.cc:859 default: break; } @@ -1187,100 +1227,108 @@ namespace isc { namespace eval { } - const signed char EvalParser::yypact_ninf_ = -47; + 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 + 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, 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 + -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, 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, 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 + 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, 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, 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 @@ -1288,7 +1336,8 @@ namespace isc { namespace eval { { 0, 2, 1, 3, 2, 3, 3, 3, 6, 6, 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 }; @@ -1302,20 +1351,21 @@ namespace isc { namespace eval { "\"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", "relay6_field", "nest_level", "pkt6_field", YY_NULLPTR }; #if YYDEBUG 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, 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 +1400,8 @@ namespace isc { namespace eval { #line 13 "parser.yy" // lalr1.cc:1167 } } // isc::eval -#line 1354 "parser.cc" // lalr1.cc:1167 -#line 288 "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 --git a/src/lib/eval/parser.h b/src/lib/eval/parser.h index c22092b985..7727cffa8b 100644 --- a/src/lib/eval/parser.h +++ b/src/lib/eval/parser.h @@ -298,21 +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" // "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. @@ -357,11 +360,14 @@ namespace isc { namespace eval { 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,6 +407,8 @@ namespace isc { namespace eval { basic_symbol (typename Base::kind_type t, const TokenOption::RepresentationType v, const location_type& l); + basic_symbol (typename Base::kind_type t, const 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); @@ -566,6 +574,18 @@ namespace isc { namespace eval { static inline symbol_type + make_PKT6 (const location_type& l); + + static inline + symbol_type + make_MSGTYPE (const location_type& l); + + static inline + symbol_type + make_TRANSID (const location_type& l); + + static inline + symbol_type make_STRING (const std::string& v, const location_type& l); static inline @@ -669,7 +689,7 @@ namespace isc { namespace eval { // number is the opposite. If YYTABLE_NINF, syntax error. static const unsigned char yytable_[]; - static const signed char yycheck_[]; + static const unsigned char yycheck_[]; // YYSTOS[STATE-NUM] -- The (internal number of the) accessing // symbol of state STATE-NUM. @@ -789,12 +809,12 @@ namespace isc { namespace eval { enum { yyeof_ = 0, - yylast_ = 98, ///< Last index in yytable_. - yynnts_ = 10, ///< Number of nonterminal symbols. - yyfinal_ = 21, ///< 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_ = 32 ///< Number of tokens. }; @@ -839,9 +859,9 @@ namespace isc { namespace eval { 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28 + 25, 26, 27, 28, 29, 30, 31 }; - const unsigned int user_token_number_max_ = 283; + const unsigned int user_token_number_max_ = 286; const token_number_type undef_token_ = 2; if (static_cast<int>(t) <= yyeof_) @@ -874,27 +894,31 @@ namespace isc { namespace eval { { switch (other.type_get ()) { - case 34: // option_repr_type + case 37: // option_repr_type value.copy< TokenOption::RepresentationType > (other.value); break; - case 37: // relay6_field + case 42: // pkt6_field + value.copy< TokenPkt6::FieldType > (other.value); + break; + + 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 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; @@ -915,27 +939,31 @@ namespace isc { namespace eval { (void) v; switch (this->type_get ()) { - case 34: // option_repr_type + case 37: // option_repr_type value.copy< TokenOption::RepresentationType > (v); break; - case 37: // relay6_field + case 42: // pkt6_field + value.copy< TokenPkt6::FieldType > (v); + break; + + 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 36: // option_code value.copy< uint16_t > (v); break; - case 38: // nest_level + case 41: // nest_level value.copy< uint8_t > (v); break; @@ -962,6 +990,13 @@ namespace isc { namespace eval { {} template <typename Base> + EvalParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const TokenPkt6::FieldType v, const location_type& l) + : Base (t) + , value (v) + , location (l) + {} + + template <typename Base> EvalParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const TokenRelay6Field::FieldType v, const location_type& l) : Base (t) , value (v) @@ -1015,27 +1050,31 @@ namespace isc { namespace eval { // Type destructor. switch (yytype) { - case 34: // option_repr_type + case 37: // option_repr_type value.template destroy< TokenOption::RepresentationType > (); break; - case 37: // relay6_field + case 42: // pkt6_field + value.template destroy< TokenPkt6::FieldType > (); + break; + + 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 36: // option_code value.template destroy< uint16_t > (); break; - case 38: // nest_level + case 41: // nest_level value.template destroy< uint8_t > (); break; @@ -1062,27 +1101,31 @@ namespace isc { namespace eval { super_type::move(s); switch (this->type_get ()) { - case 34: // option_repr_type + case 37: // option_repr_type value.move< TokenOption::RepresentationType > (s.value); break; - case 37: // relay6_field + case 42: // pkt6_field + value.move< TokenPkt6::FieldType > (s.value); + break; + + 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 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; @@ -1143,7 +1186,8 @@ namespace isc { namespace eval { { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282, 283 + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286 }; return static_cast<token_type> (yytoken_number_[type]); } @@ -1281,6 +1325,24 @@ namespace isc { namespace eval { } EvalParser::symbol_type + EvalParser::make_PKT6 (const location_type& l) + { + return symbol_type (token::TOKEN_PKT6, l); + } + + EvalParser::symbol_type + EvalParser::make_MSGTYPE (const location_type& l) + { + return symbol_type (token::TOKEN_MSGTYPE, l); + } + + EvalParser::symbol_type + EvalParser::make_TRANSID (const location_type& l) + { + return symbol_type (token::TOKEN_TRANSID, l); + } + + EvalParser::symbol_type EvalParser::make_STRING (const std::string& v, const location_type& l) { return symbol_type (token::TOKEN_STRING, v, l); @@ -1313,7 +1375,7 @@ namespace isc { namespace eval { #line 13 "parser.yy" // lalr1.cc:377 } } // isc::eval -#line 1317 "parser.h" // lalr1.cc:377 +#line 1379 "parser.h" // lalr1.cc:377 diff --git a/src/lib/eval/parser.yy b/src/lib/eval/parser.yy index cc7ed8fd50..1fd28a66f3 100644 --- a/src/lib/eval/parser.yy +++ b/src/lib/eval/parser.yy @@ -58,6 +58,9 @@ using namespace isc::eval; ALL "all" COMA "," CONCAT "concat" + PKT6 "pkt6" + MSGTYPE "msgtype" + TRANSID "transid" ; %token <std::string> STRING "constant string" @@ -70,6 +73,7 @@ using namespace isc::eval; %type <TokenOption::RepresentationType> option_repr_type %type <TokenRelay6Field::FieldType> relay6_field %type <uint8_t> nest_level +%type <TokenPkt6::FieldType> pkt6_field %left OR %left AND @@ -231,6 +235,11 @@ string_expr : STRING TokenPtr conc(new TokenConcat()); ctx.expression.push_back(conc); } + | PKT6 "." pkt6_field + { + TokenPtr pkt6_field(new TokenPkt6($3)); + ctx.expression.push_back(pkt6_field); + } ; option_code : INTEGER @@ -285,6 +294,10 @@ nest_level : INTEGER // an option or field. ; +pkt6_field:MSGTYPE { $$ = TokenPkt6::MSGTYPE; } + | TRANSID { $$ = TokenPkt6::TRANSID; } + ; + %% void isc::eval::EvalParser::error(const location_type& loc, diff --git a/src/lib/eval/tests/context_unittest.cc b/src/lib/eval/tests/context_unittest.cc index d086b3da46..eab31f9ac0 100644 --- a/src/lib/eval/tests/context_unittest.cc +++ b/src/lib/eval/tests/context_unittest.cc @@ -256,6 +256,21 @@ public: 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<TokenPkt6> pkt = + boost::dynamic_pointer_cast<TokenPkt6>(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) { @@ -280,6 +295,38 @@ public: 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); + } + Option::Universe universe_; bool parsed_; ///< Parsing status }; @@ -538,6 +585,16 @@ TEST_F(EvalContextTest, relay4Error) { "<string>:1.1-6: relay4 can only be used in DHCPv4."); } +// Tests whether message type field in DHCPv6 can be accessed. +TEST_F(EvalContextTest, pkt6FieldMsgtype) { + testPkt6Field("pkt6.msgtype == '1'", TokenPkt6::MSGTYPE, 3); +} + +// Tests whether transaction id field in DHCPv6 can be accessed. +TEST_F(EvalContextTest, pkt6FieldTransid) { + testPkt6Field("pkt6.transid == '1'", TokenPkt6::TRANSID, 3); +} + // Test parsing of logical operators TEST_F(EvalContextTest, logicalOps) { // option.exists diff --git a/src/lib/eval/tests/token_unittest.cc b/src/lib/eval/tests/token_unittest.cc index c9276bed4f..d81f078bb2 100644 --- a/src/lib/eval/tests/token_unittest.cc +++ b/src/lib/eval/tests/token_unittest.cc @@ -1203,3 +1203,29 @@ TEST_F(TokenTest, relay6Option) { // 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 --git a/src/lib/eval/token.cc b/src/lib/eval/token.cc index b3e52ba924..30b4dbc7a8 100644 --- a/src/lib/eval/token.cc +++ b/src/lib/eval/token.cc @@ -360,3 +360,46 @@ TokenRelay6Field::evaluate(const Pkt& pkt, ValueStack& values) { } values.push(value); } + +void +TokenPkt6::evaluate(const Pkt& pkt, ValueStack& values) { + + vector<uint8_t> 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<const Pkt6&>(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<int>(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 --git a/src/lib/eval/token.h b/src/lib/eval/token.h index e603192490..92591c7f20 100644 --- a/src/lib/eval/token.h +++ b/src/lib/eval/token.h @@ -580,6 +580,52 @@ protected: 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 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); + + /// @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 |