Branch data Line data Source code
1 : : /*
2 : : ** Copyright (C) 2023 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: 2023-12-21T18:09:00
21 : : ** Author: Sylvain Fargier <fargier.sylvain@gmail.com>
22 : : */
23 : :
24 : : #ifndef RAWIPMESSAGE_HPP__
25 : : #define RAWIPMESSAGE_HPP__
26 : :
27 : : #include <string>
28 : :
29 : : #include "../../BitMask.hpp"
30 : : #include "../Message.hpp"
31 : :
32 : : namespace ccut {
33 : : namespace net {
34 : :
35 : : /**
36 : : * @brief IP protocols enum
37 : : */
38 : : enum class Protocol
39 : : {
40 : : ICMP = 1,
41 : : IGMP = 2,
42 : : IPinIP = 4,
43 : : TCP = 6,
44 : : IGP = 9,
45 : : UDP = 17,
46 : : RDP = 27,
47 : : IPv6 = 41, /* 6in4 and 6to4 */
48 : : ICMPv6 = 58,
49 : : RAW = 255
50 : : };
51 : :
52 : : std::string to_string(Protocol proto);
53 : :
54 : : const logger::Logger &operator<<(const logger::Logger &logger, Protocol proto);
55 : :
56 : : size_t getRawIPVersion(const Message::data_t &buffer);
57 : :
58 : : struct RawIPv4Message : public Message
59 : : {
60 : : public:
61 : : typedef ccut::net::Protocol Protocol;
62 : :
63 : : using Message::Message;
64 : :
65 : 2 : RawIPv4Message() = default;
66 : : RawIPv4Message(const Addr &from,
67 : : const Addr &to,
68 : : Protocol proto,
69 : : size_t payloadSize);
70 : : RawIPv4Message(const Addr &to, Protocol proto, size_t payloadSize);
71 : : RawIPv4Message(Protocol proto, size_t payloadSize);
72 : :
73 : : enum class IPFlag
74 : : {
75 : : Reserved0 = 0x1,
76 : : DontFragment = 0x2,
77 : : MoreFragments = 0x4
78 : : };
79 : : typedef BitMask<IPFlag> IPFlags;
80 : :
81 : : static RawIPv4Message load(const data_t &buffer);
82 : :
83 : : bool isValid() const override;
84 : :
85 : : /**
86 : : * @brief prepares the message for sending
87 : : * @details write addresses and computes checksum
88 : : */
89 : : virtual void prepare();
90 : :
91 : : uint8_t ipVersion() const;
92 : : uint8_t ipHeaderLength() const;
93 : : uint8_t differentiatedServicesCodePoint() const;
94 : : uint8_t explicitCongestionNotification() const;
95 : : uint16_t totalLength() const;
96 : : uint16_t ipIdentification() const;
97 : : IPFlags ipFlags() const;
98 : : uint16_t ipFragmentOffset() const;
99 : : uint8_t timeToLive() const;
100 : : Protocol protocol() const;
101 : : uint16_t ipHeaderChecksum() const;
102 : : Addr ipSrc() const;
103 : : Addr ipDest() const;
104 : :
105 : : RawIPv4Message &setTotalLength(uint16_t length);
106 : : RawIPv4Message &setIpIdentification(uint16_t identification);
107 : : RawIPv4Message &setIpFlags(IPFlags flags);
108 : : RawIPv4Message &setIpFragmentOffset(uint16_t offset);
109 : : RawIPv4Message &setTimeToLive(uint8_t ttl);
110 : : RawIPv4Message &setProtocol(Protocol proto);
111 : : RawIPv4Message &setIpSrc(const Addr &from);
112 : : RawIPv4Message &setIpDest(const Addr &to);
113 : :
114 : : /* FIXME: add IP options support later-on */
115 : :
116 : : /**
117 : : * @brief get the message's payload
118 : : *
119 : : * @return data_t
120 : : */
121 : : data_t payload() const;
122 : :
123 : : /**
124 : : * @brief construct a message for the associated payload
125 : : * @details returned message may be invalid (depending on protocol)
126 : : */
127 : : template<typename Message>
128 : 0 : Message message()
129 : : {
130 : 0 : return Message(from, to, payload());
131 : : }
132 : :
133 : : static constexpr size_t MinDataSize = 20;
134 : :
135 : : protected:
136 : : void init(size_t payloadSize = 0);
137 : : };
138 : :
139 : : struct RawIPv6Message : public Message
140 : : {
141 : : public:
142 : : typedef ccut::net::Protocol Protocol;
143 : :
144 : : using Message::Message;
145 : :
146 : 2 : RawIPv6Message() = default;
147 : : RawIPv6Message(const Addr &from,
148 : : const Addr &to,
149 : : Protocol proto,
150 : : size_t payloadSize);
151 : : RawIPv6Message(const Addr &to, Protocol proto, size_t payloadSize);
152 : : RawIPv6Message(Protocol proto, size_t payloadSize);
153 : :
154 : : /**
155 : : * @brief Explicit Congestion Notification (ECN) bits
156 : : */
157 : : enum class ExplicitCongestionNotification : uint8_t
158 : : {
159 : : NoECT = 0,
160 : : ECNCapableTransport1 = 0x01,
161 : : ECT1 = ECNCapableTransport1,
162 : : ECNCapableTransport2 = 0x02,
163 : : ECT2 = ECNCapableTransport2,
164 : : CongestionExperienced = 0x3,
165 : : CE = CongestionExperienced
166 : : };
167 : : typedef ExplicitCongestionNotification ECN;
168 : :
169 : : enum class DifferentiatedServicesCodePoint : uint8_t
170 : : {
171 : : DefaultForwarding = 0,
172 : : DF = DefaultForwarding,
173 : : ExpeditedForwarding = 46,
174 : : EF = ExpeditedForwarding,
175 : : CS0 = 0,
176 : : CS1 = 8,
177 : : CS2 = 16,
178 : : CS3 = 24,
179 : : CS4 = 32,
180 : : CS5 = 40,
181 : : CS6 = 48,
182 : : CS7 = 56,
183 : : AF11 = 10, // CS1 Assured Forwarding, low drop-rate
184 : : AF12 = 12, // CS1 Assured Forwarding, medium drop-rate
185 : : AF13 = 14, // CS1 Assured Forwarding, high drop-rate
186 : : AF21 = 18, // CS2 Assured Forwarding, low drop-rate
187 : : AF22 = 20, // CS2 Assured Forwarding, medium drop-rate
188 : : AF23 = 22, // CS2 Assured Forwarding, high drop-rate
189 : : AF31 = 26, // CS3 Assured Forwarding, low drop-rate
190 : : AF32 = 28, // CS3 Assured Forwarding, medium drop-rate
191 : : AF33 = 30, // CS3 Assured Forwarding, high drop-rate
192 : : AF41 = 34, // CS4 Assured Forwarding, low drop-rate
193 : : AF42 = 36, // CS4 Assured Forwarding, medium drop-rate
194 : : AF43 = 38 // CS4 Assured Forwarding, high drop-rate
195 : : };
196 : : typedef DifferentiatedServicesCodePoint DSCP;
197 : :
198 : : /**
199 : : * @brief Get the Class Selector level from DSCP
200 : : */
201 : : static inline uint8_t getClassSelector(DSCP dscp)
202 : : {
203 : : return (enum_cast(dscp) >> 3) & 0x7;
204 : : }
205 : :
206 : : static RawIPv6Message load(const data_t &buffer);
207 : :
208 : : bool isValid() const override;
209 : :
210 : : /**
211 : : * @brief prepares the message for sending
212 : : * @details write addresses and computes checksum
213 : : */
214 : : virtual void prepare();
215 : :
216 : : uint8_t ipVersion() const;
217 : : ECN explicitCongestionNotification() const;
218 : : DSCP differentiatedServicesCodePoint() const;
219 : :
220 : : /**
221 : : * @brief short-hand for DSCP + ECN fields
222 : : */
223 : : uint8_t trafficClass() const;
224 : : uint32_t flowLabel() const;
225 : : uint16_t payloadLength() const;
226 : :
227 : : Protocol nextHeader() const;
228 : : uint8_t hopLimit() const;
229 : :
230 : : Addr ipSrc() const;
231 : : Addr ipDest() const;
232 : :
233 : : RawIPv6Message &setExplicitCongestionNotification(ECN value);
234 : : RawIPv6Message &setDifferentiatedServicesCodePoint(DSCP value);
235 : : RawIPv6Message &setFlowLabel(uint32_t label);
236 : : RawIPv6Message &setPayloadLength(uint16_t length);
237 : : RawIPv6Message &setNextHeader(Protocol proto);
238 : : RawIPv6Message &setHopLimit(uint8_t limit);
239 : : RawIPv6Message &setIpSrc(const Addr &from);
240 : : RawIPv6Message &setIpDest(const Addr &to);
241 : :
242 : : /* FIXME: add IP options support later-on */
243 : :
244 : : /**
245 : : * @brief get the message's payload
246 : : *
247 : : * @return data_t
248 : : */
249 : : data_t payload() const;
250 : :
251 : : /**
252 : : * @brief construct a message for the associated payload
253 : : * @details returned message may be invalid (depending on protocol)
254 : : */
255 : : template<typename Message>
256 : : Message message()
257 : : {
258 : : return Message(from, to, payload());
259 : : }
260 : :
261 : : static constexpr size_t MinDataSize = 40;
262 : :
263 : : protected:
264 : : void init(size_t payloadSize = 0);
265 : : };
266 : :
267 : : std::string to_string(RawIPv6Message::ExplicitCongestionNotification ecn);
268 : :
269 : : const logger::Logger &operator<<(
270 : : const logger::Logger &logger,
271 : : RawIPv6Message::ExplicitCongestionNotification ecn);
272 : :
273 : : std::string to_string(RawIPv6Message::DifferentiatedServicesCodePoint dscp);
274 : :
275 : : const logger::Logger &operator<<(
276 : : const logger::Logger &logger,
277 : : RawIPv6Message::DifferentiatedServicesCodePoint dscp);
278 : :
279 : : } // namespace net
280 : : } // namespace ccut
281 : :
282 : : template<>
283 : : struct ccut_enable_bitmask<ccut::net::RawIPv4Message::IPFlag> : std::true_type
284 : : {};
285 : :
286 : : #endif
|