2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS DNS Shared Library
4 * FILE: lib/dnslib/straddr.c
5 * PURPOSE: Functions for address<->string conversion.
8 /* INCLUDES ******************************************************************/
11 /* DATA **********************************************************************/
13 /* FUNCTIONS *****************************************************************/
17 Dns_Ip6AddressToReverseName_W(OUT LPWSTR Name
,
26 Dns_Ip4AddressToReverseName_W(OUT LPWSTR Name
,
29 /* Simply append the ARPA string */
30 return Name
+ (wsprintfW(Name
,
31 L
"%u.%u.%u.%u.in-addr.arpa.",
32 Address
.S_un
.S_addr
>> 24,
33 Address
.S_un
.S_addr
>> 10,
34 Address
.S_un
.S_addr
>> 8,
35 Address
.S_un
.S_addr
) * sizeof(WCHAR
));
40 Dns_Ip4ReverseNameToAddress_A(OUT PIN_ADDR Address
,
49 Dns_Ip6ReverseNameToAddress_A(OUT PIN6_ADDR Address
,
58 Dns_Ip6StringToAddress_A(OUT PIN6_ADDR Address
,
64 /* Let RTL Do it for us */
65 Status
= RtlIpv6StringToAddressA(Name
, &Terminator
, Address
);
66 if (NT_SUCCESS(Status
)) return TRUE
;
74 Dns_Ip6StringToAddress_W(OUT PIN6_ADDR Address
,
80 /* Let RTL Do it for us */
81 Status
= RtlIpv6StringToAddressW(Name
, &Terminator
, Address
);
82 if (NT_SUCCESS(Status
)) return TRUE
;
90 Dns_Ip4StringToAddress_A(OUT PIN_ADDR Address
,
95 /* Use inet_addr to convert it... */
96 Addr
= inet_addr(Name
);
99 /* Check if it's the wildcard (which is ok...) */
100 if (strcmp("255.255.255.255", Name
)) return FALSE
;
103 /* If we got here, then we suceeded... return the address */
104 Address
->S_un
.S_addr
= Addr
;
110 Dns_Ip4StringToAddress_W(OUT PIN_ADDR Address
,
114 ULONG Size
= sizeof(AnsiName
);
117 /* Make a copy of the name in ANSI */
118 ErrorCode
= Dns_StringCopy(&AnsiName
,
126 /* Copy made sucesfully, now convert it */
127 ErrorCode
= Dns_Ip4StringToAddress_A(Address
, AnsiName
);
130 /* Return either 0 bytes copied (failure == false) or conversion status */
136 Dns_Ip4ReverseNameToAddress_W(OUT PIN_ADDR Address
,
140 ULONG Size
= sizeof(AnsiName
);
143 /* Make a copy of the name in ANSI */
144 ErrorCode
= Dns_StringCopy(&AnsiName
,
152 /* Copy made sucesfully, now convert it */
153 ErrorCode
= Dns_Ip4ReverseNameToAddress_A(Address
, AnsiName
);
156 /* Return either 0 bytes copied (failure == false) or conversion status */
162 Dns_StringToAddressEx(OUT PVOID Address
,
163 IN OUT PULONG AddressSize
,
164 IN PVOID AddressName
,
165 IN OUT PDWORD AddressFamily
,
169 DWORD Af
= *AddressFamily
;
170 ULONG AddrSize
= *AddressSize
;
174 CHAR AnsiName
[INET6_ADDRSTRLEN
+ sizeof("ip6.arpa.")];
175 ULONG Size
= sizeof(AnsiName
);
177 /* First check if this is a reverse address string */
180 /* Convert it right now to ANSI as an optimization */
181 Dns_StringCopy(AnsiName
,
188 /* Use the ANSI Name instead */
189 AddressName
= AnsiName
;
193 * If the caller doesn't know what the family is, we'll assume IPv4 and
194 * check if we failed or not. If the caller told us it's IPv4, then just
197 if ((Af
== AF_UNSPEC
) || (Af
== AF_INET
))
199 /* Now check if the caller gave us the reverse name or not */
202 /* Get the Address */
203 Return
= Dns_Ip4ReverseNameToAddress_A((PIN_ADDR
)&Addr
, AddressName
);
207 /* Check if the caller gave us unicode or not */
210 /* Get the Address */
211 Return
= Dns_Ip4StringToAddress_W((PIN_ADDR
)&Addr
, AddressName
);
215 /* Get the Address */
216 Return
= Dns_Ip4StringToAddress_A((PIN_ADDR
)&Addr
, AddressName
);
220 /* Check if we suceeded */
223 /* Save address family */
226 /* Check if the address size matches */
227 if (AddrSize
< sizeof(IN_ADDR
))
229 /* Invalid match, set error code */
230 ErrorCode
= ERROR_MORE_DATA
;
234 /* It matches, save the address! */
235 *(PIN_ADDR
)Address
= *(PIN_ADDR
)&Addr
;
240 /* If we are here, either AF_INET6 was specified or IPv4 failed */
241 if ((Af
== AF_UNSPEC
) || (Af
== AF_INET6
))
243 /* Now check if the caller gave us the reverse name or not */
246 /* Get the Address */
247 Return
= Dns_Ip6ReverseNameToAddress_A(&Addr
, AddressName
);
251 /* Check if the caller gave us unicode or not */
254 /* Get the Address */
255 Return
= Dns_Ip6StringToAddress_W(&Addr
, AddressName
);
259 /* Get the Address */
260 Return
= Dns_Ip6StringToAddress_A(&Addr
, AddressName
);
264 /* Check if we suceeded */
267 /* Save address family */
270 /* Check if the address size matches */
271 if (AddrSize
< sizeof(IN6_ADDR
))
273 /* Invalid match, set error code */
274 ErrorCode
= ERROR_MORE_DATA
;
278 /* It matches, save the address! */
279 *(PIN6_ADDR
)Address
= Addr
;
283 else if (Af
!= AF_INET
)
285 /* You're like.. ATM or something? Get outta here! */
287 ErrorCode
= WSA_INVALID_PARAMETER
;
290 /* Set error if we had one */
291 if (ErrorCode
) SetLastError(ErrorCode
);
293 /* Return the address family and size */
295 *AddressSize
= AddrSize
;
297 /* Return success or failure */
298 return (ErrorCode
== ERROR_SUCCESS
);
303 Dns_StringToAddressW(OUT PVOID Address
,
304 IN OUT PULONG AddressSize
,
305 IN LPWSTR AddressName
,
306 IN OUT PDWORD AddressFamily
)
308 /* Call the common API */
309 return Dns_StringToAddressEx(Address
,
319 Dns_StringToDnsAddrEx(OUT PDNS_ADDRESS DnsAddr
,
320 IN PVOID AddressName
,
321 IN DWORD AddressFamily
,
327 INT ErrorCode
= ERROR_SUCCESS
;
328 CHAR AnsiName
[INET6_ADDRSTRLEN
+ sizeof("ip6.arpa.")];
329 ULONG Size
= sizeof(AnsiName
);
331 /* First check if this is a reverse address string */
332 if ((Reverse
) && (Unicode
))
334 /* Convert it right now to ANSI as an optimization */
335 Dns_StringCopy(AnsiName
,
342 /* Use the ANSI Name instead */
343 AddressName
= AnsiName
;
347 * If the caller doesn't know what the family is, we'll assume IPv4 and
348 * check if we failed or not. If the caller told us it's IPv4, then just
351 if ((AddressFamily
== AF_UNSPEC
) || (AddressFamily
== AF_INET
))
353 /* Now check if the caller gave us the reverse name or not */
356 /* Get the Address */
357 Return
= Dns_Ip4ReverseNameToAddress_A((PIN_ADDR
)&Addr
, AddressName
);
361 /* Check if the caller gave us unicode or not */
364 /* Get the Address */
365 Return
= Dns_Ip4StringToAddress_W((PIN_ADDR
)&Addr
, AddressName
);
369 /* Get the Address */
370 Return
= Dns_Ip4StringToAddress_A((PIN_ADDR
)&Addr
, AddressName
);
374 /* Check if we suceeded */
377 /* Build the IPv4 Address */
378 DnsAddr_BuildFromIp4(DnsAddr
, *(PIN_ADDR
)&Addr
, 0);
380 /* So we don't go in the code below... */
381 AddressFamily
= AF_INET
;
385 /* If we are here, either AF_INET6 was specified or IPv4 failed */
386 if ((AddressFamily
== AF_UNSPEC
) || (AddressFamily
== AF_INET6
))
388 /* Now check if the caller gave us the reverse name or not */
391 /* Get the Address */
392 Return
= Dns_Ip6ReverseNameToAddress_A(&Addr
, AddressName
);
395 /* Build the IPv6 Address */
396 DnsAddr_BuildFromIp6(DnsAddr
, &Addr
, 0, 0);
405 /* Check if the caller gave us unicode or not */
408 /* Get the Address */
409 if (NT_SUCCESS(RtlIpv6StringToAddressExW(AddressName
,
410 &DnsAddr
->Ip6Address
.sin6_addr
,
411 &DnsAddr
->Ip6Address
.sin6_scope_id
,
412 &DnsAddr
->Ip6Address
.sin6_port
)))
419 /* Get the Address */
420 if (NT_SUCCESS(RtlIpv6StringToAddressExA(AddressName
,
421 &DnsAddr
->Ip6Address
.sin6_addr
,
422 &DnsAddr
->Ip6Address
.sin6_scope_id
,
423 &DnsAddr
->Ip6Address
.sin6_port
)))
430 /* Check if we suceeded */
433 /* Finish setting up the structure */
434 DnsAddr
->Ip6Address
.sin6_family
= AF_INET6
;
435 DnsAddr
->AddressLength
= sizeof(SOCKADDR_IN6
);
438 else if (AddressFamily
!= AF_INET
)
440 /* You're like.. ATM or something? Get outta here! */
441 RtlZeroMemory(DnsAddr
, sizeof(DNS_ADDRESS
));
442 SetLastError(WSA_INVALID_PARAMETER
);
446 /* Return success or failure */
447 return (ErrorCode
== ERROR_SUCCESS
);
452 Dns_ReverseNameToDnsAddr_W(OUT PDNS_ADDRESS DnsAddr
,
455 /* Call the common API */
456 return Dns_StringToDnsAddrEx(DnsAddr
,