Source code of Windows XP (NT5)
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
/*++
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; }
|