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:51:13
21 : : ** Author: Sylvain Fargier <fargier.sylvain@gmail.com>
22 : : */
23 : :
24 : : #ifndef ICMPV6MESSAGE_HPP__
25 : : #define ICMPV6MESSAGE_HPP__
26 : :
27 : : #include "../Message.hpp"
28 : :
29 : : namespace ccut {
30 : : namespace net {
31 : :
32 : : struct ICMPv6Message : public net::Message
33 : : {
34 : : using Message::Message;
35 : :
36 : 1 : ICMPv6Message() = default;
37 : :
38 : : /**
39 : : * @brief downcast a Message to an ICMPv6Message
40 : : */
41 : : // cppcheck-suppress noExplicitConstructor
42 : 0 : ICMPv6Message(const Message &message) : Message(message) {}
43 : :
44 : : /**
45 : : * @brief Type/SubType enumeration
46 : : */
47 : : enum class Type : uint8_t
48 : : {
49 : : DestinationUnreachable = 0x1,
50 : : PacketTooBig = 0x2,
51 : : TimeExceeded = 0x3,
52 : : ParameterProblem = 0x4,
53 : : EchoRequest = 0x80,
54 : : EchoReply = 0x81,
55 : : MulticastListenerQuery = 0x82,
56 : : MulticastListenerReport = 0x83,
57 : : MulticastListenerDone = 0x84,
58 : : RouterSolicitation = 0x85,
59 : : RouterAdvertisement = 0x86,
60 : : NeighborSolicitation = 0x87,
61 : : NeighborAdvertisement = 0x88,
62 : : RedirectMessage = 0x89,
63 : : RouterRenumbering = 0x8A,
64 : : InformationQuery = 0x8B,
65 : : InformationResponse = 0x8C,
66 : : InverseNeighborDiscoverySolicitation = 0x8D,
67 : : InverseNeighborDiscoveryAdvertisement = 0x8E,
68 : : MulticastListenerDiscoveryReport = 0x8F,
69 : : HomeAgentAddressDiscoveryRequest = 0x90,
70 : : HomeAgentAddressDiscoveryReply = 0x91,
71 : : MobilePrefixSolicitation = 0x92,
72 : : MobilePrefixAdvertisement = 0x93,
73 : : CertificationPathSolicitation = 0x94,
74 : : CertificationPathAdvertisement = 0x95,
75 : : MulticastRouterAdvertisement = 0x96,
76 : : MulticastRouterSolicitation = 0x97,
77 : : MulticastRouterTermination = 0x98,
78 : : RPLControlMessage = 0x99
79 : : };
80 : :
81 : : enum class Code : uint16_t
82 : : {
83 : : NoRouteToDestination = 0x0100,
84 : : CommunicationProhibited = 0x0101,
85 : : BeyondScopeOfSourceAddress = 0x0102,
86 : : AddressUnreachable = 0x0103,
87 : : PortUnreachable = 0x0104,
88 : : SourceAddressFailedPolicy = 0x0105,
89 : : RejectRouteToDestination = 0x0106,
90 : : ErrorInSourceRoutingHeader = 0x0107,
91 : : PacketTooBig = 0x0200,
92 : : HopLimitExceeded = 0x0300,
93 : : FragmentReassemblyTimeExceeded = 0x0301,
94 : : ErroneousHeaderFieldEncountered = 0x0400,
95 : : UnrecognizedNextHeaderTypeEncountered = 0x0401,
96 : : UnrecognizedIPv6OptionEncountered = 0x0402,
97 : : EchoRequest = 0x8000,
98 : : EchoReply = 0x8100,
99 : : MulticastListenerQuery = 0x8200,
100 : : MulticastListenerReport = 0x8300,
101 : : MulticastListenerDone = 0x8400,
102 : : RouterSolicitation = 0x8500,
103 : : RouterAdvertisement = 0x8600,
104 : : NeighborSolicitation = 0x8700,
105 : : NeighborAdvertisement = 0x8800,
106 : : RedirectMessage = 0x8900,
107 : : RouterRenumberingCommand = 0x8A00,
108 : : RouterRenumberingResult = 0x8A01,
109 : : RouterRenumberingSequenceNumberReset = 0x8AFF,
110 : : InformationQueryAddress = 0x8B00,
111 : : InformationQueryName = 0x8B01,
112 : : InformationQueryAddress4 = 0x8B02,
113 : : InformationResponse = 0x8C00,
114 : : InformationResponseDenied = 0x8C01,
115 : : InformationResponseUnknown = 0x8C02,
116 : : InverseNeighborDiscoverySolicitation = 0x8D00,
117 : : InverseNeighborDiscoveryAdvertisement = 0x8E00,
118 : : MulticastListenerDiscoveryReport = 0x8F00,
119 : : HomeAgentAddressDiscoveryRequest = 0x9000,
120 : : HomeAgentAddressDiscoveryReply = 0x9100,
121 : : MobilePrefixSolicitation = 0x9200,
122 : : MobilePrefixAdvertisement = 0x9300,
123 : : CertificationPathSolicitation = 0x9400,
124 : : CertificationPathAdvertisement = 0x9500,
125 : : MulticastRouterAdvertisement = 0x9600,
126 : : MulticastRouterSolicitation = 0x9700,
127 : : MulticastRouterTermination = 0x9800,
128 : : RPLControlMessage = 0x9900
129 : : };
130 : :
131 : : /**
132 : : * @brief Get the message Type associated with the given code
133 : : */
134 : 2 : static inline Type getType(Code code)
135 : : {
136 : 2 : return static_cast<Type>((enum_cast(code) >> 8) & 0xFF);
137 : : }
138 : :
139 : : /**
140 : : * @brief get the message type and code
141 : : * @throws ccut::Exception when called on invalid message
142 : : * @return Code
143 : : */
144 : : Code code() const;
145 : :
146 : : /**
147 : : * @brief get message type
148 : : * @throws ccut::Exception when called on invalid message
149 : : * @return Type
150 : : */
151 : 3 : inline Type type() const { return getType(code()); }
152 : :
153 : : /**
154 : : * @brief set the message type
155 : : * @nothrow
156 : : */
157 : : ICMPv6Message &setCode(Code code);
158 : :
159 : : /**
160 : : * @brief retrieve checksum in packet
161 : : * @details use `prepare` to update the checksum
162 : : *
163 : : * @return uint16_t
164 : : */
165 : : uint16_t checksum() const;
166 : :
167 : : /**
168 : : * @brief update checksum and prepare packet
169 : : */
170 : : ICMPv6Message &prepare();
171 : :
172 : : bool isValid() const override;
173 : :
174 : 1 : inline data_t payload() const { return data.sub(MinDataSize); }
175 : :
176 : : static constexpr size_t MinDataSize = 8;
177 : :
178 : : protected:
179 : : void init();
180 : : uint16_t pseudoHeaderChecksum() const;
181 : : };
182 : :
183 : : std::string to_string(ICMPv6Message::Code code);
184 : :
185 : : const logger::Logger &operator<<(const logger::Logger &logger,
186 : : ICMPv6Message::Code code);
187 : :
188 : : std::string to_string(ICMPv6Message::Type type);
189 : :
190 : : const logger::Logger &operator<<(const logger::Logger &logger,
191 : : ICMPv6Message::Type type);
192 : :
193 : : } // namespace net
194 : : } // namespace ccut
195 : :
196 : : #endif
|