Leaked source code of windows server 2003
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.
 
 
 
 
 
 

213 lines
5.9 KiB

/*++
Copyright (c) 1989-2001 Microsoft Corporation
Module Name:
host.c
Abstract:
etc/hosts parser
Author:
Jiandong Ruan
Revision History:
Feb-15-2001 First functional version
--*/
#include "precomp.h"
#include "fileio.h"
#include "debug.h"
#define IS_VALID_HOSTNAME_CHAR(ch) \
(((ch) >= 'a' && (ch) <= 'z') || ((ch) == '.') || \
((ch) >= 'A' && (ch) <= 'Z') || \
((ch) >= '0' && (ch) <= '9') || \
((ch) == '_') || ((ch) == '-'))
#define IS_VALID_IPADDR_CHAR(ch) \
(((ch) >= '0' && (ch) <= '9') || \
((ch) >= 'a' && (ch) <= 'f') || \
((ch) >= 'A' && (ch) <= 'F') || \
((ch) == '.') || ((ch) == ':'))
#define ISSPACE(ch) \
(((ch) == ' ') || ((ch) == '\t'))
#define ISNEWLINE(ch) \
(((ch) == '\r') || ((ch) == '\n'))
#define NEXT_LINE() \
do { \
while (ch != EOF && !ISNEWLINE(ch)) { \
ch = Smb_fgetc(fp); \
} \
while (ISNEWLINE(ch)) { \
ch = Smb_fgetc(fp); \
} \
} while (0)
#define SKIP_SPACE() \
do { \
while (ISSPACE(ch)) { \
ch = Smb_fgetc(fp); \
} \
} while(0)
#define SKIP_EMPTY_LINE() \
do { \
while (ISNEWLINE(ch)) { \
ch = Smb_fgetc(fp); \
} \
} while(0)
#define SMB_MAX_HOST_NAME_SIZE 256
#define SMB_MAX_IPADDR_SIZE 40
BOOL
SmbLookupHost(
WCHAR *host,
PSMB_IP_ADDRESS ipaddr
)
{
PSMB_FILE fp;
int ch;
int addr_size, name_size;
CHAR addr[SMB_MAX_IPADDR_SIZE];
CHAR name[SMB_MAX_HOST_NAME_SIZE];
UNICODE_STRING ucHost;
ANSI_STRING oemHost, oemName, oemAddr;
NTSTATUS status;
//
// We need to test it in user mode. PAGED_CODE() import KeGetCurrentIrql() which
// cannot be provided by user mode
//
//PAGED_CODE();
fp = NULL;
oemHost.Buffer = NULL;
fp = Smb_fopen(L"\\SystemRoot\\System32\\drivers\\etc\\hosts", L"r");
if (fp == NULL) {
return FALSE;
}
RtlInitUnicodeString(&ucHost, host);
status = RtlUnicodeStringToAnsiString(&oemHost, &ucHost, TRUE);
BAIL_OUT_ON_ERROR(status);
ch = Smb_fgetc(fp);
while(ch != EOF) {
SKIP_EMPTY_LINE();
SKIP_SPACE();
if (ch == '#') {
//
// This is comment, skip to the next line
//
NEXT_LINE();
continue;
}
if (ch == EOF) {
break;
}
//
// Parse this entry
// ipaddr host-name
//
//
// parse the ipaddr
//
addr_size = 0;
while (IS_VALID_IPADDR_CHAR(ch)) {
addr[addr_size++] = (CHAR)ch;
ch = Smb_fgetc(fp);
if (addr_size >= SMB_MAX_IPADDR_SIZE) {
break;
}
}
if (addr_size >= SMB_MAX_IPADDR_SIZE || !ISSPACE(ch)) {
NEXT_LINE();
continue;
}
addr[addr_size] = '\0';
//
// parse the host-name
//
SKIP_SPACE();
name_size = 0;
while (IS_VALID_HOSTNAME_CHAR(ch)) {
name[name_size++] = (CHAR)ch;
ch = Smb_fgetc(fp);
if (name_size >= SMB_MAX_IPADDR_SIZE) {
break;
}
}
if (name_size >= SMB_MAX_HOST_NAME_SIZE || (ch != EOF && !ISSPACE(ch) && ch != '#' && !ISNEWLINE(ch))) {
NEXT_LINE();
continue;
}
name[name_size] = '\0';
//
// Compare
//
RtlInitAnsiString(&oemName, name);
if (RtlCompareString(&oemName, &oemHost, TRUE) == 0) {
UNICODE_STRING ucAddr;
RtlInitAnsiString(&oemAddr, addr);
status = RtlAnsiStringToUnicodeString(&ucAddr, &oemAddr, TRUE);
BAIL_OUT_ON_ERROR(status);
//
// Check if it is an IPv6 format
//
if (inet_addr6W(ucAddr.Buffer, &ipaddr->ip6)) {
RtlFreeUnicodeString(&ucAddr);
RtlFreeAnsiString(&oemHost);
Smb_fclose(fp);
ipaddr->sin_family = SMB_AF_INET6;
return TRUE;
}
//
// Check if it is an IPv4 format
//
ipaddr->ip4.sin4_addr = inet_addrW(ucAddr.Buffer);
if (ipaddr->ip4.sin4_addr != INADDR_NONE) {
RtlFreeUnicodeString(&ucAddr);
RtlFreeAnsiString(&oemHost);
Smb_fclose(fp);
ipaddr->sin_family = SMB_AF_INET;
return TRUE;
}
RtlFreeUnicodeString(&ucAddr);
}
}
cleanup:
if (fp) {
Smb_fclose(fp);
}
if (oemHost.Buffer) {
RtlFreeAnsiString(&oemHost);
}
return FALSE;
}