BACnet Networking BACnet

BACnet Basics covered the object model and the services — how to read a property, write a priority-array slot, and discover devices on the same network. This page is the other half of the story: how devices on different networks find each other, why a normal Ethernet broadcast doesn't reach across a router, and what the BBMD and Foreign Device Registration machinery is actually doing. It also unpacks the EBO hex blob the BACnet/IP Hex Converter tool decodes for you — same string, but now you can see what each byte is doing.

Three addresses, one device

Every BACnet conversation eventually targets a specific property on a specific object on a specific device. The property and the object are application-layer concepts that BACnet Basics already covered; addressing the device takes three different identifiers, each at a different layer of the stack.

  • Device instance number. A 22-bit unsigned integer (range 0 to 4,194,302) that uniquely identifies a controller across the entire BACnet internetwork. This is the identifier the application layer speaks in — device:1001 is a device instance. It does not encode location or topology; two controllers physically on opposite sides of a building must still pick different instance numbers if both are visible to the same BMS.
  • Network number. A 16-bit integer that names a BACnet network segment — a group of devices that share a single data link (one MS/TP bus, or one BACnet/IP UDP broadcast domain). Network number 0 means "the local network — wherever this message originated"; 65535 means "broadcast to every network." Useful network numbers are 1 to 65534, assigned by the system designer. The network-layer header on every BACnet message carries source and destination network numbers when a message crosses between networks.
  • MAC address. The data-link identifier that a specific transport uses to deliver the message. On BACnet/IP the MAC is six bytes: four bytes of IPv4 address plus two bytes of UDP port (almost always 0xBAC0 — 47808). On MS/TP the MAC is a single byte: the device's station address on the RS-485 bus, in the range 0 to 127.
Three addresses for one BACnet device A controller box at the centre, labeled "VAV-101." Three labeled lines point inward from outside the box. The top label is "device:1001 — application-layer device instance." The middle label is "net 5 — network-layer segment number." The bottom label is "192.168.1.100 : 47808 — data-link IP plus UDP port." Each label sits at a different layer of the stack. VAV-101 (one controller) device:1001 application — device instance net 5 network segment 192.168.1.100 : 47808 data-link MAC three identifiers, three stack layers — only the device instance is forever

A useful way to think about which layer to reach for: the device instance is what the BMS graphic remembers and what the sequence programs against; the network number is how a router decides which way to send the message; the MAC is how the cable, switch, or RS-485 chip actually delivers it. Change the network topology — a new BBMD, a re-IP, a moved controller — and the MAC and network numbers may shift, but a device's instance number is still the same instance number.

The BACnet/IP frame — BVLL + NPDU + APDU

When you put a Wireshark capture on a BACnet/IP segment, every BACnet message expands into three nested layers above the standard UDP/IP wrapping. From outside in:

  • BVLL — BACnet Virtual Link Layer. A 4-byte header that names what kind of BACnet/IP packet this is. Byte 1 is always 0x81 (the BVLL type marker for BACnet/IP). Byte 2 is the BVLL function — values like 0x0A for Original-Unicast-NPDU, 0x0B for Original-Broadcast-NPDU, or 0x04 for Forwarded-NPDU (a broadcast a BBMD has unicast across to a peer). Bytes 3–4 are the total BVLL message length. A Forwarded-NPDU additionally carries the originating IP and port as the next six bytes, so the original source survives the forward.
  • NPDU — Network Protocol Data Unit. The BACnet network-layer header. Carries the version byte, a control byte (whose flags say whether destination / source / expecting-reply fields are present), and — when set — destination network number, destination MAC length and bytes, hop count, source network number, source MAC length and bytes. Local-network messages are short; cross-network messages carry the full address pair.
  • APDU — Application Protocol Data Unit. The actual service: a ReadProperty request, an I-Am announcement, a SubscribeCOV message. The APDU's first byte encodes the PDU type (confirmed-request, unconfirmed- request, simple-ACK, complex-ACK, error, reject, abort) and segmentation flags; the rest is the encoded service parameters.
