600 lines
12 KiB
C
600 lines
12 KiB
C
|
/*++
|
|||
|
|
|||
|
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 );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
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 );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
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
|
|||
|
//
|