checkAPIs.pl: support for new-style dissectors in check_hf_entries
[metze/wireshark/wip.git] / epan / address_types.c
index f04ef53e354ecaa3fe9c318fefdf01b0f11d23ce..9e575a1f15a7f97650b4faadd8a86fe9d621d543 100644 (file)
@@ -4,35 +4,11 @@
  * By Gerald Combs <gerald@wireshark.org>
  * Copyright 1998 Gerald Combs
  *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * SPDX-License-Identifier: GPL-2.0-or-later
  */
 
 #include "config.h"
 
-#ifdef HAVE_NETINET_IN_H
-# include <netinet/in.h>        /* needed for <arpa/inet.h> on some platforms */
-#endif
-
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>         /* needed to define AF_ values on UNIX */
-#endif
-
 #include <string.h>     /* for memcmp */
 #include "packet.h"
 #include "address_types.h"
@@ -41,9 +17,7 @@
 #include "addr_resolv.h"
 #include "wsutil/pint.h"
 #include "wsutil/str_util.h"
-#include "wsutil/inet_v6defs.h"
-
-#include <epan/dissectors/packet-mtp3.h>
+#include "wsutil/inet_addr.h"
 
 struct _address_type_t {
     int                     addr_type; /* From address_type enumeration or registered value */
@@ -51,6 +25,7 @@ struct _address_type_t {
     const char             *pretty_name;
     AddrValueToString       addr_to_str;
     AddrValueToStringLen    addr_str_len;
+    AddrValueToByte         addr_to_byte;
     AddrColFilterString     addr_col_filter;
     AddrFixedLen            addr_fixed_len;
     AddrNameResolutionToString addr_name_res_str;
@@ -59,14 +34,14 @@ struct _address_type_t {
     /* XXX - Some sort of compare functions (like ftype)? ***/
 };
 
-#define MAX_DISSECTOR_ADDR_TYPE     20
+#define MAX_DISSECTOR_ADDR_TYPE     30
 #define MAX_ADDR_TYPE_VALUE (AT_END_OF_LIST+MAX_DISSECTOR_ADDR_TYPE)
 
 static int num_dissector_addr_type;
 static address_type_t dissector_type_addresses[MAX_DISSECTOR_ADDR_TYPE];
 
 /* Keep track of address_type_t's via their id number */
-static address_type_t* type_list[MAX_ADDR_TYPE_VALUE];
+static address_type_t* type_list[MAX_ADDR_TYPE_VALUE + 1];
 
 /*
  * If a user _does_ pass in a too-small buffer, this is probably
@@ -86,34 +61,34 @@ static void address_type_register(int addr_type, address_type_t *at)
     g_assert(type_list[addr_type] == NULL);
 
     /* Sanity check */
-    DISSECTOR_ASSERT(at->name);
-    DISSECTOR_ASSERT(at->pretty_name);
-    DISSECTOR_ASSERT(at->addr_to_str);
-    DISSECTOR_ASSERT(at->addr_str_len);
-    DISSECTOR_ASSERT(((at->addr_name_res_str != NULL) && (at->addr_name_res_str != NULL)) ||
-                     ((at->addr_name_res_len == NULL) && (at->addr_name_res_len == NULL)));
+    g_assert(at->name);
+    g_assert(at->pretty_name);
+    g_assert(at->addr_to_str);
+    g_assert(at->addr_str_len);
+    g_assert(((at->addr_name_res_str != NULL) && (at->addr_name_res_len != NULL)) ||
+                     ((at->addr_name_res_str == NULL) && (at->addr_name_res_len == NULL)));
 
     type_list[addr_type] = at;
 }
 
 int address_type_dissector_register(const char* name, const char* pretty_name,
                                     AddrValueToString to_str_func, AddrValueToStringLen str_len_func,
-                                    AddrColFilterString col_filter_str_func, AddrFixedLen fixed_len_func,
+                                    AddrValueToByte to_bytes_func, AddrColFilterString col_filter_str_func, AddrFixedLen fixed_len_func,
                                     AddrNameResolutionToString name_res_str_func, AddrNameResolutionLen name_res_len_func)
 {
     int addr_type;
 
     /* Ensure valid data/functions for required fields */
-    DISSECTOR_ASSERT(name);
-    DISSECTOR_ASSERT(pretty_name);
-    DISSECTOR_ASSERT(to_str_func);
-    DISSECTOR_ASSERT(str_len_func);
+    g_assert(name);
+    g_assert(pretty_name);
+    g_assert(to_str_func);
+    g_assert(str_len_func);
     /* Either have both or neither */
-    DISSECTOR_ASSERT(((name_res_str_func != NULL) && (name_res_len_func != NULL)) ||
+    g_assert(((name_res_str_func != NULL) && (name_res_len_func != NULL)) ||
                      ((name_res_str_func == NULL) && (name_res_len_func == NULL)));
 
     /* This shouldn't happen, so flag it for fixing */
-    DISSECTOR_ASSERT(num_dissector_addr_type < MAX_DISSECTOR_ADDR_TYPE);
+    g_assert(num_dissector_addr_type < MAX_DISSECTOR_ADDR_TYPE);
 
     addr_type = AT_END_OF_LIST+num_dissector_addr_type;
     dissector_type_addresses[num_dissector_addr_type].addr_type = addr_type;
@@ -121,6 +96,7 @@ int address_type_dissector_register(const char* name, const char* pretty_name,
     dissector_type_addresses[num_dissector_addr_type].pretty_name = pretty_name;
     dissector_type_addresses[num_dissector_addr_type].addr_to_str = to_str_func;
     dissector_type_addresses[num_dissector_addr_type].addr_str_len = str_len_func;
+    dissector_type_addresses[num_dissector_addr_type].addr_to_byte = to_bytes_func;
     dissector_type_addresses[num_dissector_addr_type].addr_col_filter = col_filter_str_func;
     dissector_type_addresses[num_dissector_addr_type].addr_fixed_len = fixed_len_func;
     dissector_type_addresses[num_dissector_addr_type].addr_name_res_str = name_res_str_func;
@@ -133,6 +109,21 @@ int address_type_dissector_register(const char* name, const char* pretty_name,
     return addr_type;
 }
 
+int address_type_get_by_name(const char* name)
+{
+    address_type_t** addr;
+
+    for (addr = type_list; *addr != NULL; addr++)
+    {
+        if (!strcmp((*addr)->name, name))
+        {
+            return (*addr)->addr_type;
+        }
+    }
+
+    return -1;
+}
+
 /******************************************************************************
  * AT_NONE
  ******************************************************************************/
@@ -203,15 +194,15 @@ int ether_name_resolution_len(void)
 /******************************************************************************
  * AT_IPv4
  ******************************************************************************/
-static gboolean ipv4_to_str(const address* addr, gchar *buf, int buf_len)
+static int ipv4_to_str(const address* addr, gchar *buf, int buf_len)
 {
     ip_to_str_buf((const guint8*)addr->data, buf, buf_len);
-    return TRUE;
+    return (int)(strlen(buf)+1);
 }
 
 static int ipv4_str_len(const address* addr _U_)
 {
-    return MAX_IP_STR_LEN;
+    return WS_INET_ADDRSTRLEN;
 }
 
 static const char* ipv4_col_filter_str(const address* addr _U_, gboolean is_src)
@@ -227,14 +218,14 @@ static int ipv4_len(void)
     return 4;
 }
 
-const gchar* ipv4_name_res_str(const address* addr)
+static const gchar* ipv4_name_res_str(const address* addr)
 {
     guint32 ip4_addr;
     memcpy(&ip4_addr, addr->data, sizeof ip4_addr);
     return get_hostname(ip4_addr);
 }
 
-int ipv4_name_res_len(void)
+static int ipv4_name_res_len(void)
 {
     return MAX_ADDR_STR_LEN; /* XXX - This can be lower */
 }
@@ -242,132 +233,14 @@ int ipv4_name_res_len(void)
 /******************************************************************************
  * AT_IPv6
  ******************************************************************************/
-/* const char *
- * inet_ntop6(src, dst, size)
- *  convert IPv6 binary address into presentation (printable) format
- * author:
- *  Paul Vixie, 1996.
- */
-static void
-ip6_to_str_buf_len(const guchar* src, char *buf, size_t buf_len)
-{
-    struct { int base, len; } best, cur;
-    guint words[8];
-    int i;
-
-    if (buf_len < MAX_IP6_STR_LEN) { /* buf_len < 40 */
-        g_strlcpy(buf, BUF_TOO_SMALL_ERR, buf_len); /* Let the unexpected value alert user */
-        return;
-    }
-
-    /*
-     * Preprocess:
-     *  Copy the input (bytewise) array into a wordwise array.
-     *  Find the longest run of 0x00's in src[] for :: shorthanding.
-     */
-    for (i = 0; i < 16; i += 2) {
-        words[i / 2] = (src[i+1] << 0);
-        words[i / 2] |= (src[i] << 8);
-    }
-    best.base = -1; best.len = 0;
-    cur.base = -1;  cur.len = 0;
-    for (i = 0; i < 8; i++) {
-        if (words[i] == 0) {
-            if (cur.base == -1) {
-                cur.base = i;
-                cur.len = 1;
-            } else
-                cur.len++;
-        } else {
-            if (cur.base != -1) {
-                if (best.base == -1 || cur.len > best.len)
-                    best = cur;
-                cur.base = -1;
-            }
-        }
-    }
-    if (cur.base != -1) {
-        if (best.base == -1 || cur.len > best.len)
-            best = cur;
-    }
-    if (best.base != -1 && best.len < 2)
-        best.base = -1;
-
-    /* Is this address an encapsulated IPv4? */
-    /* XXX,
-     * Orginal code dated 1996 uses ::/96 as a valid IPv4-compatible addresses
-     * but since Feb 2006 ::/96 is deprecated one.
-     * Quoting wikipedia [0]:
-     * > The 96-bit zero-value prefix ::/96, originally known as IPv4-compatible
-     * > addresses, was mentioned in 1995[35] but first described in 1998.[41]
-     * > This class of addresses was used to represent IPv4 addresses within
-     * > an IPv6 transition technology. Such an IPv6 address has its first
-     * > (most significant) 96 bits set to zero, while its last 32 bits are the
-     * > IPv4 address that is represented.
-     * > In February 2006 the Internet Engineering Task Force (IETF) has deprecated
-     * > the use of IPv4-compatible addresses.[1] The only remaining use of this address
-     * > format is to represent an IPv4 address in a table or database with fixed size
-     * > members that must also be able to store an IPv6 address.
-     *
-     * If needed it can be fixed by changing next line:
-     *   if (best.base == 0 && (best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
-     * to:
-     *   if (best.base == 0 && best.len == 5 && words[5] == 0xffff)
-     *
-     * [0] http://en.wikipedia.org/wiki/IPv6_address#Historical_notes
-     */
-
-    if (best.base == 0 && (best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
-    {
-        /* best.len == 6 -> ::IPv4; 5 -> ::ffff:IPv4 */
-        buf = g_stpcpy(buf, "::");
-        if (best.len == 5)
-        buf = g_stpcpy(buf, "ffff:");
-        ip_to_str_buf(src + 12, buf, MAX_IP_STR_LEN);
-        /* max: 2 + 5 + 16 == 23 bytes */
-        return;
-    }
-
-    /*
-     * Format the result.
-     */
-    for (i = 0; i < 8; i++) {
-        /* Are we inside the best run of 0x00's? */
-        if (i == best.base) {
-            *buf++ = ':';
-            i += best.len;
-
-            /* Was it a trailing run of 0x00's? */
-            if (i == 8) {
-                *buf++ = ':';
-                break;
-            }
-        }
-        /* Are we following an initial run of 0x00s or any real hex? */
-        if (i != 0)
-            *buf++ = ':';
-
-        buf = word_to_hex_npad(buf, words[i]); /* max: 4B */
-        /* max: 8 * 4 + 7 == 39 bytes */
-    }
-    *buf = '\0'; /* 40 byte */
-}
-
-void
-ip6_to_str_buf(const struct e_in6_addr *ad, gchar *buf)
+static int ipv6_to_str(const address* addr, gchar *buf, int buf_len)
 {
-    ip6_to_str_buf_len((const guchar*)ad, buf, MAX_IP6_STR_LEN);
-}
-
-static gboolean ipv6_to_str(const address* addr, gchar *buf, int buf_len)
-{
-    ip6_to_str_buf_len((const guchar*)addr->data, buf, buf_len);
-    return TRUE;
+    return ip6_to_str_buf((const ws_in6_addr *)addr->data, buf, buf_len) + 1;
 }
 
 static int ipv6_str_len(const address* addr _U_)
 {
-    return MAX_IP6_STR_LEN;
+    return WS_INET6_ADDRSTRLEN;
 }
 
 static const char* ipv6_col_filter_str(const address* addr _U_, gboolean is_src)
@@ -383,14 +256,14 @@ static int ipv6_len(void)
     return 16;
 }
 
-const gchar* ipv6_name_res_str(const address* addr)
+static const gchar* ipv6_name_res_str(const address* addr)
 {
-    struct e_in6_addr ip6_addr;
+    ws_in6_addr ip6_addr;
     memcpy(&ip6_addr.bytes, addr->data, sizeof ip6_addr.bytes);
     return get_hostname6(&ip6_addr);
 }
 
-int ipv6_name_res_len(void)
+static int ipv6_name_res_len(void)
 {
     return MAX_ADDR_STR_LEN; /* XXX - This can be lower */
 }
@@ -398,15 +271,16 @@ int ipv6_name_res_len(void)
 /******************************************************************************
  * AT_IPX
  ******************************************************************************/
-static gboolean ipx_to_str(const address* addr, gchar *buf, int buf_len _U_)
+static int ipx_to_str(const address* addr, gchar *buf, int buf_len _U_)
 {
     const guint8 *addrdata = (const guint8 *)addr->data;
+    gchar *bufp = buf;
 
-    buf = bytes_to_hexstr(buf, &addrdata[0], 4); /* 8 bytes */
-    *buf++ = '.'; /*1 byte */
-    buf = bytes_to_hexstr(buf, &addrdata[4], 6); /* 12 bytes */
-    *buf++ = '\0'; /* NULL terminate */
-    return TRUE;
+    bufp = bytes_to_hexstr(bufp, &addrdata[0], 4); /* 8 bytes */
+    *bufp++ = '.'; /*1 byte */
+    bufp = bytes_to_hexstr(bufp, &addrdata[4], 6); /* 12 bytes */
+    *bufp++ = '\0'; /* NULL terminate */
+    return (int)(bufp - buf);
 }
 
 static int ipx_str_len(const address* addr _U_)
@@ -419,42 +293,17 @@ static int ipx_len(void)
     return 10;
 }
 
-/******************************************************************************
- * AT_VINES
- * XXX - This functionality should really be in packet-vines.c as a dissector
- * address type, but need to resolve "address type" as "field type"
- ******************************************************************************/
-static gboolean vines_to_str(const address* addr, gchar *buf, int buf_len _U_)
-{
-    const guint8 *addr_data = (const guint8 *)addr->data;
-
-    buf = dword_to_hex(buf, pntoh32(&addr_data[0])); /* 8 bytes */
-    *buf++ = '.'; /* 1 byte */
-    buf = word_to_hex(buf, pntoh16(&addr_data[4])); /* 4 bytes */
-    *buf = '\0'; /* NULL terminate */
-
-    return TRUE;
-}
-
-static int vines_str_len(const address* addr _U_)
-{
-    return 14;
-}
-
-static int vines_len(void)
-{
-    return VINES_ADDR_LEN;
-}
-
 /******************************************************************************
  * AT_FC
  ******************************************************************************/
-static gboolean fc_to_str(const address* addr, gchar *buf, int buf_len _U_)
+static int fc_to_str(const address* addr, gchar *buf, int buf_len _U_)
 {
-    buf = bytes_to_hexstr_punct(buf, (const guint8 *)addr->data, 3, '.');
-    *buf = '\0'; /* NULL terminate */
+    gchar *bufp = buf;
+
+    bufp = bytes_to_hexstr_punct(bufp, (const guint8 *)addr->data, 3, '.');
+    *bufp++ = '\0'; /* NULL terminate */
 
-    return TRUE;
+    return (int)(bufp - buf);
 }
 
 static int fc_str_len(const address* addr _U_)
@@ -492,7 +341,7 @@ static int fcwwn_to_str(const address* addr, gchar *buf, int buf_len _U_)
     const guint8 *addrp = (const guint8*)addr->data;
 
     buf = bytes_to_hexstr_punct(buf, addrp, 8, ':'); /* 23 bytes */
-    buf[23] = '\0';
+    *buf = '\0';
 
     return fcwwn_str_len(addr);
 }
@@ -502,7 +351,7 @@ static int fcwwn_len(void)
     return FCWWN_ADDR_LEN;
 }
 
-const gchar* fcwwn_name_res_str(const address* addr)
+static const gchar* fcwwn_name_res_str(const address* addr)
 {
     const guint8 *addrp = (const guint8*)addr->data;
     int fmt;
@@ -531,34 +380,18 @@ const gchar* fcwwn_name_res_str(const address* addr)
     return "";
 }
 
-int fcwwn_name_res_len(void)
+static int fcwwn_name_res_len(void)
 {
     return MAX_ADDR_STR_LEN; /* XXX - This can be lower */
 }
 
-/******************************************************************************
- * AT_SS7PC
- * XXX - This should really be a dissector address type as its address string
- * is partially determined by a dissector preference.
- ******************************************************************************/
-static gboolean ss7pc_to_str(const address* addr, gchar *buf, int buf_len)
-{
-    mtp3_addr_to_str_buf((const mtp3_addr_pc_t *)addr->data, buf, buf_len);
-    return TRUE;
-}
-
-static int ss7pc_str_len(const address* addr _U_)
-{
-    return 50;
-}
-
 /******************************************************************************
  * AT_STRINGZ
  ******************************************************************************/
-static gboolean stringz_addr_to_str(const address* addr, gchar *buf, int buf_len)
+static int stringz_addr_to_str(const address* addr, gchar *buf, int buf_len)
 {
     g_strlcpy(buf, (const gchar *)addr->data, buf_len);
-    return TRUE;
+    return (int)(strlen(buf)+1);
 }
 
 static int stringz_addr_str_len(const address* addr)
@@ -569,11 +402,11 @@ static int stringz_addr_str_len(const address* addr)
 /******************************************************************************
  * AT_EUI64
  ******************************************************************************/
-static gboolean eui64_addr_to_str(const address* addr, gchar *buf, int buf_len _U_)
+static int eui64_addr_to_str(const address* addr, gchar *buf, int buf_len _U_)
 {
     buf = bytes_to_hexstr_punct(buf, (const guint8 *)addr->data, 8, ':');
     *buf = '\0'; /* NULL terminate */
-    return TRUE;
+    return EUI64_STR_LEN;
 }
 
 static int eui64_str_len(const address* addr _U_)
@@ -589,23 +422,17 @@ static int eui64_len(void)
 /******************************************************************************
  * AT_IB
  ******************************************************************************/
-static gboolean
-ib_addr_to_str( const address *addr, gchar *buf, int buf_len){
+static int
+ib_addr_to_str(const address *addr, gchar *buf, int buf_len)
+{
     if (addr->len >= 16) { /* GID is 128bits */
-        #define PREAMBLE_STR_LEN ((int)(sizeof("GID: ") - 1))
-        g_strlcpy(buf, "GID: ", buf_len);
-        if (buf_len < PREAMBLE_STR_LEN ||
-                inet_ntop(AF_INET6, addr->data, buf + PREAMBLE_STR_LEN,
-                          buf_len - PREAMBLE_STR_LEN) == NULL ) /* Returns NULL if no space and does not touch buf */
-            g_strlcpy(buf, BUF_TOO_SMALL_ERR, buf_len); /* Let the unexpected value alert user */
-    } else {    /* this is a LID (16 bits) */
-        guint16 lid_number;
-
-        memcpy((void *)&lid_number, addr->data, sizeof lid_number);
-        g_snprintf(buf,buf_len,"LID: %u",lid_number);
+        return ip6_to_str_buf_with_pfx((const ws_in6_addr *)addr->data, buf, buf_len, "GID: ");
     }
 
-    return TRUE;
+    /* this is a LID (16 bits) */
+    g_snprintf(buf,buf_len,"LID: %u", *(const guint16 *)addr->data);
+
+    return (int)(strlen(buf)+1);
 }
 
 static int ib_str_len(const address* addr _U_)
@@ -613,48 +440,25 @@ static int ib_str_len(const address* addr _U_)
     return MAX_ADDR_STR_LEN; /* XXX - This is overkill */
 }
 
-/******************************************************************************
- * AT_USB
- * XXX - This functionality should really be in packet-usb.c as a dissector
- * address type, but currently need support of AT_USB in conversation_table.c
- ******************************************************************************/
-static gboolean usb_addr_to_str(const address* addr, gchar *buf, int buf_len _U_)
-{
-    const guint8 *addrp = (const guint8 *)addr->data;
-
-    if(pletoh32(&addrp[0])==0xffffffff){
-        g_strlcpy(buf, "host", buf_len);
-    } else {
-        g_snprintf(buf, buf_len, "%d.%d.%d", pletoh16(&addrp[8]),
-                        pletoh32(&addrp[0]), pletoh32(&addrp[4]));
-    }
-
-    return TRUE;
-}
-
-static int usb_addr_str_len(const address* addr _U_)
-{
-    return 50;
-}
-
 /******************************************************************************
  * AT_AX25
  ******************************************************************************/
-static gboolean ax25_addr_to_str(const address* addr, gchar *buf, int buf_len _U_)
+static int ax25_addr_to_str(const address* addr, gchar *buf, int buf_len _U_)
 {
     const guint8 *addrdata = (const guint8 *)addr->data;
+    gchar *bufp = buf;
 
-    *buf++ = printable_char_or_period(addrdata[0] >> 1);
-    *buf++ = printable_char_or_period(addrdata[1] >> 1);
-    *buf++ = printable_char_or_period(addrdata[2] >> 1);
-    *buf++ = printable_char_or_period(addrdata[3] >> 1);
-    *buf++ = printable_char_or_period(addrdata[4] >> 1);
-    *buf++ = printable_char_or_period(addrdata[5] >> 1);
-    *buf++ = '-';
-    buf = uint_to_str_back(buf, (addrdata[6] >> 1) & 0x0f);
-    *buf = '\0'; /* NULL terminate */
+    *bufp++ = printable_char_or_period(addrdata[0] >> 1);
+    *bufp++ = printable_char_or_period(addrdata[1] >> 1);
+    *bufp++ = printable_char_or_period(addrdata[2] >> 1);
+    *bufp++ = printable_char_or_period(addrdata[3] >> 1);
+    *bufp++ = printable_char_or_period(addrdata[4] >> 1);
+    *bufp++ = printable_char_or_period(addrdata[5] >> 1);
+    *bufp++ = '-';
+    bufp = uint_to_str_back(bufp, (addrdata[6] >> 1) & 0x0f);
+    *bufp++ = '\0'; /* NULL terminate */
 
-    return TRUE;
+    return (int)(bufp - buf);
 }
 
 static int ax25_addr_str_len(const address* addr _U_)
@@ -675,6 +479,33 @@ static int ax25_len(void)
     return AX25_ADDR_LEN;
 }
 
