Browse Source

[trac4269] Add code for handling constant length fields in DHCPv6 messages

Shawn Routhier 9 years ago
parent
commit
ca6962112f
7 changed files with 547 additions and 307 deletions
  1. 171 129
      src/lib/eval/lexer.cc
  2. 4 0
      src/lib/eval/lexer.ll
  3. 181 140
      src/lib/eval/parser.cc
  4. 100 38
      src/lib/eval/parser.h
  5. 13 0
      src/lib/eval/parser.yy
  6. 34 0
      src/lib/eval/token.cc
  7. 44 0
      src/lib/eval/token.h

+ 171 - 129
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 26
-#define YY_END_OF_BUFFER 27
+#define YY_NUM_RULES 29
+#define YY_END_OF_BUFFER 30
 /* This struct is not used in this scanner,
    but its presence is necessary. */
 struct yy_trans_info
@@ -492,35 +492,40 @@ struct yy_trans_info
 	flex_int32_t yy_verify;
 	flex_int32_t yy_nxt;
 	};
-static yyconst flex_int16_t yy_acclist[128] =
+static yyconst flex_int16_t yy_acclist[152] =
     {   0,
-       27,   25,   26,    1,   25,   26,    2,   26,   25,   26,
-       20,   25,   26,   21,   25,   26,   24,   25,   26,   25,
-       26,   19,   25,   26,    5,   25,   26,    5,   25,   26,
-       25,   26,   25,   26,16390,   22,   25,   26,   23,   25,
-       26,   25,   26,16390,   25,   26,16390,   25,   26,16390,
-       25,   26,16390,   25,   26,16390,   25,   26,16390,   25,
-       26,16390,   25,   26,16390,   25,   26,16390,    1,    2,
-        3,    5,    7,16390, 8198,16390,16390,16390,16390,16390,
-    16390,16390,   18,16390,16390,16390,16390,    4,   14,16390,
-       17,16390,16390,16390,   11,16390,   16,16390,16390,16390,
-
-    16390,16390,16390,16390,16390,16390,16390,   10,16390,16390,
-    16390,16390,16390,16390,   15,16390,   12,16390,    8,16390,
-        9,16390,16390,16390,16390,   13,16390
+       30,   28,   29,    1,   28,   29,    2,   29,   28,   29,
+       20,   28,   29,   21,   28,   29,   24,   28,   29,   28,
+       29,   19,   28,   29,    5,   28,   29,    5,   28,   29,
+       28,   29,   28,   29,16390,   22,   28,   29,   23,   28,
+       29,   28,   29,16390,   28,   29,16390,   28,   29,16390,
+       28,   29,16390,   28,   29,16390,   28,   29,16390,   28,
+       29,16390,   28,   29,16390,   28,   29,16390,   28,   29,
+    16390,   28,   29,16390,    1,    2,    3,    5,    7,16390,
+     8198,16390,16390,16390,16390,16390,16390,16390,16390,   18,
+    16390,16390,16390,16390,16390,16390,    4,   14,16390,   17,
+
+    16390,16390,16390,   11,16390,16390,   16,16390,16390,16390,
+    16390,16390,16390,16390,16390,16390,16390,16390,   25,16390,
+    16390,16390,   10,16390,16390,16390,16390,16390,16390,16390,
+    16390,16390,   15,16390,   12,16390,16390,    8,16390,    9,
+    16390,16390,16390,   26,16390,16390,   27,16390,16390,   13,
+    16390
     } ;
 
-static yyconst flex_int16_t yy_accept[82] =
+static yyconst flex_int16_t yy_accept[99] =
     {   0,
         1,    1,    1,    2,    4,    7,    9,   11,   14,   17,
        20,   22,   25,   28,   31,   33,   36,   39,   42,   45,
-       48,   51,   54,   57,   60,   63,   66,   69,   70,   71,
-       71,   72,   73,   73,   74,   74,   74,   75,   76,   77,
-       78,   79,   80,   81,   82,   83,   85,   86,   87,   88,
-       89,   91,   93,   94,   95,   97,   99,  100,  101,  102,
-      103,  104,  105,  106,  107,  108,  110,  111,  112,  113,
-      114,  115,  117,  119,  121,  123,  124,  125,  126,  128,
-      128
+       48,   51,   54,   57,   60,   63,   66,   69,   72,   75,
+       76,   77,   77,   78,   79,   79,   80,   80,   80,   81,
+       82,   83,   84,   85,   86,   87,   88,   89,   90,   92,
+       93,   94,   95,   96,   97,   98,  100,  102,  103,  104,
+      106,  107,  109,  110,  111,  112,  113,  114,  115,  116,
+      117,  118,  119,  121,  122,  123,  125,  126,  127,  128,
+      129,  130,  131,  132,  133,  135,  137,  138,  140,  142,
+      143,  144,  146,  147,  149,  150,  152,  152
+
     } ;
 
 static yyconst YY_CHAR yy_ec[256] =
@@ -530,15 +535,15 @@ static yyconst YY_CHAR yy_ec[256] =
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    2,    1,    1,    1,    1,    1,    1,    4,    5,
         6,    1,    1,    7,    8,    9,    1,   10,   11,   11,
-       11,   12,   11,   11,   11,   11,   11,    1,    1,    1,
-       13,    1,    1,    1,   14,   14,   14,   14,   14,   14,
-       15,   15,   15,   15,   15,   15,   15,   15,   15,   15,
-       15,   15,   15,   15,   15,   15,   15,   16,   15,   15,
-       17,    1,   18,    1,   19,    1,   20,   21,   22,   23,
-
-       24,   14,   25,   26,   27,   15,   15,   28,   15,   29,
-       30,   31,   15,   32,   33,   34,   35,   15,   15,   36,
-       37,   15,    1,    1,    1,    1,    1,    1,    1,    1,
+       11,   12,   11,   13,   11,   11,   11,    1,    1,    1,
+       14,    1,    1,    1,   15,   15,   15,   15,   15,   15,
+       16,   16,   16,   16,   16,   16,   16,   16,   16,   16,
+       16,   16,   16,   16,   16,   16,   16,   17,   16,   16,
+       18,    1,   19,    1,   20,    1,   21,   22,   23,   24,
+
+       25,   15,   26,   27,   28,   16,   29,   30,   31,   32,
+       33,   34,   16,   35,   36,   37,   38,   16,   16,   39,
+       40,   16,    1,    1,    1,    1,    1,    1,    1,    1,
         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,
@@ -555,118 +560,140 @@ static yyconst YY_CHAR yy_ec[256] =
         1,    1,    1,    1,    1
     } ;
 
-static yyconst YY_CHAR yy_meta[38] =
+static yyconst YY_CHAR yy_meta[41] =
     {   0,
         1,    2,    3,    1,    1,    1,    1,    2,    1,    4,
-        4,    4,    1,    4,    2,    2,    1,    2,    2,    4,
-        4,    4,    4,    4,    2,    2,    2,    2,    2,    2,
-        2,    2,    2,    2,    2,    2,    2
+        4,    4,    4,    1,    5,    2,    6,    1,    2,    2,
+        5,    5,    5,    5,    5,    2,    2,    2,    2,    2,
+        2,    2,    2,    2,    2,    2,    2,    2,    6,    2
     } ;
 
