How to use idDnsServer lazarus / 38-Networking and Web Programming ---------------------------------------------------------------------- aydın · 2022-09-08 19:22 I don't know how to use idDnsServer, one sample code is enough. Thanks you in advance for your help. ---------------------------------------------------------------------- KodeZwerg · 2022-09-08 20:06 I just tried it once many many years ago and i gave up trying to play with it. I decided to write my own class for that purpose where "TIdUDPServer" was the "Father"-Class from what my class derived. Maybe i do find its source somewhere... ---------------------------------------------------------------------- aydın · 2022-09-09 08:32 I created an idUdpServer, assigned 0.0.0.0 as ip, 53 as port. When I searched www.jixoi.com, I got the answer "b~        wwwjixoicom   ". How should I read this data and respond back? ---------------------------------------------------------------------- KodeZwerg · 2022-09-09 09:50 My source is broken, i do not have my full source anymore but some things of how i did survived: class Header: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type  TSimpleDNSServer = class(TIdUDPServer)  protected    procedure DoUDPRead(AData: TIdBytes; ABinding: TIdSocketHandle); override; // called on receive data  private    function ReadPackage(Data: TBytes): TDNSPackage; // read packet    procedure HandlePackage(var DNSPackage: TDNSPackage; Binding: TIdSocketHandle); // handle packet    procedure SendDNSPackage(DNSPackage: TDNSPackage; Binding: TIdSocketHandle); // answer  end;packet header Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type  TDNSHeader = record    ID: Word; // 16bitu Identifier    QR: Boolean; // 1bit False=Query True=Response    OPCODE: Array[0..3] of Boolean; // 4bit 0=Query 1=IQuery 2=Status 3-15 Reserved    AA: Boolean; // 1bit True in Response - Authoritative Answer    TC: Boolean; // 1bit TrunCation    RD: Boolean; // 1bit Recursion Desired    RA: Boolean; // 1bit Recursion Available    Z: Array[0..2] of Boolean; // 3bit Reserved --> 0    RCODE: Array[0..3] of Boolean; // 4bit - Response Code    QDCOUNT: Word; // 16bitu Number of Entries in Question Section    ANCOUNT: Word; // 16bitu Number of RRs in Answer Section  NSCOUNT: Word; // 16bitu Number of Nameserver RRs in the Authority Records Section    ARCOUNT: Word; // 16bitu Number of RRs in Additional Records Section  end;request header Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type  TDNSQuestion = record   QNAME: String; // Query-Name   NamePointer: Integer; // Compression (etwas komplizierter, erkläre ich später)   QTYPE: Word; // 16bitu Type of Query   QCLASS: Word; // 16bitu Class of Query  end;content header Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type  TResorceRecord = record    NAME: TBytes; // a domain name to which this resource record pertains.    RTYPE: Word; // 16bitu Meaning of Data in RDATA    RCLASS: Word; // 16bitu Class of Data in RDATA    TTL: LongWord; // 32bitu Cache-Time    RDLENGTH: Word; // 16bitu Number of Octets in RDATA    RDATA: TBytes; // data storage  end;putting things together Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type  TDNSPackage = record    Header : TDNSHeader;    Question : Array of TDNSQuestion;    Answer : Array of TResorceRecord;  end; class methods Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TSimpleDNSServer.DoUDPRead(AData: TIdBytes; ABinding: TIdSocketHandle);var  DNSPackage: TDNSPackage;begin  DNSPackage := ReadPackage(AData);  HandlePackage(DNSPackage, ABinding);  SendDNSPackage(DNSPackage, Binding);  FreePackage(DNSPackage);end; class methods Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function TSimpleDNSServer.ReadPackage(Data: TBytes): TDNSPackage;var  Buffer16bit: TBytes;  Position: Integer;  Flags, Flags2: Array[0..7] of Boolean; // byte to bit  i: Integer;begin  SetLength(Buffer16bit, 2);  Result.Header.ID := BytesToWord(ReadFromBytes(Data, 0, 2));  Flags := ByteToBits(Data[2]);  Flags2 := ByteToBits(Data[3]);  with Result.Header do  begin    QR := Flags[0];    OPCODE[0] := Flags[1];  OPCODE[1] := Flags[2];    OPCODE[2] := Flags[3];    OPCODE[3] := Flags[4];    AA := Flags[5];    TC := Flags[6];    RD := Flags[7];    RA := Flags2[0];    Z[0] := Flags2[1];    Z[1] := Flags2[2];    Z[2] := Flags2[3];    RCODE[0] := Flags2[4];    RCODE[1] := Flags2[5];    RCODE[2] := Flags2[6];    RCODE[3] := Flags2[7];  end;  Result.Header.QDCOUNT := BytesToWord(ReadFromBytes(Data, 4, 2));  Result.Header.ANCOUNT := BytesToWord(ReadFromBytes(Data, 6, 2));  Result.Header.NSCOUNT := BytesToWord(ReadFromBytes(Data, 8, 2));  Result.Header.ARCOUNT := BytesToWord(ReadFromBytes(Data, 10, 2));  SetLength(Result.Question, Result.Header.QDCOUNT);  Position := 12;  for i := 0 to Result.Header.QDCOUNT-1 do  begin    Result.Question[i].QNAME := GetStringInBytes(Data, Position);    Result.Question[i].NamePointer := Position;    Position := Position + Length(Result.Question[i].QNAME);    Result.Question[i].QTYPE := BytesToWord(ReadFromBytes(Data, Position, 2));    Inc(Position, 2);  Result.Question[i].QCLASS := BytesToWord(ReadFromBytes(Data, Position, 2));    Inc(Position, 2);  end;  SetLength(Buffer16bit, 0);end; class methods Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TSimpleDNSServer.HandlePackage(var DNSPackage: TDNSPackage; Binding: TIdSocketHandle);var  i: Integer;  CompressionBytes: TBytes;  Compression1: Array[0..7] of Boolean;  IPAddress: Array[0..3] of Byte;begin  if DNSPackage.Header.QR then    Exit;  with DNSPackage do  begin    with Header do    begin      QR := True;      AA := False;    RA := True;      RCODE := 0;      ANCOUNT := DNSPackage.Header.QDCOUNT;    end;  end;  SetLength(DNSPackage.Answer, DNSPackage.Header.ANCOUNT);  for i := 0 to DNSPackage.Header.QDCOUNT-1 do  begin    if (DNSPackage.Question[i].QTYPE = 1) and (DNSPackage.Question[i].QCLASS = 1) then    begin      with DNSPackage.Answer[i] do      begin        IPAddress := DNSPackage.Question[i].QNAME;        CompressionBytes := WordToBytes(DNSPackage.Question[i].NamePointer);        Compression1 := ByteToBits(CompressionBytes[0]);        Compression1[0] := True;      Compression1[1] := True;        CompressionBytes[0] := BitsToByte(Compression1);        SetLength(NAME, 2);        NAME[0] := CompressionBytes[0];        NAME[1] := CompressionBytes[1];        RTYPE := 1;        RCLASS := 1;        TTL := 300;        RDLENGTH := 4;        SetLength(RDATA, 4);        RDATA[0] := IPAddress[0];      RDATA[1] := IPAddress[1];        RDATA[2] := IPAddress[2];        RDATA[3] := IPAddress[3];      end;    end;  end;end; class methods Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TSimpleDNSServer.SendDNSPackage(DNSPackage: TDNSPackage; Binding: TIdSocketHandle);var  Bytes: TBytes;  Flags, Flags2: Array[0..7] of Boolean;  i: Integer;  Position: Integer;begin  SetLength(Bytes, SizeOfPackage(DNSPackage));  WriteToBytes(Bytes, WordToBytes(DNSPackage.Header.ID), 0);  with DNSPackage.Header do  begin    Flags[0] := QR;    Flags[1] := OPCODE[0];    Flags[2] := OPCODE[1];    Flags[3] := OPCODE[2];    Flags[4] := OPCODE[3];    Flags[5] := AA;    Flags[6] := TC;    Flags[7] := RD;    Flags2[0] := RA;    Flags2[1] := Z[0];    Flags2[2] := Z[1];    Flags2[3] := Z[2];    Flags2[4] := RCODE[0];    Flags2[5] := RCODE[1];    Flags2[6] := RCODE[2];    Flags2[7] := RCODE[3];  end;  Bytes[2] := BitsToByte(Flags);  Bytes[3] := BitsToByte(Flags2);  WriteToBytes(Bytes, WordToBytes(DNSPackage.Header.QDCOUNT), 4);  WriteToBytes(Bytes, WordToBytes(DNSPackage.Header.ANCOUNT), 6);  WriteToBytes(Bytes, WordToBytes(DNSPackage.Header.NSCOUNT), 8);  WriteToBytes(Bytes, WordToBytes(DNSPackage.Header.ARCOUNT), 10);  Position := 12;  for i := 0 to DNSPackage.Header.QDCOUNT-1 do  begin  WriteToBytes(Bytes, ToBytes(DNSPackage.Question[i].QNAME), Position);    Inc(Position, Length(DNSPackage.Question[i].QNAME));    WriteToBytes(Bytes, WordToBytes(DNSPackage.Question[i].QTYPE), Position);    Inc(Position, 2);    WriteToBytes(Bytes, WordToBytes(DNSPackage.Question[i].QCLASS), Position);    Inc(Position, 2);  end;  for i := 0 to DNSPackage.Header.ANCOUNT-1 do  begin    Bytes[Position] := DNSPackage.Answer[i].NAME[0];    inc(Position);    Bytes[Position] := DNSPackage.Answer[i].NAME[1];    inc(Position);    WriteToBytes(Bytes, WordToBytes(DNSPackage.Answer[i].RTYPE), Position);    Inc(Position, 2);    WriteToBytes(Bytes, WordToBytes(DNSPackage.Answer[i].RCLASS), Position);    Inc(Position, 2);    WriteToBytes(Bytes, LongWordToBytes(DNSPackage.Answer[i].TTL), Position);    Inc(Position, 4);    WriteToBytes(Bytes, WordToBytes(DNSPackage.Answer[i].RDLENGTH), Position);    Inc(Position, 2);    WriteToBytes(Bytes, DNSPackage.Answer[i].RDATA, Position);    Inc(Position, DNSPackage.Answer[i].RDLENGTH);  end;  Binding.SendTo(Binding.PeerIP, Binding.PeerPort, Bytes);end; I hope it helps, more i can not find anymore. ---------------------------------------------------------------------- aydın · 2022-09-09 17:05 Thanks KodeZwerg for the reply. ---------------------------------------------------------------------- Remy Lebeau · 2022-09-09 17:05 Quote from: aydın on September 08, 2022, 09:22:47 pmI don't know how to use idDnsServer, one sample code is enough. Unfortunately, I'm not aware of any examples for TIdDNSServer. What exactly are you trying to accomplish? ---------------------------------------------------------------------- aydın · 2022-09-09 18:06 I want to set up my own DNS server in my local network. ---------------------------------------------------------------------- loaded · 2022-09-12 05:03 Instead of creating your own dns; There are linux-based dns servers customized just for this job. Or there may be such a setting on the modem you are using. I think using them can solve your problem faster. ---------------------------------------------------------------------- Warfley · 2022-09-14 20:13 I guess you probably want to create your own Recursive DNS server, and not an authoratative one. Generally all you need to do for that is parse incoming requests, go through each request individually and cascade down the line of authoratative DNS servers, once you get your record, you can more or less simply paste the result into your response. DNS protocol specification: https://datatracker.ietf.org/doc/html/rfc1035 For the record and request formats you could checkout my DNS client implementation from AsyncNet: https://github.com/Warfley/AsyncNet/blob /master/src/dns/asyncnet.dns.resrecords.pas and https://github.com/War fley/AsyncNet/blob/master/src/dns/asyncnet.dns.pas It's not really hard but a bit tedious