-- File: TrapBadPups.mesa
-- Edit: HGM March 24, 1981 1:40 AM
-- Edit: BLyon January 16, 1981 5:44 PM
DIRECTORY
Ascii USING [CR, SP],
CmFile USING [OpenSection, NextItem, Close],
Put USING [Text, Line],
Runtime USING [IsBound],
Storage USING [FreeString],
String USING [
AppendChar, AppendDecimal, AppendNumber, AppendString, EquivalentString],
Time USING [AppendCurrent],
Indirect USING [GetParmFileName],
Mailer USING [Level, SendMail],
BufferDefs USING [PupBuffer],
DriverDefs USING [Network],
DriverTypes USING [Encapsulation],
PupDefs USING [GetPupContentsBytes],
ForwarderDefs USING [],
PupRouterDefs USING [RejectPupWithBadChecksum, SetPupChecksum];
TrapBadPups: MONITOR
IMPORTS
CmFile, Put, Runtime, Storage, String, Time,
Indirect, Mailer, PupDefs, PupRouterDefs
EXPORTS BufferDefs, ForwarderDefs
SHARES BufferDefs =
BEGIN
-- EXPORTed TYPEs
Network: PUBLIC TYPE = DriverDefs.Network;
to, cc: STRING ← NIL;
troubles: STRING ← NIL; -- Also used as from
badSequenceAppendNumber: CARDINAL ← 0;
recent: CARDINAL ← 0;
CollectInfo: PROCEDURE =
BEGIN
parmFileName: STRING ← NIL;
sectionName: STRING = "TrapBadPups"L;
token, arg: STRING ← NIL;
IF Runtime.IsBound[Indirect.GetParmFileName] THEN
parmFileName ← Indirect.GetParmFileName[];
IF parmFileName = NIL THEN RETURN;
IF ~CmFile.OpenSection[parmFileName, sectionName] THEN
BEGIN
Problem["Can't find [TrapBadPups] section."L];
RETURN;
END;
DO
[token, arg] ← CmFile.NextItem[];
SELECT TRUE FROM
token = NIL => EXIT;
String.EquivalentString[token, "Troubles"L] =>
BEGIN
CheckForRegistry[arg];
Storage.FreeString[troubles];
troubles ← arg;
END;
String.EquivalentString[token, "To"L] =>
BEGIN
CheckForRegistry[arg];
Storage.FreeString[to];
to ← arg;
END;
String.EquivalentString[token, "cc"L] =>
BEGIN
CheckForRegistry[arg];
Storage.FreeString[cc];
cc ← arg;
END;
ENDCASE =>
BEGIN
IF token[0] # '; THEN Problem["Unknown keyword: "L, token];
Storage.FreeString[arg];
END;
Storage.FreeString[token];
ENDLOOP;
CmFile.Close[parmFileName];
IF troubles = NIL THEN
Problem["Please specify somebody in case of TROUBLES"L];
IF to = NIL THEN
Problem["Please specify somebody to send the message to"L];
RETURN;
END;
CheckForRegistry: PROCEDURE [s: STRING] =
BEGIN
dot: BOOLEAN ← FALSE;
FOR i: CARDINAL IN [0..s.length) DO
SELECT s[i] FROM
'. => dot ← TRUE;
', =>
BEGIN
IF ~dot THEN
BEGIN Problem["Registry expected in arg: "L, s]; RETURN; END;
dot ← FALSE;
END;
ENDCASE => NULL;
ENDLOOP;
IF ~dot THEN BEGIN Problem["Registry expected in arg: "L, s]; RETURN; END;
END;
Problem: PROCEDURE [one, two, three: STRING ← NIL] =
BEGIN
text: STRING = [100];
Time.AppendCurrent[text];
String.AppendString[text, " TrapBadPups: "L];
String.AppendString[text, one];
IF two # NIL THEN String.AppendString[text, two];
IF three # NIL THEN String.AppendString[text, three];
LogString[text];
END;
PrintBadPup: PUBLIC PROCEDURE [b: BufferDefs.PupBuffer] =
BEGIN
IF b = NIL THEN RETURN;
IF troubles#NIL AND to#NIL THEN
BEGIN
badSequenceAppendNumber ← badSequenceAppendNumber + 1;
IF recent < 30 THEN -- average of one every 10 min, but allow clumps of 3
BEGIN recent ← recent + 10; MailBadPup[b]; END;
END;
PupRouterDefs.RejectPupWithBadChecksum[b];
END;
maxWords: CARDINAL = 300;
maxBytes: CARDINAL = 500 + maxWords*8;
MailBadPup: PUBLIC PROCEDURE [b: BufferDefs.PupBuffer] =
BEGIN
body: STRING = [maxBytes];
size: CARDINAL ← (b.pupLength - 1)/2;
checksumLoc: LONG POINTER ← @b.pupLength + size;
words: CARDINAL ← (PupDefs.GetPupContentsBytes[b] + 1)/2;
i: CARDINAL;
p: LONG POINTER;
network: Network = b.network;
Info: PROCEDURE [s: STRING, level: Mailer.Level] = {LogString[s]; };
O7: PROCEDURE [n: WORD] =
BEGIN
temp: STRING = [10];
String.AppendNumber[temp, n, 8];
THROUGH [temp.length..7) DO String.AppendChar[body, Ascii.SP]; ENDLOOP;
String.AppendNumber[body, n, 8];
END;
Time.AppendCurrent[body];
String.AppendString[body, " ***** Bad software checksum on Pup from net "L];
String.AppendNumber[body, network.netNumber.b, 8];
String.AppendChar[body, Ascii.CR];
String.AppendString[body, "Bad pup number "L];
String.AppendDecimal[body, badSequenceAppendNumber];
String.AppendString[body, " has a checksum of "L];
String.AppendNumber[body, checksumLoc↑, 8];
PupRouterDefs.SetPupChecksum[b]; -- Fix it up
String.AppendString[body, ", but it should be "L];
String.AppendNumber[body, checksumLoc↑, 8];
String.AppendChar[body, Ascii.CR];
String.AppendString[body, "Encap: "L];
p ← @b.encapsulation;
FOR i IN [0..SIZE[DriverTypes.Encapsulation]) DO O7[(p + i)↑]; ENDLOOP;
String.AppendChar[body, Ascii.CR];
String.AppendString[body, "Header:"L];
p ← @b.bufferBody;
FOR i IN [0..11 - 1) DO O7[(p + i)↑]; ENDLOOP;
FOR i ← 0, i + 1 UNTIL i >= MIN[words, maxWords] DO
IF (i MOD 10) = 0 THEN
BEGIN
String.AppendChar[body, Ascii.CR];
String.AppendString[body, IF i = 0 THEN "Body: "L ELSE " "L];
END;
O7[b.pupWords[i]];
ENDLOOP;
String.AppendChar[body, Ascii.CR];
Put.Text[NIL, body];
IF Runtime.IsBound[Mailer.SendMail] THEN
[] ← Mailer.SendMail[
"TrapBadPups"L, "Bad Checksum info"L, to, cc, body, troubles, NIL, Info];
END;
LogString: PROCEDURE [s: STRING] = {Put.Line[NIL, s]};
-- initialization
CollectInfo[];
END.