| 1 | // |
| 2 | // ICMPv4PacketImpl.h |
| 3 | // |
| 4 | // Library: Net |
| 5 | // Package: ICMP |
| 6 | // Module: ICMPv4PacketImpl |
| 7 | // |
| 8 | // Definition of the ICMPv4PacketImpl class. |
| 9 | // |
| 10 | // Copyright (c) 2006, Applied Informatics Software Engineering GmbH. |
| 11 | // and Contributors. |
| 12 | // |
| 13 | // SPDX-License-Identifier: BSL-1.0 |
| 14 | // |
| 15 | |
| 16 | |
| 17 | #ifndef Net_ICMPv4PacketImpl_INCLUDED |
| 18 | #define Net_ICMPv4PacketImpl_INCLUDED |
| 19 | |
| 20 | |
| 21 | #include "Poco/Foundation.h" |
| 22 | #include "Poco/Net/Socket.h" |
| 23 | #include "Poco/Net/ICMPPacketImpl.h" |
| 24 | #include <cstddef> |
| 25 | |
| 26 | |
| 27 | namespace Poco { |
| 28 | namespace Net { |
| 29 | |
| 30 | |
| 31 | class Net_API ICMPv4PacketImpl : public ICMPPacketImpl |
| 32 | /// This class implements the ICMPv4 packet. |
| 33 | /// Parts are based on the original ICMP code by |
| 34 | /// Mike Muuss |
| 35 | /// U. S. Army Ballistic Research Laboratory |
| 36 | /// December, 1983 |
| 37 | { |
| 38 | public: |
| 39 | // ICMPv4 header |
| 40 | struct |
| 41 | { |
| 42 | Poco::UInt8 ; // ICMP packet type |
| 43 | Poco::UInt8 ; // Type sub code |
| 44 | Poco::UInt16 ; |
| 45 | Poco::UInt16 ; |
| 46 | Poco::UInt16 ; |
| 47 | }; |
| 48 | |
| 49 | // compile-time shield against misalignment |
| 50 | #if POCO_OS != POCO_OS_ANDROID |
| 51 | poco_static_assert (offsetof(Header, code) == 0x01); |
| 52 | poco_static_assert (offsetof(Header, checksum) == 0x02); |
| 53 | poco_static_assert (offsetof(Header, id) == 0x04); |
| 54 | poco_static_assert (offsetof(Header, seq) == 0x06); |
| 55 | #endif |
| 56 | |
| 57 | enum MessageType |
| 58 | { |
| 59 | ECHO_REPLY, |
| 60 | ICMP_1, |
| 61 | ICMP_2, |
| 62 | DESTINATION_UNREACHABLE, |
| 63 | SOURCE_QUENCH, |
| 64 | REDIRECT, |
| 65 | ICMP_6, |
| 66 | ICMP_7, |
| 67 | ECHO_REQUEST, |
| 68 | ICMP_9, |
| 69 | ICMP_10, |
| 70 | TIME_EXCEEDED, |
| 71 | PARAMETER_PROBLEM, |
| 72 | TIMESTAMP_REQUEST, |
| 73 | TIMESTAMP_REPLY, |
| 74 | INFORMATION_REQUEST, |
| 75 | INFORMATION_REPLY, |
| 76 | MESSAGE_TYPE_UNKNOWN, // non-standard default, must remain last but one |
| 77 | MESSAGE_TYPE_LENGTH // length indicator, must remain last |
| 78 | }; |
| 79 | |
| 80 | enum DestinationUnreachableCode |
| 81 | { |
| 82 | NET_UNREACHABLE, |
| 83 | HOST_UNREACHABLE, |
| 84 | PROTOCOL_UNREACHABLE, |
| 85 | PORT_UNREACHABLE, |
| 86 | FRAGMENTATION_NEEDED_AND_DF_SET, |
| 87 | SOURCE_ROUTE_FAILED, |
| 88 | DESTINATION_UNREACHABLE_UNKNOWN, // non-standard default, must remain last but one |
| 89 | DESTINATION_UNREACHABLE_LENGTH // length indicator, must remain last |
| 90 | }; |
| 91 | |
| 92 | enum RedirectMessageCode |
| 93 | { |
| 94 | REDIRECT_NETWORK, |
| 95 | REDIRECT_HOST, |
| 96 | REDIRECT_SERVICE_NETWORK, |
| 97 | REDIRECT_SERVICE_HOST, |
| 98 | REDIRECT_MESSAGE_UNKNOWN, // non-standard default, must remain last but one |
| 99 | REDIRECT_MESSAGE_LENGTH // length indicator, must remain last |
| 100 | }; |
| 101 | |
| 102 | enum TimeExceededCode |
| 103 | { |
| 104 | TIME_TO_LIVE, |
| 105 | FRAGMENT_REASSEMBLY, |
| 106 | TIME_EXCEEDED_UNKNOWN, // non-standard default, must remain last but one |
| 107 | TIME_EXCEEDED_LENGTH // length indicator, must remain last |
| 108 | }; |
| 109 | |
| 110 | enum ParameterProblemCode |
| 111 | { |
| 112 | POINTER_INDICATES_THE_ERROR, |
| 113 | PARAMETER_PROBLEM_UNKNOWN, // non-standard default, must remain last but one |
| 114 | PARAMETER_PROBLEM_LENGTH // length indicator, must remain last |
| 115 | }; |
| 116 | |
| 117 | ICMPv4PacketImpl(int dataSize = 48); |
| 118 | /// Constructor. Creates an ICMPv4PacketImpl. |
| 119 | |
| 120 | ~ICMPv4PacketImpl(); |
| 121 | /// Destructor. |
| 122 | |
| 123 | int packetSize() const; |
| 124 | /// Returns the total length of packet (header + data); |
| 125 | |
| 126 | struct timeval time(Poco::UInt8* buffer = 0, int length = 0) const; |
| 127 | /// Returns current epoch time if either buffer or length are equal to zero. |
| 128 | /// Otherwise, it extracts the time value from the supplied buffer. |
| 129 | /// |
| 130 | /// Buffer includes IP header, ICMP header and data. |
| 131 | |
| 132 | bool validReplyID(Poco::UInt8* buffer, int length) const; |
| 133 | /// Returns true if the extracted id is recognized |
| 134 | /// (i.e. equals the process id). |
| 135 | /// |
| 136 | /// Buffer includes IP header, ICMP header and data. |
| 137 | |
| 138 | virtual std::string errorDescription(Poco::UInt8* buffer, int length, int& type, int& code); |
| 139 | /// Returns error description string. |
| 140 | /// If supplied buffer contains ICMPv4 echo reply packet, an |
| 141 | /// empty string is returned indicating the absence of error. |
| 142 | /// If type and code of the error can be determined, they are |
| 143 | /// assigned to the type and code respectively. |
| 144 | /// |
| 145 | /// Buffer includes IP header, ICMP header and data. |
| 146 | |
| 147 | virtual std::string typeDescription(int typeId); |
| 148 | /// Returns the description of the packet type. |
| 149 | |
| 150 | static const Poco::UInt16 MAX_PACKET_SIZE; |
| 151 | static const std::string MESSAGE_TYPE[MESSAGE_TYPE_LENGTH]; |
| 152 | static const Poco::UInt8 DESTINATION_UNREACHABLE_TYPE; // 3 |
| 153 | static const Poco::UInt8 SOURCE_QUENCH_TYPE; // 4 |
| 154 | static const Poco::UInt8 REDIRECT_MESSAGE_TYPE; // 5 |
| 155 | static const Poco::UInt8 TIME_EXCEEDED_TYPE; // 11 |
| 156 | static const Poco::UInt8 PARAMETER_PROBLEM_TYPE; // 12 |
| 157 | |
| 158 | private: |
| 159 | void initPacket(); |
| 160 | Header* (Poco::UInt8* buffer, int length) const; |
| 161 | Poco::UInt8* data(Poco::UInt8* buffer, int length) const; |
| 162 | |
| 163 | static const std::string DESTINATION_UNREACHABLE_CODE[DESTINATION_UNREACHABLE_LENGTH]; |
| 164 | static const std::string REDIRECT_MESSAGE_CODE[REDIRECT_MESSAGE_LENGTH]; |
| 165 | static const std::string TIME_EXCEEDED_CODE[TIME_EXCEEDED_LENGTH]; |
| 166 | static const std::string PARAMETER_PROBLEM_CODE[PARAMETER_PROBLEM_LENGTH]; |
| 167 | |
| 168 | Poco::UInt16 _seq; |
| 169 | }; |
| 170 | |
| 171 | |
| 172 | } } // namespace Poco::Net |
| 173 | |
| 174 | |
| 175 | #endif // Net_ICMPv4PacketImpl_INCLUDED |
| 176 | |