-static yyconst flex_uint16_t yy_base[84] =
+static yyconst flex_uint16_t yy_base[102] =
     {   0,
-        0,    0,  202,  219,  167,  155,  138,  219,  219,  219,
-       28,  219,   31,   34,   94,   46,  219,  219,   66,   22,
-       27,   29,   31,   44,   42,   51,   53,  103,   80,   74,
-      219,   77,    0,  219,   88,   90,   68,  219,   70,   81,
-       72,   84,   86,   92,   95,   74,   88,  104,   99,    0,
-      102,  108,  112,  110,  116,  118,  121,  131,  124,  127,
-      134,  136,  138,  143,  145,  147,  149,  153,  156,  175,
-      160,  162,  165,  167,  169,  172,  177,  182,  180,  219,
-      211,  214,   58
+        0,    0,  122,  289,  103,   82,   70,  289,  289,  289,
+       31,  289,   28,   36,   59,   49,  289,  289,   68,   23,
+       33,   29,   28,   45,   49,   60,   61,   64,   74,   64,
+       59,   46,  289,  100,    0,  289,  105,  112,   50,  289,
+       65,   93,   71,   88,   89,  100,   97,  103,  106,  109,
+      113,  125,  119,  129,    0,  122,  130,  133,  134,  137,
+      141,  142,  147,  155,  159,  152,  160,  151,  172,  164,
+      168,  173,  177,  180,  181,  184,  185,  192,  195,  196,
+      202,  207,  203,  212,  211,  215,  221,  218,  222,  227,
+      232,  228,  231,  235,  240,  239,  289,  272,  275,  280,
+
+      283
     } ;
 
-static yyconst flex_int16_t yy_def[84] =
+static yyconst flex_int16_t yy_def[102] =
     {   0,
-       80,    1,   80,   80,   80,   80,   81,   80,   80,   80,
-       80,   80,   80,   80,   80,   82,   80,   80,   82,   19,
-       19,   19,   19,   19,   19,   19,   19,   80,   80,   81,
-       80,   80,   83,   80,   80,   19,   19,   80,   19,   19,
-       19,   19,   19,   19,   19,   19,   19,   19,   19,   83,
+       97,    1,   97,   97,   97,   97,   98,   97,   97,   97,
+       97,   97,   99,   97,   97,  100,   97,   97,  100,   19,
+       19,   19,   19,   19,   19,   19,   19,   19,   19,   97,
+       97,   98,   97,   97,  101,   97,   97,   19,   19,   97,
+       19,   19,   19,   19,   19,   19,   19,   19,   19,   19,
+       19,   19,   19,   19,  101,   19,   19,   19,   19,   19,
+       19,   19,   19,   19,   19,   19,   19,   19,   19,   19,
        19,   19,   19,   19,   19,   19,   19,   19,   19,   19,
        19,   19,   19,   19,   19,   19,   19,   19,   19,   19,
-       19,   19,   19,   19,   19,   19,   19,   19,   19,    0,
-       80,   80,   80
+       19,   19,   19,   19,   19,   19,    0,   97,   97,   97,
+
+       97
     } ;
 
-static yyconst flex_uint16_t yy_nxt[257] =
+static yyconst flex_uint16_t yy_nxt[330] =
     {   0,
         4,    5,    6,    7,    8,    9,   10,   11,   12,   13,
-       14,   14,   15,   16,   16,   16,   17,   18,    4,   19,
-       16,   20,   16,   21,   16,   22,   16,   16,   23,   24,
-       16,   25,   26,   27,   16,   16,   16,   32,   32,   32,
-       32,   32,   32,   32,   32,   32,   33,   35,   35,   37,
-       37,   41,   43,   36,   37,   37,   37,   37,   37,   37,
-       44,   50,   42,   38,   36,   47,   33,   35,   35,   37,
-       37,   37,   37,   36,   45,   46,   49,   31,   37,   37,
-       37,   37,   29,   38,   36,   48,   32,   32,   32,   35,
-       35,   80,   80,   39,   40,   37,   37,   51,   37,   37,
-
-       53,   37,   37,   52,   28,   38,   34,   80,   37,   37,
-       54,   37,   37,   37,   37,   58,   37,   37,   37,   37,
-       37,   55,   37,   37,   59,   56,   37,   37,   57,   37,
-       37,   37,   37,   61,   60,   37,   37,   37,   37,   37,
-       37,   31,   62,   37,   37,   37,   37,   63,   37,   37,
-       64,   37,   37,   67,   37,   37,   65,   29,   37,   37,
-       66,   37,   37,   37,   37,   37,   37,   69,   28,   68,
-       37,   37,   37,   37,   37,   37,   37,   37,   71,   70,
-       37,   37,   72,   37,   74,   73,   75,   37,   37,   37,
-       37,   76,   37,   37,   37,   37,   37,   37,   77,   37,
-
-       37,   80,   37,   37,   37,   78,   79,   37,   37,   37,
-       37,   30,   30,   80,   30,   37,   37,   37,    3,   80,
-       80,   80,   80,   80,   80,   80,   80,   80,   80,   80,
-       80,   80,   80,   80,   80,   80,   80,   80,   80,   80,
-       80,   80,   80,   80,   80,   80,   80,   80,   80,   80,
-       80,   80,   80,   80,   80,   80
+       14,   14,   14,   15,   16,   16,   16,   17,   18,    4,
+       19,   16,   20,   16,   21,   16,   22,   16,   16,   16,
+       23,   24,   25,   26,   27,   28,   29,   16,   16,   16,
+       34,   34,   34,   34,   35,   34,   34,   34,   34,   33,
+       37,   37,   39,   45,   39,   43,   38,   39,   39,   39,
+       39,   31,   39,   46,   39,   30,   35,   40,   38,   37,
+       37,   44,   36,   33,   39,   38,   39,   47,   39,   39,
+       39,   39,   48,   49,   31,   51,   40,   38,   50,   39,
+       39,   39,   39,   39,   56,   39,   39,   41,   53,   42,
+
+       39,   52,   58,   39,   30,   39,   37,   37,   54,   34,
+       34,   34,   34,   97,   97,   59,   57,   39,   39,   39,
+       39,   97,   39,   40,   39,   61,   39,   60,   39,   39,
+       97,   39,   39,   62,   39,   39,   97,   39,   39,   63,
+       39,   39,   65,   39,   39,   64,   66,   97,   39,   68,
+       39,   39,   97,   39,   39,   69,   39,   67,   39,   39,
+       39,   39,   39,   39,   39,   39,   39,   73,   39,   70,
+       39,   39,   39,   39,   72,   97,   39,   71,   39,   74,
+       39,   39,   77,   39,   39,   97,   39,   75,   39,   39,
+       39,   39,   78,   39,   97,   39,   76,   39,   97,   39,
+
+       79,   39,   39,   39,   39,   81,   39,   80,   39,   39,
+       39,   39,   39,   39,   39,   39,   39,   83,   89,   82,
+       84,   39,   97,   39,   39,   39,   39,   39,   85,   87,
+       86,   39,   39,   88,   39,   97,   39,   90,   39,   91,
+       39,   39,   39,   39,   39,   92,   39,   39,   97,   39,
+       39,   39,   39,   39,   93,   94,   39,   39,   39,   39,
+       39,   39,   95,   39,   39,   96,   39,   97,   39,   39,
+       39,   39,   32,   32,   97,   32,   32,   32,   34,   97,
+       34,   39,   39,   39,   39,   39,   55,   55,    3,   97,
+       97,   97,   97,   97,   97,   97,   97,   97,   97,   97,
+
+       97,   97,   97,   97,   97,   97,   97,   97,   97,   97,
+       97,   97,   97,   97,   97,   97,   97,   97,   97,   97,
+       97,   97,   97,   97,   97,   97,   97,   97,   97
     } ;
 