A Forwarded-NPDU Who-Is on the wire A horizontal frame breakdown for a Who-Is broadcast forwarded by a BBMD. From left to right: IP header (20 bytes), UDP header with destination port 47808, then a BVLL block highlighted in the accent color showing type 0x81, function 0x04 for Forwarded-NPDU, length, and the originating IP plus port (6 bytes). Next is the NPDU block, with the destination set to network 65535 — the BACnet broadcast-everywhere network. Finally the APDU block with the Who-Is service body. A bracket above the BVLL block calls out that the function byte is what makes this a forwarded packet rather than an original broadcast. a Who-Is, forwarded by a BBMD IP hdr 20 B UDP hdr dst port 47808 BVLL · 10 B 0x81 type 0x04 fwd len 2 B orig IP+port 6 B NPDU version · control dest-net 65535 · hop APDU unconfirmed-request Who-Is service 0x04 = Forwarded-NPDU a BBMD captured an Original-Broadcast and unicast it here; the originating IP+port travels in the BVLL so the source survives three nested layers: BVLL tags the packet kind, NPDU routes between networks, APDU is the service

Most BACnet/IP traffic on a healthy network is Original-Unicast-NPDU (a normal read or write to a known device) or Original-Broadcast-NPDU (a Who-Is or I-Am on the local segment). Forwarded-NPDU is the giveaway that a BBMD is doing the work of carrying a broadcast somewhere it wouldn't otherwise go — which is the next section.

BBMDs — broadcasts across an L3 boundary

BACnet uses broadcasts heavily — Who-Is, I-Am, the Time-Synchronization service, COV notifications to the network-broadcast address. On a single subnet that's fine: UDP broadcasts are something every Ethernet switch handles. But the moment two BACnet/IP devices sit on different IP subnets — a router between them — the broadcast story breaks. Routers, by design, do not forward UDP broadcasts. Without help, a Who-Is from subnet A is invisible to every device on subnet B.

The help is the BBMD — BACnet/IP Broadcast Management Device. A BBMD is just a BACnet/IP node (often a JACE, an EBO server, or a software service running on a controller) configured with a Broadcast Distribution Table — the BDT — that lists the IP addresses of peer BBMDs on other subnets. When the BBMD sees a local broadcast on its own subnet, it captures the message, wraps it in a Forwarded-NPDU BVLL header (so the original source IP and port survive), and unicasts a copy to each peer BBMD in its BDT. Each peer BBMD then re-broadcasts the message on its subnet, where local devices pick it up the normal way.

A Who-Is crossing two subnets via BBMDs Two subnet panels separated by a router in the middle. The left subnet is labeled 192.168.1.0/24 and contains a workstation, a controller, and a BBMD at 192.168.1.10. The right subnet is labeled 10.0.5.0/24 and contains a target controller and a BBMD at 10.0.5.10. Each BBMD's Broadcast Distribution Table is shown beside it, listing the other BBMD's IP address. Four numbered arrows trace the path of a Who-Is from the left workstation: step 1 is a broadcast on the left subnet captured by the local BBMD; step 2 is the BBMD unicasting a Forwarded-NPDU across the router to the right BBMD; step 3 is the right BBMD re-broadcasting on its local subnet; step 4 is the target controller receiving the message. subnet A · 192.168.1.0/24 workstation .50 BBMD A 192.168.1.10 BDT of BBMD A 10.0.5.10 : 47808 (BBMD B's IP) router drops broadcasts subnet B · 10.0.5.0/24 BBMD B 10.0.5.10 VAV-101 10.0.5.42 BDT of BBMD B 192.168.1.10 : 47808 (BBMD A's IP) 1 2 · Forwarded-NPDU 3 · re-broadcast on subnet B 4 · target picks up Who-Is a local broadcast becomes a unicast across the router and a local broadcast again on the far side

Two BBMDs is the simplest case. A real installation may have three, four, or a dozen — every subnet that hosts BACnet/IP devices and wants to participate in cross-network broadcasts needs one BBMD, with each BBMD's BDT carrying every other BBMD's IP. The BDTs must be kept symmetric: if BBMD A's BDT lists BBMD B but BBMD B's BDT does not list BBMD A, broadcasts from A reach B but the reverse silently fails. The asymmetric- BDT trap is one of the most common BBMD misconfigurations in the field.

