Haiku Network Interfaces: Enumerating State Without Guessing
Inspect Haiku network interfaces and addresses through Network Kit APIs, distinguish link state from configuration, and handle changes safely.
Haiku’s Network Kit exposes a higher-level view of network interfaces through BNetworkRoster and BNetworkInterface. These classes make it possible to enumerate interfaces, inspect flags and addresses, query link state, and request selected configuration changes without constructing raw ioctl structures for each operation. They are not an always-current immutable snapshot, and an interface can change between enumeration and the next API call.
The central operational distinction is between a network device, a configured interface, and usable connectivity. A hardware device may exist while no interface is configured; an interface can be up while having no useful address; an address can be present while a route or DNS configuration is wrong; and a link can be active while the remote network is unreachable. A reliable diagnostic records each layer independently instead of treating “network is down” as one state.
Enumerate interfaces with BNetworkRoster
BNetworkRoster::Default() provides the singleton roster. CountInterfaces() reports a count, while GetNextInterface() fills a BNetworkInterface using a caller-managed cookie. Initialize the cookie to zero and continue until the roster reports that no further entry is available. Do not assume that the count and enumeration form an atomic snapshot: interfaces can appear or disappear during the scan.
BNetworkRoster& roster = BNetworkRoster::Default();
uint32 cookie = 0;
BNetworkInterface interface;
while (roster.GetNextInterface(&cookie, interface) == B_OK) {
printf("%s index=%lu mtu=%lu link=%s\\n", interface.Name(),
interface.Index(), interface.MTU(),
interface.HasLink() ? "yes" : "no");
}
For production code, copy the interface name and inspected fields into an application-owned record before making other API calls. A mutable BNetworkInterface object is a handle used to query the system, not a permanent identity object. Check Exists() or SetTo() status before relying on a name or index obtained earlier.
Interface names such as a wired or wireless device label are useful to humans, but not a promise of durable identity across hardware changes or boot configurations. An interface index can also be reassigned. Persist user intent with a stable device policy supported by the system rather than assuming that a numeric index always describes the same physical card.
Read flags, addresses, and link state separately
BNetworkInterface exposes flags, MTU, media type, metric, statistics, and HasLink(). These values answer different questions. HasLink() describes the link indication exposed by the interface; it does not test gateway reachability or prove that DNS works. Flags may indicate administrative state or protocol state, but an application should interpret the specific flags in the public headers rather than infer meaning from a displayed label.
IPv4 and IPv6 configuration is represented through BNetworkInterfaceAddress and BNetworkAddress. An interface can have multiple addresses, so iterate CountAddresses() and GetAddressAt() instead of assuming a single address per family. Address records include values such as netmask, broadcast or destination, and flags. For IPv6, do not impose IPv4 concepts such as broadcast where they do not apply.
Address lists can change asynchronously. If GetAddressAt() returns an error after CountAddresses() succeeded, report the race or rescan rather than indexing beyond the available entries. If the application needs a stable presentation, take a best-effort copy and refresh it when the roster notifies the application about changes.
Watch roster changes, then reconcile current state
BNetworkRoster supports StartWatching() and StopWatching() with a BMessenger target and event mask. Notifications are valuable hints that a device or interface has changed, but a notification should not be treated as a complete, durable state log. The target may be unavailable, a message can be delayed, and a change can occur while the application is processing another event.
Use notifications to trigger a fresh enumeration. Keep a serialized update path on the target looper, debounce rapid changes if necessary, and make the reconciliation idempotent. A good UI model can safely process the same interface-change notification twice by rebuilding or updating the view from current state. It should also perform an initial enumeration after starting to watch so that startup races do not omit an interface.
If a watched interface disappears, stale interface objects should not be used indefinitely. Re-open by current name or enumerate again, check existence, and handle status failures. A UI must also handle its target’s shutdown by stopping watches and releasing any references it owns.
Configuration calls mutate system state
BNetworkInterface offers setters for flags, MTU, media, metric, and addresses. These are not harmless inspection methods. Changing the MTU can break protocols that assume a different path size; enabling an interface can expose traffic; changing an address can interrupt active connections; and changing a metric can alter route selection. Use a clear user action, privilege model, validation, and rollback plan before calling setters.
For ordinary diagnostics, prefer reading the state and displaying recommended commands or settings rather than silently applying changes. If a user-authorized configuration change is required, record the previous values, check each return status, re-read the interface after the mutation, and report partial failure accurately. A sequence of several setters is not automatically one atomic transaction.
Wireless network persistence is a separate roster feature. BNetworkRoster includes methods for listing or adding persistent networks, but saved credentials and connection state are not equivalent to the interface’s current address and link information. Keep interface telemetry distinct from profile configuration, association state, and authentication status.
Metrics need careful interpretation
GetStats() retrieves interface statistics through the network stack. Counters are cumulative values, not rates. To estimate throughput or errors per second, capture two readings with timestamps and compute deltas while accounting for counter width, device resets, and interface replacement. A counter that decreases may signal reset or wrap, not negative traffic.
MTU and media values also need context. An interface MTU describes a configured link-layer or network-interface limit; it does not guarantee the same end-to-end path MTU. A wireless interface can report a link while its current connection has poor signal or no upstream route. These metrics are useful clues, not complete diagnoses.
A layered troubleshooting workflow
Start by enumerating the roster and recording interface name, index, flags, MTU, media, and link state. Then capture every configured address and its family. Inspect the routing table and resolver configuration through their appropriate APIs or command-line tools. Finally test a numeric remote address and a hostname separately to distinguish routing from name resolution.
If no interface is present, investigate hardware and driver discovery. If an interface exists but has no address, inspect DHCP or static configuration. If the link is absent, verify cable, radio association, hardware support, and administrative state. If the address is valid but remote traffic fails, test routes, gateway, firewalls, and path behavior. The Network Kit helps inspect the interface layer; it does not replace end-to-end network tests.
Keep interface discovery race-aware
Network configuration is mutable system state. An interface can be removed while a diagnostic runs, a DHCP client can replace an address, or a user can change a profile. Treat every API result as a time-stamped observation. For operations that make decisions from multiple fields, re-read the interface just before applying a change and be prepared for that check to become stale as well.
The production-grade approach is to separate enumeration, inspection, change notification, mutation, and reachability testing. BNetworkRoster identifies the current set of interfaces; BNetworkInterface exposes useful per-interface properties; notifications prompt reconciliation; and explicit network tests determine whether a service is usable. Keeping those boundaries clear makes Haiku network diagnostics reproducible and prevents a single “connected” indicator from hiding which layer actually failed.
Related:
- Inside Haiku’s Network Stack: Interfaces, Protocol Modules, and Userland Services
- Fixing Networking and DHCP Issues on Haiku
Sources: