aboutsummaryrefslogtreecommitdiffstats
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-26 23:09:43 +0000
commite4c059f67f3b29bcc26b1faf111bf647ac630e04 (patch)
tree8ec634d7614f7a32c09c5cdb60d7509fc2dd2208 /epan/address.h
parent92537916483ec721a638cdd7c416d099a45a9304 (diff)
Add free_address_wmem(), fix warnings [-Wcast-qual]
Try to improve address API and also fix some constness warnings by not overloading the 'data' pointer to store malloc'ed buffers (use private pointer for that instead). Second try, now passing test suite. Change-Id: Idc101cd866b6d4f13500c9d59da5c7a38847fb7f Reviewed-on: https://code.wireshark.org/review/13946 Petri-Dish: João Valverde <j@v6e.pt> Reviewed-by: Alexis La Goutte <alexis.lagoutte@gmail.com> 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.h138
1 files changed, 105 insertions, 33 deletions
diff --git a/epan/address.h b/epan/address.h
index 897e7f0fe0..730acfb136 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 = 0;
+ 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,52 @@ 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) {
+ if (addr == NULL)
+ return;
+ addr->type = addr_type;
+ addr->len = addr_len;
+ if (addr_type == AT_NONE || addr->len <= 0) {
+ addr->data = addr->priv = NULL;
+ return;
+ }
+ 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 +225,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).