/** Return 1 on success, 0 on failure. */ int _rrparse(struct message *m, struct resource *rr, int count, unsigned char **bufp) { int i; for(i=0; i < count; i++) { _label(m, bufp, &(rr[i].name)); rr[i].type = net2short(bufp); rr[i].rr_class = net2short(bufp); rr[i].ttl = net2long(bufp); rr[i].rdlength = net2short(bufp); // if not going to overflow, make copy of source rdata if(rr[i].rdlength + (*bufp - m->_buf) > MAX_PACKET_LEN || m->_len + rr[i].rdlength > MAX_PACKET_LEN) return 0; rr[i].rdata = m->_packet + m->_len; m->_len += rr[i].rdlength; memcpy(rr[i].rdata,*bufp,rr[i].rdlength); // parse commonly known ones switch(rr[i].type) { case 1: if(m->_len + 16 > MAX_PACKET_LEN) return 0; rr[i].known.a.name = m->_packet + m->_len; m->_len += 16; sprintf(rr[i].known.a.name,"%d.%d.%d.%d",(*bufp)[0],(*bufp)[1],(*bufp)[2],(*bufp)[3]); rr[i].known.a.ip = net2long(bufp); break; case 2: _label(m, bufp, &(rr[i].known.ns.name)); break; case 5: _label(m, bufp, &(rr[i].known.cname.name)); break; case 12: _label(m, bufp, &(rr[i].known.ptr.name)); break; case 33: rr[i].known.srv.priority = net2short(bufp); rr[i].known.srv.weight = net2short(bufp); rr[i].known.srv.port = net2short(bufp); _label(m, bufp, &(rr[i].known.srv.name)); break; default: *bufp += rr[i].rdlength; } } return 1; }
static int process_rrsection(jdns_list_t *dest, int count, const unsigned char *data, int size, const unsigned char **bufp) { int n; int offset, at; jdns_string_t *name = 0; const unsigned char *buf; buf = *bufp; for(n = 0; n < count; ++n) { jdns_packet_resource_t *r; offset = buf - data; at = 0; if(!readlabel(data + offset, size - offset, data, size, &at, &name)) goto error; offset += at; // need 10 more bytes if(offset + 10 > size) goto error; buf = data + offset; r = jdns_packet_resource_new(); r->qname = name; name = 0; r->qtype = net2short(&buf); r->qclass = net2short(&buf); r->ttl = net2long(&buf); r->rdlength = net2short(&buf); offset = buf - data; // make sure we have enough for the rdata if(size - offset < r->rdlength) { jdns_packet_resource_delete(r); goto error; } r->rdata = jdns_copy_array(buf, r->rdlength); buf += r->rdlength; jdns_list_insert_value(dest, r, -1); jdns_packet_resource_delete(r); } *bufp = buf; return 1; error: jdns_string_delete(name); return 0; }