static int dns_q_format(struct dns_q *query, char *buff, size_t buff_sz) { int ret; size_t bytes_left, field_sz; uint16_t field_val; bytes_left = buff_sz; ret = name_to_label(&query->qname[0], buff, buff_sz); field_sz = (strlen(&query->qname[0]) + 2) * sizeof(uint8_t); if (ret != 0) { return ret; } bytes_left -= field_sz; buff += field_sz; field_sz = sizeof query->qtype; if (field_sz > bytes_left) { return -ENOMEM; } field_val = htons(query->qtype); memcpy(buff, &field_val, sizeof field_sz); bytes_left -= field_sz; buff += field_sz; field_sz = sizeof query->qclass; if (field_sz > bytes_left) { return -ENOMEM; } field_val = htons(query->qclass); memcpy(buff, &field_val, sizeof field_sz); return 0; }
// lookup list is made of jdns_packet_labels static int writelabel(const jdns_string_t *name, int at, int left, unsigned char **bufp, jdns_list_t *lookup) { unsigned char label[MAX_LABEL_LENGTH]; int n, i, len; unsigned char *l; unsigned char *ref; int refsize; len = name_to_label(name, label); if(len == -1) return 0; ref = *bufp - at; refsize = at + left; for(n = 0; label[n]; n += label[n] + 1) { for(i = 0; i < lookup->count; ++i) { jdns_packet_label_t *pl = (jdns_packet_label_t *)lookup->item[i]; if(matchlabel(label + n, len - n, pl->value->data, pl->value->size, ref, refsize, 8, 8)) { // set up a pointer right here, overwriting // the length byte and the first content // byte of this section within 'label'. // this is safe, because the length value // will always be greater than zero, // ensuring we have two bytes available to // use. l = label + n; short2net((unsigned short int)pl->offset, &l); label[n] |= 0xc0; len = n + 2; // cut things short break; } } if(label[n] & 0xc0) // double loop, so break again break; } if(left < len) return 0; // copy into buffer, point there now memcpy(*bufp, label, len); l = *bufp; *bufp += len; // for each new label, store its location for future compression for(n = 0; l[n]; n += l[n] + 1) { jdns_string_t *str; jdns_packet_label_t *pl; if(l[n] & 0xc0) break; pl = jdns_packet_label_new(); str = jdns_string_new(); jdns_string_set(str, l + n, len - n); pl->offset = l + n - ref; pl->value = str; jdns_list_insert(lookup, pl, -1); } return 1; }