Document: FTS-0001
Version: 17
Date: 06-Nov-2014
A Basic FidoNet Technical Standard
Revision 17
Introduction
This document defines the data structures which a FidoNet
implementation must provide.
1. Basic Requirements for a FidoNet Implementation
A FidoNet implementation must be able to call other nodes and
transfer messages and files in both directions. This includes pickup
and poll. A FidoNet implementation must be able to accept calls from
other nodes and transfer messages and files in both directions. This includes pickup.
2. Data Description
(* literals *)
"ABC" - ASCII character string, no termination implied
nnH - byte in hexadecimal
(* terminals *)
someName - 16-bit integer (little endian)
someName[n] - field of n bytes
someName[.n] - field of n bits
someName(n) - Null terminated string allocated n-1 chars
someName{max} - Null terminated string of up to max-1 chars
(* punctuation *)
a b - one 'a' followed by one 'b'
( a | b ) - either 'a' or 'b', but not both
{ a } - zero or more 'a's
[ b ] - zero or one 'b'
(* comment *) - ignored
(* predeclared constant *)
Null = 00H
a. The message format
Offset
dec hex
.-----------------------------------------------.
0 0 | |
~ fromUserName ~
| 36 bytes |
+-----------------------+-----------------------+
36 24 | |
~ toUserName ~
| 36 bytes |
+-----------------------+-----------------------+
72 48 | |
~ subject ~
| 72 bytes |
+-----------------------+-----------------------+
144 90 | |
~ DateTime ~
| 20 bytes |
+-----------------------+-----------------------+
164 A4 | timesRead (low order) | timesRead (high order)| +-----------------------+-----------------------+
166 A6 | destNode (low order) | destNode (high order) | +-----------------------+-----------------------+
168 A8 | origNode (low order) | origNode (high order) | +-----------------------+-----------------------+
170 AA | cost (low order) | cost (high order) | +-----------------------+-----------------------+
172 AC | origNet (low order) | origNet (high order) | +-----------------------+-----------------------+
174 AE | destNet (low order) | destNet (high order) | +-----------------------+-----------------------+
176 B0 | destZone (optional) | destZone (optional) | +-----------------------+-----------------------+
178 B2 | origZone (optional) | origZone (optional) | +-----------------------+-----------------------+
180 B4 | destPoint(optional) | destPoint(optional) | +-----------------------+-----------------------+
182 B6 | origPoint(optional) | origPoint(optional) | +-----------------------+-----------------------+
184 B8 | replyTo (low order) | replyTo (high order) | +-----------------------+-----------------------+
186 BA | Attribute (low order) | Attribute (high order)| +-----------------------+-----------------------+
188 BC | nextReply (low order) | nextReply (high order)| +-----------------------+-----------------------+
190 BE | text |
~ unbounded ~
| null terminated |
`-----------------------------------------------'
Message = fromUserName(36) (* Null terminated *)
toUserName(36) (* Null terminated *)
subject(72) (* see FileList below *)
DateTime (* last edited *)
timesRead (* not used *)
destNode (* of message *)
origNode (* of message *)
cost (* not used *)
origNet (* of message *)
destNet (* of message *)
destZone (* of message *)
origZone (* of message *)
destPoint (* of message *)
origPoint (* of message *)
replyTo (* not used *)
AttributeWord
nextReply (* not used *)
text(unbounded) (* Null terminated *)
DateTime = (* a character string 20 characters long *)
(* 01 Jan 86 02:34:56 *)
DayOfMonth " " Month " " Year " "
" " HH ":" MM ":" SS
Null
DayOfMonth = "01" | "02" | "03" | ... | "31"
Month = "Jan" | "Feb" | "Mar" | "Apr" | "May" | "Jun" |
"Jul" | "Aug" | "Sep" | "Oct" | "Nov" | "Dec"
Year = "01" | "02" | .. | "85" | "86" | ... | "99" | "00"
HH = "00" | .. | "23"
MM = "00" | .. | "59"
SS = "00" | .. | "59"
AttributeWord bit meaning
--- --------------------
0 + Private
1 + s Crash
2 Recd
3 Sent
4 + FileAttached
5 InTransit
6 Orphan
7 KillSent
8 Local
9 s HoldForPickup
10 + unused
11 s FileRequest
12 + s ReturnReceiptRequest
13 + s IsReturnReceipt
14 + s AuditRequest
15 s FileUpdateReq
s - need not be recognized, but it's ok
+ - not zeroed before packeting
Bits numbers ascend with arithmetic significance of bit position.
Message text is unbounded and null terminated (note exception below).
A 'hard' carriage return, 0DH, marks the end of a paragraph, and must
be preserved.
So called 'soft' carriage returns, 8DH, may mark a previous
processor's automatic line wrap, and should be ignored.
All linefeeds, 0AH, should be ignored.
If the first character of a physical line (e.g. the first character
of the message text, or the character immediately after a hard
carriage return (ignoring any linefeeds)) is a ^A (<control-A>, 01H),
then that line is not displayed as it contains control information.
The convention for such control lines is:
o They begin with ^A
o They end at the end of the physical line (i.e. ignore soft <cr>s).
o They begin with a keyword followed by a colon.
o The keywords are uniquely assigned to applications.
o They keyword/colon pair is followed by application specific data.
b. File Specifications
If one or more of FileAttached, FileRequest, or FileUpdateReq are
asserted in an AttributeWord, the subject{72} field is interpreted as
a list of file specifications which may include wildcards and other system-dependent data. This list is of the form
FileList = [ FileSpec { Sep FileSpec } ] Null
FileSpec = (* implementation dependent file specification. may
not contain Null or any of the characters in Sep. *)
Sep = ( " " | "," ) { " " }
c. The Packed Message format
To conserve space and eliminate fields which would be meaningless if
sent (e.g. timesRead), messages are packed for transmission. As this
is a data structure which is actually transferred, its definition is critical to FidoNet. A packed message has a number of fixed length
fields followed by four null terminated strings.
Offset
dec hex
.-----------------------------------------------.
0 0 | 0 | 2 | 0 | 0 |
+-----------------------+-----------------------+
2 2 | origNode (low order) | origNode (high order) | +-----------------------+-----------------------+
4 4 | destNode (low order) | destNode (high order) | +-----------------------+-----------------------+
6 6 | origNet (low order) | origNet (high order) | +-----------------------+-----------------------+
8 8 | destNet (low order) | destNet (high order) | +-----------------------+-----------------------+
10 A | Attribute (low order) | Attribute (high order)| +-----------------------+-----------------------+
12 C | cost (low order) | cost (high order) | +-----------------------+-----------------------+
14 E | |
~ DateTime ~
| 20 bytes |
+-----------------------+-----------------------+
34 22 | toUserName |
~ max 36 bytes ~
| null terminated |
+-----------------------+-----------------------+
| fromUserName |
~ max 36 bytes ~
| null terminated |
+-----------------------+-----------------------+
| subject |
~ max 72 bytes ~
| null terminated |
+-----------------------+-----------------------+
| text |
~ unbounded ~
| null terminated |
`-----------------------------------------------'
PakdMessage = 02H 00H (* message type *)
origNode (* of message *)
destNode (* of message *)
origNet (* of message *)
destNet (* of message *)
AttributeWord
cost (* not used *)
DateTime (* message last edited *)
toUserName{36} (* Null terminated *)
fromUserName{36} (* Null terminated *)
subject{72} (* Null terminated *)
text{unbounded} (* Null terminated *)
d. The Packet Header format
The packet contains messages in packed format to be transferred over
the net during a connection. As this data structure is transferred,
its definition is critical to FidoNet.
A packet may contain zero or more packed messages. A packet without messages is often generated as a poll packet.
Every packet begins with a packet header. The fields of the packet
header are of fixed length.
Offset
dec hex
.-----------------------------------------------.
0 0 | origNode (low order) | origNode (high order) | +-----------------------+-----------------------+
2 2 | destNode (low order) | destNode (high order) | +-----------------------+-----------------------+
4 4 | year (low order) | year (high order) | +-----------------------+-----------------------+
6 6 | month (low order) | month (high order) | +-----------------------+-----------------------+
8 8 | day (low order) | day (high order) | +-----------------------+-----------------------+
10 A | hour (low order) | hour (high order) | +-----------------------+-----------------------+
12 C | minute (low order) | minute (high order) | +-----------------------+-----------------------+
14 E | second (low order) | second (high order) | +-----------------------+-----------------------+
16 10 | baud (low order) | baud (high order) | +-----------------------+-----------------------+
18 12 | 0 | 2 | 0 | 0 |
+-----------------------+-----------------------+
20 14 | origNet (low order) | origNet (high order) | +-----------------------+-----------------------+
22 16 | destNet (low order) | destNet (high order) | +-----------------------+-----------------------+
24 18 | prodCode | serialNo | +-----------------------+-----------------------+
26 1A | |
| password (some impls) |
| eight bytes |
| null padded |
| |
+-----------------------+-----------------------+
34 22 | origZone (low) (opt) | origZone (high) (opt) | +-----------------------+-----------------------+
36 24 | destZone (low) (opt) | destZone (high) (opt) | +-----------------------+-----------------------+
38 26 | fill |
~ 20 bytes ~
| |
+-----------------------+-----------------------+
58 3A | zero or more |
~ packed ~
| messages |
+-----------------------+-----------------------+
| 0 | 0 | 0 | 0 |
`-----------------------+-----------------------'
Packet = PacketHeader { PakdMessage } 00H 00H
PacketHeader = origNode (* of packet *)
destNode (* of packet *)
year (* of packet creation, yyyy *)
month (* of packet creation, 0-11 *)
day (* of packet creation, 1-31 *)
hour (* of packet creation, 0-23 *)
minute (* of packet creation, 0-59 *)
second (* of packet creation, 0-59 *)
baud (* not used *)
PacketType (* 02H 00H *)
origNet (* of packet *)
destNet (* of packet *)
prodCode (* write to FTSC for one *)
serialNo (* binary serial number (or null)*)
password (* session password (or null) *)
origZone (* zone of pkt sender (or null) *)
destZone (* zone of pkt receiver (or null)*)
fill[20]
The remainder of the packet consists of packed messages. Each packed message begins with a message type word 0200H. A pseudo-message
beginning with the word 0000H signifies the end of the packet.
--- Mozilla/5.0 (Windows; U; Windows NT 5.1; sv-SE; rv:1.9.1.16) Gecko/20101125
* Origin: news://felten.yi.org (2:203/2)
Sysop: | Weed Hopper |
---|---|
Location: | Clearwater, FL |
Users: | 14 |
Nodes: | 6 (0 / 6) |
Uptime: | 230:35:36 |
Calls: | 55 |
Calls today: | 1 |
Files: | 50,127 |
D/L today: |
26 files (3,281K bytes) |
Messages: | 275,349 |