mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-09-01 06:25:34 +00:00
[150-add-sub-option-classification] Checkpoint: code done, todo regen and tests
This commit is contained in:
committed by
Tomek Mrugalski
parent
eda0c2f35f
commit
1ef44a79d2
@@ -1,4 +1,4 @@
|
||||
// File created from ../../../src/lib/eval/eval_messages.mes on Fri Feb 08 2019 20:17
|
||||
// File created from ../../../src/lib/eval/eval_messages.mes on Fri Jun 14 2019 20:35
|
||||
|
||||
#include <cstddef>
|
||||
#include <log/message_types.h>
|
||||
@@ -27,6 +27,8 @@ extern const isc::log::MessageID EVAL_DEBUG_STRING = "EVAL_DEBUG_STRING";
|
||||
extern const isc::log::MessageID EVAL_DEBUG_SUBSTRING = "EVAL_DEBUG_SUBSTRING";
|
||||
extern const isc::log::MessageID EVAL_DEBUG_SUBSTRING_EMPTY = "EVAL_DEBUG_SUBSTRING_EMPTY";
|
||||
extern const isc::log::MessageID EVAL_DEBUG_SUBSTRING_RANGE = "EVAL_DEBUG_SUBSTRING_RANGE";
|
||||
extern const isc::log::MessageID EVAL_DEBUG_SUB_OPTION = "EVAL_DEBUG_SUB_OPTION";
|
||||
extern const isc::log::MessageID EVAL_DEBUG_SUB_OPTION_NO_OPTION = "EVAL_DEBUG_SUB_OPTION_NO_OPTION";
|
||||
extern const isc::log::MessageID EVAL_DEBUG_TOHEXSTRING = "EVAL_DEBUG_TOHEXSTRING";
|
||||
extern const isc::log::MessageID EVAL_DEBUG_VENDOR_CLASS_DATA = "EVAL_DEBUG_VENDOR_CLASS_DATA";
|
||||
extern const isc::log::MessageID EVAL_DEBUG_VENDOR_CLASS_DATA_NOT_FOUND = "EVAL_DEBUG_VENDOR_CLASS_DATA_NOT_FOUND";
|
||||
@@ -66,6 +68,8 @@ const char* values[] = {
|
||||
"EVAL_DEBUG_SUBSTRING", "Popping length %1, start %2, string %3 pushing result %4",
|
||||
"EVAL_DEBUG_SUBSTRING_EMPTY", "Popping length %1, start %2, string %3 pushing result %4",
|
||||
"EVAL_DEBUG_SUBSTRING_RANGE", "Popping length %1, start %2, string %3 pushing result %4",
|
||||
"EVAL_DEBUG_SUB_OPTION", "Pushing option %1 sub-option %2 with value %3",
|
||||
"EVAL_DEBUG_SUB_OPTION_NO_OPTION", "Requested option %1 sub-option %2, but the parent option is not present, pushing result %3",
|
||||
"EVAL_DEBUG_TOHEXSTRING", "Popping binary value %1 and separator %2, pushing result %3",
|
||||
"EVAL_DEBUG_VENDOR_CLASS_DATA", "Data %1 (out of %2 received) in vendor class found, pushing result '%3'",
|
||||
"EVAL_DEBUG_VENDOR_CLASS_DATA_NOT_FOUND", "Requested data index %1, but option with enterprise-id %2 has only %3 data tuple(s), pushing result '%4'",
|
||||
|
@@ -1,4 +1,4 @@
|
||||
// File created from ../../../src/lib/eval/eval_messages.mes on Fri Feb 08 2019 20:17
|
||||
// File created from ../../../src/lib/eval/eval_messages.mes on Fri Jun 14 2019 20:35
|
||||
|
||||
#ifndef EVAL_MESSAGES_H
|
||||
#define EVAL_MESSAGES_H
|
||||
@@ -28,6 +28,8 @@ extern const isc::log::MessageID EVAL_DEBUG_STRING;
|
||||
extern const isc::log::MessageID EVAL_DEBUG_SUBSTRING;
|
||||
extern const isc::log::MessageID EVAL_DEBUG_SUBSTRING_EMPTY;
|
||||
extern const isc::log::MessageID EVAL_DEBUG_SUBSTRING_RANGE;
|
||||
extern const isc::log::MessageID EVAL_DEBUG_SUB_OPTION;
|
||||
extern const isc::log::MessageID EVAL_DEBUG_SUB_OPTION_NO_OPTION;
|
||||
extern const isc::log::MessageID EVAL_DEBUG_TOHEXSTRING;
|
||||
extern const isc::log::MessageID EVAL_DEBUG_VENDOR_CLASS_DATA;
|
||||
extern const isc::log::MessageID EVAL_DEBUG_VENDOR_CLASS_DATA_NOT_FOUND;
|
||||
|
@@ -1,4 +1,4 @@
|
||||
# Copyright (C) 2015-2018 Internet Systems Consortium, Inc. ("ISC")
|
||||
# Copyright (C) 2015-2019 Internet Systems Consortium, Inc. ("ISC")
|
||||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
@@ -144,6 +144,22 @@ string and an empty result will be pushed onto the stack. The start,
|
||||
length and string are still popped from the stack and the result is
|
||||
still pushed. The strings are displayed in hex.
|
||||
|
||||
# For use with TokenSubOption
|
||||
|
||||
% EVAL_DEBUG_SUB_OPTION Pushing option %1 sub-option %2 with value %3
|
||||
This debug message indicates that the given string representing the
|
||||
value of the requested sub-option of the requested parent option is
|
||||
being pushed onto the value stack. The string may be the text or
|
||||
binary value of the string based on the representation type requested
|
||||
(.text or .hex) or "true" or "false" if the requested type is .exists.
|
||||
The codes are the parent option and the sub-option codes as requested
|
||||
in the classification statement.
|
||||
|
||||
% EVAL_DEBUG_SUB_OPTION_NO_OPTION Requested option %1 sub-option %2, but the parent option is not present, pushing result %3
|
||||
This debug message indicates that the parent option was not found.
|
||||
The codes are the parent option and the sub-option codes as requested
|
||||
in the classification statement.
|
||||
|
||||
# For use with TokenToHexString
|
||||
|
||||
% EVAL_DEBUG_TOHEXSTRING Popping binary value %1 and separator %2, pushing result %3
|
||||
|
@@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2015-2018 Internet Systems Consortium, Inc. ("ISC")
|
||||
/* Copyright (C) 2015-2019 Internet Systems Consortium, Inc. ("ISC")
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
@@ -152,6 +152,11 @@ bool_expr : "(" bool_expr ")"
|
||||
TokenPtr opt(new TokenOption($3, TokenOption::EXISTS));
|
||||
ctx.expression.push_back(opt);
|
||||
}
|
||||
| OPTION "[" option_code "]" "." OPTION "[" option_code "]" "." EXISTS
|
||||
{
|
||||
TokenPtr opt(new TokenSubOption($3, $8, TokenOption::EXISTS));
|
||||
ctx.expression.push_back(opt);
|
||||
}
|
||||
| RELAY4 "[" option_code "]" "." EXISTS
|
||||
{
|
||||
switch (ctx.getUniverse()) {
|
||||
@@ -251,6 +256,11 @@ string_expr : STRING
|
||||
TokenPtr opt(new TokenOption($3, $6));
|
||||
ctx.expression.push_back(opt);
|
||||
}
|
||||
| OPTION "[" option_code "]" "." OPTION "[" option_code "]" "." option_repr_type
|
||||
{
|
||||
TokenPtr opt(new TokenSubOption($3, $8, $11));
|
||||
ctx.expression.push_back(opt);
|
||||
}
|
||||
| RELAY4 "[" option_code "]" "." option_repr_type
|
||||
{
|
||||
switch (ctx.getUniverse()) {
|
||||
|
@@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2015-2018 Internet Systems Consortium, Inc. ("ISC")
|
||||
// Copyright (C) 2015-2019 Internet Systems Consortium, Inc. ("ISC")
|
||||
//
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
@@ -985,3 +985,62 @@ TokenInteger::TokenInteger(const uint32_t value)
|
||||
:TokenString(EvalContext::fromUint32(value)), int_value_(value) {
|
||||
|
||||
}
|
||||
|
||||
OptionPtr
|
||||
TokenSubOption::getSubOption(const OptionPtr& parent) {
|
||||
return (parent->getOption(sub_option_code_));
|
||||
}
|
||||
|
||||
void
|
||||
TokenSubOption::evaluate(Pkt& pkt, ValueStack& values) {
|
||||
OptionPtr parent = getOption(pkt);
|
||||
std::string txt;
|
||||
if (!parent) {
|
||||
// There's no parent option, give up.
|
||||
txt = pushFailure(values);
|
||||
LOG_DEBUG(eval_logger, EVAL_DBG_STACK, EVAL_DEBUG_SUB_OPTION_NO_OPTION)
|
||||
.arg(option_code_)
|
||||
.arg(sub_option_code_)
|
||||
.arg(txt);
|
||||
return;
|
||||
}
|
||||
|
||||
OptionPtr sub = getSubOption(parent);
|
||||
if (!sub) {
|
||||
// Failed to find the sub-option
|
||||
txt = pushFailure(values);
|
||||
LOG_DEBUG(eval_logger, EVAL_DBG_STACK, EVAL_DEBUG_SUB_OPTION)
|
||||
.arg(option_code_)
|
||||
.arg(sub_option_code_)
|
||||
.arg(txt);
|
||||
return;
|
||||
}
|
||||
|
||||
if (representation_type_ == TEXTUAL) {
|
||||
txt = sub->toString();
|
||||
} else if (representation_type_ == HEXADECIMAL) {
|
||||
std::vector<uint8_t> binary = sub->toBinary();
|
||||
txt.resize(binary.size());
|
||||
if (!binary.empty()) {
|
||||
memmove(&txt[0], &binary[0], binary.size());
|
||||
}
|
||||
} else {
|
||||
txt = "true";
|
||||
}
|
||||
values.push(txt);
|
||||
|
||||
// Log what we pushed, both exists and textual are simple text
|
||||
// and can be output directly. We also include the code numbers
|
||||
// of the requested parent option and sub-option.
|
||||
if (representation_type_ == HEXADECIMAL) {
|
||||
LOG_DEBUG(eval_logger, EVAL_DBG_STACK, EVAL_DEBUG_SUB_OPTION)
|
||||
.arg(option_code_)
|
||||
.arg(sub_option_code_)
|
||||
.arg(toHex(txt));
|
||||
} else {
|
||||
LOG_DEBUG(eval_logger, EVAL_DBG_STACK, EVAL_DEBUG_SUB_OPTION)
|
||||
.arg(option_code_)
|
||||
.arg(sub_option_code_)
|
||||
.arg('\'' + txt + '\'');
|
||||
}
|
||||
}
|
||||
|
@@ -1057,6 +1057,68 @@ protected:
|
||||
uint16_t index_;
|
||||
};
|
||||
|
||||
/// @brief Token that represents sub-options in DHCPv4 and DHCPv6.
|
||||
///
|
||||
/// It covers any options which encapsulate sub-options, for instance
|
||||
/// dhcp-agent-options (72, DHCPv4) or rsoo (66, DHCPv6).
|
||||
/// This class is derived from TokenOption and leverages its ability
|
||||
/// to operate on sub-options. It also adds additional capabilities.
|
||||
///
|
||||
/// It can represent the following expressions:
|
||||
/// option[149].exists - check if option 149 exists
|
||||
/// option[149].option[1].exists - check if suboption 1 exists in the option 149
|
||||
/// option[149].option[1].hex - return content of suboption 1 for option 149
|
||||
class TokenSubOption : public TokenOption {
|
||||
public:
|
||||
|
||||
/// @note Does not define its own representation type:
|
||||
/// simply use the @c TokenOption::RepresentationType
|
||||
|
||||
/// @brief Constructor that takes an option and sub-option codes as parameter
|
||||
///
|
||||
/// Note: There is no constructor that takes names.
|
||||
///
|
||||
/// @param option_code code of the parent option.
|
||||
/// @param sub_option_code code of the sub-option to be represented.
|
||||
/// @param rep_type Token representation type.
|
||||
TokenSubOption(const uint16_t option_code,
|
||||
const uint16_t sub_option_code,
|
||||
const RepresentationType& rep_type)
|
||||
: TokenOption(option_code, rep_type), sub_option_code_(sub_option_code) {}
|
||||
|
||||
/// @brief This is a method for evaluating a packet.
|
||||
///
|
||||
/// This token represents a value of the sub-option, so this method
|
||||
/// attempts to extract the parent option from the packet and when
|
||||
/// it succeeds to extract the sub-option from the option and
|
||||
/// its value on the stack.
|
||||
/// If the parent option or the sub-option is not there, an empty
|
||||
/// string ("") is put on the stack.
|
||||
///
|
||||
/// @param pkt specified parent option will be extracted from this packet
|
||||
/// @param values value of the sub-option will be pushed here (or "")
|
||||
virtual void evaluate(Pkt& pkt, ValueStack& values);
|
||||
|
||||
/// @brief Returns sub-option-code
|
||||
///
|
||||
/// This method is used in testing to determine if the parser had
|
||||
/// instantiated TokenSubOption with correct parameters.
|
||||
///
|
||||
/// @return option-code of the sub-option this token expects to extract.
|
||||
uint16_t getSubCode() const {
|
||||
return (sub_option_code_);
|
||||
}
|
||||
|
||||
protected:
|
||||
/// @brief Attempts to retrieve a sub-option.
|
||||
///
|
||||
/// @param parent the sub-option will be retrieved from here
|
||||
/// @return sub-option instance (or NULL if not found)
|
||||
virtual OptionPtr getSubOption(const OptionPtr& parent);
|
||||
|
||||
uint16_t sub_option_code_; ///< Code of the sub-option to be extracted
|
||||
};
|
||||
|
||||
}; // end of isc::dhcp namespace
|
||||
}; // end of isc namespace
|
||||
|
||||
|
Reference in New Issue
Block a user