<> <> <> <> <> <> <> 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] = { <> 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 = { <> 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 = { <> 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] = { <> 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] = { <> 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"]; }; <> 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.