00001
00002 #include "config.h"
00003
00004 #include <sys/types.h>
00005 #include <sys/socket.h>
00006
00007 #include <netinet/in.h>
00008 #include <arpa/inet.h>
00009
00010 #include <dnet.h>
00011
00012 #include <stdio.h>
00013 #include <stdlib.h>
00014 #include <string.h>
00015
00016 #include <check.h>
00017
00018 #define ADDR_PACK(a, ip) \
00019 (a)->addr_type = ADDR_TYPE_IP; \
00020 (a)->addr_bits = IP_ADDR_BITS; \
00021 (a)->addr_ip = (ip)
00022
00023 #ifdef HAVE_SOCKADDR_SA_LEN
00024 #define SIN_PACK(s, ip, port) \
00025 (s)->sin_len = sizeof(struct sockaddr_in); \
00026 (s)->sin_family = AF_INET; \
00027 (s)->sin_port = htons(port); \
00028 (s)->sin_addr.s_addr = (ip)
00029 #else
00030 #define SIN_PACK(s, ip, port) \
00031 (s)->sin_family = AF_INET; \
00032 (s)->sin_port = htons(port); \
00033 (s)->sin_addr.s_addr = (ip)
00034 #endif
00035
00036 typedef struct sockaddr SA;
00037
00038 START_TEST(test_addr_pack)
00039 {
00040 struct addr a, b;
00041
00042 memset(&a, 0, sizeof(a)); memset(&b, 0, sizeof(b));
00043
00044 ADDR_PACK(&a, 666);
00045 addr_pack(&b, ADDR_TYPE_IP, IP_ADDR_BITS, &a.addr_ip, IP_ADDR_LEN);
00046 fail_unless(memcmp(&a, &b, sizeof(a)) == 0, "got different address");
00047 }
00048 END_TEST
00049
00050 START_TEST(test_addr_cmp)
00051 {
00052 struct addr a, b;
00053
00054 ADDR_PACK(&a, 666);
00055 memcpy(&b, &a, sizeof(a));
00056 fail_unless(addr_cmp(&a, &b) == 0, "failed on equal addresses");
00057 b.addr_type = ADDR_TYPE_ETH;
00058 fail_unless(addr_cmp(&a, &b) != 0, "failed on different addr_type");
00059 memcpy(&b, &a, sizeof(a)); b.addr_bits--;
00060 fail_unless(addr_cmp(&a, &b) > 0, "failed on lesser addr_bits");
00061 memcpy(&b, &a, sizeof(a)); b.addr_ip--;
00062 fail_unless(addr_cmp(&a, &b) != 0, "failed on different addr_ip");
00063
00064 addr_aton("10.0.0.1", &a);
00065 addr_aton("10.0.0.2", &b);
00066 fail_unless(addr_cmp(&a, &b) < 0, "failed on lesser addr compare");
00067 fail_unless(addr_cmp(&b, &a) > 0, "failed on greater addr compare");
00068 }
00069 END_TEST
00070
00071 START_TEST(test_addr_bcast)
00072 {
00073 struct addr a, b;
00074
00075 ADDR_PACK(&a, htonl(0x01020304));
00076 a.addr_bits = 29; addr_bcast(&a, &b);
00077 fail_unless(b.addr_ip == htonl(0x01020307), "wrong for /29");
00078 a.addr_bits = 16; addr_bcast(&a, &b);
00079 fail_unless(b.addr_ip == htonl(0x0102ffff), "wrong for /16");
00080 a.addr_bits = 5; addr_bcast(&a, &b);
00081 fail_unless(b.addr_ip == htonl(0x7ffffff), "wrong for /5");
00082 }
00083 END_TEST
00084
00085 START_TEST(test_addr_net)
00086 {
00087 struct addr a, b;
00088
00089 ADDR_PACK(&a, htonl(0x01020304));
00090 a.addr_bits = 24; addr_net(&a, &b);
00091 fail_unless(b.addr_ip == htonl(0x01020300), "wrong for /24");
00092 addr_aton("cafe:babe::dead:beef", &a);
00093 a.addr_bits = 20; addr_net(&a, &b);
00094 addr_aton("cafe:b000::", &a);
00095 a.addr_bits = IP6_ADDR_BITS;
00096 fail_unless(addr_cmp(&a, &b) == 0, "IPv6 net failed");
00097 }
00098 END_TEST
00099
00100 START_TEST(test_addr_ntop)
00101 {
00102 struct ntop {
00103 u_char *n;
00104 char *p;
00105 } *ntop, ntop_ip6[] = {
00106 { IP6_ADDR_UNSPEC, "::" },
00107 { IP6_ADDR_LOOPBACK, "::1" },
00108 { "\xfe\x08\x00\x00\x00\x00\x00\x00"
00109 "\x00\x00\x00\x00\x00\x00\x00\x01", "fe08::1" },
00110 { "\xff\xff\xff\xff\xff\xff\xff\xff"
00111 "\xff\xff\xff\xff\xff\xff\xff\xff",
00112 "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" },
00113 { "\xca\xfe\xba\xbe\x00\x00\x00\x00\x00\x00\x00\x00"
00114 "\xde\xad\xbe\xef", "cafe:babe::dead:beef" },
00115 { "\xfe\xed\xfa\xce\x00\x00\x00\x00\x00\x00\x00\x00"
00116 "\x00\x00\x00\x00", "feed:face::" },
00117 { "\x00\x00\x00\x0a\x00\x0b\x00\x0c\x00"
00118 "\x0d\x00\x0e\x00\x0f\x00\x00", "0:a:b:c:d:e:f:0" },
00119 { "\x00\x00\x00\x00\x00\x00\x00\x00"
00120 "\x00\x00\xff\xff\x01\x02\x03\x04", "::ffff:1.2.3.4" },
00121 { NULL }
00122 };
00123 struct addr a;
00124 char buf[64];
00125
00126 ADDR_PACK(&a, htonl(0x010203ff));
00127 a.addr_bits = 23; addr_ntop(&a, buf, sizeof(buf));
00128 fail_unless(strcmp(buf, "1.2.3.255/23") == 0, "bad /23 handling");
00129 a.addr_bits = 0; addr_ntop(&a, buf, sizeof(buf));
00130 fail_unless(strcmp(buf, "1.2.3.255/0") == 0, "bad /0 handling");
00131 a.addr_bits = 32; addr_ntop(&a, buf, sizeof(buf));
00132 fail_unless(strcmp(buf, "1.2.3.255") == 0, "bad /32 handling");
00133 fail_unless(addr_ntop(&a, buf, 9) == NULL, "buffer overflow?");
00134
00135 addr_pack(&a, ADDR_TYPE_ETH, ETH_ADDR_BITS,
00136 "\x00\x00\x00\x00\x00\x00", ETH_ADDR_LEN);
00137 fail_unless(strcmp(addr_ntop(&a, buf, sizeof(buf)),
00138 "00:00:00:00:00:00") == 0, "bad empty MAC handling");
00139 memcpy(&a.addr_eth, "\x00\x0d\x0e\x0a\x0d\x00", ETH_ADDR_LEN);
00140 fail_unless(strcmp(addr_ntop(&a, buf, sizeof(buf)),
00141 "00:0d:0e:0a:0d:00") == 0, "b0rked");
00142 a.addr_bits = 16;
00143 fail_unless(addr_ntop(&a, buf, sizeof(buf)) == NULL, "took /16 mask");
00144
00145 for (ntop = ntop_ip6; ntop->n != NULL; ntop++) {
00146 addr_pack(&a, ADDR_TYPE_IP6, IP6_ADDR_BITS, ntop->n,
00147 IP6_ADDR_LEN);
00148 fail_unless(strcmp(addr_ntop(&a, buf, sizeof(buf)),
00149 ntop->p) == 0, ntop->p);
00150 }
00151 }
00152 END_TEST
00153
00154 START_TEST(test_addr_pton)
00155 {
00156 struct pton {
00157 char *p;
00158 u_char *n;
00159 } *pton, pton_ip6[] = {
00160 { "::", IP6_ADDR_UNSPEC },
00161 { "::1", IP6_ADDR_LOOPBACK },
00162 { "fe08::", "\xfe\x08\x00\x00\x00\x00\x00\x00"
00163 "\x00\x00\x00\x00\x00\x00\x00\x00" },
00164 { "fe08::1", "\xfe\x08\x00\x00\x00\x00\x00\x00"
00165 "\x00\x00\x00\x00\x00\x00\x00\x01" },
00166 { "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "\xff\xff\xff\xff"
00167 "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" },
00168 { "cafe::babe:dead:beef:0:ffff", "\xca\xfe\x00\x00\x00\x00"
00169 "\xba\xbe\xde\xad\xbe\xef\x00\x00\xff\xff" },
00170 { "::1.2.3.4", "\x00\x00\x00\x00\x00\x00\x00\x00"
00171 "\x00\x00\x00\x00\x01\x02\x03\x04" },
00172 { ":cafe", NULL }, { ":::", NULL }, { "::fffff", NULL },
00173 { NULL }
00174 }, pton_eth[] = {
00175 { "0:d:e:a:d:0", "\x00\x0d\x0e\x0a\x0d\x00" },
00176 { "ff:ff:ff:ff:ff:ff", ETH_ADDR_BROADCAST },
00177 { "00:d:0e:a:0d:0", "\x00\x0d\x0e\x0a\x0d\x00" },
00178 { ":d:e:a:d:0", NULL }, { "0:d:e:a:d:", NULL },
00179 { "0:d:e:a:def:0", NULL }, { "0:d:e:a:d:0:0", NULL },
00180 { "0:0:0:0:0:0", "\x00\x00\x00\x00\x00\x00" },
00181 { NULL }
00182 };
00183 struct addr a, b;
00184 int res;
00185
00186 ADDR_PACK(&a, htonl(0x010203ff));
00187 a.addr_bits = 17; addr_pton("1.2.3.255/17", &b);
00188 fail_unless(addr_cmp(&a, &b) == 0, "bad /17 handling");
00189 a.addr_bits = 32; addr_pton("1.2.3.255", &b);
00190 fail_unless(addr_cmp(&a, &b) == 0, "bad handling of missing /32");
00191 fail_unless(addr_pton("1.2.3.4/33", &b) < 0, "accepted /33");
00192 fail_unless(addr_pton("1.2.3.256", &b) < 0, "accepted .256");
00193 fail_unless(addr_pton("1.2.3.4.5", &b) < 0, "accepted quint octet");
00194 fail_unless(addr_pton("1.2.3", &b) < 0, "accepted triple octet");
00195 fail_unless(addr_pton("localhost", &b) == 0, "barfed on localhost");
00196 fail_unless(addr_pton("localhost/24", &b) == 0,
00197 "barfed on localhost/24");
00198 addr_pton("1.2.3.4/24", &a);
00199 addr_pton("1.2.3.4/255.255.255.0", &b);
00200 fail_unless(addr_cmp(&a, &b) == 0, "bad /255.255.255.0 handling");
00201
00202 for (pton = pton_eth; pton->n != NULL; pton++) {
00203 res = addr_pton(pton->p, &a);
00204 if (pton->n != NULL) {
00205 fail_unless(res == 0 &&
00206 a.addr_type == ADDR_TYPE_ETH &&
00207 a.addr_bits == ETH_ADDR_BITS &&
00208 memcmp(&a.addr_eth, pton->n, ETH_ADDR_LEN) == 0,
00209 pton->p);
00210 } else {
00211 fail_unless(res < 0, pton->p);
00212 }
00213 }
00214 for (pton = pton_ip6; pton->n != NULL; pton++) {
00215 res = addr_pton(pton->p, &a);
00216 if (pton->n != NULL) {
00217 fail_unless(res == 0 &&
00218 a.addr_type == ADDR_TYPE_IP6 &&
00219 a.addr_bits == IP6_ADDR_BITS &&
00220 memcmp(&a.addr_ip6, pton->n, IP6_ADDR_LEN) == 0,
00221 pton->p);
00222 } else {
00223 fail_unless(res < 0, pton->p);
00224 }
00225 }
00226 }
00227 END_TEST
00228
00229 START_TEST(test_addr_ntoa)
00230 {
00231 struct addr a;
00232 int i;
00233
00234 ADDR_PACK(&a, htonl(0x01020304));
00235 for (i = 0; i < 1000; i++) {
00236 fail_unless(strcmp(addr_ntoa(&a), "1.2.3.4") == 0,
00237 "barfed on 1.2.3.4 loop");
00238 }
00239 }
00240 END_TEST
00241
00242 START_TEST(test_addr_ntos)
00243 {
00244 struct sockaddr_in s1, s2;
00245 struct addr a;
00246
00247 memset(&s1, 0, sizeof(s1));
00248 memset(&s2, 0, sizeof(s2));
00249 SIN_PACK(&s1, htonl(0x01020304), 0);
00250 ADDR_PACK(&a, htonl(0x01020304));
00251 addr_ntos(&a, (SA *)&s2);
00252 fail_unless(memcmp(&s1, &s2, sizeof(s1)) == 0, "bad sockaddr_in");
00253 }
00254 END_TEST
00255
00256 START_TEST(test_addr_ston)
00257 {
00258 struct sockaddr_in s, t;
00259 struct addr a, b;
00260
00261 memset(&a, 0, sizeof(a));
00262 ADDR_PACK(&a, htonl(0x01020304));
00263 memcpy(&b, &a, sizeof(&b));
00264 SIN_PACK(&s, htonl(0x01020304), 0);
00265 memcpy(&t, &s, sizeof(&t));
00266
00267 addr_ston((SA *)&s, &b);
00268 fail_unless(memcmp(&a, &b, sizeof(a)) == 0, "bad addr");
00269 #ifdef HAVE_SOCKADDR_SA_LEN
00270 s.sin_len = 0;
00271 fail_unless(addr_ston((SA *)&s, &b) == 0 && addr_cmp(&a, &b) == 0,
00272 "sin_len == 0");
00273 #endif
00274 s.sin_family = 123;
00275 fail_unless(addr_ston((SA *)&s, &b) < 0, "sin_family == 123");
00276 }
00277 END_TEST
00278
00279 START_TEST(test_addr_btos)
00280 {
00281 struct sockaddr s;
00282 struct addr a;
00283
00284 ADDR_PACK(&a, htonl(0xffffff00));
00285 a.addr_bits = 24;
00286 fail_unless(addr_btos(a.addr_bits, &s) == 0, "b0rked");
00287 }
00288 END_TEST
00289
00290 START_TEST(test_addr_stob)
00291 {
00292 struct sockaddr_in s;
00293 struct addr a;
00294
00295 SIN_PACK(&s, htonl(0xffffff00), 0);
00296 addr_stob((SA *)&s, &a.addr_bits);
00297 fail_unless(a.addr_bits == 24, "b0rked");
00298
00299 s.sin_family = 0;
00300 fail_unless(addr_stob((SA *)&s, &a.addr_bits) == 0 &&
00301 a.addr_bits == 24, "sin_family = 0");
00302 }
00303 END_TEST
00304
00305 START_TEST(test_addr_btom)
00306 {
00307 struct addr a;
00308 uint32_t mask;
00309
00310 ADDR_PACK(&a, htonl(0xffffff00));
00311 a.addr_bits = 24;
00312 addr_btom(a.addr_bits, &mask, sizeof(mask));
00313 fail_unless(mask == htonl(0xffffff00), "b0rked");
00314 }
00315 END_TEST
00316
00317 START_TEST(test_addr_mtob)
00318 {
00319 struct addr a;
00320 uint32_t mask;
00321
00322 mask = htonl(0xffffff00);
00323 addr_mtob(&mask, sizeof(mask), &a.addr_bits);
00324 fail_unless(a.addr_bits == 24, "b0rked");
00325 }
00326 END_TEST
00327
00328 Suite *
00329 addr_suite(void)
00330 {
00331 Suite *s = suite_create("addr");
00332 TCase *tc_core = tcase_create("core");
00333
00334 suite_add_tcase(s, tc_core);
00335 tcase_add_test(tc_core, test_addr_pack);
00336 tcase_add_test(tc_core, test_addr_cmp);
00337 tcase_add_test(tc_core, test_addr_bcast);
00338 tcase_add_test(tc_core, test_addr_net);
00339 tcase_add_test(tc_core, test_addr_ntop);
00340 tcase_add_test(tc_core, test_addr_pton);
00341 tcase_add_test(tc_core, test_addr_ntoa);
00342 tcase_add_test(tc_core, test_addr_ntos);
00343 tcase_add_test(tc_core, test_addr_ston);
00344 tcase_add_test(tc_core, test_addr_btos);
00345 tcase_add_test(tc_core, test_addr_stob);
00346 tcase_add_test(tc_core, test_addr_btom);
00347 tcase_add_test(tc_core, test_addr_mtob);
00348
00349 return (s);
00350 }
00351
00352 int
00353 main(void)
00354 {
00355 Suite *s = addr_suite();
00356 SRunner *sr = srunner_create(s);
00357 int nf;
00358
00359 srunner_run_all (sr, CK_NORMAL);
00360 nf = srunner_ntests_failed(sr);
00361 srunner_free(sr);
00362
00363 return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
00364 }