IPTest.mesa
Last Edited by: Nichols, August 10, 1983 9:14 pm
Last Edited by: Taft, January 5, 1984 5:33 pm
Last Edited by: HGM, October 7, 1984 7:11:31 am PDT
Hal Murray May 16, 1985 2:42:08 am PDT
John Larson, April 14, 1986 11:06:25 pm PST
DIRECTORY
Ascii USING [Digit],
Commander USING [CommandProc, Register],
IO USING [int, GetChar, PeekChar, EndOf, PutF, PutRope, RIS, STREAM],
IPDefs USING [CreateIPHandle, Datagram, DatagramRec, DestroyIPHandle, InternetHandle, Address, maxDataLength, nullAddress, PrintDatagram, Receive, RequestData, Send];
IPTest:
CEDAR
PROGRAM
IMPORTS Ascii, Commander, IO, IPDefs =
BEGIN
testProtocol: INT = 200;
listenerTimeout: INT ← 10000;
logStream: IO.STREAM ← NIL;
myHandle: IPDefs.InternetHandle ← NIL;
listenerProcess: PROCESS;
listening: BOOL ← FALSE;
Listener:
PROC [h: IPDefs.InternetHandle] = {
Sit around waiting for datagrams and printing them.
d: IPDefs.Datagram;
WHILE listening
DO
d ← h.Receive[listenerTimeout];
IF d #
NIL
THEN {
logStream.PutRope["Received: "];
IPDefs.PrintDatagram[logStream, d]; };
d ← NIL;
ENDLOOP; };
Send: Commander.CommandProc = {
Compose a datagram and send it.
d: IPDefs.Datagram ← NEW [IPDefs.DatagramRec];
out: IO.STREAM ← cmd.out;
d.dataLength ← 2;
d.data[0] ← LOOPHOLE['H];
d.data[1] ← LOOPHOLE['i];
myHandle.Send[d];
out.PutRope["Sending: "];
IPDefs.PrintDatagram[out, d]; };
SendBig: Commander.CommandProc = {
Compose a BIG datagram and send it. (Leftover from debugging reassembly routines.)
d: IPDefs.Datagram ← NEW [IPDefs.DatagramRec];
out: IO.STREAM ← cmd.out;
d.dataLength ← IPDefs.maxDataLength;
FOR i:
INT
IN [0..IPDefs.maxDataLength)
DO
d.data[i] ← 101B + (i MOD 25);
ENDLOOP;
myHandle.Send[d];
out.PutRope["Sending: "];
IPDefs.PrintDatagram[out, d]; };
AToI:
PROC [s:
IO.
STREAM]
RETURNS [i:
INT ← 0] = {
Convert the leading digits of s into an integer.
WHILE ~s.EndOf[]
AND Ascii.Digit[s.PeekChar[]]
DO
i ← i*10 + (s.GetChar[]-'0);
ENDLOOP; };
ParseAddress:
PROC [s:
IO.
STREAM]
RETURNS [a: IPDefs.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[]; };
StartListener: Commander.CommandProc = {
out: IO.STREAM ← cmd.out;
remoteAddress: IPDefs.Address ← ParseAddress[IO.RIS[cmd.commandLine]];
IF listening
THEN {
out.PutRope["Listener already started.\n"];
RETURN; };
logStream ← out;
out.PutF["[%g.%g.%g.%g] ", IO.int[remoteAddress[0]], IO.int[remoteAddress[1]], IO.int[remoteAddress[2]], IO.int[remoteAddress[3]]];
myHandle ← IPDefs.CreateIPHandle[IPDefs.RequestData[matchProtocol: TRUE, protocol: testProtocol, matchAddr: FALSE, address: remoteAddress, matchLocalAddr: FALSE, localAddress: IPDefs.nullAddress]];
IF myHandle =
NIL
THEN
out.PutRope["Couldn't get Internet handle.\n"]
ELSE {
listening ← TRUE;
listenerProcess ← FORK Listener[myHandle];
out.PutRope["Forked listener.\n"]; }; };
StopListener: Commander.CommandProc = {
out: IO.STREAM ← cmd.out;
IF listening
THEN {
listening ← FALSE;
TRUSTED {JOIN listenerProcess};
IPDefs.DestroyIPHandle[myHandle];
myHandle ← NIL;
out.PutRope["Listener stopped.\n"]; }
ELSE out.PutRope["Listener not running.\n"]; };
Initialization
Commander.Register["StartListener", StartListener, "Get an IP listener going."];
Commander.Register["StopListener", StopListener, "Stop the IP listener."];
Commander.Register["SendIP", Send, "Send one packet."];
Commander.Register["SendIPBig", SendBig, "Send a big packet."];
END.