?? dns_impl.inl
字號:
}
/* 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, (unsigned char *)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 */
int
setdomainname(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;
return -1;
}
if (len != 0) {
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 */
int
getdomainname(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 + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -