lh | 9ed821d | 2023-04-07 01:36:19 -0700 | [diff] [blame^] | 1 | /* |
| 2 | * tests/check-addr.c nl_addr unit tests |
| 3 | * |
| 4 | * This library is free software; you can redistribute it and/or |
| 5 | * modify it under the terms of the GNU Lesser General Public |
| 6 | * License as published by the Free Software Foundation version 2.1 |
| 7 | * of the License. |
| 8 | * |
| 9 | * Copyright (c) 2013 Thomas Graf <tgraf@suug.ch> |
| 10 | */ |
| 11 | |
| 12 | #include <check.h> |
| 13 | #include <netlink/addr.h> |
| 14 | |
| 15 | START_TEST(addr_alloc) |
| 16 | { |
| 17 | struct nl_addr *addr; |
| 18 | |
| 19 | addr = nl_addr_alloc(16); |
| 20 | fail_if(addr == NULL, |
| 21 | "Allocation should not return NULL"); |
| 22 | |
| 23 | fail_if(nl_addr_iszero(addr) == 0, |
| 24 | "New empty address should be all zeros"); |
| 25 | |
| 26 | fail_if(nl_addr_get_family(addr) != AF_UNSPEC, |
| 27 | "New empty address should have family AF_UNSPEC"); |
| 28 | |
| 29 | fail_if(nl_addr_get_prefixlen(addr) != 0, |
| 30 | "New empty address should have prefix length 0"); |
| 31 | |
| 32 | fail_if(nl_addr_shared(addr), |
| 33 | "New empty address should not be shared"); |
| 34 | |
| 35 | fail_if(nl_addr_get(addr) != addr, |
| 36 | "nl_addr_get() should return pointer to address"); |
| 37 | |
| 38 | fail_if(nl_addr_shared(addr) == 0, |
| 39 | "Address should be shared after call to nl_addr_get()"); |
| 40 | |
| 41 | nl_addr_put(addr); |
| 42 | |
| 43 | fail_if(nl_addr_shared(addr), |
| 44 | "Address should not be shared after call to nl_addr_put()"); |
| 45 | |
| 46 | fail_if(nl_addr_fill_sockaddr(addr, NULL, 0) == 0, |
| 47 | "Socket address filling should fail for empty address"); |
| 48 | |
| 49 | nl_addr_put(addr); |
| 50 | } |
| 51 | END_TEST |
| 52 | |
| 53 | START_TEST(addr_binary_addr) |
| 54 | { |
| 55 | struct nl_addr *addr, *addr2; |
| 56 | char baddr[4] = { 0x1, 0x2, 0x3, 0x4 }; |
| 57 | char baddr2[6] = { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6 }; |
| 58 | |
| 59 | addr = nl_addr_alloc(4); |
| 60 | fail_if(addr == NULL, |
| 61 | "Allocation should not return NULL"); |
| 62 | |
| 63 | fail_if(nl_addr_set_binary_addr(addr, baddr, 4) < 0, |
| 64 | "Valid binary address should be settable"); |
| 65 | |
| 66 | fail_if(nl_addr_get_prefixlen(addr) != 0, |
| 67 | "Prefix length should be unchanged after nl_addr_set_binary_addr()"); |
| 68 | |
| 69 | fail_if(nl_addr_get_len(addr) != 4, |
| 70 | "Address length should be 4"); |
| 71 | |
| 72 | fail_if(nl_addr_set_binary_addr(addr, baddr2, 6) == 0, |
| 73 | "Should not be able to set binary address exceeding maximum length"); |
| 74 | |
| 75 | fail_if(nl_addr_get_len(addr) != 4, |
| 76 | "Address length should still be 4"); |
| 77 | |
| 78 | fail_if(nl_addr_guess_family(addr) != AF_INET, |
| 79 | "Binary address of length 4 should be guessed as AF_INET"); |
| 80 | |
| 81 | fail_if(memcmp(baddr, nl_addr_get_binary_addr(addr), 4) != 0, |
| 82 | "Binary address mismatches"); |
| 83 | |
| 84 | addr2 = nl_addr_build(AF_UNSPEC, baddr, 4); |
| 85 | fail_if(addr2 == NULL, |
| 86 | "Building of address should not fail"); |
| 87 | |
| 88 | nl_addr_set_prefixlen(addr, 32); |
| 89 | fail_if(nl_addr_get_prefixlen(addr) != 32, |
| 90 | "Prefix length should be successful changed after nl_addr_set_prefixlen()"); |
| 91 | |
| 92 | fail_if(nl_addr_cmp(addr, addr2), |
| 93 | "Addresses built from same binary address should match"); |
| 94 | |
| 95 | nl_addr_put(addr); |
| 96 | nl_addr_put(addr2); |
| 97 | } |
| 98 | END_TEST |
| 99 | |
| 100 | START_TEST(addr_parse4) |
| 101 | { |
| 102 | struct nl_addr *addr4, *clone; |
| 103 | struct sockaddr_in sin; |
| 104 | socklen_t len = sizeof(sin); |
| 105 | char *addr_str = "10.0.0.1/16"; |
| 106 | char buf[128]; |
| 107 | |
| 108 | fail_if(nl_addr_parse(addr_str, AF_INET6, &addr4) == 0, |
| 109 | "Should not be able to parse IPv4 address in IPv6 mode"); |
| 110 | |
| 111 | fail_if(nl_addr_parse(addr_str, AF_UNSPEC, &addr4) != 0, |
| 112 | "Should be able to parse \"%s\"", addr_str); |
| 113 | |
| 114 | fail_if(nl_addr_get_family(addr4) != AF_INET, |
| 115 | "Address family should be AF_INET"); |
| 116 | |
| 117 | fail_if(nl_addr_get_prefixlen(addr4) != 16, |
| 118 | "Prefix length should be 16"); |
| 119 | |
| 120 | fail_if(nl_addr_iszero(addr4), |
| 121 | "Address should not be all zeroes"); |
| 122 | |
| 123 | clone = nl_addr_clone(addr4); |
| 124 | fail_if(clone == NULL, |
| 125 | "Cloned address should not be NULL"); |
| 126 | |
| 127 | fail_if(nl_addr_cmp(addr4, clone) != 0, |
| 128 | "Cloned address should not mismatch original"); |
| 129 | |
| 130 | fail_if(nl_addr_fill_sockaddr(addr4, (struct sockaddr *) &sin, &len) != 0, |
| 131 | "Should be able to fill socketaddr"); |
| 132 | |
| 133 | fail_if(strcmp(nl_addr2str(addr4, buf, sizeof(buf)), addr_str), |
| 134 | "Address translated back to string does not match original"); |
| 135 | |
| 136 | nl_addr_put(addr4); |
| 137 | nl_addr_put(clone); |
| 138 | } |
| 139 | END_TEST |
| 140 | |
| 141 | START_TEST(addr_parse6) |
| 142 | { |
| 143 | struct nl_addr *addr6, *clone; |
| 144 | struct sockaddr_in6 sin; |
| 145 | socklen_t len = sizeof(sin); |
| 146 | char *addr_str = "2001:1:2::3/64"; |
| 147 | char buf[128]; |
| 148 | |
| 149 | fail_if(nl_addr_parse(addr_str, AF_INET, &addr6) == 0, |
| 150 | "Should not be able to parse IPv6 address in IPv4 mode"); |
| 151 | |
| 152 | fail_if(nl_addr_parse(addr_str, AF_UNSPEC, &addr6) != 0, |
| 153 | "Should be able to parse \"%s\"", addr_str); |
| 154 | |
| 155 | fail_if(nl_addr_get_family(addr6) != AF_INET6, |
| 156 | "Address family should be AF_INET6"); |
| 157 | |
| 158 | fail_if(nl_addr_get_prefixlen(addr6) != 64, |
| 159 | "Prefix length should be 64"); |
| 160 | |
| 161 | fail_if(nl_addr_iszero(addr6), |
| 162 | "Address should not be all zeroes"); |
| 163 | |
| 164 | clone = nl_addr_clone(addr6); |
| 165 | fail_if(clone == NULL, |
| 166 | "Cloned address should not be NULL"); |
| 167 | |
| 168 | fail_if(nl_addr_cmp(addr6, clone) != 0, |
| 169 | "Cloned address should not mismatch original"); |
| 170 | |
| 171 | fail_if(nl_addr_fill_sockaddr(addr6, (struct sockaddr *) &sin, &len) != 0, |
| 172 | "Should be able to fill socketaddr"); |
| 173 | |
| 174 | fail_if(strcmp(nl_addr2str(addr6, buf, sizeof(buf)), addr_str), |
| 175 | "Address translated back to string does not match original"); |
| 176 | |
| 177 | nl_addr_put(addr6); |
| 178 | nl_addr_put(clone); |
| 179 | } |
| 180 | END_TEST |
| 181 | |
| 182 | START_TEST(addr_info) |
| 183 | { |
| 184 | struct nl_addr *addr; |
| 185 | char *addr_str = "127.0.0.1"; |
| 186 | struct addrinfo *result; |
| 187 | |
| 188 | fail_if(nl_addr_parse(addr_str, AF_UNSPEC, &addr) != 0, |
| 189 | "Parsing of valid address should not fail"); |
| 190 | |
| 191 | fail_if(nl_addr_info(addr, &result) != 0, |
| 192 | "getaddrinfo() on loopback address should work"); |
| 193 | |
| 194 | freeaddrinfo(result); |
| 195 | nl_addr_put(addr); |
| 196 | } |
| 197 | END_TEST |
| 198 | |
| 199 | Suite *make_nl_addr_suite(void) |
| 200 | { |
| 201 | Suite *suite = suite_create("Abstract addresses"); |
| 202 | |
| 203 | TCase *tc_addr = tcase_create("Core"); |
| 204 | tcase_add_test(tc_addr, addr_alloc); |
| 205 | tcase_add_test(tc_addr, addr_binary_addr); |
| 206 | tcase_add_test(tc_addr, addr_parse4); |
| 207 | tcase_add_test(tc_addr, addr_parse6); |
| 208 | tcase_add_test(tc_addr, addr_info); |
| 209 | suite_add_tcase(suite, tc_addr); |
| 210 | |
| 211 | return suite; |
| 212 | } |