Header
Version: TYPE ~ CARDINAL [0..0FH];
thisVersion: Version ~ 4;
IHL: TYPE ~ CARDINAL [0..0FH];
minIHL: IHL ~ 5;
FragmentCtl: TYPE ~ HWORD;
defaultFragmentCtl: FragmentCtl ~ [0, 0];
Masks for use against Basics.Card16FromHword[FragmentCtl]
dontFragmentMask: CARD16 ~ 0400H;
moreFragmentsMask: CARD16 ~ 0200H;
fragmentOffsetMask: CARD16 ~ 01FFFH;
TypeOfService:
TYPE ~
MACHINE
DEPENDENT
RECORD [
precedence: Precedence,
lowDelay: BOOL,
highThroughput: BOOL,
highReliability: BOOL,
filler0: BOOL,
filler1: BOOL
];
defaultTypeOfService: TypeOfService ~
[routine, FALSE, FALSE, FALSE, FALSE, FALSE];
Precedence:
TYPE ~
MACHINE
DEPENDENT {
routine(0),
priority(1),
immediate(2),
flash(3),
flashOverride(4),
critECP(5),
inetCtl(6),
netCtl(7)
};
Protocol:
TYPE ~
MACHINE
DEPENDENT {
icmp(1), -- Internet Control Message Protocol
igmp(2), -- Internet Group Management Protocol
tcp(6), -- Transmission Control Protocol
egp(8), -- Exterior Gateway Protocol
igp(9), -- Interior Gateway
pup(12), -- PUP
udp(17), -- User Datagram Protocol
xnsidp(22), -- XNS Internet Datagram Packet
isotp4(29), -- ISO Transport Protocol Class 4
netblt(30), -- Bulk Data Transfer Protocol
last(0FFH)
};
Hdr:
TYPE ~
MACHINE
DEPENDENT
RECORD [
version: Version ← thisVersion,
ihl: IHL ← minIHL,
typeOfService: TypeOfService ← defaultTypeOfService,
length: HWORD,
fragmentId: HWORD ← [0, 0],
fragmentCtl: FragmentCtl ← defaultFragmentCtl,
timeToLive: BYTE,
protocol: Protocol,
checksum: HWORD ← [0, 0],
source: Arpa.Address,
dest: Arpa.Address];
hdrBytes: CARDINAL ~ BYTES[Hdr];
Body
Body:
TYPE ~
MACHINE
DEPENDENT
RECORD [
SELECT
OVERLAID *
FROM
bytes => [bytes: PACKED ARRAY [0..maxBodyBytes) OF BYTE],
chars => [chars: PACKED ARRAY [0..maxBodyChars) OF CHAR],
hWords => [hWords: PACKED ARRAY [0..maxBodyHWords) OF HWORD],
fWords => [fWords: PACKED ARRAY [0..maxBodyFWords) OF FWORD]
ENDCASE
];
maxBodyBytes: CARDINAL ~ maxBytes - hdrBytes;
maxBodyChars: CARDINAL ~ maxBodyBytes;
maxBodyHWords: CARDINAL ~ maxBodyBytes/BYTES[HWORD];
maxBodyFWords: CARDINAL ~ maxBodyBytes/BYTES[FWORD];
Buffer
All buffers start out as Driver.Buffer's. Clients may SmashType between Driver.Buffer and ArpaBuf.Buffer, so the "right" module gets to do finalization. This is VERY delicate.
Buffer: TYPE ~ REF BufferObject;
BufferObject:
TYPE ~
MACHINE
DEPENDENT
RECORD [
ovh: CommBuffer.Overhead,
hdr1: Hdr,
body: Body];
Options
These appear in CommBuffer.BufferObject.spaceForOptions.
OptionType:
TYPE ~
MACHINE
DEPENDENT [
mayBeCopied: BOOL,
class: [0..3B],
number: OptionNumber
];
OptionNumber:
TYPE ~
MACHINE
DEPENDENT {
endOfList(0),
noOp(1),
security(2),
looseSourceRouting(3),
timestamp(4),
recordRoute(7),
streamID(8),
strictSourceRouting(9)
};
firstOptionWithLengthField: OptionNumber ~ security;
Options numbered no less than this have a 1-byte length field, options numbered less than this have none. Beware: the length field counts the optionType and itself, so no length field can be less than 2.
}.