| /* SPDX-License-Identifier: LGPL-2.1-only */ |
| /* |
| * Copyright (c) 2013 Thomas Graf <[email protected]> |
| */ |
| |
| #include "nl-default.h" |
| |
| #include <check.h> |
| #include <netlink/addr.h> |
| #include <netlink/route/addr.h> |
| |
| #include "cksuite-all.h" |
| |
| START_TEST(addr_alloc) |
| { |
| struct nl_addr *addr; |
| |
| addr = nl_addr_alloc(16); |
| ck_assert_msg(addr, "Allocation should not return NULL"); |
| |
| ck_assert_msg(nl_addr_iszero(addr) != 0, |
| "New empty address should be all zeros"); |
| |
| ck_assert_msg(nl_addr_get_family(addr) == AF_UNSPEC, |
| "New empty address should have family AF_UNSPEC"); |
| |
| ck_assert_msg(nl_addr_get_prefixlen(addr) == 0, |
| "New empty address should have prefix length 0"); |
| |
| ck_assert_msg(!nl_addr_shared(addr), |
| "New empty address should not be shared"); |
| |
| ck_assert_msg(nl_addr_get(addr) == addr, |
| "nl_addr_get() should return pointer to address"); |
| |
| ck_assert_msg(nl_addr_shared(addr) != 0, |
| "Address should be shared after call to nl_addr_get()"); |
| |
| nl_addr_put(addr); |
| |
| ck_assert_msg( |
| !nl_addr_shared(addr), |
| "Address should not be shared after call to nl_addr_put()"); |
| |
| ck_assert_msg(nl_addr_fill_sockaddr(addr, NULL, 0) != 0, |
| "Socket address filling should fail for empty address"); |
| |
| nl_addr_put(addr); |
| } |
| END_TEST |
| |
| START_TEST(addr_binary_addr) |
| { |
| struct nl_addr *addr, *addr2; |
| char baddr[4] = { 0x1, 0x2, 0x3, 0x4 }; |
| char baddr2[6] = { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 }; |
| |
| addr = nl_addr_alloc(4); |
| ck_assert_msg(addr != NULL, "Allocation should not return NULL"); |
| |
| ck_assert_msg(nl_addr_set_binary_addr(addr, baddr, 4) >= 0, |
| "Valid binary address should be settable"); |
| |
| ck_assert_msg( |
| nl_addr_get_prefixlen(addr) == 0, |
| "Prefix length should be unchanged after nl_addr_set_binary_addr()"); |
| |
| ck_assert_msg(nl_addr_get_len(addr) == 4, "Address length should be 4"); |
| |
| ck_assert_msg( |
| nl_addr_set_binary_addr(addr, baddr2, 6) != 0, |
| "Should not be able to set binary address exceeding maximum length"); |
| |
| ck_assert_msg(nl_addr_get_len(addr) == 4, |
| "Address length should still be 4"); |
| |
| ck_assert_msg( |
| nl_addr_guess_family(addr) == AF_INET, |
| "Binary address of length 4 should be guessed as AF_INET"); |
| |
| ck_assert_msg(memcmp(baddr, nl_addr_get_binary_addr(addr), 4) == 0, |
| "Binary address mismatches"); |
| |
| addr2 = nl_addr_build(AF_UNSPEC, baddr, 4); |
| ck_assert_msg(addr2 != NULL, "Building of address should not fail"); |
| |
| nl_addr_set_prefixlen(addr, 32); |
| ck_assert_msg( |
| nl_addr_get_prefixlen(addr) == 32, |
| "Prefix length should be successful changed after nl_addr_set_prefixlen()"); |
| |
| ck_assert_msg(!nl_addr_cmp(addr, addr2), |
| "Addresses built from same binary address should match"); |
| |
| nl_addr_put(addr); |
| nl_addr_put(addr2); |
| } |
| END_TEST |
| |
| START_TEST(addr_parse4) |
| { |
| struct nl_addr *addr4, *clone; |
| struct sockaddr_in sin; |
| socklen_t len = sizeof(sin); |
| char *addr_str = "10.0.0.1/16"; |
| char buf[128]; |
| |
| ck_assert_msg(nl_addr_parse(addr_str, AF_INET6, &addr4) != 0, |
| "Should not be able to parse IPv4 address in IPv6 mode"); |
| |
| ck_assert_msg(nl_addr_parse(addr_str, AF_UNSPEC, &addr4) == 0, |
| "Should be able to parse \"%s\"", addr_str); |
| |
| ck_assert_msg(nl_addr_get_family(addr4) == AF_INET, |
| "Address family should be AF_INET"); |
| |
| ck_assert_msg(nl_addr_get_prefixlen(addr4) == 16, |
| "Prefix length should be 16"); |
| |
| ck_assert_msg(!nl_addr_iszero(addr4), |
| "Address should not be all zeroes"); |
| |
| clone = nl_addr_clone(addr4); |
| ck_assert_msg(clone != NULL, "Cloned address should not be NULL"); |
| |
| ck_assert_msg(nl_addr_cmp(addr4, clone) == 0, |
| "Cloned address should not mismatch original"); |
| |
| ck_assert_msg(nl_addr_fill_sockaddr(addr4, (struct sockaddr *)&sin, |
| &len) == 0, |
| "Should be able to fill socketaddr"); |
| |
| ck_assert_msg( |
| !strcmp(nl_addr2str(addr4, buf, sizeof(buf)), addr_str), |
| "Address translated back to string does not match original"); |
| |
| nl_addr_put(addr4); |
| nl_addr_put(clone); |
| } |
| END_TEST |
| |
| START_TEST(addr_parse6) |
| { |
| struct nl_addr *addr6, *clone; |
| struct sockaddr_in6 sin; |
| socklen_t len = sizeof(sin); |
| char *addr_str = "2001:1:2::3/64"; |
| char buf[128]; |
| |
| ck_assert_msg(nl_addr_parse(addr_str, AF_INET, &addr6) != 0, |
| "Should not be able to parse IPv6 address in IPv4 mode"); |
| |
| ck_assert_msg(nl_addr_parse(addr_str, AF_UNSPEC, &addr6) == 0, |
| "Should be able to parse \"%s\"", addr_str); |
| |
| ck_assert_msg(nl_addr_get_family(addr6) == AF_INET6, |
| "Address family should be AF_INET6"); |
| |
| ck_assert_msg(nl_addr_get_prefixlen(addr6) == 64, |
| "Prefix length should be 64"); |
| |
| ck_assert_msg(!nl_addr_iszero(addr6), |
| "Address should not be all zeroes"); |
| |
| clone = nl_addr_clone(addr6); |
| ck_assert_msg(clone != NULL, "Cloned address should not be NULL"); |
| |
| ck_assert_msg(nl_addr_cmp(addr6, clone) == 0, |
| "Cloned address should not mismatch original"); |
| |
| ck_assert_msg(nl_addr_fill_sockaddr(addr6, (struct sockaddr *)&sin, |
| &len) == 0, |
| "Should be able to fill socketaddr"); |
| |
| ck_assert_msg( |
| !strcmp(nl_addr2str(addr6, buf, sizeof(buf)), addr_str), |
| "Address translated back to string does not match original"); |
| |
| _nl_clear_pointer(&addr6, nl_addr_put); |
| |
| ck_assert(nl_addr_parse("default", AF_INET6, &addr6) == 0); |
| ck_assert_int_eq(nl_addr_get_len(addr6), 16); |
| ck_assert_int_eq(nl_addr_get_prefixlen(addr6), 0); |
| ck_assert_mem_eq(nl_addr_get_binary_addr(addr6), ((uint8_t[16]){ 0 }), |
| 16); |
| |
| nl_addr_put(addr6); |
| nl_addr_put(clone); |
| } |
| END_TEST |
| |
| START_TEST(addr_info) |
| { |
| struct nl_addr *addr; |
| char *addr_str = "127.0.0.1"; |
| struct addrinfo *result; |
| |
| ck_assert_msg(nl_addr_parse(addr_str, AF_UNSPEC, &addr) == 0, |
| "Parsing of valid address should not fail"); |
| |
| ck_assert_msg(nl_addr_info(addr, &result) == 0, |
| "getaddrinfo() on loopback address should work"); |
| |
| freeaddrinfo(result); |
| nl_addr_put(addr); |
| } |
| END_TEST |
| |
| START_TEST(addr_flags2str) |
| { |
| int ifa_flags = IFA_F_TENTATIVE | IFA_F_DADFAILED; |
| int ifa_flags2; |
| char buf[128]; |
| |
| rtnl_addr_flags2str(ifa_flags, buf, sizeof(buf)); |
| ck_assert_str_eq(buf, "dadfailed,tentative"); |
| |
| ifa_flags2 = rtnl_addr_str2flags(buf); |
| ck_assert_int_eq(ifa_flags2, ifa_flags); |
| } |
| END_TEST |
| |
| Suite *make_nl_addr_suite(void) |
| { |
| Suite *suite = suite_create("Abstract addresses"); |
| TCase *tc = tcase_create("Core"); |
| |
| tcase_add_test(tc, addr_alloc); |
| tcase_add_test(tc, addr_binary_addr); |
| tcase_add_test(tc, addr_parse4); |
| tcase_add_test(tc, addr_parse6); |
| tcase_add_test(tc, addr_info); |
| tcase_add_test(tc, addr_flags2str); |
| suite_add_tcase(suite, tc); |
| |
| return suite; |
| } |