One BBMD per subnet, no more. Two BBMDs on the same subnet create a broadcast loop — every Forwarded-NPDU arriving from a peer gets re-broadcast by both BBMDs, each of which the other captures and re-forwards. The condition produces a quiet but persistent storm that scales with the number of peers and is usually only noticed once a Wireshark capture makes the duplicate frames visible.

Foreign Device Registration — joining from outside

A BBMD handles broadcasts between subnets that each have their own BBMD. What about a device that sits on a subnet with no local BBMD — a laptop on a guest Wi-Fi, an engineering workstation tunneled in over a VPN, a remote monitoring server in another building? It can't hear local broadcasts on its own subnet (nobody on that subnet is speaking BACnet), and it has no local BBMD to forward through.

The answer is Foreign Device Registration. The remote device sends a Register-Foreign-Device BVLL message — a unicast — to a BBMD it can reach on the BAS network. The request carries a Time-to-Live: how long the registration should stay valid (in seconds). The BBMD adds an entry to its FDT — Foreign Device Table with the remote device's IP, port, and TTL. From that moment, every broadcast the BBMD would have re-broadcast locally also gets unicast to the foreign device. The remote gains broadcast visibility into the BAS network as if it were locally attached, without needing its own BBMD.

Foreign Device Registration with a BBMD A remote engineering workstation sits to the left; the BAS subnet sits to the right, with a BBMD and a controller inside it. The workstation sends a Register-Foreign-Device request (a unicast) to the BBMD across a WAN. The BBMD's Foreign Device Table gains an entry: workstation IP, port 47808, time-to-live 600 seconds. From then on, broadcasts the BBMD would re-broadcast locally also unicast to the workstation. The workstation has broadcast visibility without being on the local subnet. remote workstation 203.0.113.55 (VPN, no local BBMD) WAN BAS subnet · 192.168.1.0/24 BBMD 192.168.1.10 FDT of BBMD 203.0.113.55 : 47808 TTL 600 s VAV-101 192.168.1.42 1 · Register-Foreign-Device 2 · forwarded broadcasts register with a TTL, re-register before it expires, and the BBMD keeps forwarding

The TTL is the catch. If the foreign device fails to send a fresh Register-Foreign-Device before the previous TTL expires, the BBMD silently drops the FDT entry and broadcasts stop arriving — no error, no notification. The remote tool just stops discovering. Most workstations and engineering tools handle re-registration automatically, but lab-built clients and ad-hoc scripts often don't, and a forgotten TTL is a classic cause of "I could see this device yesterday and now I can't."

Reading the hex blob EBO shows you

EBO and several other BAS workstations display a discovered BACnet/IP device address as a hex string rather than the dotted-decimal form. The string is just the device's MAC — the four-byte IPv4 address, optionally followed by the two-byte UDP port. Decoded:

Decoding C0A80164BAC0 to IP and port A 12-character hex string C0A80164BAC0 sits at the top. The first eight characters are grouped together in the accent color (the IP-address bytes). The last four characters are grouped in a second color (the UDP port bytes). Below, the first group decodes to 192.168.1.100 byte by byte: C0 to 192, A8 to 168, 01 to 1, 64 to 100. The second group decodes to port 47808 — 0xBAC0 written in hex. A caption notes that an 8-character hex string is IP only; 12 characters carries the port too. EBO discovery shows C0 A8 01 64 BA C0 C0 192 A8 168 01 1 64 100 192.168.1.100 IPv4 address (4 bytes) BA C0 port 47808 0xBAC0 — default BACnet/IP port 8 hex chars = IP only · 12 hex chars = IP + port · suffix usually omitted on the default

The default port (0xBAC0 = 47808) is almost always omitted from the displayed hex — an 8-character string is normal, and any 12-character string ending in BAC0 is the IP at the default port written long-hand. A 12-character string ending in something else (BAC1 = 47809, for example) means the device is on a non-default BACnet/IP port, usually because someone stood up a second logical BACnet/IP network on the same host using ASHRAE 135 Annex J's sequential-port convention.

The BACnet/IP Hex Converter tool does the same decoding in both directions — paste a hex string from an EBO discovery dialog and read the IP + port back, or assemble the hex string from an IP and port to paste into a configuration field. The math is trivial; the tool exists so you don't lose flow context doing it by hand.

