+ else
+ {
+ char formatted[128];
+
+ /* Forward lookups come back as binary data. We must format them into ascii */
+ switch (req->type)
+ {
+ case DNS_QUERY_A:
+ snprintf(formatted,16,"%u.%u.%u.%u",data.first[0],data.first[1],data.first[2],data.first[3]);
+ resultstr = formatted;
+ break;
+
+ case DNS_QUERY_AAAA:
+ {
+ snprintf(formatted,40,"%x:%x:%x:%x:%x:%x:%x:%x",
+ (ntohs(data.first[0]) + ntohs(data.first[1] << 8)),
+ (ntohs(data.first[2]) + ntohs(data.first[3] << 8)),
+ (ntohs(data.first[4]) + ntohs(data.first[5] << 8)),
+ (ntohs(data.first[6]) + ntohs(data.first[7] << 8)),
+ (ntohs(data.first[8]) + ntohs(data.first[9] << 8)),
+ (ntohs(data.first[10]) + ntohs(data.first[11] << 8)),
+ (ntohs(data.first[12]) + ntohs(data.first[13] << 8)),
+ (ntohs(data.first[14]) + ntohs(data.first[15] << 8)));
+ char* c = strstr(formatted,":0:");
+ if (c != NULL)
+ {
+ memmove(c+1,c+2,strlen(c+2) + 1);
+ c += 2;
+ while (memcmp(c,"0:",2) == 0)
+ memmove(c,c+2,strlen(c+2) + 1);
+ if (memcmp(c,"0",2) == 0)
+ *c = 0;
+ if (memcmp(formatted,"0::",3) == 0)
+ memmove(formatted,formatted + 1, strlen(formatted + 1) + 1);
+ }
+ resultstr = formatted;
+
+ /* Special case. Sending ::1 around between servers
+ * and to clients is dangerous, because the : on the
+ * start makes the client or server interpret the IP
+ * as the last parameter on the line with a value ":1".
+ */
+ if (*formatted == ':')
+ resultstr = "0" + resultstr;
+ }
+ break;
+
+ case DNS_QUERY_CNAME:
+ /* Identical handling to PTR */
+
+ case DNS_QUERY_PTR:
+ /* Reverse lookups just come back as char* */
+ resultstr = std::string((const char*)data.first);
+ break;
+
+ default:
+ ServerInstance->Log(DEBUG,"WARNING: Somehow we made a request for a DNS_QUERY_PTR4 or DNS_QUERY_PTR6, but these arent real rr types!");
+ break;
+
+ }
+
+ /* Build the reply with the id and hostname/ip in it */
+ delete req;
+ return std::make_pair(this_id,resultstr);
+ }
+}
+
+/** A result is ready, process it */
+DNSInfo DNSRequest::ResultIsReady(DNSHeader &header, int length)
+{
+ int i = 0;
+ int q = 0;
+ int curanswer, o;
+ ResourceRecord rr;
+ unsigned short ptr;
+
+ /* This is just to keep _FORTIFY_SOURCE happy */
+ rr.type = DNS_QUERY_NONE;
+ rr.rdlength = 0;
+
+ if (!(header.flags1 & FLAGS_MASK_QR))
+ return std::make_pair((unsigned char*)NULL,"Not a query result");
+
+ if (header.flags1 & FLAGS_MASK_OPCODE)
+ return std::make_pair((unsigned char*)NULL,"Unexpected value in DNS reply packet");
+
+ if (header.flags2 & FLAGS_MASK_RCODE)
+ return std::make_pair((unsigned char*)NULL,"Domain name not found");
+
+ if (header.ancount < 1)
+ return std::make_pair((unsigned char*)NULL,"No resource records returned");
+
+ /* Subtract the length of the header from the length of the packet */