{
- Copyright (C) 2010 MegaBrutal
+ Copyright (C) 2010-2018 MegaBrutal
This unit is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
unit DNSResolve;
interface
-uses WinSock, Sockets;
+uses WinSock, Sockets, ctypes;
+type
- function ResolveHost(HostName: ansistring): in_addr;
- function ResolveIP(IP: in_addr): ansistring;
+ PAddrInfo = ^TAddrInfo;
+ TAddrInfo = record
+ ai_flags: cint;
+ ai_family: cint;
+ ai_socktype: cint;
+ ai_protocol: cint;
+ ai_addrlen: size_t;
+ ai_canonname: PChar;
+ ai_addr: PSockAddr;
+ ai_next: PAddrInfo;
+ end;
+
+ TGAIResult = record
+ GAIError: integer;
+ AddrInfo: PAddrInfo;
+ end;
+
+
+ function getaddrinfo(NodeName, ServiceName: PChar; Hints: PAddrInfo; var AddrInfo: PAddrInfo): cint; stdcall;
+ external 'ws2_32.dll' name 'getaddrinfo';
+
+ procedure freeaddrinfo(AddrInfo: PAddrInfo); stdcall;
+ external 'ws2_32.dll' name 'freeaddrinfo';
+
+ function getnameinfo(SockAddr: PSockAddr; SockAddrLength: cuint32; NodeBuffer: PChar; NodeBufferSize: cuint32;
+ ServiceBuffer: PChar; ServiceBufferSize: cuint32; Flags: cint): cint; stdcall;
+ external 'ws2_32.dll' name 'getnameinfo';
+
+ function ResolveHost(HostName: ansistring): TGAIResult;
+ procedure FreeHost(var GAIResult: TGAIResult);
+ function ResolveIP(SockAddr: PSockAddr): ansistring;
implementation
-function ResolveHost(HostName: ansistring): in_addr;
-var
- HostEnt: PHostEnt;
+function ResolveHost(HostName: ansistring): TGAIResult;
+var hint: TAddrInfo;
+begin
+ FillByte(hint, SizeOf(hint), 0);
+ with hint do begin
+ ai_family:= AF_INET;
+ ai_socktype:= SOCK_STREAM;
+ ai_protocol:= IPPROTO_TCP;
+ end;
+ ResolveHost.GAIError:= getaddrinfo(PChar(HostName), nil, @hint, ResolveHost.AddrInfo);
+end;
+
+procedure FreeHost(var GAIResult: TGAIResult);
begin
- HostEnt:= gethostbyname(PChar(HostName));
- if HostEnt <> nil then
- ResolveHost.s_addr:= PLongWord(HostEnt^.h_addr_list[0])^
- else
- ResolveHost.s_addr:= 0;
+ if GAIResult.AddrInfo <> nil then begin
+ freeaddrinfo(GAIResult.AddrInfo);
+ GAIResult.AddrInfo:= nil;
+ end;
end;
-function ResolveIP(IP: in_addr): ansistring;
+function ResolveIP(SockAddr: PSockAddr): ansistring;
var
- HostEnt: PHostEnt;
+ r: integer;
+ NodeBuffer: array[0..255] of char;
begin
- HostEnt:= gethostbyaddr(@IP, 4, AF_INET);
- if HostEnt <> nil then
- ResolveIP:= HostEnt^.h_name
- else
- ResolveIP:= NetAddrToStr(IP);
+ NodeBuffer[0]:= #0;
+ r:= getnameinfo(SockAddr, SizeOf(TSockAddr), @NodeBuffer, SizeOf(NodeBuffer), nil, 0, 0);
+ if r = 0 then ResolveIP:= PChar(@NodeBuffer)
+ else ResolveIP:= NetAddrToStr(SockAddr^.sin_addr);
end;