| Document: FSC-0077
  | Version:  001
  | Date:     03rd December 1993
  | Author:   Jason Steck

                    Type-10 Packet Format
                  An FSC Standard Proposal


I.  Introduction:

     Over time, the traditional FidoNet FTS-0001 "Type 2"
packet format has been repeatedly shown to be inadequate in
a wide variety of advanced implementations.  The
inadequacies of the type-2 format have been particularly
evident in multi-zone and multi-domain environments.
     When type-2 was originally established, it was
sufficient to existing networking needs.  FidoNet was the
"only show in town" and the 2-dimensional net/node
arrangement was easily adequate to the requirements of the
network.  However, growth in FidoNet required the
introduction of "zones" to separate large geographical areas
from each other.  The advent of echomail led directly to the
creation of sub-node "point" systems, adding a fourth
dimension to the addressing scheme.  The explosion in recent
years of similar-technology, non-FidoNet networks has
required the addition of a fifth dimension, the "domain" to
differentiate between potentially conflicting addresses in
different networks.
     The 2-dimensional type-2 format is clearly inadequate
to a 5-dimensional addressing requirement.  Various schemes
have evolved to attempt to compensate for the failings of
the type-2 environment.  Type 2.2 (FSC-0045) and type-2+
("capability word" -- FSC-0039) packet format modifications
have been devised to attempt to modify the packet format to
include necessary addressing information.  Further, a
plethora of message text "kludge lines" (lines hidden behind
an ASCII #01 character) have been inserted to provide
additional addressing information required by modern
implementations.
     The major failing of all these schemes, however, comes
when they run square-on into the "real world".  Competing
implementations often use slightly different formats or
requirements within packet formats and kludge lines.  The
mere existence of kludge lines impose significant
performance and message test size and content penalties for
mail processors.
     This proposal seeks to establish a new packet format
which would resolve the problems and inadequacies presented
by the existing formats.  In acknowledgment of the fact that
a theoretical proposal is useless without a practical
implementation, this proposal has been implemented in the
JMail 2.10 (and later) versions of electronic mail
processors.  In the interests of reverse-compatibility, it
is STRONGLY RECOMMENDED that any implementations of this
proposal include some mechanism for supporting older formats
and their popular modifications.
     This proposal establishes a detailed packet format
including packet header and internal message structure.  The
format assumes the utilization of the FidoNet-style
zone:net/node.point@domain addressing format.  Other
addressing formats, such as UUCP RFC-822 domain addressing
and/or "bang-path" addressing are not directly supported by
this format.


II.  The 5-Dimensional Address

     The 5-dimensional address consists of the elements (in
hierarchical order) domain, zone, net, node, and point.  The
full ASCII representation of this is
"zone:net/node.point@domain".  Where the point number is
zero (a full node system as opposed to a dependent point
system), the period (.) and the point number (0) may be
excluded.
     Implementations with size concerns may desire to
include some facility to "assume" or "guess" at particular
elements of a particular address based on prior addresses or
user-supplied criteria.  This capability also has advantages
when dealing with older formats which supply less than
complete information.

III.  Type-10 Packet Format

     A.  Conventions

     All binary numerical values in a type-10 packet are
stored in Intel's byte-swapped format.
     Within this document, all binary numerical values will
be given in hexadecimal notation (base-16) using the (#)
designator and right-justified with leading zeros.  For
example, a single-byte value of 10 would be designated as
"#0A" while a word-length, two-byte value of 10 would be
designated as "#000A".
     "NULL" is equivalent to either a #00 byte or #0000 word
value.

     B.  File Naming Conventions -- *.P10

     Type-2 packet formats established the convention of
using the PKT extension on file names.  This naming
convention enabled mail-processing software to easily
determine which files within a given directory were intended
to be processed.
     In order to prevent conflicts and preserve easy reverse-
compatibility, it is necessary for any upgraded format to
utilize a different file naming convention.  Type-10 packets
are named with an extension of P10.  This has the additional
effect of providing an easy new path for additional
standards -- for example, a theoretical type-11 packet could
use, without conflict, an extension of P11.
     Archived type-10 mail packets may use the same
archiving file name conventions established for type-2
packets.  Indeed, the different file naming convention of
type-10 packets allows the inter-mixing of packet types
within a single archive.

     C.  Packet Header

     The PacketAddressRecord contains a complete 5-
dimensional address.

          (* Address structure -- Pascal notation *)
          PacketAddressRecord = RECORD
               Domain : ARRAY[1..8] of char;
               Zone, Net, Node, Point : integer;
          END;
          
          /* Address structure -- C notation */
          struct PacketAddressRecord {char domain[8],int
          zone,int net,int node,int point};

     A packet header must appear at the beginning of each
type-10 packet file.

          (* Packet Header structure -- Pascal notation *)
          PacketHeaderRecord = RECORD
               PktType : byte;
               PktFrom,PktTo : PacketAddressRecord;
               PktPWd : ARRAY[1..8] of char;
               ProdCode : word;
               ProdVer : word;
          END;
          
          /* Packet Header structure -- C notation */
          struct PacketHeaderRecord {unsigned char
          PktType,struct PacketAddressRecord PktFrom, struct
          PacketAddressRecord PktTo, char PktPWd[8],unsigned
          int ProdCode,                 unsigned int
          ProdVer]


     The PktType field contains a numerical value indicating
the packet type format of the rest of the packet.  The
PktType field of a type-10 packet will always contain the
value #0A.  This value has been placed in byte 0 of the file
to provide a convenient upgrade path for future packet
formats.
     The PktFrom field contains a PacketAddressRecord
structure indicating the address of the sending system.
     The PktTo field contains a PacketAddressRecord
structure indicating the address of the destination system.
     The PktPWd field may contain a 1-8 byte (NULL padded)
password for the securing of links between systems.  If the
link has no password protection, this field will contain 8
NULL bytes.
     The ProdCode field contains a 0-65535 numerical value
indicating the product code assigned by a relevant standards
committee for the software package producing the packet.
     The ProdVer field contains a 0-65535 value.  The hi-
order byte contains the major version number and the low-
order byte the sub-version number.  The ProdCode and ProdVer
fields are used to detect and assist in the elimination of
format errors produced by errant software implementations.

     D.  Packet Body Format

     After a packet header, a type-10 packet will contain
any number of packet "blocks".  Individual blocks may not
exceed 30720 bytes (30 kilobytes) in length.  (This allows
for easy buffering and data manipulation.)
     Each block is prefaced with a "block header" to define
the type of information contained within the block:

          (* Block header structure -- Pascal format *)
          BlockHeaderRecord = RECORD
               BlockID : longint;
               BlockType : byte;
               BlockLen : word;
               BlockCRC : word;
          END;
          
          /* Block header structure -- C format */
          struct BlockHeaderRecord {long int blockid,
          unsigned char BlockType, unsigned int BlockLen,
          unsigned int BlockCRC}

     The BlockID field is used for error-checking purposes.
It must alwasy be set to #22AAE0.
     The BlockType field contains a numerical value from 0-
255 indicating the type of data contained within the block:

     #00 - Packet Terminator Block. (BlockLen and BlockCRC
fields must be set to #0000.)  This block indicates an end-
of-file.  Data beyond this point will be ignored.
     #01 - Command Block.  This block is for system-to-
system commands and requests. This block is not yet
implemented and will be detailed in a future revision to
this document.
     #02 - Message Header Block.
     #03 - Seen-by Block.
     #04 - Path Block.
     #05 - Message Text Block.  (More than one successive
#05 block may be used to hold the text of messages greater
than the maximum block size.  In theory, this allows for
truly unlimited-length message capability.  However,
implementations which intend to communicate with older, type-
2 are realistically limited to message sizes which can be
adequately buffered by type-2 processors.)

     The BlockLen field indicates the number of bytes within
the block.
     The BlockCRC field is optional.  If the value of field
is other than #0000, then the field will contain the CRC
value of the field data (excluding the Block Header).  This
allows for some degree of integrity-checking on packet data.

     Following each Block Header will be BlockLen bytes of
data of the type specified in the BlockType indicator.  A
normal message would break down into a Message Header block
(#02) followed by a Seen-by Block (#03), followed by a Path
Block (#04), followed by one or more Message Text Blocks
(#05).

     Some data areas will contain structured sub-fields.
These are as follows:

     #02 - Message Header Block.  Each sub-field within this
     data block will be prefaced with a numerical sub-field
     identifier, followed by a single byte indicating the
     length (in bytes) of the sub-field, followed by the
     appropriate sub-field.  Sub-fields are as follows:
     
          #01 - From Name.  This is the ASCII name of the
     person who originally wrote the message.  This sub-
     field is required on all messages.
          #02 - To Name.  This is the ASCII name of the
     person to whom the message is directed.  This sub-field
     is required on all messages.
          #03 - Subject.  This is the ASCII representation
     of the originator-entered subject.
          #04 - Date/Time Group (binary -- length byte will
     always be #04).  This is the date and time the message
     was originally entered.  It is stored in the 32-bit
     "longint" format.  This is a "packed" time format used
     by MS-DOS to store file date/time records.  This or a
     #05 sub-field is required on all messages.
          #05 - Date/Time Group (ASCII -- length byte will
     always be #13).  This is an ASCII date/time
     representation of the origination date/time of the
     message in the format specified in the FTS-0001
     document (DD MMM YY  HH:MM:SS)  This or a #04 sub-field
     is required on all messages.
          #06 - MSGID line.  This is an FSC-0036 compliant
     MSGID line.  It is a required sub-field on all echomail
     messages.
          #07 - Origin Address (PacketAddress Format --
     length byte will always be #10).  This is the network
     address of the originating system of the message.  This
     sub-field is required on all messages.
          #09 - Destination Address Override (PacketAddress
     Format -- length byte will always be #10).  This sub-
     field contains an override for the destination address
     of the corresponding messages.  Processors should
     determine that each message is destined for the address
     listed in the PacketHeaderRecord except where
     specifically overridden in a #09 sub-field.
          #0A - Echomail Area Name.  This sub-field
     indicates the echomail area that the message is being
     distributed in.  This sub-field is required on all
     echomail messages.
          #0B - Origin Line.  This sub-field contains the
     origin line for echomail messages.  This sub-field is
     optional, but is realistically required on all
     implementations which intend to communicate using any
     older type-2 format.
          #0C - FLAGS line.  This sub-field contains the
     message attributes in FSC-0053 format.  The leading
     ASCII #01 (control-A) character should be excluded from
     this sub-field, but implementations should be tolerant
     of common minor FSC-0053 variations.
          #0D - Tear Line:  This sub-field contains a
     tearline (not to exceed 35 characters including the
     leading "---" characters.  This line is required on all
     echomail messages.
          #0E - PID Line:  This sub-field contains the
     optional Product Identification (PID) line.
          #0F - REPLY:  This sub-field contains the optional
     REPLY field, used with MSGID lines for message thread
     linking purposes on echomail messages.
     
     #03 - Seen-by Block.  The Seen-by Block contains
     address information of the systems which have "seen" an
     echomail message.  This data is used to prevent sending
     multiple copies of messages to a single system.  Seen-
     by blocks are required on all echomail messages.
     Implementations will append information for all
     addresses the local system is sending the current
     message to prior to actually sending any message.  Seen-
     by information for systems not in the same domain as
     the destination system must be excluded.  The local
     system's address information in a minimal requirement
     on all messages.
          The data is a series of two-byte integers.  The
     first four integers indicate (in order) the zone, net,
     node, and point number of the first address in the
     list.  This address serves as a "base" from which other
     addresses "evolve" as explained below:
     
          Positive value (greater than or equal to 0):  node
     number (zone and net information same as previous
     address and point number equals 0).
          Negative number (less than zero EXCEPT -32768):
     number multiplied by -1 equals new net number (absolute
     value).  Next number will be new node number.
          "Reset number" (-32768): indicates new full
     address block.  Next four integers will equate to (in
     order) the zone, net, node, and point number of next
     address in seen-by list.  Later addresses will "evolve"
     from this number.
     
          This storage format allows for an extremely
     flexible and compact method of storing seen-by
     information.
     
     #04 - Path Block.  This block contains the addresses
     that the current message has passed through.  This
     information is maintained across all domain boundaries.
     Whenever a system processes a message, it adds its own
     address to the end of this list.  Address records are
     stored in PacketAddressRecord format.
     
IV.  Development and Implementation Assistance

     As this is a proposal for a new standard, it is
reasonable to expect ambiguities and problems to eventually
develop in potential implementations of the standard.  The
author of this standard is available to clarify matters of
interpretation or ambiguity or problems in coding or
implementation of the standard.  Public-domain code
"snippets" of critical portions of the standard
implementation will be made available when necessary and
feasible.
     The author may be reached at the addresses below:

     Jason Steck                   1:285/424@FIDONET
     PROZ Software                 200:5000/400@METRONET
     12105 W. Center Rd #103       39:70/200@LDSSNET
     Omaha, NE 68144               42:1009/424@CANDYNET
                              Ready Room BBS (402)691-0946