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>