For proto_tree_add_item(..., proto_xxx, ...)use ENC_NA as the encoding arg.
[obnox/wireshark/wip.git] / epan / dissectors / packet-bvlc.c
index 19d5fb8fb2d5aa9cf9ce2e067ecd56d1f862a981..7fff6c5d0a19ea50258a890882b7b9d907f9e2be 100644 (file)
@@ -29,9 +29,6 @@
 # include "config.h"
 #endif
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
 #include <epan/prefs.h>
 #include <epan/strutil.h>
 
 
 #include <epan/packet.h>
 
+/* Taken from add-135a (BACnet-IP-standard paper):
+ *
+ * The default UDP port for both directed messages and broadcasts shall
+ * be X'BAC0' and all B/IP devices shall support it. In some cases,
+ * e.g., a situation where it is desirable for two groups of BACnet devices
+ * to coexist independently on the same IP subnet, the UDP port may be
+ * configured locally to a different value without it being considered
+ * a violation of this protocol.
+ */
+static guint global_additional_bvlc_udp_port = 0;
+
 static int proto_bvlc = -1;
 static int hf_bvlc_type = -1;
 static int hf_bvlc_function = -1;
@@ -128,15 +136,13 @@ dissect_bvlc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        if (match_strval(bvlc_type, bvlc_types) == NULL)
                return 0;
 
-       if (check_col(pinfo->cinfo, COL_PROTOCOL))
-               col_set_str(pinfo->cinfo, COL_PROTOCOL, "BVLC");
+       col_set_str(pinfo->cinfo, COL_PROTOCOL, "BVLC");
 
-       if (check_col(pinfo->cinfo, COL_INFO))
-               col_set_str(pinfo->cinfo, COL_INFO, "BACnet Virtual Link Control");
+       col_set_str(pinfo->cinfo, COL_INFO, "BACnet Virtual Link Control");
 
        bvlc_function = tvb_get_guint8(tvb, offset+1);
        packet_length = tvb_get_ntohs(tvb, offset+2);
-       length_remaining = tvb_length_remaining(tvb, offset);
+       length_remaining = tvb_reported_length_remaining(tvb, offset);
        if (bvlc_function > 0x08) {
                /*  We have a constant header length of BVLC of 4 in every
                 *  BVLC-packet forewarding an NPDU. Beware: Changes in the
@@ -161,10 +167,10 @@ dissect_bvlc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                if (bvlc_length < 4) {
                        proto_tree_add_text(tree, tvb, 2, 2,
                                "Bogus length: %d", bvlc_length);
-                       return tvb_length(tvb); /* XXX - reject? */
+                       return tvb_reported_length(tvb);        /* XXX - reject? */
                }
                ti = proto_tree_add_item(tree, proto_bvlc, tvb, 0,
-                       bvlc_length, FALSE);
+                       bvlc_length, ENC_NA);
                bvlc_tree = proto_item_add_subtree(ti, ett_bvlc);
                proto_tree_add_uint(bvlc_tree, hf_bvlc_type, tvb, offset, 1,
                        bvlc_type);
@@ -174,10 +180,10 @@ dissect_bvlc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                offset ++;
                if (length_remaining != packet_length)
                        proto_tree_add_uint_format_value(bvlc_tree, hf_bvlc_length, tvb, offset,
-                               2, bvlc_length, 
+                               2, bvlc_length,
                                "%d of %d bytes (invalid length - expected %d bytes)",
                                bvlc_length, packet_length, length_remaining);
-               else            
+               else
                        proto_tree_add_uint_format_value(bvlc_tree, hf_bvlc_length, tvb, offset,
                                2, bvlc_length, "%d of %d bytes BACnet packet length",
                                bvlc_length, packet_length);
@@ -192,7 +198,7 @@ dissect_bvlc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                        * packet to dissect, see README.developer, 1.6.2, FID */
                        proto_tree_add_uint_format_value(bvlc_tree, hf_bvlc_result, tvb,
                                offset, 2, bvlc_result,"0x%04x (%s)",
-                               bvlc_result, val_to_str(bvlc_result << 4,
+                               bvlc_result, val_to_str(bvlc_result,
                                        bvlc_result_names, "Unknown"));
                        offset += 2;
                        break;
@@ -200,19 +206,19 @@ dissect_bvlc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                case 0x03: /* Read-Broadcast-Distribution-Table-Ack */
                        /* List of BDT Entries: N*10-octet */
                        ti_bdt = proto_tree_add_item(bvlc_tree, proto_bvlc, tvb,
-                               offset, bvlc_length-4, FALSE);
+                               offset, bvlc_length-4, ENC_NA);
                        bdt_tree = proto_item_add_subtree(ti_bdt, ett_bdt);
                        /* List of BDT Entries: N*10-octet */
                        while ((bvlc_length - offset) > 9) {
                                proto_tree_add_item(bdt_tree, hf_bvlc_bdt_ip,
-                                       tvb, offset, 4, FALSE);
+                                       tvb, offset, 4, ENC_BIG_ENDIAN);
                                offset += 4;
                                proto_tree_add_item(bdt_tree, hf_bvlc_bdt_port,
-                                       tvb, offset, 2, FALSE);
+                                       tvb, offset, 2, ENC_BIG_ENDIAN);
                                offset += 2;
                                proto_tree_add_item(bdt_tree,
                                        hf_bvlc_bdt_mask, tvb, offset, 4,
-                                       FALSE);
+                                       ENC_NA);
                                offset += 4;
                        }
                        /* We check this if we get a BDT-packet somewhere */
@@ -223,7 +229,7 @@ dissect_bvlc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                case 0x05: /* Register-Foreign-Device */
                        /* Time-to-Live 2-octets T, Time-to-Live T, in seconds */
                        proto_tree_add_item(bvlc_tree, hf_bvlc_reg_ttl,
-                               tvb, offset, 2, FALSE);
+                               tvb, offset, 2, ENC_BIG_ENDIAN);
                        offset += 2;
                        break;
                case 0x06: /* Read-Foreign-Device-Table */
@@ -240,23 +246,23 @@ dissect_bvlc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                         * the registrant's FDT entry if no re-registration occurs.
                         */
                        ti_fdt = proto_tree_add_item(bvlc_tree, proto_bvlc, tvb,
-                               offset, bvlc_length -4, FALSE);
+                               offset, bvlc_length -4, ENC_NA);
                        fdt_tree = proto_item_add_subtree(ti_fdt, ett_fdt);
                        /* List of FDT Entries: N*10-octet */
                        while ((bvlc_length - offset) > 9) {
                                proto_tree_add_item(fdt_tree, hf_bvlc_fdt_ip,
-                                       tvb, offset, 4, FALSE);
+                                       tvb, offset, 4, ENC_BIG_ENDIAN);
                                offset += 4;
                                proto_tree_add_item(fdt_tree, hf_bvlc_fdt_port,
-                                       tvb, offset, 2, FALSE);
+                                       tvb, offset, 2, ENC_BIG_ENDIAN);
                                offset += 2;
                                proto_tree_add_item(fdt_tree,
                                        hf_bvlc_fdt_ttl, tvb, offset, 2,
-                                       FALSE);
+                                       ENC_BIG_ENDIAN);
                                offset += 2;
                                proto_tree_add_item(fdt_tree,
                                        hf_bvlc_fdt_timeout, tvb, offset, 2,
-                                       FALSE);
+                                       ENC_BIG_ENDIAN);
                                offset += 2;
                        }
                        /* We check this if we get a FDT-packet somewhere */
@@ -264,10 +270,10 @@ dissect_bvlc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                case 0x08: /* Delete-Foreign-Device-Table-Entry */
                        /* FDT Entry:   6-octets */
                        proto_tree_add_item(bvlc_tree, hf_bvlc_fdt_ip,
-                               tvb, offset, 4, FALSE);
+                               tvb, offset, 4, ENC_BIG_ENDIAN);
                        offset += 4;
                        proto_tree_add_item(bvlc_tree, hf_bvlc_fdt_port,
-                               tvb, offset, 2, FALSE);
+                               tvb, offset, 2, ENC_BIG_ENDIAN);
                        offset += 2;
                        break;
                        /* We check this if we get a FDT-packet somewhere */
@@ -278,10 +284,10 @@ dissect_bvlc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                                 */
                        /* proto_tree_add_bytes_format(); */
                        proto_tree_add_item(bvlc_tree, hf_bvlc_fwd_ip,
-                               tvb, offset, 4, FALSE);
+                               tvb, offset, 4, ENC_BIG_ENDIAN);
                        offset += 4;
                        proto_tree_add_item(bvlc_tree, hf_bvlc_fwd_port,
-                               tvb, offset, 2, FALSE);
+                               tvb, offset, 2, ENC_BIG_ENDIAN);
                        offset += 2;
                default:/* Distribute-Broadcast-To-Network
                         * Original-Unicast-NPDU
@@ -298,14 +304,16 @@ dissect_bvlc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        npdu_length = packet_length - bvlc_length;
        next_tvb = tvb_new_subset(tvb,bvlc_length,-1,npdu_length);
        /* Code from Guy Harris */
