Interfaces, Addressing, and Proxy ARP
PacketRF treats np2, us0, et1 and the optional PPP interface as proper network interfaces, not as special-case side channels. Each one has its own configuration section, its own addressing mode, and its own role in routing. That is the reason the system stays universal as new transports are added: every transport is "just another interface" that fits into the same model, instead of growing one-off glue in the code.
This page describes that model — the interface inventory, how addresses are assigned, what a pool is, why proxy ARP exists at all, and what the alternative would look like if you preferred routed operation instead.
The interfaces in front of you
A PacketRF node typically exposes the following:
| Runtime name | Purpose | Underlying transport |
|---|---|---|
np2 | NPR-facing IPv4 interface (the radio side) | NPR frames over 70cm band |
us0 | Default management and service interface | USB CDC-NCM |
et1 | Optional wired Ethernet | W5500 over SPI |
ppN | Optional PPP link (ppp1 config section) | PPPoS over USB or serial |
Configuration sections in persistent storage are named after the role, not after the runtime netif. That is why you may see npr1 in the config but np2 at runtime — the section describes the radio configuration, the netif is the live IPv4 interface that the radio runtime brings up.
The radio side and the local side share the same lwIP networking model, but the data path underneath them is different. Local interfaces are Ethernet-style: lwIP gives them packets, lwIP gets packets back, and the netif driver pushes bytes over USB or W5500. The NPR side is not Ethernet; the runtime takes IPv4 packets from lwIP, hands them to the NPR segmentation layer, and the radio schedule decides when they go out. Reception is the mirror image — NPR frames are reassembled into IPv4 packets and fed back into lwIP. From the host point of view it is all just IPv4 routing on a collection of interfaces.
Addressing modes
PacketRF currently supports a small set of IPv4 addressing modes:
| Mode | Where the address comes from | Typical use |
|---|---|---|
static | Configured directly in the section | Fixed local service link |
dhcp | External DHCP server reachable on this interface | Wired Ethernet client on a real LAN (et1) |
from-pool | Assigned by a named PacketRF pool | USB service interface fed from a managed range |
disabled | The interface is configured but not active | Optional interfaces left turned off |
The from-pool mode is the one that often surprises people on first contact, so it gets its own short section below.
Pools
PacketRF needs one consistent place to assign IPv4 addresses, because several pieces of the system want to do it: the USB interface needs an address to bring itself up; a DHCP server needs a range to hand IP addresses to any client; an NPR master needs to allocate addresses to connecting slaves; PPP needs a local/peer pair. Without a shared mechanism, each of those would invent its own small allocator with its own glue code and bugs. That is why packetRF has the pool manager to do this.
A pool is a named, configured IPv4 range. Pools come in two flavours:
- Static pools are configured directly. They have a fixed start address, size, subnet mask, and optional gateway and DNS values. They become valid as soon as the configuration is loaded successfully.
- Dynamic pools do not carry their range in configuration. Instead, they declare a source interface, and the runtime publishes the actual range to them when that source has one. The classic case is
pool1withsource_interface=np2: an NPR slave learns its IP range from the master at connect time, and only at that moment does the pool become valid and usable. This is why the system distinguishes between configured (the pool exists in config) and valid (it has a usable range right now).
In the factory configuration the pools are:
pool1— dynamic pool, populated from the NPR side once a slave link is uppool2— static service pool, defaults to192.168.42.1/28, gateway192.168.42.1(this is what makes the device come up at192.168.42.1over USB out of the box)pool3— static NPR master pool, defaults to192.168.43.31with master-side allocation starting at192.168.43.32
What each interface looks like by default
np2 is the live IPv4 interface exposed by the NPR runtime. Its addressing depends on the role:
- as a slave, the IPv4 configuration on
np2is learned from the master at connect time. Whatever you typed intonpr1for the client side is only an initial placeholder; the real configuration arrives over the air and overwrites it. This is the same behavior as the original NPR firmware and is what keeps client configuration simple in practice. - as a master, the IPv4 configuration comes from the local NPR config and from the pool referenced by
npr1.master_pool(factory defaultpool3).
With factory defaults on a PacketRF master, np2 lives in 192.168.43.0/24 with the master at .31 and slave allocations starting at .32. As is standard NPR practice, the address range dedicated to NPR clients does not have to be aligned to a power of two — the master can hand out 1, 5, 17 addresses, whatever fits.
us0 is the default local management and service interface, exposed as USB CDC-NCM. Its factory defaults are:
- mode:
from-pool - pool:
pool2 - pool default:
192.168.42.1/28, gateway192.168.42.1
A DHCP server is also running on us0 by default and hands addresses out of pool2 to whatever is connected on the other side. This is what makes a freshly bootstrapped node just work the moment you plug it in: from the host operating system the device shows up as an ordinary USB Ethernet adapter, the host's normal DHCP client picks up an address out of 192.168.42.0/28, and the device itself sits at 192.168.42.1 ready to answer CoAP. No host-side configuration, no static address juggling — the same workflow as plugging in a USB-to-Ethernet dongle.
The usb config section also stores a static fallback (10.10.0.2/24 style values) that you can switch to if you have a particular reason to override the pool-based defaults, but the effective default is from-pool, not static.
et1 is the Ethernet-style interface used for the W5500. By default it runs a DHCP server backed by the dynamic pool that gets its range from the NPR side once a slave link is up. In other words: on a slave node, plug a host into the W5500, wait until NPR connects, and the host receives an address from the range the master allocated to this slave. Until the radio link is up the DHCP server has nothing to hand out yet, so this only works once the slave has actually joined.
In master mode this default does not apply — there is no upstream "master" to learn a range from. A master typically wants either a static configuration on et1 or a separate static pool to feed it from, depending on how the upstream network is wired.
PacketRF does not yet implement a real DHCP client on et1. That means you cannot currently drop a node into a foreign LAN and have it pick up an address from somebody else's DHCP server. The DHCP client is on the roadmap; until it lands, treat et1 as a DHCP-server-side or static interface, not as a self-configuring LAN client.
PPP
PPP is present in the codebase but is disabled by default and not even compiled into the standard profile. It exists for historical reasons: the very first PacketRF prototypes used PPPoS over USB serial as the host link, and the USB CDC-NCM Ethernet path took its place once that was working well. PPP is mentioned here only for completeness; if you have a specific reason to bring it back, the configuration section is ppp1 and the runtime netif name is ppN (allocated by lwIP), with from-pool mode supported the same way as on the other interfaces. Most operators will never need to touch it.
Why proxy ARP
This is the part that is easy to miss until your packets stop showing up where they should. It is also the part that has been written about in the most detail on uart.cz, in Addressing and ARP in NPR networks. The short version is below; if you want the full reasoning with worked examples, that article is the long version.
The original NPR design wanted IP integration to feel as natural as possible. The chosen model is that all NPR modems on one network behave, from the IP perspective, as if they were sitting on the same big Ethernet segment. A host plugged into the master's LAN port should be able to talk to a host plugged into a slave's LAN port using a plain IPv4 address in the shared subnet, without configuring routing.
The catch is that NPR is not actually Ethernet. It does not carry broadcast frames across the radio. It does not transport ARP. So when your laptop wants to reach 192.168.43.50 and broadcasts an ARP "who has 192.168.43.50, tell me", that ARP request never crosses the radio. The slave that owns .50 will never see the question, and your laptop never gets an answer.
The way NPR resolves this is Proxy ARP. The modem on the local Ethernet segment watches ARP requests on its wired side. When it sees one for an address that is inside the NPR subnet but not part of the range it has been given itself, it answers the ARP request on behalf of the remote host, replying with its own MAC address. The host then sends the IP packet to the modem, the modem forwards it across the radio link to whichever slave owns the destination, and from the host's point of view the whole thing looks like a single flat network. This is not a PacketRF invention; the trick has a name and an RFC — Proxy ARP, RFC 1027.
PacketRF implements PARP explicitly and per interface, rather than as a global "always on" hack. The current policy lets you:
- enable or disable PARP on each Ethernet-like interface,
- bind PARP to a selected pool — typically the one populated by
np2on a slave, or the master's NPR pool on a master, - forward through to a selected target interface, normally
np2, - publish PARP route policy into lwIP through a route hook so forwarding decisions stay deterministic instead of relying on ad-hoc ARP table races.
This is an important part of the addressing model, with explicit configuration options, and it is what lets the pseudo-bridge feeling of original NPR keep working in PacketRF with more than one network interface.
The alternative: route it like a real network
Proxy ARP is the default because it is what NPR users already expect. It is not the only option, and there are good reasons to prefer the routed alternative on a more deliberately designed network.
In the routed model, every node — master and slaves — is a small router, the radio link is the backbone between them, and you assign each LAN segment its own subnet rather than pretending they all share one. The local hosts have a default route through their own modem, the modem has a default route through the master, and the master has a default route into the upstream world. There is no PARP, no pseudo-bridge, no "lying about MAC addresses", just IP routing.
The trade-off is that you have to plan addressing in advance and you have to configure routes correctly on every modem and on the upstream router. PARP avoids that planning at the cost of pretending NPR is an Ethernet segment, and that pretense leaks under a few specific conditions. Both models are legitimate; pick the one that matches what you are actually building. The uart.cz article walks through both choices in detail and is recommended reading for anyone who is going to deploy more than one node.
Routing model inside PacketRF
Status: not implemented yet. A first-class routing layer with its own configuration section is on the roadmap, but it is not in the firmware today. The paragraphs below describe the intended shape so the architecture is clear; the practical reality right now is that forwarding happens through lwIP's standard routing path with the PARP route hook layered on top, and there is no
routing1config section to edit yet.
The plan is to make the routing decision explicit rather than to hide it in scenario startup code. A dedicated routing1 section will own the default-route choice and any per-interface preferences, so multi-interface growth stays manageable as more radios and more transports show up. The intended split of responsibilities, once routing lands, is:
- Interfaces expose state. They report what they have and what they carry.
- Pools expose ranges. They are the single source of address assignment.
- Routing decides which packets go where. Default route, per-interface preferences, and overrides all live here.
- PARP solves ARP visibility on the local segments where the pseudo-bridge model is in use, and only there.
If you ever find yourself wondering where to put a new bit of networking policy, that list is the right map: it almost always belongs in exactly one of those four places, and almost never in more than one.