IPNameUdpImpl.mesa
Hal Murray June 1, 1985 11:59:46 pm PDT
John Larson, July 19, 1987 5:06:31 pm PDT
DIRECTORY
Basics USING [BytePair, HighByte, LongNumber, LowByte],
Rope USING [Concat, Fetch, Find, FromChar, Length, ROPE, Substr],
IPDefs USING [Byte, DByte, Address],
IPNameUdp USING [Class, DomainHeader, Type],
UDP USING [BodyRec, minLength, maxLength];
IPNameUdpImpl: CEDAR PROGRAM
IMPORTS Basics, Rope
EXPORTS IPNameUdp =
BEGIN
ROPE: TYPE = Rope.ROPE;
Class: TYPE = IPNameUdp.Class;
DomainHeader: TYPE = IPNameUdp.DomainHeader;
Type: TYPE = IPNameUdp.Type;
EndOfData: PUBLIC SIGNAL = CODE;
Raised when no more udp data
AppendQuery: PUBLIC PROC [
udp: LONG POINTER TO UDP.BodyRec, domain: LONG POINTER TO DomainHeader,
query: ROPE, type: Type, class: Class] = TRUSTED {
AppendName[udp, query];
AppendTwoBytes[udp, type];
AppendTwoBytes[udp, class];
domain.qdCount ← domain.qdCount + 1; };
AppendInverse: PUBLIC PROC [
udp: LONG POINTER TO UDP.BodyRec, domain: LONG POINTER TO DomainHeader,
address: IPDefs.Address, type: Type, class: Class] = TRUSTED {
AppendName[udp, "Foo"];
AppendTwoBytes[udp, type];
AppendTwoBytes[udp, class];
AppendTwoBytes[udp, 0]; -- Mumble
AppendTwoBytes[udp, 0]; -- TTL
AppendTwoBytes[udp, 4]; -- rDataLength
AppendIPAddress[udp, address];
domain.anCount ← domain.anCount + 1; };
AppendName: PUBLIC PROC [
udp: LONG POINTER TO UDP.BodyRec, name: ROPE] = TRUSTED {
DO
dot: INT ← Rope.Find[name, "."];
IF dot = -1 THEN EXIT;
IF dot = 0 THEN EXIT; -- Bounds fault
AppendFragment[udp, Rope.Substr[name, 0, dot]];
name ← Rope.Substr[name, dot+1]
ENDLOOP;
IF Rope.Length[name] # 0 THEN AppendFragment[udp, name];
AppendFragment[udp, NIL]; };
AppendFragment: PUBLIC PROC [
udp: LONG POINTER TO UDP.BodyRec, rope: ROPE] = TRUSTED {
length: INT ← udp.length;
chars: INT ← Rope.Length[rope];
udp.data[length] ← chars;
FOR i: INT IN [0..chars) DO
udp.data[length+i+1] ← LOOPHOLE[Rope.Fetch[rope, i]];
ENDLOOP;
udp.length ← udp.length + chars + 1; };
AppendTwoBytes: PUBLIC PROC [
udp: LONG POINTER TO UDP.BodyRec, data: UNSPECIFIED] = TRUSTED {
length: INT ← udp.length;
udp.data[length] ← Basics.HighByte[data];
udp.data[length+1] ← Basics.LowByte[data];
udp.length ← udp.length + 2; };
AppendIPAddress: PUBLIC PROC [
udp: LONG POINTER TO UDP.BodyRec, address: IPDefs.Address] = TRUSTED {
length: INT ← udp.length;
udp.data[length+0] ← address[0];
udp.data[length+1] ← address[1];
udp.data[length+2] ← address[2];
udp.data[length+3] ← address[3];
udp.length ← udp.length + 4; };
SkipQuery: PUBLIC PROC [udp: LONG POINTER TO UDP.BodyRec] = TRUSTED {
[] ← GetName[udp]; -- Name
[] ← GetTwoBytes[udp]; -- Type
[] ← GetTwoBytes[udp]; }; -- Class
SkipRR: PUBLIC PROC [udp: LONG POINTER TO UDP.BodyRec] = TRUSTED {
name: ROPE ← GetName[udp];
type: Type ← GetTwoBytes[udp];
class: Class ← GetTwoBytes[udp];
ttl: INT ← GetTtl[udp];
rDataLength: CARDINAL ← GetTwoBytes[udp];
udp.length ← udp.length + rDataLength; }; -- rDataLength, and rData
GetName: PUBLIC PROC [udp: LONG POINTER TO UDP.BodyRec] RETURNS [rope: ROPE] = TRUSTED {
length: INT ← udp.length;
indirect: INT ← 300B;
rope ← NIL;
DO
bytes: INT;
IF length >= UDP.maxLength THEN SIGNAL EndOfData;
bytes ← udp.data[length];
length ← length + 1;
IF bytes = 0 THEN EXIT;
IF bytes >= indirect THEN { -- Indirect link, keep length we have
temp: INT;
IF length >= UDP.maxLength THEN SIGNAL EndOfData;
temp ← (bytes-indirect)*256 + udp.data[length];
temp ← temp + UDP.minLength;
length ← length + 1;
udp.length ← temp;
rope ← Rope.Concat[rope, GetName[udp]];
EXIT; };
FOR i: INT IN [0..bytes) DO
IF length >= UDP.maxLength THEN SIGNAL EndOfData;
rope ← Rope.Concat[rope, Rope.FromChar[LOOPHOLE[udp.data[length]]]];
length ← length + 1;
ENDLOOP;
IF length >= UDP.maxLength THEN SIGNAL EndOfData;
IF udp.data[length] # 0 THEN rope ← Rope.Concat[rope, "."];
ENDLOOP;
udp.length ← length; };
longTime: LONG CARDINAL = 10*365*86400;
GetTtl: PUBLIC PROC [
udp: LONG POINTER TO UDP.BodyRec] RETURNS [INT] = {
card: LONG CARDINAL ← GetCard[udp];
IF card > longTime THEN card ← longTime;
RETURN[card]; };
GetCard: PUBLIC PROC [
udp: LONG POINTER TO UDP.BodyRec] RETURNS [LONG CARDINAL] = {
ln: Basics.LongNumber;
ln.hi ← GetCardinal[udp];
ln.lo ← GetCardinal[udp];
RETURN[ln.lc]; };
GetCardinal: PUBLIC PROC [
udp: LONG POINTER TO UDP.BodyRec] RETURNS [CARDINAL] = {
RETURN[GetTwoBytes[udp]]; };
GetTwoBytes: PUBLIC PROC [
udp: LONG POINTER TO UDP.BodyRec] RETURNS [UNSPECIFIED] = TRUSTED {
length: INT ← udp.length;
temp: Basics.BytePair;
IF length +1 >= UDP.maxLength THEN SIGNAL EndOfData;
temp.high ← udp.data[length];
temp.low ← udp.data[length+1];
udp.length ← udp.length + 2;
RETURN[temp]; };
GetIPAddress: PUBLIC PROC [
udp: LONG POINTER TO UDP.BodyRec] RETURNS [a: IPDefs.Address] = TRUSTED {
length: INT ← udp.length;
IF length +3 >= UDP.maxLength THEN SIGNAL EndOfData;
a[0] ← udp.data[length+0];
a[1] ← udp.data[length+1];
a[2] ← udp.data[length+2];
a[3] ← udp.data[length+3];
udp.length ← udp.length + 4; };
GetOneByte: PUBLIC PROC [
udp: LONG POINTER TO UDP.BodyRec] RETURNS [UNSPECIFIED] = TRUSTED {
length: INT ← udp.length;
temp: Basics.BytePair;
IF length >= UDP.maxLength THEN SIGNAL EndOfData;
temp.high ← 0;
temp.low ← udp.data[length];
udp.length ← udp.length + 1;
RETURN[temp]; };
GetChar: PUBLIC PROC [
udp: LONG POINTER TO UDP.BodyRec] RETURNS [c: CHAR] = TRUSTED {
length: INT ← udp.length;
IF length >= UDP.maxLength THEN SIGNAL EndOfData;
c ← LOOPHOLE[udp.data[length]];
udp.length ← udp.length + 1;
RETURN[c]; };
GetRope: PUBLIC PROC [
udp: LONG POINTER TO UDP.BodyRec] RETURNS [rope: Rope.ROPE] = TRUSTED {
chars: CARDINAL ← GetOneByte[udp];
FOR i: INT IN [0..chars) DO
rope ← Rope.Concat[rope, Rope.FromChar[GetChar[udp]]];
ENDLOOP;
RETURN[rope]; };
END.