+/******************************************************************************
+ * AT_VINES
+ ******************************************************************************/
+
+static int vines_addr_to_str(const address* addr, gchar *buf, int buf_len _U_)
+{
+       const guint8 *addr_data = (const guint8 *)addr->data;
+       gchar *bufp = buf;
+
+       bufp = dword_to_hex(bufp, pntoh32(&addr_data[0])); /* 8 bytes */
+       *bufp++ = '.'; /* 1 byte */
+       bufp = word_to_hex(bufp, pntoh16(&addr_data[4])); /* 4 bytes */
+       *bufp++ = '\0'; /* NULL terminate */
+
+       return (int)(bufp - buf);
+}
+
+static int vines_addr_str_len(const address* addr _U_)
+{
+       return 14;
+}
+
+static int vines_len(void)
+{
+       return VINES_ADDR_LEN;
+}
+
 /******************************************************************************
  * END OF PROVIDED ADDRESS TYPES
  ******************************************************************************/
@@ -690,6 +521,7 @@ void address_types_initialize(void)
         "No address",       /* pretty_name */
         none_addr_to_str,   /* addr_to_str */
         none_addr_str_len,  /* addr_str_len */
+        NULL,               /* addr_to_byte */
         NULL,               /* addr_col_filter */
         none_addr_len,      /* addr_fixed_len */
         none_name_res_str, /* addr_name_res_str */
