Unix.DNS.Mod 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. (* Aos, Copyright 2001, Pieter Muller, ETH Zurich *)
  2. MODULE DNS; (** AUTHOR "pjm, mvt, gf"; PURPOSE "DNS client"; *)
  3. IMPORT S := SYSTEM, Out := KernelLog, Unix, IP, Files;
  4. CONST
  5. (** Error codes *)
  6. Ok* = 0; NotFound* = 3601; BadName* = 3602;
  7. MaxNofServer* = 10; (* max. number registered of DNS servers *)
  8. TYPE
  9. Name* = ARRAY 128 OF CHAR; (* domain or host name type *)
  10. Hostent = POINTER {UNSAFE, UNTRACED} TO RECORD
  11. name : POINTER {UNSAFE, UNTRACED} TO Name;
  12. aliases : ADDRESS;
  13. addrtype : LONGINT;
  14. length : LONGINT;
  15. addrlist : ADDRESS
  16. END;
  17. VAR
  18. (** Local domain name *)
  19. domain*: Name;
  20. nlib: ADDRESS;
  21. gethostbyaddr : PROCEDURE {C} ( adr: ADDRESS; len, typ: LONGINT ): Hostent;
  22. gethostbyname : PROCEDURE {C} ( name: ADDRESS ): Hostent;
  23. gethostname : PROCEDURE {C} ( name: ADDRESS; len: SIZE ): LONGINT;
  24. (* Statistic variables *)
  25. NDNSReceived-, NDNSSent-, NDNSMismatchID-, NDNSError-: LONGINT;
  26. (** Find the host responsible for mail exchange of the specified domain. *)
  27. PROCEDURE MailHostByDomain*( CONST domain: ARRAY OF CHAR; VAR hostname: ARRAY OF CHAR; VAR res: WORD );
  28. BEGIN
  29. HALT( 99 ); (* not implemented yet. needed ?? *)
  30. hostname[0] := 0X
  31. END MailHostByDomain;
  32. (** Find the IP address of the specified host. *)
  33. PROCEDURE HostByName*( CONST hostname: ARRAY OF CHAR; VAR addr: IP.Adr; VAR res: WORD );
  34. VAR
  35. hostent: Hostent;
  36. firstaddrPtr: ADDRESS;
  37. BEGIN {EXCLUSIVE}
  38. hostent := gethostbyname( ADDRESSOF( hostname ) );
  39. IF hostent # NIL THEN
  40. S.GET( hostent.addrlist, firstaddrPtr );
  41. IF hostent.length = 4 THEN
  42. S.MOVE( firstaddrPtr, ADDRESSOF( addr.ipv4Adr ), 4 );
  43. addr.usedProtocol := IP.IPv4;
  44. ELSE
  45. S.MOVE( firstaddrPtr, ADDRESSOF( addr.ipv6Adr ), 16 );
  46. addr.usedProtocol := IP.IPv6;
  47. END;
  48. res := Ok
  49. ELSE
  50. res := NotFound
  51. END
  52. END HostByName;
  53. (** Find the host name of the specified IP address. *)
  54. PROCEDURE HostByNumber*( addr: IP.Adr; VAR hostname: ARRAY OF CHAR; VAR res: WORD );
  55. VAR
  56. hostent: Hostent;
  57. BEGIN {EXCLUSIVE}
  58. IF IP.IsNilAdr( addr ) THEN
  59. hostname[0] := 0X; res := BadName; RETURN
  60. END;
  61. IF addr.usedProtocol = IP.IPv4 THEN
  62. hostent := gethostbyaddr( ADDRESSOF( addr.ipv4Adr ), 4, Unix.PFINET )
  63. ELSE
  64. hostent := gethostbyaddr( ADDRESSOF( addr.ipv6Adr ), 16, Unix.PFINET6 )
  65. END;
  66. IF hostent # NIL THEN (* err points to struct hostent *)
  67. COPY (hostent.name^, hostname);
  68. res := Ok
  69. ELSE
  70. res := NotFound
  71. END
  72. END HostByNumber;
  73. (* none portable, Unix ports only! *)
  74. PROCEDURE GetHostName*( VAR name: ARRAY OF CHAR; VAR res: WORD );
  75. VAR x: LONGINT;
  76. BEGIN
  77. x := gethostname( ADDRESSOF( name ), LEN( name ) );
  78. IF x >= 0 THEN res := Ok ELSE res := NotFound END
  79. END GetHostName;
  80. PROCEDURE GetLocalDomain( VAR dom: ARRAY OF CHAR );
  81. VAR f: Files.File; r: Files.Reader; buf: ARRAY 256 OF CHAR; ignore: BOOLEAN;
  82. BEGIN
  83. f := Files.Old( "/etc/resolv.conf" );
  84. IF f # NIL THEN
  85. Files.OpenReader( r, f, 0 );
  86. WHILE r.GetString( buf ) & (buf # "domain") DO
  87. IF buf[0] = "#" THEN r.Ln( buf ) END (* skip comment *)
  88. END;
  89. IF buf = "domain" THEN ignore := r.GetString( buf );
  90. ELSE buf := "unknown.edu"
  91. END
  92. ELSE buf := "unknown.edu"
  93. END;
  94. COPY( buf, dom )
  95. END GetLocalDomain;
  96. BEGIN
  97. GetLocalDomain( domain );
  98. NDNSReceived := 0;
  99. NDNSSent := 0;
  100. NDNSMismatchID := 0;
  101. NDNSError := 0;
  102. IF Unix.Version = "Darwin" THEN
  103. nlib := Unix.libc
  104. ELSE
  105. nlib := Unix.Dlopen( "libnsl.so.1", 2 );
  106. IF nlib = 0 THEN nlib := Unix.Dlopen( "libnsl.so", 2 ) END;
  107. IF nlib = 0 THEN
  108. Out.String( "Unix.Dlopen( 'libnsl.so' ) failed" ); Out.Ln
  109. END;
  110. END;
  111. Unix.Dlsym( nlib, "gethostbyaddr", ADDRESSOF( gethostbyaddr ) );
  112. Unix.Dlsym( nlib, "gethostbyname", ADDRESSOF( gethostbyname ) );
  113. Unix.Dlsym( nlib, "gethostname", ADDRESSOF( gethostname ) );
  114. END DNS.