With help from Bob Armstrong and Peter Lothberg, I have a reverse engineered Python
implementation of the Multinet tunnel over TCP working now.
Peter forwarded an old HECnet message that roughly describes the protocol, but some
details were missing and some were not quite accurate. For the benefit of anyone else
who wants to implement this, here is the protocol description plus some implementation
notes.
paul
Multinet protocol for DECnet
A Multinet tunnel runs the Point to Point mode of the DECnet protocol. Traffic may be
carried over a TCP connection, or over UDP packets. The operation is nearly the same for
both.
In TCP mode, one end is designated the connecting end and the other the listening end.
In UDP mode, operation is symmetric since there are no connections. In either case, the
port number may be configured; the default is 700.
Multinet puts a 4 byte header on each DECnet packet. For TCP, the first two bytes are
the DECnet packet length, little endian. The TCP data stream consists of these packets
with headers.
For UDP, the first two byte are a sequence number, little endian. The next two bytes
appear to be unused and were observed to contain zero. Each DECnet packet, with its
header, is sent as a separate UDP packet. Some Multinet implementations can be
configured to check the sequence number in UDP mode; it is not clear how this works (in
particular, how it is initialized). Linux does not, and things seem to work fine without
this extra check.
Multinet tunneling does not obey many of the requirements that the DECnet Routing
architecture imposes on point to point datalinks. The most obvious issue is that routing
layer point to point init messages (control packet, type code 0) may appear unexpectedly.
This happens even in TCP mode where it might be expected that the TCP connection would be
closed and re-established before the init message.
A conforming DECnet implementation reacts to such an unexpected init message by restarting
the circuit, sending an init message, and expecting one in return. Multinet does not
expect this, and if the peer operates according to the standard, initialization may
require many cycles before it finally succeeds. As a workaround, the response to an
unexpected init should be to set the routing initialization sublayer state machine to the
DS state (without restarting the TCP connection, if any), and processing the unexpected
init message as if it had been received in that state.
In testing with a DECnet/VMS system, it was observed to send an Init message requesting
verification even though verification was not called for in the circuit parameters. It
may be that this was due to the routing architecture requirement to use verification in
areas other than area 1. A null verification message (empty FCNVAL field) was accepted
by the VMS system in that test.