-static yyconst flex_int16_t yy_chk[257] =
+static yyconst flex_int16_t yy_chk[330] =
     {   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,   11,   11,   11,
-       13,   13,   13,   14,   14,   14,   13,   16,   16,   20,
-       20,   20,   22,   16,   21,   21,   22,   22,   23,   23,
-       23,   83,   21,   16,   16,   25,   13,   19,   19,   25,
-       25,   24,   24,   19,   24,   24,   27,   30,   26,   26,
-       27,   27,   29,   19,   19,   26,   32,   32,   32,   35,
-       35,   36,   36,   19,   19,   37,   37,   39,   39,   41,
-
-       41,   46,   46,   40,   28,   35,   15,   36,   40,   40,
-       42,   42,   42,   43,   43,   47,   47,   36,   36,   44,
-       44,   43,   45,   45,   48,   44,   49,   49,   45,   51,
-       51,   48,   48,   53,   49,   52,   52,   54,   54,   53,
-       53,    7,   54,   55,   55,   56,   56,   57,   57,   57,
-       58,   59,   59,   61,   60,   60,   59,    6,   58,   58,
-       60,   61,   61,   62,   62,   63,   63,   63,    5,   62,
-       64,   64,   65,   65,   66,   66,   67,   67,   65,   64,
-       68,   68,   67,   69,   69,   68,   70,   71,   71,   72,
-       72,   71,   73,   73,   74,   74,   75,   75,   76,   76,
-
-       76,    3,   70,   70,   77,   77,   78,   79,   79,   78,
-       78,   81,   81,    0,   81,   82,   82,   82,   80,   80,
-       80,   80,   80,   80,   80,   80,   80,   80,   80,   80,
-       80,   80,   80,   80,   80,   80,   80,   80,   80,   80,
-       80,   80,   80,   80,   80,   80,   80,   80,   80,   80,
-       80,   80,   80,   80,   80,   80
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+       11,   11,   11,   11,   13,   14,   14,   14,   14,   32,
+       16,   16,   20,   22,   20,   20,   16,   23,   22,   23,
+       22,   31,   21,   23,   21,   30,   13,   16,   16,   19,
+       19,   21,   15,    7,   24,   19,   24,   24,   25,   39,
+       25,   39,   25,   25,    6,   27,   19,   19,   26,   26,
+       27,   26,   27,   28,   41,   28,   41,   19,   29,   19,
+
+       43,   28,   43,   29,    5,   29,   37,   37,   29,   34,
+       34,   34,   34,   38,   38,   44,   42,   44,   45,   44,
+       45,    3,   42,   37,   42,   46,   47,   45,   47,   46,
+       38,   46,   48,   47,   48,   49,    0,   49,   50,   48,
+       50,   38,   51,   38,   51,   50,   52,    0,   53,   54,
+       53,   56,    0,   56,   52,   58,   52,   53,   54,   57,
+       54,   57,   58,   59,   58,   59,   60,   64,   60,   59,
+       61,   62,   61,   62,   63,    0,   63,   61,   63,   65,
+       68,   66,   68,   66,   64,    0,   64,   66,   65,   67,
+       65,   67,   69,   70,    0,   70,   67,   71,    0,   71,
+
+       70,   69,   72,   69,   72,   72,   73,   71,   73,   74,
+       75,   74,   75,   76,   77,   76,   77,   75,   82,   74,
+       77,   78,    0,   78,   79,   80,   79,   80,   78,   80,
+       79,   81,   83,   81,   83,    0,   82,   83,   82,   84,
+       85,   84,   85,   84,   86,   87,   86,   88,    0,   88,
+       87,   89,   87,   89,   90,   91,   90,   92,   90,   92,
+       93,   91,   93,   91,   94,   95,   94,    0,   96,   95,
+       96,   95,   98,   98,    0,   98,   98,   98,   99,    0,
+       99,  100,  100,  100,  100,  100,  101,  101,   97,   97,
+       97,   97,   97,   97,   97,   97,   97,   97,   97,   97,
+
+       97,   97,   97,   97,   97,   97,   97,   97,   97,   97,
+       97,   97,   97,   97,   97,   97,   97,   97,   97,   97,
+       97,   97,   97,   97,   97,   97,   97,   97,   97
     } ;
 
 /* Table of booleans, true if rule could match eol. */
-static yyconst flex_int32_t yy_rule_can_match_eol[27] =
+static yyconst flex_int32_t yy_rule_can_match_eol[30] =
     {   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,     };
 
 extern int yy_flex_debug;
 int yy_flex_debug = 1;
 
-static yyconst flex_int16_t yy_rule_linenum[26] =
+static yyconst flex_int16_t yy_rule_linenum[29] =
     {   0,
        78,   82,   88,   98,  104,  118,  125,  126,  127,  128,
       129,  130,  131,  132,  133,  134,  135,  136,  137,  138,
-      139,  140,  141,  142,  144
+      139,  140,  141,  142,  144,  145,  146,  148
     } ;
 
 static yy_state_type *yy_state_buf=0, *yy_state_ptr=0;
@@ -743,7 +770,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 747 "lexer.cc"
+#line 774 "lexer.cc"
 
 #define INITIAL 0
 
@@ -1040,7 +1067,7 @@ YY_DECL
     loc.step();
 
 
-#line 1044 "lexer.cc"
+#line 1071 "lexer.cc"
 
 	while ( /*CONSTCOND*/1 )		/* loops until end-of-file is reached */
 		{
@@ -1068,14 +1095,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 >= 81 )
+				if ( yy_current_state >= 98 )
 					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 != 80 );
+		while ( yy_current_state != 97 );
 
 yy_find_action:
 /* %% [10.0] code to find the action number goes here */
@@ -1138,13 +1165,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 < 26 )
+			else if ( yy_act < 29 )
 				fprintf( stderr, "--accepting rule at line %ld (\"%s\")\n",
 				         (long)yy_rule_linenum[yy_act], yytext );
-			else if ( yy_act == 26 )
+			else if ( yy_act == 29 )
 				fprintf( stderr, "--accepting default rule (\"%s\")\n",
 				         yytext );
-			else if ( yy_act == 27 )
+			else if ( yy_act == 30 )
 				fprintf( stderr, "--(end of buffer or a NUL)\n" );
 			else
 				fprintf( stderr, "--EOF (start condition %d)\n", YY_START );
