230 lines
4.7 KiB
C
230 lines
4.7 KiB
C
//=============================================================================
|
|
// Copyright (c) Microsoft Corporation
|
|
// Abstract:
|
|
// This module implements string-address conversion functions.
|
|
//=============================================================================
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
WCHAR *
|
|
FormatIPv6Address(
|
|
IN IN6_ADDR *Address,
|
|
IN DWORD dwScopeId
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Converts an IPv6 address to a string in a static buffer.
|
|
|
|
Arguments:
|
|
|
|
Address - Supplies the IPv6 address.
|
|
dwScopeId - Supplies the scope identifier.
|
|
|
|
Returns:
|
|
|
|
Pointer to static buffer holding address literal string.
|
|
|
|
--*/
|
|
{
|
|
static WCHAR Buffer[128];
|
|
ULONG buflen = sizeof(Buffer);
|
|
SOCKADDR_IN6 sin6;
|
|
|
|
ZeroMemory(&sin6, sizeof(sin6));
|
|
sin6.sin6_family = AF_INET6;
|
|
sin6.sin6_scope_id = dwScopeId;
|
|
sin6.sin6_addr = *Address;
|
|
|
|
if (WSAAddressToString((SOCKADDR *) &sin6,
|
|
sizeof sin6,
|
|
NULL, // LPWSAPROTOCOL_INFO
|
|
Buffer,
|
|
&buflen) == SOCKET_ERROR) {
|
|
wcscpy(Buffer, L"???");
|
|
}
|
|
|
|
return Buffer;
|
|
}
|
|
|
|
|
|
WCHAR *
|
|
FormatIPv6Prefix(
|
|
IN IN6_ADDR *Address,
|
|
IN ULONG Length
|
|
)
|
|
{
|
|
static WCHAR Buffer[128];
|
|
|
|
swprintf(Buffer, L"%s/%d", FormatIPv6Address(Address, 0), Length);
|
|
|
|
return Buffer;
|
|
}
|
|
|
|
WCHAR *
|
|
FormatIPv4Address(
|
|
IN IN_ADDR *Address
|
|
)
|
|
{
|
|
static WCHAR Buffer[128];
|
|
ULONG buflen = sizeof(Buffer);
|
|
SOCKADDR_IN sin;
|
|
|
|
ZeroMemory(&sin, sizeof(sin));
|
|
sin.sin_family = AF_INET;
|
|
sin.sin_addr = *Address;
|
|
|
|
if (WSAAddressToString((SOCKADDR *) &sin,
|
|
sizeof sin,
|
|
NULL, // LPWSAPROTOCOL_INFO
|
|
Buffer,
|
|
&buflen) == SOCKET_ERROR) {
|
|
wcscpy(Buffer, L"<invalid>");
|
|
}
|
|
|
|
return Buffer;
|
|
}
|
|
|
|
WCHAR *
|
|
FormatLinkLayerAddress(
|
|
IN ULONG Length,
|
|
IN UCHAR *Addr
|
|
)
|
|
{
|
|
static WCHAR Buffer[128];
|
|
|
|
switch (Length) {
|
|
case 6: {
|
|
int i, digit;
|
|
WCHAR *s = Buffer;
|
|
|
|
for (i = 0; i < 6; i++) {
|
|
if (i != 0)
|
|
*s++ = '-';
|
|
|
|
digit = Addr[i] >> 4;
|
|
if (digit < 10)
|
|
*s++ = digit + '0';
|
|
else
|
|
*s++ = digit - 10 + 'a';
|
|
|
|
digit = Addr[i] & 0xf;
|
|
if (digit < 10)
|
|
*s++ = digit + '0';
|
|
else
|
|
*s++ = digit - 10 + 'a';
|
|
}
|
|
*s = '\0';
|
|
break;
|
|
}
|
|
|
|
case 4:
|
|
//
|
|
// IPv4 Address (6-over-4 link)
|
|
//
|
|
wcscpy(Buffer, FormatIPv4Address((struct in_addr *)Addr));
|
|
break;
|
|
|
|
case 0:
|
|
default:
|
|
//
|
|
// Null or loop-back address
|
|
//
|
|
Buffer[0] = '\0';
|
|
break;
|
|
}
|
|
|
|
return Buffer;
|
|
}
|
|
|
|
DWORD
|
|
GetIpv4Address(
|
|
IN PWCHAR pwszArgument,
|
|
OUT IN_ADDR *pipAddress
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Gets the IPv4 address from the string.
|
|
|
|
Arguments:
|
|
|
|
pwszArgument argument specifing an ip address
|
|
pipAddress ip address
|
|
|
|
Return Value:
|
|
|
|
NO_ERROR if success
|
|
Failure code o/w
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS ntStatus;
|
|
PWCHAR Terminator;
|
|
|
|
//
|
|
// Parse unicode IPv4 address with "strict" semantics (full dotted-decimal
|
|
// only). There's no other function that does this today other than
|
|
// the Rtl function below.
|
|
//
|
|
ntStatus = RtlIpv4StringToAddressW(pwszArgument, TRUE, &Terminator,
|
|
pipAddress);
|
|
|
|
if (!NT_SUCCESS(ntStatus) || (*Terminator != 0)) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
|
|
DWORD
|
|
GetIpv6Prefix(
|
|
IN PWCHAR pwszArgument,
|
|
OUT IN6_ADDR *pipAddress,
|
|
OUT DWORD *dwPrefixLength
|
|
)
|
|
{
|
|
NTSTATUS ntStatus;
|
|
PWCHAR Terminator;
|
|
DWORD Length = 0;
|
|
|
|
ntStatus = RtlIpv6StringToAddressW(pwszArgument, &Terminator,
|
|
pipAddress);
|
|
|
|
if (!NT_SUCCESS(ntStatus) || (*Terminator++ != L'/')) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
while (iswdigit(*Terminator)) {
|
|
Length = (Length * 10) + (*Terminator++ - L'0');
|
|
}
|
|
if (*Terminator != 0) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
*dwPrefixLength = Length;
|
|
return NO_ERROR;
|
|
}
|
|
|
|
DWORD
|
|
GetIpv6Address(
|
|
IN PWCHAR pwszArgument,
|
|
OUT IN6_ADDR *pipAddress
|
|
)
|
|
{
|
|
NTSTATUS ntStatus;
|
|
PWCHAR Terminator;
|
|
|
|
ntStatus = RtlIpv6StringToAddressW(pwszArgument, &Terminator,
|
|
pipAddress);
|
|
|
|
if (!NT_SUCCESS(ntStatus) || (*Terminator != 0)) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|