As with "file_write_error_message()", so with
[obnox/wireshark/wip.git] / packet-bacnet.c
index c5ea2731b69832dd2838a1944356d8ffd50284f3..d66ca35f451ebbe24259e878dc5ed81c73145885 100644 (file)
@@ -2,7 +2,7 @@
  * Routines for BACnet (NPDU) dissection
  * Copyright 2001, Hartmut Mueller <hartmut@abmlinux.org>, FH Dortmund
  *
- * $Id: packet-bacnet.c,v 1.3 2001/05/30 07:48:23 guy Exp $
+ * $Id: packet-bacnet.c,v 1.17 2003/01/25 00:06:12 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
 #include <stdlib.h>
 #include <string.h>
 
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-
-#ifdef HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-
 #include <glib.h>
 
-#ifdef NEED_SNPRINTF_H
-# include "snprintf.h"
-#endif
+#include <epan/packet.h>
 
-#include "packet.h"
+#include "llcsaps.h"
 
-static dissector_table_t bacnet_dissector_table;
+static dissector_handle_t bacapp_handle;
+static dissector_handle_t data_handle;
 
 static const char*
 bacnet_mesgtyp_name (guint8 bacnet_mesgtyp){
@@ -121,7 +112,7 @@ static const true_false_string control_dest_high = {
        "DNET, DLEN and Hop Count present. If DLEN=0: broadcast, dest. address field absent.",
        "DNET, DLEN, DADR and Hop Count absent."
 };
+
 static const true_false_string control_src_high = {
        "SNET, SLEN and SADR present, SLEN=0 invalid, SLEN specifies length of SADR",
        "SNET, SLEN and SADR absent"
@@ -186,7 +177,6 @@ dissect_bacnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        gint offset;
        guint8 bacnet_version;
        guint8 bacnet_control;
-       guint8 bacnet_control_net;
        guint8 bacnet_dlen;
        guint8 bacnet_slen;
        guint8 bacnet_mesgtyp;
@@ -197,16 +187,15 @@ dissect_bacnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        guint8 j;
        tvbuff_t *next_tvb;
 
-       if (check_col(pinfo->fd, COL_PROTOCOL)) 
-               col_set_str(pinfo->fd, COL_PROTOCOL, "BACnet-NPDU");
+       if (check_col(pinfo->cinfo, COL_PROTOCOL))
+               col_set_str(pinfo->cinfo, COL_PROTOCOL, "BACnet-NPDU");
 
-       if (check_col(pinfo->fd, COL_INFO)) 
-               col_set_str(pinfo->fd, COL_INFO, "Building Automation and Control Network NPDU");
+       if (check_col(pinfo->cinfo, COL_INFO))
+               col_set_str(pinfo->cinfo, COL_INFO, "Building Automation and Control Network NPDU");
 
        offset = 0;
        bacnet_version = tvb_get_guint8(tvb, offset);
        bacnet_control = tvb_get_guint8(tvb, offset+1);
-       bacnet_control_net = tvb_get_guint8(tvb, offset+1) & BAC_CONTROL_NET;
        bacnet_dlen = 0;
        bacnet_slen = 0;
        bacnet_mesgtyp = 0;
@@ -219,35 +208,35 @@ dissect_bacnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        if (tree) {
 
 /* I don't know the length of the NPDU by know. Setting the length after dissection */
-               ti = proto_tree_add_item(tree, proto_bacnet, tvb, 0, 0, FALSE);
+               ti = proto_tree_add_item(tree, proto_bacnet, tvb, 0, -1, FALSE);
 
                bacnet_tree = proto_item_add_subtree(ti, ett_bacnet);
 
-               proto_tree_add_uint_format(bacnet_tree, hf_bacnet_version, tvb, 
+               proto_tree_add_uint_format(bacnet_tree, hf_bacnet_version, tvb,
                        offset, 1,
                         bacnet_version,"Version: 0x%02x (%s)",bacnet_version,
                         (bacnet_version == 0x01)?"ASHRAE 135-1995":"unknown");
                offset ++;
-               ct = proto_tree_add_uint_format(bacnet_tree, hf_bacnet_control, 
+               ct = proto_tree_add_uint_format(bacnet_tree, hf_bacnet_control,
                        tvb, offset, 1,
                         bacnet_control,"Control: 0x%02x",bacnet_control);
-               control_tree = proto_item_add_subtree(ct, 
+               control_tree = proto_item_add_subtree(ct,
                        ett_bacnet_control);
-               proto_tree_add_boolean(control_tree, hf_bacnet_control_net, 
+               proto_tree_add_boolean(control_tree, hf_bacnet_control_net,
                        tvb, offset, 1, bacnet_control);
-               proto_tree_add_boolean(control_tree, hf_bacnet_control_res1, tvb, 
+               proto_tree_add_boolean(control_tree, hf_bacnet_control_res1, tvb,
                        offset, 1, bacnet_control);
-               proto_tree_add_boolean(control_tree, hf_bacnet_control_dest, tvb, 
+               proto_tree_add_boolean(control_tree, hf_bacnet_control_dest, tvb,
                        offset, 1, bacnet_control);
-               proto_tree_add_boolean(control_tree, hf_bacnet_control_res2, tvb, 
+               proto_tree_add_boolean(control_tree, hf_bacnet_control_res2, tvb,
                        offset, 1, bacnet_control);
-               proto_tree_add_boolean(control_tree, hf_bacnet_control_src, tvb, 
+               proto_tree_add_boolean(control_tree, hf_bacnet_control_src, tvb,
                        offset, 1, bacnet_control);
-               proto_tree_add_boolean(control_tree, hf_bacnet_control_expect, tvb, 
+               proto_tree_add_boolean(control_tree, hf_bacnet_control_expect, tvb,
                        offset, 1, bacnet_control);
-               proto_tree_add_boolean(control_tree, hf_bacnet_control_prio_high, 
+               proto_tree_add_boolean(control_tree, hf_bacnet_control_prio_high,
                        tvb, offset, 1, bacnet_control);
-               proto_tree_add_boolean(control_tree, hf_bacnet_control_prio_low, 
+               proto_tree_add_boolean(control_tree, hf_bacnet_control_prio_low,
                        tvb, offset, 1, bacnet_control);
                offset ++;
                if (bacnet_control & BAC_CONTROL_DEST) { /* DNET, DLEN, DADR */
@@ -258,8 +247,8 @@ dissect_bacnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                        /* DLEN = 0 is broadcast on dest.network */
                        if( bacnet_dlen == 0) {
                                /* append to hf_bacnet_dlen: broadcast */
-                               proto_tree_add_uint_format(bacnet_tree, 
-                               hf_bacnet_dlen, tvb, offset, 1, bacnet_dlen, 
+                               proto_tree_add_uint_format(bacnet_tree,
+                               hf_bacnet_dlen, tvb, offset, 1, bacnet_dlen,
                                "Destination MAC Layer Address Length: %d indicates Broadcast on Destination Network",
                                bacnet_dlen);
                                offset ++;
@@ -269,8 +258,8 @@ dissect_bacnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                                        tvb, offset, 1, bacnet_dlen);
                                offset ++;
                                /* Ethernet MAC */
-                               proto_tree_add_item(bacnet_tree, 
-                                       hf_bacnet_dadr_eth, tvb, offset, 
+                               proto_tree_add_item(bacnet_tree,
+                                       hf_bacnet_dadr_eth, tvb, offset,
                                        bacnet_dlen, FALSE);
                                offset += bacnet_dlen;
                        } else if (bacnet_dlen<7) {
@@ -278,13 +267,13 @@ dissect_bacnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                                        tvb, offset, 1, bacnet_dlen);
                                offset ++;
                                /* Other MAC formats should be included here */
-                               proto_tree_add_item(bacnet_tree, 
-                                       hf_bacnet_dadr_tmp, tvb, offset, 
+                               proto_tree_add_item(bacnet_tree,
+                                       hf_bacnet_dadr_tmp, tvb, offset,
                                        bacnet_dlen, FALSE);
                                offset += bacnet_dlen;
                        } else {
-                               proto_tree_add_uint_format(bacnet_tree, 
-                               hf_bacnet_dlen, tvb, offset, 1, bacnet_dlen, 
+                               proto_tree_add_uint_format(bacnet_tree,
+                               hf_bacnet_dlen, tvb, offset, 1, bacnet_dlen,
                                "Destination MAC Layer Address Length: %d invalid!",
                                bacnet_dlen);
                        }
@@ -297,7 +286,7 @@ dissect_bacnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                        bacnet_slen = tvb_get_guint8(tvb, offset);
                        if( bacnet_slen == 0) { /* SLEN = 0 invalid */
                                proto_tree_add_uint_format(bacnet_tree,
-                               hf_bacnet_slen, tvb, offset, 1, bacnet_slen, 
+                               hf_bacnet_slen, tvb, offset, 1, bacnet_slen,
                                "Source MAC Layer Address Length: %d invalid!",
                                bacnet_slen);
                                offset ++;
@@ -307,8 +296,8 @@ dissect_bacnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                                        tvb, offset, 1, bacnet_slen);
                                offset ++;
                                /* Ethernet MAC */
-                               proto_tree_add_item(bacnet_tree, 
-                                       hf_bacnet_sadr_eth, tvb, offset, 
+                               proto_tree_add_item(bacnet_tree,
+                                       hf_bacnet_sadr_eth, tvb, offset,
                                        bacnet_slen, FALSE);
                                offset += bacnet_slen;
                        } else if (bacnet_slen<6) { /* LON,ARCNET,MS/TP MAC */
@@ -317,13 +306,13 @@ dissect_bacnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                                        tvb, offset, 1, bacnet_slen);
                                offset ++;
                                /* Other MAC formats should be included here */
-                               proto_tree_add_item(bacnet_tree, 
-                                       hf_bacnet_sadr_tmp, tvb, offset, 
+                               proto_tree_add_item(bacnet_tree,
+                                       hf_bacnet_sadr_tmp, tvb, offset,
                                        bacnet_slen, FALSE);
                                offset += bacnet_slen;
                        } else {
                                proto_tree_add_uint_format(bacnet_tree,
-                               hf_bacnet_slen, tvb, offset, 1, bacnet_slen, 
+                               hf_bacnet_slen, tvb, offset, 1, bacnet_slen,
                                "Source MAC Layer Address Length: %d invalid!",
                                bacnet_slen);
                                offset ++;
@@ -335,7 +324,7 @@ dissect_bacnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                        offset ++;
                }
                /* Network Layer Message Type */
-               if (bacnet_control & BAC_CONTROL_NET) { 
+               if (bacnet_control & BAC_CONTROL_NET) {
                        bacnet_mesgtyp =  tvb_get_guint8(tvb, offset);
                        proto_tree_add_uint_format(bacnet_tree,
                        hf_bacnet_mesgtyp, tvb, offset, 1, bacnet_mesgtyp,
@@ -343,9 +332,9 @@ dissect_bacnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                        bacnet_mesgtyp_name(bacnet_mesgtyp));
                        offset ++;
                }
-               /* Vendor ID 
-                * The standard says: "If Bit 7 of the control octet is 1 and 
-                * the Message Type field contains a value in the range 
+               /* Vendor ID
+                * The standard says: "If Bit 7 of the control octet is 1 and
+                * the Message Type field contains a value in the range
                 * X'80' - X'FF', then a Vendor ID field shall be present (...)."
                 * We should not go any further in dissecting the packet if it's
                 * not present, but we don't know about that: No length field...
@@ -355,7 +344,8 @@ dissect_bacnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                                tvb, offset, 2, FALSE);
                        offset += 2;
                        /* attention: doesnt work here because of if(tree) */
-                       dissect_data(tvb, offset, pinfo, tree);
+                       call_dissector(data_handle,
+                           tvb_new_subset(tvb, offset, -1, -1), pinfo, tree);
                }
                /* Performance Index (in I-Could-Be-Router-To-Network) */
                if (bacnet_mesgtyp == BAC_NET_ICB_R) {
@@ -366,9 +356,9 @@ dissect_bacnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                /* Reason, DNET (in Reject-Message-To-Network) */
                if (bacnet_mesgtyp == BAC_NET_REJ) {
                        bacnet_rejectreason = tvb_get_guint8(tvb, offset);
-                       proto_tree_add_uint_format(bacnet_tree, 
+                       proto_tree_add_uint_format(bacnet_tree,
                                hf_bacnet_rejectreason,
-                               tvb, offset, 1, 
+                               tvb, offset, 1,
                                bacnet_rejectreason, "Rejection Reason: %d (%s)",
                                bacnet_rejectreason,
                                bacnet_rejectreason_name(bacnet_rejectreason));
@@ -378,7 +368,7 @@ dissect_bacnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                        offset += 2;
                }
                /* N*DNET (in Router-Busy-To-Network,Router-Available-To-Network) */
-               if ((bacnet_mesgtyp == BAC_NET_R_BUSY) || 
+               if ((bacnet_mesgtyp == BAC_NET_R_BUSY) ||
                (bacnet_mesgtyp == BAC_NET_R_AVA) || (bacnet_mesgtyp == BAC_NET_IAM_R) ) {
                    while(tvb_reported_length_remaining(tvb, offset) > 1 ) {
                        proto_tree_add_item(bacnet_tree, hf_bacnet_dnet,
@@ -387,7 +377,7 @@ dissect_bacnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                    }
                }
                /* Initialize-Routing-Table */
-               if ( (bacnet_mesgtyp == BAC_NET_INIT_RTAB) || 
+               if ( (bacnet_mesgtyp == BAC_NET_INIT_RTAB) ||
                    (bacnet_mesgtyp == BAC_NET_INIT_RTAB_ACK) ) {
                    bacnet_rportnum = tvb_get_guint8(tvb, offset);
                    /* number of ports */
@@ -415,7 +405,7 @@ dissect_bacnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                            offset ++;
                        }
                    }
-                   
+
                }
                proto_item_set_len(ti, offset);
        }
@@ -423,11 +413,12 @@ dissect_bacnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 /* dissect BACnet APDU
  */
         next_tvb = tvb_new_subset(tvb,offset,-1,-1);
-        /* Code from Guy Harris */
-        if (!dissector_try_port(bacnet_dissector_table,
-        bacnet_control_net, next_tvb, pinfo, tree)) {
+        if (bacnet_control & BAC_CONTROL_NET) {
                 /* Unknown function - dissect the payload as data */
-                dissect_data(next_tvb, 0, pinfo, tree);
+                call_dissector(data_handle, next_tvb, pinfo, tree);
+        } else {
+               /* APDU - call the APDU dissector */
+               call_dissector(bacapp_handle, next_tvb, pinfo, tree);
         }
 }
 
@@ -438,145 +429,145 @@ proto_register_bacnet(void)
                { &hf_bacnet_version,
                        { "Version",           "bacnet.version",
                        FT_UINT8, BASE_DEC, NULL, 0,
-                       "BACnet Version" }
+                       "BACnet Version", HFILL }
                },
                { &hf_bacnet_control,
                        { "Control",           "bacnet.control",
                        FT_UINT8, BASE_HEX, NULL, 0xff,
-                       "BACnet Control" }
+                       "BACnet Control", HFILL }
                },
                { &hf_bacnet_control_net,
-                       { "NSDU contains",           
+                       { "NSDU contains",
                        "bacnet.control_net",
                        FT_BOOLEAN, 8, TFS(&control_net_set_high),
-                       BAC_CONTROL_NET, "BACnet Control" }
+                       BAC_CONTROL_NET, "BACnet Control", HFILL }
                },
                { &hf_bacnet_control_res1,
-                       { "Reserved",           
+                       { "Reserved",
                        "bacnet.control_res1",
                        FT_BOOLEAN, 8, TFS(&control_res_high),
-                       BAC_CONTROL_RES1, "BACnet Control" }
+                       BAC_CONTROL_RES1, "BACnet Control", HFILL }
                },
                { &hf_bacnet_control_dest,
-                       { "Destination Specifier",           
+                       { "Destination Specifier",
                        "bacnet.control_dest",
                        FT_BOOLEAN, 8, TFS(&control_dest_high),
-                       BAC_CONTROL_DEST, "BACnet Control" }
+                       BAC_CONTROL_DEST, "BACnet Control", HFILL }
                },
                { &hf_bacnet_control_res2,
-                       { "Reserved",           
+                       { "Reserved",
                        "bacnet.control_res2",
                        FT_BOOLEAN, 8, TFS(&control_res_high),
-                       BAC_CONTROL_RES2, "BACnet Control" }
+                       BAC_CONTROL_RES2, "BACnet Control", HFILL }
                },
                { &hf_bacnet_control_src,
-                       { "Source specifier",           
+                       { "Source specifier",
                        "bacnet.control_src",
                        FT_BOOLEAN, 8, TFS(&control_src_high),
-                       BAC_CONTROL_SRC, "BACnet Control" }
+                       BAC_CONTROL_SRC, "BACnet Control", HFILL }
                },
                { &hf_bacnet_control_expect,
-                       { "Expecting Reply",           
+                       { "Expecting Reply",
                        "bacnet.control_expect",
                        FT_BOOLEAN, 8, TFS(&control_expect_high),
-                       BAC_CONTROL_EXPECT, "BACnet Control" }
+                       BAC_CONTROL_EXPECT, "BACnet Control", HFILL }
                },
                { &hf_bacnet_control_prio_high,
-                       { "Priority",           
+                       { "Priority",
                        "bacnet.control_prio_high",
                        FT_BOOLEAN, 8, TFS(&control_prio_high_high),
-                       BAC_CONTROL_PRIO_HIGH, "BACnet Control" }
+                       BAC_CONTROL_PRIO_HIGH, "BACnet Control", HFILL }
                },
                { &hf_bacnet_control_prio_low,
-                       { "Priority",           
+                       { "Priority",
                        "bacnet.control_prio_low",
                        FT_BOOLEAN, 8, TFS(&control_prio_low_high),
-                       BAC_CONTROL_PRIO_LOW, "BACnet Control" }
+                       BAC_CONTROL_PRIO_LOW, "BACnet Control", HFILL }
                },
                { &hf_bacnet_dnet,
                        { "Destination Network Address", "bacnet.dnet",
                        FT_UINT16, BASE_HEX, NULL, 0,
-                       "Destination Network Address" }
+                       "Destination Network Address", HFILL }
                },
                { &hf_bacnet_dlen,
                        { "Destination MAC Layer Address Length", "bacnet.dlen",
                        FT_UINT8, BASE_DEC, NULL, 0,
-                       "Destination MAC Layer Address Length" }
+                       "Destination MAC Layer Address Length", HFILL }
                },
                { &hf_bacnet_dadr_eth,
                        { "Destination ISO 8802-3 MAC Address", "bacnet.dadr_eth",
                        FT_ETHER, BASE_HEX, NULL, 0,
-                       "Destination ISO 8802-3 MAC Address" }
+                       "Destination ISO 8802-3 MAC Address", HFILL }
                },
                { &hf_bacnet_dadr_tmp,
                        { "Unknown Destination MAC", "bacnet.dadr_tmp",
                        FT_BYTES, BASE_HEX, NULL, 0,
-                       "Unknown Destination MAC" }
+                       "Unknown Destination MAC", HFILL }
                },
                { &hf_bacnet_snet,
                        { "Source Network Address", "bacnet.snet",
                        FT_UINT16, BASE_HEX, NULL, 0,
-                       "Source Network Address" }
+                       "Source Network Address", HFILL }
                },
                { &hf_bacnet_slen,
                        { "Source MAC Layer Address Length", "bacnet.slen",
                        FT_UINT8, BASE_DEC, NULL, 0,
-                       "Source MAC Layer Address Length" }
+                       "Source MAC Layer Address Length", HFILL }
                },
                { &hf_bacnet_sadr_eth,
                        { "SADR", "bacnet.sadr_eth",
                        FT_ETHER, BASE_HEX, NULL, 0,
-                       "Source ISO 8802-3 MAC Address" }
+                       "Source ISO 8802-3 MAC Address", HFILL }
                },
                { &hf_bacnet_sadr_tmp,
                        { "Unknown Source MAC", "bacnet.sadr_tmp",
                        FT_BYTES, BASE_HEX, NULL, 0,
-                       "Unknown Source MAC" }
+                       "Unknown Source MAC", HFILL }
                },
                { &hf_bacnet_hopc,
                        { "Hop Count", "bacnet.hopc",
                        FT_UINT8, BASE_DEC, NULL, 0,
-                       "Hop Count" }
+                       "Hop Count", HFILL }
                },
                { &hf_bacnet_mesgtyp,
                        { "Message Type", "bacnet.mesgtyp",
                        FT_UINT8, BASE_HEX, NULL, 0,
-                       "Message Type" }
+                       "Message Type", HFILL }
                },
                { &hf_bacnet_vendor,
                        { "Vendor ID", "bacnet.vendor",
                        FT_UINT16, BASE_HEX, NULL, 0,
-                       "Vendor ID" }
+                       "Vendor ID", HFILL }
                },
                { &hf_bacnet_perf,
                        { "Performance Index", "bacnet.perf",
                        FT_UINT8, BASE_DEC, NULL, 0,
-                       "Performance Index" }
+                       "Performance Index", HFILL }
                },
                { &hf_bacnet_rejectreason,
                        { "Reject Reason", "bacnet.rejectreason",
                        FT_UINT8, BASE_DEC, NULL, 0,
-                       "Reject Reason" }
+                       "Reject Reason", HFILL }
                },
                { &hf_bacnet_rportnum,
                        { "Number of Port Mappings", "bacnet.rportnum",
                        FT_UINT8, BASE_DEC, NULL, 0,
-                       "Number of Port Mappings" }
+                       "Number of Port Mappings", HFILL }
                },
                { &hf_bacnet_pinfolen,
                        { "Port Info Length", "bacnet.pinfolen",
                        FT_UINT8, BASE_DEC, NULL, 0,
-                       "Port Info Length" }
+                       "Port Info Length", HFILL }
                },
                { &hf_bacnet_portid,
                        { "Port ID", "bacnet.portid",
                        FT_UINT8, BASE_HEX, NULL, 0,
-                       "Port ID" }
+                       "Port ID", HFILL }
                },
                { &hf_bacnet_pinfo,
                        { "Port Info", "bacnet.pinfo",
                        FT_UINT8, BASE_HEX, NULL, 0,
-                       "Port Info" }
+                       "Port Info", HFILL }
                },
        };
 
