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 <epan/wmem_scopes.h>
19 #include <wsutil/ws_assert.h>
20 #include <wsutil/inet_cidr.h>
24 #endif /* __cplusplus */
26 /* Types of "global" addresses Wireshark knows about. */
27 /* Address types can be added here if there are many dissectors that use them or just
28 * within a specific dissector.
29 * If an address type is added here, it must be "registered" within address_types.c
30 * For dissector address types, just use the address_type_dissector_register function
31 * from address_types.h
33 * AT_NUMERIC - a numeric address type can consist of a uint8_t, uint16_t, uint32_t or uint64_t
34 * value. If no correct length is provided, to avoid data bleed, a uint8_t is
35 * assumed. Only representation (aka conversion of value to string) is implemented for this type.
38 AT_NONE
, /* no link-layer address */
39 AT_ETHER
, /* MAC (Ethernet, 802.x, FDDI) address */
43 AT_FC
, /* Fibre Channel */
44 AT_FCWWN
, /* Fibre Channel WWN */
45 AT_STRINGZ
, /* null-terminated string */
46 AT_EUI64
, /* IEEE EUI-64 */
47 AT_IB
, /* Infiniband GID/LID */
49 AT_VINES
, /* Banyan Vines address */
50 AT_NUMERIC
, /* Numeric address type. */
53 AT_END_OF_LIST
/* Must be last in list */
56 typedef struct _address
{
57 int type
; /* type of address */
58 int len
; /* length of address, in bytes */
59 const void *data
; /* pointer to address data */
65 #define ADDRESS_INIT(type, len, data) {type, len, data, NULL}
66 #define ADDRESS_INIT_NONE ADDRESS_INIT(AT_NONE, 0, NULL)
69 clear_address(address
*addr
)
77 /** Initialize an address with the given values.
79 * @param addr [in,out] The address to initialize.
80 * @param addr_type [in] Address type.
81 * @param addr_len [in] The length in bytes of the address data. For example, 4 for
82 * AT_IPv4 or sizeof(ws_in6_addr) for AT_IPv6.
83 * @param addr_data [in] Pointer to the address data.
86 set_address(address
*addr
, int addr_type
, int addr_len
, const void *addr_data
) {
88 /* Zero length must mean no data */
89 ws_assert(addr_data
== NULL
);
91 /* Must not be AT_NONE - AT_NONE must have no data */
92 ws_assert(addr_type
!= AT_NONE
);
93 /* Make sure we *do* have data */
94 ws_assert(addr_data
!= NULL
);
96 addr
->type
= addr_type
;
98 addr
->data
= addr_data
;
103 set_address_ipv4(address
*addr
, const ipv4_addr_and_mask
*ipv4
) {
104 addr
->type
= AT_IPv4
;
106 uint32_t val
= g_htonl(ipv4
->addr
);
107 addr
->priv
= g_memdup2(&val
, sizeof(val
));
108 addr
->data
= addr
->priv
;
112 set_address_ipv6(address
*addr
, const ipv6_addr_and_prefix
*ipv6
) {
113 set_address(addr
, AT_IPv6
, sizeof(ws_in6_addr
), &ipv6
->addr
);
116 /** Initialize an address from TVB data.
118 * Same as set_address but it takes a TVB and an offset. This is preferred
119 * over passing the return value of tvb_get_ptr() to set_address().
121 * This calls tvb_get_ptr() (including throwing any exceptions) before
122 * modifying the address.
124 * @param addr [in,out] The address to initialize.
125 * @param addr_type [in] Address type.
126 * @param tvb [in] Pointer to the TVB.
127 * @param offset [in] Offset within the TVB.
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.
132 set_address_tvb(address
*addr
, int addr_type
, int addr_len
, tvbuff_t
*tvb
, int offset
) {
136 /* Must not be AT_NONE - AT_NONE must have no data */
137 ws_assert(addr_type
!= AT_NONE
);
138 p
= tvb_get_ptr(tvb
, offset
, addr_len
);
141 set_address(addr
, addr_type
, addr_len
, p
);
144 /** Initialize an address with the given values, allocating a new buffer
145 * for the address data using wmem-scoped memory.
147 * @param scope [in] The lifetime of the allocated memory, e.g., pinfo->pool
148 * @param addr [in,out] The address to initialize.
149 * @param addr_type [in] Address type.
150 * @param addr_len [in] The length in bytes of the address data. For example, 4 for
151 * AT_IPv4 or sizeof(ws_in6_addr) for AT_IPv6.
152 * @param addr_data [in] Pointer to the address data.
155 alloc_address_wmem(wmem_allocator_t
*scope
, address
*addr
,
156 int addr_type
, int addr_len
, const void *addr_data
) {
159 addr
->type
= addr_type
;
161 /* Zero length must mean no data */
162 ws_assert(addr_data
== NULL
);
163 /* Nothing to copy */
166 /* Must not be AT_NONE - AT_NONE must have no data */
167 ws_assert(addr_type
!= AT_NONE
);
168 /* Make sure we *do* have data to copy */
169 ws_assert(addr_data
!= NULL
);
170 addr
->data
= addr
->priv
= wmem_memdup(scope
, addr_data
, addr_len
);
171 addr
->len
= addr_len
;
174 /** Allocate an address from TVB data.
176 * Same as alloc_address_wmem but it takes a TVB and an offset.
178 * @param scope [in] The lifetime of the allocated memory, e.g., pinfo->pool
179 * @param addr [in,out] The address to initialize.
180 * @param addr_type [in] Address type.
181 * @param addr_len [in] The length in bytes of the address data. For example, 4 for
182 * AT_IPv4 or sizeof(ws_in6_addr) for AT_IPv6.
183 * @param tvb [in] Pointer to the TVB.
184 * @param offset [in] Offset within the TVB.
187 alloc_address_tvb(wmem_allocator_t
*scope
, address
*addr
,
188 int addr_type
, int addr_len
, tvbuff_t
*tvb
, int offset
) {
191 p
= tvb_get_ptr(tvb
, offset
, addr_len
);
192 alloc_address_wmem(scope
, addr
, addr_type
, addr_len
, p
);
195 /** Compare two addresses.
197 * @param addr1 [in] The first address to compare.
198 * @param addr2 [in] The second address to compare.
199 * @return 0 if the addresses are equal,
200 * A positive number if addr1 > addr2 in some nondefined metric,
201 * A negative number if addr1 < addr2 in some nondefined metric.
204 cmp_address(const address
*addr1
, const address
*addr2
) {
205 if (addr1
->type
> addr2
->type
) return 1;
206 if (addr1
->type
< addr2
->type
) return -1;
207 if (addr1
->len
> addr2
->len
) return 1;
208 if (addr1
->len
< addr2
->len
) return -1;
209 if (addr1
->len
== 0) {
211 * memcmp(NULL, NULL, 0) is *not* guaranteed to work, so
212 * if both addresses are zero-length, don't compare them
213 * (there's nothing to compare, so they're equal).
217 return memcmp(addr1
->data
, addr2
->data
, addr1
->len
);
220 /** Check two addresses for equality.
222 * Given two addresses, return "true" if they're equal, "false" otherwise.
223 * Addresses are equal only if they have the same type and length; if the
224 * length is zero, they are then equal, otherwise the data must be the
227 * @param addr1 [in] The first address to compare.
228 * @param addr2 [in] The second address to compare.
229 * @return true if the addresses are equal, false otherwise.
232 addresses_equal(const address
*addr1
, const address
*addr2
) {
234 * memcmp(NULL, NULL, 0) is *not* guaranteed to work, so
235 * if both addresses are zero-length, don't compare them
236 * (there's nothing to compare, so they're equal).
238 if (addr1
->type
== addr2
->type
&&
239 addr1
->len
== addr2
->len
&&
241 memcmp(addr1
->data
, addr2
->data
, addr1
->len
) == 0))
246 /** Check the data of two addresses for equality.
248 * Given two addresses, return "true" if they have the same length and,
249 * their data is equal, "false" otherwise.
250 * The address types are ignored. This can be used to compare custom
251 * address types defined with address_type_dissector_register.
253 * @param addr1 [in] The first address to compare.
254 * @param addr2 [in] The second address to compare.
255 * @return true if the addresses are equal, false otherwise.
258 addresses_data_equal(const address
*addr1
, const address
*addr2
) {
259 if ( addr1
->len
== addr2
->len
260 && memcmp(addr1
->data
, addr2
->data
, addr1
->len
) == 0
265 /** Perform a shallow copy of the address (both addresses point to the same
268 * @param to [in,out] The destination address.
269 * @param from [in] The source address.
271 * \warning Make sure 'from' memory stays valid for the lifetime of this object.
272 * Also it's strongly recommended to use this function instead of copy-assign.
275 copy_address_shallow(address
*to
, const address
*from
) {
276 set_address(to
, from
->type
, from
->len
, from
->data
);
279 /** Copy an address, allocating a new buffer for the address data
280 * using wmem-scoped memory.
282 * @param scope [in] The lifetime of the allocated memory, e.g., pinfo->pool
283 * @param to [in,out] The destination address.
284 * @param from [in] The source address.
287 copy_address_wmem(wmem_allocator_t
*scope
, address
*to
, const address
*from
) {
288 alloc_address_wmem(scope
, to
, from
->type
, from
->len
, from
->data
);
291 /** Copy an address, allocating a new buffer for the address data.
293 * @param to [in,out] The destination address.
294 * @param from [in] The source address.
297 copy_address(address
*to
, const address
*from
) {
298 copy_address_wmem(NULL
, to
, from
);
301 /** Free an address allocated with wmem-scoped memory.
303 * @param scope [in] The lifetime of the allocated memory, e.g., pinfo->pool
304 * @param addr [in,out] The address whose data to free.
307 free_address_wmem(wmem_allocator_t
*scope
, address
*addr
) {
308 /* Because many dissectors set 'type = AT_NONE' to mean clear we check for that */
309 if (addr
->type
!= AT_NONE
&& addr
->len
> 0 && addr
->priv
!= NULL
) {
310 /* Make sure API use is correct */
311 /* if priv is not null then data == priv */
312 ws_assert(addr
->data
== addr
->priv
);
313 wmem_free(scope
, addr
->priv
);
320 * @param addr [in,out] The address whose data to free.
323 free_address(address
*addr
) {
324 free_address_wmem(NULL
, addr
);
327 /** Hash an address into a hash value (which must already have been set).
329 * @param hash_val The existing hash value.
330 * @param addr The address to add.
331 * @return The new hash value.
333 static inline unsigned
334 add_address_to_hash(unsigned hash_val
, const address
*addr
) {
335 const uint8_t *hash_data
= (const uint8_t *)(addr
)->data
;
338 for (idx
= 0; idx
< (addr
)->len
; idx
++) {
339 hash_val
+= hash_data
[idx
];
340 hash_val
+= ( hash_val
<< 10 );
341 hash_val
^= ( hash_val
>> 6 );
346 /** Hash an address into a hash value (which must already have been set).
347 * 64-bit version of add_address_to_hash().
349 * @param hash_val The existing hash value.
350 * @param addr The address to add.
351 * @return The new hash value.
353 static inline uint64_t
354 add_address_to_hash64(uint64_t hash_val
, const address
*addr
) {
355 const uint8_t *hash_data
= (const uint8_t *)(addr
)->data
;
358 for (idx
= 0; idx
< (addr
)->len
; idx
++) {
359 hash_val
+= hash_data
[idx
];
360 hash_val
+= ( hash_val
<< 10 );
361 hash_val
^= ( hash_val
>> 6 );
366 WS_DLL_PUBLIC
unsigned address_to_bytes(const address
*addr
, uint8_t *buf
, unsigned buf_len
);
368 /* Types of port numbers Wireshark knows about. */
370 PT_NONE
, /* no port number */
375 PT_IPX
, /* IPX sockets */
376 PT_DDP
, /* DDP AppleTalk connection */
377 PT_IDP
, /* XNS IDP sockets */
378 PT_USB
, /* USB endpoint 0xffff means the host */
380 PT_IBQP
, /* Infiniband QP number */
382 PT_IWARP_MPA
, /* iWarp MPA */
388 #endif /* __cplusplus */
390 #endif /* __ADDRESS_H__ */
393 * Editor modelines - https://www.wireshark.org/tools/modelines.html
398 * indent-tabs-mode: nil
401 * vi: set shiftwidth=4 tabstop=8 expandtab:
402 * :indentSize=4:tabSize=8:noTabs=true: