From Didier Gautheron:
[obnox/wireshark/wip.git] / epan / dissectors / packet-s5066.c
index 466fbf3a83b093b57bb156def552ba8a76bd8fb2..3b07ce7cc6998937a103ba40a9dfe3a9ea4e97d2 100644 (file)
@@ -1,12 +1,12 @@
 /* packet-s5066.c
  * Routines for STANAG 5066 SIS layer packet disassembly
  *
- * $Id$
+ * $Id$
  *
  * Copyright (c) 2005 by Menno Andriesse <s5066 [AT] nc3a.nato.int>
  *
- * Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@ethereal.com>
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
  * Copyright 1999 Gerald Combs
  *
  * This program is free software; you can redistribute it and/or
 
 /* Forward reference */
 /* Register functions */
-void proto_register_s5066(void);
 void proto_reg_handoff_s5066(void);
 /* Main dissectors */
 static void dissect_s5066_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
-static guint get_s5066_pdu_len(tvbuff_t *tvb, int offset);
+static guint get_s5066_pdu_len(packet_info *pinfo, tvbuff_t *tvb, int offset);
 static void dissect_s5066_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
 /* Service type and address dissectors */
 static guint dissect_s5066_servicetype(tvbuff_t *tvb, guint offset, proto_tree *tree);
@@ -74,7 +73,6 @@ static guint dissect_s5066_26(tvbuff_t *tvb, guint offset, proto_tree *tree);
 static guint dissect_s5066_27(tvbuff_t *tvb, guint offset, proto_tree *tree);
 
 static gint proto_s5066 = -1;
-static dissector_handle_t s5066_tcp_handle;
 static dissector_handle_t data_handle;
 
 /* Enable desegmentation of S5066 over TCP */
@@ -82,7 +80,7 @@ static gboolean s5066_desegment = TRUE;
 /* Dissect old 'edition 1' of STANAG 5066 (It lacks the 'version' field.) */
 static gboolean s5066_edition_one = FALSE;
 /* This port is registered with IANA */
-static gint global_s5066_port = 5066; 
+static guint global_s5066_port = 5066;
 /* Size of header outside 'size' field */
 static gint s5066_header_size = 5;
 /* Offset of 'size' field */
@@ -131,19 +129,19 @@ static const value_string s5066_pdu_type[] = {
 /* STANAG 5066 Address */
 /* Size is defined in nibbles (4 bits) */
 static gint hf_s5066_ad_size = -1;
-/* Group flag: 0 = false, 1 = true */ 
-static gint hf_s5066_ad_group = -1; 
+/* Group flag: 0 = false, 1 = true */
+static gint hf_s5066_ad_group = -1;
 /* The remainder of the 4 bytes form the address */
-static gint hf_s5066_ad_address = -1; 
+static gint hf_s5066_ad_address = -1;
 
 /* Service type */
 /* Transmission mode: */
-static gint hf_s5066_st_txmode = -1; 
+static gint hf_s5066_st_txmode = -1;
 static const value_string s5066_st_txmode[] = {
        { 0, "Ignore service type field"},
        { 1, "ARQ"},
-       { 2, "Non-ARQ (Broacast)"},
-       { 3, "Other non-ARQ types"},
+       { 2, "Non-ARQ (Broadcast)"},
+       { 3, "Non-ARQ (with errors)"},
        { 4, "Other non-ARQ types"},
        { 5, "Other non-ARQ types"},
        { 6, "Other non-ARQ types"},
@@ -159,7 +157,7 @@ static const value_string s5066_st_txmode[] = {
        { 0, NULL },
 };
 /* Delivery confirmation: */
-static gint hf_s5066_st_delivery_confirmation = -1; 
+static gint hf_s5066_st_delivery_confirmation = -1;
 static const value_string s5066_st_delivery_confirmation[] = {
        { 0, "No confirmation"},
        { 1, "Node delivery confirmation"},
@@ -168,21 +166,21 @@ static const value_string s5066_st_delivery_confirmation[] = {
        { 0, NULL },
 };
 /* Delivery order: */
-static gint hf_s5066_st_delivery_order = -1; 
+static gint hf_s5066_st_delivery_order = -1;
 static const value_string s5066_st_delivery_order[] = {
        { 0, "In-order delivery"},
        { 1, "As-they-arrive"},
        { 0, NULL },
 };
 /* Extended field present: (Never in the current version.) */
-static gint hf_s5066_st_extended = -1; 
+static gint hf_s5066_st_extended = -1;
 static const value_string s5066_st_extended[] = {
        { 0, "No extended field"},
        { 1, "Extended field follows"},
        { 0, NULL },
 };
 /* Number of retransmissions when in Non-ARQ: */
-static gint hf_s5066_st_retries = -1; 
+static gint hf_s5066_st_retries = -1;
 
 /* Type  1: S_BIND_REQUEST */
 static gint hf_s5066_01_sapid = -1;
@@ -333,7 +331,7 @@ static const value_string s5066_14_reason[] = {
 
 /* Type 18: S_MANAGEMENT_MESSAGE_REQUEST */
 static gint hf_s5066_18_type = -1;
-static gint hf_s5066_18_body = -1; 
+static gint hf_s5066_18_body = -1;
 
 /* Type 19: S_MANAGEMENT_MESSAGE_INDICATION */
 static gint hf_s5066_19_type = -1;
@@ -346,15 +344,17 @@ static gint hf_s5066_20_ttl = -1;
 static gint hf_s5066_20_size = -1;
 
 /* Type 21: S_UNIDATA_INDICATION */
-/* TODO: handle RockwellCollins (v2.1 and earlier) 4-byte offset. */
-/* TODO: handle NON-ARQ With Errors case. */
 static gint hf_s5066_21_priority = -1;
 static gint hf_s5066_21_dest_sapid = -1;
 static gint hf_s5066_21_tx_mode = -1;
 static gint hf_s5066_21_src_sapid = -1;
 static gint hf_s5066_21_size = -1;
 static gint hf_s5066_21_err_blocks = -1;
-static gint hf_s5066_21_nrx_blocks = -1; 
+static gint hf_s5066_21_err_ptr = -1;
+static gint hf_s5066_21_err_size = -1;
+static gint hf_s5066_21_nrx_blocks = -1;
+static gint hf_s5066_21_nrx_ptr = -1;
+static gint hf_s5066_21_nrx_size = -1;
 
 
 /* Type 22: S_UNIDATA_REQUEST_CONFIRM */
@@ -385,15 +385,17 @@ static gint hf_s5066_24_ttl = -1;
 static gint hf_s5066_24_size = -1;
 
 /* Type 25: S_EXPEDITED_UNIDATA_INDICATION */
-/* TODO: handle RockwellCollins (v2.1 and earlier) 4-byte offset. */
-/* TODO: handle NON-ARQ With Errors case. */
 static gint hf_s5066_25_unused = -1;
 static gint hf_s5066_25_dest_sapid = -1;
 static gint hf_s5066_25_tx_mode = -1;
 static gint hf_s5066_25_src_sapid = -1;
 static gint hf_s5066_25_size = -1;
 static gint hf_s5066_25_err_blocks = -1;
-static gint hf_s5066_25_nrx_blocks = -1; 
+static gint hf_s5066_25_err_ptr = -1;
+static gint hf_s5066_25_err_size = -1;
+static gint hf_s5066_25_nrx_blocks = -1;
+static gint hf_s5066_25_nrx_ptr = -1;
+static gint hf_s5066_25_nrx_size = -1;
 
 /* Type 26: S_EXPEDITED_UNIDATA_REQUEST_CONFIRM */
 static gint hf_s5066_26_unused = -1;
@@ -427,166 +429,166 @@ proto_register_s5066(void)
 {
        static hf_register_info hf[] = {
                { &hf_s5066_sync_word,
-                       { "Sync preample", "s5066.sync", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }
+                       { "Sync preamble", "s5066.sync", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
                },
                { &hf_s5066_version,
-                       { "S5066 version", "s5066.version", FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL }
+                       { "S5066 version", "s5066.version", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }
                },
                { &hf_s5066_size,
-                       { "S_Primitive size", "s5066.size", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
+                       { "S_Primitive size", "s5066.size", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
                },
                { &hf_s5066_type,
-                       { "PDU Type", "s5066.type", FT_UINT8, BASE_DEC, VALS(s5066_pdu_type), 0x0, "", HFILL }
+                       { "PDU Type", "s5066.type", FT_UINT8, BASE_DEC, VALS(s5066_pdu_type), 0x0, NULL, HFILL }
                },
                /* STANAG 5066 Address */
                { &hf_s5066_ad_size,
-                       { "Address size (1/2 Bytes)", "s5066.address.size", FT_UINT8, BASE_HEX, NULL, 0xE0, "", HFILL }
+                       { "Address size (1/2 Bytes)", "s5066.address.size", FT_UINT8, BASE_HEX, NULL, 0xE0, NULL, HFILL }
                },
                { &hf_s5066_ad_group,
-                       { "Group address", "s5066.address.group", FT_UINT8, BASE_HEX, NULL, 0x10, "", HFILL }
+                       { "Group address", "s5066.address.group", FT_UINT8, BASE_HEX, NULL, 0x10, NULL, HFILL }
                },
                { &hf_s5066_ad_address,
-                       { "Address", "s5066.address.address", FT_IPv4, BASE_NONE, NULL, 0x1FFFFFFF, "", HFILL }
+                       { "Address", "s5066.address.address", FT_IPv4, BASE_NONE, NULL, 0, NULL, HFILL }
                },
                /* Service type */
                { &hf_s5066_st_txmode,
-                       { "Transmission mode", "s5066.st.txmode", FT_UINT8, BASE_HEX, VALS(s5066_st_txmode), 0xF0, "", HFILL }
+                       { "Transmission mode", "s5066.st.txmode", FT_UINT8, BASE_HEX, VALS(s5066_st_txmode), 0xF0, NULL, HFILL }
                },
                { &hf_s5066_st_delivery_confirmation,
-                       { "Delivery confirmation", "s5066.st.confirm", FT_UINT8, BASE_HEX, VALS(s5066_st_delivery_confirmation),  0x0C, "", HFILL }
+                       { "Delivery confirmation", "s5066.st.confirm", FT_UINT8, BASE_HEX, VALS(s5066_st_delivery_confirmation),  0x0C, NULL, HFILL }
                },
                { &hf_s5066_st_delivery_order,
-                       { "Delivery order", "s5066.st.order", FT_UINT8, BASE_HEX, VALS(s5066_st_delivery_order), 0x02, "", HFILL }
+                       { "Delivery order", "s5066.st.order", FT_UINT8, BASE_HEX, VALS(s5066_st_delivery_order), 0x02, NULL, HFILL }
                },
                { &hf_s5066_st_extended,
-                       { "Extended field", "s5066.st.extended", FT_UINT8, BASE_HEX, VALS(s5066_st_extended), 0x01, "", HFILL }
+                       { "Extended field", "s5066.st.extended", FT_UINT8, BASE_HEX, VALS(s5066_st_extended), 0x01, NULL, HFILL }
                },
                { &hf_s5066_st_retries,
-                       { "Minimum number of retransmissions", "s5066.st.retries", FT_UINT8, BASE_DEC, NULL, 0xF0, "", HFILL }
+                       { "Minimum number of retransmissions", "s5066.st.retries", FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }
                },
                /* PDU Type 01: S_BIND_REQUEST */
                { &hf_s5066_01_sapid,
-                       { "Sap ID", "s5066.01.sapid", FT_UINT8, BASE_DEC, NULL, 0xF0, "", HFILL }
+                       { "Sap ID", "s5066.01.sapid", FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }
                },
                { &hf_s5066_01_rank,
-                       { "Rank", "s5066.01.rank", FT_UINT8, BASE_DEC, NULL, 0x0F, "", HFILL }
+                       { "Rank", "s5066.01.rank", FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL }
                },
                { &hf_s5066_01_unused,
-                       { "(Unused)", "s5066.01.unused", FT_UINT8, BASE_HEX, NULL, 0x0F, "", HFILL }
+                       { "(Unused)", "s5066.01.unused", FT_UINT8, BASE_HEX, NULL, 0x0F, NULL, HFILL }
                },
                /* PDU Type 02: S_UNBIND_REQUEST */
                /*     --- no subfields ---     */
                /* PDU Type 03: S_BIND_ACCEPTED */
                { &hf_s5066_03_sapid,
-                       { "Sap ID", "s5066.03.sapid", FT_UINT8, BASE_DEC, NULL, 0xF0, "", HFILL }
+                       { "Sap ID", "s5066.03.sapid", FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }
                },
                { &hf_s5066_03_unused,
-                       { "(Unused)", "s5066.03.unused", FT_UINT8, BASE_HEX, NULL, 0x0F, "", HFILL }
+                       { "(Unused)", "s5066.03.unused", FT_UINT8, BASE_HEX, NULL, 0x0F, NULL, HFILL }
                },
                { &hf_s5066_03_mtu,
-                       { "MTU", "s5066.03.mtu", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
+                       { "MTU", "s5066.03.mtu", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
                },
                /* PDU Type 04: S_BIND_REJECTED */
                { &hf_s5066_04_reason,
-                       { "Reason", "s5066.04.reason", FT_UINT8, BASE_DEC, VALS(s5066_04_reason), 0x0, "", HFILL }
+                       { "Reason", "s5066.04.reason", FT_UINT8, BASE_DEC, VALS(s5066_04_reason), 0x0, NULL, HFILL }
                },
                /* PDU Type 05: S_UNBIND_INDICATION */
                { &hf_s5066_05_reason,
-                       { "Reason", "s5066.05.reason", FT_UINT8, BASE_DEC, VALS(s5066_05_reason), 0x0, "", HFILL }
+                       { "Reason", "s5066.05.reason", FT_UINT8, BASE_DEC, VALS(s5066_05_reason), 0x0, NULL, HFILL }
                },
                /* Type  6: S_HARD_LINK_ESTABLISH */
                { &hf_s5066_06_link_type,
-                       { "Hardlink type", "s5066.06.type", FT_UINT8, BASE_DEC, VALS(s5066_hard_link_type), 0xC0, "", HFILL }
+                       { "Hardlink type", "s5066.06.type", FT_UINT8, BASE_DEC, VALS(s5066_hard_link_type), 0xC0, NULL, HFILL }
                },
                { &hf_s5066_06_link_priority,
-                       { "Priority", "s5066.06.priority", FT_UINT8, BASE_DEC, NULL, 0x30, "", HFILL }
+                       { "Priority", "s5066.06.priority", FT_UINT8, BASE_DEC, NULL, 0x30, NULL, HFILL }
                },
                { &hf_s5066_06_sapid,
-                       { "Remote Sap ID", "s5066.06.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, "", HFILL }
+                       { "Remote Sap ID", "s5066.06.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL }
                },
                /* Type  7: S_HARD_LINK_TERMINATE */
                /* --- Only remote node address --- */
                /* Type  8: S_HARD_LINK_ESTABLISHED */
                { &hf_s5066_08_remote_status,
-                       { "Remote node status", "s5066.08.status", FT_UINT8, BASE_DEC, VALS(s5066_08_remote_status), 0x0, "", HFILL }
+                       { "Remote node status", "s5066.08.status", FT_UINT8, BASE_DEC, VALS(s5066_08_remote_status), 0x0, NULL, HFILL }
                },
                { &hf_s5066_08_link_type,
-                       { "Hardlink type", "s5066.08.type", FT_UINT8, BASE_DEC, VALS(s5066_hard_link_type), 0xC0, "", HFILL }
+                       { "Hardlink type", "s5066.08.type", FT_UINT8, BASE_DEC, VALS(s5066_hard_link_type), 0xC0, NULL, HFILL }
                },
                { &hf_s5066_08_link_priority,
-                       { "Priority", "s5066.08.priority", FT_UINT8, BASE_DEC, NULL, 0x30, "", HFILL }
+                       { "Priority", "s5066.08.priority", FT_UINT8, BASE_DEC, NULL, 0x30, NULL, HFILL }
                },
                { &hf_s5066_08_sapid,
-                       { "Remote Sap ID", "s5066.08.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, "", HFILL }
+                       { "Remote Sap ID", "s5066.08.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL }
                },
                /* Type  9: S_HARD_LINK_REJECTED */
                { &hf_s5066_09_reason,
-                       { "Reason", "s5066.09.reason", FT_UINT8, BASE_DEC, VALS(s5066_09_reason), 0x0, "", HFILL }
+                       { "Reason", "s5066.09.reason", FT_UINT8, BASE_DEC, VALS(s5066_09_reason), 0x0, NULL, HFILL }
                },
                { &hf_s5066_09_link_type,
-                       { "Hardlink type", "s5066.09.type", FT_UINT8, BASE_DEC, VALS(s5066_hard_link_type), 0xC0, "", HFILL }
+                       { "Hardlink type", "s5066.09.type", FT_UINT8, BASE_DEC, VALS(s5066_hard_link_type), 0xC0, NULL, HFILL }
                },
                { &hf_s5066_09_link_priority,
-                       { "Priority", "s5066.09.priority", FT_UINT8, BASE_DEC, NULL, 0x30, "", HFILL }
+                       { "Priority", "s5066.09.priority", FT_UINT8, BASE_DEC, NULL, 0x30, NULL, HFILL }
                },
                { &hf_s5066_09_sapid,
-                       { "Remote Sap ID", "s5066.09.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, "", HFILL }
+                       { "Remote Sap ID", "s5066.09.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL }
                },
                /* Type 10: S_HARD_LINK_TERMINATED */
                { &hf_s5066_10_reason,
-                       { "Reason", "s5066.10.reason", FT_UINT8, BASE_DEC, VALS(s5066_10_reason), 0x0, "", HFILL }
+                       { "Reason", "s5066.10.reason", FT_UINT8, BASE_DEC, VALS(s5066_10_reason), 0x0, NULL, HFILL }
                },
                { &hf_s5066_10_link_type,
-                       { "Hardlink type", "s5066.10.type", FT_UINT8, BASE_DEC, VALS(s5066_hard_link_type), 0xC0, "", HFILL }
+                       { "Hardlink type", "s5066.10.type", FT_UINT8, BASE_DEC, VALS(s5066_hard_link_type), 0xC0, NULL, HFILL }
                },
                { &hf_s5066_10_link_priority,
-                       { "Priority", "s5066.10.priority", FT_UINT8, BASE_DEC, NULL, 0x30, "", HFILL }
+                       { "Priority", "s5066.10.priority", FT_UINT8, BASE_DEC, NULL, 0x30, NULL, HFILL }
                },
                { &hf_s5066_10_sapid,
-                       { "Remote Sap ID", "s5066.10.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, "", HFILL }
+                       { "Remote Sap ID", "s5066.10.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL }
                },
                /* Type 11: S_HARD_LINK_INDICATION */
                { &hf_s5066_11_remote_status,
-                       { "Remote node status", "s5066.11.status", FT_UINT8, BASE_DEC, VALS(s5066_11_remote_status), 0x0, "", HFILL }
+                       { "Remote node status", "s5066.11.status", FT_UINT8, BASE_DEC, VALS(s5066_11_remote_status), 0x0, NULL, HFILL }
                },
                { &hf_s5066_11_link_type,
-                       { "Hardlink type", "s5066.11.type", FT_UINT8, BASE_DEC, VALS(s5066_hard_link_type), 0xC0, "", HFILL }
+                       { "Hardlink type", "s5066.11.type", FT_UINT8, BASE_DEC, VALS(s5066_hard_link_type), 0xC0, NULL, HFILL }
                },
                { &hf_s5066_11_link_priority,
-                       { "Priority", "s5066.11.priority", FT_UINT8, BASE_DEC, NULL, 0x30, "", HFILL }
+                       { "Priority", "s5066.11.priority", FT_UINT8, BASE_DEC, NULL, 0x30, NULL, HFILL }
                },
                { &hf_s5066_11_sapid,
-                       { "Remote Sap ID", "s5066.11.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, "", HFILL }
+                       { "Remote Sap ID", "s5066.11.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL }
                },
                /* Type 12: S_HARD_LINK_ACCEPT */
                { &hf_s5066_12_link_type,
-                       { "Hardlink type", "s5066.12.type", FT_UINT8, BASE_DEC, VALS(s5066_hard_link_type), 0xC0, "", HFILL }
+                       { "Hardlink type", "s5066.12.type", FT_UINT8, BASE_DEC, VALS(s5066_hard_link_type), 0xC0, NULL, HFILL }
                },
                { &hf_s5066_12_link_priority,
-                       { "Priority", "s5066.12.priority", FT_UINT8, BASE_DEC, NULL, 0x30, "", HFILL }
+                       { "Priority", "s5066.12.priority", FT_UINT8, BASE_DEC, NULL, 0x30, NULL, HFILL }
                },
                { &hf_s5066_12_sapid,
-                       { "Remote Sap ID", "s5066.12.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, "", HFILL }
+                       { "Remote Sap ID", "s5066.12.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL }
                },
                /* Type 13: S_HARD_LINK_REJECT */
                { &hf_s5066_13_reason,
-                       { "Reason", "s5066.13.reason", FT_UINT8, BASE_DEC, VALS(s5066_13_reason), 0x0, "", HFILL }
+                       { "Reason", "s5066.13.reason", FT_UINT8, BASE_DEC, VALS(s5066_13_reason), 0x0, NULL, HFILL }
                },
                { &hf_s5066_13_link_type,
-                       { "Hardlink type", "s5066.13.type", FT_UINT8, BASE_DEC, VALS(s5066_hard_link_type), 0xC0, "", HFILL }
+                       { "Hardlink type", "s5066.13.type", FT_UINT8, BASE_DEC, VALS(s5066_hard_link_type), 0xC0, NULL, HFILL }
                },
                { &hf_s5066_13_link_priority,
-                       { "Priority", "s5066.13.priority", FT_UINT8, BASE_DEC, NULL, 0x30, "", HFILL }
+                       { "Priority", "s5066.13.priority", FT_UINT8, BASE_DEC, NULL, 0x30, NULL, HFILL }
                },
                { &hf_s5066_13_sapid,
-                       { "Remote Sap ID", "s5066.13.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, "", HFILL }
+                       { "Remote Sap ID", "s5066.13.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL }
                },
                /* Type 14: S_SUBNET_AVAILABILITY */
                { &hf_s5066_14_status,
-                       { "Status", "s5066.14.status", FT_UINT8, BASE_DEC, VALS(s5066_14_status), 0x0, "", HFILL }
+                       { "Status", "s5066.14.status", FT_UINT8, BASE_DEC, VALS(s5066_14_status), 0x0, NULL, HFILL }
                },
                { &hf_s5066_14_reason,
-                       { "Reason", "s5066.14.reason", FT_UINT8, BASE_DEC, VALS(s5066_14_reason), 0x0, "", HFILL }
+                       { "Reason", "s5066.14.reason", FT_UINT8, BASE_DEC, VALS(s5066_14_reason), 0x0, NULL, HFILL }
                },
                /* Type 15: S_DATAFLOW_ON */
                /*   --- no subfields ---   */
@@ -596,139 +598,163 @@ proto_register_s5066(void)
                /*   --- no subfields ---   */
                /* Type 18: S_MANAGEMENT_MESSAGE_REQUEST */
                { &hf_s5066_18_type,
-                       { "Message Type", "s5066.18.type", FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL }
+                       { "Message Type", "s5066.18.type", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }
                },
                { &hf_s5066_18_body,
-                       { "Message Body", "s5066.18.body", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }
+                       { "Message Body", "s5066.18.body", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
                },
                /* Type 19: S_MANAGEMENT_MESSAGE_INDICATION */
                { &hf_s5066_19_type,
-                       { "Message Type", "s5066.19.type", FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL }
+                       { "Message Type", "s5066.19.type", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }
                },
                { &hf_s5066_19_body,
-                       { "Message Body", "s5066.19.body", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }
+                       { "Message Body", "s5066.19.body", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
                },
                /* Type 20: S_UNIDATA_REQUEST */
                { &hf_s5066_20_priority,
-                       { "Priority", "s5066.20.priority", FT_UINT8, BASE_DEC, NULL, 0xF0, "", HFILL }
+                       { "Priority", "s5066.20.priority", FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }
                },
                { &hf_s5066_20_sapid,
-                       { "Destination Sap ID", "s5066.20.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, "", HFILL }
+                       { "Destination Sap ID", "s5066.20.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL }
                },
                { &hf_s5066_20_ttl,
-                       { "Time-To-Live (x2 seconds)", "s5066.20.ttl", FT_UINT24, BASE_DEC, NULL, 0x0FFFFF, "", HFILL }
+                       { "Time-To-Live (x2 seconds)", "s5066.20.ttl", FT_UINT24, BASE_DEC, NULL, 0x0FFFFF, NULL, HFILL }
                },
                { &hf_s5066_20_size,
-                       { "U_PDU Size", "s5066.20.size", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
+                       { "U_PDU Size", "s5066.20.size", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
                },
                /* Type 21: S_UNIDATA_INDICATION */
                { &hf_s5066_21_priority,
-                       { "Priority", "s5066.21.priority", FT_UINT8, BASE_DEC, NULL, 0xF0, "", HFILL }
+                       { "Priority", "s5066.21.priority", FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }
                },
                { &hf_s5066_21_dest_sapid,
-                       { "Destination Sap ID", "s5066.21.dest_sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, "", HFILL }
+                       { "Destination Sap ID", "s5066.21.dest_sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL }
                },
                { &hf_s5066_21_tx_mode,
-                       { "Transmission Mode", "s5066.21.txmode", FT_UINT8, BASE_HEX, VALS(s5066_st_txmode), 0xF0, "", HFILL }
+                       { "Transmission Mode", "s5066.21.txmode", FT_UINT8, BASE_HEX, VALS(s5066_st_txmode), 0xF0, NULL, HFILL }
                },
                { &hf_s5066_21_src_sapid,
-                       { "Source Sap ID", "s5066.21.src_sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, "", HFILL }
+                       { "Source Sap ID", "s5066.21.src_sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL }
                },
                { &hf_s5066_21_size,
-                       { "U_PDU Size", "s5066.21.size", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
+                       { "U_PDU Size", "s5066.21.size", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
                },
                { &hf_s5066_21_err_blocks,
-                       { "Number of errored blocks", "s5066.21.err_blocks", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
+                       { "Number of errored blocks", "s5066.21.err_blocks", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
+               },
+               { &hf_s5066_21_err_ptr,
+                       { "Pointer to error block", "s5066.21.err_ptr", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
+               },
+               { &hf_s5066_21_err_size,
+                       { "Size of error block", "s5066.21.err_size", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
                },
                { &hf_s5066_21_nrx_blocks,
-                       { "Number of non-received blocks", "s5066.21.nrx_blocks", FT_UINT16, BASE_DEC, NULL, 0x0F, "", HFILL }
+                       { "Number of non-received blocks", "s5066.21.nrx_blocks", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
+               },
+               { &hf_s5066_21_nrx_ptr,
+                       { "Pointer to non-received block", "s5066.21.nrx_ptr", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
+               },
+               { &hf_s5066_21_nrx_size,
+                       { "Size of non-received block", "s5066.21.nrx_size", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
                },
                /* Type 22: S_UNIDATA_REQUEST_CONFIRM */
                { &hf_s5066_22_unused,
-                       { "(Unused)", "s5066.22.unused", FT_UINT8, BASE_DEC, NULL, 0xF0, "", HFILL }
+                       { "(Unused)", "s5066.22.unused", FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }
                },
                { &hf_s5066_22_sapid,
-                       { "Destination Sap ID", "s5066.22.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, "", HFILL }
+                       { "Destination Sap ID", "s5066.22.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL }
                },
                { &hf_s5066_22_size,
-                       { "U_PDU Size", "s5066.22.size", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
+                       { "U_PDU Size", "s5066.22.size", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
                },
                { &hf_s5066_22_data,
-                       { "(Part of) Confirmed data", "s5066.22.data", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }
+                       { "(Part of) Confirmed data", "s5066.22.data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
                },
                /* Type 23: S_UNIDATA_REQUEST_REJECTED */
                { &hf_s5066_23_reason,
-                       { "Reason", "s5066.23.reason", FT_UINT8, BASE_DEC, VALS(s5066_23_reason), 0xF0, "", HFILL }
+                       { "Reason", "s5066.23.reason", FT_UINT8, BASE_DEC, VALS(s5066_23_reason), 0xF0, NULL, HFILL }
                },
                { &hf_s5066_23_sapid,
-                       { "Destination Sap ID", "s5066.23.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, "", HFILL }
+                       { "Destination Sap ID", "s5066.23.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL }
                },
                { &hf_s5066_23_size,
-                       { "U_PDU Size", "s5066.23.size", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
+                       { "U_PDU Size", "s5066.23.size", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
                },
                { &hf_s5066_23_data,
-                       { "(Part of) Rejected data", "s5066.23.data", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }
+                       { "(Part of) Rejected data", "s5066.23.data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
                },
                /* Type 24: S_EXPEDITED_UNIDATA_REQUEST */
                { &hf_s5066_24_unused,
-                       { "(Unused)", "s5066.24.unused", FT_UINT8, BASE_DEC, NULL, 0xF0, "", HFILL }
+                       { "(Unused)", "s5066.24.unused", FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }
                },
                { &hf_s5066_24_sapid,
-                       { "Destination Sap ID", "s5066.24.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, "", HFILL }
+                       { "Destination Sap ID", "s5066.24.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL }
                },
                { &hf_s5066_24_ttl,
-                       { "Time-To-Live (x2 seconds)", "s5066.24.ttl", FT_UINT24, BASE_DEC, NULL, 0x0FFFFF, "", HFILL }
+                       { "Time-To-Live (x2 seconds)", "s5066.24.ttl", FT_UINT24, BASE_DEC, NULL, 0x0FFFFF, NULL, HFILL }
                },
                { &hf_s5066_24_size,
-                       { "U_PDU Size", "s5066.24.size", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
+                       { "U_PDU Size", "s5066.24.size", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
                },
                /* Type 25: S_EXPEDITED_UNIDATA_INDICATION */
                { &hf_s5066_25_unused,
-                       { "(Unused)", "s5066.25.unused", FT_UINT8, BASE_DEC, NULL, 0xF0, "", HFILL }
+                       { "(Unused)", "s5066.25.unused", FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }
                },
-               { &hf_s5066_25_dest_sapid, 
-                       { "Destination Sap ID", "s5066.25.dest_sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, "", HFILL }
+               { &hf_s5066_25_dest_sapid,
+                       { "Destination Sap ID", "s5066.25.dest_sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL }
                },
                { &hf_s5066_25_tx_mode,
-                       { "Transmission Mode", "s5066.25.txmode", FT_UINT8, BASE_HEX, VALS(s5066_st_txmode), 0xF0, "", HFILL }
+                       { "Transmission Mode", "s5066.25.txmode", FT_UINT8, BASE_HEX, VALS(s5066_st_txmode), 0xF0, NULL, HFILL }
                },
                { &hf_s5066_25_src_sapid,
-                       { "Source Sap ID", "s5066.25.src_sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, "", HFILL }
+                       { "Source Sap ID", "s5066.25.src_sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL }
                },
                { &hf_s5066_25_size,
-                       { "U_PDU Size", "s5066.25.size", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
+                       { "U_PDU Size", "s5066.25.size", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
                },
                { &hf_s5066_25_err_blocks,
-                       { "Number of errored blocks", "s5066.25.err_blocks", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
+                       { "Number of errored blocks", "s5066.25.err_blocks", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
+               },
+               { &hf_s5066_25_err_ptr,
+                       { "Pointer to error block", "s5066.25.err_ptr", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
+               },
+               { &hf_s5066_25_err_size,
+                       { "Size of error block", "s5066.25.err_size", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
                },
                { &hf_s5066_25_nrx_blocks,
-                       { "Number of non-received blocks", "s5066.25.nrx_blocks", FT_UINT16, BASE_DEC, NULL, 0x0F, "", HFILL }
+                       { "Number of non-received blocks", "s5066.25.nrx_blocks", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
+               },
+               { &hf_s5066_25_nrx_ptr,
+                       { "Pointer to non-received block", "s5066.25.nrx_ptr", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }
+               },
+               { &hf_s5066_25_nrx_size,
+                       { "Size of non-received block", "s5066.25.nrx_size", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
                },
                /* Type 26: S_EXPEDITED_UNIDATA_REQUEST_CONFIRM */
                { &hf_s5066_26_unused,
-                       { "(Unused)", "s5066.26.unused", FT_UINT8, BASE_DEC, NULL, 0xF0, "", HFILL }
+                       { "(Unused)", "s5066.26.unused", FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }
                },
                { &hf_s5066_26_sapid,
-                       { "Destination Sap ID", "s5066.26.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, "", HFILL }
+                       { "Destination Sap ID", "s5066.26.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL }
                },
                { &hf_s5066_26_size,
-                       { "U_PDU Size", "s5066.26.size", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
+                       { "U_PDU Size", "s5066.26.size", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
                },
                { &hf_s5066_26_data,
-                       { "(Part of) Confirmed data", "s5066.26.data", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }
+                       { "(Part of) Confirmed data", "s5066.26.data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
                },
                /* Type 27: S_EXPEDITED_UNIDATA_REQUEST_REJECTED */
                { &hf_s5066_27_reason,
-                       { "Reason", "s5066.27.reason", FT_UINT8, BASE_DEC, VALS(s5066_27_reason), 0xF0, "", HFILL }
+                       { "Reason", "s5066.27.reason", FT_UINT8, BASE_DEC, VALS(s5066_27_reason), 0xF0, NULL, HFILL }
                },
                { &hf_s5066_27_sapid,
-                       { "Destination Sap ID", "s5066.27.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, "", HFILL }
+                       { "Destination Sap ID", "s5066.27.sapid", FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL }
                },
                { &hf_s5066_27_size,
-                       { "U_PDU Size", "s5066.27.size", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }
+                       { "U_PDU Size", "s5066.27.size", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
                },
                { &hf_s5066_27_data,
-                       { "(Part of) Rejected data", "s5066.27.data", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }
+                       { "(Part of) Rejected data", "s5066.27.data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }
                },
 
        };
@@ -743,42 +769,50 @@ proto_register_s5066(void)
 
        module_t *s5066_module;
 
-       if (proto_s5066 == -1) {
-               proto_s5066 = proto_register_protocol (
+       proto_s5066 = proto_register_protocol (
                        "STANAG 5066 (SIS layer)",      /* name */
                        "STANAG 5066",                  /* short name*/
                        "s5066"                         /* abbrev */
                );
-               proto_register_field_array(proto_s5066, hf, array_length(hf));  
-               proto_register_subtree_array(ett, array_length(ett));
-       }
+       proto_register_field_array(proto_s5066, hf, array_length(hf));
+       proto_register_subtree_array(ett, array_length(ett));
 
        s5066_module = prefs_register_protocol(proto_s5066, proto_reg_handoff_s5066);
        prefs_register_bool_preference(s5066_module, "desegment_pdus",
-               "Reassemble S5066 PDUs spanning multiple TCP segments",
-               "Whether the S5066 dissector should reassemble PDUs spanning multiple TCP segments."
-               " The default is to use reassembly.",
-               &s5066_desegment);
+                                      "Reassemble S5066 PDUs spanning multiple TCP segments",
+                                      "Whether the S5066 dissector should reassemble PDUs spanning multiple TCP segments."
+                                      " The default is to use reassembly.",
+                                      &s5066_desegment);
        prefs_register_bool_preference(s5066_module, "edition_one",
-               "Dissect edition 1.0 of STANAG 5066",
-               "Whether the S5066 dissector should dissect editon 1 of the STANAG."
-               " This editon was never formally approved and is very rare. The common edition is editon 1.2.",
-               &s5066_edition_one);
-
+                                      "Dissect edition 1.0 of STANAG 5066",
+                                      "Whether the S5066 dissector should dissect this edition of the STANAG."
+                                      " This edition was never formally approved and is very rare. The common edition is edition 1.2.",
+                                      &s5066_edition_one);
+       prefs_register_uint_preference(s5066_module, "tcp.port",
+                                      "STANAG 5066 TCP Port",
+                                      "Set the port for STANAG 5066. (If other than the default 5066."
+                                      " This number is registered with IANA.)",
+                                      10, &global_s5066_port);
 }
 
 void
 proto_reg_handoff_s5066(void)
 {
-       static gint Initialized = FALSE;
+       static gboolean Initialized = FALSE;
+       static dissector_handle_t s5066_tcp_handle;
+       static guint saved_s5066_port;
 
        if (!Initialized) {
                s5066_tcp_handle = create_dissector_handle(dissect_s5066_tcp, proto_s5066);
-               dissector_add("tcp.port", global_s5066_port, s5066_tcp_handle);
-
                data_handle = find_dissector("data");
                Initialized = TRUE;
+       } else {
+               dissector_delete("tcp.port", saved_s5066_port, s5066_tcp_handle);
        }
+
+       dissector_add("tcp.port", global_s5066_port, s5066_tcp_handle);
+       saved_s5066_port = global_s5066_port;
+
        if (!s5066_edition_one) {
                s5066_header_size = 5;
                s5066_size_offset = 3;
@@ -788,7 +822,7 @@ proto_reg_handoff_s5066(void)
        }
 }
 
-static guint 
+static guint
 dissect_s5066_address(tvbuff_t *tvb, guint offset, proto_tree *tree, gint source)
 {
         proto_item *ti = NULL;
@@ -808,10 +842,10 @@ dissect_s5066_address(tvbuff_t *tvb, guint offset, proto_tree *tree, gint source
        address = address & 0x1FFFFFFF;
        proto_tree_add_ipv4(s5066_tree_address, hf_s5066_ad_address, tvb, offset, 4, g_htonl(address));
 
-       return offset += 4;
+       return offset + 4;
 }
 
-static guint 
+static guint
 dissect_s5066_servicetype(tvbuff_t *tvb, guint offset, proto_tree *tree)
 {
         proto_item *ti = NULL;
@@ -830,7 +864,7 @@ dissect_s5066_servicetype(tvbuff_t *tvb, guint offset, proto_tree *tree)
 }
 
 /* S_BIND_REQUEST */
-static guint 
+static guint
 dissect_s5066_01(tvbuff_t *tvb, guint offset, proto_tree *tree)
 {
        proto_tree_add_item(tree, hf_s5066_01_sapid, tvb, offset, 1, FALSE);
@@ -844,7 +878,7 @@ dissect_s5066_01(tvbuff_t *tvb, guint offset, proto_tree *tree)
 
 /* S_UNBIND_REQUEST */
 /* Commented out: does nothing and causes <variable not used> messages.
-static guint 
+static guint
 dissect_s5066_02(tvbuff_t *tvb, guint offset, proto_tree *tree)
 {
        return offset;
@@ -852,7 +886,7 @@ dissect_s5066_02(tvbuff_t *tvb, guint offset, proto_tree *tree)
 */
 
 /* S_BIND_ACCEPTED */
-static guint 
+static guint
 dissect_s5066_03(tvbuff_t *tvb, guint offset, proto_tree *tree)
 {
        proto_tree_add_item(tree, hf_s5066_03_sapid, tvb, offset, 1, FALSE);
@@ -862,7 +896,7 @@ dissect_s5066_03(tvbuff_t *tvb, guint offset, proto_tree *tree)
 }
 
 /* S_BIND_REJECTED */
-static guint 
+static guint
 dissect_s5066_04(tvbuff_t *tvb, guint offset, proto_tree *tree)
 {
        proto_tree_add_item(tree, hf_s5066_04_reason, tvb, offset, 1, FALSE); offset++;
@@ -870,7 +904,7 @@ dissect_s5066_04(tvbuff_t *tvb, guint offset, proto_tree *tree)
 }
 
 /* S_UNBIND_INDICATION */
-static guint 
+static guint
 dissect_s5066_05(tvbuff_t *tvb, guint offset, proto_tree *tree)
 {
        proto_tree_add_item(tree, hf_s5066_05_reason, tvb, offset, 1, FALSE); offset++;
@@ -878,7 +912,7 @@ dissect_s5066_05(tvbuff_t *tvb, guint offset, proto_tree *tree)
 }
 
 /* S_HARD_LINK_ESTABLISH */
-static guint 
+static guint
 dissect_s5066_06(tvbuff_t *tvb, guint offset, proto_tree *tree)
 {
        proto_tree_add_item(tree, hf_s5066_06_link_type, tvb, offset, 1, FALSE);
@@ -889,7 +923,7 @@ dissect_s5066_06(tvbuff_t *tvb, guint offset, proto_tree *tree)
 }
 
 /* S_HARD_LINK_TERMINATE */
-static guint 
+static guint
 dissect_s5066_07(tvbuff_t *tvb, guint offset, proto_tree *tree)
 {
        offset = dissect_s5066_address(tvb, offset, tree, FALSE);
@@ -897,7 +931,7 @@ dissect_s5066_07(tvbuff_t *tvb, guint offset, proto_tree *tree)
 }
 
 /* S_HARD_LINK_ESTABLISHED */
-static guint 
+static guint
 dissect_s5066_08(tvbuff_t *tvb, guint offset, proto_tree *tree)
 {
        proto_tree_add_item(tree, hf_s5066_08_remote_status, tvb, offset, 1, FALSE); offset++;
@@ -909,7 +943,7 @@ dissect_s5066_08(tvbuff_t *tvb, guint offset, proto_tree *tree)
 }
 
 /* S_HARD_LINK_REJECTED */
-static guint 
+static guint
 dissect_s5066_09(tvbuff_t *tvb, guint offset, proto_tree *tree)
 {
        proto_tree_add_item(tree, hf_s5066_09_reason, tvb, offset, 1, FALSE); offset++;
@@ -921,7 +955,7 @@ dissect_s5066_09(tvbuff_t *tvb, guint offset, proto_tree *tree)
 }
 
 /* S_HARD_LINK_TERMINATED */
-static guint 
+static guint
 dissect_s5066_10(tvbuff_t *tvb, guint offset, proto_tree *tree)
 {
        proto_tree_add_item(tree, hf_s5066_10_reason, tvb, offset, 1, FALSE); offset++;
@@ -933,7 +967,7 @@ dissect_s5066_10(tvbuff_t *tvb, guint offset, proto_tree *tree)
 }
 
 /* S_HARD_LINK_INDICATION */
-static guint 
+static guint
 dissect_s5066_11(tvbuff_t *tvb, guint offset, proto_tree *tree)
 {
        proto_tree_add_item(tree, hf_s5066_11_remote_status, tvb, offset, 1, FALSE); offset++;
@@ -945,7 +979,7 @@ dissect_s5066_11(tvbuff_t *tvb, guint offset, proto_tree *tree)
 }
 
 /* S_HARD_LINK_ACCEPT */
-static guint 
+static guint
 dissect_s5066_12(tvbuff_t *tvb, guint offset, proto_tree *tree)
 {
        proto_tree_add_item(tree, hf_s5066_12_link_type, tvb, offset, 1, FALSE);
@@ -956,7 +990,7 @@ dissect_s5066_12(tvbuff_t *tvb, guint offset, proto_tree *tree)
 }
 
 /* S_HARD_LINK_REJECT */
-static guint 
+static guint
 dissect_s5066_13(tvbuff_t *tvb, guint offset, proto_tree *tree)
 {
        proto_tree_add_item(tree, hf_s5066_13_reason, tvb, offset, 1, FALSE); offset++;
@@ -968,7 +1002,7 @@ dissect_s5066_13(tvbuff_t *tvb, guint offset, proto_tree *tree)
 }
 
 /* S_SUBNET_AVAILABILITY */
-static guint 
+static guint
 dissect_s5066_14(tvbuff_t *tvb, guint offset, proto_tree *tree)
 {
        proto_tree_add_item(tree, hf_s5066_14_status, tvb, offset, 1, FALSE); offset++;
@@ -979,7 +1013,7 @@ dissect_s5066_14(tvbuff_t *tvb, guint offset, proto_tree *tree)
 /* Following three commented out: do nothing and cause <variable not used> messages. */
 /* S_DATA_FLOW_ON */
 /*
-static guint 
+static guint
 dissect_s5066_15(tvbuff_t *tvb, guint offset, proto_tree *tree)
 {
        return offset;
@@ -988,7 +1022,7 @@ dissect_s5066_15(tvbuff_t *tvb, guint offset, proto_tree *tree)
 
 /* S_DATA_FLOW_OFF */
 /*
-static guint 
+static guint
 dissect_s5066_16(tvbuff_t *tvb, guint offset, proto_tree *tree)
 {
        return offset;
@@ -997,7 +1031,7 @@ dissect_s5066_16(tvbuff_t *tvb, guint offset, proto_tree *tree)
 
 /* S_KEEP_ALIVE */
 /*
-static guint 
+static guint
 dissect_s5066_17(tvbuff_t *tvb, guint offset, proto_tree *tree)
 {
        return offset;
@@ -1005,29 +1039,29 @@ dissect_s5066_17(tvbuff_t *tvb, guint offset, proto_tree *tree)
 */
 
 /* S_MANAGEMENT_MESSAGE_REQUEST */
-static guint 
+static guint
 dissect_s5066_18(tvbuff_t *tvb, guint offset, proto_tree *tree, guint pdu_size)
 {
        guint body_size = 0;
        proto_tree_add_item(tree, hf_s5066_18_type, tvb, offset, 1, FALSE); offset++;
        body_size = pdu_size - offset;
-       proto_tree_add_bytes(tree, hf_s5066_18_body, tvb, offset, body_size, FALSE); offset += body_size; 
+       proto_tree_add_item(tree, hf_s5066_18_body, tvb, offset, body_size, FALSE); offset += body_size;
        return offset;
 }
 
 /* S_MANAGEMENT_MESSAGE_INDICATION */
-static guint 
+static guint
 dissect_s5066_19(tvbuff_t *tvb, guint offset, proto_tree *tree, guint pdu_size)
 {
        guint body_size = 0;
        proto_tree_add_item(tree, hf_s5066_19_type, tvb, offset, 1, FALSE); offset++;
        body_size = pdu_size - offset;
-       proto_tree_add_bytes(tree, hf_s5066_19_body, tvb, offset, body_size, FALSE); offset += body_size;
+       proto_tree_add_item(tree, hf_s5066_19_body, tvb, offset, body_size, FALSE); offset += body_size;
        return offset;
 }
 
 /* S_UNIDATA_REQUEST */
-static guint 
+static guint
 dissect_s5066_20(tvbuff_t *tvb, guint offset, proto_tree *tree)
 {
        proto_tree_add_item(tree, hf_s5066_20_priority, tvb, offset, 1, FALSE);
@@ -1041,14 +1075,27 @@ dissect_s5066_20(tvbuff_t *tvb, guint offset, proto_tree *tree)
 }
 
 /* S_UNIDATA_INDICATION */
-static guint 
+static guint
 dissect_s5066_21(tvbuff_t *tvb, guint offset, proto_tree *tree, guint pdu_size)
 {
+       guint i=0;
        proto_item *ti = NULL;
        guint d_pdu_size = 0;
+       guint8 tx_mode = 0;
+       guint16 no_err_blocks = 0;
+       guint16 no_nrx_blocks = 0;
+       gboolean non_arq_w_errors = FALSE;
+
        proto_tree_add_item(tree, hf_s5066_21_priority, tvb, offset, 1, FALSE);
        proto_tree_add_item(tree, hf_s5066_21_dest_sapid, tvb, offset, 1, FALSE); offset++;
        offset = dissect_s5066_address(tvb, offset, tree, FALSE);
+
+       tx_mode = tvb_get_guint8(tvb, offset);
+       tx_mode = (tx_mode & 0xF0) >> 4;
+       if (tx_mode == 3) {
+               non_arq_w_errors = TRUE;
+       }
+
        proto_tree_add_item(tree, hf_s5066_21_tx_mode, tvb, offset, 1, FALSE);
        proto_tree_add_item(tree, hf_s5066_21_src_sapid, tvb, offset, 1, FALSE); offset++;
        offset = dissect_s5066_address(tvb, offset, tree, TRUE);
@@ -1064,15 +1111,25 @@ dissect_s5066_21(tvbuff_t *tvb, guint offset, proto_tree *tree, guint pdu_size)
                proto_item_append_text(ti, ", (Field should not be present. Rockwell Collins v2.1 or earlier.) ");
        }
        /* Handle Non-ARQ with errors */
-       if ( FALSE ) {
+       if ( non_arq_w_errors ) {
+               no_err_blocks = tvb_get_ntohs(tvb, offset);
                proto_tree_add_item(tree, hf_s5066_21_err_blocks, tvb, offset, 2, FALSE); offset += 2;
+               for (i=0; i<no_err_blocks; i++) {
+                       proto_tree_add_item(tree, hf_s5066_21_err_ptr, tvb, offset, 2, FALSE); offset += 2;
+                       proto_tree_add_item(tree, hf_s5066_21_err_size, tvb, offset, 2, FALSE); offset += 2;
+               }
+               no_nrx_blocks = tvb_get_ntohs(tvb, offset);
                proto_tree_add_item(tree, hf_s5066_21_nrx_blocks, tvb, offset, 2, FALSE); offset += 2;
+               for (i=0; i<no_nrx_blocks; i++) {
+                       proto_tree_add_item(tree, hf_s5066_21_nrx_ptr, tvb, offset, 2, FALSE); offset += 2;
+                       proto_tree_add_item(tree, hf_s5066_21_nrx_size, tvb, offset, 2, FALSE); offset += 2;
+               }
        }
        return offset;
 }
 
 /* S_UNIDATA_REQUEST_CONFIRM */
-static guint 
+static guint
 dissect_s5066_22(tvbuff_t *tvb, guint offset, proto_tree *tree)
 {
        guint pdu_size = 0;
@@ -1081,13 +1138,13 @@ dissect_s5066_22(tvbuff_t *tvb, guint offset, proto_tree *tree)
        offset = dissect_s5066_address(tvb, offset, tree, FALSE);
        pdu_size = tvb_get_ntohs(tvb, offset);
        proto_tree_add_item(tree, hf_s5066_22_size, tvb, offset, 2, FALSE); offset += 2;
-       proto_tree_add_bytes(tree, hf_s5066_22_data, tvb, offset, pdu_size, tvb_get_ptr(tvb, offset, pdu_size)); offset += pdu_size;
+       proto_tree_add_item(tree, hf_s5066_22_data, tvb, offset, pdu_size, FALSE); offset += pdu_size;
 
        return offset;
 }
 
 /* S_UNIDATA_REQUEST_REJECTED */
-static guint 
+static guint
 dissect_s5066_23(tvbuff_t *tvb, guint offset, proto_tree *tree)
 {
        guint pdu_size = 0;
@@ -1096,13 +1153,13 @@ dissect_s5066_23(tvbuff_t *tvb, guint offset, proto_tree *tree)
        offset = dissect_s5066_address(tvb, offset, tree, FALSE);
        pdu_size = tvb_get_ntohs(tvb, offset);
        proto_tree_add_item(tree, hf_s5066_23_size, tvb, offset, 2, FALSE); offset += 2;
-       proto_tree_add_bytes(tree, hf_s5066_23_data, tvb, offset, pdu_size, tvb_get_ptr(tvb, offset, pdu_size)); offset += pdu_size;
+       proto_tree_add_item(tree, hf_s5066_23_data, tvb, offset, pdu_size, FALSE); offset += pdu_size;
 
        return offset;
 }
 
 /* S_EXPEDITED_UNIDATA_REQUEST */
-static guint 
+static guint
 dissect_s5066_24(tvbuff_t *tvb, guint offset, proto_tree *tree)
 {
        proto_tree_add_item(tree, hf_s5066_24_unused, tvb, offset, 1, FALSE);
@@ -1116,40 +1173,61 @@ dissect_s5066_24(tvbuff_t *tvb, guint offset, proto_tree *tree)
 }
 
 /* S_EXPEDITED_UNIDATA_INDICATION */
-static guint 
+static guint
 dissect_s5066_25(tvbuff_t *tvb, guint offset, proto_tree *tree, guint pdu_size)
 {
+       guint i=0;
        proto_item *ti = NULL;
        guint d_pdu_size = 0;
+       guint8 tx_mode = 0;
+       guint16 no_err_blocks = 0;
+       guint16 no_nrx_blocks = 0;
+       gboolean non_arq_w_errors = FALSE;
 
        proto_tree_add_item(tree, hf_s5066_25_unused, tvb, offset, 1, FALSE);
        proto_tree_add_item(tree, hf_s5066_25_dest_sapid, tvb, offset, 1, FALSE); offset++;
        offset = dissect_s5066_address(tvb, offset, tree, FALSE);
+
+       tx_mode = tvb_get_guint8(tvb, offset);
+       tx_mode = (tx_mode & 0xF0) >> 4;
+       if (tx_mode == 3) {
+               non_arq_w_errors = TRUE;
+       }
+
        proto_tree_add_item(tree, hf_s5066_25_tx_mode, tvb, offset, 1, FALSE);
        proto_tree_add_item(tree, hf_s5066_25_src_sapid, tvb, offset, 1, FALSE); offset++;
        offset = dissect_s5066_address(tvb, offset, tree, TRUE);
-       proto_tree_add_item(tree, hf_s5066_25_size, tvb, offset, 2, FALSE); offset += 2;
 
        d_pdu_size = tvb_get_ntohs(tvb, offset);
-       proto_tree_add_item(tree, hf_s5066_21_size, tvb, offset, 2, FALSE); offset += 2;
+       proto_tree_add_item(tree, hf_s5066_25_size, tvb, offset, 2, FALSE); offset += 2;
 
        /* Handle RockwellCollins (<= v2.1) 4-byte offset */
-       if ( (pdu_size - offset) == d_pdu_size + 4 ) {
+       if ( (pdu_size - offset) == (d_pdu_size + 4) ) {
                ti = proto_tree_add_item(tree, hf_s5066_25_err_blocks, tvb, offset, 2, FALSE); offset += 2;
                proto_item_append_text(ti, ", (Field should not be present. Rockwell Collins v2.1 or earlier.) ");
                ti = proto_tree_add_item(tree, hf_s5066_25_nrx_blocks, tvb, offset, 2, FALSE); offset += 2;
                proto_item_append_text(ti, ", (Field should not be present. Rockwell Collins v2.1 or earlier.) ");
        }
        /* Handle Non-ARQ with errors */
-       if ( FALSE ) {
+       if ( non_arq_w_errors ) {
+               no_err_blocks = tvb_get_ntohs(tvb, offset);
                proto_tree_add_item(tree, hf_s5066_25_err_blocks, tvb, offset, 2, FALSE); offset += 2;
+               for (i=0; i<no_err_blocks; i++) {
+                       proto_tree_add_item(tree, hf_s5066_25_err_ptr, tvb, offset, 2, FALSE); offset += 2;
+                       proto_tree_add_item(tree, hf_s5066_25_err_size, tvb, offset, 2, FALSE); offset += 2;
+               }
+               no_nrx_blocks = tvb_get_ntohs(tvb, offset);
                proto_tree_add_item(tree, hf_s5066_25_nrx_blocks, tvb, offset, 2, FALSE); offset += 2;
+               for (i=0; i<no_nrx_blocks; i++) {
+                       proto_tree_add_item(tree, hf_s5066_25_nrx_ptr, tvb, offset, 2, FALSE); offset += 2;
+                       proto_tree_add_item(tree, hf_s5066_25_nrx_size, tvb, offset, 2, FALSE); offset += 2;
+               }
        }
        return offset;
 }
 
 /* S_EXPEDITED_UNIDATA_REQUEST_CONFIRM */
-static guint 
+static guint
 dissect_s5066_26(tvbuff_t *tvb, guint offset, proto_tree *tree)
 {
        guint pdu_size = 0;
@@ -1158,13 +1236,13 @@ dissect_s5066_26(tvbuff_t *tvb, guint offset, proto_tree *tree)
        offset = dissect_s5066_address(tvb, offset, tree, FALSE);
        pdu_size = tvb_get_ntohs(tvb, offset);
        proto_tree_add_item(tree, hf_s5066_26_size, tvb, offset, 2, FALSE); offset += 2;
-       proto_tree_add_bytes(tree, hf_s5066_26_data, tvb, offset, pdu_size, tvb_get_ptr(tvb, offset, pdu_size)); offset += pdu_size;
+       proto_tree_add_item(tree, hf_s5066_26_data, tvb, offset, pdu_size, FALSE); offset += pdu_size;
 
        return offset;
 }
 
 /* S_EXPEDITED_UNIDATA_REQUEST_REJECTED */
-static guint 
+static guint
 dissect_s5066_27(tvbuff_t *tvb, guint offset, proto_tree *tree)
 {
        guint pdu_size = 0;
@@ -1173,13 +1251,13 @@ dissect_s5066_27(tvbuff_t *tvb, guint offset, proto_tree *tree)
        offset = dissect_s5066_address(tvb, offset, tree, FALSE);
        pdu_size = tvb_get_ntohs(tvb, offset);
        proto_tree_add_item(tree, hf_s5066_27_size, tvb, offset, 2, FALSE); offset += 2;
-       proto_tree_add_bytes(tree, hf_s5066_27_data, tvb, offset, pdu_size, tvb_get_ptr(tvb, offset, pdu_size)); offset += pdu_size;
+       proto_tree_add_item(tree, hf_s5066_27_data, tvb, offset, pdu_size, FALSE); offset += pdu_size;
 
        return offset;
 }
 
 static guint
-get_s5066_pdu_len(tvbuff_t *tvb, int offset)
+get_s5066_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
 {
   guint16 plen;
 
@@ -1199,8 +1277,8 @@ dissect_s5066_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        /* Check if the first two bytes are 0x90 0xEB: if not,
           then this is not a S5066 PDU or an unreassembled one.
           The third byte is the STANAG 5066 version: Right now only 0x00 is defined. */
-       if( (tvb_get_guint8(tvb, 0) != 0x90) &&
-           (tvb_get_guint8(tvb, 1) != 0xEB) &&
+       if( (tvb_get_guint8(tvb, 0) != 0x90) ||
+           (tvb_get_guint8(tvb, 1) != 0xEB) ||
            (tvb_get_guint8(tvb, 2) != 0x00) ) {
                return;
        }
@@ -1215,18 +1293,14 @@ dissect_s5066_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        proto_item *ti_s5066 = NULL;
        proto_item *ti_pdu = NULL;
        tvbuff_t *next_tvb;
-       gint available_length, reported_length;
+       gint available_length = 0;
+       gint reported_length = 0;
 
        /* Determine PDU type to display in INFO column */
        guint8 pdu_type = tvb_get_guint8(tvb, s5066_header_size);
 
-       if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
-               col_set_str(pinfo->cinfo, COL_PROTOCOL, "S5066");
-       }
+       col_set_str(pinfo->cinfo, COL_PROTOCOL, "S5066");
        /* Clear out stuff in the info column, the add PDU type */
-       if (check_col(pinfo->cinfo, COL_INFO)) {
-               col_clear(pinfo->cinfo, COL_INFO); 
-       }
        if (check_col(pinfo->cinfo, COL_INFO)) {
                col_add_fstr(pinfo->cinfo, COL_INFO, "PDU type %s", val_to_str(pdu_type, s5066_pdu_type, "Unknown (0x%02x)"));
        }
@@ -1278,16 +1352,13 @@ dissect_s5066_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                }
        }
        proto_item_set_len(ti_s5066, offset);
-       /* proto_item_set_len(ti_pdu, offset - s5066_header_size); */
 
        /* Call sub dissector(s) */
        reported_length = pdu_size - offset;
        available_length = tvb_length(tvb) - offset;
 
        next_tvb = tvb_new_subset(tvb, offset, MIN(available_length, reported_length), reported_length);
-       call_dissector(data_handle, next_tvb, pinfo, tree); 
-       
+       call_dissector(data_handle, next_tvb, pinfo, tree);
+
        return;
 }
-
-