This is an old revision of the document!
Table of Contents
BBS Forwarding protocol
SID
The System IDentifier string (or SID) is used by BBS software exchange their author, their version, and, optionally, a list of extended features, as described in the next subsection.
Here is an ABNF syntax of the SID string:
SID_ALNUM = %x20-2c / %x2e-5a / %x5c / %x5e-7e ; All printables except for "[", "-" and "]". AUTHOR = 1*SID_ALNUM VERSION = 1*SID_ALNUM FEATURES = 1*SID_ALNUM SID = "[" AUTHOR "-" VERSION [ "-" FEATURES ] "]"
PCRE compatible format string:
/^\[(?<author>[^-]+)-(?<version>[^-\]]+)(?:-(?<features>[^\]]+))?\]$/
Extensions list
Letter(s) | Description | F6FBB? | WL2K? | W0RLI? | LA5NTA? | F4HOF1) |
---|---|---|---|---|---|---|
A | Acknowledge for personal messages | X | X | |||
B | FBB compressed protocol version 0 | X | # | X | ||
B1 | FBB compressed protocol version 1 | X | # | X | ||
B2 | FBB compressed protocol version 2 | X | X | |||
C | Automatic distribution of current date / time (obsolete) | # | ||||
D | | X | ||||
F | FBB basic protocol support | X | X | |||
G | GZIP compression | X | ||||
H | Hierarchical Location designators | X | # | X | ||
I | Calling station ID support | X | ||||
J | Winlink: Seems to indicate “Linked to CMS” | X | ||||
L | G1NNA Compression | # | ||||
M | Message Identifier support | X | # | |||
N | Winlink: Calling station ID with SSID | # | ||||
R | AA4RE Extended reject responses | # | ||||
S | AA4RE Extended S commands support | # | ||||
T | Winlink | # | ||||
U | Winlink | # | ||||
W | Winlink features (non required for P2P) | X | ||||
X | Compressed batch forwarding | X | ||||
$ | BID supported | X |
- X ⇒ Fully specified
- # ⇒ Partially described, or references its existence
Required extensions for Winlink
TODO Actually challenge which extensions break the nominal operation of Winlink Express
Here are the strict minimum extensions required by Winlink to accept a remote party, according the selected mode of operation:
Operating mode | Extensions |
---|---|
Winlink | B2FWIHJM$ |
Radio Only | B2FWIHM$ |
Post Office | B2FWIHM$ |
P2P | B2FHM$ |
Commands (AKA proposals)
Common subset
The FS
command is issued by the client, and used to tell the server, based on the list of message that have been reported, how to process the messages.
Format:
FS <response>
Code | Action | Remarks |
---|---|---|
+ | Accept | Send the message and delete it from the queue |
- | Reject | Don't send the message and delete it from the queue |
= | Defer | Keep in the queue to retrieve it later |
Starting from Binary compressed format version 1, additional responses are possible:
Code | Action | Remarks |
---|---|---|
+ or Y | Accept | Send the message and delete it from the queue |
- or N | Reject | Don't send the message and delete it from the queue |
= or L | Defer | Keep in the queue to retrieve it later |
H | Message accepted, but held in queue | |
R | Message rejected | |
E | Error detected in the line | |
!offset | Resume transfer from offset bytes | Offset is expressed according to the compressed stream |
Calling Station ID
The calling station identification command is to be sent PRIOR the calling station SID.
;FW CALLSIGN
Ascii Basic Protocol
(i) Usage of this proposal implies the presence of the F
feature in the SID.
Details in the dedicated page on the ASCII Basic Protocol
Binary compressed protocol version 0
(i) Usage of this proposal implies the presence of both the F
and B
features in the SID.
Details in the dedicated page on the Binary Compressed Forward Version 0.
Binary compressed protocol version 1
Binary compressed protocol version 2
B2F is a superset of BCFv1, so FA
and FB
commands work the same way.
Additionally, it defines a new command FC
as following:
GZIP Experiment
The GZIP Experiment is a superset of BCPv2 which adds the FD
command, following the FC
format
Winlink specifics
Apparently, clients and servers add the feature W
in their SID string when establishing a WL2K connection. Some even complain if the remote peer doesn't expose it. The precise meaning and purpose of that flag is undocumented.
W0RLI also ties the features T
and U
in their specification, but without any details on their real meaning.
Secure login
The exchange happens after the SID has been transmitted.
The server sends a ;PQ
proposal with an authentication challenge, which is formatted as follow:
;PQ 99685857
The client computes the response using the following pseudocode:
// Trailing salt uint8_t sl_salt[] = { 77, 197, 101, 206, 190, 249, 93, 200, 51, 243, 93, 237, 71, 94, 239, 138, 68, 108, 70, 185, 225, 137, 217, 16, 51, 122, 193, 48, 194, 195, 198, 175, 172, 169, 70, 84, 61, 62, 104, 186, 114, 52, 61, 168, 66, 129, 192, 208, 187, 249, 232, 193, 41, 113, 41, 45, 240, 16, 29, 228, 208, 228, 61, 20 }; // Concatenate the challenge, the password and the salt. payload = concat( challenge, password, sl_salt) // Compute the md5 of the last result md5sum = md5(payload) // Take the first 4 bytes of the hash, flip the byte-wise endianness, and cap the first byte to 0x3f response = ( (uint8_t)(md5sum[3]) & 0x3f ) << 24 | (uint8_t)(md5sum[2]) << 16 | (uint8_t)(md5sum[1]) << 8 | (uint8_t)(md5sum[0]) ) // Keep the 8 least significant digits in base 10 of response. // If response is shorter than 8 digits, 0-pad from the left. resval = itoa( response % 100000000, base10) sprintf( result, "%08d", resval)
The result is then sent to the server using the following format:
;PR 99685857
Reference source code in paclink-unix, function compute_secure_login_response() and wl2k-go
Forward messages
Pending messages
Radio Only mode
Data Transfer Modes
Standard Forwarding protocol (MBL/RLI)
No online documentation found, as of Feb 2025 on the specifics of this protocol.
According to the FBB forwarding protocol specification, it is the least common denominator that enables message transfer.
Your software is supposed to fall back in this mode when the feature F
is not proposed by the remote party.
Best recommended stance, for now, is to reject connections with an error message, given the lack of available documentation.
ASCII Basic Protocol
Ascii Basic Protocol
Binary compressed protocol version 0
Header
Format:
0x01 head_len(uint8) fname(c-string) offset(bytes in c-string)
fname
is a null-terminated C-String which either contains the title of the message or the filename, respectively for an ASCII or a Binary transfer.offset
is a null-terminated C-String which contains an ASCII printable representation of the offset in bytes of the following data fragments. Valid values for the offset span from 0 to 999999 bytes.head_len
expresses the sum of the length of the two above C strings, including their null terminator
Data
Format:
0x02 payload_len(uint8) data(bytes)
payload_len
represents the length in bytes of the followingdata
byte stream. Valid values span from 1 to 256 bytes, 256 bytes being represented by the value0x00
.
Checksum
Format:
Csum: 0x04 csum(uint8)
The checksum is designed so that the bytewise sum of data bytes, plus the checksum modulo 256 equals to zero if no error occured.
To generate the checksum, compute the two's complement of the bytewise sum of data bytes.
Binary compressed protocol version 1
Binary compressed protocol version 2
Compression algorithm defined in https://github.com/ham-radio-software/lzhuf