When discovery silently fails

BACnet has no "couldn't deliver" feedback for broadcasts. When discovery doesn't work, the symptom is almost always "I can't see a device I expect to see," with no error to grep for. The list below is what to check, in roughly the order it bites in the field:

  • No BBMD on the remote subnet. The target device sits on a subnet with no BBMD configured at all. Local devices on that subnet see each other fine; cross-network discovery never reaches them. Stand up a BBMD on that subnet and add it to every peer's BDT.
  • Asymmetric BDT. BBMD A lists B, but B's BDT doesn't list A. Discovery from A reaches B, but the I-Am reply doesn't make it back. Symmetric BDT entries are a deployment hygiene rule; every BBMD's BDT needs every other BBMD.
  • Firewall blocks UDP 47808. A firewall rule (host-based on the BBMD, network ACL on the router, or a corporate edge filter) is dropping UDP 47808 between the subnets. Symptom: BBMDs are configured correctly but no Forwarded-NPDU ever arrives. Confirm with a Wireshark capture or by pinging UDP 47808 between the two BBMDs.
  • Network-number collision. Two BACnet network segments routed together both claim the same network number. The network layer can't disambiguate; routers and BBMDs throw the message away or send it the wrong way. Every BACnet network in an internetwork needs a unique number.
  • BBMD on the wrong VLAN. The BBMD's IP is on a different VLAN than the BACnet/IP devices it's supposed to serve. The BBMD captures nothing because it isn't actually on the broadcast domain. The fix is network plumbing: put the BBMD's NIC on the BAS VLAN, or trunk the VLAN to it.
  • FDR TTL expired. A foreign-registered workstation isn't re-sending Register-Foreign-Device often enough; the BBMD's FDT entry timed out. Most engineering tools handle this automatically; a custom client may not. Symptom: discovery works briefly after a re-connect, then stops.
  • Two BBMDs on one subnet. Someone added a second BBMD to a subnet that already had one. Every Forwarded-NPDU arriving from a peer gets re-broadcast by both — and each of those re-broadcasts gets captured by the other BBMD and forwarded again. A slow, expensive loop. One BBMD per subnet is the rule.
  • Max APDU mismatch on segmented replies. The client asks for a property whose value is too large for a single APDU; the device tries to send a segmented reply; segmentation is disabled or the client's Max APDU doesn't match what the device announced in its I-Am. The exchange falls on the floor. Rare in everyday work, common when reading very large object-property lists from a Device object.

What this page didn't cover

Two pages on BACnet — one on the object model and services, one on addressing and networking — cover what most BMS techs need to read a point list, form a request, route a message across a router, and reason about why a device isn't showing up in a discovery scan. What's left, deliberately out of scope on this pair:

  • MS/TP on the wire. Token rotation, the master-token-passing mechanic, Max_Master and Max_Info_Frames, baud rates, the cable- length and device-count limits per segment. Now its own page: BACnet MS/TP.
  • Segmentation of long messages. When an APDU is too big for one frame, how segmentation breaks it up and how the receiver reassembles. Hinted at in the discovery-fails list above; a deeper treatment belongs on its own page.
  • BACnet/SC — Secure Connect. The newer TLS-WebSocket transport. Different framing, different discovery (no broadcasts at all — hub-and-spoke), worth its own page once it's common enough in BAS work to justify the depth.
  • Capture-driven troubleshooting. A Wireshark or Yabe walkthrough — what a Who-Is looks like in a capture, how to spot a Forwarded-NPDU, what an Abort or Reject PDU is telling you. Worth its own treatment given how often a capture is the fastest path to a root cause.
  • Alarms and event notifications. The confirmed and unconfirmed alarm services, the Notification Class object, recipient lists, COV-style push for events. Their own page; touches BACnet's biggest object-model surface outside the analog/binary/multi-state core.
  • Vendor profile differences. The practical reality that two BACnet devices, both advertising the same object types, may expose them with very different property sets and command behavior. Vendor-specific notes don't fit on a general education page; they belong on per-platform pages (Niagara, EBO, …) when those land.
← Back to Education