#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) |
|
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 } |