#include #include #include "solution.cpp" static int failures = 0; #define CHECK(cond, name) do { if (cond) std::printf("ok %s\n", name); \ else { std::printf("FAIL %s (line %d)\n", name, __LINE__); ++failures; } } while (0) static uint32_t ip4(int a, int b, int c, int d) { return (uint32_t(a) << 24) | (uint32_t(b) << 16) | (uint32_t(c) << 8) | uint32_t(d); } int main() { { Subnet s = subnet_of(ip4(10, 0, 1, 130), 26); CHECK(s.network == ip4(10, 0, 1, 128), "/26: адрес сети 10.0.1.128"); CHECK(s.broadcast == ip4(10, 0, 1, 191), "/26: broadcast 10.0.1.191"); CHECK(s.first_host == ip4(10, 0, 1, 129), "/26: первый узел 10.0.1.129"); CHECK(s.last_host == ip4(10, 0, 1, 190), "/26: последний узел 10.0.1.190"); CHECK(s.host_count == 62, "/26: 62 узла (не 64)"); } { Subnet s = subnet_of(ip4(192, 168, 5, 200), 24); CHECK(s.network == ip4(192, 168, 5, 0), "/24: сеть 192.168.5.0"); CHECK(s.broadcast == ip4(192, 168, 5, 255), "/24: broadcast 192.168.5.255"); CHECK(s.host_count == 254, "/24: 254 узла"); Subnet t = subnet_of(ip4(172, 16, 4, 9), 30); CHECK(t.network == ip4(172, 16, 4, 8) && t.broadcast == ip4(172, 16, 4, 11), "/30: сеть 172.16.4.8, broadcast 172.16.4.11"); CHECK(t.host_count == 2 && t.first_host == ip4(172, 16, 4, 9) && t.last_host == ip4(172, 16, 4, 10), "/30: 2 узла, 9 и 10"); Subnet z = subnet_of(ip4(10, 0, 0, 5), 32); CHECK(z.network == ip4(10, 0, 0, 5) && z.broadcast == ip4(10, 0, 0, 5) && z.host_count == 1, "/32: один адрес, сеть == broadcast == узел"); Subnet p31 = subnet_of(ip4(10, 0, 0, 1), 31); CHECK(p31.host_count == 2 && p31.first_host == ip4(10, 0, 0, 0) && p31.last_host == ip4(10, 0, 0, 1), "/31: RFC 3021 — 2 узла без вычета"); Subnet eight = subnet_of(ip4(10, 200, 30, 40), 8); CHECK(eight.network == ip4(10, 0, 0, 0) && eight.broadcast == ip4(10, 255, 255, 255), "/8: сеть 10.0.0.0, broadcast 10.255.255.255"); Subnet zero = subnet_of(ip4(8, 8, 8, 8), 0); CHECK(zero.network == 0 && zero.broadcast == 0xFFFFFFFFu && zero.host_count == 4294967294LL, "/0: вся сеть, узлов 2^32-2"); } { CHECK(same_subnet(ip4(10, 0, 1, 130), ip4(10, 0, 1, 150), 26), "/26: 130 и 150 в одной подсети"); CHECK(!same_subnet(ip4(10, 0, 1, 130), ip4(10, 0, 1, 200), 26), "/26: 130 и 200 — разные подсети"); CHECK(!same_subnet(ip4(10, 0, 1, 130), ip4(10, 0, 1, 127), 26), "/26: 130 и 127 — разные подсети"); CHECK(same_subnet(ip4(10, 0, 1, 1), ip4(10, 0, 2, 1), 16), "/16: разные третьи октеты — одна сеть"); CHECK(!same_subnet(ip4(10, 0, 1, 1), ip4(10, 1, 1, 1), 16), "/16: 10.0.x и 10.1.x — разные"); CHECK(same_subnet(ip4(10, 0, 0, 0), ip4(10, 0, 0, 1), 31), "/31: соседи по RFC 3021"); } { CHECK(prefix_for_hosts(62) == 26, "prefix_for_hosts(62) -> 26"); CHECK(prefix_for_hosts(63) == 25, "prefix_for_hosts(63) -> 25 (63 в /26 не влезает)"); CHECK(prefix_for_hosts(254) == 24, "prefix_for_hosts(254) -> 24"); CHECK(prefix_for_hosts(255) == 23, "prefix_for_hosts(255) -> 23"); CHECK(prefix_for_hosts(2) == 30, "prefix_for_hosts(2) -> 30"); CHECK(prefix_for_hosts(1) == 30, "prefix_for_hosts(1) -> 30 (узкая подсеть общего вида)"); CHECK(prefix_for_hosts(0) == -1, "prefix_for_hosts(0) -> -1"); CHECK(prefix_for_hosts(4294967295) == -1, "prefix_for_hosts(2^32-1) -> -1 (не влезает)"); CHECK(prefix_for_hosts(1000000) == 12, "prefix_for_hosts(1000000) -> 12"); } std::printf(failures ? "\nFAILURES: %d\n" : "\nALL PASS\n", failures); return failures ? 1 : 0; }