📄 dnslookup.c
字号:
/* * Copyright (C) 2006 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. *//* * This module uses Windows lookup facilities to get the address information * wherever it resides. This avoids calling the Internet standard funcction * gethostbyname and gives us more control over the results since the * Microsoft implementation seems to return the wrong error code for some * conditions. */#include <config.h>#include <ws2tcpip.h>#include <nspapi.h>#include <svcguid.h>#include <ntp_rfc2553.h>#include <malloc.h>#include <ntp_stdlib.h>#include <syslog.h>/* * Set this Macro to force retries even if it fails * the lookup */#ifdef FORCE_DNSRETRY#undef EAI_NONAME#define EAI_NONAME EAI_AGAIN#endiftypedef struct hostent hostent_t;int ReturnCode(int errcode){ int retcode; switch (errcode) { case 0: return (0); case WSAEINVAL: return (EAI_BADFLAGS); case WSANO_DATA: return (EAI_NONAME); case WSANOTINITIALISED: case WSASERVICE_NOT_FOUND: return (EAI_FAIL); case WSA_NOT_ENOUGH_MEMORY: return (EAI_MEMORY); default: return (EAI_FAIL); }}intAddToAddresses(char **Addresses, int *cnt, CSADDR_INFO *csaddr){ int csize; struct in_addr *sinaddr; char *addr; struct in_addr *addr_list; struct sockaddr_in *sin; sin = (struct sockaddr_in *) csaddr->RemoteAddr.lpSockaddr; if (*Addresses != NULL) { csize = _msize(*Addresses); addr_list = realloc(*Addresses, csize + sizeof(struct in_addr)); } else { csize = 0; addr_list = malloc(sizeof(struct in_addr)); } addr = (char *) addr_list; sinaddr = &((struct in_addr*) addr)[(*cnt)]; memset(sinaddr, 0, sizeof(sinaddr)); memcpy(sinaddr, &sin->sin_addr, sizeof(struct in_addr)); (*cnt)++; *Addresses = (char *) addr_list; return 0;}intDNSlookup_name( const char *name, int ai_family, struct hostent **Addresses){ char buffer[sizeof(WSAQUERYSET) + 2048]; WSAQUERYSET query; struct hostent *addr = NULL; char *bufaddr = NULL; char ** addrlist = &bufaddr; int addrcnt = 0; WSAQUERYSET *results = (WSAQUERYSET *) buffer; GUID HostnameGUID = SVCID_INET_HOSTADDRBYNAME; HANDLE handle; DWORD dwLength; int err = 0; int retcode = 0; int errcode = 0; DWORD i; /* * First we must create a query set */ memset(&query, 0, sizeof(query)); query.dwSize = sizeof(query); query.lpszServiceInstanceName = (char *)name; query.dwNameSpace = NS_DNS; query.lpServiceClassId = &HostnameGUID; err = WSALookupServiceBegin(&query, LUP_RETURN_NAME | LUP_RETURN_BLOB | LUP_RETURN_ADDR, &handle); if(err == SOCKET_ERROR) { /* * Convert the error code and return */ return (ReturnCode(WSAGetLastError())); } /* * Initially none * Change if we get something */ retcode = EAI_NONAME; dwLength = sizeof(buffer); while(err == 0) /* Drop out when error */ { memset(&buffer, 0, dwLength); err = WSALookupServiceNext( handle, 0, &dwLength, results); errcode = WSAGetLastError(); if (results->dwNumberOfCsAddrs > 0) { if (addr == NULL) { addr = (struct hostent *) malloc(sizeof(struct hostent)); memset(addr, 0, sizeof(struct hostent)); addr->h_addrtype = (short) results->lpcsaBuffer->iSocketType; addr->h_length = sizeof(struct in_addr); /* Only passing back the address */ addrlist = malloc(sizeof(char *)); *addrlist = NULL; } for (i = 0; i < results->dwNumberOfCsAddrs; i++) { AddToAddresses(addrlist, &addrcnt, &results->lpcsaBuffer[i]); } } } if (addr != NULL) { addr->h_name = (char *) name; addr->h_addr_list = addrlist; retcode = 0; *Addresses = addr; } else {#ifdef FORCE_DNSRETRY /* * We do this or the error would never be logged */ if (errcode == WSANO_DATA) msyslog(LOG_ERR, "Address not found for %s", name);#endif retcode = ReturnCode(errcode); } WSALookupServiceEnd(handle); return (retcode);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -