2001-03-31 10:13:13 +00:00
/* packet-bacnet.c
* Routines for BACnet ( NPDU ) dissection
* Copyright 2001 , Hartmut Mueller < hartmut @ abmlinux . org > , FH Dortmund
2005-04-14 09:20:02 +00:00
* Enhanced by Steve Karg , 2005 , < skarg @ users . sourceforge . net >
2001-03-31 10:13:13 +00:00
*
2004-07-18 00:24:25 +00:00
* $ Id $
2001-03-31 10:13:13 +00:00
*
* Ethereal - Network traffic analyzer
2001-04-20 20:34:31 +00:00
* By Gerald Combs < gerald @ ethereal . com >
2001-03-31 10:13:13 +00:00
* Copyright 1998 Gerald Combs
*
* Copied from README . developer , v 1.23
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version 2
* of the License , or ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
*/
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <glib.h>
2002-01-21 07:37:49 +00:00
# include <epan/packet.h>
2001-03-31 10:13:13 +00:00
2005-09-17 00:02:31 +00:00
# include <epan/llcsaps.h>
2002-11-16 08:55:13 +00:00
2001-12-08 06:41:48 +00:00
static dissector_handle_t bacapp_handle ;
2001-11-26 04:52:51 +00:00
static dissector_handle_t data_handle ;
2001-03-31 10:13:13 +00:00
static const char *
bacnet_mesgtyp_name ( guint8 bacnet_mesgtyp ) {
static const char * type_names [ ] = {
" Who-Is-Router-To-Network " ,
" I-Am-Router-To-Network " ,
" I-Could-Be-Router-To-Network " ,
" Reject-Message-To-Network " ,
" Router-Busy-To-Network " ,
" Router-Available-To-Network " ,
" Initialize-Routing-Table " ,
" Initialize-Routing-Table-Ack " ,
" Establish-Connection-To-Network " ,
" Disconnect-Connection-To-Network "
} ;
if ( bacnet_mesgtyp < 0x0a ) {
return type_names [ bacnet_mesgtyp ] ;
} else {
return ( bacnet_mesgtyp < 0x80 ) ? " Reserved for Use by ASHRAE " : " Vendor Proprietary Message " ;
}
}
static const char *
bacnet_rejectreason_name ( guint8 bacnet_rejectreason ) {
static const char * type_names [ ] = {
" Other error. " ,
" The router is not directly connected to DNET and cannot find a router to DNET on any directly connected network using Who-Is-Router-To-Network messages. " ,
" The router is busy and unable to accept messages for the specified DNET at the present time. " ,
" It is an unknown network layer message type. " ,
" The message is too long to be routed to this DNET. " ,
" The router is no longer directly connected to DNET but can reconnect if requested. " ,
" The router is no longer directly connected to DNET and cannot reconnect even if requested. "
} ;
return ( bacnet_rejectreason > 6 ) ? " Invalid Rejection Reason. " : type_names [ bacnet_rejectreason ] ;
}
/* Network Layer Control Information */
# define BAC_CONTROL_NET 0x80
# define BAC_CONTROL_RES1 0x40
# define BAC_CONTROL_DEST 0x20
# define BAC_CONTROL_RES2 0x10
# define BAC_CONTROL_SRC 0x08
# define BAC_CONTROL_EXPECT 0x04
# define BAC_CONTROL_PRIO_HIGH 0x02
# define BAC_CONTROL_PRIO_LOW 0x01
/* Network Layer Message Types */
# define BAC_NET_WHO_R 0x00
# define BAC_NET_IAM_R 0x01
# define BAC_NET_ICB_R 0x02
# define BAC_NET_REJ 0x03
# define BAC_NET_R_BUSY 0x04
# define BAC_NET_R_AVA 0x05
# define BAC_NET_INIT_RTAB 0x06
# define BAC_NET_INIT_RTAB_ACK 0x07
# define BAC_NET_EST_CON 0x08
# define BAC_NET_DISC_CON 0x09
static const true_false_string control_net_set_high = {
" network layer message, message type field present. " ,
" BACnet APDU, message type field absent. "
} ;
static const true_false_string control_res_high = {
" Shall be zero, but is one. " ,
" Shall be zero and is zero. "
} ;
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. "
} ;
2002-08-28 21:04:11 +00:00
2001-03-31 10:13:13 +00:00
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 "
} ;
static const true_false_string control_expect_high = {
" BACnet-Confirmed-Request-PDU, a segment of BACnet-ComplexACK-PDU or Network Message expecting a reply present. " ,
" Other than a BACnet-Confirmed-Request-PDU, segment of BACnet-ComplexACK-PDU or network layer message expecting a reply present. "
} ;
static const true_false_string control_prio_high_high = {
" Life Safety or Critical Equipment message. " ,
" Not a Life Safety or Critical Equipment message. "
} ;
static const true_false_string control_prio_low_high = {
" Urgent message " ,
" Normal message "
} ;
static int proto_bacnet = - 1 ;
static int hf_bacnet_version = - 1 ;
static int hf_bacnet_control = - 1 ;
static int hf_bacnet_control_net = - 1 ;
static int hf_bacnet_control_res1 = - 1 ;
static int hf_bacnet_control_dest = - 1 ;
static int hf_bacnet_control_res2 = - 1 ;
static int hf_bacnet_control_src = - 1 ;
static int hf_bacnet_control_expect = - 1 ;
static int hf_bacnet_control_prio_high = - 1 ;
static int hf_bacnet_control_prio_low = - 1 ;
static int hf_bacnet_dnet = - 1 ;
static int hf_bacnet_dlen = - 1 ;
static int hf_bacnet_dadr_eth = - 1 ;
2005-04-14 09:20:02 +00:00
static int hf_bacnet_dadr_mstp = - 1 ;
2001-03-31 10:13:13 +00:00
static int hf_bacnet_dadr_tmp = - 1 ;
static int hf_bacnet_snet = - 1 ;
static int hf_bacnet_slen = - 1 ;
static int hf_bacnet_sadr_eth = - 1 ;
2005-04-14 09:20:02 +00:00
static int hf_bacnet_sadr_mstp = - 1 ;
2001-03-31 10:13:13 +00:00
static int hf_bacnet_sadr_tmp = - 1 ;
static int hf_bacnet_hopc = - 1 ;
static int hf_bacnet_mesgtyp = - 1 ;
static int hf_bacnet_vendor = - 1 ;
static int hf_bacnet_perf = - 1 ;
static int hf_bacnet_rejectreason = - 1 ;
static int hf_bacnet_rportnum = - 1 ;
static int hf_bacnet_portid = - 1 ;
static int hf_bacnet_pinfolen = - 1 ;
static int hf_bacnet_pinfo = - 1 ;
static gint ett_bacnet = - 1 ;
static gint ett_bacnet_control = - 1 ;
static void
dissect_bacnet ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree )
{
proto_item * ti ;
proto_item * ct ;
proto_tree * bacnet_tree ;
proto_tree * control_tree ;
gint offset ;
guint8 bacnet_version ;
guint8 bacnet_control ;
guint8 bacnet_dlen ;
guint8 bacnet_slen ;
guint8 bacnet_mesgtyp ;
guint8 bacnet_rejectreason ;
guint8 bacnet_rportnum ;
guint8 bacnet_pinfolen ;
guint8 i ;
guint8 j ;
tvbuff_t * next_tvb ;
2002-08-28 21:04:11 +00:00
if ( check_col ( pinfo - > cinfo , COL_PROTOCOL ) )
2001-12-10 00:26:21 +00:00
col_set_str ( pinfo - > cinfo , COL_PROTOCOL , " BACnet-NPDU " ) ;
2001-03-31 10:13:13 +00:00
2002-08-28 21:04:11 +00:00
if ( check_col ( pinfo - > cinfo , COL_INFO ) )
2001-12-10 00:26:21 +00:00
col_set_str ( pinfo - > cinfo , COL_INFO , " Building Automation and Control Network NPDU " ) ;
2001-03-31 10:13:13 +00:00
offset = 0 ;
bacnet_version = tvb_get_guint8 ( tvb , offset ) ;
bacnet_control = tvb_get_guint8 ( tvb , offset + 1 ) ;
bacnet_dlen = 0 ;
bacnet_slen = 0 ;
bacnet_mesgtyp = 0 ;
bacnet_rejectreason = 0 ;
bacnet_rportnum = 0 ;
bacnet_pinfolen = 0 ;
i = 0 ;
j = 0 ;
2004-05-12 19:55:14 +00:00
/* I don't know the length of the NPDU by now. Setting the length after dissection */
ti = proto_tree_add_item ( tree , proto_bacnet , tvb , 0 , - 1 , FALSE ) ;
2001-03-31 10:13:13 +00:00
2004-05-12 19:55:14 +00:00
bacnet_tree = proto_item_add_subtree ( ti , ett_bacnet ) ;
2001-03-31 10:13:13 +00:00
2006-02-16 11:43:38 +00:00
proto_tree_add_uint_format_value ( bacnet_tree , hf_bacnet_version , tvb ,
2004-05-12 19:55:14 +00:00
offset , 1 ,
2006-02-16 11:43:38 +00:00
bacnet_version , " 0x%02x (%s) " , bacnet_version ,
2004-05-12 19:55:14 +00:00
( bacnet_version = = 0x01 ) ? " ASHRAE 135-1995 " : " unknown " ) ;
offset + + ;
ct = proto_tree_add_uint ( bacnet_tree , hf_bacnet_control ,
tvb , offset , 1 , bacnet_control ) ;
control_tree = proto_item_add_subtree ( ct , ett_bacnet_control ) ;
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 ,
offset , 1 , bacnet_control ) ;
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 ,
offset , 1 , bacnet_control ) ;
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 ,
offset , 1 , bacnet_control ) ;
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 ,
tvb , offset , 1 , bacnet_control ) ;
offset + + ;
if ( bacnet_control & BAC_CONTROL_DEST ) { /* DNET, DLEN, DADR */
proto_tree_add_item ( bacnet_tree , hf_bacnet_dnet ,
tvb , offset , 2 , FALSE ) ;
offset + = 2 ;
bacnet_dlen = tvb_get_guint8 ( tvb , offset ) ;
/* DLEN = 0 is broadcast on dest.network */
if ( bacnet_dlen = = 0 ) {
/* append to hf_bacnet_dlen: broadcast */
2006-02-16 11:43:38 +00:00
proto_tree_add_uint_format_value ( bacnet_tree ,
2004-05-12 19:55:14 +00:00
hf_bacnet_dlen , tvb , offset , 1 , bacnet_dlen ,
2006-02-16 11:43:38 +00:00
" %d indicates Broadcast on Destination Network " ,
2004-05-12 19:55:14 +00:00
bacnet_dlen ) ;
2001-03-31 10:13:13 +00:00
offset + + ;
2004-05-12 19:55:14 +00:00
/* going to SNET */
} else if ( bacnet_dlen = = 6 ) {
proto_tree_add_uint ( bacnet_tree , hf_bacnet_dlen ,
tvb , offset , 1 , bacnet_dlen ) ;
offset + + ;
/* Ethernet MAC */
proto_tree_add_item ( bacnet_tree ,
hf_bacnet_dadr_eth , tvb , offset ,
bacnet_dlen , FALSE ) ;
offset + = bacnet_dlen ;
2005-04-14 09:20:02 +00:00
} else if ( bacnet_dlen = = 1 ) {
proto_tree_add_uint ( bacnet_tree , hf_bacnet_dlen ,
tvb , offset , 1 , bacnet_dlen ) ;
offset + + ;
/* MS/TP or ARCNET MAC */
proto_tree_add_item ( bacnet_tree ,
hf_bacnet_dadr_mstp , tvb , offset ,
bacnet_dlen , FALSE ) ;
offset + = bacnet_dlen ;
2004-05-12 19:55:14 +00:00
} else if ( bacnet_dlen < 7 ) {
proto_tree_add_uint ( bacnet_tree , hf_bacnet_dlen ,
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 ,
bacnet_dlen , FALSE ) ;
offset + = bacnet_dlen ;
} else {
2006-02-16 11:43:38 +00:00
proto_tree_add_uint_format_value ( bacnet_tree ,
2004-05-12 19:55:14 +00:00
hf_bacnet_dlen , tvb , offset , 1 , bacnet_dlen ,
2006-02-16 11:43:38 +00:00
" %d invalid! " ,
2004-05-12 19:55:14 +00:00
bacnet_dlen ) ;
2001-03-31 10:13:13 +00:00
}
2004-05-12 19:55:14 +00:00
}
if ( bacnet_control & BAC_CONTROL_SRC ) { /* SNET, SLEN, SADR */
/* SNET */
proto_tree_add_uint ( bacnet_tree , hf_bacnet_snet ,
tvb , offset , 2 , tvb_get_ntohs ( tvb , offset ) ) ;
offset + = 2 ;
bacnet_slen = tvb_get_guint8 ( tvb , offset ) ;
if ( bacnet_slen = = 0 ) { /* SLEN = 0 invalid */
2006-02-16 11:43:38 +00:00
proto_tree_add_uint_format_value ( bacnet_tree ,
2004-05-12 19:55:14 +00:00
hf_bacnet_slen , tvb , offset , 1 , bacnet_slen ,
2006-02-16 11:43:38 +00:00
" %d invalid! " ,
2004-05-12 19:55:14 +00:00
bacnet_slen ) ;
2001-03-31 10:13:13 +00:00
offset + + ;
2004-05-12 19:55:14 +00:00
} else if ( bacnet_slen = = 6 ) {
/* SLEN */
proto_tree_add_uint ( bacnet_tree , hf_bacnet_slen ,
tvb , offset , 1 , bacnet_slen ) ;
2001-03-31 10:13:13 +00:00
offset + + ;
2004-05-12 19:55:14 +00:00
/* Ethernet MAC */
proto_tree_add_item ( bacnet_tree ,
hf_bacnet_sadr_eth , tvb , offset ,
bacnet_slen , FALSE ) ;
offset + = bacnet_slen ;
2005-04-14 09:20:02 +00:00
} else if ( bacnet_slen = = 1 ) {
/* SLEN */
proto_tree_add_uint ( bacnet_tree , hf_bacnet_slen ,
tvb , offset , 1 , bacnet_slen ) ;
offset + + ;
/* MS/TP or ARCNET MAC */
proto_tree_add_item ( bacnet_tree ,
hf_bacnet_sadr_mstp , tvb , offset ,
bacnet_slen , FALSE ) ;
offset + = bacnet_slen ;
} else if ( bacnet_slen < 6 ) { /* LON MAC */
2004-05-12 19:55:14 +00:00
/* SLEN */
proto_tree_add_uint ( bacnet_tree , hf_bacnet_slen ,
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 ,
bacnet_slen , FALSE ) ;
offset + = bacnet_slen ;
} else {
2006-02-16 11:43:38 +00:00
proto_tree_add_uint_format_value ( bacnet_tree ,
2004-05-12 19:55:14 +00:00
hf_bacnet_slen , tvb , offset , 1 , bacnet_slen ,
2006-02-16 11:43:38 +00:00
" %d invalid! " ,
2004-05-12 19:55:14 +00:00
bacnet_slen ) ;
2001-03-31 10:13:13 +00:00
offset + + ;
}
2004-05-12 19:55:14 +00:00
}
if ( bacnet_control & BAC_CONTROL_DEST ) { /* Hopcount */
proto_tree_add_item ( bacnet_tree , hf_bacnet_hopc ,
tvb , offset , 1 , FALSE ) ;
offset + + ;
}
/* Network Layer Message Type */
if ( bacnet_control & BAC_CONTROL_NET ) {
bacnet_mesgtyp = tvb_get_guint8 ( tvb , offset ) ;
2006-02-16 11:43:38 +00:00
proto_tree_add_uint_format_value ( bacnet_tree ,
2004-05-12 19:55:14 +00:00
hf_bacnet_mesgtyp , tvb , offset , 1 , bacnet_mesgtyp ,
2006-02-16 11:43:38 +00:00
" %02x (%s) " , bacnet_mesgtyp ,
2004-05-12 19:55:14 +00:00
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
* 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 . . .
*/
if ( ( bacnet_mesgtyp > 0x7f ) & & ( bacnet_control = = BAC_CONTROL_NET ) ) {
proto_tree_add_item ( bacnet_tree , hf_bacnet_vendor ,
tvb , offset , 2 , FALSE ) ;
offset + = 2 ;
/* attention: doesnt work here because of if(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 ) {
proto_tree_add_item ( bacnet_tree , hf_bacnet_perf ,
tvb , offset , 1 , FALSE ) ;
offset + + ;
}
/* Reason, DNET (in Reject-Message-To-Network) */
if ( bacnet_mesgtyp = = BAC_NET_REJ ) {
bacnet_rejectreason = tvb_get_guint8 ( tvb , offset ) ;
2006-02-16 11:43:38 +00:00
proto_tree_add_uint_format_value ( bacnet_tree ,
2004-05-12 19:55:14 +00:00
hf_bacnet_rejectreason ,
tvb , offset , 1 ,
2006-02-16 11:43:38 +00:00
bacnet_rejectreason , " %d (%s) " ,
2004-05-12 19:55:14 +00:00
bacnet_rejectreason ,
bacnet_rejectreason_name ( bacnet_rejectreason ) ) ;
offset + + ;
proto_tree_add_item ( bacnet_tree , hf_bacnet_dnet ,
tvb , offset , 2 , FALSE ) ;
offset + = 2 ;
}
/* N*DNET (in Router-Busy-To-Network,Router-Available-To-Network) */
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 ) {
2001-03-31 10:13:13 +00:00
proto_tree_add_item ( bacnet_tree , hf_bacnet_dnet ,
tvb , offset , 2 , FALSE ) ;
offset + = 2 ;
}
2004-05-12 19:55:14 +00:00
}
/* Initialize-Routing-Table */
if ( ( bacnet_mesgtyp = = BAC_NET_INIT_RTAB ) | |
( bacnet_mesgtyp = = BAC_NET_INIT_RTAB_ACK ) ) {
bacnet_rportnum = tvb_get_guint8 ( tvb , offset ) ;
/* number of ports */
proto_tree_add_uint ( bacnet_tree , hf_bacnet_rportnum ,
2001-03-31 10:13:13 +00:00
tvb , offset , 1 , bacnet_rportnum ) ;
2004-05-12 19:55:14 +00:00
offset + + ;
for ( i = 0 ; i > bacnet_rportnum ; i + + ) {
2001-03-31 10:13:13 +00:00
/* Connected DNET */
proto_tree_add_item ( bacnet_tree , hf_bacnet_dnet ,
tvb , offset , 2 , FALSE ) ;
offset + = 2 ;
/* Port ID */
proto_tree_add_item ( bacnet_tree , hf_bacnet_portid ,
tvb , offset , 1 , FALSE ) ;
offset + + ;
/* Port Info Length */
bacnet_pinfolen = tvb_get_guint8 ( tvb , offset ) ;
proto_tree_add_uint ( bacnet_tree , hf_bacnet_pinfolen ,
tvb , offset , 1 , bacnet_pinfolen ) ;
offset + + ;
for ( j = 0 ; j > bacnet_pinfolen ; j + + ) {
/* Port Info */
proto_tree_add_item ( bacnet_tree , hf_bacnet_pinfo ,
tvb , offset , 1 , FALSE ) ;
offset + + ;
}
}
}
2004-05-12 19:55:14 +00:00
proto_item_set_len ( ti , offset ) ;
2001-03-31 10:13:13 +00:00
/* dissect BACnet APDU
*/
next_tvb = tvb_new_subset ( tvb , offset , - 1 , - 1 ) ;
2001-12-08 06:41:48 +00:00
if ( bacnet_control & BAC_CONTROL_NET ) {
2001-03-31 10:13:13 +00:00
/* Unknown function - dissect the payload as data */
2001-12-08 06:41:48 +00:00
call_dissector ( data_handle , next_tvb , pinfo , tree ) ;
} else {
/* APDU - call the APDU dissector */
call_dissector ( bacapp_handle , next_tvb , pinfo , tree ) ;
2001-03-31 10:13:13 +00:00
}
}
void
proto_register_bacnet ( void )
{
static hf_register_info hf [ ] = {
{ & hf_bacnet_version ,
{ " Version " , " bacnet.version " ,
FT_UINT8 , BASE_DEC , NULL , 0 ,
2001-06-18 02:18:27 +00:00
" BACnet Version " , HFILL }
2001-03-31 10:13:13 +00:00
} ,
{ & hf_bacnet_control ,
{ " Control " , " bacnet.control " ,
2004-05-12 19:55:14 +00:00
FT_UINT8 , BASE_HEX , NULL , 0 ,
2001-06-18 02:18:27 +00:00
" BACnet Control " , HFILL }
2001-03-31 10:13:13 +00:00
} ,
{ & hf_bacnet_control_net ,
2002-08-28 21:04:11 +00:00
{ " NSDU contains " ,
2001-03-31 10:13:13 +00:00
" bacnet.control_net " ,
FT_BOOLEAN , 8 , TFS ( & control_net_set_high ) ,
2001-06-18 02:18:27 +00:00
BAC_CONTROL_NET , " BACnet Control " , HFILL }
2001-03-31 10:13:13 +00:00
} ,
{ & hf_bacnet_control_res1 ,
2002-08-28 21:04:11 +00:00
{ " Reserved " ,
2001-03-31 10:13:13 +00:00
" bacnet.control_res1 " ,
FT_BOOLEAN , 8 , TFS ( & control_res_high ) ,
2001-06-18 02:18:27 +00:00
BAC_CONTROL_RES1 , " BACnet Control " , HFILL }
2001-03-31 10:13:13 +00:00
} ,
{ & hf_bacnet_control_dest ,
2002-08-28 21:04:11 +00:00
{ " Destination Specifier " ,
2001-03-31 10:13:13 +00:00
" bacnet.control_dest " ,
FT_BOOLEAN , 8 , TFS ( & control_dest_high ) ,
2001-06-18 02:18:27 +00:00
BAC_CONTROL_DEST , " BACnet Control " , HFILL }
2001-03-31 10:13:13 +00:00
} ,
{ & hf_bacnet_control_res2 ,
2002-08-28 21:04:11 +00:00
{ " Reserved " ,
2001-03-31 10:13:13 +00:00
" bacnet.control_res2 " ,
FT_BOOLEAN , 8 , TFS ( & control_res_high ) ,
2001-06-18 02:18:27 +00:00
BAC_CONTROL_RES2 , " BACnet Control " , HFILL }
2001-03-31 10:13:13 +00:00
} ,
{ & hf_bacnet_control_src ,
2002-08-28 21:04:11 +00:00
{ " Source specifier " ,
2001-03-31 10:13:13 +00:00
" bacnet.control_src " ,
FT_BOOLEAN , 8 , TFS ( & control_src_high ) ,
2001-06-18 02:18:27 +00:00
BAC_CONTROL_SRC , " BACnet Control " , HFILL }
2001-03-31 10:13:13 +00:00
} ,
{ & hf_bacnet_control_expect ,
2002-08-28 21:04:11 +00:00
{ " Expecting Reply " ,
2001-03-31 10:13:13 +00:00
" bacnet.control_expect " ,
FT_BOOLEAN , 8 , TFS ( & control_expect_high ) ,
2001-06-18 02:18:27 +00:00
BAC_CONTROL_EXPECT , " BACnet Control " , HFILL }
2001-03-31 10:13:13 +00:00
} ,
{ & hf_bacnet_control_prio_high ,
2002-08-28 21:04:11 +00:00
{ " Priority " ,
2001-03-31 10:13:13 +00:00
" bacnet.control_prio_high " ,
FT_BOOLEAN , 8 , TFS ( & control_prio_high_high ) ,
2001-06-18 02:18:27 +00:00
BAC_CONTROL_PRIO_HIGH , " BACnet Control " , HFILL }
2001-03-31 10:13:13 +00:00
} ,
{ & hf_bacnet_control_prio_low ,
2002-08-28 21:04:11 +00:00
{ " Priority " ,
2001-03-31 10:13:13 +00:00
" bacnet.control_prio_low " ,
FT_BOOLEAN , 8 , TFS ( & control_prio_low_high ) ,
2001-06-18 02:18:27 +00:00
BAC_CONTROL_PRIO_LOW , " BACnet Control " , HFILL }
2001-03-31 10:13:13 +00:00
} ,
{ & hf_bacnet_dnet ,
{ " Destination Network Address " , " bacnet.dnet " ,
2005-04-14 09:20:02 +00:00
FT_UINT16 , BASE_DEC , NULL , 0 ,
2001-06-18 02:18:27 +00:00
" Destination Network Address " , HFILL }
2001-03-31 10:13:13 +00:00
} ,
{ & hf_bacnet_dlen ,
{ " Destination MAC Layer Address Length " , " bacnet.dlen " ,
FT_UINT8 , BASE_DEC , NULL , 0 ,
2001-06-18 02:18:27 +00:00
" Destination MAC Layer Address Length " , HFILL }
2001-03-31 10:13:13 +00:00
} ,
{ & hf_bacnet_dadr_eth ,
{ " Destination ISO 8802-3 MAC Address " , " bacnet.dadr_eth " ,
FT_ETHER , BASE_HEX , NULL , 0 ,
2001-06-18 02:18:27 +00:00
" Destination ISO 8802-3 MAC Address " , HFILL }
2001-03-31 10:13:13 +00:00
} ,
2005-04-14 09:20:02 +00:00
{ & hf_bacnet_dadr_mstp ,
{ " DADR " , " bacnet.dadr_mstp " ,
FT_UINT8 , BASE_DEC , NULL , 0 ,
" Destination MS/TP or ARCNET MAC Address " , HFILL }
} ,
2001-03-31 10:13:13 +00:00
{ & hf_bacnet_dadr_tmp ,
{ " Unknown Destination MAC " , " bacnet.dadr_tmp " ,
FT_BYTES , BASE_HEX , NULL , 0 ,
2001-06-18 02:18:27 +00:00
" Unknown Destination MAC " , HFILL }
2001-03-31 10:13:13 +00:00
} ,
{ & hf_bacnet_snet ,
{ " Source Network Address " , " bacnet.snet " ,
2005-04-14 09:20:02 +00:00
FT_UINT16 , BASE_DEC , NULL , 0 ,
2001-06-18 02:18:27 +00:00
" Source Network Address " , HFILL }
2001-03-31 10:13:13 +00:00
} ,
{ & hf_bacnet_slen ,
{ " Source MAC Layer Address Length " , " bacnet.slen " ,
FT_UINT8 , BASE_DEC , NULL , 0 ,
2001-06-18 02:18:27 +00:00
" Source MAC Layer Address Length " , HFILL }
2001-03-31 10:13:13 +00:00
} ,
{ & hf_bacnet_sadr_eth ,
{ " SADR " , " bacnet.sadr_eth " ,
FT_ETHER , BASE_HEX , NULL , 0 ,
2001-06-18 02:18:27 +00:00
" Source ISO 8802-3 MAC Address " , HFILL }
2001-03-31 10:13:13 +00:00
} ,
2005-04-14 09:20:02 +00:00
{ & hf_bacnet_sadr_mstp ,
{ " SADR " , " bacnet.sadr_mstp " ,
FT_UINT8 , BASE_DEC , NULL , 0 ,
" Source MS/TP or ARCNET MAC Address " , HFILL }
} ,
2001-03-31 10:13:13 +00:00
{ & hf_bacnet_sadr_tmp ,
{ " Unknown Source MAC " , " bacnet.sadr_tmp " ,
FT_BYTES , BASE_HEX , NULL , 0 ,
2001-06-18 02:18:27 +00:00
" Unknown Source MAC " , HFILL }
2001-03-31 10:13:13 +00:00
} ,
{ & hf_bacnet_hopc ,
{ " Hop Count " , " bacnet.hopc " ,
FT_UINT8 , BASE_DEC , NULL , 0 ,
2001-06-18 02:18:27 +00:00
" Hop Count " , HFILL }
2001-03-31 10:13:13 +00:00
} ,
{ & hf_bacnet_mesgtyp ,
2006-02-16 11:43:38 +00:00
{ " Network Layer Message Type " , " bacnet.mesgtyp " ,
2001-03-31 10:13:13 +00:00
FT_UINT8 , BASE_HEX , NULL , 0 ,
2006-02-16 11:43:38 +00:00
" Network Layer Message Type " , HFILL }
2001-03-31 10:13:13 +00:00
} ,
{ & hf_bacnet_vendor ,
{ " Vendor ID " , " bacnet.vendor " ,
2005-04-14 09:20:02 +00:00
FT_UINT16 , BASE_DEC , NULL , 0 ,
2001-06-18 02:18:27 +00:00
" Vendor ID " , HFILL }
2001-03-31 10:13:13 +00:00
} ,
{ & hf_bacnet_perf ,
{ " Performance Index " , " bacnet.perf " ,
FT_UINT8 , BASE_DEC , NULL , 0 ,
2001-06-18 02:18:27 +00:00
" Performance Index " , HFILL }
2001-03-31 10:13:13 +00:00
} ,
{ & hf_bacnet_rejectreason ,
{ " Reject Reason " , " bacnet.rejectreason " ,
FT_UINT8 , BASE_DEC , NULL , 0 ,
2001-06-18 02:18:27 +00:00
" Reject Reason " , HFILL }
2001-03-31 10:13:13 +00:00
} ,
{ & hf_bacnet_rportnum ,
{ " Number of Port Mappings " , " bacnet.rportnum " ,
FT_UINT8 , BASE_DEC , NULL , 0 ,
2001-06-18 02:18:27 +00:00
" Number of Port Mappings " , HFILL }
2001-03-31 10:13:13 +00:00
} ,
{ & hf_bacnet_pinfolen ,
{ " Port Info Length " , " bacnet.pinfolen " ,
FT_UINT8 , BASE_DEC , NULL , 0 ,
2001-06-18 02:18:27 +00:00
" Port Info Length " , HFILL }
2001-03-31 10:13:13 +00:00
} ,
{ & hf_bacnet_portid ,
{ " Port ID " , " bacnet.portid " ,
FT_UINT8 , BASE_HEX , NULL , 0 ,
2001-06-18 02:18:27 +00:00
" Port ID " , HFILL }
2001-03-31 10:13:13 +00:00
} ,
{ & hf_bacnet_pinfo ,
{ " Port Info " , " bacnet.pinfo " ,
FT_UINT8 , BASE_HEX , NULL , 0 ,
2001-06-18 02:18:27 +00:00
" Port Info " , HFILL }
2001-03-31 10:13:13 +00:00
} ,
} ;
static gint * ett [ ] = {
& ett_bacnet ,
& ett_bacnet_control ,
} ;
proto_bacnet = proto_register_protocol ( " Building Automation and Control Network NPDU " ,
" BACnet " , " bacnet " ) ;
proto_register_field_array ( proto_bacnet , hf , array_length ( hf ) ) ;
proto_register_subtree_array ( ett , array_length ( ett ) ) ;
register_dissector ( " bacnet " , dissect_bacnet , proto_bacnet ) ;
}
void
proto_reg_handoff_bacnet ( void )
{
2001-12-03 04:00:26 +00:00
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 ) ;
2002-11-16 08:55:13 +00:00
dissector_add ( " llc.dsap " , SAP_BACNET , bacnet_handle ) ;
2001-12-08 06:41:48 +00:00
bacapp_handle = find_dissector ( " bacapp " ) ;
2001-11-26 04:52:51 +00:00
data_handle = find_dissector ( " data " ) ;
2001-03-31 10:13:13 +00:00
}