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
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.STREAMNIL;
myHandle: IP.InternetHandle ← NIL;
listening: BOOLFALSE;
remoteAddress: IP.Address;
localAddress: IP.Address;
sequenceNo: INT ← 0; -- sequence numbers for echo packets.
Send: Commander.CommandProc = TRUSTED {
Compose a datagram and send it.
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] = {
Convert the leading digits of s into an integer.
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] = {
Get an internet address from the input stream.
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.STREAMIO.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]]]; };
Initialization
Commander.Register["SetEchoAddress", SetAddress, "Set the address to aim echos at (setecho remote local)."];
Commander.Register["SendEchoMe", Send, "Send an echo me packet."];
END.