// Copyright (C) 2013-2023 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 // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include #include #include #include #include /// @file pkt_captures6.cc /// /// @brief contains packet captures imported from Wireshark /// /// These are actual packets captured over wire. They are used in various /// tests. /// /// The procedure to export Wireshark -> unit-tests is manual, but rather /// easy to follow: /// 1. Open a file in wireshark /// 2. Find the packet you want to export /// 3. There's a protocol stack (Frame, Ethernet, IPv6, UDP, DHCPv6, ...) /// 4. Right click on DHCPv6 -> Copy -> Bytes -> Hex Stream /// 5. Paste it as: string hex_string="[paste here]"; /// 6. Coding guidelines line restrictions apply, so wrap your code as necessary /// 7. Make sure you describe the capture appropriately /// 8. Follow whatever rest of the methods are doing (set ports, ifaces etc.) /// 9. To easily copy packet description, click File... -> Extract packet /// dissections -> as plain text file... /// (Make sure that the packet is expanded in the view. The text file will /// contain whatever expansion level you have in the graphical tree.) using namespace isc::dhcp; using namespace isc::asiolink; using namespace std; namespace isc { namespace dhcp { namespace test { void PktCaptures::captureSetDefaultFields(const Pkt6Ptr& pkt) { pkt->setRemotePort(546); pkt->setRemoteAddr(IOAddress("fe80::1")); pkt->setLocalPort(0); pkt->setLocalAddr(IOAddress("ff02::1:2")); pkt->setIndex(2); pkt->setIface("eth0"); } // This function returns buffer for very simple Solicit Pkt6Ptr PktCaptures::captureSimpleSolicit() { uint8_t data[] = { 1, // type 1 = SOLICIT 0xca, 0xfe, 0x01, // trans-id = 0xcafe01 0, 1, // option type 1 (client-id) 0, 10, // option length 10 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, // DUID 0, 3, // option type 3 (IA_NA) 0, 12, // option length 12 0, 0, 0, 1, // iaid = 1 0, 0, 0, 0, // T1 = 0 0, 0, 0, 0 // T2 = 0 }; Pkt6Ptr pkt(new Pkt6(data, sizeof(data))); captureSetDefaultFields(pkt); return (pkt); } Pkt6Ptr PktCaptures::captureRelayedSolicit() { // This is a very simple relayed SOLICIT message: // RELAY-FORW // - interface-id // - relay-message // - SOLICIT // - client-id // - IA_NA (iaid=1, t1=0, t2=0) // - ORO (7) // string exported from Wireshark string hex_string = "0c0500000000000000000000000000000000fc00000000000000000000000000000900" "12000231350009002c010517100001000e0001000151b5e46208002758f1e80003000c" "000000010000000000000000000600020007"; std::vector bin; // Decode the hex string and store it in bin (which happens // to be OptionBuffer format) isc::util::encode::decodeHex(hex_string, bin); Pkt6Ptr pkt(new Pkt6(&bin[0], bin.size())); captureSetDefaultFields(pkt); return (pkt); } /// returns a buffer with relayed SOLICIT (from DOCSIS3.0 cable modem) Pkt6Ptr PktCaptures::captureDocsisRelayedSolicit() { // This is an actual DOCSIS packet // RELAY-FORW (12) // - Relay Message // - SOLICIT (1) // - client-id // - IA_NA (iaid=7f000788, t2=0, t2=0) // - IAAddress (::, pref=0,valid=0) // - rapid-commit // - elapsed // - ORO // - Reconfigure-accept // - Vendor-Class ("docsis3.0") // - Vendor-specific Info // - subopt 1: Option request = 32,33,34,37,38 // - subopt 36: Device identifier // - subopt 35: TLV5 // - subopt 2: Device type = ECM // - subopt 3: Embedded components // - subopt 4: Serial Number // - subopt 5: Hardware version // - subopt 6: Software version // - subopt 7: Boot ROM Version // - subopt 8: Organization Unique Identifier // - subopt 9: Model Number // - subopt 10: Vendor Name (Netgear) // - subopt 15: unknown // - Interface-Id // - Vendor-specific Information // - Suboption 1025: CMTS capabilities // - Suboption 1026: Cable Modem MAC addr = 10:0d:7f:00:07:88 // string exported from Wireshark string hex_string = "0c002a0288fe00fe00015a8d09fffe7af955fe80000000000000120d7ffffe00078800" "090189010d397f0001000a00030001100d7f000788000300287f000788000000000000" "000000050018000000000000000000000000000000000000000000000000000e000000" "0800020000000600020011001400000010000f0000118b0009646f63736973332e3000" "1101200000118b0001000a0020002100220025002600240006100d7f00078800230081" "0101010201030301010401010501010601010701180801080901000a01010b01180c01" "010d0200400e0200100f01011004000000021101011301011401001501381601011701" "011801041901041a01041b01281c01021d01081e01201f011020011821010222010123" "010124011825010126020040270101120701100d7f00078a0002000345434d0003000b" "45434d3a45524f555445520004000d3335463132395550303030353200050004332e31" "310006000956312e30312e31315400070013505350552d426f6f7420312e302e31362e" "323200080006303030393542000900084347343030305444000a00074e657467656172" "000f000745524f5554455200120012427531264361312f3000100d7f00078800000011" "00160000118b040100040102030004020006100d7f000788"; std::vector bin; // Decode the hex string and store it in bin (which happens // to be OptionBuffer format) isc::util::encode::decodeHex(hex_string, bin); Pkt6Ptr pkt(new Pkt6(&bin[0], bin.size())); captureSetDefaultFields(pkt); return (pkt); } /// returns a buffer with relayed SOLICIT (from DOCSIS3.0 eRouter) Pkt6Ptr PktCaptures::captureeRouterRelayedSolicit() { /* Packet description exported from wireshark: DHCPv6 Message type: Relay-forw (12) Hopcount: 0 Link address: 2001:558:ffa8::1 (2001:558:ffa8::1) Peer address: fe80::22e5:2aff:feb8:1515 (fe80::22e5:2aff:feb8:1515) Relay Message Option: Relay Message (9) Length: 241 Value: 01a90044000e000000140000000600080011001700180019... DHCPv6 Message type: Solicit (1) Transaction ID: 0xa90044 Rapid Commit Option: Rapid Commit (14) Length: 0 Reconfigure Accept Option: Reconfigure Accept (20) Length: 0 Option Request Option: Option Request (6) Length: 8 Value: 0011001700180019 Requested Option code: Vendor-specific Information (17) Requested Option code: DNS recursive name server (23) Requested Option code: Domain Search List (24) Requested Option code: Identity Association for Prefix Delegation (25) Vendor Class Option: Vendor Class (16) Length: 16 Value: 0000118b000a65526f75746572312e30 Enterprise ID: Cable Television Laboratories, Inc. (4491) vendor-class-data: eRouter1.0 Vendor-specific Information Option: Vendor-specific Information (17) Length: 112 Value: 0000118b0002000745524f555445520003000b45434d3a45... Enterprise ID: Cable Television Laboratories, Inc. (4491) Suboption: Device Type = (2)"EROUTER" Suboption: Embedded Components = (3)"ECM:EROUTER" Suboption: Serial Number = (4)"2BR229U40044C" Suboption: Hardware Version = (5)"1.04" Suboption: Software Version = (6)"V1.33.03" Suboption: Boot ROM Version = (7)"2.3.0R2" Suboption: Organization Unique Identifier = (8)"00095B" Suboption: Model Number = (9)"CG3000DCR" Suboption: Vendor Name = (10)"Netgear" Client Identifier Option: Client Identifier (1) Length: 10 Value: 0003000120e52ab81515 DUID: 0003000120e52ab81515 DUID Type: link-layer address (3) Hardware type: Ethernet (1) Link-layer address: 20:e5:2a:b8:15:15 Identity Association for Prefix Delegation Option: Identity Association for Prefix Delegation (25) Length: 41 Value: 2ab815150000000000000000001a00190000000000000000... IAID: 2ab81515 T1: 0 T2: 0 IA Prefix Option: IA Prefix (26) Length: 25 Value: 000000000000000038000000000000000000000000000000... Preferred lifetime: 0 Valid lifetime: 0 Prefix length: 56 Prefix address: :: (::) Identity Association for Non-temporary Address Option: Identity Association for Non-temporary Address (3) Length: 12 Value: 2ab815150000000000000000 IAID: 2ab81515 T1: 0 T2: 0 Elapsed time Option: Elapsed time (8) Length: 2 Value: 0000 Elapsed time: 0 ms Vendor-specific Information Option: Vendor-specific Information (17) Length: 22 Value: 0000118b0402000620e52ab815140401000401020300 Enterprise ID: Cable Television Laboratories, Inc. (4491) Suboption: CM MAC Address Option = (1026)20:e5:2a:b8:15:14 Suboption: CMTS Capabilities Option : (1025) Interface-Id Option: Interface-Id (18) Length: 4 Value: 00000022 Interface-ID: Remote Identifier Option: Remote Identifier (37) Length: 14 Value: 0000101300015c228d4110000122 Enterprise ID: Arris Interactive LLC (4115) Remote-ID: 00015c228d4110000122 DHCP option 53 Option: Unknown (53) Length: 10 Value: 0003000100015c228d3d DUID: 0003000100015c228d3d DUID Type: link-layer address (3) Hardware type: Ethernet (1) Link-layer address: 00:01:5c:22:8d:3d */ // string exported from Wireshark string hex_string = "0c0020010558ffa800000000000000000001fe8000000000000022e52afffeb8151500" "0900f101a90044000e000000140000000600080011001700180019001000100000118b" "000a65526f75746572312e30001100700000118b0002000745524f555445520003000b" "45434d3a45524f555445520004000d3242523232395534303034344300050004312e30" "340006000856312e33332e303300070007322e332e3052320008000630303039354200" "090009434733303030444352000a00074e6574676561720001000a0003000120e52ab8" "1515001900292ab815150000000000000000001a001900000000000000003800000000" "0000000000000000000000000003000c2ab81515000000000000000000080002000000" "1100160000118b0402000620e52ab81514040100040102030000120004000000220025" "000e0000101300015c228d41100001220035000a0003000100015c228d3d"; std::vector bin; // Decode the hex string and store it in bin (which happens // to be OptionBuffer format) isc::util::encode::decodeHex(hex_string, bin); Pkt6Ptr pkt(new Pkt6(&bin[0], bin.size())); captureSetDefaultFields(pkt); return (pkt); } Pkt6Ptr PktCaptures::captureCableLabsShortVendorClass() { // This is a simple non-relayed Solicit: // - client-identifier // - IA_NA // - Vendor Class (4 bytes) // - enterprise-id 4491 // - Vendor-specific Information // - enterprise-id 4491 std::string hex_string = "01671cb90001000e0001000152ea903a08002758f1e80003000c00004bd10000000000" "000000001000040000118b0011000a0000118b000100020020"; std::vector bin; // Decode the hex string and store it in bin (which happens // to be OptionBuffer format) isc::util::encode::decodeHex(hex_string, bin); Pkt6Ptr pkt(new Pkt6(&bin[0], bin.size())); captureSetDefaultFields(pkt); return (pkt); } /// @brief creates doubly relayed solicit message /// /// This is a traffic capture exported from wireshark and manually modified /// to include necessary options (RSOO). It includes a SOLICIT message /// that passed through two relays. It is especially interesting, /// because of the following properties: /// - double encapsulation /// - first relay inserts relay-msg before extra options /// - second relay inserts relay-msg after extra options /// - both relays are from different vendors /// - interface-id are different for each relay /// - first relay inserts valid remote-id /// - second relay inserts remote-id with empty vendor data /// - the solicit message requests for custom options in ORO /// - there are option types in RELAY-FORW that do not appear in SOLICIT /// - there are option types in SOLICT that do not appear in RELAY-FORW /// /// RELAY-FORW /// - relay message option /// - RELAY-FORW /// - rsoo (66) /// - option 255 (len 4) /// - option 256 (len 9) /// - remote-id option (37) /// - relay message option /// - SOLICIT /// - client-id option /// - ia_na option /// - elapsed time /// - ORO /// - interface-id option (18) /// - remote-id option (37) /// /// The original capture was posted to dibbler users mailing list. /// /// @return created double relayed SOLICIT message isc::dhcp::Pkt6Ptr PktCaptures::captureRelayed2xRSOO() { // string exported from Wireshark string hex_string = "0c01200108880db800010000000000000000fe80000000000000020021fffe5c18a9" "0009007d0c0000000000000000000000000000000000fe80000000000000020021fffe5c18a9" "00420015" // RSOO (includes ... "00ff000401020304" // ... option 255, len 4, content 0x01020304 "01000009010203040506070809" // ... option 256, len 9, content 0x010203040506070809 "0025000400000de9" // remote-id "00090036" // relay-msg, len 54 "016b4fe2" // solicit" "0001000e0001000118b033410000215c18a9" // client-id "0003000c00000001ffffffffffffffff" // ia-na "000800020000" "00060006001700f200f3" "0012001c4953414d3134347c3239397c697076367c6e743a76703a313a" // vendor-class "313130002500120000197f0001000118b033410000215c18a9"; std::vector bin; // Decode the hex string and store it in bin (which happens // to be OptionBuffer format) isc::util::encode::decodeHex(hex_string, bin); Pkt6Ptr pkt(new Pkt6(&bin[0], bin.size())); pkt->setRemotePort(547); pkt->setRemoteAddr(IOAddress("fe80::1234")); pkt->setLocalPort(547); pkt->setLocalAddr(IOAddress("ff05::1:3")); pkt->setIndex(2); pkt->setIface("eth0"); return (pkt); } isc::dhcp::Pkt6Ptr PktCaptures::captureSolicitWithVIVSO() { // Message type: Solicit (1) // Transaction ID: 0xba048e // Client Identifier // Option: Client Identifier (1) // Length: 10 // Value: 0003000108002725d3f4 // DUID: 0003000108002725d3f4 // DUID Type: link-layer address (3) // Hardware type: Ethernet (1) // Link-layer address: 08:00:27:25:d3:f4 // Identity Association for Non-temporary Address // Option: Identity Association for Non-temporary Address (3) // Length: 40 // Value: 00aabbcc0000000000000000000500180000000000000000... // IAID: 00aabbcc // T1: 0 // T2: 0 // IA Address // Option: IA Address (5) // Length: 24 // Value: 000000000000000000000000000000000000000000000000 // IPv6 address: :: // Preferred lifetime: 0 // Valid lifetime: // Option Request // Option: Option Request (6) // Length: 6 // Value: 00d100d2000c // Vendor-specific Information // Option: Vendor-specific Information (17) // Length: 4 // Value: 00001e61 // Enterprise ID: E-DYNAMICS.ORG (7777) string hex_string = "01ba048e0001000a0003000108002725d3f40003002800aabbcc" "00000000000000000005001800000000000000000000000000000" "00000000000000000000006000600d100d2000c0011000400001e61"; std::vector bin; // Decode the hex string and store it in bin (which happens // to be OptionBuffer format) isc::util::encode::decodeHex(hex_string, bin); Pkt6Ptr pkt(new Pkt6(&bin[0], bin.size())); pkt->setRemotePort(547); pkt->setRemoteAddr(IOAddress("fe80::1234")); pkt->setLocalPort(547); pkt->setLocalAddr(IOAddress("ff05::1:3")); pkt->setIndex(2); pkt->setIface("eth0"); return (pkt); } isc::dhcp::Pkt6Ptr PktCaptures::captureSolicitWithTruncatedVIVSO() { // Message type: Solicit (1) // Transaction ID: 0xba048e // Client Identifier // Option: Client Identifier (1) // Length: 10 // Value: 0003000108002725d3f4 // DUID: 0003000108002725d3f4 // DUID Type: link-layer address (3) // Hardware type: Ethernet (1) // Link-layer address: 08:00:27:25:d3:f4 // Identity Association for Non-temporary Address // Option: Identity Association for Non-temporary Address (3) // Length: 40 // Value: 00aabbcc0000000000000000000500180000000000000000... // IAID: 00aabbcc // T1: 0 // T2: 0 // IA Address // Option: IA Address (5) // Length: 24 // Value: 000000000000000000000000000000000000000000000000 // IPv6 address: :: // Preferred lifetime: 0 // Valid lifetime: // Option Request // Option: Option Request (6) // Length: 6 // Value: 00d100d2000c // Vendor-specific Information // Option: Vendor-specific Information (17) // Length: 1 <-------- length too short! // Value: 00001e61 // Enterprise ID: E-DYNAMICS.ORG (7777) string hex_string = "01ba048e0001000a0003000108002725d3f40003002800aabbcc" "00000000000000000005001800000000000000000000000000000" "00000000000000000000006000600d100d2000c0011000100001e61"; std::vector bin; // Decode the hex string and store it in bin (which happens // to be OptionBuffer format) isc::util::encode::decodeHex(hex_string, bin); Pkt6Ptr pkt(new Pkt6(&bin[0], bin.size())); pkt->setRemotePort(547); pkt->setRemoteAddr(IOAddress("fe80::1234")); pkt->setLocalPort(547); pkt->setLocalAddr(IOAddress("ff05::1:3")); pkt->setIndex(2); pkt->setIface("eth0"); return (pkt); } }; // end of isc::dhcp::test namespace }; // end of isc::dhcp namespace }; // end of isc namespace