Wireshark and BACnet MS/TP

I wrote an article about Analyzing BACnet with Wireshark for ASHRAE Journal special supplement BACnet Today.  ASHRAE is very particular about endorsing specific company products, and removed some references I had to information about how BACnet MS/TP can be supported on Wireshark by adding an external interface which sends Ethernet SNAP protocol packets.  The external interface was originally a Cimetrics U+4 device which connects BACnet MS/TP via USB to a computer, and uses a special driver to appear as a network interface to Wireshark.

In April, 2008, I was informed that the Cimetrics U+4 packets showed up in Wireshark, but were not decoded correctly.  I asked for a sample of the capture, and reverse engineered the header.  I then created the BACnet MS/TP decoding in Wireshark in order to display the MS/TP data, and passed the BACnet Network Layer and Application Layer information along to the existing dissectors.

The beauty of the BACnet protocol is that it is layered.  The NPDU (network layer) and APDU (application layer) encodings are the same regardless of the datalink layer used.  The NDPU layer is decoded by packet-bacnet.c, which passes the APDU layer to packet-bacapp.c.  The BACnet MS/TP datalink layer is decoded by packet-mstp.c which I created, and passes the NPDU, if it exists, to packet-bacnet.c, for decoding.  The ARCNET, Ethernet, and BACnet/IP (packet-bvlc.c) all pass a relevant packet to packet-bacnet.c for BACnet decoding.  I created packet-cimetrics.c for the Cimetrics header which passes the BACnet MS/TP datalink layer to packet-mstp.c.

The BACnet MS/TP patches were accepted into the Wireshark repository on May 13, 2008, checked in as SVN 25291.  The SVN 25881 was a fix to the Length decoding.  The BACnet MS/TP decoding eventually made it into the Wireshark 1.1 development release, but is not present in the Wireshark 1.0 stable release.

Wireshark now sees packets with the Cimetrics U+4 signature encapsulated in the SNAP protocol as MS/TP packets, and it is able to open a file that has been saved in PCAP format using the MS/TP WTAP signature.  But I didn’t have a Cimetrics U+4 device.  So I used a standard RS485 converter, my open source BACnet stack, and wrote a simple application to packetize the MS/TP frames and saves them to PCAP format.  I could now capture MS/TP packets and view them!

In August, 2008, I received an email from John in New Zealand.  His intention was “to use an existing simple VB application that captures MS/TP traffic from a low cost USB to RS-485 converter, to send the MS/TP packets using Winsock/UDP to Wireshark for final dissection and display.”  I figured that we could do this by making use of the existing SNAP protocol dissector that I created for the Cimetrics packets.

I reused the code that I had written to save in PCAP format, and wrote a simple application to packetize the MS/TP frames and resend them on Ethernet as the Cimetrics U+4 signature encapsulated in the SNAP protocol.  I got it to work under Linux, but would probably need to use WinPcap to get it to work under Windows.

Sending those SNAP protocol packets on Ethernet allows the display of BACnet MS/TP packets in realtime alongside BACnet/IP and BACnet Ethernet.  This makes it very easy to relate traffic going to and from workstations and routers with what is happening on the BACnet MS/TP network.

There are some sample captures (see cimetrics_mstp.pcap and mstp_wtap.cap) that demostrate some of the abilities of Wireshark.

I use a USB to RS-485 converter from SerialGear USB-COMi-SI-M, and am told that the B&B Electronics USOPTL4 works very well.  I am also told that the USB to RS-485 adapters that use the FTDI chipset are great for this as they allow the use of 76800 baud which is usually the stumbling block for native MS/TP interfacing with a standard PC serial port.