@@ -592,14 +583,19 @@ proto_register_bacnet(void)
        proto_register_subtree_array(ett, array_length(ett));
 
        register_dissector("bacnet", dissect_bacnet, proto_bacnet);
-       bacnet_dissector_table = register_dissector_table("bacnet_control_net");
 }
 
 void
 proto_reg_handoff_bacnet(void)
 {
-       dissector_add("bvlc.function", 0x04, dissect_bacnet, proto_bacnet);
-       dissector_add("bvlc.function", 0x09, dissect_bacnet, proto_bacnet);
-       dissector_add("bvlc.function", 0x0a, dissect_bacnet, proto_bacnet);
-       dissector_add("bvlc.function", 0x0b, dissect_bacnet, proto_bacnet);
+       dissector_handle_t bacnet_handle;
+
+       bacnet_handle = find_dissector("bacnet");
+       dissector_add("bvlc.function", 0x04, bacnet_handle);
+       dissector_add("bvlc.function", 0x09, bacnet_handle);
+       dissector_add("bvlc.function", 0x0a, bacnet_handle);
+       dissector_add("bvlc.function", 0x0b, bacnet_handle);
+       dissector_add("llc.dsap", SAP_BACNET, bacnet_handle);
+       bacapp_handle = find_dissector("bacapp");
+       data_handle = find_dissector("data");
 }