Browse Source

[master] Merge branch 'trac5131' (relay options logged)

Tomek Mrugalski 8 years ago
parent
commit
5bf58b21fc
4 changed files with 79 additions and 7 deletions
  1. 10 3
      doc/guide/hooks.xml
  2. 31 3
      src/lib/dhcp/pkt6.cc
  3. 6 1
      src/lib/dhcp/pkt6.h
  4. 32 0
      src/lib/dhcp/tests/pkt6_unittest.cc

+ 10 - 3
doc/guide/hooks.xml

@@ -419,8 +419,9 @@ address duration device-id {client-info} {relay-info}
             a hex string.
             a hex string.
             </para></listitem>
             </para></listitem>
             <listitem><para>
             <listitem><para>
-            relay-info - for relayed packets the giaddr and the RAI circuit id
-            and remote id options (option 82 sub options 1 and 2) if present.
+            relay-info - for relayed packets the giaddr and the RAI circuit-id,
+            remote-id and subscriber-id options (option 82 sub
+            options: 1, 2 and 6) if present.
             The circuit id and remote id are presented as hex strings
             The circuit id and remote id are presented as hex strings
             </para></listitem>
             </para></listitem>
           </itemizedlist>
           </itemizedlist>
@@ -467,7 +468,13 @@ address duration device-id {relay-info}*
             </para></listitem>
             </para></listitem>
             <listitem><para>
             <listitem><para>
             relay-info - for relayed packets the content of relay agent
             relay-info - for relayed packets the content of relay agent
-            messages, remote id and subscriber id options (x and xx) if present.
+            messages, remote-id (code 37), subscriber-id (code 38) and
+            interface-id (code 18) options if present. Note that
+            interface-id option, if present, identifies the whole interface the
+            relay agent received the message on. This typically translates to a
+            single link in your network, but it depends on your specific network
+            topology. Nevertheless, this is useful information to better scope
+            down the location of the device, so it is being recorded, if present.
             </para></listitem>
             </para></listitem>
           </itemizedlist>
           </itemizedlist>
           </para>
           </para>

+ 31 - 3
src/lib/dhcp/pkt6.cc

@@ -37,6 +37,19 @@ Pkt6::RelayInfo::RelayInfo()
     peeraddr_(DEFAULT_ADDRESS6), relay_msg_len_(0) {
     peeraddr_(DEFAULT_ADDRESS6), relay_msg_len_(0) {
 }
 }
 
 
