BOOLEAN WINAPI Dns_Ip4ReverseNameToAddress_W(OUT PIN_ADDR Address, IN LPWSTR Name) { CHAR AnsiName[32]; ULONG Size = sizeof(AnsiName); INT ErrorCode; /* Make a copy of the name in ANSI */ ErrorCode = Dns_StringCopy(&AnsiName, &Size, Name, 0, UnicodeString, AnsiString); if (ErrorCode) { /* Copy made sucesfully, now convert it */ ErrorCode = Dns_Ip4ReverseNameToAddress_A(Address, AnsiName); } /* Return either 0 bytes copied (failure == false) or conversion status */ return ErrorCode; }
PHOSTENT WINAPI SaBlob_CreateHostent(IN OUT PULONG_PTR BufferPosition, IN OUT PSIZE_T FreeBufferSpace, IN OUT PSIZE_T HostEntrySize, IN PDNS_BLOB Blob, IN DWORD StringType, IN BOOLEAN Relative, IN BOOLEAN BufferAllocated) { PDNS_ARRAY DnsAddrArray = Blob->DnsAddrArray; ULONG AliasCount = Blob->AliasCount; WORD AddressFamily = AF_UNSPEC; ULONG AddressCount = 0, AddressSize = 0, TotalSize, NamePointerSize; ULONG AliasPointerSize; PDNS_FAMILY_INFO FamilyInfo = NULL; ULONG StringLength = 0; ULONG i; ULONG HostentSize = 0; PHOSTENT Hostent = NULL; ULONG_PTR HostentPtr; PVOID CurrentAddress; /* Check if we actually have any addresses */ if (DnsAddrArray) { /* Get the address family */ AddressFamily = DnsAddrArray->Addresses[0].AddressFamily; /* Get family information */ FamilyInfo = FamilyInfo_GetForFamily(AddressFamily); /* Save the current address count and their size */ AddressCount = DnsAddrArray->UsedAddresses; AddressSize = FamilyInfo->AddressSize; } /* Calculate total size for all the addresses, and their pointers */ TotalSize = AddressSize * AddressCount; NamePointerSize = AddressCount * sizeof(PVOID) + sizeof(PVOID); /* Check if we have a name */ if (Blob->Name) { /* Find out the size we'll need for a copy */ StringLength = (Dns_GetBufferLengthForStringCopy(Blob->Name, 0, UnicodeString, StringType) + 1) & ~1; } /* Now do the same for the aliases */ for (i = AliasCount; i; i--) { /* Find out the size we'll need for a copy */ HostentSize += (Dns_GetBufferLengthForStringCopy(Blob->Aliases[i], 0, UnicodeString, StringType) + 1) & ~1; } /* Find out how much the pointers will take */ AliasPointerSize = AliasCount * sizeof(PVOID) + sizeof(PVOID); /* Calculate Hostent Size */ HostentSize += TotalSize + NamePointerSize + AliasPointerSize + StringLength + sizeof(HOSTENT); /* Check if we already have a buffer */ if (!BufferAllocated) { /* We don't, allocate space ourselves */ HostentPtr = (ULONG_PTR)Dns_AllocZero(HostentSize); } else { /* We do, so allocate space in the buffer */ HostentPtr = (ULONG_PTR)FlatBuf_Arg_ReserveAlignPointer(BufferPosition, FreeBufferSpace, HostentSize); } /* Make sure we got space */ if (HostentPtr) { /* Initialize it */ Hostent = Hostent_Init((PVOID)&HostentPtr, AddressFamily, AddressSize, AddressCount, AliasCount); } /* Loop the addresses */ for (i = 0; i < AddressCount; i++) { /* Get the pointer of the current address */ CurrentAddress = (PVOID)((ULONG_PTR)&DnsAddrArray->Addresses[i] + FamilyInfo->AddressOffset); /* Write the pointer */ Hostent->h_addr_list[i] = (PCHAR)HostentPtr; /* Copy the address */ RtlCopyMemory((PVOID)HostentPtr, CurrentAddress, AddressSize); /* Advance the buffer */ HostentPtr += AddressSize; } /* Check if we have a name */ if (Blob->Name) { /* Align our current position */ HostentPtr += 1 & ~1; /* Save our name here */ Hostent->h_name = (LPSTR)HostentPtr; /* Now copy it in the blob */ HostentPtr += Dns_StringCopy((PVOID)HostentPtr, NULL, Blob->Name, 0, UnicodeString, StringType); } /* Loop the Aliases */ for (i = AliasCount; i; i--) { /* Align our current position */ HostentPtr += 1 & ~1; /* Save our alias here */ Hostent->h_aliases[i] = (LPSTR)HostentPtr; /* Now copy it in the blob */ HostentPtr += Dns_StringCopy((PVOID)HostentPtr, NULL, Blob->Aliases[i], 0, UnicodeString, StringType); } /* Check if the caller didn't have a buffer */ if (!BufferAllocated) { /* Return the size; not needed if we had a blob, since it's internal */ *HostEntrySize = *BufferPosition - (ULONG_PTR)HostentPtr; } /* Convert to Offsets if requested */ if(Relative) Hostent_ConvertToOffsets(Hostent); /* Return the full, complete, hostent */ return Hostent; }
BOOLEAN WINAPI Dns_StringToDnsAddrEx(OUT PDNS_ADDRESS DnsAddr, IN PVOID AddressName, IN DWORD AddressFamily, IN BOOLEAN Unicode, IN BOOLEAN Reverse) { IN6_ADDR Addr; BOOLEAN Return; INT ErrorCode = ERROR_SUCCESS; CHAR AnsiName[INET6_ADDRSTRLEN + sizeof("ip6.arpa.")]; ULONG Size = sizeof(AnsiName); /* First check if this is a reverse address string */ if ((Reverse) && (Unicode)) { /* Convert it right now to ANSI as an optimization */ Dns_StringCopy(AnsiName, &Size, AddressName, 0, UnicodeString, AnsiString); /* Use the ANSI Name instead */ AddressName = AnsiName; } /* * If the caller doesn't know what the family is, we'll assume IPv4 and * check if we failed or not. If the caller told us it's IPv4, then just * do IPv4... */ if ((AddressFamily == AF_UNSPEC) || (AddressFamily == AF_INET)) { /* Now check if the caller gave us the reverse name or not */ if (Reverse) { /* Get the Address */ Return = Dns_Ip4ReverseNameToAddress_A((PIN_ADDR)&Addr, AddressName); } else { /* Check if the caller gave us unicode or not */ if (Unicode) { /* Get the Address */ Return = Dns_Ip4StringToAddress_W((PIN_ADDR)&Addr, AddressName); } else { /* Get the Address */ Return = Dns_Ip4StringToAddress_A((PIN_ADDR)&Addr, AddressName); } } /* Check if we suceeded */ if (Return) { /* Build the IPv4 Address */ DnsAddr_BuildFromIp4(DnsAddr, *(PIN_ADDR)&Addr, 0); /* So we don't go in the code below... */ AddressFamily = AF_INET; } } /* If we are here, either AF_INET6 was specified or IPv4 failed */ if ((AddressFamily == AF_UNSPEC) || (AddressFamily == AF_INET6)) { /* Now check if the caller gave us the reverse name or not */ if (Reverse) { /* Get the Address */ Return = Dns_Ip6ReverseNameToAddress_A(&Addr, AddressName); if (Return) { /* Build the IPv6 Address */ DnsAddr_BuildFromIp6(DnsAddr, &Addr, 0, 0); } else { goto Quickie; } } else { /* Check if the caller gave us unicode or not */ if (Unicode) { /* Get the Address */ if (NT_SUCCESS(RtlIpv6StringToAddressExW(AddressName, &DnsAddr->Ip6Address.sin6_addr, &DnsAddr->Ip6Address.sin6_scope_id, &DnsAddr->Ip6Address.sin6_port))) Return = TRUE; else Return = FALSE; } else { /* Get the Address */ if (NT_SUCCESS(RtlIpv6StringToAddressExA(AddressName, &DnsAddr->Ip6Address.sin6_addr, &DnsAddr->Ip6Address.sin6_scope_id, &DnsAddr->Ip6Address.sin6_port))) Return = TRUE; else Return = FALSE; } } /* Check if we suceeded */ if (Return) { /* Finish setting up the structure */ DnsAddr->Ip6Address.sin6_family = AF_INET6; DnsAddr->AddressLength = sizeof(SOCKADDR_IN6); } } else if (AddressFamily != AF_INET) { /* You're like.. ATM or something? Get outta here! */ RtlZeroMemory(DnsAddr, sizeof(DNS_ADDRESS)); SetLastError(WSA_INVALID_PARAMETER); } Quickie: /* Return success or failure */ return (ErrorCode == ERROR_SUCCESS); }
BOOLEAN WINAPI Dns_StringToAddressEx(OUT PVOID Address, IN OUT PULONG AddressSize, IN PVOID AddressName, IN OUT PDWORD AddressFamily, IN BOOLEAN Unicode, IN BOOLEAN Reverse) { DWORD Af = *AddressFamily; ULONG AddrSize = *AddressSize; IN6_ADDR Addr; BOOLEAN Return; INT ErrorCode; CHAR AnsiName[INET6_ADDRSTRLEN + sizeof("ip6.arpa.")]; ULONG Size = sizeof(AnsiName); /* First check if this is a reverse address string */ if (Reverse) { /* Convert it right now to ANSI as an optimization */ Dns_StringCopy(AnsiName, &Size, AddressName, 0, UnicodeString, AnsiString); /* Use the ANSI Name instead */ AddressName = AnsiName; } /* * If the caller doesn't know what the family is, we'll assume IPv4 and * check if we failed or not. If the caller told us it's IPv4, then just * do IPv4... */ if ((Af == AF_UNSPEC) || (Af == AF_INET)) { /* Now check if the caller gave us the reverse name or not */ if (Reverse) { /* Get the Address */ Return = Dns_Ip4ReverseNameToAddress_A((PIN_ADDR)&Addr, AddressName); } else { /* Check if the caller gave us unicode or not */ if (Unicode) { /* Get the Address */ Return = Dns_Ip4StringToAddress_W((PIN_ADDR)&Addr, AddressName); } else { /* Get the Address */ Return = Dns_Ip4StringToAddress_A((PIN_ADDR)&Addr, AddressName); } } /* Check if we suceeded */ if (Return) { /* Save address family */ Af = AF_INET; /* Check if the address size matches */ if (AddrSize < sizeof(IN_ADDR)) { /* Invalid match, set error code */ ErrorCode = ERROR_MORE_DATA; } else { /* It matches, save the address! */ *(PIN_ADDR)Address = *(PIN_ADDR)&Addr; } } } /* If we are here, either AF_INET6 was specified or IPv4 failed */ if ((Af == AF_UNSPEC) || (Af == AF_INET6)) { /* Now check if the caller gave us the reverse name or not */ if (Reverse) { /* Get the Address */ Return = Dns_Ip6ReverseNameToAddress_A(&Addr, AddressName); } else { /* Check if the caller gave us unicode or not */ if (Unicode) { /* Get the Address */ Return = Dns_Ip6StringToAddress_W(&Addr, AddressName); } else { /* Get the Address */ Return = Dns_Ip6StringToAddress_A(&Addr, AddressName); } } /* Check if we suceeded */ if (Return) { /* Save address family */ Af = AF_INET6; /* Check if the address size matches */ if (AddrSize < sizeof(IN6_ADDR)) { /* Invalid match, set error code */ ErrorCode = ERROR_MORE_DATA; } else { /* It matches, save the address! */ *(PIN6_ADDR)Address = Addr; } } } else if (Af != AF_INET) { /* You're like.. ATM or something? Get outta here! */ Af = AF_UNSPEC; ErrorCode = WSA_INVALID_PARAMETER; } /* Set error if we had one */ if (ErrorCode) SetLastError(ErrorCode); /* Return the address family and size */ *AddressFamily = Af; *AddressSize = AddrSize; /* Return success or failure */ return (ErrorCode == ERROR_SUCCESS); }