Inside Haiku's Network Stack: Interfaces, Protocol Modules, and Userland Services
A layered account of Haiku networking, from device drivers and kernel protocols through routes, DNS, services, and application APIs.
Haiku networking is a chain of cooperating layers, not one component that is simply “up” or “down.” A hardware driver exposes a network device. Kernel modules provide interfaces, link-layer handling, address families, routing, and transport protocols. Userland configuration services arrange addresses and routes. The resolver turns names into addresses, and applications consume socket or higher-level APIs. Each layer can succeed while the one above it fails.
That distinction is the key to both design and troubleshooting. An interface visible to the system proves that some device and driver plumbing exists; it does not prove that a cable has link, DHCP supplied a lease, a default route is installed, a DNS server answers, or TLS negotiation succeeds. Conversely, one browser failing to load a modern site does not establish a kernel network-stack defect when another application can reach the same address.
From hardware to a kernel interface
At the lowest relevant layer, a driver must recognize the network controller, initialize it, exchange frames, and report link-related state. Haiku’s device-manager documentation describes drivers and devices as kernel modules organized through device nodes. Network drivers live within that native driver model even when some hardware-specific code originated in another operating system. Adaptation must connect interrupts, DMA, memory ownership, device publication, and Haiku’s synchronization rules correctly.
Once the device is available, Haiku’s networking code represents it as an interface. The public Network Kit exposes BNetworkRoster::Default() to enumerate interfaces and BNetworkInterface to inspect or change interface properties. Its current header includes operations for flags, MTU, media, metric, hardware address, configured addresses, routes, and default gateways. These are management APIs over system networking state, not packet parsers embedded in every application.
An interface can have multiple addresses and address families. BNetworkInterfaceAddress groups an address with its mask, broadcast address, or point-to-point destination. Treating “the IP” as a single string loses that structure and breaks down immediately with IPv4/IPv6 coexistence, multiple networks, or a loopback interface.
Hardware presence, administrative state, and physical link are separate facts. A driver can publish an interface for an unplugged Ethernet adapter. An interface can be administratively enabled without receiving frames. A Wi-Fi device can exist without association to an access point. Diagnostic reports should record those states independently instead of reducing them to a green or red network icon.
Protocol modules and the socket boundary
Haiku’s source tree keeps the kernel networking implementation under src/add-ons/kernel/network, with modules for the stack, devices, interfaces, protocols, and related facilities. This modular arrangement lets packet flow pass through a defined interface rather than compiling every supported protocol and link type into one indivisible block.
Applications ordinarily do not talk to these kernel modules directly. Haiku’s source organization describes libnetwork.so as providing the POSIX/BSD socket implementation and extensions, together with resolver functionality. The familiar socket sequence—selecting an address family and transport, creating a socket, binding or connecting, then reading and writing—crosses this user/kernel boundary.
The socket API communicates endpoints and byte or datagram streams; it does not promise that a peer exists or that application data is valid. A successful socket creation proves only local resource allocation. A successful TCP connection proves that a transport handshake completed to the selected address and port. It does not prove that HTTP, TLS, mail, or another application protocol will succeed.
This layered contract explains error locality. B_NO_MEMORY or file-descriptor exhaustion can stop socket creation locally. An unreachable route fails before any remote application responds. A refused connection commonly means the destination was reachable but nothing accepted that port. A timeout may reflect filtering, packet loss, a missing route, or a silent peer; it requires evidence rather than one fixed interpretation.
Address configuration, routes, and DNS
Address assignment can be static or negotiated. Haiku’s Network preferences panel exposes per-interface settings, including automatic or manual configuration, while system services apply the result. An automatically assigned address depends on more than the interface driver: discovery packets must leave, replies must return, and the configuration client must parse and install the lease.
A valid local address still does not define where every packet goes. Connected routes describe directly reachable networks, while a default route selects a gateway for other destinations. BNetworkInterface provides route inspection and manipulation methods, reflecting that routes are first-class state. If a host on the local subnet responds but an Internet address does not, the mask, gateway, and routing table are more relevant than the DNS configuration.
Name resolution is another independent layer. The resolver translates a hostname into one or more addresses using configured services and policy. Testing only a hostname combines routing and DNS into one result. A better comparison tries a known numeric destination, then resolves the desired name, then connects to the resolved address. If numeric connectivity works while lookup fails, resetting the hardware driver is unlikely to address the cause.
DNS success is not application success. A hostname may resolve to IPv4 and IPv6 addresses with different reachability. The server may reject the requested TLS version or certificate validation may fail because the system clock or trust store is wrong. HTTP can return an error after both transport and encryption succeed. Record the exact stage and error rather than calling every failure “DNS.”
Native APIs above raw sockets
The Network Kit includes classes for addresses, interfaces, cookies, URLs, and other network-related data. Haiku also documents an experimental Network Services API for higher-level requests. That API is explicitly marked experimental and lives in a private namespace, so it should not be presented as a stable replacement for every shipping application.
Its documentation nevertheless reinforces an important design rule: do not block a GUI window’s message loop on network I/O. Higher-level request facilities can report milestones through Haiku’s Looper/Handler messaging model, such as name resolution and connection establishment. A native application can update progress or cancellation state without polling every few CPU cycles.
For a stable application, choose the narrowest supported abstraction that matches the task. Raw sockets are appropriate for a custom protocol or low-level diagnostic tool. A URL or service library can centralize parsing, redirects, authentication, and protocol behavior where its stability contract is acceptable. Regardless of layer, network data is untrusted: lengths, encodings, decompression, certificates, and protocol state must be validated before use.
A forensic troubleshooting ladder
Begin with hardware identity. Record the controller, loaded driver, interface name, and whether link or association is present. If the interface never appears, DHCP and browser settings are premature. If transmit counters increase but receive counters remain fixed, examine link, access point, switch, driver receive path, and filtering rather than repeatedly editing DNS servers.
Next inspect interface state: flags, MTU, addresses, masks, and hardware address. An address in a link-local range may indicate that normal automatic configuration did not complete. Check whether the expected family is configured and whether a duplicate address or wrong mask could misclassify remote hosts as local.
Then inspect routes. Verify a connected route for the local network and the intended default gateway. Test the gateway itself before an external numeric address. This divides local link failure from routing beyond the local network. Packet capture is especially useful here because it shows whether address-resolution requests, DHCP exchanges, and transport handshakes leave and receive replies.
Only after numeric reachability is established should DNS become the main suspect. Record the configured name servers, query result, returned addresses, and whether each address family is reachable. Finally test the application protocol with a second client or a simpler endpoint. A browser-specific rendering failure, proxy setting, certificate error, or HTTP incompatibility belongs above the kernel stack.
Logs and captures should be collected before toggling the interface because reconfiguration can erase timing and state that identify the fault. A reproducible sequence with timestamps, packet direction, interface counters, route table, and exact error is more actionable than “networking stopped until reboot.”
Porting code does not erase Haiku’s architecture
Network-driver and protocol work often benefits from compatible open-source implementations, but imported code still has to conform to Haiku’s kernel, device, module, locking, and userland ABI. The public result is a Haiku interface used through Haiku’s stack and libraries. Describing the whole subsystem as “a BSD port” ignores the integration work and can lead developers to assume foreign configuration paths or kernel interfaces that do not exist.
The practical architecture is visible in the source: hardware support, kernel networking add-ons, libnetwork, net_server, preferences, and applications occupy distinct directories and responsibilities. That separation lets a driver be replaced without rewriting every browser and lets resolver or configuration behavior change without changing the wire protocol implementation.
A good network-status claim therefore states the tested layer: the device is detected; link is established; DHCP installed an address; a gateway is reachable; DNS resolves; TCP connects; TLS validates; or the application completed its request. Those statements compose into a functioning network, but no single one substitutes for all the others.
Related:
- Fixing Networking and DHCP Issues on Haiku
- The Haiku Kernel: A Modular, Pervasively Multithreaded Design
Sources: