Use MAC address documentation range in filter examples
[metze/wireshark/wip.git] / epan / dissectors / packet-sna.c
index b41f1e56fce4423110d39ed2ded0365be1e1ca93..82bd620550988929069c9bf39bceb8fcd16bdf52 100644 (file)
 
 #include "config.h"
 
-#include <glib.h>
 #include <epan/packet.h>
 #include <epan/llcsaps.h>
 #include <epan/ppptypes.h>
-#include <epan/sna-utils.h>
+#include <epan/address_types.h>
 #include <epan/prefs.h>
 #include <epan/reassemble.h>
+#include <epan/to_str-int.h>
+#include "wsutil/pint.h"
 
 /*
  * http://www.wanresources.com/snacell.html
@@ -304,6 +305,8 @@ static gint ett_sna_control_0e = -1;
 
 static dissector_handle_t data_handle;
 
+static int sna_address_type = -1;
+
 /* Defragment fragmented SNA BIUs*/
 static gboolean sna_defragment = TRUE;
 static reassembly_table sna_reassembly_table;
@@ -806,6 +809,17 @@ enum parse {
        KL
 };
 
+/*
+ * Structure used to represent an FID Type 4 address; gives the layout of the
+ * data pointed to by an AT_SNA "address" structure if the size is
+ * SNA_FID_TYPE_4_ADDR_LEN.
+ */
+#define        SNA_FID_TYPE_4_ADDR_LEN 6
+struct sna_fid_type_4_addr {
+       guint32 saf;
+       guint16 ef;
+};
+
 typedef enum next_dissection_enum next_dissection_t;
 
 static void dissect_xid (tvbuff_t*, packet_info*, proto_tree*, proto_tree*);
@@ -815,6 +829,51 @@ static void dissect_gds (tvbuff_t*, packet_info*, proto_tree*, proto_tree*);
 static void dissect_rh (tvbuff_t*, int, proto_tree*);
 static void dissect_control(tvbuff_t*, int, int, proto_tree*, int, enum parse);
 
+static int sna_fid_to_str_buf(const address *addr, gchar *buf, int buf_len _U_)
+{
+       const guint8 *addrdata;
+       struct sna_fid_type_4_addr sna_fid_type_4_addr;
+       gchar *bufp = buf;
+
+       switch (addr->len) {
+
+       case 1:
+               addrdata = (const guint8 *)addr->data;
+               word_to_hex(buf, addrdata[0]);
+               buf[4] = '\0';
+               break;
+
+       case 2:
+               addrdata = (const guint8 *)addr->data;
+               word_to_hex(buf, pntoh16(&addrdata[0]));
+               buf[4] = '\0';
+               break;
+
+       case SNA_FID_TYPE_4_ADDR_LEN:
+               /* FID Type 4 */
+               memcpy(&sna_fid_type_4_addr, addr->data, SNA_FID_TYPE_4_ADDR_LEN);
+
+               bufp = dword_to_hex(bufp, sna_fid_type_4_addr.saf);
+               *bufp++ = '.';
+               bufp = word_to_hex(bufp, sna_fid_type_4_addr.ef);
+               *bufp++ = '\0'; /* NULL terminate */
+               break;
+       default:
+               buf[0] = '\0';
+               return 1;
+       }
+
+       return (int)strlen(buf)+1;
+}
+
+
+static int sna_address_str_len(const address* addr _U_)
+{
+       /* We could do this based on address length, but 14 bytes isn't THAT much space */
+       return 14;
+}
+
+
 /* --------------------------------------------------------------------
  * Chapter 2 High-Performance Routing (HPR) Headers
  * --------------------------------------------------------------------
@@ -1647,7 +1706,6 @@ dissect_fid0_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        proto_tree      *bf_tree;
        proto_item      *bf_item;
        guint8          th_0;
-       const guint8    *ptr;
 
        const int bytes_in_header = 10;
 
@@ -1670,21 +1728,14 @@ dissect_fid0_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        }
 
        /* Set DST addr */
-       ptr = tvb_get_ptr(tvb, 2, SNA_FID01_ADDR_LEN);
-       SET_ADDRESS(&pinfo->net_dst, AT_SNA, SNA_FID01_ADDR_LEN, ptr);
-       SET_ADDRESS(&pinfo->dst, AT_SNA, SNA_FID01_ADDR_LEN, ptr);
+       TVB_SET_ADDRESS(&pinfo->net_dst, sna_address_type, tvb, 2, SNA_FID01_ADDR_LEN);
+       COPY_ADDRESS_SHALLOW(&pinfo->dst, &pinfo->net_dst);
 
-       if (tree)
-               proto_tree_add_item(tree, hf_sna_th_oaf, tvb, 4, 2, ENC_BIG_ENDIAN);
+       proto_tree_add_item(tree, hf_sna_th_oaf, tvb, 4, 2, ENC_BIG_ENDIAN);
 
        /* Set SRC addr */
-       ptr = tvb_get_ptr(tvb, 4, SNA_FID01_ADDR_LEN);
-       SET_ADDRESS(&pinfo->net_src, AT_SNA, SNA_FID01_ADDR_LEN, ptr);
-       SET_ADDRESS(&pinfo->src, AT_SNA, SNA_FID01_ADDR_LEN, ptr);
-
-       /* If we're not filling a proto_tree, return now */
-       if (tree)
-               return bytes_in_header;
+       TVB_SET_ADDRESS(&pinfo->net_src, sna_address_type, tvb, 4, SNA_FID01_ADDR_LEN);
+       COPY_ADDRESS_SHALLOW(&pinfo->src, &pinfo->net_src);
 
        proto_tree_add_item(tree, hf_sna_th_snf, tvb, 6, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(tree, hf_sna_th_dcf, tvb, 8, 2, ENC_BIG_ENDIAN);
@@ -1702,7 +1753,6 @@ dissect_fid2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        proto_tree      *bf_tree;
        proto_item      *bf_item;
        guint8          th_0;
-       const guint8    *ptr;
        unsigned int    mpf, id;
 
        const int bytes_in_header = 6;
@@ -1730,17 +1780,15 @@ dissect_fid2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        }
 
        /* Set DST addr */
-       ptr = tvb_get_ptr(tvb, 2, SNA_FID2_ADDR_LEN);
-       SET_ADDRESS(&pinfo->net_dst, AT_SNA, SNA_FID2_ADDR_LEN, ptr);
-       SET_ADDRESS(&pinfo->dst, AT_SNA, SNA_FID2_ADDR_LEN, ptr);
+       TVB_SET_ADDRESS(&pinfo->net_dst, sna_address_type, tvb, 2, SNA_FID2_ADDR_LEN);
+       COPY_ADDRESS_SHALLOW(&pinfo->dst, &pinfo->net_dst);
 
        /* Byte 3 */
        proto_tree_add_item(tree, hf_sna_th_oaf, tvb, 3, 1, ENC_BIG_ENDIAN);
 
        /* Set SRC addr */
-       ptr = tvb_get_ptr(tvb, 3, SNA_FID2_ADDR_LEN);
-       SET_ADDRESS(&pinfo->net_src, AT_SNA, SNA_FID2_ADDR_LEN, ptr);
-       SET_ADDRESS(&pinfo->src, AT_SNA, SNA_FID2_ADDR_LEN, ptr);
+       TVB_SET_ADDRESS(&pinfo->net_src, sna_address_type, tvb, 3, SNA_FID2_ADDR_LEN);
+       COPY_ADDRESS_SHALLOW(&pinfo->src, &pinfo->net_src);
 
        id = tvb_get_ntohs(tvb, 4);
        proto_tree_add_item(tree, hf_sna_th_snf, tvb, 4, 2, ENC_BIG_ENDIAN);
@@ -1855,7 +1903,7 @@ dissect_fid4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                NULL
        };
 
