/** Compare two test-vectors @param is The data as it is @param is_len The length of is @param should The data as it should @param should_len The length of should @param what The type of the data @param which The iteration count @return 0 on equality, -1 or 1 on difference */ int compare_testvector(const void* is, const unsigned long is_len, const void* should, const unsigned long should_len, const char* what, int which) { int res = 0; if(is_len != should_len) res = is_len > should_len ? -1 : 1; else res = XMEMCMP(is, should, is_len); #if defined(LTC_TEST) && defined(LTC_TEST_DBG) if (res != 0) { fprintf(stderr, "Testvector #%i of %s failed:\n", which, what); _print_hex("SHOULD", should, should_len); _print_hex("IS ", is, is_len); } #else LTC_UNUSED_PARAM(which); LTC_UNUSED_PARAM(what); #endif return res; }
int rfc5444_print_raw(struct autobuf *out, void *buffer, size_t length) { static uint8_t ZEROTAIL[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; uint8_t *ptr, *end; size_t idx, idx2, prefix_idx, i; uint8_t flags, head_len, tail_len, *head, *tail, num_addr; uint16_t msg_size, addr_length, mid_len; ptr = buffer; idx = 0; end = &ptr[length]; if (idx + 1 > length) { return -1; } abuf_puts(out, "\t,------------------\n"); abuf_puts(out, "\t| PACKET\n"); abuf_puts(out, "\t|------------------\n"); flags = ptr[0]; abuf_appendf(out, "\t| Packet version: %u\n", flags >> 4); abuf_appendf(out, "\t| Packet flags: 0x%02x\n", flags & 0x0f); idx++; if (flags & RFC5444_PKT_FLAG_SEQNO) { if (idx + 2 > length) { return -1; } abuf_appendf(out, "\t| Packet seq number: %u\n", (ptr[0] << 8) | ptr[1]); idx += 2; } if (flags & RFC5444_PKT_FLAG_TLV) { if (idx + 2 > length) { return -1; } if (_print_raw_tlvblock(out, "\t| | ", ptr, &idx, length)) { return -1; } } while (idx < length) { idx2 = idx; /* print messages */ if (idx2 + 4 > length) { return -1; } abuf_puts(out, "\t| ,-------------------\n"); abuf_puts(out, "\t| | MESSAGE\n"); abuf_puts(out, "\t| |-------------------\n"); abuf_appendf(out, "\t| | Message type: %u\n", ptr[idx]); flags = ptr[idx2 + 1]; abuf_appendf(out, "\t| | Message flags: 0x%02x\n", flags >> 4); addr_length = (flags & 15) + 1; abuf_appendf(out, "\t| | Address length: %u\n", addr_length); msg_size = (ptr[idx2 + 2] << 8) + ptr[idx + 3]; abuf_appendf(out, "\t| | Size: %u\n", msg_size); idx2 += 4; if (flags & RFC5444_MSG_FLAG_ORIGINATOR) { if (idx2 + addr_length > idx + msg_size) { return -1; } abuf_appendf(out, "\t| | Originator address: "); _print_hex(out, &ptr[idx2], addr_length, end); idx2 += addr_length; } if (flags & RFC5444_MSG_FLAG_HOPLIMIT) { if (idx2 + 1 > idx + msg_size) { return -1; } abuf_appendf(out, "\t| | Hop limit: %u\n", ptr[idx2]); idx2++; } if (flags & RFC5444_MSG_FLAG_HOPCOUNT) { if (idx2 + 1 > idx + msg_size) { return -1; } abuf_appendf(out, "\t| | Hop count: %u\n", ptr[idx2]); idx2++; } if (flags & RFC5444_MSG_FLAG_SEQNO) { if (idx2 + 2 > idx + msg_size) { return -1; } abuf_appendf(out, "\t| | Sequence Number: %u\n", (ptr[idx2] << 8) | ptr[idx2 + 1]); idx2 += 2; } if (_print_raw_tlvblock(out, "\t| | ", ptr, &idx2, msg_size)) { return -1; } while (idx2 < idx + msg_size) { /* print address blocks */ if (idx2 + 2 > idx + msg_size) { return -1; } abuf_puts(out, "\t| | ,-------------------\n"); abuf_puts(out, "\t| | | ADDRESS-BLOCK\n"); abuf_puts(out, "\t| | |-------------------\n"); num_addr = ptr[idx2]; abuf_appendf(out, "\t| | | Num-Addr: %u\n", num_addr); flags = ptr[idx2 + 1]; abuf_appendf(out, "\t| | | Flags: 0x%02x\n", flags); idx2 += 2; head_len = tail_len = 0; head = NULL; tail = NULL; if (flags & RFC5444_ADDR_FLAG_HEAD) { if (idx2 + 1 > idx + msg_size) { return -1; } head_len = ptr[idx2]; idx2++; if (idx2 + head_len > idx + msg_size) { return -1; } head = &ptr[idx2]; abuf_appendf(out, "\t| | | Head: "); _print_hex(out, head, head_len, end); abuf_puts(out, "\n"); idx2 += head_len; } if (flags & RFC5444_ADDR_FLAG_FULLTAIL) { if (idx2 + 1 > idx + msg_size) { return -1; } tail_len = ptr[idx2]; idx2++; if (idx2 + tail_len > idx + msg_size) { return -1; } tail = &ptr[idx2]; abuf_appendf(out, "\t| | | Tail: "); _print_hex(out, tail, tail_len, end); abuf_puts(out, "\n"); idx2 += tail_len; } if (flags & RFC5444_ADDR_FLAG_ZEROTAIL) { if (idx2 + 1 > idx + msg_size) { return -1; } tail_len = ptr[idx2]; tail = ZEROTAIL; abuf_appendf(out, "\t| | | ZeroTail: "); _print_hex(out, tail, tail_len, end); abuf_puts(out, "\n"); idx2++; } if (head_len + tail_len >= addr_length) { return -1; } mid_len = (addr_length - head_len - tail_len) * num_addr; if (idx2 + mid_len > idx + msg_size) { return -1; } prefix_idx = idx + mid_len; if (flags & RFC5444_ADDR_FLAG_SINGLEPLEN) { if (prefix_idx + 1 > idx + msg_size) { return -1; } } else if (flags & RFC5444_ADDR_FLAG_MULTIPLEN) { if (prefix_idx + num_addr > idx + msg_size) { return -1; } } else { prefix_idx = 0; } for (i = 0; i < num_addr; i++) { abuf_puts(out, "\t| | | ,-------------------\n"); abuf_puts(out, "\t| | | | Address\n"); abuf_puts(out, "\t| | | |-------------------\n"); abuf_appendf(out, "\t| | | | Address: "); if (head_len) { _print_hex(out, head, head_len, end); abuf_puts(out, " | "); } _print_hex(out, &ptr[idx2], addr_length - head_len - tail_len, end); idx2 += addr_length - head_len - tail_len; if (tail_len) { abuf_puts(out, " | "); _print_hex(out, tail, tail_len, end); } if (prefix_idx) { abuf_appendf(out, " / %u", ptr[prefix_idx]); } if (flags & RFC5444_ADDR_FLAG_MULTIPLEN) { prefix_idx++; } abuf_puts(out, "\n"); } if (_print_raw_tlvblock(out, "\t| | | ", ptr, &idx2, msg_size)) { return -1; } } if (idx + msg_size != idx2) { return -1; } idx = idx2; } return 0; }