PageRenderTime 27ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/ProSnooperFx_src/indy10.0.52_source/Protocols/IdDNSCommon.pas

http://github.com/lookias/ProSnooper
Pascal | 2244 lines | 1674 code | 283 blank | 287 comment | 128 complexity | 216b360157b284ab29a8be8687e591a1 MD5 | raw file
  1. { $HDR$}
  2. {**********************************************************************}
  3. { Unit archived using Team Coherence }
  4. { Team Coherence is Copyright 2002 by Quality Software Components }
  5. { }
  6. { For further information / comments, visit our WEB site at }
  7. { http://www.TeamCoherence.com }
  8. {**********************************************************************}
  9. {}
  10. { $Log: 13798: IdDNSCommon.pas
  11. {
  12. { Rev 1.21 10/26/2004 9:06:30 PM JPMugaas
  13. { Updated references.
  14. }
  15. {
  16. Rev 1.20 9/15/2004 4:59:34 PM DSiders
  17. Added localization comments.
  18. }
  19. {
  20. { Rev 1.19 2004/7/19 U 09:43:40 DChang
  21. { 1. Move the TIdTextModeResourceRecords which was defined in
  22. { IdDNSServer.pas to here.
  23. { 2. Add a QueryType (DqtIXFR) in TDNSQueryRecordTypes.
  24. }
  25. {
  26. { Rev 1.18 6/29/04 1:22:32 PM RLebeau
  27. { Updated NormalStrToDNSStr() to use CopyTIdBytes() instead of AppendBytes()
  28. }
  29. {
  30. { Rev 1.17 2/11/2004 5:21:12 AM JPMugaas
  31. { Vladimir Vassiliev changes for removal of byte flipping. Network conversion
  32. { order conversion functions are used instead.
  33. { IPv6 addresses are returned in the standard form.
  34. { In WKS records, Address was changed to IPAddress to be consistant with other
  35. { record types. Address can also imply a hostname.
  36. }
  37. {
  38. { Rev 1.16 2/7/2004 7:18:30 PM JPMugaas
  39. { Moved some functions out of IdDNSCommon so we can use them elsewhere.
  40. }
  41. {
  42. { Rev 1.15 2004.02.07 5:45:10 PM czhower
  43. { Fixed compile error in D7.
  44. }
  45. {
  46. { Rev 1.14 2004.02.07 5:03:26 PM czhower
  47. { .net fixes.
  48. }
  49. {
  50. { Rev 1.13 2004.02.03 5:45:56 PM czhower
  51. { Name changes
  52. }
  53. {
  54. { Rev 1.12 12/7/2003 8:07:24 PM VVassiliev
  55. { string -> TIdBytes
  56. }
  57. {
  58. { Rev 1.11 11/15/2003 1:16:06 PM VVassiliev
  59. { Move AppendByte from IdDNSCommon to IdCoreGlobal
  60. }
  61. {
  62. { Rev 1.10 11/13/2003 5:46:04 PM VVassiliev
  63. { DotNet
  64. }
  65. {
  66. { Rev 1.9 10/25/2003 06:51:50 AM JPMugaas
  67. { Updated for new API changes and tried to restore some functionality.
  68. }
  69. {
  70. Rev 1.8 10/19/2003 11:56:12 AM DSiders
  71. Added localization comments.
  72. }
  73. {
  74. { Rev 1.7 2003.10.12 3:50:38 PM czhower
  75. { Compile todos
  76. }
  77. {
  78. { Rev 1.6 2003/5/8 U 08:07:12 DChang
  79. { Add several constants for IdDNSServer
  80. }
  81. {
  82. { Rev 1.5 4/28/2003 03:34:56 PM JPMugaas
  83. { Illiminated constant for the service path. IFDEF's for platforms are only
  84. { allowed in designated units. Besides, the location of the services file is
  85. { different in Win9x operating systems than NT operating systems.
  86. }
  87. {
  88. { Rev 1.4 4/28/2003 02:30:46 PM JPMugaas
  89. { reverted back to the old one as the new one checked will not compile, has
  90. { problametic dependancies on Contrs and Dialogs (both not permitted).
  91. }
  92. {
  93. { Rev 1.2 4/28/2003 07:00:04 AM JPMugaas
  94. { Should now compile.
  95. }
  96. {
  97. { Rev 1.0 11/14/2002 02:18:20 PM JPMugaas
  98. Rev 1.3 04/28/2003 01:15:20 AM DenniesChang
  99. }
  100. {
  101. // Add iRCode mode constants in May 4, 2003.
  102. // Modify all DNS relative header in IdDNSCommon.pas
  103. // Apr. 28, 2003
  104. // Jun. 03, 2002.
  105. // Add AXFR function
  106. Duplicate some varible and constants in DNSCommon,
  107. because Indy change version very frequently, these
  108. varlibles and objects are isolated.
  109. I had added some methods into IdDNSResolver of Indy 9.02,
  110. for parsing DN record directly and skip some check actions
  111. from original query, but this modification will not relfect
  112. the action of DN Query.
  113. Original Programmer: Dennies Chang <dennies@ms4.hinet.net>
  114. No Copyright. Code is given to the Indy Pit Crew.
  115. Started: Jan. 20, 2002.
  116. Finished:
  117. }
  118. unit IdDNSCommon;
  119. interface
  120. uses
  121. Classes,
  122. IdGlobal,
  123. IdResourceStringsProtocols,
  124. IdException,
  125. IdResourceStrings,
  126. IdContainers,
  127. IdTStrings;
  128. Resourcestring
  129. RSQueryMustProvideSOARecord = 'You have to provide a TIdRR_SOA object with Serial number and Name to progress IXFR. %d';
  130. const
  131. IdDNSServerVersion = 'Indy DNSServer 2004071501'; {do not localize}
  132. cRCodeNoError = 0;
  133. cRCodeFormatErr = 1;
  134. cRCodeServerErr = 2;
  135. cRCodeNameErr = 3;
  136. cRCodeNotImplemented = 4;
  137. cRCodeRefused = 5;
  138. iRCodeQueryNotImplement = 0;
  139. iRCodeQueryReturned = 1;
  140. iRCodeQueryOK = 2;
  141. iRCodeQueryNotFound = 3;
  142. iRCodeNoError = 0;
  143. iRCodeFormatError = 1;
  144. iRCodeServerFailure = 2;
  145. iRCodeNameError = 3;
  146. iRCodeNotImplemented = 4;
  147. iRCodeRefused = 5;
  148. iQr_Question = 0;
  149. iQr_Answer = 1;
  150. iAA_NotAuthoritative = 0;
  151. iAA_Authoritative = 1;
  152. cRCodeQueryNotImplement = 'NA'; {do not localize}
  153. cRCodeQueryReturned = 'RC'; // Return Completed. {do not localize}
  154. cRCodeQueryOK = 'OK'; {do not localize}
  155. cRCodeQueryCacheOK = 'COK'; {do not localize}
  156. cRCodeQueryNotFound = 'NOTFOUND'; {do not localize}
  157. cRCodeQueryCacheFindError = 'CFoundError'; {do not localize}
  158. RSDNSServerAXFRError_QuerySequenceError = 'First record must be SOA!'; {do not localize}
  159. RSDNSServerSettingError_MappingHostError = 'Host must be an IP address'; {do not localize}
  160. cOrigin = '$ORIGIN'; {do not localize}
  161. cInclude = '$INCLUDE'; {do not localize}
  162. cAAAA = 'AAAA'; {do not localize}
  163. cAt = '@'; {do not localize}
  164. cA = 'A'; {do not localize}
  165. cNS = 'NS'; {do not localize}
  166. cMD = 'MD'; {do not localize}
  167. cMF = 'MF'; {do not localize}
  168. cCName = 'CNAME'; {do not localize}
  169. cSOA = 'SOA'; {do not localize}
  170. cMB = 'MB'; {do not localize}
  171. cMG = 'MG'; {do not localize}
  172. cMR = 'MR'; {do not localize}
  173. cNULL = 'NULL'; {do not localize}
  174. cWKS = 'WKS'; {do not localize}
  175. cPTR = 'PTR'; {do not localize}
  176. cHINFO = 'HINFO'; {do not localize}
  177. cMINFO = 'MINFO'; {do not localize}
  178. cMX = 'MX'; {do not localize}
  179. cTXT = 'TXT'; {do not localize}
  180. cNSAP = 'NSAP'; {do not localize}
  181. cNSAP_PTR = 'NSAP-PTR'; {do not localize}
  182. cLOC = 'LOC'; {do not localize}
  183. cAXFR = 'AXFR'; {do not localize}
  184. cIXFR = 'IXFR'; {do not localize}
  185. cSTAR = 'STAR'; {do not localize}
  186. cRCodeStrs : Array[cRCodeNoError..cRCodeRefused] Of String =
  187. (RSCodeNoError,
  188. RSCodeQueryFormat,
  189. RSCodeQueryServer,
  190. RSCodeQueryName,
  191. RSCodeQueryNotImplemented,
  192. RSCodeQueryQueryRefused);
  193. Class_IN = 1;
  194. TypeCode_A = 1;
  195. TypeCode_NS = 2;
  196. TypeCode_MD = 3;
  197. TypeCode_MF = 4;
  198. TypeCode_CName = 5;
  199. TypeCode_SOA = 6;
  200. TypeCode_MB = 7;
  201. TypeCode_MG = 8;
  202. TypeCode_MR = 9;
  203. TypeCode_NULL = 10;
  204. TypeCode_WKS = 11;
  205. TypeCode_PTR = 12;
  206. TypeCode_HINFO = 13;
  207. TypeCode_MINFO = 14;
  208. TypeCode_MX = 15;
  209. TypeCode_TXT = 16;
  210. TypeCode_RP = 17;
  211. TypeCode_AFSDB = 18;
  212. TypeCode_X25 = 19;
  213. TypeCode_ISDN = 20;
  214. TypeCode_RT = 21;
  215. TypeCode_NSAP = 22;
  216. TypeCode_NSAP_PTR = 23;
  217. TypeCode_SIG = 24;
  218. TypeCode_KEY = 25;
  219. TypeCode_PX = 26;
  220. TypeCode_QPOS = 27;
  221. TypeCode_AAAA = 28;
  222. TypeCode_LOC = 29;
  223. TypeCode_NXT = 30;
  224. TypeCode_R31 = 31;
  225. TypeCode_R32 = 32;
  226. TypeCode_Service = 33;
  227. TypeCode_R34 = 34;
  228. TypeCode_NAPTR = 35;
  229. TypeCode_KX = 36;
  230. TypeCode_CERT = 37;
  231. TypeCode_V6Addr = 38;
  232. TypeCode_DNAME = 39;
  233. TypeCode_R40 = 40;
  234. TypeCode_OPTIONAL = 41;
  235. TypeCode_IXFR = 251;
  236. TypeCode_AXFR = 252;
  237. TypeCode_STAR = 255;
  238. TypeCode_Error = 0;
  239. type
  240. {NormalTags = (cA, cNS, cMD, cMF, cCName, cSOA, cMB, cMG, cMR, cNULL, cWKS, cPTR,
  241. cHINFO, cMINFO, cMX, cTXT); }
  242. TDNSQueryRecordTypes = (DqtA, DqtNS, DqtMD, DqtMF, DqtName, DqtSOA, DqtMB,
  243. DqtMG, DqtMR, DqtNull, DqtWKS, DqtPTR, DqtHINFO, DqtMINFO, DqtMX, DqtTXT,
  244. DqtNSAP, DqtNSAP_PTR, DqtLOC, DqtIXFR, DqtAXFR, DqtSTAR, DqtAAAA);
  245. TDNSServerTypes = (stPrimary, stSecondary);
  246. EIdDNSServerSyncException = class(EIdSilentException);
  247. EIdDNSServerSettingException = class(EIdSilentException);
  248. TDNSHeader = class
  249. private
  250. FID: Word;
  251. FBitCode: Word;
  252. FQDCount: Word;
  253. FANCount: Word;
  254. FNSCount: Word;
  255. FARCount: Word;
  256. function GetAA: Word;
  257. function GetOpCode: Word;
  258. function GetQr: Word;
  259. function GetRA: Word;
  260. function GetRCode: Word;
  261. function GetRD: Word;
  262. function GetTC: Word;
  263. procedure SetAA(const Value: Word);
  264. procedure SetOpCode(const Value: Word);
  265. procedure SetQr(const Value: Word);
  266. procedure SetRA(const Value: Word);
  267. procedure SetRCode(const Value: Word);
  268. procedure SetRD(const Value: Word);
  269. procedure SetTC(const Value: Word);
  270. procedure SetBitCode(const Value: Word);
  271. public
  272. constructor Create;
  273. procedure ClearByteCode;
  274. function ParseQuery(Data : TIdBytes) : integer;
  275. function GenerateBinaryHeader : TIdBytes ;
  276. property ID: Word read FID write FID;
  277. property Qr: Word read GetQr write SetQr;
  278. property OpCode: Word read GetOpCode write SetOpCode;
  279. property AA: Word read GetAA write SetAA;
  280. property TC: Word read GetTC write SetTC;
  281. property RD: Word read GetRD write SetRD;
  282. property RA: Word read GetRA write SetRA;
  283. property RCode: Word read GetRCode write SetRCode;
  284. property BitCode: Word read FBitCode write SetBitCode;
  285. property QDCount: Word read FQDCount write FQDCount;
  286. property ANCount: Word read FANCount write FANCount;
  287. property NSCount: Word read FNSCount write FNSCount;
  288. property ARCount: Word read FARCount write FARCount;
  289. end;
  290. TIdTextModeResourceRecord = class (TObject)
  291. private
  292. FRRName: string;
  293. FRRDatas: TIdStrings; //TODO Should not be TIdStrings
  294. FTTL: integer;
  295. FTypeCode: integer;
  296. FTimeOut: string;
  297. procedure SetRRDatas(const Value: TIdStrings);
  298. procedure SetTTL(const Value: integer);
  299. public
  300. constructor Create;
  301. destructor Destroy; override;
  302. property TypeCode : integer read FTypeCode write FTypeCode;
  303. property RRName : string read FRRName write FRRName;
  304. property RRDatas : TIdStrings read FRRDatas write SetRRDatas;
  305. property TTL : integer read FTTL write SetTTL;
  306. property TimeOut :string read FTimeOut write FTimeOut;
  307. procedure AddOneParameter(ParameterName, Value : string);
  308. function ifAddFullName(FullName : string; givenName : string= '') : boolean;
  309. function GetValue(ParameterName : string) : string;
  310. function ItemCount : integer;
  311. function BinQueryRecord(FullName : string): TIdBytes; virtual;
  312. function TextRecord(FullName : string) : string; virtual;
  313. end;
  314. TIdTextModeRRs = class (TIdObjectList)
  315. private
  316. FItemNames : TIdStrings;
  317. function GetItem(Index: Integer): TIdTextModeResourceRecord;
  318. procedure SetItem(Index: Integer;
  319. const Value: TIdTextModeResourceRecord);
  320. procedure SetItemNames(const Value: TIdStrings);
  321. public
  322. constructor Create;
  323. destructor Destroy; override;
  324. property ItemNames : TIdStrings read FItemNames write SetItemNames;
  325. property Items[Index: Integer]: TIdTextModeResourceRecord read GetItem write SetItem; default;
  326. end;
  327. TIdRR_CName = class(TIdTextModeResourceRecord)
  328. private
  329. function GetCName: AnsiString;
  330. procedure SetCName(const Value: AnsiString);
  331. public
  332. constructor Create;
  333. property CName : AnsiString read GetCName write SetCName;
  334. function BinQueryRecord(FullName: string): TIdBytes; override;
  335. function TextRecord(FullName : string) : string; override;
  336. end;
  337. TIdRR_HINFO = class(TIdTextModeResourceRecord)
  338. private
  339. procedure SetCPU(const Value: AnsiString);
  340. function GetCPU: AnsiString;
  341. function GetOS: AnsiString;
  342. procedure SetOS(const Value: AnsiString);
  343. public
  344. constructor Create;
  345. property CPU : AnsiString read GetCPU write SetCPU;
  346. property OS : AnsiString read GetOS write SetOS;
  347. function BinQueryRecord(FullName : string): TIdBytes; override;
  348. function TextRecord(FullName : string) : string; override;
  349. end;
  350. TIdRR_MB = class(TIdTextModeResourceRecord)
  351. private
  352. function GetMADName: AnsiString;
  353. procedure SetMADName(const Value: AnsiString);
  354. public
  355. constructor Create;
  356. property MADName : AnsiString read GetMADName write SetMADName;
  357. function BinQueryRecord(FullName : string) : TIdBytes; override;
  358. function TextRecord(FullName : string) : string; override;
  359. end;
  360. TIdRR_MG = class(TIdTextModeResourceRecord)
  361. private
  362. function GetMGMName: AnsiString;
  363. procedure SetMGMName(const Value: AnsiString);
  364. public
  365. constructor Create;
  366. property MGMName : AnsiString read GetMGMName write SetMGMName;
  367. function BinQueryRecord(FullName : string) : TIdBytes; override;
  368. function TextRecord(FullName : string) : string; override;
  369. end;
  370. TIdRR_MINFO = class(TIdTextModeResourceRecord)
  371. private
  372. procedure SetErrorHandle_Mail(const Value: AnsiString);
  373. procedure SetResponsible_Mail(const Value: AnsiString);
  374. function GetEMail: AnsiString;
  375. function GetRMail: AnsiString;
  376. public
  377. constructor Create;
  378. property Responsible_Mail : AnsiString read GetRMail write SetResponsible_Mail;
  379. property ErrorHandle_Mail : AnsiString read GetEMail write SetErrorHandle_Mail;
  380. function BinQueryRecord(FullName : string) : TIdBytes; override;
  381. function TextRecord(FullName : string) : string; override;
  382. end;
  383. TIdRR_MR = class(TIdTextModeResourceRecord)
  384. private
  385. function GetNewName: AnsiString;
  386. procedure SetNewName(const Value: AnsiString);
  387. public
  388. constructor Create;
  389. property NewName : AnsiString read GetNewName write SetNewName;
  390. function BinQueryRecord(FullName : string) : TIdBytes; override;
  391. function TextRecord(FullName : string) : string; override;
  392. end;
  393. TIdRR_MX = class(TIdTextModeResourceRecord)
  394. private
  395. function GetExchang: AnsiString;
  396. procedure SetExchange(const Value: AnsiString);
  397. function GetPref: AnsiString;
  398. procedure SetPref(const Value: AnsiString);
  399. public
  400. constructor Create;
  401. property Exchange : AnsiString read GetExchang write SetExchange;
  402. property Preference : AnsiString read GetPref write SetPref;
  403. function BinQueryRecord(FullName : string) : TIdBytes; override;
  404. function TextRecord(FullName : string) : string; override;
  405. end;
  406. TIdRR_NS = class(TIdTextModeResourceRecord)
  407. private
  408. function GetNS: AnsiString;
  409. procedure SetNS(const Value: AnsiString);
  410. public
  411. constructor Create;
  412. property NSDName : AnsiString read GetNS write SetNS;
  413. function BinQueryRecord(FullName : string): TIdBytes; override;
  414. function TextRecord(FullName : string) : string; override;
  415. end;
  416. TIdRR_PTR = class(TIdTextModeResourceRecord)
  417. private
  418. function GetPTRName: AnsiString;
  419. procedure SetPTRName(const Value: AnsiString);
  420. public
  421. constructor Create;
  422. property PTRDName : AnsiString read GetPTRName write SetPTRName;
  423. function BinQueryRecord(FullName : string): TIdBytes; override;
  424. function TextRecord(FullName : string) : string; override;
  425. end;
  426. TIdRR_SOA = class(TIdTextModeResourceRecord)
  427. private
  428. function GetName(CLabel : string):AnsiString;
  429. procedure SetName(CLabel, Value : AnsiString);
  430. function GetMName: AnsiString;
  431. function GetRName: AnsiString;
  432. procedure SetMName(const Value: AnsiString);
  433. procedure SetRName(const Value: AnsiString);
  434. function GetMin: AnsiString;
  435. function GetRefresh: AnsiString;
  436. function GetRetry: AnsiString;
  437. function GetSerial: AnsiString;
  438. procedure SetMin(const Value: AnsiString);
  439. procedure SetRefresh(const Value: AnsiString);
  440. procedure SetRetry(const Value: AnsiString);
  441. procedure SetSerial(const Value: AnsiString);
  442. function GetExpire: AnsiString;
  443. procedure SetExpire(const Value: AnsiString);
  444. public
  445. constructor Create;
  446. property MName : AnsiString read GetMName write SetMName;
  447. property RName : AnsiString read GetRName write SetRName;
  448. property Serial : AnsiString read GetSerial write SetSerial;
  449. property Refresh : AnsiString read GetRefresh write SetRefresh;
  450. property Retry : AnsiString read GetRetry write SetRetry;
  451. property Expire : AnsiString read GetExpire write SetExpire;
  452. property Minimum : AnsiString read GetMin write SetMin;
  453. function BinQueryRecord(FullName : string) : TIdBytes; override;
  454. function TextRecord(FullName : string) : string; override;
  455. end;
  456. TIdRR_A = class(TIdTextModeResourceRecord)
  457. private
  458. function GetA: AnsiString;
  459. procedure SetA(const Value: AnsiString);
  460. public
  461. constructor Create;
  462. property Address : AnsiString read GetA write SetA;
  463. function BinQueryRecord(FullName : string) : TIdBytes; override;
  464. function TextRecord(FullName : string) : string; override;
  465. end;
  466. TIdRR_AAAA = class(TIdTextModeResourceRecord)
  467. private
  468. function GetA: AnsiString;
  469. procedure SetA(const Value: AnsiString);
  470. public
  471. constructor Create;
  472. property Address : AnsiString read GetA write SetA;
  473. function BinQueryRecord(FullName : string) : TIdBytes; override;
  474. function TextRecord(FullName : string) : string; override;
  475. end;
  476. { TODO : implement WKS record class }
  477. TIdRR_WKS = class(TIdTextModeResourceRecord)
  478. public
  479. constructor Create;
  480. end;
  481. TIdRR_TXT = class(TIdTextModeResourceRecord)
  482. private
  483. function GetTXT: AnsiString;
  484. procedure SetTXT(const Value: AnsiString);
  485. public
  486. constructor Create;
  487. property TXT : AnsiString read GetTXT write SetTXT;
  488. function BinQueryRecord(FullName : string) : TIdBytes; override;
  489. function TextRecord(FullName : string) : string; override;
  490. end;
  491. TIdRR_Error = class(TIdTextModeResourceRecord)
  492. public
  493. constructor Create;
  494. end;
  495. function DomainNameToDNSStr(ADomain : String): TIdBytes;
  496. function NormalStrToDNSStr(Str : String): TIdBytes;
  497. function IPAddrToDNSStr(IPAddress : String): TIdBytes;
  498. function IsValidIPv6(v6Address : String): boolean;
  499. function ConvertToVaildv6IP(OrgIP : String) : string;
  500. function ConvertToCanonical6IP(OrgIP : String) : string;
  501. function IPv6AAAAToDNSStr(IPv6Address : String): TIdBytes;
  502. function GetErrorStr(Code, Id :Integer): String;
  503. function GetRCodeStr(RCode : Integer): String;
  504. function ReplaceSpecString(Source, Target, NewString : string; ReplaceAll : boolean = True) : string;
  505. function IsBig5(ch1, ch2:char) : boolean;
  506. implementation
  507. uses
  508. IdGlobalProtocols,
  509. IdStack,
  510. SysUtils;
  511. function DomainNameToDNSStr(ADomain : String): TIdBytes;
  512. var
  513. BufStr : String;
  514. aPos : Integer;
  515. begin { DomainNameToDNSStr }
  516. SetLength(Result, 0);
  517. while Length(ADomain) > 0 do
  518. begin
  519. aPos := Pos ( '.', ADomain ); {do not localize}
  520. if aPos = 0 then
  521. begin
  522. aPos := Length(ADomain) + 1;
  523. end; //if aPos = 0 then
  524. BufStr := Copy(ADomain, 1, aPos - 1);
  525. Delete(ADomain, 1, aPos);
  526. AppendByte(Result, Length (BufStr));
  527. AppendBytes(Result, ToBytes(BufStr));
  528. end;
  529. if Length(Result) > 0 then
  530. AppendByte(Result, 0);
  531. end;
  532. function NormalStrToDNSStr(Str : String): TIdBytes;
  533. var
  534. LLen: Byte;
  535. begin
  536. LLen := Length(Str);
  537. SetLength(Result, 1 + LLen);
  538. Result[0] := LLen;
  539. CopyTIdBytes(ToBytes(Str), 0, Result, 1, LLen);
  540. //AppendBytes(Result, ToBytes(Str));
  541. //Result := Chr(Length(Str)) + Str;
  542. end;
  543. function IPAddrToDNSStr(IPAddress : String): TIdBytes;
  544. Var
  545. j, i: Integer;
  546. s : string;
  547. ret : boolean;
  548. begin
  549. SetLength(Result, 0);
  550. if IsValidIP(IPAddress) then
  551. begin
  552. s := Trim(IPAddress);
  553. ret := True;
  554. for i := 1 to 4 do
  555. begin
  556. j := StrToIntDef(Fetch(IPAddress, '.'), -1); {do not localize}
  557. ret := ret and (j > -1) and (j < 256);
  558. if not ret then
  559. begin
  560. Result := ToBytes('Error IP'); {do not localize}
  561. break;
  562. end else
  563. AppendByte(Result, j);
  564. end;
  565. end else
  566. Result := ToBytes('Error IP'); {do not localize}
  567. end;
  568. function IdHexToBin(Text, Buffer: TIdBytes; BufSize: Integer): Integer;
  569. const
  570. Convert: array['0'..'f'] of SmallInt = {do not localize}
  571. ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,
  572. -1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  573. -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  574. -1,10,11,12,13,14,15);
  575. var
  576. I: Integer;
  577. s: string;
  578. BufferPos, TextPos: Integer;
  579. begin
  580. I := BufSize;
  581. BufferPos := 0;
  582. TextPos := 0;
  583. s := BytesToString(Text);
  584. while I > 0 do begin
  585. if not CharIsInSet(s, TextPos, ['0'..'9', 'a'..'f', 'A'..'F']) then begin
  586. Break; {do not localize}
  587. end;
  588. Buffer[BufferPos] := (Convert[char(Text[TextPos])] shl 4) + Convert[char(Text[TextPos + 1])];
  589. Inc(BufferPos);
  590. Inc(TextPos, 2);
  591. Dec(I);
  592. end;
  593. Result := BufSize - I;
  594. end;
  595. function IPv6AAAAToDNSStr(IPv6Address : String): TIdBytes;
  596. var
  597. TempAddr, Selected : string;
  598. TempMem : TIdBytes;
  599. //array [0..15] of char;
  600. TempOrg : TIdBytes;
  601. //array [0..31] of char;
  602. //PRet, Porg : PChar;
  603. Count : integer;
  604. begin
  605. SetLength(Result, 0);
  606. TempAddr := IPv6Address;
  607. repeat
  608. Selected := Fetch(TempAddr, ':'); {do not localize}
  609. AppendBytes(Result, ToBytes(Selected));
  610. until TempAddr = ''; {do not localize}
  611. SetLength(TempMem, 16);
  612. SetLength(TempOrg, 32);
  613. {Porg := @TempOrg[0];
  614. StrPCopy(Porg, Result);
  615. PRet := @TempMem[0];}
  616. IdHexToBin(Result, TempMem, 16);
  617. SetLength(Result, 0);
  618. for Count := 0 to 15 do
  619. begin
  620. if TempMem[Count] <> 0 then
  621. AppendByte(Result, TempMem[Count])
  622. //Result := Result + Copy(TempMem[Count], 1, 1)
  623. else
  624. AppendByte(Result, 0);
  625. end;
  626. end;
  627. function IsValidIPv6(v6Address : String): boolean;
  628. var
  629. Temps : TIdStrings;
  630. Apart, All: String;
  631. Count, Loc, Goal : integer;
  632. begin
  633. All := v6Address;
  634. Temps := TIdStringList.Create;
  635. try
  636. // Check Double Colon existence, but only single.
  637. Count := 0;
  638. repeat
  639. Loc := Pos('::', All); {do not localize}
  640. if Loc > 0 then
  641. begin
  642. Count := Count + 1;
  643. Delete(All, Loc, 2);
  644. end;
  645. until Loc = 0;
  646. if Count <= 1 then
  647. begin
  648. All := v6Address;
  649. // Convert Double colon into compatible format.
  650. All := ReplaceSpecString(All, '::', ':Multi:'); {do not localize}
  651. repeat
  652. Apart := Fetch(All, ':'); {do not localize}
  653. Temps.Add(Apart);
  654. until (All = ''); {do not localize}
  655. Loc := Temps.IndexOf('Multi'); {do not localize}
  656. if Loc > -1 then
  657. begin
  658. Goal := 8 - Temps.Count;
  659. Temps.Strings[Loc] := '0000'; {do not localize}
  660. for Count := 0 to Goal -1 do
  661. begin
  662. Temps.Insert(Loc, '0000'); {do not localize}
  663. end;
  664. if Temps.Strings[0] = '' then {do not localize}
  665. Temps.Strings[0] := '0000'; {do not localize}
  666. end;
  667. All := Temps.CommaText;
  668. All := ReplaceSpecString(All, ',', ':'); {do not localize}
  669. Result := True;
  670. Temps.Clear;
  671. repeat
  672. Apart := Trim(Fetch(All, ':')); {do not localize}
  673. if Length(Apart) <= 4 then
  674. begin
  675. Apart := '0000' + Apart; {do not localize}
  676. Apart := Copy(Apart, Length(Apart)-3, 4);
  677. Temps.Add(Apart);
  678. end else
  679. begin
  680. Result := False;
  681. end;
  682. until (All = '') or (not Result); {do not localize}
  683. if (not Result) or (Temps.Count > 8) then
  684. begin
  685. Result := False;
  686. end else
  687. begin
  688. for Count := 0 to Temps.Count -1 do
  689. begin
  690. All := All + Temps.Strings[Count];
  691. end;
  692. Result := Length(All) > 0;
  693. for Count := 1 to Length(All) do
  694. begin
  695. if not Result then begin
  696. Break;
  697. end;
  698. Result := Result and CharIsInSet(All, Count, ['0'..'9', 'A'..'F', 'a'..'f']); {do not localize}
  699. end;
  700. end;
  701. end else
  702. begin
  703. // mulitple Double colon, it's an incorrect IPv6 address.
  704. Result := False;
  705. end;
  706. finally
  707. Temps.Free;
  708. end;
  709. end;
  710. function ConvertToVaildv6IP(OrgIP : String) : string;
  711. var
  712. All, Apart : string;
  713. Temps : TIdStrings;
  714. Count, Loc, Goal : integer;
  715. begin
  716. All := OrgIP;
  717. Temps := TIdStringList.Create;
  718. // Check Double Colon existence, but only single.
  719. // Count := 0;
  720. repeat
  721. Loc := Pos('::', All); {do not localize}
  722. if Loc > 0 then begin
  723. // Count := Count + 1;
  724. Delete(All, Loc, 2);
  725. end;
  726. until Loc = 0;
  727. All := OrgIP;
  728. // Convert Double colon into compatible format.
  729. All := ReplaceSpecString(All, '::', ':Multi:'); {do not localize}
  730. repeat
  731. Apart := Fetch(All, ':'); {do not localize}
  732. Temps.Add(Apart);
  733. until (All = ''); {do not localize}
  734. Loc := Temps.IndexOf('Multi'); {do not localize}
  735. if Loc > -1 then begin
  736. Goal := 8 - Temps.Count;
  737. Temps.Strings[Loc] := '0000'; {do not localize}
  738. for Count := 0 to Goal -1 do begin
  739. Temps.Insert(Loc, '0000'); {do not localize}
  740. end;
  741. if Temps.Strings[0] = '' then Temps.Strings[0] := '0000'; {do not localize}
  742. end;
  743. All := Temps.CommaText;
  744. All := ReplaceSpecString(All, ',', ':'); {do not localize}
  745. Temps.Free;
  746. Result := All;
  747. end;
  748. function ConvertToCanonical6IP(OrgIP : String) : string;
  749. var
  750. All, Apart: string;
  751. begin
  752. {Supposed OrgIp is valid IPV6 string}
  753. All := ConvertToVaildv6IP(OrgIp);
  754. Result := ''; {do not localize}
  755. repeat
  756. Apart := Trim(Fetch(All, ':')); {do not localize}
  757. if Length(Apart) < 4 then
  758. begin
  759. Apart := '0000' + Apart; {do not localize}
  760. Apart := Copy(Apart, Length(Apart)-3, 4);
  761. end;
  762. Result := Result + Apart + ':'; {do not localize}
  763. until (All = ''); {do not localize}
  764. SetLength(Result, Length(Result) - 1); //Remove last :
  765. end;
  766. { TODO : Move these to member }
  767. function GetErrorStr(Code, Id :Integer): String;
  768. begin
  769. case code Of
  770. 1 : Result := Format ( RSQueryInvalidQueryCount, [ Id ] );
  771. 2 : Result := Format ( RSQueryInvalidPacketSize, [ Id ] );
  772. 3 : Result := Format ( RSQueryLessThanFour, [ Id ] );
  773. 4 : Result := Format ( RSQueryInvalidHeaderID, [ Id ] );
  774. 5 : Result := Format ( RSQueryLessThanTwelve, [ Id ] );
  775. 6 : Result := Format ( RSQueryPackReceivedTooSmall, [Id] );
  776. end; //case code Of
  777. end;
  778. function GetRCodeStr(RCode : Integer): String;
  779. begin
  780. if Rcode in [cRCodeNoError..cRCodeRefused] then
  781. begin
  782. Result := cRCodeStrs[Rcode];
  783. end // if Rcode in [cRCodeNoError..cRCodeRefused] then
  784. else
  785. begin
  786. Result := RSCodeQueryUnknownError;
  787. end; //else.. if Rcode in [cRCodeNoError..cRCodeRefused] then
  788. end;
  789. { TDNSHeader }
  790. procedure TDNSHeader.ClearByteCode;
  791. begin
  792. FBitCode := 0;
  793. end;
  794. constructor TDNSHeader.Create;
  795. begin
  796. inherited;
  797. Randomize;
  798. FId := Random(65535);
  799. end;
  800. function TDNSHeader.GenerateBinaryHeader: TIdBytes;
  801. {
  802. The header contains the following fields:
  803. 1 1 1 1 1 1
  804. 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
  805. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  806. | ID |
  807. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  808. |QR| Opcode |AA|TC|RD|RA| Z | RCODE |
  809. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  810. | QDCOUNT |
  811. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  812. | ANCOUNT |
  813. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  814. | NSCOUNT |
  815. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  816. | ARCOUNT |
  817. +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  818. where:
  819. ID A 16 bit identifier assigned by the program that
  820. generates any kind of query. This identifier is copied
  821. the corresponding reply and can be used by the requester
  822. to match up replies to outstanding queries.
  823. QR A one bit field that specifies whether this message is a
  824. query (0), or a response (1).
  825. OPCODE A four bit field that specifies kind of query in this
  826. message. This value is set by the originator of a query
  827. and copied into the response. The values are:
  828. 0 a standard query (QUERY)
  829. 1 an inverse query (IQUERY)
  830. 2 a server status request (STATUS)
  831. 3-15 reserved for future use
  832. AA Authoritative Answer - this bit is valid in responses,
  833. and specifies that the responding name server is an
  834. authority for the domain name in question section.
  835. Note that the contents of the answer section may have
  836. multiple owner names because of aliases. The AA bit
  837. corresponds to the name which matches the query name, or
  838. the first owner name in the answer section.
  839. TC TrunCation - specifies that this message was truncated
  840. due to length greater than that permitted on the
  841. transmission channel.
  842. RD Recursion Desired - this bit may be set in a query and
  843. is copied into the response. If RD is set, it directs
  844. the name server to pursue the query recursively.
  845. Recursive query support is optional.
  846. RA Recursion Available - this be is set or cleared in a
  847. response, and denotes whether recursive query support is
  848. available in the name server.
  849. Z Reserved for future use. Must be zero in all queries
  850. and responses.
  851. RCODE Response code - this 4 bit field is set as part of
  852. responses. The values have the following
  853. interpretation:
  854. 0 No error condition
  855. 1 Format error - The name server was
  856. unable to interpret the query.
  857. 2 Server failure - The name server was
  858. unable to process this query due to a
  859. problem with the name server.
  860. 3 Name Error - Meaningful only for
  861. responses from an authoritative name
  862. server, this code signifies that the
  863. domain name referenced in the query does
  864. not exist.
  865. 4 Not Implemented - The name server does
  866. not support the requested kind of query.
  867. 5 Refused - The name server refuses to
  868. perform the specified operation for
  869. policy reasons. For example, a name
  870. server may not wish to provide the
  871. information to the particular requester,
  872. or a name server may not wish to perform
  873. a particular operation (e.g., zone
  874. transfer) for particular data.
  875. 6-15 Reserved for future use.
  876. QDCOUNT an unsigned 16 bit integer specifying the number of
  877. entries in the question section.
  878. ANCOUNT an unsigned 16 bit integer specifying the number of
  879. resource records in the answer section.
  880. NSCOUNT an unsigned 16 bit integer specifying the number of name
  881. server resource records in the authority records
  882. section.
  883. ARCOUNT an unsigned 16 bit integer specifying the number of
  884. resource records in the additional records section.
  885. }
  886. begin
  887. SetLength(Result, 12);
  888. WordToTwoBytes(GStack.HostToNetwork( Self.ID), Result, 0);
  889. //strip off reserved bits
  890. BitCode := BitCode and $F1FF; //E00
  891. WordToTwoBytes(GStack.HostToNetwork(Self.BitCode), Result, 2);
  892. WordToTwoBytes(GStack.HostToNetwork(Self.QDCount), Result, 4);
  893. WordToTwoBytes(GStack.HostToNetwork(Self.ANCount), Result, 6);
  894. WordToTwoBytes(GStack.HostToNetwork(Self.NSCount), Result, 8);
  895. WordToTwoBytes(GStack.HostToNetwork(Self.ARCount), Result, 10);
  896. end;
  897. function TDNSHeader.GetAA: Word;
  898. begin
  899. Result := (FBitCode and $0700) shr 10;
  900. end;
  901. function TDNSHeader.GetOpCode: Word;
  902. begin
  903. Result := ((FBitCode and $7800) shr 11) and $000F;
  904. end;
  905. function TDNSHeader.GetQr: Word;
  906. begin
  907. Result := FBitCode shr 15;
  908. end;
  909. function TDNSHeader.GetRA: Word;
  910. begin
  911. Result := (FBitCode and $0800) shr 7;
  912. end;
  913. function TDNSHeader.GetRCode: Word;
  914. begin
  915. Result := FBitCode and $000F;
  916. end;
  917. function TDNSHeader.GetRD: Word;
  918. begin
  919. Result := (FBitCode and $0100) shr 8;
  920. end;
  921. function TDNSHeader.GetTC: Word;
  922. begin
  923. Result := (FBitCode and $0200) shr 9;
  924. end;
  925. function TDNSHeader.ParseQuery(Data: TIdBytes): integer;
  926. begin
  927. if Length(Data) >= 12 then
  928. try
  929. Self.ID := GStack.NetworkToHost(TwoByteToWord(Data[0],Data[1]));
  930. Self.BitCode := GStack.NetworkToHost(TwoByteToWord(Data[2], Data[3]));
  931. Self.QDCount := GStack.NetworkToHost(TwoByteToWord(Data[4], Data[5]));
  932. Self.ANCount := GStack.NetworkToHost(TwoByteToWord(Data[6], Data[7]));
  933. Self.NSCount := GStack.NetworkToHost(TwoByteToWord(Data[8], Data[9]));
  934. Self.ARCount := GStack.NetworkToHost(TwoByteToWord(Data[10], Data[11]));
  935. Result := 0;
  936. except
  937. Result := -1;
  938. end
  939. else
  940. Result := -1;
  941. end;
  942. procedure TDNSHeader.SetAA(const Value: Word);
  943. begin
  944. if Value = 0 then begin
  945. // FBitCode := FBitCode and $FBFF;
  946. FBitCode := FBitCode and $FFDF;
  947. end else begin
  948. FBitCode := FBitCode or $0020;
  949. // FBitCode := FBitCode or $0400;
  950. end;
  951. end;
  952. procedure TDNSHeader.SetBitCode(const Value: Word);
  953. begin
  954. FBitCode := Value;
  955. end;
  956. procedure TDNSHeader.SetOpCode(const Value: Word);
  957. begin
  958. case Value of // $1E should mask the bits
  959. 0: FBitCode := FBitCode and $FFE1;
  960. //FBitCode := FBitCode and $87FF;
  961. 1: FBitCode := (FBitCode and $FFE1) or $0002;
  962. //FBitCode := FBitCode and $8FFF;
  963. 2: FBitCode := (FBitCode and $FFE1) or $0004;
  964. //FBitCode := FBitCode and $4BFF;
  965. end;
  966. end;
  967. procedure TDNSHeader.SetQr(const Value: Word);
  968. begin
  969. if Value = 0 then begin
  970. FBitCode := FBitCode and $FFFE;
  971. // FBitCode := FBitCode and $EFFF;
  972. end else begin
  973. FBitCode := FBitCode or $0001;
  974. // FBitCode := FBitCode or $8000;
  975. end;
  976. end;
  977. procedure TDNSHeader.SetRA(const Value: Word);
  978. begin
  979. if Value = 0 then begin
  980. // FBitCode := FBitCode and $FF7F;
  981. FBitCode := FBitCode or $FEFF;
  982. end else begin
  983. FBitCode := FBitCode or $100;
  984. // FBitCode := FBitCode or $0080;
  985. end;
  986. end;
  987. procedure TDNSHeader.SetRCode(const Value: Word);
  988. begin
  989. FBitCode := (FBitCode and $FFF0) or (Value and $000F);
  990. end;
  991. procedure TDNSHeader.SetRD(const Value: Word);
  992. begin
  993. if Value = 0 then begin
  994. FBitCode := FBitCode and $FEFFF;
  995. end else begin
  996. FBitCode := FBitCode or $0100;
  997. end;
  998. end;
  999. procedure TDNSHeader.SetTC(const Value: Word);
  1000. begin
  1001. if Value = 0 then begin
  1002. FBitCode := FBitCode and $FDFF;
  1003. end else begin
  1004. FBitCode := FBitCode or $0200;
  1005. end;
  1006. end;
  1007. { TIdTextModeResourceRecord }
  1008. procedure TIdTextModeResourceRecord.AddOneParameter(ParameterName,
  1009. Value: string);
  1010. begin
  1011. Self.RRDatas.Values[ParameterName] := Value;
  1012. end;
  1013. function TIdTextModeResourceRecord.BinQueryRecord(
  1014. FullName: string): TIdBytes;
  1015. begin
  1016. // This was empty? Where did it go?
  1017. todo;
  1018. Result := nil;
  1019. end;
  1020. constructor TIdTextModeResourceRecord.Create;
  1021. begin
  1022. inherited;
  1023. Self.FRRDatas := TIdStringList.Create;
  1024. Self.TTL := 0;
  1025. end;
  1026. destructor TIdTextModeResourceRecord.Destroy;
  1027. begin
  1028. Self.FRRDatas.Free;
  1029. inherited;
  1030. end;
  1031. function TIdTextModeResourceRecord.GetValue(ParameterName: string): string;
  1032. begin
  1033. Result := Self.RRDatas.Values[ParameterName];
  1034. end;
  1035. function TIdTextModeResourceRecord.ifAddFullName(FullName,
  1036. givenName: string): boolean;
  1037. var
  1038. TailString, BackString, Destination : string;
  1039. LTS, LRR : integer;
  1040. TailwithDot : boolean;
  1041. begin
  1042. if givenName = '' then begin
  1043. Destination := Self.RRName;
  1044. end else begin
  1045. Destination := givenName;
  1046. end;
  1047. TailwithDot := Copy(Destination, Length(Destination),1) = '.';
  1048. if TailwithDot then begin
  1049. Result := False;
  1050. end else begin
  1051. if Copy(FullName, Length(FullName),1) = '.' then begin
  1052. TailString := Copy(FullName, 1, Length(FullName) - 1);
  1053. end else begin
  1054. TailString := FullName;
  1055. end;
  1056. LTS := Length(TailString);
  1057. LRR := Length(Destination);
  1058. if LRR >= LTS then begin
  1059. BackString := Copy(Destination, LRR - LTS + 1 , LTS);
  1060. Result := not (BackString = TailString);
  1061. end else begin
  1062. Result := True;
  1063. end;
  1064. end;
  1065. end;
  1066. function TIdTextModeResourceRecord.ItemCount: integer;
  1067. begin
  1068. Result := Self.RRDatas.Count;
  1069. end;
  1070. procedure TIdTextModeResourceRecord.SetRRDatas(const Value: TIdStrings);
  1071. begin
  1072. FRRDatas.Assign(Value);
  1073. end;
  1074. procedure TIdTextModeResourceRecord.SetTTL(const Value: integer);
  1075. var
  1076. TM : TTimeStamp;
  1077. begin
  1078. FTTL := Value;
  1079. TM := DateTimeToTimeStamp(Now);
  1080. TM.Time := TM.Time + (Value * 1000);
  1081. Self.FTimeOut := DateTimeToStr(TimeStampToDateTime(TM));
  1082. end;
  1083. function TIdTextModeResourceRecord.TextRecord(FullName: string): string;
  1084. begin
  1085. end;
  1086. { TIdTextModeRRs }
  1087. constructor TIdTextModeRRs.Create;
  1088. begin
  1089. inherited Create;
  1090. Self.FItemNames := TIdStringList.Create;
  1091. end;
  1092. destructor TIdTextModeRRs.Destroy;
  1093. begin
  1094. Self.FItemNames.Free;
  1095. inherited;
  1096. end;
  1097. function TIdTextModeRRs.GetItem(Index: Integer): TIdTextModeResourceRecord;
  1098. begin
  1099. Result := TIdTextModeResourceRecord(inherited GetItem(Index));
  1100. end;
  1101. procedure TIdTextModeRRs.SetItem(Index: Integer;
  1102. const Value: TIdTextModeResourceRecord);
  1103. begin
  1104. inherited SetItem(Index, Value);
  1105. end;
  1106. procedure TIdTextModeRRs.SetItemNames(const Value: TIdStrings);
  1107. begin
  1108. FItemNames.Assign(Value);
  1109. end;
  1110. { TIdRR_CName }
  1111. function TIdRR_CName.BinQueryRecord(FullName: string): TIdBytes;
  1112. var
  1113. QName: string;
  1114. RRData: TIdBytes;
  1115. begin
  1116. SetLength(Result, 0);
  1117. if Copy(Self.RRName, Length(Self.RRName), 1) <> '.' then begin
  1118. QName := Self.RRName + '.' + FullName;
  1119. end else begin
  1120. QName := Self.RRName;
  1121. end;
  1122. RRData := DomainNameToDNSStr((Self.CName));
  1123. Result := DomainNameToDNSStr((QName));
  1124. AppendBytes(Result, ToBytes(SmallInt(TypeCode_CName)));
  1125. AppendBytes(Result, ToBytes(SmallInt(Class_IN)));
  1126. AppendBytes(Result, ToBytes(Self.TTL));
  1127. AppendBytes(Result, ToBytes(SmallInt(Length(RRData))));
  1128. AppendBytes(Result, RRData);
  1129. end;
  1130. constructor TIdRR_CName.Create;
  1131. begin
  1132. inherited;
  1133. Self.RRName := 'CName'; {do not localize}
  1134. Self.CName := '';
  1135. Self.TypeCode := TypeCode_CName;
  1136. end;
  1137. function TIdRR_CName.GetCName: AnsiString;
  1138. begin
  1139. Result := Self.GetValue('CName'); {do not localize}
  1140. end;
  1141. procedure TIdRR_CName.SetCName(const Value: AnsiString);
  1142. begin
  1143. Self.RRDatas.Values['CName'] := Value; {do not localize}
  1144. end;
  1145. function TIdRR_CName.TextRecord(FullName: string): string;
  1146. var
  1147. QName: string;
  1148. begin
  1149. Result := '';
  1150. QName := Self.RRName + '.';
  1151. if QName <> FullName then begin
  1152. if Copy(Self.RRName, Length(Self.RRName),1) <> '.' then begin
  1153. QName := Self.RRName + '.' + FullName;
  1154. end else begin
  1155. QName := Self.RRName;
  1156. end;
  1157. end;
  1158. if QName = FullName then QName := '@';
  1159. Result := QName + Chr(9) + 'IN' + Chr(9) + 'CNAME' + Chr(9) + Self.CName + #13+#10; {do not localize}
  1160. end;
  1161. { TIdRR_HINFO }
  1162. function TIdRR_HINFO.BinQueryRecord(FullName: string): TIdBytes;
  1163. var
  1164. QName: string;
  1165. RRData: TIdBytes;
  1166. begin
  1167. SetLength(Result, 0);
  1168. if Copy(Self.RRName, Length(Self.RRName), 1) <> '.' then
  1169. begin
  1170. QName := Self.RRName + '.' + FullName;
  1171. end else
  1172. begin
  1173. QName := Self.RRName;
  1174. end;
  1175. RRData := NormalStrToDNSStr(Self.CPU);
  1176. AppendBytes(RRData, NormalStrToDNSStr(Self.OS));
  1177. Result := DomainNameToDNSStr((QName));
  1178. AppendBytes(Result, ToBytes(SmallInt(TypeCode_HINFO)));
  1179. AppendBytes(Result, ToBytes(SmallInt(Class_IN)));
  1180. AppendBytes(Result, ToBytes(Self.TTL));
  1181. AppendBytes(Result, ToBytes(integer(Length(RRData))));
  1182. AppendBytes(Result, RRData);
  1183. end;
  1184. constructor TIdRR_HINFO.Create;
  1185. begin
  1186. inherited;
  1187. Self.RRName := 'HINFO'; {do not localize}
  1188. Self.CPU := '';
  1189. Self.OS := '';
  1190. Self.TypeCode := TypeCode_HINFO;
  1191. end;
  1192. function TIdRR_HINFO.GetCPU: AnsiString;
  1193. begin
  1194. Result := Self.RRDatas.Values['CPU']; {do not localize}
  1195. end;
  1196. function TIdRR_HINFO.GetOS: AnsiString;
  1197. begin
  1198. Result := Self.RRDatas.Values['OS']; {do not localize}
  1199. end;
  1200. procedure TIdRR_HINFO.SetCPU(const Value: AnsiString);
  1201. begin
  1202. Self.RRDatas.Values['CPU'] := Value; {do not localize}
  1203. end;
  1204. procedure TIdRR_HINFO.SetOS(const Value: AnsiString);
  1205. begin
  1206. Self.RRDatas.Values['OS'] := Value; {do not localize}
  1207. end;
  1208. function TIdRR_HINFO.TextRecord(FullName: string): string;
  1209. var
  1210. QName: string;
  1211. begin
  1212. Result := '';
  1213. QName := Self.RRName + '.';
  1214. if QName <> FullName then begin
  1215. if Copy(Self.RRName, Length(Self.RRName),1) <> '.' then begin
  1216. QName := Self.RRName + '.' + FullName;
  1217. end else begin
  1218. QName := Self.RRName;
  1219. end;
  1220. end;
  1221. if QName = FullName then QName := '@';
  1222. Result := QName + Chr(9) + 'IN' + Chr(9) + 'HINFO' + Chr(9) + '"' + Self.CPU + '" "' + Self.OS + '"' + #13+#10; {do not localize}
  1223. end;
  1224. { TIdRR_MB }
  1225. function TIdRR_MB.BinQueryRecord(FullName: string): TIdBytes;
  1226. var
  1227. QName: string;
  1228. RRData: TIdBytes;
  1229. begin
  1230. SetLength(Result, 0);
  1231. if Copy(Self.RRName, Length(Self.RRName),1) <> '.' then begin
  1232. QName := Self.RRName + '.' + FullName;
  1233. end else begin
  1234. QName := Self.RRName;
  1235. end;
  1236. RRData := DomainNameToDNSStr((Self.MADName));
  1237. Result := DomainNameToDNSStr((QName));
  1238. AppendBytes(Result, ToBytes(SmallInt(TypeCode_MB)));
  1239. AppendBytes(Result, ToBytes(SmallInt(Class_IN)));
  1240. AppendBytes(Result, ToBytes((Self.TTL)));
  1241. AppendBytes(Result, ToBytes((Length(RRData))));
  1242. AppendBytes(Result, RRData);
  1243. end;
  1244. constructor TIdRR_MB.Create;
  1245. begin
  1246. inherited;
  1247. Self.RRName := 'MB'; {do not localize}
  1248. Self.MADName := '';
  1249. Self.TypeCode := TypeCode_MB;
  1250. end;
  1251. function TIdRR_MB.GetMADName: AnsiString;
  1252. begin
  1253. Result := Self.RRDatas.Values['MADNAME']; {do not localize}
  1254. end;
  1255. procedure TIdRR_MB.SetMADName(const Value: AnsiString);
  1256. begin
  1257. Self.RRDatas.Values['MADNAME'] := Value; {do not localize}
  1258. end;
  1259. function TIdRR_MB.TextRecord(FullName: string): string;
  1260. var
  1261. QName: string;
  1262. begin
  1263. Result := '';
  1264. QName := Self.RRName + '.';
  1265. if QName <> FullName then begin
  1266. if Copy(Self.RRName, Length(Self.RRName),1) <> '.' then begin
  1267. QName := Self.RRName + '.' + FullName;
  1268. end else begin
  1269. QName := Self.RRName;
  1270. end;
  1271. end;
  1272. if QName = FullName then QName := '@';
  1273. Result := QName + Chr(9) + 'IN' + Chr(9) + 'MB' + Chr(9) + Self.MADName + #13+#10; {do not localize}
  1274. end;
  1275. { TIdRR_MG }
  1276. function TIdRR_MG.BinQueryRecord(FullName: string): TIdBytes;
  1277. var
  1278. QName: string;
  1279. RRData: TIdBytes;
  1280. begin
  1281. SetLength(Result, 0);
  1282. if Copy(Self.RRName, Length(Self.RRName),1) <> '.' then begin
  1283. QName := Self.RRName + '.' + FullName;
  1284. end else begin
  1285. QName := Self.RRName;
  1286. end;
  1287. RRData := DomainNameToDNSStr((Self.MGMName));
  1288. Result := DomainNameToDNSStr((QName));
  1289. AppendBytes(Result, ToBytes(SmallInt((TypeCode_MG))));
  1290. AppendBytes(Result, ToBytes(SmallInt(Class_IN)));
  1291. AppendBytes(Result, ToBytes((Self.TTL)));
  1292. AppendBytes(Result, ToBytes((Length(RRData))));
  1293. AppendBytes(Result, RRData);
  1294. end;
  1295. constructor TIdRR_MG.Create;
  1296. begin
  1297. inherited;
  1298. Self.RRName := 'MG'; {do not localize}
  1299. Self.MGMName := '';
  1300. Self.TypeCode := TypeCode_MG;
  1301. end;
  1302. function TIdRR_MG.GetMGMName: AnsiString;
  1303. begin
  1304. Result := Self.RRDatas.Values['MGMNAME']; {do not localize}
  1305. end;
  1306. procedure TIdRR_MG.SetMGMName(const Value: AnsiString);
  1307. begin
  1308. Self.RRDatas.Values['MGMNAME'] := Value; {do not localize}
  1309. end;
  1310. function TIdRR_MG.TextRecord(FullName: string): string;
  1311. var
  1312. QName: string;
  1313. begin
  1314. Result := '';
  1315. QName := Self.RRName + '.';
  1316. if QName <> FullName then begin
  1317. if Copy(Self.RRName, Length(Self.RRName),1) <> '.' then begin
  1318. QName := Self.RRName + '.' + FullName;
  1319. end else begin
  1320. QName := Self.RRName;
  1321. end;
  1322. end;
  1323. if QName = FullName then QName := '@';
  1324. Result := QName + Chr(9) + 'IN' + Chr(9) + 'MG' + Chr(9) + Self.MGMName + #13+#10; {do not localize}
  1325. end;
  1326. { TIdRR_MINFO }
  1327. function TIdRR_MINFO.BinQueryRecord(FullName: string): TIdBytes;
  1328. var
  1329. QName: string;
  1330. RRData: TIdBytes;
  1331. begin
  1332. SetLength(Result, 0);
  1333. if Copy(Self.RRName, Length(Self.RRName),1) <> '.' then begin
  1334. QName := Self.RRName + '.' + FullName;
  1335. end else begin
  1336. QName := Self.RRName;
  1337. end;
  1338. RRData := DomainNameToDNSStr((Self.Responsible_Mail));
  1339. RRData := DomainNameToDNSStr((Self.ErrorHandle_Mail));
  1340. Result := DomainNameToDNSStr((QName));
  1341. AppendBytes(Result, ToBytes(SmallInt(TypeCode_MINFO)));
  1342. AppendBytes(Result, ToBytes(SmallInt(Class_IN)));
  1343. AppendBytes(Result, ToBytes((Self.TTL)));
  1344. AppendBytes(Result, ToBytes((Length(RRData))));
  1345. AppendBytes(Result, RRData);
  1346. end;
  1347. constructor TIdRR_MINFO.Create;
  1348. begin
  1349. inherited;
  1350. Self.RRName := 'MINFO'; {do not localize}
  1351. Self.Responsible_Mail := '';
  1352. Self.ErrorHandle_Mail := '';
  1353. Self.TypeCode := TypeCode_MINFO;
  1354. end;
  1355. function TIdRR_MINFO.GetEMail: AnsiString;
  1356. begin
  1357. Result := Self.RRDatas.Values['EMAILBX']; {do not localize}
  1358. end;
  1359. function TIdRR_MINFO.GetRMail: AnsiString;
  1360. begin
  1361. Result := Self.RRDatas.Values['RMAILBX']; {do not localize}
  1362. end;
  1363. procedure TIdRR_MINFO.SetErrorHandle_Mail(const Value: AnsiString);
  1364. begin
  1365. Self.RRDatas.Values['EMAILBX'] := Value; {do not localize}
  1366. end;
  1367. procedure TIdRR_MINFO.SetResponsible_Mail(const Value: AnsiString);
  1368. begin
  1369. Self.RRDatas.Values['RMAILBX'] := Value; {do not localize}
  1370. end;
  1371. function TIdRR_MINFO.TextRecord(FullName: string): string;
  1372. var
  1373. QName: string;
  1374. begin
  1375. Result := '';
  1376. QName := Self.RRName + '.';
  1377. if QName <> FullName then begin
  1378. if Copy(Self.RRName, Length(Self.RRName),1) <> '.' then begin
  1379. QName := Self.RRName + '.' + FullName;
  1380. end else begin
  1381. QName := Self.RRName;
  1382. end;
  1383. end;
  1384. if QName = FullName then QName := '@';
  1385. Result := QName + Chr(9) + 'IN' + Chr(9) + 'MINFO' + Chr(9) + Self.Responsible_Mail + ' ' + Self.ErrorHandle_Mail + #13+#10; {do not localize}
  1386. end;
  1387. { TIdRR_MR }
  1388. function TIdRR_MR.BinQueryRecord(FullName: string): TIdBytes;
  1389. var
  1390. QName: string;
  1391. RRData: TIdBytes;
  1392. begin
  1393. SetLength(Result, 0);
  1394. if Copy(Self.RRName, Length(Self.RRName),1) <> '.' then begin
  1395. QName := Self.RRName + '.' + FullName;
  1396. end else begin
  1397. QName := Self.RRName;
  1398. end;
  1399. RRData := DomainNameToDNSStr((Self.NewName));
  1400. Result := DomainNameToDNSStr((QName));
  1401. AppendBytes(Result, ToBytes(SmallInt(TypeCode_MR)));
  1402. AppendBytes(Result, ToBytes(SmallInt(Class_IN)));
  1403. AppendBytes(Result, ToBytes((Self.TTL)));
  1404. AppendBytes(Result, ToBytes((Length(RRData))));
  1405. AppendBytes(Result, RRData);
  1406. end;
  1407. constructor TIdRR_MR.Create;
  1408. begin
  1409. inherited;
  1410. Self.RRName := 'MR'; {do not localize}
  1411. Self.NewName := '';
  1412. Self.TypeCode := TypeCode_MR;
  1413. end;
  1414. function TIdRR_MR.GetNewName: AnsiString;
  1415. begin
  1416. Result := Self.RRDatas.Values['NewName']; {do not localize}
  1417. end;
  1418. procedure TIdRR_MR.SetNewName(const Value: AnsiString);
  1419. begin
  1420. Self.RRDatas.Values['NewName'] := Value; {do not localize}
  1421. end;
  1422. function TIdRR_MR.TextRecord(FullName: string): string;
  1423. var
  1424. QName: string;
  1425. begin
  1426. Result := '';
  1427. QName := Self.RRName + '.';
  1428. if QName <> FullName then begin
  1429. if Copy(Self.RRName, Length(Self.RRName),1) <> '.' then begin
  1430. QName := Self.RRName + '.' + FullName;
  1431. end else begin
  1432. QName := Self.RRName;
  1433. end;
  1434. end;
  1435. if QName = FullName then QName := '@';
  1436. Result := QName + Chr(9) + 'IN' + Chr(9) + 'MR' + Chr(9) + Self.NewName + #13+#10; {do not localize}
  1437. end;
  1438. { TIdRR_MX }
  1439. function TIdRR_MX.BinQueryRecord(FullName: string): TIdBytes;
  1440. var
  1441. QName: string;
  1442. RRData: TIdBytes;
  1443. Pref : Word;
  1444. begin
  1445. SetLength(Result, 0);
  1446. if Copy(Self.RRName, Length(Self.RRName),1) <> '.' then begin
  1447. QName := Self.RRName + '.' + FullName;
  1448. end else begin
  1449. QName := Self.RRName;
  1450. end;
  1451. Pref := StrToInt(Self.Preference);
  1452. RRData := ToBytes(SmallInt(Pref));
  1453. if Copy(Self.Exchange, Length(Self.Exchange),1) <> '.' then
  1454. AppendBytes(RRData, DomainNameToDNSStr(Self.Exchange + '.' + FullName))
  1455. else
  1456. AppendBytes(RRData, DomainNameToDNSStr((Self.Exchange)));
  1457. Result := DomainNameToDNSStr((QName));
  1458. AppendBytes(Result, ToBytes(SmallInt(TypeCode_MX)));
  1459. AppendBytes(Result, ToBytes(SmallInt(Class_IN)));
  1460. AppendBytes(Result, ToBytes((Self.TTL)));
  1461. AppendBytes(Result, ToBytes((Length(RRData))));
  1462. AppendBytes(Result, RRData);
  1463. end;
  1464. constructor TIdRR_MX.Create;
  1465. begin
  1466. inherited;
  1467. Self.RRName := 'MX'; {do not localize}
  1468. Self.Exchange := '';
  1469. Self.TypeCode := TypeCode_MX;
  1470. end;
  1471. function TIdRR_MX.GetExchang: AnsiString;
  1472. begin
  1473. Result := Self.RRDatas.Values['EXCHANGE']; {do not localize}
  1474. end;
  1475. function TIdRR_MX.GetPref: AnsiString;
  1476. begin
  1477. Result := Self.RRDatas.Values['PREF']; {do not localize}
  1478. end;
  1479. procedure TIdRR_MX.SetExchange(const Value: AnsiString);
  1480. begin
  1481. Self.RRDatas.Values['EXCHANGE'] := Value; {do not localize}
  1482. end;
  1483. procedure TIdRR_MX.SetPref(const Value: AnsiString);
  1484. begin
  1485. Self.RRDatas.Values['PREF'] := Value; {do not localize}
  1486. end;
  1487. function TIdRR_MX.TextRecord(FullName: string): string;
  1488. var
  1489. QName: string;
  1490. begin
  1491. Result := '';
  1492. QName := Self.RRName + '.';
  1493. if QName <> FullName then begin
  1494. if Copy(Self.RRName, Length(Self.RRName),1) <> '.' then begin
  1495. QName := Self.RRName + '.' + FullName;
  1496. end else begin
  1497. QName := Self.RRName;
  1498. end;
  1499. end;
  1500. if QName = FullName then QName := '@';
  1501. Result := QName + Chr(9) + 'IN' + Chr(9) + 'MX' + Chr(9) + Self.Preference + ' ' + Self.Exchange + #13+#10; {do not localize}
  1502. end;
  1503. { TIdRR_NS }
  1504. function TIdRR_NS.BinQueryRecord(FullName: string): TIdBytes;
  1505. var
  1506. QName: string;
  1507. RRData: TIdBytes;
  1508. begin
  1509. SetLength(Result, 0);
  1510. if Copy(Self.RRName, Length(Self.RRName),1) <> '.' then begin
  1511. QName := Self.RRName + '.' + FullName;
  1512. end else begin
  1513. QName := Self.RRName;
  1514. end;
  1515. RRData := DomainNameToDNSStr((Self.NSDName));
  1516. Result := DomainNameToDNSStr((QName));
  1517. AppendBytes(Result, ToBytes(SmallInt(TypeCode_NS)));
  1518. AppendBytes(Result, ToBytes(SmallInt(Class_IN)));
  1519. AppendBytes(Result, ToBytes((Self.TTL)));
  1520. AppendBytes(Result, ToBytes((Length(RRData))));
  1521. AppendBytes(Result, RRData);
  1522. end;
  1523. constructor TIdRR_NS.Create;
  1524. begin
  1525. inherited;
  1526. Self.RRName := 'NS'; {do not localize}
  1527. Self.NSDName := '';
  1528. Self.TypeCode := TypeCode_NS;
  1529. end;
  1530. function TIdRR_NS.GetNS: AnsiString;
  1531. begin
  1532. Result := Self.RRDatas.Values['NSDNAME']; {do not localize}
  1533. end;
  1534. procedure TIdRR_NS.SetNS(const Value: AnsiString);
  1535. begin
  1536. Self.RRDatas.Values['NSDNAME'] := Value; {do not localize}
  1537. end;
  1538. function TIdRR_NS.TextRecord(FullName: string): string;
  1539. var
  1540. QName: string;
  1541. begin
  1542. Result := '';
  1543. QName := Self.RRName + '.';
  1544. if QName <> FullName then begin
  1545. if Copy(Self.RRName, Length(Self.RRName),1) <> '.' then begin
  1546. QName := Self.RRName + '.' + FullName;
  1547. end else begin
  1548. QName := Self.RRName;
  1549. end;
  1550. end;
  1551. if QName = FullName then QName := '@';
  1552. Result := QName + Chr(9) + 'IN' + Chr(9) + 'NS' + Chr(9) + Self.NSDName + #13+#10; {do not localize}
  1553. end;
  1554. { TIdRR_PTR }
  1555. function TIdRR_PTR.BinQueryRecord(FullName: string): TIdBytes;
  1556. var
  1557. QName: string;
  1558. RRData: TIdBytes;
  1559. begin
  1560. SetLength(Result, 0);
  1561. if Copy(Self.RRName, Length(Self.RRName),1) <> '.' then begin
  1562. QName := Self.RRName + '.' + FullName;
  1563. end else begin
  1564. QName := Self.RRName;
  1565. end;
  1566. RRData := DomainNameToDNSStr(Self.PTRDName);
  1567. Result := DomainNameToDNSStr((QName));
  1568. AppendBytes(Result, ToBytes(SmallInt(TypeCode_PTR)));
  1569. AppendBytes(Result, ToBytes(SmallInt(Class_IN)));
  1570. AppendBytes(Result, ToBytes((Self.TTL)));
  1571. AppendBytes(Result, ToBytes((Length(RRData))));
  1572. AppendBytes(Result, RRData);
  1573. end;
  1574. constructor TIdRR_PTR.Create;
  1575. begin
  1576. inherited;
  1577. Self.RRName := 'PTR'; {do not localize}
  1578. Self.PTRDName := '';
  1579. Self.TypeCode := TypeCode_PTR;
  1580. end;
  1581. function TIdRR_PTR.GetPTRName: AnsiString;
  1582. begin
  1583. Result := Self.RRDatas.Values['PTRDNAME']; {do not localize}
  1584. end;
  1585. procedure TIdRR_PTR.SetPTRName(const Value: AnsiString);
  1586. begin
  1587. Self.RRDatas.Values['PTRDNAME'] := Value; {do not localize}
  1588. end;
  1589. function TIdRR_PTR.TextRecord(FullName: string): string;
  1590. var
  1591. QName: string;
  1592. begin
  1593. Result := '';
  1594. QName := Self.RRName + '.';
  1595. if QName <> FullName then begin
  1596. if Copy(Self.RRName, Length(Self.RRName),1) <> '.' then begin
  1597. QName := Self.RRName + '.' + FullName;
  1598. end else begin
  1599. QName := Self.RRName;
  1600. end;
  1601. end;
  1602. if QName = FullName then QName := '@';
  1603. Result := QName + Chr(9) + 'IN' + Chr(9) + 'PTR' + Chr(9) + Self.PTRDName + #13+#10; {do not localize}
  1604. end;
  1605. { TIdRR_SOA }
  1606. function TIdRR_SOA.BinQueryRecord(FullName: string): TIdBytes;
  1607. var
  1608. QName: string;
  1609. RRData: TIdBytes;
  1610. begin
  1611. SetLength(Result, 0);
  1612. if Copy(Self.RRName, Length(Self.RRName),1) <> '.' then begin
  1613. QName := Self.RRName + '.' + FullName;
  1614. end else begin
  1615. QName := Self.RRName;
  1616. end;
  1617. RRData := DomainNameToDNSStr((Self.MName));
  1618. AppendBytes(RRData, DomainNameToDNSStr((Self.RName)));
  1619. AppendBytes(RRData, ToBytes(StrToInt(Self.Serial)));
  1620. AppendBytes(RRData, ToBytes(StrToInt(Self.Refresh)));
  1621. AppendBytes(RRData, ToBytes(StrToInt(Self.Retry)));
  1622. AppendBytes(RRData, ToBytes(StrToInt(Self.Expire)));
  1623. AppendBytes(RRData, ToBytes(StrToInt(Self.Minimum)));
  1624. Result := DomainNameToDNSStr((QName));
  1625. AppendBytes(Result, ToBytes(SmallInt(TypeCode_SOA)));
  1626. AppendBytes(Result, ToBytes(SmallInt(Class_IN)));
  1627. AppendBytes(Result, ToBytes((Self.TTL)));
  1628. AppendBytes(Result, ToBytes((Length(RRData))));
  1629. AppendBytes(Result, RRData);
  1630. end;
  1631. constructor TIdRR_SOA.Create;
  1632. begin
  1633. inherited;
  1634. Self.RRName := 'SOA'; {do not localize}
  1635. Self.TypeCode := TypeCode_SOA;
  1636. Self.MName := '';
  1637. Self.RName := '';
  1638. Self.Serial := '';
  1639. Self.Refresh := '';
  1640. Self.Retry := '';
  1641. Self.Expire := '';
  1642. Self.Minimum := '';
  1643. end;
  1644. function TIdRR_SOA.GetExpire: AnsiString;
  1645. begin
  1646. Result := Self.GetName('EXPIRE'); {do not localize}
  1647. end;
  1648. function TIdRR_SOA.GetMin: AnsiString;
  1649. begin
  1650. Result := Self.GetName('MINIMUM'); {do not localize}
  1651. end;
  1652. function TIdRR_SOA.GetMName: AnsiString;
  1653. begin
  1654. Result := Self.GetName('MNAME'); {do not localize}
  1655. end;
  1656. function TIdRR_SOA.GetName(CLabel: string): AnsiString;
  1657. begin
  1658. Result := Self.RRDatas.Values[CLabel];
  1659. end;
  1660. function TIdRR_SOA.GetRefresh: AnsiString;
  1661. begin
  1662. Result := Self.GetName('REFRESH'); {do not localize}
  1663. end;
  1664. function TIdRR_SOA.GetRetry: AnsiString;
  1665. begin
  1666. Result := Self.GetName('RETRY'); {do not localize}
  1667. end;
  1668. function TIdRR_SOA.GetRName: AnsiString;
  1669. begin
  1670. Result := Self.GetName('RNAME'); {do not localize}
  1671. end;
  1672. function TIdRR_SOA.GetSerial: AnsiString;
  1673. begin
  1674. Result := Self.GetName('SERIAL'); {do not localize}
  1675. end;
  1676. procedure TIdRR_SOA.SetExpire(const Value: AnsiString);
  1677. begin
  1678. Self.SetName('EXPIRE', Value); {do not localize}
  1679. end;
  1680. procedure TIdRR_SOA.SetMin(const Value: AnsiString);
  1681. begin
  1682. Self.SetName('MINIMUM', Value); {do not localize}
  1683. end;
  1684. procedure TIdRR_SOA.SetMName(const Value: AnsiString);
  1685. begin
  1686. Self.SetName('MNAME', Value); {do not localize}
  1687. end;
  1688. procedure TIdRR_SOA.SetName(CLabel, Value: AnsiString);
  1689. begin
  1690. Self.RRDatas.Values[CLabel] := Value;
  1691. end;
  1692. procedure TIdRR_SOA.SetRefresh(const Value: AnsiString);
  1693. begin
  1694. Self.SetName('REFRESH', Value); {do not localize}
  1695. end;
  1696. procedure TIdRR_SOA.SetRetry(const Value: AnsiString);
  1697. begin
  1698. Self.SetName('RETRY', Value); {do not localize}
  1699. end;
  1700. procedure TIdRR_SOA.SetRName(const Value: AnsiString);
  1701. begin
  1702. Self.SetName('RNAME', Value); {do not localize}
  1703. end;
  1704. procedure TIdRR_SOA.SetSerial(const Value: AnsiString);
  1705. begin
  1706. Self.SetName('SERIAL', Value); {do not localize}
  1707. end;
  1708. function TIdRR_SOA.TextRecord(FullName: string): string;
  1709. var
  1710. QName: string;
  1711. begin
  1712. Result := '';
  1713. QName := Self.RRName + '.';
  1714. if QName <> FullName then begin
  1715. if Copy(Self.RRName, Length(Self.RRName),1) <> '.' then begin
  1716. QName := Self.RRName + '.' + FullName;
  1717. end else begin
  1718. QName := Self.RRName;
  1719. end;
  1720. end;
  1721. if QName = FullName then QName := '@';
  1722. Result := QName + Chr(9) + 'IN' + Chr(9) + 'SOA' + Chr(9) + {do not localize}
  1723. Self.MName + ' ' + Self.RName + ' ' +
  1724. Self.Serial + ' ' + Self.Refresh + ' ' + Self.Retry + ' '+
  1725. Self.Expire + ' ' + Self.Minimum +
  1726. #13+#10;
  1727. end;
  1728. { TIdRR_A }
  1729. function TIdRR_A.BinQueryRecord(FullName: string): TIdBytes;
  1730. var
  1731. QName: string;
  1732. RRData: TIdBytes;
  1733. begin
  1734. SetLength(Result, 0);
  1735. if Copy(Self.RRName, Length(Self.RRName),1) <> '.' then begin
  1736. QName := Self.RRName + '.' + FullName;
  1737. end else begin
  1738. QName := Self.RRName;
  1739. end;
  1740. RRData := IPAddrToDNSStr(Self.Address);
  1741. Result := DomainNameToDNSStr((QName));
  1742. AppendBytes(Result, ToBytes(SmallInt(TypeCode_A)));
  1743. AppendBytes(Result, ToBytes(SmallInt(Class_IN)));
  1744. AppendBytes(Result, ToBytes((Self.TTL)));
  1745. AppendBytes(Result, ToBytes((Length(RRData))));
  1746. AppendBytes(Result, RRData);
  1747. end;
  1748. constructor TIdRR_A.Create;
  1749. begin
  1750. inherited;
  1751. Self.RRName := 'A'; {do not localize}
  1752. Self.Address := '';
  1753. Self.TypeCode := TypeCode_A;
  1754. end;
  1755. function TIdRR_A.GetA: AnsiString;
  1756. begin
  1757. Result := Self.RRDatas.Values['A']; {do not localize}
  1758. end;
  1759. procedure TIdRR_A.SetA(const Value: AnsiString);
  1760. begin
  1761. Self.RRDatas.Values['A'] := Value; {do not localize}
  1762. end;
  1763. function TIdRR_A.TextRecord(FullName: string): string;
  1764. var
  1765. QName: string;
  1766. begin
  1767. Result := '';
  1768. QName := Self.RRName + '.';
  1769. if QName <> FullName then begin
  1770. if Copy(Self.RRName, Length(Self.RRName),1) <> '.' then begin
  1771. QName := Self.RRName + '.' + FullName;
  1772. end else begin
  1773. QName := Self.RRName;
  1774. end;
  1775. end;
  1776. if QName = FullName then QName := '@';
  1777. Result := QName + Chr(9) + 'IN' + Chr(9) + 'A' + Chr(9) + Self.Address + #13+#10; {do not localize}
  1778. end;
  1779. { TIdRR_AAAA }
  1780. function TIdRR_AAAA.BinQueryRecord(FullName: string): TIdBytes;
  1781. var
  1782. QName: string;
  1783. RRData: TIdBytes;
  1784. begin
  1785. SetLength(Result, 0);
  1786. if Copy(Self.RRName, Length(Self.RRName),1) <> '.' then begin
  1787. QName := Self.RRName + '.' + FullName;
  1788. end else begin
  1789. QName := Self.RRName;
  1790. end;
  1791. RRData := IPv6AAAAToDNSStr(Self.Address);
  1792. Result := DomainNameToDNSStr((QName));
  1793. AppendBytes(Result, ToBytes(SmallInt(TypeCode_AAAA)));
  1794. AppendBytes(Result, ToBytes(SmallInt(Class_IN)));
  1795. AppendBytes(Result, ToBytes(Self.TTL));
  1796. AppendBytes(Result, ToBytes(SmallInt(16)));
  1797. AppendBytes(Result, RRData);
  1798. end;
  1799. constructor TIdRR_AAAA.Create;
  1800. begin
  1801. inherited;
  1802. Self.RRName := 'AAAA'; {do not localize}
  1803. Self.Address := '';
  1804. Self.TypeCode := TypeCode_AAAA;
  1805. end;
  1806. function TIdRR_AAAA.GetA: AnsiString;
  1807. begin
  1808. Result := Self.RRDatas.Values['AAAA']; {do not localize}
  1809. end;
  1810. procedure TIdRR_AAAA.SetA(const Value: AnsiString);
  1811. begin
  1812. Self.RRDatas.Values['AAAA'] := Value; {do not localize}
  1813. end;
  1814. function TIdRR_AAAA.TextRecord(FullName: string): string;
  1815. var
  1816. QName: string;
  1817. begin
  1818. Result := '';
  1819. QName := Self.RRName + '.';
  1820. if QName <> FullName then begin
  1821. if Copy(Self.RRName, Length(Self.RRName),1) <> '.' then begin
  1822. QName := Self.RRName + '.' + FullName;
  1823. end else begin
  1824. QName := Self.RRName;
  1825. end;
  1826. end;
  1827. if QName = FullName then QName := '@';
  1828. Result := QName + Chr(9) + 'IN' + Chr(9) + 'AAAA' + Chr(9) + Self.Address + #13+#10; {do not localize}
  1829. end;
  1830. { TIdRR_TXT }
  1831. function TIdRR_TXT.BinQueryRecord(FullName: string): TIdBytes;
  1832. var
  1833. QName: string;
  1834. RRData: TIdBytes;
  1835. begin
  1836. SetLength(Result, 0);
  1837. if Copy(Self.RRName, Length(Self.RRName),1) <> '.' then begin
  1838. QName := Self.RRName + '.' + FullName;
  1839. end else begin
  1840. QName := Self.RRName;
  1841. end;
  1842. RRData := ToBytes(Self.TXT); //TODO ???
  1843. Result := NormalStrToDNSStr((QName));
  1844. AppendBytes(Result, ToBytes(SmallInt((TypeCode_TXT))));
  1845. AppendBytes(Result, ToBytes(SmallInt(Class_IN)));
  1846. AppendBytes(Result, ToBytes((Self.TTL)));
  1847. AppendBytes(Result, ToBytes((Length(RRData))));
  1848. AppendBytes(Result, RRData);
  1849. end;
  1850. constructor TIdRR_TXT.Create;
  1851. begin
  1852. inherited;
  1853. Self.RRName := 'TXT'; {do not localize}
  1854. Self.TXT := '';
  1855. Self.TypeCode := TypeCode_TXT;
  1856. end;
  1857. function TIdRR_TXT.GetTXT: AnsiString;
  1858. begin
  1859. Result := Self.RRDatas.Values['TXT']; {do not localize}
  1860. end;
  1861. procedure TIdRR_TXT.SetTXT(const Value: AnsiString);
  1862. begin
  1863. Self.RRDatas.Values['TXT'] := Value; {do not localize}
  1864. end;
  1865. function TIdRR_TXT.TextRecord(FullName: string): string;
  1866. var
  1867. QName: string;
  1868. begin
  1869. Result := '';
  1870. QName := Self.RRName + '.';
  1871. if QName <> FullName then begin
  1872. if Copy(Self.RRName, Length(Self.RRName),1) <> '.' then begin
  1873. QName := Self.RRName + '.' + FullName;
  1874. end else begin
  1875. QName := Self.RRName;
  1876. end;
  1877. end;
  1878. if QName = FullName then QName := '@';
  1879. Result := QName + Chr(9) + 'IN' + Chr(9) + 'TXT' + Chr(9) + '"' + Self.TXT + '"' + #13+#10; {do not localize}
  1880. end;
  1881. { TIdRR_WKS }
  1882. constructor TIdRR_WKS.Create;
  1883. begin
  1884. inherited;
  1885. Self.RRName := 'WKS'; {do not localize}
  1886. Self.TypeCode := TypeCode_WKS;
  1887. end;
  1888. { TIdRR_Error }
  1889. constructor TIdRR_Error.Create;
  1890. begin
  1891. inherited;
  1892. Self.TypeCode := TypeCode_Error;
  1893. end;
  1894. function ReplaceSpecString(Source, Target, NewString : string; ReplaceAll : boolean = True) : string;
  1895. var
  1896. FixingString, MiddleString, FixedString : string;
  1897. begin
  1898. if Target = NewString then Result := Source
  1899. else begin
  1900. FixingString := Source;
  1901. MiddleString := ''; {do not localize}
  1902. FixedString := ''; {do not localize}
  1903. if (POS(Target, Source) > 0) then begin
  1904. repeat
  1905. MiddleString := Fetch(FixingString, Target);
  1906. FixedString := FixedString + MiddleString + NewString;
  1907. until (POS(Target, FixingString) = 0) or (not ReplaceAll);
  1908. FixedString := FixedString + FixingString;
  1909. Result := FixedString;
  1910. end else begin
  1911. Result := Source;
  1912. end;
  1913. end;
  1914. end;
  1915. function IsBig5(ch1, ch2:char) : boolean;
  1916. begin
  1917. if (not (((ch1 >= #161) and (ch1 <= #254)) or
  1918. ((ch1 >= #142) and (ch1 <= #160)) or
  1919. ((ch1 >= #129) and (ch1 <= #141))) ) or
  1920. (not (((ch2 >= #64) and (ch2 <= #126)) or
  1921. ((ch2 >= #161) and (ch2 <= #254))) ) then
  1922. Result := False
  1923. else
  1924. Result := True;
  1925. end;
  1926. end.