-       static struct sna_fid_type_4_addr src, dst; /* has to be static due to SET_ADDRESS */
+       struct sna_fid_type_4_addr *src, *dst;
 
        const int bytes_in_header = 26;
 
@@ -1927,23 +1975,21 @@ dissect_fid4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        proto_tree_add_uint(tree, hf_sna_th_def, tvb, offset, 2, def);
 
        /* Addresses in FID 4 are discontiguous, sigh */
-       dst.saf = dsaf;
-       dst.ef = def;
-       SET_ADDRESS(&pinfo->net_dst, AT_SNA, SNA_FID_TYPE_4_ADDR_LEN,
-           (guint8* )&dst);
-       SET_ADDRESS(&pinfo->dst, AT_SNA, SNA_FID_TYPE_4_ADDR_LEN,
-           (guint8 *)&dst);
+       dst = wmem_new0(pinfo->pool, struct sna_fid_type_4_addr);
+       dst->saf = dsaf;
+       dst->ef = def;
+       SET_ADDRESS(&pinfo->net_dst, sna_address_type, SNA_FID_TYPE_4_ADDR_LEN, dst);
+       COPY_ADDRESS_SHALLOW(&pinfo->dst, &pinfo->net_dst);
 
        oef = tvb_get_ntohs(tvb, 20);
        proto_tree_add_uint(tree, hf_sna_th_oef, tvb, offset+2, 2, oef);
 
        /* Addresses in FID 4 are discontiguous, sigh */
-       src.saf = osaf;
-       src.ef = oef;
-       SET_ADDRESS(&pinfo->net_src, AT_SNA, SNA_FID_TYPE_4_ADDR_LEN,
-           (guint8 *)&src);
-       SET_ADDRESS(&pinfo->src, AT_SNA, SNA_FID_TYPE_4_ADDR_LEN,
-           (guint8 *)&src);
+       src = wmem_new0(pinfo->pool, struct sna_fid_type_4_addr);
+       src->saf = osaf;
+       src->ef = oef;
+       SET_ADDRESS(&pinfo->net_src, sna_address_type, SNA_FID_TYPE_4_ADDR_LEN, src);
+       COPY_ADDRESS_SHALLOW(&pinfo->src, &pinfo->net_src);
 
        proto_tree_add_item(tree, hf_sna_th_snf, tvb, offset+4, 2, ENC_BIG_ENDIAN);
        proto_tree_add_item(tree, hf_sna_th_dcf, tvb, offset+6, 2, ENC_BIG_ENDIAN);
@@ -2281,7 +2327,7 @@ dissect_control(tvbuff_t *parent_tvb, int offset, int control_len,
        int             len, key;
        gint            ett;
 
-       length = tvb_length_remaining(parent_tvb, offset);
+       length = tvb_captured_length_remaining(parent_tvb, offset);
        reported_length = tvb_reported_length_remaining(parent_tvb, offset);
        if (control_len < length)
                length = control_len;
@@ -2465,6 +2511,12 @@ sna_init(void)
            &addresses_reassembly_table_functions);
 }
 
+static void
+sna_cleanup(void)
+{
+       reassembly_table_destroy(&sna_reassembly_table);
+}
+
 
 void
 proto_register_sna(void)
@@ -3436,6 +3488,8 @@ proto_register_sna(void)
            "Systems Network Architecture XID", "SNA XID", "sna_xid");
        register_dissector("sna_xid", dissect_sna_xid, proto_sna_xid);
 
+       sna_address_type = address_type_dissector_register("AT_SNA", "SNA Address", sna_fid_to_str_buf, sna_address_str_len, NULL, NULL, NULL, NULL);
+
        /* Register configuration options */
        sna_module = prefs_register_protocol(proto_sna, NULL);
        prefs_register_bool_preference(sna_module, "defragment",
@@ -3444,6 +3498,7 @@ proto_register_sna(void)
                &sna_defragment);
 
        register_init_routine(sna_init);
+       register_cleanup_routine(sna_cleanup);
 }
 
 void