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
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;
|
|
}
|