A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
address.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2007 INRIA
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
7 * Modified by: Dhiraj Lokesh <dhirajlokesh@gmail.com>
8 */
9
10#ifndef ADDRESS_H
11#define ADDRESS_H
12
13#include "tag-buffer.h"
14
15#include "ns3/attribute-helper.h"
16#include "ns3/attribute.h"
17
18#include <array>
19#include <compare>
20#include <ostream>
21#include <stdint.h>
22#include <unordered_map>
23
24namespace ns3
25{
26
27/**
28 * @ingroup network
29 * @defgroup address Address
30 *
31 * Network Address abstractions, including MAC, IPv4 and IPv6.
32 */
33
34/**
35 * @ingroup address
36 * @brief a polymophic address class
37 *
38 * This class is very similar in design and spirit to the BSD sockaddr
39 * structure: they are both used to hold multiple types of addresses
40 * together with the type of the address.
41 *
42 * A new address class defined by a user needs to:
43 * - allocate a type id with Address::Register
44 * - provide a method to convert his new address to an Address
45 * instance. This method is typically a member method named ConvertTo:
46 * Address MyAddress::ConvertTo () const;
47 * - provide a method to convert an Address instance back to
48 * an instance of his new address type. This method is typically
49 * a static member method of his address class named ConvertFrom:
50 * static MyAddress MyAddress::ConvertFrom (const Address &address);
51 * - the ConvertFrom method is expected to check that the type of the
52 * input Address instance is compatible with its own type.
53 *
54 * Typical code to create a new class type looks like:
55 * @code
56 * // this class represents addresses which are 2 bytes long.
57 * class MyAddress
58 * {
59 * public:
60 * Address ConvertTo () const;
61 * static MyAddress ConvertFrom ();
62 * private:
63 * static uint8_t GetType ();
64 * };
65 *
66 * Address MyAddress::ConvertTo () const
67 * {
68 * return Address (GetType (), m_buffer, 2);
69 * }
70 *
71 * MyAddress MyAddress::ConvertFrom (const Address &address)
72 * {
73 * MyAddress ad;
74 * NS_ASSERT (address.CheckCompatible (GetType (), 2));
75 * address.CopyTo (ad.m_buffer, 2);
76 * return ad;
77 * }
78 *
79 * uint8_t MyAddress::GetType ()
80 * {
81 * static uint8_t type = Address::Register ("AddressType", 2);
82 * return type;
83 * }
84 * @endcode
85 *
86 * To convert a specific Address T (e.g., Ipv6Address) to and from an Address type,
87 * a class must implement three public functions:
88 * @code
89 * static T ConvertFrom(const Address& address);
90 * Address ConvertTo() const;
91 * operator Address() const;
92 * @endcode
93 *
94 * Furthermore, the specific address must call the static function
95 * ``Address::Register(kind, length)``. This is typically done in a static function like
96 * ``GetType``.
97 *
98 * The kind/length pair is used to set the address type when this is not known a-priori.
99 * The typical use-case is when you decode a header where the address kind is known, but its
100 * length is specified in the header itself. The concrete example is the ARP or NDP headers,
101 * where you have a MAC address with a variable length.
102 * In these cases the code will be (assuming the address is a MAC address):
103 * @code
104 * Address addr;
105 * addr.SetType("MacAddress", addressLen);
106 * ReadFrom(i, addr, addressLen);
107 * @endcode
108 *
109 * It is forbidden to have two specific addresses sharing the same kind and length.
110 *
111 * @see attribute_Address
112 */
114{
115 private:
116 /**
117 * Key for the address registry: kind (string) / type (uint8_t)
118 */
119 using KindType = std::pair<std::string, uint8_t>;
120
121 /**
122 * Structure necessary to hash KindType, used as the key for the m_typeRegistry map
123 */
124 struct KeyHash
125 {
126 /**
127 * Functional operator for (string, uint8_t) hash computation.
128 * @param k the key to hash
129 * @return The key hash
130 */
131 std::size_t operator()(const KindType& k) const
132 {
133 return std::hash<std::string>()(k.first) ^ (std::hash<uint8_t>()(k.second));
134 }
135 };
136
137 /**
138 * Type of the address registry.
139 */
140 using KindTypeRegistry = std::unordered_map<KindType, uint8_t, Address::KeyHash>;
141
142 /**
143 * Container of allocated address types.
144 *
145 * The data is ordered by KindType (a {kind, length} pair), and sores the address type.
146 */
148
149 /// Unassigned Address type is reserved. Defined for clarity.
150 static constexpr uint8_t UNASSIGNED_TYPE{0};
151
152 public:
153 /**
154 * The maximum size of a byte buffer which
155 * can be stored in an Address instance.
156 */
157 static constexpr uint32_t MAX_SIZE{20};
158
159 /**
160 * Create an invalid address
161 */
162 Address() = default;
163 /**
164 * @brief Create an address from a type and a buffer.
165 *
166 * This constructor is typically invoked from the conversion
167 * functions of various address types when they have to
168 * convert themselves to an Address instance.
169 *
170 * @param type the type of the Address to create
171 * @param buffer a pointer to a buffer of bytes which hold
172 * a serialized representation of the address in network
173 * byte order.
174 * @param len the length of the buffer.
175 */
176 Address(uint8_t type, const uint8_t* buffer, uint8_t len);
177 /**
178 * Set the address type.
179 *
180 * Works only if the type is not yet set.
181 * @see Register()
182 *
183 * @param kind address kind
184 * @param length address length
185 */
186 void SetType(const std::string& kind, uint8_t length);
187 /**
188 * @return true if this address is invalid, false otherwise.
189 *
190 * An address is invalid if and only if it was created
191 * through the default constructor and it was never
192 * re-initialized.
193 */
194 bool IsInvalid() const;
195 /**
196 * @brief Get the length of the underlying address.
197 * @return the length of the underlying address.
198 */
199 uint8_t GetLength() const;
200 /**
201 * @brief Copy the address bytes into a buffer.
202 * @param buffer buffer to copy the address bytes to.
203 * @return the number of bytes copied.
204 */
205 uint32_t CopyTo(uint8_t buffer[MAX_SIZE]) const;
206 /**
207 * @param buffer buffer to copy the whole address data structure to
208 * @param len the size of the buffer
209 * @return the number of bytes copied.
210 *
211 * Copies the type to buffer[0], the length of the address internal buffer
212 * to buffer[1] and copies the internal buffer starting at buffer[2]. len
213 * must be at least the size of the internal buffer plus a byte for the type
214 * and a byte for the length.
215 */
216 uint32_t CopyAllTo(uint8_t* buffer, uint8_t len) const;
217 /**
218 * @param buffer pointer to a buffer of bytes which contain
219 * a serialized representation of the address in network
220 * byte order.
221 * @param len length of buffer
222 * @return the number of bytes copied.
223 *
224 * Copy the address bytes from buffer into to the internal buffer of this
225 * address instance.
226 */
227 uint32_t CopyFrom(const uint8_t* buffer, uint8_t len);
228 /**
229 * @param buffer pointer to a buffer of bytes which contain
230 * a copy of all the members of this Address class.
231 * @param len the length of the buffer
232 * @return the number of bytes copied.
233 *
234 * The inverse of CopyAllTo().
235 *
236 * @see CopyAllTo
237 */
238 uint32_t CopyAllFrom(const uint8_t* buffer, uint8_t len);
239 /**
240 * @param type a type id as returned by Address::Register
241 * @param len the length associated to this type id.
242 *
243 * @return true if the type of the address stored internally
244 * is compatible with the requested type, false otherwise.
245 */
246 bool CheckCompatible(uint8_t type, uint8_t len) const;
247 /**
248 * @param type a type id as returned by Address::Register
249 * @return true if the type of the address stored internally
250 * is compatible with the requested type, false otherwise.
251 *
252 * This method checks that the types are _exactly_ equal.
253 * This method is really used only by the PacketSocketAddress
254 * and there is little point in using it otherwise so,
255 * you have been warned: DO NOT USE THIS METHOD.
256 */
257 bool IsMatchingType(uint8_t type) const;
258 /**
259 * Allocate a new type id for a new type of address.
260 *
261 * Each address-like class that needs to be converted to/from an
262 * ``Address`` needs to register itself once. This is typically done
263 * in the ``GetType`` function.
264 *
265 * The address kind and length are typically used during the buffer
266 * deserialization, where the exact address type is unknown, and only its
267 * kind and length are known, e.g., if you parse an ARP reply.
268 *
269 * It is not allowed to have two different addresses with the same
270 * kind and length.
271 *
272 * @param kind address kind, such as "MacAddress"
273 * @param length address length
274 * @return a new type id.
275 */
276 static uint8_t Register(const std::string& kind, uint8_t length);
277 /**
278 * Get the number of bytes needed to serialize the underlying Address
279 * Typically, this is GetLength () + 2
280 *
281 * @return the number of bytes required for an Address in serialized form
282 */
284 /**
285 * Serialize this address in host byte order to a byte buffer
286 *
287 * @param buffer output buffer that gets written with this Address
288 */
289 void Serialize(TagBuffer buffer) const;
290 /**
291 * @param buffer buffer to read address from
292 *
293 * The input address buffer is expected to be in host byte order format.
294 */
295 void Deserialize(TagBuffer buffer);
296
297 /**
298 * @brief Three-way comparison operator.
299 *
300 * @param other the other address to compare with
301 * @return comparison result
302 */
303 constexpr std::strong_ordering operator<=>(const Address& other) const = default;
304
305 private:
306 /**
307 * @brief Stream insertion operator.
308 *
309 * @param os the stream
310 * @param address the address
311 * @return a reference to the stream
312 */
313 friend std::ostream& operator<<(std::ostream& os, const Address& address);
314
315 /**
316 * @brief Stream extraction operator.
317 *
318 * @param is the stream
319 * @param address the address
320 * @return a reference to the stream
321 */
322 friend std::istream& operator>>(std::istream& is, Address& address);
323
324 uint8_t m_type{UNASSIGNED_TYPE}; //!< Type of the address
325 uint8_t m_len{0}; //!< Length of the address
326 std::array<uint8_t, MAX_SIZE> m_data{}; //!< The address value
327};
328
330
331std::ostream& operator<<(std::ostream& os, const Address& address);
332std::istream& operator>>(std::istream& is, Address& address);
333
334} // namespace ns3
335
336#endif /* ADDRESS_H */
a polymophic address class
Definition address.h:114
friend std::istream & operator>>(std::istream &is, Address &address)
Stream extraction operator.
Definition address.cc:194
uint32_t GetSerializedSize() const
Get the number of bytes needed to serialize the underlying Address Typically, this is GetLength () + ...
Definition address.cc:142
void Serialize(TagBuffer buffer) const
Serialize this address in host byte order to a byte buffer.
Definition address.cc:149
static constexpr uint8_t UNASSIGNED_TYPE
Unassigned Address type is reserved. Defined for clarity.
Definition address.h:150
uint32_t CopyFrom(const uint8_t *buffer, uint8_t len)
Definition address.cc:90
friend std::ostream & operator<<(std::ostream &os, const Address &address)
Stream insertion operator.
Definition address.cc:170
static constexpr uint32_t MAX_SIZE
The maximum size of a byte buffer which can be stored in an Address instance.
Definition address.h:157
bool IsInvalid() const
Definition address.cc:55
std::pair< std::string, uint8_t > KindType
Key for the address registry: kind (string) / type (uint8_t).
Definition address.h:119
uint8_t m_len
Length of the address.
Definition address.h:325
void SetType(const std::string &kind, uint8_t length)
Set the address type.
Definition address.cc:37
std::array< uint8_t, MAX_SIZE > m_data
The address value.
Definition address.h:326
uint8_t m_type
Type of the address.
Definition address.h:324
std::unordered_map< KindType, uint8_t, Address::KeyHash > KindTypeRegistry
Type of the address registry.
Definition address.h:140
static KindTypeRegistry m_typeRegistry
Container of allocated address types.
Definition address.h:147
uint32_t CopyAllFrom(const uint8_t *buffer, uint8_t len)
Definition address.cc:102
bool CheckCompatible(uint8_t type, uint8_t len) const
Definition address.cc:115
Address()=default
Create an invalid address.
uint8_t GetLength() const
Get the length of the underlying address.
Definition address.cc:62
constexpr std::strong_ordering operator<=>(const Address &other) const =default
Three-way comparison operator.
uint32_t CopyTo(uint8_t buffer[MAX_SIZE]) const
Copy the address bytes into a buffer.
Definition address.cc:70
void Deserialize(TagBuffer buffer)
Definition address.cc:158
static uint8_t Register(const std::string &kind, uint8_t length)
Allocate a new type id for a new type of address.
Definition address.cc:130
bool IsMatchingType(uint8_t type) const
Definition address.cc:123
uint32_t CopyAllTo(uint8_t *buffer, uint8_t len) const
Definition address.cc:79
read and write tag data
Definition tag-buffer.h:41
#define ATTRIBUTE_HELPER_HEADER(type)
Declare the attribute value, accessor and checkers for class type.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition angles.cc:148
std::istream & operator>>(std::istream &is, Angles &a)
Definition angles.cc:172
Structure necessary to hash KindType, used as the key for the m_typeRegistry map.
Definition address.h:125
std::size_t operator()(const KindType &k) const
Functional operator for (string, uint8_t) hash computation.
Definition address.h:131