windows-nt/Source/XPSP1/NT/net/tcpip/apis/iphlpapi/dll/str2addt.h

257 lines
6.5 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 2001 Microsoft Corporation
Module Name:
str2addt.h
Abstract:
Code file for IP string-to-address translation routines.
Author:
Dave Thaler (dthaler) 3-28-2001
Revision History:
IPv4 conversion code originally from old winsock code
IPv6 conversion code originally by Rich Draves (richdr)
--*/
//
// Define some versions of crt functions which are not affected by locale.
//
#define ISDIGIT(c) (_istascii(c) && _istdigit(c))
#define ISLOWER(c) (_istascii(c) && _istlower(c))
#define ISXDIGIT(c) (_istascii(c) && _istxdigit(c))
NTSTATUS
RtlIpv6StringToAddressExT (
IN LPCTSTR AddressString,
OUT struct in6_addr *Address,
OUT PULONG ScopeId,
OUT PUSHORT Port
)
/*++
Routine Description:
Parsing a human-readable string to Address, port number and scope id.
The syntax is address%scope-id or [address%scope-id]:port, where
the scope-id and port are optional.
Note that since the IPv6 address format uses a varying number
of ':' characters, the IPv4 convention of address:port cannot
be supported without the braces.
Arguments:
AddressString - Points to the zero-terminated human-readable string.
Address - Receive address part (in6_addr) of this address.
ScopeId - Receive scopeid of this address. If there is no scope id in
the address string, 0 is returned.
Port - Receive port number of this address. If there is no port number
in the string, 0 is returned. Port is returned in network byte order.
Return Value:
NT_STATUS - STATUS_SUCCESS if successful, NT error code if not.
--*/
{
LPTSTR Terminator;
ULONG TempScopeId;
USHORT TempPort;
TCHAR Ch;
BOOLEAN ExpectBrace;
//
// Quick sanity checks.
//
if ((AddressString == NULL) ||
(Address == NULL) ||
(ScopeId == NULL) ||
(Port == NULL)) {
return STATUS_INVALID_PARAMETER;
}
TempPort = 0;
TempScopeId = 0;
ExpectBrace = FALSE;
if (*AddressString == _T('[')) {
ExpectBrace = TRUE;
AddressString++;
}
if (!NT_SUCCESS(RtlIpv6StringToAddressT(AddressString,
&Terminator,
Address))) {
return STATUS_INVALID_PARAMETER;
}
//
// We have parsed the address, check for a scope-id.
//
if (*Terminator == _T('%')) {
Terminator++;
Ch = *Terminator;
if (!ISDIGIT(Ch)) {
return STATUS_INVALID_PARAMETER;
}
while ((Ch != 0) && (Ch != _T(']'))) {
if (!ISDIGIT(Ch)) {
return STATUS_INVALID_PARAMETER;
}
TempScopeId = 10*TempScopeId + (Ch - _T('0'));
Terminator++;
Ch = *Terminator;
}
}
//
// When we come here, the current char should either be the
// end of the string or ']' if expectbrace is true.
//
if (*Terminator == _T(']')) {
if (!ExpectBrace) {
return STATUS_INVALID_PARAMETER;
}
ExpectBrace = FALSE;
Terminator++;
//
// See if we have a port to parse.
//
if (*Terminator == _T(':')) {
USHORT Base;
Terminator++;
Base = 10;
if (*Terminator == _T('0')) {
Base = 8;
Terminator++;
if (*Terminator == _T('x')) {
Base = 16;
Terminator++;
}
}
Ch = *Terminator;
while (Ch != 0) {
if (ISDIGIT(Ch) && (Ch - _T('0')) < Base) {
TempPort = (TempPort * Base) + (Ch - _T('0'));
} else if (Base == 16 && ISXDIGIT(Ch)) {
TempPort = (TempPort << 4);
TempPort += Ch + 10 - (ISLOWER(Ch)? _T('a') : _T('A'));
} else {
return STATUS_INVALID_PARAMETER;
}
Terminator++;
Ch = *Terminator;
}
}
}
//
// We finished parsing address, scope id and port number. We are expecting the
// end of the string.
//
if ((*Terminator != 0) || ExpectBrace) {
return STATUS_INVALID_PARAMETER;
}
//
// Now construct the address.
//
*Port = RtlUshortByteSwap(TempPort);
*ScopeId = TempScopeId;
return STATUS_SUCCESS;
}
NTSTATUS
RtlIpv4StringToAddressExT (
IN LPCTSTR AddressString,
OUT struct in_addr *Address,
OUT PUSHORT Port
)
/*++
Routine Description:
Parsing a human-readable string to in_addr and port number.
Arguments:
AddressString - Points to the zero-terminated human-readable string.
Address - Receives the address (in_addr) itself.
Port - Receives port number. 0 is returned if there is no port number.
Port is returned in network byte order.
Return Value:
NTSTATUS - STATUS_SUCCESS if successful, error code if not.
--*/
{
LPTSTR Terminator;
USHORT TempPort;
if ((AddressString == NULL) ||
(Address == NULL) ||
(Port == NULL)) {
return STATUS_INVALID_PARAMETER;
}
if (!NT_SUCCESS(RtlIpv4StringToAddressT(AddressString,
FALSE,
&Terminator,
Address))) {
return STATUS_INVALID_PARAMETER;
}
if (*((ULONG*)Address) == INADDR_NONE) {
return STATUS_INVALID_PARAMETER;
}
if (*Terminator == _T(':')) {
TCHAR Ch;
USHORT Base;
Terminator++;
TempPort = 0;
Base = 10;
if (*Terminator == _T('0')) {
Base = 8;
Terminator++;
if (*Terminator == _T('x')) {
Base = 16;
Terminator++;
}
}
while (Ch = *Terminator++) {
if (ISDIGIT(Ch) && (USHORT)(Ch-_T('0')) < Base) {
TempPort = (TempPort * Base) + (Ch - _T('0'));
} else if (Base == 16 && ISXDIGIT(Ch)) {
TempPort = TempPort << 4;
TempPort += Ch + 10 - (ISLOWER(Ch) ? _T('a') : _T('A'));
} else {
return STATUS_INVALID_PARAMETER;
}
}
} else if (*Terminator == 0) {
TempPort = 0;
} else {
return STATUS_INVALID_PARAMETER;
}
*Port = RtlUshortByteSwap(TempPort);
return STATUS_SUCCESS;
}