@@ -702,6 +534,7 @@ void address_types_initialize(void)
         "Ethernet address", /* pretty_name */
         ether_to_str,       /* addr_to_str */
         ether_str_len,      /* addr_str_len */
+        NULL,               /* addr_to_byte */
         ether_col_filter_str, /* addr_col_filter */
         ether_len,          /* addr_fixed_len */
         ether_name_resolution_str, /* addr_name_res_str */
@@ -714,6 +547,7 @@ void address_types_initialize(void)
         "IPv4 address",     /* pretty_name */
         ipv4_to_str,        /* addr_to_str */
         ipv4_str_len,       /* addr_str_len */
+        NULL,               /* addr_to_byte */
         ipv4_col_filter_str, /* addr_col_filter */
         ipv4_len,           /* addr_fixed_len */
         ipv4_name_res_str, /* addr_name_res_str */
@@ -726,6 +560,7 @@ void address_types_initialize(void)
         "IPv6 address",     /* pretty_name */
         ipv6_to_str,        /* addr_to_str */
         ipv6_str_len,       /* addr_str_len */
+        NULL,               /* addr_to_byte */
         ipv6_col_filter_str, /* addr_col_filter */
         ipv6_len,            /* addr_fixed_len */
         ipv6_name_res_str, /* addr_name_res_str */
