Packet Options
UMSH packet options use the delta-length encoding described in Packet Structure. Each option has a numeric option number whose two least significant bits encode two semantic attributes:
- Bit 0: Critical (1) / Non-Critical (0)
- Bit 1: Dynamic (1) / Static (0)
This means a node can determine an unrecognized option’s attributes by inspecting its option number without consulting a registry.
Attribute Encoding
The four attribute combinations and their option number patterns:
| Low 2 bits | Option numbers | Classification |
|---|---|---|
0b00 | 0, 4, 8, 12, … | Non-Critical, Static |
0b01 | 1, 5, 9, 13, … | Critical, Static |
0b10 | 2, 6, 10, 14, … | Non-Critical, Dynamic |
0b11 | 3, 7, 11, 15, … | Critical, Dynamic |
Critical vs. Non-Critical
These determine behavior when a node encounters an unknown option:
- Critical (bit 0 set): if unrecognized, the packet must be dropped
- Non-Critical (bit 0 clear): if unrecognized, the option is ignored and the node continues processing
Dynamic vs. Static
These determine whether an option is covered by the MIC:
- Dynamic (bit 1 set): not protected by the security MIC; may be modified in transit by repeaters
- Static (bit 1 clear): protected by the security MIC; must not be modified in transit
This distinction allows forwarding-related metadata (source routes, trace routes, station callsigns) to be modified by repeaters without invalidating end-to-end authentication.
Defined Options
| Number | Name | Classification | Value |
|---|---|---|---|
| 0 | RESERVED | Non-Critical, Static | |
| 1 | UNASSIGNED | Critical, Static | |
| 2 | Trace Route | Non-Critical, Dynamic | 0+ bytes |
| 3 | Source Route | Critical, Dynamic | 0+ bytes |
| 4 | Operator Callsign | Non-Critical, Static | ARNCE/HAM-64 |
| 5 | Minimum RSSI | Critical, Static | 0–1 bytes |
| 6 | Route Retry | Non-Critical, Dynamic | 0 bytes |
| 7 | Station Callsign | Critical, Dynamic | ARNCE/HAM-64 |
| 8 | Ack MIC | Non-Critical, Static | 4 bytes |
| 9 | Minimum SNR | Critical, Static | 0–1 bytes |
| 10 | Trace Signal | Non-Critical, Dynamic | 0–1 bytes |
| 11 | Region Code | Critical, Dynamic | 2 bytes |
Trace Route (option 2)
- Semantics: if present, repeaters prepend their own repeater hint before retransmitting.
- If absent, no trace-route information is added automatically.
- If more than one option with this number is present, the packet MUST be dropped.
- Value layout: see Trace Route Option Value.
- If implemented, Trace Signal (option 10) MUST also be implemented.
Important
If a repeater supports the Trace Route option, it MUST also implement the Trace Signal option (even if it is just adding placeholder values). Failure to do this breaks the one-to-one relationship between the Trace option and the Trace Signal options, making the Trace Signal value useless.
Source Route (option 3)
- Semantics: contains an ordered list of repeater hints designating the forwarding path.
- If more than one option with this number is present, the packet MUST be dropped.
- Repeater behavior:
- Only the repeater matching the first hint may forward the packet.
- That repeater removes its own hint before retransmission.
- If removing its own hint leaves zero remaining hints, the repeater still preserves the source-route option with an empty value.
- This is important: the forwarded packet still carries the information that it was explicitly source-routed, even though the route is now exhausted.
- Removing the last hint does not change what kind of hop this is. The repeater was named, so it forwards as a source-routed hop and leaves
FHOPS, region policy, and signal-quality thresholds alone. The next repeater sees the empty option and is the first to flood.
- Repeaters that do not match the first hint must not forward the packet.
- Value layout: see Source Route Option Value.
Operator Callsign (option 4)
- Encoding: ARNCE/HAM-64 (2, 4, 6, or 8 bytes; encodes callsigns up to 12 characters)
- Semantics: identifies the original packet sender’s amateur radio callsign.
- Use: required for locally originated packets in
Licensed-Onlyamateur operation. - In
Hybridoperation, its presence marks the packet as eligible for forwarding under amateur-radio authority; packets without it may still be forwarded under unlicensed authority if local rules allow.
Minimum RSSI (option 5)
- Type: unsigned 1-byte integer, interpreted as a negative dBm value
- If more than one option with this number is present, the packet MUST be dropped.
- Semantics: packet must be received with at least this RSSI to be flood-forwarded. This option does not apply to source-routed hops.
- Example: value
130means-130 dBm - If present with no value (length 0), default is
-100 dBm(THIS VALUE IS SUBJECT TO CHANGE) - If a repeater has a locally configured minimum RSSI, it must use the higher of the packet’s minimum RSSI threshold and the repeater’s configured minimum RSSI threshold.
Route Retry (option 6)
-
Type: zero-length flag
-
Semantics: indicates that the originator is re-attempting forwarding of the same logical packet after a route it had assumed was considered failed.
-
If more than one option with this number is present, the packet MUST be dropped.
-
This option is intended for sender-originated route recovery, not for ordinary first transmission.
-
The failed assumption need not be a source route. A sender that narrowed
FHOPSbecause it believed the destination was directly reachable, or reachable within a known flood distance, has made the same kind of assumption; nothing on the wire distinguishes that packet from an ordinary short-radius flood, and the recovery is the same. -
When present, repeaters treat the packet as a distinct forwarding attempt for duplicate-suppression purposes even though the MIC and frame counter are unchanged.
-
The destination does not treat this option as creating a new logical packet. Replay acceptance and duplicate application delivery remain governed by the packet’s normal security state, especially its frame counter.
-
A sender using this option for route recovery typically:
- removes the stale source-route option, if one was present
- adds or refreshes flood hops, up to but not beyond the budget the sending application was willing to spend
- includes a trace-route option to learn a replacement route
- preserves the same frame counter and payload
Each of these rewrites a field the associated data excludes, which is what lets the retry reuse the original MIC unchanged. Adding
FHOPSto a packet that had none also sets the FCF’sHbit, and the AAD clears that bit for this reason.
Station Callsign (option 7)
- Encoding: ARNCE/HAM-64 (2, 4, 6, or 8 bytes; encodes callsigns up to 12 characters)
- Semantics: identifies the transmitting station’s amateur radio callsign.
- If absent, the station callsign is assumed to equal the source callsign (if present)
- This option is critical because repeaters must replace or remove it during forwarding.
- Use:
- in
Licensed-Onlymode, repeaters replace or insert it on every forwarded packet - in
Hybridmode, repeaters also replace or insert it on every forwarded packet - in
Unlicensedmode, repeaters remove it if present and do not add their own
- in
Ack MIC (option 8)
This option represents a piggy-backed MAC ack that, when received, behaves as if it was an ack for the referenced packet, instead of sending both a MAC ack and an application-level response in two separate packets.
- Type: 4-byte ack MIC — the first 4 bytes of the acknowledged packet’s on-wire MIC (see Ack Tag Construction).
The option carries only the correlation handle, not a keyed ack tag: the packet carrying the option is itself authenticated to the original sender, so its own MIC already proves the acknowledgement is genuine. The ack_mic value simply identifies which outstanding request the reply acknowledges.
Because the option sits in the plaintext options block, forwarders read it under the same terms as a standalone MAC ack, including for ack cancellation.
Minimum SNR (option 9)
- Type: signed 1-byte integer, in dB
- Semantics: packet must be received with at least this SNR to be flood-forwarded. This option does not apply to source-routed hops.
- If present with no value (length 0), default is
-3 dB. (THIS VALUE IS SUBJECT TO CHANGE) - If more than one option with this number is present, the packet MUST be dropped.
- If a repeater has a locally configured minimum SNR, it must use the higher of the packet’s minimum SNR and the repeater’s configured minimum SNR.
Trace Signal (option 10)
This option works very much like the Trace Route option, except that repeaters append signal quality information instead of router hints.
When this option is present, each repeater that will repeat the packet must first prepend the signal quality metrics for the packet they received to the value of this option. The signal quality metrics are two bytes: the first byte is the negative RSSI in dBm (so -90 becomes 90, for example), and the second is the signed SNR in cB (centibells, or 1/10ths of a dB).
Region Code (option 11)
- Type: 2-byte region identifier
- Semantics: restricts flood-routing to repeaters configured for the specified region.
- A repeater configured for one or more regions MUST NOT flood-forward a packet whose region is none of them. A repeater configured for no regions makes no regional claim and applies no such restriction.
- This option MUST NOT be enforced on a source-routed hop, which includes the hop that removes the last remaining hint. A repeater named in the route forwards regardless of region.
- Multiple region-code options may appear on the same packet. In that case, a repeater MAY flood-forward the packet if any one of the listed regions matches local policy.
- Because this option is dynamic, repeaters may insert it while flood-forwarding a packet that currently has no region code.
- A repeater must never rewrite an existing region code and must never add a second region code to a packet that already has one or more region-code options.
- Region insertion is a local policy decision. When no explicit local policy exists, a reasonable default is the IATA code of the closest regional commercial airport.
- Region insertion applies only during flood forwarding. An untagged source-routed packet is first tagged by the repeater that flood-forwards it — the one that receives it with an already-empty source route — not by the repeater that emptied the route.
Region Code Encoding
Region codes are 2-byte identifiers derived by one of two methods, depending on the type of region:
IATA-based regions. For regions defined by proximity to an airport or a metro area with its own IATA code, encode the 3-letter IATA code into a 16-bit value using ARNCE/HAM-16. Examples:
| IATA Code | Region Code |
|---|---|
| SJC | 0x7853 |
| MFR | 0x5242 |
Named regions. For regions that are not associated with a single airport (super-regions, cities without a nearby airport, geographic areas, etc.), the region code is the first two bytes of the SHA-256 hash of the region name (UTF-8 encoded), EXCEPT when performing ARNCE/HAM-16 decoding on the resulting value would yield three letters. In that case, you additionally perform the following transform:
def transform_letter_chunk(encoded: int) -> int:
"""Transform a three-letter ARNCE chunk into a non-letter ARNCE chunk."""
LETTER_MIN = 1
LETTER_MAX = 26
TRANSFORM_BASE = 27 * 1600 # 0xA8C0
TRANSFORM_COUNT = 26 ** 3 # 17,576
a = encoded // 1600
b = (encoded // 40) % 40
c = encoded % 40
if not all(LETTER_MIN <= x <= LETTER_MAX for x in (a, b, c)):
return encoded
rank = (a - 1) * 26 * 26 + (b - 1) * 26 + (c - 1)
return TRANSFORM_BASE + rank
Examples:
| Region Name | SHA-256 prefix | Region Code |
|---|---|---|
| Rogue Valley | 0xdf6f... | 0xdf6f |
| SF Bay Area | 0x31d9... | 0x31d9 |
| Southern Oregon | 0x6af2... | 0xD35F |
Note that the first two bytes of the SHA256 of “Southern Oregon” is 0x6AF2, which would decode to QDR, so it is transformed to 0xD35F (which would decode as 654).
Thus, non-IATA-based region codes will never collide with IATA-based region codes. This allows all region codes which decode to three letters to be assumed to be an IATA region code and can be used/displayed unambiguously without additional context.
However, collisions can still happen between hash-originated region codes. These collisions are rarely of practical concern. If a region code in one part of the world collides with a region code in a different part of the world, there is no actual ambiguity because flood repeating is an inherently local event. In the rare case of a collision within a geographic area, it can be resolved by adjusting the named region slightly (for example, making it more specific).
The assignment and scope of non-IATA-based region codes—and resolution of any collisions—are generally handled locally.
Routing Option Layouts
Source Route Option Value
A source-route option contains zero or more router hints:
+----------+----------+----------+-----+
| RH[0] | RH[1] | RH[2] | ... |
+----------+----------+----------+-----+
2 B 2 B 2 B
Where each RH[i] is the first two bytes of a repeater’s public key.
Interpretation:
RH[0]is the next repeater that must forward the packet- when that repeater forwards, it removes
RH[0]
An empty source-route option indicates that all explicit routing hints have been consumed.
- For forwarding purposes, an empty source-route option behaves the same as an absent source-route option: there is no remaining explicit next hop.
- However, it is still semantically useful and should be preserved when produced by forwarding, because it records that the packet did in fact traverse an explicit source-routed path before the hints were exhausted.
Trace Route Option Value
A trace-route option also contains zero or more router hints:
+----------+----------+----------+-----+
| RH[0] | RH[1] | RH[2] | ... |
+----------+----------+----------+-----+
2 B 2 B 2 B
Repeaters prepend their 2-byte router hint:
new_trace = my_router_hint || old_trace
So the list is ordered most-recent repeater first.