📄 check_addr.c
字号:
#include "config.h"#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <dnet.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <check.h>#define ADDR_PACK(a, ip) \ (a)->addr_type = ADDR_TYPE_IP; \ (a)->addr_bits = IP_ADDR_BITS; \ (a)->addr_ip = (ip)#ifdef HAVE_SOCKADDR_SA_LEN#define SIN_PACK(s, ip, port) \ (s)->sin_len = sizeof(struct sockaddr_in); \ (s)->sin_family = AF_INET; \ (s)->sin_port = htons(port); \ (s)->sin_addr.s_addr = (ip)#else#define SIN_PACK(s, ip, port) \ (s)->sin_family = AF_INET; \ (s)->sin_port = htons(port); \ (s)->sin_addr.s_addr = (ip)#endiftypedef struct sockaddr SA;START_TEST(test_addr_pack){ struct addr a, b; memset(&a, 0, sizeof(a)); memset(&b, 0, sizeof(b)); ADDR_PACK(&a, 666); addr_pack(&b, ADDR_TYPE_IP, IP_ADDR_BITS, &a.addr_ip, IP_ADDR_LEN); fail_unless(memcmp(&a, &b, sizeof(a)) == 0, "got different address");}END_TEST START_TEST(test_addr_cmp){ struct addr a, b; ADDR_PACK(&a, 666); memcpy(&b, &a, sizeof(a)); fail_unless(addr_cmp(&a, &b) == 0, "failed on equal addresses"); b.addr_type = ADDR_TYPE_ETH; fail_unless(addr_cmp(&a, &b) != 0, "failed on different addr_type"); memcpy(&b, &a, sizeof(a)); b.addr_bits--; fail_unless(addr_cmp(&a, &b) > 0, "failed on lesser addr_bits"); memcpy(&b, &a, sizeof(a)); b.addr_ip--; fail_unless(addr_cmp(&a, &b) != 0, "failed on different addr_ip"); addr_aton("10.0.0.1", &a); addr_aton("10.0.0.2", &b); fail_unless(addr_cmp(&a, &b) < 0, "failed on lesser addr compare"); fail_unless(addr_cmp(&b, &a) > 0, "failed on greater addr compare");}END_TESTSTART_TEST(test_addr_bcast){ struct addr a, b; ADDR_PACK(&a, htonl(0x01020304)); a.addr_bits = 29; addr_bcast(&a, &b); fail_unless(b.addr_ip == htonl(0x01020307), "wrong for /29"); a.addr_bits = 16; addr_bcast(&a, &b); fail_unless(b.addr_ip == htonl(0x0102ffff), "wrong for /16"); a.addr_bits = 5; addr_bcast(&a, &b); fail_unless(b.addr_ip == htonl(0x7ffffff), "wrong for /5");}END_TESTSTART_TEST(test_addr_net){ struct addr a, b; ADDR_PACK(&a, htonl(0x01020304)); a.addr_bits = 24; addr_net(&a, &b); fail_unless(b.addr_ip == htonl(0x01020300), "wrong for /24"); addr_aton("cafe:babe::dead:beef", &a); a.addr_bits = 20; addr_net(&a, &b); addr_aton("cafe:b000::", &a); a.addr_bits = IP6_ADDR_BITS; fail_unless(addr_cmp(&a, &b) == 0, "IPv6 net failed");}END_TESTSTART_TEST(test_addr_ntop){ struct ntop { u_char *n; char *p; } *ntop, ntop_ip6[] = { { IP6_ADDR_UNSPEC, "::" }, { IP6_ADDR_LOOPBACK, "::1" }, { "\xfe\x08\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x01", "fe08::1" }, { "\xff\xff\xff\xff\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\xff\xff\xff", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" }, { "\xca\xfe\xba\xbe\x00\x00\x00\x00\x00\x00\x00\x00" "\xde\xad\xbe\xef", "cafe:babe::dead:beef" }, { "\xfe\xed\xfa\xce\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00", "feed:face::" }, { "\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00" "\x0d\x00\x0e\x00\x0f\x00\x00", "0:a:b:c:d:e:f:0" }, { "\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\xff\xff\x01\x02\x03\x04", "::ffff:1.2.3.4" }, { NULL } }; struct addr a; char buf[64]; ADDR_PACK(&a, htonl(0x010203ff)); a.addr_bits = 23; addr_ntop(&a, buf, sizeof(buf)); fail_unless(strcmp(buf, "1.2.3.255/23") == 0, "bad /23 handling"); a.addr_bits = 0; addr_ntop(&a, buf, sizeof(buf)); fail_unless(strcmp(buf, "1.2.3.255/0") == 0, "bad /0 handling"); a.addr_bits = 32; addr_ntop(&a, buf, sizeof(buf)); fail_unless(strcmp(buf, "1.2.3.255") == 0, "bad /32 handling"); fail_unless(addr_ntop(&a, buf, 9) == NULL, "buffer overflow?"); addr_pack(&a, ADDR_TYPE_ETH, ETH_ADDR_BITS, "\x00\x00\x00\x00\x00\x00", ETH_ADDR_LEN); fail_unless(strcmp(addr_ntop(&a, buf, sizeof(buf)), "00:00:00:00:00:00") == 0, "bad empty MAC handling"); memcpy(&a.addr_eth, "\x00\x0d\x0e\x0a\x0d\x00", ETH_ADDR_LEN); fail_unless(strcmp(addr_ntop(&a, buf, sizeof(buf)), "00:0d:0e:0a:0d:00") == 0, "b0rked"); a.addr_bits = 16; fail_unless(addr_ntop(&a, buf, sizeof(buf)) == NULL, "took /16 mask"); for (ntop = ntop_ip6; ntop->n != NULL; ntop++) { addr_pack(&a, ADDR_TYPE_IP6, IP6_ADDR_BITS, ntop->n, IP6_ADDR_LEN); fail_unless(strcmp(addr_ntop(&a, buf, sizeof(buf)), ntop->p) == 0, ntop->p); }}END_TESTSTART_TEST(test_addr_pton){ struct pton { char *p; u_char *n; } *pton, pton_ip6[] = { { "::", IP6_ADDR_UNSPEC }, { "::1", IP6_ADDR_LOOPBACK }, { "fe08::", "\xfe\x08\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" }, { "fe08::1", "\xfe\x08\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x01" }, { "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "\xff\xff\xff\xff" "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" }, { "cafe::babe:dead:beef:0:ffff", "\xca\xfe\x00\x00\x00\x00" "\xba\xbe\xde\xad\xbe\xef\x00\x00\xff\xff" }, { "::1.2.3.4", "\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x01\x02\x03\x04" }, { ":cafe", NULL }, { ":::", NULL }, { "::fffff", NULL }, { NULL } }, pton_eth[] = { { "0:d:e:a:d:0", "\x00\x0d\x0e\x0a\x0d\x00" }, { "ff:ff:ff:ff:ff:ff", ETH_ADDR_BROADCAST }, { "00:d:0e:a:0d:0", "\x00\x0d\x0e\x0a\x0d\x00" }, { ":d:e:a:d:0", NULL }, { "0:d:e:a:d:", NULL }, { "0:d:e:a:def:0", NULL }, { "0:d:e:a:d:0:0", NULL }, { "0:0:0:0:0:0", "\x00\x00\x00\x00\x00\x00" }, { NULL } }; struct addr a, b; int res; ADDR_PACK(&a, htonl(0x010203ff)); a.addr_bits = 17; addr_pton("1.2.3.255/17", &b); fail_unless(addr_cmp(&a, &b) == 0, "bad /17 handling"); a.addr_bits = 32; addr_pton("1.2.3.255", &b); fail_unless(addr_cmp(&a, &b) == 0, "bad handling of missing /32"); fail_unless(addr_pton("1.2.3.4/33", &b) < 0, "accepted /33"); fail_unless(addr_pton("1.2.3.256", &b) < 0, "accepted .256"); fail_unless(addr_pton("1.2.3.4.5", &b) < 0, "accepted quint octet"); fail_unless(addr_pton("1.2.3", &b) < 0, "accepted triple octet"); fail_unless(addr_pton("localhost", &b) == 0, "barfed on localhost"); fail_unless(addr_pton("localhost/24", &b) == 0, "barfed on localhost/24"); addr_pton("1.2.3.4/24", &a); addr_pton("1.2.3.4/255.255.255.0", &b); fail_unless(addr_cmp(&a, &b) == 0, "bad /255.255.255.0 handling"); for (pton = pton_eth; pton->n != NULL; pton++) { res = addr_pton(pton->p, &a); if (pton->n != NULL) { fail_unless(res == 0 && a.addr_type == ADDR_TYPE_ETH && a.addr_bits == ETH_ADDR_BITS && memcmp(&a.addr_eth, pton->n, ETH_ADDR_LEN) == 0, pton->p); } else { fail_unless(res < 0, pton->p); } } for (pton = pton_ip6; pton->n != NULL; pton++) { res = addr_pton(pton->p, &a); if (pton->n != NULL) { fail_unless(res == 0 && a.addr_type == ADDR_TYPE_IP6 && a.addr_bits == IP6_ADDR_BITS && memcmp(&a.addr_ip6, pton->n, IP6_ADDR_LEN) == 0, pton->p); } else { fail_unless(res < 0, pton->p); } }}END_TESTSTART_TEST(test_addr_ntoa){ struct addr a; int i; ADDR_PACK(&a, htonl(0x01020304)); for (i = 0; i < 1000; i++) { fail_unless(strcmp(addr_ntoa(&a), "1.2.3.4") == 0, "barfed on 1.2.3.4 loop"); }}END_TESTSTART_TEST(test_addr_ntos){ struct sockaddr_in s1, s2; struct addr a; memset(&s1, 0, sizeof(s1)); memset(&s2, 0, sizeof(s2)); SIN_PACK(&s1, htonl(0x01020304), 0); ADDR_PACK(&a, htonl(0x01020304)); addr_ntos(&a, (SA *)&s2); fail_unless(memcmp(&s1, &s2, sizeof(s1)) == 0, "bad sockaddr_in");}END_TESTSTART_TEST(test_addr_ston){ struct sockaddr_in s, t; struct addr a, b; memset(&a, 0, sizeof(a)); ADDR_PACK(&a, htonl(0x01020304)); memcpy(&b, &a, sizeof(&b)); SIN_PACK(&s, htonl(0x01020304), 0); memcpy(&t, &s, sizeof(&t)); addr_ston((SA *)&s, &b); fail_unless(memcmp(&a, &b, sizeof(a)) == 0, "bad addr");#ifdef HAVE_SOCKADDR_SA_LEN s.sin_len = 0; fail_unless(addr_ston((SA *)&s, &b) == 0 && addr_cmp(&a, &b) == 0, "sin_len == 0");#endif s.sin_family = 123; fail_unless(addr_ston((SA *)&s, &b) < 0, "sin_family == 123");}END_TESTSTART_TEST(test_addr_btos){ struct sockaddr s; struct addr a; ADDR_PACK(&a, htonl(0xffffff00)); a.addr_bits = 24; fail_unless(addr_btos(a.addr_bits, &s) == 0, "b0rked");}END_TESTSTART_TEST(test_addr_stob){ struct sockaddr_in s; struct addr a; SIN_PACK(&s, htonl(0xffffff00), 0); addr_stob((SA *)&s, &a.addr_bits); fail_unless(a.addr_bits == 24, "b0rked"); /* XXX - BSD routing sockets or SIOCGIFNETMASK */ s.sin_family = 0; fail_unless(addr_stob((SA *)&s, &a.addr_bits) == 0 && a.addr_bits == 24, "sin_family = 0");}END_TESTSTART_TEST(test_addr_btom){ struct addr a; uint32_t mask; ADDR_PACK(&a, htonl(0xffffff00)); a.addr_bits = 24; addr_btom(a.addr_bits, &mask, sizeof(mask)); fail_unless(mask == htonl(0xffffff00), "b0rked");}END_TESTSTART_TEST(test_addr_mtob){ struct addr a; uint32_t mask; mask = htonl(0xffffff00); addr_mtob(&mask, sizeof(mask), &a.addr_bits); fail_unless(a.addr_bits == 24, "b0rked");}END_TESTSuite *addr_suite(void){ Suite *s = suite_create("addr"); TCase *tc_core = tcase_create("core"); suite_add_tcase(s, tc_core); tcase_add_test(tc_core, test_addr_pack); tcase_add_test(tc_core, test_addr_cmp); tcase_add_test(tc_core, test_addr_bcast); tcase_add_test(tc_core, test_addr_net); tcase_add_test(tc_core, test_addr_ntop); tcase_add_test(tc_core, test_addr_pton); tcase_add_test(tc_core, test_addr_ntoa); tcase_add_test(tc_core, test_addr_ntos); tcase_add_test(tc_core, test_addr_ston); tcase_add_test(tc_core, test_addr_btos); tcase_add_test(tc_core, test_addr_stob); tcase_add_test(tc_core, test_addr_btom); tcase_add_test(tc_core, test_addr_mtob); return (s);}intmain(void){ Suite *s = addr_suite(); SRunner *sr = srunner_create(s); int nf; srunner_run_all (sr, CK_NORMAL); nf = srunner_ntests_failed(sr); srunner_free(sr); suite_free(s); return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -