📄 dns_impl.inl
字号:
ptr += sizeof(struct resource_record) - sizeof(rr.rdata) + ntohs(rr.rdlength);
dns_hdr->ancount--;
}
/* 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;
}
/* Given a hostname find out the IP address */
struct hostent *
gethostbyname(const char * hostname)
{
unsigned char msg[MAXDNSMSGSIZE];
char name[256];
struct hostent *hent;
int len;
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 */
hent = dot_hostname(hostname);
store_hent(hent);
CYG_REPORT_RETVAL( hent );
return hent;
}
cyg_drv_mutex_lock(&dns_mutex);
/* First try the name as passed in */
memset(msg, 0, sizeof(msg));
len = build_query(msg, hostname, DNS_TYPE_A);
if (len < 0) {
cyg_drv_mutex_unlock(&dns_mutex);
CYG_REPORT_RETVAL( NULL );
return NULL;
}
/* Send the query 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;
}
/* Decode the answer */
hent = parse_answer(msg, DNS_TYPE_A);
if (hent) {
cyg_drv_mutex_unlock(&dns_mutex);
store_hent(hent);
CYG_REPORT_RETVAL( hent );
return hent;
}
/* If no match, try appending the domainname if we have one */
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);
memset(msg, 0, sizeof(msg));
len = build_query(msg, name, DNS_TYPE_A);
if (len < 0) {
cyg_drv_mutex_unlock(&dns_mutex);
CYG_REPORT_RETVAL( NULL );
return NULL;
}
/* Send the query 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;
}
/* Decode the answer */
hent = parse_answer(msg, DNS_TYPE_A);
}
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;
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!" );
ptr = alloc_string(len+1);
if (!ptr) {
CYG_REPORT_RETVAL( -1 );
return -1;
}
memcpy(ptr, name, len);
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 + -