-       if (!dissector_try_port(bvlc_dissector_table,
+       if (!dissector_try_uint(bvlc_dissector_table,
            bvlc_function, next_tvb, pinfo, tree)) {
                /* Unknown function - dissect the paylod as data */
                call_dissector(data_handle,next_tvb, pinfo, tree);
        }
-       return tvb_length(tvb);
+       return tvb_reported_length(tvb);
 }
 
+void proto_reg_handoff_bvlc(void);
+
 void
 proto_register_bvlc(void)
 {
@@ -313,7 +321,7 @@ proto_register_bvlc(void)
                { &hf_bvlc_type,
                        { "Type",           "bvlc.type",
                        FT_UINT8, BASE_HEX, VALS(bvlc_types), 0,
-                       "Type", HFILL }
+                       NULL, HFILL }
                },
                { &hf_bvlc_function,
                        { "Function",           "bvlc.function",
@@ -329,7 +337,7 @@ proto_register_bvlc(void)
                 * packet to dissect */
                { &hf_bvlc_result,
                        { "Result",           "bvlc.result",
-                       FT_UINT16, BASE_HEX, NULL, 0xffff,
+                       FT_UINT16, BASE_HEX, NULL, 0,
                        "Result Code", HFILL }
                },
                { &hf_bvlc_bdt_ip,
@@ -344,7 +352,7 @@ proto_register_bvlc(void)
                },
                { &hf_bvlc_bdt_mask,
                        { "Mask",           "bvlc.bdt_mask",
-                       FT_BYTES, BASE_HEX, NULL, 0,
+                       FT_BYTES, BASE_NONE, NULL, 0,
                        "BDT Broadcast Distribution Mask", HFILL }
                },
                { &hf_bvlc_reg_ttl,
@@ -390,12 +398,20 @@ proto_register_bvlc(void)
                &ett_fdt,
        };
 
+       module_t *bvlc_module;
+
        proto_bvlc = proto_register_protocol("BACnet Virtual Link Control",
            "BVLC", "bvlc");
 
        proto_register_field_array(proto_bvlc, hf, array_length(hf));
        proto_register_subtree_array(ett, array_length(ett));
 
+       bvlc_module = prefs_register_protocol(proto_bvlc, proto_reg_handoff_bvlc);
+       prefs_register_uint_preference(bvlc_module, "additional_udp_port",
+                                       "Additional UDP port", "Set an additional UDP port, "
+                                       "besides the standard X'BAC0' (47808) port.",
+                                       10, &global_additional_bvlc_udp_port);
+
        new_register_dissector("bvlc", dissect_bvlc, proto_bvlc);
 
        bvlc_dissector_table = register_dissector_table("bvlc.function",
@@ -405,22 +421,26 @@ proto_register_bvlc(void)
 void
 proto_reg_handoff_bvlc(void)
 {
-       dissector_handle_t bvlc_handle;
+       static gboolean bvlc_initialized = FALSE;
+       static dissector_handle_t bvlc_handle;
+       static guint additional_bvlc_udp_port;
+
+       if (!bvlc_initialized)
+       {
+               bvlc_handle = find_dissector("bvlc");
+               dissector_add_uint("udp.port", 0xBAC0, bvlc_handle);
+               data_handle = find_dissector("data");
+               bvlc_initialized = TRUE;
+       }
+       else
+       {
+               if (additional_bvlc_udp_port != 0) {
+                       dissector_delete_uint("udp.port", additional_bvlc_udp_port, bvlc_handle);
+               }
+       }
 
-       bvlc_handle = find_dissector("bvlc");
-       dissector_add("udp.port", 0xBAC0, bvlc_handle);
-       data_handle = find_dissector("data");
+       if (global_additional_bvlc_udp_port != 0) {
+               dissector_add_uint("udp.port", global_additional_bvlc_udp_port, bvlc_handle);
+       }
+       additional_bvlc_udp_port = global_additional_bvlc_udp_port;
 }
-/* Taken from add-135a (BACnet-IP-standard paper):
- *
- * The default UDP port for both directed messages and broadcasts shall
- * be X'BAC0' and all B/IP devices shall support it. In some cases,
- * e.g., a situation where it is desirable for two groups of BACnet devices
- * to coexist independently on the same IP subnet, the UDP port may be
- * configured locally to a different value without it being considered
- * a violation of this protocol.
- *
- * This dissector does not analyse UDP packets other than on port 0xBAC0.
- * If you changed your BACnet port locally, use the wireshark feature
- * "Decode As".
- */