@@ -1314,18 +1341,33 @@ return isc::eval::EvalParser::make_COMA(loc);
 case 25:
 YY_RULE_SETUP
 #line 144 "lexer.ll"
+return isc::eval::EvalParser::make_PKT6(loc);
+	YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 145 "lexer.ll"
+return isc::eval::EvalParser::make_MSGTYPE(loc);
+	YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 146 "lexer.ll"
+return isc::eval::EvalParser::make_TRANSID(loc);
+	YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 148 "lexer.ll"
 driver.error (loc, "Invalid character: " + std::string(yytext));
 	YY_BREAK
 case YY_STATE_EOF(INITIAL):
-#line 145 "lexer.ll"
+#line 149 "lexer.ll"
 return isc::eval::EvalParser::make_END(loc);
 	YY_BREAK
-case 26:
+case 29:
 YY_RULE_SETUP
-#line 146 "lexer.ll"
+#line 150 "lexer.ll"
 ECHO;
 	YY_BREAK
-#line 1329 "lexer.cc"
+#line 1371 "lexer.cc"
 
 	case YY_END_OF_BUFFER:
 		{
@@ -1610,7 +1652,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 >= 81 )
+			if ( yy_current_state >= 98 )
 				yy_c = yy_meta[(unsigned int) yy_c];
 			}
 		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1638,11 +1680,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 >= 81 )
+		if ( yy_current_state >= 98 )
 			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 == 80);
+	yy_is_jam = (yy_current_state == 97);
 	if ( ! yy_is_jam )
 		*(yy_state_ptr)++ = yy_current_state;
 
@@ -2408,7 +2450,7 @@ void yyfree (void * ptr )
 
 /* %ok-for-header */
 
-#line 146 "lexer.ll"
+#line 150 "lexer.ll"
 
 
 

+ 4 - 0
src/lib/eval/lexer.ll

@@ -141,6 +141,10 @@ blank [ \t]
 "]"         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);
 %%

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

