int label_compare(const uint8_t *left, const uint8_t *right) { int left_length; int right_length; size_t size; int result; assert(left); assert(right); assert(label_is_normal(left)); assert(label_is_normal(right)); left_length = label_length(left); right_length = label_length(right); size = left_length < right_length ? left_length : right_length; result = memcmp(label_data(left), label_data(right), size); if (result) { return result; } else { return (int) left_length - (int) right_length; } }
/** * Length of label. * */ uint8_t label_length(const uint8_t* label) { assert(label); assert(label_is_normal(label)); return label[0]; }
/** * Get the next label. * */ const uint8_t* label_next(const uint8_t* label) { assert(label); assert(label_is_normal(label)); assert(!label_is_root(label)); return label + label_length(label) + 1; }
int dname_make_wire_from_packet(uint8_t *buf, buffer_type *packet, int allow_pointers) { int done = 0; uint8_t visited[(MAX_PACKET_SIZE+7)/8]; size_t dname_length = 0; const uint8_t *label; ssize_t mark = -1; memset(visited, 0, (buffer_limit(packet)+7)/8); while (!done) { if (!buffer_available(packet, 1)) { /* error("dname out of bounds"); */ return 0; } if (get_bit(visited, buffer_position(packet))) { /* error("dname loops"); */ return 0; } set_bit(visited, buffer_position(packet)); label = buffer_current(packet); if (label_is_pointer(label)) { size_t pointer; if (!allow_pointers) { return 0; } if (!buffer_available(packet, 2)) { /* error("dname pointer out of bounds"); */ return 0; } pointer = label_pointer_location(label); if (pointer >= buffer_limit(packet)) { /* error("dname pointer points outside packet"); */ return 0; } buffer_skip(packet, 2); if (mark == -1) { mark = buffer_position(packet); } buffer_set_position(packet, pointer); } else if (label_is_normal(label)) { size_t length = label_length(label) + 1; done = label_is_root(label); if (!buffer_available(packet, length)) { /* error("dname label out of bounds"); */ return 0; } if (dname_length + length >= MAXDOMAINLEN+1) { /* error("dname too large"); */ return 0; } buffer_read(packet, buf + dname_length, length); dname_length += length; } else { /* error("bad label type"); */ return 0; } } if (mark != -1) { buffer_set_position(packet, mark); } return dname_length; }