Exemple #1
0
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;

    }


}
Exemple #2
0
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);
		}
	}
}
Exemple #3
0
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;
    }
}
Exemple #4
0
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);
	}
}
Exemple #5
0
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;
}
Exemple #6
0
/* 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;
}