//============================================================================= // 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""); } 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; }