]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[67-expressions-hexa-strings] checkpoint to update syntax
authorFrancis Dupont <fdupont@isc.org>
Sun, 16 Sep 2018 10:41:06 +0000 (12:41 +0200)
committerFrancis Dupont <fdupont@isc.org>
Tue, 18 Sep 2018 07:18:37 +0000 (03:18 -0400)
doc/guide/classify.xml
src/lib/eval/eval.dox
src/lib/eval/eval_messages.mes
src/lib/eval/lexer.ll
src/lib/eval/parser.yy
src/lib/eval/tests/context_unittest.cc
src/lib/eval/token.cc
src/lib/eval/token.h

index 491ee1502b064b822173993838e57e2df2a934b1..0be70b329bfc23bf9268a715cf42c3a5b41a59e9 100644 (file)
 <row><entry>Concat</entry><entry>concat('foo','bar')</entry><entry>Return the
 concatenation of the strings</entry></row>
 <row><entry>Ifelse</entry><entry>ifelse('foo' == 'bar','us','them')</entry><entry>Return the branch value according to the condition</entry></row>
+<row><entry>Hexstring</entry><entry>hexstring('foo', '-')</entry><entry>Return the binary value as an hexadecimal string</entry></row>
           </tbody>
           </tgroup>
         </table>
@@ -772,6 +773,16 @@ concatenation of the strings</entry></row>
          ifelse(option[230].exists, option[230].hex, 'none')
            </screen>
         </section>
+        <section>
+          <title>Hexstring</title>
+          The hexstring function "hexstring(binary, separator)" returns
+          the binary value as its hexadecimal string representation:
+          pairs of hexadecimal digits separated by '-' or ':' or not
+          separated (separator '').
+            <screen>
+          hexstring(pkt4.mac, ':')
+            </screen>
+        </section>
     </section>
 
   <note>
index 4f7d814273e120dc409a3c3a61e464cc81550049..bb7e1ff178440adaf417b353b3699e9966b9efde 100644 (file)
@@ -160,7 +160,9 @@ instantiated with the appropriate value and put onto the expression vector.
  - isc::dhcp::TokenSubstring -- represents the substring(text, start, length) operator.
  - isc::dhcp::TokenConcat -- represents the concat operator which
    concatenate two other tokens.
- - isc::dhcp::TokenIfElse == represents the ifelse(cond, iftrue, ifelse) operator.
+ - isc::dhcp::TokenIfElse -- represents the ifelse(cond, iftrue, ifelse) operator.
+ - isc::dhcp::TokenToHexString -- represents the hexstring operator which
+   converts a binary value to its hexadecimal string representation. 
  - isc::dhcp::TokenNot -- the logical not operator.
  - isc::dhcp::TokenAnd -- the logical and (strict) operator.
  - isc::dhcp::TokenOr -- the logical or (strict) operator (strict means
index c70b7aeb3fb7124f4624cef5028849fead252e4b..1bf42ed9f62f57e40d1e5216072f753637017ba9 100644 (file)
@@ -144,6 +144,15 @@ 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 TokenToHexString
+
+% EVAL_DEBUG_TOHEXSTRING Popping binary value %1 and separator %2, pushing result %3
+This debug message indicates that two values are being popped from
+the value stack and a result is being pushed onto the value stack.
+The values being popped are the binary value to convert and the separator.
+The binary value is converted to its hexadecimal string representation
+and pushed onto the stack. The binary value is displayed in hex.
+
 % EVAL_DEBUG_VENDOR_CLASS_DATA Data %1 (out of %2 received) in vendor class found, pushing result '%3'
 This debug message indicates that vendor class option was found and passed
 enterprise-id checks and has sufficient number of data chunks. The total number
index d990b013ebeee470e860624f367599b22f180d32..8d3f1b4fd3e3126d088197ee6bf2d35f04560f17 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015-2017 Internet Systems Consortium, Inc. ("ISC")
+/* Copyright (C) 2015-2018 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
@@ -201,6 +201,7 @@ addr6 [0-9a-fA-F]*\:[0-9a-fA-F]*\:[0-9a-fA-F:.]*
 "all"          return isc::eval::EvalParser::make_ALL(loc);
 "concat"       return isc::eval::EvalParser::make_CONCAT(loc);
 "ifelse"       return isc::eval::EvalParser::make_IFELSE(loc);
+"hexstring"    return isc::eval::EvalParser::make_TOHEXSTRING(loc);
 "not"          return isc::eval::EvalParser::make_NOT(loc);
 "and"          return isc::eval::EvalParser::make_AND(loc);
 "or"           return isc::eval::EvalParser::make_OR(loc);
index f9f026162777dfc41965f62c165c2914497a6480..f35fa23a77a65f56b020a7bac53e3662412e22e3 100644 (file)
@@ -74,6 +74,7 @@ using namespace isc::eval;
   COMA ","
   CONCAT "concat"
   IFELSE "ifelse"
+  TOHEXSTRING "hexstring"
   PKT6 "pkt6"
   MSGTYPE "msgtype"
   TRANSID "transid"
@@ -349,6 +350,11 @@ string_expr : STRING
                       TokenPtr cond(new TokenIfElse());
                       ctx.expression.push_back(cond);
                   }
+            | TOHEXSTRING "(" string_expr "," string_expr ")"
+                  {
+                      TokenPtr tohex(new TokenToHexString());
+                      ctx.expression.push_back(tohex);
+                  }
             | VENDOR "." ENTERPRISE
                 {
                     // expression: vendor.enterprise
index ab487cc138590f0e4b8025acae3c9ca2cc4e8b2b..f40df5e0d0f6839410bb41e4d0c038785831de41 100644 (file)
@@ -1056,6 +1056,12 @@ TEST_F(EvalContextTest, pkt4FieldChaddr) {
     testPkt4Field("pkt4.mac == 0x000102030405", TokenPkt4::CHADDR, 3);
 }
 
+// Tests whether chaddr field in DHCPv4 can be accessed and converted.
+TEST_F(EvalContextTest, pkt4FieldChaddrHexa) {
+    testPkt4Field("hexstring(pkt4.mac, ':') == '00:01:02:03:04:05'",
+                  TokenPkt4::CHADDR, 5);
+}
+
 // Tests whether hlen field in DHCPv4 can be accessed.
 TEST_F(EvalContextTest, pkt4FieldHlen) {
     testPkt4Field("pkt4.hlen == 0x6", TokenPkt4::HLEN, 3);
index 7225d4bb1fbc96e036ef34fedcd9731238240717..e223aa0b6d347952a23d4e4e14f7b1bb97c33880 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2015-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2015-2018 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
@@ -21,6 +21,8 @@
 #include <dhcp/option_vendor_class.h>
 #include <cstring>
 #include <string>
+#include <iomanip>
+#include <sstream>
 
 using namespace isc::dhcp;
 using namespace isc::util;
@@ -629,6 +631,42 @@ TokenIfElse::evaluate(Pkt& /*pkt*/, ValueStack& values) {
     }
 }
 
+void
+TokenToHexString::evaluate(Pkt& /*pkt*/, ValueStack& values) {
+    if (values.size() < 2) {
+        isc_throw(EvalBadStack, "Incorrect stack order. Expected at least "
+                  "2 values for hexstring, got " << values.size());
+    }
+
+    string separator = values.top();
+    values.pop();
+    string binary = values.top();
+    values.pop();
+
+    // Unknown separator is interpreted as none.
+    if ((separator != ":") && (separator != "-") && !separator.empty()) {
+        separator.clear();
+    }
+
+    bool first = true;
+    stringstream tmp;
+    tmp << hex;
+    for (size_t i = 0; i < binary.size(); ++i) {
+        if (!first) {
+            tmp << separator;
+            first = false;
+        }
+        tmp << setw(2) << setfill('0') << static_cast<unsigned>(binary[i]);
+    }
+    values.push(tmp.str());
+
+    // Log what we popped and pushed
+    LOG_DEBUG(eval_logger, EVAL_DBG_STACK, EVAL_DEBUG_TOHEXSTRING)
+        .arg(toHex(binary))
+        .arg(separator)
+        .arg(tmp.str());
+}
+
 void
 TokenNot::evaluate(Pkt& /*pkt*/, ValueStack& values) {
 
index 330bc60dfbd5bc01cfb87dd69752f7328202d492..bba3ab99173e16da2e498ff616726120113ffee0 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2015-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2015-2018 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
@@ -725,6 +725,45 @@ public:
     void evaluate(Pkt& pkt, ValueStack& values);
 };
 
+/// @brief Token that converts to hexadecimal string
+///
+/// For example in the sub-expression "hexstring(pkt4.mac, ':')"
+/// the binary MAC address is converted to its usual hexadecimal
+/// representation as a list of (6) pairs of hexadecimal digits
+/// separated by colons (':').
+/// Please note the token is named TokenToHexString when the syntax
+/// use the hexstring name without a leading "to".
+class TokenToHexString : public Token {
+public:
+    /// @brief Constructor (does nothing)
+    TokenToHexString() { }
+
+    /// @brief Convert a binary value to its hexadecimal string representation
+    ///
+    /// Evaluation does not use packet information. It requires at least
+    /// two values to be present on the stack. It will consume the top
+    /// two values on the stack as parameters and push the resulting
+    /// hexadecimal string onto the stack.
+    /// From the top it expects the values on the stack as:
+    /// - separator ('-', ':' or something else interpreted as '')
+    /// - binary
+    ///
+    /// binary is the binary value (note it can be any value, i.e.
+    /// it is not checked to really be not printable).
+    /// separator is litteral '-' or ':' or something else interpreted as ''
+    /// i.e. no separator.
+    ///
+    /// The following example use a binary MAC address 06:ce:8f:55:b3:33:
+    /// - <mac>, '-' => "06-ce-8f-55-b3-33"
+    ///
+    /// @throw EvalBadStack if there are less than 2 values on stack
+    ///
+    /// @param pkt (unused)
+    /// @param values - stack of values (2 arguments will be popped, 1 result
+    ///        will be pushed)
+    void evaluate(Pkt& pkt, ValueStack& values);
+};
+
 /// @brief Token that represents logical negation operator
 ///
 /// For example in the expression "not(option[vendor-class].text == 'MSF')"