Use MAC address documentation range in filter examples
[metze/wireshark/wip.git] / epan / dissectors / packet-sna.c
index 09ba02c6e6041954f9ea6bedd7d2cacce075eec4..82bd620550988929069c9bf39bceb8fcd16bdf52 100644 (file)
 #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
@@ -303,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;
@@ -805,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*);
@@ -814,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
  * --------------------------------------------------------------------
@@ -1668,14 +1728,14 @@ dissect_fid0_1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        }
 
        /* Set DST addr */
-       TVB_SET_ADDRESS(&pinfo->net_dst, AT_SNA, tvb, 2, SNA_FID01_ADDR_LEN);
-       TVB_SET_ADDRESS(&pinfo->dst, AT_SNA, tvb, 2, SNA_FID01_ADDR_LEN);
+       TVB_SET_ADDRESS(&pinfo->net_dst, sna_address_type, tvb, 2, SNA_FID01_ADDR_LEN);
+       COPY_ADDRESS_SHALLOW(&pinfo->dst, &pinfo->net_dst);
 
        proto_tree_add_item(tree, hf_sna_th_oaf, tvb, 4, 2, ENC_BIG_ENDIAN);
 
        /* Set SRC addr */
-       TVB_SET_ADDRESS(&pinfo->net_src, AT_SNA, tvb, 4, SNA_FID01_ADDR_LEN);
-       TVB_SET_ADDRESS(&pinfo->src, AT_SNA, tvb, 4, SNA_FID01_ADDR_LEN);
+       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);
@@ -1720,15 +1780,15 @@ dissect_fid2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        }
 
        /* Set DST addr */
-       TVB_SET_ADDRESS(&pinfo->net_dst, AT_SNA, tvb, 2, SNA_FID2_ADDR_LEN);
-       TVB_SET_ADDRESS(&pinfo->dst, AT_SNA, tvb, 2, SNA_FID2_ADDR_LEN);
+       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 */
-       TVB_SET_ADDRESS(&pinfo->net_src, AT_SNA, tvb, 3, SNA_FID2_ADDR_LEN);
-       TVB_SET_ADDRESS(&pinfo->src, AT_SNA, tvb, 3, SNA_FID2_ADDR_LEN);
+       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);
@@ -1915,25 +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 = wmem_new(pinfo->pool, struct sna_fid_type_4_addr);
+       dst = wmem_new0(pinfo->pool, struct sna_fid_type_4_addr);
        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);
+       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 = wmem_new(pinfo->pool, struct sna_fid_type_4_addr);
+       src = wmem_new0(pinfo->pool, struct sna_fid_type_4_addr);
        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);
+       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);
@@ -2271,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;
@@ -2455,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)
@@ -3426,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",
@@ -3434,6 +3498,7 @@ proto_register_sna(void)
                &sna_defragment);
 
        register_init_routine(sna_init);
+       register_cleanup_routine(sna_cleanup);
 }
 
 void