resolve.pp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647
  1. {$MODE OBJFPC}
  2. {$H+}
  3. Unit resolve;
  4. { --------------------------------------------------------------------
  5. Unit for internet domain calls.
  6. Copyright (C) 2003 Michael Van Canneyt
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 1, or (at your option)
  10. any later version.
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU General Public License for more details.
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. ------------------------------------------------------------------- }
  19. interface
  20. uses
  21. Classes;
  22. Type
  23. THostAddr = array[1..4] of byte;
  24. PHostAddr = ^THostAddr;
  25. TNetAddr = THostAddr;
  26. PNetAddr = ^TNetAddr;
  27. Const
  28. NoAddress : THostAddr = (0,0,0,0);
  29. NoNet : TNetAddr = (0,0,0,0);
  30. { ---------------------------------------------------------------------
  31. Axuliary routines
  32. ---------------------------------------------------------------------}
  33. function HostAddrToStr (Entry : THostAddr) : String;
  34. function StrToHostAddr (IP : String) : THostAddr;
  35. function NetAddrToStr (Entry : TNetAddr) : String;
  36. function StrToNetAddr (IP : String) : TNetAddr;
  37. Function HostToNet (Host : ThostAddr) : ThostAddr;
  38. Function HostToNet (Host : Longint) : Longint;
  39. Function NetToHost (Net : Longint) : Longint;
  40. Function NetToHost (Net : TNetAddr) : TNetAddr;
  41. Function ShortHostToNet (Host : Word) : Word;
  42. Function ShortNetToHost (Net : Word) : Word;
  43. Type
  44. { ---------------------------------------------------------------------
  45. TResolver
  46. ---------------------------------------------------------------------}
  47. TResolver = Class (TComponent)
  48. Private
  49. FName : String;
  50. FAliases : TStringList;
  51. FRaiseOnError : Boolean;
  52. FLastError: Integer;
  53. Function GetAlias(Index : Integer) : STring;
  54. Function GetAliasCount : Integer;
  55. Function GetAliasSorted : Boolean;
  56. Procedure SetAliasSorted (Value : Boolean);
  57. Protected
  58. Procedure CheckOperation(Msg : String);
  59. Function NameLookup(Const S : String) : Boolean; virtual;
  60. Procedure SaveAliases(P : PPChar);
  61. Public
  62. Constructor Create(AOwner : TComponent); override;
  63. Destructor Destroy; override;
  64. Procedure ClearData; virtual;
  65. Property ResolvedName : String Read FName;
  66. Property Aliases [Index : integer ] : string Read GetAlias;
  67. Property AliasCount : Integer read GetAliasCount;
  68. Property SortAliases : Boolean Read GetAliasSorted Write SetAliasSorted;
  69. Property RaiseOnError : Boolean Read FRaiseOnError Write FRAiseOnError;
  70. Property LastError : Integer Read FlastError;
  71. end;
  72. { ---------------------------------------------------------------------
  73. THostResolver
  74. ---------------------------------------------------------------------}
  75. THostResolver = Class(TResolver)
  76. Private
  77. FHostAddress : THostAddr;
  78. FAddressCount : Integer;
  79. FAddresses : PHostAddr;
  80. Function GetAddress (Index : Integer) : THostAddr;
  81. Function GetNetAddress (Index : Integer) : THostAddr;
  82. Function GetNetHostAddress : THostAddr;
  83. Function GetAsString : String;
  84. Procedure SaveHostEntry (Entry : Pointer);
  85. Public
  86. Procedure ClearData; Override;
  87. Function NameLookup(Const S : String) : Boolean; override;
  88. Function AddressLookup(Const S : String) : Boolean; virtual;
  89. Function AddressLookup(Const Address : THostAddr) : Boolean; virtual;
  90. Property HostAddress : THostAddr Read FHostAddress;
  91. Property NetHostAddress : THostAddr Read GetNetHostAddress;
  92. Property AddressAsString : String Read GetAsString;
  93. Property AddressCount : Integer Read FAddressCount ;
  94. Property Addresses [Index : Integer] : ThostAddr Read GetAddress;
  95. Property NetAddresses [Index : Integer] : ThostAddr Read GetNetAddress;
  96. end;
  97. { ---------------------------------------------------------------------
  98. TNetResolver
  99. ---------------------------------------------------------------------}
  100. TNetResolver = Class(TResolver)
  101. Private
  102. FNetAddress : TNetAddr;
  103. FAddrType : Integer;
  104. Function GetAsString : String;
  105. Procedure SaveNetEntry(Entry : Pointer);
  106. Function GetNetAddress : TNetAddr;
  107. Public
  108. Procedure ClearData; override;
  109. Function NameLookup(Const S : String) : boolean; override;
  110. Function AddressLookup(Const S : String) : Boolean; virtual;
  111. Function AddressLookup(Const Address : TNetAddr) : Boolean; virtual;
  112. Property NetAddress : TNetAddr Read FNetAddress;
  113. Property NetNetAddress : TNetAddr Read GetNetAddress;
  114. Property AddressAsString : String Read GetAsString;
  115. Property AddressType : Integer Read FAddrType;
  116. end;
  117. { ---------------------------------------------------------------------
  118. TServiceResolver
  119. ---------------------------------------------------------------------}
  120. TServiceResolver = Class(TResolver)
  121. private
  122. FProtocol : String;
  123. FPort : Integer;
  124. Procedure SaveServiceEntry(Entry : Pointer);
  125. Function GetNetPort : Integer ;
  126. public
  127. Procedure ClearData; override;
  128. Function NameLookup (Const S : String) : boolean; override;
  129. Function NameLookup (Const S,Proto : String) : Boolean;
  130. Function PortLookup (APort : Longint; Proto: string) : Boolean;
  131. Property Protocol : String Read FProtocol;
  132. Property Port : Integer Read FPort;
  133. Property NetPort : Integer Read GetNetPort;
  134. end;
  135. Resourcestring
  136. SErrHostByName = 'Host by name';
  137. SErrHostByAddr = 'Host by address';
  138. SErrNetByName = 'Net by name';
  139. SErrServByName = 'Service by name';
  140. SErrServByPort = 'Service by port';
  141. Implementation
  142. { ---------------------------------------------------------------------
  143. Include system dependent stuff.
  144. ---------------------------------------------------------------------}
  145. {$i resolve.inc}
  146. function HostAddrToStr (Entry : THostAddr) : String;
  147. Var Dummy : String[4];
  148. I : Longint;
  149. begin
  150. HostAddrToStr:='';
  151. For I:=1 to 4 do
  152. begin
  153. Str(Entry[I],Dummy);
  154. HostAddrToStr:=HostAddrToStr+Dummy;
  155. If I<4 Then
  156. HostAddrToStr:=HostAddrToStr+'.';
  157. end;
  158. end;
  159. function StrToHostAddr(IP : String) : THostAddr ;
  160. Var
  161. Dummy : String;
  162. I : Longint;
  163. J : Integer;
  164. Temp : THostAddr;
  165. begin
  166. Result:=NoAddress;
  167. For I:=1 to 4 do
  168. begin
  169. If I<4 Then
  170. begin
  171. J:=Pos('.',IP);
  172. If J=0 then
  173. exit;
  174. Dummy:=Copy(IP,1,J-1);
  175. Delete (IP,1,J);
  176. end
  177. else
  178. Dummy:=IP;
  179. Val (Dummy,Temp[I],J);
  180. If J<>0 then Exit;
  181. end;
  182. Result:=Temp;
  183. end;
  184. function NetAddrToStr (Entry : TNetAddr) : String;
  185. Var Dummy : String[4];
  186. I : Longint;
  187. begin
  188. NetAddrToStr:='';
  189. For I:=4 downto 1 do
  190. begin
  191. Str(Entry[I],Dummy);
  192. NetAddrToStr:=NetAddrToStr+Dummy;
  193. If I>1 Then
  194. NetAddrToStr:=NetAddrToStr+'.';
  195. end;
  196. end;
  197. function StrToNetAddr(IP : String) : TNetAddr;
  198. begin
  199. StrToNetAddr:=TNetAddr(StrToHostAddr(IP));
  200. end;
  201. Function HostToNet (Host : ThostAddr) : THostAddr;
  202. begin
  203. Result[1]:=Host[4];
  204. Result[2]:=Host[3];
  205. Result[3]:=Host[2];
  206. Result[4]:=Host[1];
  207. end;
  208. Function NetToHost (Net : TNetAddr) : TNetAddr;
  209. begin
  210. Result[1]:=Net[4];
  211. Result[2]:=Net[3];
  212. Result[3]:=Net[2];
  213. Result[4]:=Net[1];
  214. end;
  215. Function HostToNet (Host : Longint) : Longint;
  216. begin
  217. Result:=Longint(HostToNet(THostAddr(host)));
  218. end;
  219. Function NetToHost (Net : Longint) : Longint;
  220. begin
  221. Result:=Longint(NetToHost(TNetAddr(Net)));
  222. end;
  223. Function ShortHostToNet (Host : Word) : Word;
  224. begin
  225. ShortHostToNet:=lo(host)*256+Hi(Host);
  226. end;
  227. Function ShortNetToHost (Net : Word) : Word;
  228. begin
  229. ShortNetToHost:=lo(Net)*256+Hi(Net);
  230. end;
  231. { ---------------------------------------------------------------------
  232. TResolver
  233. ---------------------------------------------------------------------}
  234. Constructor TResolver.Create(AOwner : TComponent);
  235. begin
  236. Inherited;
  237. FAliases:=TstringList.Create;
  238. end;
  239. Destructor TResolver.Destroy;
  240. begin
  241. ClearData;
  242. FAliases.Free;
  243. end;
  244. Procedure TResolver.ClearData;
  245. begin
  246. FName:='';
  247. FAliases.Clear;
  248. end;
  249. Function TResolver.GetAlias(Index : Integer) : STring;
  250. begin
  251. Result:=FAliases[Index];
  252. end;
  253. Function TResolver.GetAliasCount : Integer;
  254. begin
  255. Result:=FAliases.Count;
  256. end;
  257. Function TResolver.GetAliasSorted : Boolean;
  258. begin
  259. Result:=FAliases.Sorted;
  260. end;
  261. Procedure TResolver.SetAliasSorted (Value : Boolean);
  262. begin
  263. FAliases.Sorted:=Value;
  264. end;
  265. Procedure TResolver.CheckOperation(Msg : String);
  266. begin
  267. end;
  268. Function TResolver.NameLookup(Const S : String) : Boolean;
  269. begin
  270. ClearData;
  271. FName:=S;
  272. Result:=True;
  273. end;
  274. Procedure TResolver.SaveAliases(P : PPChar);
  275. Var
  276. I : Integer;
  277. begin
  278. If (P<>Nil) then
  279. begin
  280. I:=0;
  281. While P[I]<>Nil do
  282. begin
  283. FAliases.Add(StrPas(P[I]));
  284. Inc(I);
  285. end;
  286. end;
  287. end;
  288. { ---------------------------------------------------------------------
  289. THostResolver
  290. ---------------------------------------------------------------------}
  291. Function THostResolver.GetAddress (Index : Integer) : THostAddr;
  292. begin
  293. If (Index>=0) and (Index<FAddressCount) then
  294. Result:=FAddresses[Index];
  295. end;
  296. Function THostResolver.GetAsString : String;
  297. begin
  298. Result:=HostAddrToStr(FHostAddress);
  299. end;
  300. Procedure THostResolver.ClearData;
  301. begin
  302. Inherited;
  303. FHostAddress:=NoAddress;
  304. If FAddressCount<>0 Then
  305. FreeMem(FAddresses);
  306. FAddressCount:=0;
  307. FAddresses:=Nil;
  308. end;
  309. Function THostResolver.AddressLookup(Const S : String) : Boolean;
  310. begin
  311. Result:=AddressLookup(StrToHostAddr(S));
  312. end;
  313. Function THostResolver.NameLookup (Const S : String) : Boolean;
  314. Var
  315. FHostEntry : PHostEntry;
  316. begin
  317. Result:=Inherited NameLookup(S);
  318. If Result then
  319. begin
  320. FHostEntry:=GetHostByName(pchar(FName));
  321. Result:=FHostEntry<>Nil;
  322. If Result then
  323. SaveHostEntry(FHostEntry)
  324. else
  325. begin
  326. FLastError:=GetDNSError;
  327. CheckOperation(SErrHostByName);
  328. end;
  329. end;
  330. end;
  331. Procedure THostResolver.SaveHostEntry(Entry : Pointer);
  332. Var
  333. P : Pointer;
  334. I,Count : Integer;
  335. begin
  336. With PHostEntry(Entry)^ do
  337. begin
  338. FName:=StrPas(H_Name);
  339. FAddressCount:=0;
  340. While H_Addr[FAddressCount]<>Nil do
  341. Inc(FAddressCount);
  342. If FAddressCount>0 then
  343. begin
  344. GetMem(FAddresses,FAddressCount*SizeOf(THostAddr));
  345. For I:=0 to FAddressCount-1 do
  346. FAddresses[I]:=PHostAddr(H_Addr[I])^;
  347. FHostAddress:=FAddresses[0];
  348. end;
  349. SaveAliases(H_Aliases);
  350. end;
  351. end;
  352. Function THostResolver.AddressLookup (Const Address: THostAddr) : Boolean;
  353. Var
  354. FHostEntry : PHostEntry;
  355. begin
  356. ClearData;
  357. FHostEntry:=GetHostByAddr(Pchar(@Address),SizeOf(Address),AF_INET);
  358. Result:=FHostEntry<>Nil;
  359. If Result then
  360. SaveHostEntry(FHostEntry)
  361. else
  362. begin
  363. FLastError:=GetDNSError;
  364. CheckOperation(SErrHostByAddr);
  365. end;
  366. end;
  367. Function THostResolver.GetNetAddress (Index : Integer) : THostAddr;
  368. begin
  369. Result:=HostToNet(Addresses[Index]);
  370. end;
  371. Function THostResolver.GetNetHostAddress : THostAddr;
  372. begin
  373. Result:=HostToNet(FHostAddress);
  374. end;
  375. { ---------------------------------------------------------------------
  376. TNetResolver
  377. ---------------------------------------------------------------------}
  378. Function TNetResolver.NameLookup (Const S : String) : Boolean;
  379. Var
  380. FNetEntry : PNetEntry;
  381. begin
  382. Result:=Inherited NameLookup(S);
  383. If Result then
  384. begin
  385. FNetEntry:=GetNetByName(pchar(S));
  386. Result:=FNetEntry<>Nil;
  387. If Result then
  388. SaveNetEntry(FNetEntry)
  389. else
  390. begin
  391. FLastError:=GetDNSError;
  392. Checkoperation(SErrNetByName);
  393. end;
  394. end;
  395. end;
  396. Procedure TNetResolver.SaveNetEntry(Entry : Pointer);
  397. begin
  398. With PNetEntry(Entry)^ do
  399. begin
  400. FName:=StrPas(N_Name);
  401. FAddrType:=N_addrtype;
  402. FNetAddress:=NetToHost(TNetAddr(N_net));
  403. SaveAliases(N_Aliases);
  404. end;
  405. end;
  406. Function TNetResolver.AddressLookup (Const Address: TNetAddr) : boolean;
  407. Var
  408. FNetEntry : PNetEntry;
  409. begin
  410. ClearData;
  411. {$ifndef win32}
  412. FNetEntry:=GetNetByAddr(Longint(HostToNet(Address)),AF_INET);
  413. {$else}
  414. FNetEntry:=Nil;
  415. {$endif}
  416. Result:=FNetEntry<>Nil;
  417. If Result then
  418. SaveNetEntry(FNetEntry)
  419. else
  420. begin
  421. FLastError:=GetDNSError;
  422. CheckOperation(SErrNetByName);
  423. end;
  424. end;
  425. Function TNetResolver.AddressLookup(Const S : String) : Boolean;
  426. begin
  427. Result:=AddressLookup(StrToNetAddr(S));
  428. end;
  429. Function TNetResolver.GetAsString : String;
  430. begin
  431. Result:=HostAddrToStr(FNetAddress);
  432. end;
  433. Function TNetResolver.GetNetAddress : TNetAddr;
  434. begin
  435. Result:=HostToNet(FNetAddress);
  436. end;
  437. Procedure TNetResolver.ClearData;
  438. begin
  439. Inherited;
  440. FNetAddress:=NoAddress;
  441. FAddrType:=0;
  442. end;
  443. { ---------------------------------------------------------------------
  444. TServiceResolver
  445. ---------------------------------------------------------------------}
  446. Function TServiceResolver.NameLookup (Const S : String) : Boolean;
  447. begin
  448. Result:=NameLookup(S,'');
  449. end;
  450. Function TServiceResolver.NameLookup (Const S,Proto : String) : Boolean;
  451. Var
  452. FServiceEntry : PServEntry;
  453. begin
  454. ClearData;
  455. FName:=S;
  456. FProtocol:=Proto;
  457. If (proto='') then
  458. FServiceEntry:=GetServByName(pchar(S),Nil)
  459. else
  460. FServiceEntry:=GetServByName(pchar(S),PChar(FProtocol));
  461. Result:=FServiceEntry<>Nil;
  462. If Result then
  463. SaveServiceEntry(FServiceEntry)
  464. else
  465. begin
  466. FLastError:=GetDNSError;
  467. CheckOperation(SErrServByName);
  468. end;
  469. end;
  470. Function TServiceResolver.PortLookup (APort: Longint; Proto : String) : Boolean;
  471. Var
  472. FServiceEntry : PServEntry;
  473. begin
  474. ClearData;
  475. APort:=ShortHostToNet(APort);
  476. FProtoCol:=Proto;
  477. If (Proto='') then
  478. FServiceEntry:=GetServByPort(APort,Nil)
  479. else
  480. FServiceEntry:=GetServByPort(APort,pchar(Proto));
  481. Result:=FServiceEntry<>Nil;
  482. If Result then
  483. SaveServiceEntry(FServiceEntry)
  484. else
  485. begin
  486. FLastError:=GetDNSError;
  487. CheckOperation(SErrServByPort);
  488. end;
  489. end;
  490. Procedure TServiceResolver.SaveServiceEntry(Entry : Pointer);
  491. begin
  492. With PServEntry(Entry)^ do
  493. begin
  494. FName:=strpas(s_name);
  495. FPort:=ShortHostToNet(S_port);
  496. FProtocol:=strpas(s_proto);
  497. SaveAliases(S_aliases);
  498. end;
  499. end;
  500. Procedure TServiceResolver.ClearData;
  501. begin
  502. Inherited;
  503. FProtocol:='';
  504. FPort:=0;
  505. end;
  506. Function TServiceResolver.GetNetPort : Integer;
  507. begin
  508. Result:=ShortHostToNet(FPort);
  509. end;
  510. end.
  511. {
  512. $Log$
  513. Revision 1.1 2003-02-01 16:50:38 michael
  514. + Added resolve unit for WIndows/unix
  515. }