To filter BACnet traffic in Wireshark, use the display filter bacnet || bacapp to show all BACnet packets. For BACnet/IP networks that include BBMD traffic, use bvlc || bacnet || bacapp instead. These filters cover the three BACnet protocol layers Wireshark dissects: BVLC (transport), NPDU (network), and APDU (application).
Why BACnet Wireshark Filters Matter
A typical building automation network carries far more than just BACnet. ARP broadcasts, DNS queries, DHCP renewals, web traffic from supervisory workstations, and sometimes IT infrastructure traffic all share the same wire. Without proper display filters, a technician staring at a raw Wireshark capture is searching for a needle in a haystack. The right filters strip away the noise and surface only the BACnet conversations that matter for troubleshooting.
Wireshark ships with a built-in BACnet dissector that decodes three protocol layers: BVLC (BACnet Virtual Link Control, the BACnet/IP transport header), BACnet NPDU (Network Protocol Data Unit, the network layer), and bacapp (BACnet APDU, the application layer where services like ReadProperty and Who-Is live). Understanding which layer to filter on is the key to efficient packet analysis.
Essential BACnet Wireshark Display Filters
These are the filters every BAS technician should know. Copy them directly into the Wireshark display filter bar and press Enter or click Apply.
| Filter | What It Shows |
|---|---|
bacnet | All packets containing a BACnet NPDU (network layer) |
bacapp | All packets containing a BACnet APDU (application layer services) |
bvlc | All BACnet/IP Virtual Link Control packets, including BBMD messages |
bvlc || bacnet || bacapp | All BACnet-related traffic across every protocol layer |
udp.port == 47808 | All UDP traffic on the default BACnet/IP port (0xBAC0) |
udp.port == 47808 && !bacnet | Non-BACnet traffic on the BACnet port (helps find port conflicts) |
bacapp.type | Any packet with a BACnet APDU type field (confirmed, unconfirmed, simple ACK, complex ACK, error, reject, abort) |
Filtering by BACnet Service Type
BACnet services fall into two categories: confirmed services (which require a response) and unconfirmed services (fire-and-forget). Wireshark uses separate filter fields for each: bacapp.confirmed_service and bacapp.unconfirmed_service. The values correspond to the service choice numbers defined in ASHRAE 135.
Unconfirmed Services
| Filter | Service |
|---|---|
bacapp.unconfirmed_service == 0 | I-Am |
bacapp.unconfirmed_service == 1 | I-Have |
bacapp.unconfirmed_service == 2 | Unconfirmed COV Notification |
bacapp.unconfirmed_service == 3 | Unconfirmed Event Notification |
bacapp.unconfirmed_service == 5 | Unconfirmed Text Message |
bacapp.unconfirmed_service == 6 | Time Synchronization |
bacapp.unconfirmed_service == 7 | Who-Has |
bacapp.unconfirmed_service == 8 | Who-Is |
bacapp.unconfirmed_service == 9 | UTC Time Synchronization |
Confirmed Services
| Filter | Service |
|---|---|
bacapp.confirmed_service == 0 | AcknowledgeAlarm |
bacapp.confirmed_service == 1 | Confirmed COV Notification |
bacapp.confirmed_service == 2 | Confirmed Event Notification |
bacapp.confirmed_service == 5 | SubscribeCOV |
bacapp.confirmed_service == 6 | AtomicReadFile |
bacapp.confirmed_service == 7 | AtomicWriteFile |
bacapp.confirmed_service == 8 | AddListElement |
bacapp.confirmed_service == 9 | RemoveListElement |
bacapp.confirmed_service == 10 | CreateObject |
bacapp.confirmed_service == 11 | DeleteObject |
bacapp.confirmed_service == 12 | ReadProperty |
bacapp.confirmed_service == 14 | ReadPropertyMultiple |
bacapp.confirmed_service == 15 | WriteProperty |
bacapp.confirmed_service == 16 | WritePropertyMultiple |
bacapp.confirmed_service == 26 | ReadRange |
bacapp.confirmed_service == 28 | SubscribeCOVProperty |
bacapp.confirmed_service == 29 | GetEventInformation |
Tip: To see Who-Is and I-Am together (a common troubleshooting pair), combine them:
bacapp.unconfirmed_service == 8 || bacapp.unconfirmed_service == 0Filtering by Device or Object
When you need to narrow a capture down to a specific controller or a particular object, Wireshark's BACnet dissector provides fields for object type and instance number.
By Object Type
The bacapp.objectType field filters packets by BACnet object type. Common values:
| Filter | Object Type |
|---|---|
bacapp.objectType == 0 | Analog Input (AI) |
bacapp.objectType == 1 | Analog Output (AO) |
bacapp.objectType == 2 | Analog Value (AV) |
bacapp.objectType == 3 | Binary Input (BI) |
bacapp.objectType == 4 | Binary Output (BO) |
bacapp.objectType == 5 | Binary Value (BV) |
bacapp.objectType == 8 | Device |
bacapp.objectType == 13 | Multi-state Input (MI) |
bacapp.objectType == 14 | Multi-state Output (MO) |
bacapp.objectType == 17 | Schedule |
bacapp.objectType == 19 | Multi-state Value (MV) |
bacapp.objectType == 20 | Trend Log |
By Instance Number
Use bacapp.instance_number to target a specific object instance. For example, to find all traffic referencing Device instance 12345:
bacapp.objectType == 8 && bacapp.instance_number == 12345To find all ReadProperty requests targeting Analog Input 1:
bacapp.confirmed_service == 12 && bacapp.objectType == 0 && bacapp.instance_number == 1By IP Address
When you know the IP of a specific controller, combine a standard Wireshark IP filter with a BACnet filter:
ip.addr == 192.168.1.100 && bacappUse ip.src or ip.dst instead of ip.addr if you only want to see traffic originating from or destined to that address. This is particularly helpful when debugging one-way communication failures where a controller sends requests but never receives responses (or vice versa).
Advanced BACnet Wireshark Filter Combinations
Compound filters are where Wireshark becomes a precision tool. These examples address real-world BAS troubleshooting scenarios.
Find Unanswered Who-Is Broadcasts
If a device sends Who-Is but never gets an I-Am back, it cannot discover its peers. This is one of the most common BACnet troubleshooting scenarios—a controller that should appear in a device list simply does not respond. Filter for both Who-Is and I-Am traffic, then compare timestamps and source addresses to determine which devices are replying and which are silent:
bacapp.unconfirmed_service == 8 || bacapp.unconfirmed_service == 0After applying this filter, sort by the Info column. You should see Who-Is requests followed by I-Am responses from each device on the network. A device that never sends an I-Am is either offline, misconfigured, on a different subnet without proper BBMD routing, or blocked by a firewall.
Isolate WriteProperty to a Specific Controller
ip.dst == 192.168.1.50 && bacapp.confirmed_service == 15Find BACnet Errors and Rejects
BACnet error and reject APDUs indicate a device refused or could not process a request:
bacapp.type == 5 || bacapp.type == 6 || bacapp.type == 7These values correspond to APDU types: 5 = Error, 6 = Reject, 7 = Abort. If you see a high volume of these, something is misconfigured.
BBMD and Foreign Device Registration
To troubleshoot cross-subnet BACnet/IP routing, filter for BBMD-specific BVLC functions:
bvlc.function == 0x05This shows Register-Foreign-Device messages. Other useful BVLC function values:
| Filter | BVLC Function |
|---|---|
bvlc.function == 0x00 | BVLC-Result (registration acknowledgments) |
bvlc.function == 0x01 | Write-Broadcast-Distribution-Table |
bvlc.function == 0x04 | Forwarded-NPDU |
bvlc.function == 0x05 | Register-Foreign-Device |
bvlc.function == 0x09 | Distribute-Broadcast-To-Network |
bvlc.function == 0x0a | Original-Unicast-NPDU |
bvlc.function == 0x0b | Original-Broadcast-NPDU |
Excessive COV Notifications
A chatty device flooding the network with Change of Value notifications can degrade BAS performance and overwhelm controllers with limited processing power. COV subscriptions that fire too frequently—often due to noisy sensor inputs or overly tight COV increments—are a common source of network congestion. Filter for both confirmed and unconfirmed COV traffic:
bacapp.confirmed_service == 1 || bacapp.unconfirmed_service == 2Use Wireshark's Statistics > I/O Graphs feature after applying this filter to visualize COV notification rates over time. Spikes may correlate with specific devices or time-of-day events.
Exclude Noisy Services
Sometimes you want to see everything except a high-volume service. To exclude Who-Is and I-Am from the display:
bacapp && !(bacapp.unconfirmed_service == 8 || bacapp.unconfirmed_service == 0)Common Mistakes
Capture Filters vs. Display Filters
This is the most common source of confusion for technicians new to Wireshark. The application has two completely separate filter systems with incompatible syntax. Capture filters (set before recording begins, in the capture options dialog) use Berkeley Packet Filter (BPF) syntax—the same syntax used by tcpdump. Display filters (applied after recording, in the filter bar at the top of the main window) use Wireshark's own protocol-aware syntax. All the filters on this page are display filters.
If you want to restrict what Wireshark records to only BACnet/IP traffic, set this capture filter before starting the capture:
udp portrange 47808-47823Do not paste bacnet or bacapp into the capture filter field—those are display filter names and will cause a syntax error.
Using "bacnet" Alone and Missing Application Data
The filter bacnet only matches the NPDU layer. Some BACnet packets (particularly those from BBMDs) may only register under the bvlc filter. For complete visibility, always use bvlc || bacnet || bacapp.
Wrong Comparison Operators
Wireshark display filters use == for equality, not =. Writing bacapp.confirmed_service = 12 will fail. The correct syntax is bacapp.confirmed_service == 12.
Forgetting Boolean Operator Syntax
Wireshark accepts both C-style and English-style operators. These pairs are equivalent:
&&orand||oror!ornot
Both work, but be consistent within a single filter expression to keep it readable.
Non-Standard Port Numbers
If BACnet/IP is running on a port other than 47808, Wireshark may not automatically decode it as BACnet. Right-click a packet, select Decode As, and set the UDP port to use the BACnet dissector. Only then will bacnet, bacapp, and bvlc filters work on that traffic.
Platform and Version Compatibility
The BACnet dissector has been part of Wireshark since its early releases. All display filters listed on this page work with Wireshark 2.x, 3.x, and 4.x on Windows, macOS, and Linux. The dissector covers BACnet/IP natively. For BACnet MS/TP captures (serial-based), you need a dedicated MS/TP-to-Wireshark capture tool (such as an Optigo BACnet Capture device or a compatible RS-485 adapter with capture firmware) that converts MS/TP frames into a pcap-compatible format. Once imported, the same bacnet and bacapp display filters apply to MS/TP traffic. The MS/TP-specific filter prefix mstp provides additional fields for MS/TP frame analysis.
To verify your Wireshark version supports a specific filter field, type the field name into the display filter bar. Wireshark will show a green background if the field is valid, or red if it is unrecognized.
Source Attribution
- Wireshark Display Filter Reference: BACnet APDU (bacapp)
- Wireshark Display Filter Reference: BACnet NPDU
- Wireshark Display Filter Reference: BVLC
- Wireshark Wiki: BACnet Protocol Page
- Optigo Networks: How to Filter for BACnet Data in Wireshark
- Events2HVAC: Using Wireshark to Troubleshoot BACnet
- Wireshark BACnet APDU Dissector Source (packet-bacapp.c) — authoritative reference for service choice values
Was this article helpful?
Related Articles
Need to do this remotely? SiteConduit connects remote technicians directly to the BAS VLAN without exposing corporate IT networks. Join the waitlist.
SiteConduit Technical Team
Idea Networks Inc.
SiteConduit builds managed remote access for building automation. Our knowledge base is maintained by BAS professionals with hands-on experience deploying and troubleshooting BACnet, Niagara, Modbus, and Facility Explorer systems.