ArpaTranslationImpl.mesa
Demers, January 9, 1988 10:35:20 am PST
A crude temporary hack for filling in Arpa host numbers and subnet masks. This has a compiled-in list of known hosts/networks.
DIRECTORY
Arpa USING [Address, NetNumber, nullAddress],
ArpaTranslation USING [NetAndSubnetMask, NetAndSubnetMaskObject],
Basics USING [HighByte, LowByte],
CommDriver USING [Network],
ConvertExtras USING [ArpaAddressFromRope, RopeFromArpaAddress],
EditedStream USING [Create, Rubout],
IO USING [GetLineRope, PutRope, STREAM],
Rope USING [ROPE, SkipOver, Substr],
SimpleTerminal USING [TurnOff, TurnOn]
;
ArpaTranslationImpl: CEDAR MONITOR
IMPORTS Arpa, Basics, ConvertExtras, EditedStream, IO, Rope, SimpleTerminal
EXPORTS ArpaTranslation
~ {
Address: TYPE ~ Arpa.Address;
Network: TYPE ~ CommDriver.Network;
xeroxSubnetMask: Arpa.Address ~ [0FFH, 0FFH, 0FCH, 000H];
xeroxClassANetworkNumber: BYTE ~ 13;
alwaysAskUser: BOOLFALSE; -- DEBUG
DetermineAddressAndSubnetMaskForInterface: PUBLIC PROC [n: Network]
RETURNS [ok: BOOLFALSE] ~ {
p: ArpaTranslation.NetAndSubnetMask ← NEW[ArpaTranslation.NetAndSubnetMaskObject];
n.arpa.translation ← p;
IF NOT alwaysAskUser THEN {
SELECT n.type FROM
This looks stupid, since the two algorithms below are exactly the same
ethernet => ok ← DoEthernet[n, p];
ethernetOne => ok ← DoEthernetOne[n, p];
ENDCASE;
};
IF NOT ok THEN ok ← DoByAskingUser[n, p]
};
DoEthernetOne: PROC [n: Network, p: ArpaTranslation.NetAndSubnetMask]
RETURNS [ok: BOOL] ~ {
RETURN[DoByMappingPupNet[n, p]];
};
DoEthernet: PROC [n: Network, p: ArpaTranslation.NetAndSubnetMask]
RETURNS [ok: BOOL] ~ {
RETURN[DoByMappingPupNet[n, p]];
};
DoByMappingPupNet: PROC [n: Network, p: ArpaTranslation.NetAndSubnetMask]
RETURNS [ok: BOOL] ~ {
Hope that PUP has installed itself and knows its host/net number.
Simple algorithm:
8 bit network number = 13 (decimal)
14-bit subnet number = pup network number
10-bit host number = pup host number
arpaAddress, mask: Address;
temp: CARD16;
IF (temp ← 4*CARD16[n.pup.net]) = 0 THEN RETURN[ok~FALSE];
SELECT n.pup.net FROM
3B, 64B => { -- CONNECTATHON ONLY - this should be in ENDCASE!
arpaAddress ← [xeroxClassANetworkNumber, Basics.HighByte[temp], Basics.LowByte[temp], n.pup.host];
mask ← xeroxSubnetMask;
};
44B => {
arpaAddress ← [1, 0, 1, n.pup.host];
mask ← [255, 255, 255, 0];
};
ENDCASE => RETURN[ok~FALSE];
n.arpa.host ← arpaAddress;
p.net ← Arpa.NetNumber[arpaAddress];
p.subnetMask ← mask;
RETURN[ok~TRUE];
};
DoByAskingUser: ENTRY PROC [n: Network, p: ArpaTranslation.NetAndSubnetMask]
RETURNS [ok: BOOLTRUE] ~ {
in, out: IO.STREAM;
GetAddressFromUser: PROC [msg: Rope.ROPE, eg: Address] RETURNS [ans: Address] ~ {
r: Rope.ROPENIL;
IO.PutRope[out, msg];
IO.PutRope[out, " (e.g. "];
IO.PutRope[out, ConvertExtras.RopeFromArpaAddress[eg]];
IO.PutRope[out, "): "];
r ← IO.GetLineRope[in ! EditedStream.Rubout => CONTINUE]; -- r = NIL gives nullAddress
r ← Rope.Substr[r, Rope.SkipOver[r, 0, " "]];
ans ← ConvertExtras.ArpaAddressFromRope[r];
};
[in, out] ← SimpleTerminal.TurnOn["Arpa Address Determination"];
in ← EditedStream.Create[in, out];
DO
ENABLE ABORTED => { IO.PutRope[out, "XXX"]; LOOP };
address, subnetMask: Address;
thisHost: BYTE ~ IF n # NIL THEN n.pup.host ELSE 0;
address ← GetAddressFromUser["Enter ARPA address", [0, 0, 0, thisHost]];
IF address = Arpa.nullAddress THEN { IO.PutRope[out, "???\n"]; LOOP };
subnetMask ← GetAddressFromUser["Enter subnet mask", xeroxSubnetMask];
IF subnetMask = Arpa.nullAddress THEN { IO.PutRope[out, "???\n"]; LOOP };
IF n # NIL THEN n.arpa.host ← address;
IF p # NIL THEN { p.net ← Arpa.NetNumber[address]; p.subnetMask ← subnetMask };
EXIT;
ENDLOOP;
SimpleTerminal.TurnOff[];
};
}...