Annotation of embedaddon/ntp/ports/winnt/libntp/dnslookup.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2006 Internet Systems Consortium, Inc. ("ISC")
! 3: *
! 4: * Permission to use, copy, modify, and distribute this software for any
! 5: * purpose with or without fee is hereby granted, provided that the above
! 6: * copyright notice and this permission notice appear in all copies.
! 7: *
! 8: * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
! 9: * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
! 10: * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
! 11: * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
! 12: * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
! 13: * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
! 14: * PERFORMANCE OF THIS SOFTWARE.
! 15: */
! 16:
! 17: /*
! 18: * This module uses Windows lookup facilities to get the address information
! 19: * wherever it resides. This avoids calling the Internet standard funcction
! 20: * gethostbyname and gives us more control over the results since the
! 21: * Microsoft implementation seems to return the wrong error code for some
! 22: * conditions.
! 23: */
! 24:
! 25: #include <config.h>
! 26: #include <ws2tcpip.h>
! 27: #include <nspapi.h>
! 28: #include <svcguid.h>
! 29: #include <ntp_rfc2553.h>
! 30: #include <malloc.h>
! 31: #include <ntp_stdlib.h>
! 32: #include <syslog.h>
! 33:
! 34: /*
! 35: * Set this Macro to force retries even if it fails
! 36: * the lookup
! 37: */
! 38: #ifdef FORCE_DNSRETRY
! 39:
! 40: #undef EAI_NONAME
! 41: #define EAI_NONAME EAI_AGAIN
! 42:
! 43: #endif
! 44:
! 45: typedef struct hostent hostent_t;
! 46:
! 47: int ReturnCode(int errcode)
! 48: {
! 49: int retcode;
! 50:
! 51: switch (errcode)
! 52: {
! 53: case 0:
! 54: return (0);
! 55: case WSAEINVAL:
! 56: return (EAI_BADFLAGS);
! 57: case WSANO_DATA:
! 58: return (EAI_NONAME);
! 59: case WSANOTINITIALISED:
! 60: case WSASERVICE_NOT_FOUND:
! 61: return (EAI_FAIL);
! 62: case WSA_NOT_ENOUGH_MEMORY:
! 63: return (EAI_MEMORY);
! 64: default:
! 65: return (EAI_FAIL);
! 66: }
! 67: }
! 68:
! 69: int
! 70: AddToAddresses(char **Addresses, int *cnt, CSADDR_INFO *csaddr)
! 71: {
! 72:
! 73: int csize;
! 74: struct in_addr *sinaddr;
! 75: char *addr;
! 76: struct in_addr *addr_list;
! 77: struct sockaddr_in *sin;
! 78: sin = (struct sockaddr_in *) csaddr->RemoteAddr.lpSockaddr;
! 79: if (*Addresses != NULL)
! 80: {
! 81: csize = _msize(*Addresses);
! 82: addr_list = realloc(*Addresses, csize + sizeof(struct in_addr));
! 83: }
! 84: else
! 85: {
! 86: csize = 0;
! 87: addr_list = malloc(sizeof(struct in_addr));
! 88: }
! 89: addr = (char *) addr_list;
! 90: sinaddr = &((struct in_addr*) addr)[(*cnt)];
! 91: memset(sinaddr, 0, sizeof(sinaddr));
! 92: memcpy(sinaddr, &sin->sin_addr, sizeof(struct in_addr));
! 93:
! 94: (*cnt)++;
! 95: *Addresses = (char *) addr_list;
! 96: return 0;
! 97: }
! 98:
! 99: int
! 100: DNSlookup_name(
! 101: const char *name,
! 102: int ai_family,
! 103: struct hostent **Addresses
! 104: )
! 105: {
! 106: char buffer[sizeof(WSAQUERYSET) + 2048];
! 107: WSAQUERYSET query;
! 108: struct hostent *addr = NULL;
! 109: char *bufaddr = NULL;
! 110: char ** addrlist = &bufaddr;
! 111: int addrcnt = 0;
! 112: WSAQUERYSET *results = (WSAQUERYSET *) buffer;
! 113: GUID HostnameGUID = SVCID_INET_HOSTADDRBYNAME;
! 114: HANDLE handle;
! 115: DWORD dwLength;
! 116: int err = 0;
! 117: int retcode = 0;
! 118: int errcode = 0;
! 119: DWORD i;
! 120:
! 121: /*
! 122: * First we must create a query set
! 123: */
! 124: memset(&query, 0, sizeof(query));
! 125: query.dwSize = sizeof(query);
! 126: query.lpszServiceInstanceName = (char *)name;
! 127: query.dwNameSpace = NS_DNS;
! 128: query.lpServiceClassId = &HostnameGUID;
! 129:
! 130: err = WSALookupServiceBegin(&query,
! 131: LUP_RETURN_NAME | LUP_RETURN_BLOB | LUP_RETURN_ADDR,
! 132: &handle);
! 133:
! 134: if(err == SOCKET_ERROR)
! 135: {
! 136: /*
! 137: * Convert the error code and return
! 138: */
! 139: return (ReturnCode(WSAGetLastError()));
! 140: }
! 141:
! 142: /*
! 143: * Initially none
! 144: * Change if we get something
! 145: */
! 146: retcode = EAI_NONAME;
! 147: dwLength = sizeof(buffer);
! 148:
! 149: while(err == 0) /* Drop out when error */
! 150: {
! 151: memset(&buffer, 0, dwLength);
! 152: err = WSALookupServiceNext(
! 153: handle,
! 154: 0,
! 155: &dwLength,
! 156: results);
! 157: errcode = WSAGetLastError();
! 158: if (results->dwNumberOfCsAddrs > 0)
! 159: {
! 160: if (addr == NULL)
! 161: {
! 162: addr = (struct hostent *) malloc(sizeof(struct hostent));
! 163: memset(addr, 0, sizeof(struct hostent));
! 164: addr->h_addrtype = (short) results->lpcsaBuffer->iSocketType;
! 165: addr->h_length = sizeof(struct in_addr); /* Only passing back the address */
! 166: addrlist = malloc(sizeof(char *));
! 167: *addrlist = NULL;
! 168: }
! 169: for (i = 0; i < results->dwNumberOfCsAddrs; i++)
! 170: {
! 171: AddToAddresses(addrlist, &addrcnt, &results->lpcsaBuffer[i]);
! 172: }
! 173: }
! 174:
! 175: }
! 176: if (addr != NULL)
! 177: {
! 178: addr->h_name = (char *) name;
! 179: addr->h_addr_list = addrlist;
! 180: retcode = 0;
! 181: *Addresses = addr;
! 182: }
! 183: else
! 184: {
! 185: #ifdef FORCE_DNSRETRY
! 186: /*
! 187: * We do this or the error would never be logged
! 188: */
! 189: if (errcode == WSANO_DATA)
! 190: msyslog(LOG_ERR, "Address not found for %s", name);
! 191: #endif
! 192: retcode = ReturnCode(errcode);
! 193: }
! 194: WSALookupServiceEnd(handle);
! 195: return (retcode);
! 196: }
! 197:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>