Parcourir la source

Merge branch 'trac4269' Merge 4269 after updates to fix conflicts

Shawn Routhier il y a 9 ans
Parent
commit
48be5f5cea

+ 7 - 2
ChangeLog

@@ -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
 1105.	[bug]		pallotron
 	perfdhcp uses the same transaction id throughout the DORA
 	perfdhcp uses the same transaction id throughout the DORA
 	exchange to adhere with RFC 2131.
 	exchange to adhere with RFC 2131.
@@ -5,7 +10,7 @@
 
 
 1104.	[func]		tmark
 1104.	[func]		tmark
 	The DDNS parameter, replace-client-name, has been changed from a boolean
 	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
 	servers replace or supply DNS names for clients.  This is supported both
 	kea-dhcp4 and kea-dhcp6.
 	kea-dhcp4 and kea-dhcp6.
 	(Trac #4529, git 45e56d7aa0d4a6224a1a28941f6cb11575391222)
 	(Trac #4529, git 45e56d7aa0d4a6224a1a28941f6cb11575391222)
@@ -19,7 +24,7 @@
 1102.	[func]		sar
 1102.	[func]		sar
 	Added access to the peer address, link address and option
 	Added access to the peer address, link address and option
 	information added by relays in a DHCPv6 message.
 	information added by relays in a DHCPv6 message.
-	(Trac $4269, git bb00d9d205ee047961ba70417d7ce02c37d80ce7)
+	(Trac $4265, git bb00d9d205ee047961ba70417d7ce02c37d80ce7)
 
 
 1101.	[bug]		stephen
 1101.	[bug]		stephen
 	Made DHCPSRV_MEMFILE_LFC_UNREGISTER_TIMER_FAILED a debug message as the
 	Made DHCPSRV_MEMFILE_LFC_UNREGISTER_TIMER_FAILED a debug message as the

+ 22 - 0
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>2001:DB8::1</entry> -->n
   <entry>The value of the link address field from the relay encapsulation "nest"</entry>
   <entry>The value of the link address field from the relay encapsulation "nest"</entry>
 </row>
 </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>
           </tbody>
           </tgroup>
           </tgroup>
         </table>
         </table>
@@ -248,6 +262,14 @@ sub-option with code "code" from the DHCPv4 Relay Agent Information option
       </para>
       </para>
 
 
       <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">
         <table frame="all" id="classification-expressions-list">
           <title>List of Classification Expressions</title>
           <title>List of Classification Expressions</title>
           <tgroup cols='3'>
           <tgroup cols='3'>

+ 158 - 132
src/lib/eval/lexer.cc

@@ -483,8 +483,8 @@ static void yy_fatal_error (yyconst char msg[]  );
 	(yy_c_buf_p) = yy_cp;
 	(yy_c_buf_p) = yy_cp;
 
 
 /* %% [4.0] data tables for the DFA and the user's section 1 definitions go here */
 /* %% [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,
 /* This struct is not used in this scanner,
    but its presence is necessary. */
    but its presence is necessary. */
 struct yy_trans_info
 struct yy_trans_info
@@ -492,43 +492,46 @@ struct yy_trans_info
 	flex_int32_t yy_verify;
 	flex_int32_t yy_verify;
 	flex_int32_t yy_nxt;
 	flex_int32_t yy_nxt;
 	};
 	};
-static yyconst flex_int16_t yy_acclist[162] =
+static yyconst flex_int16_t yy_acclist[183] =
     {   0,
     {   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,
     {   0,
         1,    1,    1,    2,    4,    7,    9,   11,   14,   17,
         1,    1,    1,    2,    4,    7,    9,   11,   14,   17,
        20,   22,   25,   28,   31,   33,   35,   38,   41,   44,
        20,   22,   25,   28,   31,   33,   35,   38,   41,   44,
        47,   50,   53,   56,   59,   62,   65,   68,   71,   74,
        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] =
 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,
        17,   17,   17,   17,   17,   17,   17,   18,   17,   17,
        19,    1,   20,    1,   21,    1,   22,   23,   24,   25,
        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,
         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
         1,    1,    1,    1,    1
     } ;
     } ;
 
 
