APRSDIGI(8)

πŸ“¦
version 3.11.0 Β· 3 versions
, in debian trixie, ubuntu questing, ubuntu resolute, ubuntu stonking

πŸ‘‘ APRSDIGI β€” the manual page, but make it a group chat πŸ’…

okay bestie, so this is aprsdigi, from the System Manager's Manual (that's the APRSDIGI(8) section, iykyk). Sit down, grab a strawberry, we're doing this. πŸ“


✨ NAME ✨

aprsdigi β€” an APRS(β„’) digipeater. that's it, that's the whole name section, slay.


🌸 SYNOPSIS 🌸

aprsdigi options

like… that's the whole vibe. you pass it options. iconic.


πŸ¦‹ DESCRIPTION πŸ¦‹

So aprsdigi is a specialized Amateur Packet Radio (AX.25) UI-frame digipeater built for the Automatic Position Reporting Systems, aka APRS(β„’). πŸ’–

It runs on the Linux kernel AX.25 network stack plus the SOCK_PACKET facility so it can listen for packets on one or more radio interfaces (we call those ports) and repeat those packets β€” with several possible modifications, no cap β€” on the same interfaces or on other ones. And because it's a multitasker, aprsdigi can also use the Internet to tunnel connections among other APRS digipeaters and nodes, using IPv4 or IPv6 UDP unicast or multicast. 🌈

It implements conventional packet radio AX.25 digipeating, which is the classic move: a packet gets digipeated if the next hop (the non-repeated one) digipeater β€” the "via" callsign β€” matches the AX.25 port's callsign and sub-station ID (SSID), or an alias callsign and SSID. πŸ’…

Now here's the tea β˜•: there are a bunch of extensions to conventional digipeating that have been proposed for the APRS community. Some of these features got adopted by Terminal Node Controller (TNC) manufacturers β€” notably Paccomm and Kantronics. And aprsdigi implements most if not all of the commercially adopted and proposed features. If you want the actual protocol documentation, see the APRS 1.0 Protocol Specification at www.tapr.org. aprsdigi attempts to minimally comply with the protocol spec while also supporting experimental APRS features. 🧚

