From 5d303ec17efc511d8cfe0919a790b44e24a8aad9 Mon Sep 17 00:00:00 2001 From: patacongo Date: Sat, 1 Sep 2007 18:06:15 +0000 Subject: Added support for socket descriptors git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@318 42af7a65-404d-4744-a932-0658087f49c3 --- nuttx/netutils/resolv/Make.defs | 2 +- nuttx/netutils/resolv/resolv.c | 553 +++++++++++++++++++++------------------- 2 files changed, 296 insertions(+), 259 deletions(-) (limited to 'nuttx/netutils/resolv') diff --git a/nuttx/netutils/resolv/Make.defs b/nuttx/netutils/resolv/Make.defs index e83757d36..0ca95b94e 100644 --- a/nuttx/netutils/resolv/Make.defs +++ b/nuttx/netutils/resolv/Make.defs @@ -33,7 +33,7 @@ # ############################################################################ -ifeq ($(CONFIG_UIP_UDP),y) +ifeq ($(CONFIG_NET_UDP),y) RESOLV_ASRCS = RESOLV_CSRCS = resolv.c endif diff --git a/nuttx/netutils/resolv/resolv.c b/nuttx/netutils/resolv/resolv.c index 0a38faea8..14159e906 100644 --- a/nuttx/netutils/resolv/resolv.c +++ b/nuttx/netutils/resolv/resolv.c @@ -1,6 +1,5 @@ /* uip-resolv.c * DNS host name to IP address resolver. - * Author: Adam Dunkels * * The uIP DNS resolver functions are used to lookup a hostname and * map it to a numerical IP address. It maintains a list of resolved @@ -12,8 +11,14 @@ * the resolver code calls a callback function called resolv_found() * that must be implemented by the module that uses the resolver. * - * Copyright (c) 2002-2003, Adam Dunkels. - * All rights reserved. + * Copyright (C) 2007 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Based heavily on portions of uIP: + * + * Author: Adam Dunkels + * Copyright (c) 2002-2003, Adam Dunkels. + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -39,11 +44,11 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * This file is part of the uIP TCP/IP stack. - * - * $Id: resolv.c,v 1.1.1.1 2007-08-26 23:07:05 patacongo Exp $ - * - */ + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ #include #include @@ -51,17 +56,24 @@ #include #include +/**************************************************************************** + * Definitions + ****************************************************************************/ + +#ifndef CONFIG_NET_RESOLV_ENTRIES +#define RESOLV_ENTRIES 4 +#else /* CONFIG_NET_RESOLV_ENTRIES */ +#define RESOLV_ENTRIES CONFIG_NET_RESOLV_ENTRIES +#endif /* CONFIG_NET_RESOLV_ENTRIES */ + #ifndef NULL #define NULL (void *)0 #endif /* NULL */ -/** \internal The maximum number of retries when asking for a name. */ +/* The maximum number of retries when asking for a name */ + #define MAX_RETRIES 8 -/** \internal The DNS message header. */ -struct dns_hdr { - uint16 id; - uint8 flags1, flags2; #define DNS_FLAG1_RESPONSE 0x80 #define DNS_FLAG1_OPCODE_STATUS 0x10 #define DNS_FLAG1_OPCODE_INVERSE 0x08 @@ -73,16 +85,37 @@ struct dns_hdr { #define DNS_FLAG2_ERR_MASK 0x0f #define DNS_FLAG2_ERR_NONE 0x00 #define DNS_FLAG2_ERR_NAME 0x03 + +#define STATE_UNUSED 0 +#define STATE_NEW 1 +#define STATE_ASKING 2 +#define STATE_DONE 3 +#define STATE_ERROR 4 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* The DNS message header */ + +struct dns_hdr +{ + uint16 id; + uint8 flags1, flags2; uint16 numquestions; uint16 numanswers; uint16 numauthrr; uint16 numextrarr; }; -/** \internal The DNS answer message structure. */ -struct dns_answer { +/* The DNS answer message structure */ + +struct dns_answer +{ /* DNS answer record starts with either a domain name or a pointer - to a name already present somewhere in the packet. */ + * to a name already present somewhere in the packet. + */ + uint16 type; uint16 class; uint16 ttl[2]; @@ -90,12 +123,8 @@ struct dns_answer { uip_ipaddr_t ipaddr; }; -struct namemap { -#define STATE_UNUSED 0 -#define STATE_NEW 1 -#define STATE_ASKING 2 -#define STATE_DONE 3 -#define STATE_ERROR 4 +struct namemap +{ uint8 state; uint8 tmr; uint8 retries; @@ -105,51 +134,43 @@ struct namemap { uip_ipaddr_t ipaddr; }; -#ifndef CONFIG_UIP_RESOLV_ENTRIES -#define RESOLV_ENTRIES 4 -#else /* CONFIG_UIP_RESOLV_ENTRIES */ -#define RESOLV_ENTRIES CONFIG_UIP_RESOLV_ENTRIES -#endif /* CONFIG_UIP_RESOLV_ENTRIES */ - +/**************************************************************************** + * Private Data + ****************************************************************************/ static struct namemap names[RESOLV_ENTRIES]; - static uint8 seqno; - static struct uip_udp_conn *resolv_conn = NULL; +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/* Walk through a compact encoded DNS name and return the end of it. */ -/*---------------------------------------------------------------------------*/ -/** \internal - * Walk through a compact encoded DNS name and return the end of it. - * - * \return The end of the name. - */ -/*---------------------------------------------------------------------------*/ static unsigned char *parse_name(unsigned char *query) { unsigned char n; - do { - n = *query++; + do + { + n = *query++; - while(n > 0) - { - ++query; - --n; - }; - } while(*query != 0); + while(n > 0) + { + ++query; + --n; + } + } + while(*query != 0); return query + 1; } -/*---------------------------------------------------------------------------*/ -/** \internal - * Runs through the list of names to see if there are any that have +/* Runs through the list of names to see if there are any that have * not yet been queried and, if so, sends out a query. */ -/*---------------------------------------------------------------------------*/ -static void -check_entries(void) + +static void check_entries(void) { register struct dns_hdr *hdr; char *query, *nptr, *nameptr; @@ -157,66 +178,73 @@ check_entries(void) static uint8 n; register struct namemap *namemapptr; - for(i = 0; i < RESOLV_ENTRIES; ++i) { - namemapptr = &names[i]; - if(namemapptr->state == STATE_NEW || - namemapptr->state == STATE_ASKING) { - if(namemapptr->state == STATE_ASKING) { - if(--namemapptr->tmr == 0) { - if(++namemapptr->retries == MAX_RETRIES) { - namemapptr->state = STATE_ERROR; - resolv_found(namemapptr->name, NULL); - continue; - } - namemapptr->tmr = namemapptr->retries; - } else { - /* printf("Timer %d\n", namemapptr->tmr);*/ - /* Its timer has not run out, so we move on to next - entry. */ - continue; - } - } else { - namemapptr->state = STATE_ASKING; - namemapptr->tmr = 1; - namemapptr->retries = 0; - } - hdr = (struct dns_hdr *)uip_appdata; - memset(hdr, 0, sizeof(struct dns_hdr)); - hdr->id = htons(i); - hdr->flags1 = DNS_FLAG1_RD; - hdr->numquestions = HTONS(1); - query = (char *)uip_appdata + 12; - nameptr = namemapptr->name; - --nameptr; - /* Convert hostname into suitable query format. */ - do { - ++nameptr; - nptr = query; - ++query; - for(n = 0; *nameptr != '.' && *nameptr != 0; ++nameptr) { - *query = *nameptr; - ++query; - ++n; - } - *nptr = n; - } while(*nameptr != 0); - { - static unsigned char endquery[] = - {0,0,1,0,1}; - memcpy(query, endquery, 5); - } - uip_udp_send((unsigned char)(query + 5 - (char *)uip_appdata)); - break; + for(i = 0; i < RESOLV_ENTRIES; ++i) + { + namemapptr = &names[i]; + if (namemapptr->state == STATE_NEW || + namemapptr->state == STATE_ASKING) + { + if (namemapptr->state == STATE_ASKING) + { + if (--namemapptr->tmr == 0) + { + if (++namemapptr->retries == MAX_RETRIES) + { + namemapptr->state = STATE_ERROR; + resolv_found(namemapptr->name, NULL); + continue; + } + namemapptr->tmr = namemapptr->retries; + } + else + { + /* Its timer has not run out, so we move on to next entry. */ + continue; + } + } + else + { + namemapptr->state = STATE_ASKING; + namemapptr->tmr = 1; + namemapptr->retries = 0; + } + hdr = (struct dns_hdr *)uip_appdata; + memset(hdr, 0, sizeof(struct dns_hdr)); + hdr->id = htons(i); + hdr->flags1 = DNS_FLAG1_RD; + hdr->numquestions = HTONS(1); + query = (char *)uip_appdata + 12; + nameptr = namemapptr->name; + --nameptr; + + /* Convert hostname into suitable query format. */ + do + { + ++nameptr; + nptr = query; + ++query; + for (n = 0; *nameptr != '.' && *nameptr != 0; ++nameptr) + { + *query = *nameptr; + ++query; + ++n; + } + *nptr = n; + } + while(*nameptr != 0); + { + static unsigned char endquery[] = {0,0,1,0,1}; + memcpy(query, endquery, 5); + } + uip_udp_send((unsigned char)(query + 5 - (char *)uip_appdata)); + break; + } } - } } -/*---------------------------------------------------------------------------*/ -/** \internal - * Called when new UDP data arrives. - */ -/*---------------------------------------------------------------------------*/ -static void -newdata(void) + +/* Called when new UDP data arrives */ + +static void newdata(void) { unsigned char *nameptr; struct dns_answer *ans; @@ -226,114 +254,127 @@ newdata(void) register struct namemap *namemapptr; hdr = (struct dns_hdr *)uip_appdata; - /* printf("ID %d\n", htons(hdr->id)); - printf("Query %d\n", hdr->flags1 & DNS_FLAG1_RESPONSE); - printf("Error %d\n", hdr->flags2 & DNS_FLAG2_ERR_MASK); - printf("Num questions %d, answers %d, authrr %d, extrarr %d\n", - htons(hdr->numquestions), - htons(hdr->numanswers), - htons(hdr->numauthrr), - htons(hdr->numextrarr)); - */ + + dbg( "ID %d\n", htons(hdr->id)); + dbg( "Query %d\n", hdr->flags1 & DNS_FLAG1_RESPONSE); + dbg( "Error %d\n", hdr->flags2 & DNS_FLAG2_ERR_MASK); + dbg( "Num questions %d, answers %d, authrr %d, extrarr %d\n", + htons(hdr->numquestions), htons(hdr->numanswers), + htons(hdr->numauthrr), htons(hdr->numextrarr)); /* The ID in the DNS header should be our entry into the name - table. */ + * table. + */ + i = htons(hdr->id); namemapptr = &names[i]; - if(i < RESOLV_ENTRIES && - namemapptr->state == STATE_ASKING) { - - /* This entry is now finished. */ - namemapptr->state = STATE_DONE; - namemapptr->err = hdr->flags2 & DNS_FLAG2_ERR_MASK; - - /* Check for error. If so, call callback to inform. */ - if(namemapptr->err != 0) { - namemapptr->state = STATE_ERROR; - resolv_found(namemapptr->name, NULL); - return; - } + if (i < RESOLV_ENTRIES && namemapptr->state == STATE_ASKING) + { + /* This entry is now finished */ - /* We only care about the question(s) and the answers. The authrr - and the extrarr are simply discarded. */ - nquestions = htons(hdr->numquestions); - nanswers = htons(hdr->numanswers); - - /* Skip the name in the question. XXX: This should really be - checked agains the name in the question, to be sure that they - match. */ - nameptr = parse_name((unsigned char *)uip_appdata + 12) + 4; - - while(nanswers > 0) { - /* The first byte in the answer resource record determines if it - is a compressed record or a normal one. */ - if(*nameptr & 0xc0) { - /* Compressed name. */ - nameptr +=2; - /* printf("Compressed anwser\n");*/ - } else { - /* Not compressed name. */ - nameptr = parse_name(nameptr); - } - - ans = (struct dns_answer *)nameptr; - /* printf("Answer: type %x, class %x, ttl %x, length %x\n", - htons(ans->type), htons(ans->class), (htons(ans->ttl[0]) - << 16) | htons(ans->ttl[1]), htons(ans->len));*/ - - /* Check for IP address type and Internet class. Others are - discarded. */ - if(ans->type == HTONS(1) && - ans->class == HTONS(1) && - ans->len == HTONS(4)) { - /* printf("IP address %d.%d.%d.%d\n", - htons(ans->ipaddr[0]) >> 8, - htons(ans->ipaddr[0]) & 0xff, - htons(ans->ipaddr[1]) >> 8, - htons(ans->ipaddr[1]) & 0xff);*/ - /* XXX: we should really check that this IP address is the one - we want. */ - namemapptr->ipaddr[0] = ans->ipaddr[0]; - namemapptr->ipaddr[1] = ans->ipaddr[1]; - - resolv_found(namemapptr->name, namemapptr->ipaddr); - return; - } else { - nameptr = nameptr + 10 + htons(ans->len); - } - --nanswers; - } - } + namemapptr->state = STATE_DONE; + namemapptr->err = hdr->flags2 & DNS_FLAG2_ERR_MASK; + + /* Check for error. If so, call callback to inform */ + + if (namemapptr->err != 0) + { + namemapptr->state = STATE_ERROR; + resolv_found(namemapptr->name, NULL); + return; + } + + /* We only care about the question(s) and the answers. The authrr + * and the extrarr are simply discarded. + */ + + nquestions = htons(hdr->numquestions); + nanswers = htons(hdr->numanswers); + + /* Skip the name in the question. XXX: This should really be + * checked agains the name in the question, to be sure that they + * match. + */ + + nameptr = parse_name((unsigned char *)uip_appdata + 12) + 4; + while(nanswers > 0) + { + /* The first byte in the answer resource record determines if it + * is a compressed record or a normal one. + */ + + if (*nameptr & 0xc0) + { + /* Compressed name. */ + + nameptr +=2; + dbg("Compressed anwser\n"); + } + else + { + /* Not compressed name. */ + nameptr = parse_name(nameptr); + } + + ans = (struct dns_answer *)nameptr; + dbg("Answer: type %x, class %x, ttl %x, length %x\n", + htons(ans->type), htons(ans->class), (htons(ans->ttl[0]) << 16) | htons(ans->ttl[1]), + htons(ans->len)); + + /* Check for IP address type and Internet class. Others are discarded. */ + + if (ans->type == HTONS(1) && ans->class == HTONS(1) && ans->len == HTONS(4)) + { + dbg("IP address %d.%d.%d.%d\n", + htons(ans->ipaddr[0]) >> 8, htons(ans->ipaddr[0]) & 0xff, + htons(ans->ipaddr[1]) >> 8, htons(ans->ipaddr[1]) & 0xff); + + /* XXX: we should really check that this IP address is the one + * we want. + */ + + namemapptr->ipaddr[0] = ans->ipaddr[0]; + namemapptr->ipaddr[1] = ans->ipaddr[1]; + + resolv_found(namemapptr->name, namemapptr->ipaddr); + return; + } + else + { + nameptr = nameptr + 10 + htons(ans->len); + } + --nanswers; + } + } } +/**************************************************************************** + * Private Functions + ****************************************************************************/ + /* This function is called by the UIP interrupt handling logic whenevent an * event of interest occurs. */ void uip_interrupt_udp_event(void) { - if(uip_udp_conn->rport == HTONS(53)) + if (uip_udp_conn->rport == HTONS(53)) { - if(uip_poll()) + if (uip_poll()) { check_entries(); } - if(uip_newdata()) + if (uip_newdata()) { newdata(); } } } -/** - * Queues a name so that a question for the name will be sent out. - * - * \param name The hostname that is to be queried. - */ -/*---------------------------------------------------------------------------*/ -void -resolv_query(char *name) +/* Queues a name so that a question for the name will be sent out. */ + +void resolv_query(char *name) { static uint8 i; static uint8 lseq, lseqi; @@ -341,110 +382,106 @@ resolv_query(char *name) lseq = lseqi = 0; - for(i = 0; i < RESOLV_ENTRIES; ++i) { - nameptr = &names[i]; - if(nameptr->state == STATE_UNUSED) { - break; - } - if(seqno - nameptr->seqno > lseq) { - lseq = seqno - nameptr->seqno; - lseqi = i; + for(i = 0; i < RESOLV_ENTRIES; ++i) + { + nameptr = &names[i]; + if (nameptr->state == STATE_UNUSED) + { + break; + } + if (seqno - nameptr->seqno > lseq) + { + lseq = seqno - nameptr->seqno; + lseqi = i; + } } - } - if(i == RESOLV_ENTRIES) { - i = lseqi; - nameptr = &names[i]; - } + if (i == RESOLV_ENTRIES) + { + i = lseqi; + nameptr = &names[i]; + } - /* printf("Using entry %d\n", i);*/ + dbg("Using entry %d\n", i); strcpy(nameptr->name, name); nameptr->state = STATE_NEW; nameptr->seqno = seqno; ++seqno; } -/*---------------------------------------------------------------------------*/ -/** - * Look up a hostname in the array of known hostnames. + +/* Look up a hostname in the array of known hostnames. * - * \note This function only looks in the internal array of known + * Note: This function only looks in the internal array of known * hostnames, it does not send out a query for the hostname if none * was found. The function resolv_query() can be used to send a query * for a hostname. * - * \return A pointer to a 4-byte representation of the hostname's IP + * Return A pointer to a 4-byte representation of the hostname's IP * address, or NULL if the hostname was not found in the array of * hostnames. */ -/*---------------------------------------------------------------------------*/ -uint16 * -resolv_lookup(char *name) + +uint16 *resolv_lookup(char *name) { static uint8 i; struct namemap *nameptr; /* Walk through the list to see if the name is in there. If it is - not, we return NULL. */ - for(i = 0; i < RESOLV_ENTRIES; ++i) { - nameptr = &names[i]; - if(nameptr->state == STATE_DONE && - strcmp(name, nameptr->name) == 0) { - return nameptr->ipaddr; + * not, we return NULL. + */ + + for(i = 0; i < RESOLV_ENTRIES; ++i) + { + nameptr = &names[i]; + if (nameptr->state == STATE_DONE && strcmp(name, nameptr->name) == 0) + { + return nameptr->ipaddr; + } } - } return NULL; } -/*---------------------------------------------------------------------------*/ -/** - * Obtain the currently configured DNS server. + +/* Obtain the currently configured DNS server. * - * \return A pointer to a 4-byte representation of the IP address of + * Return: A pointer to a 4-byte representation of the IP address of * the currently configured DNS server or NULL if no DNS server has * been configured. */ -/*---------------------------------------------------------------------------*/ -uint16 * -resolv_getserver(void) + +uint16 *resolv_getserver(void) { - if(resolv_conn == NULL) { - return NULL; - } + if (resolv_conn == NULL) + { + return NULL; + } return resolv_conn->ripaddr; } -/*---------------------------------------------------------------------------*/ -/** - * Configure which DNS server to use for queries. + +/* Configure which DNS server to use for queries. * - * \param dnsserver A pointer to a 4-byte representation of the IP + * dnsserver A pointer to a 4-byte representation of the IP * address of the DNS server to be configured. */ -/*---------------------------------------------------------------------------*/ -void -resolv_conf(uint16 *dnsserver) + +void resolv_conf(uint16 *dnsserver) { - if(resolv_conn != NULL) { - uip_udp_remove(resolv_conn); - } - + if (resolv_conn != NULL) + { + uip_udp_remove(resolv_conn); + } + resolv_conn = uip_udp_new(dnsserver, HTONS(53)); } -/*---------------------------------------------------------------------------*/ -/** - * Initalize the resolver. - */ -/*---------------------------------------------------------------------------*/ -void -resolv_init(void) + +/* Initalize the resolver. */ + +void resolv_init(void) { static uint8 i; - for(i = 0; i < RESOLV_ENTRIES; ++i) { - names[i].state = STATE_DONE; - } - + for(i = 0; i < RESOLV_ENTRIES; ++i) + { + names[i].state = STATE_DONE; + } } -/*---------------------------------------------------------------------------*/ - -/** @} */ -/** @} */ -- cgit v1.2.3