Annotation of embedaddon/ntp/ports/winnt/libntp/dnslookup.c, revision 1.1.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>