void DNSTaskResolvCallback(void *arg, int status, int timeouts, unsigned char *abuf, int alen) { struct DNSTask *dnstask = (struct DNSTask *) arg; char *query; int id, qr, opcode, aa, tc, rd, ra, rcode; long len; unsigned int qdcount, ancount, nscount, arcount, i; const unsigned char *aptr; debug("LobjId:%d, Hostname %s", dnstask->task->LObjId, dnstask->task->Record.HostName); if (status != ARES_SUCCESS and status != ARES_ENODATA) { return; } /* Parse the answer header. */ id = DNS_HEADER_QID(abuf); qr = DNS_HEADER_QR(abuf); opcode = DNS_HEADER_OPCODE(abuf); aa = DNS_HEADER_AA(abuf); tc = DNS_HEADER_TC(abuf); rd = DNS_HEADER_RD(abuf); ra = DNS_HEADER_RA(abuf); rcode = DNS_HEADER_RCODE(abuf); qdcount = DNS_HEADER_QDCOUNT(abuf); ancount = DNS_HEADER_ANCOUNT(abuf); nscount = DNS_HEADER_NSCOUNT(abuf); arcount = DNS_HEADER_ARCOUNT(abuf); aptr = abuf + HFIXEDSZ; ares_expand_name(aptr, abuf, alen, &query, &len); for (i = 0; i < qdcount; i++) { aptr = skip_question(aptr, abuf, alen); if (aptr == NULL) return; } dnstask->task->code = STATE_ERROR; switch (dnstask->role) { case DNS_TASK: for (i = 0; i < ancount; i++) { debug("try %d %d ", dnstask->task->LObjId, ancount); aptr = CheckPatternAfterParseAnswer(dnstask, aptr, abuf, alen); if (aptr == NULL) break; } dnstask->task->callback(dnstask->task); break; } }
static void cares_callback(void *arg, int status, unsigned char *abuf, int alen) { int i; unsigned int ancount, nscount, arcount; const unsigned char *aptr; #ifdef DEBUG printf("cares_callback: status=%i, alen=%i\n", status, alen); #endif if (status != ARES_SUCCESS) { if (verbose > 1) printf("ares failed: %s\n", ares_strerror(status)); return; } ancount = DNS_HEADER_ANCOUNT(abuf); nscount = DNS_HEADER_NSCOUNT(abuf); arcount = DNS_HEADER_ARCOUNT(abuf); #ifdef DEBUG printf("ancount: %i, nscount: %i, arcount: %i\n", ancount, nscount, arcount); #endif /* safety check */ if (alen < NS_HFIXEDSZ) return; aptr = abuf + NS_HFIXEDSZ; aptr = skip_query(aptr, abuf, alen); for (i = 0; i < ancount && caadr == 0; i++) { if (ca_tmpname == NULL) aptr = parse_rr(aptr, abuf, alen); else aptr = skip_rr(aptr, abuf, alen); } if (caadr == 0) { for (i = 0; i < nscount; i++) { aptr = skip_rr(aptr, abuf, alen); } for (i = 0; i < arcount && caadr == 0; i++) { aptr = parse_rr(aptr, abuf, alen); } } }
static void callback(void *arg, int status, int timeouts, unsigned char *abuf, int alen) { char *name = (char *) arg; int id, qr, opcode, aa, tc, rd, ra, rcode; unsigned int qdcount, ancount, nscount, arcount, i; const unsigned char *aptr; (void) timeouts; /* Display the query name if given. */ if (name) printf("Answer for query %s:\n", name); /* Display an error message if there was an error, but only stop if * we actually didn't get an answer buffer. */ if (status != ARES_SUCCESS) { printf("%s\n", ares_strerror(status)); if (!abuf) return; } /* Won't happen, but check anyway, for safety. */ if (alen < HFIXEDSZ) return; /* Parse the answer header. */ id = DNS_HEADER_QID(abuf); qr = DNS_HEADER_QR(abuf); opcode = DNS_HEADER_OPCODE(abuf); aa = DNS_HEADER_AA(abuf); tc = DNS_HEADER_TC(abuf); rd = DNS_HEADER_RD(abuf); ra = DNS_HEADER_RA(abuf); rcode = DNS_HEADER_RCODE(abuf); qdcount = DNS_HEADER_QDCOUNT(abuf); ancount = DNS_HEADER_ANCOUNT(abuf); nscount = DNS_HEADER_NSCOUNT(abuf); arcount = DNS_HEADER_ARCOUNT(abuf); /* Display the answer header. */ printf("id: %d\n", id); printf("flags: %s%s%s%s%s\n", qr ? "qr " : "", aa ? "aa " : "", tc ? "tc " : "", rd ? "rd " : "", ra ? "ra " : ""); printf("opcode: %d %s\n", opcode, opcodes[opcode]); printf("rcode: %d %s\n", rcode, rcodes[rcode]); printf("qdcount: %d\n", qdcount); printf("ancount: %d\n", ancount); printf("nscount: %d\n", nscount); printf("arcount: %d\n", arcount); /* Display the questions. */ printf("Questions:\n"); aptr = abuf + HFIXEDSZ; for (i = 0; i < qdcount; i++) { aptr = display_question(aptr, abuf, alen); if (aptr == NULL) return; } /* Display the answers. */ printf("Answers:\n"); for (i = 0; i < ancount; i++) { aptr = display_rr(aptr, abuf, alen); if (aptr == NULL) return; } /* Display the NS records. */ printf("NS records:\n"); for (i = 0; i < nscount; i++) { aptr = display_rr(aptr, abuf, alen); if (aptr == NULL) return; } /* Display the additional records. */ printf("Additional records:\n"); for (i = 0; i < arcount; i++) { aptr = display_rr(aptr, abuf, alen); if (aptr == NULL) return; } }
void LLQueryResponder::queryResult(const char *buf, size_t len) { const char *pos = buf; int qdcount = DNS_HEADER_QDCOUNT(pos); int ancount = DNS_HEADER_ANCOUNT(pos); int nscount = DNS_HEADER_NSCOUNT(pos); int arcount = DNS_HEADER_ARCOUNT(pos); int ret; if (qdcount == 0 || ancount + nscount + arcount == 0) { ret = ARES_ENODATA; goto bail; } pos += NS_HFIXEDSZ; for (int i = 0; i < qdcount; i++) { std::string ignore; size_t enclen; ret = LLAres::expandName(pos, buf, len, i == 0 ? mQuery : ignore, enclen); if (ret != ARES_SUCCESS) { goto bail; } pos += enclen; if (i == 0) { int t = DNS_QUESTION_TYPE(pos); switch (t) { case RES_A: case RES_NS: case RES_CNAME: case RES_PTR: case RES_AAAA: case RES_SRV: mType = (LLResType) t; break; default: LL_INFOS() << "Cannot grok query type " << t << LL_ENDL; ret = ARES_EBADQUERY; goto bail; } } pos += NS_QFIXEDSZ; if (pos > buf + len) { ret = ARES_EBADRESP; goto bail; } } ret = parseSection(buf, len, ancount, pos, mAnswers); if (ret != ARES_SUCCESS) { goto bail; } ret = parseSection(buf, len, nscount, pos, mAuthorities); if (ret != ARES_SUCCESS) { goto bail; } ret = parseSection(buf, len, arcount, pos, mAdditional); bail: mResult = ret; if (mResult == ARES_SUCCESS) { querySuccess(); } else { queryError(mResult); } }
void dns_detail_callback(void *arg, int status, int timeouts, unsigned char *abuf, int alen) { int id, qr, opcode, aa, tc, rd, ra, rcode; unsigned int qdcount, ancount, nscount, arcount, i; const unsigned char *aptr; dns_resp_t *response = (dns_resp_t *) arg; clearstrbuffer(response->msgbuf); response->msgstatus = status; /* * Display an error message if there was an error, but only stop if * we actually didn't get an answer buffer. */ switch (status) { case ARES_SUCCESS: break; case ARES_ENODATA: addtobuffer(response->msgbuf, "No data returned from server\n"); if (!abuf) return; break; case ARES_EFORMERR: addtobuffer(response->msgbuf, "Server could not understand query\n"); if (!abuf) return; break; case ARES_ESERVFAIL: addtobuffer(response->msgbuf, "Server failed\n"); if (!abuf) return; break; case ARES_ENOTFOUND: addtobuffer(response->msgbuf, "Name not found\n"); if (!abuf) return; break; case ARES_ENOTIMP: addtobuffer(response->msgbuf, "Not implemented\n"); if (!abuf) return; break; case ARES_EREFUSED: addtobuffer(response->msgbuf, "Server refused query\n"); if (!abuf) return; break; case ARES_EBADNAME: addtobuffer(response->msgbuf, "Invalid name in query\n"); if (!abuf) return; break; case ARES_ETIMEOUT: addtobuffer(response->msgbuf, "Timeout\n"); if (!abuf) return; break; case ARES_ECONNREFUSED: addtobuffer(response->msgbuf, "Server unavailable\n"); if (!abuf) return; break; case ARES_ENOMEM: addtobuffer(response->msgbuf, "Out of memory\n"); if (!abuf) return; break; case ARES_EDESTRUCTION: addtobuffer(response->msgbuf, "Timeout (channel destroyed)\n"); if (!abuf) return; break; default: addtobuffer(response->msgbuf, "Undocumented ARES return code\n"); if (!abuf) return; break; } /* Won't happen, but check anyway, for safety. */ if (alen < HFIXEDSZ) return; /* Parse the answer header. */ id = DNS_HEADER_QID(abuf); qr = DNS_HEADER_QR(abuf); opcode = DNS_HEADER_OPCODE(abuf); aa = DNS_HEADER_AA(abuf); tc = DNS_HEADER_TC(abuf); rd = DNS_HEADER_RD(abuf); ra = DNS_HEADER_RA(abuf); rcode = DNS_HEADER_RCODE(abuf); qdcount = DNS_HEADER_QDCOUNT(abuf); ancount = DNS_HEADER_ANCOUNT(abuf); nscount = DNS_HEADER_NSCOUNT(abuf); arcount = DNS_HEADER_ARCOUNT(abuf); /* Display the answer header. */ sprintf(msg, "id: %d\n", id); addtobuffer(response->msgbuf, msg); sprintf(msg, "flags: %s%s%s%s%s\n", qr ? "qr " : "", aa ? "aa " : "", tc ? "tc " : "", rd ? "rd " : "", ra ? "ra " : ""); addtobuffer(response->msgbuf, msg); sprintf(msg, "opcode: %s\n", opcodes[opcode]); addtobuffer(response->msgbuf, msg); sprintf(msg, "rcode: %s\n", rcodes[rcode]); addtobuffer(response->msgbuf, msg); /* Display the questions. */ addtobuffer(response->msgbuf, "Questions:\n"); aptr = abuf + HFIXEDSZ; for (i = 0; i < qdcount; i++) { aptr = display_question(aptr, abuf, alen, response); if (aptr == NULL) return; } /* Display the answers. */ addtobuffer(response->msgbuf, "Answers:\n"); for (i = 0; i < ancount; i++) { aptr = display_rr(aptr, abuf, alen, response); if (aptr == NULL) return; } /* Display the NS records. */ addtobuffer(response->msgbuf, "NS records:\n"); for (i = 0; i < nscount; i++) { aptr = display_rr(aptr, abuf, alen, response); if (aptr == NULL) return; } /* Display the additional records. */ addtobuffer(response->msgbuf, "Additional records:\n"); for (i = 0; i < arcount; i++) { aptr = display_rr(aptr, abuf, alen, response); if (aptr == NULL) return; } return; }
/* parse reply record */ int evdns_parse_reply(unsigned char *buf, int nbuf, HOSTENT *hostent) { unsigned char *p = NULL, *end = NULL, *s = NULL, *ps = NULL; int i = 0, qdcount = 0, ancount = 0, nscount = 0, arcount = 0, qr = 0, opcode = 0, aa = 0, tc = 0, rd = 0, ra = 0, rcode = 0, type = 0, dnsclass = 0, ttl = 0, rrlen = 0; if(buf && nbuf > HFIXEDSZ) { hostent->naddrs = 0; hostent->nalias = 0; p = buf; end = buf + nbuf; hostent->qid = DNS_HEADER_QID(p); qr = DNS_HEADER_QR(p); opcode = DNS_HEADER_OPCODE(p); aa = DNS_HEADER_AA(p); tc = DNS_HEADER_TC(p); rd = DNS_HEADER_RD(p); ra = DNS_HEADER_RA(p); rcode = DNS_HEADER_RCODE(p); qdcount = DNS_HEADER_QDCOUNT(p); ancount = DNS_HEADER_ANCOUNT(p); nscount = DNS_HEADER_NSCOUNT(p); arcount = DNS_HEADER_ARCOUNT(p); p += HFIXEDSZ; /* Display the answer header. */ /* printf("id: %d\n", id); printf("flags: %s%s%s%s%s\n", qr ? "qr " : "", aa ? "aa " : "", tc ? "tc " : "", rd ? "rd " : "", ra ? "ra " : ""); printf("opcode: %s\n", opcodes[opcode]); printf("rcode: %s\n", rcodes[rcode]); fprintf(stdout, "qdcount:%d\nancount:%d\nnscount:%d\narcount:%d\n", qdcount, ancount, nscount, arcount); */ /* parse question */ for(i = 0; i < qdcount; i++) { ps = (unsigned char *)hostent->name; p = evdns_expand_name(p, buf, end, ps); /* Parse the question type and class. */ type = DNS_QUESTION_TYPE(p); dnsclass = DNS_QUESTION_CLASS(p); p += QFIXEDSZ; /* fprintf(stdout, "qname:%-15s", name); fprintf(stdout, "\tqtype:%d", type); fprintf(stdout, "\tqclass:%d\r\n", dnsclass); */ } /* parse A name */ for(i = 0; i < ancount; i++) { ps = (unsigned char *)hostent->alias[hostent->nalias++]; p = evdns_expand_name(p, buf, end, ps); type = DNS_RR_TYPE(p); dnsclass = DNS_RR_CLASS(p); ttl = DNS_RR_TTL(p); rrlen = DNS_RR_LEN(p); p += RRFIXEDSZ; /* fprintf(stdout, "name:%s type:%d dnsclass:%d ttl:%d rrlen:%d ", name, type, dnsclass, ttl, rrlen); */ /* addr name */ if(type == TYPE_ANAME) { hostent->addrs[hostent->naddrs++] = *((int *)p); } /* Canonical name */ else if(type == TYPE_CNAME) { ps = (unsigned char *)hostent->alias[hostent->nalias++]; s = evdns_expand_name(p, buf, end, ps); //fprintf(stdout, "cname:%s ", cname); } /* pointer */ else if(type == TYPE_PTR) { ps = (unsigned char *)hostent->alias[hostent->nalias++]; s = evdns_expand_name(p, buf, end, ps); //fprintf(stdout, "pointer:%s ", cname); } //fprintf(stdout, "\r\n"); p += rrlen; } return 0; } return -1; }