Private Data Stamp: No X:6.5" Y:11.25"
Page Numbers: Yes X: 527 Y: -.5" First Page: 2 Not-on-first-page
Heading: Not-on-first-page
Mesa Pup Package Functional Specification
Introduction
This document describes the Mesa Pup Package. The FTP Package is described in the FTP Functional Specification. The Stream Interface is described in appendix A.
If you are looking for some simple examples, the Mesa PupTest package is probably a good place to start. Look at PtBSP.mesa and/or PtEcho.mesa.
Currently, November 20, 1979, the Pup Package has the following performance characteristics. These numbers were obtained using FatPup with the default parameters and a very simple test program so there is no disk activity or other significant interference. Even the display and the keyboard/mouse interrupts were turned off. Things would, of course, go faster without the Statistics option.
Checksums On OffOff-Local

Socket:
150kb614kb423kb
PktStream:
117kb365kb248kb
ByteStream:
106kb331kb226kb

Echo long packets:
38kb/110ms222kb/19ms
Echo short packets:
21ms18ms
The Pup Package consists of a set of modules built up in a layered structure, where each layer adds more service to the structure of the previous layers. The client program may interface to the package at any layer, trading service against speed and space for its particular application.
The layers are:

Ethernet Driver (not directly accessible)
PupRouter (not directly accessible)
Socket
PacketStream
ByteStream

