-- File: ArpaSptpImpl.mesa - last edit: -- AOF 1-Mar-88 13:22:48 -- JAV 30-Nov-87 12:08:38 -- Copyright (C) 1987, 1988 by Xerox Corporation. All rights reserved. DIRECTORY ArpaBuffer USING [Body], ArpaInit USING [GetArpaInitInfo], ArpaPort USING [minIPHeaderBytes], ArpaPortInternal USING [BuildMasks], ArpaRouter USING [InternetAddress, unknownInternetAddress], ArpaRoutingTable USING [ContextObject, NetworkContext], ArpaSptp USING [], CommHeap USING [zone], Driver USING [Device], Environment USING [bytesPerWord], Inline USING [LongCOPY], Protocol1 USING [AddFamilyMember, DecapsulatorProc, EncapsulatorProc, Family, GetContext, GetFamilyUnit, MatrixRecord, RemoveFamilyMember], SptpOps USING [defaultMaxRS232CBytes], SptpProtocol USING [Encapsulation, EncapsulationObject]; ArpaSptpImpl: MONITOR IMPORTS ArpaInit, ArpaPortInternal, ArpaRouter, CommHeap, Inline, Protocol1 EXPORTS ArpaSptp = BEGIN bpw: NATURAL = Environment.bytesPerWord; AdoptForArpa: PUBLIC <<ArpaSptp>> PROC[ host: ArpaRouter.InternetAddress, adoptee: Driver.Device] = BEGIN mySubnetMask: ArpaRouter.InternetAddress; family: Protocol1.Family ← Protocol1.GetFamilyUnit[arpa]; matrix: Protocol1.MatrixRecord ← [ family: family, context: , encapsulator: ArpaEncapsulation, decapsulator: ArpaDecapsulation]; BEGIN OPEN c: LOOPHOLE[matrix.context, ArpaRoutingTable.NetworkContext]; matrix.context ← CommHeap.zone.NEW[ArpaRoutingTable.ContextObject]; c.network ← adoptee; c.stats ← NIL; c.protocol ← NIL; c.net ← host; c.host ← host; -- this is the address of the host for this net. [c.hostMask, c.netMask] ← ArpaPortInternal.BuildMasks[c.host]; IF (mySubnetMask ← ArpaInit.GetArpaInitInfo[].subnetMask) # ArpaRouter.unknownInternetAddress THEN c.netMask ← mySubnetMask; --are subnets in use? Protocol1.AddFamilyMember[LOOPHOLE[adoptee], @matrix]; END; END; --AdoptForArpa DisownFromArpa: PUBLIC <<ArpaSptp>> PROC [adoptee: Driver.Device] = BEGIN context: ArpaRoutingTable.NetworkContext ← Protocol1.GetContext[LOOPHOLE[adoptee], arpa]; family: Protocol1.Family ← Protocol1.GetFamilyUnit[arpa]; Protocol1.RemoveFamilyMember[LOOPHOLE[adoptee], family]; CommHeap.zone.FREE[@context]; END; --DisownFromArpa --**************** Encapsulation and decapsulation ************** ArpaDecapsulation: PUBLIC Protocol1.DecapsulatorProc = --PROCEDURE [b: Buffer.Buffer] RETURNS [type: Buffer.Type] BEGIN << When coming in here we are assured that b.linkLayer.blockPointer points to the beginning of the physical frame. That frame starts with the sptp's encapsulation record. From that information we should be able to compute the address of the data portion. >> size: NATURAL; body: ArpaBuffer.Body; device: Driver.Device = LOOPHOLE[b.fo.network]; --get pointer to network WITH e: LOOPHOLE[b.linkLayer.blockPointer, SptpProtocol.Encapsulation] SELECT FROM arpa => NULL; --data packet for arpa customer - get it up to network layer ENDCASE => RETURN[vagrant]; size ← SIZE[arpa SptpProtocol.EncapsulationObject]; --in words body ← LOOPHOLE[b.linkLayer.blockPointer + size]; --that's fair b.highLayer ← [LOOPHOLE[body], 0, body.ipHeader.length]; b.linkLayer.stopIndexPlusOne ← size ← (bpw * size); --in bytes SELECT TRUE FROM (b.fo.driver.length < size --in bytes--) => RETURN[orphan]; --busted (body.ipHeader.length < ArpaPort.minIPHeaderBytes) => RETURN[orphan]; --busted ENDCASE => RETURN[arpa]; --life is sooooo good END; --ArpaDecapsulation ArpaEncapsulation: PUBLIC Protocol1.EncapsulatorProc = BEGIN << Coming in here we know that the packet is an Arpa packet and that b.highLayer.blockPointer points to the ArpaBuffer.Body. We need to back off some number of bytes from that point and stick in the proper encap- sulation. NB: The Inline.LongCOPYs are here because the compiler generates somewhat unuseful code if you use a more direct approach to things. >> size: NATURAL; link: LONG POINTER; encapsulation: SptpProtocol.EncapsulationObject; body: ArpaBuffer.Body = LOOPHOLE[b.highLayer.blockPointer]; of: NATURAL = body.ipHeader.length / SptpOps.defaultMaxRS232CBytes; encapsulation ← [arpa[LTA: FALSE, more: FALSE, fragment: [1, of.SUCC]]]; size ← SIZE[arpa SptpProtocol.EncapsulationObject]; --in words <<THIS DOESN'T SUPPORT MULTIPLE VERSIONS OF THE SPTP PROTOCOL>> link ← body - size; --this is backoff to beginning of link layer Inline.LongCOPY[to: link, from: @encapsulation, nwords: size]; size ← bpw * size; --in bytes b.linkLayer ← [link, 0, size]; --set the link layer values b.fo.driver.length ← body.ipHeader.length + size; --and frame is sum of both END; --ArpaEncapsulation END..