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.
687 lines
14 KiB
687 lines
14 KiB
/*++
|
|
|
|
Copyright (c) 1996-2000 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
table.c
|
|
|
|
Abstract:
|
|
|
|
Domain Name System (DNS) Library
|
|
|
|
Routines to handle general table lookup.
|
|
|
|
Author:
|
|
|
|
Jim Gilroy (jamesg) December 1996
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
|
|
#include "local.h"
|
|
|
|
#include "time.h"
|
|
|
|
|
|
//
|
|
// Comparison function
|
|
//
|
|
|
|
typedef INT (__cdecl * COMPARISON_FUNCTION)(
|
|
const CHAR *,
|
|
const CHAR *,
|
|
size_t );
|
|
|
|
|
|
|
|
//
|
|
// Table lookup.
|
|
//
|
|
// Many DNS Records have human readable mnemonics for given data values.
|
|
// These are used for data file formats, and display in nslookup or debug
|
|
// output or cmdline tools.
|
|
//
|
|
// To simplify this process, have a single mapping functionality that
|
|
// supports DWORD \ LPSTR mapping tables. Tables for indivual types
|
|
// may then be layered on top of this.
|
|
//
|
|
// Support two table types.
|
|
// VALUE_TABLE_ENTRY is simple value-string mapping
|
|
// FLAG_TABLE_ENTRY is designed for bit field flag mappings where
|
|
// several flag strings might be contained in flag; this table
|
|
// contains additional mask field to allow multi-bit fields
|
|
// within the flag
|
|
//
|
|
|
|
#if 0
|
|
//
|
|
// Defined in local.h here only for reference
|
|
//
|
|
typedef struct
|
|
{
|
|
DWORD dwValue; // flag value
|
|
PCHAR pszString; // string representation of value
|
|
}
|
|
DNS_VALUE_TABLE_ENTRY;
|
|
|
|
typedef struct
|
|
{
|
|
DWORD dwFlag; // flag value
|
|
DWORD dwMask; // flag value mask
|
|
PCHAR pszString; // string representation of value
|
|
}
|
|
DNS_FLAG_TABLE_ENTRY;
|
|
|
|
// Error return on unmatched string
|
|
|
|
#define DNS_TABLE_LOOKUP_ERROR (-1)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
DWORD
|
|
Dns_ValueForString(
|
|
IN DNS_VALUE_TABLE_ENTRY * Table,
|
|
IN BOOL fIgnoreCase,
|
|
IN PCHAR pchName,
|
|
IN INT cchNameLength
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Retrieve value for given string.
|
|
|
|
Arguments:
|
|
|
|
Table - table with value\string mapping
|
|
|
|
fIgnoreCase - TRUE if case-insensitive string lookup
|
|
|
|
pchName - ptr to string
|
|
|
|
cchNameLength - length of string
|
|
|
|
Return Value:
|
|
|
|
Flag value corresponding to string, if found.
|
|
DNS_TABLE_LOOKUP_ERROR otherwise.
|
|
|
|
--*/
|
|
{
|
|
INT i = 0;
|
|
// INT (* pcompareFunction)( const char *, const char *, size_t );
|
|
COMPARISON_FUNCTION pcompareFunction;
|
|
|
|
|
|
//
|
|
// if not given get string length
|
|
//
|
|
|
|
if ( !cchNameLength )
|
|
{
|
|
cchNameLength = strlen( pchName );
|
|
}
|
|
|
|
//
|
|
// determine comparison routine
|
|
//
|
|
|
|
if ( fIgnoreCase )
|
|
{
|
|
pcompareFunction = _strnicmp;
|
|
}
|
|
else
|
|
{
|
|
pcompareFunction = strncmp;
|
|
}
|
|
|
|
//
|
|
// find value matching name
|
|
//
|
|
|
|
while( Table[i].pszString != NULL )
|
|
{
|
|
if ( pcompareFunction( pchName, Table[i].pszString, cchNameLength ) == 0 )
|
|
{
|
|
return( Table[i].dwValue );
|
|
}
|
|
i++;
|
|
}
|
|
|
|
return( (DWORD)DNS_TABLE_LOOKUP_ERROR );
|
|
}
|
|
|
|
|
|
|
|
DWORD
|
|
Dns_ValueForStringEx(
|
|
IN DNS_VALUE_TABLE_ENTRY * Table,
|
|
IN BOOL fIgnoreCase,
|
|
IN DNS_CHARSET InCharSet,
|
|
IN PCHAR pchName,
|
|
IN INT cchNameLength
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Retrieve value for given string.
|
|
|
|
Arguments:
|
|
|
|
Table - table with value\string mapping
|
|
|
|
fIgnoreCase - TRUE if case-insensitive string lookup
|
|
|
|
InCharSet - input string char set
|
|
|
|
pchName - ptr to string
|
|
|
|
cchNameLength - length of string
|
|
|
|
Return Value:
|
|
|
|
Flag value corresponding to string, if found.
|
|
DNS_TABLE_LOOKUP_ERROR otherwise.
|
|
|
|
--*/
|
|
{
|
|
DWORD result;
|
|
PSTR pnameAlloc;
|
|
|
|
|
|
//
|
|
// convert
|
|
//
|
|
|
|
#if 0
|
|
if ( InCharSet != 0 &&
|
|
InCharSet != DnsCharSetAnsi )
|
|
{
|
|
#endif
|
|
pnameAlloc = Dns_StringCopyAllocate(
|
|
pchName,
|
|
cchNameLength,
|
|
InCharSet,
|
|
DnsCharSetAnsi );
|
|
|
|
//
|
|
// do the lookup
|
|
//
|
|
|
|
result = Dns_ValueForString(
|
|
Table,
|
|
fIgnoreCase,
|
|
pnameAlloc,
|
|
0 // null terminated
|
|
);
|
|
|
|
//
|
|
// cleanup
|
|
//
|
|
|
|
FREE_HEAP( pnameAlloc );
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
|
|
PCHAR
|
|
Dns_GetStringForValue(
|
|
IN DNS_VALUE_TABLE_ENTRY * Table,
|
|
IN DWORD dwValue
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Retrieve string representation of given value.
|
|
|
|
Arguments:
|
|
|
|
Table - table with value\string mapping
|
|
|
|
dwValue - value to map to strings
|
|
|
|
Return Value:
|
|
|
|
Ptr to mapping mneumonic string.
|
|
NULL if unknown mapping type.
|
|
|
|
--*/
|
|
{
|
|
INT i = 0;
|
|
|
|
//
|
|
// check all supported values for match
|
|
//
|
|
|
|
while( Table[i].pszString != NULL )
|
|
{
|
|
if ( dwValue == Table[i].dwValue )
|
|
{
|
|
return( Table[i].pszString );
|
|
}
|
|
i++;
|
|
}
|
|
return( NULL );
|
|
}
|
|
|
|
|
|
|
|
DWORD
|
|
Dns_FlagForString(
|
|
IN DNS_FLAG_TABLE_ENTRY * Table,
|
|
IN BOOL fIgnoreCase,
|
|
IN PCHAR pchName,
|
|
IN INT cchNameLength
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Retrieve flag value for given string.
|
|
|
|
This may be called repeatedly with additional strings and OR the result
|
|
together to build flag with independent bit settings.
|
|
|
|
Arguments:
|
|
|
|
Table - table with value\string mapping
|
|
|
|
fIgnoreCase - TRUE if case-insensitive string lookup
|
|
|
|
pchName - ptr to string
|
|
|
|
cchNameLength - length of string
|
|
|
|
Return Value:
|
|
|
|
Flag value corresponding to string, if found.
|
|
DNS_TABLE_LOOKUP_ERROR otherwise.
|
|
|
|
--*/
|
|
{
|
|
INT i = 0;
|
|
|
|
//
|
|
// if not given get string length
|
|
//
|
|
|
|
if ( !cchNameLength )
|
|
{
|
|
cchNameLength = strlen( pchName );
|
|
}
|
|
|
|
//
|
|
// check all supported values for name match
|
|
//
|
|
|
|
if ( fIgnoreCase )
|
|
{
|
|
while( Table[i].pszString != NULL )
|
|
{
|
|
if ( cchNameLength == (INT)strlen( Table[i].pszString )
|
|
&&
|
|
! _strnicmp( pchName, Table[i].pszString, cchNameLength ) )
|
|
{
|
|
return( Table[i].dwFlag );
|
|
}
|
|
i++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
while( Table[i].pszString != NULL )
|
|
{
|
|
if ( cchNameLength == (INT)strlen( Table[i].pszString )
|
|
&&
|
|
! strncmp( pchName, Table[i].pszString, cchNameLength ) )
|
|
{
|
|
return( Table[i].dwFlag );
|
|
}
|
|
i++;
|
|
}
|
|
}
|
|
|
|
return( (DWORD) DNS_TABLE_LOOKUP_ERROR );
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
DnsPrint_ValueTable(
|
|
IN PRINT_ROUTINE PrintRoutine,
|
|
IN PPRINT_CONTEXT pPrintContext,
|
|
IN LPSTR pszHeader,
|
|
IN PDNS_VALUE_TABLE Table
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Print value table.
|
|
|
|
Arguments:
|
|
|
|
PrintRoutine - routine to print with
|
|
|
|
pPrintContext - print context
|
|
|
|
pszHeader - header to print
|
|
|
|
Table - value table to print
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
DWORD i = 0;
|
|
|
|
if ( !pszHeader )
|
|
{
|
|
pszHeader = "Table";
|
|
}
|
|
|
|
if ( ! pszHeader )
|
|
{
|
|
PrintRoutine(
|
|
pPrintContext,
|
|
"%s NULL value table to print",
|
|
pszHeader );
|
|
}
|
|
|
|
//
|
|
// print each value in table
|
|
//
|
|
|
|
DnsPrint_Lock();
|
|
|
|
PrintRoutine(
|
|
pPrintContext,
|
|
"%s\n",
|
|
pszHeader );
|
|
|
|
while( Table[i].pszString != NULL )
|
|
{
|
|
PrintRoutine(
|
|
pPrintContext,
|
|
"\t%40s\t\t%08x\n",
|
|
Table[i].pszString,
|
|
Table[i].dwValue );
|
|
i++;
|
|
}
|
|
|
|
DnsPrint_Unlock();
|
|
}
|
|
|
|
|
|
|
|
PCHAR
|
|
Dns_WriteStringsForFlag(
|
|
IN DNS_FLAG_TABLE_ENTRY * Table,
|
|
IN DWORD dwFlag,
|
|
IN OUT PCHAR pchFlag
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Retrieve flag string(s) corresponding to a given flag value.
|
|
|
|
This function is specifically for mapping a flag value into the
|
|
corresponding flag mnemonics.
|
|
|
|
No attempt is made to insure that every bit of dwValue is mapped,
|
|
nor are bits eliminated as they are mapped. Every value in table
|
|
that exactly matches bits in the table is returned.
|
|
|
|
Arguments:
|
|
|
|
Table - table with value\string mapping
|
|
|
|
dwFlag - flag value to map to strings
|
|
|
|
pchFlag - buffer to write flag to
|
|
|
|
Return Value:
|
|
|
|
Ptr to next location in pchFlag buffer.
|
|
If this is same as input, then no strings were written.
|
|
|
|
--*/
|
|
{
|
|
INT i = 0;
|
|
|
|
// init buffer for no-match
|
|
|
|
DNS_ASSERT( pchFlag != NULL );
|
|
*pchFlag = 0;
|
|
|
|
//
|
|
// check all supported flags types for name match
|
|
// - note comparing flag within mask to allow match of multi-bit
|
|
// flags
|
|
//
|
|
|
|
while( Table[i].pszString != NULL )
|
|
{
|
|
if ( (dwFlag & Table[i].dwMask) == Table[i].dwFlag )
|
|
{
|
|
pchFlag += sprintf( pchFlag, "%s ", Table[i].pszString );
|
|
}
|
|
i++;
|
|
}
|
|
return( pchFlag );
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
// Specific simple tables
|
|
//
|
|
|
|
//
|
|
// RnR Flag mappings
|
|
//
|
|
|
|
DNS_VALUE_TABLE_ENTRY RnrLupFlagTable[] =
|
|
{
|
|
LUP_DEEP , "LUP_DEEP" ,
|
|
LUP_CONTAINERS , "LUP_CONTAINERS" ,
|
|
LUP_NOCONTAINERS , "LUP_NOCONTAINERS" ,
|
|
LUP_RETURN_NAME , "LUP_RETURN_NAME" ,
|
|
LUP_RETURN_TYPE , "LUP_RETURN_TYPE" ,
|
|
LUP_RETURN_VERSION , "LUP_RETURN_VERSION" ,
|
|
LUP_RETURN_COMMENT , "LUP_RETURN_COMMENT" ,
|
|
LUP_RETURN_ADDR , "LUP_RETURN_ADDR" ,
|
|
LUP_RETURN_BLOB , "LUP_RETURN_BLOB" ,
|
|
LUP_RETURN_ALIASES , "LUP_RETURN_ALIASES" ,
|
|
LUP_RETURN_QUERY_STRING , "LUP_RETURN_QUERY_STRING" ,
|
|
LUP_RETURN_ALL , "LUP_RETURN_ALL" ,
|
|
LUP_RES_SERVICE , "LUP_RES_SERVICE" ,
|
|
LUP_FLUSHCACHE , "LUP_FLUSHCACHE" ,
|
|
LUP_FLUSHPREVIOUS , "LUP_FLUSHPREVIOUS" ,
|
|
|
|
0, NULL,
|
|
};
|
|
|
|
|
|
|
|
DWORD
|
|
Dns_RnrLupFlagForString(
|
|
IN PCHAR pchName,
|
|
IN INT cchNameLength
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Retrieve RnR LUP flag corresponding to string.
|
|
|
|
Arguments:
|
|
|
|
pchName - ptr to string
|
|
cchNameLength - length of string
|
|
|
|
Return Value:
|
|
|
|
Flag corresponding to string, if found.
|
|
Zero otherwise.
|
|
|
|
--*/
|
|
{
|
|
return Dns_ValueForString(
|
|
RnrLupFlagTable,
|
|
FALSE, // always upper case
|
|
pchName,
|
|
cchNameLength );
|
|
}
|
|
|
|
|
|
|
|
PCHAR
|
|
Dns_GetRnrLupFlagString(
|
|
IN DWORD dwFlag
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Get string corresponding to a given RnR LUP flag.
|
|
|
|
Arguments:
|
|
|
|
dwFlag -- flag
|
|
|
|
Return Value:
|
|
|
|
Ptr to flag mneumonic string.
|
|
NULL if unknown flag.
|
|
|
|
--*/
|
|
{
|
|
return Dns_GetStringForValue(
|
|
RnrLupFlagTable,
|
|
dwFlag );
|
|
}
|
|
|
|
|
|
//
|
|
// RnR Name Space ID mappings
|
|
//
|
|
|
|
DNS_VALUE_TABLE_ENTRY RnrNameSpaceMappingTable[] =
|
|
{
|
|
NS_ALL , "NS_ALL" ,
|
|
//NS_DEFAULT , "NS_DEFAULT" ,
|
|
NS_SAP , "NS_SAP" ,
|
|
NS_NDS , "NS_NDS" ,
|
|
NS_PEER_BROWSE , "NS_PEER_BROWSEE" ,
|
|
NS_SLP , "NS_SLP" ,
|
|
NS_DHCP , "NS_DHCP" ,
|
|
NS_TCPIP_LOCAL , "NS_TCPIP_LOCAL" ,
|
|
NS_TCPIP_HOSTS , "NS_TCPIP_HOSTS" ,
|
|
NS_DNS , "NS_DNS" ,
|
|
NS_NETBT , "NS_NETBT" ,
|
|
NS_WINS , "NS_WINS" ,
|
|
NS_NLA , "NS_NLA" ,
|
|
NS_NBP , "NS_NBP" ,
|
|
NS_MS , "NS_MS" ,
|
|
NS_STDA , "NS_STDA" ,
|
|
NS_NTDS , "NS_NTDS" ,
|
|
NS_X500 , "NS_X500" ,
|
|
NS_NIS , "NS_NIS" ,
|
|
NS_NISPLUS , "NS_NISPLUS" ,
|
|
NS_WRQ , "NS_WRQ" ,
|
|
NS_NETDES , "NS_NETDES" ,
|
|
|
|
0, NULL,
|
|
};
|
|
|
|
|
|
DWORD
|
|
Dns_RnrNameSpaceIdForString(
|
|
IN PCHAR pchName,
|
|
IN INT cchNameLength
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Retrieve RnR Name Space Id corresponding to string.
|
|
|
|
Arguments:
|
|
|
|
pchName - ptr to string
|
|
cchNameLength - length of string
|
|
|
|
Return Value:
|
|
|
|
Name space ID corresponding to string, if found.
|
|
Zero otherwise.
|
|
|
|
--*/
|
|
{
|
|
return Dns_ValueForString(
|
|
RnrNameSpaceMappingTable,
|
|
FALSE, // always upper case
|
|
pchName,
|
|
cchNameLength );
|
|
}
|
|
|
|
|
|
DWORD
|
|
Dns_RnrNameSpaceIdForStringW(
|
|
IN PWSTR pwsName
|
|
)
|
|
{
|
|
return Dns_ValueForStringEx(
|
|
RnrNameSpaceMappingTable,
|
|
FALSE, // always upper case
|
|
DnsCharSetUnicode,
|
|
(PCHAR) pwsName,
|
|
0 );
|
|
}
|
|
|
|
|
|
|
|
PCHAR
|
|
Dns_GetRnrNameSpaceIdString(
|
|
IN DWORD dwFlag
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Get string corresponding to a given RnR name space id.
|
|
|
|
Arguments:
|
|
|
|
dwFlag -- flag
|
|
|
|
Return Value:
|
|
|
|
Ptr to name space mneumonic string.
|
|
NULL if unknown flag.
|
|
|
|
--*/
|
|
{
|
|
return Dns_GetStringForValue(
|
|
RnrNameSpaceMappingTable,
|
|
dwFlag );
|
|
}
|
|
|
|
//
|
|
// End table.c
|
|
//
|