Binkp is a protocol intended for use over bidirectional channels with reliable transmission. Data sent by both of the parties should be split into frames that have the following general format:
binkp's frames: +---------------------- 0=data block, 1=message(command) | +---- data block size / msg's argument size | | 7 6543210 76543210 +-+-------+--------+--- ..... ---+ | | HI LO | | -- data block / msg's argument +-+-------+--------+--- ..... ---+ |<- 2 bytes ->|<- 32K max ->| (frame header) (frame data)
Frame header is 2 bytes long and defines type and length of data following the header.
If the highest bit of the header is set to 0, then all the frame data shall be appended to the current file being received. If such file is not open, frame data can be discarded.
Otherwise (if the highest bit is set to 1), frame data shall be parsed as a
command changing protocol state.
First byte of a command frame data is the command ID. The rest of the bytes carry
command arguments. Command arguments are an arbitrary symbol string not
necessarily limited by an '\0'
. A command without arguments
(e.g. M_OK) may look like this:
7 6543210 76543210 76543210 +-+-------+--------+--------+ |1| 0 1| 4| +-+-------+--------+--------+ | | +----- command ID (no arguments) | +-------- frame length (excluding header) +- command frame flag
Format: symbolic_command_name command_ID
Command arguments are ignored and (optionally) logged. This is the way how binkd transmits nodelist info, sysop name, etc...
e.g. "ZYZ Dima Maloff"
List of 5D addresses (space separated).
e.g. "2:5047/13@fidonet 2:5047/0@fidonet"
Password. After successful password identification of the remote, binkd server rereads *.?lo files for the addresses presented by remote.
e.g. "pAsSwOrD"
Acknowledgement for a correct password. Upon receiving of this command, binkd client rereads *.?lo files for the addresses presented by remote. Arguments are ignored.
e.g. ""
Space separated list of next file parameters: filename size in bytes; unix time; file transmission offset.
Filenames can not include symbols with ASCII value less than 0x20.
All parameters
are decimal. Until the next M_FILE command is received, all data frames
shall carry data from this file. There is no end of file identifier as the
file size is known beforehand. If there are "extra" data frames, binkd will
append this data to the file. Transmission of each file shall be started
from offset 0. M_GET command sent by the remote party
shall force us to make seek()
.
e.g. "config.sys 125 2476327846 0"
or, answering to M_GET with offset 100:
"config.sys 125 2476327846 100"
End-of-Batch. M_EOB command shall be transmitted after all the files have been sent.
If all of the following applies:
e.g. ""
File acknowledgement, that shall be transmitted upon receiving of the last data frame for this file. Arguments for this command shall be the same as for the M_FILE sent by remote, excluding the last argument, file offset, which is not transmitted back to the system which have sent M_FILE. M_GOT can also be transmitted while receiving a file, in which case transmitting party may interpret it as a destructive skip.
e.g. "config.sys 125 2476327846"
This command indicates a fatal error. Party, sending M_ERR, may abort the session. Argument shall contain error explanation and may be logged. Binkd sends M_ERR in response for an incorrect password.
e.g. "Incorrect password"
M_BSY command is transmitted if our system is busy. The argument may contain an explanation of the situation and may be logged by remote.
e.g. "Too many servers are running already"
M_GET command allows to resend files. Arguments of the command are the same as for the M_FILE command which we'd like to receive from remote.
Binkd sends M_GET when it doesn't like transmission file offset.
e.g. "config.sys 125 2476327846 100"
As of nowadays, binkd processes this command as follows: according to the
first three arguments (filename/size/unixtime), it determines whether the
M_GET argument is the current file being transmitted to the remote (or a
file that have been transmitted, but we are still waiting an M_GOT ack for it). If this is the case, binkd performs
seek()
to the specified offset and sends an M_FILE. For the example above, corresponding M_FILE will have the following arguments:
e.g. "config.sys 125 2476327846 100"
Non destructive skip. Parameter is a space separated list of filename, size and unixtime.
e.g. "config.sys 125 2476327846"
calling part sends | called party sends |
---|---|
M_NUL "SYS ..." | M_NUL "SYS ..." |
M_NUL "ZYZ ..." | M_NUL "ZYZ ..." |
M_NUL "LOC ..." | M_NUL "LOC ..." |
M_NUL "VER ..." | M_NUL "VER ..." |
M_ADR "2:2/2.2@fidonet" | M_ADR "3:3/3.3@fidonet" |
M_PWD "password" | (waiting for a password from remote) |
M_OK "" or M_ERR "Bad password" | |
(waiting for M_OK) | M_FILE "file2 200 42342434 0" |
M_FILE "file1 100 423424244 0" | data |
data | data |
data | data |
M_EOB | (got file1, acknowledging it) |
(got file2, acknowledging it) | M_GOT "file1 100 423424244" |
M_GOT "file2 200 42342434" | data |
M_EOB |
Binkd User Guide for discussion on a particular implementation of binkp protocol.
Original of this document in Russian, http://www.magadan.ru/~maloff/binkd/binkp.html.