-- File: ChecksumsImpl.mesa - last edit: -- AOF 13-Aug-87 16:42:23 -- Copyright (C) 1984, 1986, 1987 by Xerox Corporation. All rights reserved. DIRECTORY Checksums USING [ComputeChecksum], Environment USING [bytesPerWord], Inline USING [BITAND, BITNOT, BITROTATE], Mopcodes USING [zADD, zACD, zDUP, zINC, zJNEB, zLIN1, zLI0], NSBuffer USING [Body], NSTypes USING [base, BufferBody, TransportControl]; ChecksumsImpl: PROGRAM IMPORTS Checksums, Inline EXPORTS Checksums SHARES NSTypes = BEGIN RawWords: TYPE = LONG POINTER TO RawWord; RawWord: TYPE = RECORD[SEQUENCE COMPUTED WORD OF WORD]; bpw: NATURAL = Environment.bytesPerWord; transportControlOffset: CARDINAL = LOOPHOLE[@NSTypes.base.pktLength, CARDINAL] + SIZE[CARDINAL --pktLength field--]; -- These procedures sets the checksum field of the NS Packet. SetChecksum: PUBLIC PROC[b: NSBuffer.Body] = BEGIN b.checksum ← Checksums.ComputeChecksum[ 0, (b.pktLength + bpw - 1) / bpw - 1, @b.pktLength]; END; -- These procedures checks the checksum field of the NS Packet, -- and returns TRUE or FALSE. The buffer is always a system buffer TestChecksum: PUBLIC PROC[b: NSBuffer.Body] RETURNS [BOOLEAN] = BEGIN cs: CARDINAL; --local used so we can look at cs with debugger IF b.checksum = 177777B THEN RETURN[TRUE]; cs ← Checksums.ComputeChecksum[ 0, (b.pktLength + bpw - 1) / bpw - 1, @b.pktLength]; RETURN[b.checksum = cs]; END; SlowlyComputeChecksum: PUBLIC PROC[ cs: CARDINAL, nWords: CARDINAL, p: LONG POINTER] RETURNS [CARDINAL] = BEGIN t: CARDINAL; THROUGH [0..nWords) DO IF cs > (t ← cs + p↑) THEN cs ← t + 1 ELSE cs ← t; IF cs >= 100000B THEN cs ← cs*2 + 1 ELSE cs ← cs*2; p ← p + 1; ENDLOOP; IF cs = 177777B THEN cs ← 0; RETURN[cs]; END; -- This procedure updates the checksum field of the NS Packet -- after it increments the nsTransportControl. IncrNSTransportControlAndUpdateChecksum: PUBLIC PROC[b: NSBuffer.Body] = BEGIN resisdual: INTEGER; newVal, oldVal: WORD; raw: RawWords = LOOPHOLE[b]; oldVal ← raw[transportControlOffset]; --save the old value before mods b.transportControl.hopCount ← SUCC[b.transportControl.hopCount]; --modify IF b.checksum = 177777B THEN RETURN; newVal ← raw[transportControlOffset]; --capture the new value resisdual ← Inline.BITAND[ (b.pktLength + bpw - 1) / bpw - transportControlOffset, 17B]; b.checksum ← OnesAdd[ b.checksum, Inline.BITROTATE[OnesSub[newVal, oldVal], resisdual]]; END; -- UpdateChecksum OnesAdd: PROC[a, b: WORD] RETURNS [CARDINAL] = MACHINE CODE BEGIN -- c ← a + b; IF c < a THEN c ← c + 1; IF c=177777B THEN c ← 0; Mopcodes.zLI0; Mopcodes.zACD; Mopcodes.zADD; Mopcodes.zDUP; Mopcodes.zLIN1; Mopcodes.zJNEB, 3; Mopcodes.zINC; END; OnesSub: PROC[a, b: WORD] RETURNS [CARDINAL] = INLINE {RETURN[OnesAdd[a, Inline.BITNOT[b]]]}; END. -- ChecksumsImpl LOG 17-May-84 10:21:03 AOF Post Klamath 18-Aug-86 15:48:41 AOF Trying to get back bytes for 14.0 BufferMgr 13-Aug-87 13:25:58 AOF Computing increment checksums correctly