| File: | builds/wireshark/wireshark/epan/dissectors/packet-bvlc.c |
| Warning: | line 727, column 3 Value stored to 'offset' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* packet-bvlc.c |
| 2 | * Routines for BACnet/IP (BVLL, BVLC) dissection |
| 3 | * Copyright 2001, Hartmut Mueller <[email protected]>, FH Dortmund |
| 4 | * |
| 5 | * Wireshark - Network traffic analyzer |
| 6 | * By Gerald Combs <[email protected]> |
| 7 | * Copyright 1998 Gerald Combs |
| 8 | * |
| 9 | * Copied from README.developer,v 1.23 |
| 10 | * |
| 11 | * SPDX-License-Identifier: GPL-2.0-or-later |
| 12 | */ |
| 13 | |
| 14 | #include "config.h" |
| 15 | |
| 16 | #include <epan/packet.h> |
| 17 | #include <epan/tfs.h> |
| 18 | |
| 19 | #include "packet-bacnet.h" |
| 20 | #include "packet-bacapp.h" |
| 21 | |
| 22 | void proto_register_bvlc(void); |
| 23 | void proto_reg_handoff_bvlc(void); |
| 24 | |
| 25 | #define BVLC_UDP_PORT0xBAC0 0xBAC0 |
| 26 | |
| 27 | /* Network Layer Wrapper Control Information */ |
| 28 | #define BAC_WRAPPER_CONTROL_NET0x80 0x80 |
| 29 | #define BAC_WRAPPER_MSG_ENCRYPED0x40 0x40 |
| 30 | #define BAC_WRAPPER_RESERVED0x20 0x20 |
| 31 | #define BAC_WRAPPER_AUTHD_PRESENT0x10 0x10 |
| 32 | #define BAC_WRAPPER_DO_NOT_UNWRAP0x08 0x08 |
| 33 | #define BAC_WRAPPER_DO_NOT_DECRPT0x04 0x04 |
| 34 | #define BAC_WRAPPER_NO_TRUST_SRC0x02 0x02 |
| 35 | #define BAC_WRAPPER_SECURE_BY_RTR0x01 0x01 |
| 36 | |
| 37 | static int proto_bvlc; |
| 38 | static int proto_bscvlc; |
| 39 | static int hf_bvlc_type; |
| 40 | static int hf_bvlc_function; |
| 41 | static int hf_bvlc_ipv6_function; |
| 42 | static int hf_bvlc_length; |
| 43 | static int hf_bvlc_result_ip4; |
| 44 | static int hf_bvlc_result_ip6; |
| 45 | static int hf_bvlc_bdt_ip; |
| 46 | static int hf_bvlc_bdt_mask; |
| 47 | static int hf_bvlc_bdt_port; |
| 48 | static int hf_bvlc_reg_ttl; |
| 49 | static int hf_bvlc_fdt_ip; |
| 50 | static int hf_bvlc_fdt_ipv6; |
| 51 | static int hf_bvlc_fdt_port; |
| 52 | static int hf_bvlc_fdt_ttl; |
| 53 | static int hf_bvlc_fdt_timeout; |
| 54 | static int hf_bvlc_fwd_ip; |
| 55 | static int hf_bvlc_fwd_port; |
| 56 | static int hf_bvlc_virt_source; |
| 57 | static int hf_bvlc_virt_dest; |
| 58 | static int hf_bvlc_orig_source_addr; |
| 59 | static int hf_bvlc_orig_source_port; |
| 60 | static int hf_bscvlc_control; |
| 61 | static int hf_bscvlc_control_data_option; |
| 62 | static int hf_bscvlc_control_destination_option; |
| 63 | static int hf_bscvlc_control_destination_address; |
| 64 | static int hf_bscvlc_control_origin_address; |
| 65 | static int hf_bscvlc_control_reserved; |
| 66 | static int hf_bscvlc_header; |
| 67 | static int hf_bscvlc_header_marker; |
| 68 | static int hf_bscvlc_header_length; |
| 69 | static int hf_bscvlc_header_data; |
| 70 | static int hf_bscvlc_header_opt_type; |
| 71 | static int hf_bscvlc_header_opt_data; |
| 72 | static int hf_bscvlc_header_opt_must_understand; |
| 73 | static int hf_bscvlc_header_opt_more; |
| 74 | static int hf_bscvlc_vendor_id; |
| 75 | static int hf_bscvlc_proprietary_opt_type; |
| 76 | static int hf_bscvlc_proprietary_data; |
| 77 | static int hf_bscvlc_hub_conn_state; |
| 78 | static int hf_bscvlc_accept_conns; |
| 79 | static int hf_bscvlc_max_bvlc_length; |
| 80 | static int hf_bscvlc_max_npdu_length; |
| 81 | static int hf_bscvlc_function; |
| 82 | static int hf_bscvlc_result; |
| 83 | static int hf_bscvlc_error_class; |
| 84 | static int hf_bscvlc_error_code; |
| 85 | static int hf_bscvlc_result_data; |
| 86 | static int hf_bscvlc_uris; |
| 87 | static int hf_bscvlc_msg_id; |
| 88 | static int hf_bscvlc_orig_vmac; |
| 89 | static int hf_bscvlc_dest_vmac; |
| 90 | static int hf_bscvlc_connect_vmac; |
| 91 | static int hf_bscvlc_connect_uuid; |
| 92 | static int hf_bscvlc_identity_device_id; |
| 93 | static int hf_bscvlc_hello_opt; |
| 94 | static int hf_bscvlc_hello_opt_identity_relay; |
| 95 | |
| 96 | static dissector_table_t bvlc_dissector_table; |
| 97 | static dissector_table_t bscvlc_dissector_table; |
| 98 | static dissector_table_t bvlc_ipv6_dissector_table; |
| 99 | static dissector_handle_t bvlc_handle; |
| 100 | static dissector_handle_t bscvlc_handle; |
| 101 | |
| 102 | static const value_string bvlc_function_names[] = { |
| 103 | { 0x00, "BVLC-Result" }, |
| 104 | { 0x01, "Write-Broadcast-Distribution-Table" }, |
| 105 | { 0x02, "Read-Broadcast-Distribution-Table" }, |
| 106 | { 0x03, "Read-Broadcast-Distribution-Table-Ack" }, |
| 107 | { 0x04, "Forwarded-NPDU" }, |
| 108 | { 0x05, "Register-Foreign-Device" }, |
| 109 | { 0x06, "Read-Foreign-Device-Table" }, |
| 110 | { 0x07, "Read-Foreign-Device-Table-Ack" }, |
| 111 | { 0x08, "Delete-Foreign-Device-Table-Entry" }, |
| 112 | { 0x09, "Distribute-Broadcast-To-Network" }, |
| 113 | { 0x0a, "Original-Unicast-NPDU" }, |
| 114 | { 0x0b, "Original-Broadcast-NPDU" }, |
| 115 | { 0x0c, "Secured-BVLL" }, |
| 116 | { 0, NULL((void*)0) } |
| 117 | }; |
| 118 | |
| 119 | static const value_string bscvlc_function_names[] = { |
| 120 | { 0x00, "BVLC-Result" }, |
| 121 | { 0x01, "Encapsulated-NPDU" }, |
| 122 | { 0x02, "Address-Resolution" }, |
| 123 | { 0x03, "Address-Resolution-ACK" }, |
| 124 | { 0x04, "Advertisement" }, |
| 125 | { 0x05, "Advertisement-Solicitation" }, |
| 126 | { 0x06, "Connect-Request" }, |
| 127 | { 0x07, "Connect-Accept" }, |
| 128 | { 0x08, "Disconnect-Request" }, |
| 129 | { 0x09, "Disconnect-ACK" }, |
| 130 | { 0x0A, "Heartbeat-Request" }, |
| 131 | { 0x0B, "Heartbeat-ACK" }, |
| 132 | { 0x0C, "Proprietary-Message" }, |
| 133 | { 0, NULL((void*)0) } |
| 134 | }; |
| 135 | |
| 136 | static const value_string bvlc_result_names[] = { |
| 137 | { 0x00, "Successful completion" }, |
| 138 | { 0x10, "Write-Broadcast-Distribution-Table NAK" }, |
| 139 | { 0x20, "Read-Broadcast-Distribution-Table NAK" }, |
| 140 | { 0x30, "Register-Foreign-Device NAK" }, |
| 141 | { 0x40, "Read-Foreign-Device-Table NAK" }, |
| 142 | { 0x50, "Delete-Foreign-Device-Table-Entry NAK" }, |
| 143 | { 0x60, "Distribute-Broadcast-To-Network NAK" }, |
| 144 | { 0, NULL((void*)0) } |
| 145 | }; |
| 146 | |
| 147 | static const value_string bscvlc_result_names[] = { |
| 148 | { 0x00, "Successful completion (ACK)" }, |
| 149 | { 0x01, "Completion failed (NAK)" }, |
| 150 | { 0, NULL((void*)0) } |
| 151 | }; |
| 152 | |
| 153 | static const value_string bvlc_ipv6_function_names[] = { |
| 154 | { 0x00, "BVLC-Result", }, |
| 155 | { 0x01, "Original-Unicast-NPDU", }, |
| 156 | { 0x02, "Original-Broadcast-NPDU", }, |
| 157 | { 0x03, "Address-Resolution", }, |
| 158 | { 0x04, "Forwarded-Address-Resolution", }, |
| 159 | { 0x05, "Address-Resolution-ACK", }, |
| 160 | { 0x06, "Virtual-Address-Resolution", }, |
| 161 | { 0x07, "Virtual-Address-Resolution-ACK", }, |
| 162 | { 0x08, "Forwarded-NPDU", }, |
| 163 | { 0x09, "Register-Foreign-Device", }, |
| 164 | { 0x0A, "Delete-Foreign-Device-Table-Entry", }, |
| 165 | { 0x0B, "Secure-BVLL", }, |
| 166 | { 0x0C, "Distribute-Broadcast-To-Network", }, |
| 167 | { 0, NULL((void*)0) } |
| 168 | }; |
| 169 | |
| 170 | static const value_string bvlc_ipv6_result_names[] = { |
| 171 | { 0x00, "Successful completion" }, |
| 172 | { 0x30, "Address-Resolution NAK" }, |
| 173 | { 0x60, "Virtual-Address-Resolution NAK" }, |
| 174 | { 0x90, "Register-Foreign-Device NAK" }, |
| 175 | { 0xA0, "Delete-Foreign-Device-Table-Entry NAK" }, |
| 176 | { 0xC0, "Distribute-Broadcast-To-Network NAK" }, |
| 177 | { 0, NULL((void*)0) } |
| 178 | }; |
| 179 | |
| 180 | static const value_string bscvlc_header_type_names[] = { |
| 181 | { 0x01, "Secure Path" }, |
| 182 | { 0x02, "Hello" }, |
| 183 | { 0x03, "Identity" }, |
| 184 | { 0x04, "Hint" }, |
| 185 | { 0x05, "Token" }, |
| 186 | { 0x1F, "Proprietary Header Option" }, |
| 187 | { 0, NULL((void*)0) } |
| 188 | }; |
| 189 | |
| 190 | static const value_string bscvlc_hub_conn_state_names[] = { |
| 191 | { 0x00, "No hub connection" }, |
| 192 | { 0x01, "Connected to primary hub" }, |
| 193 | { 0x02, "Connected to failover hub" }, |
| 194 | { 0, NULL((void*)0) } |
| 195 | }; |
| 196 | |
| 197 | static const value_string bscvlc_hub_accept_conns_names[] = { |
| 198 | { 0x00, "The node does not support accepting direct connections" }, |
| 199 | { 0x01, "The node supports accepting direct connections" }, |
| 200 | { 0, NULL((void*)0) } |
| 201 | }; |
| 202 | |
| 203 | static int ett_bvlc; |
| 204 | static int ett_bscvlc; |
| 205 | static int ett_bscvlc_ctrl; |
| 206 | static int ett_bscvlc_hdr; |
| 207 | static int ett_bdt; |
| 208 | static int ett_fdt; |
| 209 | |
| 210 | #define BACNET_IP_ANNEX_J0x81 0x81 |
| 211 | #define BACNET_IPV6_ANNEX_U0x82 0x82 |
| 212 | |
| 213 | static const value_string bvlc_types[] = { |
| 214 | { BACNET_IP_ANNEX_J0x81, "BACnet/IP (Annex J)" }, |
| 215 | { BACNET_IPV6_ANNEX_U0x82, "BACnet/IPV6 (Annex U)" }, |
| 216 | { 0, NULL((void*)0) } |
| 217 | }; |
| 218 | |
| 219 | #define BSCVLC_CONTROL_DATA_OPTION0x01 0x01 |
| 220 | #define BSCVLC_CONTROL_DEST_OPTION0x02 0x02 |
| 221 | #define BSCVLC_CONTROL_DEST_ADDRESS0x04 0x04 |
| 222 | #define BSCVLC_CONTROL_ORIG_ADDRESS0x08 0x08 |
| 223 | #define BSCVLC_CONTROL_RESERVED0xF0 0xF0 |
| 224 | |
| 225 | static const true_false_string control_data_option_set_high = { |
| 226 | "Data Options field is present.", |
| 227 | "Data Options field is absent." |
| 228 | }; |
| 229 | |
| 230 | static const true_false_string control_destination_option_set_high = { |
| 231 | "Destination Options field is present.", |
| 232 | "Destination Options field is absent." |
| 233 | }; |
| 234 | |
| 235 | static const true_false_string control_destination_address_set_high = { |
| 236 | "Destination Virtual Address is present.", |
| 237 | "Destination Virtual Address is absent." |
| 238 | }; |
| 239 | |
| 240 | static const true_false_string control_orig_address_set_high = { |
| 241 | "Originating Virtual Address is present.", |
| 242 | "Originating Virtual Address is absent." |
| 243 | }; |
| 244 | |
| 245 | static const true_false_string control_reserved_set_high = { |
| 246 | "Shall be zero, but is not.", |
| 247 | "Shall be zero and is zero." |
| 248 | }; |
| 249 | |
| 250 | /* BSCVLC Header option bits */ |
| 251 | #define BSCVLC_HDR_MORE_OPTIONS_FOLLOW0x80 0x80 |
| 252 | #define BSCVLC_HDR_MUST_UNDERSTAND0x40 0x40 |
| 253 | #define BSCVLC_HDR_EVERY_SEGMENT0x40 0x40 |
| 254 | #define BSCVLC_HDR_DATA_PRESENT0x20 0x20 |
| 255 | #define BSCVLC_HDR_OPTION_TYPE_MASK0x1F 0x1F |
| 256 | |
| 257 | /* BSCVLC Header options and their bits */ |
| 258 | #define BSCVLC_HDR_OPT_SECURE_PATH0x01 0x01 /* only data option */ |
| 259 | #define BSCVLC_HDR_OPT_HELLO0x02 0x02 /* only destination option */ |
| 260 | #define BSCVLC_HDR_OPT_HELLO_BIT_IDENT_RELAY0x01 0x01 /* only with the connect request */ |
| 261 | #define BSCVLC_HDR_OPT_IDENTITY0x03 0x03 /* only data option */ |
| 262 | #define BSCVLC_HDR_OPT_HINT0x04 0x04 /* only data option */ |
| 263 | #define BSCVLC_HDR_OPT_TOKEN0x05 0x05 /* only data option */ |
| 264 | #define BSCVLC_HDR_OPT_PROPRIETARY0x1F 0x1F /* data or destination option */ |
| 265 | |
| 266 | |
| 267 | static const true_false_string header_opt_data_set_high = { |
| 268 | "The 'Header Length' and 'Header Data' fields are present.", |
| 269 | "The 'Header Length' and 'Header Data' fields are absent." |
| 270 | }; |
| 271 | |
| 272 | static const true_false_string header_opt_must_understand_set_high = { |
| 273 | "This header option must be understood for consuming the message.", |
| 274 | "This header option can be ignored if not understood." |
| 275 | }; |
| 276 | |
| 277 | static const true_false_string header_opt_more_set_high = { |
| 278 | "Another header option follows in the current header option list.", |
| 279 | "This is the last header option in the current header option list." |
| 280 | }; |
| 281 | |
| 282 | #define BSCVLC_HELLO_IDENTITY_RELAY0x01 0x01 |
| 283 | |
| 284 | static const true_false_string hello_opt_identity_relay_set_high = { |
| 285 | "Identity relay is allowed.", |
| 286 | "Identity relay is forbidden." |
| 287 | }; |
| 288 | |
| 289 | static int * const bscvlc_hello1_opt_flags[] = { |
| 290 | &hf_bscvlc_hello_opt_identity_relay, |
| 291 | NULL((void*)0) |
| 292 | }; |
| 293 | |
| 294 | static const value_string |
| 295 | BACnetErrorClass [] = { |
| 296 | { 0, "device" }, |
| 297 | { 1, "object" }, |
| 298 | { 2, "property" }, |
| 299 | { 3, "resources" }, |
| 300 | { 4, "security" }, |
| 301 | { 5, "services" }, |
| 302 | { 6, "vt" }, |
| 303 | { 7, "communication" }, |
| 304 | { 0, NULL((void*)0) } |
| 305 | /* Enumerated values 0-63 are reserved for definition by ASHRAE. |
| 306 | Enumerated values64-65535 may be used by others subject to |
| 307 | the procedures and constraints described in Clause 23. */ |
| 308 | }; |
| 309 | |
| 310 | static const value_string |
| 311 | BACnetErrorCode[] = { |
| 312 | { 0, "other"}, |
| 313 | { 1, "authentication-failed"}, |
| 314 | { 2, "configuration-in-progress"}, |
| 315 | { 3, "device-busy"}, |
| 316 | { 4, "dynamic-creation-not-supported"}, |
| 317 | { 5, "file-access-denied"}, |
| 318 | { 6, "incompatible-security-levels"}, |
| 319 | { 7, "inconsistent-parameters"}, |
| 320 | { 8, "inconsistent-selection-criterion"}, |
| 321 | { 9, "invalid-data-type"}, |
| 322 | { 10, "invalid-file-access-method"}, |
| 323 | { 11, "invalid-file-start-position"}, |
| 324 | { 12, "invalid-operator-name"}, |
| 325 | { 13, "invalid-parameter-data-type"}, |
| 326 | { 14, "invalid-time-stamp"}, |
| 327 | { 15, "key-generation-error"}, |
| 328 | { 16, "missing-required-parameter"}, |
| 329 | { 17, "no-objects-of-specified-type"}, |
| 330 | { 18, "no-space-for-object"}, |
| 331 | { 19, "no-space-to-add-list-element"}, |
| 332 | { 20, "no-space-to-write-property"}, |
| 333 | { 21, "no-vt-sessions-available"}, |
| 334 | { 22, "property-is-not-a-list"}, |
| 335 | { 23, "object-deletion-not-permitted"}, |
| 336 | { 24, "object-identifier-already-exists"}, |
| 337 | { 25, "operational-problem"}, |
| 338 | { 26, "password-failure"}, |
| 339 | { 27, "read-access-denied"}, |
| 340 | { 28, "security-not-supported"}, |
| 341 | { 29, "service-request-denied"}, |
| 342 | { 30, "timeout"}, |
| 343 | { 31, "unknown-object"}, |
| 344 | { 32, "unknown-property"}, |
| 345 | { 33, "removed enumeration"}, |
| 346 | { 34, "unknown-vt-class"}, |
| 347 | { 35, "unknown-vt-session"}, |
| 348 | { 36, "unsupported-object-type"}, |
| 349 | { 37, "value-out-of-range"}, |
| 350 | { 38, "vt-session-already-closed"}, |
| 351 | { 39, "vt-session-termination-failure"}, |
| 352 | { 40, "write-access-denied"}, |
| 353 | { 41, "character-set-not-supported"}, |
| 354 | { 42, "invalid-array-index"}, |
| 355 | { 43, "cov-subscription-failed"}, |
| 356 | { 44, "not-cov-property"}, |
| 357 | { 45, "optional-functionality-not-supported"}, |
| 358 | { 46, "invalid-configuration-data"}, |
| 359 | { 47, "datatype-not-supported"}, |
| 360 | { 48, "duplicate-name"}, |
| 361 | { 49, "duplicate-object-id"}, |
| 362 | { 50, "property-is-not-an-array"}, |
| 363 | { 51, "abort - buffer - overflow" }, |
| 364 | { 52, "abort - invalid - apdu - in - this - state" }, |
| 365 | { 53, "abort - preempted - by - higher - priority - task" }, |
| 366 | { 54, "abort - segmentation - not - supported" }, |
| 367 | { 55, "abort - proprietary" }, |
| 368 | { 56, "abort - other" }, |
| 369 | { 57, "reject - invalid - tag" }, |
| 370 | { 58, "reject - network - down" }, |
| 371 | { 59, "reject - buffer - overflow" }, |
| 372 | { 60, "reject - inconsistent - parameters" }, |
| 373 | { 61, "reject - invalid - parameter - data - type" }, |
| 374 | { 62, "reject - invalid - tag" }, |
| 375 | { 63, "reject - missing - required - parameter" }, |
| 376 | { 64, "reject - parameter - out - of - range" }, |
| 377 | { 65, "reject - too - many - arguments" }, |
| 378 | { 66, "reject - undefined - enumeration" }, |
| 379 | { 67, "reject - unrecognized - service" }, |
| 380 | { 68, "reject - proprietary" }, |
| 381 | { 69, "reject - other" }, |
| 382 | { 70, "unknown - device" }, |
| 383 | { 71, "unknown - route" }, |
| 384 | { 72, "value - not - initialized" }, |
| 385 | { 73, "invalid-event-state"}, |
| 386 | { 74, "no-alarm-configured"}, |
| 387 | { 75, "log-buffer-full"}, |
| 388 | { 76, "logged-value-purged"}, |
| 389 | { 77, "no-property-specified"}, |
| 390 | { 78, "not-configured-for-triggered-logging"}, |
| 391 | { 79, "unknown-subscription"}, |
| 392 | { 80, "parameter-out-of-range"}, |
| 393 | { 81, "list-element-not-found"}, |
| 394 | { 82, "busy"}, |
| 395 | { 83, "communication-disabled"}, |
| 396 | { 84, "success"}, |
| 397 | { 85, "access-denied"}, |
| 398 | { 86, "bad-destination-address"}, |
| 399 | { 87, "bad-destination-device-id"}, |
| 400 | { 88, "bad-signature"}, |
| 401 | { 89, "bad-source-address"}, |
| 402 | { 90, "bad-timestamp"}, |
| 403 | { 91, "cannot-use-key"}, |
| 404 | { 92, "cannot-verify-message-id"}, |
| 405 | { 93, "correct-key-revision"}, |
| 406 | { 94, "destination-device-id-required"}, |
| 407 | { 95, "duplicate-message"}, |
| 408 | { 96, "encryption-not-configured"}, |
| 409 | { 97, "encryption-required"}, |
| 410 | { 98, "incorrect-key"}, |
| 411 | { 99, "invalid-key-data"}, |
| 412 | { 100, "key-update-in-progress"}, |
| 413 | { 101, "malformed-message"}, |
| 414 | { 102, "not-key-server"}, |
| 415 | { 103, "security-not-configured"}, |
| 416 | { 104, "source-security-required"}, |
| 417 | { 105, "too-many-keys"}, |
| 418 | { 106, "unknown-authentication-type"}, |
| 419 | { 107, "unknown-key"}, |
| 420 | { 108, "unknown-key-revision"}, |
| 421 | { 109, "unknown-source-message"}, |
| 422 | { 110, "not-router-to-dnet"}, |
| 423 | { 111, "router-busy"}, |
| 424 | { 112, "unknown-network-message"}, |
| 425 | { 113, "message-too-long"}, |
| 426 | { 114, "security-error"}, |
| 427 | { 115, "addressing-error"}, |
| 428 | { 116, "write-bdt-failed"}, |
| 429 | { 117, "read-bdt-failed"}, |
| 430 | { 118, "register-foreign-device-failed"}, |
| 431 | { 119, "read-fdt-failed"}, |
| 432 | { 120, "delete-fdt-entry-failed"}, |
| 433 | { 121, "distribute-broadcast-failed"}, |
| 434 | { 122, "unknown-file-size"}, |
| 435 | { 123, "abort-apdu-too-long"}, |
| 436 | { 124, "abort-application-exceeded-reply-time"}, |
| 437 | { 125, "abort-out-of-resources"}, |
| 438 | { 126, "abort-tsm-timeout"}, |
| 439 | { 127, "abort-window-size-out-of-range"}, |
| 440 | { 128, "file-full"}, |
| 441 | { 129, "inconsistent-configuration"}, |
| 442 | { 130, "inconsistent-object-type"}, |
| 443 | { 131, "internal-error"}, |
| 444 | { 132, "not-configured"}, |
| 445 | { 133, "out-of-memory"}, |
| 446 | { 134, "value-too-long"}, |
| 447 | { 135, "abort-insufficient-security"}, |
| 448 | { 136, "abort-security-error"}, |
| 449 | { 137, "duplicate-entry"}, |
| 450 | { 138, "invalid-value-in-this-state"}, |
| 451 | { 139, "invalid-operation-in-this-state"}, |
| 452 | { 140, "list-item-not-numbered"}, |
| 453 | { 141, "list-item-not-timestamped"}, |
| 454 | { 142, "invalid-data-encoding"}, |
| 455 | { 143, "bvlc-function-unknown"}, |
| 456 | { 144, "bvlc-proprietary-function-unknown"}, |
| 457 | { 145, "header-encoding-error"}, |
| 458 | { 146, "header-not-understood"}, |
| 459 | { 147, "message-incomplete"}, |
| 460 | { 148, "not-a-bacnet-sc-hub"}, |
| 461 | { 149, "payload-expected"}, |
| 462 | { 150, "unexpected-data"}, |
| 463 | { 151, "node-duplicate-vmac"}, |
| 464 | { 152, "http-unexpected-response-code"}, |
| 465 | { 153, "http-no-upgrade"}, |
| 466 | { 154, "http-resource-not-local"}, |
| 467 | { 155, "http-proxy-authentication-failed"}, |
| 468 | { 156, "http-response-timeout"}, |
| 469 | { 157, "http-response-syntax-error"}, |
| 470 | { 158, "http-response-value-error"}, |
| 471 | { 159, "http-response-missing-header"}, |
| 472 | { 160, "http-websocket-header-error"}, |
| 473 | { 161, "http-upgrade-required"}, |
| 474 | { 162, "http-upgrade-error"}, |
| 475 | { 163, "http-temporary-unavailable"}, |
| 476 | { 164, "http-not-a-server"}, |
| 477 | { 165, "http-error"}, |
| 478 | { 166, "websocket-scheme-not-supported"}, |
| 479 | { 167, "websocket-unknown-control-message"}, |
| 480 | { 168, "websocket-close-error"}, |
| 481 | { 169, "websocket-closed-by-peer"}, |
| 482 | { 170, "websocket-endpoint-leaves"}, |
| 483 | { 171, "websocket-protocol-error"}, |
| 484 | { 172, "websocket-data-not-accepted"}, |
| 485 | { 173, "websocket-closed-abnormally"}, |
| 486 | { 174, "websocket-data-inconsistent"}, |
| 487 | { 175, "websocket-data-against-policy"}, |
| 488 | { 176, "websocket-frame-too-long"}, |
| 489 | { 177, "websocket-extension-missing"}, |
| 490 | { 178, "websocket-request-unavailable"}, |
| 491 | { 179, "websocket-error"}, |
| 492 | { 180, "tls-client-certificate-error"}, |
| 493 | { 181, "tls-server-certificate-error"}, |
| 494 | { 182, "tls-client-authentication-failed"}, |
| 495 | { 183, "tls-server-authentication-failed"}, |
| 496 | { 184, "tls-client-certificate-expired"}, |
| 497 | { 185, "tls-server-certificate-expired"}, |
| 498 | { 186, "tls-client-certificate-revoked"}, |
| 499 | { 187, "tls-server-certificate-revoked"}, |
| 500 | { 188, "tls-error"}, |
| 501 | { 189, "dns-unavailable"}, |
| 502 | { 190, "dns-name-resolution-failed"}, |
| 503 | { 191, "dns-resolver-failure"}, |
| 504 | { 192, "dns-error"}, |
| 505 | { 193, "tcp-connect-timeout"}, |
| 506 | { 194, "tcp-connection-refused"}, |
| 507 | { 195, "tcp-closed-by-local"}, |
| 508 | { 196, "tcp-closed-other"}, |
| 509 | { 197, "tcp-error"}, |
| 510 | { 198, "ip-address-not-reachable"}, |
| 511 | { 199, "ip-error"}, |
| 512 | { 200, "certificate-expired"}, |
| 513 | { 201, "certificate-invalid"}, |
| 514 | { 202, "certificate-malformed"}, |
| 515 | { 203, "certificate-revoked"}, |
| 516 | { 204, "unknown-key"}, |
| 517 | { 205, "referenced-port-in-error"}, |
| 518 | { 206, "not-enabled"}, |
| 519 | { 207, "adjust-scope-required"}, |
| 520 | { 208, "auth-scope-required"}, |
| 521 | { 209, "bind-scope-required"}, |
| 522 | { 210, "config-scope-required"}, |
| 523 | { 211, "control-scope-required"}, |
| 524 | { 212, "extended-scope-required"}, |
| 525 | { 213, "incorrect-client"}, |
| 526 | { 214, "install-scope-required"}, |
| 527 | { 215, "insufficient-scope"}, |
| 528 | { 216, "no-default-scope"}, |
| 529 | { 217, "no-policy"}, |
| 530 | { 218, "revoked-token"}, |
| 531 | { 219, "override-scope-required"}, |
| 532 | { 220, "inactive-token"}, |
| 533 | { 221, "unknown-audience"}, |
| 534 | { 222, "unknown-client"}, |
| 535 | { 223, "unknown-scope"}, |
| 536 | { 224, "view-scope-required"}, |
| 537 | { 225, "incorrect-audience"}, |
| 538 | { 226, "incorrect-client-origin"}, |
| 539 | { 227, "invalid-array-size"}, |
| 540 | { 228, "incorrect-issuer"}, |
| 541 | { 229, "invalid-token"}, |
| 542 | { 0, NULL((void*)0)} |
| 543 | /* Enumerated values 0-255 are reserved for definition by ASHRAE. |
| 544 | Enumerated values 256-65535 may be used by others subject to the |
| 545 | procedures and constraints described in Clause 23. */ |
| 546 | }; |
| 547 | static value_string_ext BACnetErrorCode_ext = VALUE_STRING_EXT_INIT(BACnetErrorCode){ _try_val_to_str_ext_init, 0, (sizeof (BACnetErrorCode) / sizeof ((BACnetErrorCode)[0]))-1, BACnetErrorCode, "BACnetErrorCode" , ((void*)0) }; |
| 548 | |
| 549 | |
| 550 | |
| 551 | static int * const bscvlc_control_flags[] = { |
| 552 | &hf_bscvlc_control_data_option, |
| 553 | &hf_bscvlc_control_destination_option, |
| 554 | &hf_bscvlc_control_destination_address, |
| 555 | &hf_bscvlc_control_origin_address, |
| 556 | &hf_bscvlc_control_reserved, |
| 557 | NULL((void*)0) |
| 558 | }; |
| 559 | |
| 560 | static int * const bscvlc_header_flags[] = { |
| 561 | &hf_bscvlc_header_opt_type, |
| 562 | &hf_bscvlc_header_opt_data, |
| 563 | &hf_bscvlc_header_opt_must_understand, |
| 564 | &hf_bscvlc_header_opt_more, |
| 565 | NULL((void*)0) |
| 566 | }; |
| 567 | |
| 568 | static int |
| 569 | // NOLINTNEXTLINE(misc-no-recursion) |
| 570 | dissect_ipv4_bvlc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U___attribute__((unused))) |
| 571 | { |
| 572 | |
| 573 | proto_item *ti; |
| 574 | proto_item *ti_bdt; |
| 575 | proto_item *ti_fdt; |
| 576 | proto_tree *bvlc_tree; |
| 577 | proto_tree *bdt_tree; /* Broadcast Distribution Table */ |
| 578 | proto_tree *fdt_tree; /* Foreign Device Table */ |
| 579 | |
| 580 | unsigned offset; |
| 581 | bool_Bool sec_decrypted; |
| 582 | uint8_t bvlc_type; |
| 583 | uint8_t bvlc_function; |
| 584 | uint16_t bvlc_length; |
| 585 | uint16_t packet_length; |
| 586 | unsigned npdu_length; |
| 587 | unsigned length_remaining; |
| 588 | tvbuff_t *next_tvb; |
| 589 | |
| 590 | offset = 0; |
| 591 | |
| 592 | bvlc_type = tvb_get_uint8(tvb, offset); |
| 593 | bvlc_function = tvb_get_uint8(tvb, offset + 1); |
| 594 | packet_length = tvb_get_ntohs(tvb, offset + 2); |
| 595 | length_remaining = tvb_reported_length_remaining(tvb, offset); |
| 596 | |
| 597 | if (bvlc_function > 0x08) { |
| 598 | /* We have a constant header length of BVLC of 4 in every |
| 599 | * BVLC-packet forewarding an NPDU. Beware: Changes in the |
| 600 | * BACnet-IP-standard may break this. |
| 601 | */ |
| 602 | bvlc_length = 4; |
| 603 | } else if (bvlc_function == 0x04) { |
| 604 | /* 4 Bytes + 6 Bytes for B/IP Address of Originating Device */ |
| 605 | bvlc_length = 10; |
| 606 | } else { |
| 607 | /* BVLC-packets with function below 0x09 contain |
| 608 | * routing-level data (e.g. Broadcast Distribution) |
| 609 | * but no NPDU for BACnet, so bvlc_length goes up to the end |
| 610 | * of the captured frame. |
| 611 | */ |
| 612 | bvlc_length = packet_length; |
| 613 | } |
| 614 | |
| 615 | if (bvlc_length < 4 || bvlc_length > packet_length) { |
| 616 | return 0; /* reject */ |
| 617 | } |
| 618 | |
| 619 | /* Put the BVLC Type in the info column */ |
| 620 | col_append_fstr(pinfo->cinfo, COL_INFO, " BVLC Function %s ", |
| 621 | val_to_str_const(bvlc_function, bvlc_function_names, "unknown")); |
| 622 | |
| 623 | ti = proto_tree_add_item(tree, proto_bvlc, tvb, 0, bvlc_length, ENC_NA0x00000000); |
| 624 | bvlc_tree = proto_item_add_subtree(ti, ett_bvlc); |
| 625 | proto_tree_add_uint(bvlc_tree, hf_bvlc_type, tvb, offset, 1, |
| 626 | bvlc_type); |
| 627 | offset++; |
| 628 | proto_tree_add_uint(bvlc_tree, hf_bvlc_function, tvb, |
| 629 | offset, 1, bvlc_function); |
| 630 | offset++; |
| 631 | if (length_remaining != packet_length) |
| 632 | proto_tree_add_uint_format_value(bvlc_tree, hf_bvlc_length, tvb, offset, |
| 633 | 2, bvlc_length, |
| 634 | "%d of %d bytes (invalid length - expected %d bytes)", |
| 635 | bvlc_length, packet_length, length_remaining); |
| 636 | else |
| 637 | proto_tree_add_uint_format_value(bvlc_tree, hf_bvlc_length, tvb, offset, |
| 638 | 2, bvlc_length, "%d of %d bytes BACnet packet length", |
| 639 | bvlc_length, packet_length); |
| 640 | offset += 2; |
| 641 | switch (bvlc_function) { |
| 642 | case 0x00: /* BVLC-Result */ |
| 643 | /* I don't know why the result code is encoded in 4 nibbles, |
| 644 | * but only using one: 0x00r0. Shifting left 4 bits. |
| 645 | */ |
| 646 | /* We should bitmask the result correctly when we have a |
| 647 | * packet to dissect, see README.developer, 1.6.2, FID */ |
| 648 | proto_tree_add_item(bvlc_tree, hf_bvlc_result_ip4, tvb, |
| 649 | offset, 2, ENC_BIG_ENDIAN0x00000000); |
| 650 | /*offset += 2;*/ |
| 651 | break; |
| 652 | case 0x01: /* Write-Broadcast-Distribution-Table */ |
| 653 | case 0x03: /* Read-Broadcast-Distribution-Table-Ack */ |
| 654 | /* List of BDT Entries: N*10-octet */ |
| 655 | ti_bdt = proto_tree_add_item(bvlc_tree, proto_bvlc, tvb, |
| 656 | offset, bvlc_length-4, ENC_NA0x00000000); |
| 657 | bdt_tree = proto_item_add_subtree(ti_bdt, ett_bdt); |
| 658 | /* List of BDT Entries: N*10-octet */ |
| 659 | while ((bvlc_length - offset) > 9) { |
| 660 | proto_tree_add_item(bdt_tree, hf_bvlc_bdt_ip, |
| 661 | tvb, offset, 4, ENC_BIG_ENDIAN0x00000000); |
| 662 | offset += 4; |
| 663 | proto_tree_add_item(bdt_tree, hf_bvlc_bdt_port, |
| 664 | tvb, offset, 2, ENC_BIG_ENDIAN0x00000000); |
| 665 | offset += 2; |
| 666 | proto_tree_add_item(bdt_tree, |
| 667 | hf_bvlc_bdt_mask, tvb, offset, 4, |
| 668 | ENC_NA0x00000000); |
| 669 | offset += 4; |
| 670 | } |
| 671 | /* We check this if we get a BDT-packet somewhere */ |
| 672 | break; |
| 673 | case 0x02: /* Read-Broadcast-Distribution-Table */ |
| 674 | /* nothing to do here */ |
| 675 | break; |
| 676 | case 0x05: /* Register-Foreign-Device */ |
| 677 | /* Time-to-Live 2-octets T, Time-to-Live T, in seconds */ |
| 678 | proto_tree_add_item(bvlc_tree, hf_bvlc_reg_ttl, |
| 679 | tvb, offset, 2, ENC_BIG_ENDIAN0x00000000); |
| 680 | /*offset += 2;*/ |
| 681 | break; |
| 682 | case 0x06: /* Read-Foreign-Device-Table */ |
| 683 | /* nothing to do here */ |
| 684 | break; |
| 685 | case 0x07: /* Read-Foreign-Device-Table-Ack */ |
| 686 | /* List of FDT Entries: N*10-octet */ |
| 687 | /* N indicates the number of entries in the FDT whose |
| 688 | * contents are being returned. Each returned entry |
| 689 | * consists of the 6-octet B/IP address of the registrant; |
| 690 | * the 2-octet Time-to-Live value supplied at the time of |
| 691 | * registration; and a 2-octet value representing the |
| 692 | * number of seconds remaining before the BBMD will purge |
| 693 | * the registrant's FDT entry if no re-registration occurs. |
| 694 | */ |
| 695 | ti_fdt = proto_tree_add_item(bvlc_tree, proto_bvlc, tvb, |
| 696 | offset, bvlc_length -4, ENC_NA0x00000000); |
| 697 | fdt_tree = proto_item_add_subtree(ti_fdt, ett_fdt); |
| 698 | /* List of FDT Entries: N*10-octet */ |
| 699 | while ((bvlc_length - offset) > 9) { |
| 700 | proto_tree_add_item(fdt_tree, hf_bvlc_fdt_ip, |
| 701 | tvb, offset, 4, ENC_BIG_ENDIAN0x00000000); |
| 702 | offset += 4; |
| 703 | proto_tree_add_item(fdt_tree, hf_bvlc_fdt_port, |
| 704 | tvb, offset, 2, ENC_BIG_ENDIAN0x00000000); |
| 705 | offset += 2; |
| 706 | proto_tree_add_item(fdt_tree, |
| 707 | hf_bvlc_fdt_ttl, tvb, offset, 2, |
| 708 | ENC_BIG_ENDIAN0x00000000); |
| 709 | offset += 2; |
| 710 | proto_tree_add_item(fdt_tree, |
| 711 | hf_bvlc_fdt_timeout, tvb, offset, 2, |
| 712 | ENC_BIG_ENDIAN0x00000000); |
| 713 | offset += 2; |
| 714 | } |
| 715 | /* We check this if we get a FDT-packet somewhere */ |
| 716 | break; |
| 717 | case 0x08: /* Delete-Foreign-Device-Table-Entry */ |
| 718 | /* FDT Entry: 6-octets */ |
| 719 | proto_tree_add_item(bvlc_tree, hf_bvlc_fdt_ip, |
| 720 | tvb, offset, 4, ENC_BIG_ENDIAN0x00000000); |
| 721 | offset += 4; |
| 722 | proto_tree_add_item(bvlc_tree, hf_bvlc_fdt_port, |
| 723 | tvb, offset, 2, ENC_BIG_ENDIAN0x00000000); |
| 724 | /*offset += 2;*/ |
| 725 | break; |
| 726 | case 0x0C: /* Secure-BVLL */ |
| 727 | offset = bacnet_dissect_sec_wrapper(tvb, pinfo, tree, offset, NULL((void*)0), &sec_decrypted); |
Value stored to 'offset' is never read | |
| 728 | if (!sec_decrypted) { |
| 729 | call_data_dissector(tvb, pinfo, tree); |
| 730 | return tvb_captured_length(tvb); |
| 731 | } |
| 732 | increment_dissection_depth(pinfo); |
| 733 | dissect_ipv4_bvlc(tvb, pinfo, tree, data); |
| 734 | decrement_dissection_depth(pinfo); |
| 735 | break; |
| 736 | /* We check this if we get a FDT-packet somewhere */ |
| 737 | case 0x04: /* Forwarded-NPDU |
| 738 | * Why is this 0x04? It would have been a better |
| 739 | * idea to append all forewarded NPDUs at the |
| 740 | * end of the function table in the B/IP-standard! |
| 741 | */ |
| 742 | /* proto_tree_add_bytes_format(); */ |
| 743 | proto_tree_add_item(bvlc_tree, hf_bvlc_fwd_ip, |
| 744 | tvb, offset, 4, ENC_BIG_ENDIAN0x00000000); |
| 745 | offset += 4; |
| 746 | proto_tree_add_item(bvlc_tree, hf_bvlc_fwd_port, |
| 747 | tvb, offset, 2, ENC_BIG_ENDIAN0x00000000); |
| 748 | /*offset += 2;*/ |
| 749 | break; |
| 750 | default: |
| 751 | /* Distribute-Broadcast-To-Network |
| 752 | * Original-Unicast-NPDU |
| 753 | * Original-Broadcast-NPDU |
| 754 | * Going to the next dissector... |
| 755 | */ |
| 756 | break; |
| 757 | } |
| 758 | |
| 759 | /* Ok, no routing information BVLC packet. Dissect as |
| 760 | * BACnet NPDU |
| 761 | */ |
| 762 | npdu_length = packet_length - bvlc_length; |
| 763 | next_tvb = tvb_new_subset_length(tvb, bvlc_length, npdu_length); |
| 764 | /* Code from Guy Harris */ |
| 765 | if (!dissector_try_uint(bvlc_dissector_table, |
| 766 | bvlc_function, next_tvb, pinfo, tree)) { |
| 767 | /* Unknown function - dissect the payload as data */ |
| 768 | call_data_dissector(next_tvb, pinfo, tree); |
| 769 | } |
| 770 | return tvb_reported_length(tvb); |
| 771 | } |
| 772 | |
| 773 | static int |
| 774 | // NOLINTNEXTLINE(misc-no-recursion) |
| 775 | dissect_ipv6_bvlc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U___attribute__((unused))) |
| 776 | { |
| 777 | proto_item *ti; |
| 778 | proto_tree *bvlc_tree; |
| 779 | |
| 780 | unsigned offset; |
| 781 | bool_Bool sec_decrypted; |
| 782 | uint8_t bvlc_type; |
| 783 | uint8_t bvlc_function; |
| 784 | uint16_t bvlc_length = 0; |
| 785 | uint16_t packet_length; |
| 786 | unsigned npdu_length; |
| 787 | unsigned length_remaining; |
| 788 | tvbuff_t *next_tvb; |
| 789 | |
| 790 | offset = 0; |
| 791 | |
| 792 | bvlc_type = tvb_get_uint8(tvb, offset); |
| 793 | bvlc_function = tvb_get_uint8(tvb, offset + 1); |
| 794 | packet_length = tvb_get_ntohs(tvb, offset + 2); |
| 795 | length_remaining = tvb_reported_length_remaining(tvb, offset); |
| 796 | |
| 797 | switch (bvlc_function) { |
| 798 | case 0x00: |
| 799 | case 0x09: |
| 800 | bvlc_length = 9; |
| 801 | break; |
| 802 | case 0x01: |
| 803 | bvlc_length = 10; |
| 804 | break; |
| 805 | case 0x02: |
| 806 | case 0x06: |
| 807 | case 0x0C: |
| 808 | bvlc_length = 7; |
| 809 | break; |
| 810 | case 0x03: |
| 811 | case 0x05: |
| 812 | case 0x07: |
| 813 | bvlc_length = 10; |
| 814 | break; |
| 815 | case 0x04: |
| 816 | bvlc_length = 28; |
| 817 | break; |
| 818 | case 0x08: |
| 819 | case 0x0A: |
| 820 | bvlc_length = 25; |
| 821 | break; |
| 822 | case 0x0B: |
| 823 | bvlc_length = 4; |
| 824 | break; |
| 825 | default: |
| 826 | break; |
| 827 | } |
| 828 | |
| 829 | if (bvlc_length > packet_length) { |
| 830 | return 0; /* reject */ |
| 831 | } |
| 832 | |
| 833 | /* Put the BVLC Type in the info column */ |
| 834 | col_append_fstr(pinfo->cinfo, COL_INFO, " BVLC Function %s ", |
| 835 | val_to_str_const(bvlc_function, bvlc_ipv6_function_names, "unknown")); |
| 836 | |
| 837 | ti = proto_tree_add_item(tree, proto_bvlc, tvb, 0, |
| 838 | bvlc_length, ENC_NA0x00000000); |
| 839 | bvlc_tree = proto_item_add_subtree(ti, ett_bvlc); |
| 840 | /* add the BVLC type */ |
| 841 | proto_tree_add_uint(bvlc_tree, hf_bvlc_type, tvb, offset, 1, |
| 842 | bvlc_type); |
| 843 | offset++; |
| 844 | /* add the BVLC function */ |
| 845 | proto_tree_add_uint(bvlc_tree, hf_bvlc_ipv6_function, tvb, |
| 846 | offset, 1, bvlc_function); |
| 847 | offset++; |
| 848 | /* add the length information */ |
| 849 | if (length_remaining != packet_length) |
| 850 | proto_tree_add_uint_format_value(bvlc_tree, hf_bvlc_length, tvb, offset, |
| 851 | 2, bvlc_length, |
| 852 | "%d of %d bytes (invalid length - expected %d bytes)", |
| 853 | bvlc_length, packet_length, length_remaining); |
| 854 | else |
| 855 | proto_tree_add_uint_format_value(bvlc_tree, hf_bvlc_length, tvb, offset, |
| 856 | 2, bvlc_length, |
| 857 | "%d of %d bytes BACnet packet length", |
| 858 | bvlc_length, packet_length); |
| 859 | offset += 2; |
| 860 | |
| 861 | /* add the optional present virtual source address */ |
| 862 | if (bvlc_function != 0x0B) { |
| 863 | proto_tree_add_item(bvlc_tree, hf_bvlc_virt_source, tvb, offset, |
| 864 | 3, ENC_BIG_ENDIAN0x00000000); |
| 865 | offset += 3; |
| 866 | } |
| 867 | |
| 868 | /* handle additional function parameters */ |
| 869 | switch (bvlc_function) { |
| 870 | case 0x00: /* BVLC-Result */ |
| 871 | proto_tree_add_item(bvlc_tree, hf_bvlc_result_ip6, tvb, |
| 872 | offset, 2, ENC_BIG_ENDIAN0x00000000); |
| 873 | offset += 2; |
| 874 | break; |
| 875 | case 0x01: /* Original-Unicast-NPDU */ |
| 876 | case 0x03: /* Address-Resolution */ |
| 877 | case 0x05: /* Address-Resolution-ACK */ |
| 878 | case 0x07: /* Virtual-Address-Resolution-ACK */ |
| 879 | proto_tree_add_item(bvlc_tree, hf_bvlc_virt_dest, tvb, offset, |
| 880 | 3, ENC_BIG_ENDIAN0x00000000); |
| 881 | offset += 3; |
| 882 | break; |
| 883 | case 0x04: /* Forwarded-Address-Resolution */ |
| 884 | proto_tree_add_item(bvlc_tree, hf_bvlc_virt_dest, tvb, offset, |
| 885 | 3, ENC_BIG_ENDIAN0x00000000); |
| 886 | offset += 3; |
| 887 | proto_tree_add_item(bvlc_tree, hf_bvlc_orig_source_addr, |
| 888 | tvb, offset, 16, ENC_NA0x00000000); |
| 889 | offset += 16; |
| 890 | proto_tree_add_item(bvlc_tree, hf_bvlc_orig_source_port, |
| 891 | tvb, offset, 2, ENC_BIG_ENDIAN0x00000000); |
| 892 | offset += 2; |
| 893 | break; |
| 894 | case 0x08: /* Forwarded-NPDU */ |
| 895 | proto_tree_add_item(bvlc_tree, hf_bvlc_orig_source_addr, |
| 896 | tvb, offset, 16, ENC_NA0x00000000); |
| 897 | offset += 16; |
| 898 | proto_tree_add_item(bvlc_tree, hf_bvlc_orig_source_port, |
| 899 | tvb, offset, 2, ENC_BIG_ENDIAN0x00000000); |
| 900 | offset += 2; |
| 901 | break; |
| 902 | case 0x06: /* Virtual-Address-Resolution */ |
| 903 | break; |
| 904 | case 0x09: /* Register-Foreign-Device */ |
| 905 | proto_tree_add_item(bvlc_tree, hf_bvlc_reg_ttl, |
| 906 | tvb, offset, 2, ENC_BIG_ENDIAN0x00000000); |
| 907 | offset += 2; |
| 908 | break; |
| 909 | case 0x0A: /* Delete-Foreign-Device-Table-Entry */ |
| 910 | proto_tree_add_item(bvlc_tree, hf_bvlc_fdt_ipv6, |
| 911 | tvb, offset, 16, ENC_NA0x00000000); |
| 912 | offset += 16; |
| 913 | proto_tree_add_item(bvlc_tree, hf_bvlc_fdt_port, |
| 914 | tvb, offset, 2, ENC_BIG_ENDIAN0x00000000); |
| 915 | offset += 2; |
| 916 | break; |
| 917 | case 0x0B: /* Secure-BVLL */ |
| 918 | offset = bacnet_dissect_sec_wrapper(tvb, pinfo, tree, offset, NULL((void*)0), &sec_decrypted); |
| 919 | if (!sec_decrypted) { |
| 920 | call_data_dissector(tvb, pinfo, tree); |
| 921 | return tvb_captured_length(tvb); |
| 922 | } |
| 923 | increment_dissection_depth(pinfo); |
| 924 | dissect_ipv6_bvlc(tvb, pinfo, tree, data); |
| 925 | decrement_dissection_depth(pinfo); |
| 926 | break; |
| 927 | case 0x02: /* Original-Broadcast-NPDU */ |
| 928 | case 0x0c: /* Distribute-Broadcast-To-Network */ |
| 929 | default: |
| 930 | /* |
| 931 | * Going to the next dissector... |
| 932 | */ |
| 933 | break; |
| 934 | } |
| 935 | |
| 936 | /* Ok, no routing information BVLC packet. Dissect as |
| 937 | * BACnet NPDU |
| 938 | */ |
| 939 | npdu_length = packet_length - offset; |
| 940 | next_tvb = tvb_new_subset_length(tvb, offset, npdu_length); |
| 941 | /* Code from Guy Harris */ |
| 942 | if ( ! dissector_try_uint(bvlc_ipv6_dissector_table, |
| 943 | bvlc_function, next_tvb, pinfo, tree)) { |
| 944 | /* Unknown function - dissect the payload as data */ |
| 945 | call_data_dissector(next_tvb, pinfo, tree); |
| 946 | } |
| 947 | |
| 948 | return tvb_reported_length(tvb); |
| 949 | } |
| 950 | |
| 951 | static int |
| 952 | dissect_bvlc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U___attribute__((unused))) |
| 953 | { |
| 954 | uint8_t bvlc_type; |
| 955 | unsigned ret = 0; |
| 956 | |
| 957 | bvlc_type = tvb_get_uint8(tvb, 0); |
| 958 | |
| 959 | /* |
| 960 | * Simple sanity check - make sure the type is one we know about. |
| 961 | */ |
| 962 | if (try_val_to_str(bvlc_type, bvlc_types) == NULL((void*)0)) |
| 963 | return 0; |
| 964 | |
| 965 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "BVLC"); |
| 966 | col_set_str(pinfo->cinfo, COL_INFO, "BACnet Virtual Link Control"); |
| 967 | |
| 968 | switch (bvlc_type) |
| 969 | { |
| 970 | case BACNET_IP_ANNEX_J0x81: |
| 971 | ret = dissect_ipv4_bvlc(tvb, pinfo, tree, data); |
| 972 | break; |
| 973 | case BACNET_IPV6_ANNEX_U0x82: |
| 974 | ret = dissect_ipv6_bvlc(tvb, pinfo, tree, data); |
| 975 | break; |
| 976 | } |
| 977 | |
| 978 | return ret; |
| 979 | } |
| 980 | |
| 981 | static int |
| 982 | dissect_bscvlc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U___attribute__((unused))) |
| 983 | { |
| 984 | proto_item *ti; |
| 985 | proto_tree *bvlc_tree; |
| 986 | tvbuff_t *next_tvb; |
| 987 | int offset; |
| 988 | int start; |
| 989 | int bvlc_length; |
| 990 | int packet_length; |
| 991 | int npdu_length = 0; |
| 992 | uint8_t bvlc_function; |
| 993 | uint8_t bvlc_control; |
| 994 | uint8_t bvlc_result; |
| 995 | uint8_t hdr_byte; |
| 996 | uint8_t option; |
| 997 | unsigned bvlc_message_id; |
| 998 | bool_Bool bMustSegment; |
| 999 | bool_Bool bMoreFlag; |
| 1000 | bool_Bool bDataFlag; |
| 1001 | const char *pszUnderstand; |
| 1002 | const char *pszOption; |
| 1003 | proto_tree *subtree; |
| 1004 | |
| 1005 | /* Calculate length of BSCVLC block to get remaining payload length */ |
| 1006 | offset = 0; |
| 1007 | |
| 1008 | packet_length = tvb_reported_length_remaining(tvb, offset); |
| 1009 | if(packet_length < 4) |
| 1010 | return 0; /* reject */ |
| 1011 | |
| 1012 | /* Fix part of the header first */ |
| 1013 | bvlc_function = tvb_get_uint8(tvb, offset++); |
| 1014 | bvlc_control = tvb_get_uint8(tvb, offset++); |
| 1015 | bvlc_message_id = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN0x00000000); |
| 1016 | offset += 2; |
| 1017 | |
| 1018 | /* Variable part of the header next */ |
| 1019 | bvlc_length = offset; |
| 1020 | |
| 1021 | if ((bvlc_control & BSCVLC_CONTROL_ORIG_ADDRESS0x08) != 0) |
| 1022 | bvlc_length += 6; |
| 1023 | |
| 1024 | if ((bvlc_control & BSCVLC_CONTROL_DEST_ADDRESS0x04) != 0) |
| 1025 | bvlc_length += 6; |
| 1026 | |
| 1027 | if ((bvlc_control & BSCVLC_CONTROL_DEST_OPTION0x02) != 0) |
| 1028 | { |
| 1029 | bMoreFlag = true1; |
| 1030 | |
| 1031 | while(tvb_reported_length_remaining(tvb, bvlc_length) > 0 && |
| 1032 | (hdr_byte = tvb_get_uint8(tvb, bvlc_length)) != 0 && bMoreFlag) |
| 1033 | { |
| 1034 | /* get flags and type... */ |
| 1035 | bMoreFlag = (hdr_byte & BSCVLC_HDR_MORE_OPTIONS_FOLLOW0x80); |
| 1036 | bDataFlag = (hdr_byte & BSCVLC_HDR_DATA_PRESENT0x20); |
| 1037 | bvlc_length++; |
| 1038 | |
| 1039 | if(bDataFlag) |
| 1040 | { |
| 1041 | npdu_length = (int)(tvb_get_uint8(tvb, bvlc_length++) << 8); |
| 1042 | npdu_length += (int)tvb_get_uint8(tvb, bvlc_length++); |
| 1043 | bvlc_length += npdu_length; |
| 1044 | } |
| 1045 | } |
| 1046 | } |
| 1047 | |
| 1048 | if ((bvlc_control & BSCVLC_CONTROL_DATA_OPTION0x01) != 0) |
| 1049 | { |
| 1050 | bMoreFlag = true1; |
| 1051 | |
| 1052 | while(tvb_reported_length_remaining(tvb, bvlc_length) > 0 && |
| 1053 | (hdr_byte = tvb_get_uint8(tvb, bvlc_length)) != 0 && bMoreFlag) |
| 1054 | { |
| 1055 | /* get flags and type... */ |
| 1056 | bMoreFlag= (hdr_byte & BSCVLC_HDR_MORE_OPTIONS_FOLLOW0x80); |
| 1057 | bDataFlag= (hdr_byte & BSCVLC_HDR_DATA_PRESENT0x20); |
| 1058 | bvlc_length++; |
| 1059 | |
| 1060 | if(bDataFlag) |
| 1061 | { |
| 1062 | npdu_length = (int)(tvb_get_uint8(tvb, bvlc_length++) << 8); |
| 1063 | npdu_length += (int)tvb_get_uint8(tvb, bvlc_length++); |
| 1064 | bvlc_length += npdu_length; |
| 1065 | } |
| 1066 | } |
| 1067 | } |
| 1068 | |
| 1069 | /* Now add the BSCVLC payload size for specified function */ |
| 1070 | switch (bvlc_function) |
| 1071 | { |
| 1072 | case 0x00: /* BVLC-Result */ |
| 1073 | case 0x03: /* Address-Resolution-ACK */ |
| 1074 | case 0x0C: /* Proprietary-Message */ |
| 1075 | /* complete packet length because of optional present variable length error data |
| 1076 | but no length encoded for it in the structure of this frame */ |
| 1077 | bvlc_length = packet_length; |
| 1078 | break; |
| 1079 | case 0x02: /* Address-Resolution */ |
| 1080 | case 0x05: /* Advertisement-Solicitation */ |
| 1081 | case 0x08: /* Disconnect-Request */ |
| 1082 | case 0x09: /* Disconnect-ACK */ |
| 1083 | case 0x0A: /* Heartbeat-Request */ |
| 1084 | case 0x0B: /* Heartbeat-ACK */ |
| 1085 | /* No additional payload here */ |
| 1086 | break; |
| 1087 | case 0x04: /* Advertisement */ |
| 1088 | bvlc_length += 6; |
| 1089 | break; |
| 1090 | case 0x06: /* Connect-Request */ |
| 1091 | case 0x07: /* Connect-Accept */ |
| 1092 | bvlc_length += 26; |
| 1093 | break; |
| 1094 | case 0x01: /* Encapsulated-NPDU */ |
| 1095 | default: |
| 1096 | /* The additional payload will be decoded elsewhere */ |
| 1097 | break; |
| 1098 | } |
| 1099 | |
| 1100 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "BSCVLC"); |
| 1101 | col_set_str(pinfo->cinfo, COL_INFO, "BACnet Secure Connect Virtual Link Control"); |
| 1102 | |
| 1103 | /* Put the BSCVLC Type and Message ID in the info column */ |
| 1104 | col_append_fstr(pinfo->cinfo, COL_INFO, " BSCVLC Function %s Message-ID %u", |
| 1105 | val_to_str_const(bvlc_function, bscvlc_function_names, "unknown"), bvlc_message_id); |
| 1106 | |
| 1107 | /* Fill the tree... */ |
| 1108 | offset = 0; |
| 1109 | ti = proto_tree_add_item(tree, proto_bscvlc, tvb, 0, bvlc_length, ENC_NA0x00000000); |
| 1110 | bvlc_tree = proto_item_add_subtree(ti, ett_bvlc); |
| 1111 | |
| 1112 | proto_tree_add_uint(bvlc_tree, hf_bscvlc_function, tvb, |
| 1113 | offset, 1, bvlc_function); |
| 1114 | offset++; |
| 1115 | proto_tree_add_bitmask(bvlc_tree, tvb, offset, hf_bscvlc_control, |
| 1116 | ett_bscvlc_ctrl, bscvlc_control_flags, ENC_NA0x00000000); |
| 1117 | offset ++; |
| 1118 | proto_tree_add_uint(bvlc_tree, hf_bscvlc_msg_id, tvb, |
| 1119 | offset, 2, bvlc_message_id); |
| 1120 | offset += 2; |
| 1121 | |
| 1122 | if ((bvlc_control & BSCVLC_CONTROL_ORIG_ADDRESS0x08) != 0) |
| 1123 | { |
| 1124 | col_append_fstr(pinfo->cinfo, COL_INFO, " SMAC %s", tvb_bytes_to_str(pinfo->pool, tvb, offset, 6)); |
| 1125 | |
| 1126 | proto_tree_add_item(bvlc_tree, hf_bscvlc_orig_vmac, tvb, offset, 6, ENC_NA0x00000000); |
| 1127 | offset += 6; |
| 1128 | } |
| 1129 | |
| 1130 | if ((bvlc_control & BSCVLC_CONTROL_DEST_ADDRESS0x04) != 0) |
| 1131 | { |
| 1132 | col_append_fstr(pinfo->cinfo, COL_INFO, " DMAC %s", tvb_bytes_to_str(pinfo->pool, tvb, offset, 6)); |
| 1133 | |
| 1134 | proto_tree_add_item(bvlc_tree, hf_bscvlc_dest_vmac, tvb, offset, 6, ENC_NA0x00000000); |
| 1135 | offset += 6; |
| 1136 | } |
| 1137 | |
| 1138 | if ((bvlc_control & BSCVLC_CONTROL_DEST_OPTION0x02) != 0) |
| 1139 | { |
| 1140 | bMoreFlag = true1; |
| 1141 | |
| 1142 | while(tvb_reported_length_remaining(tvb, offset) > 0 && |
| 1143 | (hdr_byte = tvb_get_uint8(tvb, offset)) != 0 && bMoreFlag) |
| 1144 | { |
| 1145 | /* get flags and type... */ |
| 1146 | option = (hdr_byte & BSCVLC_HDR_OPTION_TYPE_MASK0x1F); |
| 1147 | bMustSegment = (hdr_byte & BSCVLC_HDR_MUST_UNDERSTAND0x40); |
| 1148 | bMoreFlag = (hdr_byte & BSCVLC_HDR_MORE_OPTIONS_FOLLOW0x80); |
| 1149 | bDataFlag = (hdr_byte & BSCVLC_HDR_DATA_PRESENT0x20); |
| 1150 | start = offset; |
| 1151 | |
| 1152 | offset++; |
| 1153 | |
| 1154 | if(bDataFlag) |
| 1155 | { |
| 1156 | npdu_length = (int)(tvb_get_uint8(tvb, offset++) << 8); |
| 1157 | npdu_length += (int)tvb_get_uint8(tvb, offset++); |
| 1158 | offset += npdu_length; |
| 1159 | } |
| 1160 | |
| 1161 | if(bMustSegment) |
| 1162 | pszUnderstand = "must understand"; |
| 1163 | else |
| 1164 | pszUnderstand = "optional"; |
| 1165 | |
| 1166 | switch(option) |
| 1167 | { |
| 1168 | case BSCVLC_HDR_OPT_SECURE_PATH0x01: |
| 1169 | pszOption = "secure path"; |
| 1170 | break; |
| 1171 | case BSCVLC_HDR_OPT_HELLO0x02: |
| 1172 | pszOption = "hello"; |
| 1173 | break; |
| 1174 | case BSCVLC_HDR_OPT_IDENTITY0x03: |
| 1175 | pszOption = "identity"; |
| 1176 | break; |
| 1177 | case BSCVLC_HDR_OPT_HINT0x04: |
| 1178 | pszOption = "hint"; |
| 1179 | break; |
| 1180 | case BSCVLC_HDR_OPT_TOKEN0x05: |
| 1181 | pszOption = "token"; |
| 1182 | break; |
| 1183 | case BSCVLC_HDR_OPT_PROPRIETARY0x1F: |
| 1184 | pszOption = "proprietary"; |
| 1185 | break; |
| 1186 | default: |
| 1187 | pszOption = "reserved by ASHREA"; |
| 1188 | break; |
| 1189 | } |
| 1190 | |
| 1191 | subtree = proto_tree_add_subtree_format(bvlc_tree, tvb, start, offset - start, |
| 1192 | ett_bscvlc_hdr, NULL((void*)0), "Destination %s option %s", pszUnderstand, pszOption); |
| 1193 | proto_tree_add_bitmask_value(subtree, tvb, start, hf_bscvlc_header, |
| 1194 | ett_bscvlc_hdr, bscvlc_header_flags, hdr_byte); |
| 1195 | |
| 1196 | if(bDataFlag) |
| 1197 | { |
| 1198 | proto_tree_add_item(subtree, hf_bscvlc_header_length, tvb, start + 1, 2, ENC_BIG_ENDIAN0x00000000); |
| 1199 | switch(option) |
| 1200 | { |
| 1201 | case BSCVLC_HDR_OPT_HELLO0x02: |
| 1202 | proto_tree_add_bitmask_value(subtree, tvb, start + 3, hf_bscvlc_hello_opt, |
| 1203 | ett_bscvlc_hdr, bscvlc_hello1_opt_flags, tvb_get_uint8(tvb, start + 3)); |
| 1204 | break; |
| 1205 | case BSCVLC_HDR_OPT_IDENTITY0x03: |
| 1206 | proto_tree_add_item(subtree, hf_bscvlc_identity_device_id, tvb, start + 3, 3, ENC_BIG_ENDIAN0x00000000); |
| 1207 | break; |
| 1208 | case BSCVLC_HDR_OPT_HINT0x04: |
| 1209 | bacnet_dissect_scope(tvb_new_subset_length(tvb, start, npdu_length + 3), pinfo, subtree, 3, "scope: "); |
| 1210 | break; |
| 1211 | case BSCVLC_HDR_OPT_TOKEN0x05: |
| 1212 | bacnet_dissect_token(tvb_new_subset_length(tvb, start, npdu_length + 3), pinfo, subtree, 3, "token: "); |
| 1213 | break; |
| 1214 | default: |
| 1215 | proto_tree_add_item(subtree, hf_bscvlc_header_data, tvb, start + 3, npdu_length, ENC_NA0x00000000); |
| 1216 | break; |
| 1217 | } |
| 1218 | } |
| 1219 | } |
| 1220 | } |
| 1221 | |
| 1222 | if ((bvlc_control & BSCVLC_CONTROL_DATA_OPTION0x01) != 0) |
| 1223 | { |
| 1224 | bMoreFlag = true1; |
| 1225 | |
| 1226 | while(tvb_reported_length_remaining(tvb, offset) > 0 && |
| 1227 | (hdr_byte = tvb_get_uint8(tvb, offset)) != 0 && bMoreFlag) |
| 1228 | { |
| 1229 | /* get flags and type... */ |
| 1230 | option = (hdr_byte & BSCVLC_HDR_OPTION_TYPE_MASK0x1F); |
| 1231 | bMustSegment = (hdr_byte & BSCVLC_HDR_EVERY_SEGMENT0x40); |
| 1232 | bMoreFlag = (hdr_byte & BSCVLC_HDR_MORE_OPTIONS_FOLLOW0x80); |
| 1233 | bDataFlag = (hdr_byte & BSCVLC_HDR_DATA_PRESENT0x20); |
| 1234 | start = offset; |
| 1235 | |
| 1236 | offset++; |
| 1237 | |
| 1238 | if(bDataFlag) |
| 1239 | { |
| 1240 | npdu_length = (int)(tvb_get_uint8(tvb, offset++) << 8); |
| 1241 | npdu_length += (int)tvb_get_uint8(tvb, offset++); |
| 1242 | offset += npdu_length; |
| 1243 | } |
| 1244 | |
| 1245 | if(bMustSegment) |
| 1246 | pszUnderstand = "must understand"; |
| 1247 | else |
| 1248 | pszUnderstand = "optional"; |
| 1249 | |
| 1250 | switch(option) |
| 1251 | { |
| 1252 | case BSCVLC_HDR_OPT_SECURE_PATH0x01: |
| 1253 | pszOption = "secure path"; |
| 1254 | break; |
| 1255 | case BSCVLC_HDR_OPT_HELLO0x02: |
| 1256 | pszOption = "hello"; |
| 1257 | break; |
| 1258 | case BSCVLC_HDR_OPT_IDENTITY0x03: |
| 1259 | pszOption = "identity"; |
| 1260 | break; |
| 1261 | case BSCVLC_HDR_OPT_HINT0x04: |
| 1262 | pszOption = "hint"; |
| 1263 | break; |
| 1264 | case BSCVLC_HDR_OPT_TOKEN0x05: |
| 1265 | pszOption = "token"; |
| 1266 | break; |
| 1267 | case BSCVLC_HDR_OPT_PROPRIETARY0x1F: |
| 1268 | pszOption = "proprietary"; |
| 1269 | break; |
| 1270 | default: |
| 1271 | pszOption = "reserved by ASHREA"; |
| 1272 | break; |
| 1273 | } |
| 1274 | |
| 1275 | subtree = proto_tree_add_subtree_format(bvlc_tree, tvb, start, offset - start, |
| 1276 | ett_bscvlc_hdr, NULL((void*)0), "Data %s option %s", pszUnderstand, pszOption); |
| 1277 | proto_tree_add_bitmask_value(subtree, tvb, start, hf_bscvlc_header, |
| 1278 | ett_bscvlc_hdr, bscvlc_header_flags, hdr_byte); |
| 1279 | |
| 1280 | if(bDataFlag) |
| 1281 | { |
| 1282 | proto_tree_add_item(subtree, hf_bscvlc_header_length, tvb, start + 1, 2, ENC_BIG_ENDIAN0x00000000); |
| 1283 | switch(option) |
| 1284 | { |
| 1285 | case BSCVLC_HDR_OPT_HELLO0x02: |
| 1286 | proto_tree_add_bitmask_value(subtree, tvb, start + 3, hf_bscvlc_hello_opt, |
| 1287 | ett_bscvlc_hdr, bscvlc_hello1_opt_flags, tvb_get_uint8(tvb, start + 3)); |
| 1288 | break; |
| 1289 | case BSCVLC_HDR_OPT_IDENTITY0x03: |
| 1290 | proto_tree_add_item(subtree, hf_bscvlc_identity_device_id, tvb, start + 3, 3, ENC_BIG_ENDIAN0x00000000); |
| 1291 | break; |
| 1292 | case BSCVLC_HDR_OPT_HINT0x04: |
| 1293 | bacnet_dissect_scope(tvb_new_subset_length(tvb, start, npdu_length + 3), pinfo, subtree, 3, "scope: "); |
| 1294 | break; |
| 1295 | case BSCVLC_HDR_OPT_TOKEN0x05: |
| 1296 | bacnet_dissect_token(tvb_new_subset_length(tvb, start, npdu_length + 3), pinfo, subtree, 3, "token: "); |
| 1297 | break; |
| 1298 | default: |
| 1299 | proto_tree_add_item(subtree, hf_bscvlc_header_data, tvb, start + 3, npdu_length, ENC_NA0x00000000); |
| 1300 | break; |
| 1301 | } |
| 1302 | } |
| 1303 | } |
| 1304 | } |
| 1305 | |
| 1306 | switch (bvlc_function) |
| 1307 | { |
| 1308 | case 0x02: /* Address-Resolution */ |
| 1309 | case 0x05: /* Advertisement-Solicitation */ |
| 1310 | case 0x08: /* Disconnect-Request */ |
| 1311 | case 0x09: /* Disconnect-ACK */ |
| 1312 | case 0x0A: /* Heartbeat-Request */ |
| 1313 | case 0x0B: /* Heartbeat-ACK */ |
| 1314 | break; |
| 1315 | case 0x00: /* BVLC-Result */ |
| 1316 | subtree = proto_tree_add_subtree_format(bvlc_tree, tvb, offset, packet_length - offset, |
| 1317 | ett_bscvlc_hdr, NULL((void*)0), "%s", "BVLC-Result"); |
| 1318 | proto_tree_add_item(subtree, hf_bscvlc_function, tvb, |
| 1319 | offset, 1, ENC_NA0x00000000); |
| 1320 | offset++; |
| 1321 | proto_tree_add_item(subtree, hf_bscvlc_result, tvb, |
| 1322 | offset, 1, ENC_NA0x00000000); |
| 1323 | bvlc_result = tvb_get_uint8(tvb, offset); |
| 1324 | offset++; |
| 1325 | |
| 1326 | col_append_fstr(pinfo->cinfo, COL_INFO, " %s", |
| 1327 | val_to_str_const(bvlc_result, bscvlc_result_names, "unknown")); |
| 1328 | |
| 1329 | if(bvlc_result) |
| 1330 | { |
| 1331 | proto_tree_add_item(subtree, hf_bscvlc_header_marker, tvb, |
| 1332 | offset, 1, ENC_NA0x00000000); |
| 1333 | offset++; |
| 1334 | proto_tree_add_item(subtree, hf_bscvlc_error_class, tvb, |
| 1335 | offset, 2, ENC_BIG_ENDIAN0x00000000); |
| 1336 | offset += 2; |
| 1337 | proto_tree_add_item(subtree, hf_bscvlc_error_code, tvb, |
| 1338 | offset, 2, ENC_BIG_ENDIAN0x00000000); |
| 1339 | offset += 2; |
| 1340 | proto_tree_add_item(subtree, hf_bscvlc_result_data, tvb, |
| 1341 | offset, packet_length - offset, ENC_NA0x00000000); |
| 1342 | } |
| 1343 | /* Force and of packet */ |
| 1344 | offset = packet_length; |
| 1345 | break; |
| 1346 | case 0x03: /* Address-Resolution-ACK */ |
| 1347 | subtree = proto_tree_add_subtree_format(bvlc_tree, tvb, offset, packet_length - offset, |
| 1348 | ett_bscvlc_hdr, NULL((void*)0), "%s", "Address-Resolution-ACK"); |
| 1349 | proto_tree_add_item(subtree, hf_bscvlc_uris, tvb, |
| 1350 | offset, packet_length - offset, ENC_NA0x00000000); |
| 1351 | /* Force and of packet */ |
| 1352 | offset = packet_length; |
| 1353 | break; |
| 1354 | case 0x04: /* Advertisement */ |
| 1355 | subtree = proto_tree_add_subtree_format(bvlc_tree, tvb, offset, packet_length - offset, |
| 1356 | ett_bscvlc_hdr, NULL((void*)0), "%s", "Advertisement"); |
| 1357 | proto_tree_add_item(subtree, hf_bscvlc_hub_conn_state, tvb, |
| 1358 | offset, 1, ENC_NA0x00000000); |
| 1359 | offset++; |
| 1360 | proto_tree_add_item(subtree, hf_bscvlc_accept_conns, tvb, |
| 1361 | offset, 1, ENC_NA0x00000000); |
| 1362 | offset++; |
| 1363 | proto_tree_add_item(subtree, hf_bscvlc_max_bvlc_length, tvb, |
| 1364 | offset, 2, ENC_BIG_ENDIAN0x00000000); |
| 1365 | offset += 2; |
| 1366 | proto_tree_add_item(subtree, hf_bscvlc_max_npdu_length, tvb, |
| 1367 | offset, 2, ENC_BIG_ENDIAN0x00000000); |
| 1368 | offset += 2; |
| 1369 | break; |
| 1370 | case 0x06: /* Connect-Request */ |
| 1371 | subtree = proto_tree_add_subtree_format(bvlc_tree, tvb, offset, packet_length - offset, |
| 1372 | ett_bscvlc_hdr, NULL((void*)0), "%s", "Connect-Request"); |
| 1373 | proto_tree_add_item(subtree, hf_bscvlc_connect_vmac, tvb, |
| 1374 | offset, 6, ENC_NA0x00000000); |
| 1375 | offset += 6; |
| 1376 | proto_tree_add_item(subtree, hf_bscvlc_connect_uuid, tvb, |
| 1377 | offset, 16, ENC_NA0x00000000); |
| 1378 | offset += 16; |
| 1379 | proto_tree_add_item(subtree, hf_bscvlc_max_bvlc_length, tvb, |
| 1380 | offset, 2, ENC_BIG_ENDIAN0x00000000); |
| 1381 | offset += 2; |
| 1382 | proto_tree_add_item(subtree, hf_bscvlc_max_npdu_length, tvb, |
| 1383 | offset, 2, ENC_BIG_ENDIAN0x00000000); |
| 1384 | offset += 2; |
| 1385 | break; |
| 1386 | case 0x07: /* Connect-Accept */ |
| 1387 | subtree = proto_tree_add_subtree_format(bvlc_tree, tvb, offset, packet_length - offset, |
| 1388 | ett_bscvlc_hdr, NULL((void*)0), "%s", "Connect-Accept"); |
| 1389 | proto_tree_add_item(subtree, hf_bscvlc_connect_vmac, tvb, |
| 1390 | offset, 6, ENC_NA0x00000000); |
| 1391 | offset += 6; |
| 1392 | proto_tree_add_item(subtree, hf_bscvlc_connect_uuid, tvb, |
| 1393 | offset, 16, ENC_NA0x00000000); |
| 1394 | offset += 16; |
| 1395 | proto_tree_add_item(subtree, hf_bscvlc_max_bvlc_length, tvb, |
| 1396 | offset, 2, ENC_BIG_ENDIAN0x00000000); |
| 1397 | offset += 2; |
| 1398 | proto_tree_add_item(subtree, hf_bscvlc_max_npdu_length, tvb, |
| 1399 | offset, 2, ENC_BIG_ENDIAN0x00000000); |
| 1400 | offset += 2; |
| 1401 | break; |
| 1402 | case 0x0C: /* Proprietary-Message */ |
| 1403 | subtree = proto_tree_add_subtree_format(bvlc_tree, tvb, offset, packet_length - offset, |
| 1404 | ett_bscvlc_hdr, NULL((void*)0), "%s", "Proprietary-Message"); |
| 1405 | proto_tree_add_item(subtree, hf_bscvlc_vendor_id, tvb, |
| 1406 | offset, 2, ENC_BIG_ENDIAN0x00000000); |
| 1407 | offset += 2; |
| 1408 | proto_tree_add_item(subtree, hf_bscvlc_proprietary_opt_type, tvb, |
| 1409 | offset, 1, ENC_NA0x00000000); |
| 1410 | offset++; |
| 1411 | proto_tree_add_item(subtree, hf_bscvlc_proprietary_data, tvb, |
| 1412 | offset, packet_length - offset, ENC_NA0x00000000); |
| 1413 | /* Force and of packet */ |
| 1414 | offset = packet_length; |
| 1415 | break; |
| 1416 | case 0x01: /* Encapsulated-NPDU */ |
| 1417 | default: |
| 1418 | /* Here we assume additional payload belongs to upper layers and will be decoded later */ |
| 1419 | break; |
| 1420 | } |
| 1421 | |
| 1422 | /* Let the remaining frame to be decoded elsewhere */ |
| 1423 | npdu_length = packet_length - offset; |
| 1424 | next_tvb = tvb_new_subset_length(tvb, offset, npdu_length); |
| 1425 | /* Code from Guy Harris */ |
| 1426 | if (!dissector_try_uint(bscvlc_dissector_table, |
| 1427 | bvlc_function, next_tvb, pinfo, tree)) { |
| 1428 | /* Unknown function - dissect the payload as data */ |
| 1429 | call_data_dissector(next_tvb, pinfo, tree); |
| 1430 | } |
| 1431 | |
| 1432 | return tvb_reported_length(tvb); |
| 1433 | } |
| 1434 | |
| 1435 | void |
| 1436 | proto_register_bvlc(void) |
| 1437 | { |
| 1438 | static hf_register_info hf[] = { |
| 1439 | { &hf_bvlc_type, |
| 1440 | { "Type", "bvlc.type", |
| 1441 | FT_UINT8, BASE_HEX, VALS(bvlc_types)((0 ? (const struct _value_string*)0 : ((bvlc_types)))), 0, |
| 1442 | NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1443 | }, |
| 1444 | { &hf_bvlc_function, |
| 1445 | { "Function", "bvlc.function", |
| 1446 | FT_UINT8, BASE_HEX, VALS(bvlc_function_names)((0 ? (const struct _value_string*)0 : ((bvlc_function_names) ))), 0, |
| 1447 | "BVLC Function", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1448 | }, |
| 1449 | { &hf_bvlc_ipv6_function, |
| 1450 | { "Function", "bvlc.function_ipv6", |
| 1451 | FT_UINT8, BASE_HEX, VALS(bvlc_ipv6_function_names)((0 ? (const struct _value_string*)0 : ((bvlc_ipv6_function_names )))), 0, |
| 1452 | "BVLC Function IPV6", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1453 | }, |
| 1454 | { &hf_bvlc_length, |
| 1455 | { "BVLC-Length", "bvlc.length", |
| 1456 | FT_UINT16, BASE_DEC, NULL((void*)0), 0, |
| 1457 | "Length of BVLC", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1458 | }, |
| 1459 | { &hf_bvlc_virt_source, |
| 1460 | { "BVLC-Virtual-Source", "bvlc.virtual_source", |
| 1461 | FT_UINT24, BASE_DEC_HEX, NULL((void*)0), 0, |
| 1462 | "Virtual source address of BVLC", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1463 | }, |
| 1464 | { &hf_bvlc_virt_dest, |
| 1465 | { "BVLC-Virtual-Destination", "bvlc.virtual_dest", |
| 1466 | FT_UINT24, BASE_DEC_HEX, NULL((void*)0), 0, |
| 1467 | "Virtual destination address of BVLC", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1468 | }, |
| 1469 | { &hf_bvlc_result_ip4, |
| 1470 | { "Result", "bvlc.result", |
| 1471 | FT_UINT16, BASE_HEX, VALS(bvlc_result_names)((0 ? (const struct _value_string*)0 : ((bvlc_result_names))) ), 0, |
| 1472 | "Result Code", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1473 | }, |
| 1474 | { &hf_bvlc_result_ip6, |
| 1475 | { "Result", "bvlc.result", |
| 1476 | FT_UINT16, BASE_HEX, VALS(bvlc_ipv6_result_names)((0 ? (const struct _value_string*)0 : ((bvlc_ipv6_result_names )))), 0, |
| 1477 | "Result Code", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1478 | }, |
| 1479 | { &hf_bvlc_bdt_ip, |
| 1480 | { "IP", "bvlc.bdt_ip", |
| 1481 | FT_IPv4, BASE_NONE, NULL((void*)0), 0, |
| 1482 | "BDT IP", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1483 | }, |
| 1484 | { &hf_bvlc_bdt_port, |
| 1485 | { "Port", "bvlc.bdt_port", |
| 1486 | FT_UINT16, BASE_DEC, NULL((void*)0), 0, |
| 1487 | "BDT Port", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1488 | }, |
| 1489 | { &hf_bvlc_bdt_mask, |
| 1490 | { "Mask", "bvlc.bdt_mask", |
| 1491 | FT_BYTES, BASE_NONE, NULL((void*)0), 0, |
| 1492 | "BDT Broadcast Distribution Mask", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1493 | }, |
| 1494 | { &hf_bvlc_reg_ttl, |
| 1495 | { "TTL", "bvlc.reg_ttl", |
| 1496 | FT_UINT16, BASE_DEC, NULL((void*)0), 0, |
| 1497 | "Foreign Device Time To Live", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1498 | }, |
| 1499 | { &hf_bvlc_fdt_ip, |
| 1500 | { "IP", "bvlc.fdt_ip", |
| 1501 | FT_IPv4, BASE_NONE, NULL((void*)0), 0, |
| 1502 | "FDT IP", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1503 | }, |
| 1504 | { &hf_bvlc_fdt_ipv6, |
| 1505 | { "IP", "bvlc.fdt_ipv6", |
| 1506 | FT_IPv6, BASE_NONE, NULL((void*)0), 0, |
| 1507 | "FDT IP", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1508 | }, |
| 1509 | { &hf_bvlc_fdt_port, |
| 1510 | { "Port", "bvlc.fdt_port", |
| 1511 | FT_UINT16, BASE_DEC, NULL((void*)0), 0, |
| 1512 | "FDT Port", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1513 | }, |
| 1514 | { &hf_bvlc_fdt_ttl, |
| 1515 | { "TTL", "bvlc.fdt_ttl", |
| 1516 | FT_UINT16, BASE_DEC, NULL((void*)0), 0, |
| 1517 | "Foreign Device Time To Live", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1518 | }, |
| 1519 | { &hf_bvlc_fdt_timeout, |
| 1520 | { "Timeout", "bvlc.fdt_timeout", |
| 1521 | FT_UINT16, BASE_DEC, NULL((void*)0), 0, |
| 1522 | "Foreign Device Timeout (seconds)", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1523 | }, |
| 1524 | { &hf_bvlc_fwd_ip, |
| 1525 | { "IP", "bvlc.fwd_ip", |
| 1526 | FT_IPv4, BASE_NONE, NULL((void*)0), 0, |
| 1527 | "FWD IP", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1528 | }, |
| 1529 | { &hf_bvlc_fwd_port, |
| 1530 | { "Port", "bvlc.fwd_port", |
| 1531 | FT_UINT16, BASE_DEC, NULL((void*)0), 0, |
| 1532 | "FWD Port", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1533 | }, |
| 1534 | { &hf_bvlc_orig_source_addr, |
| 1535 | { "IP", "bvlc.orig_source_addr", |
| 1536 | FT_IPv6, BASE_NONE, NULL((void*)0), 0, |
| 1537 | "ORIG IP", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1538 | }, |
| 1539 | { &hf_bvlc_orig_source_port, |
| 1540 | { "Port", "bvlc.orig_source_port", |
| 1541 | FT_UINT16, BASE_DEC, NULL((void*)0), 0, |
| 1542 | "ORIG Port", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1543 | }, |
| 1544 | }; |
| 1545 | |
| 1546 | static int *ett[] = { |
| 1547 | &ett_bvlc, |
| 1548 | &ett_bdt, |
| 1549 | &ett_fdt, |
| 1550 | }; |
| 1551 | |
| 1552 | static hf_register_info bsc_hf[] = { |
| 1553 | { &hf_bscvlc_control, |
| 1554 | { "Control", "bscvlc.control", |
| 1555 | FT_UINT8, BASE_HEX, NULL((void*)0), 0, |
| 1556 | "BSCVLC Control", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1557 | }, |
| 1558 | { &hf_bscvlc_control_data_option, |
| 1559 | { "Data Option", "bscvlc.control_data_option", |
| 1560 | FT_BOOLEAN, 8, TFS(&control_data_option_set_high)((0 ? (const struct true_false_string*)0 : ((&control_data_option_set_high )))), |
| 1561 | BSCVLC_CONTROL_DATA_OPTION0x01, "BSCVLC Control", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1562 | }, |
| 1563 | { &hf_bscvlc_control_destination_option, |
| 1564 | { "Destination Option", "bscvlc.control_dest_option", |
| 1565 | FT_BOOLEAN, 8, TFS(&control_destination_option_set_high)((0 ? (const struct true_false_string*)0 : ((&control_destination_option_set_high )))), |
| 1566 | BSCVLC_CONTROL_DEST_OPTION0x02, "BSCVLC Control", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1567 | }, |
| 1568 | { &hf_bscvlc_control_destination_address, |
| 1569 | { "Destination Address","bscvlc.control_dest_address", |
| 1570 | FT_BOOLEAN, 8, TFS(&control_destination_address_set_high)((0 ? (const struct true_false_string*)0 : ((&control_destination_address_set_high )))), |
| 1571 | BSCVLC_CONTROL_DEST_ADDRESS0x04, "BSCVLC Control", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1572 | }, |
| 1573 | { &hf_bscvlc_control_origin_address, |
| 1574 | { "Origin Address", "bscvlc.control_orig_address", |
| 1575 | FT_BOOLEAN, 8, TFS(&control_orig_address_set_high)((0 ? (const struct true_false_string*)0 : ((&control_orig_address_set_high )))), |
| 1576 | BSCVLC_CONTROL_ORIG_ADDRESS0x08, "BSCVLC Control", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1577 | }, |
| 1578 | { &hf_bscvlc_control_reserved, |
| 1579 | { "Reserved", "bscvlc.control_reserved", |
| 1580 | FT_BOOLEAN, 8, TFS(&control_reserved_set_high)((0 ? (const struct true_false_string*)0 : ((&control_reserved_set_high )))), |
| 1581 | BSCVLC_CONTROL_RESERVED0xF0, "BSCVLC Control", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1582 | }, |
| 1583 | { &hf_bscvlc_header, |
| 1584 | { "Header Data Length", "bscvlc.header", |
| 1585 | FT_UINT8, BASE_HEX, NULL((void*)0), 0, |
| 1586 | "BSCVLC Header Control Data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1587 | }, |
| 1588 | { &hf_bscvlc_header_marker, |
| 1589 | { "Header Error Marker","bscvlc.header_error_marker", |
| 1590 | FT_UINT8, BASE_HEX, NULL((void*)0), 0, |
| 1591 | "BSCVLC Header Error Marker", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1592 | }, |
| 1593 | { &hf_bscvlc_header_length, |
| 1594 | { "Header Data Length", "bscvlc.header_length", |
| 1595 | FT_UINT16, BASE_DEC, NULL((void*)0), 0, |
| 1596 | "BSCVLC Header Data Length", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1597 | }, |
| 1598 | { &hf_bscvlc_header_data, |
| 1599 | { "Header Data", "bscvlc.header_data", |
| 1600 | FT_BYTES, BASE_NONE, NULL((void*)0), 0, |
| 1601 | "BSCVLC Header Option", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1602 | }, |
| 1603 | { &hf_bscvlc_header_opt_type, |
| 1604 | { "Header Type", "bscvlc.header_type", |
| 1605 | FT_UINT8, BASE_HEX, VALS(bscvlc_header_type_names)((0 ? (const struct _value_string*)0 : ((bscvlc_header_type_names )))), |
| 1606 | BSCVLC_HDR_OPTION_TYPE_MASK0x1F, "BSCVLC Header Option", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1607 | }, |
| 1608 | { &hf_bscvlc_header_opt_data, |
| 1609 | { "Header Data", "bscvlc.header_data_present", |
| 1610 | FT_BOOLEAN, 8, TFS(&header_opt_data_set_high)((0 ? (const struct true_false_string*)0 : ((&header_opt_data_set_high )))), |
| 1611 | BSCVLC_HDR_DATA_PRESENT0x20, "BSCVLC Header Option", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1612 | }, |
| 1613 | { &hf_bscvlc_header_opt_must_understand, |
| 1614 | { "Header Must Understand","bscvlc.header_understand", |
| 1615 | FT_BOOLEAN, 8, TFS(&header_opt_must_understand_set_high)((0 ? (const struct true_false_string*)0 : ((&header_opt_must_understand_set_high )))), |
| 1616 | BSCVLC_HDR_MUST_UNDERSTAND0x40, "BSCVLC Header Option", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1617 | }, |
| 1618 | { &hf_bscvlc_header_opt_more, |
| 1619 | { "Header More", "bscvlc.header_more", |
| 1620 | FT_BOOLEAN, 8, TFS(&header_opt_more_set_high)((0 ? (const struct true_false_string*)0 : ((&header_opt_more_set_high )))), |
| 1621 | BSCVLC_HDR_MORE_OPTIONS_FOLLOW0x80, "BSCVLC Header Option", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1622 | }, |
| 1623 | { &hf_bscvlc_vendor_id, |
| 1624 | { "Vendor ID", "bscvlc.vendor_id", |
| 1625 | FT_UINT16, BASE_HEX, NULL((void*)0), 0, |
| 1626 | "BSCVLC Vendor ID", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1627 | }, |
| 1628 | { &hf_bscvlc_proprietary_opt_type, |
| 1629 | { "Proprietary Type", "bscvlc.proprietary_type", |
| 1630 | FT_UINT8, BASE_HEX, NULL((void*)0), 0, |
| 1631 | "BSCVLC Proprietary Type", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1632 | }, |
| 1633 | { &hf_bscvlc_proprietary_data, |
| 1634 | { "Proprietary Data", "bscvlc.proprietary_data", |
| 1635 | FT_BYTES, BASE_NONE, NULL((void*)0), 0, |
| 1636 | "BSCVLC Proprietary Data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1637 | }, |
| 1638 | { &hf_bscvlc_hub_conn_state, |
| 1639 | { "Hub Connection Status","bscvlc.hub_conn_state", |
| 1640 | FT_UINT8, BASE_HEX, VALS(bscvlc_hub_conn_state_names)((0 ? (const struct _value_string*)0 : ((bscvlc_hub_conn_state_names )))), 0, |
| 1641 | "BSCVLC Hub Connection Status", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1642 | }, |
| 1643 | { &hf_bscvlc_accept_conns, |
| 1644 | { "Hub Accepts Connections","bscvlc.accept_conns", |
| 1645 | FT_UINT8, BASE_HEX, VALS(bscvlc_hub_accept_conns_names)((0 ? (const struct _value_string*)0 : ((bscvlc_hub_accept_conns_names )))), 0, |
| 1646 | "BSCVLC Accepts Connections", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1647 | }, |
| 1648 | { &hf_bscvlc_max_bvlc_length, |
| 1649 | { "Max. BVLC Length", "bscvlc.max_bvlc_length", |
| 1650 | FT_UINT16, BASE_DEC, NULL((void*)0), 0, |
| 1651 | "Max Supported BVLC Length", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1652 | }, |
| 1653 | { &hf_bscvlc_max_npdu_length, |
| 1654 | { "Max. NPDU Length", "bscvlc.max_npdu_length", |
| 1655 | FT_UINT16, BASE_DEC, NULL((void*)0), 0, |
| 1656 | "Max Supported NPDU Length", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1657 | }, |
| 1658 | { &hf_bscvlc_function, |
| 1659 | { "Function", "bscvlc.function", |
| 1660 | FT_UINT8, BASE_HEX, VALS(bscvlc_function_names)((0 ? (const struct _value_string*)0 : ((bscvlc_function_names )))), 0, |
| 1661 | "BSCVLC Function", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1662 | }, |
| 1663 | { &hf_bscvlc_result, |
| 1664 | { "Result", "bscvlc.result", |
| 1665 | FT_UINT8, BASE_HEX, VALS(bscvlc_result_names)((0 ? (const struct _value_string*)0 : ((bscvlc_result_names) ))), 0, |
| 1666 | "Result Code", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1667 | }, |
| 1668 | { &hf_bscvlc_error_class, |
| 1669 | { "Error Class", "bscvlc.error_class", |
| 1670 | FT_UINT32, BASE_DEC, VALS(BACnetErrorClass)((0 ? (const struct _value_string*)0 : ((BACnetErrorClass)))), 0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1671 | }, |
| 1672 | { &hf_bscvlc_error_code, |
| 1673 | { "Error Code", "bscvlc.error_code", |
| 1674 | FT_UINT32, BASE_DEC|BASE_EXT_STRING0x00000200, &BACnetErrorCode_ext, 0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1675 | }, |
| 1676 | { &hf_bscvlc_result_data, |
| 1677 | { "Result Data", "bscvlc.result_data", |
| 1678 | FT_BYTES, BASE_NONE, NULL((void*)0), 0, |
| 1679 | "BSCVLC Result Data", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1680 | }, |
| 1681 | { &hf_bscvlc_uris, |
| 1682 | { "URI's", "bscvlc.uris", |
| 1683 | FT_BYTES, BASE_NONE, NULL((void*)0), 0, |
| 1684 | "BSCVLC Address URI's", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1685 | }, |
| 1686 | { &hf_bscvlc_msg_id, |
| 1687 | { "Message ID", "bscvlc.msgid", |
| 1688 | FT_UINT16, BASE_DEC, NULL((void*)0), 0, |
| 1689 | "BSCVLC Message ID", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1690 | }, |
| 1691 | { &hf_bscvlc_orig_vmac, |
| 1692 | { "SVMAC", "bscvlc.orig_virtual_address", |
| 1693 | FT_BYTES, BASE_NONE, NULL((void*)0), 0, |
| 1694 | "ORIG VMAC", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1695 | }, |
| 1696 | { &hf_bscvlc_dest_vmac, |
| 1697 | { "DVMAC", "bscvlc.dest_virtual_address", |
| 1698 | FT_BYTES, BASE_NONE, NULL((void*)0), 0, |
| 1699 | "DEST VMAC", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1700 | }, |
| 1701 | { &hf_bscvlc_connect_vmac, |
| 1702 | { "Connecting VMAC", "bscvlc.connect_virtual_address", |
| 1703 | FT_BYTES, BASE_NONE, NULL((void*)0), 0, |
| 1704 | "BSCVLC Connecting VMAC", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1705 | }, |
| 1706 | { &hf_bscvlc_connect_uuid, |
| 1707 | { "Connecting UUID", "bscvlc.connect_uuid", |
| 1708 | FT_BYTES, BASE_NONE, NULL((void*)0), 0, |
| 1709 | "BSCVLC Connecting UUID", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1710 | }, |
| 1711 | { &hf_bscvlc_identity_device_id, |
| 1712 | { "Identity Device ID", "bscvlc.identity_device_id", |
| 1713 | FT_UINT24, BASE_DEC, NULL((void*)0), 0, |
| 1714 | "BSCVLC Identity Device ID", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1715 | }, |
| 1716 | { &hf_bscvlc_hello_opt, |
| 1717 | { "Hello option", "bscvlc.hello_opt", |
| 1718 | FT_UINT8, BASE_HEX, NULL((void*)0), 0, |
| 1719 | "BSCVLC Hello option", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1720 | }, |
| 1721 | { &hf_bscvlc_hello_opt_identity_relay, |
| 1722 | { "Hello Identity Relay","bscvlc.hello_opt_identity_relay", |
| 1723 | FT_BOOLEAN, 8, TFS(&hello_opt_identity_relay_set_high)((0 ? (const struct true_false_string*)0 : ((&hello_opt_identity_relay_set_high )))), |
| 1724 | BSCVLC_HELLO_IDENTITY_RELAY0x01, "BSCVLC Hello Option", HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) } |
| 1725 | }, |
| 1726 | }; |
| 1727 | |
| 1728 | static int *bsc_ett[] = { |
| 1729 | &ett_bscvlc, |
| 1730 | &ett_bscvlc_ctrl, |
| 1731 | &ett_bscvlc_hdr |
| 1732 | }; |
| 1733 | |
| 1734 | proto_bvlc = proto_register_protocol("BACnet Virtual Link Control", "BVLC", "bvlc"); |
| 1735 | |
| 1736 | proto_register_field_array(proto_bvlc, hf, array_length(hf)(sizeof (hf) / sizeof (hf)[0])); |
| 1737 | proto_register_subtree_array(ett, array_length(ett)(sizeof (ett) / sizeof (ett)[0])); |
| 1738 | |
| 1739 | bvlc_handle = register_dissector("bvlc", dissect_bvlc, proto_bvlc); |
| 1740 | |
| 1741 | bvlc_dissector_table = register_dissector_table("bvlc.function", "BVLC Function", proto_bvlc, FT_UINT8, BASE_HEX); |
| 1742 | bvlc_ipv6_dissector_table = register_dissector_table("bvlc.function_ipv6", "BVLC Function IPV6", proto_bvlc, FT_UINT8, BASE_HEX); |
| 1743 | |
| 1744 | proto_bscvlc = proto_register_protocol("BACnet Secure Connect Virtual Link Control", "BSCVLC", "bscvlc"); |
| 1745 | |
| 1746 | proto_register_field_array(proto_bscvlc, bsc_hf, array_length(bsc_hf)(sizeof (bsc_hf) / sizeof (bsc_hf)[0])); |
| 1747 | proto_register_subtree_array(bsc_ett, array_length(bsc_ett)(sizeof (bsc_ett) / sizeof (bsc_ett)[0])); |
| 1748 | |
| 1749 | bscvlc_handle = register_dissector("bscvlc", dissect_bscvlc, proto_bscvlc); |
| 1750 | |
| 1751 | bscvlc_dissector_table = register_dissector_table("bscvlc.function", "BSCVLC Function", proto_bscvlc, FT_UINT8, BASE_HEX); |
| 1752 | } |
| 1753 | |
| 1754 | void |
| 1755 | proto_reg_handoff_bvlc(void) |
| 1756 | { |
| 1757 | dissector_add_uint_with_preference("udp.port", BVLC_UDP_PORT0xBAC0, bvlc_handle); |
| 1758 | dissector_add_string("ws.protocol", "hub.bsc.bacnet.org", bscvlc_handle); |
| 1759 | dissector_add_string("ws.protocol", "dc.bsc.bacnet.org", bscvlc_handle); |
| 1760 | } |
| 1761 | |
| 1762 | /* |
| 1763 | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
| 1764 | * |
| 1765 | * Local variables: |
| 1766 | * c-basic-offset: 8 |
| 1767 | * tab-width: 8 |
| 1768 | * indent-tabs-mode: t |
| 1769 | * End: |
| 1770 | * |
| 1771 | * vi: set shiftwidth=8 tabstop=8 noexpandtab: |
| 1772 | * :indentSize=8:tabSize=8:noTabs=false: |
| 1773 | */ |