@@ -738,30 +573,20 @@ void address_types_initialize(void)
         "IPX address",      /* pretty_name */
         ipx_to_str,         /* addr_to_str */
         ipx_str_len,        /* addr_str_len */
+        NULL,               /* addr_to_byte */
         NULL,               /* addr_col_filter */
         ipx_len,            /* addr_fixed_len */
         NULL,               /* addr_name_res_str */
         NULL,               /* addr_name_res_len */
     };
 
-    static address_type_t vines_address = {
-        AT_VINES,           /* addr_type */
-        "AT_VINES",         /* name */
-        "Banyan Vines address", /* pretty_name */
-        vines_to_str,       /* addr_to_str */
-        vines_str_len,      /* addr_str_len */
-        NULL,               /* addr_col_filter */
-        vines_len,          /* addr_fixed_len */
-        NULL,               /* addr_name_res_str */
-        NULL,               /* addr_name_res_len */
-    };
-
     static address_type_t fc_address = {
         AT_FC,          /* addr_type */
         "AT_FC",        /* name */
         "FC address",   /* pretty_name */
         fc_to_str,      /* addr_to_str */
         fc_str_len,     /* addr_str_len */
+        NULL,           /* addr_to_byte */
         NULL,           /* addr_col_filter */
         fc_len,         /* addr_fixed_len */
         NULL,           /* addr_name_res_str */
@@ -774,30 +599,20 @@ void address_types_initialize(void)
         "Fibre Channel WWN",    /* pretty_name */
         fcwwn_to_str,   /* addr_to_str */
         fcwwn_str_len,  /* addr_str_len */
+        NULL,           /* addr_to_byte */
         NULL,           /* addr_col_filter */
         fcwwn_len,         /* addr_fixed_len */
         fcwwn_name_res_str, /* addr_name_res_str */
         fcwwn_name_res_len, /* addr_name_res_len */
     };
 
-    static address_type_t ss7pc_address = {
-        AT_SS7PC,          /* addr_type */
-        "AT_SS7PC",        /* name */
-        "SS7 Point Code",  /* pretty_name */
-        ss7pc_to_str,      /* addr_to_str */
-        ss7pc_str_len,     /* addr_str_len */
-        NULL,              /* addr_col_filter */
-        NULL,              /* addr_fixed_len */
-        NULL,              /* addr_name_res_str */
-        NULL,              /* addr_name_res_len */
-    };
-
     static address_type_t stringz_address = {
         AT_STRINGZ,          /* addr_type */
         "AT_STRINGZ",        /* name */
         "String address",   /* pretty_name */
         stringz_addr_to_str, /* addr_to_str */
         stringz_addr_str_len, /* addr_str_len */
+        NULL,              /* addr_to_byte */
         NULL,              /* addr_col_filter */
         NULL,              /* addr_fixed_len */
         NULL,              /* addr_name_res_str */
@@ -810,6 +625,7 @@ void address_types_initialize(void)
         "IEEE EUI-64",     /* pretty_name */
         eui64_addr_to_str, /* addr_to_str */
         eui64_str_len,     /* addr_str_len */
+        NULL,              /* addr_to_byte */
         NULL,              /* addr_col_filter */
         eui64_len,         /* addr_fixed_len */
         NULL,              /* addr_name_res_str */
@@ -822,18 +638,7 @@ void address_types_initialize(void)
         "Infiniband GID/LID",   /* pretty_name */
         ib_addr_to_str,  /* addr_to_str */
         ib_str_len,      /* addr_str_len */
-        NULL,              /* addr_col_filter */
-        NULL,              /* addr_fixed_len */
-        NULL,              /* addr_name_res_str */
-        NULL,              /* addr_name_res_len */
-    };
-
-    static address_type_t usb_address = {
-        AT_USB,          /* addr_type */
-        "AT_USB",        /* name */
-        "USB Address",   /* pretty_name */
-        usb_addr_to_str, /* addr_to_str */
-        usb_addr_str_len, /* addr_str_len */
+        NULL,              /* addr_to_byte */
         NULL,              /* addr_col_filter */
         NULL,              /* addr_fixed_len */
         NULL,              /* addr_name_res_str */
@@ -846,32 +651,43 @@ void address_types_initialize(void)
         "AX.25 Address",  /* pretty_name */
         ax25_addr_to_str, /* addr_to_str */
         ax25_addr_str_len,/* addr_str_len */
+        NULL,             /* addr_to_byte */
         ax25_col_filter_str, /* addr_col_filter */
         ax25_len,          /* addr_fixed_len */
         NULL,              /* addr_name_res_str */
         NULL,              /* addr_name_res_len */
     };
