How does a network know a received packet is for them?

Hello! I’m trying to dig into the LoraWan specifications, but I still do not understand how a network knows a certain packet is for that network or an application within that network.

The specification says: "The process to build those keys (NwkSKey and AppSkey) should be such that the keys cannot be delivered in any way from public available information (like the node address for example)”

Is the network using a non-public private key to decrypt that information to have access to the appEUI? But how is ‘roaming’ facilitated then?


How a network knows a certain packet is for that network:

Each network has to apply for a NetID with the LoRa Alliance. For example, The Things Network has NetID 19 (0x000013). Device addresses are based on this NetID as follows: The seven LSB of the NetID (which are called NwkID) match the seven MSB of the device address. This means that all devices within The Things Network will have addresses that start with 0x26 (0x13<<1) or 0x27. This allows us to drop messages that are not meant for The Things Network (or forward them to the correct networks when the specification for roaming is done).

Note that this filter is currently not active in the staging environment. When the production environment is launched we will probably start doing this.

How a network knows a certain packet is for a specific application within that network:

An application has to register devices with the network. This is done when you create a device in the dashboard or through the ttnctl command line tool. With this registration, you must also give the network your NwkSKey, which is used to “sign” messages (MIC). When a message arrives from a device, it only contains a dynamic, non-unique DevAddr, no AppEUI or DevEUI. The network retrieves a list of all devices with that specific address from the database. Next, it tries to verify the message signature (MIC) for all matching devices using the NwkSKey of each device. When a match is found, the network knows to which application the message should be forwarded.


Thank you for your answer @htdvisser !
Now things fall into place.

Note that this process does not need to happen for all packets, since typically the frame counter of a packet also helps to disambiguate between multiple devices with the same DevAddr (Not sure if this is implemented already, I expect not).

Assuming there will be more than 128 networks, the NwkID won’t be unique. So I guess that even after filtering it’s still to be expected to get packets for which no application can be found, just as they happen to be for a different network (which should have received the packet through its own gateways as well).

(The NetID is 24 bits; the NwkID is 7 bits.)

@matthijs: True, this is implemented for the production version of the backend. Devices with a lower FCnt will be ignored.

@arjanvanb: True. We’ll just drop these, as we don’t know what to do with them.

I think you’re referring to the replay protection, which is not what I meant. I meant that if two devices have the same devAddr and the last Fcnt for one is 100 and the other has 400, then a new message with Fcnt 401 will likely be originating from the second device, not the first one, so no need to check the MIC with both devices’ keys.

Likely, but it is not completely impossible that we missed 200 messages from the device. It might however be a nice optimization to sort the results in increasing order of FCnt and improve the chances of an early exit from the loop.

The device addresses I get when using OTAA all start with 0x1C or 0x1D.
Does this mean we are now using someone else’s NETID ?

When we set up the staging server we didn’t have a netid yet, so we just picked something and never bothered to change it :wink:

The production servers will use the correct netid.

Is there a public list of assigned NetID’s from the Lora Alliance?

I don’t know. Let me know if you find it!