Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

ares_mkquery.c File Reference

#include "ares_private.h"
#include "ares_dns.h"

Include dependency graph for ares_mkquery.c:

Go to the source code of this file.

Functions

int ares_mkquery (const char *name, int dnsclass, int type, unsigned short id, int rd, unsigned char **buf, int *buflen)


Function Documentation

int ares_mkquery const char *  name,
int  dnsclass,
int  type,
unsigned short  id,
int  rd,
unsigned char **  buf,
int *  buflen
 

Definition at line 74 of file ares_mkquery.c.

References ARES_EBADNAME, ARES_ENOMEM, ARES_SUCCESS, DNS_HEADER_SET_OPCODE, DNS_HEADER_SET_QDCOUNT, DNS_HEADER_SET_QID, DNS_HEADER_SET_RD, DNS_QUESTION_SET_CLASS, DNS_QUESTION_SET_TYPE, HFIXEDSZ, len, malloc, MAXLABEL, name, QFIXEDSZ, and QUERY.

Referenced by ares_query().

00076 {
00077   int len;
00078   unsigned char *q;
00079   const char *p;
00080 
00081   /* Compute the length of the encoded name so we can check buflen.
00082    * Start counting at 1 for the zero-length label at the end. */
00083   len = 1;
00084   for (p = name; *p; p++)
00085     {
00086       if (*p == '\\' && *(p + 1) != 0)
00087         p++;
00088       len++;
00089     }
00090   /* If there are n periods in the name, there are n + 1 labels, and
00091    * thus n + 1 length fields, unless the name is empty or ends with a
00092    * period.  So add 1 unless name is empty or ends with a period.
00093    */
00094   if (*name && *(p - 1) != '.')
00095     len++;
00096 
00097   *buflen = len + HFIXEDSZ + QFIXEDSZ;
00098   *buf = malloc(*buflen);
00099   if (!*buf)
00100       return ARES_ENOMEM;
00101 
00102   /* Set up the header. */
00103   q = *buf;
00104   memset(q, 0, HFIXEDSZ);
00105   DNS_HEADER_SET_QID(q, id);
00106   DNS_HEADER_SET_OPCODE(q, QUERY);
00107   DNS_HEADER_SET_RD(q, (rd) ? 1 : 0);
00108   DNS_HEADER_SET_QDCOUNT(q, 1);
00109 
00110   /* A name of "." is a screw case for the loop below, so adjust it. */
00111   if (strcmp(name, ".") == 0)
00112     name++;
00113 
00114   /* Start writing out the name after the header. */
00115   q += HFIXEDSZ;
00116   while (*name)
00117     {
00118       if (*name == '.')
00119         return ARES_EBADNAME;
00120 
00121       /* Count the number of bytes in this label. */
00122       len = 0;
00123       for (p = name; *p && *p != '.'; p++)
00124         {
00125           if (*p == '\\' && *(p + 1) != 0)
00126             p++;
00127           len++;
00128         }
00129       if (len > MAXLABEL)
00130         return ARES_EBADNAME;
00131 
00132       /* Encode the length and copy the data. */
00133       *q++ = len;
00134       for (p = name; *p && *p != '.'; p++)
00135         {
00136           if (*p == '\\' && *(p + 1) != 0)
00137             p++;
00138           *q++ = *p;
00139         }
00140 
00141       /* Go to the next label and repeat, unless we hit the end. */
00142       if (!*p)
00143         break;
00144       name = p + 1;
00145     }
00146 
00147   /* Add the zero-length label at the end. */
00148   *q++ = 0;
00149 
00150   /* Finish off the question with the type and class. */
00151   DNS_QUESTION_SET_TYPE(q, type);
00152   DNS_QUESTION_SET_CLASS(q, dnsclass);
00153 
00154   return ARES_SUCCESS;
00155 }


Generated on Wed Jan 14 12:59:00 2004 for RTL-lwIP-0.4 by doxygen 1.3.4