+    static address_type_t vines_address = {
+        AT_VINES,          /* addr_type */
+        "AT_VINES",        /* name */
+        "Banyan Vines Address",  /* pretty_name */
+        vines_addr_to_str, /* addr_to_str */
+        vines_addr_str_len,/* addr_str_len */
+        NULL,             /* addr_to_byte */
+        NULL,              /* addr_col_filter */
+        vines_len,         /* addr_fixed_len */
+        NULL,              /* addr_name_res_str */
+        NULL,              /* addr_name_res_len */
+    };
 
     num_dissector_addr_type = 0;
 
     /* Initialize the type array.  This is mostly for handling
        "dissector registered" address type range (for NULL checking) */
-    memset(type_list, 0, MAX_ADDR_TYPE_VALUE*sizeof(address_type_t*));
+    memset(type_list, 0, (MAX_ADDR_TYPE_VALUE + 1)*sizeof(address_type_t*));
 
     address_type_register(AT_NONE, &none_address );
     address_type_register(AT_ETHER, &ether_address );
     address_type_register(AT_IPv4, &ipv4_address );
     address_type_register(AT_IPv6, &ipv6_address );
     address_type_register(AT_IPX, &ipx_address );
-    address_type_register(AT_VINES, &vines_address );
     address_type_register(AT_FC, &fc_address );
     address_type_register(AT_FCWWN, &fcwwn_address );
