Example #1
0
static int
dns_parse_a(dnscc_t *qdn, dnscc_t *pkt, dnscc_t *cur, dnscc_t *end,
            void **result, unsigned dsize) {
  struct dns_rr_a *ret;
  struct dns_parse p;
  struct dns_rr rr;
  int r;

  /* first, validate and count number of addresses */
  dns_initparse(&p, qdn, pkt, cur, end);
  while((r = dns_nextrr(&p, &rr)) > 0)
    if (rr.dnsrr_dsz != dsize)
      return DNS_E_PROTOCOL;
  if (r < 0)
    return DNS_E_PROTOCOL;
  else if (!p.dnsp_nrr)
    return DNS_E_NODATA;

  ret = malloc(sizeof(*ret) + dsize * p.dnsp_nrr + dns_stdrr_size(&p));
  if (!ret)
    return DNS_E_NOMEM;

  ret->dnsa_nrr = p.dnsp_nrr;
  ret->dnsa_addr = (unsigned char*)(ret+1);

  /* copy the RRs */
  for (dns_rewind(&p, qdn), r = 0; dns_nextrr(&p, &rr); ++r)
    memcpy(ret->dnsa_addr + dsize * r, rr.dnsrr_dptr, dsize);

  dns_stdrr_finish((struct dns_rr_null *)ret,
                   (char *)(ret->dnsa_addr + dsize * p.dnsp_nrr), &p);
  *result = ret;
  return 0;
}
Example #2
0
int
dns_parse_srv(dnscc_t *qdn, dnscc_t *pkt, dnscc_t *cur, dnscc_t *end,
              void **result) {
  struct dns_rr_srv *ret;
  struct dns_parse p;
  struct dns_rr rr;
  int r, l;
  char *sp;
  dnsc_t srv[DNS_MAXDN];

  assert(dns_get16(cur+2) == DNS_C_IN && dns_get16(cur+0) == DNS_T_SRV);

  /* first, validate the answer and count size of the result */
  l = 0;
  dns_initparse(&p, qdn, pkt, cur, end);
  while((r = dns_nextrr(&p, &rr)) > 0) {
    cur = rr.dnsrr_dptr + 6;
    r = dns_getdn(pkt, &cur, end, srv, sizeof(srv));
    if (r <= 0 || cur != rr.dnsrr_dend)
      return DNS_E_PROTOCOL;
    l += dns_dntop_size(srv);
  }
  if (r < 0)
    return DNS_E_PROTOCOL;
  if (!p.dnsp_nrr)
    return DNS_E_NODATA;

  /* next, allocate and set up result */
  l += dns_stdrr_size(&p);
  ret = malloc(sizeof(*ret) + sizeof(struct dns_srv) * p.dnsp_nrr + l);
  if (!ret)
    return DNS_E_NOMEM;
  ret->dnssrv_nrr = p.dnsp_nrr;
  ret->dnssrv_srv = (struct dns_srv *)(ret+1);

  /* and 3rd, fill in result, finally */
  sp = (char*)(ret->dnssrv_srv + p.dnsp_nrr);
  for (dns_rewind(&p, qdn), r = 0; dns_nextrr(&p, &rr); ++r) {
    ret->dnssrv_srv[r].name = sp;
    cur = rr.dnsrr_dptr;
    ret->dnssrv_srv[r].priority = dns_get16(cur);
    ret->dnssrv_srv[r].weight = dns_get16(cur+2);
    ret->dnssrv_srv[r].port = dns_get16(cur+4);
    cur += 6;
    dns_getdn(pkt, &cur, end, srv, sizeof(srv));
    sp += dns_dntop(srv, sp, DNS_MAXNAME);
  }
  dns_stdrr_finish((struct dns_rr_null *)ret, sp, &p);
  *result = ret;
  return 0;
}