@@ -251,18 +251,22 @@ namespace isc { namespace eval {
   {
       switch (that.type_get ())
     {
-      case 30: // option_repr_type
+      case 33: // option_repr_type
         value.move< TokenOption::RepresentationType > (that.value);
         break;
 
-      case 21: // "constant string"
-      case 22: // "integer"
-      case 23: // "constant hexstring"
-      case 24: // "option name"
+      case 36: // pkt6_field
+        value.move< TokenPkt6::FieldType > (that.value);
+        break;
+
+      case 24: // "constant string"
+      case 25: // "integer"
+      case 26: // "constant hexstring"
+      case 27: // "option name"
         value.move< std::string > (that.value);
         break;
 
-      case 29: // option_code
+      case 32: // option_code
         value.move< uint16_t > (that.value);
         break;
 
@@ -281,18 +285,22 @@ namespace isc { namespace eval {
     state = that.state;
       switch (that.type_get ())
     {
-      case 30: // option_repr_type
+      case 33: // option_repr_type
         value.copy< TokenOption::RepresentationType > (that.value);
         break;
 
-      case 21: // "constant string"
-      case 22: // "integer"
-      case 23: // "constant hexstring"
-      case 24: // "option name"
+      case 36: // pkt6_field
+        value.copy< TokenPkt6::FieldType > (that.value);
+        break;
+
+      case 24: // "constant string"
+      case 25: // "integer"
+      case 26: // "constant hexstring"
+      case 27: // "option name"
         value.copy< std::string > (that.value);
         break;
 
-      case 29: // option_code
+      case 32: // option_code
         value.copy< uint16_t > (that.value);
         break;
 
@@ -332,46 +340,53 @@ namespace isc { namespace eval {
         << yysym.location << ": ";
     switch (yytype)
     {
-            case 21: // "constant string"
+            case 24: // "constant string"
 
-#line 72 "parser.yy" // lalr1.cc:636
+#line 76 "parser.yy" // lalr1.cc:636
         { yyoutput << yysym.value.template as< std::string > (); }
-#line 340 "parser.cc" // lalr1.cc:636
+#line 348 "parser.cc" // lalr1.cc:636
         break;
 
-      case 22: // "integer"
+      case 25: // "integer"
 
-#line 72 "parser.yy" // lalr1.cc:636
+#line 76 "parser.yy" // lalr1.cc:636
         { yyoutput << yysym.value.template as< std::string > (); }
-#line 347 "parser.cc" // lalr1.cc:636
+#line 355 "parser.cc" // lalr1.cc:636
         break;
 
-      case 23: // "constant hexstring"
+      case 26: // "constant hexstring"
 
-#line 72 "parser.yy" // lalr1.cc:636
+#line 76 "parser.yy" // lalr1.cc:636
         { yyoutput << yysym.value.template as< std::string > (); }
-#line 354 "parser.cc" // lalr1.cc:636
+#line 362 "parser.cc" // lalr1.cc:636
         break;
 
-      case 24: // "option name"
+      case 27: // "option name"
 
-#line 72 "parser.yy" // lalr1.cc:636
+#line 76 "parser.yy" // lalr1.cc:636
         { yyoutput << yysym.value.template as< std::string > (); }
-#line 361 "parser.cc" // lalr1.cc:636
+#line 369 "parser.cc" // lalr1.cc:636
         break;
 
-      case 29: // option_code
+      case 32: // option_code
 
-#line 72 "parser.yy" // lalr1.cc:636
+#line 76 "parser.yy" // lalr1.cc:636
         { yyoutput << yysym.value.template as< uint16_t > (); }
-#line 368 "parser.cc" // lalr1.cc:636
+#line 376 "parser.cc" // lalr1.cc:636
         break;
 
-      case 30: // option_repr_type
+      case 33: // option_repr_type
 
-#line 72 "parser.yy" // lalr1.cc:636
+#line 76 "parser.yy" // lalr1.cc:636
         { yyoutput << yysym.value.template as< TokenOption::RepresentationType > (); }
-#line 375 "parser.cc" // lalr1.cc:636
+#line 383 "parser.cc" // lalr1.cc:636
+        break;
+
+      case 36: // pkt6_field
+
+#line 76 "parser.yy" // lalr1.cc:636
+        { yyoutput << yysym.value.template as< TokenPkt6::FieldType > (); }
+#line 390 "parser.cc" // lalr1.cc:636
         break;
 
 
@@ -571,18 +586,22 @@ namespace isc { namespace eval {
          when using variants.  */
         switch (yyr1_[yyn])
     {
-      case 30: // option_repr_type
+      case 33: // option_repr_type
         yylhs.value.build< TokenOption::RepresentationType > ();
         break;
 
-      case 21: // "constant string"
-      case 22: // "integer"
-      case 23: // "constant hexstring"
-      case 24: // "option name"
+      case 36: // pkt6_field
+        yylhs.value.build< TokenPkt6::FieldType > ();
+        break;
+
+      case 24: // "constant string"
+      case 25: // "integer"
+      case 26: // "constant hexstring"
+      case 27: // "option name"
         yylhs.value.build< std::string > ();
         break;
 
-      case 29: // option_code
+      case 32: // option_code
         yylhs.value.build< uint16_t > ();
         break;
 
@@ -604,52 +623,52 @@ namespace isc { namespace eval {
           switch (yyn)
             {
   case 4:
-#line 86 "parser.yy" // lalr1.cc:859
+#line 90 "parser.yy" // lalr1.cc:859
     {
                     TokenPtr neg(new TokenNot());
                     ctx.expression.push_back(neg);
                 }
-#line 613 "parser.cc" // lalr1.cc:859
+#line 632 "parser.cc" // lalr1.cc:859
     break;
 
   case 5:
-#line 91 "parser.yy" // lalr1.cc:859
+#line 95 "parser.yy" // lalr1.cc:859
     {
                     TokenPtr neg(new TokenAnd());
                     ctx.expression.push_back(neg);
                 }
-#line 622 "parser.cc" // lalr1.cc:859
+#line 641 "parser.cc" // lalr1.cc:859
     break;
 
   case 6:
-#line 96 "parser.yy" // lalr1.cc:859
+#line 100 "parser.yy" // lalr1.cc:859
     {
                     TokenPtr neg(new TokenOr());
                     ctx.expression.push_back(neg);
                 }
-#line 631 "parser.cc" // lalr1.cc:859
+#line 650 "parser.cc" // lalr1.cc:859
     break;
 
   case 7:
-#line 101 "parser.yy" // lalr1.cc:859
+#line 105 "parser.yy" // lalr1.cc:859
     {
                     TokenPtr eq(new TokenEqual());
                     ctx.expression.push_back(eq);
                 }
-#line 640 "parser.cc" // lalr1.cc:859
+#line 659 "parser.cc" // lalr1.cc:859
     break;
 
   case 8:
-#line 106 "parser.yy" // lalr1.cc:859
+#line 110 "parser.yy" // lalr1.cc:859
     {
                     TokenPtr opt(new TokenOption(yystack_[3].value.as< uint16_t > (), TokenOption::EXISTS));
                     ctx.expression.push_back(opt);
                 }
-#line 649 "parser.cc" // lalr1.cc:859
+#line 668 "parser.cc" // lalr1.cc:859
     break;
 
   case 9:
-#line 111 "parser.yy" // lalr1.cc:859
+#line 115 "parser.yy" // lalr1.cc:859
     {
                    switch (ctx.getUniverse()) {
                    case Option::V4:
@@ -669,38 +688,47 @@ namespace isc { namespace eval {
                        error(yystack_[5].location, "relay4 can only be used in DHCPv4.");
                    }
                 }
-#line 673 "parser.cc" // lalr1.cc:859
+#line 692 "parser.cc" // lalr1.cc:859
     break;
 
   case 10:
-#line 133 "parser.yy" // lalr1.cc:859
+#line 135 "parser.yy" // lalr1.cc:859
+    {
+                    TokenPtr pkt6field(new TokenPkt6(yystack_[0].value.as< TokenPkt6::FieldType > ()));
+                    ctx.expression.push_back(pkt6field);
+                }
+#line 701 "parser.cc" // lalr1.cc:859
+    break;
+
+  case 11:
+#line 142 "parser.yy" // lalr1.cc:859
     {
                       TokenPtr str(new TokenString(yystack_[0].value.as< std::string > ()));
                       ctx.expression.push_back(str);
                   }
-#line 682 "parser.cc" // lalr1.cc:859
+#line 710 "parser.cc" // lalr1.cc:859
     break;
 
-  case 11:
-#line 138 "parser.yy" // lalr1.cc:859
+  case 12:
+#line 147 "parser.yy" // lalr1.cc:859
     {
                       TokenPtr hex(new TokenHexString(yystack_[0].value.as< std::string > ()));
                       ctx.expression.push_back(hex);
                   }
-#line 691 "parser.cc" // lalr1.cc:859
+#line 719 "parser.cc" // lalr1.cc:859
     break;
 
-  case 12:
-#line 143 "parser.yy" // lalr1.cc:859
+  case 13:
+#line 152 "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 700 "parser.cc" // lalr1.cc:859
+#line 728 "parser.cc" // lalr1.cc:859
     break;
 
-  case 13:
-#line 148 "parser.yy" // lalr1.cc:859
+  case 14:
+#line 157 "parser.yy" // lalr1.cc:859
     {
                      switch (ctx.getUniverse()) {
                      case Option::V4:
@@ -720,88 +748,100 @@ namespace isc { namespace eval {
                          error(yystack_[5].location, "relay4 can only be used in DHCPv4.");
                      }
                   }
-#line 724 "parser.cc" // lalr1.cc:859
+#line 752 "parser.cc" // lalr1.cc:859
     break;
 
-  case 14:
-#line 168 "parser.yy" // lalr1.cc:859
+  case 15:
+#line 177 "parser.yy" // lalr1.cc:859
     {
                       TokenPtr sub(new TokenSubstring());
                       ctx.expression.push_back(sub);
                   }
-#line 733 "parser.cc" // lalr1.cc:859
+#line 761 "parser.cc" // lalr1.cc:859
     break;
 
-  case 15:
-#line 173 "parser.yy" // lalr1.cc:859
+  case 16:
+#line 182 "parser.yy" // lalr1.cc:859
     {
                       TokenPtr conc(new TokenConcat());
                       ctx.expression.push_back(conc);
                   }
-#line 742 "parser.cc" // lalr1.cc:859
+#line 770 "parser.cc" // lalr1.cc:859
     break;
 
-  case 16:
-#line 180 "parser.yy" // lalr1.cc:859
+  case 17:
+#line 189 "parser.yy" // lalr1.cc:859
     {
                      yylhs.value.as< uint16_t > () = ctx.convertOptionCode(yystack_[0].value.as< std::string > (), yystack_[0].location);
                  }
-#line 750 "parser.cc" // lalr1.cc:859
+#line 778 "parser.cc" // lalr1.cc:859
     break;
 
-  case 17:
-#line 184 "parser.yy" // lalr1.cc:859
+  case 18:
+#line 193 "parser.yy" // lalr1.cc:859
     {
                      yylhs.value.as< uint16_t > () = ctx.convertOptionName(yystack_[0].value.as< std::string > (), yystack_[0].location);
                  }
-#line 758 "parser.cc" // lalr1.cc:859
+#line 786 "parser.cc" // lalr1.cc:859
     break;
 
-  case 18:
-#line 190 "parser.yy" // lalr1.cc:859
+  case 19:
+#line 199 "parser.yy" // lalr1.cc:859
     {
                           yylhs.value.as< TokenOption::RepresentationType > () = TokenOption::TEXTUAL;
                       }
-#line 766 "parser.cc" // lalr1.cc:859
+#line 794 "parser.cc" // lalr1.cc:859
     break;
 
-  case 19:
-#line 194 "parser.yy" // lalr1.cc:859
+  case 20:
+#line 203 "parser.yy" // lalr1.cc:859
     {
                           yylhs.value.as< TokenOption::RepresentationType > () = TokenOption::HEXADECIMAL;
                       }
-#line 774 "parser.cc" // lalr1.cc:859
+#line 802 "parser.cc" // lalr1.cc:859
     break;
 
-  case 20:
-#line 200 "parser.yy" // lalr1.cc:859
+  case 21:
+#line 209 "parser.yy" // lalr1.cc:859
     {
                      TokenPtr str(new TokenString(yystack_[0].value.as< std::string > ()));
                      ctx.expression.push_back(str);
                  }
-#line 783 "parser.cc" // lalr1.cc:859
+#line 811 "parser.cc" // lalr1.cc:859
     break;
 
-  case 21:
-#line 207 "parser.yy" // lalr1.cc:859
+  case 22:
+#line 216 "parser.yy" // lalr1.cc:859
     {
                       TokenPtr str(new TokenString(yystack_[0].value.as< std::string > ()));
                       ctx.expression.push_back(str);
                   }
-#line 792 "parser.cc" // lalr1.cc:859
+#line 820 "parser.cc" // lalr1.cc:859
     break;
 
-  case 22:
-#line 212 "parser.yy" // lalr1.cc:859
+  case 23:
+#line 221 "parser.yy" // lalr1.cc:859
     {
                      TokenPtr str(new TokenString("all"));
                      ctx.expression.push_back(str);
                  }
-#line 801 "parser.cc" // lalr1.cc:859
+#line 829 "parser.cc" // lalr1.cc:859
+    break;
+
+  case 24:
+#line 227 "parser.yy" // lalr1.cc:859
+    { yylhs.value.as< TokenPkt6::FieldType > () = TokenPkt6::MSGTYPE; }
+#line 835 "parser.cc" // lalr1.cc:859
+    break;
+
+  case 25:
+#line 228 "parser.yy" // lalr1.cc:859
+    { yylhs.value.as< TokenPkt6::FieldType > () = TokenPkt6::TRANSID; }
+#line 841 "parser.cc" // lalr1.cc:859
     break;
 
 
-#line 805 "parser.cc" // lalr1.cc:859
+#line 845 "parser.cc" // lalr1.cc:859
             default:
               break;
             }
@@ -1056,98 +1096,98 @@ namespace isc { namespace eval {
   }
 
 
-  const signed char EvalParser::yypact_ninf_ = -29;
+  const signed char EvalParser::yypact_ninf_ = -42;
 
   const signed char EvalParser::yytable_ninf_ = -1;
 
   const signed char
   EvalParser::yypact_[] =
   {
-      -1,    -1,    -1,     1,    10,    28,    36,   -29,   -29,    32,
-       0,    41,    29,   -29,    -7,    -7,    17,    17,   -29,    -1,
-      -1,    17,   -29,   -29,   -29,    38,    39,    42,    43,    37,
-      40,   -29,    46,   -29,    44,    45,    -7,    -7,    47,    17,
-      27,    30,    48,    49,   -29,    51,    58,   -29,   -29,   -29,
-     -29,   -29,   -29,    50,    52,    -4,   -29,    33,    33,   -29,
-     -29,    60,   -29
+      -1,    -1,    -1,    10,    13,    35,    45,    39,   -42,   -42,
+      26,     6,    46,    11,   -42,    12,    12,    23,    23,    19,
+     -42,    -1,    -1,    23,   -42,   -42,   -42,    41,    43,    47,
+      48,    37,    38,   -42,   -42,   -42,   -42,    54,   -42,    49,
+      50,    12,    12,    40,    23,    20,    30,    52,    55,   -42,
+      42,    62,   -42,   -42,   -42,   -42,   -42,   -42,    56,    57,
+     -11,   -42,    36,    36,   -42,   -42,    64,   -42
   };
 
   const unsigned char
   EvalParser::yydefact_[] =
   {
-       0,     0,     0,     0,     0,     0,     0,    10,    11,     0,
-       2,     0,     0,     4,     0,     0,     0,     0,     1,     0,
-       0,     0,     3,    16,    17,     0,     0,     0,     0,     0,
-       0,     5,     6,     7,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,    20,     0,     0,    18,    19,     8,
-      12,     9,    13,     0,     0,     0,    15,     0,     0,    22,
-      21,     0,    14
+       0,     0,     0,     0,     0,     0,     0,     0,    11,    12,
+       0,     2,     0,     0,     4,     0,     0,     0,     0,     0,
+       1,     0,     0,     0,     3,    17,    18,     0,     0,     0,
+       0,     0,     0,    24,    25,    10,     5,     6,     7,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,    21,
+       0,     0,    19,    20,     8,    13,     9,    14,     0,     0,
+       0,    16,     0,     0,    23,    22,     0,    15
   };
 
   const signed char
   EvalParser::yypgoto_[] =
   {
-     -29,   -29,     9,   -16,   -12,   -28,   -29,   -29
+     -42,   -42,     9,   -17,   -13,   -41,   -42,   -42,   -42
   };
 
   const signed char
   EvalParser::yydefgoto_[] =
   {
-      -1,     9,    10,    11,    25,    50,    45,    61
+      -1,    10,    11,    12,    27,    55,    50,    66,    35
   };
 
   const unsigned char
   EvalParser::yytable_[] =
   {
-      29,    30,     1,    26,     2,    33,    19,    20,     3,     4,
-      12,    13,    14,    52,    59,    23,     5,    24,    60,     6,
-       7,    15,     8,    46,    42,    43,    27,    28,    31,    32,
-      52,    16,    18,    22,     5,    19,    20,     6,     7,    17,
-       8,    47,    48,    49,    47,    48,    51,    47,    48,    21,
-      34,    35,    19,    36,    37,     0,    38,    40,    41,    39,
-      53,    54,    56,    57,    62,    58,     0,     0,     0,    44,
-      55
+      31,    32,     1,    28,     2,    57,    38,    64,     3,     4,
+      13,    14,    21,    22,    65,    24,     5,    21,    22,     6,
+       7,    15,    57,     8,    16,     9,    20,    51,    47,    48,
+      36,    37,    29,    30,    52,    53,    54,    25,    17,    26,
+       5,    33,    34,     6,    52,    53,    56,     8,    18,     9,
+      52,    53,    19,    39,    23,    40,    43,    44,    41,    42,
+      21,    60,    45,    46,    58,    49,    61,    59,    67,    62,
+      63
   };
 
-  const signed char
+  const unsigned char
   EvalParser::yycheck_[] =
   {
-      16,    17,     3,    15,     5,    21,     6,     7,     9,    10,
-       1,     2,    11,    41,    18,    22,    17,    24,    22,    20,
-      21,    11,    23,    39,    36,    37,     9,    10,    19,    20,
-      58,     3,     0,     4,    17,     6,     7,    20,    21,     3,
-      23,    14,    15,    16,    14,    15,    16,    14,    15,     8,
-      12,    12,     6,    11,    11,    -1,    19,    13,    13,    19,
-      12,    12,     4,    13,     4,    13,    -1,    -1,    -1,    22,
-      19
+      17,    18,     3,    16,     5,    46,    23,    18,     9,    10,
+       1,     2,     6,     7,    25,     4,    17,     6,     7,    20,
+      21,    11,    63,    24,    11,    26,     0,    44,    41,    42,
+      21,    22,     9,    10,    14,    15,    16,    25,     3,    27,
+      17,    22,    23,    20,    14,    15,    16,    24,     3,    26,
+      14,    15,    13,    12,     8,    12,    19,    19,    11,    11,
+       6,    19,    13,    13,    12,    25,     4,    12,     4,    13,
+      13
   };
 
   const unsigned char
   EvalParser::yystos_[] =
   {
-       0,     3,     5,     9,    10,    17,    20,    21,    23,    26,
-      27,    28,    27,    27,    11,    11,     3,     3,     0,     6,
-       7,     8,     4,    22,    24,    29,    29,     9,    10,    28,
-      28,    27,    27,    28,    12,    12,    11,    11,    19,    19,
-      13,    13,    29,    29,    22,    31,    28,    14,    15,    16,
-      30,    16,    30,    12,    12,    19,     4,    13,    13,    18,
-      22,    32,     4
+       0,     3,     5,     9,    10,    17,    20,    21,    24,    26,
+      29,    30,    31,    30,    30,    11,    11,     3,     3,    13,
+       0,     6,     7,     8,     4,    25,    27,    32,    32,     9,
+      10,    31,    31,    22,    23,    36,    30,    30,    31,    12,
+      12,    11,    11,    19,    19,    13,    13,    32,    32,    25,
+      34,    31,    14,    15,    16,    33,    16,    33,    12,    12,
+      19,     4,    13,    13,    18,    25,    35,     4
   };
 
   const unsigned char
   EvalParser::yyr1_[] =
   {
-       0,    25,    26,    27,    27,    27,    27,    27,    27,    27,
-      28,    28,    28,    28,    28,    28,    29,    29,    30,    30,
-      31,    32,    32
+       0,    28,    29,    30,    30,    30,    30,    30,    30,    30,
+      30,    31,    31,    31,    31,    31,    31,    32,    32,    33,
+      33,    34,    35,    35,    36,    36
   };
 
   const unsigned char
   EvalParser::yyr2_[] =
   {
        0,     2,     1,     3,     2,     3,     3,     3,     6,     6,
-       1,     1,     6,     6,     8,     6,     1,     1,     1,     1,
-       1,     1,     1
+       3,     1,     1,     6,     6,     8,     6,     1,     1,     1,
+       1,     1,     1,     1,     1,     1
   };
 
 
@@ -1160,19 +1200,20 @@ namespace isc { namespace eval {
   "\"end of file\"", "error", "$undefined", "\"(\"", "\")\"", "\"not\"",
   "\"and\"", "\"or\"", "\"==\"", "\"option\"", "\"relay4\"", "\"[\"",
   "\"]\"", "\".\"", "\"text\"", "\"hex\"", "\"exists\"", "\"substring\"",
-  "\"all\"", "\",\"", "\"concat\"", "\"constant string\"", "\"integer\"",
+  "\"all\"", "\",\"", "\"concat\"", "\"pkt6\"", "\"msgtype\"",
+  "\"transid\"", "\"constant string\"", "\"integer\"",
   "\"constant hexstring\"", "\"option name\"", "$accept", "expression",
   "bool_expr", "string_expr", "option_code", "option_repr_type",
-  "start_expr", "length_expr", YY_NULLPTR
+  "start_expr", "length_expr", "pkt6_field", YY_NULLPTR
   };
 
 #if YYDEBUG
   const unsigned char
   EvalParser::yyrline_[] =
   {
-       0,    81,    81,    84,    85,    90,    95,   100,   105,   110,
-     132,   137,   142,   147,   167,   172,   179,   183,   189,   193,
-     199,   206,   211
+       0,    85,    85,    88,    89,    94,    99,   104,   109,   114,
+     134,   141,   146,   151,   156,   176,   181,   188,   192,   198,
+     202,   208,   215,   220,   227,   228
   };
 
   // Print the state stack on the debug stream.
@@ -1207,8 +1248,8 @@ namespace isc { namespace eval {
 
 #line 13 "parser.yy" // lalr1.cc:1167
 } } // isc::eval
-#line 1211 "parser.cc" // lalr1.cc:1167
-#line 218 "parser.yy" // lalr1.cc:1168
+#line 1252 "parser.cc" // lalr1.cc:1167
+#line 231 "parser.yy" // lalr1.cc:1168
 
 void
 isc::eval::EvalParser::error(const location_type& loc,

+ 100 - 38
src/lib/eval/parser.h

@@ -298,14 +298,17 @@ namespace isc { namespace eval {
       // option_repr_type
       char dummy1[sizeof(TokenOption::RepresentationType)];
 
+      // pkt6_field
+      char dummy2[sizeof(TokenPkt6::FieldType)];
+
       // "constant string"
       // "integer"
       // "constant hexstring"
       // "option name"
-      char dummy2[sizeof(std::string)];
+      char dummy3[sizeof(std::string)];
 
       // option_code
-      char dummy3[sizeof(uint16_t)];
+      char dummy4[sizeof(uint16_t)];
 };
 
     /// Symbol semantic values.
@@ -347,10 +350,13 @@ namespace isc { namespace eval {
         TOKEN_ALL = 273,
         TOKEN_COMA = 274,
         TOKEN_CONCAT = 275,
-        TOKEN_STRING = 276,
-        TOKEN_INTEGER = 277,
-        TOKEN_HEXSTRING = 278,
-        TOKEN_OPTION_NAME = 279
+        TOKEN_PKT6 = 276,
+        TOKEN_MSGTYPE = 277,
+        TOKEN_TRANSID = 278,
+        TOKEN_STRING = 279,
+        TOKEN_INTEGER = 280,
+        TOKEN_HEXSTRING = 281,
+        TOKEN_OPTION_NAME = 282
       };
     };
 
@@ -390,6 +396,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 std::string v, const location_type& l);
 
   basic_symbol (typename Base::kind_type t, const uint16_t v, const location_type& l);
@@ -539,6 +547,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
@@ -638,7 +658,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.
@@ -759,11 +779,11 @@ namespace isc { namespace eval {
     {
       yyeof_ = 0,
       yylast_ = 70,     ///< Last index in yytable_.
-      yynnts_ = 8,  ///< Number of nonterminal symbols.
-      yyfinal_ = 18, ///< Termination state number.
+      yynnts_ = 9,  ///< Number of nonterminal symbols.
+      yyfinal_ = 20, ///< Termination state number.
       yyterror_ = 1,
       yyerrcode_ = 256,
-      yyntokens_ = 25  ///< Number of tokens.
+      yyntokens_ = 28  ///< Number of tokens.
     };
 
 
@@ -807,9 +827,10 @@ namespace isc { namespace eval {
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        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
+      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
+      25,    26,    27
     };
-    const unsigned int user_token_number_max_ = 279;
+    const unsigned int user_token_number_max_ = 282;
     const token_number_type undef_token_ = 2;
 
     if (static_cast<int>(t) <= yyeof_)
@@ -842,18 +863,22 @@ namespace isc { namespace eval {
   {
       switch (other.type_get ())
     {
-      case 30: // option_repr_type
+      case 33: // option_repr_type
         value.copy< TokenOption::RepresentationType > (other.value);
         break;
 
-      case 21: // "constant string"
-      case 22: // "integer"
-      case 23: // "constant hexstring"
-      case 24: // "option name"
+      case 36: // pkt6_field
+        value.copy< TokenPkt6::FieldType > (other.value);
+        break;
+
+      case 24: // "constant string"
+      case 25: // "integer"
+      case 26: // "constant hexstring"
+      case 27: // "option name"
         value.copy< std::string > (other.value);
         break;
 
-      case 29: // option_code
+      case 32: // option_code
         value.copy< uint16_t > (other.value);
         break;
 
@@ -874,18 +899,22 @@ namespace isc { namespace eval {
     (void) v;
       switch (this->type_get ())
     {
-      case 30: // option_repr_type
+      case 33: // option_repr_type
         value.copy< TokenOption::RepresentationType > (v);
         break;
 
-      case 21: // "constant string"
-      case 22: // "integer"
-      case 23: // "constant hexstring"
-      case 24: // "option name"
+      case 36: // pkt6_field
+        value.copy< TokenPkt6::FieldType > (v);
+        break;
+
+      case 24: // "constant string"
+      case 25: // "integer"
+      case 26: // "constant hexstring"
+      case 27: // "option name"
         value.copy< std::string > (v);
         break;
 
-      case 29: // option_code
+      case 32: // option_code
         value.copy< uint16_t > (v);
         break;
 
@@ -912,6 +941,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 std::string v, const location_type& l)
     : Base (t)
     , value (v)
@@ -951,18 +987,22 @@ namespace isc { namespace eval {
     // Type destructor.
     switch (yytype)
     {
-      case 30: // option_repr_type
+      case 33: // option_repr_type
         value.template destroy< TokenOption::RepresentationType > ();
         break;
 
-      case 21: // "constant string"
-      case 22: // "integer"
-      case 23: // "constant hexstring"
-      case 24: // "option name"
+      case 36: // pkt6_field
+        value.template destroy< TokenPkt6::FieldType > ();
+        break;
+
+      case 24: // "constant string"
+      case 25: // "integer"
+      case 26: // "constant hexstring"
+      case 27: // "option name"
         value.template destroy< std::string > ();
         break;
 
-      case 29: // option_code
+      case 32: // option_code
         value.template destroy< uint16_t > ();
         break;
 
@@ -989,18 +1029,22 @@ namespace isc { namespace eval {
     super_type::move(s);
       switch (this->type_get ())
     {
-      case 30: // option_repr_type
+      case 33: // option_repr_type
         value.move< TokenOption::RepresentationType > (s.value);
         break;
 
-      case 21: // "constant string"
-      case 22: // "integer"
-      case 23: // "constant hexstring"
-      case 24: // "option name"
+      case 36: // pkt6_field
+        value.move< TokenPkt6::FieldType > (s.value);
+        break;
+
+      case 24: // "constant string"
+      case 25: // "integer"
+      case 26: // "constant hexstring"
+      case 27: // "option name"
         value.move< std::string > (s.value);
         break;
 
-      case 29: // option_code
+      case 32: // option_code
         value.move< uint16_t > (s.value);
         break;
 
@@ -1061,7 +1105,7 @@ namespace isc { namespace eval {
     {
        0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
      265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
-     275,   276,   277,   278,   279
+     275,   276,   277,   278,   279,   280,   281,   282
     };
     return static_cast<token_type> (yytoken_number_[type]);
   }
@@ -1181,6 +1225,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);
@@ -1207,7 +1269,7 @@ namespace isc { namespace eval {
 
 #line 13 "parser.yy" // lalr1.cc:377
 } } // isc::eval
-#line 1211 "parser.h" // lalr1.cc:377
+#line 1273 "parser.h" // lalr1.cc:377
 
 
 

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

@@ -55,6 +55,9 @@ using namespace isc::eval;
   ALL "all"
   COMA ","
   CONCAT "concat"
+  PKT6 "pkt6"
+  MSGTYPE "msgtype"
+  TRANSID "transid"
 ;
 
 %token <std::string> STRING "constant string"
@@ -64,6 +67,7 @@ using namespace isc::eval;
 
 %type <uint16_t> option_code
 %type <TokenOption::RepresentationType> option_repr_type
+%type <TokenPkt6::FieldType> pkt6_field
 
 %left OR
 %left AND
@@ -127,6 +131,11 @@ bool_expr : "(" bool_expr ")"
                        error(@1, "relay4 can only be used in DHCPv4.");
                    }
                 }
+          | PKT6 "." pkt6_field
+                {
+                    TokenPtr pkt6field(new TokenPkt6($3));
+                    ctx.expression.push_back(pkt6field);
+                }
           ;
 
 string_expr : STRING
@@ -215,6 +224,10 @@ length_expr : INTEGER
                  }
             ;
 
+pkt6_field:MSGTYPE { $$ = TokenPkt6::MSGTYPE; }
+          | TRANSID { $$ = TokenPkt6::TRANSID; }
+          ;
+
 %%
 void
 isc::eval::EvalParser::error(const location_type& loc,

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

@@ -8,6 +8,7 @@
 #include <eval/eval_log.h>
 #include <util/encode/hex.h>
 #include <boost/lexical_cast.hpp>
+#include <dhcp/pkt6.h>
 #include <cstring>
 #include <string>
 
@@ -273,3 +274,36 @@ TokenOr::evaluate(const Pkt& /*pkt*/, ValueStack& values) {
         values.push("false");
     }
 }
+
+void
+TokenPkt6::evaluate(const Pkt& pkt, ValueStack& values) {
+
+    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 need to represent it as a string.
+          stringstream tmp;
+          tmp << static_cast<int>(pkt6.getType());
+          values.push(tmp.str());
+          return;
+      }
+      case TRANSID: {
+          // transaction id is an uint32_t integer.  We need to represent it as a string.
+          stringstream tmp;
+          tmp << static_cast<int>(pkt6.getTransid());
+          values.push(tmp.str());
+          return;
+      }
+      default:
+          isc_throw(EvalTypeError, "Bad filed specified: "
+                    << static_cast<int>(type_) );
+      }
+    } catch (const std::bad_cast&) {
+        isc_throw(EvalTypeError, "Specified packet is not Pkt6");
+    }
+};

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

@@ -444,6 +444,50 @@ public:
     void evaluate(const Pkt& pkt, ValueStack& values);
 };
 
+/// @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
+///
+/// Currently supported fields are:
+/// - msgtype
+/// - transid
+class TokenPkt6 : public Token {
+public:
+    /// @brief enum value that determins the field.
+    enum FieldType {
+        MSGTYPE, ///< msg type
+        TRANSID  ///< transaction id (integer but manipulated as as string)
+    };
+
+    /// @brief Constructor (does nothing)
+    TokenPkt6(const FieldType type)
+        : type_(type) {}
+
+    /// @brief Gets a value of the specified packet.
+    ///
+    /// The evaluation uses fields that are availabe in the packet.  It does not
+    /// require any values to be present on the stack.
+    ///
+    /// @throw EvalTypeError when called for a DHCPv4 packet
+    ///
+    /// @param pkt - packet from which to extract the fields
+    /// @param values - stack of values, 1 result will be pushed
+    void evaluate(const Pkt& pkt, ValueStack& values);
+
+    /// @breif Returns field type
+    ///
+    /// 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