DIRECTORY Ascii USING [Digit], Commander USING [CommandProc, Register], ICMP USING [Echo, ICMPBody, ICMPChecksum], IO USING [int, GetChar, PeekChar, EndOf, PutF, PutRope, RIS, STREAM], IP USING [Byte, DataBuffer, Datagram, DatagramRec, DByte, Address, InternetHandle, InternetHeader, PrintDatagram, SendSpecific]; EchoTest: CEDAR PROGRAM IMPORTS Ascii, Commander, ICMP, IO, IP = BEGIN testProtocol: INT = 1; listenerTimeout: INT _ 10000; logStream: IO.STREAM _ NIL; myHandle: IP.InternetHandle _ NIL; listening: BOOL _ FALSE; remoteAddress: IP.Address; localAddress: IP.Address; sequenceNo: INT _ 0; -- sequence numbers for echo packets. Send: Commander.CommandProc = TRUSTED { d: IP.Datagram _ NEW [IP.DatagramRec]; out: IO.STREAM _ cmd.out; body: LONG POINTER TO ICMP.ICMPBody _ LOOPHOLE[@d.data]; d.inHdr.protocol _ testProtocol; d.inHdr.source _ localAddress; d.inHdr.destination _ remoteAddress; d.inHdr.timeToLive _ 100; d.dataLength _ 10; body.type _ ICMP.Echo; body.code _ 0; body.id _ 0; body.sequenceNo _ (sequenceNo _ sequenceNo+1); body.data[0] _ LOOPHOLE['H]; body.data[1] _ LOOPHOLE['e]; body.checksum _ ICMP.ICMPChecksum[body, 5]; d.SendSpecific[]; out.PutRope["Sending: "]; IP.PrintDatagram[out, d]; }; AToI: PROC [s: IO.STREAM] RETURNS [i: INT _ 0] = { WHILE NOT s.EndOf[] AND Ascii.Digit[s.PeekChar[]] DO i _ i*10 + (s.GetChar[]-'0); ENDLOOP; }; ParseAddress: PROC [s: IO.STREAM] RETURNS [a: IP.Address] = { WHILE s.PeekChar[] = ' DO [] _ s.GetChar[]; ENDLOOP; IF s.PeekChar[] = '[ THEN [] _ s.GetChar[]; FOR i: INT IN [0..3] DO a[i] _ AToI[s]; IF ~s.EndOf[] AND s.PeekChar[] = '. THEN [] _ s.GetChar[]; ENDLOOP; IF ~s.EndOf[] AND s.PeekChar[] = '] THEN [] _ s.GetChar[]; }; SetAddress: Commander.CommandProc = { out: IO.STREAM _ cmd.out; commandLineStream: IO.STREAM _ IO.RIS[cmd.commandLine]; remoteAddress _ ParseAddress[commandLineStream]; localAddress _ ParseAddress[commandLineStream]; out.PutF["[%g.%g.%g.%g]\n", IO.int[remoteAddress[0]], IO.int[remoteAddress[1]], IO.int[remoteAddress[2]], IO.int[remoteAddress[3]]]; }; Commander.Register["SetEchoAddress", SetAddress, "Set the address to aim echos at (setecho remote local)."]; Commander.Register["SendEchoMe", Send, "Send an echo me packet."]; END. \Copyright (C) 1983, 1985 by Xerox Corporation. All rights reserved. The following program was created in 1983 but has not been published within the meaning of the copyright law, is furnished under license, and may not be used, copied and/or disclosed except in accordance with the terms of said license. EchoTest.mesa Hal Murray May 16, 1985 2:42:24 am PDT Last Edited by: Nichols, August 25, 1983 11:58 am Last Edited by: Taft, January 5, 1984 5:39 pm Compose a datagram and send it. Convert the leading digits of s into an integer. Get an internet address from the input stream. Initialization Κ#– "cedar" style˜Icode2šœ―™―head™ code™&J™1J™-—šΟk ˜ Kšœœ ˜Kšœ œ˜(Kšœœ ˜*Kšœœ0œœ˜EKšœœx˜€——šœ œ˜Kšœœœœ˜(š˜Kšœœ˜Kšœœ ˜Kšœ œœœ˜Kšœ œœ˜"Kšœ œœ˜Kšœœ ˜Kšœœ ˜Kšœ œΟc%˜:—šΟbœœ˜'K™Kšœœ œœ˜&Kšœœœ ˜Kš œœœœœ œ ˜8Kšœ ˜ Kšœ˜Kšœ$˜$K˜Kšœ˜Kšœ œ˜K˜K˜ K˜.Kšœœ˜Kšœœ˜Kšœœ˜+K˜K˜Kšœ˜—š Οnœœœœœœ ˜2K™0šœœ œ˜4K˜Kšœ˜ ——š   œœœœœœ ˜=Kšœ.™.Kšœœœ˜5Kšœœ˜+šœœœ˜K˜Kšœ œœ˜:Kšœ˜—Kšœ œœ˜=—šŸ œ˜%Kšœœœ ˜Kš œœœœœ˜7KšœΟrœ˜0K˜/Kš œœœœœ˜‡—™Kšœl˜lKšœB˜B—Kšœ˜K™——…—Ά5