mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
411 lines
9.9 KiB
411 lines
9.9 KiB
/*++
|
|
|
|
Copyright (c) 1991 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
r_init.c
|
|
|
|
Abstract:
|
|
|
|
This module contains routines to initialize the DNS resolver.
|
|
|
|
Author:
|
|
|
|
Mike Massa (mikemas) Sept 20, 1991
|
|
|
|
Revision History:
|
|
|
|
Who When What
|
|
-------- -------- ----------------------------------------------
|
|
mikemas 9-20-91 created
|
|
|
|
Notes:
|
|
|
|
Exports:
|
|
res_init()
|
|
|
|
--*/
|
|
|
|
#ident "@(#)res_init.c 5.3 3/8/91"
|
|
|
|
/******************************************************************
|
|
*
|
|
* SpiderTCP BIND
|
|
*
|
|
* Copyright 1990 Spider Systems Limited
|
|
*
|
|
* RES_INIT.C
|
|
*
|
|
******************************************************************/
|
|
|
|
/*-
|
|
* /usr/projects/tcp/SCCS.rel3/rel/src/lib/net/0/s.res_init.c
|
|
* @(#)res_init.c 5.3
|
|
*
|
|
* Last delta created 14:11:42 3/4/91
|
|
* This file extracted 11:20:32 3/8/91
|
|
*
|
|
* Modifications:
|
|
*
|
|
* GSS 24 Jul 90 New File
|
|
*/
|
|
/*
|
|
* Copyright (c) 1985, 1989 Regents of the University of California.
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms are permitted provided
|
|
* that: (1) source distributions retain this entire copyright notice and
|
|
* comment, and (2) distributions including binaries display the following
|
|
* acknowledgement: ``This product includes software developed by the
|
|
* University of California, Berkeley and its contributors'' in the
|
|
* documentation or other materials provided with the distribution and in
|
|
* all advertising materials mentioning features or use of this software.
|
|
* Neither the name of the University nor the names of its contributors may
|
|
* be used to endorse or promote products derived from this software without
|
|
* specific prior written permission.
|
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
|
|
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
*/
|
|
|
|
#if defined(LIBC_SCCS) && !defined(lint)
|
|
static char sccsid[] = "@(#)res_init.c 6.14 (Berkeley) 6/27/90";
|
|
#endif /* LIBC_SCCS and not lint */
|
|
/****************************************************************************/
|
|
|
|
#include "winsockp.h"
|
|
|
|
#define LOCALHOST "127.0.0.1"
|
|
|
|
#define WORK_BUFFER_SIZE 1024
|
|
|
|
#define RESCONF_SIZE (_MAX_PATH + 10)
|
|
|
|
#define index strchr
|
|
|
|
BOOL
|
|
BuildDnsServerList(
|
|
LPADDR_LIST AddressList,
|
|
PUCHAR RawData
|
|
);
|
|
|
|
int
|
|
_pgethostname(
|
|
OUT char *name,
|
|
IN int namelen
|
|
);
|
|
|
|
/*
|
|
* Set up default settings. If the configuration file exist, the values
|
|
* there will have precedence. Otherwise, the server address is set to
|
|
* LOCALHOST and the default domain name comes from the gethostname().
|
|
*
|
|
* The configuration file should only be used if you want to redefine your
|
|
* domain or run without a server on your machine.
|
|
*
|
|
* Return 0 if completes successfully, -1 on error
|
|
*/
|
|
int
|
|
res_init(
|
|
void
|
|
)
|
|
{
|
|
register char *cp, *cpt, **pp;
|
|
register int n;
|
|
int nserv = 0; /* number of nameserver records read from file */
|
|
int havesearch = 0;
|
|
long options = 0L;
|
|
PUCHAR temp;
|
|
HANDLE myKey;
|
|
NTSTATUS status;
|
|
ULONG myType;
|
|
DWORD numLists = 0;
|
|
DWORD oneAddress;
|
|
extern int GetIpAddressList(LPDWORD IpAddressList, WORD ListCount);
|
|
|
|
IF_DEBUG(RESOLVER) {
|
|
WS_PRINT(("res_init entered\n"));
|
|
}
|
|
|
|
if ((_res.options & RES_INIT) != 0) {
|
|
return (0);
|
|
}
|
|
|
|
//
|
|
// Hack! If there are no IP addresses, then fail resolver init.
|
|
//
|
|
|
|
if( GetIpAddressList( &oneAddress, 1 ) <= 0 ||
|
|
oneAddress == htonl( INADDR_LOOPBACK ) ) {
|
|
SetLastError( WSANO_DATA );
|
|
return -1;
|
|
}
|
|
|
|
RtlZeroMemory(
|
|
&_res.nslist,
|
|
sizeof(_res.nslist)
|
|
);
|
|
|
|
status = SockOpenKeyEx( &myKey, VTCPPARM, NTCPPARM, TCPPARM );
|
|
if (!NT_SUCCESS(status)) {
|
|
IF_DEBUG(RESOLVER) {
|
|
WS_PRINT(("Required Registry Key is missing -- %s\n", NTCPPARM));
|
|
}
|
|
SetLastError( ERROR_INVALID_PARAMETER );
|
|
return -1;
|
|
}
|
|
|
|
if ((temp=ALLOCATE_HEAP(WORK_BUFFER_SIZE))==NULL) {
|
|
IF_DEBUG(RESOLVER) {
|
|
WS_PRINT(("Out of memory!\n"));
|
|
}
|
|
NtClose(myKey);
|
|
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
|
|
return -1;
|
|
}
|
|
|
|
/* read default domain name */
|
|
status = SockGetSingleValue(myKey, "Domain", temp,
|
|
&myType, WORK_BUFFER_SIZE);
|
|
if (!NT_SUCCESS(status) || (strlen(temp) == 0)) {
|
|
status = SockGetSingleValue(myKey, "DhcpDomain", temp,
|
|
&myType, WORK_BUFFER_SIZE);
|
|
}
|
|
if (NT_SUCCESS(status)) {
|
|
(void)strncpy(_res.defdname, temp, sizeof(_res.defdname) - 1);
|
|
havesearch = 0;
|
|
}
|
|
|
|
/* set search list */
|
|
status = SockGetSingleValue(myKey, "SearchList", temp,
|
|
&myType, WORK_BUFFER_SIZE);
|
|
if (NT_SUCCESS(status) && (strlen(temp)>0)) {
|
|
(void)strncpy(_res.defdname, temp, sizeof(_res.defdname) - 1);
|
|
/*
|
|
* Set search list to be blank-separated strings
|
|
* on rest of line.
|
|
*/
|
|
cp = _res.defdname;
|
|
pp = _res.dnsrch;
|
|
*pp++ = cp;
|
|
for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) {
|
|
if (*cp == ' ' || *cp == '\t') {
|
|
*cp = 0;
|
|
n = 1;
|
|
} else if (n) {
|
|
*pp++ = cp;
|
|
n = 0;
|
|
}
|
|
}
|
|
/* null terminate last domain if there are excess */
|
|
while (*cp != '\0' && *cp != ' ' && *cp != '\t') {
|
|
cp++;
|
|
}
|
|
*cp = '\0';
|
|
*pp++ = 0;
|
|
havesearch = 1;
|
|
}
|
|
|
|
//
|
|
// List 0 is the statically configured DNS server list.
|
|
//
|
|
|
|
status = SockGetSingleValue(
|
|
myKey,
|
|
"NameServer",
|
|
temp,
|
|
&myType,
|
|
WORK_BUFFER_SIZE
|
|
);
|
|
|
|
if( NT_SUCCESS(status) ) {
|
|
if( BuildDnsServerList(
|
|
&_res.nslist[0],
|
|
temp
|
|
) ) {
|
|
numLists++;
|
|
}
|
|
}
|
|
|
|
//
|
|
// List 1 is the DHCP configured list.
|
|
//
|
|
|
|
status = SockGetSingleValue(
|
|
myKey,
|
|
"DhcpNameServer",
|
|
temp,
|
|
&myType,
|
|
WORK_BUFFER_SIZE
|
|
);
|
|
|
|
if( NT_SUCCESS(status) ) {
|
|
if( BuildDnsServerList(
|
|
&_res.nslist[numLists],
|
|
temp
|
|
) ) {
|
|
numLists++;
|
|
}
|
|
}
|
|
|
|
//
|
|
// List 2 is the RAS configured list.
|
|
//
|
|
|
|
{
|
|
HANDLE tKey;
|
|
|
|
status = SockOpenKey( &tKey, TTCPPARM );
|
|
|
|
if( NT_SUCCESS(status) ) {
|
|
status = SockGetSingleValue(
|
|
tKey,
|
|
"NameServer",
|
|
temp,
|
|
&myType,
|
|
WORK_BUFFER_SIZE
|
|
);
|
|
|
|
if( NT_SUCCESS(status) ) {
|
|
if( BuildDnsServerList(
|
|
&_res.nslist[numLists],
|
|
temp
|
|
) ) {
|
|
numLists++;
|
|
}
|
|
}
|
|
|
|
NtClose( tKey );
|
|
}
|
|
}
|
|
|
|
NtClose(myKey);
|
|
|
|
IF_DEBUG(RESOLVER) {
|
|
WS_PRINT(("options = %lx\n", options));
|
|
}
|
|
|
|
_res.options |= options;
|
|
|
|
if (_res.defdname[0] == 0) {
|
|
if (_pgethostname(temp, sizeof(_res.defdname)) == 0 &&
|
|
(cp = index(temp, '.'))) {
|
|
(void)strcpy(_res.defdname, cp + 1);
|
|
}
|
|
}
|
|
|
|
/* find components of local domain that might be searched */
|
|
if (havesearch == 0) {
|
|
pp = _res.dnsrch;
|
|
*pp++ = _res.defdname;
|
|
for (cp = _res.defdname, n = 0; *cp; cp++) {
|
|
if (*cp == '.') {
|
|
n++;
|
|
}
|
|
}
|
|
cp = _res.defdname;
|
|
for (; n >= LOCALDOMAINPARTS && pp < _res.dnsrch+MAXDFLSRCH; n--) {
|
|
cp = index(cp, '.');
|
|
*pp++ = ++cp;
|
|
}
|
|
*pp++ = 0;
|
|
}
|
|
_res.options |= RES_INIT;
|
|
FREE_HEAP(temp);
|
|
return (0);
|
|
}
|
|
|
|
BOOL
|
|
querydnsaddrs (
|
|
IN LPDWORD *Array,
|
|
IN PVOID Buffer
|
|
)
|
|
{
|
|
u_long listIndex;
|
|
u_long serverIndex;
|
|
u_long numServers;
|
|
int i;
|
|
LPDWORD next = Buffer;
|
|
|
|
if (res_init() == -1) {
|
|
return FALSE;
|
|
}
|
|
|
|
i = 0;
|
|
|
|
for( listIndex = 0 ; listIndex < MAXNSLIST ; listIndex++ ) {
|
|
numServers = _res.nslist[listIndex].ServerCount;
|
|
|
|
for( serverIndex = 0 ; serverIndex < numServers ; serverIndex++ ) {
|
|
*next = _res.nslist[listIndex].Servers[serverIndex];
|
|
*(Array + i) = next;
|
|
next++;
|
|
i++;
|
|
}
|
|
}
|
|
|
|
*(Array + i) = NULL;
|
|
|
|
if ( i == 0 ) {
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
} // querydnsaddrs
|
|
|
|
BOOL
|
|
BuildDnsServerList(
|
|
LPADDR_LIST AddressList,
|
|
PUCHAR RawData
|
|
)
|
|
{
|
|
int dataLength;
|
|
u_long numServers;
|
|
PUCHAR tmp;
|
|
|
|
dataLength = strlen( RawData );
|
|
numServers = 0;
|
|
|
|
while( ( *RawData != '\0' ) && ( numServers < MAXNS ) ) {
|
|
|
|
while( dataLength > 0 &&
|
|
( *RawData == ' ' || *RawData == '\t' || *RawData == ',' ) ) {
|
|
RawData++;
|
|
dataLength--;
|
|
}
|
|
|
|
tmp = RawData;
|
|
|
|
while( dataLength > 0 &&
|
|
( *tmp != ' ' && *tmp != '\t' && *tmp != '\0' && *tmp != ',' ) ) {
|
|
tmp++;
|
|
dataLength--;
|
|
}
|
|
|
|
*tmp = '\0';
|
|
|
|
AddressList->Servers[numServers] = inet_addr( RawData );
|
|
|
|
if( AddressList->Servers[numServers] == INADDR_ANY ||
|
|
AddressList->Servers[numServers] == INADDR_NONE ) {
|
|
return FALSE;
|
|
}
|
|
|
|
numServers++;
|
|
|
|
if( dataLength > 0 ) {
|
|
RawData = tmp + 1;
|
|
dataLength--;
|
|
} else {
|
|
*RawData = '\0';
|
|
}
|
|
}
|
|
|
|
AddressList->ServerCount = numServers;
|
|
|
|
return TRUE;
|
|
|
|
} // BuildDnsServerList
|
|
|