2 * Definitions for structures storing addresses, and for the type of
3 * variables holding port-type values
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
15 #include <string.h> /* for memcmp */
18 #include "wmem/wmem.h"
22 #endif /* __cplusplus */
24 /* Types of "global" addresses Wireshark knows about. */
25 /* Address types can be added here if there are many dissectors that use them or just
26 * within a specific dissector.
27 * If an address type is added here, it must be "registered" within address_types.c
28 * For dissector address types, just use the address_type_dissector_register function
29 * from address_types.h
32 AT_NONE, /* no link-layer address */
33 AT_ETHER, /* MAC (Ethernet, 802.x, FDDI) address */
37 AT_FC, /* Fibre Channel */
38 AT_FCWWN, /* Fibre Channel WWN */
39 AT_STRINGZ, /* null-terminated string */
40 AT_EUI64, /* IEEE EUI-64 */
41 AT_IB, /* Infiniband GID/LID */
43 AT_VINES, /* Banyan Vines address */
45 AT_END_OF_LIST /* Must be last in list */
48 typedef struct _address {
49 int type; /* type of address */
50 int len; /* length of address, in bytes */
51 const void *data; /* pointer to address data */
57 #define ADDRESS_INIT(type, len, data) {type, len, data, NULL}
58 #define ADDRESS_INIT_NONE ADDRESS_INIT(AT_NONE, 0, NULL)
61 clear_address(address *addr)
69 /** Initialize an address with the given values.
71 * @param addr [in,out] The address to initialize.
72 * @param addr_type [in] Address type.
73 * @param addr_len [in] The length in bytes of the address data. For example, 4 for
74 * AT_IPv4 or sizeof(ws_in6_addr) for AT_IPv6.
75 * @param addr_data [in] Pointer to the address data.
78 set_address(address *addr, int addr_type, int addr_len, const void *addr_data) {
80 /* Zero length must mean no data */
81 g_assert(addr_data == NULL);
83 /* Must not be AT_NONE - AT_NONE must have no data */
84 g_assert(addr_type != AT_NONE);
85 /* Make sure we *do* have data */
86 g_assert(addr_data != NULL);
88 addr->type = addr_type;
90 addr->data = addr_data;
94 /** Initialize an address from TVB data.
96 * Same as set_address but it takes a TVB and an offset. This is preferred
97 * over passing the return value of tvb_get_ptr() to set_address().
99 * This calls tvb_get_ptr() (including throwing any exceptions) before
100 * modifying the address.
102 * @param addr [in,out] The address to initialize.
103 * @param addr_type [in] Address type.
104 * @param tvb [in] Pointer to the TVB.
105 * @param offset [in] Offset within the TVB.
106 * @param addr_len [in] The length in bytes of the address data. For example, 4 for
107 * AT_IPv4 or sizeof(ws_in6_addr) for AT_IPv6.
110 set_address_tvb(address *addr, int addr_type, int addr_len, tvbuff_t *tvb, int offset) {
114 /* Must not be AT_NONE - AT_NONE must have no data */
115 g_assert(addr_type != AT_NONE);
116 p = tvb_get_ptr(tvb, offset, addr_len);
119 set_address(addr, addr_type, addr_len, p);
122 /** Initialize an address with the given values, allocating a new buffer
123 * for the address data using wmem-scoped memory.
125 * @param scope [in] The lifetime of the allocated memory, e.g., wmem_packet_scope()
126 * @param addr [in,out] The address to initialize.
127 * @param addr_type [in] Address type.
128 * @param addr_len [in] The length in bytes of the address data. For example, 4 for
129 * AT_IPv4 or sizeof(ws_in6_addr) for AT_IPv6.
130 * @param addr_data [in] Pointer to the address data.
133 alloc_address_wmem(wmem_allocator_t *scope, address *addr,
134 int addr_type, int addr_len, const void *addr_data) {
137 addr->type = addr_type;
139 /* Zero length must mean no data */
140 g_assert(addr_data == NULL);
141 /* Nothing to copy */
144 /* Must not be AT_NONE - AT_NONE must have no data */
145 g_assert(addr_type != AT_NONE);
146 /* Make sure we *do* have data to copy */
147 g_assert(addr_data != NULL);
148 addr->data = addr->priv = wmem_memdup(scope, addr_data, addr_len);
149 addr->len = addr_len;
152 /** Allocate an address from TVB data.
154 * Same as alloc_address_wmem but it takes a TVB and an offset.
156 * @param scope [in] The lifetime of the allocated memory, e.g., wmem_packet_scope()
157 * @param addr [in,out] The address to initialize.
158 * @param addr_type [in] Address type.
159 * @param addr_len [in] The length in bytes of the address data. For example, 4 for
160 * AT_IPv4 or sizeof(ws_in6_addr) for AT_IPv6.
161 * @param tvb [in] Pointer to the TVB.
162 * @param offset [in] Offset within the TVB.
165 alloc_address_tvb(wmem_allocator_t *scope, address *addr,
166 int addr_type, int addr_len, tvbuff_t *tvb, int offset) {
169 p = tvb_get_ptr(tvb, offset, addr_len);
170 alloc_address_wmem(scope, addr, addr_type, addr_len, p);
173 /** Compare two addresses.
175 * @param addr1 [in] The first address to compare.
176 * @param addr2 [in] The second address to compare.
177 * @return 0 if the addresses are equal,
178 * A positive number if addr1 > addr2 in some nondefined metric,
179 * A negative number if addr1 < addr2 in some nondefined metric.
182 cmp_address(const address *addr1, const address *addr2) {
183 if (addr1->type > addr2->type) return 1;
184 if (addr1->type < addr2->type) return -1;
185 if (addr1->len > addr2->len) return 1;
186 if (addr1->len < addr2->len) return -1;
187 if (addr1->len == 0) {
189 * memcmp(NULL, NULL, 0) is *not* guaranteed to work, so
190 * if both addresses are zero-length, don't compare them
191 * (there's nothing to compare, so they're equal).
195 return memcmp(addr1->data, addr2->data, addr1->len);
198 /** Check two addresses for equality.
200 * Given two addresses, return "true" if they're equal, "false" otherwise.
201 * Addresses are equal only if they have the same type and length; if the
202 * length is zero, they are then equal, otherwise the data must be the
205 * @param addr1 [in] The first address to compare.
206 * @param addr2 [in] The second address to compare.
207 * @return TRUE if the addresses are equal, FALSE otherwise.
209 static inline gboolean
210 addresses_equal(const address *addr1, const address *addr2) {
212 * memcmp(NULL, NULL, 0) is *not* guaranteed to work, so
213 * if both addresses are zero-length, don't compare them
214 * (there's nothing to compare, so they're equal).
216 if (addr1->type == addr2->type &&
217 addr1->len == addr2->len &&
219 memcmp(addr1->data, addr2->data, addr1->len) == 0))
224 /** Check the data of two addresses for equality.
226 * Given two addresses, return "true" if they have the same length and,
227 * their data is equal, "false" otherwise.
228 * The address types are ignored. This can be used to compare custom
229 * address types defined with address_type_dissector_register.
231 * @param addr1 [in] The first address to compare.
232 * @param addr2 [in] The second address to compare.
233 * @return TRUE if the addresses are equal, FALSE otherwise.
235 static inline gboolean
236 addresses_data_equal(const address *addr1, const address *addr2) {
237 if ( addr1->len == addr2->len
238 && memcmp(addr1->data, addr2->data, addr1->len) == 0
243 /** Perform a shallow copy of the address (both addresses point to the same
246 * @param to [in,out] The destination address.
247 * @param from [in] The source address.
249 * \warning Make sure 'from' memory stays valid for the lifetime of this object.
250 * Also it's strongly recommended to use this function instead of copy-assign.
253 copy_address_shallow(address *to, const address *from) {
254 set_address(to, from->type, from->len, from->data);
257 /** Copy an address, allocating a new buffer for the address data
258 * using wmem-scoped memory.
260 * @param scope [in] The lifetime of the allocated memory, e.g., wmem_packet_scope()
261 * @param to [in,out] The destination address.
262 * @param from [in] The source address.
265 copy_address_wmem(wmem_allocator_t *scope, address *to, const address *from) {
266 alloc_address_wmem(scope, to, from->type, from->len, from->data);
269 /** Copy an address, allocating a new buffer for the address data.
271 * @param to [in,out] The destination address.
272 * @param from [in] The source address.
275 copy_address(address *to, const address *from) {
276 copy_address_wmem(NULL, to, from);
279 /** Free an address allocated with wmem-scoped memory.
281 * @param scope [in] The lifetime of the allocated memory, e.g., wmem_packet_scope()
282 * @param addr [in,out] The address whose data to free.
285 free_address_wmem(wmem_allocator_t *scope, address *addr) {
286 /* Because many dissectors set 'type = AT_NONE' to mean clear we check for that */
287 if (addr->type != AT_NONE && addr->len > 0 && addr->priv != NULL) {
288 /* Make sure API use is correct */
289 /* if priv is not null then data == priv */
290 g_assert(addr->data == addr->priv);
291 wmem_free(scope, addr->priv);
298 * @param addr [in,out] The address whose data to free.
301 free_address(address *addr) {
302 free_address_wmem(NULL, addr);
305 /** Hash an address into a hash value (which must already have been set).
307 * @param hash_val The existing hash value.
308 * @param addr The address to add.
309 * @return The new hash value.
312 add_address_to_hash(guint hash_val, const address *addr) {
313 const guint8 *hash_data = (const guint8 *)(addr)->data;
316 for (idx = 0; idx < (addr)->len; idx++) {
317 hash_val += hash_data[idx];
318 hash_val += ( hash_val << 10 );
319 hash_val ^= ( hash_val >> 6 );
324 /** Hash an address into a hash value (which must already have been set).
325 * 64-bit version of add_address_to_hash().
327 * @param hash_val The existing hash value.
328 * @param addr The address to add.
329 * @return The new hash value.
331 static inline guint64
332 add_address_to_hash64(guint64 hash_val, const address *addr) {
333 const guint8 *hash_data = (const guint8 *)(addr)->data;
336 for (idx = 0; idx < (addr)->len; idx++) {
337 hash_val += hash_data[idx];
338 hash_val += ( hash_val << 10 );
339 hash_val ^= ( hash_val >> 6 );
344 WS_DLL_PUBLIC guint address_to_bytes(const address *addr, guint8 *buf, guint buf_len);
346 /* Types of port numbers Wireshark knows about. */
348 PT_NONE, /* no port number */
353 PT_IPX, /* IPX sockets */
354 PT_DDP, /* DDP AppleTalk connection */
355 PT_IDP, /* XNS IDP sockets */
356 PT_USB, /* USB endpoint 0xffff means the host */
358 PT_IBQP, /* Infiniband QP number */
364 #endif /* __cplusplus */
366 #endif /* __ADDRESS_H__ */
369 * Editor modelines - http://www.wireshark.org/tools/modelines.html
374 * indent-tabs-mode: nil
377 * vi: set shiftwidth=4 tabstop=8 expandtab:
378 * :indentSize=4:tabSize=8:noTabs=true: