summaryrefslogtreecommitdiff
path: root/epan/address.h
diff options
context:
space:
mode:
authorJoão Valverde <joao.valverde@tecnico.ulisboa.pt>2015-11-26 04:44:52 +0000
committerJoão Valverde <j@v6e.pt>2016-02-07 23:22:30 +0000
commit13ec77a9fc3af3b0b502820d0b55796c89997896 (patch)
treec5f5f72f090efd5471cf95095b00e13efa407959 /epan/address.h
parentd762a895ab570680e4e72142a348ad2b07c97d4f (diff)
downloadwireshark-13ec77a9fc3af3b0b502820d0b55796c89997896.tar.gz
Add free_address_wmem() and other extensions to address API
Try to improve 'address' API (to be easier/safer) and also avoid some constness warnings by not overloading the 'data' pointer to store malloc'ed buffers (use private pointer for that instead). Change-Id: I7456516b12c67620ceadac447907c12f5905bd49 Reviewed-on: https://code.wireshark.org/review/13463 Petri-Dish: João Valverde <j@v6e.pt> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: João Valverde <j@v6e.pt>
Diffstat (limited to 'epan/address.h')
-rw-r--r--epan/address.h132
1 files changed, 99 insertions, 33 deletions
diff --git a/epan/address.h b/epan/address.h
index f0a42c1eee..027bc0fef0 100644
--- a/epan/address.h
+++ b/epan/address.h
@@ -63,9 +63,24 @@ typedef enum {
typedef struct _address {
int type; /* type of address */
int len; /* length of address, in bytes */
- const void *data; /* pointer to address data */
+ const void *data; /* pointer to address data */
+
+ /* private */
+ void *priv;
} address;
+#define ADDRESS_INIT(type, len, data) {type, len, data, NULL}
+#define ADDRESS_INIT_NONE ADDRESS_INIT(AT_NONE, 0, NULL)
+
+static inline void
+clear_address(address *addr)
+{
+ addr->type = AT_NONE;
+ addr->len = -1;
+ addr->data = NULL;
+ addr->priv = NULL;
+}
+
/** Initialize an address with the given values.
*
* @param addr [in,out] The address to initialize.
@@ -76,9 +91,10 @@ typedef struct _address {
*/
static inline void
set_address(address *addr, int addr_type, int addr_len, const void *addr_data) {
- addr->data = addr_data;
addr->type = addr_type;
addr->len = addr_len;
+ addr->data = addr_data;
+ addr->priv = NULL;
}
/** Initialize an address from TVB data.
@@ -104,6 +120,46 @@ set_address_tvb(address *addr, int addr_type, int addr_len, tvbuff_t *tvb, int o
set_address(addr, addr_type, addr_len, p);
}
+/** Initialize an address with the given values, allocating a new buffer
+ * for the address data using wmem-scoped memory.
+ *
+ * @param scope [in] The lifetime of the allocated memory, e.g., wmem_packet_scope()
+ * @param addr [in,out] The address to initialize.
+ * @param addr_type [in] Address type.
+ * @param addr_len [in] The length in bytes of the address data. For example, 4 for
+ * AT_IPv4 or sizeof(struct e_in6_addr) for AT_IPv6.
+ * @param addr_data [in] Pointer to the address data.
+ */
+static inline void
+alloc_address_wmem(wmem_allocator_t *scope, address *addr,
+ int addr_type, int addr_len, const void *addr_data) {
+ addr->type = addr_type;
+ addr->len = addr_len;
+ addr->priv = wmem_memdup(scope, addr_data, addr->len);
+ addr->data = addr->priv;
+}
+
+/** Allocate an address from TVB data.
+ *
+ * Same as alloc_address_wmem but it takes a TVB and an offset.
+ *
+ * @param scope [in] The lifetime of the allocated memory, e.g., wmem_packet_scope()
+ * @param addr [in,out] The address to initialize.
+ * @param addr_type [in] Address type.
+ * @param addr_len [in] The length in bytes of the address data. For example, 4 for
+ * AT_IPv4 or sizeof(struct e_in6_addr) for AT_IPv6.
+ * @param tvb [in] Pointer to the TVB.
+ * @param offset [in] Offset within the TVB.
+ */
+static inline void
+alloc_address_tvb(wmem_allocator_t *scope, address *addr,
+ int addr_type, int addr_len, tvbuff_t *tvb, int offset) {
+ const void *p;
+
+ p = tvb_get_ptr(tvb, offset, addr_len);
+ alloc_address_wmem(scope, addr, addr_type, addr_len, p);
+}
+
/** Compare two addresses.
*
* @param addr1 [in] The first address to compare.
@@ -163,56 +219,66 @@ addresses_data_equal(const address *addr1, const address *addr2) {
return FALSE;
}
-/** Copy an address, allocating a new buffer for the address data.
+/** Perform a shallow copy of the address (both addresses point to the same
+ * memory location).
*
* @param to [in,out] The destination address.
* @param from [in] The source address.
+ *
+ * \warning Make sure 'from' memory stays valid for the lifetime of this object.
+ * Also it's strongly recommended to use this function instead of copy-assign.
*/
static inline void
-copy_address(address *to, const address *from) {
- guint8 *to_data;
-
- to->type = from->type;
- to->len = from->len;
- to_data = (guint8 *)g_malloc(from->len);
- if (from->len != 0)
- memcpy(to_data, from->data, from->len);
- to->data = to_data;
+copy_address_shallow(address *to, const address *from) {
+ set_address(to, from->type, from->len, from->data);
}
-/** Perform a shallow copy of the address (both addresses point to the same
- * memory location).
+/** Copy an address, allocating a new buffer for the address data
+ * using wmem-scoped memory.
*
+ * @param scope [in] The lifetime of the allocated memory, e.g., wmem_packet_scope()
* @param to [in,out] The destination address.
* @param from [in] The source address.
*/
static inline void
-copy_address_shallow(address *to, const address *from) {
- memcpy(to, from, sizeof(address));
- /*
- to->type = from->type;
- to->len = from->len;
- to->data = from->data;
- */
+copy_address_wmem(wmem_allocator_t *scope, address *to, const address *from) {
+ alloc_address_wmem(scope, to, from->type, from->len, from->data);
}
-/** Copy an address, allocating a new buffer for the address data
- * using wmem-scoped memory.
+/** Copy an address, allocating a new buffer for the address data.
*
- * @param scope [in] The lifetime of the allocated memory, wmem_packet_scope()
* @param to [in,out] The destination address.
* @param from [in] The source address.
*/
static inline void
-copy_address_wmem(wmem_allocator_t *scope, address *to, const address *from) {
- void *to_data;
-
- to->type = from->type;
- to->len = from->len;
- to_data = wmem_alloc(scope, from->len);
- if (from->len != 0)
- memcpy(to_data, from->data, from->len);
- to->data = to_data;
+copy_address(address *to, const address *from) {
+ copy_address_wmem(NULL, to, from);
+}
+
+/** Free an address allocated with wmem-scoped memory.
+ *
+ * @param scope [in] The lifetime of the allocated memory, e.g., wmem_packet_scope()
+ * @param addr [in,out] The address whose data to free.
+ */
+static inline void
+free_address_wmem(wmem_allocator_t *scope, address *addr) {
+ /* Because many dissectors set 'type = AT_NONE' to mean clear we check for that */
+ if (addr->type != AT_NONE && addr->len > 0 && addr->priv != NULL) {
+ /* Make sure API use is correct */
+ /* if priv is not null then data == priv */
+ g_assert(addr->data == addr->priv);
+ wmem_free(scope, addr->priv);
+ }
+ clear_address(addr);
+}
+
+/** Free an address.
+ *
+ * @param addr [in,out] The address whose data to free.
+ */
+static inline void
+free_address(address *addr) {
+ free_address_wmem(NULL, addr);
}
/** Hash an address into a hash value (which must already have been set).