Main Page | Modules | Class List | Directories | File List | Class Members | File Members | Related Pages

check_addr.c

Go to the documentation of this file.
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         /* XXX - BSD routing sockets or SIOCGIFNETMASK */
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 }

Generated on Sun May 14 14:51:12 2006 by  doxygen 1.4.2