windows-nt/Source/XPSP1/NT/net/tcpip/tpipv6/ipv6mon/parse.c

230 lines
4.7 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
//=============================================================================
// 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;
}