+std::string Pkt6::RelayInfo::toText() const {
+    stringstream tmp;
+    tmp << "msg-type=" << static_cast<int>(msg_type_) << "(" << getName(msg_type_)
+        << "), hop-count=" << static_cast<int>(hop_count_)  << "," << endl
+        << "link-address=" << linkaddr_.toText()
+        << ", peer-address=" << peeraddr_.toText() << ", "
+        << options_.size() << " option(s)" << endl;
+    for (auto option = options_.cbegin(); option != options_.cend(); ++option) {
+        tmp << option->second->toText() << endl;
+    }
+    return (tmp.str());
+}
+
 Pkt6::Pkt6(const uint8_t* buf, uint32_t buf_len, DHCPv6Proto proto /* = UDP */)
 Pkt6::Pkt6(const uint8_t* buf, uint32_t buf_len, DHCPv6Proto proto /* = UDP */)
    :Pkt(buf, buf_len, DEFAULT_ADDRESS6, DEFAULT_ADDRESS6, 0, 0),
    :Pkt(buf, buf_len, DEFAULT_ADDRESS6, DEFAULT_ADDRESS6, 0, 0),
     proto_(proto), msg_type_(0) {
     proto_(proto), msg_type_(0) {
@@ -607,16 +620,31 @@ Pkt6::getLabel() const {
 std::string
 std::string
 Pkt6::toText() const {
 Pkt6::toText() const {
     stringstream tmp;
     stringstream tmp;
+
+    // First print the basics
     tmp << "localAddr=[" << local_addr_ << "]:" << local_port_
     tmp << "localAddr=[" << local_addr_ << "]:" << local_port_
-        << " remoteAddr=[" << remote_addr_
-        << "]:" << remote_port_ << endl;
-    tmp << "msgtype=" << static_cast<int>(msg_type_) << ", transid=0x" <<
+        << " remoteAddr=[" << remote_addr_ << "]:" << remote_port_ << endl;
+    tmp << "msgtype=" << static_cast<int>(msg_type_) << "(" << getName(msg_type_)
+        << "), transid=0x" <<
         hex << transid_ << dec << endl;
         hex << transid_ << dec << endl;
+
+    // Then print the options
     for (isc::dhcp::OptionCollection::const_iterator opt=options_.begin();
     for (isc::dhcp::OptionCollection::const_iterator opt=options_.begin();
          opt != options_.end();
          opt != options_.end();
          ++opt) {
          ++opt) {
         tmp << opt->second->toText() << std::endl;
         tmp << opt->second->toText() << std::endl;
     }
     }
+
+    // Finally, print the relay information (if present)
+    if (!relay_info_.empty()) {
+        tmp << relay_info_.size() << " relay(s):" << endl;
+        int cnt = 0;
+        for (auto relay = relay_info_.cbegin(); relay != relay_info_.cend(); ++relay) {
+            tmp << "relay[" << cnt++ << "]: " << relay->toText();
+        }
+    } else {
+        tmp << "No relays traversed." << endl;
+    }
     return tmp.str();
     return tmp.str();
 }
 }
 
 

+ 6 - 1
src/lib/dhcp/pkt6.h

@@ -1,4 +1,4 @@
-// Copyright (C) 2011-2016 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-2017 Internet Systems Consortium, Inc. ("ISC")
 //
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // 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
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -86,6 +86,11 @@ public:
 
 
         /// @brief default constructor
         /// @brief default constructor
         RelayInfo();
         RelayInfo();
+
+        /// @brief Returns prinable representation of the relay information.
+        /// @return text representation of the structure (used in debug logging)
+        std::string toText() const;
+
         uint8_t   msg_type_;               ///< message type (RELAY-FORW oro RELAY-REPL)
         uint8_t   msg_type_;               ///< message type (RELAY-FORW oro RELAY-REPL)
         uint8_t   hop_count_;              ///< number of traversed relays (up to 32)
         uint8_t   hop_count_;              ///< number of traversed relays (up to 32)
         isc::asiolink::IOAddress linkaddr_;///< fixed field in relay-forw/relay-reply
         isc::asiolink::IOAddress linkaddr_;///< fixed field in relay-forw/relay-reply

+ 32 - 0
src/lib/dhcp/tests/pkt6_unittest.cc

@@ -1049,6 +1049,38 @@ TEST_F(Pkt6Test, getAnyRelayOption) {
     EXPECT_FALSE(opt);
     EXPECT_FALSE(opt);
 }
 }
 
 
+// Tests whether Pkt6::toText() properly prints out all parameters, including
+// relay options: remote-id, interface-id.
+TEST_F(Pkt6Test, toText) {
+
+    // This packet contains doubly relayed solicit. The inner-most
+    // relay-forward contains inteface-id and remote-id. We will
+    // check that these are printed correctly.
+    Pkt6Ptr msg(capture2());
+    EXPECT_NO_THROW(msg->unpack());
+
+    ASSERT_EQ(2, msg->relay_info_.size());
+
+    string expected =
+        "localAddr=[ff05::1:3]:547 remoteAddr=[fe80::1234]:547\n"
+        "msgtype=1(SOLICIT), transid=0x6b4fe2\n"
+        "type=00001, len=00014: 00:01:00:01:18:b0:33:41:00:00:21:5c:18:a9\n"
+        "type=00003(IA_NA), len=00012: iaid=1, t1=4294967295, t2=4294967295\n"
+        "type=00006, len=00006: 23(uint16) 242(uint16) 243(uint16)\n"
+        "type=00008, len=00002: 0 (uint16)\n"
+        "2 relay(s):\n"
+        "relay[0]: msg-type=12(RELAY_FORWARD), hop-count=1,\n"
+        "link-address=2001:888:db8:1::, peer-address=fe80::200:21ff:fe5c:18a9, 2 option(s)\n"
+        "type=00018, len=00028: 49:53:41:4d:31:34:34:7c:32:39:39:7c:69:70:76:36:7c:6e:74:3a:76:70:3a:31:3a:31:31:30\n"
+        "type=00037, len=00018: 6527 (uint32) 0001000118B033410000215C18A9 (binary)\n"
+        "relay[1]: msg-type=12(RELAY_FORWARD), hop-count=0,\n"
+        "link-address=::, peer-address=fe80::200:21ff:fe5c:18a9, 2 option(s)\n"
+        "type=00018, len=00021: 49:53:41:4d:31:34:34:20:65:74:68:20:31:2f:31:2f:30:35:2f:30:31\n"
+        "type=00037, len=00004: 3561 (uint32)  (binary)\n";
+
+    EXPECT_EQ(expected, msg->toText());
+}
+
 // Tests whether a packet can be assigned to a class and later
 // Tests whether a packet can be assigned to a class and later
 // checked if it belongs to a given class
 // checked if it belongs to a given class
 TEST_F(Pkt6Test, clientClasses) {
 TEST_F(Pkt6Test, clientClasses) {