This document will describe the various interfaces to the Pup Package. First comes a section on describing how to turn the Pup Package on. Then the ByteStream interface will be described, followed by the Socket interface. (The PacketStream interface isn’t described because of lack of interest. Contact me if you are interested.) Next comes the description of the name utilities, the packet utilities, and the
SIGNALs and ERRORs generated by the Pup Package. Finally, there are sections describing the EFTP Package and the Stats Package.
Terminology
There are a lot of buzzwords in the network business. Here is my attempt to explain the important ones.
Connections
The Ethernet hardware delivers packets from one machine to another with high probability. Unfortunately, packets will be lost occasionally, so protocols are needed to transfer data reliably. When two processes on two machines agree to communicate with each other, they establish a connection. (Actually, they can be two portions of the same process, or two processes on the same machine.) A connection has a local end and a remote end.
Streams
Once a connection is opened, a stream of data flows across it. Actually, since the Pup Package supports full duplex connections, each connection has a send stream, and a receive stream. Note that this is not the normal Mesa meaning of stream. Streams may be punctuated with marks, which are useful for synchronizing both ends of a connection. A mark is sent in a seperate packet that includes only one byte of data. Logically, it is like having a ninth bit on the data bytes. The Pup Package uses marks to implement the SST Change operation. It can be considered like an End-Of-Record or End-Of-File. Because they are sent in small (one data byte) packets, and may use the SIGNAL machinery, marks are not very efficient. An interrupt (called attention in the stream documentation) mechanisim is provided to bypaass the normal flow control restrictions. This is useful, for example, in Chat if the sender wants to flush the output buffer but the receiver is busy processing things in the buffer.
Address
Each end of a connection requires an address to identify it. Since there may be more than one active process on a machine, an address includes a socket number (like a post office box number) as well as the obvious network number and host number. In PupTypes, a PupAddress is a three word record. It is also copied into PupStream.
PupAddress: TYPE = RECORD [
net: PupNetID, host: PupHostID, socket: PupSocketID];
PupNetID: TYPE = RECORD [Byte];
PupHostID: TYPE = RECORD [Byte];
PupSocketID: TYPE = RECORD [a, b: WORD];
There are a number of conventions associated with addresses (the second I in fillIn is a capital):
A local network of
fillInNetID will be replaced by the local network number (if known).
A local host of
fillInHostID will be replaced by the local host number.
A local socket of
fillInSocketID will be replaced by a unique local socket number.
A local address of
fillInPupAddress will be replaced by a unique local socket number.
A remote network of
fillInNetID means use the local network.
A remote host of
fillInHostID will be replaced by the local host number.
Servers, Users, and Listeners
Frequently a user will want to talk to another machine without having an operator at the remote site. FTP is the common example. In this case, the remote site is called a server, and the local end is referred to as the user site. The server is normally passive, merely responding to requests from the user. In actual implementation, there is usually an extra process called a listener that only waits passively for a user to try to establish a connection to a well known socket number, and then accepts the connection and creates a server process to do the real work.
Packets
The raw unit of transfer is a data structure called a packet. A packet lives in a buffer which also has room for all the other bookkeeping fields needed by the Pup Package. A packet consists of up to 532 bytes of user supplied data, and 22 bytes of control information manipulated by both the user and the Pup Package. Each packet has a source address and a destination address. These will be the same as the local and remote addresses of the connection if the packet is flowing towards the remote machine, but they will be reversed if the packet is flowing towards the user’s machine. There are utility routines to implement most of the common operations on the control information, but the only operations provided on the data are to set and retrieve its length.
Where to find it
The Alto Mesa Pup Package lives on the <Mesa>Pup> directory of your favorite file server. It comes it two sizes: Tiny and Fat. The Tiny version is for production use. It does not include anything extra. The Fat version includes a lot of consistency checks and the Stats Package, too. Except for a few minor differences, they both export the same interfaces -- you can switch back and forth without recompiling.
You will be interested in the following files:
PupTypes.bcd+mesa includes the basic RECORD type definitions and the enumerations for PupType and other things that are not likely to change very often.
BufferDefs.bcd+mesa includes the definition for Buffer and PupBuffer.
PupDefs.bcd+mesa includes miscelleneaous PROCEDURE interfaces. You will need this if you are programming at the socket level. Otherwise, you probably won’t need it unless you are doing something fancy.
PupStream.bcd+mesa (it is a Defs file in spite of its name) includes the the interface to the Pup ByteStream package. You will also need Stream.bcd to compile.
TinyPup.bcd is the tiny version of the PupPackage.
FatPup>FatPup.bcd is the fat version of the PupPackage. It contains the Stats package, and has been compiled with NIL and bounds checking. If you are having troubles finding an obscure bug, try using FatPup rather than TinyPup.
The bcd’s for code modules in FatPup are different from those used to build TinyPup. (The public interfaces are the same.) If you want the debugger to cooperate, be sure to fetch the correct ones.
Turning the Pup Package on and off
The Pup Package uses some core for buffers and resident code if it is on. If it is not on, it cannot send or receive Pups. The Pup Package is designed to be shared by several client programs that do not know about each other. Thus each client program must turn it on and reserve its own copy of the Pup Package.
PupPackageMake: PROCEDURE;
PupPackageDestroy: PROCEDURE;
PupPackageMake will bump a use count and turn the Pup Package on if needed. PupPackageDestroy will decrement a use count and turn the Pup Package off if it reaches 0. Turning things on involves allocating the buffer pool, locking things into core, turning on the Ethernet Driver, and trying to initialize the Pup routing table. You can’t call MakeImage while the Pup Package is on. (It gets very complicated to reinitalize the routing table and anything involving host numbers when starting up again.)
AdjustBufferParms: PROCEDURE [bufferPoolSize, bufferSize: CARDINAL];
AdjustBufferParms can only be called while the PupPackage is off. bufferPoolSize is the number of buffers that will be created when the PupPackage is turned on. The default is 15. Remember that the Pup Package keeps 2 in reserve for itself, and the normal Ethernet Driver uses 2 input buffers. bufferSize is the number of data words that will fit into the pup body of each buffer. The default is 266 words which is largest sized packet that gateways will forward. There is also a lower limit on the size of buffers. If you make it too small, you won’t be able to talk to other networks because you won’t be able to hear routing packets. The gateways break the routing table up into several packets if the size overflows 64 words, so that is the practical minimum. Actually, it is only the Mesa 6 Gateways that break the routing tables up into several packets, so the preceeding description may not be correct when you read this.
GetBufferParms: PROCEDURE RETURNS [bufferPoolSize, bufferSize: CARDINAL];
GetPupPackageUseCount: PROCEDURE RETURNS [CARDINAL];
GetBufferParms simply returns the current values of bufferPoolSize and bufferSize. If the PupPackage is not on, they are the numbers that will be used when it is next turned on. GetPupPackageUseCount returns the current use count of the communications package. If it is not 0, the Pup Package is on, and you should not call AdjustBufferParms, MakeImage or similar things.