The specific features implemented include, and bestie I am obsessed with this list:

  • Single-interface conventional UI-frame digipeating. ⭐
  • Cross-interface digipeating (also known as bridging, routing or gatewaying) and one-to-many fanout. 🌈
  • Substitution of a digipeated alias with the interface's callsign (typically used to substitute RELAY, WIDE or TRACE aliases). πŸ”₯
  • WIDEn-n flooding algorithm. πŸ’§
  • TRACEn-n route recording. πŸ“
  • Mic-Encoder(tm) support, including SSID-based digipeating and decompression of packets into the conventional APRS MIM format. (Fun fact: the Mic-Encoder compression is also used by other products such as the Kenwood TH-D7A and D700, and the TAPR PIC-Encoder.) πŸŽ€
  • TheNet X1J4 node beacon text translation (that's removing the β€œTheNet X1J4 (alias)” prefix from the btext). 🧹

πŸŽ€ GENERAL OPTIONS πŸŽ€

These are the everywhere-options, bestie. They apply globally, no per-interface drama. πŸ’–

  • -v, --verbose β€” Produce verbose debugging output. she's chatty, we love her. πŸ—£οΈ
  • -T, --testing β€” Test mode: listen to my packets too. This mode is useful for off-air experimentation and configuration testing. > Do not use it on-air. seriously. πŸ™ˆ
  • -D, --kill_dupes β€” Suppress Duplicate packets. Remembers duplicate packets for the number of seconds given by the -k option and will not repeat them more than once. This reduces congestion caused when several digipeaters that share a common flooding alias (e.g. WIDE) have overlapping footprints, which causes geometric duplication of packets addressed via β€œWIDE,WIDE” for example. basically it stops the echo chamber. πŸ’€
  • -L, --kill_loops β€” Suppress Looping packets. Similar in function to duplicate packet suppression, but it looks back through the list of already digipeated callsigns in the packet's digipeat list and kills any packets that list a callsign belonging to this aprsdigi. Note that only real callsigns are compared. Generic flooding aliases are not. Therefore, loop detection is only useful when callsign substitution is used. πŸ‘€
  • -V, --version β€” Print program version and exit. short and sweet, periodt. ✨
  • -n|s|e|w, --north|south|east|west β€” Set North|South|East|West SSID directional path. 🧭
  • -d, --digipath β€” Set SSID omnidirectional next-hops when operating in a non-flooding network (e.g. when WIDEn-n is not an option). 🌐
  • -W, --floodnlimit β€” Limit each flooding alias to this many hops, to limit traffic from excessive specifications. Default is off. πŸ›‘
  • -f, --flood β€” Set flooding alias. Use β€œ-f WIDE” to enable WIDEn-n flooding. Use -f multiple times to define several flooding aliases. 🌊
  • -F, --trace β€” Set flooding trace callsign. Use β€œ-F TRACE” to enable TRACE and TRACEn-n flooding. Use -F multiple times to define several trace aliases. πŸ”
  • -k, --keep secs β€” Remember old packets for this long for duplicate packet detection. Default is 28 seconds. ⏳
  • -H, --hops digipeats β€” Limit the total number of digipeats a packet that comes to us direct can request. This value is compared to the sum of the hops computed from the via list. Those packets exceeding this value are suppressed. Packets relayed to us by other digipeaters are not affected. Default is no limit. 🚦
  • -l, --logfile file β€” Log digipeated packets to this file. πŸ““

🌈 PER-INTERFACE OPTIONS 🌈

okay so real talk: put these options before each -p / --interface to set new values as needed. The values you set are remembered for subsequent -p's, so options you want to set for all interfaces only need to be specified once β€” before the first -p. 🫢

But you have to remember to unset an option if you don't want it to apply to subsequent interfaces. the memory is real, bestie, so don't get caught slipping. 😭
  • -C (-c), --[no]subst_mycall β€” Do (not) perform callsign substitution. When enabled, aliases are replaced with the interface's callsign when repeated. πŸ”
  • -M (-m), --[no]mice_xlate β€” Do (not) perform Mic-E to MIM translation. When enabled, compressed Mic-E reports are expanded into one MIM-style position report packet and optionally a second telemetry packet if telemetry was supplied in the Mic-E packet. πŸ›°οΈ
  • -X (-x), --[no]x1j4_xlate β€” Do (not) perform X1J4 translation. When enabled, the leading β€œTheNet X1J4 (alias)” text is removed when digipeated. This allows non-compliant APRS implementations to detect an APRS position report in an X1J4 beacon. 🧽
  • -i, --idinterval secs β€” Seconds between ID transmissions. Set to 0 to disable IDs on this interface. Default is 570 (that's 9 minutes 30 seconds, she's precise ✨). IDs are only sent if the interface transmitted anything since the last ID. ID packets are addressed to the β€œID” callsign, have no digipeat path, and list the callsign and aliases for the interface the ID is being transmitted on. πŸͺͺ
  • -t, --tag text β€” Text to append to received packets. Use -t - to reset to empty. Use this, for example, when gatewaying Mic-E packets from a voice repeater to the APRS net frequency to indicate where the report originated. 🏷️
  • -3, --3rdparty β€” Enable 3rd party tunneling. Packets tunneled to a 3rd party interface are sent with the unused digipeaters removed from the digipeater list. Packets tunneled from a 3rd party interface have the Source Path Header prepended to the packet payload prefixed by the "}" character. πŸ“¦
  • -0, --no3rdparty β€” Enable transparent tunneling. No special tricks are done when sending to or receiving from a tunneled interface. If the interface does not natively support AX.25 addresses (from-call, to-call, and digipeater list), then the address header is prepended to the payload in "cooked" format. Likewise, a cooked prepended header is stripped from a cooked interface and put back in the AX.25 address when going from a non-AX.25 to AX.25 interface. πŸ«₯
  • -o r, --norx β€” Disable receiving on the following interface(s). πŸ”‡
  • -o R, --rx β€” Enable receiving on the following interface(s). πŸ”Š
  • -o t, --notx β€” Disable transmitting on the following interface(s). 🚫
  • -o T, --tx β€” Enable transmitting on the following interface(s). πŸ“‘
  • -o s, --notxsame β€” Disable retransmitting a received packet on the same interface. πŸ™…
  • -o S, --txsame β€” Enable retransmitting a received packet on the same interface. πŸ’«
  • -o d, --duplicate intf β€” Duplicate received packets without modification to the given interface (port). πŸ‘―
  • -p, --interface ax25:port:alias1,alias2,... β€” AX25 interface name (port) and optional list of aliases. The primary callsign is obtained from the interface's configuration. (See ifconfig(8).) 🐧
  • -p, --interface udp:host/port/ttl:alias1,alias2,... β€” IP host name or address and list of aliases. IP addresses may be IPv4 unicast or multicast, or IPv6 unicast. The primary callsign is obtained from the first alias. 🌐
  • -p, --interface unix:filename:alias1,alias2,... β€” Unix file and list of aliases. Useful for debugging by setting up a simulated APRS network on one machine. You may want to make your FIFOs explicitly transmit- or receive-only to avoid confusion. The primary callsign is obtained from the first alias. πŸ§ͺ
  • -B|b, --[no]bud addr β€” Is similar to a TNC-2's BUDLIST. Use -B --bud to accept or -b --nobud to ignore packets from a sender or group of senders. Budlists are attached to each interface and can be reset with --bud -. You can set up a global budlist once, or per-interface budlists. The format of addr varies based on the interface type, and the options below show you the flavors: πŸ‘‘
    • --bud ax25:callsign-ssid β€” matches only a given digipeater callsign and SSID. For example, -B ax25:n0clu-14. 🎯
    • --bud ax25:callsign β€” matches all SSIDs for the given callsign. For example -B ax25:n0clu. 🎯
    • --bud ip:hostname β€” matches one Internet host name (IPv6 or IPv4). For example -B ip:n0clu.ampr.net. 🌍
    • --bud ip:address/maskbits β€” matches all IP addresses that have the given prefix. For example --bud ip:44.0.0.0/8 matches the entire class-A network. --bud ip:192.168.0.0/16 matches the entire class-B network. --bud ip:fe80::201:3ff:fe9a:38c6 matches a single IPv6 host. --bud ip:2002:905::/32 matches the 32-bit IPv6 prefix. πŸ•ΈοΈ

okay that's part one bestie, there's more coming so don't go anywhere πŸ’–

πŸ”” RUNTIME CONTROLS πŸ””

okay so bestie, aprsdigi is always listening πŸ‘‚ and it answers to these signals:

  • SIGUSR1 β€” prints out the cumulative statistics. for every single port, you get these counters: packets received, plus how many of those were ignored, duplicates, loops, and mic-E formatted; then packets transmitted, plus how many of those were conventional digipeats, flooding digipeats (WIDEn-n), SSID-based digipeats, and IDs. and if you gave it a log file with the -l --logfile option, the stats get written to that file instead. no log file? they go to stderr πŸ’…
  • SIGUSR2 β€” prints the statistics and then ✨resets every counter back to zero✨. fresh start, clean slate, new me.
  • All other normal termination signals β€” cause the final statistics to print before aprsdigi exits. it's giving last-words energy πŸ₯Ί

πŸ—ΊοΈ SSID-BASED ROUTING πŸ—ΊοΈ

SSID-based routing is the girlboss move where you use a non-zero sub-station ID in the destination callsign, plus an empty digipeater path, to tell the APRS digipeater "hey, repeat this packet and fill in an appropriate digipeater path for me bestie" πŸ’–

so like, a packet sent to T1QS4W-3 would get repeated with a modified destination of APRS VIA WIDE3-3 β€” that's in a network that supports WIDEn-n flooding, iykyk. and a packet sent to APRS-11 would be repeated to the West unproto path, as defined with the --west option. 🌈

here's the whole table of SSID values and their paths, no cap:

  • 0 β€” none
  • 1 β€” WIDE1-1
  • 2 β€” WIDE2-2
  • 3 β€” WIDE3-3
  • 4 β€” WIDE4-4
  • 5 β€” WIDE5-5
  • 6 β€” WIDE6-6
  • 7 β€” WIDE7-7
  • 8 β€” NORTH UNPROTO path
  • 9 β€” SOUTH UNPROTO path
  • 10 β€” EAST UNPROTO path
  • 11 β€” WEST UNPROTO path
  • 12 β€” NORTH UNPROTO path + WIDE
  • 13 β€” SOUTH UNPROTO path + WIDE
  • 14 β€” EAST UNPROTO path + WIDE
  • 15 β€” WEST UNPROTO path + WIDE

SSID digipeating was first introduced with the Mic-Encoder, but bestie it works with any destination callsign that has a non-zero SSID. the theory behind destination SSID digipeating is spelled out in more detail in the APRSdos README, MIC-E.TXT. 🧚

basically β€” and this is the whole vibe β€” the idea is to minimize packet lengths and let the manager of the WIDE APRS digipeater figure out the most appropriate directional digipeat paths, which takes that whole burden off the mobile user. iconic delegation honestly πŸ‘‘

aprsdigi also fits into a non-WIDEn-n network by using the exact same algorithm for selecting a subset of digipeaters from a list supplied with the --digipath option as the MIC-E does. so: SSIDs of 1, 2 or 3 select that number of digipeaters from the first three digipeaters in the --digipath list. and SSIDs of 4, 5, 6, or 7 start at the fourth digipeater in the list. πŸŽ€


🌊 FLOODING ALIASES 🌊

APRS flooding (WIDEn-n) digipeating works by repeating any received packet whose next hop digipeater has a flooding alias β€” that's the alias you specify with the --flood option β€” and whose SSID is 1 or greater. then the SSID gets decremented by one, and the packet is repeated. πŸ’«

AND, to stop broadcast storms from ruining everyone's day, recently transmitted packets are remembered for a period of time specified by the --keep option, and they will not be repeated if they get heard again inside that time window. πŸ›‘

unlike conventional digipeating β€” where the digipeater callsign/alias gets flagged as β€œrepeated” β€” the flooding mode does not do that. once the SSID decrements down to zero, then a flooding alias is treated just like any other alias, and it does get marked as repeated when transmitted. periodt. πŸ’…


πŸ¦‹ TRACE and TRACEn-n ALIASES πŸ¦‹

β€œFlooding” Trace aliases (that's TRACEn-n, via the --trace option) are treated like flooding aliases, with one extra lil garnish: besides decrementing the SSID, the current interface's callsign gets inserted in front of the trace alias, which gives you a record-route function. 🌸

β€œPlain” trace aliases (TRACE, also via the --trace option) are simply substituted in the conventional (--subst_mycall) manner. no fancy insert, just a swap. 🫢


🌐 MULTI PORT OPERATION 🌐

In single port operation, there's only one interface, specified with --interface. all packets are received, and some get retransmitted on that same interface β€” depending on whether they match the criteria for retransmission after translation of the digipeater path from one of the APRS-specific formats:

  • Mic-E TO-call SSID-based route. πŸ“»
  • WIDEn-n/TRACEn-n flooding. 🌊

or a conventional next-hop (non-repeated) digipeater that matches the callsign or one of the aliases for the interface. 🎯

The decision to transmit is made by matching the next hop callsign/alias against the table of callsigns and aliases you supply to --interface. πŸ’–

In multi-port operation, this same technique just extends out to several interfaces. and besides each interface's unique callsign, you can give the same alias to several interfaces. this gives you a one-to-many fanout, which is lowkey useful for dual frequency operation β€” like a general-use APRS net frequency plus an event-specific frequency. πŸ“‘βœ¨

and by using different flags for Mic-E expansions, etc. you can tailor these fanouts differently on each of those interfaces β€” maybe keeping Mic-E packets compressed on one frequency while decompressing them on another. chef's kiss, honestly πŸ‘©β€πŸ³πŸ’‹


πŸͺž DUPLICATING PACKETS πŸͺž

The --dupe intf option will duplicate a packet received on one interface over to the interface name you give it. and if you wanna duplicate to several other interfaces? just repeat --dupe intf for each interface. easy. πŸ’…

the packet gets duplicated verbatim as received. that means no callsign substitution, no flooding, no other processing or checking β€” not even a check for whether the packet still has any non-repeated digipeaters left in the list. πŸ™ˆ

this feature is meant to give you a way to simply repeat received packets verbatim, on an RF interface, for example, out an interface that might be an Ethernet β€” one that has APRS client applications running on it (or aprsd listening on a UDP interface). πŸ–₯️

⚠️ bestie, listen to me: Digipeating without the normal processing can be dangerous since the digipeater list is never used up. this is not a drill 😭

because of that, packets received on a given interface will never be blindly duplicated back to the same interface, regardless of what the option setting says. 🚫


πŸ” TRACE vs. TRACEN-N πŸ”

not me having to say this but: TRACEn-n vs. plain TRACE do different things, okay? πŸ‘€ TRACEn-n inserts calls into the digipath while decrementing ssid, like this:

RELAY*,TRACE3-3
RELAY,N2YGK-7*,TRACE3-2
RELAY,N2YGK-7,WB2ZII*,TRACE3-1
RELAY,N2YGK-7,WB2ZII,N2MH-15,TRACE3*

see the way it just builds up the route? obsessed πŸŒ€


πŸ’€ KILLING LOOPING PACKETS πŸ’€

kill looping packets β€” that's the --kill_loops option β€” and here's what it's looking at:

RELAY*,WIDE,WIDE,WIDE
RELAY,N2YGK-7*,WIDE,WIDE
RELAY,N2YGK-7,WIDE*,WIDE

normally n2ygk-7 would respond to this, but by finding one of mycall earlier in the path, it knows to ignore it. caught in 4k πŸ•΅οΈβ€β™€οΈ


✨ EXAMPLES ✨

here's a sample invocation of aprsdigi running on two ports. it's a contrived example that tries to show off all the features β€” comments on the right describe each one. πŸ“

aprsdigi \
   --verbose \                                 # verbose
   --north "N2YGK-2 WB2ZII WA2YSM-14" \        # North digi path
   --south "N2YGK-3 WB2ZII WA2JNF-4" \         # South ...
   --east "N2YGK-3 WB2ZII KD1LY" \             # East ...
   --west "N2YGK-2 WB2ZII N2MH-15" \           # West ...
   --flood "WIDE" \                            # WIDEn-n flooding
   --trace "TRACE" \                           # TRACEn-n tracing
   --kill_dupes \                              # kill dupes
   --kill_loops \                              # kill loops
   --mice_xlate \                              # do Mic-E translation
   --subst_mycall \                            # do callsign substituton
   --tag " via 147.06 (WB2ZII/R)" \            # add this tag to rec'd pkts
   --nobud "ax25:NOCALL" \                     # ignore pkts from NOCALL
   --dupe udp:233.0.14.100 \                   # dupe everything heard
   --int ax25:sm0:RELAY,WIDE,TRACE \           # ax25 soundmodem intf
   --nomice_xlate \                            # turn off Mic-E translation
   --x1j4_xlate \                              # do X1J4 translation
   --nosubst_mycall \                          # turn off callsign subst.
   --tag - \                                   # clear the tag
   --int ax25:ax0:RELAY,WIDE,FOO,TRACE \       # ax25 ax0 intf.
   --bud - \                                   # clear the budlist
   --bud ip:128.59.39.150/32 \                 # allow only from this IP host
   --int udp:233.0.14.99/12345/16:N2YGK-4,RELAY,WIDE,TRACE \ # multicast
   --int udp:233.0.14.100/12345/16:N2YGK-5      # to this mcast group

and here's what it prints on the way up:

opening UDP socket on 233.0.14.99/12345/16
UDP address info: family 2 type 2 proto 17 next 0x0
Linux APRS(tm) digipeater
Copyright (c) 1996,1997,1999,2001,2002,2003 Alan Crosswell, n2ygk@weca.org
Version: aprsdigi aprsdigi-2.4.3
This is free software covered under the GNU General Public License.
There is no warranty.  See the file COPYING for details.

then the config it's working from:

# configuration:
 budlist 1 deny NOCALL/48
 budlist 2 permit 128.59.39.150/32
interface ax25:sm0
 callsign N2YGK-2
 alias RELAY
 alias WIDE
 alias TRACE
 option SUBST_MYCALL on
 option MICE_XLATE on
 option X1J4_XLATE off
 option I_TX on
 option I_RX on
 option I_TXSAME on
 option idinterval 570 #(09:30)
 option tag  via 147.06 (WB2ZII/R)
 budlist 1
interface ax25:ax0
 callsign N2YGK-3
 alias RELAY
 alias WIDE
 alias FOO
 option SUBST_MYCALL off
 option MICE_XLATE off
 option X1J4_XLATE on
 option I_TX on
 option I_RX on
 option I_TXSAME on
 option idinterval 570 #(09:30)
 option tag #(none)
 budlist 2
interface udp:233.0.14.99
 callsign N2YGK-4
 alias RELAY
 alias WIDE
 alias FOO
 option SUBST_MYCALL off
 option MICE_XLATE off
 option X1J4_XLATE on
 option I_TX on
 option I_RX on
 option I_TXSAME off
 option idinterval 570 #(09:30)
 option tag #(none)
 budlist 2
# end of configuration

and then, my callsigns and aliases (the routing table) πŸŽ€:

Callsign  Interfaces...
N2YGK-2   sm0
RELAY     sm0       ax0       233.0.14.99
WIDEn-n   sm0       ax0       233.0.14.99
TRACEn-n  sm0
N2YGK-3   ax0
FOO       ax0       233.0.14.99
N2YGK-4   233.0.14.99
SSID-based directional routing:

N:        N2YGK-2   WB2ZII    WA2YSM-14
S:        N2YGK-3   WB2ZII    WA2JNF-4
E:        N2YGK-3   WB2ZII    KD1LY
W:        N2YGK-2   WB2ZII    N2MH-15
keep dupes for: 28 seconds
log file: (none)
kill dupes: ON loops: ON  testing: OFF

πŸ™ˆ BUGS πŸ™ˆ

Aprsdigi should not be confused with a Wes Johnson's DOS program of the same name β€” different girl, same name, happens to everyone 😭

this code has most recently been tested with the Linux 2.4.20 kernel under Red Hat Fedora Core 1. 🐧

the command line syntax is ugly and will eventually be replaced by a configuration file. short options are deprecated and will disappear in a future release. please use long options, bestie, i'm begging πŸ™


πŸ“ FILES πŸ“

/etc/ax25/axports


πŸ‘€ SEE ALSO πŸ‘€

call(1), listen(1), beacon(1), ax25(4), kissattach(8), ifconfig(8), aprsmon(1), http://www.tapr.org

✨ AUTHORS ✨

Bestie, this whole masterpiece was brought to you by:

  • Alan Crosswell, aka n2ygk@weca.org β€” absolute legend, main character energy, wrote the thing πŸ‘‘

And the legal tea, because we keep it official around here:

  • APRS and the Mic-Encoder are Trademarks of APRS Engineering LLC.

And that's the whole page, fr fr πŸŽ€ you read all of it, which is giving dedicated, which is giving iconic πŸ’…

This one came out of the APRSDIGI(8) manual, dated 14 August 2020. Go forth and digi responsibly, bestie β€” 73 πŸ¦‹πŸ’–

πŸ“¦ where this page comes from