mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-31 14:05:33 +00:00
[master] Finish merge of trac4268a (DHCPv4 fields)
This commit is contained in:
@@ -1,3 +1,8 @@
|
|||||||
|
1107. [func] fdupont
|
||||||
|
Added support for extracting constant length fields from a DHCPv4
|
||||||
|
packet.
|
||||||
|
(Trac #4268, git xxx)
|
||||||
|
|
||||||
1106. [func] sar
|
1106. [func] sar
|
||||||
Added support for accessing DHCPv6 packet fields message type
|
Added support for accessing DHCPv6 packet fields message type
|
||||||
and transaction id in a classification expression.
|
and transaction id in a classification expression.
|
||||||
|
@@ -152,56 +152,145 @@
|
|||||||
<thead>
|
<thead>
|
||||||
<row>
|
<row>
|
||||||
<entry>Name</entry>
|
<entry>Name</entry>
|
||||||
<entry>Example</entry>
|
<entry>Example expression</entry>
|
||||||
|
<entry>Example value</entry>
|
||||||
<entry>Description</entry>
|
<entry>Description</entry>
|
||||||
</row>
|
</row>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
<row><entry>String</entry><entry>'example'</entry><entry>A string</entry></row>
|
<row>
|
||||||
<row><entry>Hex String</entry><entry>0XABCD</entry><entry>A hexadecimal string</entry></row>
|
<entry>String literal</entry>
|
||||||
<row><entry>IP Address</entry><entry>10.0.0.1</entry><entry>An IP address</entry></row>
|
<entry>'example'</entry>
|
||||||
<row><entry>Integer</entry><entry>123</entry><entry>An integer value</entry></row>
|
<entry>'example'</entry>
|
||||||
|
<entry>A string</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry>Hexadecimal string literal</entry>
|
||||||
|
<entry>0x5a7d</entry>
|
||||||
|
<entry>'Z}'</entry>
|
||||||
|
<entry>A hexadecimal string</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry>IP address literal</entry>
|
||||||
|
<entry>10.0.0.1</entry>
|
||||||
|
<entry>0x0a000001</entry>
|
||||||
|
<entry>An IP address</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry>Integer literal</entry>
|
||||||
|
<entry>123</entry>
|
||||||
|
<entry>'123'</entry>
|
||||||
|
<entry>An integer value</entry>
|
||||||
|
</row>
|
||||||
|
<row></row>
|
||||||
|
<row>
|
||||||
|
<entry>Binary content of the option</entry>
|
||||||
|
<entry>option[123].hex</entry>
|
||||||
|
<entry>'(content of the option)'</entry>
|
||||||
|
<entry>The value of the option with given code from the
|
||||||
|
packet as hex</entry>
|
||||||
|
</row>
|
||||||
<!-- Text option not fully defined yet, leave it out
|
<!-- Text option not fully defined yet, leave it out
|
||||||
<row><entry>Option Text</entry><entry>option[code].text</entry><entry>The value of the option with code "code" from the packet as text</entry></row>
|
<row>
|
||||||
|
<entry>Option Text</entry>
|
||||||
|
<entry>option[123].text</entry>
|
||||||
|
<entry>'foobar'</entry>
|
||||||
|
<entry>The value of the option with given code from the
|
||||||
|
packet as text</entry>
|
||||||
|
</row>
|
||||||
-->
|
-->
|
||||||
<row><entry>Option Hex</entry><entry>option[code].hex</entry><entry>The value of the option with code "code" from the packet as hex</entry></row>
|
<row>
|
||||||
<row><entry>Option Exist</entry><entry>option[code].exist</entry><entry>If the option with code "code" is present in the packet "true" else "false"</entry></row>
|
<entry>Option existence</entry>
|
||||||
<row><entry>DHCPv4 Relay Agent
|
<entry>option[123].exist</entry>
|
||||||
sub-option</entry><entry>relay4[code].hex</entry><entry>The value of
|
<entry>'true'</entry>
|
||||||
sub-option with code "code" from the DHCPv4 Relay Agent Information option
|
<entry>If the option with given code is present in the
|
||||||
(option 82)</entry></row>
|
packet "true" else "false"</entry>
|
||||||
<row>
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry>DHCPv4 relay agent sub-option</entry>
|
||||||
|
<entry>relay4[123].hex</entry>
|
||||||
|
<entry>'(content of the RAI sub-option)'</entry>
|
||||||
|
<entry>The value of sub-option with given code from the
|
||||||
|
DHCPv4 Relay Agent Information option (option 82)</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
<entry>DHCPv6 Relay Options</entry>
|
<entry>DHCPv6 Relay Options</entry>
|
||||||
<entry>relay6[nest].option[code].hex</entry>
|
<entry>relay6[nest].option[code].hex</entry>
|
||||||
<!-- <entry>Value of the option</entry> -->
|
<!-- <entry>Value of the option</entry> -->
|
||||||
<entry>The value of the option with code "code" from the relay encapsulation "nest"</entry>
|
<entry>The value of the option with code "code" from the
|
||||||
</row>
|
relay encapsulation "nest"</entry>
|
||||||
<row>
|
</row>
|
||||||
|
<row>
|
||||||
<entry>DHCPv6 Relay Peer Address</entry>
|
<entry>DHCPv6 Relay Peer Address</entry>
|
||||||
<entry>relay6[nest].peeraddr</entry>
|
<entry>relay6[nest].peeraddr</entry>
|
||||||
<!-- <entry>2001:DB8::1</entry> -->n
|
<!-- <entry>2001:DB8::1</entry> -->n
|
||||||
<entry>The value of the peer address field from the relay encapsulation "nest"</entry>
|
<entry>The value of the peer address field from the
|
||||||
</row>
|
relay encapsulation "nest"</entry>
|
||||||
<row>
|
</row>
|
||||||
|
<row>
|
||||||
<entry>DHCPv6 Relay Link Address</entry>
|
<entry>DHCPv6 Relay Link Address</entry>
|
||||||
<entry>relay6[nest].linkaddr</entry>
|
<entry>relay6[nest].linkaddr</entry>
|
||||||
<!-- <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
|
||||||
</row>
|
relay encapsulation "nest"</entry>
|
||||||
<row>
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry>Hardware address in DHCPv4 packet</entry>
|
||||||
|
<entry>pkt4.mac</entry>
|
||||||
|
<entry>0x010203040506</entry>
|
||||||
|
<entry>The value of the chaddr field of the DHCPv4 packet, hlen (0 to 16) bytes</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry>Hardware length in DHCPv4 packet</entry>
|
||||||
|
<entry>pkt4.hlen</entry>
|
||||||
|
<entry>0x00000006</entry>
|
||||||
|
<entry>The value of the hlen field of the DHCPv4 packet padded to 4 bytes</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry>Hardware type in DHCPv4 packet</entry>
|
||||||
|
<entry>pkt4.htype</entry>
|
||||||
|
<entry>0x0000007b</entry>
|
||||||
|
<entry>The value of the htype field of the DHCPv4 packet padded to 4 bytes</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry>ciaddr field in DHCPv4 packet</entry>
|
||||||
|
<entry>pkt4.ciaddr</entry>
|
||||||
|
<entry>192.0.2.1</entry>
|
||||||
|
<entry>The value of the ciaddr field of the DHCPv4 packet (IPv4 address, 4 bytes)</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry>giaddr field in DHCPv4 packet</entry>
|
||||||
|
<entry>pkt4.giaddr</entry>
|
||||||
|
<entry>192.0.2.1</entry>
|
||||||
|
<entry>The value of the giaddr field of the DHCPv4 packet (IPv4 address, 4 bytes)</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry>yiaddr field in DHCPv4 packet</entry>
|
||||||
|
<entry>pkt4.yiaddr</entry>
|
||||||
|
<entry>192.0.2.1</entry>
|
||||||
|
<entry>The value of the yiaddr field of the DHCPv4 packet (IPv4 address, 4 bytes)</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
|
<entry>siaddr field in DHCPv4 packet</entry>
|
||||||
|
<entry>pkt4.siaddr</entry>
|
||||||
|
<entry>192.0.2.1</entry>
|
||||||
|
<entry>The value of the siaddr field of the DHCPv4 packet (IPv4 address, 4 bytes)</entry>
|
||||||
|
</row>
|
||||||
|
<row>
|
||||||
<entry>Message Type in DHCPv6 packet</entry>
|
<entry>Message Type in DHCPv6 packet</entry>
|
||||||
<entry>pkt6.msgtype</entry>
|
<entry>pkt6.msgtype</entry>
|
||||||
<!-- <entry>1</entry>
|
<!-- <entry>1</entry> -->
|
||||||
-->
|
<entry>The value of the message type field in the DHCPv6
|
||||||
<entry>The value of the message type field in the DHCPv6 packet.</entry>
|
packet.</entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
<row>
|
||||||
<entry>Transaction ID in DHCPv6 packet</entry>
|
<entry>Transaction ID in DHCPv6 packet</entry>
|
||||||
<entry>pkt6.transid</entry>
|
<entry>pkt6.transid</entry>
|
||||||
<!-- <entry>12345</entry>
|
<!-- <entry>12345</entry> -->
|
||||||
-->
|
<entry>The value of the transaction id in the DHCPv6
|
||||||
<entry>The value of the transaction id in the DHCPv6 packet.</entry>
|
packet.</entry>
|
||||||
</row>
|
</row>
|
||||||
</tbody>
|
</tbody>
|
||||||
</tgroup>
|
</tgroup>
|
||||||
</table>
|
</table>
|
||||||
@@ -221,14 +310,14 @@ sub-option with code "code" from the DHCPv4 Relay Agent Information option
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
"option[code].hex" extracts the value of the option with the given code
|
"option[code].hex" extracts the value of the option with the code "code"
|
||||||
from the incoming packet. If the packet doesn't contain the option, it
|
from the incoming packet. If the packet doesn't contain the option, it
|
||||||
returns the empty string. The string is presented as a byte string of
|
returns the empty string. The string is presented as a byte string of
|
||||||
the option payload without the type code or length fields.
|
the option payload without the type code or length fields.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
"option[code].exist" checks if an option with the given code is present
|
"option[code].exist" checks if an option with the code "code" is present
|
||||||
in the incoming packet. It can be used with empty options.
|
in the incoming packet. It can be used with empty options.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@@ -261,6 +350,10 @@ sub-option with code "code" from the DHCPv4 Relay Agent Information option
|
|||||||
"option", for instance "relay6[nest].option[code].exists" is supported.
|
"option", for instance "relay6[nest].option[code].exists" is supported.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
Expressions starting with pkt4 can be used only in DHCPv4.
|
||||||
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
"pkt6" refers to information from the client request. To access any
|
"pkt6" refers to information from the client request. To access any
|
||||||
information from an intermediate relay use "relay6". "pkt6.msgtype"
|
information from an intermediate relay use "relay6". "pkt6.msgtype"
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -149,6 +149,14 @@ addr6 [0-9a-fA-F]*\:[0-9a-fA-F]*\:[0-9a-fA-F:.]*
|
|||||||
"text" return isc::eval::EvalParser::make_TEXT(loc);
|
"text" return isc::eval::EvalParser::make_TEXT(loc);
|
||||||
"hex" return isc::eval::EvalParser::make_HEX(loc);
|
"hex" return isc::eval::EvalParser::make_HEX(loc);
|
||||||
"exists" return isc::eval::EvalParser::make_EXISTS(loc);
|
"exists" return isc::eval::EvalParser::make_EXISTS(loc);
|
||||||
|
"pkt4" return isc::eval::EvalParser::make_PKT4(loc);
|
||||||
|
"mac" return isc::eval::EvalParser::make_CHADDR(loc);
|
||||||
|
"hlen" return isc::eval::EvalParser::make_HLEN(loc);
|
||||||
|
"htype" return isc::eval::EvalParser::make_HTYPE(loc);
|
||||||
|
"ciaddr" return isc::eval::EvalParser::make_CIADDR(loc);
|
||||||
|
"giaddr" return isc::eval::EvalParser::make_GIADDR(loc);
|
||||||
|
"yiaddr" return isc::eval::EvalParser::make_YIADDR(loc);
|
||||||
|
"siaddr" return isc::eval::EvalParser::make_SIADDR(loc);
|
||||||
"substring" return isc::eval::EvalParser::make_SUBSTRING(loc);
|
"substring" return isc::eval::EvalParser::make_SUBSTRING(loc);
|
||||||
"all" return isc::eval::EvalParser::make_ALL(loc);
|
"all" return isc::eval::EvalParser::make_ALL(loc);
|
||||||
"concat" return isc::eval::EvalParser::make_CONCAT(loc);
|
"concat" return isc::eval::EvalParser::make_CONCAT(loc);
|
||||||
|
@@ -251,31 +251,35 @@ namespace isc { namespace eval {
|
|||||||
{
|
{
|
||||||
switch (that.type_get ())
|
switch (that.type_get ())
|
||||||
{
|
{
|
||||||
case 37: // option_repr_type
|
case 45: // option_repr_type
|
||||||
value.move< TokenOption::RepresentationType > (that.value);
|
value.move< TokenOption::RepresentationType > (that.value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 42: // pkt6_field
|
case 46: // pkt4_field
|
||||||
|
value.move< TokenPkt4::FieldType > (that.value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 51: // pkt6_field
|
||||||
value.move< TokenPkt6::FieldType > (that.value);
|
value.move< TokenPkt6::FieldType > (that.value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 40: // relay6_field
|
case 49: // relay6_field
|
||||||
value.move< TokenRelay6Field::FieldType > (that.value);
|
value.move< TokenRelay6Field::FieldType > (that.value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 27: // "constant string"
|
case 35: // "constant string"
|
||||||
case 28: // "integer"
|
case 36: // "integer"
|
||||||
case 29: // "constant hexstring"
|
case 37: // "constant hexstring"
|
||||||
case 30: // "option name"
|
case 38: // "option name"
|
||||||
case 31: // "ip address"
|
case 39: // "ip address"
|
||||||
value.move< std::string > (that.value);
|
value.move< std::string > (that.value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 36: // option_code
|
case 44: // option_code
|
||||||
value.move< uint16_t > (that.value);
|
value.move< uint16_t > (that.value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 41: // nest_level
|
case 50: // nest_level
|
||||||
value.move< uint8_t > (that.value);
|
value.move< uint8_t > (that.value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -294,31 +298,35 @@ namespace isc { namespace eval {
|
|||||||
state = that.state;
|
state = that.state;
|
||||||
switch (that.type_get ())
|
switch (that.type_get ())
|
||||||
{
|
{
|
||||||
case 37: // option_repr_type
|
case 45: // option_repr_type
|
||||||
value.copy< TokenOption::RepresentationType > (that.value);
|
value.copy< TokenOption::RepresentationType > (that.value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 42: // pkt6_field
|
case 46: // pkt4_field
|
||||||
|
value.copy< TokenPkt4::FieldType > (that.value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 51: // pkt6_field
|
||||||
value.copy< TokenPkt6::FieldType > (that.value);
|
value.copy< TokenPkt6::FieldType > (that.value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 40: // relay6_field
|
case 49: // relay6_field
|
||||||
value.copy< TokenRelay6Field::FieldType > (that.value);
|
value.copy< TokenRelay6Field::FieldType > (that.value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 27: // "constant string"
|
case 35: // "constant string"
|
||||||
case 28: // "integer"
|
case 36: // "integer"
|
||||||
case 29: // "constant hexstring"
|
case 37: // "constant hexstring"
|
||||||
case 30: // "option name"
|
case 38: // "option name"
|
||||||
case 31: // "ip address"
|
case 39: // "ip address"
|
||||||
value.copy< std::string > (that.value);
|
value.copy< std::string > (that.value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 36: // option_code
|
case 44: // option_code
|
||||||
value.copy< uint16_t > (that.value);
|
value.copy< uint16_t > (that.value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 41: // nest_level
|
case 50: // nest_level
|
||||||
value.copy< uint8_t > (that.value);
|
value.copy< uint8_t > (that.value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -358,74 +366,81 @@ namespace isc { namespace eval {
|
|||||||
<< yysym.location << ": ";
|
<< yysym.location << ": ";
|
||||||
switch (yytype)
|
switch (yytype)
|
||||||
{
|
{
|
||||||
case 27: // "constant string"
|
case 35: // "constant string"
|
||||||
|
|
||||||
#line 82 "parser.yy" // lalr1.cc:636
|
#line 91 "parser.yy" // lalr1.cc:636
|
||||||
{ yyoutput << yysym.value.template as< std::string > (); }
|
{ yyoutput << yysym.value.template as< std::string > (); }
|
||||||
#line 366 "parser.cc" // lalr1.cc:636
|
#line 374 "parser.cc" // lalr1.cc:636
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 28: // "integer"
|
case 36: // "integer"
|
||||||
|
|
||||||
#line 82 "parser.yy" // lalr1.cc:636
|
#line 91 "parser.yy" // lalr1.cc:636
|
||||||
{ yyoutput << yysym.value.template as< std::string > (); }
|
{ yyoutput << yysym.value.template as< std::string > (); }
|
||||||
#line 373 "parser.cc" // lalr1.cc:636
|
#line 381 "parser.cc" // lalr1.cc:636
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 29: // "constant hexstring"
|
case 37: // "constant hexstring"
|
||||||
|
|
||||||
#line 82 "parser.yy" // lalr1.cc:636
|
#line 91 "parser.yy" // lalr1.cc:636
|
||||||
{ yyoutput << yysym.value.template as< std::string > (); }
|
{ yyoutput << yysym.value.template as< std::string > (); }
|
||||||
#line 380 "parser.cc" // lalr1.cc:636
|
#line 388 "parser.cc" // lalr1.cc:636
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 30: // "option name"
|
case 38: // "option name"
|
||||||
|
|
||||||
#line 82 "parser.yy" // lalr1.cc:636
|
#line 91 "parser.yy" // lalr1.cc:636
|
||||||
{ yyoutput << yysym.value.template as< std::string > (); }
|
{ yyoutput << yysym.value.template as< std::string > (); }
|
||||||
#line 387 "parser.cc" // lalr1.cc:636
|
#line 395 "parser.cc" // lalr1.cc:636
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 31: // "ip address"
|
case 39: // "ip address"
|
||||||
|
|
||||||
#line 82 "parser.yy" // lalr1.cc:636
|
#line 91 "parser.yy" // lalr1.cc:636
|
||||||
{ yyoutput << yysym.value.template as< std::string > (); }
|
{ yyoutput << yysym.value.template as< std::string > (); }
|
||||||
#line 394 "parser.cc" // lalr1.cc:636
|
#line 402 "parser.cc" // lalr1.cc:636
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 36: // option_code
|
case 44: // option_code
|
||||||
|
|
||||||
#line 82 "parser.yy" // lalr1.cc:636
|
#line 91 "parser.yy" // lalr1.cc:636
|
||||||
{ yyoutput << yysym.value.template as< uint16_t > (); }
|
{ yyoutput << yysym.value.template as< uint16_t > (); }
|
||||||
#line 401 "parser.cc" // lalr1.cc:636
|
#line 409 "parser.cc" // lalr1.cc:636
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 37: // option_repr_type
|
case 45: // option_repr_type
|
||||||
|
|
||||||
#line 82 "parser.yy" // lalr1.cc:636
|
#line 91 "parser.yy" // lalr1.cc:636
|
||||||
{ yyoutput << yysym.value.template as< TokenOption::RepresentationType > (); }
|
{ yyoutput << yysym.value.template as< TokenOption::RepresentationType > (); }
|
||||||
#line 408 "parser.cc" // lalr1.cc:636
|
#line 416 "parser.cc" // lalr1.cc:636
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 40: // relay6_field
|
case 46: // pkt4_field
|
||||||
|
|
||||||
#line 82 "parser.yy" // lalr1.cc:636
|
#line 91 "parser.yy" // lalr1.cc:636
|
||||||
|
{ yyoutput << yysym.value.template as< TokenPkt4::FieldType > (); }
|
||||||
|
#line 423 "parser.cc" // lalr1.cc:636
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 49: // relay6_field
|
||||||
|
|
||||||
|
#line 91 "parser.yy" // lalr1.cc:636
|
||||||
{ yyoutput << yysym.value.template as< TokenRelay6Field::FieldType > (); }
|
{ yyoutput << yysym.value.template as< TokenRelay6Field::FieldType > (); }
|
||||||
#line 415 "parser.cc" // lalr1.cc:636
|
#line 430 "parser.cc" // lalr1.cc:636
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 41: // nest_level
|
case 50: // nest_level
|
||||||
|
|
||||||
#line 82 "parser.yy" // lalr1.cc:636
|
#line 91 "parser.yy" // lalr1.cc:636
|
||||||
{ yyoutput << yysym.value.template as< uint8_t > (); }
|
{ yyoutput << yysym.value.template as< uint8_t > (); }
|
||||||
#line 422 "parser.cc" // lalr1.cc:636
|
#line 437 "parser.cc" // lalr1.cc:636
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 42: // pkt6_field
|
case 51: // pkt6_field
|
||||||
|
|
||||||
#line 82 "parser.yy" // lalr1.cc:636
|
#line 91 "parser.yy" // lalr1.cc:636
|
||||||
{ yyoutput << yysym.value.template as< TokenPkt6::FieldType > (); }
|
{ yyoutput << yysym.value.template as< TokenPkt6::FieldType > (); }
|
||||||
#line 429 "parser.cc" // lalr1.cc:636
|
#line 444 "parser.cc" // lalr1.cc:636
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
@@ -625,31 +640,35 @@ namespace isc { namespace eval {
|
|||||||
when using variants. */
|
when using variants. */
|
||||||
switch (yyr1_[yyn])
|
switch (yyr1_[yyn])
|
||||||
{
|
{
|
||||||
case 37: // option_repr_type
|
case 45: // option_repr_type
|
||||||
yylhs.value.build< TokenOption::RepresentationType > ();
|
yylhs.value.build< TokenOption::RepresentationType > ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 42: // pkt6_field
|
case 46: // pkt4_field
|
||||||
|
yylhs.value.build< TokenPkt4::FieldType > ();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 51: // pkt6_field
|
||||||
yylhs.value.build< TokenPkt6::FieldType > ();
|
yylhs.value.build< TokenPkt6::FieldType > ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 40: // relay6_field
|
case 49: // relay6_field
|
||||||
yylhs.value.build< TokenRelay6Field::FieldType > ();
|
yylhs.value.build< TokenRelay6Field::FieldType > ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 27: // "constant string"
|
case 35: // "constant string"
|
||||||
case 28: // "integer"
|
case 36: // "integer"
|
||||||
case 29: // "constant hexstring"
|
case 37: // "constant hexstring"
|
||||||
case 30: // "option name"
|
case 38: // "option name"
|
||||||
case 31: // "ip address"
|
case 39: // "ip address"
|
||||||
yylhs.value.build< std::string > ();
|
yylhs.value.build< std::string > ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 36: // option_code
|
case 44: // option_code
|
||||||
yylhs.value.build< uint16_t > ();
|
yylhs.value.build< uint16_t > ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 41: // nest_level
|
case 50: // nest_level
|
||||||
yylhs.value.build< uint8_t > ();
|
yylhs.value.build< uint8_t > ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -671,52 +690,52 @@ namespace isc { namespace eval {
|
|||||||
switch (yyn)
|
switch (yyn)
|
||||||
{
|
{
|
||||||
case 4:
|
case 4:
|
||||||
#line 96 "parser.yy" // lalr1.cc:859
|
#line 105 "parser.yy" // lalr1.cc:859
|
||||||
{
|
{
|
||||||
TokenPtr neg(new TokenNot());
|
TokenPtr neg(new TokenNot());
|
||||||
ctx.expression.push_back(neg);
|
ctx.expression.push_back(neg);
|
||||||
}
|
}
|
||||||
#line 680 "parser.cc" // lalr1.cc:859
|
#line 699 "parser.cc" // lalr1.cc:859
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 5:
|
case 5:
|
||||||
#line 101 "parser.yy" // lalr1.cc:859
|
#line 110 "parser.yy" // lalr1.cc:859
|
||||||
{
|
{
|
||||||
TokenPtr neg(new TokenAnd());
|
TokenPtr neg(new TokenAnd());
|
||||||
ctx.expression.push_back(neg);
|
ctx.expression.push_back(neg);
|
||||||
}
|
}
|
||||||
#line 689 "parser.cc" // lalr1.cc:859
|
#line 708 "parser.cc" // lalr1.cc:859
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 6:
|
case 6:
|
||||||
#line 106 "parser.yy" // lalr1.cc:859
|
#line 115 "parser.yy" // lalr1.cc:859
|
||||||
{
|
{
|
||||||
TokenPtr neg(new TokenOr());
|
TokenPtr neg(new TokenOr());
|
||||||
ctx.expression.push_back(neg);
|
ctx.expression.push_back(neg);
|
||||||
}
|
}
|
||||||
#line 698 "parser.cc" // lalr1.cc:859
|
#line 717 "parser.cc" // lalr1.cc:859
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 7:
|
case 7:
|
||||||
#line 111 "parser.yy" // lalr1.cc:859
|
#line 120 "parser.yy" // lalr1.cc:859
|
||||||
{
|
{
|
||||||
TokenPtr eq(new TokenEqual());
|
TokenPtr eq(new TokenEqual());
|
||||||
ctx.expression.push_back(eq);
|
ctx.expression.push_back(eq);
|
||||||
}
|
}
|
||||||
#line 707 "parser.cc" // lalr1.cc:859
|
#line 726 "parser.cc" // lalr1.cc:859
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 8:
|
case 8:
|
||||||
#line 116 "parser.yy" // lalr1.cc:859
|
#line 125 "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 716 "parser.cc" // lalr1.cc:859
|
#line 735 "parser.cc" // lalr1.cc:859
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 9:
|
case 9:
|
||||||
#line 121 "parser.yy" // lalr1.cc:859
|
#line 130 "parser.yy" // lalr1.cc:859
|
||||||
{
|
{
|
||||||
switch (ctx.getUniverse()) {
|
switch (ctx.getUniverse()) {
|
||||||
case Option::V4:
|
case Option::V4:
|
||||||
@@ -736,11 +755,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 740 "parser.cc" // lalr1.cc:859
|
#line 759 "parser.cc" // lalr1.cc:859
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 10:
|
case 10:
|
||||||
#line 141 "parser.yy" // lalr1.cc:859
|
#line 150 "parser.yy" // lalr1.cc:859
|
||||||
{
|
{
|
||||||
switch (ctx.getUniverse()) {
|
switch (ctx.getUniverse()) {
|
||||||
case Option::V6:
|
case Option::V6:
|
||||||
@@ -754,47 +773,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 758 "parser.cc" // lalr1.cc:859
|
#line 777 "parser.cc" // lalr1.cc:859
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 11:
|
case 11:
|
||||||
#line 157 "parser.yy" // lalr1.cc:859
|
#line 166 "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 767 "parser.cc" // lalr1.cc:859
|
#line 786 "parser.cc" // lalr1.cc:859
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 12:
|
case 12:
|
||||||
#line 162 "parser.yy" // lalr1.cc:859
|
#line 171 "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 776 "parser.cc" // lalr1.cc:859
|
#line 795 "parser.cc" // lalr1.cc:859
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 13:
|
case 13:
|
||||||
#line 167 "parser.yy" // lalr1.cc:859
|
#line 176 "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 785 "parser.cc" // lalr1.cc:859
|
#line 804 "parser.cc" // lalr1.cc:859
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 14:
|
case 14:
|
||||||
#line 172 "parser.yy" // lalr1.cc:859
|
#line 181 "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 794 "parser.cc" // lalr1.cc:859
|
#line 813 "parser.cc" // lalr1.cc:859
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 15:
|
case 15:
|
||||||
#line 177 "parser.yy" // lalr1.cc:859
|
#line 186 "parser.yy" // lalr1.cc:859
|
||||||
{
|
{
|
||||||
switch (ctx.getUniverse()) {
|
switch (ctx.getUniverse()) {
|
||||||
case Option::V4:
|
case Option::V4:
|
||||||
@@ -814,11 +833,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 818 "parser.cc" // lalr1.cc:859
|
#line 837 "parser.cc" // lalr1.cc:859
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 16:
|
case 16:
|
||||||
#line 198 "parser.yy" // lalr1.cc:859
|
#line 207 "parser.yy" // lalr1.cc:859
|
||||||
{
|
{
|
||||||
switch (ctx.getUniverse()) {
|
switch (ctx.getUniverse()) {
|
||||||
case Option::V6:
|
case Option::V6:
|
||||||
@@ -832,11 +851,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 836 "parser.cc" // lalr1.cc:859
|
#line 855 "parser.cc" // lalr1.cc:859
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 17:
|
case 17:
|
||||||
#line 213 "parser.yy" // lalr1.cc:859
|
#line 222 "parser.yy" // lalr1.cc:859
|
||||||
{
|
{
|
||||||
switch (ctx.getUniverse()) {
|
switch (ctx.getUniverse()) {
|
||||||
case Option::V6:
|
case Option::V6:
|
||||||
@@ -850,129 +869,194 @@ 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 854 "parser.cc" // lalr1.cc:859
|
#line 873 "parser.cc" // lalr1.cc:859
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 18:
|
case 18:
|
||||||
#line 229 "parser.yy" // lalr1.cc:859
|
#line 237 "parser.yy" // lalr1.cc:859
|
||||||
{
|
{
|
||||||
TokenPtr sub(new TokenSubstring());
|
TokenPtr pkt4_field(new TokenPkt4(yystack_[0].value.as< TokenPkt4::FieldType > ()));
|
||||||
ctx.expression.push_back(sub);
|
ctx.expression.push_back(pkt4_field);
|
||||||
}
|
}
|
||||||
#line 863 "parser.cc" // lalr1.cc:859
|
#line 882 "parser.cc" // lalr1.cc:859
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 19:
|
case 19:
|
||||||
#line 234 "parser.yy" // lalr1.cc:859
|
#line 242 "parser.yy" // lalr1.cc:859
|
||||||
{
|
|
||||||
TokenPtr conc(new TokenConcat());
|
|
||||||
ctx.expression.push_back(conc);
|
|
||||||
}
|
|
||||||
#line 872 "parser.cc" // lalr1.cc:859
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 20:
|
|
||||||
#line 239 "parser.yy" // lalr1.cc:859
|
|
||||||
{
|
{
|
||||||
TokenPtr pkt6_field(new TokenPkt6(yystack_[0].value.as< TokenPkt6::FieldType > ()));
|
TokenPtr pkt6_field(new TokenPkt6(yystack_[0].value.as< TokenPkt6::FieldType > ()));
|
||||||
ctx.expression.push_back(pkt6_field);
|
ctx.expression.push_back(pkt6_field);
|
||||||
}
|
}
|
||||||
#line 881 "parser.cc" // lalr1.cc:859
|
#line 891 "parser.cc" // lalr1.cc:859
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 20:
|
||||||
|
#line 247 "parser.yy" // lalr1.cc:859
|
||||||
|
{
|
||||||
|
TokenPtr sub(new TokenSubstring());
|
||||||
|
ctx.expression.push_back(sub);
|
||||||
|
}
|
||||||
|
#line 900 "parser.cc" // lalr1.cc:859
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 21:
|
case 21:
|
||||||
#line 246 "parser.yy" // lalr1.cc:859
|
#line 252 "parser.yy" // lalr1.cc:859
|
||||||
{
|
{
|
||||||
yylhs.value.as< uint16_t > () = ctx.convertOptionCode(yystack_[0].value.as< std::string > (), yystack_[0].location);
|
TokenPtr conc(new TokenConcat());
|
||||||
|
ctx.expression.push_back(conc);
|
||||||
}
|
}
|
||||||
#line 889 "parser.cc" // lalr1.cc:859
|
#line 909 "parser.cc" // lalr1.cc:859
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 22:
|
case 22:
|
||||||
#line 250 "parser.yy" // lalr1.cc:859
|
#line 259 "parser.yy" // lalr1.cc:859
|
||||||
{
|
{
|
||||||
yylhs.value.as< uint16_t > () = ctx.convertOptionName(yystack_[0].value.as< std::string > (), yystack_[0].location);
|
yylhs.value.as< uint16_t > () = ctx.convertOptionCode(yystack_[0].value.as< std::string > (), yystack_[0].location);
|
||||||
}
|
}
|
||||||
#line 897 "parser.cc" // lalr1.cc:859
|
#line 917 "parser.cc" // lalr1.cc:859
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 23:
|
case 23:
|
||||||
#line 256 "parser.yy" // lalr1.cc:859
|
#line 263 "parser.yy" // lalr1.cc:859
|
||||||
{
|
{
|
||||||
yylhs.value.as< TokenOption::RepresentationType > () = TokenOption::TEXTUAL;
|
yylhs.value.as< uint16_t > () = ctx.convertOptionName(yystack_[0].value.as< std::string > (), yystack_[0].location);
|
||||||
}
|
}
|
||||||
#line 905 "parser.cc" // lalr1.cc:859
|
#line 925 "parser.cc" // lalr1.cc:859
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 24:
|
case 24:
|
||||||
#line 260 "parser.yy" // lalr1.cc:859
|
#line 269 "parser.yy" // lalr1.cc:859
|
||||||
{
|
{
|
||||||
yylhs.value.as< TokenOption::RepresentationType > () = TokenOption::HEXADECIMAL;
|
yylhs.value.as< TokenOption::RepresentationType > () = TokenOption::TEXTUAL;
|
||||||
}
|
}
|
||||||
#line 913 "parser.cc" // lalr1.cc:859
|
#line 933 "parser.cc" // lalr1.cc:859
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 25:
|
case 25:
|
||||||
#line 266 "parser.yy" // lalr1.cc:859
|
#line 273 "parser.yy" // lalr1.cc:859
|
||||||
{
|
{
|
||||||
TokenPtr str(new TokenString(yystack_[0].value.as< std::string > ()));
|
yylhs.value.as< TokenOption::RepresentationType > () = TokenOption::HEXADECIMAL;
|
||||||
ctx.expression.push_back(str);
|
|
||||||
}
|
}
|
||||||
#line 922 "parser.cc" // lalr1.cc:859
|
#line 941 "parser.cc" // lalr1.cc:859
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 26:
|
case 26:
|
||||||
#line 273 "parser.yy" // lalr1.cc:859
|
#line 279 "parser.yy" // lalr1.cc:859
|
||||||
|
{
|
||||||
|
yylhs.value.as< TokenPkt4::FieldType > () = TokenPkt4::CHADDR;
|
||||||
|
}
|
||||||
|
#line 949 "parser.cc" // lalr1.cc:859
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 27:
|
||||||
|
#line 283 "parser.yy" // lalr1.cc:859
|
||||||
|
{
|
||||||
|
yylhs.value.as< TokenPkt4::FieldType > () = TokenPkt4::HLEN;
|
||||||
|
}
|
||||||
|
#line 957 "parser.cc" // lalr1.cc:859
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 28:
|
||||||
|
#line 287 "parser.yy" // lalr1.cc:859
|
||||||
|
{
|
||||||
|
yylhs.value.as< TokenPkt4::FieldType > () = TokenPkt4::HTYPE;
|
||||||
|
}
|
||||||
|
#line 965 "parser.cc" // lalr1.cc:859
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 29:
|
||||||
|
#line 291 "parser.yy" // lalr1.cc:859
|
||||||
|
{
|
||||||
|
yylhs.value.as< TokenPkt4::FieldType > () = TokenPkt4::CIADDR;
|
||||||
|
}
|
||||||
|
#line 973 "parser.cc" // lalr1.cc:859
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 30:
|
||||||
|
#line 295 "parser.yy" // lalr1.cc:859
|
||||||
|
{
|
||||||
|
yylhs.value.as< TokenPkt4::FieldType > () = TokenPkt4::GIADDR;
|
||||||
|
}
|
||||||
|
#line 981 "parser.cc" // lalr1.cc:859
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 31:
|
||||||
|
#line 299 "parser.yy" // lalr1.cc:859
|
||||||
|
{
|
||||||
|
yylhs.value.as< TokenPkt4::FieldType > () = TokenPkt4::YIADDR;
|
||||||
|
}
|
||||||
|
#line 989 "parser.cc" // lalr1.cc:859
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 32:
|
||||||
|
#line 303 "parser.yy" // lalr1.cc:859
|
||||||
|
{
|
||||||
|
yylhs.value.as< TokenPkt4::FieldType > () = TokenPkt4::SIADDR;
|
||||||
|
}
|
||||||
|
#line 997 "parser.cc" // lalr1.cc:859
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 33:
|
||||||
|
#line 309 "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 931 "parser.cc" // lalr1.cc:859
|
#line 1006 "parser.cc" // lalr1.cc:859
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 27:
|
case 34:
|
||||||
#line 278 "parser.yy" // lalr1.cc:859
|
#line 316 "parser.yy" // lalr1.cc:859
|
||||||
|
{
|
||||||
|
TokenPtr str(new TokenString(yystack_[0].value.as< std::string > ()));
|
||||||
|
ctx.expression.push_back(str);
|
||||||
|
}
|
||||||
|
#line 1015 "parser.cc" // lalr1.cc:859
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 35:
|
||||||
|
#line 321 "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 940 "parser.cc" // lalr1.cc:859
|
#line 1024 "parser.cc" // lalr1.cc:859
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 28:
|
case 36:
|
||||||
#line 284 "parser.yy" // lalr1.cc:859
|
#line 327 "parser.yy" // lalr1.cc:859
|
||||||
{ yylhs.value.as< TokenRelay6Field::FieldType > () = TokenRelay6Field::PEERADDR; }
|
{ yylhs.value.as< TokenRelay6Field::FieldType > () = TokenRelay6Field::PEERADDR; }
|
||||||
#line 946 "parser.cc" // lalr1.cc:859
|
#line 1030 "parser.cc" // lalr1.cc:859
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 29:
|
case 37:
|
||||||
#line 285 "parser.yy" // lalr1.cc:859
|
#line 328 "parser.yy" // lalr1.cc:859
|
||||||
{ yylhs.value.as< TokenRelay6Field::FieldType > () = TokenRelay6Field::LINKADDR; }
|
{ yylhs.value.as< TokenRelay6Field::FieldType > () = TokenRelay6Field::LINKADDR; }
|
||||||
#line 952 "parser.cc" // lalr1.cc:859
|
#line 1036 "parser.cc" // lalr1.cc:859
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 30:
|
case 38:
|
||||||
#line 289 "parser.yy" // lalr1.cc:859
|
#line 332 "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 960 "parser.cc" // lalr1.cc:859
|
#line 1044 "parser.cc" // lalr1.cc:859
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 31:
|
case 39:
|
||||||
#line 297 "parser.yy" // lalr1.cc:859
|
#line 340 "parser.yy" // lalr1.cc:859
|
||||||
{ yylhs.value.as< TokenPkt6::FieldType > () = TokenPkt6::MSGTYPE; }
|
{ yylhs.value.as< TokenPkt6::FieldType > () = TokenPkt6::MSGTYPE; }
|
||||||
#line 966 "parser.cc" // lalr1.cc:859
|
#line 1050 "parser.cc" // lalr1.cc:859
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 32:
|
case 40:
|
||||||
#line 298 "parser.yy" // lalr1.cc:859
|
#line 341 "parser.yy" // lalr1.cc:859
|
||||||
{ yylhs.value.as< TokenPkt6::FieldType > () = TokenPkt6::TRANSID; }
|
{ yylhs.value.as< TokenPkt6::FieldType > () = TokenPkt6::TRANSID; }
|
||||||
#line 972 "parser.cc" // lalr1.cc:859
|
#line 1056 "parser.cc" // lalr1.cc:859
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
#line 976 "parser.cc" // lalr1.cc:859
|
#line 1060 "parser.cc" // lalr1.cc:859
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1227,117 +1311,124 @@ namespace isc { namespace eval {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const signed char EvalParser::yypact_ninf_ = -54;
|
const signed char EvalParser::yypact_ninf_ = -62;
|
||||||
|
|
||||||
const signed char EvalParser::yytable_ninf_ = -1;
|
const signed char EvalParser::yytable_ninf_ = -1;
|
||||||
|
|
||||||
const signed char
|
const signed char
|
||||||
EvalParser::yypact_[] =
|
EvalParser::yypact_[] =
|
||||||
{
|
{
|
||||||
29, 29, 29, -12, -4, 7, 21, 30, 32, -54,
|
14, 14, 14, 6, 17, 18, 21, 41, 44, 48,
|
||||||
-54, -54, 13, 10, 46, 16, -54, -3, -3, 9,
|
-62, -62, -62, 72, 20, 66, 29, -62, 12, 12,
|
||||||
52, 52, 42, -54, 29, 29, 52, -54, -54, -54,
|
16, 36, 45, 45, -24, -62, 14, 14, 45, -62,
|
||||||
40, 54, -54, 56, 43, 59, 60, 55, 58, -54,
|
-62, -62, 60, 63, -62, 73, -62, -62, -62, -62,
|
||||||
-54, -54, -54, 72, -54, 66, 68, 69, -3, -3,
|
-62, -62, -62, -62, 67, 69, 75, 61, 62, -62,
|
||||||
9, 61, 52, 25, 28, -1, 71, 73, 75, -54,
|
-62, -62, -62, 84, -62, 77, 78, 79, 12, 12,
|
||||||
65, 87, -54, -54, -54, -54, -54, -54, 78, -54,
|
16, 64, 45, -3, 52, -1, 81, 82, 83, -62,
|
||||||
-54, -54, 77, 79, 80, -14, -54, -3, 33, 33,
|
71, 95, -62, -62, -62, -62, -62, -62, 88, -62,
|
||||||
6, -54, -54, 90, 82, 84, -54, 83, -3, 47,
|
-62, -62, 87, 89, 90, -23, -62, 12, 49, 49,
|
||||||
85, -54, -54, 86, 33
|
9, -62, -62, 100, 92, 94, -62, 93, 12, 68,
|
||||||
|
96, -62, -62, 97, 49
|
||||||
};
|
};
|
||||||
|
|
||||||
const unsigned char
|
const unsigned char
|
||||||
EvalParser::yydefact_[] =
|
EvalParser::yydefact_[] =
|
||||||
{
|
{
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 11,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
12, 13, 0, 2, 0, 0, 4, 0, 0, 0,
|
11, 12, 13, 0, 2, 0, 0, 4, 0, 0,
|
||||||
0, 0, 0, 1, 0, 0, 0, 3, 21, 22,
|
0, 0, 0, 0, 0, 1, 0, 0, 0, 3,
|
||||||
0, 0, 30, 0, 0, 0, 0, 0, 0, 31,
|
22, 23, 0, 0, 38, 0, 26, 27, 28, 29,
|
||||||
32, 20, 5, 6, 7, 0, 0, 0, 0, 0,
|
30, 31, 32, 18, 0, 0, 0, 0, 0, 39,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 25,
|
40, 19, 5, 6, 7, 0, 0, 0, 0, 0,
|
||||||
0, 0, 23, 24, 8, 14, 9, 15, 0, 28,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 33,
|
||||||
29, 17, 0, 0, 0, 0, 19, 0, 0, 0,
|
0, 0, 24, 25, 8, 14, 9, 15, 0, 36,
|
||||||
0, 27, 26, 0, 0, 0, 18, 0, 0, 0,
|
37, 17, 0, 0, 0, 0, 21, 0, 0, 0,
|
||||||
|
0, 35, 34, 0, 0, 0, 20, 0, 0, 0,
|
||||||
0, 10, 16, 0, 0
|
0, 10, 16, 0, 0
|
||||||
};
|
};
|
||||||
|
|
||||||
const signed char
|
const signed char
|
||||||
EvalParser::yypgoto_[] =
|
EvalParser::yypgoto_[] =
|
||||||
{
|
{
|
||||||
-54, -54, 4, -17, -18, -53, -54, -54, -54, 51,
|
-62, -62, 3, -21, -19, -61, -62, -62, -62, -62,
|
||||||
-54
|
50, -62
|
||||||
};
|
};
|
||||||
|
|
||||||
const signed char
|
const signed char
|
||||||
EvalParser::yydefgoto_[] =
|
EvalParser::yydefgoto_[] =
|
||||||
{
|
{
|
||||||
-1, 12, 13, 14, 30, 65, 60, 83, 71, 33,
|
-1, 13, 14, 15, 32, 75, 43, 70, 93, 81,
|
||||||
41
|
35, 51
|
||||||
};
|
};
|
||||||
|
|
||||||
const unsigned char
|
const unsigned char
|
||||||
EvalParser::yytable_[] =
|
EvalParser::yytable_[] =
|
||||||
{
|
{
|
||||||
31, 67, 17, 37, 38, 15, 16, 81, 68, 44,
|
33, 47, 48, 77, 16, 17, 91, 54, 78, 49,
|
||||||
18, 69, 70, 23, 82, 85, 24, 25, 69, 70,
|
50, 79, 80, 92, 72, 73, 74, 1, 95, 2,
|
||||||
27, 19, 24, 25, 20, 28, 67, 29, 42, 43,
|
18, 79, 80, 3, 4, 5, 26, 27, 77, 52,
|
||||||
56, 57, 1, 21, 2, 61, 92, 32, 3, 4,
|
53, 19, 20, 29, 6, 26, 27, 21, 102, 66,
|
||||||
5, 92, 62, 63, 64, 62, 63, 66, 22, 6,
|
67, 71, 7, 102, 22, 8, 9, 23, 30, 10,
|
||||||
62, 63, 7, 8, 26, 45, 9, 48, 10, 84,
|
31, 11, 34, 12, 44, 45, 46, 36, 37, 38,
|
||||||
11, 34, 35, 36, 62, 63, 91, 39, 40, 46,
|
39, 40, 41, 42, 24, 6, 72, 73, 94, 72,
|
||||||
90, 47, 6, 49, 50, 7, 8, 51, 24, 9,
|
73, 76, 25, 7, 28, 55, 8, 9, 56, 100,
|
||||||
52, 10, 53, 11, 54, 55, 72, 75, 73, 59,
|
10, 58, 11, 59, 12, 72, 73, 101, 57, 60,
|
||||||
74, 76, 77, 78, 86, 79, 80, 87, 88, 89,
|
26, 61, 62, 63, 64, 65, 82, 83, 84, 86,
|
||||||
93, 58, 94
|
69, 85, 87, 88, 96, 89, 90, 97, 98, 99,
|
||||||
|
68, 103, 0, 104
|
||||||
};
|
};
|
||||||
|
|
||||||
const unsigned char
|
const signed char
|
||||||
EvalParser::yycheck_[] =
|
EvalParser::yycheck_[] =
|
||||||
{
|
{
|
||||||
18, 54, 14, 20, 21, 1, 2, 21, 9, 26,
|
19, 22, 23, 64, 1, 2, 29, 28, 9, 33,
|
||||||
14, 12, 13, 0, 28, 9, 6, 7, 12, 13,
|
34, 12, 13, 36, 17, 18, 19, 3, 9, 5,
|
||||||
4, 14, 6, 7, 3, 28, 79, 30, 24, 25,
|
14, 12, 13, 9, 10, 11, 6, 7, 89, 26,
|
||||||
48, 49, 3, 3, 5, 52, 89, 28, 9, 10,
|
27, 14, 14, 4, 20, 6, 7, 16, 99, 58,
|
||||||
11, 94, 17, 18, 19, 17, 18, 19, 16, 20,
|
59, 62, 28, 104, 3, 31, 32, 3, 36, 35,
|
||||||
17, 18, 23, 24, 8, 15, 27, 14, 29, 77,
|
38, 37, 36, 39, 9, 10, 11, 21, 22, 23,
|
||||||
31, 9, 10, 11, 17, 18, 19, 25, 26, 15,
|
24, 25, 26, 27, 16, 20, 17, 18, 87, 17,
|
||||||
88, 15, 20, 14, 14, 23, 24, 22, 6, 27,
|
18, 19, 0, 28, 8, 15, 31, 32, 15, 98,
|
||||||
22, 29, 16, 31, 16, 16, 15, 22, 15, 28,
|
35, 14, 37, 14, 39, 17, 18, 19, 15, 14,
|
||||||
15, 4, 14, 16, 4, 16, 16, 15, 14, 16,
|
6, 30, 30, 16, 16, 16, 15, 15, 15, 4,
|
||||||
15, 50, 16
|
36, 30, 14, 16, 4, 16, 16, 15, 14, 16,
|
||||||
|
60, 15, -1, 16
|
||||||
};
|
};
|
||||||
|
|
||||||
const unsigned char
|
const unsigned char
|
||||||
EvalParser::yystos_[] =
|
EvalParser::yystos_[] =
|
||||||
{
|
{
|
||||||
0, 3, 5, 9, 10, 11, 20, 23, 24, 27,
|
0, 3, 5, 9, 10, 11, 20, 28, 31, 32,
|
||||||
29, 31, 33, 34, 35, 34, 34, 14, 14, 14,
|
35, 37, 39, 41, 42, 43, 42, 42, 14, 14,
|
||||||
3, 3, 16, 0, 6, 7, 8, 4, 28, 30,
|
14, 16, 3, 3, 16, 0, 6, 7, 8, 4,
|
||||||
36, 36, 28, 41, 9, 10, 11, 35, 35, 25,
|
36, 38, 44, 44, 36, 50, 21, 22, 23, 24,
|
||||||
26, 42, 34, 34, 35, 15, 15, 15, 14, 14,
|
25, 26, 27, 46, 9, 10, 11, 43, 43, 33,
|
||||||
14, 22, 22, 16, 16, 16, 36, 36, 41, 28,
|
34, 51, 42, 42, 43, 15, 15, 15, 14, 14,
|
||||||
38, 35, 17, 18, 19, 37, 19, 37, 9, 12,
|
14, 30, 30, 16, 16, 16, 44, 44, 50, 36,
|
||||||
13, 40, 15, 15, 15, 22, 4, 14, 16, 16,
|
47, 43, 17, 18, 19, 45, 19, 45, 9, 12,
|
||||||
16, 21, 28, 39, 36, 9, 4, 15, 14, 16,
|
13, 49, 15, 15, 15, 30, 4, 14, 16, 16,
|
||||||
36, 19, 37, 15, 16
|
16, 29, 36, 48, 44, 9, 4, 15, 14, 16,
|
||||||
|
44, 19, 45, 15, 16
|
||||||
};
|
};
|
||||||
|
|
||||||
const unsigned char
|
const unsigned char
|
||||||
EvalParser::yyr1_[] =
|
EvalParser::yyr1_[] =
|
||||||
{
|
{
|
||||||
0, 32, 33, 34, 34, 34, 34, 34, 34, 34,
|
0, 40, 41, 42, 42, 42, 42, 42, 42, 42,
|
||||||
34, 35, 35, 35, 35, 35, 35, 35, 35, 35,
|
42, 43, 43, 43, 43, 43, 43, 43, 43, 43,
|
||||||
35, 36, 36, 37, 37, 38, 39, 39, 40, 40,
|
43, 43, 44, 44, 45, 45, 46, 46, 46, 46,
|
||||||
41, 42, 42
|
46, 46, 46, 47, 48, 48, 49, 49, 50, 51,
|
||||||
|
51
|
||||||
};
|
};
|
||||||
|
|
||||||
const unsigned char
|
const unsigned char
|
||||||
EvalParser::yyr2_[] =
|
EvalParser::yyr2_[] =
|
||||||
{
|
{
|
||||||
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, 3, 3,
|
||||||
3, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
8, 6, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
1, 1, 1
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -1350,22 +1441,25 @@ namespace isc { namespace eval {
|
|||||||
"\"end of file\"", "error", "$undefined", "\"(\"", "\")\"", "\"not\"",
|
"\"end of file\"", "error", "$undefined", "\"(\"", "\")\"", "\"not\"",
|
||||||
"\"and\"", "\"or\"", "\"==\"", "\"option\"", "\"relay4\"", "\"relay6\"",
|
"\"and\"", "\"or\"", "\"==\"", "\"option\"", "\"relay4\"", "\"relay6\"",
|
||||||
"\"peeraddr\"", "\"linkaddr\"", "\"[\"", "\"]\"", "\".\"", "\"text\"",
|
"\"peeraddr\"", "\"linkaddr\"", "\"[\"", "\"]\"", "\".\"", "\"text\"",
|
||||||
"\"hex\"", "\"exists\"", "\"substring\"", "\"all\"", "\",\"",
|
"\"hex\"", "\"exists\"", "\"pkt4\"", "\"mac\"", "\"hlen\"", "\"htype\"",
|
||||||
"\"concat\"", "\"pkt6\"", "\"msgtype\"", "\"transid\"",
|
"\"ciaddr\"", "\"giaddr\"", "\"yiaddr\"", "\"siaddr\"", "\"substring\"",
|
||||||
"\"constant string\"", "\"integer\"", "\"constant hexstring\"",
|
"\"all\"", "\",\"", "\"concat\"", "\"pkt6\"", "\"msgtype\"",
|
||||||
"\"option name\"", "\"ip address\"", "$accept", "expression",
|
"\"transid\"", "\"constant string\"", "\"integer\"",
|
||||||
"bool_expr", "string_expr", "option_code", "option_repr_type",
|
"\"constant hexstring\"", "\"option name\"", "\"ip address\"", "$accept",
|
||||||
"start_expr", "length_expr", "relay6_field", "nest_level", "pkt6_field", YY_NULLPTR
|
"expression", "bool_expr", "string_expr", "option_code",
|
||||||
|
"option_repr_type", "pkt4_field", "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, 91, 91, 94, 95, 100, 105, 110, 115, 120,
|
0, 100, 100, 103, 104, 109, 114, 119, 124, 129,
|
||||||
140, 156, 161, 166, 171, 176, 197, 212, 228, 233,
|
149, 165, 170, 175, 180, 185, 206, 221, 236, 241,
|
||||||
238, 245, 249, 255, 259, 265, 272, 277, 284, 285,
|
246, 251, 258, 262, 268, 272, 278, 282, 286, 290,
|
||||||
288, 297, 298
|
294, 298, 302, 308, 315, 320, 327, 328, 331, 340,
|
||||||
|
341
|
||||||
};
|
};
|
||||||
|
|
||||||
// Print the state stack on the debug stream.
|
// Print the state stack on the debug stream.
|
||||||
@@ -1400,8 +1494,8 @@ namespace isc { namespace eval {
|
|||||||
|
|
||||||
#line 13 "parser.yy" // lalr1.cc:1167
|
#line 13 "parser.yy" // lalr1.cc:1167
|
||||||
} } // isc::eval
|
} } // isc::eval
|
||||||
#line 1404 "parser.cc" // lalr1.cc:1167
|
#line 1498 "parser.cc" // lalr1.cc:1167
|
||||||
#line 301 "parser.yy" // lalr1.cc:1168
|
#line 344 "parser.yy" // lalr1.cc:1168
|
||||||
|
|
||||||
void
|
void
|
||||||
isc::eval::EvalParser::error(const location_type& loc,
|
isc::eval::EvalParser::error(const location_type& loc,
|
||||||
|
@@ -40,7 +40,7 @@
|
|||||||
#ifndef YY_YY_PARSER_H_INCLUDED
|
#ifndef YY_YY_PARSER_H_INCLUDED
|
||||||
# define YY_YY_PARSER_H_INCLUDED
|
# define YY_YY_PARSER_H_INCLUDED
|
||||||
// // "%code requires" blocks.
|
// // "%code requires" blocks.
|
||||||
#line 16 "parser.yy" // lalr1.cc:377
|
#line 16 "parser.yy" // lalr1.cc:392
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <eval/token.h>
|
#include <eval/token.h>
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
using namespace isc::dhcp;
|
using namespace isc::dhcp;
|
||||||
using namespace isc::eval;
|
using namespace isc::eval;
|
||||||
|
|
||||||
#line 55 "parser.h" // lalr1.cc:377
|
#line 55 "parser.h" // lalr1.cc:392
|
||||||
|
|
||||||
# include <cassert>
|
# include <cassert>
|
||||||
# include <cstdlib> // std::abort
|
# include <cstdlib> // std::abort
|
||||||
@@ -126,9 +126,9 @@ using namespace isc::eval;
|
|||||||
# define YYDEBUG 1
|
# define YYDEBUG 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#line 13 "parser.yy" // lalr1.cc:377
|
#line 13 "parser.yy" // lalr1.cc:392
|
||||||
namespace isc { namespace eval {
|
namespace isc { namespace eval {
|
||||||
#line 132 "parser.h" // lalr1.cc:377
|
#line 132 "parser.h" // lalr1.cc:392
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -298,24 +298,27 @@ namespace isc { namespace eval {
|
|||||||
// option_repr_type
|
// option_repr_type
|
||||||
char dummy1[sizeof(TokenOption::RepresentationType)];
|
char dummy1[sizeof(TokenOption::RepresentationType)];
|
||||||
|
|
||||||
|
// pkt4_field
|
||||||
|
char dummy2[sizeof(TokenPkt4::FieldType)];
|
||||||
|
|
||||||
// pkt6_field
|
// pkt6_field
|
||||||
char dummy2[sizeof(TokenPkt6::FieldType)];
|
char dummy3[sizeof(TokenPkt6::FieldType)];
|
||||||
|
|
||||||
// relay6_field
|
// relay6_field
|
||||||
char dummy3[sizeof(TokenRelay6Field::FieldType)];
|
char dummy4[sizeof(TokenRelay6Field::FieldType)];
|
||||||
|
|
||||||
// "constant string"
|
// "constant string"
|
||||||
// "integer"
|
// "integer"
|
||||||
// "constant hexstring"
|
// "constant hexstring"
|
||||||
// "option name"
|
// "option name"
|
||||||
// "ip address"
|
// "ip address"
|
||||||
char dummy4[sizeof(std::string)];
|
char dummy5[sizeof(std::string)];
|
||||||
|
|
||||||
// option_code
|
// option_code
|
||||||
char dummy5[sizeof(uint16_t)];
|
char dummy6[sizeof(uint16_t)];
|
||||||
|
|
||||||
// nest_level
|
// nest_level
|
||||||
char dummy6[sizeof(uint8_t)];
|
char dummy7[sizeof(uint8_t)];
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Symbol semantic values.
|
/// Symbol semantic values.
|
||||||
@@ -356,18 +359,26 @@ namespace isc { namespace eval {
|
|||||||
TOKEN_TEXT = 272,
|
TOKEN_TEXT = 272,
|
||||||
TOKEN_HEX = 273,
|
TOKEN_HEX = 273,
|
||||||
TOKEN_EXISTS = 274,
|
TOKEN_EXISTS = 274,
|
||||||
TOKEN_SUBSTRING = 275,
|
TOKEN_PKT4 = 275,
|
||||||
TOKEN_ALL = 276,
|
TOKEN_CHADDR = 276,
|
||||||
TOKEN_COMA = 277,
|
TOKEN_HLEN = 277,
|
||||||
TOKEN_CONCAT = 278,
|
TOKEN_HTYPE = 278,
|
||||||
TOKEN_PKT6 = 279,
|
TOKEN_CIADDR = 279,
|
||||||
TOKEN_MSGTYPE = 280,
|
TOKEN_GIADDR = 280,
|
||||||
TOKEN_TRANSID = 281,
|
TOKEN_YIADDR = 281,
|
||||||
TOKEN_STRING = 282,
|
TOKEN_SIADDR = 282,
|
||||||
TOKEN_INTEGER = 283,
|
TOKEN_SUBSTRING = 283,
|
||||||
TOKEN_HEXSTRING = 284,
|
TOKEN_ALL = 284,
|
||||||
TOKEN_OPTION_NAME = 285,
|
TOKEN_COMA = 285,
|
||||||
TOKEN_IP_ADDRESS = 286
|
TOKEN_CONCAT = 286,
|
||||||
|
TOKEN_PKT6 = 287,
|
||||||
|
TOKEN_MSGTYPE = 288,
|
||||||
|
TOKEN_TRANSID = 289,
|
||||||
|
TOKEN_STRING = 290,
|
||||||
|
TOKEN_INTEGER = 291,
|
||||||
|
TOKEN_HEXSTRING = 292,
|
||||||
|
TOKEN_OPTION_NAME = 293,
|
||||||
|
TOKEN_IP_ADDRESS = 294
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -407,6 +418,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 TokenPkt4::FieldType 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 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);
|
||||||
@@ -556,6 +569,38 @@ namespace isc { namespace eval {
|
|||||||
symbol_type
|
symbol_type
|
||||||
make_EXISTS (const location_type& l);
|
make_EXISTS (const location_type& l);
|
||||||
|
|
||||||
|
static inline
|
||||||
|
symbol_type
|
||||||
|
make_PKT4 (const location_type& l);
|
||||||
|
|
||||||
|
static inline
|
||||||
|
symbol_type
|
||||||
|
make_CHADDR (const location_type& l);
|
||||||
|
|
||||||
|
static inline
|
||||||
|
symbol_type
|
||||||
|
make_HLEN (const location_type& l);
|
||||||
|
|
||||||
|
static inline
|
||||||
|
symbol_type
|
||||||
|
make_HTYPE (const location_type& l);
|
||||||
|
|
||||||
|
static inline
|
||||||
|
symbol_type
|
||||||
|
make_CIADDR (const location_type& l);
|
||||||
|
|
||||||
|
static inline
|
||||||
|
symbol_type
|
||||||
|
make_GIADDR (const location_type& l);
|
||||||
|
|
||||||
|
static inline
|
||||||
|
symbol_type
|
||||||
|
make_YIADDR (const location_type& l);
|
||||||
|
|
||||||
|
static inline
|
||||||
|
symbol_type
|
||||||
|
make_SIADDR (const location_type& l);
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
symbol_type
|
symbol_type
|
||||||
make_SUBSTRING (const location_type& l);
|
make_SUBSTRING (const location_type& l);
|
||||||
@@ -689,7 +734,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 unsigned char yycheck_[];
|
static const signed 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.
|
||||||
@@ -809,12 +854,12 @@ namespace isc { namespace eval {
|
|||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
yyeof_ = 0,
|
yyeof_ = 0,
|
||||||
yylast_ = 102, ///< Last index in yytable_.
|
yylast_ = 113, ///< Last index in yytable_.
|
||||||
yynnts_ = 11, ///< Number of nonterminal symbols.
|
yynnts_ = 12, ///< Number of nonterminal symbols.
|
||||||
yyfinal_ = 23, ///< Termination state number.
|
yyfinal_ = 25, ///< Termination state number.
|
||||||
yyterror_ = 1,
|
yyterror_ = 1,
|
||||||
yyerrcode_ = 256,
|
yyerrcode_ = 256,
|
||||||
yyntokens_ = 32 ///< Number of tokens.
|
yyntokens_ = 40 ///< Number of tokens.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -859,9 +904,10 @@ 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, 29, 30, 31
|
25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
|
||||||
|
35, 36, 37, 38, 39
|
||||||
};
|
};
|
||||||
const unsigned int user_token_number_max_ = 286;
|
const unsigned int user_token_number_max_ = 294;
|
||||||
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_)
|
||||||
@@ -894,31 +940,35 @@ namespace isc { namespace eval {
|
|||||||
{
|
{
|
||||||
switch (other.type_get ())
|
switch (other.type_get ())
|
||||||
{
|
{
|
||||||
case 37: // option_repr_type
|
case 45: // option_repr_type
|
||||||
value.copy< TokenOption::RepresentationType > (other.value);
|
value.copy< TokenOption::RepresentationType > (other.value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 42: // pkt6_field
|
case 46: // pkt4_field
|
||||||
|
value.copy< TokenPkt4::FieldType > (other.value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 51: // pkt6_field
|
||||||
value.copy< TokenPkt6::FieldType > (other.value);
|
value.copy< TokenPkt6::FieldType > (other.value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 40: // relay6_field
|
case 49: // relay6_field
|
||||||
value.copy< TokenRelay6Field::FieldType > (other.value);
|
value.copy< TokenRelay6Field::FieldType > (other.value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 27: // "constant string"
|
case 35: // "constant string"
|
||||||
case 28: // "integer"
|
case 36: // "integer"
|
||||||
case 29: // "constant hexstring"
|
case 37: // "constant hexstring"
|
||||||
case 30: // "option name"
|
case 38: // "option name"
|
||||||
case 31: // "ip address"
|
case 39: // "ip address"
|
||||||
value.copy< std::string > (other.value);
|
value.copy< std::string > (other.value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 36: // option_code
|
case 44: // option_code
|
||||||
value.copy< uint16_t > (other.value);
|
value.copy< uint16_t > (other.value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 41: // nest_level
|
case 50: // nest_level
|
||||||
value.copy< uint8_t > (other.value);
|
value.copy< uint8_t > (other.value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -939,31 +989,35 @@ namespace isc { namespace eval {
|
|||||||
(void) v;
|
(void) v;
|
||||||
switch (this->type_get ())
|
switch (this->type_get ())
|
||||||
{
|
{
|
||||||
case 37: // option_repr_type
|
case 45: // option_repr_type
|
||||||
value.copy< TokenOption::RepresentationType > (v);
|
value.copy< TokenOption::RepresentationType > (v);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 42: // pkt6_field
|
case 46: // pkt4_field
|
||||||
|
value.copy< TokenPkt4::FieldType > (v);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 51: // pkt6_field
|
||||||
value.copy< TokenPkt6::FieldType > (v);
|
value.copy< TokenPkt6::FieldType > (v);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 40: // relay6_field
|
case 49: // relay6_field
|
||||||
value.copy< TokenRelay6Field::FieldType > (v);
|
value.copy< TokenRelay6Field::FieldType > (v);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 27: // "constant string"
|
case 35: // "constant string"
|
||||||
case 28: // "integer"
|
case 36: // "integer"
|
||||||
case 29: // "constant hexstring"
|
case 37: // "constant hexstring"
|
||||||
case 30: // "option name"
|
case 38: // "option name"
|
||||||
case 31: // "ip address"
|
case 39: // "ip address"
|
||||||
value.copy< std::string > (v);
|
value.copy< std::string > (v);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 36: // option_code
|
case 44: // option_code
|
||||||
value.copy< uint16_t > (v);
|
value.copy< uint16_t > (v);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 41: // nest_level
|
case 50: // nest_level
|
||||||
value.copy< uint8_t > (v);
|
value.copy< uint8_t > (v);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -989,6 +1043,13 @@ namespace isc { namespace eval {
|
|||||||
, location (l)
|
, location (l)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
template <typename Base>
|
||||||
|
EvalParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const TokenPkt4::FieldType v, const location_type& l)
|
||||||
|
: Base (t)
|
||||||
|
, value (v)
|
||||||
|
, location (l)
|
||||||
|
{}
|
||||||
|
|
||||||
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)
|
EvalParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const TokenPkt6::FieldType v, const location_type& l)
|
||||||
: Base (t)
|
: Base (t)
|
||||||
@@ -1050,31 +1111,35 @@ namespace isc { namespace eval {
|
|||||||
// Type destructor.
|
// Type destructor.
|
||||||
switch (yytype)
|
switch (yytype)
|
||||||
{
|
{
|
||||||
case 37: // option_repr_type
|
case 45: // option_repr_type
|
||||||
value.template destroy< TokenOption::RepresentationType > ();
|
value.template destroy< TokenOption::RepresentationType > ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 42: // pkt6_field
|
case 46: // pkt4_field
|
||||||
|
value.template destroy< TokenPkt4::FieldType > ();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 51: // pkt6_field
|
||||||
value.template destroy< TokenPkt6::FieldType > ();
|
value.template destroy< TokenPkt6::FieldType > ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 40: // relay6_field
|
case 49: // relay6_field
|
||||||
value.template destroy< TokenRelay6Field::FieldType > ();
|
value.template destroy< TokenRelay6Field::FieldType > ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 27: // "constant string"
|
case 35: // "constant string"
|
||||||
case 28: // "integer"
|
case 36: // "integer"
|
||||||
case 29: // "constant hexstring"
|
case 37: // "constant hexstring"
|
||||||
case 30: // "option name"
|
case 38: // "option name"
|
||||||
case 31: // "ip address"
|
case 39: // "ip address"
|
||||||
value.template destroy< std::string > ();
|
value.template destroy< std::string > ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 36: // option_code
|
case 44: // option_code
|
||||||
value.template destroy< uint16_t > ();
|
value.template destroy< uint16_t > ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 41: // nest_level
|
case 50: // nest_level
|
||||||
value.template destroy< uint8_t > ();
|
value.template destroy< uint8_t > ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1101,31 +1166,35 @@ namespace isc { namespace eval {
|
|||||||
super_type::move(s);
|
super_type::move(s);
|
||||||
switch (this->type_get ())
|
switch (this->type_get ())
|
||||||
{
|
{
|
||||||
case 37: // option_repr_type
|
case 45: // option_repr_type
|
||||||
value.move< TokenOption::RepresentationType > (s.value);
|
value.move< TokenOption::RepresentationType > (s.value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 42: // pkt6_field
|
case 46: // pkt4_field
|
||||||
|
value.move< TokenPkt4::FieldType > (s.value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 51: // pkt6_field
|
||||||
value.move< TokenPkt6::FieldType > (s.value);
|
value.move< TokenPkt6::FieldType > (s.value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 40: // relay6_field
|
case 49: // relay6_field
|
||||||
value.move< TokenRelay6Field::FieldType > (s.value);
|
value.move< TokenRelay6Field::FieldType > (s.value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 27: // "constant string"
|
case 35: // "constant string"
|
||||||
case 28: // "integer"
|
case 36: // "integer"
|
||||||
case 29: // "constant hexstring"
|
case 37: // "constant hexstring"
|
||||||
case 30: // "option name"
|
case 38: // "option name"
|
||||||
case 31: // "ip address"
|
case 39: // "ip address"
|
||||||
value.move< std::string > (s.value);
|
value.move< std::string > (s.value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 36: // option_code
|
case 44: // option_code
|
||||||
value.move< uint16_t > (s.value);
|
value.move< uint16_t > (s.value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 41: // nest_level
|
case 50: // nest_level
|
||||||
value.move< uint8_t > (s.value);
|
value.move< uint8_t > (s.value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1187,7 +1256,7 @@ 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, 284,
|
275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
|
||||||
285, 286
|
285, 286, 287, 288, 289, 290, 291, 292, 293, 294
|
||||||
};
|
};
|
||||||
return static_cast<token_type> (yytoken_number_[type]);
|
return static_cast<token_type> (yytoken_number_[type]);
|
||||||
}
|
}
|
||||||
@@ -1300,6 +1369,54 @@ namespace isc { namespace eval {
|
|||||||
return symbol_type (token::TOKEN_EXISTS, l);
|
return symbol_type (token::TOKEN_EXISTS, l);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EvalParser::symbol_type
|
||||||
|
EvalParser::make_PKT4 (const location_type& l)
|
||||||
|
{
|
||||||
|
return symbol_type (token::TOKEN_PKT4, l);
|
||||||
|
}
|
||||||
|
|
||||||
|
EvalParser::symbol_type
|
||||||
|
EvalParser::make_CHADDR (const location_type& l)
|
||||||
|
{
|
||||||
|
return symbol_type (token::TOKEN_CHADDR, l);
|
||||||
|
}
|
||||||
|
|
||||||
|
EvalParser::symbol_type
|
||||||
|
EvalParser::make_HLEN (const location_type& l)
|
||||||
|
{
|
||||||
|
return symbol_type (token::TOKEN_HLEN, l);
|
||||||
|
}
|
||||||
|
|
||||||
|
EvalParser::symbol_type
|
||||||
|
EvalParser::make_HTYPE (const location_type& l)
|
||||||
|
{
|
||||||
|
return symbol_type (token::TOKEN_HTYPE, l);
|
||||||
|
}
|
||||||
|
|
||||||
|
EvalParser::symbol_type
|
||||||
|
EvalParser::make_CIADDR (const location_type& l)
|
||||||
|
{
|
||||||
|
return symbol_type (token::TOKEN_CIADDR, l);
|
||||||
|
}
|
||||||
|
|
||||||
|
EvalParser::symbol_type
|
||||||
|
EvalParser::make_GIADDR (const location_type& l)
|
||||||
|
{
|
||||||
|
return symbol_type (token::TOKEN_GIADDR, l);
|
||||||
|
}
|
||||||
|
|
||||||
|
EvalParser::symbol_type
|
||||||
|
EvalParser::make_YIADDR (const location_type& l)
|
||||||
|
{
|
||||||
|
return symbol_type (token::TOKEN_YIADDR, l);
|
||||||
|
}
|
||||||
|
|
||||||
|
EvalParser::symbol_type
|
||||||
|
EvalParser::make_SIADDR (const location_type& l)
|
||||||
|
{
|
||||||
|
return symbol_type (token::TOKEN_SIADDR, l);
|
||||||
|
}
|
||||||
|
|
||||||
EvalParser::symbol_type
|
EvalParser::symbol_type
|
||||||
EvalParser::make_SUBSTRING (const location_type& l)
|
EvalParser::make_SUBSTRING (const location_type& l)
|
||||||
{
|
{
|
||||||
@@ -1373,9 +1490,9 @@ namespace isc { namespace eval {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#line 13 "parser.yy" // lalr1.cc:377
|
#line 13 "parser.yy" // lalr1.cc:392
|
||||||
} } // isc::eval
|
} } // isc::eval
|
||||||
#line 1379 "parser.h" // lalr1.cc:377
|
#line 1496 "parser.h" // lalr1.cc:392
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@@ -54,6 +54,14 @@ using namespace isc::eval;
|
|||||||
TEXT "text"
|
TEXT "text"
|
||||||
HEX "hex"
|
HEX "hex"
|
||||||
EXISTS "exists"
|
EXISTS "exists"
|
||||||
|
PKT4 "pkt4"
|
||||||
|
CHADDR "mac"
|
||||||
|
HLEN "hlen"
|
||||||
|
HTYPE "htype"
|
||||||
|
CIADDR "ciaddr"
|
||||||
|
GIADDR "giaddr"
|
||||||
|
YIADDR "yiaddr"
|
||||||
|
SIADDR "siaddr"
|
||||||
SUBSTRING "substring"
|
SUBSTRING "substring"
|
||||||
ALL "all"
|
ALL "all"
|
||||||
COMA ","
|
COMA ","
|
||||||
@@ -73,6 +81,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 <TokenPkt4::FieldType> pkt4_field
|
||||||
%type <TokenPkt6::FieldType> pkt6_field
|
%type <TokenPkt6::FieldType> pkt6_field
|
||||||
|
|
||||||
%left OR
|
%left OR
|
||||||
@@ -224,7 +233,16 @@ string_expr : STRING
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
| PKT4 "." pkt4_field
|
||||||
|
{
|
||||||
|
TokenPtr pkt4_field(new TokenPkt4($3));
|
||||||
|
ctx.expression.push_back(pkt4_field);
|
||||||
|
}
|
||||||
|
| PKT6 "." pkt6_field
|
||||||
|
{
|
||||||
|
TokenPtr pkt6_field(new TokenPkt6($3));
|
||||||
|
ctx.expression.push_back(pkt6_field);
|
||||||
|
}
|
||||||
| SUBSTRING "(" string_expr "," start_expr "," length_expr ")"
|
| SUBSTRING "(" string_expr "," start_expr "," length_expr ")"
|
||||||
{
|
{
|
||||||
TokenPtr sub(new TokenSubstring());
|
TokenPtr sub(new TokenSubstring());
|
||||||
@@ -235,11 +253,6 @@ 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
|
||||||
@@ -262,6 +275,36 @@ option_repr_type : TEXT
|
|||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
pkt4_field : CHADDR
|
||||||
|
{
|
||||||
|
$$ = TokenPkt4::CHADDR;
|
||||||
|
}
|
||||||
|
| HLEN
|
||||||
|
{
|
||||||
|
$$ = TokenPkt4::HLEN;
|
||||||
|
}
|
||||||
|
| HTYPE
|
||||||
|
{
|
||||||
|
$$ = TokenPkt4::HTYPE;
|
||||||
|
}
|
||||||
|
| CIADDR
|
||||||
|
{
|
||||||
|
$$ = TokenPkt4::CIADDR;
|
||||||
|
}
|
||||||
|
| GIADDR
|
||||||
|
{
|
||||||
|
$$ = TokenPkt4::GIADDR;
|
||||||
|
}
|
||||||
|
| YIADDR
|
||||||
|
{
|
||||||
|
$$ = TokenPkt4::YIADDR;
|
||||||
|
}
|
||||||
|
| SIADDR
|
||||||
|
{
|
||||||
|
$$ = TokenPkt4::SIADDR;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
start_expr : INTEGER
|
start_expr : INTEGER
|
||||||
{
|
{
|
||||||
TokenPtr str(new TokenString($1));
|
TokenPtr str(new TokenString($1));
|
||||||
|
@@ -132,6 +132,51 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @brief checks if the given token is Pkt4 of specified type
|
||||||
|
/// @param token token to be checked
|
||||||
|
/// @param type expected type of the Pkt4 field
|
||||||
|
void checkTokenPkt4(const TokenPtr& token, TokenPkt4::FieldType type) {
|
||||||
|
ASSERT_TRUE(token);
|
||||||
|
boost::shared_ptr<TokenPkt4> pkt =
|
||||||
|
boost::dynamic_pointer_cast<TokenPkt4>(token);
|
||||||
|
ASSERT_TRUE(pkt);
|
||||||
|
|
||||||
|
EXPECT_EQ(type, pkt->getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Test that verifies access to the DHCPv4 packet fields.
|
||||||
|
///
|
||||||
|
/// This test attempts to parse the expression, will check if the number
|
||||||
|
/// of tokens is exactly as expected and then will try to verify if the
|
||||||
|
/// first token represents the expected field in DHCPv4 packet.
|
||||||
|
///
|
||||||
|
/// @param expr expression to be parsed
|
||||||
|
/// @param exp_type expected field type to be parsed
|
||||||
|
/// @param exp_tokens expected number of tokens
|
||||||
|
void testPkt4Field(std::string expr,
|
||||||
|
TokenPkt4::FieldType exp_type,
|
||||||
|
int exp_tokens) {
|
||||||
|
EvalContext eval(Option::V4);
|
||||||
|
|
||||||
|
// 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 exactly the expected number of tokens.
|
||||||
|
ASSERT_EQ(exp_tokens, eval.expression.size());
|
||||||
|
|
||||||
|
// Check that the first token is TokenPkt4 instance and has correct type.
|
||||||
|
checkTokenPkt4(eval.expression.at(0), exp_type);
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief checks if the given token is a substring operator
|
/// @brief checks if the given token is a substring operator
|
||||||
void checkTokenSubstring(const TokenPtr& token) {
|
void checkTokenSubstring(const TokenPtr& token) {
|
||||||
ASSERT_TRUE(token);
|
ASSERT_TRUE(token);
|
||||||
@@ -585,6 +630,41 @@ 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 chaddr field in DHCPv4 can be accessed.
|
||||||
|
TEST_F(EvalContextTest, pkt4FieldChaddr) {
|
||||||
|
testPkt4Field("pkt4.mac == 0x000102030405", TokenPkt4::CHADDR, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests whether hlen field in DHCPv4 can be accessed.
|
||||||
|
TEST_F(EvalContextTest, pkt4FieldHlen) {
|
||||||
|
testPkt4Field("pkt4.hlen == 0x6", TokenPkt4::HLEN, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests whether htype field in DHCPv4 can be accessed.
|
||||||
|
TEST_F(EvalContextTest, pkt4FieldHtype) {
|
||||||
|
testPkt4Field("pkt4.htype == 0x1", TokenPkt4::HTYPE, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests whether ciaddr field in DHCPv4 can be accessed.
|
||||||
|
TEST_F(EvalContextTest, pkt4FieldCiaddr) {
|
||||||
|
testPkt4Field("pkt4.ciaddr == 192.0.2.1", TokenPkt4::CIADDR, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests whether giaddr field in DHCPv4 can be accessed.
|
||||||
|
TEST_F(EvalContextTest, pkt4FieldGiaddr) {
|
||||||
|
testPkt4Field("pkt4.giaddr == 192.0.2.1", TokenPkt4::GIADDR, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests whether yiaddr field in DHCPv4 can be accessed.
|
||||||
|
TEST_F(EvalContextTest, pkt4FieldYiaddr) {
|
||||||
|
testPkt4Field("pkt4.yiaddr == 192.0.2.1", TokenPkt4::YIADDR, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests whether siaddr field in DHCPv4 can be accessed.
|
||||||
|
TEST_F(EvalContextTest, pkt4FieldSiaddr) {
|
||||||
|
testPkt4Field("pkt4.siaddr == 192.0.2.1", TokenPkt4::SIADDR, 3);
|
||||||
|
}
|
||||||
|
|
||||||
// Tests whether message type field in DHCPv6 can be accessed.
|
// Tests whether message type field in DHCPv6 can be accessed.
|
||||||
TEST_F(EvalContextTest, pkt6FieldMsgtype) {
|
TEST_F(EvalContextTest, pkt6FieldMsgtype) {
|
||||||
testPkt6Field("pkt6.msgtype == '1'", TokenPkt6::MSGTYPE, 3);
|
testPkt6Field("pkt6.msgtype == '1'", TokenPkt6::MSGTYPE, 3);
|
||||||
@@ -790,6 +870,7 @@ TEST_F(EvalContextTest, scanErrors) {
|
|||||||
checkError("foo", "<string>:1.1: Invalid character: f");
|
checkError("foo", "<string>:1.1: Invalid character: f");
|
||||||
checkError(" bar", "<string>:1.2: Invalid character: b");
|
checkError(" bar", "<string>:1.2: Invalid character: b");
|
||||||
checkError("relay[12].hex == 'foo'", "<string>:1.1: Invalid character: r");
|
checkError("relay[12].hex == 'foo'", "<string>:1.1: Invalid character: r");
|
||||||
|
checkError("pkt4.ziaddr", "<string>:1.6: Invalid character: z");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tests some scanner/parser error cases
|
// Tests some scanner/parser error cases
|
||||||
|
@@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace isc::dhcp;
|
using namespace isc::dhcp;
|
||||||
|
using namespace isc::asiolink;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@@ -708,6 +709,86 @@ TEST_F(TokenTest, relay4RAIOnly) {
|
|||||||
EXPECT_EQ("false", values_.top());
|
EXPECT_EQ("false", values_.top());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verifies if the DHCPv4 packet fields can be extracted.
|
||||||
|
TEST_F(TokenTest, pkt4Fields) {
|
||||||
|
pkt4_->setGiaddr(IOAddress("192.0.2.1"));
|
||||||
|
pkt4_->setCiaddr(IOAddress("192.0.2.2"));
|
||||||
|
pkt4_->setYiaddr(IOAddress("192.0.2.3"));
|
||||||
|
pkt4_->setSiaddr(IOAddress("192.0.2.4"));
|
||||||
|
|
||||||
|
// We're setting hardware address to uncommon (7 bytes rather than 6 and
|
||||||
|
// hardware type 123) HW address. We'll use it in hlen and htype checks.
|
||||||
|
HWAddrPtr hw(new HWAddr(HWAddr::fromText("01:02:03:04:05:06:07", 123)));
|
||||||
|
pkt4_->setHWAddr(hw);
|
||||||
|
|
||||||
|
// Check hardware address field.
|
||||||
|
ASSERT_NO_THROW(t_.reset(new TokenPkt4(TokenPkt4::CHADDR)));
|
||||||
|
EXPECT_NO_THROW(t_->evaluate(*pkt4_, values_));
|
||||||
|
ASSERT_EQ(1, values_.size());
|
||||||
|
uint8_t expected_hw[] = { 1, 2, 3, 4, 5, 6, 7 };
|
||||||
|
ASSERT_EQ(7, values_.top().size());
|
||||||
|
EXPECT_EQ(0, memcmp(expected_hw, &values_.top()[0], 7));
|
||||||
|
|
||||||
|
// Check hlen value field.
|
||||||
|
clearStack();
|
||||||
|
ASSERT_NO_THROW(t_.reset(new TokenPkt4(TokenPkt4::HLEN)));
|
||||||
|
EXPECT_NO_THROW(t_->evaluate(*pkt4_, values_));
|
||||||
|
ASSERT_EQ(1, values_.size());
|
||||||
|
ASSERT_EQ(4, values_.top().size());
|
||||||
|
uint32_t expected_hlen = htonl(7);
|
||||||
|
EXPECT_EQ(0, memcmp(&expected_hlen, &values_.top()[0], 4));
|
||||||
|
|
||||||
|
// Check htype value.
|
||||||
|
clearStack();
|
||||||
|
ASSERT_NO_THROW(t_.reset(new TokenPkt4(TokenPkt4::HTYPE)));
|
||||||
|
EXPECT_NO_THROW(t_->evaluate(*pkt4_, values_));
|
||||||
|
ASSERT_EQ(1, values_.size());
|
||||||
|
ASSERT_EQ(4, values_.top().size());
|
||||||
|
uint32_t expected_htype = htonl(123);
|
||||||
|
EXPECT_EQ(0, memcmp(&expected_htype, &values_.top()[0], 4));
|
||||||
|
|
||||||
|
// Check giaddr value.
|
||||||
|
clearStack();
|
||||||
|
ASSERT_NO_THROW(t_.reset(new TokenPkt4(TokenPkt4::GIADDR)));
|
||||||
|
EXPECT_NO_THROW(t_->evaluate(*pkt4_, values_));
|
||||||
|
ASSERT_EQ(1, values_.size());
|
||||||
|
uint8_t expected_addr[] = { 192, 0, 2, 1 };
|
||||||
|
ASSERT_EQ(4, values_.top().size());
|
||||||
|
EXPECT_EQ(0, memcmp(expected_addr, &values_.top()[0], 4));
|
||||||
|
|
||||||
|
// Check ciaddr value.
|
||||||
|
clearStack();
|
||||||
|
ASSERT_NO_THROW(t_.reset(new TokenPkt4(TokenPkt4::CIADDR)));
|
||||||
|
EXPECT_NO_THROW(t_->evaluate(*pkt4_, values_));
|
||||||
|
ASSERT_EQ(1, values_.size());
|
||||||
|
expected_addr[3] = 2;
|
||||||
|
ASSERT_EQ(4, values_.top().size());
|
||||||
|
EXPECT_EQ(0, memcmp(expected_addr, &values_.top()[0], 4));
|
||||||
|
|
||||||
|
// Check yiaddr value.
|
||||||
|
clearStack();
|
||||||
|
ASSERT_NO_THROW(t_.reset(new TokenPkt4(TokenPkt4::YIADDR)));
|
||||||
|
EXPECT_NO_THROW(t_->evaluate(*pkt4_, values_));
|
||||||
|
ASSERT_EQ(1, values_.size());
|
||||||
|
expected_addr[3] = 3;
|
||||||
|
ASSERT_EQ(4, values_.top().size());
|
||||||
|
EXPECT_EQ(0, memcmp(expected_addr, &values_.top()[0], 4));
|
||||||
|
|
||||||
|
// Check siaddr value.
|
||||||
|
clearStack();
|
||||||
|
ASSERT_NO_THROW(t_.reset(new TokenPkt4(TokenPkt4::SIADDR)));
|
||||||
|
EXPECT_NO_THROW(t_->evaluate(*pkt4_, values_));
|
||||||
|
ASSERT_EQ(1, values_.size());
|
||||||
|
expected_addr[3] = 4;
|
||||||
|
ASSERT_EQ(4, values_.top().size());
|
||||||
|
EXPECT_EQ(0, memcmp(expected_addr, &values_.top()[0], 4));
|
||||||
|
|
||||||
|
// Check a DHCPv6 packet throws.
|
||||||
|
clearStack();
|
||||||
|
ASSERT_NO_THROW(t_.reset(new TokenPkt4(TokenPkt4::HLEN)));
|
||||||
|
EXPECT_THROW(t_->evaluate(*pkt6_, values_), EvalTypeError);
|
||||||
|
}
|
||||||
|
|
||||||
// This test checks if a token representing an == operator is able to
|
// This test checks if a token representing an == operator is able to
|
||||||
// compare two values (with incorrectly built stack).
|
// compare two values (with incorrectly built stack).
|
||||||
TEST_F(TokenTest, optionEqualInvalid) {
|
TEST_F(TokenTest, optionEqualInvalid) {
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
#include <eval/eval_log.h>
|
#include <eval/eval_log.h>
|
||||||
#include <util/encode/hex.h>
|
#include <util/encode/hex.h>
|
||||||
#include <asiolink/io_address.h>
|
#include <asiolink/io_address.h>
|
||||||
|
#include <dhcp/pkt4.h>
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
#include <dhcp/pkt6.h>
|
#include <dhcp/pkt6.h>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
@@ -124,6 +125,77 @@ OptionPtr TokenRelay4Option::getOption(const Pkt& pkt) {
|
|||||||
return (rai->getOption(option_code_));
|
return (rai->getOption(option_code_));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TokenPkt4::evaluate(const Pkt& pkt, ValueStack& values) {
|
||||||
|
|
||||||
|
vector<uint8_t> binary;
|
||||||
|
try {
|
||||||
|
// Check if it's a Pkt4. If it's not, the dynamic_cast will throw
|
||||||
|
// std::bad_cast (failed dynamic_cast returns NULL for pointers and
|
||||||
|
// throws for references).
|
||||||
|
const Pkt4& pkt4 = dynamic_cast<const Pkt4&>(pkt);
|
||||||
|
|
||||||
|
switch (type_) {
|
||||||
|
case CHADDR: {
|
||||||
|
HWAddrPtr hwaddr = pkt4.getHWAddr();
|
||||||
|
if (!hwaddr) {
|
||||||
|
// This should never happen. Every Pkt4 should always have
|
||||||
|
// a hardware address.
|
||||||
|
isc_throw(EvalTypeError,
|
||||||
|
"Packet does not have hardware address");
|
||||||
|
}
|
||||||
|
binary = hwaddr->hwaddr_;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GIADDR:
|
||||||
|
binary = pkt4.getGiaddr().toBytes();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CIADDR:
|
||||||
|
binary = pkt4.getCiaddr().toBytes();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case YIADDR:
|
||||||
|
binary = pkt4.getYiaddr().toBytes();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIADDR:
|
||||||
|
binary = pkt4.getSiaddr().toBytes();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HLEN:
|
||||||
|
// Pad the uint8_t field to 4 bytes.
|
||||||
|
binary.push_back(0);
|
||||||
|
binary.push_back(0);
|
||||||
|
binary.push_back(0);
|
||||||
|
binary.push_back(pkt4.getHlen());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HTYPE:
|
||||||
|
// Pad the uint8_t field to 4 bytes.
|
||||||
|
binary.push_back(0);
|
||||||
|
binary.push_back(0);
|
||||||
|
binary.push_back(0);
|
||||||
|
binary.push_back(pkt4.getHtype());
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
isc_throw(EvalTypeError, "Bad field specified: "
|
||||||
|
<< static_cast<int>(type_) );
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (const std::bad_cast&) {
|
||||||
|
isc_throw(EvalTypeError, "Specified packet is not a Pkt4");
|
||||||
|
}
|
||||||
|
|
||||||
|
string value;
|
||||||
|
value.resize(binary.size());
|
||||||
|
if (!binary.empty()) {
|
||||||
|
memmove(&value[0], &binary[0], binary.size());
|
||||||
|
}
|
||||||
|
values.push(value);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TokenEqual::evaluate(const Pkt& /*pkt*/, ValueStack& values) {
|
TokenEqual::evaluate(const Pkt& /*pkt*/, ValueStack& values) {
|
||||||
|
|
||||||
|
@@ -288,6 +288,61 @@ protected:
|
|||||||
virtual OptionPtr getOption(const Pkt& pkt);
|
virtual OptionPtr getOption(const Pkt& pkt);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// @brief Token that represents fields of a DHCPv4 packet.
|
||||||
|
///
|
||||||
|
/// For example in the expression pkt4.chaddr == 0x0102030405
|
||||||
|
/// this token represents the pkt4.chaddr expression.
|
||||||
|
///
|
||||||
|
/// Currently supported fields are:
|
||||||
|
/// - chaddr (client hardware address, hlen [0..16] octets)
|
||||||
|
/// - giaddr (relay agent IP address, 4 octets)
|
||||||
|
/// - ciaddr (client IP address, 4 octets)
|
||||||
|
/// - yiaddr ('your' (client) IP address, 4 octets)
|
||||||
|
/// - siaddr (next server IP address, 4 octets)
|
||||||
|
/// - hlen (hardware address length, padded to 4 octets)
|
||||||
|
/// - htype (hardware address type, padded to 4 octets)
|
||||||
|
class TokenPkt4 : public Token {
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// @brief enum value that determines the field.
|
||||||
|
enum FieldType {
|
||||||
|
CHADDR, ///< chaddr field (up to 16 bytes link-layer address)
|
||||||
|
GIADDR, ///< giaddr (IPv4 address)
|
||||||
|
CIADDR, ///< ciaddr (IPv4 address)
|
||||||
|
YIADDR, ///< yiaddr (IPv4 address)
|
||||||
|
SIADDR, ///< siaddr (IPv4 address)
|
||||||
|
HLEN, ///< hlen (hardware address length)
|
||||||
|
HTYPE ///< htype (hardware address type)
|
||||||
|
};
|
||||||
|
|
||||||
|
/// @brief Constructor (does nothing)
|
||||||
|
TokenPkt4(const FieldType type)
|
||||||
|
: type_(type) {}
|
||||||
|
|
||||||
|
/// @brief Gets a value from the specified packet.
|
||||||
|
///
|
||||||
|
/// Evaluation uses fields available in the packet. It does not require
|
||||||
|
/// any values to be present on the stack.
|
||||||
|
///
|
||||||
|
/// @throw EvalTypeError when called for DHCPv6 packet
|
||||||
|
///
|
||||||
|
/// @param pkt - fields will be extracted from here
|
||||||
|
/// @param values - stack of values (1 result will be pushed)
|
||||||
|
void evaluate(const Pkt& pkt, ValueStack& values);
|
||||||
|
|
||||||
|
/// @brief Returns field type
|
||||||
|
///
|
||||||
|
/// This method is used only in tests.
|
||||||
|
/// @return type of the field.
|
||||||
|
FieldType getType() {
|
||||||
|
return (type_);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// @brief Specifies field of the DHCPv4 packet
|
||||||
|
FieldType type_;
|
||||||
|
};
|
||||||
|
|
||||||
/// @brief Token that represents equality operator (compares two other tokens)
|
/// @brief Token that represents equality operator (compares two other tokens)
|
||||||
///
|
///
|
||||||
/// For example in the expression option[vendor-class].text == "MSFT"
|
/// For example in the expression option[vendor-class].text == "MSFT"
|
||||||
|
Reference in New Issue
Block a user