|
|
///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1997, Microsoft Corp. All rights reserved.
//
// FILE
//
// inet.c
//
// SYNOPSIS
//
// Implements the functions ias_inet_addr and ias_inet_ntoa.
//
// MODIFICATION HISTORY
//
// 09/17/1997 Original version.
// 02/04/1998 Added ias_inet_htow.
// 02/25/1998 Rewritten to use TCHAR macros.
//
///////////////////////////////////////////////////////////////////////////////
#include <tchar.h>
//////////
// Sentinel to indicate an invalid address.
//////////
#define INVALID_ADDRESS (0xFFFFFFFF)
//////////
// Macro to test if a character is a digit.
//////////
#define isdigit(p) ((_TUCHAR)(p - _T('0')) <= 9)
//////////
// Macro to strip whitespace characters
//////////
#define STRIP_WHITESPACE(p) \
(p) += _tcsspn((p), _T(" \t"))
//////////
// Macro to strip one byte of an IP address from a character string.
// 'p' pointer to the string to be parsed
// 'ul' unsigned long that will receive the result.
//////////
#define STRIP_BYTE(p,ul) { \
if (!isdigit(*p)) goto error; \ ul = *p++ - _T('0'); \ if (isdigit(*p)) { \ ul *= 10; ul += *p++ - _T('0'); \ if (isdigit(*p)) { \ ul *= 10; ul += *p++ - _T('0'); \ } \ } \ if (ul > 0xff) goto error; \ }
//////////
// Macro to strip a subnet width.
// 'p' pointer to the string to be parsed
// 'ul' unsigned long that will receive the result.
//////////
#define STRIP_WIDTH(p,ul) { \
if (!isdigit(*p)) goto error; \ ul = *p++ - _T('0'); \ if (isdigit(*p)) { \ ul *= 10; ul += *p++ - _T('0'); \ } \ if (ul > 32) goto error; \ }
//////////
// Helper function to parse a dotted decimal address.
//////////
static unsigned long __stdcall StringToAddress( const _TCHAR* cp, const _TCHAR** endptr ) { unsigned long token; unsigned long addr;
STRIP_WHITESPACE(cp);
STRIP_BYTE(cp,addr); if (*cp++ != _T('.')) goto error;
STRIP_BYTE(cp,token); if (*cp++ != _T('.')) goto error; addr <<= 8; addr |= token;
STRIP_BYTE(cp,token); if (*cp++ != _T('.')) goto error; addr <<= 8; addr |= token;
STRIP_BYTE(cp,token); addr <<= 8; addr |= token;
if (endptr) { *endptr = cp; } return addr;
error: if (endptr) { *endptr = cp; } return INVALID_ADDRESS; }
///////////////////////////////////////////////////////////////////////////////
//
// FUNCTION
//
// ias_inet_addr
//
// DESCRIPTION
//
// This function is similar to the WinSock inet_addr function (q.v.) except
// it returns the address in host order and it can operate on both ANSI
// and UNICODE strings.
//
///////////////////////////////////////////////////////////////////////////////
unsigned long __stdcall ias_inet_addr(const _TCHAR* cp) { unsigned long address; const _TCHAR* end;
address = StringToAddress(cp, &end);
STRIP_WHITESPACE(end);
return (*end == _T('\0')) ? address : INVALID_ADDRESS; }
///////////////////////////////////////////////////////////////////////////////
//
// FUNCTION
//
// IASStringToSubNet
//
// DESCRIPTION
//
// Similar to ias_inet_addr except it also parses an optional subnet width.
//
///////////////////////////////////////////////////////////////////////////////
unsigned long __stdcall IASStringToSubNet( const _TCHAR* cp, unsigned long* widthptr ) { unsigned long address, width; const _TCHAR* end;
address = StringToAddress(cp, &end);
if (*end == _T('/')) { ++end; STRIP_WIDTH(end,width); } else { width = 32; }
STRIP_WHITESPACE(end);
if (*end != _T('\0')) { goto error; }
if (widthptr) { *widthptr = width; }
return address;
error: return INVALID_ADDRESS; }
int __stdcall IASIsStringSubNet( const _TCHAR* cp ) { unsigned long width; return (IASStringToSubNet(cp, &width) != INVALID_ADDRESS) && (width != 32); }
//////////
// Macro to shove one byte of an IP address into a character string.
// 'p' pointer to the destination string.
// 'ul' value to be shoved.
//////////
#define SHOVE_BYTE(p, ul) { \
*--p = _T('0') + (_TCHAR)(ul % 10); \ if (ul /= 10) { \ *--p = _T('0') + (_TCHAR)(ul % 10); \ if (ul /= 10) { \ *--p = _T('0') + (_TCHAR)(ul % 10); \ } \ } \ }
///////////////////////////////////////////////////////////////////////////////
//
// FUNCTION
//
// ias_inet_ntoa
//
// DESCRIPTION
//
// This function uses the supplied buffer to convert a host order IPv4
// network address to dotted-decimal format.
//
///////////////////////////////////////////////////////////////////////////////
_TCHAR* __stdcall ias_inet_ntoa(unsigned long addr, _TCHAR* dst) { unsigned long token; _TCHAR buffer[16], *p;
*(p = buffer + 15) = _T('\0');
token = (addr ) & 0xff; SHOVE_BYTE(p, token); *--p = _T('.');
token = (addr >> 8) & 0xff; SHOVE_BYTE(p, token); *--p = _T('.');
token = (addr >> 16) & 0xff; SHOVE_BYTE(p, token); *--p = _T('.');
token = (addr >> 24) & 0xff; SHOVE_BYTE(p, token);
return _tcscpy(dst, p); }
|