-static yyconst YY_CHAR yy_meta[41] =
+static yyconst YY_CHAR yy_meta[42] =
     {   0,
     {   0,
         1,    1,    2,    1,    1,    1,    1,    1,    3,    4,
         1,    1,    2,    1,    1,    1,    1,    1,    3,    4,
         4,    4,    4,    5,    1,    4,    1,    1,    1,    1,
         4,    4,    4,    5,    1,    4,    1,    1,    1,    1,
         1,    4,    4,    4,    4,    4,    1,    1,    1,    1,
         1,    4,    4,    4,    4,    4,    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,    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,
     {   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,
        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,   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,
     {   0,
         4,    5,    6,    7,    8,    9,   10,   11,   12,   13,
         4,    5,    6,    7,    8,    9,   10,   11,   12,   13,
        14,   14,   14,   15,   16,   17,   18,   18,   19,   20,
        14,   14,   14,   15,   16,   17,   18,   18,   19,   20,
         4,   21,   17,   22,   17,   23,   18,   24,   18,   18,
         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,
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    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,   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. */
 /* 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,
 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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;
 extern int yy_flex_debug;
 int yy_flex_debug = 1;
 int yy_flex_debug = 1;
 
 
-static yyconst flex_int16_t yy_rule_linenum[30] =
+static yyconst flex_int16_t yy_rule_linenum[33] =
     {   0,
     {   0,
        82,   86,   92,  102,  108,  122,  129,  143,  144,  145,
        82,   86,   92,  102,  108,  122,  129,  143,  144,  145,
       146,  147,  148,  149,  150,  151,  152,  153,  154,  155,
       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;
 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
 // by moving it ahead by yyleng bytes. yyleng specifies the length of the
 // currently matched token.
 // currently matched token.
 #define YY_USER_ACTION  loc.columns(yyleng);
 #define YY_USER_ACTION  loc.columns(yyleng);
-#line 767 "lexer.cc"
+#line 778 "lexer.cc"
 
 
 #define INITIAL 0
 #define INITIAL 0
 
 
@@ -1060,7 +1071,7 @@ YY_DECL
     loc.step();
     loc.step();
 
 
 
 
-#line 1064 "lexer.cc"
+#line 1075 "lexer.cc"
 
 
 	while ( /*CONSTCOND*/1 )		/* loops until end-of-file is reached */
 	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 )
 			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 				{
 				{
 				yy_current_state = (int) yy_def[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_c = yy_meta[(unsigned int) yy_c];
 				}
 				}
 			yy_current_state = yy_nxt[yy_base[yy_current_state] + (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_state_ptr)++ = yy_current_state;
 			++yy_cp;
 			++yy_cp;
 			}
 			}
-		while ( yy_current_state != 112 );
+		while ( yy_current_state != 128 );
 
 
 yy_find_action:
 yy_find_action:
 /* %% [10.0] code to find the action number goes here */
 /* %% [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 )
 			if ( yy_act == 0 )
 				fprintf( stderr, "--scanner backing up\n" );
 				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",
 				fprintf( stderr, "--accepting rule at line %ld (\"%s\")\n",
 				         (long)yy_rule_linenum[yy_act], yytext );
 				         (long)yy_rule_linenum[yy_act], yytext );
-			else if ( yy_act == 30 )
+			else if ( yy_act == 33 )
 				fprintf( stderr, "--accepting default rule (\"%s\")\n",
 				fprintf( stderr, "--accepting default rule (\"%s\")\n",
 				         yytext );
 				         yytext );
-			else if ( yy_act == 31 )
+			else if ( yy_act == 34 )
 				fprintf( stderr, "--(end of buffer or a NUL)\n" );
 				fprintf( stderr, "--(end of buffer or a NUL)\n" );
 			else
 			else
 				fprintf( stderr, "--EOF (start condition %d)\n", YY_START );
 				fprintf( stderr, "--EOF (start condition %d)\n", YY_START );
@@ -1366,18 +1377,33 @@ return isc::eval::EvalParser::make_COMA(loc);
 case 29:
 case 29:
 YY_RULE_SETUP
 YY_RULE_SETUP
 #line 165 "lexer.ll"
 #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));
 driver.error (loc, "Invalid character: " + std::string(yytext));
 	YY_BREAK
 	YY_BREAK
 case YY_STATE_EOF(INITIAL):
 case YY_STATE_EOF(INITIAL):
-#line 166 "lexer.ll"
+#line 170 "lexer.ll"
 return isc::eval::EvalParser::make_END(loc);
 return isc::eval::EvalParser::make_END(loc);
 	YY_BREAK
 	YY_BREAK
-case 30:
+case 33:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 167 "lexer.ll"
+#line 171 "lexer.ll"
 ECHO;
 ECHO;
 	YY_BREAK
 	YY_BREAK
-#line 1381 "lexer.cc"
+#line 1407 "lexer.cc"
 
 
 	case YY_END_OF_BUFFER:
 	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 )
 		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 			{
 			{
 			yy_current_state = (int) yy_def[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_c = yy_meta[(unsigned int) yy_c];
 			}
 			}
 		yy_current_state = yy_nxt[yy_base[yy_current_state] + (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 )
 	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 		{
 		{
 		yy_current_state = (int) yy_def[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_c = yy_meta[(unsigned int) yy_c];
 		}
 		}
 	yy_current_state = yy_nxt[yy_base[yy_current_state] + (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 )
 	if ( ! yy_is_jam )
 		*(yy_state_ptr)++ = yy_current_state;
 		*(yy_state_ptr)++ = yy_current_state;
 
 
@@ -2460,7 +2486,7 @@ void yyfree (void * ptr )
 
 
 /* %ok-for-header */
 /* %ok-for-header */
 
 
-#line 167 "lexer.ll"
+#line 171 "lexer.ll"
 
 
 
 
 
 

+ 4 - 0
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_RBRACKET(loc);
 ","         return isc::eval::EvalParser::make_COMA(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));
 .          driver.error (loc, "Invalid character: " + std::string(yytext));
 <<EOF>>    return isc::eval::EvalParser::make_END(loc);
 <<EOF>>    return isc::eval::EvalParser::make_END(loc);
 %%
 %%

+ 231 - 181
src/lib/eval/parser.cc

@@ -251,27 +251,31 @@ namespace isc { namespace eval {
   {
   {
       switch (that.type_get ())
       switch (that.type_get ())
     {
     {
-      case 34: // option_repr_type
+      case 37: // option_repr_type
         value.move< TokenOption::RepresentationType > (that.value);
         value.move< TokenOption::RepresentationType > (that.value);
         break;
         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);
         value.move< TokenRelay6Field::FieldType > (that.value);
         break;
         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);
         value.move< std::string > (that.value);
         break;
         break;
 
 
-      case 33: // option_code
+      case 36: // option_code
         value.move< uint16_t > (that.value);
         value.move< uint16_t > (that.value);
         break;
         break;
 
 
-      case 38: // nest_level
+      case 41: // nest_level
         value.move< uint8_t > (that.value);
         value.move< uint8_t > (that.value);
         break;
         break;
 
 
@@ -290,27 +294,31 @@ namespace isc { namespace eval {
     state = that.state;
     state = that.state;
       switch (that.type_get ())
       switch (that.type_get ())
     {
     {
-      case 34: // option_repr_type
+      case 37: // option_repr_type
         value.copy< TokenOption::RepresentationType > (that.value);
         value.copy< TokenOption::RepresentationType > (that.value);
         break;
         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);
         value.copy< TokenRelay6Field::FieldType > (that.value);
         break;
         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);
         value.copy< std::string > (that.value);
         break;
         break;
 
 
-      case 33: // option_code
+      case 36: // option_code
         value.copy< uint16_t > (that.value);
         value.copy< uint16_t > (that.value);
         break;
         break;
 
 
-      case 38: // nest_level
+      case 41: // nest_level
         value.copy< uint8_t > (that.value);
         value.copy< uint8_t > (that.value);
         break;
         break;
 
 
@@ -350,67 +358,74 @@ namespace isc { namespace eval {
         << yysym.location << ": ";
         << yysym.location << ": ";
     switch (yytype)
     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 > (); }
         { yyoutput << yysym.value.template as< std::string > (); }
-#line 358 "parser.cc" // lalr1.cc:636
+#line 366 "parser.cc" // lalr1.cc:636
         break;
         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 > (); }
         { yyoutput << yysym.value.template as< std::string > (); }
-#line 365 "parser.cc" // lalr1.cc:636
+#line 373 "parser.cc" // lalr1.cc:636
         break;
         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 > (); }
         { yyoutput << yysym.value.template as< std::string > (); }
-#line 372 "parser.cc" // lalr1.cc:636
+#line 380 "parser.cc" // lalr1.cc:636
         break;
         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 > (); }
         { yyoutput << yysym.value.template as< std::string > (); }
-#line 379 "parser.cc" // lalr1.cc:636
+#line 387 "parser.cc" // lalr1.cc:636
         break;
         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 > (); }
         { yyoutput << yysym.value.template as< std::string > (); }
-#line 386 "parser.cc" // lalr1.cc:636
+#line 394 "parser.cc" // lalr1.cc:636
         break;
         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 > (); }
         { yyoutput << yysym.value.template as< uint16_t > (); }
-#line 393 "parser.cc" // lalr1.cc:636
+#line 401 "parser.cc" // lalr1.cc:636
         break;
         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 > (); }
         { yyoutput << yysym.value.template as< TokenOption::RepresentationType > (); }
-#line 400 "parser.cc" // lalr1.cc:636
+#line 408 "parser.cc" // lalr1.cc:636
         break;
         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 > (); }
         { yyoutput << yysym.value.template as< TokenRelay6Field::FieldType > (); }
-#line 407 "parser.cc" // lalr1.cc:636
+#line 415 "parser.cc" // lalr1.cc:636
         break;
         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 > (); }
         { 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;
         break;
 
 
 
 
@@ -610,27 +625,31 @@ namespace isc { namespace eval {
          when using variants.  */
          when using variants.  */
         switch (yyr1_[yyn])
         switch (yyr1_[yyn])
     {
     {
-      case 34: // option_repr_type
+      case 37: // option_repr_type
         yylhs.value.build< TokenOption::RepresentationType > ();
         yylhs.value.build< TokenOption::RepresentationType > ();
         break;
         break;
 
 
-      case 37: // relay6_field
+      case 42: // pkt6_field
+        yylhs.value.build< TokenPkt6::FieldType > ();
+        break;
+
+      case 40: // relay6_field
         yylhs.value.build< TokenRelay6Field::FieldType > ();
         yylhs.value.build< TokenRelay6Field::FieldType > ();
         break;
         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 > ();
         yylhs.value.build< std::string > ();
         break;
         break;
 
 
-      case 33: // option_code
+      case 36: // option_code
         yylhs.value.build< uint16_t > ();
         yylhs.value.build< uint16_t > ();
         break;
         break;
 
 
-      case 38: // nest_level
+      case 41: // nest_level
         yylhs.value.build< uint8_t > ();
         yylhs.value.build< uint8_t > ();
         break;
         break;
 
 
@@ -652,52 +671,52 @@ namespace isc { namespace eval {
           switch (yyn)
           switch (yyn)
             {
             {
   case 4:
   case 4:
-#line 92 "parser.yy" // lalr1.cc:859
+#line 96 "parser.yy" // lalr1.cc:859
     {
     {
                     TokenPtr neg(new TokenNot());
                     TokenPtr neg(new TokenNot());
                     ctx.expression.push_back(neg);
                     ctx.expression.push_back(neg);
                 }
                 }
-#line 661 "parser.cc" // lalr1.cc:859
+#line 680 "parser.cc" // lalr1.cc:859
     break;
     break;
 
 
   case 5:
   case 5:
-#line 97 "parser.yy" // lalr1.cc:859
+#line 101 "parser.yy" // lalr1.cc:859
     {
     {
                     TokenPtr neg(new TokenAnd());
                     TokenPtr neg(new TokenAnd());
                     ctx.expression.push_back(neg);
                     ctx.expression.push_back(neg);
                 }
                 }
-#line 670 "parser.cc" // lalr1.cc:859
+#line 689 "parser.cc" // lalr1.cc:859
     break;
     break;
 
 
   case 6:
   case 6:
-#line 102 "parser.yy" // lalr1.cc:859
+#line 106 "parser.yy" // lalr1.cc:859
     {
     {
                     TokenPtr neg(new TokenOr());
                     TokenPtr neg(new TokenOr());
                     ctx.expression.push_back(neg);
                     ctx.expression.push_back(neg);
                 }
                 }
-#line 679 "parser.cc" // lalr1.cc:859
+#line 698 "parser.cc" // lalr1.cc:859
     break;
     break;
 
 
   case 7:
   case 7:
-#line 107 "parser.yy" // lalr1.cc:859
+#line 111 "parser.yy" // lalr1.cc:859
     {
     {
                     TokenPtr eq(new TokenEqual());
                     TokenPtr eq(new TokenEqual());
                     ctx.expression.push_back(eq);
                     ctx.expression.push_back(eq);
                 }
                 }
-#line 688 "parser.cc" // lalr1.cc:859
+#line 707 "parser.cc" // lalr1.cc:859
     break;
     break;
 
 
   case 8:
   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));
                     TokenPtr opt(new TokenOption(yystack_[3].value.as< uint16_t > (), TokenOption::EXISTS));
                     ctx.expression.push_back(opt);
                     ctx.expression.push_back(opt);
                 }
                 }
-#line 697 "parser.cc" // lalr1.cc:859
+#line 716 "parser.cc" // lalr1.cc:859
     break;
     break;
 
 
   case 9:
   case 9:
-#line 117 "parser.yy" // lalr1.cc:859
+#line 121 "parser.yy" // lalr1.cc:859
     {
     {
                    switch (ctx.getUniverse()) {
                    switch (ctx.getUniverse()) {
                    case Option::V4:
                    case Option::V4:
@@ -717,11 +736,11 @@ namespace isc { namespace eval {
                        error(yystack_[5].location, "relay4 can only be used in DHCPv4.");
                        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;
     break;
 
 
   case 10:
   case 10:
-#line 137 "parser.yy" // lalr1.cc:859
+#line 141 "parser.yy" // lalr1.cc:859
     {
     {
                     switch (ctx.getUniverse()) {
                     switch (ctx.getUniverse()) {
                     case Option::V6:
                     case Option::V6:
@@ -735,47 +754,47 @@ namespace isc { namespace eval {
                         error(yystack_[10].location, "relay6 can only be used 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;
     break;
 
 
   case 11:
   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 > ()));
                       TokenPtr str(new TokenString(yystack_[0].value.as< std::string > ()));
                       ctx.expression.push_back(str);
                       ctx.expression.push_back(str);
                   }
                   }
-#line 748 "parser.cc" // lalr1.cc:859
+#line 767 "parser.cc" // lalr1.cc:859
     break;
     break;
 
 
   case 12:
   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 > ()));
                       TokenPtr hex(new TokenHexString(yystack_[0].value.as< std::string > ()));
                       ctx.expression.push_back(hex);
                       ctx.expression.push_back(hex);
                   }
                   }
-#line 757 "parser.cc" // lalr1.cc:859
+#line 776 "parser.cc" // lalr1.cc:859
     break;
     break;
 
 
   case 13:
   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 > ()));
                       TokenPtr ip(new TokenIpAddress(yystack_[0].value.as< std::string > ()));
                       ctx.expression.push_back(ip);
                       ctx.expression.push_back(ip);
                   }
                   }
-#line 766 "parser.cc" // lalr1.cc:859
+#line 785 "parser.cc" // lalr1.cc:859
     break;
     break;
 
 
   case 14:
   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 > ()));
                       TokenPtr opt(new TokenOption(yystack_[3].value.as< uint16_t > (), yystack_[0].value.as< TokenOption::RepresentationType > ()));
                       ctx.expression.push_back(opt);
                       ctx.expression.push_back(opt);
                   }
                   }
-#line 775 "parser.cc" // lalr1.cc:859
+#line 794 "parser.cc" // lalr1.cc:859
     break;
     break;
 
 
   case 15:
   case 15:
-#line 173 "parser.yy" // lalr1.cc:859
+#line 177 "parser.yy" // lalr1.cc:859
     {
     {
                      switch (ctx.getUniverse()) {
                      switch (ctx.getUniverse()) {
                      case Option::V4:
                      case Option::V4:
@@ -795,11 +814,11 @@ namespace isc { namespace eval {
                          error(yystack_[5].location, "relay4 can only be used in DHCPv4.");
                          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;
     break;
 
 
   case 16:
   case 16:
-#line 194 "parser.yy" // lalr1.cc:859
+#line 198 "parser.yy" // lalr1.cc:859
     {
     {
                      switch (ctx.getUniverse()) {
                      switch (ctx.getUniverse()) {
                      case Option::V6:
                      case Option::V6:
@@ -813,11 +832,11 @@ namespace isc { namespace eval {
                          error(yystack_[10].location, "relay6 can only be used 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;
     break;
 
 
   case 17:
   case 17:
-#line 209 "parser.yy" // lalr1.cc:859
+#line 213 "parser.yy" // lalr1.cc:859
     {
     {
                      switch (ctx.getUniverse()) {
                      switch (ctx.getUniverse()) {
                      case Option::V6:
                      case Option::V6:
@@ -831,108 +850,129 @@ namespace isc { namespace eval {
                          error(yystack_[5].location, "relay6 can only be used 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;
     break;
 
 
   case 18:
   case 18:
-#line 225 "parser.yy" // lalr1.cc:859
+#line 229 "parser.yy" // lalr1.cc:859
     {
     {
                       TokenPtr sub(new TokenSubstring());
                       TokenPtr sub(new TokenSubstring());
                       ctx.expression.push_back(sub);
                       ctx.expression.push_back(sub);
                   }
                   }
-#line 844 "parser.cc" // lalr1.cc:859
+#line 863 "parser.cc" // lalr1.cc:859
     break;
     break;
 
 
   case 19:
   case 19:
-#line 230 "parser.yy" // lalr1.cc:859
+#line 234 "parser.yy" // lalr1.cc:859
     {
     {
                       TokenPtr conc(new TokenConcat());
                       TokenPtr conc(new TokenConcat());
                       ctx.expression.push_back(conc);
                       ctx.expression.push_back(conc);
                   }
                   }
-#line 853 "parser.cc" // lalr1.cc:859
+#line 872 "parser.cc" // lalr1.cc:859
     break;
     break;
 
 
   case 20:
   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);
                      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;
     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);
                      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;
     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;
                           yylhs.value.as< TokenOption::RepresentationType > () = TokenOption::TEXTUAL;
                       }
                       }
-#line 877 "parser.cc" // lalr1.cc:859
+#line 905 "parser.cc" // lalr1.cc:859
     break;
     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;
                           yylhs.value.as< TokenOption::RepresentationType > () = TokenOption::HEXADECIMAL;
                       }
                       }
-#line 885 "parser.cc" // lalr1.cc:859
+#line 913 "parser.cc" // lalr1.cc:859
     break;
     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 > ()));
                      TokenPtr str(new TokenString(yystack_[0].value.as< std::string > ()));
                      ctx.expression.push_back(str);
                      ctx.expression.push_back(str);
                  }
                  }
-#line 894 "parser.cc" // lalr1.cc:859
+#line 922 "parser.cc" // lalr1.cc:859
     break;
     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 > ()));
                       TokenPtr str(new TokenString(yystack_[0].value.as< std::string > ()));
                       ctx.expression.push_back(str);
                       ctx.expression.push_back(str);
                   }
                   }
-#line 903 "parser.cc" // lalr1.cc:859
+#line 931 "parser.cc" // lalr1.cc:859
     break;
     break;
 
 
-  case 26:
-#line 269 "parser.yy" // lalr1.cc:859
+  case 27:
+#line 278 "parser.yy" // lalr1.cc:859
     {
     {
                      TokenPtr str(new TokenString("all"));
                      TokenPtr str(new TokenString("all"));
                      ctx.expression.push_back(str);
                      ctx.expression.push_back(str);
                  }
                  }
-#line 912 "parser.cc" // lalr1.cc:859
+#line 940 "parser.cc" // lalr1.cc:859
     break;
     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; }
     { yylhs.value.as< TokenRelay6Field::FieldType > () = TokenRelay6Field::PEERADDR; }
-#line 918 "parser.cc" // lalr1.cc:859
+#line 946 "parser.cc" // lalr1.cc:859
     break;
     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; }
     { yylhs.value.as< TokenRelay6Field::FieldType > () = TokenRelay6Field::LINKADDR; }
-#line 924 "parser.cc" // lalr1.cc:859
+#line 952 "parser.cc" // lalr1.cc:859
     break;
     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);
 		 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;
     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:
             default:
               break;
               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::yytable_ninf_ = -1;
 
 
   const signed char
   const signed char
   EvalParser::yypact_[] =
   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
   const unsigned char
   EvalParser::yydefact_[] =
   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
   const signed char
   EvalParser::yypgoto_[] =
   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
   const signed char
   EvalParser::yydefgoto_[] =
   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
   const unsigned char
   EvalParser::yytable_[] =
   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_[] =
   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
   const unsigned char
   EvalParser::yystos_[] =
   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
   const unsigned char
   EvalParser::yyr1_[] =
   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
   const unsigned char
@@ -1288,7 +1336,8 @@ namespace isc { namespace eval {
   {
   {
        0,     2,     1,     3,     2,     3,     3,     3,     6,     6,
        0,     2,     1,     3,     2,     3,     3,     3,     6,     6,
       11,     1,     1,     1,     6,     6,    11,     6,     8,     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\"",
   "\"and\"", "\"or\"", "\"==\"", "\"option\"", "\"relay4\"", "\"relay6\"",
   "\"peeraddr\"", "\"linkaddr\"", "\"[\"", "\"]\"", "\".\"", "\"text\"",
   "\"peeraddr\"", "\"linkaddr\"", "\"[\"", "\"]\"", "\".\"", "\"text\"",
   "\"hex\"", "\"exists\"", "\"substring\"", "\"all\"", "\",\"",
   "\"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
 #if YYDEBUG
   const unsigned short int
   const unsigned short int
   EvalParser::yyrline_[] =
   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.
   // Print the state stack on the debug stream.
@@ -1350,8 +1400,8 @@ namespace isc { namespace eval {
 
 
 #line 13 "parser.yy" // lalr1.cc:1167
 #line 13 "parser.yy" // lalr1.cc:1167
 } } // isc::eval
 } } // 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
 void
 isc::eval::EvalParser::error(const location_type& loc,
 isc::eval::EvalParser::error(const location_type& loc,

+ 116 - 54
src/lib/eval/parser.h

@@ -298,21 +298,24 @@ namespace isc { namespace eval {
       // option_repr_type
       // option_repr_type
       char dummy1[sizeof(TokenOption::RepresentationType)];
       char dummy1[sizeof(TokenOption::RepresentationType)];
 
 
+      // pkt6_field
+      char dummy2[sizeof(TokenPkt6::FieldType)];
+
       // relay6_field
       // relay6_field
-      char dummy2[sizeof(TokenRelay6Field::FieldType)];
+      char dummy3[sizeof(TokenRelay6Field::FieldType)];
 
 
       // "constant string"
       // "constant string"
       // "integer"
       // "integer"
       // "constant hexstring"
       // "constant hexstring"
       // "option name"
       // "option name"
       // "ip address"
       // "ip address"
-      char dummy3[sizeof(std::string)];
+      char dummy4[sizeof(std::string)];
 
 
       // option_code
       // option_code
-      char dummy4[sizeof(uint16_t)];
+      char dummy5[sizeof(uint16_t)];
 
 
       // nest_level
       // nest_level
-      char dummy5[sizeof(uint8_t)];
+      char dummy6[sizeof(uint8_t)];
 };
 };
 
 
     /// Symbol semantic values.
     /// Symbol semantic values.
@@ -357,11 +360,14 @@ namespace isc { namespace eval {
         TOKEN_ALL = 276,
         TOKEN_ALL = 276,
         TOKEN_COMA = 277,
         TOKEN_COMA = 277,
         TOKEN_CONCAT = 278,
         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 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 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 std::string v, const location_type& l);
@@ -566,6 +574,18 @@ namespace isc { namespace eval {
 
 
     static inline
     static inline
     symbol_type
     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);
     make_STRING (const std::string& v, const location_type& l);
 
 
     static inline
     static inline
@@ -669,7 +689,7 @@ namespace isc { namespace eval {
   // number is the opposite.  If YYTABLE_NINF, syntax error.
   // number is the opposite.  If YYTABLE_NINF, syntax error.
   static const unsigned char yytable_[];
   static const unsigned char yytable_[];
 
 
-  static const signed char yycheck_[];
+  static const unsigned char yycheck_[];
 
 
   // YYSTOS[STATE-NUM] -- The (internal number of the) accessing
   // YYSTOS[STATE-NUM] -- The (internal number of the) accessing
   // symbol of state STATE-NUM.
   // symbol of state STATE-NUM.
@@ -789,12 +809,12 @@ namespace isc { namespace eval {
     enum
     enum
     {
     {
       yyeof_ = 0,
       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,
       yyterror_ = 1,
       yyerrcode_ = 256,
       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,
        2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
        5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
        5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
       15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
       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;
     const token_number_type undef_token_ = 2;
 
 
     if (static_cast<int>(t) <= yyeof_)
     if (static_cast<int>(t) <= yyeof_)
@@ -874,27 +894,31 @@ namespace isc { namespace eval {
   {
   {
       switch (other.type_get ())
       switch (other.type_get ())
     {
     {
-      case 34: // option_repr_type
+      case 37: // option_repr_type
         value.copy< TokenOption::RepresentationType > (other.value);
         value.copy< TokenOption::RepresentationType > (other.value);
         break;
         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);
         value.copy< TokenRelay6Field::FieldType > (other.value);
         break;
         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);
         value.copy< std::string > (other.value);
         break;
         break;
 
 
-      case 33: // option_code
+      case 36: // option_code
         value.copy< uint16_t > (other.value);
         value.copy< uint16_t > (other.value);
         break;
         break;
 
 
-      case 38: // nest_level
+      case 41: // nest_level
         value.copy< uint8_t > (other.value);
         value.copy< uint8_t > (other.value);
         break;
         break;
 
 
@@ -915,27 +939,31 @@ namespace isc { namespace eval {
     (void) v;
     (void) v;
       switch (this->type_get ())
       switch (this->type_get ())
     {
     {
-      case 34: // option_repr_type
+      case 37: // option_repr_type
         value.copy< TokenOption::RepresentationType > (v);
         value.copy< TokenOption::RepresentationType > (v);
         break;
         break;
 
 
-      case 37: // relay6_field
+      case 42: // pkt6_field
+        value.copy< TokenPkt6::FieldType > (v);
+        break;
+
+      case 40: // relay6_field
         value.copy< TokenRelay6Field::FieldType > (v);
         value.copy< TokenRelay6Field::FieldType > (v);
         break;
         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);
         value.copy< std::string > (v);
         break;
         break;
 
 
-      case 33: // option_code
+      case 36: // option_code
         value.copy< uint16_t > (v);
         value.copy< uint16_t > (v);
         break;
         break;
 
 
-      case 38: // nest_level
+      case 41: // nest_level
         value.copy< uint8_t > (v);
         value.copy< uint8_t > (v);
         break;
         break;
 
 
@@ -962,6 +990,13 @@ namespace isc { namespace eval {
   {}
   {}
 
 
   template <typename Base>
   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)
   EvalParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const TokenRelay6Field::FieldType v, const location_type& l)
     : Base (t)
     : Base (t)
     , value (v)
     , value (v)
@@ -1015,27 +1050,31 @@ namespace isc { namespace eval {
     // Type destructor.
     // Type destructor.
     switch (yytype)
     switch (yytype)
     {
     {
-      case 34: // option_repr_type
+      case 37: // option_repr_type
         value.template destroy< TokenOption::RepresentationType > ();
         value.template destroy< TokenOption::RepresentationType > ();
         break;
         break;
 
 
-      case 37: // relay6_field
+      case 42: // pkt6_field
+        value.template destroy< TokenPkt6::FieldType > ();
+        break;
+
+      case 40: // relay6_field
         value.template destroy< TokenRelay6Field::FieldType > ();
         value.template destroy< TokenRelay6Field::FieldType > ();
         break;
         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 > ();
         value.template destroy< std::string > ();
         break;
         break;
 
 
-      case 33: // option_code
+      case 36: // option_code
         value.template destroy< uint16_t > ();
         value.template destroy< uint16_t > ();
         break;
         break;
 
 
-      case 38: // nest_level
+      case 41: // nest_level
         value.template destroy< uint8_t > ();
         value.template destroy< uint8_t > ();
         break;
         break;
 
 
@@ -1062,27 +1101,31 @@ namespace isc { namespace eval {
     super_type::move(s);
     super_type::move(s);
       switch (this->type_get ())
       switch (this->type_get ())
     {
     {
-      case 34: // option_repr_type
+      case 37: // option_repr_type
         value.move< TokenOption::RepresentationType > (s.value);
         value.move< TokenOption::RepresentationType > (s.value);
         break;
         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);
         value.move< TokenRelay6Field::FieldType > (s.value);
         break;
         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);
         value.move< std::string > (s.value);
         break;
         break;
 
 
-      case 33: // option_code
+      case 36: // option_code
         value.move< uint16_t > (s.value);
         value.move< uint16_t > (s.value);
         break;
         break;
 
 
-      case 38: // nest_level
+      case 41: // nest_level
         value.move< uint8_t > (s.value);
         value.move< uint8_t > (s.value);
         break;
         break;
 
 
@@ -1143,7 +1186,8 @@ namespace isc { namespace eval {
     {
     {
        0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
        0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
      265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
      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]);
     return static_cast<token_type> (yytoken_number_[type]);
   }
   }
@@ -1281,6 +1325,24 @@ namespace isc { namespace eval {
   }
   }
 
 
   EvalParser::symbol_type
   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)
   EvalParser::make_STRING (const std::string& v, const location_type& l)
   {
   {
     return symbol_type (token::TOKEN_STRING, v, l);
     return symbol_type (token::TOKEN_STRING, v, l);
@@ -1313,7 +1375,7 @@ namespace isc { namespace eval {
 
 
 #line 13 "parser.yy" // lalr1.cc:377
 #line 13 "parser.yy" // lalr1.cc:377
 } } // isc::eval
 } } // isc::eval
-#line 1317 "parser.h" // lalr1.cc:377
+#line 1379 "parser.h" // lalr1.cc:377
 
 
 
 
 
 

+ 13 - 0
src/lib/eval/parser.yy

@@ -58,6 +58,9 @@ using namespace isc::eval;
   ALL "all"
   ALL "all"
   COMA ","
   COMA ","
   CONCAT "concat"
   CONCAT "concat"
+  PKT6 "pkt6"
+  MSGTYPE "msgtype"
+  TRANSID "transid"
 ;
 ;
 
 
 %token <std::string> STRING "constant string"
 %token <std::string> STRING "constant string"
@@ -70,6 +73,7 @@ using namespace isc::eval;
 %type <TokenOption::RepresentationType> option_repr_type
 %type <TokenOption::RepresentationType> option_repr_type
 %type <TokenRelay6Field::FieldType> relay6_field
 %type <TokenRelay6Field::FieldType> relay6_field
 %type <uint8_t> nest_level
 %type <uint8_t> nest_level
+%type <TokenPkt6::FieldType> pkt6_field
 
 
 %left OR
 %left OR
 %left AND
 %left AND
@@ -231,6 +235,11 @@ string_expr : STRING
                       TokenPtr conc(new TokenConcat());
                       TokenPtr conc(new TokenConcat());
                       ctx.expression.push_back(conc);
                       ctx.expression.push_back(conc);
                   }
                   }
+            | PKT6 "." pkt6_field
+                  {
+                      TokenPtr pkt6_field(new TokenPkt6($3));
+                      ctx.expression.push_back(pkt6_field);
+                  }
             ;
             ;
 
 
 option_code : INTEGER
 option_code : INTEGER
@@ -285,6 +294,10 @@ nest_level : INTEGER
                  // an option or field.
                  // an option or field.
            ;
            ;
 
 
+pkt6_field:MSGTYPE { $$ = TokenPkt6::MSGTYPE; }
+          | TRANSID { $$ = TokenPkt6::TRANSID; }
+          ;
+
 %%
 %%
 void
 void
 isc::eval::EvalParser::error(const location_type& loc,
 isc::eval::EvalParser::error(const location_type& loc,

+ 57 - 0
src/lib/eval/tests/context_unittest.cc

@@ -256,6 +256,21 @@ public:
         checkTokenRelay6Field(eval.expression.at(0), exp_level, exp_type);
         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
     /// @brief checks if the given expression raises the expected message
     /// when it is parsed.
     /// when it is parsed.
     void checkError(const string& expr, const string& msg) {
     void checkError(const string& expr, const string& msg) {
@@ -280,6 +295,38 @@ public:
         universe_ = universe;
         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_;
     Option::Universe universe_;
     bool parsed_; ///< Parsing status
     bool parsed_; ///< Parsing status
 };
 };
@@ -538,6 +585,16 @@ TEST_F(EvalContextTest, relay4Error) {
                "<string>:1.1-6: relay4 can only be used in DHCPv4.");
                "<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 parsing of logical operators
 TEST_F(EvalContextTest, logicalOps) {
 TEST_F(EvalContextTest, logicalOps) {
     // option.exists
     // option.exists

+ 26 - 0
src/lib/eval/tests/token_unittest.cc

@@ -1203,3 +1203,29 @@ TEST_F(TokenTest, relay6Option) {
     // Level 2, no encapsulation so no options
     // Level 2, no encapsulation so no options
     verifyRelay6Option(2, 100, TokenOption::TEXTUAL, "");
     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);
+}

+ 43 - 0
src/lib/eval/token.cc

@@ -360,3 +360,46 @@ TokenRelay6Field::evaluate(const Pkt& pkt, ValueStack& values) {
     }
     }
     values.push(value);
     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);
+}

+ 46 - 0
src/lib/eval/token.h

@@ -580,6 +580,52 @@ protected:
     FieldType type_; ///< field to get
     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::dhcp namespace
 }; // end of isc namespace
 }; // end of isc namespace