Use getaddrinfo & getnameinfo
[mgsmtp.git] / DNSResolve.pas
1 {
2 Copyright (C) 2010-2018 MegaBrutal
3
4 This unit is free software: you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 This unit is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
16 }
17
18
19 {$MODE FPC}
20
21 unit DNSResolve;
22
23 interface
24 uses WinSock, Sockets, ctypes;
25
26 type
27
28 PAddrInfo = ^TAddrInfo;
29 TAddrInfo = record
30 ai_flags: cint;
31 ai_family: cint;
32 ai_socktype: cint;
33 ai_protocol: cint;
34 ai_addrlen: size_t;
35 ai_canonname: PChar;
36 ai_addr: PSockAddr;
37 ai_next: PAddrInfo;
38 end;
39
40 TGAIResult = record
41 GAIError: integer;
42 AddrInfo: PAddrInfo;
43 end;
44
45
46 function getaddrinfo(NodeName, ServiceName: PChar; Hints: PAddrInfo; var AddrInfo: PAddrInfo): cint; stdcall;
47 external 'ws2_32.dll' name 'getaddrinfo';
48
49 procedure freeaddrinfo(AddrInfo: PAddrInfo); stdcall;
50 external 'ws2_32.dll' name 'freeaddrinfo';
51
52 function getnameinfo(SockAddr: PSockAddr; SockAddrLength: cuint32; NodeBuffer: PChar; NodeBufferSize: cuint32;
53 ServiceBuffer: PChar; ServiceBufferSize: cuint32; Flags: cint): cint; stdcall;
54 external 'ws2_32.dll' name 'getnameinfo';
55
56 function ResolveHost(HostName: ansistring): TGAIResult;
57 procedure FreeHost(var GAIResult: TGAIResult);
58 function ResolveIP(SockAddr: PSockAddr): ansistring;
59
60
61 implementation
62
63
64 function ResolveHost(HostName: ansistring): TGAIResult;
65 var hint: TAddrInfo;
66 begin
67 FillByte(hint, SizeOf(hint), 0);
68 with hint do begin
69 ai_family:= AF_INET;
70 ai_socktype:= SOCK_STREAM;
71 ai_protocol:= IPPROTO_TCP;
72 end;
73 ResolveHost.GAIError:= getaddrinfo(PChar(HostName), nil, @hint, ResolveHost.AddrInfo);
74 end;
75
76 procedure FreeHost(var GAIResult: TGAIResult);
77 begin
78 if GAIResult.AddrInfo <> nil then begin
79 freeaddrinfo(GAIResult.AddrInfo);
80 GAIResult.AddrInfo:= nil;
81 end;
82 end;
83
84 function ResolveIP(SockAddr: PSockAddr): ansistring;
85 var
86 r: integer;
87 NodeBuffer: array[0..255] of char;
88 begin
89 NodeBuffer[0]:= #0;
90 r:= getnameinfo(SockAddr, SizeOf(TSockAddr), @NodeBuffer, SizeOf(NodeBuffer), nil, 0, 0);
91 if r = 0 then ResolveIP:= PChar(@NodeBuffer)
92 else ResolveIP:= NetAddrToStr(SockAddr^.sin_addr);
93 end;
94
95
96
97 end.