diff --git a/send.c b/send.c index fecdf46..ad54bdf 100644 --- a/send.c +++ b/send.c @@ -217,12 +217,7 @@ static void add_ra_header(struct safe_buffer *sb, struct ra_header_info const *r /* Mobile IPv6 ext */ radvert.nd_ra_flags_reserved |= (ra_header_info->AdvHomeAgentFlag) ? ND_RA_FLAG_HOME_AGENT : 0; - if (cease_adv) { - radvert.nd_ra_router_lifetime = 0; - } else { - /* if forwarding is disabled, send zero router lifetime */ - radvert.nd_ra_router_lifetime = !check_ip6_forwarding() ? htons(ra_header_info->AdvDefaultLifetime) : 0; - } + radvert.nd_ra_router_lifetime = cease_adv ? 0 : htons(ra_header_info->AdvDefaultLifetime); radvert.nd_ra_flags_reserved |= (ra_header_info->AdvDefaultPreference << ND_OPT_RI_PRF_SHIFT) & ND_OPT_RI_PRF_MASK; radvert.nd_ra_reachable = htonl(ra_header_info->AdvReachableTime); @@ -888,7 +883,10 @@ static int send_ra(int sock, struct Interface *iface, struct in6_addr const *des // Build RA header struct safe_buffer *ra_hdr = new_safe_buffer(); - add_ra_header(ra_hdr, &iface->ra_header_info, iface->state_info.cease_adv); + // if forwarding is disabled, send zero router lifetime + // the check_ip6 function is hoisted here to enable testing of add_ra_header + int cease_adv = iface->state_info.cease_adv || !check_ip6_forwarding(); + add_ra_header(ra_hdr, &iface->ra_header_info, cease_adv); // Build RA option list struct safe_buffer_list *ra_opts = build_ra_options(iface, dest); diff --git a/test/print_safe_buffer.c b/test/print_safe_buffer.c index 55988c8..a9d62b7 100644 --- a/test/print_safe_buffer.c +++ b/test/print_safe_buffer.c @@ -16,8 +16,7 @@ size_t snprint_safe_buffer(char *s, size_t size, struct safe_buffer const *sb) { size_t count = 0; - count += snprintf((s + count), (size - count), "unsigned char expected[] = {"); - count--; + count += snprintf((s + count), (size - count), "unsigned char expected[] = { /* sb.allocated = %ld, sb.used = %ld */", sb->allocated, sb->used); for (size_t i = 0; i < sb->used; ++i) { if (i % 8 == 0) { @@ -25,8 +24,9 @@ size_t snprint_safe_buffer(char *s, size_t size, struct safe_buffer const *sb) } else { count += snprintf((s + count), (size - count), " 0x%02x,", sb->buffer[i]); } - count--; } + /* Do not remove the final byte's comma. Only JSON requires the comma is + * removed, and this is not JSON. */ count += snprintf((s + count), (size - count), "\n};\n"); return count; diff --git a/test/send.c b/test/send.c index 1241a9f..7eaf81d 100644 --- a/test/send.c +++ b/test/send.c @@ -34,11 +34,50 @@ static void iface_teardown(void) iface = 0; } -START_TEST(test_add_ra_header) +START_TEST(test_add_ra_header_cease_adv0) { struct safe_buffer sb = SAFE_BUFFER_INIT; - add_ra_header(&sb, &iface->ra_header_info, iface->state_info.cease_adv); + add_ra_header(&sb, &iface->ra_header_info, 0); + +#ifdef PRINT_SAFE_BUFFER + char buf[4096]; + snprint_safe_buffer(buf, 4096, &sb); + ck_assert_msg(0, "\n// ra_header_info->AdvDefaultLifetime = %x\n%s", iface->ra_header_info.AdvDefaultLifetime, &buf); +#else + // Lifetime should be -1/ffff in this case, because we have not set it to anything else. + // interface.c:40:iface->ra_header_info.AdvDefaultLifetime = -1; + unsigned char expected[] = { + // nd_ra_type + // nd_ra_code + 0x86, 0x00, + // nd_ra_cksum + 0x00, 0x00, + // nd_ra_curhoplimit + 0x40, + // nd_ra_flags_reserved + 0x00, + // nd_ra_router_lifetime + 0xff, 0xff, + // nd_ra_reachable + 0x00, 0x00, 0x00, 0x00, + // nd_ra_retransmit + 0x00, 0x00, 0x00, 0x00, + }; + + ck_assert_int_eq(sizeof(expected), sb.used); + ck_assert_int_eq(0, memcmp(expected, sb.buffer, sb.used)); +#endif + + safe_buffer_free(&sb); +} +END_TEST + +START_TEST(test_add_ra_header_cease_adv1) +{ + + struct safe_buffer sb = SAFE_BUFFER_INIT; + add_ra_header(&sb, &iface->ra_header_info, 1); #ifdef PRINT_SAFE_BUFFER char buf[4096]; @@ -46,7 +85,21 @@ START_TEST(test_add_ra_header) ck_assert_msg(0, "\n%s", &buf); #else unsigned char expected[] = { - 0x86, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // nd_ra_type + // nd_ra_code + 0x86, 0x00, + // nd_ra_cksum + 0x00, 0x00, + // nd_ra_curhoplimit + 0x40, + // nd_ra_flags_reserved + 0x00, + // nd_ra_router_lifetime + 0x00, 0x00, + // nd_ra_reachable + 0x00, 0x00, 0x00, 0x00, + // nd_ra_retransmit + 0x00, 0x00, 0x00, 0x00, }; ck_assert_int_eq(sizeof(expected), sb.used); @@ -75,12 +128,12 @@ START_TEST(test_add_ra_options_prefix) ck_assert_msg(0, "\n%s", &buf); #else unsigned char expected[] = { - 0x03, 0x04, 0x40, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, - 0xfe, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x04, 0x30, 0x80, 0x00, 0x00, 0x27, 0x10, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x00, 0x00, - 0xfe, 0x80, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x04, 0x40, 0xc0, 0x00, 0x01, 0x51, 0x80, 0x00, 0x00, 0x38, 0x40, 0x00, 0x00, 0x00, 0x00, - 0xfe, 0x80, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x04, 0x40, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0xfe, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x04, 0x30, 0x80, 0x00, 0x00, 0x27, 0x10, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x00, 0x00, + 0xfe, 0x80, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x04, 0x40, 0xc0, 0x00, 0x01, 0x51, 0x80, 0x00, 0x00, 0x38, 0x40, 0x00, 0x00, 0x00, 0x00, + 0xfe, 0x80, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; ck_assert_int_eq(sizeof(expected), sb.used); @@ -109,10 +162,10 @@ START_TEST(test_add_ra_options_route) ck_assert_msg(0, "\n%s", &buf); #else unsigned char expected[] = { - 0x18, 0x03, 0x30, 0x18, 0x00, 0x00, 0x27, 0x10, 0xfe, 0x80, 0x00, 0x0f, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x03, 0x28, 0x08, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x80, 0x00, 0x0f, - 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x03, 0x20, 0x00, 0x00, 0x00, - 0x0b, 0xb8, 0xfe, 0x80, 0x00, 0x0f, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x03, 0x30, 0x18, 0x00, 0x00, 0x27, 0x10, 0xfe, 0x80, 0x00, 0x0f, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x03, 0x28, 0x08, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x80, 0x00, 0x0f, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x03, 0x20, 0x00, 0x00, 0x00, + 0x0b, 0xb8, 0xfe, 0x80, 0x00, 0x0f, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; ck_assert_int_eq(sizeof(expected), sb.used); @@ -140,9 +193,9 @@ START_TEST(test_add_ra_options_rdnss) ck_assert_msg(0, "\n%s", &buf); #else unsigned char expected[] = { - 0x19, 0x07, 0x00, 0x00, 0x00, 0x00, 0x04, 0xd2, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x02, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + 0x19, 0x07, 0x00, 0x00, 0x00, 0x00, 0x04, 0xd2, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, }; ck_assert_int_eq(sizeof(expected), sb.used); @@ -174,8 +227,8 @@ START_TEST(test_add_ra_options_rdnss2) ck_assert_msg(0, "\n%s", &buf); #else unsigned char expected[] = { - 0x19, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x12, 0x34, 0x04, 0x23, - 0xfe, 0xfe, 0x04, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x19, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x12, 0x34, 0x04, 0x23, + 0xfe, 0xfe, 0x04, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, }; ck_assert_int_eq(sizeof(expected), sb.used); @@ -204,17 +257,17 @@ START_TEST(test_add_ra_options_dnssl) ck_assert_msg(0, "\n%s", &buf); #else unsigned char expected[] = { - 0x1f, 0x09, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe8, 0x06, 0x6f, 0x66, 0x66, 0x69, 0x63, 0x65, 0x06, 0x62, 0x72, 0x61, - 0x6e, 0x63, 0x68, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x06, 0x62, 0x72, - 0x61, 0x6e, 0x63, 0x68, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x07, 0x65, - 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x09, 0x00, 0x00, - 0x00, 0x00, 0x04, 0x4b, 0x06, 0x6f, 0x66, 0x66, 0x69, 0x63, 0x65, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x07, - 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, 0x6e, 0x65, 0x74, 0x00, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, - 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, 0x6e, 0x65, 0x74, 0x00, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, - 0x6c, 0x65, 0x03, 0x6e, 0x65, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x04, 0x4c, - 0x06, 0x6f, 0x66, 0x66, 0x69, 0x63, 0x65, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x07, 0x65, 0x78, 0x61, 0x6d, - 0x70, 0x6c, 0x65, 0x00, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, - 0x00, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x00, + 0x1f, 0x09, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe8, 0x06, 0x6f, 0x66, 0x66, 0x69, 0x63, 0x65, 0x06, 0x62, 0x72, 0x61, + 0x6e, 0x63, 0x68, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x06, 0x62, 0x72, + 0x61, 0x6e, 0x63, 0x68, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x07, 0x65, + 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x4b, 0x06, 0x6f, 0x66, 0x66, 0x69, 0x63, 0x65, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x07, + 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, 0x6e, 0x65, 0x74, 0x00, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, + 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x03, 0x6e, 0x65, 0x74, 0x00, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, + 0x6c, 0x65, 0x03, 0x6e, 0x65, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x04, 0x4c, + 0x06, 0x6f, 0x66, 0x66, 0x69, 0x63, 0x65, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x07, 0x65, 0x78, 0x61, 0x6d, + 0x70, 0x6c, 0x65, 0x00, 0x06, 0x62, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, + 0x00, 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x00, }; ck_assert_int_eq(sizeof(expected), sb.used); @@ -238,7 +291,7 @@ START_TEST(test_add_ra_option_mtu) ck_assert_msg(0, "\n%s", &buf); #else unsigned char expected[] = { - 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0xd2, + 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0xd2, }; ck_assert_int_eq(sb.used, sizeof(expected)); @@ -252,7 +305,7 @@ END_TEST START_TEST(test_add_ra_option_sllao) { struct sllao sllao48 = { - {1, 2, 3, 4, 5, 6, 7, 8}, 48, 64, 1500, + {1, 2, 3, 4, 5, 6, 7, 8}, 48, 64, 1500, }; struct safe_buffer sb = SAFE_BUFFER_INIT; @@ -264,7 +317,7 @@ START_TEST(test_add_ra_option_sllao) ck_assert_msg(0, "\n%s", &buf); #else unsigned char expected48[] = { - 0x01, 0x01, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x01, 0x01, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, }; ck_assert_int_eq(sizeof(expected48), sb.used); @@ -274,7 +327,7 @@ START_TEST(test_add_ra_option_sllao) safe_buffer_free(&sb); struct sllao sllao64 = { - {1, 2, 3, 4, 5, 6, 7, 8}, 64, 64, 1500, + {1, 2, 3, 4, 5, 6, 7, 8}, 64, 64, 1500, }; sb = SAFE_BUFFER_INIT; @@ -285,7 +338,7 @@ START_TEST(test_add_ra_option_sllao) ck_assert_msg(0, "\n%s", &buf); #else unsigned char expected64[] = { - 0x01, 0x02, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x02, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; ck_assert_int_eq(sizeof(expected64), sb.used); @@ -309,8 +362,8 @@ START_TEST(test_add_ra_option_lowpanco) ck_assert_msg(0, "\n%s", &buf); #else unsigned char expected[] = { - 0x22, 0x03, 0x32, 0x14, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x22, 0x03, 0x32, 0x14, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; ck_assert_int_eq(sb.used, sizeof(expected)); ck_assert_int_eq(0, memcmp(expected, sb.buffer, sizeof(expected))); @@ -333,8 +386,8 @@ START_TEST(test_add_ra_option_abro) ck_assert_msg(0, "\n%s", &buf); #else unsigned char expected[] = { - 0x23, 0x03, 0x00, 0x0a, 0x00, 0x02, 0x00, 0x02, 0xfe, 0x80, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x23, 0x03, 0x00, 0x0a, 0x00, 0x02, 0x00, 0x02, 0xfe, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, }; ck_assert_int_eq(sb.used, sizeof(expected)); @@ -352,7 +405,8 @@ Suite *send_suite(void) TCase *tc_build = tcase_create("build"); tcase_add_unchecked_fixture(tc_build, iface_setup, iface_teardown); - tcase_add_test(tc_build, test_add_ra_header); + tcase_add_test(tc_build, test_add_ra_header_cease_adv0); + tcase_add_test(tc_build, test_add_ra_header_cease_adv1); tcase_add_test(tc_build, test_add_ra_options_prefix); tcase_add_test(tc_build, test_add_ra_options_route); tcase_add_test(tc_build, test_add_ra_options_rdnss);