-- File: ArpaAddressTranslationImpl.mesa - last edit: -- AOF 3-Mar-88 12:44:17 -- JAV 17-Aug-87 11:31:45 -- Copyright (C) 1985, 1986, 1987, 1988 by Xerox Corporation. All rights reserved. DIRECTORY ArpaAddressCache USING [Lookup], ArpaAddressTranslation USING [ ErrorRecord, INetAddr, INetAddressOrName, nullINetAddress, ProtocolType], ArpaAddressTranslationPriv USING [], ArpaRouter USING [InternetAddress], ArpaToken USING [ Decimal, FreeStringHandle, Handle, NilData, StringToHandle, SyntaxError], Environment USING [Long], Inline USING [HighByte, LowByte], String USING [ AppendChar, AppendDecimal, AppendNumber, AppendString, ExpandString, StringBoundsFault, StringToNumber]; ArpaAddressTranslationImpl: PROGRAM IMPORTS ArpaAddressCache, ArpaAddressTranslation, ArpaToken, Inline, String EXPORTS ArpaAddressTranslation, ArpaAddressTranslationPriv = BEGIN Error: PUBLIC ERROR [errorRecord: ArpaAddressTranslation.ErrorRecord] = CODE; dot: CHARACTER = '.; comma: CHARACTER = ',; InternetAddressX: TYPE = MACHINE DEPENDENT RECORD [ InternetAddress(0): SELECT OVERLAID * FROM Raw => [IAddress(0): ArpaRouter.InternetAddress], Working => [ octet1(0:0..7): [0..256), octet2(0:8..15): [0..256), octet3(1:0..7): [0..256), octet4(1:8..15): [0..256)], ClassA => [ addrTypeA(0:0..0): [0..2), netNumA(0:1..7): [0..128), hostNumA1(0:8..15): [0..256), hostNumA2(1:0..15): [0..65534)], <<[class 1 bit][net number 7 bits][host number 24 bits]>> ClassB => [ addrTypeB(0:0..1): [0..4), netNumB(0:2..15): [0..16384), hostNumB(1:0..15): [0..65534)], <<[class 2 bits][net number 14 bits][host number 16 bits]>> ClassC => [ addrTypeC(0:0..2): [0..8), netNumC1(0: 3..15): [0..8192), netNumC2(1:0..7): [0..256), hostNumC(1: 8..15): [0..256)], <<[class 3 bits][net number 21 bits][host number 8 bits]>> ExtendedAddr => [ addrTypeExtended(0:0..2): [0..8), undefined1(0:3..15): [0..8192), undefined2(1:0..15): [0..65534)] <<[class 3 bits][undefined 29 bits]>> ENDCASE]; << Addresses of class - A have a zero in the first bit postition. B have a one-zero in the first two bit postitions. C have a one-one-zero in the first three bit positions. Extended have a one-one-one in the first three bit positions. >> StringToInternetAddress: PUBLIC PROC[ s: LONG STRING] RETURNS[addr: ArpaRouter.InternetAddress] = BEGIN found: BOOLEAN; IF s = NIL THEN ERROR Error[[scanError[0]]]; [addr, found] ← ArpaAddressCache.Lookup[s]; IF found THEN RETURN; --found it in cache addr ← LOOPHOLE[ArpaAddressTranslation.INetAddressOrName[s]]; IF addr # LOOPHOLE[ArpaAddressTranslation.nullINetAddress] THEN ERROR Error[[nameLookupProblem[noSuchName]]]; END; --StringToInternetAddress StringToInternetAddressPriv: PUBLIC PROC[s: LONG STRING] RETURNS[addr: ArpaRouter.InternetAddress] = {RETURN[LOOPHOLE[INetAddress[s]]]}; --StringToInternetAddressPriv INetAddress: PUBLIC PROC [s: LONG STRING] RETURNS[address: ArpaAddressTranslation.INetAddr] = BEGIN temp: CARDINAL; h: ArpaToken.Handle ← ArpaToken.StringToHandle[s]; BEGIN ENABLE {ArpaToken.NilData, ArpaToken.SyntaxError => GOTO error}; -- compiled without BoundsFault! IF s = NIL OR s.length = 0 THEN GOTO error; IF (temp ← ArpaToken.Decimal[h]) > 377B THEN GOTO error ELSE address.a ← temp; IF (temp ← ArpaToken.Decimal[h]) > 377B THEN GOTO error ELSE address.b ← temp; IF (temp ← ArpaToken.Decimal[h]) > 377B THEN GOTO error ELSE address.c ← temp; IF (temp ← ArpaToken.Decimal[h]) > 377B THEN GOTO error ELSE address.d ← temp; EXITS error => address ← ArpaAddressTranslation.nullINetAddress; END; h ← ArpaToken.FreeStringHandle[h]; END; -- INetAddress AppendINetAddress: PUBLIC PROC[ to: LONG STRING, address: ArpaAddressTranslation.INetAddr] = BEGIN String.AppendDecimal[to, address.a]; String.AppendChar[to, '.]; String.AppendDecimal[to, address.b]; String.AppendChar[to, '.]; String.AppendDecimal[to, address.c]; String.AppendChar[to, '.]; String.AppendDecimal[to, address.d]; END; -- AppendINetAddress AppendINetAddressAndGrow: PUBLIC PROC[ to: LONG POINTER TO LONG STRING, address: ArpaAddressTranslation.INetAddr, z: UNCOUNTED ZONE] = BEGIN ENABLE String.StringBoundsFault => {String.ExpandString[to, 20, z]; RESUME[to↑]}; String.AppendDecimal[to↑, address.a]; String.AppendChar[to↑, '.]; String.AppendDecimal[to↑, address.b]; String.AppendChar[to↑, '.]; String.AppendDecimal[to↑, address.c]; String.AppendChar[to↑, '.]; String.AppendDecimal[to↑, address.d]; END; -- AppendINetAddressAndGrow AppendProtocol: PUBLIC PROC[ s: LONG STRING, protocol: ArpaAddressTranslation.ProtocolType, radix: CARDINAL ← 10] = BEGIN temp: LONG STRING ← [20]; String.AppendNumber[temp, CARDINAL[LOOPHOLE[protocol]], radix]; IF radix # 10 THEN String.AppendChar[temp, SELECT radix FROM 8 => 'B, 16 => 'H, ENDCASE => ' ]; String.AppendString[s, SELECT protocol FROM icmp => "icmp"L, ggp => "ggp"L, st => "st"L, tcp => "tcp"L, egp => "egp"L, udp => "udp"L, mitRvd => "mitRvd"L, sunRvd => "sunRvd"L, ENDCASE => temp]; END; -- AppendProtocol InternetAddressToString: PUBLIC PROC[ addr: ArpaRouter.InternetAddress, s: LONG STRING, radix: CARDINAL] = { address: InternetAddressX ← LOOPHOLE[addr]; radixChar: CHARACTER ← '0; SELECT radix FROM 8 => radixChar ← 'B; 10 => radixChar ← 'D; ENDCASE => {radix ← 10; radixChar ← 'D}; String.AppendNumber[s, address.octet1, radix]; IF radixChar # '0 THEN String.AppendChar[s, radixChar]; String.AppendChar[s, dot]; String.AppendNumber[s, address.octet2, radix]; IF radixChar # '0 THEN String.AppendChar[s, radixChar]; String.AppendChar[s, dot]; String.AppendNumber[s, address.octet3, radix]; IF radixChar # '0 THEN String.AppendChar[s, radixChar]; String.AppendChar[s, dot]; String.AppendNumber[s, address.octet4, radix]; IF radixChar # '0 THEN String.AppendChar[s, radixChar]; }; --InternetAddressToString InternetAddrToTelnetPort: PUBLIC PROC[ addr: ArpaRouter.InternetAddress, s: LONG STRING, portNumber: CARDINAL] = { tempNumber: Environment.Long; tempNumber.lu ← LOOPHOLE[addr]; String.AppendDecimal[s, Inline.HighByte[tempNumber.low]]; String.AppendChar[s, comma]; String.AppendDecimal[s, Inline.LowByte[tempNumber.low]]; String.AppendChar[s, comma]; String.AppendDecimal[s, Inline.HighByte[tempNumber.high]]; String.AppendChar[s, comma]; String.AppendDecimal[s, Inline.LowByte[tempNumber.high]]; String.AppendChar[s, comma]; String.AppendDecimal[s, Inline.HighByte[portNumber]]; String.AppendChar[s, comma]; String.AppendDecimal[s, Inline.LowByte[portNumber]]; }; --InternetAddrToTelnetPort TelnetPortAddressToInternetAddr: PUBLIC PROC[s: LONG STRING] RETURNS[addr: ArpaRouter.InternetAddress, portNumber: CARDINAL ← 0] = BEGIN string: LONG STRING ← [20]; arrayIndex: CARDINAL ← 0; tempAddr: InternetAddressX; tempPort: MACHINE DEPENDENT RECORD[ HighHalf(0:0..7): [0..256), LowHalf(0:8..15): [0..256)]; tempNumber: UNSPECIFIED ← 0; FOR i: CARDINAL IN [0..s.length) DO SELECT s[i] FROM comma => { tempNumber ← String.StringToNumber[string]; IF tempNumber >= 256 THEN ERROR Error[[scanError[i]]]; SELECT arrayIndex FROM 0 => tempAddr.octet1 ← tempNumber; 1 => tempAddr.octet2 ← tempNumber; 2 => tempAddr.octet3 ← tempNumber; 3 => tempAddr.octet4 ← tempNumber; 4 => tempPort.HighHalf ← tempNumber; 5 => tempPort.LowHalf ← tempNumber; ENDCASE => ERROR Error[[scanError[i]]]; arrayIndex ← arrayIndex.SUCC; string.length ← 0}; IN ['0..'9] => String.AppendChar[string, s[i]] ENDCASE => LOOP; ENDLOOP; IF arrayIndex # 5 THEN ERROR Error[[scanError[s.length]]]; tempNumber ← String.StringToNumber[string]; IF tempNumber >= 256 THEN ERROR Error[[scanError[s.length]]]; tempPort.LowHalf ← tempNumber; RETURN[LOOPHOLE[tempAddr], LOOPHOLE[tempPort]]; END; END. LOG 0-000-00 00:00:00 ALD/ISI - added Domain NameServer stuff 3-Mar-88 12:38:19 AOF - Just cleaning up