amzn / zeek-plugin-bacnet

Zeek network security monitor plugin that enables parsing of the BACnet standard building controls protocol
BSD 3-Clause "New" or "Revised" License
29 stars 12 forks source link

Reject-Message-To-Network as 'Rorschach' #20

Open duffy-ocraven opened 4 years ago

duffy-ocraven commented 4 years ago

This ticket raises a conceptual enhancement entirely distinct from #12. Resolution there will successfully implement a loop construct as the proper way to capture what is in the actual packet (after provisioning for the 'reason' octet that is specified only in 0x03 and with proper handling for a potential malformed 1-octet final network number in all network_layer_message_types 0x00 through 0x05).

This 'Rorschach' additionally gives an excellent opportunity for our design to decide its architecture for something that goes beyond weirdness/malformed.

This discussion arises because there are six defined reasons, plus Other, as described in http://www.bacnet.org/Addenda/Add-135-2010ao.pdf

6.4.4 Reject-Message-To-Network
This message is indicated by a Message Type of X'03' followed by an octet indicating the reason for the rejection and a 2- octet network number (see Figure 6-7). It is directed to the node that originated the message being rejected, as indicated by the source address information in that message. The rejection reason octet shall contain an unsigned integer with one of the following values:
0: Other error.
1: 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.
2: The router is busy and unable to accept messages for the specified DNET at the present time.
3: It is an unknown network layer message type. The DNET returned in this case is a local matter. 
4: The message is too long to be routed to this DNET.
5. The source message was rejected due to a BACnet security error and that error cannot be forwarded to the source device. See Clause 24.12.1.1 for more details on the generation of Reject-Message-To-Network messages indicating this reason.
6. The source message was rejected due to errors in the addressing. The length of the DADR or SADR was determined to be invalid.

The rectilinearity of that table belies a very asymmetric tendency for implementations to emit those different 'reason' codes. Every quality BACnet router implementation has code that emits reason 1 and that emits reason 2. Those are respectively, the mechanism for dynamically updating router tables at run-time, and a mandate for throttling traffic rates to avoid router buffer exhaustion which would produce dropped packets.

In ordinary BACnet network traffic there will be Reject-Message-To-Network messages (message Type of X'03') followed by an octet indicating the reason 1, in any network traffic where there is a media or connectivity failure. In ordinary BACnet network traffic there will be Reject-Message-To-Network messages with reason 2, in any network traffic which spikes in volume to the point where a router needs to temporarily and proactively do the right thing to reduce packet dropping. But in ordinary BACnet network traffic there won't be Reject-Message-To-Network messages with the other described reasons. If one or more of those are ever observed, the reason is more likely pathological (or a genuine report of a deficient implementation) than benign. They are so rare that the things that might make a coder raise an accusation that the peer is a deficient implementation, are as likely to be a flaw in the reasoning of the accuser as they are to be an actual flaw in the implementation which sent the traffic that produced the accusation. That is why I term it 'Rorschach'. What one coder sees as a flaw in the sender, another coder might see as: "try things that might not work, with code as a fall-back triggering on the Reject response".

What seeing any of these could motivate a protocol parser and policy framework to decide to do, is a subject worthy of discussion and here I set a place to hold that discussion.

duffy-ocraven commented 4 years ago

"Nobody's right if everybody's wrong." quote comes from "For What it's Worth", a popular song released by Buffalo Springfield in December 1966.