OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /or1k/trunk/ecos-2.0/packages/net/ns
    from Rev 1254 to Rev 1765
    Reverse comparison

Rev 1254 → Rev 1765

/dns/v2_0/cdl/dns.cdl
0,0 → 1,152
# ====================================================================
#
# dns.cdl
#
# DNS configuration data
#
# ====================================================================
#####ECOSGPLCOPYRIGHTBEGIN####
## -------------------------------------------
## This file is part of eCos, the Embedded Configurable Operating System.
## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
## Copyright (C) 2003 Andrew Lunn <andrew.lunn@ascom.ch>
##
## eCos is free software; you can redistribute it and/or modify it under
## the terms of the GNU General Public License as published by the Free
## Software Foundation; either version 2 or (at your option) any later version.
##
## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
## WARRANTY; without even the implied warranty of MERCHANTABILITY or
## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
## for more details.
##
## You should have received a copy of the GNU General Public License along
## with eCos; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
##
## As a special exception, if other files instantiate templates or use macros
## or inline functions from this file, or you compile this file and link it
## with other works to produce a work based on this file, this file does not
## by itself cause the resulting work to be covered by the GNU General Public
## License. However the source code for this file must still be made available
## in accordance with section (3) of the GNU General Public License.
##
## This exception does not invalidate any other reasons why a work based on
## this file might be covered by the GNU General Public License.
##
## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
## at http://sources.redhat.com/ecos/ecos-license/
## -------------------------------------------
#####ECOSGPLCOPYRIGHTEND####
# ====================================================================
######DESCRIPTIONBEGIN####
#
# Author(s): jskov
# Original data: jskov
# Contributors: andrew.lunn@ascom.ch
# Date: 2001-09-18
#
#####DESCRIPTIONEND####
#
# ====================================================================
 
cdl_package CYGPKG_NS_DNS {
display "DNS client"
include_dir cyg/ns/dns
doc ref/net-ns-dns.html
 
cdl_option CYGPKG_NS_DNS_BUILD {
display "Build DNS NS client package"
default_value 1
implements CYGINT_ISO_DNS
requires { CYGBLD_ISO_DNS_HEADER == "<cyg/ns/dns/dns.h>" }
 
requires CYGPKG_NET
requires CYGINT_ISO_CTYPE
requires CYGINT_ISO_MALLOC
requires CYGINT_ISO_STRING_STRFUNCS
requires CYGSEM_KERNEL_THREADS_DESTRUCTORS_PER_THREAD
 
compile dns.c
}
 
cdl_component CYGPKG_NS_DNS_DEFAULT {
display "Provide a hard coded default server address"
flavor bool
active_if CYGPKG_NS_DNS_BUILD
default_value 0
description "
This option controls the use of a default, hard coded DNS
server. When this is enabled, the IP address in the CDL
option CYGDAT_NS_DNS_DEFAULT_SERVER is used in
init_all_network_interfaces() to start the resolver using
the specified server. The DHCP client or user code may
override this by restarting the resolver."
 
cdl_option CYGDAT_NS_DNS_DEFAULT_SERVER {
display "IP address of the default DNS server"
flavor data
default_value { "192.168.1.1" }
}
}
cdl_component CYGPKG_NS_DNS_DOMAINNAME {
display "Provide a hard coded default domain name"
flavor bool
active_if CYGPKG_NS_DNS_BUILD
default_value 0
description "
This option controls the use of a default, hard coded
domain name to be used when querying a DNS server. When
this is enabled, the name in the CDL option
CYGDAT_NS_DNS_DOMAINNAME_NAME is used in
init_all_network_interfaces() to set the domain name as
accessed by getdomainname()."
 
cdl_option CYGDAT_NS_DNS_DOMAINNAME_NAME {
display "Domain name for this device"
flavor data
default_value { "default.domain.com" }
}
}
cdl_component CYGPKG_NS_DNS_OPTIONS {
display "DNS support build options"
flavor none
no_define
 
cdl_option CYGPKG_NS_DNS_CFLAGS_ADD {
display "Additional compiler flags"
flavor data
no_define
default_value { "-D_KERNEL -D__ECOS" }
description "
This option modifies the set of compiler flags for
building the DNS package.
These flags are used in addition
to the set of global flags."
}
 
cdl_option CYGPKG_NS_DNS_CFLAGS_REMOVE {
display "Suppressed compiler flags"
flavor data
no_define
default_value { "" }
description "
This option modifies the set of compiler flags for
building the DNS package. These flags are removed from
the set of global flags if present."
}
}
 
cdl_option CYGPKG_NS_DNS_TESTS {
display "Networking tests"
flavor data
active_if CYGPKG_NS_DNS_BUILD
no_define
calculated { "tests/dns1 tests/dns2" }
 
description "
This option specifies the set of tests for the DNS package."
}
}
 
# EOF dns.cdl
/dns/v2_0/tests/dns1.c
0,0 → 1,185
//==========================================================================
//
// tests/dns1.c
//
// Simple test of DNS client support
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): andrew.lunn
// Contributors: andrew.lunn, jskov
// Date: 2001-09-18
// Purpose:
// Description: Test DNS functions. Note that the _XXX defines below
// control what addresses the test uses. These must be
// changed to match the particular testing network in which
// the test is to be run.
//
//####DESCRIPTIONEND####
//
//==========================================================================
 
#include <network.h>
#include <netdb.h>
 
#include <arpa/inet.h>
 
#include <cyg/infra/testcase.h>
 
#define STACK_SIZE (CYGNUM_HAL_STACK_SIZE_TYPICAL + 0x1000)
static char stack[STACK_SIZE];
static cyg_thread thread_data;
static cyg_handle_t thread_handle;
 
#define __string(_x) #_x
#define __xstring(_x) __string(_x)
 
// Change the following if you aren't using BOOTP! It's almost certainly not right for you.
#define _DNS_IP __xstring(172.16.1.254) // test farm host addr
#define _LOOKUP_FQDN __xstring(b.root-servers.net.) // should stay the same?
#define _LOOKUP_DOMAINNAME __xstring(root-servers.net.)
#define _LOOKUP_HOSTNAME __xstring(b)
#define _LOOKUP_IP __xstring(128.9.0.107) // must be same as _LOOKUP_FQDN
#define _LOOKUP_IP_BAD __xstring(10.0.0.0)
 
void
dns_test(cyg_addrword_t p)
{
struct in_addr addr;
struct hostent *hent;
char dn[256];
int i;
 
CYG_TEST_INIT();
 
init_all_network_interfaces();
 
CYG_TEST_INFO("Starting dns1 test");
 
setdomainname(NULL,0);
for (i=0; i<2; i++) {
/* Expect _LOOKUP_IP as the answer. This is a CNAME lookup */
inet_aton(_LOOKUP_IP, &addr);
hent = gethostbyname(_LOOKUP_FQDN);
if (hent != NULL) {
diag_printf("PASS:<%s is %s>\n", hent->h_name, inet_ntoa(*(struct in_addr *)hent->h_addr));
if (0 != memcmp((void*)&addr, (void*)(hent->h_addr), sizeof(struct in_addr))) {
diag_printf("FAIL:<expected " _LOOKUP_FQDN " to be " _LOOKUP_IP ">\n");
}
break;
} else {
diag_printf("FAIL:<Asked for " _LOOKUP_FQDN ". No answer: %s>\n", hstrerror(h_errno));
CYG_TEST_INFO("Retrying with explicit DNS server");
CYG_TEST_INFO("Connecting to DNS at " _DNS_IP);
inet_aton(_DNS_IP, &addr);
CYG_TEST_CHECK(cyg_dns_res_init(&addr) == 0, "Failed to initialize resolver");
}
}
 
/* Reverse lookup the _LOOKUP_IP addres, expect _LOOKUP_FQDN
as the answer. */
hent = gethostbyaddr((char *)&addr, sizeof(struct in_addr), AF_INET);
if (hent != NULL) {
diag_printf("PASS:<%s is %s>\n", hent->h_name, inet_ntoa(*(struct in_addr *)hent->h_addr));
if (0 != strcmp(_LOOKUP_FQDN, hent->h_name)) {
diag_printf("FAIL:<expected " _LOOKUP_IP " to be " _LOOKUP_FQDN ">\n");
}
} else {
diag_printf("FAIL:<Asked for " _LOOKUP_IP ". No answer: %s>\n", hstrerror(h_errno));
}
/* This does not require a DNS lookup. Just turn the value into
binary */
hent = gethostbyname(_LOOKUP_IP);
if (hent != NULL) {
diag_printf("PASS:<%s is %s>\n", hent->h_name, inet_ntoa(*(struct in_addr *)hent->h_addr));
} else {
diag_printf("FAIL:<Asked for " _LOOKUP_IP ". No answer: %s>\n", hstrerror(h_errno));
}
/* Reverse lookup an address this is not in the server. Expect a
NULL back */
inet_aton(_LOOKUP_IP_BAD, &addr);
hent = gethostbyaddr((char *)&addr, sizeof(struct in_addr), AF_INET);
if (hent != NULL) {
diag_printf("FAIL:<%s is %s>\n", hent->h_name, inet_ntoa(*(struct in_addr *)hent->h_addr));
} else {
diag_printf("PASS:<Asked for bad IP " _LOOKUP_IP_BAD ". No answer: %s>\n", hstrerror(h_errno));
}
 
/* Setup a domainname. We now don't have to use fully qualified
domain names */
setdomainname(_LOOKUP_DOMAINNAME, sizeof(_LOOKUP_DOMAINNAME));
getdomainname(dn, sizeof(dn));
diag_printf("INFO:<Domainname is now %s>\n", dn);
 
/* Make sure FQDN still work */
hent = gethostbyname(_LOOKUP_FQDN);
if (hent != NULL) {
diag_printf("PASS:<%s is %s>\n", hent->h_name, inet_ntoa(*(struct in_addr *)hent->h_addr));
} else {
diag_printf("FAIL:<Asked for " _LOOKUP_FQDN ". No answer: %s>\n", hstrerror(h_errno));
}
 
/* Now just the hostname */
hent = gethostbyname(_LOOKUP_HOSTNAME);
if (hent != NULL) {
diag_printf("PASS:<%s is %s>\n", _LOOKUP_HOSTNAME, inet_ntoa(*(struct in_addr *)hent->h_addr));
} else {
diag_printf("FAIL:<Asked for " _LOOKUP_HOSTNAME ". No answer: %s>\n", hstrerror(h_errno));
}
 
CYG_TEST_FINISH("dns1 test completed");
}
 
void
cyg_start(void)
{
// Create a main thread, so we can run the scheduler and have time 'pass'
cyg_thread_create(10, // Priority - just a number
dns_test, // entry
0, // entry parameter
"DNS test", // Name
&stack[0], // Stack
STACK_SIZE, // Size
&thread_handle, // Handle
&thread_data // Thread data structure
);
cyg_thread_resume(thread_handle); // Start it
cyg_scheduler_start();
}
/dns/v2_0/tests/dns2.c
0,0 → 1,156
//==========================================================================
//
// tests/dns2.c
//
// Simple test of DNS client support. This time use DHCP
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): andrew.lunn
// Contributors: andrew.lunn, jskov
// Date: 2001-12-03
// Purpose:
// Description: Test DNS functions. Use the server and domain name the
// DHCP server told us.
//
//####DESCRIPTIONEND####
//
//==========================================================================
 
#include <network.h>
#include <netdb.h>
 
#include <arpa/inet.h>
 
#include <cyg/infra/testcase.h>
 
#ifdef CYGPKG_NET_DHCP
 
#define STACK_SIZE (CYGNUM_HAL_STACK_SIZE_TYPICAL + 0x1000)
static char stack[STACK_SIZE];
static cyg_thread thread_data;
static cyg_handle_t thread_handle;
 
#define __string(_x) #_x
#define __xstring(_x) __string(_x)
 
#define USE_HARDCODED_DOMAIN 1
 
// Change the following if you aren't using BOOTP! It's almost certainly not right for you.
#define _DNS_IP __xstring(172.16.1.254) // test farm host addr
#define _LOOKUP_FQDN __xstring(b.root-servers.net.) // should stay the same?
#define _LOOKUP_DOMAINNAME __xstring(root-servers.net.)
#define _LOOKUP_HOSTNAME __xstring(b)
#define _LOOKUP_IP __xstring(128.9.0.107) // must be same as _LOOKUP_FQDN
#define _LOOKUP_IP_BAD __xstring(10.0.0.0)
 
void
dns_test(cyg_addrword_t p)
{
struct in_addr addr;
struct hostent *hent;
char dn[256];
 
CYG_TEST_INIT();
 
init_all_network_interfaces();
 
CYG_TEST_INFO("Starting dns2 test");
 
getdomainname(dn,sizeof(dn));
diag_printf("INFO:<DHCP said domain name is %s>\n",dn);
#ifndef USE_HARDCODED_DOMAIN
// If not hard-coded we can't tell what it's _meant_ to be
CYG_TEST_CHECK(!strncmp(dn,_LOOKUP_DOMAINNAME,sizeof(_LOOKUP_DOMAINNAME)),
"DHCP got the wrong domainname");
#endif //ifdef _LOOKUP_DOMAINNAME
/* Expect _LOOKUP_IP as the answer. This is a CNAME lookup */
inet_aton(_LOOKUP_IP, &addr);
hent = gethostbyname(_LOOKUP_FQDN);
if (hent != NULL) {
diag_printf("PASS:<%s is %s>\n", hent->h_name, inet_ntoa(*(struct in_addr *)hent->h_addr));
if (0 != memcmp((void*)&addr, (void*)(hent->h_addr), sizeof(struct in_addr))) {
diag_printf("FAIL:<expected " _LOOKUP_FQDN " to be " _LOOKUP_IP ">\n");
}
} else {
diag_printf("FAIL:<Asked for " _LOOKUP_FQDN ". No answer: %s>\n", hstrerror(h_errno));
}
 
/* Now just the hostname */
#ifdef USE_HARDCODED_DOMAIN
// set the domain by hand if required.
setdomainname(_LOOKUP_DOMAINNAME, sizeof(_LOOKUP_DOMAINNAME));
#endif //ifdef _LOOKUP_DOMAINNAME
hent = gethostbyname(_LOOKUP_HOSTNAME);
if (hent != NULL) {
diag_printf("PASS:<%s is %s>\n", _LOOKUP_HOSTNAME, inet_ntoa(*(struct in_addr *)hent->h_addr));
} else {
diag_printf("FAIL:<Asked for " _LOOKUP_HOSTNAME ". No answer: %s>\n", hstrerror(h_errno));
}
 
CYG_TEST_FINISH("dns2 test completed");
}
 
void
cyg_start(void)
{
// Create a main thread, so we can run the scheduler and have time 'pass'
cyg_thread_create(10, // Priority - just a number
dns_test, // entry
0, // entry parameter
"DNS test", // Name
&stack[0], // Stack
STACK_SIZE, // Size
&thread_handle, // Handle
&thread_data // Thread data structure
);
cyg_thread_resume(thread_handle); // Start it
cyg_scheduler_start();
}
 
#else // CYGPKG_NET_DHCP
 
externC void
cyg_start( void )
{
CYG_TEST_INIT();
 
CYG_TEST_NA("This test needs DHCP enabled");
}
 
#endif
/dns/v2_0/include/dns_impl.inl
0,0 → 1,619
#ifndef CYGONCE_NS_DNS_DNS_IMPL_H
#define CYGONCE_NS_DNS_DNS_IMPL_H
//=============================================================================
//
// dns_impl.inl
//
// DNS client code implementation.
//
//=============================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//=============================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): andrew.lunn
// Contributors:andrew.lunn, jskov
// Date: 2001-09-18
// Description: The code is kept in this separate file to allow it to be
// used from RedBoot.
//
//####DESCRIPTIONEND####
//
//=============================================================================
 
#include <cyg/ns/dns/dns_priv.h>
 
/* Validate a hostname is legal as defined in RFC 1035 */
static int
valid_hostname(const char *hostname)
{
const char * label;
const char * label_end;
if (!hostname) {
return false;
}
label = hostname;
while (*label) {
if (!isalpha(*label))
return false;
label_end = strchr(label, (int)'.') - 1;
if (label_end == (char *)-1) {
label_end = strchr(label, (int)'\0') - 1;
}
while (label != label_end) {
if (!isalnum(*label) && (*label != '-')) {
return false;
}
label++;
}
label = label_end+1; /* Move onto the . or the null. */
if (*label == '.') { /* Move over the . if there is one */
label++;
}
}
return true;
}
 
/* Build a qname structure. The structure consists of pairs of
<len><label> where <label> is eg ma in tux.ma.tech.ascom.ch. len is
the length of the label. */
static int
build_qname(char *ptr, const char *hostname)
{
const char *label = hostname;
char *end_label;
int total_len = 0;
int len;
while (*label) {
end_label = strchr(label, (int)'.') - 1;
if (end_label == (char *)-1) {
end_label = strchr(label, (int)'\0') - 1;
}
len = end_label - label + 1;
if (len > 63) {
return -1;
}
*ptr++ = (char) len; /* Put the length of the label */
memcpy(ptr, label, len); /* and now the label */
ptr += len;
total_len += len +1;
label = end_label+1; /* Move onto the . or the null. */
if (*label == '.') { /* Move over the . if there is one */
label++;
}
}
*ptr = 0; /* Add the last length of zero
to mark the end */
return (total_len+1);
}
 
/* Given a pointer to a qname, find the length of the qname. This is
the number of bytes needed to represent the qname, not the length
of the name. A qname is terminated by either a 00, or a pointer
into another qname. This pointer has the top two bits set. */
static int
qname_len(unsigned char * qname)
{
unsigned char * ptr = qname;
while ((*ptr != 0) && ((*ptr & 0xc0) != 0xc0)) {
ptr += *ptr + 1;
}
/* Pointers are two bytes */
if ((*ptr & 0xc0) == 0xc0) {
ptr++;
}
ptr++; /* Skip over the trailing byte */
 
return (ptr - qname);
}
 
/* Build a real name from a qname. Alloc the memory needed and return
it. Return NULL on error */
char *
real_name(char *msg, unsigned char *qname)
{
unsigned char * ptr = qname;
char * name;
char * label;
int len = 0;
int offset;
 
/* First pass works out the length of the name */
while (*ptr != 0) {
if ((*ptr & 0xc0) == 0xc0) {
/* pointer to somewhere else. Follow the pointer */
offset = ((*ptr & 0x3f) << 8) | *(ptr+1);
ptr = msg + offset;
} else {
len += *ptr + 1;
ptr += *ptr + 1;
}
}
 
/* Now allocate the memory needed and copy the host name into it */
name = alloc_string(len+1);
if (name) {
label = name;
ptr = qname;
while (*ptr != 0) {
if ((*ptr & 0xc0) == 0xc0) {
/* pointer to somewhere else. Follow the pointer */
offset = ((*ptr & 0x3f) << 8) | *(ptr+1);
ptr = msg + offset;
} else {
len = *ptr;
memcpy(label, (ptr+1), len);
label += len;
*label++ = '.';
ptr += *ptr + 1;
}
}
*label = '\0';
}
return name;
}
 
/* Build a query message which can be sent to the server. If something
goes wrong return -1, otherwise the length of the query message */
static int
build_query(char * msg, const char * hostname, short rr_type)
{
struct dns_header *dns_hdr;
char *ptr;
int len;
 
/* Fill out the header */
dns_hdr = (struct dns_header *) msg;
dns_hdr->id = htons(id++);
dns_hdr->rd = true;
dns_hdr->opcode = DNS_QUERY;
dns_hdr->qdcount = htons(1);
/* Now the question we want to ask */
ptr = (char *)&dns_hdr[1];
 
len = build_qname(ptr, hostname);
 
if (len < 0) {
h_errno = NO_RECOVERY;
return -1;
}
ptr += len;
 
/* Set the type and class fields */
*ptr++ = (rr_type >> 8) & 0xff;
*ptr++ = rr_type & 0xff;
*ptr++ = (DNS_CLASS_IN >> 8) & 0xff;
*ptr++ = DNS_CLASS_IN & 0xff;
 
len = ptr - msg;
 
return len;
}
 
/* Check if the hostname is actually of dot format. If so convert it
and return host entity structure. If not, return NULL. */
static struct hostent *
dot_hostname(const char *hostname)
{
struct hostent *hent = NULL;
struct in_addr addr;
 
if (inet_aton(hostname, &addr)) {
hent = alloc_hent();
if (hent) {
memcpy(hent->h_addr_list[0], &addr, sizeof(struct in_addr));
hent->h_addrtype = AF_INET;
hent->h_length = sizeof(struct in_addr);
hent->h_name = alloc_string(strlen(hostname)+1);
if (!hent->h_name) {
free_hent(hent);
return NULL;
}
strcpy(hent->h_name, hostname);
}
}
return hent;
}
 
/* Decode the answer from the server. Returns NULL if failed, or
a hostent structure containing different data depending on the
query type:
DNS_TYPE_A:
h_name: a pointer to the hostname
h_addr_list[0]: a pointer to in_addr structure
DNS_TYPE_PTR:
h_name: a pointer to the hostname
h_addr_list[0]: a pointer to an empty in_addr structure. Caller
must fill out!
*/
static struct hostent *
parse_answer(char * msg, short rr_type)
{
static struct hostent *hent;
struct dns_header *dns_hdr;
struct resource_record rr, *rr_p = NULL;
char *qname = NULL;
char *ptr;
 
dns_hdr = (struct dns_header *)msg;
 
if (DNS_REPLY_NAME_ERROR == dns_hdr->rcode) {
h_errno = HOST_NOT_FOUND;
return NULL;
}
 
if ((dns_hdr->qr != 1) ||
(dns_hdr->opcode != DNS_QUERY) ||
(dns_hdr->rcode != DNS_REPLY_NOERR)) {
h_errno = NO_RECOVERY;
return NULL;
}
dns_hdr->ancount = ntohs(dns_hdr->ancount);
dns_hdr->qdcount = ntohs(dns_hdr->qdcount);
ptr = (char *)&dns_hdr[1];
 
/* Skip over the query section */
if (dns_hdr->qdcount > 0) {
while (dns_hdr->qdcount) {
ptr += qname_len(ptr);
ptr += 4; /* skip type & class */
dns_hdr->qdcount--;
}
}
/* Skip over the answers resource records to find an answer of the
correct type. */
while (dns_hdr->ancount) {
qname = ptr;
ptr += qname_len(ptr);
rr_p = (struct resource_record *)ptr;
memcpy(&rr, ptr, sizeof(rr));
if ((rr.rr_type == htons(rr_type)) &&
(rr.class == htons(DNS_CLASS_IN))) {
break;
}
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
/dns/v2_0/include/dns.h
0,0 → 1,88
#ifndef CYGONCE_NS_DNS_DNS_H
#define CYGONCE_NS_DNS_DNS_H
//=============================================================================
//
// dns.h
//
// DNS client code.
//
//=============================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//=============================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): andrew.lunn
// Contributors:andrew.lunn, jskov
// Date: 2001-09-18
//
//####DESCRIPTIONEND####
//
//=============================================================================
 
#include <network.h>
#include <netinet/in.h>
 
#ifndef _POSIX_SOURCE
/* Initialise the DNS client with the address of the server */
externC int cyg_dns_res_init(struct in_addr *dns_server);
externC int getdomainname(char *name, size_t len);
externC int setdomainname(const char *name, size_t len);
#endif
 
// Host name / IP mapping
struct hostent {
char *h_name; /* official name of host */
char **h_aliases; /* alias list */
int h_addrtype; /* host address type */
int h_length; /* length of address */
char **h_addr_list; /* list of addresses */
};
#define h_addr h_addr_list[0] /* for backward compatibility */
 
externC struct hostent *gethostbyname(const char *host);
externC struct hostent *gethostbyaddr(const char *addr, int len, int type);
 
// Error reporting
externC int h_errno;
externC const char* hstrerror(int err);
 
#define DNS_SUCCESS 0
#define HOST_NOT_FOUND 1
#define TRY_AGAIN 2
#define NO_RECOVERY 3
#define NO_DATA 4
 
//-----------------------------------------------------------------------------
#endif // CYGONCE_NS_DNS_DNS_H
// End of dns.h
/dns/v2_0/include/dns_priv.h
0,0 → 1,127
#ifndef CYGONCE_NS_DNS_DNS_PRIV_H
#define CYGONCE_NS_DNS_DNS_PRIV_H
//=============================================================================
//
// dns-priv.h
//
// Private DNS client definitions.
//
//=============================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//=============================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): andrew.lunn
// Contributors:andrew.lunn, jskov
// Date: 2001-09-18
//
//####DESCRIPTIONEND####
//
//=============================================================================
 
struct dns_header {
#if (CYG_BYTEORDER == CYG_LSBFIRST)
unsigned id :16; /* query identification number */
/* fields in third byte */
unsigned rd :1; /* recursion desired */
unsigned tc :1; /* truncated message */
unsigned aa :1; /* authoritive answer */
unsigned opcode :4; /* purpose of message */
unsigned qr :1; /* response flag */
/* fields in fourth byte */
unsigned rcode :4; /* response code */
unsigned cd: 1; /* checking disabled by resolver */
unsigned ad: 1; /* authentic data from named */
unsigned unused :1; /* unused bits */
unsigned ra :1; /* recursion available */
/* remaining bytes */
unsigned qdcount :16; /* number of question entries */
unsigned ancount :16; /* number of answer entries */
unsigned nscount :16; /* number of authority entries */
unsigned arcount :16; /* number of resource entries */
#else
unsigned id :16; /* query identification number */
/* fields in third byte */
unsigned qr :1; /* response flag */
unsigned opcode :4; /* purpose of message */
unsigned aa :1; /* authoritive answer */
unsigned tc :1; /* truncated message */
unsigned rd :1; /* recursion desired */
/* fields in fourth byte */
unsigned ra :1; /* recursion available */
unsigned unused :1; /* unused bits */
unsigned ad: 1; /* authentic data from named */
unsigned cd: 1; /* checking disabled by resolver */
unsigned rcode :4; /* response code */
/* remaining bytes */
unsigned qdcount :16; /* number of question entries */
unsigned ancount :16; /* number of answer entries */
unsigned nscount :16; /* number of authority entries */
unsigned arcount :16; /* number of resource entries */
#endif
};
 
struct resource_record {
unsigned rr_type : 16; /* Type of resourse */
unsigned class : 16; /* Class of resource */
unsigned ttl : 32; /* Time to live of this record */
unsigned rdlength: 16; /* Lenght of data to follow */
char rdata [2]; /* Resource DATA */
};
 
/* Opcodes */
#define DNS_QUERY 0 /* Standard query */
#define DNS_IQUERY 1 /* Inverse query */
#define DNS_STATUS 2 /* Name server status */
#define DNS_NOTIFY 4 /* Zone change notification */
#define DNS_UPDATE 5 /* Zone update message */
 
/* DNS TYPEs */
#define DNS_TYPE_A 1 /* Host address */
#define DNS_TYPE_NS 2 /* Authoritative name server */
#define DNS_TYPE_CNAME 5 /* Canonical name for an alias */
#define DNS_TYPE_PTR 12 /* Domain name pointer */
 
/* DNS CLASSs */
#define DNS_CLASS_IN 1 /* Internet */
 
/* DNS reply codes */
#define DNS_REPLY_NOERR 0
#define DNS_REPLY_NAME_ERROR 3
 
#define MAXDNSMSGSIZE 512
 
//-----------------------------------------------------------------------------
#endif // CYGONCE_NS_DNS_DNS_PRIV_H
// End of dns-priv.h
/dns/v2_0/doc/dns.sgml
0,0 → 1,118
<!-- {{{ Banner -->
 
<!-- =============================================================== -->
<!-- -->
<!-- dns.sgml -->
<!-- -->
<!-- eCos TCP/IP Stacks -->
<!-- -->
<!-- =============================================================== -->
<!-- ####COPYRIGHTBEGIN#### -->
<!-- -->
<!-- =============================================================== -->
<!-- Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. -->
<!-- This material may be distributed only subject to the terms -->
<!-- and conditions set forth in the Open Publication License, v1.0 -->
<!-- or later (the latest version is presently available at -->
<!-- http://www.opencontent.org/openpub/) -->
<!-- Distribution of the work or derivative of the work in any -->
<!-- standard (paper) book form is prohibited unless prior -->
<!-- permission obtained from the copyright holder -->
<!-- =============================================================== -->
<!-- -->
<!-- ####COPYRIGHTEND#### -->
<!-- =============================================================== -->
<!-- #####DESCRIPTIONBEGIN#### -->
<!-- -->
<!-- ####DESCRIPTIONEND#### -->
<!-- =============================================================== -->
 
<!-- }}} -->
 
<PART ID="net-ns-dns">
<TITLE>DNS for eCos and RedBoot</TITLE>
<PARTINTRO>
<PARA>
<productname>eCos</productname> and
<productname>RedBoot</productname>
can both use the DNS package to perform network name lookups.
</PARA>
</PARTINTRO>
<CHAPTER id="net-ns-dns-api">
<TITLE>DNS</TITLE>
<SECT1 id="net-ns-dns-api1">
<TITLE>DNS API</TITLE>
<PARA>The DNS client uses the normal BSD API for performing lookups:
<function>gethostbyname()</function> and
<FUNCTION>gethostbyaddr()</FUNCTION>.
</PARA>
<PARA>There are a few restrictions:</PARA>
<ITEMIZEDLIST>
<LISTITEM>
<PARA>Only IPv4 is supported, ie IPv6 addresses cannot be looked
up.</PARA>
</LISTITEM>
<LISTITEM>
<PARA>If the DNS server returns multiple authoritive records
for a host name, the hostent will only contain a record for the
first entry.</PARA>
</LISTITEM>
<LISTITEM>
<PARA>The code has been made thread safe. ie multiple threads
may call
<FUNCTION>gethostbyname()</FUNCTION>
without causing problems to the hostent structure returned. What
is not safe is one thread using both
<FUNCTION>gethostbyname()</FUNCTION>
and
<FUNCTION>gethostbyaddr()</FUNCTION>.
A call to one will destroy the results from the previous call
to the other function.</PARA>
</LISTITEM>
</ITEMIZEDLIST>
<PARA>To initialise the DNS client the following function must be
called:</PARA>
<PROGRAMLISTING>#include &lt;network.h&gt;
int cyg_dns_res_init(struct in_addr *dns_server)</PROGRAMLISTING>
<PARA>where dns_server is the address of the DNS server
the client should query. On Error this function returns -1, otherwise
0 for success. If lookups are attemped before this function has
been called, they will fail and return NULL.</PARA>
 
<PARA>A default, hard coded, server may be specified in the CDL option
<literal>CYGDAT_NS_DNS_DEFAULT_SERVER</literal>. The use of this is
controlled by <literal>CYGPKG_NS_DNS_DEFAULT</literal>. If this is
enabled, <literal>init_all_network_interfaces</literal> will
initialize the resolver with the hard coded address. The DHCP client
or user code my override this address by calling
<literal>cyg_dns_res_init</literal> again. </PARA>
 
<PARA>The DNS client understands the concepts of the target being
in a domain. By default no domain will be used. Host name lookups
should be for fully qualified names. The domain name can be set
and retrieved using the functions:
<funcsynopsis>
<funcprototype>
<funcdef>int <function>getdomainname</function></funcdef>
<paramdef>char *<parameter>name</parameter></paramdef>
<paramdef>size_t <parameter>len</parameter></paramdef>
</funcprototype>
<funcprototype>
<funcdef>int <function>setdomainname</function></funcdef>
<paramdef>const char *<parameter>name</parameter></paramdef>
<paramdef>size_t <parameter>len</parameter></paramdef>
</funcprototype>
</funcsynopsis>
</para>
 
<PARA>Alternatively, a hard coded domain name can be set using CDL.
The boolean <literal>CYGPKG_NS_DNS_DOMAINNAME</literal> enables this
and the domain name is taken from
<literal>CYGPKG_NS_DNS_DOMAINNAME_NAME</literal>.</PARA>
 
<PARA>Once set, the DNS client will first perform a lookup with the domain
name appended. If this fails it will then perform a second lookup
without the appended domain name. </PARA>
</SECT1>
</CHAPTER>
</PART>
dns/v2_0/doc/dns.sgml Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: dns/v2_0/ChangeLog =================================================================== --- dns/v2_0/ChangeLog (nonexistent) +++ dns/v2_0/ChangeLog (revision 1765) @@ -0,0 +1,238 @@ +2003-03-03 Jonathan Larmour + + * tests/dns1.c: Use BOOTP info where possible in preference to + (likely incorrect!) hardcoded info. Use non-Red Hat test + addresses. + + * tests/dns2.c: Use non-Red Hat test addresses. And don't check + BOOTP-derived domainname as we don't know what it should be! + +2003-02-24 Jonathan Larmour + + * cdl/dns.cdl: Add doc link. + +2003-01-22 Jonathan Larmour + + * doc/dns.sgml: Use correct (and working!) docbook. + +2003-01-18 Jonathan Larmour + + * include/dns_impl.inl (setdomainname): define with const name + argument. + * include/dns.h: Ditto. + * doc/dns.sgml: Document const in setdomainname proto here. + +2003-01-10 Andrew Lunn + + * cdl/dns.cdl: Added the ability to hard code a domain name. + Inspired by Motoya Kurotsu. + * doc/dns.sgml: Documentation for this. + +2003-01-10 Motoya Kurotsu + + * tests/dns2.c: Verify domain name from the DHCP server with + _LOOKUP_DOMAINNAME, not _DNS_IP which is the address of the DNS + server. + +2003-01-09 Andrew Lunn + + * cdl/dns.cdl: Added the ability to hard code a DNS server + address into the image which is used as the default. + * doc/dns.sgml: Documentation for this. + +2002-10-18 Jonathan Larmour + + * cdl/dns.cdl: Move CYGBLD_ISO_DNS_HEADER requires in with + CYGINT_ISO_DNS which is where it should always be beside. + +2002-10-11 Andrew Lunn + + * cdl/dns.cdl: If CYGPKG_NS_DNS_BUILD is disable we don't + implement the CYGINT_ISO_DNS interface. + +2002-08-29 Roland Caßebohm + + * include/dns_priv.h: Make dns_header structure endian dependent. + + * include/dns_impl.inl: Don't use htons() for bitfields <= 8 bit. + Change the way setting the type and class fields in build_query() + to work with big-endian. + +2002-05-30 Jesper Skov + + * src/dns.c: fixed index->ptdindex oversight. + +2002-05-24 Jonathan Larmour + + * src/dns.c (free_hent): Actually free hent itself! + +2002-05-23 Jonathan Larmour + + * cdl/dns.cdl (CYGPKG_NS_DNS_BUILD): Require thread destructors in + kernel. + * include/dns_impl.inl: Instead of using cyg_thread_get_data + and _set_data directly, instead use store_hent and free_stored_hent + defined by includer. + * src/dns.c: Define store_hent() and free_stored_hent() and make + them use thread destructors thus fixing a memory leak. + +2002-05-14 Jesper Skov + + * tests/dns2.c: Fix warning. + +2002-02-22 Hugo Tyson + + * doc/dns.sgml: New file. Documentation separated from monolithic + network component. + +2002-02-01 Gary Thomas + + * src/dns.c (cyg_dns_res_init): Need valid value for sin_len. + +2002-01-31 Jonathan Larmour + + * cdl/dns.cdl: Don't build tests if no DNS! + +2001-12-06 Andrew Lunn + + * src/dns.c (cyg_dns_res_init): Allow this to be called more than + once. The DHCP client will do this when interfaces YoYo. + Restarting requires closing the socket (if any) and freeing the + per-thread-data slot number. + + * include/dns_impl.inl (setdomainname): Allow the name to be + cleared. Check for NULL pointers variously before checking for + valid pointer asserts. + + * tests/dns2.c: New file: Test the DNS configuration via DHCP. + + * tests/dns1.c: Initially clear the domainname. + +2001-11-29 Jonathan Larmour + + * src/dns.c: Rename index -> ptdindex to avoid conflict with BSD + index() function. + * include/dns_impl.inl: Ditto. + +2001-09-28 Jesper Skov + + * tests/dns1.c (_DNS_IP): Changed to IP used in farm. + +2001-09-27 Jesper Skov + + * include/dns_priv.h: Added DNS_REPLY definitions. + + * include/dns_impl.inl: Handle NXDomain returns. + + * include/dns_impl.inl: Added tracing. + * src/dns.c: Same. + +2001-09-26 Jesper Skov + + * tests/dns1.c (dns_test): Use hstrerror instead of strerror. + + * include/dns.h: Added h_errno support. + * include/dns_impl.inl: Use h_errno instead of errno. Added + hstrerror(). Make hostname lookups before hostname.domainmain + lookups. + +2001-09-25 Jesper Skov + + * include/dns.h: Moved some more defs to.. + * include/dns_priv.h: ...here. + + * src/dns-priv.h: [deleted] + * include/dns_priv.h: [added] + + * tests/dns1.c: Include netdb.h instead of dns.h. + + * src/dns.c: Moved all DNS protocol functions into + dns_impl.inl. Allow for RedBoot to share the implementation with a + smaller overhead. + * include/dns_impl.inl: Added. + + * cdl/dns.cdl: Moved compile statement and requirements into + CYGPKG_NS_DNS_BUILD option which can be forced off by RedBoot. + Moved headers to cyg/ns/dns. + + * src/dns.c (alloc_hent, free_hent, alloc_string, free_string): + Added these wrapper functions for malloc/free calls - allow easier + maintaining of cloned function in RedBoot which uses static + variables for storage. Incidently removed a little code + duplication. + + * include/dns.h: Only include exported information. + * src/dns-priv.h: Everything else moved to this file. + + * cdl/dns.cdl: Added feature requirements and CYGINT_ISO_DNS + magic. + + * include/dns.h: Renamed res_init to cyg_dns_res_init. + * src/dns.c: Same. + * tests/dns1.c: Same. + + * src/dns.c: Use drv_api mutex, removed some include statements. + * include/dns.h: Provide hostent definition and function + declarations. + + * tests/dns1.c: Use cambridge.redhat.com addresses. Changed to + output PASS/FAIL. + + * src/dns.c (parse_answer): On PTR lookups, alloc space for + in_addr, so caller can copy data there. Fix gethostbyaddr() to + do so. + Note that error values do not match gethostbyaddr(3). + +2001-09-20 Jesper Skov + + * src/dns.c: More cosmetic changes, a few htons -> ntohs changes, + reducing size of critical section a few places, rely on + build_query setting errno, and set errno when getdomainname can't + copy domain name out due to size limitation. + +2001-09-19 Jesper Skov + + * tests/dns1.c (dns_test): Fix inet_aton check. + * src/dns.c: A few comment and cosmetic changes. + +2001-09-18 Jesper Skov + + * src/dns.c: Added DNS code contributed by Andrew Lunn + + * include/dns.h: Same. + * tests/dns1.c: Same. + +//=========================================================================== +//####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. +// +// eCos is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 or (at your option) any later version. +// +// eCos is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with eCos; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +// +// As a special exception, if other files instantiate templates or use macros +// or inline functions from this file, or you compile this file and link it +// with other works to produce a work based on this file, this file does not +// by itself cause the resulting work to be covered by the GNU General Public +// License. However the source code for this file must still be made available +// in accordance with section (3) of the GNU General Public License. +// +// This exception does not invalidate any other reasons why a work based on +// this file might be covered by the GNU General Public License. +// +// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. +// at http://sources.redhat.com/ecos/ecos-license/ +// ------------------------------------------- +//####ECOSGPLCOPYRIGHTEND#### +//=========================================================================== Index: dns/v2_0/src/dns.c =================================================================== --- dns/v2_0/src/dns.c (nonexistent) +++ dns/v2_0/src/dns.c (revision 1765) @@ -0,0 +1,317 @@ +//============================================================================= +// +// dns.c +// +// DNS client code +// +//============================================================================= +//####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. +// +// eCos is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 or (at your option) any later version. +// +// eCos is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with eCos; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +// +// As a special exception, if other files instantiate templates or use macros +// or inline functions from this file, or you compile this file and link it +// with other works to produce a work based on this file, this file does not +// by itself cause the resulting work to be covered by the GNU General Public +// License. However the source code for this file must still be made available +// in accordance with section (3) of the GNU General Public License. +// +// This exception does not invalidate any other reasons why a work based on +// this file might be covered by the GNU General Public License. +// +// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. +// at http://sources.redhat.com/ecos/ecos-license/ +// ------------------------------------------- +//####ECOSGPLCOPYRIGHTEND#### +//============================================================================= +//#####DESCRIPTIONBEGIN#### +// +// Author(s): andrew.lunn +// Contributors:andrew.lunn, jskov +// Date: 2001-09-18 +// Description: Provides DNS lookup as per RFC 1034/1035. +// +// Note: Does only support A and PTR lookups. Maybe add for other +// types as well? +// +// parse_answer() only returns the first found record. +// +// Add tracing and assertions. +// +//####DESCRIPTIONEND#### +// +//============================================================================= + +#include +#ifdef CYGPKG_KERNEL +# include +# include +#endif +#include +#include +#include /* Tracing support */ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +static short id = 0; /* ID of the last query */ +static int s = -1; /* Socket to the DNS server */ +static cyg_drv_mutex_t dns_mutex; /* Mutex to stop multiple queries as once */ +static cyg_ucount32 ptdindex; /* Index for the per thread data */ +static char * domainname=NULL; /* Domain name used for queries */ + +/* Allocate space for string of length len. Return NULL on failure. */ +static inline char* +alloc_string(int len) +{ + return malloc(len); +} + +static inline void +free_string(char* s) +{ + free(s); +} + +/* Deallocate the memory taken to hold a hent structure */ +static void +free_hent(struct hostent * hent) +{ + if (hent->h_name) { + free_string(hent->h_name); + } + + if (hent->h_addr_list) { + int i = 0; + while (hent->h_addr_list[i]) { + free(hent->h_addr_list[i]); + i++; + } + free(hent->h_addr_list); + } + free(hent); +} + +/* Allocate hent structure with room for one in_addr. Returns NULL on + failure. */ +static struct hostent* +alloc_hent(void) +{ + struct hostent *hent; + + hent = malloc(sizeof(struct hostent)); + if (hent) { + memset(hent, 0, sizeof(struct hostent)); + hent->h_addr_list = malloc(sizeof(char *)*2); + if (!hent->h_addr_list) { + free_hent(hent); + return NULL; + } + hent->h_addr_list[0] = malloc(sizeof(struct in_addr)); + if (!hent->h_addr_list[0]) { + free_hent(hent); + return NULL; + } + hent->h_addr_list[1] = NULL; + } + + return hent; +} + +/* Thread destructor used to free stuff stored in per-thread data slot. */ +static void +thread_destructor(CYG_ADDRWORD data) +{ + struct hostent *hent; + hent = (struct hostent *)cyg_thread_get_data(ptdindex); + if (hent) + free_hent(hent); + return; + data=data; +} + +/* Store the hent away in the per-thread data. */ +static void +store_hent(struct hostent *hent) +{ + // Prevent memory leaks by setting a destructor to be + // called on thread exit to free per-thread data. + cyg_thread_add_destructor( &thread_destructor, 0 ); + cyg_thread_set_data(ptdindex, (CYG_ADDRWORD)hent); +} + +/* If there is an answer to an old query, free the memory it uses. */ +static void +free_stored_hent(void) +{ + struct hostent *hent; + hent = (struct hostent *)cyg_thread_get_data(ptdindex); + if (hent) { + free_hent(hent); + cyg_thread_set_data(ptdindex, (CYG_ADDRWORD)NULL); + cyg_thread_rem_destructor( &thread_destructor, 0 ); + } +} + +/* Send the query to the server and read the response back. Return -1 + if it fails, otherwise put the response back in msg and return the + length of the response. */ +static int +send_recv(char * msg, int len, int msglen) +{ + struct dns_header *dns_hdr; + struct timeval timeout; + int finished = false; + int backoff = 1; + fd_set readfds; + int written; + int ret; + + CYG_REPORT_FUNCNAMETYPE( "send_recv", "returning %d" ); + CYG_REPORT_FUNCARG3( "msg=%08x, len=%d, msglen", msg, len, msglen ); + + CYG_CHECK_DATA_PTR( msg, "msg is not a valid pointer!" ); + + dns_hdr = (struct dns_header *) msg; + + do { + written = write(s, msg, len); + if (written < 0) { + ret = -1; + break; + } + + FD_ZERO(&readfds); + FD_SET(s, &readfds); + + timeout.tv_sec = backoff; + timeout.tv_usec = 0; + backoff = backoff << 1; + + ret = select(s+1, &readfds, NULL, NULL, &timeout); + if (ret < 0) { + ret = -1; + break; + } + /* Timeout */ + if (ret == 0) { + if (backoff > 16) { + h_errno = TRY_AGAIN; + ret = -1; + break; + } + } + if (ret == 1) { + ret = read(s, msg, msglen); + if (ret < 0) { + ret = -1; + break; + } + + /* Reply to an old query. Ignore it */ + if (ntohs(dns_hdr->id) != (id-1)) { + continue; + } + finished = true; + } + } while (!finished); + + CYG_REPORT_RETVAL( ret ); + + return ret; +} + +/* Include the DNS client implementation code */ +#include + +/* Initialise the resolver. Open a socket and bind it to the address + of the server. return -1 if something goes wrong, otherwise 0. If + we are being called a second time we have to be careful to allow + any ongoing lookups to finish before we close the socket and + connect to a different DNS server. The danger here is that we may + have to wait for upto 32 seconds if the DNS server is down. + */ +int +cyg_dns_res_init(struct in_addr *dns_server) +{ + struct sockaddr_in server; + struct servent *sent; + static int init =0; + + CYG_REPORT_FUNCNAMETYPE( "cyg_dns_res_init", "returning %d" ); + CYG_REPORT_FUNCARG1( "dns_server=%08x", dns_server ); + + CYG_CHECK_DATA_PTR( dns_server, "dns_server is not a valid pointer!" ); + + if (init) { + cyg_drv_mutex_lock(&dns_mutex); + cyg_thread_free_data_index(ptdindex); + if (s >= 0) { + close(s); + } + } else { + init = 1; + cyg_drv_mutex_init(&dns_mutex); + cyg_drv_mutex_lock(&dns_mutex); + } + + + s = socket(PF_INET, SOCK_DGRAM, 0); + if (s < 0) { + cyg_drv_mutex_unlock(&dns_mutex); + CYG_REPORT_RETVAL( -1 ); + return -1; + } + + sent = getservbyname("domain", "udp"); + if (sent == (struct servent *)0) { + s = -1; + cyg_drv_mutex_unlock(&dns_mutex); + CYG_REPORT_RETVAL( -1 ); + return -1; + } + + memcpy((char *)&server.sin_addr, dns_server, sizeof(server.sin_addr)); + server.sin_port = sent->s_port; + server.sin_family = AF_INET; + server.sin_len = sizeof(server); + + if (connect(s, (struct sockaddr *)&server, sizeof(server)) < 0) { + s = -1; + cyg_drv_mutex_unlock(&dns_mutex); + CYG_REPORT_RETVAL( -1 ); + return -1; + } + ptdindex = cyg_thread_new_data_index(); + + cyg_drv_mutex_unlock(&dns_mutex); + + CYG_REPORT_RETVAL( 0 ); + return 0; +}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.