void jdns_packet_resource_add_bytes(jdns_packet_resource_t *a, const unsigned char *data, int size) { jdns_packet_write_t *write = jdns_packet_write_new(); write->type = JDNS_PACKET_WRITE_RAW; write->value = jdns_string_new(); jdns_string_set(write->value, data, size); jdns_list_insert_value(a->writelog, write, -1); jdns_packet_write_delete(write); }
static jdns_string_t *file_nextline(FILE *f) { int at, size; unsigned char *buf; jdns_string_t *str; size = 1023; buf = (unsigned char *)jdns_alloc(size); at = 0; while(1) { unsigned char c = (unsigned char)fgetc(f); // cast is intentional if(feof(f)) // checking EOF here { if(at > 0) { // if we read at least one char, take it as a // line break; } else { jdns_free(buf); return 0; } } if(c == '\n') break; if(c == '\r') continue; if(at < 1023) buf[at++] = c; } str = jdns_string_new(); jdns_string_set(str, buf, at); jdns_free(buf); return str; }
static jdns_string_t *string_simplify(const jdns_string_t *in) { int n; int pos; int total; unsigned char *out; int outlen; jdns_string_t *outstr; jdns_stringlist_t *wordlist; // gather words and total of lengths pos = 0; total = 0; wordlist = jdns_stringlist_new(); while(1) { jdns_string_t *word; unsigned char *str = string_getnextword(in->data, in->size, pos, &pos); if(!str) break; word = jdns_string_new(); jdns_string_set_cstr(word, (char *)str); jdns_free(str); jdns_stringlist_append(wordlist, word); total += word->size; jdns_string_delete(word); } if(total == 0) { jdns_stringlist_delete(wordlist); outstr = jdns_string_new(); jdns_string_set_cstr(outstr, ""); return outstr; } // we need to allocate space for total lengths and wordcount-1 spaces outlen = total + (wordlist->count - 1); out = (unsigned char *)jdns_alloc(outlen); // lay out the words pos = 0; for(n = 0; n < wordlist->count; ++n) { unsigned char *data = wordlist->item[n]->data; int size = wordlist->item[n]->size; memcpy(out + pos, data, size); pos += size; // if this is not the last word, append a space if(n + 1 < wordlist->count) out[pos++] = ' '; } jdns_stringlist_delete(wordlist); outstr = jdns_string_new(); jdns_string_set(outstr, out, outlen); jdns_free(out); return outstr; }
// 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; }
static int readlabel(const unsigned char *in, int insize, const unsigned char *ref, int refsize, int *_at, jdns_string_t **name) { int at; // string format is one character smaller than dns format. e.g.: // dns: [7] affinix [3] com [0] = 13 bytes // string: "affinix.com." = 12 bytes // only exception is '.' itself, but that won't influence the max. unsigned char out[MAX_LABEL_LENGTH - 1]; int out_size; const unsigned char *label, *last; int hopped_yet; int hopsleft; int label_size; at = *_at; // stay in range if(at < 0 || at >= insize) return 0; out_size = 0; label = in + at; hopped_yet = 0; last = in + insize; while(1) { // need a byte if(label + 1 > last) goto error; // we make this a while loop instead of an 'if', in case // there's a pointer to a pointer. as a precaution, // we will hop no more than 8 times hopsleft = 8; while(*label & 0xc0) { int offset; // need the next byte, too if(label + 2 > last) goto error; offset = getoffset(label, refsize, &hopsleft); if(offset == -1) goto error; label = ref + offset; if(!hopped_yet) { at += 2; hopped_yet = 1; last = ref + refsize; } // need a byte if(label + 1 > last) goto error; } label_size = *label & 0x3f; // null label? then we're done if(label_size == 0) { if(!hopped_yet) ++at; break; } // enough source bytes? (length byte + length) if(label + label_size + 1 > last) goto error; // enough dest bytes? (length + dot) if(out_size + label_size + 1 > MAX_LABEL_LENGTH - 1) goto error; memcpy(out + out_size, label + 1, label_size); out_size += label_size; out[out_size] = '.'; ++out_size; if(!hopped_yet) at += label_size + 1; label += label_size + 1; } *_at = at; *name = jdns_string_new(); jdns_string_set(*name, out, out_size); return 1; error: return 0; }
static int readlabel(const unsigned char *in, int insize, const unsigned char *ref, int refsize, int *_at, jdns_string_t **name) { int at; unsigned char out[255]; int out_size; const unsigned char *label, *last; int hopped_yet; int hopsleft; int label_size; at = *_at; // stay in range if(at < 0 || at >= insize) return 0; out_size = 0; label = in + at; hopped_yet = 0; last = in + insize; while(1) { // need a byte if(label + 1 > last) goto error; // we make this a while loop instead of an 'if', in case // there's a pointer to a pointer. as a precaution, // we will hop no more than 8 times hopsleft = 8; while(*label & 0xc0) { int offset; // need the next byte, too if(label + 2 > last) goto error; offset = getoffset(label, refsize, &hopsleft); if(offset == -1) goto error; label = ref + offset; if(!hopped_yet) { at += 2; hopped_yet = 1; last = ref + refsize; } // need a byte if(label + 1 > last) goto error; } label_size = *label & 0x3f; // null label? then we're done if(label_size == 0) { if(!hopped_yet) ++at; break; } // enough source bytes? (length byte + length) if(label + label_size + 1 > last) goto error; // enough dest bytes? (length + dot) if(out_size + label_size + 1 > 255) goto error; memcpy(out + out_size, label + 1, label_size); out_size += label_size; out[out_size] = '.'; ++out_size; if(!hopped_yet) at += label_size + 1; label += label_size + 1; } *_at = at; *name = jdns_string_new(); jdns_string_set(*name, out, out_size); return 1; error: return 0; }