<> <> <> DIRECTORY Basics USING [BITAND, bytesPerWord], Endian USING [bytesPerFWord, bytesPerHWord, FWORD, HWORD], CommBuffer USING [Overhead], Pup USING [Address, Host, Net], PupType USING [bytesInPupHeader, bytesOfPupOverhead, ErrorCode, HeaderWithoutChecksum, maxNewGatewayBytes, maxOldGatewayBytes, Type]; PupBuffer: CEDAR DEFINITIONS IMPORTS Basics = { BYTE: TYPE = [0..100H); HWORD: TYPE = Endian.HWORD; FWORD: TYPE = Endian.FWORD; <> maxOldGatewayBytes: NAT = PupType.maxOldGatewayBytes; maxNewGatewayBytes: NAT = PupType.maxNewGatewayBytes; maxDataBytes: NAT = 1500-PupType.bytesOfPupOverhead; <> << Beware: round down to maxXxxGatewayBytes if you are going through a gateway.>> maxDataHWords: NAT = maxDataBytes/Endian.bytesPerHWord; maxDataFWords: NAT = maxDataBytes/Endian.bytesPerFWord; ByteAlloc: TYPE = [0..maxDataBytes); HWordAlloc: TYPE = [0..maxDataHWords); FWordAlloc: TYPE = [0..maxDataFWords); ByteIndex: TYPE = [0..maxDataBytes]; HWordIndex: TYPE = [0..maxDataHWords]; FWordIndex: TYPE = [0..maxDataFWords]; <> StringIndex: TYPE = [0..maxDataBytes-stringOverheadBytes); AbortIndex: TYPE = [0..maxDataBytes-abortOverheadBytes); ErrorIndex: TYPE = [0..maxDataBytes-errorOverheadBytes); <> Buffer: TYPE = REF BufferObject; <> PupBufferPointer: TYPE = LONG POINTER TO BufferObject; -- Needed by Stupid Debugger BufferObject: TYPE = MACHINE DEPENDENT RECORD [ ovh: CommBuffer.Overhead, <> byteLength: HWORD, -- includes header and software checksum hopCount: [0..16), spares: [0..16), type: PupType.Type, id: FWORD, dest, source: Pup.Address, body: SELECT OVERLAID * FROM bytes => [ byte: PACKED ARRAY ByteAlloc OF BYTE ], chars => [ char: PACKED ARRAY ByteAlloc OF CHAR ], hWords => [ hWord: ARRAY HWordAlloc OF HWORD ], fWords => [ fWord: ARRAY FWordAlloc OF FWORD ], string => [ string: RECORD [ length: HWORD, maxLength: HWORD, text: PACKED ARRAY StringIndex OF CHAR ] ], rfc => [ address: Pup.Address ], ack => [ maxBytesPerPup: HWORD, maxPupsAhead: HWORD, maxBytesAhead: HWORD], abort => [ abort: RECORD [ code: HWORD, text: PACKED ARRAY AbortIndex OF CHAR ] ], error => [ error: RECORD [ header: PupType.HeaderWithoutChecksum, code: PupType.ErrorCode, options: HWORD, text: PACKED ARRAY ErrorIndex OF CHAR ] ], addresses => [ addresses: ARRAY AddressAlloc OF Pup.Address ], echoStats => [ echoStats: EchoStatsResponse], fileLookupReply => [ fileLookupReply: FileLookupReply ], routing => [ routing: ARRAY RoutingEntryAlloc OF RoutingInfoResponse ], time => [ time: TimeResponse ], ENDCASE <> ]; <> noChecksum: Endian.HWORD = 0FFFFH; RoundUpForChecksum: PROC [bytes: NAT] RETURNS [NAT] = INLINE { RETURN[Basics.BITAND[(bytes+1), 0FFFEH]]; }; <> WordsWithoutChecksum: PROC [bytes: NAT] RETURNS [words: NAT] = INLINE { RETURN[(bytes-1)/Endian.bytesPerHWord]; }; <> <> stringOverheadBytes: NAT = 2*Endian.bytesPerHWord; abortOverheadBytes: NAT = 1*Endian.bytesPerHWord; errorOverheadBytes: NAT = PupType.bytesInPupHeader + SIZE[PupType.ErrorCode, Basics.bytesPerWord] + 1*Endian.bytesPerHWord; <> <> <> <> <<>> <> <> bytesPerAddress: NAT = SIZE[Pup.Address, Basics.bytesPerWord]; maxAddresses: NAT = maxOldGatewayBytes/bytesPerAddress; AddressAlloc: TYPE = [0..maxAddresses); <> echoStatsVersion: NAT = 1; EchoStatsResponse: TYPE = MACHINE DEPENDENT RECORD [ version: HWORD, pupsEchoed: FWORD ]; <> FileLookupReply: TYPE = MACHINE DEPENDENT RECORD [ version: HWORD, createTime: FWORD, length: FWORD ]; <> bytesPerRoutingInfoResponse: NAT = SIZE[RoutingInfoResponse, Basics.bytesPerWord]; maxRoutingEntrys: NAT = maxOldGatewayBytes/bytesPerRoutingInfoResponse; RoutingEntryAlloc: TYPE = [0..maxRoutingEntrys); RoutingInfoResponse: TYPE = MACHINE DEPENDENT RECORD [ net: Pup.Net, viaNet: Pup.Net, viaHost: Pup.Host, hop: BYTE ]; <