mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-30 21:45:37 +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
|
||||
Added support for accessing DHCPv6 packet fields message type
|
||||
and transaction id in a classification expression.
|
||||
|
@@ -152,56 +152,145 @@
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Name</entry>
|
||||
<entry>Example</entry>
|
||||
<entry>Example expression</entry>
|
||||
<entry>Example value</entry>
|
||||
<entry>Description</entry>
|
||||
</row>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<row><entry>String</entry><entry>'example'</entry><entry>A string</entry></row>
|
||||
<row><entry>Hex String</entry><entry>0XABCD</entry><entry>A hexadecimal string</entry></row>
|
||||
<row><entry>IP Address</entry><entry>10.0.0.1</entry><entry>An IP address</entry></row>
|
||||
<row><entry>Integer</entry><entry>123</entry><entry>An integer value</entry></row>
|
||||
<row>
|
||||
<entry>String literal</entry>
|
||||
<entry>'example'</entry>
|
||||
<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
|
||||
<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><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>
|
||||
<row><entry>DHCPv4 Relay Agent
|
||||
sub-option</entry><entry>relay4[code].hex</entry><entry>The value of
|
||||
sub-option with code "code" from the DHCPv4 Relay Agent Information option
|
||||
(option 82)</entry></row>
|
||||
<row>
|
||||
<row>
|
||||
<entry>Option existence</entry>
|
||||
<entry>option[123].exist</entry>
|
||||
<entry>'true'</entry>
|
||||
<entry>If the option with given code is present in the
|
||||
packet "true" else "false"</entry>
|
||||
</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>relay6[nest].option[code].hex</entry>
|
||||
<!-- <entry>Value of the option</entry> -->
|
||||
<entry>The value of the option with code "code" from the relay encapsulation "nest"</entry>
|
||||
</row>
|
||||
<row>
|
||||
<!-- <entry>Value of the option</entry> -->
|
||||
<entry>The value of the option with code "code" from the
|
||||
relay encapsulation "nest"</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>DHCPv6 Relay Peer Address</entry>
|
||||
<entry>relay6[nest].peeraddr</entry>
|
||||
<!-- <entry>2001:DB8::1</entry> -->n
|
||||
<entry>The value of the peer address field from the relay encapsulation "nest"</entry>
|
||||
</row>
|
||||
<row>
|
||||
<!-- <entry>2001:DB8::1</entry> -->n
|
||||
<entry>The value of the peer address field from the
|
||||
relay encapsulation "nest"</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>DHCPv6 Relay Link Address</entry>
|
||||
<entry>relay6[nest].linkaddr</entry>
|
||||
<!-- <entry>2001:DB8::1</entry> -->n
|
||||
<entry>The value of the link address field from the relay encapsulation "nest"</entry>
|
||||
</row>
|
||||
<row>
|
||||
<!-- <entry>2001:DB8::1</entry> -->n
|
||||
<entry>The value of the link address field from the
|
||||
relay encapsulation "nest"</entry>
|
||||
</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>pkt6.msgtype</entry>
|
||||
<!-- <entry>1</entry>
|
||||
-->
|
||||
<entry>The value of the message type field in the DHCPv6 packet.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<!-- <entry>1</entry> -->
|
||||
<entry>The value of the message type field in the DHCPv6
|
||||
packet.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Transaction ID in DHCPv6 packet</entry>
|
||||
<entry>pkt6.transid</entry>
|
||||
<!-- <entry>12345</entry>
|
||||
-->
|
||||
<entry>The value of the transaction id in the DHCPv6 packet.</entry>
|
||||
</row>
|
||||
<!-- <entry>12345</entry> -->
|
||||
<entry>The value of the transaction id in the DHCPv6
|
||||
packet.</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
@@ -221,14 +310,14 @@ sub-option with code "code" from the DHCPv4 Relay Agent Information option
|
||||
</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
|
||||
returns the empty string. The string is presented as a byte string of
|
||||
the option payload without the type code or length fields.
|
||||
</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.
|
||||
</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.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Expressions starting with pkt4 can be used only in DHCPv4.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
"pkt6" refers to information from the client request. To access any
|
||||
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);
|
||||
"hex" return isc::eval::EvalParser::make_HEX(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);
|
||||
"all" return isc::eval::EvalParser::make_ALL(loc);
|
||||
"concat" return isc::eval::EvalParser::make_CONCAT(loc);
|
||||
|
@@ -251,31 +251,35 @@ namespace isc { namespace eval {
|
||||
{
|
||||
switch (that.type_get ())
|
||||
{
|
||||
case 37: // option_repr_type
|
||||
case 45: // option_repr_type
|
||||
value.move< TokenOption::RepresentationType > (that.value);
|
||||
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);
|
||||
break;
|
||||
|
||||
case 40: // relay6_field
|
||||
case 49: // relay6_field
|
||||
value.move< TokenRelay6Field::FieldType > (that.value);
|
||||
break;
|
||||
|
||||
case 27: // "constant string"
|
||||
case 28: // "integer"
|
||||
case 29: // "constant hexstring"
|
||||
case 30: // "option name"
|
||||
case 31: // "ip address"
|
||||
case 35: // "constant string"
|
||||
case 36: // "integer"
|
||||
case 37: // "constant hexstring"
|
||||
case 38: // "option name"
|
||||
case 39: // "ip address"
|
||||
value.move< std::string > (that.value);
|
||||
break;
|
||||
|
||||
case 36: // option_code
|
||||
case 44: // option_code
|
||||
value.move< uint16_t > (that.value);
|
||||
break;
|
||||
|
||||
case 41: // nest_level
|
||||
case 50: // nest_level
|
||||
value.move< uint8_t > (that.value);
|
||||
break;
|
||||
|
||||
@@ -294,31 +298,35 @@ namespace isc { namespace eval {
|
||||
state = that.state;
|
||||
switch (that.type_get ())
|
||||
{
|
||||
case 37: // option_repr_type
|
||||
case 45: // option_repr_type
|
||||
value.copy< TokenOption::RepresentationType > (that.value);
|
||||
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);
|
||||
break;
|
||||
|
||||
case 40: // relay6_field
|
||||
case 49: // relay6_field
|
||||
value.copy< TokenRelay6Field::FieldType > (that.value);
|
||||
break;
|
||||
|
||||
case 27: // "constant string"
|
||||
case 28: // "integer"
|
||||
case 29: // "constant hexstring"
|
||||
case 30: // "option name"
|
||||
case 31: // "ip address"
|
||||
case 35: // "constant string"
|
||||
case 36: // "integer"
|
||||
case 37: // "constant hexstring"
|
||||
case 38: // "option name"
|
||||
case 39: // "ip address"
|
||||
value.copy< std::string > (that.value);
|
||||
break;
|
||||
|
||||
case 36: // option_code
|
||||
case 44: // option_code
|
||||
value.copy< uint16_t > (that.value);
|
||||
break;
|
||||
|
||||
case 41: // nest_level
|
||||
case 50: // nest_level
|
||||
value.copy< uint8_t > (that.value);
|
||||
break;
|
||||
|
||||
@@ -358,74 +366,81 @@ namespace isc { namespace eval {
|
||||
<< yysym.location << ": ";
|
||||
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 > (); }
|
||||
#line 366 "parser.cc" // lalr1.cc:636
|
||||
#line 374 "parser.cc" // lalr1.cc:636
|
||||
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 > (); }
|
||||
#line 373 "parser.cc" // lalr1.cc:636
|
||||
#line 381 "parser.cc" // lalr1.cc:636
|
||||
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 > (); }
|
||||
#line 380 "parser.cc" // lalr1.cc:636
|
||||
#line 388 "parser.cc" // lalr1.cc:636
|
||||
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 > (); }
|
||||
#line 387 "parser.cc" // lalr1.cc:636
|
||||
#line 395 "parser.cc" // lalr1.cc:636
|
||||
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 > (); }
|
||||
#line 394 "parser.cc" // lalr1.cc:636
|
||||
#line 402 "parser.cc" // lalr1.cc:636
|
||||
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 > (); }
|
||||
#line 401 "parser.cc" // lalr1.cc:636
|
||||
#line 409 "parser.cc" // lalr1.cc:636
|
||||
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 > (); }
|
||||
#line 408 "parser.cc" // lalr1.cc:636
|
||||
#line 416 "parser.cc" // lalr1.cc:636
|
||||
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 > (); }
|
||||
#line 415 "parser.cc" // lalr1.cc:636
|
||||
#line 430 "parser.cc" // lalr1.cc:636
|
||||
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 > (); }
|
||||
#line 422 "parser.cc" // lalr1.cc:636
|
||||
#line 437 "parser.cc" // lalr1.cc:636
|
||||
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 > (); }
|
||||
#line 429 "parser.cc" // lalr1.cc:636
|
||||
#line 444 "parser.cc" // lalr1.cc:636
|
||||
break;
|
||||
|
||||
|
||||
@@ -625,31 +640,35 @@ namespace isc { namespace eval {
|
||||
when using variants. */
|
||||
switch (yyr1_[yyn])
|
||||
{
|
||||
case 37: // option_repr_type
|
||||
case 45: // option_repr_type
|
||||
yylhs.value.build< TokenOption::RepresentationType > ();
|
||||
break;
|
||||
|
||||
case 42: // pkt6_field
|
||||
case 46: // pkt4_field
|
||||
yylhs.value.build< TokenPkt4::FieldType > ();
|
||||
break;
|
||||
|
||||
case 51: // pkt6_field
|
||||
yylhs.value.build< TokenPkt6::FieldType > ();
|
||||
break;
|
||||
|
||||
case 40: // relay6_field
|
||||
case 49: // relay6_field
|
||||
yylhs.value.build< TokenRelay6Field::FieldType > ();
|
||||
break;
|
||||
|
||||
case 27: // "constant string"
|
||||
case 28: // "integer"
|
||||
case 29: // "constant hexstring"
|
||||
case 30: // "option name"
|
||||
case 31: // "ip address"
|
||||
case 35: // "constant string"
|
||||
case 36: // "integer"
|
||||
case 37: // "constant hexstring"
|
||||
case 38: // "option name"
|
||||
case 39: // "ip address"
|
||||
yylhs.value.build< std::string > ();
|
||||
break;
|
||||
|
||||
case 36: // option_code
|
||||
case 44: // option_code
|
||||
yylhs.value.build< uint16_t > ();
|
||||
break;
|
||||
|
||||
case 41: // nest_level
|
||||
case 50: // nest_level
|
||||
yylhs.value.build< uint8_t > ();
|
||||
break;
|
||||
|
||||
@@ -671,52 +690,52 @@ namespace isc { namespace eval {
|
||||
switch (yyn)
|
||||
{
|
||||
case 4:
|
||||
#line 96 "parser.yy" // lalr1.cc:859
|
||||
#line 105 "parser.yy" // lalr1.cc:859
|
||||
{
|
||||
TokenPtr neg(new TokenNot());
|
||||
ctx.expression.push_back(neg);
|
||||
}
|
||||
#line 680 "parser.cc" // lalr1.cc:859
|
||||
#line 699 "parser.cc" // lalr1.cc:859
|
||||
break;
|
||||
|
||||
case 5:
|
||||
#line 101 "parser.yy" // lalr1.cc:859
|
||||
#line 110 "parser.yy" // lalr1.cc:859
|
||||
{
|
||||
TokenPtr neg(new TokenAnd());
|
||||
ctx.expression.push_back(neg);
|
||||
}
|
||||
#line 689 "parser.cc" // lalr1.cc:859
|
||||
#line 708 "parser.cc" // lalr1.cc:859
|
||||
break;
|
||||
|
||||
case 6:
|
||||
#line 106 "parser.yy" // lalr1.cc:859
|
||||
#line 115 "parser.yy" // lalr1.cc:859
|
||||
{
|
||||
TokenPtr neg(new TokenOr());
|
||||
ctx.expression.push_back(neg);
|
||||
}
|
||||
#line 698 "parser.cc" // lalr1.cc:859
|
||||
#line 717 "parser.cc" // lalr1.cc:859
|
||||
break;
|
||||
|
||||
case 7:
|
||||
#line 111 "parser.yy" // lalr1.cc:859
|
||||
#line 120 "parser.yy" // lalr1.cc:859
|
||||
{
|
||||
TokenPtr eq(new TokenEqual());
|
||||
ctx.expression.push_back(eq);
|
||||
}
|
||||
#line 707 "parser.cc" // lalr1.cc:859
|
||||
#line 726 "parser.cc" // lalr1.cc:859
|
||||
break;
|
||||
|
||||
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));
|
||||
ctx.expression.push_back(opt);
|
||||
}
|
||||
#line 716 "parser.cc" // lalr1.cc:859
|
||||
#line 735 "parser.cc" // lalr1.cc:859
|
||||
break;
|
||||
|
||||
case 9:
|
||||
#line 121 "parser.yy" // lalr1.cc:859
|
||||
#line 130 "parser.yy" // lalr1.cc:859
|
||||
{
|
||||
switch (ctx.getUniverse()) {
|
||||
case Option::V4:
|
||||
@@ -736,11 +755,11 @@ namespace isc { namespace eval {
|
||||
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;
|
||||
|
||||
case 10:
|
||||
#line 141 "parser.yy" // lalr1.cc:859
|
||||
#line 150 "parser.yy" // lalr1.cc:859
|
||||
{
|
||||
switch (ctx.getUniverse()) {
|
||||
case Option::V6:
|
||||
@@ -754,47 +773,47 @@ namespace isc { namespace eval {
|
||||
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;
|
||||
|
||||
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 > ()));
|
||||
ctx.expression.push_back(str);
|
||||
}
|
||||
#line 767 "parser.cc" // lalr1.cc:859
|
||||
#line 786 "parser.cc" // lalr1.cc:859
|
||||
break;
|
||||
|
||||
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 > ()));
|
||||
ctx.expression.push_back(hex);
|
||||
}
|
||||
#line 776 "parser.cc" // lalr1.cc:859
|
||||
#line 795 "parser.cc" // lalr1.cc:859
|
||||
break;
|
||||
|
||||
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 > ()));
|
||||
ctx.expression.push_back(ip);
|
||||
}
|
||||
#line 785 "parser.cc" // lalr1.cc:859
|
||||
#line 804 "parser.cc" // lalr1.cc:859
|
||||
break;
|
||||
|
||||
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 > ()));
|
||||
ctx.expression.push_back(opt);
|
||||
}
|
||||
#line 794 "parser.cc" // lalr1.cc:859
|
||||
#line 813 "parser.cc" // lalr1.cc:859
|
||||
break;
|
||||
|
||||
case 15:
|
||||
#line 177 "parser.yy" // lalr1.cc:859
|
||||
#line 186 "parser.yy" // lalr1.cc:859
|
||||
{
|
||||
switch (ctx.getUniverse()) {
|
||||
case Option::V4:
|
||||
@@ -814,11 +833,11 @@ namespace isc { namespace eval {
|
||||
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;
|
||||
|
||||
case 16:
|
||||
#line 198 "parser.yy" // lalr1.cc:859
|
||||
#line 207 "parser.yy" // lalr1.cc:859
|
||||
{
|
||||
switch (ctx.getUniverse()) {
|
||||
case Option::V6:
|
||||
@@ -832,11 +851,11 @@ namespace isc { namespace eval {
|
||||
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;
|
||||
|
||||
case 17:
|
||||
#line 213 "parser.yy" // lalr1.cc:859
|
||||
#line 222 "parser.yy" // lalr1.cc:859
|
||||
{
|
||||
switch (ctx.getUniverse()) {
|
||||
case Option::V6:
|
||||
@@ -850,129 +869,194 @@ namespace isc { namespace eval {
|
||||
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;
|
||||
|
||||
case 18:
|
||||
#line 229 "parser.yy" // lalr1.cc:859
|
||||
#line 237 "parser.yy" // lalr1.cc:859
|
||||
{
|
||||
TokenPtr sub(new TokenSubstring());
|
||||
ctx.expression.push_back(sub);
|
||||
TokenPtr pkt4_field(new TokenPkt4(yystack_[0].value.as< TokenPkt4::FieldType > ()));
|
||||
ctx.expression.push_back(pkt4_field);
|
||||
}
|
||||
#line 863 "parser.cc" // lalr1.cc:859
|
||||
#line 882 "parser.cc" // lalr1.cc:859
|
||||
break;
|
||||
|
||||
case 19:
|
||||
#line 234 "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
|
||||
#line 242 "parser.yy" // lalr1.cc:859
|
||||
{
|
||||
TokenPtr pkt6_field(new TokenPkt6(yystack_[0].value.as< TokenPkt6::FieldType > ()));
|
||||
ctx.expression.push_back(pkt6_field);
|
||||
}
|
||||
#line 881 "parser.cc" // lalr1.cc:859
|
||||
#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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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 > ()));
|
||||
ctx.expression.push_back(str);
|
||||
yylhs.value.as< TokenOption::RepresentationType > () = TokenOption::HEXADECIMAL;
|
||||
}
|
||||
#line 922 "parser.cc" // lalr1.cc:859
|
||||
#line 941 "parser.cc" // lalr1.cc:859
|
||||
break;
|
||||
|
||||
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 > ()));
|
||||
ctx.expression.push_back(str);
|
||||
}
|
||||
#line 931 "parser.cc" // lalr1.cc:859
|
||||
#line 1006 "parser.cc" // lalr1.cc:859
|
||||
break;
|
||||
|
||||
case 27:
|
||||
#line 278 "parser.yy" // lalr1.cc:859
|
||||
case 34:
|
||||
#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"));
|
||||
ctx.expression.push_back(str);
|
||||
}
|
||||
#line 940 "parser.cc" // lalr1.cc:859
|
||||
#line 1024 "parser.cc" // lalr1.cc:859
|
||||
break;
|
||||
|
||||
case 28:
|
||||
#line 284 "parser.yy" // lalr1.cc:859
|
||||
case 36:
|
||||
#line 327 "parser.yy" // lalr1.cc:859
|
||||
{ yylhs.value.as< TokenRelay6Field::FieldType > () = TokenRelay6Field::PEERADDR; }
|
||||
#line 946 "parser.cc" // lalr1.cc:859
|
||||
#line 1030 "parser.cc" // lalr1.cc:859
|
||||
break;
|
||||
|
||||
case 29:
|
||||
#line 285 "parser.yy" // lalr1.cc:859
|
||||
case 37:
|
||||
#line 328 "parser.yy" // lalr1.cc:859
|
||||
{ yylhs.value.as< TokenRelay6Field::FieldType > () = TokenRelay6Field::LINKADDR; }
|
||||
#line 952 "parser.cc" // lalr1.cc:859
|
||||
#line 1036 "parser.cc" // lalr1.cc:859
|
||||
break;
|
||||
|
||||
case 30:
|
||||
#line 289 "parser.yy" // lalr1.cc:859
|
||||
case 38:
|
||||
#line 332 "parser.yy" // lalr1.cc:859
|
||||
{
|
||||
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;
|
||||
|
||||
case 31:
|
||||
#line 297 "parser.yy" // lalr1.cc:859
|
||||
case 39:
|
||||
#line 340 "parser.yy" // lalr1.cc:859
|
||||
{ yylhs.value.as< TokenPkt6::FieldType > () = TokenPkt6::MSGTYPE; }
|
||||
#line 966 "parser.cc" // lalr1.cc:859
|
||||
#line 1050 "parser.cc" // lalr1.cc:859
|
||||
break;
|
||||
|
||||
case 32:
|
||||
#line 298 "parser.yy" // lalr1.cc:859
|
||||
case 40:
|
||||
#line 341 "parser.yy" // lalr1.cc:859
|
||||
{ yylhs.value.as< TokenPkt6::FieldType > () = TokenPkt6::TRANSID; }
|
||||
#line 972 "parser.cc" // lalr1.cc:859
|
||||
#line 1056 "parser.cc" // lalr1.cc:859
|
||||
break;
|
||||
|
||||
|
||||
#line 976 "parser.cc" // lalr1.cc:859
|
||||
#line 1060 "parser.cc" // lalr1.cc:859
|
||||
default:
|
||||
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::yypact_[] =
|
||||
{
|
||||
29, 29, 29, -12, -4, 7, 21, 30, 32, -54,
|
||||
-54, -54, 13, 10, 46, 16, -54, -3, -3, 9,
|
||||
52, 52, 42, -54, 29, 29, 52, -54, -54, -54,
|
||||
40, 54, -54, 56, 43, 59, 60, 55, 58, -54,
|
||||
-54, -54, -54, 72, -54, 66, 68, 69, -3, -3,
|
||||
9, 61, 52, 25, 28, -1, 71, 73, 75, -54,
|
||||
65, 87, -54, -54, -54, -54, -54, -54, 78, -54,
|
||||
-54, -54, 77, 79, 80, -14, -54, -3, 33, 33,
|
||||
6, -54, -54, 90, 82, 84, -54, 83, -3, 47,
|
||||
85, -54, -54, 86, 33
|
||||
14, 14, 14, 6, 17, 18, 21, 41, 44, 48,
|
||||
-62, -62, -62, 72, 20, 66, 29, -62, 12, 12,
|
||||
16, 36, 45, 45, -24, -62, 14, 14, 45, -62,
|
||||
-62, -62, 60, 63, -62, 73, -62, -62, -62, -62,
|
||||
-62, -62, -62, -62, 67, 69, 75, 61, 62, -62,
|
||||
-62, -62, -62, 84, -62, 77, 78, 79, 12, 12,
|
||||
16, 64, 45, -3, 52, -1, 81, 82, 83, -62,
|
||||
71, 95, -62, -62, -62, -62, -62, -62, 88, -62,
|
||||
-62, -62, 87, 89, 90, -23, -62, 12, 49, 49,
|
||||
9, -62, -62, 100, 92, 94, -62, 93, 12, 68,
|
||||
96, -62, -62, 97, 49
|
||||
};
|
||||
|
||||
const unsigned char
|
||||
EvalParser::yydefact_[] =
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 11,
|
||||
12, 13, 0, 2, 0, 0, 4, 0, 0, 0,
|
||||
0, 0, 0, 1, 0, 0, 0, 3, 21, 22,
|
||||
0, 0, 30, 0, 0, 0, 0, 0, 0, 31,
|
||||
32, 20, 5, 6, 7, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 25,
|
||||
0, 0, 23, 24, 8, 14, 9, 15, 0, 28,
|
||||
29, 17, 0, 0, 0, 0, 19, 0, 0, 0,
|
||||
0, 27, 26, 0, 0, 0, 18, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
11, 12, 13, 0, 2, 0, 0, 4, 0, 0,
|
||||
0, 0, 0, 0, 0, 1, 0, 0, 0, 3,
|
||||
22, 23, 0, 0, 38, 0, 26, 27, 28, 29,
|
||||
30, 31, 32, 18, 0, 0, 0, 0, 0, 39,
|
||||
40, 19, 5, 6, 7, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 33,
|
||||
0, 0, 24, 25, 8, 14, 9, 15, 0, 36,
|
||||
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
|
||||
};
|
||||
|
||||
const signed char
|
||||
EvalParser::yypgoto_[] =
|
||||
{
|
||||
-54, -54, 4, -17, -18, -53, -54, -54, -54, 51,
|
||||
-54
|
||||
-62, -62, 3, -21, -19, -61, -62, -62, -62, -62,
|
||||
50, -62
|
||||
};
|
||||
|
||||
const signed char
|
||||
EvalParser::yydefgoto_[] =
|
||||
{
|
||||
-1, 12, 13, 14, 30, 65, 60, 83, 71, 33,
|
||||
41
|
||||
-1, 13, 14, 15, 32, 75, 43, 70, 93, 81,
|
||||
35, 51
|
||||
};
|
||||
|
||||
const unsigned char
|
||||
EvalParser::yytable_[] =
|
||||
{
|
||||
31, 67, 17, 37, 38, 15, 16, 81, 68, 44,
|
||||
18, 69, 70, 23, 82, 85, 24, 25, 69, 70,
|
||||
27, 19, 24, 25, 20, 28, 67, 29, 42, 43,
|
||||
56, 57, 1, 21, 2, 61, 92, 32, 3, 4,
|
||||
5, 92, 62, 63, 64, 62, 63, 66, 22, 6,
|
||||
62, 63, 7, 8, 26, 45, 9, 48, 10, 84,
|
||||
11, 34, 35, 36, 62, 63, 91, 39, 40, 46,
|
||||
90, 47, 6, 49, 50, 7, 8, 51, 24, 9,
|
||||
52, 10, 53, 11, 54, 55, 72, 75, 73, 59,
|
||||
74, 76, 77, 78, 86, 79, 80, 87, 88, 89,
|
||||
93, 58, 94
|
||||
33, 47, 48, 77, 16, 17, 91, 54, 78, 49,
|
||||
50, 79, 80, 92, 72, 73, 74, 1, 95, 2,
|
||||
18, 79, 80, 3, 4, 5, 26, 27, 77, 52,
|
||||
53, 19, 20, 29, 6, 26, 27, 21, 102, 66,
|
||||
67, 71, 7, 102, 22, 8, 9, 23, 30, 10,
|
||||
31, 11, 34, 12, 44, 45, 46, 36, 37, 38,
|
||||
39, 40, 41, 42, 24, 6, 72, 73, 94, 72,
|
||||
73, 76, 25, 7, 28, 55, 8, 9, 56, 100,
|
||||
10, 58, 11, 59, 12, 72, 73, 101, 57, 60,
|
||||
26, 61, 62, 63, 64, 65, 82, 83, 84, 86,
|
||||
69, 85, 87, 88, 96, 89, 90, 97, 98, 99,
|
||||
68, 103, 0, 104
|
||||
};
|
||||
|
||||
const unsigned char
|
||||
const signed char
|
||||
EvalParser::yycheck_[] =
|
||||
{
|
||||
18, 54, 14, 20, 21, 1, 2, 21, 9, 26,
|
||||
14, 12, 13, 0, 28, 9, 6, 7, 12, 13,
|
||||
4, 14, 6, 7, 3, 28, 79, 30, 24, 25,
|
||||
48, 49, 3, 3, 5, 52, 89, 28, 9, 10,
|
||||
11, 94, 17, 18, 19, 17, 18, 19, 16, 20,
|
||||
17, 18, 23, 24, 8, 15, 27, 14, 29, 77,
|
||||
31, 9, 10, 11, 17, 18, 19, 25, 26, 15,
|
||||
88, 15, 20, 14, 14, 23, 24, 22, 6, 27,
|
||||
22, 29, 16, 31, 16, 16, 15, 22, 15, 28,
|
||||
15, 4, 14, 16, 4, 16, 16, 15, 14, 16,
|
||||
15, 50, 16
|
||||
19, 22, 23, 64, 1, 2, 29, 28, 9, 33,
|
||||
34, 12, 13, 36, 17, 18, 19, 3, 9, 5,
|
||||
14, 12, 13, 9, 10, 11, 6, 7, 89, 26,
|
||||
27, 14, 14, 4, 20, 6, 7, 16, 99, 58,
|
||||
59, 62, 28, 104, 3, 31, 32, 3, 36, 35,
|
||||
38, 37, 36, 39, 9, 10, 11, 21, 22, 23,
|
||||
24, 25, 26, 27, 16, 20, 17, 18, 87, 17,
|
||||
18, 19, 0, 28, 8, 15, 31, 32, 15, 98,
|
||||
35, 14, 37, 14, 39, 17, 18, 19, 15, 14,
|
||||
6, 30, 30, 16, 16, 16, 15, 15, 15, 4,
|
||||
36, 30, 14, 16, 4, 16, 16, 15, 14, 16,
|
||||
60, 15, -1, 16
|
||||
};
|
||||
|
||||
const unsigned char
|
||||
EvalParser::yystos_[] =
|
||||
{
|
||||
0, 3, 5, 9, 10, 11, 20, 23, 24, 27,
|
||||
29, 31, 33, 34, 35, 34, 34, 14, 14, 14,
|
||||
3, 3, 16, 0, 6, 7, 8, 4, 28, 30,
|
||||
36, 36, 28, 41, 9, 10, 11, 35, 35, 25,
|
||||
26, 42, 34, 34, 35, 15, 15, 15, 14, 14,
|
||||
14, 22, 22, 16, 16, 16, 36, 36, 41, 28,
|
||||
38, 35, 17, 18, 19, 37, 19, 37, 9, 12,
|
||||
13, 40, 15, 15, 15, 22, 4, 14, 16, 16,
|
||||
16, 21, 28, 39, 36, 9, 4, 15, 14, 16,
|
||||
36, 19, 37, 15, 16
|
||||
0, 3, 5, 9, 10, 11, 20, 28, 31, 32,
|
||||
35, 37, 39, 41, 42, 43, 42, 42, 14, 14,
|
||||
14, 16, 3, 3, 16, 0, 6, 7, 8, 4,
|
||||
36, 38, 44, 44, 36, 50, 21, 22, 23, 24,
|
||||
25, 26, 27, 46, 9, 10, 11, 43, 43, 33,
|
||||
34, 51, 42, 42, 43, 15, 15, 15, 14, 14,
|
||||
14, 30, 30, 16, 16, 16, 44, 44, 50, 36,
|
||||
47, 43, 17, 18, 19, 45, 19, 45, 9, 12,
|
||||
13, 49, 15, 15, 15, 30, 4, 14, 16, 16,
|
||||
16, 29, 36, 48, 44, 9, 4, 15, 14, 16,
|
||||
44, 19, 45, 15, 16
|
||||
};
|
||||
|
||||
const unsigned char
|
||||
EvalParser::yyr1_[] =
|
||||
{
|
||||
0, 32, 33, 34, 34, 34, 34, 34, 34, 34,
|
||||
34, 35, 35, 35, 35, 35, 35, 35, 35, 35,
|
||||
35, 36, 36, 37, 37, 38, 39, 39, 40, 40,
|
||||
41, 42, 42
|
||||
0, 40, 41, 42, 42, 42, 42, 42, 42, 42,
|
||||
42, 43, 43, 43, 43, 43, 43, 43, 43, 43,
|
||||
43, 43, 44, 44, 45, 45, 46, 46, 46, 46,
|
||||
46, 46, 46, 47, 48, 48, 49, 49, 50, 51,
|
||||
51
|
||||
};
|
||||
|
||||
const unsigned char
|
||||
EvalParser::yyr2_[] =
|
||||
{
|
||||
0, 2, 1, 3, 2, 3, 3, 3, 6, 6,
|
||||
11, 1, 1, 1, 6, 6, 11, 6, 8, 6,
|
||||
3, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1
|
||||
11, 1, 1, 1, 6, 6, 11, 6, 3, 3,
|
||||
8, 6, 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\"",
|
||||
"\"and\"", "\"or\"", "\"==\"", "\"option\"", "\"relay4\"", "\"relay6\"",
|
||||
"\"peeraddr\"", "\"linkaddr\"", "\"[\"", "\"]\"", "\".\"", "\"text\"",
|
||||
"\"hex\"", "\"exists\"", "\"substring\"", "\"all\"", "\",\"",
|
||||
"\"concat\"", "\"pkt6\"", "\"msgtype\"", "\"transid\"",
|
||||
"\"constant string\"", "\"integer\"", "\"constant hexstring\"",
|
||||
"\"option name\"", "\"ip address\"", "$accept", "expression",
|
||||
"bool_expr", "string_expr", "option_code", "option_repr_type",
|
||||
"start_expr", "length_expr", "relay6_field", "nest_level", "pkt6_field", YY_NULLPTR
|
||||
"\"hex\"", "\"exists\"", "\"pkt4\"", "\"mac\"", "\"hlen\"", "\"htype\"",
|
||||
"\"ciaddr\"", "\"giaddr\"", "\"yiaddr\"", "\"siaddr\"", "\"substring\"",
|
||||
"\"all\"", "\",\"", "\"concat\"", "\"pkt6\"", "\"msgtype\"",
|
||||
"\"transid\"", "\"constant string\"", "\"integer\"",
|
||||
"\"constant hexstring\"", "\"option name\"", "\"ip address\"", "$accept",
|
||||
"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
|
||||
const unsigned short int
|
||||
EvalParser::yyrline_[] =
|
||||
{
|
||||
0, 91, 91, 94, 95, 100, 105, 110, 115, 120,
|
||||
140, 156, 161, 166, 171, 176, 197, 212, 228, 233,
|
||||
238, 245, 249, 255, 259, 265, 272, 277, 284, 285,
|
||||
288, 297, 298
|
||||
0, 100, 100, 103, 104, 109, 114, 119, 124, 129,
|
||||
149, 165, 170, 175, 180, 185, 206, 221, 236, 241,
|
||||
246, 251, 258, 262, 268, 272, 278, 282, 286, 290,
|
||||
294, 298, 302, 308, 315, 320, 327, 328, 331, 340,
|
||||
341
|
||||
};
|
||||
|
||||
// Print the state stack on the debug stream.
|
||||
@@ -1400,8 +1494,8 @@ namespace isc { namespace eval {
|
||||
|
||||
#line 13 "parser.yy" // lalr1.cc:1167
|
||||
} } // isc::eval
|
||||
#line 1404 "parser.cc" // lalr1.cc:1167
|
||||
#line 301 "parser.yy" // lalr1.cc:1168
|
||||
#line 1498 "parser.cc" // lalr1.cc:1167
|
||||
#line 344 "parser.yy" // lalr1.cc:1168
|
||||
|
||||
void
|
||||
isc::eval::EvalParser::error(const location_type& loc,
|
||||
|
@@ -40,7 +40,7 @@
|
||||
#ifndef YY_YY_PARSER_H_INCLUDED
|
||||
# define YY_YY_PARSER_H_INCLUDED
|
||||
// // "%code requires" blocks.
|
||||
#line 16 "parser.yy" // lalr1.cc:377
|
||||
#line 16 "parser.yy" // lalr1.cc:392
|
||||
|
||||
#include <string>
|
||||
#include <eval/token.h>
|
||||
@@ -51,7 +51,7 @@
|
||||
using namespace isc::dhcp;
|
||||
using namespace isc::eval;
|
||||
|
||||
#line 55 "parser.h" // lalr1.cc:377
|
||||
#line 55 "parser.h" // lalr1.cc:392
|
||||
|
||||
# include <cassert>
|
||||
# include <cstdlib> // std::abort
|
||||
@@ -126,9 +126,9 @@ using namespace isc::eval;
|
||||
# define YYDEBUG 1
|
||||
#endif
|
||||
|
||||
#line 13 "parser.yy" // lalr1.cc:377
|
||||
#line 13 "parser.yy" // lalr1.cc:392
|
||||
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
|
||||
char dummy1[sizeof(TokenOption::RepresentationType)];
|
||||
|
||||
// pkt4_field
|
||||
char dummy2[sizeof(TokenPkt4::FieldType)];
|
||||
|
||||
// pkt6_field
|
||||
char dummy2[sizeof(TokenPkt6::FieldType)];
|
||||
char dummy3[sizeof(TokenPkt6::FieldType)];
|
||||
|
||||
// relay6_field
|
||||
char dummy3[sizeof(TokenRelay6Field::FieldType)];
|
||||
char dummy4[sizeof(TokenRelay6Field::FieldType)];
|
||||
|
||||
// "constant string"
|
||||
// "integer"
|
||||
// "constant hexstring"
|
||||
// "option name"
|
||||
// "ip address"
|
||||
char dummy4[sizeof(std::string)];
|
||||
char dummy5[sizeof(std::string)];
|
||||
|
||||
// option_code
|
||||
char dummy5[sizeof(uint16_t)];
|
||||
char dummy6[sizeof(uint16_t)];
|
||||
|
||||
// nest_level
|
||||
char dummy6[sizeof(uint8_t)];
|
||||
char dummy7[sizeof(uint8_t)];
|
||||
};
|
||||
|
||||
/// Symbol semantic values.
|
||||
@@ -356,18 +359,26 @@ namespace isc { namespace eval {
|
||||
TOKEN_TEXT = 272,
|
||||
TOKEN_HEX = 273,
|
||||
TOKEN_EXISTS = 274,
|
||||
TOKEN_SUBSTRING = 275,
|
||||
TOKEN_ALL = 276,
|
||||
TOKEN_COMA = 277,
|
||||
TOKEN_CONCAT = 278,
|
||||
TOKEN_PKT6 = 279,
|
||||
TOKEN_MSGTYPE = 280,
|
||||
TOKEN_TRANSID = 281,
|
||||
TOKEN_STRING = 282,
|
||||
TOKEN_INTEGER = 283,
|
||||
TOKEN_HEXSTRING = 284,
|
||||
TOKEN_OPTION_NAME = 285,
|
||||
TOKEN_IP_ADDRESS = 286
|
||||
TOKEN_PKT4 = 275,
|
||||
TOKEN_CHADDR = 276,
|
||||
TOKEN_HLEN = 277,
|
||||
TOKEN_HTYPE = 278,
|
||||
TOKEN_CIADDR = 279,
|
||||
TOKEN_GIADDR = 280,
|
||||
TOKEN_YIADDR = 281,
|
||||
TOKEN_SIADDR = 282,
|
||||
TOKEN_SUBSTRING = 283,
|
||||
TOKEN_ALL = 284,
|
||||
TOKEN_COMA = 285,
|
||||
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 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 TokenRelay6Field::FieldType v, const location_type& l);
|
||||
@@ -556,6 +569,38 @@ namespace isc { namespace eval {
|
||||
symbol_type
|
||||
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
|
||||
symbol_type
|
||||
make_SUBSTRING (const location_type& l);
|
||||
@@ -689,7 +734,7 @@ namespace isc { namespace eval {
|
||||
// number is the opposite. If YYTABLE_NINF, syntax error.
|
||||
static const unsigned char yytable_[];
|
||||
|
||||
static const unsigned char yycheck_[];
|
||||
static const signed char yycheck_[];
|
||||
|
||||
// YYSTOS[STATE-NUM] -- The (internal number of the) accessing
|
||||
// symbol of state STATE-NUM.
|
||||
@@ -809,12 +854,12 @@ namespace isc { namespace eval {
|
||||
enum
|
||||
{
|
||||
yyeof_ = 0,
|
||||
yylast_ = 102, ///< Last index in yytable_.
|
||||
yynnts_ = 11, ///< Number of nonterminal symbols.
|
||||
yyfinal_ = 23, ///< Termination state number.
|
||||
yylast_ = 113, ///< Last index in yytable_.
|
||||
yynnts_ = 12, ///< Number of nonterminal symbols.
|
||||
yyfinal_ = 25, ///< Termination state number.
|
||||
yyterror_ = 1,
|
||||
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,
|
||||
5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
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;
|
||||
|
||||
if (static_cast<int>(t) <= yyeof_)
|
||||
@@ -894,31 +940,35 @@ namespace isc { namespace eval {
|
||||
{
|
||||
switch (other.type_get ())
|
||||
{
|
||||
case 37: // option_repr_type
|
||||
case 45: // option_repr_type
|
||||
value.copy< TokenOption::RepresentationType > (other.value);
|
||||
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);
|
||||
break;
|
||||
|
||||
case 40: // relay6_field
|
||||
case 49: // relay6_field
|
||||
value.copy< TokenRelay6Field::FieldType > (other.value);
|
||||
break;
|
||||
|
||||
case 27: // "constant string"
|
||||
case 28: // "integer"
|
||||
case 29: // "constant hexstring"
|
||||
case 30: // "option name"
|
||||
case 31: // "ip address"
|
||||
case 35: // "constant string"
|
||||
case 36: // "integer"
|
||||
case 37: // "constant hexstring"
|
||||
case 38: // "option name"
|
||||
case 39: // "ip address"
|
||||
value.copy< std::string > (other.value);
|
||||
break;
|
||||
|
||||
case 36: // option_code
|
||||
case 44: // option_code
|
||||
value.copy< uint16_t > (other.value);
|
||||
break;
|
||||
|
||||
case 41: // nest_level
|
||||
case 50: // nest_level
|
||||
value.copy< uint8_t > (other.value);
|
||||
break;
|
||||
|
||||
@@ -939,31 +989,35 @@ namespace isc { namespace eval {
|
||||
(void) v;
|
||||
switch (this->type_get ())
|
||||
{
|
||||
case 37: // option_repr_type
|
||||
case 45: // option_repr_type
|
||||
value.copy< TokenOption::RepresentationType > (v);
|
||||
break;
|
||||
|
||||
case 42: // pkt6_field
|
||||
case 46: // pkt4_field
|
||||
value.copy< TokenPkt4::FieldType > (v);
|
||||
break;
|
||||
|
||||
case 51: // pkt6_field
|
||||
value.copy< TokenPkt6::FieldType > (v);
|
||||
break;
|
||||
|
||||
case 40: // relay6_field
|
||||
case 49: // relay6_field
|
||||
value.copy< TokenRelay6Field::FieldType > (v);
|
||||
break;
|
||||
|
||||
case 27: // "constant string"
|
||||
case 28: // "integer"
|
||||
case 29: // "constant hexstring"
|
||||
case 30: // "option name"
|
||||
case 31: // "ip address"
|
||||
case 35: // "constant string"
|
||||
case 36: // "integer"
|
||||
case 37: // "constant hexstring"
|
||||
case 38: // "option name"
|
||||
case 39: // "ip address"
|
||||
value.copy< std::string > (v);
|
||||
break;
|
||||
|
||||
case 36: // option_code
|
||||
case 44: // option_code
|
||||
value.copy< uint16_t > (v);
|
||||
break;
|
||||
|
||||
case 41: // nest_level
|
||||
case 50: // nest_level
|
||||
value.copy< uint8_t > (v);
|
||||
break;
|
||||
|
||||
@@ -989,6 +1043,13 @@ namespace isc { namespace eval {
|
||||
, 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>
|
||||
EvalParser::basic_symbol<Base>::basic_symbol (typename Base::kind_type t, const TokenPkt6::FieldType v, const location_type& l)
|
||||
: Base (t)
|
||||
@@ -1050,31 +1111,35 @@ namespace isc { namespace eval {
|
||||
// Type destructor.
|
||||
switch (yytype)
|
||||
{
|
||||
case 37: // option_repr_type
|
||||
case 45: // option_repr_type
|
||||
value.template destroy< TokenOption::RepresentationType > ();
|
||||
break;
|
||||
|
||||
case 42: // pkt6_field
|
||||
case 46: // pkt4_field
|
||||
value.template destroy< TokenPkt4::FieldType > ();
|
||||
break;
|
||||
|
||||
case 51: // pkt6_field
|
||||
value.template destroy< TokenPkt6::FieldType > ();
|
||||
break;
|
||||
|
||||
case 40: // relay6_field
|
||||
case 49: // relay6_field
|
||||
value.template destroy< TokenRelay6Field::FieldType > ();
|
||||
break;
|
||||
|
||||
case 27: // "constant string"
|
||||
case 28: // "integer"
|
||||
case 29: // "constant hexstring"
|
||||
case 30: // "option name"
|
||||
case 31: // "ip address"
|
||||
case 35: // "constant string"
|
||||
case 36: // "integer"
|
||||
case 37: // "constant hexstring"
|
||||
case 38: // "option name"
|
||||
case 39: // "ip address"
|
||||
value.template destroy< std::string > ();
|
||||
break;
|
||||
|
||||
case 36: // option_code
|
||||
case 44: // option_code
|
||||
value.template destroy< uint16_t > ();
|
||||
break;
|
||||
|
||||
case 41: // nest_level
|
||||
case 50: // nest_level
|
||||
value.template destroy< uint8_t > ();
|
||||
break;
|
||||
|
||||
@@ -1101,31 +1166,35 @@ namespace isc { namespace eval {
|
||||
super_type::move(s);
|
||||
switch (this->type_get ())
|
||||
{
|
||||
case 37: // option_repr_type
|
||||
case 45: // option_repr_type
|
||||
value.move< TokenOption::RepresentationType > (s.value);
|
||||
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);
|
||||
break;
|
||||
|
||||
case 40: // relay6_field
|
||||
case 49: // relay6_field
|
||||
value.move< TokenRelay6Field::FieldType > (s.value);
|
||||
break;
|
||||
|
||||
case 27: // "constant string"
|
||||
case 28: // "integer"
|
||||
case 29: // "constant hexstring"
|
||||
case 30: // "option name"
|
||||
case 31: // "ip address"
|
||||
case 35: // "constant string"
|
||||
case 36: // "integer"
|
||||
case 37: // "constant hexstring"
|
||||
case 38: // "option name"
|
||||
case 39: // "ip address"
|
||||
value.move< std::string > (s.value);
|
||||
break;
|
||||
|
||||
case 36: // option_code
|
||||
case 44: // option_code
|
||||
value.move< uint16_t > (s.value);
|
||||
break;
|
||||
|
||||
case 41: // nest_level
|
||||
case 50: // nest_level
|
||||
value.move< uint8_t > (s.value);
|
||||
break;
|
||||
|
||||
@@ -1187,7 +1256,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, 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]);
|
||||
}
|
||||
@@ -1300,6 +1369,54 @@ namespace isc { namespace eval {
|
||||
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::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
|
||||
#line 1379 "parser.h" // lalr1.cc:377
|
||||
#line 1496 "parser.h" // lalr1.cc:392
|
||||
|
||||
|
||||
|
||||
|
@@ -54,6 +54,14 @@ using namespace isc::eval;
|
||||
TEXT "text"
|
||||
HEX "hex"
|
||||
EXISTS "exists"
|
||||
PKT4 "pkt4"
|
||||
CHADDR "mac"
|
||||
HLEN "hlen"
|
||||
HTYPE "htype"
|
||||
CIADDR "ciaddr"
|
||||
GIADDR "giaddr"
|
||||
YIADDR "yiaddr"
|
||||
SIADDR "siaddr"
|
||||
SUBSTRING "substring"
|
||||
ALL "all"
|
||||
COMA ","
|
||||
@@ -73,6 +81,7 @@ using namespace isc::eval;
|
||||
%type <TokenOption::RepresentationType> option_repr_type
|
||||
%type <TokenRelay6Field::FieldType> relay6_field
|
||||
%type <uint8_t> nest_level
|
||||
%type <TokenPkt4::FieldType> pkt4_field
|
||||
%type <TokenPkt6::FieldType> pkt6_field
|
||||
|
||||
%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 ")"
|
||||
{
|
||||
TokenPtr sub(new TokenSubstring());
|
||||
@@ -235,11 +253,6 @@ string_expr : STRING
|
||||
TokenPtr conc(new TokenConcat());
|
||||
ctx.expression.push_back(conc);
|
||||
}
|
||||
| PKT6 "." pkt6_field
|
||||
{
|
||||
TokenPtr pkt6_field(new TokenPkt6($3));
|
||||
ctx.expression.push_back(pkt6_field);
|
||||
}
|
||||
;
|
||||
|
||||
option_code : INTEGER
|
||||
@@ -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
|
||||
{
|
||||
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
|
||||
void checkTokenSubstring(const TokenPtr& token) {
|
||||
ASSERT_TRUE(token);
|
||||
@@ -585,6 +630,41 @@ TEST_F(EvalContextTest, relay4Error) {
|
||||
"<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.
|
||||
TEST_F(EvalContextTest, pkt6FieldMsgtype) {
|
||||
testPkt6Field("pkt6.msgtype == '1'", TokenPkt6::MSGTYPE, 3);
|
||||
@@ -790,6 +870,7 @@ TEST_F(EvalContextTest, scanErrors) {
|
||||
checkError("foo", "<string>:1.1: Invalid character: f");
|
||||
checkError(" bar", "<string>:1.2: Invalid character: b");
|
||||
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
|
||||
|
@@ -20,6 +20,7 @@
|
||||
|
||||
using namespace std;
|
||||
using namespace isc::dhcp;
|
||||
using namespace isc::asiolink;
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -708,6 +709,86 @@ TEST_F(TokenTest, relay4RAIOnly) {
|
||||
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
|
||||
// compare two values (with incorrectly built stack).
|
||||
TEST_F(TokenTest, optionEqualInvalid) {
|
||||
|
@@ -8,6 +8,7 @@
|
||||
#include <eval/eval_log.h>
|
||||
#include <util/encode/hex.h>
|
||||
#include <asiolink/io_address.h>
|
||||
#include <dhcp/pkt4.h>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <dhcp/pkt6.h>
|
||||
#include <cstring>
|
||||
@@ -124,6 +125,77 @@ OptionPtr TokenRelay4Option::getOption(const Pkt& pkt) {
|
||||
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
|
||||
TokenEqual::evaluate(const Pkt& /*pkt*/, ValueStack& values) {
|
||||
|
||||
|
@@ -288,6 +288,61 @@ protected:
|
||||
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)
|
||||
///
|
||||
/// For example in the expression option[vendor-class].text == "MSFT"
|
||||
|
Reference in New Issue
Block a user