fb4b467bd6424946f05825e80f7dde6f2958a09f
[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; Family: cint): TGAIResult;
57 procedure FreeHost(var GAIResult: TGAIResult);
58 function ResolveIP(AddrInfo: PAddrInfo): ansistring;
59 function IPToStr(SockAddr: PSockAddr): ansistring;
60
61
62 implementation
63
64
65 function ResolveHost(HostName: ansistring; Family: cint): TGAIResult;
66 var hint: TAddrInfo;
67 begin
68 FillByte(hint, SizeOf(hint), 0);
69 with hint do begin
70 ai_family:= Family;
71 ai_socktype:= SOCK_STREAM;
72 ai_protocol:= IPPROTO_TCP;
73 end;
74 ResolveHost.GAIError:= getaddrinfo(PChar(HostName), nil, @hint, ResolveHost.AddrInfo);
75 end;
76
77 procedure FreeHost(var GAIResult: TGAIResult);
78 begin
79 if GAIResult.AddrInfo <> nil then begin
80 freeaddrinfo(GAIResult.AddrInfo);
81 GAIResult.AddrInfo:= nil;
82 end;
83 end;
84
85 function ResolveIP(AddrInfo: PAddrInfo): ansistring;
86 var
87 r: integer;
88 NodeBuffer: array[0..255] of char;
89 begin
90 NodeBuffer[0]:= #0;
91 r:= getnameinfo(AddrInfo^.ai_addr, AddrInfo^.ai_addrlen, @NodeBuffer, SizeOf(NodeBuffer), nil, 0, 0);
92 if r = 0 then ResolveIP:= PChar(@NodeBuffer)
93 else ResolveIP:= IPToStr(AddrInfo^.ai_addr);
94 end;
95
96 function IPToStr(SockAddr: PSockAddr): ansistring;
97 begin
98 if SockAddr^.sa_family = AF_INET then
99 IPToStr:= NetAddrToStr(SockAddr^.sin_addr)
100 else if SockAddr^.sa_family = AF_INET6 then
101 IPToStr:= NetAddrToStr6(PSockAddr6(SockAddr)^.sin6_addr)
102 else
103 IPToStr:= 'unknown';
104 end;
105
106
107 end.