Branch data Line data Source code
1 : : /*
2 : : ** Copyright (C) 2024 Sylvain Fargier
3 : : **
4 : : ** This software is provided 'as-is', without any express or implied
5 : : ** warranty. In no event will the authors be held liable for any damages
6 : : ** arising from the use of this software.
7 : : **
8 : : ** Permission is granted to anyone to use this software for any purpose,
9 : : ** including commercial applications, and to alter it and redistribute it
10 : : ** freely, subject to the following restrictions:
11 : : **
12 : : ** 1. The origin of this software must not be misrepresented; you must not
13 : : ** claim that you wrote the original software. If you use this software
14 : : ** in a product, an acknowledgment in the product documentation would be
15 : : ** appreciated but is not required.
16 : : ** 2. Altered source versions must be plainly marked as such, and must not be
17 : : ** misrepresented as being the original software.
18 : : ** 3. This notice may not be removed or altered from any source distribution.
19 : : **
20 : : ** Created on: 2024-01-02T08:46:26
21 : : ** Author: Sylvain Fargier <fargier.sylvain@gmail.com>
22 : : */
23 : :
24 : : #ifndef ICMPMESSAGE_HPP__
25 : : #define ICMPMESSAGE_HPP__
26 : :
27 : : #include "../Message.hpp"
28 : : #include "ICMPv6Message.hpp"
29 : :
30 : : namespace ccut {
31 : : namespace net {
32 : :
33 : : struct ICMPMessage : public net::Message
34 : : {
35 : : using Message::Message;
36 : :
37 : 2 : ICMPMessage() = default;
38 : :
39 : : /**
40 : : * @brief downcast a Message to an ICMPMessage
41 : : */
42 : : // cppcheck-suppress noExplicitConstructor
43 : 1 : ICMPMessage(const Message &message) : Message(message) {}
44 : :
45 : : /**
46 : : * @brief Type/SubType enumeration
47 : : */
48 : : enum class Type : uint8_t
49 : : {
50 : : EchoReply = 0x00,
51 : : DestinationUnreachable = 0x03,
52 : : SourceQuench = 0x04,
53 : : RedirectMessage = 0x05,
54 : : Echo = 0x08,
55 : : RouterAdvertisement = 0x09,
56 : : RouterSolicitation = 0x0A,
57 : : TimeExceeded = 0x0B,
58 : : BadIPHeader = 0x0C,
59 : : Timestamp = 0x0D,
60 : : TimestampReply = 0x0E,
61 : : InformationRequest = 0x0F,
62 : : InformationReply = 0x10,
63 : : AddressMaskRequest = 0x11,
64 : : AddressMaskReply = 0x12,
65 : : ExtendedEchoRequest = 0x2A,
66 : : ExtendedEchoReply = 0x2B
67 : : };
68 : :
69 : : enum class Code : uint16_t
70 : : {
71 : : EchoReply = 0x0000,
72 : : DestinationNetworkUnreachable = 0x0300,
73 : : DestinationHostUnreachable = 0x0301,
74 : : DestinationProtocolUnreachable = 0x0302,
75 : : DestinationPortUnreachable = 0x0303,
76 : : FragmentationRequired = 0x0304,
77 : : SourceRouteFailed = 0x0305,
78 : : DestinationNetworkUnknown = 0x0306,
79 : : DestinationHostUnknown = 0x0307,
80 : : SourceHostIsolated = 0x0308,
81 : : NetworkAdministrativelyProhibited = 0x0309,
82 : : HostAdministrativelyProhibited = 0x030A,
83 : : NetworkUnreachableForToS = 0x030B,
84 : : HostUnreachableForToS = 0x030C,
85 : : CommunicationAdministrativelyProhibited = 0x030D,
86 : : HostPrecedenceViolation = 0x030E,
87 : : PrecedenceCutoffInEffect = 0x030F,
88 : : SourceQuench = 0x0400, /* deprecated */
89 : : RedirectDatagramForTheNetwork = 0x0500,
90 : : RedirectDatagramForTheHost = 0x0501,
91 : : RedirectDatagramForTheToSNetwork = 0x0502,
92 : : RedirectDatagramForTheToSHost = 0x0503,
93 : : AlternateHostAddress = 0x0600, /* deprecated */
94 : : Echo = 0x0800,
95 : : RouterAdvertisement = 0x0900,
96 : : RouterSolicitation = 0x0A00,
97 : : TTLExpiredInTransit = 0x0B00,
98 : : FragmentReassemblyTimeExceeded = 0x0B01,
99 : : BadIPHeader = 0x0C00,
100 : : BadIPHeaderMissingRequiredOption = 0x0C01,
101 : : BadIPHeaderLength = 0x0C02,
102 : : Timestamp = 0x0D00,
103 : : TimestampReply = 0x0E00,
104 : : InformationRequest = 0x0F00, /* deprecated */
105 : : InformationReply = 0x1000, /* deprecated */
106 : : AddressMaskRequest = 0x1100, /* deprecated */
107 : : AddressMaskReply = 0x1200, /* deprecated */
108 : : ExtendedEchoRequest = 0x2A00,
109 : : ExtendedEchoReply = 0x2B00,
110 : : ExtendedEchoMalformedQuery = 0x2B01,
111 : : ExtendedEchoNoSuchInterface = 0x2B02,
112 : : ExtendedEchoNoSuchTableEntry = 0x2B03,
113 : : ExtendedEchoMultipleInterfacesSatisfyQuery = 0x2B04,
114 : : };
115 : :
116 : : /**
117 : : * @brief Get the message Type associated with the given code
118 : : */
119 : 6 : static inline Type getType(Code code)
120 : : {
121 : 6 : return static_cast<Type>((enum_cast(code) >> 8) & 0xFF);
122 : : }
123 : :
124 : : /**
125 : : * @brief get message type
126 : : * @throws ccut::Exception when called on invalid message
127 : : * @return Type
128 : : */
129 : : Code code() const;
130 : :
131 : : /**
132 : : * @brief get message type
133 : : * @throws ccut::Exception when called on invalid message
134 : : * @return Type
135 : : */
136 : 8 : inline Type type() const { return getType(code()); }
137 : :
138 : : /**
139 : : * @brief set the message type
140 : : * @nothrow
141 : : */
142 : : ICMPMessage &setCode(Code code);
143 : :
144 : : /**
145 : : * @brief retrieve checksum in packet
146 : : * @details use `prepare` to update the checksum
147 : : *
148 : : * @return uint16_t
149 : : */
150 : : uint16_t checksum() const;
151 : :
152 : : /**
153 : : * @brief update checksum and prepare packet
154 : : */
155 : : ICMPMessage &prepare();
156 : :
157 : : bool isValid() const override;
158 : :
159 : 1 : inline data_t payload() const { return data.sub(MinDataSize); }
160 : :
161 : : static constexpr size_t MinDataSize = 8;
162 : :
163 : : protected:
164 : : void init(size_t payloadSize = 0);
165 : : };
166 : :
167 : : std::string to_string(ICMPMessage::Code code);
168 : :
169 : : const logger::Logger &operator<<(const logger::Logger &logger,
170 : : ICMPMessage::Code code);
171 : :
172 : : std::string to_string(ICMPMessage::Type type);
173 : :
174 : : const logger::Logger &operator<<(const logger::Logger &logger,
175 : : ICMPMessage::Type type);
176 : :
177 : : } // namespace net
178 : : } // namespace ccut
179 : :
180 : : #endif
|