MODULE DNS;
IMPORT S := SYSTEM, Out := KernelLog, Unix, Machine, IP;
CONST
Ok* = 0; NotFound* = 3601; BadName* = 3602;
MaxNofServer* = 10;
TYPE
Address = S.ADDRESS;
Name* = ARRAY 128 OF CHAR;
Hostent = POINTER TO RECORD
name : Address;
aliases : Address;
addrtype : LONGINT;
length : LONGINT;
addrlist : Address
END;
VAR
domain*: Name;
nlib: Address;
gethostbyaddr : PROCEDURE {C} ( adr: Address; len, typ: LONGINT ): Hostent;
gethostbyname : PROCEDURE {C} ( name: Address ): Hostent;
gethostname : PROCEDURE {C} ( name: Address; len: LONGINT ): LONGINT;
NDNSReceived-, NDNSSent-, NDNSMismatchID-, NDNSError-: LONGINT;
PROCEDURE MailHostByDomain*( CONST domain: ARRAY OF CHAR; VAR hostname: ARRAY OF CHAR; VAR res: LONGINT );
BEGIN
HALT( 99 );
hostname[0] := 0X
END MailHostByDomain;
PROCEDURE HostByName*( CONST hostname: ARRAY OF CHAR; VAR addr: IP.Adr; VAR res: LONGINT );
VAR
hostent: Hostent;
firstaddrPtr: Address;
BEGIN {EXCLUSIVE}
hostent := gethostbyname( S.ADR( hostname ) );
IF hostent # NIL THEN
S.GET( hostent.addrlist, firstaddrPtr );
IF hostent.length = 4 THEN
S.MOVE( firstaddrPtr, S.ADR( addr.ipv4Adr ), 4 );
addr.usedProtocol := IP.IPv4;
ELSE
S.MOVE( firstaddrPtr, S.ADR( addr.ipv6Adr ), 16 );
addr.usedProtocol := IP.IPv6;
END;
res := Ok
ELSE
res := NotFound
END
END HostByName;
PROCEDURE HostByNumber*( addr: IP.Adr; VAR hostname: ARRAY OF CHAR; VAR res: LONGINT );
VAR
hostent: Hostent;
namePtr: Address;
ch: CHAR; i: INTEGER;
BEGIN {EXCLUSIVE}
IF IP.IsNilAdr( addr ) THEN
hostname[0] := 0X; res := BadName; RETURN
END;
IF addr.usedProtocol = IP.IPv4 THEN
hostent := gethostbyaddr( S.ADR( addr.ipv4Adr ), 4, Unix.PFINET )
ELSE
hostent := gethostbyaddr( S.ADR( addr.ipv6Adr ), 16, Unix.PFINET6 )
END;
IF hostent # NIL THEN
S.GET( hostent.name, namePtr );
i := 0;
REPEAT
S.GET( namePtr + i, ch );
hostname[i]:= ch; INC( i )
UNTIL ch = 0X;
res := Ok
ELSE
res := NotFound
END
END HostByNumber;
PROCEDURE GetHostName*( VAR name: ARRAY OF CHAR; VAR res: LONGINT );
VAR len, x: LONGINT;
BEGIN
x := gethostname( S.ADR( name ), S.ADR( len ) );
IF x >= 0 THEN res := Ok ELSE res := NotFound END
END GetHostName;
BEGIN
Machine.GetConfig( "Domain", domain );
NDNSReceived := 0;
NDNSSent := 0;
NDNSMismatchID := 0;
NDNSError := 0;
IF Unix.sysinfo.sysname = "Darwin" THEN
nlib := Unix.libc
ELSE
nlib := Unix.Dlopen( "libnsl.so.1", 2 );
IF nlib = 0 THEN nlib := Unix.Dlopen( "libnsl.so", 2 ) END;
IF nlib = 0 THEN
Out.String( "Unix.Dlopen( 'libnsl.so' ) failed" ); Out.Ln
END;
END;
Unix.Dlsym( nlib, "gethostbyaddr", S.VAL( Address, gethostbyaddr ) );
Unix.Dlsym( nlib, "gethostbyname", S.VAL( Address, gethostbyname ) );
Unix.Dlsym( nlib, "gethostname", S.VAL( Address, gethostname ) );
END DNS.