5058 lines
104 KiB
C
5058 lines
104 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1996-2001 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
dnsup.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
Domain Name System (DNS) Update Client
|
|||
|
|
|||
|
Main program.
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Jim Gilroy (jamesg) October, 1996
|
|||
|
|
|||
|
Environment:
|
|||
|
|
|||
|
User Mode - Win32
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include "..\dnsapi\local.h"
|
|||
|
#if 0
|
|||
|
#include <windows.h>
|
|||
|
#include <winsock2.h>
|
|||
|
#include <stdlib.h>
|
|||
|
#include <stdio.h> // printf()
|
|||
|
#include <string.h> // strtoul()
|
|||
|
|
|||
|
#include <windns.h>
|
|||
|
#include <dnsapi.h>
|
|||
|
|
|||
|
#include "dnslib.h"
|
|||
|
#include "..\resolver\idl\resrpc.h"
|
|||
|
#include "dnsapip.h"
|
|||
|
#include "dnslibp.h"
|
|||
|
#endif
|
|||
|
|
|||
|
#include "svcguid.h" // RnR guids
|
|||
|
|
|||
|
|
|||
|
// Use dnslib memory routines
|
|||
|
#if 0
|
|||
|
#define ALLOCATE_HEAP(iSize) Dns_Alloc(iSize)
|
|||
|
#define ALLOCATE_HEAP_ZERO(iSize) Dns_AllocZero(iSize)
|
|||
|
#define REALLOCATE_HEAP(pMem,iSize) Dns_Realloc((pMem),(iSize))
|
|||
|
#define FREE_HEAP(pMem) Dns_Free(pMem)
|
|||
|
#endif
|
|||
|
|
|||
|
// Debug flag
|
|||
|
|
|||
|
DWORD LocalDebugFlag;
|
|||
|
|
|||
|
//
|
|||
|
// Printing
|
|||
|
//
|
|||
|
|
|||
|
#define dnsup_PrintRoutine ((PRINT_ROUTINE) fprintf)
|
|||
|
|
|||
|
#define dnsup_PrintContext ((PPRINT_CONTEXT) stdout)
|
|||
|
|
|||
|
//
|
|||
|
// Special names and buffers
|
|||
|
//
|
|||
|
|
|||
|
PCHAR SingleLongName = "longname";
|
|||
|
CHAR SeLongName[] = "longname";
|
|||
|
|
|||
|
PCHAR LongName = ( "longname"
|
|||
|
".label22222222222222222222222222222222222222222222222222"
|
|||
|
".label33333333333333333333333333333333333333333333333333"
|
|||
|
".label44444444444444444444444444444444444444444444444444"
|
|||
|
".label55555555555555555555555555555555555555555555555555"
|
|||
|
".label66666666666666666666666666666666666666666666666666.");
|
|||
|
|
|||
|
#define LONG_LABEL_NAME ("longlabel" \
|
|||
|
".longlabel2222222222222222222222222222222222222222222222222222222222")
|
|||
|
|
|||
|
CHAR NameBuffer[ DNS_MAX_NAME_BUFFER_LENGTH ];
|
|||
|
|
|||
|
CHAR AddressBuffer[ sizeof(DNS_IP6_ADDRESS) ];
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Quit or Exit status
|
|||
|
//
|
|||
|
|
|||
|
#define ERROR_DNSUP_QUIT ((DNS_STATUS)(0x87654321))
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Command table setup
|
|||
|
//
|
|||
|
|
|||
|
typedef DNS_STATUS (* COMMAND_FUNCTION)( DWORD Argc, CHAR** Argv);
|
|||
|
|
|||
|
typedef struct _COMMAND_INFO
|
|||
|
{
|
|||
|
PSTR pszCommandName;
|
|||
|
PSTR pszDescription;
|
|||
|
COMMAND_FUNCTION pCommandFunction;
|
|||
|
}
|
|||
|
COMMAND_INFO, *LPCOMMAND_INFO;
|
|||
|
|
|||
|
//
|
|||
|
// Note, command table is at bottom of file to
|
|||
|
// avoid need for prototyping all the functions
|
|||
|
//
|
|||
|
|
|||
|
extern COMMAND_INFO GlobalCommandInfo[];
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
COMMAND_FUNCTION
|
|||
|
GetCommandFunction(
|
|||
|
IN PSTR pszCommandName
|
|||
|
)
|
|||
|
{
|
|||
|
DWORD i;
|
|||
|
|
|||
|
//
|
|||
|
// find command in list matching string
|
|||
|
//
|
|||
|
|
|||
|
i = 0;
|
|||
|
while( GlobalCommandInfo[i].pszCommandName )
|
|||
|
{
|
|||
|
if( _stricmp(
|
|||
|
pszCommandName,
|
|||
|
GlobalCommandInfo[i].pszCommandName ) == 0 )
|
|||
|
{
|
|||
|
return( GlobalCommandInfo[i].pCommandFunction );
|
|||
|
}
|
|||
|
i++;
|
|||
|
}
|
|||
|
return( NULL );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Print utils
|
|||
|
//
|
|||
|
|
|||
|
VOID
|
|||
|
PrintCommands(
|
|||
|
VOID
|
|||
|
)
|
|||
|
{
|
|||
|
DWORD i;
|
|||
|
|
|||
|
//
|
|||
|
// print all commands in list
|
|||
|
//
|
|||
|
|
|||
|
i = 0;
|
|||
|
while( GlobalCommandInfo[i].pszCommandName )
|
|||
|
{
|
|||
|
printf(
|
|||
|
" %10s (%s)\n",
|
|||
|
GlobalCommandInfo[i].pszCommandName,
|
|||
|
GlobalCommandInfo[i].pszDescription );
|
|||
|
i++;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
PrintDnsQueryFlags(
|
|||
|
VOID
|
|||
|
)
|
|||
|
{
|
|||
|
DWORD i;
|
|||
|
|
|||
|
//
|
|||
|
// print query flags
|
|||
|
//
|
|||
|
|
|||
|
printf(
|
|||
|
"DNS Query flags:\n"
|
|||
|
"\tDNS_QUERY_STANDARD = 0x%x\n"
|
|||
|
"\tDNS_QUERY_ACCEPT_PARTIAL_UDP = 0x%x\n"
|
|||
|
"\tDNS_QUERY_USE_TCP_ONLY = 0x%x\n"
|
|||
|
"\tDNS_QUERY_NO_RECURSION = 0x%x\n"
|
|||
|
"\tDNS_QUERY_BYPASS_CACHE = 0x%x\n"
|
|||
|
"\tDNS_QUERY_NO_WIRE_QUERY = 0x%x\n"
|
|||
|
"\tDNS_QUERY_NO_HOSTS_FILE = 0x%x\n"
|
|||
|
"\tDNS_QUERY_NO_LOCAL_NAME = 0x%x\n",
|
|||
|
DNS_QUERY_STANDARD ,
|
|||
|
DNS_QUERY_ACCEPT_PARTIAL_UDP ,
|
|||
|
DNS_QUERY_USE_TCP_ONLY ,
|
|||
|
DNS_QUERY_NO_RECURSION ,
|
|||
|
DNS_QUERY_BYPASS_CACHE ,
|
|||
|
DNS_QUERY_NO_WIRE_QUERY ,
|
|||
|
DNS_QUERY_NO_HOSTS_FILE ,
|
|||
|
DNS_QUERY_NO_LOCAL_NAME
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Optional DNS server list to use
|
|||
|
//
|
|||
|
// Overides default list on this client for some commands
|
|||
|
//
|
|||
|
|
|||
|
PIP_ARRAY pDnsServerArray = NULL;
|
|||
|
|
|||
|
DNS_STATUS
|
|||
|
readNameServers(
|
|||
|
IN PIP_ARRAY * ppIpServers,
|
|||
|
IN DWORD * pArgc,
|
|||
|
IN PSTR ** pArgv
|
|||
|
)
|
|||
|
{
|
|||
|
DWORD argc = *pArgc;
|
|||
|
PCHAR * argv = *pArgv;
|
|||
|
PCHAR * startArgv;
|
|||
|
PCHAR arg;
|
|||
|
CHAR ch;
|
|||
|
IP_ADDRESS ipserver;
|
|||
|
PIP_ARRAY aipservers = NULL;
|
|||
|
DWORD countServers = 0;
|
|||
|
DWORD i;
|
|||
|
|
|||
|
//
|
|||
|
// -n / -N denotes DNS server
|
|||
|
// server IP immediate follows (in same arg)
|
|||
|
//
|
|||
|
|
|||
|
startArgv = argv;
|
|||
|
|
|||
|
while ( argc )
|
|||
|
{
|
|||
|
arg = argv[0];
|
|||
|
if ( '-' == *arg++ )
|
|||
|
{
|
|||
|
ch = *arg++;
|
|||
|
if ( ch == 'n' || ch == 'N' )
|
|||
|
{
|
|||
|
countServers++;
|
|||
|
argc--;
|
|||
|
argv++;
|
|||
|
continue;
|
|||
|
}
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// found servers
|
|||
|
// - allocate IP array
|
|||
|
// - parse servers into it
|
|||
|
// - reset callers Argc, Argv
|
|||
|
//
|
|||
|
|
|||
|
if ( countServers )
|
|||
|
{
|
|||
|
*pArgc = argc;
|
|||
|
*pArgv = argv;
|
|||
|
argv = startArgv;
|
|||
|
|
|||
|
aipservers = DnsCreateIpArray( countServers );
|
|||
|
if ( ! aipservers )
|
|||
|
{
|
|||
|
return( ERROR_OUTOFMEMORY );
|
|||
|
}
|
|||
|
|
|||
|
for (i=0; i<(INT)countServers; i++)
|
|||
|
{
|
|||
|
arg = (*argv++) + 2;
|
|||
|
if ( *arg == '.' )
|
|||
|
{
|
|||
|
arg = "127.0.0.1";
|
|||
|
}
|
|||
|
ipserver = inet_addr( arg );
|
|||
|
if ( ipserver == INADDR_NONE )
|
|||
|
{
|
|||
|
printf( "ERROR: name server IP (in arg %s) is bogus\n", arg );
|
|||
|
return( ERROR_INVALID_PARAMETER );
|
|||
|
}
|
|||
|
IF_DNSDBG( INIT )
|
|||
|
{
|
|||
|
DNS_PRINT((
|
|||
|
"Read name server address from arg %s.\n",
|
|||
|
arg ));
|
|||
|
}
|
|||
|
aipservers->AddrArray[i] = ipserver;
|
|||
|
}
|
|||
|
|
|||
|
DnsDbg_IpArray(
|
|||
|
"Name servers to register with\n",
|
|||
|
NULL,
|
|||
|
aipservers );
|
|||
|
}
|
|||
|
|
|||
|
*ppIpServers = aipservers;
|
|||
|
return( ERROR_SUCCESS );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DNS_STATUS
|
|||
|
ProcessCommandLine(
|
|||
|
IN INT Argc,
|
|||
|
IN CHAR ** Argv
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Process command in Argc\Argv form.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Argc -- arg count
|
|||
|
|
|||
|
Argv -- argument list
|
|||
|
Argv[0] -- dnsup
|
|||
|
Argv[1] -- Command to execute
|
|||
|
Argv[2...] -- arguments to command
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Return from the desired command.
|
|||
|
Usually a pass through of the return code from DNS Update API call.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
DNS_STATUS status;
|
|||
|
COMMAND_FUNCTION pcommandFunction;
|
|||
|
PCHAR pcommand;
|
|||
|
|
|||
|
if ( Argc < 1 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
DNS_PRINT(( "Argc = %d\n", Argc ));
|
|||
|
|
|||
|
//
|
|||
|
// check for server list
|
|||
|
//
|
|||
|
|
|||
|
status = readNameServers(
|
|||
|
& pDnsServerArray,
|
|||
|
& Argc,
|
|||
|
& Argv );
|
|||
|
if ( status != ERROR_SUCCESS )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// next param is command
|
|||
|
// - optionally decorated with leading "-"
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc < 1 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
pcommand = Argv[0];
|
|||
|
if ( *pcommand == '-' )
|
|||
|
{
|
|||
|
pcommand++;
|
|||
|
}
|
|||
|
|
|||
|
pcommandFunction = GetCommandFunction( pcommand );
|
|||
|
if ( ! pcommandFunction )
|
|||
|
{
|
|||
|
status = ERROR_INVALID_PARAMETER;
|
|||
|
printf( "Unknown Command Specified -- type dnsup -?.\n" );
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// dispatch to processor for this command
|
|||
|
// - skip over command argv
|
|||
|
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
status = pcommandFunction( Argc, Argv );
|
|||
|
|
|||
|
if ( status == ERROR_SUCCESS ||
|
|||
|
status == ERROR_DNSUP_QUIT )
|
|||
|
{
|
|||
|
printf( "Command successfully completed.\n" );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
printf( "Command failed, %d (%ul)\n", status, status );
|
|||
|
}
|
|||
|
return( status );
|
|||
|
|
|||
|
Usage:
|
|||
|
|
|||
|
printf(
|
|||
|
"DnsUp command line:\n"
|
|||
|
"\t[-n<Server IP List>] -<Command> [Command Parameters].\n"
|
|||
|
"\t<Server IP List> is a list of one or more DNS server IP addresses\n"
|
|||
|
"\t\toverriding the default list on this client\n"
|
|||
|
"Commands:\n"
|
|||
|
);
|
|||
|
PrintCommands();
|
|||
|
return( ERROR_INVALID_PARAMETER );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
InteractiveLoop(
|
|||
|
VOID
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Interactive loop.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
#define MAX_ARG_COUNT 50
|
|||
|
|
|||
|
DNS_STATUS status;
|
|||
|
INT argc;
|
|||
|
CHAR * argv[ MAX_ARG_COUNT ];
|
|||
|
CHAR lineBuffer[500];
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// loop taking command params
|
|||
|
//
|
|||
|
|
|||
|
while ( 1 )
|
|||
|
{
|
|||
|
printf( "\n> " );
|
|||
|
|
|||
|
// read next command line
|
|||
|
|
|||
|
gets( lineBuffer );
|
|||
|
|
|||
|
argc = Dns_TokenizeString(
|
|||
|
lineBuffer,
|
|||
|
argv,
|
|||
|
MAX_ARG_COUNT );
|
|||
|
|
|||
|
DNS_PRINT(( "argc = %d\n", argc ));
|
|||
|
|
|||
|
IF_DNSDBG( INIT )
|
|||
|
{
|
|||
|
DnsDbg_Argv(
|
|||
|
NULL,
|
|||
|
argv,
|
|||
|
argc,
|
|||
|
FALSE // not unicode
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
// process next command line
|
|||
|
|
|||
|
status = ProcessCommandLine(
|
|||
|
argc,
|
|||
|
argv );
|
|||
|
|
|||
|
if ( status == ERROR_DNSUP_QUIT )
|
|||
|
{
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
LONG
|
|||
|
__cdecl
|
|||
|
main(
|
|||
|
IN INT Argc,
|
|||
|
IN CHAR ** Argv
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
DnsUp program entry point.
|
|||
|
|
|||
|
Executes specified command corresponding to a DNS update API operation.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Argc -- arg count
|
|||
|
|
|||
|
Argv -- argument list
|
|||
|
Argv[0] -- dnsup
|
|||
|
Argv[1] -- Command to execute
|
|||
|
Argv[2...] -- arguments to command
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Zero if successful.
|
|||
|
1 on error.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
DNS_STATUS status;
|
|||
|
|
|||
|
//
|
|||
|
// initialize debug
|
|||
|
//
|
|||
|
|
|||
|
Dns_StartDebugEx(
|
|||
|
0, // no flag value
|
|||
|
"dnsup.flag", // read flag from file
|
|||
|
NULL, //&LocalDebugFlag,
|
|||
|
"dnsup.log", // log to file
|
|||
|
0, // no wrap limit
|
|||
|
FALSE, // don't use existing global
|
|||
|
FALSE,
|
|||
|
TRUE // make this file global
|
|||
|
);
|
|||
|
|
|||
|
DNS_PRINT(( "*pDnsDebugFlag = %08x\n", *pDnsDebugFlag ));
|
|||
|
//DNS_PRINT(( "LocalDebugFlag = %08x\n", LocalDebugFlag ));
|
|||
|
|
|||
|
if ( Argc < 1 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
DNS_PRINT(( "Argc = %d\n", Argc ));
|
|||
|
|
|||
|
// skip "dnsup" argument
|
|||
|
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
|
|||
|
//
|
|||
|
// interactive mode?
|
|||
|
// - if no command, just open interactively
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc == 0 )
|
|||
|
{
|
|||
|
InteractiveLoop();
|
|||
|
status = ERROR_SUCCESS;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
status = ProcessCommandLine(
|
|||
|
Argc,
|
|||
|
Argv );
|
|||
|
}
|
|||
|
|
|||
|
Dns_EndDebug();
|
|||
|
|
|||
|
return( status != ERROR_SUCCESS );
|
|||
|
|
|||
|
Usage:
|
|||
|
|
|||
|
Dns_EndDebug();
|
|||
|
printf(
|
|||
|
"usage: DnsUp [-n<Server IP List>] -<Command> [Command Parameters].\n"
|
|||
|
"\t<Server IP List> is a list of one or more DNS server IP addresses\n"
|
|||
|
"\t\toverriding the default list on this client\n"
|
|||
|
"Commands:\n"
|
|||
|
);
|
|||
|
PrintCommands();
|
|||
|
return(1);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Command processing
|
|||
|
//
|
|||
|
|
|||
|
PDNS_RECORD
|
|||
|
buildRecordList(
|
|||
|
IN DWORD Argc,
|
|||
|
IN PSTR * Argv
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Build record list from Argc \ Argv list.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Argc -- arg count
|
|||
|
|
|||
|
Argv -- argument list
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Ptr to list of records built.
|
|||
|
NULL on parsing error.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
PCHAR arg;
|
|||
|
PCHAR pszname;
|
|||
|
WORD type;
|
|||
|
BOOLEAN fadd;
|
|||
|
BOOLEAN section;
|
|||
|
CHAR ch;
|
|||
|
PDNS_RECORD prr;
|
|||
|
DNS_RRSET rrset;
|
|||
|
INT recordArgc;
|
|||
|
PCHAR * recordArgv;
|
|||
|
|
|||
|
//
|
|||
|
// loop through remaining arguments building appropriate record types
|
|||
|
//
|
|||
|
|
|||
|
DNS_RRSET_INIT( rrset );
|
|||
|
recordArgc = (-3);
|
|||
|
pszname = NULL;
|
|||
|
|
|||
|
while ( Argc-- && (arg = *Argv++) )
|
|||
|
{
|
|||
|
//
|
|||
|
// if previous arg started new record, first parameter is name
|
|||
|
//
|
|||
|
|
|||
|
if ( recordArgc == (-2) )
|
|||
|
{
|
|||
|
pszname = arg;
|
|||
|
type = 0;
|
|||
|
recordArgc++;
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// second parameter is type
|
|||
|
//
|
|||
|
|
|||
|
else if ( recordArgc == (-1) )
|
|||
|
{
|
|||
|
type = DnsRecordTypeForName( arg, 0 );
|
|||
|
if ( type == 0 )
|
|||
|
{
|
|||
|
printf( "ERROR: unknown type %s.\n", arg );
|
|||
|
goto Failed;
|
|||
|
}
|
|||
|
recordArgc++;
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// check for end of existing record \ start of new record
|
|||
|
//
|
|||
|
|
|||
|
ch = *arg;
|
|||
|
|
|||
|
if ( ch == '+' || ch == '-' )
|
|||
|
{
|
|||
|
// build old record (if any)
|
|||
|
|
|||
|
if ( pszname != NULL )
|
|||
|
{
|
|||
|
prr = Dns_RecordBuild_A(
|
|||
|
& rrset,
|
|||
|
pszname,
|
|||
|
type,
|
|||
|
fadd,
|
|||
|
section,
|
|||
|
recordArgc,
|
|||
|
recordArgv );
|
|||
|
if ( !prr )
|
|||
|
{
|
|||
|
printf( "ERROR: building record.\n" );
|
|||
|
goto Failed;
|
|||
|
}
|
|||
|
if ( fadd && section == DNSREC_UPDATE )
|
|||
|
{
|
|||
|
prr->dwTtl = 3600;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
fadd = ( ch == '+' );
|
|||
|
recordArgc = (-2);
|
|||
|
|
|||
|
//
|
|||
|
// second character in new arg, indicates section
|
|||
|
// - for update ADD records use 3600 TTL instead of zero
|
|||
|
//
|
|||
|
|
|||
|
ch = *++arg;
|
|||
|
if ( ch == 0 )
|
|||
|
{
|
|||
|
section = DNSREC_QUESTION;
|
|||
|
}
|
|||
|
else if ( ch == 'p' )
|
|||
|
{
|
|||
|
section = DNSREC_PREREQ;
|
|||
|
}
|
|||
|
else if ( ch == 'u' )
|
|||
|
{
|
|||
|
section = DNSREC_UPDATE;
|
|||
|
}
|
|||
|
else if ( ch == 'a' )
|
|||
|
{
|
|||
|
section = DNSREC_ADDITIONAL;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
printf( "ERROR: unknown section id %d.\n", ch );
|
|||
|
goto Failed;
|
|||
|
}
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
// catch bad starting record (no +/-)
|
|||
|
|
|||
|
else if ( recordArgc < 0 )
|
|||
|
{
|
|||
|
printf( "ERROR: bad start of record arg %s\n", arg );
|
|||
|
goto Failed;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// anything else is data, save in argv format
|
|||
|
// - save starting point
|
|||
|
// - count records
|
|||
|
|
|||
|
else if ( recordArgc == 0 )
|
|||
|
{
|
|||
|
recordArgv = --Argv;
|
|||
|
Argv++;
|
|||
|
}
|
|||
|
recordArgc++;
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// build any final record
|
|||
|
//
|
|||
|
|
|||
|
if ( pszname != NULL )
|
|||
|
{
|
|||
|
prr = Dns_RecordBuild_A(
|
|||
|
& rrset,
|
|||
|
pszname,
|
|||
|
type,
|
|||
|
fadd,
|
|||
|
section,
|
|||
|
recordArgc,
|
|||
|
recordArgv );
|
|||
|
if ( !prr )
|
|||
|
{
|
|||
|
printf( "ERROR: building record.\n" );
|
|||
|
goto Failed;
|
|||
|
}
|
|||
|
if ( fadd && section == DNSREC_UPDATE )
|
|||
|
{
|
|||
|
prr->dwTtl = 3600;
|
|||
|
}
|
|||
|
}
|
|||
|
IF_DNSDBG( INIT )
|
|||
|
{
|
|||
|
DnsDbg_RecordSet(
|
|||
|
"Record set:\n",
|
|||
|
rrset.pFirstRR );
|
|||
|
}
|
|||
|
|
|||
|
return( rrset.pFirstRR );
|
|||
|
|
|||
|
Failed:
|
|||
|
|
|||
|
printf( "ERROR: building records from arguments.\n" );
|
|||
|
SetLastError( ERROR_INVALID_PARAMETER );
|
|||
|
return( NULL );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
PCHAR
|
|||
|
getNamePointer(
|
|||
|
IN PSTR pszName
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Get name pointer.
|
|||
|
|
|||
|
This may be legit pointer or tag
|
|||
|
Tags:
|
|||
|
- null
|
|||
|
- blank
|
|||
|
- badptr
|
|||
|
- badname
|
|||
|
- longname
|
|||
|
- longlabel
|
|||
|
- buffer
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Argc -- arg count
|
|||
|
|
|||
|
Argv -- argument list
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Ptr to list of records built.
|
|||
|
NULL on parsing error.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
PCHAR pname = pszName;
|
|||
|
|
|||
|
//
|
|||
|
// check special case names
|
|||
|
//
|
|||
|
|
|||
|
if ( _stricmp( pname, "null" ) == 0 )
|
|||
|
{
|
|||
|
pname = NULL;
|
|||
|
}
|
|||
|
else if ( _stricmp( pname, "blank" ) == 0 )
|
|||
|
{
|
|||
|
pname = "";
|
|||
|
}
|
|||
|
else if ( _stricmp( pname, "badname" ) == 0 )
|
|||
|
{
|
|||
|
pname = "..badname..";
|
|||
|
}
|
|||
|
else if ( _stricmp( pname, "longname" ) == 0 )
|
|||
|
{
|
|||
|
//pname = LONG_NAME;
|
|||
|
pname = LongName;
|
|||
|
}
|
|||
|
else if ( _stricmp( pname, "longlabel" ) == 0 )
|
|||
|
{
|
|||
|
pname = LONG_LABEL_NAME;
|
|||
|
}
|
|||
|
else if ( _stricmp( pname, "badptr" ) == 0 )
|
|||
|
{
|
|||
|
pname = (PCHAR) (-1);
|
|||
|
}
|
|||
|
else if ( _stricmp( pname, "buffer" ) == 0 )
|
|||
|
{
|
|||
|
pname = (PCHAR) NameBuffer;
|
|||
|
}
|
|||
|
|
|||
|
return( pname );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
BOOL
|
|||
|
getAddressPointer(
|
|||
|
IN PSTR pAddrString,
|
|||
|
OUT PCHAR * ppAddr,
|
|||
|
OUT PDWORD pLength,
|
|||
|
OUT PDWORD pFamily
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Get address from address string argument.
|
|||
|
|
|||
|
Wraps up special arguments (NULL, badptr), with string
|
|||
|
to address conversion.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pAddrString -- address as string
|
|||
|
|
|||
|
pAddr -- ptr to recv address
|
|||
|
|
|||
|
pLength -- ptr to recv length of returned address
|
|||
|
|
|||
|
pFamily -- ptr to recv family (socket family) of returned address
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
TRUE if valid address converted.
|
|||
|
FALSE if special ptr or pass through.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
PCHAR paddr;
|
|||
|
INT length = sizeof(IP4_ADDRESS);
|
|||
|
INT family = AF_INET;
|
|||
|
BOOL result = FALSE;
|
|||
|
|
|||
|
//
|
|||
|
// first check for special cases
|
|||
|
// - default to AF_INET
|
|||
|
//
|
|||
|
|
|||
|
if ( _stricmp( pAddrString, "null" ) == 0 )
|
|||
|
{
|
|||
|
paddr = NULL;
|
|||
|
}
|
|||
|
else if ( _stricmp( pAddrString, "blank" ) == 0 )
|
|||
|
{
|
|||
|
paddr = "";
|
|||
|
length = 0;
|
|||
|
}
|
|||
|
else if ( _stricmp( pAddrString, "badptr" ) == 0 )
|
|||
|
{
|
|||
|
paddr = (PCHAR) (-1);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// not-special -- treat as address string
|
|||
|
// - use type and length on successful conversion
|
|||
|
// - just return pAddrString and it's length if not successful
|
|||
|
//
|
|||
|
|
|||
|
else
|
|||
|
{
|
|||
|
family = 0; // any family
|
|||
|
length = sizeof(AddressBuffer);
|
|||
|
|
|||
|
result = Dns_StringToAddress_A(
|
|||
|
AddressBuffer,
|
|||
|
& length,
|
|||
|
pAddrString,
|
|||
|
& family );
|
|||
|
if ( result )
|
|||
|
{
|
|||
|
paddr = AddressBuffer;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
paddr = pAddrString;
|
|||
|
length = strlen( pAddrString );
|
|||
|
family = AF_INET;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
*ppAddr = paddr;
|
|||
|
*pLength = length;
|
|||
|
*pFamily = family;
|
|||
|
|
|||
|
return( result );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
BOOL
|
|||
|
getSockaddrFromString(
|
|||
|
IN OUT PSOCKADDR * ppSockaddr,
|
|||
|
IN OUT PDWORD pSockaddrLength,
|
|||
|
IN PSTR pAddrString
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Get sockaddr from address string argument.
|
|||
|
|
|||
|
Wraps up special arguments (NULL, badptr), with string
|
|||
|
to address conversion.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
ppSockaddr -- addr of ptr to sockaddr buffer
|
|||
|
on return may be set to point at dummy sockaddr
|
|||
|
|
|||
|
pSockaddrLength -- addr with sockaddr buffer length
|
|||
|
receives sockaddr length
|
|||
|
|
|||
|
pAddrString -- address as string
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
TRUE if parsed sockaddr string
|
|||
|
Note this does not mean it is a valid sockaddr.
|
|||
|
FALSE if special ptr or pass through.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
PCHAR paddr = NULL;
|
|||
|
DWORD addrLength;
|
|||
|
DWORD family;
|
|||
|
DWORD flags = 0;
|
|||
|
DNS_STATUS status;
|
|||
|
|
|||
|
//
|
|||
|
// convert address string
|
|||
|
//
|
|||
|
// if valid string => write into given sockaddr
|
|||
|
// if invalid => set sockaddr ptr to dummy sockaddr
|
|||
|
//
|
|||
|
|
|||
|
if ( getAddressPointer(
|
|||
|
pAddrString,
|
|||
|
& paddr,
|
|||
|
& addrLength,
|
|||
|
& family ) )
|
|||
|
{
|
|||
|
status = Dns_AddressToSockaddr(
|
|||
|
*ppSockaddr,
|
|||
|
pSockaddrLength,
|
|||
|
TRUE, // clear sockaddr
|
|||
|
paddr,
|
|||
|
addrLength,
|
|||
|
family );
|
|||
|
|
|||
|
if ( status != NO_ERROR )
|
|||
|
{
|
|||
|
DNS_ASSERT( FALSE );
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
}
|
|||
|
else // special bogus address, use it directly
|
|||
|
{
|
|||
|
*ppSockaddr = (PSOCKADDR) paddr;
|
|||
|
}
|
|||
|
return TRUE;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Command functions
|
|||
|
//
|
|||
|
|
|||
|
DNS_STATUS
|
|||
|
ProcessQuit(
|
|||
|
IN DWORD Argc,
|
|||
|
IN PSTR * Argv
|
|||
|
)
|
|||
|
{
|
|||
|
//
|
|||
|
// alert command processor to break iteractive loop
|
|||
|
//
|
|||
|
|
|||
|
return( ERROR_DNSUP_QUIT );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Update routines
|
|||
|
//
|
|||
|
// DCR: could add context handle interface to update routines
|
|||
|
//
|
|||
|
|
|||
|
DNS_STATUS
|
|||
|
ProcessUpdate(
|
|||
|
IN DWORD Argc,
|
|||
|
IN PSTR * Argv
|
|||
|
)
|
|||
|
{
|
|||
|
DNS_STATUS status;
|
|||
|
DWORD flags = 0;
|
|||
|
PCHAR arg;
|
|||
|
PDNS_RECORD prr = NULL;
|
|||
|
PDNS_MSG_BUF pmsgRecv = NULL;
|
|||
|
HANDLE hCreds=NULL;
|
|||
|
|
|||
|
//
|
|||
|
// flags?
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc < 1 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
arg = Argv[0];
|
|||
|
if ( strncmp( arg, "-f", 2 ) == 0 )
|
|||
|
{
|
|||
|
flags = strtoul( arg+2, NULL, 16 );
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// build update packet RRs
|
|||
|
//
|
|||
|
|
|||
|
prr = buildRecordList(
|
|||
|
Argc,
|
|||
|
Argv );
|
|||
|
if ( !prr )
|
|||
|
{
|
|||
|
status = GetLastError();
|
|||
|
if ( status != ERROR_SUCCESS )
|
|||
|
{
|
|||
|
printf( "ERROR: building records from arguments\n" );
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// build \ send update
|
|||
|
//
|
|||
|
|
|||
|
status = DnsUpdate(
|
|||
|
prr,
|
|||
|
flags,
|
|||
|
NULL, // no UPDATE adapter list specified
|
|||
|
hCreds,
|
|||
|
&pmsgRecv
|
|||
|
);
|
|||
|
if ( pmsgRecv )
|
|||
|
{
|
|||
|
DnsPrint_Message(
|
|||
|
dnsup_PrintRoutine,
|
|||
|
dnsup_PrintContext,
|
|||
|
"Update response:\n",
|
|||
|
pmsgRecv );
|
|||
|
}
|
|||
|
|
|||
|
Dns_RecordListFree( prr );
|
|||
|
|
|||
|
FREE_HEAP( pmsgRecv );
|
|||
|
|
|||
|
if ( status != ERROR_SUCCESS )
|
|||
|
{
|
|||
|
printf(
|
|||
|
"DnsUpdate failed, %x %s.\n",
|
|||
|
status,
|
|||
|
DnsStatusString(status) );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
printf( "Update successfully completed.\n" );
|
|||
|
}
|
|||
|
return( status );
|
|||
|
|
|||
|
Usage:
|
|||
|
|
|||
|
Dns_RecordListFree( prr );
|
|||
|
|
|||
|
printf(
|
|||
|
"DnsUpdate\n"
|
|||
|
"usage:\n"
|
|||
|
" DnsUp -u [-f<Flags>] [<Record> | ...]\n"
|
|||
|
" <Record> record for update packet\n"
|
|||
|
" <Record> == (-,+)(p,u,a) <Name> <Type> [Data | ...]\n"
|
|||
|
" (-,+) - add or delete, exist or no-exist flag\n"
|
|||
|
" (p,u,a) - prereq, update or additional section\n"
|
|||
|
" <Name> - RR owner name\n"
|
|||
|
" <Type> - record type (ex A, SRV, PTR, TXT, CNAME, etc.)\n"
|
|||
|
" <Data> - data strings (type specific), if any\n"
|
|||
|
);
|
|||
|
return( ERROR_INVALID_PARAMETER );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DNS_STATUS
|
|||
|
ProcessUpdateTest(
|
|||
|
IN DWORD Argc,
|
|||
|
IN PSTR * Argv
|
|||
|
)
|
|||
|
{
|
|||
|
DNS_STATUS status;
|
|||
|
DWORD flags = 0;
|
|||
|
PCHAR pszzone = NULL;
|
|||
|
PCHAR arg;
|
|||
|
PDNS_RECORD prr = NULL;
|
|||
|
PDNS_MSG_BUF pmsg = NULL;
|
|||
|
PDNS_MSG_BUF pmsgRecv = NULL;
|
|||
|
IP_ADDRESS ipserver;
|
|||
|
PIP_ARRAY aipservers = NULL;
|
|||
|
PSTR pszserverName = NULL;
|
|||
|
HANDLE hCreds = NULL;
|
|||
|
|
|||
|
//
|
|||
|
// optional name server to query?
|
|||
|
//
|
|||
|
|
|||
|
aipservers = pDnsServerArray;
|
|||
|
if ( !aipservers )
|
|||
|
{
|
|||
|
aipservers = DnsQueryConfigAlloc(
|
|||
|
DnsConfigDnsServerList,
|
|||
|
NULL );
|
|||
|
}
|
|||
|
if ( !aipservers )
|
|||
|
{
|
|||
|
printf( "Update failed: no DNS server list available.\n" );
|
|||
|
return( GetLastError() );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// flags?
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc < 1 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
arg = Argv[0];
|
|||
|
if ( strncmp( arg, "-f", 2 ) == 0 )
|
|||
|
{
|
|||
|
flags = strtoul( arg+2, NULL, 16 );
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// security -- then need target server name
|
|||
|
// presence of server name automatically turns on security
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc < 1 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
arg = Argv[0];
|
|||
|
if ( strncmp( arg, "-s", 2 ) == 0 )
|
|||
|
{
|
|||
|
pszserverName = arg+2;
|
|||
|
flags |= DNS_UPDATE_SECURITY_ONLY;
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// name of zone to update
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc < 1 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
arg = Argv[0];
|
|||
|
if ( *arg != '-' && *arg != '+' )
|
|||
|
{
|
|||
|
pszzone = arg;
|
|||
|
DNSDBG( INIT, (
|
|||
|
"Read update zone name %s\n",
|
|||
|
pszzone ));
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// build update packet RRs
|
|||
|
//
|
|||
|
|
|||
|
prr = buildRecordList(
|
|||
|
Argc,
|
|||
|
Argv );
|
|||
|
if ( !prr )
|
|||
|
{
|
|||
|
status = GetLastError();
|
|||
|
if ( status != ERROR_SUCCESS )
|
|||
|
{
|
|||
|
printf( "ERROR: building records from arguments\n" );
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// build \ send update
|
|||
|
//
|
|||
|
|
|||
|
status = Dns_UpdateLibEx(
|
|||
|
prr,
|
|||
|
flags,
|
|||
|
pszzone,
|
|||
|
pszserverName,
|
|||
|
aipservers,
|
|||
|
NULL,
|
|||
|
&pmsgRecv
|
|||
|
);
|
|||
|
if ( pmsgRecv )
|
|||
|
{
|
|||
|
DnsPrint_Message(
|
|||
|
dnsup_PrintRoutine,
|
|||
|
dnsup_PrintContext,
|
|||
|
"Update response:\n",
|
|||
|
pmsgRecv );
|
|||
|
}
|
|||
|
|
|||
|
DnsApiFree( aipservers );
|
|||
|
Dns_RecordListFree( prr );
|
|||
|
FREE_HEAP( pmsg );
|
|||
|
FREE_HEAP( pmsgRecv );
|
|||
|
|
|||
|
if( status != ERROR_SUCCESS )
|
|||
|
{
|
|||
|
printf(
|
|||
|
"DnsUpdateEx failed, %x %s.\n",
|
|||
|
status,
|
|||
|
DnsStatusString(status) );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
printf( "Update successfully completed.\n" );
|
|||
|
}
|
|||
|
return( status );
|
|||
|
|
|||
|
Usage:
|
|||
|
|
|||
|
FREE_HEAP( aipservers );
|
|||
|
Dns_RecordListFree( prr );
|
|||
|
FREE_HEAP( pmsg );
|
|||
|
FREE_HEAP( pmsgRecv );
|
|||
|
|
|||
|
printf(
|
|||
|
"UpdateTest -- Dns_UpdateLibEx\n"
|
|||
|
"usage:\n"
|
|||
|
" DnsUp [-n<DNS IP>|...] -ut [-f<Flags>] [-s<ServerName>] [<ZoneName>] [<Record> | ...]\n"
|
|||
|
" <DNS IP> optional IP address of server to send update to.\n"
|
|||
|
" <ServerName> name of DNS server we are sending update to;\n"
|
|||
|
" presence of server name automatically turns on update security\n"
|
|||
|
" <ZoneName> name of zone to update\n"
|
|||
|
" <Record> record for update packet\n"
|
|||
|
" <Record> == (-,+)(p,u,a) <Name> <Type> [Data | ...]\n"
|
|||
|
" (-,+) - add or delete, exist or no-exist flag\n"
|
|||
|
" (p,u,a) - prereq, update or additional section\n"
|
|||
|
" <Name> - RR owner name\n"
|
|||
|
" <Type> - record type (ex A, SRV, PTR, TXT, CNAME, etc.)\n"
|
|||
|
" <Data> - data strings (type specific), if any\n"
|
|||
|
);
|
|||
|
return( ERROR_INVALID_PARAMETER );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DNS_STATUS
|
|||
|
ProcessDhcpTest(
|
|||
|
IN DWORD Argc,
|
|||
|
IN PSTR * Argv
|
|||
|
)
|
|||
|
{
|
|||
|
DNS_STATUS status;
|
|||
|
REGISTER_HOST_ENTRY hostEntry;
|
|||
|
REGISTER_HOST_STATUS hostStatus;
|
|||
|
HANDLE doneEvent;
|
|||
|
|
|||
|
//
|
|||
|
// create completion event
|
|||
|
//
|
|||
|
|
|||
|
doneEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
|
|||
|
|
|||
|
//
|
|||
|
// build dumpy DHCP update
|
|||
|
//
|
|||
|
|
|||
|
hostEntry.Addr.ipAddr = 0x01010101;
|
|||
|
hostEntry.dwOptions = REGISTER_HOST_A;
|
|||
|
hostStatus.hDoneEvent = doneEvent;
|
|||
|
|
|||
|
//
|
|||
|
// send to DHCP DynDNS update routine
|
|||
|
//
|
|||
|
|
|||
|
status = DnsAsyncRegisterHostAddrs(
|
|||
|
L"El59x1",
|
|||
|
L"testdhcpname",
|
|||
|
&hostEntry,
|
|||
|
1, // address count
|
|||
|
NULL, // no regkey with previous
|
|||
|
0,
|
|||
|
L"nttest.microsoft.com",
|
|||
|
& hostStatus,
|
|||
|
60, // TTL
|
|||
|
0
|
|||
|
);
|
|||
|
|
|||
|
if( status != ERROR_SUCCESS )
|
|||
|
{
|
|||
|
printf(
|
|||
|
"DnsAsynRegisterHostAddrs_W() %s.\n",
|
|||
|
status,
|
|||
|
DnsStatusString(status) );
|
|||
|
return( status );
|
|||
|
}
|
|||
|
|
|||
|
printf( "DHCP DynDNS registration successfully completed.\n" );
|
|||
|
|
|||
|
WaitForSingleObject(
|
|||
|
doneEvent,
|
|||
|
INFINITE );
|
|||
|
|
|||
|
return( status );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Query routines
|
|||
|
//
|
|||
|
|
|||
|
DNS_STATUS
|
|||
|
ProcessQueryEx(
|
|||
|
IN DWORD Argc,
|
|||
|
IN PSTR * Argv
|
|||
|
)
|
|||
|
{
|
|||
|
DNS_STATUS status;
|
|||
|
PCHAR pszname;
|
|||
|
WORD type;
|
|||
|
DWORD flags = 0;
|
|||
|
PDNS_MSG_BUF pmsgRecv = NULL;
|
|||
|
HANDLE hevent = NULL;
|
|||
|
DNS_QUERY_INFO queryInfo;
|
|||
|
|
|||
|
//
|
|||
|
// name to query
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc < 2 || Argc > 4 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
pszname = Argv[0];
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
|
|||
|
//
|
|||
|
// type
|
|||
|
//
|
|||
|
|
|||
|
type = DnsRecordTypeForName( Argv[0], 0 );
|
|||
|
if ( type == 0 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
|
|||
|
//
|
|||
|
// flags and options
|
|||
|
//
|
|||
|
|
|||
|
while ( Argc )
|
|||
|
{
|
|||
|
if ( _stricmp( Argv[0], "-a" ) == 0 )
|
|||
|
{
|
|||
|
hevent = CreateEvent( NULL, FALSE, FALSE, NULL );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
flags = strtoul( Argv[0], NULL, 16 );
|
|||
|
}
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// query
|
|||
|
//
|
|||
|
|
|||
|
RtlZeroMemory(
|
|||
|
& queryInfo,
|
|||
|
sizeof(queryInfo) );
|
|||
|
|
|||
|
queryInfo.pName = pszname;
|
|||
|
queryInfo.Type = type;
|
|||
|
queryInfo.Flags = flags;
|
|||
|
queryInfo.pDnsServers = pDnsServerArray;
|
|||
|
queryInfo.hEvent = hevent;
|
|||
|
|
|||
|
status = DnsQueryEx( &queryInfo );
|
|||
|
|
|||
|
if ( status == ERROR_IO_PENDING )
|
|||
|
{
|
|||
|
printf(
|
|||
|
"DnsQueryEx() running asynchronously.\n"
|
|||
|
"\tEvent = %p\n",
|
|||
|
hevent );
|
|||
|
|
|||
|
WaitForSingleObject( hevent, INFINITE );
|
|||
|
|
|||
|
printf( "DnsQueryEx() async completion.\n" );
|
|||
|
|
|||
|
status = queryInfo.Status;
|
|||
|
}
|
|||
|
|
|||
|
if ( status == ERROR_SUCCESS ||
|
|||
|
status == DNS_ERROR_RCODE_NAME_ERROR ||
|
|||
|
status == DNS_INFO_NO_RECORDS )
|
|||
|
{
|
|||
|
printf(
|
|||
|
"DnsQueryEx() completed => %s.\n"
|
|||
|
"\tstatus = %d\n",
|
|||
|
DnsStatusString( status ),
|
|||
|
status );
|
|||
|
|
|||
|
DnsPrint_QueryInfo(
|
|||
|
dnsup_PrintRoutine,
|
|||
|
dnsup_PrintContext,
|
|||
|
"DnsQueryEx() result",
|
|||
|
&queryInfo );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
printf(
|
|||
|
"DnsQueryEx() failed, %x %s.\n",
|
|||
|
status,
|
|||
|
DnsStatusString(status) );
|
|||
|
|
|||
|
DNS_ASSERT( !queryInfo.pAnswerRecords );
|
|||
|
DNS_ASSERT( !queryInfo.pAliasRecords );
|
|||
|
DNS_ASSERT( !queryInfo.pAdditionalRecords );
|
|||
|
DNS_ASSERT( !queryInfo.pAuthorityRecords );
|
|||
|
}
|
|||
|
|
|||
|
return( status );
|
|||
|
|
|||
|
Usage:
|
|||
|
|
|||
|
printf(
|
|||
|
"DnsQueryEx\n"
|
|||
|
"usage:\n"
|
|||
|
" DnsUp [-n<DNS IP>|...] -qex <Name> <Type> <Flags> [-a]\n"
|
|||
|
" <DNS IP> optional IP address of DNS server to query.\n"
|
|||
|
" <Name> DNS name to query\n"
|
|||
|
" <Type> type of query\n"
|
|||
|
" <Flags> flags to use in query (in hex)\n"
|
|||
|
" -a to indicate asynchronous operation\n"
|
|||
|
);
|
|||
|
return( ERROR_INVALID_PARAMETER );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DNS_STATUS
|
|||
|
ProcessQueryCompare(
|
|||
|
IN DWORD Argc,
|
|||
|
IN PSTR * Argv
|
|||
|
)
|
|||
|
{
|
|||
|
DNS_STATUS status;
|
|||
|
PCHAR pszname;
|
|||
|
WORD type;
|
|||
|
PIP_ARRAY aipservers;
|
|||
|
PDNS_MSG_BUF pmsgRecv = NULL;
|
|||
|
PDNS_RECORD prrQuery;
|
|||
|
PDNS_RECORD prrParsed;
|
|||
|
PDNS_RECORD prrQueryDiff;
|
|||
|
PDNS_RECORD prrParsedDiff;
|
|||
|
|
|||
|
//
|
|||
|
// optional name server to query?
|
|||
|
//
|
|||
|
|
|||
|
aipservers = pDnsServerArray;
|
|||
|
|
|||
|
//
|
|||
|
// name to query
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc < 2 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
pszname = Argv[0];
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
|
|||
|
//
|
|||
|
// type
|
|||
|
//
|
|||
|
|
|||
|
type = DnsRecordTypeForName( Argv[0], 0 );
|
|||
|
if ( type == 0 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
|
|||
|
//
|
|||
|
// build expected RR set
|
|||
|
//
|
|||
|
|
|||
|
prrParsed = buildRecordList(
|
|||
|
Argc,
|
|||
|
Argv );
|
|||
|
if ( !prrParsed )
|
|||
|
{
|
|||
|
status = GetLastError();
|
|||
|
if ( status != ERROR_SUCCESS )
|
|||
|
{
|
|||
|
printf( "ERROR: building records from arguments\n" );
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
}
|
|||
|
DnsPrint_RecordSet(
|
|||
|
dnsup_PrintRoutine,
|
|||
|
dnsup_PrintContext,
|
|||
|
"Parsed comparison record list:\n",
|
|||
|
prrParsed );
|
|||
|
|
|||
|
//
|
|||
|
// query
|
|||
|
//
|
|||
|
// DCR: waiting for new DnsQueryEx()
|
|||
|
//
|
|||
|
|
|||
|
return( ERROR_CALL_NOT_IMPLEMENTED );
|
|||
|
|
|||
|
#if 0
|
|||
|
status = DnsQueryEx(
|
|||
|
& pmsgRecv,
|
|||
|
& prrQuery,
|
|||
|
pszname,
|
|||
|
type,
|
|||
|
0, // currently no flag support
|
|||
|
aipservers,
|
|||
|
NULL
|
|||
|
);
|
|||
|
|
|||
|
if( status != ERROR_SUCCESS )
|
|||
|
{
|
|||
|
printf(
|
|||
|
"DnsQueryEx() failed, %x %s.\n",
|
|||
|
status,
|
|||
|
DnsStatusString(status) );
|
|||
|
if ( DnsIsStatusRcode(status) )
|
|||
|
{
|
|||
|
DnsPrint_Message(
|
|||
|
dnsup_PrintRoutine,
|
|||
|
dnsup_PrintContext,
|
|||
|
"Query response:\n",
|
|||
|
pmsgRecv );
|
|||
|
}
|
|||
|
return( status );
|
|||
|
}
|
|||
|
DnsPrint_RecordSet(
|
|||
|
dnsup_PrintRoutine,
|
|||
|
dnsup_PrintContext,
|
|||
|
"Query response records:\n",
|
|||
|
prrQuery );
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// compare with records received
|
|||
|
//
|
|||
|
|
|||
|
DnsRecordSetCompare(
|
|||
|
prrQuery,
|
|||
|
prrParsed,
|
|||
|
& prrQueryDiff,
|
|||
|
& prrParsedDiff );
|
|||
|
|
|||
|
DnsPrint_RecordSet(
|
|||
|
dnsup_PrintRoutine,
|
|||
|
dnsup_PrintContext,
|
|||
|
"Unmatch records in query response:\n",
|
|||
|
prrQueryDiff );
|
|||
|
|
|||
|
DnsPrint_RecordSet(
|
|||
|
dnsup_PrintRoutine,
|
|||
|
dnsup_PrintContext,
|
|||
|
"Unmatch records in parsed list:\n",
|
|||
|
prrParsedDiff );
|
|||
|
|
|||
|
return( ERROR_SUCCESS );
|
|||
|
#endif
|
|||
|
|
|||
|
Usage:
|
|||
|
|
|||
|
printf(
|
|||
|
"Query compare\n"
|
|||
|
"usage:\n"
|
|||
|
" DnsUp [-n<DNS IP>|...] -qc <Name> <Type> [<Record> | ...]\n"
|
|||
|
" <DNS IP> optional IP address of DNS server to update.\n"
|
|||
|
" <Name> DNS name to query\n"
|
|||
|
" <Type> type of query\n"
|
|||
|
" <Record> record in list to compare\n"
|
|||
|
" <Record> == (-,+) <Name> <Type> [Data | ...]\n"
|
|||
|
" (-,+) - add or delete, exist or no-exist flag\n"
|
|||
|
" <Name> - RR owner name\n"
|
|||
|
" <Type> - record type\n"
|
|||
|
" <Data> - data strings (type specific), if any\n"
|
|||
|
);
|
|||
|
return( ERROR_INVALID_PARAMETER );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DNS_STATUS
|
|||
|
ProcessQuery(
|
|||
|
IN DWORD Argc,
|
|||
|
IN PSTR * Argv
|
|||
|
)
|
|||
|
{
|
|||
|
DNS_STATUS status;
|
|||
|
PCHAR pszname;
|
|||
|
WORD type;
|
|||
|
DWORD flags = 0;
|
|||
|
PDNS_RECORD precord = NULL;
|
|||
|
PDNS_MSG_BUF pmsgRecv = NULL;
|
|||
|
PDNS_MSG_BUF * ppmsgRecv = NULL;
|
|||
|
PIP_ARRAY aipservers = NULL;
|
|||
|
|
|||
|
//
|
|||
|
// name to query
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc < 2 || Argc > 3 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
|
|||
|
pszname = getNamePointer( Argv[0] );
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
|
|||
|
//
|
|||
|
// type
|
|||
|
//
|
|||
|
|
|||
|
type = DnsRecordTypeForName( Argv[0], 0 );
|
|||
|
if ( type == 0 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
|
|||
|
//
|
|||
|
// flags
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc )
|
|||
|
{
|
|||
|
flags = strtoul( Argv[0], NULL, 16 );
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
}
|
|||
|
if ( Argc )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// only if flag has BYPASS_CACHE set can we
|
|||
|
// 1) send to specific servers
|
|||
|
// 2) receive message buffer itself
|
|||
|
//
|
|||
|
|
|||
|
aipservers = pDnsServerArray;
|
|||
|
|
|||
|
if ( flags & DNS_QUERY_BYPASS_CACHE )
|
|||
|
{
|
|||
|
ppmsgRecv = & pmsgRecv;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// query
|
|||
|
//
|
|||
|
|
|||
|
status = DnsQuery(
|
|||
|
pszname,
|
|||
|
type,
|
|||
|
flags,
|
|||
|
aipservers,
|
|||
|
& precord,
|
|||
|
ppmsgRecv );
|
|||
|
|
|||
|
if( status != ERROR_SUCCESS )
|
|||
|
{
|
|||
|
printf(
|
|||
|
"DnsQuery() failed, %x %s.\n",
|
|||
|
status,
|
|||
|
DnsStatusString(status) );
|
|||
|
if ( DnsIsStatusRcode(status) && pmsgRecv )
|
|||
|
{
|
|||
|
DnsPrint_Message(
|
|||
|
dnsup_PrintRoutine,
|
|||
|
dnsup_PrintContext,
|
|||
|
"Query response:\n",
|
|||
|
pmsgRecv );
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
printf( "DnsQuery() successfully completed.\n" );
|
|||
|
if ( pmsgRecv )
|
|||
|
{
|
|||
|
DnsPrint_Message(
|
|||
|
dnsup_PrintRoutine,
|
|||
|
dnsup_PrintContext,
|
|||
|
"Query response:\n",
|
|||
|
pmsgRecv );
|
|||
|
}
|
|||
|
DnsPrint_RecordSet(
|
|||
|
dnsup_PrintRoutine,
|
|||
|
dnsup_PrintContext,
|
|||
|
"Query response records:\n",
|
|||
|
precord );
|
|||
|
}
|
|||
|
|
|||
|
DnsRecordListFree( precord, DnsFreeRecordListDeep );
|
|||
|
return( status );
|
|||
|
|
|||
|
Usage:
|
|||
|
|
|||
|
printf(
|
|||
|
"DnsQuery\n"
|
|||
|
"usage:\n"
|
|||
|
" DnsUp [-n<DNS IP>|...] -q <Name> <Type> [<Flags>]\n"
|
|||
|
" <DNS IP> optional IP address of DNS server to query.\n"
|
|||
|
" <Name> DNS name to query\n"
|
|||
|
" <Type> type of query\n"
|
|||
|
" <Flags> flags to use in query (in hex)\n"
|
|||
|
"\n"
|
|||
|
" Note for DnsQuery() to use specific server or to return\n"
|
|||
|
" a DNS message buffer, BYPASS_CACHE flag MUST be set.\n"
|
|||
|
);
|
|||
|
PrintDnsQueryFlags();
|
|||
|
|
|||
|
return( ERROR_INVALID_PARAMETER );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DNS_STATUS
|
|||
|
ProcessQueryMultiple(
|
|||
|
IN DWORD Argc,
|
|||
|
IN PSTR * Argv
|
|||
|
)
|
|||
|
{
|
|||
|
DNS_STATUS status;
|
|||
|
PCHAR pszname1;
|
|||
|
WORD type1;
|
|||
|
PCHAR pszname2;
|
|||
|
WORD type2;
|
|||
|
DWORD flags = 0;
|
|||
|
PDNS_RECORD precord = NULL;
|
|||
|
PDNS_MSG_BUF pmsgRecv = NULL;
|
|||
|
PDNS_MSG_BUF * ppmsgRecv = NULL;
|
|||
|
PIP_ARRAY aipservers = NULL;
|
|||
|
|
|||
|
//
|
|||
|
// optional name server to query?
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc < 4 || Argc > 5 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// first name to query
|
|||
|
//
|
|||
|
|
|||
|
pszname1 = Argv[0];
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
|
|||
|
//
|
|||
|
// first type
|
|||
|
//
|
|||
|
|
|||
|
type1 = DnsRecordTypeForName( Argv[0], 0 );
|
|||
|
if ( type1 == 0 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
|
|||
|
//
|
|||
|
// second name to query
|
|||
|
//
|
|||
|
|
|||
|
pszname2 = Argv[0];
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
|
|||
|
//
|
|||
|
// second type
|
|||
|
//
|
|||
|
|
|||
|
type2 = DnsRecordTypeForName( Argv[0], 0 );
|
|||
|
if ( type2 == 0 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
|
|||
|
//
|
|||
|
// flags
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc )
|
|||
|
{
|
|||
|
flags = strtoul( Argv[0], NULL, 16 );
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
}
|
|||
|
if ( Argc )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// only if flag has BYPASS_CACHE set can we
|
|||
|
// 1) send to specific servers
|
|||
|
// 2) receive message buffer itself
|
|||
|
//
|
|||
|
|
|||
|
if ( flags & DNS_QUERY_BYPASS_CACHE )
|
|||
|
{
|
|||
|
aipservers = pDnsServerArray;
|
|||
|
ppmsgRecv = & pmsgRecv;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// make first query
|
|||
|
//
|
|||
|
|
|||
|
status = DnsQuery(
|
|||
|
pszname1,
|
|||
|
type1,
|
|||
|
flags,
|
|||
|
aipservers,
|
|||
|
& precord,
|
|||
|
ppmsgRecv );
|
|||
|
|
|||
|
if( status != ERROR_SUCCESS )
|
|||
|
{
|
|||
|
printf(
|
|||
|
"DnsQuery() failed, %x %s.\n",
|
|||
|
status,
|
|||
|
DnsStatusString(status) );
|
|||
|
if ( DnsIsStatusRcode(status) && pmsgRecv )
|
|||
|
{
|
|||
|
DnsPrint_Message(
|
|||
|
dnsup_PrintRoutine,
|
|||
|
dnsup_PrintContext,
|
|||
|
"Query response:\n",
|
|||
|
pmsgRecv );
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
printf( "DnsQuery() successfully completed.\n" );
|
|||
|
if ( pmsgRecv )
|
|||
|
{
|
|||
|
DnsPrint_Message(
|
|||
|
dnsup_PrintRoutine,
|
|||
|
dnsup_PrintContext,
|
|||
|
"Query response:\n",
|
|||
|
pmsgRecv );
|
|||
|
}
|
|||
|
DnsPrint_RecordSet(
|
|||
|
dnsup_PrintRoutine,
|
|||
|
dnsup_PrintContext,
|
|||
|
"Query response records:\n",
|
|||
|
precord );
|
|||
|
}
|
|||
|
DnsRecordListFree( precord, DnsFreeRecordListDeep );
|
|||
|
|
|||
|
//
|
|||
|
// make second query
|
|||
|
//
|
|||
|
|
|||
|
status = DnsQuery(
|
|||
|
pszname2,
|
|||
|
type2,
|
|||
|
flags,
|
|||
|
aipservers,
|
|||
|
& precord,
|
|||
|
ppmsgRecv );
|
|||
|
|
|||
|
if( status != ERROR_SUCCESS )
|
|||
|
{
|
|||
|
printf(
|
|||
|
"DnsQuery() failed, %x %s.\n",
|
|||
|
status,
|
|||
|
DnsStatusString(status) );
|
|||
|
if ( DnsIsStatusRcode(status) && pmsgRecv )
|
|||
|
{
|
|||
|
DnsPrint_Message(
|
|||
|
dnsup_PrintRoutine,
|
|||
|
dnsup_PrintContext,
|
|||
|
"Query response:\n",
|
|||
|
pmsgRecv );
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
printf( "DnsQuery() successfully completed.\n" );
|
|||
|
if ( pmsgRecv )
|
|||
|
{
|
|||
|
DnsPrint_Message(
|
|||
|
dnsup_PrintRoutine,
|
|||
|
dnsup_PrintContext,
|
|||
|
"Query response:\n",
|
|||
|
pmsgRecv );
|
|||
|
}
|
|||
|
DnsPrint_RecordSet(
|
|||
|
dnsup_PrintRoutine,
|
|||
|
dnsup_PrintContext,
|
|||
|
"Query response records:\n",
|
|||
|
precord );
|
|||
|
}
|
|||
|
DnsRecordListFree( precord, DnsFreeRecordListDeep );
|
|||
|
return( status );
|
|||
|
|
|||
|
Usage:
|
|||
|
|
|||
|
printf(
|
|||
|
"Multiple DnsQuery()s\n"
|
|||
|
"usage:\n"
|
|||
|
" DnsUp [-n<DNS IP>|...] -qm <Name1> <Type1> <Name2> <Type2> [<Flags>]\n"
|
|||
|
" <DNS IP> optional IP address of DNS server to query.\n"
|
|||
|
" <Name1> DNS name to query\n"
|
|||
|
" <Type1> type of query\n"
|
|||
|
" <Name2> DNS name to query\n"
|
|||
|
" <Type2> type of query\n"
|
|||
|
" <Flags> flags to use in query (in hex)\n"
|
|||
|
"\n"
|
|||
|
" Note for DnsQuery() to use specific server or to return\n"
|
|||
|
" a DNS message buffer, BYPASS_CACHE flag MUST be set.\n"
|
|||
|
);
|
|||
|
PrintDnsQueryFlags();
|
|||
|
return( ERROR_INVALID_PARAMETER );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DNS_STATUS
|
|||
|
ProcessQueryTest(
|
|||
|
IN DWORD Argc,
|
|||
|
IN PSTR * Argv
|
|||
|
)
|
|||
|
{
|
|||
|
DNS_STATUS status;
|
|||
|
PCHAR pszname;
|
|||
|
WORD type;
|
|||
|
DWORD flags = 0;
|
|||
|
PDNS_RECORD precord = NULL;
|
|||
|
PDNS_MSG_BUF pmsgRecv = NULL;
|
|||
|
PIP_ARRAY aipservers = NULL;
|
|||
|
|
|||
|
//
|
|||
|
// optional name server to query?
|
|||
|
//
|
|||
|
|
|||
|
aipservers = pDnsServerArray;
|
|||
|
|
|||
|
//
|
|||
|
// name to query
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc < 2 || Argc > 3 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
pszname = Argv[0];
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
|
|||
|
//
|
|||
|
// type
|
|||
|
//
|
|||
|
|
|||
|
type = DnsRecordTypeForName( Argv[0], 0 );
|
|||
|
if ( type == 0 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
|
|||
|
//
|
|||
|
// flags
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc )
|
|||
|
{
|
|||
|
flags = strtoul( Argv[0], NULL, 16 );
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
}
|
|||
|
if ( Argc )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// query
|
|||
|
//
|
|||
|
|
|||
|
status = QueryDirectEx(
|
|||
|
& pmsgRecv,
|
|||
|
& precord,
|
|||
|
NULL, // no header
|
|||
|
0, // no header counts
|
|||
|
pszname,
|
|||
|
type,
|
|||
|
NULL, // no records
|
|||
|
flags,
|
|||
|
aipservers,
|
|||
|
NULL
|
|||
|
);
|
|||
|
|
|||
|
if( status != ERROR_SUCCESS )
|
|||
|
{
|
|||
|
printf(
|
|||
|
"QueryDirectEx() failed, %x %s.\n",
|
|||
|
status,
|
|||
|
DnsStatusString(status) );
|
|||
|
if ( DnsIsStatusRcode(status) )
|
|||
|
{
|
|||
|
DnsPrint_Message(
|
|||
|
dnsup_PrintRoutine,
|
|||
|
dnsup_PrintContext,
|
|||
|
"Query response:\n",
|
|||
|
pmsgRecv );
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
printf( "QueryDirectEx() successfully completed.\n" );
|
|||
|
DnsPrint_Message(
|
|||
|
dnsup_PrintRoutine,
|
|||
|
dnsup_PrintContext,
|
|||
|
"Query response:\n",
|
|||
|
pmsgRecv );
|
|||
|
DnsPrint_RecordSet(
|
|||
|
dnsup_PrintRoutine,
|
|||
|
dnsup_PrintContext,
|
|||
|
"Query response records:\n",
|
|||
|
precord );
|
|||
|
}
|
|||
|
DnsRecordListFree( precord, DnsFreeRecordListDeep );
|
|||
|
return( status );
|
|||
|
|
|||
|
Usage:
|
|||
|
|
|||
|
printf(
|
|||
|
"QueryDirectEx()\n"
|
|||
|
"usage:\n"
|
|||
|
" DnsUp [-n<DNS IP>|...] -qt <Name> <Type> [<Flags>]\n"
|
|||
|
" QueryTest -- uses dnslib.lib QueryDirectEx()\n"
|
|||
|
" <DNS IP> optional IP address of DNS server to query.\n"
|
|||
|
" <Name> DNS name to query\n"
|
|||
|
" <Type> type of query\n"
|
|||
|
" <Flags> flags to use in query (in hex)\n"
|
|||
|
);
|
|||
|
return( ERROR_INVALID_PARAMETER );
|
|||
|
}
|
|||
|
|
|||
|
#if 0
|
|||
|
|
|||
|
DNS_STATUS
|
|||
|
ProcessUpdateMultiple(
|
|||
|
IN DWORD Argc,
|
|||
|
IN PSTR * Argv
|
|||
|
)
|
|||
|
{
|
|||
|
DNS_STATUS status;
|
|||
|
DWORD flags = 0;
|
|||
|
PCHAR pszzone = NULL;
|
|||
|
PCHAR pszname = NULL;
|
|||
|
IP_ADDRESS ip;
|
|||
|
IP_ADDRESS hostIp;
|
|||
|
DWORD countIp;
|
|||
|
DWORD i;
|
|||
|
PCHAR arg;
|
|||
|
PDNS_RECORD prr = NULL;
|
|||
|
PDNS_MSG_BUF pmsg = NULL;
|
|||
|
PDNS_MSG_BUF pmsgRecv = NULL;
|
|||
|
IP_ADDRESS ipserver;
|
|||
|
PIP_ARRAY aipservers = NULL;
|
|||
|
PIP_ARRAY ipArray = NULL;
|
|||
|
PSTR pszserverName = NULL;
|
|||
|
HANDLE hCreds=NULL;
|
|||
|
|
|||
|
//
|
|||
|
// optional name server to query?
|
|||
|
//
|
|||
|
|
|||
|
aipservers = pDnsServerArray;
|
|||
|
if ( !aipservers )
|
|||
|
{
|
|||
|
aipservers = Dns_GetDnsServerList( FALSE );
|
|||
|
}
|
|||
|
if ( !aipservers )
|
|||
|
{
|
|||
|
printf( "Update failed: no DNS server list available.\n" );
|
|||
|
return( GetLastError() );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// flags?
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc < 1 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
arg = Argv[0];
|
|||
|
if ( strncmp( arg, "-f", 2 ) == 0 )
|
|||
|
{
|
|||
|
flags = strtoul( arg+2, NULL, 16 );
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// security -- then need target server name
|
|||
|
// presence of server name automatically turns on security
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc < 1 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
arg = Argv[0];
|
|||
|
if ( strncmp( arg, "-s", 2 ) == 0 )
|
|||
|
{
|
|||
|
pszserverName = arg+2;
|
|||
|
flags |= DNS_UPDATE_SECURITY_ON;
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// name of zone to update
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc < 1 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
pszzone = Argv[0];
|
|||
|
DNSDBG( INIT, (
|
|||
|
"Read update zone name %s\n",
|
|||
|
pszzone ));
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
|
|||
|
//
|
|||
|
// name to update
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc < 1 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
pszname = Argv[0];
|
|||
|
DNSDBG( INIT, (
|
|||
|
"Read update host name %s\n",
|
|||
|
pszname ));
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
|
|||
|
//
|
|||
|
// start IP
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc < 1 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
ip = inet_addr( Argv[0] );
|
|||
|
if ( ip == (-1) )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
|
|||
|
//
|
|||
|
// IP count
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc < 1 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
countIp = strtoul( Argv[0], NULL, 10 );
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
|
|||
|
//
|
|||
|
// build update record list
|
|||
|
// - allocate and generate IP array
|
|||
|
// - then create DNS records
|
|||
|
//
|
|||
|
|
|||
|
ipArray = Dns_CreateIpArray( countIp );
|
|||
|
if ( !ipArray )
|
|||
|
{
|
|||
|
status = GetLastError();
|
|||
|
if ( status != ERROR_SUCCESS )
|
|||
|
{
|
|||
|
printf( "ERROR: creating IP array\n" );
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
|
|||
|
hostIp = ntohl( ip );
|
|||
|
|
|||
|
for ( i=0; i<countIp; i++ )
|
|||
|
{
|
|||
|
ipArray->AddrArray[i] = htonl( hostIp );
|
|||
|
hostIp++;
|
|||
|
}
|
|||
|
|
|||
|
prr = Dns_HostUpdateRRSet(
|
|||
|
pszname,
|
|||
|
ipArray,
|
|||
|
3600 );
|
|||
|
if ( !prr )
|
|||
|
{
|
|||
|
status = GetLastError();
|
|||
|
if ( status != ERROR_SUCCESS )
|
|||
|
{
|
|||
|
printf( "ERROR: building records from arguments\n" );
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// build \ send update
|
|||
|
//
|
|||
|
|
|||
|
status = Dns_UpdateLibEx(
|
|||
|
prr,
|
|||
|
flags,
|
|||
|
pszzone,
|
|||
|
pszserverName,
|
|||
|
aipservers,
|
|||
|
hCreds,
|
|||
|
&pmsgRecv
|
|||
|
);
|
|||
|
if ( pmsgRecv )
|
|||
|
{
|
|||
|
DnsPrint_Message(
|
|||
|
dnsup_PrintRoutine,
|
|||
|
dnsup_PrintContext,
|
|||
|
"Update response:\n",
|
|||
|
pmsgRecv );
|
|||
|
}
|
|||
|
|
|||
|
FREE_HEAP( aipservers );
|
|||
|
Dns_RecordListFree( prr );
|
|||
|
FREE_HEAP( pmsg );
|
|||
|
FREE_HEAP( pmsgRecv );
|
|||
|
|
|||
|
if( status != ERROR_SUCCESS )
|
|||
|
{
|
|||
|
printf(
|
|||
|
"Dns_UpdateLibEx failed, %x %s.\n",
|
|||
|
status,
|
|||
|
DnsStatusString(status) );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
printf( "Update successfully completed.\n" );
|
|||
|
}
|
|||
|
return( status );
|
|||
|
|
|||
|
Usage:
|
|||
|
|
|||
|
FREE_HEAP( aipservers );
|
|||
|
Dns_RecordListFree( prr );
|
|||
|
FREE_HEAP( pmsg );
|
|||
|
FREE_HEAP( pmsgRecv );
|
|||
|
|
|||
|
printf(
|
|||
|
"usage:\n"
|
|||
|
" DnsUp [-n<DNS IP>|...] -um [-f<Flags>] [-s<ServerName>] <ZoneName>\n"
|
|||
|
" <HostName> <Starting IP> <IP Count>\n"
|
|||
|
" <DNS IP> optional IP address of server to send update to.\n"
|
|||
|
" <ServerName> name of DNS server we are sending update to;\n"
|
|||
|
" presence of server name automatically turns on update security\n"
|
|||
|
" <ZoneName> name of zone to update\n"
|
|||
|
" <HostName> name of host to update\n"
|
|||
|
" <Starting IP> first IP (in dotted decimal) in range to update\n"
|
|||
|
" <IP Count> count of IPs to send in update; IP address in update will\n"
|
|||
|
" be the next <IP count> after <Starting IP>\n"
|
|||
|
);
|
|||
|
return( ERROR_INVALID_PARAMETER );
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DNS_STATUS
|
|||
|
ProcessIQuery(
|
|||
|
IN DWORD Argc,
|
|||
|
IN PSTR * Argv
|
|||
|
)
|
|||
|
{
|
|||
|
DNS_STATUS status;
|
|||
|
DWORD flags = 0;
|
|||
|
PCHAR arg;
|
|||
|
PDNS_RECORD prr = NULL;
|
|||
|
PDNS_MSG_BUF pmsg = NULL;
|
|||
|
PDNS_MSG_BUF pmsgRecv = NULL;
|
|||
|
IP_ADDRESS ipserver;
|
|||
|
PIP_ARRAY aipservers = NULL;
|
|||
|
DNS_HEADER header;
|
|||
|
|
|||
|
//
|
|||
|
// setup header
|
|||
|
// - zero flags
|
|||
|
|
|||
|
*(PDWORD) &header = 0;
|
|||
|
header.Xid = (WORD) GetCurrentTimeInSeconds();
|
|||
|
header.Opcode = DNS_OPCODE_IQUERY;
|
|||
|
|
|||
|
//
|
|||
|
// optional name server to query?
|
|||
|
//
|
|||
|
|
|||
|
aipservers = pDnsServerArray;
|
|||
|
if ( !aipservers )
|
|||
|
{
|
|||
|
aipservers = DnsQueryConfigAlloc(
|
|||
|
DnsConfigDnsServerList,
|
|||
|
NULL );
|
|||
|
}
|
|||
|
if ( !aipservers )
|
|||
|
{
|
|||
|
printf( "Update failed: no DNS server list available.\n" );
|
|||
|
return( GetLastError() );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// flags?
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc < 1 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
arg = Argv[0];
|
|||
|
if ( strncmp( arg, "-f", 2 ) == 0 )
|
|||
|
{
|
|||
|
flags = strtoul( arg+2, NULL, 16 );
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// build update packet RRs
|
|||
|
//
|
|||
|
|
|||
|
prr = buildRecordList(
|
|||
|
Argc,
|
|||
|
Argv );
|
|||
|
if ( !prr )
|
|||
|
{
|
|||
|
status = GetLastError();
|
|||
|
if ( status != ERROR_SUCCESS )
|
|||
|
{
|
|||
|
printf( "ERROR: building records from arguments\n" );
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// build \ send update
|
|||
|
//
|
|||
|
|
|||
|
status = QueryDirectEx(
|
|||
|
& pmsgRecv,
|
|||
|
NULL, // no response records
|
|||
|
& header, // header with IQUERY set
|
|||
|
TRUE, // no copy header count fields
|
|||
|
NULL, // no question
|
|||
|
0, // no question type
|
|||
|
prr, // record list built
|
|||
|
0, // flags
|
|||
|
aipservers, // server IP list
|
|||
|
NULL // no adapter list
|
|||
|
);
|
|||
|
if ( pmsgRecv )
|
|||
|
{
|
|||
|
DnsPrint_Message(
|
|||
|
dnsup_PrintRoutine,
|
|||
|
dnsup_PrintContext,
|
|||
|
"IQUERY response:\n",
|
|||
|
pmsgRecv );
|
|||
|
}
|
|||
|
|
|||
|
FREE_HEAP( aipservers );
|
|||
|
Dns_RecordListFree( prr );
|
|||
|
FREE_HEAP( pmsg );
|
|||
|
FREE_HEAP( pmsgRecv );
|
|||
|
|
|||
|
if( status != ERROR_SUCCESS )
|
|||
|
{
|
|||
|
printf(
|
|||
|
"QueryDirectExEx failed, %x %s.\n",
|
|||
|
status,
|
|||
|
DnsStatusString(status) );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
printf( "IQUERY successfully completed.\n" );
|
|||
|
}
|
|||
|
return( status );
|
|||
|
|
|||
|
Usage:
|
|||
|
|
|||
|
FREE_HEAP( aipservers );
|
|||
|
Dns_RecordListFree( prr );
|
|||
|
FREE_HEAP( pmsg );
|
|||
|
FREE_HEAP( pmsgRecv );
|
|||
|
|
|||
|
printf(
|
|||
|
"usage:\n"
|
|||
|
" DnsUp [-n<DNS IP>|...] -iq [-f<Flags>] [<Record> | ...]\n"
|
|||
|
" <DNS IP> optional IP address of server to send update to.\n"
|
|||
|
" <ServerName> name of DNS server we are sending update to;\n"
|
|||
|
" presence of server name automatically turns on update security\n"
|
|||
|
" <ZoneName> name of zone to update\n"
|
|||
|
" <Record> record for update packet\n"
|
|||
|
" <Record> == (-,+)(p,u,a) <Name> <Type> [Data | ...]\n"
|
|||
|
" (-,+) - add or delete, exist or no-exist flag\n"
|
|||
|
" (p,u,a) - prereq, update or additional section\n"
|
|||
|
" <Name> - RR owner name\n"
|
|||
|
" <Type> - record type\n"
|
|||
|
" <Data> - data strings (type specific), if any\n"
|
|||
|
);
|
|||
|
return( ERROR_INVALID_PARAMETER );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DNS_STATUS
|
|||
|
ProcessValidateName(
|
|||
|
IN DWORD Argc,
|
|||
|
IN PSTR * Argv
|
|||
|
)
|
|||
|
{
|
|||
|
DNS_STATUS status;
|
|||
|
PCHAR pszname;
|
|||
|
DWORD format;
|
|||
|
|
|||
|
//
|
|||
|
// name to validate
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc != 2 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
pszname = Argv[0];
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
|
|||
|
//
|
|||
|
// name format
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc )
|
|||
|
{
|
|||
|
format = strtoul( Argv[0], NULL, 10 );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// validate
|
|||
|
//
|
|||
|
|
|||
|
status = DnsValidateName_A(
|
|||
|
pszname,
|
|||
|
format );
|
|||
|
|
|||
|
printf(
|
|||
|
"DnsValidateName( %s, %d ) status = %d %s.\n",
|
|||
|
pszname,
|
|||
|
format,
|
|||
|
status,
|
|||
|
DnsStatusString(status) );
|
|||
|
|
|||
|
return( status );
|
|||
|
|
|||
|
Usage:
|
|||
|
|
|||
|
printf(
|
|||
|
"DnsValidateName\n"
|
|||
|
"usage:\n"
|
|||
|
" DnsUp -vn <Name> <Format>\n"
|
|||
|
" <Name> DNS name to validate\n"
|
|||
|
" <Format> format of name\n"
|
|||
|
"\tDomainName -- %d\n"
|
|||
|
"\tDomainLabel -- %d\n"
|
|||
|
"\tHostnameFull -- %d\n"
|
|||
|
"\tHostnameLabel -- %d\n"
|
|||
|
"\tWildcard -- %d\n"
|
|||
|
"\tSrvRecord -- %d\n",
|
|||
|
DnsNameDomain,
|
|||
|
DnsNameDomainLabel,
|
|||
|
DnsNameHostnameFull,
|
|||
|
DnsNameHostnameLabel,
|
|||
|
DnsNameWildcard,
|
|||
|
DnsNameSrvRecord
|
|||
|
);
|
|||
|
return( ERROR_INVALID_PARAMETER );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DNS_STATUS
|
|||
|
ProcessNameCompare(
|
|||
|
IN DWORD Argc,
|
|||
|
IN PSTR * Argv
|
|||
|
)
|
|||
|
{
|
|||
|
BOOL result;
|
|||
|
PCHAR pszname1;
|
|||
|
PCHAR pszname2;
|
|||
|
|
|||
|
//
|
|||
|
// names to compare
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc != 2 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
pszname1 = Argv[0];
|
|||
|
pszname2 = Argv[1];
|
|||
|
|
|||
|
//
|
|||
|
// compare
|
|||
|
//
|
|||
|
|
|||
|
result = DnsNameCompare_A(
|
|||
|
pszname1,
|
|||
|
pszname2 );
|
|||
|
|
|||
|
printf(
|
|||
|
"DnsNameCompare( %s, %s ) result = %s.\n",
|
|||
|
pszname1,
|
|||
|
pszname2,
|
|||
|
result ? "TRUE" : "FALSE"
|
|||
|
);
|
|||
|
|
|||
|
return( ERROR_SUCCESS );
|
|||
|
|
|||
|
Usage:
|
|||
|
|
|||
|
printf(
|
|||
|
"DnsNameCompare\n"
|
|||
|
"usage:\n"
|
|||
|
" DnsUp -nc <Name1> <Name2>\n"
|
|||
|
" <Name1> <Name2> DNS names to compare.\n"
|
|||
|
);
|
|||
|
return( ERROR_INVALID_PARAMETER );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DNS_STATUS
|
|||
|
ProcessNameCompareEx(
|
|||
|
IN DWORD Argc,
|
|||
|
IN PSTR * Argv
|
|||
|
)
|
|||
|
{
|
|||
|
DNS_STATUS status;
|
|||
|
PCHAR pszname1;
|
|||
|
PCHAR pszname2;
|
|||
|
|
|||
|
//
|
|||
|
// names to compare
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc != 2 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
pszname1 = Argv[0];
|
|||
|
pszname2 = Argv[1];
|
|||
|
|
|||
|
//
|
|||
|
// compare
|
|||
|
//
|
|||
|
|
|||
|
status = DnsNameCompareEx_A(
|
|||
|
pszname1,
|
|||
|
pszname2,
|
|||
|
0 );
|
|||
|
|
|||
|
printf(
|
|||
|
"DnsNameCompareEx( %s, %s ) result = %d.\n",
|
|||
|
pszname1,
|
|||
|
pszname2,
|
|||
|
status
|
|||
|
);
|
|||
|
|
|||
|
return( ERROR_SUCCESS );
|
|||
|
|
|||
|
Usage:
|
|||
|
|
|||
|
printf(
|
|||
|
"DnsNameCompareEx\n"
|
|||
|
"usage:\n"
|
|||
|
" DnsUp -cnx <Name1> <Name2>\n"
|
|||
|
" <Name1> <Name2> DNS names to compare.\n"
|
|||
|
"Compare Result:\n"
|
|||
|
"\tNot Equal -- %d\n"
|
|||
|
"\tEqual -- %d\n"
|
|||
|
"\tLeft is Ancestor -- %d\n"
|
|||
|
"\tRight is Ancestor -- %d\n"
|
|||
|
"\tInvalid Name -- %d\n",
|
|||
|
DnsNameCompareNotEqual,
|
|||
|
DnsNameCompareEqual,
|
|||
|
DnsNameCompareLeftParent,
|
|||
|
DnsNameCompareRightParent,
|
|||
|
DnsNameCompareInvalid
|
|||
|
);
|
|||
|
return( ERROR_INVALID_PARAMETER );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DNS_STATUS
|
|||
|
ProcessStringTranslate(
|
|||
|
IN DWORD Argc,
|
|||
|
IN PSTR * Argv
|
|||
|
)
|
|||
|
{
|
|||
|
DNS_STATUS status;
|
|||
|
WCHAR unicodeString[ DNS_MAX_NAME_LENGTH ];
|
|||
|
WCHAR unicodeStandard[ DNS_MAX_NAME_LENGTH ];
|
|||
|
BYTE utf8Standard[ DNS_MAX_NAME_LENGTH ];
|
|||
|
PWCHAR punicode;
|
|||
|
PCHAR putf8;
|
|||
|
DWORD unicodeLength;
|
|||
|
DWORD utf8Length;
|
|||
|
DWORD unicodeLengthStandard;
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// string translate
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc < 1 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// read in unicode characters
|
|||
|
//
|
|||
|
|
|||
|
unicodeLength = 0;
|
|||
|
while ( Argc )
|
|||
|
{
|
|||
|
unicodeString[ unicodeLength++] = (WORD) strtoul( Argv[0], NULL, 16 );
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
}
|
|||
|
unicodeString[ unicodeLength ] = 0;
|
|||
|
|
|||
|
DnsPrint_UnicodeStringBytes(
|
|||
|
dnsup_PrintRoutine,
|
|||
|
dnsup_PrintContext,
|
|||
|
"DnsStringTranslate().\n"
|
|||
|
"Input string",
|
|||
|
unicodeString,
|
|||
|
unicodeLength );
|
|||
|
|
|||
|
//
|
|||
|
// convert to UTF8 -- my way and their way
|
|||
|
//
|
|||
|
|
|||
|
putf8 = Dns_StringCopyAllocate(
|
|||
|
(PCHAR) unicodeString,
|
|||
|
0,
|
|||
|
DnsCharSetUnicode,
|
|||
|
DnsCharSetUtf8 );
|
|||
|
if ( !putf8 )
|
|||
|
{
|
|||
|
return( DNS_ERROR_NO_MEMORY );
|
|||
|
}
|
|||
|
|
|||
|
utf8Length = WideCharToMultiByte(
|
|||
|
CP_UTF8,
|
|||
|
0, // no flags
|
|||
|
(PWCHAR) unicodeString,
|
|||
|
(-1), // null terminated
|
|||
|
utf8Standard,
|
|||
|
MAXWORD, // assuming adequate length
|
|||
|
NULL,
|
|||
|
NULL );
|
|||
|
|
|||
|
DnsPrint_Utf8StringBytes(
|
|||
|
dnsup_PrintRoutine,
|
|||
|
dnsup_PrintContext,
|
|||
|
"My UTF8",
|
|||
|
putf8,
|
|||
|
strlen(putf8) );
|
|||
|
|
|||
|
DnsPrint_Utf8StringBytes(
|
|||
|
dnsup_PrintRoutine,
|
|||
|
dnsup_PrintContext,
|
|||
|
"Standard UTF8",
|
|||
|
utf8Standard,
|
|||
|
strlen(utf8Standard) );
|
|||
|
|
|||
|
//
|
|||
|
// convert back to unicode
|
|||
|
//
|
|||
|
|
|||
|
punicode = Dns_StringCopyAllocate(
|
|||
|
(PCHAR) utf8Standard,
|
|||
|
0,
|
|||
|
DnsCharSetUtf8,
|
|||
|
DnsCharSetUnicode );
|
|||
|
|
|||
|
unicodeLengthStandard = MultiByteToWideChar(
|
|||
|
CP_UTF8,
|
|||
|
0, // no flags
|
|||
|
(PCHAR) utf8Standard,
|
|||
|
(-1), // null terminated
|
|||
|
(PWCHAR) unicodeStandard,
|
|||
|
MAXWORD // assuming adequate length
|
|||
|
);
|
|||
|
|
|||
|
DnsPrint_UnicodeStringBytes(
|
|||
|
dnsup_PrintRoutine,
|
|||
|
dnsup_PrintContext,
|
|||
|
"My unicode",
|
|||
|
punicode,
|
|||
|
wcslen(punicode) );
|
|||
|
|
|||
|
DnsPrint_UnicodeStringBytes(
|
|||
|
dnsup_PrintRoutine,
|
|||
|
dnsup_PrintContext,
|
|||
|
"Standard unicode",
|
|||
|
unicodeStandard,
|
|||
|
wcslen(unicodeStandard) );
|
|||
|
|
|||
|
status = ERROR_SUCCESS;
|
|||
|
return( status );
|
|||
|
|
|||
|
Usage:
|
|||
|
|
|||
|
printf(
|
|||
|
"usage:\n"
|
|||
|
" DnsUp -s [unicode chars in hex]\n"
|
|||
|
);
|
|||
|
return( ERROR_INVALID_PARAMETER );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DNS_STATUS
|
|||
|
ProcessQueryConfig(
|
|||
|
IN DWORD Argc,
|
|||
|
IN PSTR * Argv
|
|||
|
)
|
|||
|
{
|
|||
|
#define CONFIG_BUF_SIZE (100)
|
|||
|
|
|||
|
DNS_STATUS status;
|
|||
|
DNS_CONFIG_TYPE config;
|
|||
|
PCHAR psznext;
|
|||
|
PCHAR pendString;
|
|||
|
PWSTR pwsadapter = NULL;
|
|||
|
DWORD flag = 0;
|
|||
|
BOOL ballocated = FALSE;
|
|||
|
BOOL bsleep = FALSE;
|
|||
|
DWORD bufLength = 0;
|
|||
|
DWORD sentBufLength;
|
|||
|
PBYTE pbuffer = NULL;
|
|||
|
PBYTE pallocResult;
|
|||
|
BYTE buffer[ CONFIG_BUF_SIZE ];
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// query config
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc < 1 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
|
|||
|
// config value
|
|||
|
|
|||
|
config = strtoul( Argv[0], &pendString, 10 );
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
|
|||
|
// flag?
|
|||
|
|
|||
|
while ( Argc )
|
|||
|
{
|
|||
|
psznext = Argv[0];
|
|||
|
|
|||
|
// flag
|
|||
|
|
|||
|
if ( !_stricmp( psznext, "-f" ) ||
|
|||
|
!_stricmp( psznext, "/f" ) )
|
|||
|
{
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
flag = strtoul( Argv[0], &pendString, 16 );
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
|
|||
|
if ( flag & DNS_CONFIG_FLAG_ALLOC )
|
|||
|
{
|
|||
|
bufLength = sizeof(PVOID);
|
|||
|
pbuffer = buffer;
|
|||
|
}
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
// length input
|
|||
|
|
|||
|
if ( !_stricmp( psznext, "-l" ) ||
|
|||
|
!_stricmp( psznext, "/l" ) )
|
|||
|
{
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
bufLength = strtoul( Argv[0], &pendString, 16 );
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
// sleep?
|
|||
|
|
|||
|
if ( !_stricmp( psznext, "-s" ) ||
|
|||
|
!_stricmp( psznext, "/s" ) )
|
|||
|
{
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
bsleep = TRUE;
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
// buffer
|
|||
|
|
|||
|
if ( !_stricmp( psznext, "-b" ) ||
|
|||
|
!_stricmp( psznext, "/b" ) )
|
|||
|
{
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
pbuffer = buffer;
|
|||
|
bufLength = CONFIG_BUF_SIZE;
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
// adapter name
|
|||
|
|
|||
|
else
|
|||
|
{
|
|||
|
pwsadapter = DnsStringCopyAllocateEx(
|
|||
|
Argv[0],
|
|||
|
0,
|
|||
|
DnsCharSetAnsi, // ANSI in
|
|||
|
DnsCharSetUnicode // unicode out
|
|||
|
);
|
|||
|
continue;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// query DNS config
|
|||
|
//
|
|||
|
|
|||
|
sentBufLength = bufLength;
|
|||
|
|
|||
|
status = DnsQueryConfig(
|
|||
|
config,
|
|||
|
flag,
|
|||
|
pwsadapter,
|
|||
|
NULL,
|
|||
|
pbuffer,
|
|||
|
& bufLength );
|
|||
|
|
|||
|
if ( status == ERROR_SUCCESS )
|
|||
|
{
|
|||
|
printf(
|
|||
|
"DnsQueryConfig() successful.\n"
|
|||
|
"\tflag = 0x%.8X\n"
|
|||
|
"\tadapter = %s\n"
|
|||
|
"\tsent length = %d\n"
|
|||
|
"\tlength required = %d\n",
|
|||
|
flag,
|
|||
|
pwsadapter,
|
|||
|
sentBufLength,
|
|||
|
bufLength );
|
|||
|
|
|||
|
if ( !pbuffer )
|
|||
|
{
|
|||
|
return( status );
|
|||
|
}
|
|||
|
|
|||
|
printf(
|
|||
|
"\tbuffer = %02x %02x %02x %02x ...\n",
|
|||
|
pbuffer[0],
|
|||
|
pbuffer[1],
|
|||
|
pbuffer[2],
|
|||
|
pbuffer[3] );
|
|||
|
|
|||
|
if ( flag & DNS_CONFIG_FLAG_ALLOC )
|
|||
|
{
|
|||
|
pbuffer = * (PVOID *) pbuffer;
|
|||
|
}
|
|||
|
|
|||
|
switch( config )
|
|||
|
{
|
|||
|
|
|||
|
case DnsConfigPrimaryDomainName_W:
|
|||
|
|
|||
|
printf(
|
|||
|
"Primary domain name = %S\n",
|
|||
|
pbuffer );
|
|||
|
break;
|
|||
|
|
|||
|
case DnsConfigPrimaryDomainName_A:
|
|||
|
case DnsConfigPrimaryDomainName_UTF8:
|
|||
|
|
|||
|
printf(
|
|||
|
"Primary domain name = %s\n",
|
|||
|
pbuffer );
|
|||
|
break;
|
|||
|
|
|||
|
case DnsConfigDnsServerList:
|
|||
|
|
|||
|
DnsPrint_IpArray(
|
|||
|
dnsup_PrintRoutine,
|
|||
|
dnsup_PrintContext,
|
|||
|
"DNS server list",
|
|||
|
NULL,
|
|||
|
(PIP_ARRAY) pbuffer );
|
|||
|
break;
|
|||
|
|
|||
|
case DnsConfigPrimaryHostNameRegistrationEnabled:
|
|||
|
|
|||
|
printf(
|
|||
|
"Is Primary registration enabled = %d\n",
|
|||
|
*(PBOOL)pbuffer );
|
|||
|
break;
|
|||
|
|
|||
|
case DnsConfigAdapterHostNameRegistrationEnabled:
|
|||
|
|
|||
|
printf(
|
|||
|
"Is Adapter registration enabled = %d\n",
|
|||
|
*(PBOOL)pbuffer );
|
|||
|
break;
|
|||
|
|
|||
|
case DnsConfigAddressRegistrationMaxCount:
|
|||
|
|
|||
|
printf(
|
|||
|
"Max IP registration count = %d\n",
|
|||
|
*(PDWORD)pbuffer );
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
|
|||
|
printf( "Unknown config %d", config );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
else if ( status == ERROR_MORE_DATA )
|
|||
|
{
|
|||
|
printf(
|
|||
|
"DnsQueryConfig() ERROR_MORE_DATA.\n"
|
|||
|
"\tsent length = %d\n"
|
|||
|
"\tlength required = %d\n",
|
|||
|
sentBufLength,
|
|||
|
bufLength );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
printf(
|
|||
|
"DnsQueryConfig() failed status = %d (0x%.8X).\n",
|
|||
|
status, status );
|
|||
|
}
|
|||
|
|
|||
|
if ( bsleep )
|
|||
|
{
|
|||
|
printf( "Sleeping" );
|
|||
|
Sleep( MAXDWORD );
|
|||
|
}
|
|||
|
return( status );
|
|||
|
|
|||
|
Usage:
|
|||
|
|
|||
|
printf(
|
|||
|
"usage:\n"
|
|||
|
" DnsUp -config <Config> [-f <flag>] [-b] [-l <length>] [<adapter name>]\n"
|
|||
|
);
|
|||
|
|
|||
|
return( ERROR_INVALID_PARAMETER );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DNS_STATUS
|
|||
|
ProcessReplaceRecordSet(
|
|||
|
IN DWORD Argc,
|
|||
|
IN PSTR * Argv
|
|||
|
)
|
|||
|
{
|
|||
|
DNS_STATUS status;
|
|||
|
DWORD flags = 0;
|
|||
|
PCHAR arg;
|
|||
|
PDNS_RECORD prr = NULL;
|
|||
|
HANDLE hCreds=NULL;
|
|||
|
|
|||
|
//
|
|||
|
// flags?
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc < 1 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
arg = Argv[0];
|
|||
|
if ( strncmp( arg, "-f", 2 ) == 0 )
|
|||
|
{
|
|||
|
flags = strtoul( arg+2, NULL, 16 );
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// build update packet RRs
|
|||
|
//
|
|||
|
|
|||
|
prr = buildRecordList(
|
|||
|
Argc,
|
|||
|
Argv );
|
|||
|
if ( !prr )
|
|||
|
{
|
|||
|
status = GetLastError();
|
|||
|
if ( status != ERROR_SUCCESS )
|
|||
|
{
|
|||
|
printf( "ERROR: building records from arguments\n" );
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// build \ send update
|
|||
|
//
|
|||
|
|
|||
|
status = DnsReplaceRecordSetA(
|
|||
|
prr,
|
|||
|
flags,
|
|||
|
hCreds,
|
|||
|
NULL, // no adapter list specified
|
|||
|
NULL // reserved
|
|||
|
);
|
|||
|
|
|||
|
Dns_RecordListFree( prr );
|
|||
|
|
|||
|
if ( status != ERROR_SUCCESS )
|
|||
|
{
|
|||
|
printf(
|
|||
|
"DnsReplaceRecordSet failed, %x %s.\n",
|
|||
|
status,
|
|||
|
DnsStatusString(status) );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
printf( "ReplaceRecordSet successfully completed.\n" );
|
|||
|
}
|
|||
|
return( status );
|
|||
|
|
|||
|
Usage:
|
|||
|
|
|||
|
Dns_RecordListFree( prr );
|
|||
|
|
|||
|
printf(
|
|||
|
"usage:\n"
|
|||
|
" DnsUp -rs [-f<Flags>] [<Record> | ...]\n"
|
|||
|
" <Record> record for update packet\n"
|
|||
|
" <Record> == (+)(u) <Name> <Type> [Data | ...]\n"
|
|||
|
" <Name> - RR owner name\n"
|
|||
|
" <Type> - record type (ex A, SRV, PTR, TXT, CNAME, etc.)\n"
|
|||
|
" <Data> - data strings (type specific), if any\n"
|
|||
|
);
|
|||
|
return( ERROR_INVALID_PARAMETER );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DNS_STATUS
|
|||
|
ProcessModifyRecordsInSet(
|
|||
|
IN DWORD Argc,
|
|||
|
IN PSTR * Argv
|
|||
|
)
|
|||
|
{
|
|||
|
DNS_STATUS status;
|
|||
|
DWORD flags = 0;
|
|||
|
PCHAR arg;
|
|||
|
PDNS_RECORD prr;
|
|||
|
PDNS_RECORD prrAdd = NULL;
|
|||
|
PDNS_RECORD prrDelete = NULL;
|
|||
|
HANDLE hCreds=NULL;
|
|||
|
INT addCount;
|
|||
|
DNS_RRSET rrsetDelete;
|
|||
|
DNS_RRSET rrsetAdd;
|
|||
|
|
|||
|
DNS_RRSET_INIT( rrsetAdd );
|
|||
|
DNS_RRSET_INIT( rrsetDelete );
|
|||
|
|
|||
|
//
|
|||
|
// flags?
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc < 1 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
|
|||
|
// flag?
|
|||
|
|
|||
|
arg = Argv[0];
|
|||
|
if ( strncmp( arg, "-f", 2 ) == 0 )
|
|||
|
{
|
|||
|
flags = strtoul( arg+2, NULL, 16 );
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// build update add RRs
|
|||
|
//
|
|||
|
|
|||
|
prr = buildRecordList(
|
|||
|
Argc,
|
|||
|
Argv );
|
|||
|
if ( !prr )
|
|||
|
{
|
|||
|
status = GetLastError();
|
|||
|
if ( status != ERROR_SUCCESS )
|
|||
|
{
|
|||
|
printf( "ERROR: building records from arguments\n" );
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// build separate Add and Delete lists
|
|||
|
//
|
|||
|
|
|||
|
while ( prr )
|
|||
|
{
|
|||
|
if ( prr->Flags.S.Delete )
|
|||
|
{
|
|||
|
DNS_RRSET_ADD( rrsetDelete, prr );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
DNS_RRSET_ADD( rrsetAdd, prr );
|
|||
|
}
|
|||
|
prr = prr->pNext;
|
|||
|
}
|
|||
|
|
|||
|
DNS_RRSET_TERMINATE( rrsetAdd );
|
|||
|
DNS_RRSET_TERMINATE( rrsetDelete );
|
|||
|
|
|||
|
//
|
|||
|
// build \ send update
|
|||
|
//
|
|||
|
|
|||
|
status = DnsModifyRecordsInSet_A(
|
|||
|
rrsetAdd.pFirstRR,
|
|||
|
rrsetDelete.pFirstRR,
|
|||
|
flags,
|
|||
|
hCreds,
|
|||
|
NULL, // no adapter list specified
|
|||
|
NULL // reserved
|
|||
|
);
|
|||
|
|
|||
|
Dns_RecordListFree( rrsetAdd.pFirstRR );
|
|||
|
Dns_RecordListFree( rrsetDelete.pFirstRR );
|
|||
|
|
|||
|
if ( status != ERROR_SUCCESS )
|
|||
|
{
|
|||
|
printf(
|
|||
|
"DnsModifyRecordsInSet failed, %x %s.\n",
|
|||
|
status,
|
|||
|
DnsStatusString(status) );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
printf( "ModifyRecordsInSet successfully completed.\n" );
|
|||
|
}
|
|||
|
return( status );
|
|||
|
|
|||
|
Usage:
|
|||
|
|
|||
|
Dns_RecordListFree( rrsetAdd.pFirstRR );
|
|||
|
Dns_RecordListFree( rrsetDelete.pFirstRR );
|
|||
|
|
|||
|
printf(
|
|||
|
"usage:\n"
|
|||
|
" DnsUp -mr [-f<Flags>] [<Record> | ...]\n"
|
|||
|
" <Record> == (-,+)(u) <Name> <Type> [Data | ...]\n"
|
|||
|
" (-,+) - add or delete, exist or no-exist flag\n"
|
|||
|
" <Name> - RR owner name\n"
|
|||
|
" <Type> - record type (ex A, SRV, PTR, TXT, CNAME, etc.)\n"
|
|||
|
" <Data> - data strings (type specific), if any\n"
|
|||
|
);
|
|||
|
return( ERROR_INVALID_PARAMETER );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Winsock \ RnR
|
|||
|
//
|
|||
|
|
|||
|
//
|
|||
|
// Protocol array for WSAQUERYSET
|
|||
|
//
|
|||
|
// DCR: may want to default to NULL instead?
|
|||
|
//
|
|||
|
|
|||
|
AFPROTOCOLS g_ProtocolArray[2] =
|
|||
|
{
|
|||
|
{ AF_INET, IPPROTO_UDP },
|
|||
|
{ AF_INET, IPPROTO_TCP }
|
|||
|
};
|
|||
|
|
|||
|
//
|
|||
|
// Service GUIDs
|
|||
|
//
|
|||
|
|
|||
|
GUID HostNameGuid = SVCID_HOSTNAME;
|
|||
|
GUID HostAddrByNameGuid = SVCID_INET_HOSTADDRBYNAME;
|
|||
|
GUID AddressGuid = SVCID_INET_HOSTADDRBYINETSTRING;
|
|||
|
GUID IANAGuid = SVCID_INET_SERVICEBYNAME;
|
|||
|
|
|||
|
typedef struct _GuidStringMap
|
|||
|
{
|
|||
|
LPGUID pGuid;
|
|||
|
LPSTR pString;
|
|||
|
};
|
|||
|
|
|||
|
struct _GuidStringMap GuidMapTable[] =
|
|||
|
{
|
|||
|
& HostNameGuid , "HostName" ,
|
|||
|
& HostAddrByNameGuid , "AddrByName" ,
|
|||
|
& HostAddrByNameGuid , "HostAddrByName" ,
|
|||
|
& AddressGuid , "HostAddrByInetString" ,
|
|||
|
& IANAGuid , "ServiceByName" ,
|
|||
|
& IANAGuid , "Iana" ,
|
|||
|
NULL , "NULL" ,
|
|||
|
NULL , NULL ,
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
PGUID
|
|||
|
guidForString(
|
|||
|
IN PSTR pszGuidName
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Get GUID for string.
|
|||
|
|
|||
|
This is to allow simple specification of command line for GUIDs.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pszGuidName -- name of desired GUID
|
|||
|
(see table above for current names of common guids)
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Ptr to desired GUID if found.
|
|||
|
Errors default to hostname (host lookup) GUID.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
DWORD i;
|
|||
|
PCHAR pname;
|
|||
|
|
|||
|
//
|
|||
|
// if no guid name, use host name guid
|
|||
|
//
|
|||
|
|
|||
|
if ( !pszGuidName )
|
|||
|
{
|
|||
|
return &HostNameGuid;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// find guid matching name in table
|
|||
|
//
|
|||
|
|
|||
|
i = 0;
|
|||
|
|
|||
|
while ( pname = GuidMapTable[i].pString )
|
|||
|
{
|
|||
|
if ( _stricmp( pname, pszGuidName ) == 0 )
|
|||
|
{
|
|||
|
return GuidMapTable[i].pGuid;
|
|||
|
}
|
|||
|
i++;
|
|||
|
}
|
|||
|
|
|||
|
// default to HostName guid
|
|||
|
|
|||
|
return &HostNameGuid;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Parsing utility
|
|||
|
//
|
|||
|
|
|||
|
typedef struct _RnRParseBlob
|
|||
|
{
|
|||
|
HANDLE Handle;
|
|||
|
PCHAR pBuffer;
|
|||
|
PWSAQUERYSET pQuerySet;
|
|||
|
PGUID pGuid;
|
|||
|
PSTR pName;
|
|||
|
DWORD Flags;
|
|||
|
DWORD NameSpace;
|
|||
|
DWORD BufferLength;
|
|||
|
}
|
|||
|
RNR_PARSE_BLOB, *PRNR_PARSE_BLOB;
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
printRnRArgHelp(
|
|||
|
VOID
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Print RnR argument usage.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
None
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
//
|
|||
|
// describe standard RnR lookup arguements
|
|||
|
//
|
|||
|
// DCR: add flag, ptr validity check
|
|||
|
// DCR: add "already set" check for names and guids
|
|||
|
// DCR: fix zero flag case below
|
|||
|
//
|
|||
|
|
|||
|
printf(
|
|||
|
"\tRnR Arguments:\n"
|
|||
|
"\t\t-h<handle> -- ptr in hex to lookup handle\n"
|
|||
|
"\t\t-b<buffer> -- ptr in hex to result buffer to use\n"
|
|||
|
"\t\t-l<buf length> -- buffer length to use\n"
|
|||
|
"\t\t-f<flag> -- RnR control flag in hex or LUP_X mneumonic\n"
|
|||
|
"\t\t may be multiple flags specified\n"
|
|||
|
"\t\t-q<query set> -- ptr in hex to existing WSAQUERYSET struct\n"
|
|||
|
"\t\t-i<name space> -- name space id NS_X mneumonic\n"
|
|||
|
"\t\t-a<name> -- ANSI lookup name\n"
|
|||
|
"\t\t-g<guid> -- NS GUID mneumonic:\n"
|
|||
|
"\t\t HostName\n"
|
|||
|
"\t\t HostAddrByName\n"
|
|||
|
"\t\t HostAddrByInetString\n"
|
|||
|
"\t\t ServiceByName\n"
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DNS_STATUS
|
|||
|
parseForRnr(
|
|||
|
IN DWORD Argc,
|
|||
|
IN PSTR * Argv,
|
|||
|
OUT PRNR_PARSE_BLOB pBlob
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Parse RnR routine command line params.
|
|||
|
|
|||
|
This is to simplify avoid duplicate parsing for various RnR
|
|||
|
functions.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Argc -- argc
|
|||
|
|
|||
|
Argv -- argument array
|
|||
|
|
|||
|
pBlob -- ptr to RnR parsing blob to be filled by function
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
ERROR_SUCCESS if successful parsing.
|
|||
|
ErrorCode on parsing error.
|
|||
|
(Note, currently errors are ignored and whatever parsing is possible
|
|||
|
is completed.)
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
PCHAR parg;
|
|||
|
|
|||
|
//
|
|||
|
// init parse blob
|
|||
|
//
|
|||
|
|
|||
|
RtlZeroMemory(
|
|||
|
pBlob,
|
|||
|
sizeof(RNR_PARSE_BLOB) );
|
|||
|
|
|||
|
//
|
|||
|
// read arguments
|
|||
|
//
|
|||
|
// DCR: add flag, ptr validity check
|
|||
|
// DCR: add "already set" check for names and guids
|
|||
|
// DCR: fix zero flag case below
|
|||
|
//
|
|||
|
|
|||
|
while ( Argc )
|
|||
|
{
|
|||
|
parg = Argv[0];
|
|||
|
|
|||
|
if ( strncmp( parg, "-h", 2 ) == 0 )
|
|||
|
{
|
|||
|
pBlob->Handle = (PVOID) (ULONG_PTR) strtoul( parg+2, NULL, 16 );
|
|||
|
}
|
|||
|
else if ( strncmp( parg, "-f", 2 ) == 0 )
|
|||
|
{
|
|||
|
DWORD thisFlag;
|
|||
|
|
|||
|
thisFlag = strtoul( parg+2, NULL, 16 );
|
|||
|
if ( thisFlag == 0 )
|
|||
|
{
|
|||
|
thisFlag = Dns_RnrLupFlagForString( parg+2, 0 );
|
|||
|
}
|
|||
|
pBlob->Flags |= thisFlag;
|
|||
|
}
|
|||
|
else if ( strncmp( parg, "-b", 2 ) == 0 )
|
|||
|
{
|
|||
|
pBlob->pBuffer = (PBYTE) (ULONG_PTR) strtoul( parg+2, NULL, 16 );
|
|||
|
}
|
|||
|
else if ( strncmp( parg, "-l", 2 ) == 0 )
|
|||
|
{
|
|||
|
pBlob->BufferLength = strtoul( parg+2, NULL, 10 );
|
|||
|
}
|
|||
|
else if ( strncmp( parg, "-a", 2 ) == 0 )
|
|||
|
{
|
|||
|
pBlob->pName = parg+2;
|
|||
|
}
|
|||
|
else if ( strncmp( parg, "-g", 2 ) == 0 )
|
|||
|
{
|
|||
|
pBlob->pGuid = guidForString( parg+2 );
|
|||
|
}
|
|||
|
else if ( strncmp( parg, "-i", 2 ) == 0 )
|
|||
|
{
|
|||
|
pBlob->NameSpace = Dns_RnrNameSpaceIdForString(
|
|||
|
parg+2,
|
|||
|
0 // length unknown
|
|||
|
);
|
|||
|
}
|
|||
|
else if ( strncmp( parg, "-q", 2 ) == 0 )
|
|||
|
{
|
|||
|
pBlob->pQuerySet = (PWSAQUERYSET) (ULONG_PTR) strtoul( parg+2, NULL, 16 );
|
|||
|
}
|
|||
|
else if ( *parg=='?' || strncmp( parg, "-?", 2 ) == 0 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
printf( "Unknown Arg = %s\n", parg );
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
}
|
|||
|
|
|||
|
return( ERROR_SUCCESS );
|
|||
|
|
|||
|
Usage:
|
|||
|
|
|||
|
printRnRArgHelp();
|
|||
|
|
|||
|
return( ERROR_INVALID_PARAMETER );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
PWSAQUERYSET
|
|||
|
buildWsaQuerySet(
|
|||
|
IN PRNR_PARSE_BLOB pBlob
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Create (allocate) a query set.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pBlob -- ptr to blob of parsing info
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Ptr to new WSAQUERYSET struct.
|
|||
|
NULL on allocation failure.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
PWSAQUERYSET pwsaq;
|
|||
|
|
|||
|
//
|
|||
|
// allocate
|
|||
|
//
|
|||
|
|
|||
|
pwsaq = ALLOCATE_HEAP_ZERO( sizeof(WSAQUERYSET) );
|
|||
|
if ( !pwsaq )
|
|||
|
{
|
|||
|
return( NULL );
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// basic
|
|||
|
// - default GUID to hostname lookup
|
|||
|
//
|
|||
|
|
|||
|
pwsaq->dwSize = sizeof(WSAQUERYSET);
|
|||
|
pwsaq->dwNumberOfProtocols = 2;
|
|||
|
pwsaq->lpafpProtocols = g_ProtocolArray;
|
|||
|
pwsaq->lpServiceClassId = & HostNameGuid;
|
|||
|
|
|||
|
//
|
|||
|
// tack on info from blob
|
|||
|
// - keep parsing generic by casting name to TSTR
|
|||
|
//
|
|||
|
|
|||
|
if ( pBlob )
|
|||
|
{
|
|||
|
pwsaq->dwNameSpace = pBlob->NameSpace;
|
|||
|
pwsaq->lpszServiceInstanceName = (LPTSTR) pBlob->pName;
|
|||
|
pwsaq->lpServiceClassId = pBlob->pGuid;
|
|||
|
}
|
|||
|
|
|||
|
return (PWSAQUERYSET) pwsaq;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DNS_STATUS
|
|||
|
ProcessLookupServiceBegin(
|
|||
|
IN DWORD Argc,
|
|||
|
IN PSTR * Argv
|
|||
|
)
|
|||
|
{
|
|||
|
DNS_STATUS status;
|
|||
|
HANDLE handle = NULL;
|
|||
|
PWSAQUERYSET pquerySet = NULL;
|
|||
|
PWSAQUERYSET pquerySetLocal = NULL;
|
|||
|
RNR_PARSE_BLOB blob;
|
|||
|
|
|||
|
//
|
|||
|
// WSALookupServiceBegin
|
|||
|
//
|
|||
|
|
|||
|
//
|
|||
|
// parse args
|
|||
|
//
|
|||
|
|
|||
|
status = parseForRnr( Argc, Argv, &blob );
|
|||
|
|
|||
|
if ( status != ERROR_SUCCESS )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// setup query set
|
|||
|
//
|
|||
|
|
|||
|
pquerySet = blob.pQuerySet;
|
|||
|
|
|||
|
if ( !pquerySet )
|
|||
|
{
|
|||
|
pquerySet = buildWsaQuerySet( &blob );
|
|||
|
pquerySetLocal = pquerySet;
|
|||
|
}
|
|||
|
|
|||
|
IF_DNSDBG( INIT )
|
|||
|
{
|
|||
|
DnsDbg_WsaQuerySet(
|
|||
|
"Query set to WLSBegin",
|
|||
|
pquerySet,
|
|||
|
FALSE // currently ANSI
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
DnsPrint_WsaQuerySet(
|
|||
|
dnsup_PrintRoutine,
|
|||
|
dnsup_PrintContext,
|
|||
|
"QuerySet to LookupServiceBegin",
|
|||
|
(PWSAQUERYSET) pquerySet,
|
|||
|
FALSE // ANSI call
|
|||
|
);
|
|||
|
|
|||
|
//
|
|||
|
// force winsock start
|
|||
|
//
|
|||
|
|
|||
|
Dns_InitializeWinsock();
|
|||
|
|
|||
|
//
|
|||
|
// call
|
|||
|
//
|
|||
|
|
|||
|
status = WSALookupServiceBeginA(
|
|||
|
pquerySet,
|
|||
|
blob.Flags,
|
|||
|
& handle );
|
|||
|
|
|||
|
if ( status != ERROR_SUCCESS )
|
|||
|
{
|
|||
|
status = GetLastError();
|
|||
|
|
|||
|
printf(
|
|||
|
"WSALookupServiceBegin( %p, %08x, %p ) failed, %d %s.\n",
|
|||
|
pquerySet,
|
|||
|
blob.Flags,
|
|||
|
& handle,
|
|||
|
status,
|
|||
|
DnsStatusString(status) );
|
|||
|
|
|||
|
if ( pquerySetLocal )
|
|||
|
{
|
|||
|
FREE_HEAP( pquerySetLocal );
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
printf(
|
|||
|
"WSALookupServiceBegin() succeeded.\n"
|
|||
|
"\thandle = %p\n"
|
|||
|
"\tqueryset = %p\n",
|
|||
|
handle,
|
|||
|
pquerySet );
|
|||
|
}
|
|||
|
return( status );
|
|||
|
|
|||
|
Usage:
|
|||
|
|
|||
|
printf(
|
|||
|
"WSALookupServiceBegin\n"
|
|||
|
"usage:\n"
|
|||
|
" DnsUp -lsb [RnR args]\n"
|
|||
|
" note handle arg does not apply\n"
|
|||
|
);
|
|||
|
|
|||
|
printRnRArgHelp();
|
|||
|
|
|||
|
return( ERROR_INVALID_PARAMETER );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DNS_STATUS
|
|||
|
ProcessLookupServiceNext(
|
|||
|
IN DWORD Argc,
|
|||
|
IN PSTR * Argv
|
|||
|
)
|
|||
|
{
|
|||
|
DNS_STATUS status;
|
|||
|
HANDLE handle = NULL;
|
|||
|
PCHAR pbuf = NULL;
|
|||
|
PCHAR pbufLocal = NULL;
|
|||
|
DWORD bufLength;
|
|||
|
RNR_PARSE_BLOB blob;
|
|||
|
|
|||
|
//
|
|||
|
// WSALookupServiceNext
|
|||
|
//
|
|||
|
|
|||
|
//
|
|||
|
// parse args
|
|||
|
//
|
|||
|
|
|||
|
status = parseForRnr( Argc, Argv, &blob );
|
|||
|
if ( status != ERROR_SUCCESS )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// if no handle need to do WLSBegin
|
|||
|
//
|
|||
|
|
|||
|
handle = blob.Handle;
|
|||
|
if ( !handle )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// setup buffer
|
|||
|
//
|
|||
|
|
|||
|
bufLength = blob.BufferLength;
|
|||
|
pbuf = blob.pBuffer;
|
|||
|
|
|||
|
if ( !pbuf && bufLength )
|
|||
|
{
|
|||
|
pbuf = ALLOCATE_HEAP( blob.BufferLength );
|
|||
|
if ( !pbuf )
|
|||
|
{
|
|||
|
status = DNS_ERROR_NO_MEMORY;
|
|||
|
}
|
|||
|
pbufLocal = pbuf;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// call
|
|||
|
//
|
|||
|
|
|||
|
printf(
|
|||
|
"Enter WSALookupServiceNext()\n"
|
|||
|
"\thandle = %p\n"
|
|||
|
"\tflag = %08x\n"
|
|||
|
"\tlength = %p (%d)\n"
|
|||
|
"\tbuffer = %p\n",
|
|||
|
handle,
|
|||
|
blob.Flags,
|
|||
|
&bufLength, bufLength,
|
|||
|
pbuf );
|
|||
|
|
|||
|
status = WSALookupServiceNextA(
|
|||
|
handle,
|
|||
|
blob.Flags,
|
|||
|
& bufLength,
|
|||
|
(PWSAQUERYSETA) pbuf );
|
|||
|
|
|||
|
if ( status != ERROR_SUCCESS )
|
|||
|
{
|
|||
|
status = GetLastError();
|
|||
|
|
|||
|
printf(
|
|||
|
"WSALookupServiceNext( h=%p, f=%08x, len=%d, buf=%p ) failed, %d %s.\n",
|
|||
|
handle,
|
|||
|
blob.Flags,
|
|||
|
bufLength,
|
|||
|
pbuf,
|
|||
|
status,
|
|||
|
DnsStatusString(status) );
|
|||
|
|
|||
|
if ( pbufLocal )
|
|||
|
{
|
|||
|
FREE_HEAP( pbufLocal );
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
printf(
|
|||
|
"WSALookupServiceNext() succeeded.\n"
|
|||
|
"\thandle = %p\n"
|
|||
|
"\tbuf length = %d\n"
|
|||
|
"\tpbuffer = %p\n",
|
|||
|
handle,
|
|||
|
bufLength,
|
|||
|
pbuf );
|
|||
|
|
|||
|
if ( pbuf )
|
|||
|
{
|
|||
|
DnsPrint_WsaQuerySet(
|
|||
|
dnsup_PrintRoutine,
|
|||
|
dnsup_PrintContext,
|
|||
|
"Result from LookupServiceNext",
|
|||
|
(PWSAQUERYSET) pbuf,
|
|||
|
FALSE // ANSI call
|
|||
|
);
|
|||
|
}
|
|||
|
}
|
|||
|
return( status );
|
|||
|
|
|||
|
Usage:
|
|||
|
|
|||
|
printf(
|
|||
|
"WSALookupServiceNext\n"
|
|||
|
"usage:\n"
|
|||
|
" DnsUp -lsn [RnR args]\n"
|
|||
|
" valid WSALookupServiceNext args:\n"
|
|||
|
" <handle> <flags> <buffer> <buf length>\n"
|
|||
|
" <handle> is required, call WSALookupServiceBegin\n"
|
|||
|
" to get handle to use with this function\n"
|
|||
|
);
|
|||
|
|
|||
|
printRnRArgHelp();
|
|||
|
|
|||
|
return( ERROR_INVALID_PARAMETER );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DNS_STATUS
|
|||
|
ProcessLookupServiceEnd(
|
|||
|
IN DWORD Argc,
|
|||
|
IN PSTR * Argv
|
|||
|
)
|
|||
|
{
|
|||
|
DNS_STATUS status;
|
|||
|
HANDLE handle;
|
|||
|
|
|||
|
//
|
|||
|
// WSALookupServiceEnd <handle>
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc < 1 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
|
|||
|
// read handle
|
|||
|
//
|
|||
|
// DCR: need QWORD read to handle win64 case
|
|||
|
|
|||
|
handle = (HANDLE) (UINT_PTR) strtoul( Argv[0], NULL, 16 );
|
|||
|
|
|||
|
//
|
|||
|
// call
|
|||
|
//
|
|||
|
|
|||
|
status = WSALookupServiceEnd( handle );
|
|||
|
if ( status != ERROR_SUCCESS )
|
|||
|
{
|
|||
|
printf(
|
|||
|
"WSALookupServiceEnd( %p ) failed, %d %s.\n",
|
|||
|
handle,
|
|||
|
status,
|
|||
|
DnsStatusString(status) );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
printf(
|
|||
|
"WSALookupServiceEnd( %p ) succeeded.\n",
|
|||
|
handle );
|
|||
|
}
|
|||
|
|
|||
|
Dns_CleanupWinsock();
|
|||
|
|
|||
|
return( status );
|
|||
|
|
|||
|
Usage:
|
|||
|
|
|||
|
printf(
|
|||
|
"WSALookupServiceEnd\n"
|
|||
|
"usage:\n"
|
|||
|
" DnsUp -lse -h<handle>\n"
|
|||
|
" <handle> - lookup handle to close in hex.\n"
|
|||
|
" handle is from prior WSALookupServiceBegin call.\n"
|
|||
|
);
|
|||
|
return( ERROR_INVALID_PARAMETER );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DNS_STATUS
|
|||
|
ProcessGetHostName(
|
|||
|
IN DWORD Argc,
|
|||
|
IN PSTR * Argv
|
|||
|
)
|
|||
|
{
|
|||
|
DNS_STATUS status;
|
|||
|
CHAR nameBuffer[ DNS_MAX_NAME_BUFFER_LENGTH ];
|
|||
|
DWORD length = DNS_MAX_NAME_BUFFER_LENGTH;
|
|||
|
PCHAR pname = nameBuffer;
|
|||
|
INT result;
|
|||
|
|
|||
|
//
|
|||
|
// gethostname [-n<name>] [-l<length>]
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc > 2 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// get optional name or length
|
|||
|
// - defaults to full size buffer above
|
|||
|
//
|
|||
|
|
|||
|
while ( Argc )
|
|||
|
{
|
|||
|
PCHAR arg = Argv[0];
|
|||
|
|
|||
|
if ( strncmp( arg, "-n", 2 ) == 0 )
|
|||
|
{
|
|||
|
pname = getNamePointer( arg+2 );
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
}
|
|||
|
else if ( strncmp( arg, "-l", 2 ) == 0 )
|
|||
|
{
|
|||
|
length = strtoul( arg+2, NULL, 10 );
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// force winsock start
|
|||
|
//
|
|||
|
|
|||
|
Dns_InitializeWinsock();
|
|||
|
|
|||
|
//
|
|||
|
// call
|
|||
|
//
|
|||
|
|
|||
|
result = gethostname( (PSTR)pname, length );
|
|||
|
|
|||
|
if ( result != 0 )
|
|||
|
{
|
|||
|
status = GetLastError();
|
|||
|
|
|||
|
printf(
|
|||
|
"gethostname(), %d (%x) %s.\n",
|
|||
|
status, status,
|
|||
|
DnsStatusString(status) );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
printf(
|
|||
|
"gethostname() successfully completed.\n"
|
|||
|
"\tname = %s\n",
|
|||
|
pname );
|
|||
|
}
|
|||
|
return( status );
|
|||
|
|
|||
|
Usage:
|
|||
|
|
|||
|
printf(
|
|||
|
"gethostname\n"
|
|||
|
"usage:\n"
|
|||
|
" DnsUp -ghn [-n<Name>] [-l<length>]\n"
|
|||
|
" <Name> - one of special names.\n"
|
|||
|
" <Length> - buffer length to pass in\n"
|
|||
|
" Defaults to valid name buffer of full DNS name length\n"
|
|||
|
);
|
|||
|
return( ERROR_INVALID_PARAMETER );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DNS_STATUS
|
|||
|
ProcessGetHostByName(
|
|||
|
IN DWORD Argc,
|
|||
|
IN PSTR * Argv
|
|||
|
)
|
|||
|
{
|
|||
|
DNS_STATUS status;
|
|||
|
PCHAR pname;
|
|||
|
PHOSTENT phost;
|
|||
|
|
|||
|
//
|
|||
|
// gethostbyname <name>
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc != 1 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
|
|||
|
// name
|
|||
|
|
|||
|
pname = getNamePointer( Argv[0] );
|
|||
|
|
|||
|
//
|
|||
|
// force winsock start
|
|||
|
//
|
|||
|
|
|||
|
Dns_InitializeWinsock();
|
|||
|
|
|||
|
//
|
|||
|
// call
|
|||
|
//
|
|||
|
|
|||
|
phost = gethostbyname( (PCSTR)pname );
|
|||
|
|
|||
|
status = GetLastError();
|
|||
|
|
|||
|
if ( !phost )
|
|||
|
{
|
|||
|
printf(
|
|||
|
"gethostbyname(), %x %s.\n",
|
|||
|
status,
|
|||
|
DnsStatusString(status) );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
printf( "gethostbyname successfully completed.\n" );
|
|||
|
|
|||
|
DnsPrint_Hostent(
|
|||
|
dnsup_PrintRoutine,
|
|||
|
dnsup_PrintContext,
|
|||
|
NULL, // default header
|
|||
|
phost,
|
|||
|
FALSE // ANSI
|
|||
|
);
|
|||
|
}
|
|||
|
return( status );
|
|||
|
|
|||
|
Usage:
|
|||
|
|
|||
|
printf(
|
|||
|
"gethostbyname\n"
|
|||
|
"usage:\n"
|
|||
|
" DnsUp -ghbn <Name>\n"
|
|||
|
" <Name> - DNS name to query.\n"
|
|||
|
" \"NULL\" for null input.\n"
|
|||
|
" \"blank\" for blank (empty string)\n"
|
|||
|
);
|
|||
|
return( ERROR_INVALID_PARAMETER );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DNS_STATUS
|
|||
|
ProcessGetHostByAddr(
|
|||
|
IN DWORD Argc,
|
|||
|
IN PSTR * Argv
|
|||
|
)
|
|||
|
{
|
|||
|
DNS_STATUS status;
|
|||
|
PCHAR pname;
|
|||
|
PCHAR paddr;
|
|||
|
PHOSTENT phost;
|
|||
|
IP6_ADDRESS ip6;
|
|||
|
INT length;
|
|||
|
INT family;
|
|||
|
|
|||
|
//
|
|||
|
// gethostbyaddr <ip> [len] [family]
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc < 1 || Argc > 3 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// address
|
|||
|
//
|
|||
|
|
|||
|
pname = getNamePointer( Argv[0] );
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
|
|||
|
length = sizeof(IP6_ADDRESS);
|
|||
|
family = 0;
|
|||
|
|
|||
|
if ( pname
|
|||
|
&&
|
|||
|
Dns_StringToAddress_A(
|
|||
|
(PCHAR) & ip6,
|
|||
|
& length,
|
|||
|
pname,
|
|||
|
& family ) )
|
|||
|
{
|
|||
|
paddr = (PCHAR) &ip6;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
paddr = pname;
|
|||
|
length = sizeof(IP4_ADDRESS);
|
|||
|
family = AF_INET;
|
|||
|
}
|
|||
|
|
|||
|
// length -- optional
|
|||
|
|
|||
|
if ( Argc )
|
|||
|
{
|
|||
|
length = strtoul( Argv[0], NULL, 10 );
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
}
|
|||
|
|
|||
|
// family -- optional
|
|||
|
|
|||
|
if ( Argc )
|
|||
|
{
|
|||
|
family = strtoul( Argv[0], NULL, 10 );
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// force winsock start
|
|||
|
//
|
|||
|
|
|||
|
Dns_InitializeWinsock();
|
|||
|
|
|||
|
//
|
|||
|
// call
|
|||
|
//
|
|||
|
|
|||
|
printf(
|
|||
|
"calling gethostbyaddr( %p, %d, %d )\n",
|
|||
|
paddr,
|
|||
|
length,
|
|||
|
family );
|
|||
|
|
|||
|
phost = gethostbyaddr(
|
|||
|
(PSTR)paddr,
|
|||
|
length,
|
|||
|
family );
|
|||
|
|
|||
|
status = GetLastError();
|
|||
|
|
|||
|
if ( !phost )
|
|||
|
{
|
|||
|
printf(
|
|||
|
"gethostbyaddr(), %d %s.\n",
|
|||
|
status,
|
|||
|
DnsStatusString(status) );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
printf( "gethostbyaddr successfully completed.\n" );
|
|||
|
|
|||
|
DnsPrint_Hostent(
|
|||
|
dnsup_PrintRoutine,
|
|||
|
dnsup_PrintContext,
|
|||
|
NULL, // default header
|
|||
|
phost,
|
|||
|
FALSE // ANSI
|
|||
|
);
|
|||
|
}
|
|||
|
return( status );
|
|||
|
|
|||
|
Usage:
|
|||
|
|
|||
|
printf(
|
|||
|
"gethostbyaddr\n"
|
|||
|
"usage:\n"
|
|||
|
" DnsUp -ghba <Address> [<length>] [<family>]\n"
|
|||
|
" <Name> - DNS name to query.\n"
|
|||
|
" \"null\" for null input.\n"
|
|||
|
" \"blank\" for blank (empty string)\n"
|
|||
|
" [length] - length of address\n"
|
|||
|
" defaults to sizeof(IP_ADDRESS)\n"
|
|||
|
" [family] - address family\n"
|
|||
|
" AF_INET = %d\n"
|
|||
|
" AF_INET6 = %d\n"
|
|||
|
" AF_ATM = %d\n"
|
|||
|
" defaults to AF_INET\n",
|
|||
|
AF_INET,
|
|||
|
AF_INET6,
|
|||
|
AF_ATM );
|
|||
|
|
|||
|
return( ERROR_INVALID_PARAMETER );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DNS_STATUS
|
|||
|
ProcessGetAddrInfo(
|
|||
|
IN DWORD Argc,
|
|||
|
IN PSTR * Argv
|
|||
|
)
|
|||
|
{
|
|||
|
DNS_STATUS status;
|
|||
|
PCHAR pname;
|
|||
|
PSTR pservice = NULL;
|
|||
|
PADDRINFO phint = NULL;
|
|||
|
PADDRINFO paddrInfo = NULL;
|
|||
|
ADDRINFO hintAddrInfo;
|
|||
|
BOOL fhint = FALSE;
|
|||
|
INT result;
|
|||
|
|
|||
|
//
|
|||
|
// getaddrinfo <name> [service] [hints]
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc < 1 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// name
|
|||
|
//
|
|||
|
|
|||
|
pname = getNamePointer( Argv[0] );
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
|
|||
|
//
|
|||
|
// setup hints
|
|||
|
// - default flags to include canonnical name
|
|||
|
//
|
|||
|
|
|||
|
RtlZeroMemory(
|
|||
|
& hintAddrInfo,
|
|||
|
sizeof(hintAddrInfo) );
|
|||
|
|
|||
|
hintAddrInfo.ai_flags = AI_CANONNAME;
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// get optional service name or hints
|
|||
|
//
|
|||
|
|
|||
|
while ( Argc )
|
|||
|
{
|
|||
|
PCHAR arg = Argv[0];
|
|||
|
|
|||
|
if ( strncmp( arg, "-s", 2 ) == 0 )
|
|||
|
{
|
|||
|
pservice = getNamePointer( arg+2 );
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
}
|
|||
|
if ( strncmp( arg, "-h", 2 ) == 0 )
|
|||
|
{
|
|||
|
fhint = TRUE;
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
}
|
|||
|
else if ( strncmp( arg, "-f", 2 ) == 0 )
|
|||
|
{
|
|||
|
hintAddrInfo.ai_flags = strtoul( arg+2, NULL, 16 );
|
|||
|
fhint = TRUE;
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
}
|
|||
|
else if ( strncmp( arg, "-m", 2 ) == 0 )
|
|||
|
{
|
|||
|
hintAddrInfo.ai_family = strtoul( arg+2, NULL, 10 );
|
|||
|
fhint = TRUE;
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
}
|
|||
|
else if ( strncmp( arg, "-t", 2 ) == 0 )
|
|||
|
{
|
|||
|
hintAddrInfo.ai_socktype = strtoul( arg+2, NULL, 10 );
|
|||
|
fhint = TRUE;
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
}
|
|||
|
else if ( strncmp( arg, "-p", 2 ) == 0 )
|
|||
|
{
|
|||
|
hintAddrInfo.ai_protocol = strtoul( arg+2, NULL, 10 );
|
|||
|
fhint = TRUE;
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
}
|
|||
|
else if ( strncmp( arg, "-l", 2 ) == 0 )
|
|||
|
{
|
|||
|
hintAddrInfo.ai_addrlen = strtoul( arg+2, NULL, 10 );
|
|||
|
fhint = TRUE;
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// setup hints
|
|||
|
//
|
|||
|
|
|||
|
if ( fhint )
|
|||
|
{
|
|||
|
phint = &hintAddrInfo;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// force winsock start
|
|||
|
//
|
|||
|
|
|||
|
Dns_InitializeWinsock();
|
|||
|
|
|||
|
//
|
|||
|
// call
|
|||
|
//
|
|||
|
|
|||
|
printf(
|
|||
|
"calling getaddrinfo()\n"
|
|||
|
"\tpname = %s\n"
|
|||
|
"\tpservice = %s\n"
|
|||
|
"\tphint = %p\n"
|
|||
|
"\tpaddrinfo buf = %p\n",
|
|||
|
pname,
|
|||
|
pservice,
|
|||
|
phint,
|
|||
|
paddrInfo );
|
|||
|
|
|||
|
if ( phint )
|
|||
|
{
|
|||
|
DnsPrint_AddrInfo(
|
|||
|
dnsup_PrintRoutine,
|
|||
|
dnsup_PrintContext,
|
|||
|
"hint addrinfo",
|
|||
|
1, // indent
|
|||
|
phint
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
result = getaddrinfo(
|
|||
|
pname,
|
|||
|
pservice,
|
|||
|
phint,
|
|||
|
& paddrInfo );
|
|||
|
|
|||
|
status = GetLastError();
|
|||
|
|
|||
|
if ( result != NO_ERROR )
|
|||
|
{
|
|||
|
printf(
|
|||
|
"getaddrinfo(), %x %s.\n",
|
|||
|
status,
|
|||
|
DnsStatusString(status) );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
printf( "getaddrinfo successfully completed.\n" );
|
|||
|
|
|||
|
DnsPrint_AddrInfo(
|
|||
|
dnsup_PrintRoutine,
|
|||
|
dnsup_PrintContext,
|
|||
|
NULL, // default header
|
|||
|
0, // no indent
|
|||
|
paddrInfo
|
|||
|
);
|
|||
|
|
|||
|
freeaddrinfo( paddrInfo );
|
|||
|
}
|
|||
|
return( status );
|
|||
|
|
|||
|
Usage:
|
|||
|
|
|||
|
printf(
|
|||
|
"getaddrinfo\n"
|
|||
|
"usage:\n"
|
|||
|
" DnsUp -gai <Name> [-s<Service>] [-h] [-f<flags>] [-m<family>]\n"
|
|||
|
" [-p<Protocol>] [-t<SockType>] [-l<length>]\n"
|
|||
|
" <Name> - DNS name to query.\n"
|
|||
|
" \"null\" for null input.\n"
|
|||
|
" \"blank\" for blank (empty string)\n"
|
|||
|
" <Service> - service name to query for.\n"
|
|||
|
" [-h] - use hints (this allows empty hint buffer\n"
|
|||
|
" <flags> - hint flags\n"
|
|||
|
" AI_PASSIVE = %0x\n"
|
|||
|
" AI_CANONNAME = %0x\n"
|
|||
|
" AI_NUMERICHOST = %0x\n"
|
|||
|
" <family> - hint family\n"
|
|||
|
" AF_INET = %d\n"
|
|||
|
" AF_INET6 = %d\n"
|
|||
|
" AF_ATM = %d\n"
|
|||
|
" <socktype> - hint socket type\n"
|
|||
|
" <protocol> - hint protocol\n"
|
|||
|
" <length> - hint address length\n",
|
|||
|
|
|||
|
AI_PASSIVE,
|
|||
|
AI_CANONNAME,
|
|||
|
AI_NUMERICHOST,
|
|||
|
|
|||
|
AF_INET,
|
|||
|
AF_INET6,
|
|||
|
AF_ATM );
|
|||
|
|
|||
|
return( ERROR_INVALID_PARAMETER );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DNS_STATUS
|
|||
|
ProcessGetNameInfo(
|
|||
|
IN DWORD Argc,
|
|||
|
IN PSTR * Argv
|
|||
|
)
|
|||
|
{
|
|||
|
DNS_STATUS status;
|
|||
|
BOOL result;
|
|||
|
PCHAR paddr = NULL;
|
|||
|
DWORD addrLength;
|
|||
|
DWORD family;
|
|||
|
DWORD flags = 0;
|
|||
|
|
|||
|
SOCKADDR_IN6 sockaddr;
|
|||
|
CHAR hostBuffer[ DNS_MAX_NAME_BUFFER_LENGTH ];
|
|||
|
CHAR serviceBuffer[ DNS_MAX_NAME_BUFFER_LENGTH ];
|
|||
|
|
|||
|
PSOCKADDR_IN6 psockaddr = &sockaddr;
|
|||
|
PCHAR pservice = serviceBuffer;
|
|||
|
PCHAR phost = hostBuffer;
|
|||
|
DWORD sockaddrLength = sizeof(sockaddr);
|
|||
|
DWORD serviceLength = sizeof(hostBuffer);
|
|||
|
DWORD hostLength = DNS_MAX_NAME_BUFFER_LENGTH;
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// getnameinfo <address> [sockaddr fields | args]
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc < 1 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// address
|
|||
|
//
|
|||
|
|
|||
|
RtlZeroMemory(
|
|||
|
psockaddr,
|
|||
|
sizeof(*psockaddr) );
|
|||
|
|
|||
|
#if 0
|
|||
|
if ( getAddressPointer(
|
|||
|
Argv[0],
|
|||
|
& paddr,
|
|||
|
& addrLength,
|
|||
|
& family ) )
|
|||
|
{
|
|||
|
sockaddr.sin6_family = (SHORT) family;
|
|||
|
|
|||
|
if ( family == AF_INET )
|
|||
|
{
|
|||
|
RtlCopyMemory(
|
|||
|
& ((PSOCKADDR_IN)psockaddr)->sin_addr,
|
|||
|
paddr,
|
|||
|
addrLength );
|
|||
|
|
|||
|
sockaddrLength = sizeof(SOCKADDR_IN);
|
|||
|
}
|
|||
|
else // IP6
|
|||
|
{
|
|||
|
RtlCopyMemory(
|
|||
|
& psockaddr->sin6_addr,
|
|||
|
paddr,
|
|||
|
addrLength );
|
|||
|
|
|||
|
sockaddrLength = sizeof(SOCKADDR_IN6);
|
|||
|
}
|
|||
|
}
|
|||
|
else // special bogus address, use it directly
|
|||
|
{
|
|||
|
psockaddr = (PSOCKADDR_IN6) paddr;
|
|||
|
}
|
|||
|
#endif
|
|||
|
if ( getAddressPointer(
|
|||
|
Argv[0],
|
|||
|
& paddr,
|
|||
|
& addrLength,
|
|||
|
& family ) )
|
|||
|
{
|
|||
|
status = Dns_AddressToSockaddr(
|
|||
|
(PSOCKADDR) &sockaddr,
|
|||
|
& sockaddrLength,
|
|||
|
TRUE, // clear
|
|||
|
paddr,
|
|||
|
addrLength,
|
|||
|
family );
|
|||
|
|
|||
|
if ( status != NO_ERROR )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
}
|
|||
|
else // special bogus address, use it directly
|
|||
|
{
|
|||
|
psockaddr = (PSOCKADDR_IN6) paddr;
|
|||
|
}
|
|||
|
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
|
|||
|
//
|
|||
|
// get sockaddr fields or optional arguments
|
|||
|
// - note, if using bogus sockaddr, the sockaddr tweaks are lost
|
|||
|
//
|
|||
|
|
|||
|
while ( Argc )
|
|||
|
{
|
|||
|
PCHAR arg = Argv[0];
|
|||
|
|
|||
|
// flags
|
|||
|
|
|||
|
if ( strncmp( arg, "-f", 2 ) == 0 )
|
|||
|
{
|
|||
|
flags = strtoul( arg+2, NULL, 16 );
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
}
|
|||
|
|
|||
|
// sockaddr subfields
|
|||
|
|
|||
|
else if ( strncmp( arg, "-m", 2 ) == 0 )
|
|||
|
{
|
|||
|
sockaddr.sin6_family = (SHORT) strtoul( arg+2, NULL, 10 );
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
}
|
|||
|
else if ( strncmp( arg, "-p", 2 ) == 0 )
|
|||
|
{
|
|||
|
sockaddr.sin6_port = (SHORT) strtoul( arg+2, NULL, 10 );
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
}
|
|||
|
|
|||
|
// tweak out params
|
|||
|
|
|||
|
else if ( strncmp( arg, "-sl", 3 ) == 0 )
|
|||
|
{
|
|||
|
serviceLength = strtoul( arg+3, NULL, 10 );
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
}
|
|||
|
else if ( _strnicmp( arg, "-snull", 5 ) == 0 )
|
|||
|
{
|
|||
|
pservice = NULL;
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
}
|
|||
|
else if ( strncmp( arg, "-hl", 3 ) == 0 )
|
|||
|
{
|
|||
|
hostLength = strtoul( arg+3, NULL, 10 );
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
}
|
|||
|
else if ( _strnicmp( arg, "-hnull", 5 ) == 0 )
|
|||
|
{
|
|||
|
phost = NULL;
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// force winsock start
|
|||
|
//
|
|||
|
|
|||
|
Dns_InitializeWinsock();
|
|||
|
|
|||
|
//
|
|||
|
// call
|
|||
|
//
|
|||
|
|
|||
|
printf(
|
|||
|
"Calling getnameinfo()\n"
|
|||
|
"\tsockaddr %p\n"
|
|||
|
"\tsockaddr len %d\n"
|
|||
|
"\thost buffer %p\n"
|
|||
|
"\thost buflen %d\n"
|
|||
|
"\tservice buffer %p\n"
|
|||
|
"\tservice buflen %d\n"
|
|||
|
"\tflags %08x\n",
|
|||
|
psockaddr,
|
|||
|
sockaddrLength,
|
|||
|
phost,
|
|||
|
hostLength,
|
|||
|
pservice,
|
|||
|
serviceLength,
|
|||
|
flags );
|
|||
|
|
|||
|
DnsPrint_Sockaddr(
|
|||
|
dnsup_PrintRoutine,
|
|||
|
dnsup_PrintContext,
|
|||
|
"\n\tsockaddr",
|
|||
|
1, // indent
|
|||
|
(PSOCKADDR) psockaddr,
|
|||
|
sockaddrLength );
|
|||
|
|
|||
|
result = getnameinfo(
|
|||
|
(PSOCKADDR) psockaddr,
|
|||
|
sockaddrLength,
|
|||
|
phost,
|
|||
|
hostLength,
|
|||
|
pservice,
|
|||
|
serviceLength,
|
|||
|
flags );
|
|||
|
|
|||
|
status = GetLastError();
|
|||
|
|
|||
|
if ( result != NO_ERROR )
|
|||
|
{
|
|||
|
printf(
|
|||
|
"getnameinfo(), %x %s.\n",
|
|||
|
status,
|
|||
|
DnsStatusString(status) );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
printf(
|
|||
|
"getnameinfo successfully completed.\n"
|
|||
|
"\thost = %s\n"
|
|||
|
"\tservice = %s\n",
|
|||
|
phost,
|
|||
|
pservice );
|
|||
|
}
|
|||
|
return( status );
|
|||
|
|
|||
|
Usage:
|
|||
|
|
|||
|
printf(
|
|||
|
"getnameinfo\n"
|
|||
|
"usage:\n"
|
|||
|
" DnsUp -gni <Address> [-s<Service>] [-f<flags>] [-m<family>]\n"
|
|||
|
" [-p<port>] [-sl<length>] [-snull] [-hl<length>] [-hnull]\n"
|
|||
|
" <Address> - Address string to query name for.\n"
|
|||
|
" \"null\" for null input.\n"
|
|||
|
" \"blank\" for blank (empty string)\n"
|
|||
|
" <flags> - hint flags\n"
|
|||
|
" AI_PASSIVE = %0x\n"
|
|||
|
" AI_CANONNAME = %0x\n"
|
|||
|
" AI_NUMERICHOST = %0x\n"
|
|||
|
" <family> - sockaddr family, overrides default for address;\n"
|
|||
|
" AF_INET = %d\n"
|
|||
|
" AF_INET6 = %d\n"
|
|||
|
" AF_ATM = %d\n"
|
|||
|
" <port> - port to set in sockaddr; defaults to zero\n"
|
|||
|
" <length> - length of out buffer\n"
|
|||
|
" -sl<length> - length of service name buffer\n"
|
|||
|
" -hl<length> - length of host name buffer\n"
|
|||
|
" [-snull] - server buffer ptr NULL\n"
|
|||
|
" [-hnull] - host buffer ptr NULL\n",
|
|||
|
|
|||
|
AI_PASSIVE,
|
|||
|
AI_CANONNAME,
|
|||
|
AI_NUMERICHOST,
|
|||
|
|
|||
|
AF_INET,
|
|||
|
AF_INET6,
|
|||
|
AF_ATM );
|
|||
|
|
|||
|
return( ERROR_INVALID_PARAMETER );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DNS_STATUS
|
|||
|
ProcessClusterIp(
|
|||
|
IN DWORD Argc,
|
|||
|
IN PSTR * Argv
|
|||
|
)
|
|||
|
{
|
|||
|
SOCKADDR_IN6 sockaddr;
|
|||
|
PSOCKADDR psockaddr = (PSOCKADDR) &sockaddr;
|
|||
|
DWORD sockaddrLength = sizeof(sockaddr);
|
|||
|
IP_ADDRESS ip;
|
|||
|
BOOL fadd = TRUE;
|
|||
|
PWSTR pname = NULL;
|
|||
|
DNS_STATUS status;
|
|||
|
|
|||
|
//
|
|||
|
// -ci <Name> <IP> [-d]
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc < 1 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// name
|
|||
|
//
|
|||
|
|
|||
|
pname = (PWSTR) Dns_StringCopyAllocate(
|
|||
|
Argv[0],
|
|||
|
0, // unknown length
|
|||
|
DnsCharSetAnsi,
|
|||
|
DnsCharSetUnicode );
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
|
|||
|
//
|
|||
|
// cluster IP
|
|||
|
//
|
|||
|
|
|||
|
#if 0
|
|||
|
ip = inet_addr( Argv[0] );
|
|||
|
if ( ip == (-1) )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
#endif
|
|||
|
|
|||
|
if ( !getSockaddrFromString(
|
|||
|
& psockaddr,
|
|||
|
& sockaddrLength,
|
|||
|
Argv[0] ) )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
|
|||
|
//
|
|||
|
// optional delete flag
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc > 0 )
|
|||
|
{
|
|||
|
if ( strncmp( Argv[0], "-d", 2 ) == 0 )
|
|||
|
{
|
|||
|
fadd = FALSE;
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
}
|
|||
|
if ( Argc != 0 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// notify resolver
|
|||
|
//
|
|||
|
|
|||
|
status = DnsRegisterClusterAddress(
|
|||
|
0xd734453d,
|
|||
|
pname,
|
|||
|
psockaddr,
|
|||
|
fadd );
|
|||
|
|
|||
|
FREE_HEAP( pname );
|
|||
|
return( status );
|
|||
|
|
|||
|
Usage:
|
|||
|
|
|||
|
printf(
|
|||
|
"Set Cluster IP\n"
|
|||
|
"usage:\n"
|
|||
|
" DnsUp [-ci] <Name> <IP> [-d]\n"
|
|||
|
" <Name> is cluster name\n"
|
|||
|
" <IP> is cluster IP\n"
|
|||
|
" [-d] to indicate delete of cluster IP\n"
|
|||
|
);
|
|||
|
|
|||
|
FREE_HEAP( pname );
|
|||
|
return( ERROR_INVALID_PARAMETER );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
#if 0
|
|||
|
DNS_STATUS
|
|||
|
ProcessAddIp(
|
|||
|
IN DWORD Argc,
|
|||
|
IN PSTR * Argv
|
|||
|
)
|
|||
|
{
|
|||
|
IP_ADDRESS ip;
|
|||
|
BOOL fadd = TRUE;
|
|||
|
|
|||
|
//
|
|||
|
// -addip <IP>
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc < 1 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// IP to add
|
|||
|
//
|
|||
|
|
|||
|
ip = inet_addr( Argv[0] );
|
|||
|
if ( ip == (-1) )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
|
|||
|
//
|
|||
|
// optional delete flag
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc > 0 )
|
|||
|
{
|
|||
|
if ( strncmp( Argv[0], "-d", 2 ) == 0 )
|
|||
|
{
|
|||
|
fadd = FALSE;
|
|||
|
Argc--;
|
|||
|
Argv++;
|
|||
|
}
|
|||
|
if ( Argc != 0 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// notify resolver
|
|||
|
//
|
|||
|
|
|||
|
DnsNotifyResolverClusterIp(
|
|||
|
ip,
|
|||
|
fadd );
|
|||
|
|
|||
|
return( ERROR_SUCCESS );
|
|||
|
|
|||
|
Usage:
|
|||
|
|
|||
|
printf(
|
|||
|
"usage:\n"
|
|||
|
" DnsUp [-ci] <IP> [-d]\n"
|
|||
|
" <IP> is cluster IP\n"
|
|||
|
" [-d] to indicate delete of cluster IP\n"
|
|||
|
);
|
|||
|
return( ERROR_INVALID_PARAMETER );
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DNS_STATUS
|
|||
|
ProcessSetEnvironmentVariable(
|
|||
|
IN DWORD Argc,
|
|||
|
IN PSTR * Argv
|
|||
|
)
|
|||
|
{
|
|||
|
//
|
|||
|
// setenv <name> <value>
|
|||
|
//
|
|||
|
|
|||
|
if ( Argc < 1 || Argc > 2 )
|
|||
|
{
|
|||
|
goto Usage;
|
|||
|
}
|
|||
|
|
|||
|
SetEnvironmentVariableA(
|
|||
|
Argv[0],
|
|||
|
(Argc == 2) ? Argv[1] : NULL );
|
|||
|
|
|||
|
return( ERROR_SUCCESS );
|
|||
|
|
|||
|
Usage:
|
|||
|
|
|||
|
printf(
|
|||
|
"Set environment variable\n"
|
|||
|
"usage:\n"
|
|||
|
" DnsUp [-setenv] <name> [<value>]\n"
|
|||
|
" <name> name of environment variable\n"
|
|||
|
" <value> value of environment variable, if missing\n"
|
|||
|
" then environment variable is deleted\n"
|
|||
|
);
|
|||
|
return( ERROR_INVALID_PARAMETER );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Command Table
|
|||
|
//
|
|||
|
// Keep this down here to avoid having prototypes for
|
|||
|
// all these functions.
|
|||
|
//
|
|||
|
|
|||
|
COMMAND_INFO GlobalCommandInfo[] =
|
|||
|
{
|
|||
|
// query
|
|||
|
|
|||
|
{ "qex" , "QueryEx" , ProcessQueryEx },
|
|||
|
{ "qc" , "QueryCompare" , ProcessQueryCompare },
|
|||
|
{ "q" , "Query" , ProcessQuery },
|
|||
|
{ "qm" , "QueryMulitple" , ProcessQueryMultiple },
|
|||
|
{ "qt" , "QueryTest" , ProcessQueryTest },
|
|||
|
{ "iq" , "IQuery" , ProcessIQuery },
|
|||
|
|
|||
|
// update
|
|||
|
|
|||
|
{ "u" , "Update" , ProcessUpdate },
|
|||
|
{ "ut" , "UpdateTest" , ProcessUpdateTest },
|
|||
|
//{ "um" , "UpdateMultiple" , ProcessUpdateMultiple },
|
|||
|
{ "dt" , "DhcpTest" , ProcessDhcpTest },
|
|||
|
{ "mr" , "ModifyRecordsInSet" , ProcessModifyRecordsInSet },
|
|||
|
{ "rs" , "ReplaceRecordSet" , ProcessReplaceRecordSet },
|
|||
|
|
|||
|
// utility
|
|||
|
|
|||
|
{ "vn" , "ValidateName" , ProcessValidateName },
|
|||
|
{ "s" , "StringTranslate" , ProcessStringTranslate },
|
|||
|
{ "cn" , "NameCompare" , ProcessNameCompare },
|
|||
|
{ "cnx" , "NameCompareEx" , ProcessNameCompareEx },
|
|||
|
{ "config" , "QueryConfig" , ProcessQueryConfig },
|
|||
|
|
|||
|
// config
|
|||
|
|
|||
|
{ "setenv" , "SetEnvironmentVariable", ProcessSetEnvironmentVariable },
|
|||
|
|
|||
|
// resolver
|
|||
|
|
|||
|
{ "ci" , "ClusterIp" , ProcessClusterIp },
|
|||
|
|
|||
|
// RnR
|
|||
|
|
|||
|
{ "ghn" , "gethostname" , ProcessGetHostName },
|
|||
|
{ "ghbn" , "gethostbyname" , ProcessGetHostByName },
|
|||
|
{ "ghba" , "gethostbyaddr" , ProcessGetHostByAddr },
|
|||
|
{ "gai" , "getaddrinfo" , ProcessGetAddrInfo },
|
|||
|
{ "gni" , "getnameinfo" , ProcessGetNameInfo },
|
|||
|
{ "lsb" , "LookupServiceBegin" , ProcessLookupServiceBegin },
|
|||
|
{ "lsn" , "LookupServiceNext" , ProcessLookupServiceNext },
|
|||
|
{ "lse" , "LookupServiceEnd" , ProcessLookupServiceEnd },
|
|||
|
|
|||
|
// quit
|
|||
|
|
|||
|
{ "quit" , "Quit" , ProcessQuit },
|
|||
|
{ "exit" , "Quit" , ProcessQuit },
|
|||
|
|
|||
|
{ NULL, NULL, NULL },
|
|||
|
};
|
|||
|
|
|||
|
//
|
|||
|
// End dnsup.c
|
|||
|
//
|