-    address_type_register(AT_SS7PC, &ss7pc_address );
     address_type_register(AT_STRINGZ, &stringz_address );
     address_type_register(AT_EUI64, &eui64_address );
     address_type_register(AT_IB, &ib_address );
-    address_type_register(AT_USB, &usb_address );
     address_type_register(AT_AX25, &ax25_address );
+    address_type_register(AT_VINES, &vines_address );
 }
 
 /* Given an address type id, return an address_type_t* */
@@ -924,6 +740,86 @@ void address_to_str_buf(const address* addr, gchar *buf, int buf_len)
     at->addr_to_str(addr, buf, buf_len);
 }
 
+
+guint address_to_bytes(const address *addr, guint8 *buf, guint buf_len)
+{
+    address_type_t *at;
+    guint copy_len = 0;
+
+    if (!buf || !buf_len)
+        return 0;
+
+    ADDR_TYPE_LOOKUP(addr->type, at);
+
+    if (at == NULL)
+        return 0;
+
+    if (at->addr_to_byte == NULL)
+    {
+        /* If a specific function isn't provided, just do a memcpy */
+        copy_len = MIN(((guint)addr->len), buf_len);
+        memcpy(buf, addr->data, copy_len);
+    }
+    else
+    {
+        copy_len = at->addr_to_byte(addr, buf, buf_len);
+    }
+
+    return copy_len;
+}
+
+const gchar *
+address_to_name(const address *addr)
+{
+    address_type_t *at;
+
+    ADDR_TYPE_LOOKUP(addr->type, at);
+
+    if (at == NULL)
+    {
+        return NULL;
+    }
+
+    /*
+     * XXX - addr_name_res_str is expected to return a string from
+     * a persistent database, so that it lives a long time, past
+     * the lifetime of addr itself.
+     *
+     * We'd like to avoid copying, so this is what we do here.
+     */
+    switch (addr->type) {
+
+    case AT_STRINGZ:
+        return (const gchar *)addr->data;
+
+    default:
+        if (at->addr_name_res_str != NULL)
+            return at->addr_name_res_str(addr);
+        else
+            return NULL;
+    }
+}
+
+gchar *
+address_to_display(wmem_allocator_t *allocator, const address *addr)
+{
+    gchar *str = NULL;
+    const gchar *result = address_to_name(addr);
+
+    if (result != NULL) {
+        str = wmem_strdup(allocator, result);
+    }
+    else if (addr->type == AT_NONE) {
+        str = wmem_strdup(allocator, "NONE");
+    }
+    else {
+        str = (gchar *) wmem_alloc(allocator, MAX_ADDR_STR_LEN);
+        address_to_str_buf(addr, str, MAX_ADDR_STR_LEN);
+    }
+
+    return str;
+}
+
 static void address_with_resolution_to_str_buf(const address* addr, gchar *buf, int buf_len)
 {
     address_type_t *at;
@@ -953,11 +849,11 @@ static void address_with_resolution_to_str_buf(const address* addr, gchar *buf,
     /* Copy the resolved name */
     pos = g_strlcpy(buf, at->addr_name_res_str(addr), buf_len);
 
-    /* Don't wrap "emptyness" in parathesis */
+    /* Don't wrap "emptyness" in parentheses */
     if (addr->type == AT_NONE)
         return;
 
-    /* Make sure there is enough room for the address string wrapped in parathesis */
+    /* Make sure there is enough room for the address string wrapped in parentheses */
     if ((int)(pos + 4 + at->addr_str_len(addr)) >= buf_len)
         return;
 
@@ -969,8 +865,8 @@ static void address_with_resolution_to_str_buf(const address* addr, gchar *buf,
         buf[pos++] = '(';
     }
 
-    addr_len = at->addr_to_str(addr, &buf[pos], buf_len-pos);
-    pos += addr_len;
+    addr_len = at->addr_to_str(addr, &buf[pos], (int)(buf_len-pos));
+    pos += addr_len - 1; /* addr_len includes the trailing '\0' */
 
     if (!empty)
     {
@@ -991,8 +887,11 @@ gchar* address_with_resolution_to_str(wmem_allocator_t *scope, const address *ad
         return wmem_strdup(scope, "");
 
     /* No name resolution support, just return address string */
-    if (at->addr_name_res_str == NULL)
+    if ((at->addr_name_res_str == NULL) ||
+            (ADDR_RESOLV_MACADDR(addr) && !gbl_resolv_flags.mac_name) ||
+            (ADDR_RESOLV_NETADDR(addr) && !gbl_resolv_flags.network_name)) {
         return address_to_str(scope, addr);
+    }
 
     len = at->addr_name_res_len() + at->addr_str_len(addr) + 4; /* For format of %s (%s) */
 
@@ -1037,7 +936,7 @@ tvb_address_to_str(wmem_allocator_t *scope, tvbuff_t *tvb, int type, const gint
         return NULL;
     }
 
-    TVB_SET_ADDRESS(&addr, type, tvb, offset, at->addr_fixed_len());
+    set_address_tvb(&addr, type, at->addr_fixed_len(), tvb, offset);
 
     return address_to_str(scope, &addr);
 }
@@ -1046,11 +945,37 @@ gchar* tvb_address_var_to_str(wmem_allocator_t *scope, tvbuff_t *tvb, address_ty
 {
     address addr;
 
-    TVB_SET_ADDRESS(&addr, type, tvb, offset, length);
+    set_address_tvb(&addr, type, length, tvb, offset);
 
     return address_to_str(scope, &addr);
 }
 
+gchar*
+tvb_address_with_resolution_to_str(wmem_allocator_t *scope, tvbuff_t *tvb, int type, const gint offset)
+{
+    address addr;
+    address_type_t *at;
+
+    ADDR_TYPE_LOOKUP(type, at);
+
+    if (at == NULL)
+    {
+        return NULL;
+    }
+
+    /* The address type must have a fixed length to use this function */
+    /* For variable length fields, use tvb_address_var_with_resolution_to_str() */
+    if (at->addr_fixed_len == NULL)
+    {
+        g_assert_not_reached();
+        return NULL;
+    }
+
+    set_address_tvb(&addr, type, at->addr_fixed_len(), tvb, offset);
+
+    return address_with_resolution_to_str(scope, &addr);
+}
+
 
 /*
  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html