27 Responses to “Wireshark and BACnet MS/TP”

  1. Hello

    I did something similar. Not as cool as your solution.
    I didn’t want to buy any new hardware and I only had about 12hrs to get it working and use it to fix my system. So it quick and dirty.

    I created a little command line application that takes the MSTP frames with APDUs and encapsulates them in BACnet Eth packets. using the Ethernet frames MAC address for the MSTP MAC address. Then sent them out the port, looped it back and captured it with wireshark.

    Timing is a little off but not by much, and it Worked!

  2. Langstein says:

    Is a super idea mstp-way communication in wireshark. I find on the internet but so far only the version 1.0.8. In Sourceforge, however, is the speech of 1.1.0. Why is this getting?

  3. skarg says:

    The 1.0.x is the stable release of Wireshark, and the Wireshark team only wants bug fixes, not new features in it.

    So the new BACnet MS/TP decoding feature is still in the 1.1.x development branch until 1.1.x becomes the stable release.
    http://www.wireshark.org/download/
    or specifically for Windows:
    http://www.wireshark.org/download/win32/wireshark-win32-1.1.3.exe

  4. Controls-Man says:

    From what I understand, to get WireShark 1.1.x to recieve the MS/TP data, a separate application needs to be built to packetize the data to get them on Ethernet. It looks like you made one for Linux. Do you have one for Windows using WinPcap or know where I could find one?

    Thanks in advance!

  5. skarg says:

    Today I added Win32 binary releases of mstpcap (along with the other BACnet/IP tools) to the BACnet Protocol Stack project hosted on SourceForge.net.

    The mstpcap tool stores the packets to a file (named with the current date and time), and puts up to 65535 packets into a single file. A new file is created when the file is full, or when mstpcap is first started.
    http://prdownloads.sourceforge.net/bacnet/bacnet-tools-0.5.1.zip?download

    I have not tried to create an mstpsnap for Win32 with WinPcap.

  6. Andrej says:

    I used BACnet/IP to BACnet MS/TP Router (cimetrics e+ series), wich I conected with PC. On Router. I has connected mstp master deviece with this router. I wont use Wireshark to read BACnet MS/TP-Frames.
    Is it possible?How?

  7. skarg says:

    I don’t know of a way to read the BACnet MS/TP frames through that router. BACnet routers usually just “route” packets, and most of the MS/TP frames don’t get routed (token, poll-for-master, reply-to-poll-for-master, test-request, test-response, reply-postponed) You will need to add an RS485 card/converter to use the mstpcap utility and see the BACnet MS/TP frames.

  8. Andrej says:

    Hello Mr. Karg.

    I have ICP CON 7561 USB to RS485 converter.
    http://www.inovis-group.ch/d/artikel_ausgabe.asp?ID=2949&form=7
    This converter uses the USB interface to conect with PC.

    And other converter to connect mstp-bus to serial interface.

    I can see the beatstream over HyperTerminal (serail interface (COMx)).

    It is possible to connect Wireshark on Serial Port an decode the beatsream?

  9. skarg says:

    Hello Andrej,

    To decode the serial port directly under Wireshark requires a driver that packetizes the serial stream, and makes the packets available as a network interface. I have not done any drivers like that for Linux (line discipline driver) or Windows.

    However, it is still possible to use mstpcap to capture the Serial Port stream, which packetize it into a file. Then open that file with Wireshark to view the MS/TP messages. It is also possible (at least under Linux currently) to use mstpsnap to capture the Serial Port stream and send it out on an Ethernet port and monitor the capture in realtime with Wireshark.

    Perhaps there will be better solutions (i.e. Wireshark Remote) for serial packet captures in the future that work on all platforms.

  10. Controls-Man says:

    Steve-

    I have to give you a big THANKS for the mstpcap-Wireshark 1.1.x development combo. It works GREAT! Using Wireshark filters work wonderful with your mstpcap tool.

    Thanks again!

  11. Kevin Edison says:

    It looks like it is a great tool, but when I run mstpcap in Windows, I receive an error: “Unable to open COM4″. Is there a way to specify the COM port? Is there some documentation that I am missing? Thanks!

  12. skarg says:

    from the demo/mstpcap/readme.txt file in the source code:

    BACnet MS/TP Capture Tool

    This tool captures BACnet MS/TP packets on an RS485 serial interface,
    and saves the packets to a file in Wireshark PCAP format for
    the BACnet MS/TP dissector to read. The filename has a date and time
    code in it, and will contain up to 65535 packets. A new file
    will be created at each 65535 packet interval. The tool can
    be stopped by using Control-C.

    Here is a sample of the tool running (use CTRL-C to quit).
    D:\code\bacnet-stack\bin>mstpcap COM3 38400
    Adjusted interface name to \\.\COM3
    mstpcap: Using \\.\COM3 for capture at 38400 bps.
    mstpcap: saving capture to mstp_20090729123548.cap
    1400 packets
    MAC MaxMstr Tokens Retries Treply Tusage Trpfm Tder Tpostpd
    0 0 525 0 32 0 0 0 0
    1 127 525 0 16 79 0 0 0

    The BACnet MS/TP capture tool also includes statistics which are
    listed for any MAC addresses found passing a token,
    or any MAC address replying to a DER message.
    The statistics are emitted when Control-C is pressed, or when
    65535 packets are captured and the new file is created.
    The statistics are cleared when the new file is created.

    MaxMstr = highest destination MAC address during PFM

    Tokens = number of tokens transmitted by this MAC address.

    Retries = number of second tokens sent to this MAC address.

    Treply = maximum number of milliseconds it took to reply with
    a token after receiving a token. Treply is required to be less
    than 25ms (but the mstpcap tool may not have that good of
    resolution on Windows).

    Tusage = the maximum number of milliseconds the
    device waits for a ReplyToPollForMaster or Token retry.
    Tusage is required to be between 20ms and 100ms.

    Trpfm = maximum number of milliseconds to respond to PFM with RPFM. It is
    required to be less than 25ms.

    Tder = maximum number of milliseconds that a device takes to
    respond to a DataExpectingReply request. Tder is required to be less
    than 250ms.

    Tpostpd = maximum number of milliseconds to respond to
    DataExpectingReply request with ReplyPostponed. Tpostpd is
    required to be less than 250ms.

    Note that the mstpcap tool may not have that good of
    resolution on Windows, so timing under 50ms may not be accurate.

  13. David says:

    Hola, alguien sabe de casualidad donde puedo encontrar informacion sobre el protocolo Bacnet? lo que quiero saber es como se envian los paquetes, como codificarlos y decodificarlos, el formato que tiene, etc.

    Gracias.

  14. skarg says:

    David asks “Hi, anyone know by chance where I can find information about the protocol Bacnet? I want to know is how to send packets as encoding and decoding, the format has, etc..”.

    The official information is the ASHRAE 135-2008 BACnet standard, available from ashrae.org bookstore. You can use the open source BACnet stack or Wireshark to see how we have encoded and decoded the various services and data in BACnet.

  15. mike says:

    how to find out the encapsulation process of packets captured in wireshark?

  16. skarg says:

    The application code for the mstpcap utility shows the encapsulation process for a PCAP file format for a WTAP. See the write_global_header() and write_received_packet() functions.

    The magic is partly the data link type in the header:
    uint32_t network = 165; /* data link type – BACNET_MS_TP */

  17. Jochen says:

    We tried to get the 76800 to work with a FTDI chipset. We tried “mstpcap COM9 76800″ but the mstpcap tells:
    mstpcap: Using \\.\COM9 for capture at 38400 bps.

    Do have an idea what is going wrong?

  18. skarg says:

    Hi Jochen,

    The 76800 is a non-standard baud rate (for personal computers, anyway), and the mstpcap tool is just using the computers serial port for communication. However, some chipset drivers, like FTDI, allow you to create a non-standard baud rate at one of the PC standard baud rates (i.e. 300 baud is now 76800). From the mstpcap.txt file:

    If you are using FTDI chip in your RS485 converter, you can alias an existing baud rate on Windows in the FTDIPORT.INF file in order to acheive non-standard 76800 bps:
    HKR,,”ConfigData”,1,11,00,3F,3F,27,C0,00,00,27,00,00,00,C4,09,00,00,E2,04,00,00,71,02,00,00,38,41,00,00,9C,80,00,00,4E,C0,00,00,34,00,00,00,1A,00,00,00,0D,00,00,00,06,40,00,00,03,80,00,00,00,00,00,00,D0,80,00,00

    replace the 10,27,00,00 => divisor = 10000, rate = 300 bps alias

    hex values actual
    ———– ———
    27,C0,00,00 – 76923 bps => divisor=39.125
    27,00,00,00 – 76677 bps => divisor=39.000

    Then you would run:
    mstpcap COM9 300

    Note that earlier versions of mstpcap had only the standard MS/TP valid baud rates allowed. The current released version allows any of the standard computer baud rates to be used.

  19. Kris says:

    I’m not understanding how to use 76800 baud rate. Can you please show me what the “HRK,,”ConfigData” line should look like to make an alias where 300 baud is really 76800?

    Thanks

  20. skarg says:

    Here is a procedure that Chad Z. gave me for using the 76800 baud rate by faking a 300 baud entry on FTDI chip-set converters:
    1. Delete COM port in Device Manager
    2. Unplug USB dongle
    3. Delete the following files that are installed by FTDI.
    Windows\System32
    ftbusui.dll
    ftd2xx.dll
    ftlang.dll
    ftserui2.dll
    Windows\System32\Drivers
    ftdibus.sys
    ftser2k.sys
    4. Copy the original ftdiport.ini to another name or location
    5. Edit the ftdiport.ini file and change the ConfigData value.

    for 300bps = 76677 bps:
    HKR,,”ConfigData”,1,11,00,3F,3F,27,00,00,00,88,13,00,00,C4,09,00,00,E2,04,00,00,71,02,00,00,38,41,00,00,9C,80,00,00,4E,C0,00,00,34,00,00,00,1A,00,00,00,0D,00,00,00,06,40,00,00,03,80,00,00,00,00,00,00,D0,80,00,00

    or

    for 300bps = 76923 bps:
    HKR,,”ConfigData”,1,11,00,3F,3F,27,C0,00,00,88,13,00,00,C4,09,00,00,E2,04,00,00,71,02,00,00,38,41,00,00,9C,80,00,00,4E,C0,00,00,34,00,00,00,1A,00,00,00,0D,00,00,00,06,40,00,00,03,80,00,00,00,00,00,00,D0,80,00,00

    6. Plug USB dongle back in and always select “Have Disk” and navigate to ftdibus.inf or ftdiport.inf files which should be in the same folder.

  21. Kris says:

    Thanks,

    In case someone else has problems, I also had to get the latest VCP driver from FTDI’s site to get it to work. The latest driver SerialGear had would not work for me.

    Thanks again for all of the great information.

  22. Trevor says:

    I have been trying to get this to work for a little while now and it seems like its my capture program that isn’t working right. When I type in 300 it auto bauds to the 38400 and doesn’t even try to fake the 76800 at 300. I was wondering where I can get the capture program that allows 300 capture.

  23. skarg says:

    The latest mstpcap utility and friends is available at the BACnet Protocol Stack site hosted by SourceForge.net. Since we still update various things in the tools and in the stack, the download link is a moving target. It is currently at 0.6.0, and can be found here:
    http://prdownloads.sourceforge.net/bacnet/bacnet-tools-0.6.0.zip?download

    One of the handy things that mstpcap does is display some capture statistics, and so we added the ability to scan an existing capture file and produce those statistics again. The option is “–scan” followed by a space and a capture file name.

    I also improved the timing resolution to 1ms on Windows.

  24. Michel D says:

    In the main.c file of the mstpcap project, there is an ordering function call problem in the main routine.

    The function RS485_Initialize() is called before the RS485_Set_Baud_Rate(). This is why even you want to set the port to an other baud rate than 38400, it always takes the 38400 baud rate.

    Just put the RS485_Set_Baud_Rate() before the RS485_Initialize() function and it will do the good job.

  25. Michel D says:

    I forgot to say that this problem is in the V0.6.0

  26. skarg says:

    Thanks for the bug report/fix on the baud rate problem. I have corrected it in the svn repository, and will release new binaries soon.

  27. Peter says:

    I’ve modified the program to allow the selection of 76800 as a baud rate as it will work directly with some serial port drivers.
    I use the USOPTL4 and it will work for the most part with that – I do get some receive errors on the port which are not being seen by my devices or the router which mey be down to a problem with my hardware setup or the USOPTL4 baud rate not being close enough to 76800 for comfort.

Leave a Reply