dns_impl.inl

来自「eCos操作系统源码」· INL 代码 · 共 678 行 · 第 1/2 页

INL
678
字号
    }    /* If we found one. decode it */    if (dns_hdr->ancount > 0) {        hent = alloc_hent();        if (!hent)             return NULL;        switch (rr_type) {        case DNS_TYPE_A:            hent->h_name = real_name(msg, qname);            if (!hent->h_name) {                free_hent(hent);                return NULL;            }            memcpy(hent->h_addr_list[0], rr_p->rdata, sizeof(struct in_addr));            hent->h_addrtype = AF_INET;            hent->h_length = sizeof(struct in_addr);            return hent;        case DNS_TYPE_PTR:            hent->h_name = real_name(msg, rr_p->rdata);            if (!hent->h_name) {                free_hent(hent);                return NULL;            }            hent->h_addrtype = AF_INET;            hent->h_length = sizeof(struct in_addr);            return hent;        default:            free_hent(hent);        }    }    h_errno = NO_DATA;    return NULL;}/* Given an address, find out the hostname. */struct hostent *gethostbyaddr(const char *addr, int len, int type){    unsigned char msg[MAXDNSMSGSIZE];    char hostname[40];    struct hostent * hent;    CYG_REPORT_FUNCNAMETYPE( "gethostbyaddr", "returning %08x" );    CYG_REPORT_FUNCARG3( "addr=%08x, len=%d, type=%d", addr, len, type );    if ( !addr || 0 == len) {        CYG_REPORT_RETVAL( NULL );        return NULL;    }    CYG_CHECK_DATA_PTR( addr, "addr is not a valid pointer!" );    /* Has the socket to the DNS server been opened? */    if (s < 0) {        CYG_REPORT_RETVAL( NULL );        return NULL;    }    /* See if there is an answer to an old query. If so free the memory       it uses. */    free_stored_hent();    /* Only IPv4 addresses accepted */    if ((type != AF_INET) || (len != sizeof(struct in_addr))) {        CYG_REPORT_RETVAL( NULL );        return NULL;    }    cyg_drv_mutex_lock(&dns_mutex);    /* Build the 'hostname' we want to lookup. */    sprintf(hostname, "%d.%d.%d.%d.IN-ADDR.ARPA.",            (unsigned char)addr[3],            (unsigned char)addr[2],            (unsigned char)addr[1],            (unsigned char)addr[0]);      memset(msg, 0, sizeof(msg));      /* Build a PTR type request using the hostname */    len = build_query(msg, hostname, DNS_TYPE_PTR);    if (len < 0) {        cyg_drv_mutex_unlock(&dns_mutex);        CYG_REPORT_RETVAL( NULL );        return NULL;    }    /* Send the request and wait for an answer */    len = send_recv(msg, len, sizeof(msg));    if (len < 0) {        cyg_drv_mutex_unlock(&dns_mutex);        CYG_REPORT_RETVAL( NULL );        return NULL;    }    /* Fill in the missing address */    hent = parse_answer(msg, DNS_TYPE_PTR);    if (hent) {        memcpy(hent->h_addr_list[0], addr, sizeof(struct in_addr));        store_hent(hent);    }    cyg_drv_mutex_unlock(&dns_mutex);    CYG_REPORT_RETVAL( hent );    return hent;}/* Build message, send, receive and decode */static struct hostent *do_query(const char * hostname) {    unsigned char msg[MAXDNSMSGSIZE];    int len;            memset(msg, 0, sizeof(msg));    len = build_query(msg, hostname, DNS_TYPE_A);    if (len < 0) {        return NULL;    }      /* Send the query and wait for an answer */    len = send_recv(msg, len, sizeof(msg));    if (len < 0) {        return NULL;    }      /* Decode the answer */    return parse_answer(msg, DNS_TYPE_A);}/* Given a hostname find out the IP address */struct hostent *gethostbyname(const char * hostname){    char name[256];    char * dot;    struct hostent *hent;    CYG_REPORT_FUNCNAMETYPE( "gethostbyname", "returning %08x" );    CYG_REPORT_FUNCARG1( "hostname=%08x", hostname );    if ( !hostname ) {        CYG_REPORT_RETVAL( NULL );        return NULL;    }    CYG_CHECK_DATA_PTR( hostname, "hostname is not a valid pointer!" );    /* Has the socket to the DNS server been opened? */    if (s < 0) {        CYG_REPORT_RETVAL( NULL );        return NULL;    }    /* See if there is an answer to an old query. If so free the memory       it uses */    free_stored_hent();      if (!valid_hostname(hostname)) {         /* It could be a dot address */         if ((hent = dot_hostname(hostname)) != NULL) {              store_hent(hent);              CYG_REPORT_RETVAL( hent );              return hent;         }#ifdef CYGPKG_NET_INET6         /* It could be a colon seperated IPv6 address */         if ((hent = colon_hostname(hostname)) != NULL) {              store_hent(hent);              CYG_REPORT_RETVAL( hent );              return hent;         }#endif         CYG_REPORT_RETVAL( hent );         return hent;    }    cyg_drv_mutex_lock(&dns_mutex);    if (domainname) {        if ((strlen(hostname) + strlen(domainname)) > 254) {            h_errno = NO_RECOVERY;            cyg_drv_mutex_unlock(&dns_mutex);            CYG_REPORT_RETVAL( NULL );            return NULL;        }        strcpy(name, hostname);        strcat(name, ".");        strcat(name, domainname);    }        /* If the hostname ends with . it a FQDN. Don't bother adding the    domainname. If it does not contain a . , try appending with the    domainname first. If it does have a . , try without a domain name    first. */    dot = strrchr(hostname,'.');    if (dot) {        if (*(dot+1) == '\0') {            /* FQDN */            hent = do_query(hostname);        } else {          /* Dot somewhere */          hent = do_query(hostname);          if (domainname && (hent == NULL)) {             hent = do_query(name);          }        }    } else {    /* No Dot. Try adding domainname first */        hent = NULL;        if (domainname) {            hent = do_query(name);        }        if (hent == NULL) {            hent = do_query(hostname);        }    }        cyg_drv_mutex_unlock(&dns_mutex);     store_hent(hent);    CYG_REPORT_RETVAL( hent );    return hent;}/* Set the domain names, as used by the DNS server */intsetdomainname(const char *name, size_t len){    char * ptr;    int length;    CYG_REPORT_FUNCNAMETYPE( "setdomainname", "returning %d" );    CYG_REPORT_FUNCARG2( "name=%08x, len=%d", name, len );    if ((len < 0) || (len > 255)) {        h_errno = NO_RECOVERY;        CYG_REPORT_RETVAL( -1 );        return -1;    }    if (len != 0) {        CYG_CHECK_DATA_PTR( name, "name is not a valid pointer!" );        length = strlen(name);        if (length > len) {            h_errno = NO_RECOVERY;            CYG_REPORT_RETVAL( -1 );            return -1;        }        if (name[length-1] != '.') {                length++;        }               ptr = alloc_string(length+1);        if (!ptr) {                     h_errno = NO_RECOVERY;            CYG_REPORT_RETVAL( -1 );            return -1;        }         memcpy(ptr, name, len);        if (name[length-1] != '.') {            ptr[length-1] = '.';            ptr[length] = '\0';        } else {            ptr[len]=0;        }    } else {        ptr = NULL;    }      if (domainname) {        free_string(domainname);    }    domainname = ptr;    CYG_REPORT_RETVAL( 0 );    return 0;}/* Return the domain name as used by the DNS server */intgetdomainname(char *name, size_t len){    CYG_REPORT_FUNCNAMETYPE( "getdomainname", "returning %d" );    CYG_REPORT_FUNCARG2( "name=%08x, len=%d", name, len );    if ( !name || 0 == len) {        CYG_REPORT_RETVAL( -1 );        return -1;    }    CYG_CHECK_DATA_PTR( name, "name is not a valid pointer!" );    /* No domainname set, return a 0 */    if (!domainname) {        if (len == 0) {            h_errno = HOST_NOT_FOUND;            CYG_REPORT_RETVAL( -1 );            return -1;        }        name[0]='\0';    } else {        if ((strlen(domainname) + 1) > len) {            h_errno = NO_RECOVERY;            CYG_REPORT_RETVAL( -1 );            return -1;        }        strncpy(name, domainname, len);    }    CYG_REPORT_RETVAL( 0 );    return 0;}int h_errno = DNS_SUCCESS;const char*hstrerror(int err){    CYG_REPORT_FUNCNAMETYPE( "hstrerror", "returning %08x" );    CYG_REPORT_FUNCARG1( "err=%d", err );    switch (err) {    case DNS_SUCCESS:        return "No error";    case HOST_NOT_FOUND:        return "No such host is known";    case TRY_AGAIN:        return "Timeout";    case NO_RECOVERY:        return "Server failure or invalid input";    case NO_DATA:        return "No data for type";    default:        return "Uknown error";    }}//-----------------------------------------------------------------------------#endif // CYGONCE_NS_DNS_DNS_IMPL_H// End of dns_impl.h

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?