2 * sockettest.c: Testing for src/util/network.c APIs
4 * Copyright (C) 2010-2011, 2014, 2015 Red Hat, Inc.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library. If not, see
18 * <http://www.gnu.org/licenses/>.
25 #include "virsocketaddr.h"
26 #include "testutils.h"
30 VIR_LOG_INIT("tests.sockettest");
32 static int testParse(virSocketAddr
*addr
, const char *addrstr
, int family
, bool pass
)
36 rc
= virSocketAddrParse(addr
, addrstr
, family
);
44 static int testFormat(virSocketAddr
*addr
, const char *addrstr
, bool pass
)
48 newaddrstr
= virSocketAddrFormat(addr
);
52 if (STRNEQ(newaddrstr
, addrstr
)) {
53 virTestDifference(stderr
, addrstr
, newaddrstr
);
62 struct testParseData
{
68 static int testParseHelper(const void *opaque
)
70 const struct testParseData
*data
= opaque
;
71 return testParse(data
->addr
, data
->addrstr
, data
->family
, data
->pass
);
74 struct testFormatData
{
79 static int testFormatHelper(const void *opaque
)
81 const struct testFormatData
*data
= opaque
;
82 return testFormat(data
->addr
, data
->addrstr
, data
->pass
);
87 testRange(const char *saddrstr
, const char *eaddrstr
,
88 const char *netstr
, int prefix
, int size
, bool pass
)
92 virSocketAddr netaddr
;
94 if (virSocketAddrParse(&saddr
, saddrstr
, AF_UNSPEC
) < 0)
96 if (virSocketAddrParse(&eaddr
, eaddrstr
, AF_UNSPEC
) < 0)
98 if (netstr
&& virSocketAddrParse(&netaddr
, netstr
, AF_UNSPEC
) < 0)
101 int gotsize
= virSocketAddrGetRange(&saddr
, &eaddr
,
102 netstr
? &netaddr
: NULL
, prefix
);
103 VIR_DEBUG("Size want %d vs got %d", size
, gotsize
);
105 /* fail if virSocketAddrGetRange returns failure, or unexpected size */
106 return (gotsize
< 0 || gotsize
!= size
) ? -1 : 0;
108 /* succeed if virSocketAddrGetRange fails, otherwise fail. */
109 return gotsize
< 0 ? 0 : -1;
114 struct testRangeData
{
124 static int testRangeHelper(const void *opaque
)
126 const struct testRangeData
*data
= opaque
;
127 return testRange(data
->saddr
, data
->eaddr
,
128 data
->netaddr
, data
->prefix
,
129 data
->size
, data
->pass
);
133 static int testNetmask(const char *addr1str
, const char *addr2str
,
134 const char *netmaskstr
, bool pass
)
138 virSocketAddr netmask
;
140 if (virSocketAddrParse(&addr1
, addr1str
, AF_UNSPEC
) < 0)
142 if (virSocketAddrParse(&addr2
, addr2str
, AF_UNSPEC
) < 0)
144 if (virSocketAddrParse(&netmask
, netmaskstr
, AF_UNSPEC
) < 0)
147 int ret
= virSocketAddrCheckNetmask(&addr1
, &addr2
, &netmask
);
150 return pass
? -1 : 0;
152 return pass
? 0 : -1;
156 struct testNetmaskData
{
162 static int testNetmaskHelper(const void *opaque
)
164 const struct testNetmaskData
*data
= opaque
;
165 return testNetmask(data
->addr1
, data
->addr2
, data
->netmask
, data
->pass
);
170 static int testMaskNetwork(const char *addrstr
,
172 const char *networkstr
)
175 virSocketAddr network
;
178 /* Intentionally fill with garbage */
179 memset(&network
, 1, sizeof(network
));
181 if (virSocketAddrParse(&addr
, addrstr
, AF_UNSPEC
) < 0)
184 if (virSocketAddrMaskByPrefix(&addr
, prefix
, &network
) < 0)
187 if (!(gotnet
= virSocketAddrFormat(&network
)))
190 if (STRNEQ(networkstr
, gotnet
)) {
192 fprintf(stderr
, "Expected %s, got %s\n", networkstr
, gotnet
);
199 struct testMaskNetworkData
{
204 static int testMaskNetworkHelper(const void *opaque
)
206 const struct testMaskNetworkData
*data
= opaque
;
207 return testMaskNetwork(data
->addr1
, data
->prefix
, data
->network
);
211 static int testWildcard(const char *addrstr
,
216 if (virSocketAddrParse(&addr
, addrstr
, AF_UNSPEC
) < 0)
219 if (virSocketAddrIsWildcard(&addr
))
220 return pass
? 0 : -1;
221 return pass
? -1 : 0;
224 struct testWildcardData
{
228 static int testWildcardHelper(const void *opaque
)
230 const struct testWildcardData
*data
= opaque
;
231 return testWildcard(data
->addr
, data
->pass
);
234 struct testNumericData
{
240 testNumericHelper(const void *opaque
)
242 const struct testNumericData
*data
= opaque
;
244 if (virSocketAddrNumericFamily(data
->addr
) != data
->expected
)
249 struct testIsLocalhostData
{
255 testIsLocalhostHelper(const void *opaque
)
257 const struct testIsLocalhostData
*data
= opaque
;
259 if (virSocketAddrIsNumericLocalhost(data
->addr
) != data
->result
)
268 /* Some of our tests deliberately test failure cases, so
269 * register a handler to stop error messages cluttering
272 virTestQuiesceLibvirtErrors(false);
274 #define DO_TEST_PARSE_AND_FORMAT(addrstr, family, pass) \
276 virSocketAddr addr; \
277 struct testParseData data = { &addr, addrstr, family, pass }; \
278 memset(&addr, 0, sizeof(addr)); \
279 if (virTestRun("Test parse " addrstr " family " #family, \
280 testParseHelper, &data) < 0) \
282 struct testFormatData data2 = { &addr, addrstr, pass }; \
283 if (virTestRun("Test format " addrstr " family " #family, \
284 testFormatHelper, &data2) < 0) \
288 #define DO_TEST_PARSE_AND_CHECK_FORMAT(addrstr, addrformated, family, pass) \
290 virSocketAddr addr; \
291 struct testParseData data = { &addr, addrstr, family, true}; \
292 memset(&addr, 0, sizeof(addr)); \
293 if (virTestRun("Test parse " addrstr " family " #family, \
294 testParseHelper, &data) < 0) \
296 struct testFormatData data2 = { &addr, addrformated, pass }; \
297 if (virTestRun("Test format " addrstr " family " #family, \
298 testFormatHelper, &data2) < 0) \
302 #define DO_TEST_RANGE(saddr, eaddr, netaddr, prefix, size, pass) \
304 struct testRangeData data \
305 = { saddr, eaddr, netaddr, prefix, size, pass }; \
306 if (virTestRun("Test range " saddr " -> " eaddr "(" netaddr \
307 "/" #prefix") size " #size, \
308 testRangeHelper, &data) < 0) \
312 #define DO_TEST_RANGE_SIMPLE(saddr, eaddr, size, pass) \
314 struct testRangeData data \
315 = { saddr, eaddr, NULL, 0, size, pass }; \
316 if (virTestRun("Test range " saddr " -> " eaddr "size " #size, \
317 testRangeHelper, &data) < 0) \
321 #define DO_TEST_NETMASK(addr1, addr2, netmask, pass) \
323 struct testNetmaskData data = { addr1, addr2, netmask, pass }; \
324 if (virTestRun("Test netmask " addr1 " + " addr2 " in " netmask, \
325 testNetmaskHelper, &data) < 0) \
329 #define DO_TEST_MASK_NETWORK(addr1, prefix, network) \
331 struct testMaskNetworkData data = { addr1, prefix, network }; \
332 if (virTestRun("Test mask network " addr1 " / " #prefix " == " network, \
333 testMaskNetworkHelper, &data) < 0) \
337 #define DO_TEST_WILDCARD(addr, pass) \
339 struct testWildcardData data = { addr, pass}; \
340 if (virTestRun("Test wildcard " addr, \
341 testWildcardHelper, &data) < 0) \
345 #define DO_TEST_NUMERIC_FAMILY(addr, pass) \
347 struct testNumericData data = { addr, pass }; \
348 if (virTestRun("Test Numeric Family" addr, \
349 testNumericHelper, &data) < 0) \
353 #define DO_TEST_LOCALHOST(addr, pass) \
355 struct testIsLocalhostData data = { addr, pass }; \
356 if (virTestRun("Test localhost " addr, \
357 testIsLocalhostHelper, &data) < 0) \
361 DO_TEST_PARSE_AND_FORMAT("127.0.0.1", AF_UNSPEC
, true);
362 DO_TEST_PARSE_AND_FORMAT("127.0.0.1", AF_INET
, true);
363 DO_TEST_PARSE_AND_FORMAT("127.0.0.1", AF_INET6
, false);
364 DO_TEST_PARSE_AND_FORMAT("127.0.0.1", AF_UNIX
, false);
365 DO_TEST_PARSE_AND_FORMAT("127.0.0.256", AF_UNSPEC
, false);
367 DO_TEST_PARSE_AND_CHECK_FORMAT("127.0.0.2", "127.0.0.2", AF_INET
, true);
368 DO_TEST_PARSE_AND_CHECK_FORMAT("127.0.0.2", "127.0.0.3", AF_INET
, false);
369 DO_TEST_PARSE_AND_CHECK_FORMAT("0", "0.0.0.0", AF_INET
, true);
370 DO_TEST_PARSE_AND_CHECK_FORMAT("127", "0.0.0.127", AF_INET
, true);
371 DO_TEST_PARSE_AND_CHECK_FORMAT("127", "127.0.0.0", AF_INET
, false);
372 DO_TEST_PARSE_AND_CHECK_FORMAT("127.2", "127.0.0.2", AF_INET
, true);
373 DO_TEST_PARSE_AND_CHECK_FORMAT("127.2", "127.2.0.0", AF_INET
, false);
374 DO_TEST_PARSE_AND_CHECK_FORMAT("1.2.3", "1.2.0.3", AF_INET
, true);
375 DO_TEST_PARSE_AND_CHECK_FORMAT("1.2.3", "1.2.3.0", AF_INET
, false);
377 DO_TEST_PARSE_AND_FORMAT("::1", AF_UNSPEC
, true);
378 DO_TEST_PARSE_AND_FORMAT("::1", AF_INET
, false);
379 DO_TEST_PARSE_AND_FORMAT("::1", AF_INET6
, true);
380 DO_TEST_PARSE_AND_FORMAT("::1", AF_UNIX
, false);
381 DO_TEST_PARSE_AND_FORMAT("::ffff", AF_UNSPEC
, true);
383 /* tests that specify a network that should contain the range */
384 DO_TEST_RANGE("192.168.122.1", "192.168.122.1", "192.168.122.1", 24, 1, true);
385 DO_TEST_RANGE("192.168.122.1", "192.168.122.20", "192.168.122.22", 24, 20, true);
386 /* start of range is "network address" */
387 DO_TEST_RANGE("192.168.122.0", "192.168.122.254", "192.168.122.1", 24, -1, false);
388 /* end of range is "broadcast address" */
389 DO_TEST_RANGE("192.168.122.1", "192.168.122.255", "192.168.122.1", 24, -1, false);
390 DO_TEST_RANGE("192.168.122.0", "192.168.122.255", "192.168.122.1", 16, 256, true);
391 /* range is reversed */
392 DO_TEST_RANGE("192.168.122.20", "192.168.122.1", "192.168.122.1", 24, -1, false);
393 /* start address outside network */
394 DO_TEST_RANGE("10.0.0.1", "192.168.122.20", "192.168.122.1", 24, -1, false);
395 /* end address outside network and range reversed */
396 DO_TEST_RANGE("192.168.122.20", "10.0.0.1", "192.168.122.1", 24, -1, false);
397 /* entire range outside network */
398 DO_TEST_RANGE("172.16.0.50", "172.16.0.254", "1.2.3.4", 8, -1, false);
399 /* end address outside network */
400 DO_TEST_RANGE("192.168.122.1", "192.168.123.20", "192.168.122.22", 24, -1, false);
401 DO_TEST_RANGE("192.168.122.1", "192.168.123.20", "192.168.122.22", 23, 276, true);
403 DO_TEST_RANGE("2000::1", "2000::1", "2000::1", 64, 1, true);
404 DO_TEST_RANGE("2000::1", "2000::2", "2000::1", 64, 2, true);
406 DO_TEST_RANGE("2000::2", "2000::1", "2000::1", 64, -1, false);
407 /* range too large (> 65536) */
408 DO_TEST_RANGE("2000::1", "9001::1", "2000::1", 64, -1, false);
410 /* tests that *don't* specify a containing network
411 * (so fewer things can be checked)
413 DO_TEST_RANGE_SIMPLE("192.168.122.1", "192.168.122.1", 1, true);
414 DO_TEST_RANGE_SIMPLE("192.168.122.1", "192.168.122.20", 20, true);
415 DO_TEST_RANGE_SIMPLE("192.168.122.0", "192.168.122.255", 256, true);
416 /* range is reversed */
417 DO_TEST_RANGE_SIMPLE("192.168.122.20", "192.168.122.1", -1, false);
418 /* range too large (> 65536) */
419 DO_TEST_RANGE_SIMPLE("10.0.0.1", "192.168.122.20", -1, false);
421 DO_TEST_RANGE_SIMPLE("192.168.122.20", "10.0.0.1", -1, false);
422 DO_TEST_RANGE_SIMPLE("172.16.0.50", "172.16.0.254", 205, true);
423 DO_TEST_RANGE_SIMPLE("192.168.122.1", "192.168.123.20", 276, true);
425 DO_TEST_RANGE_SIMPLE("2000::1", "2000::1", 1, true);
426 DO_TEST_RANGE_SIMPLE("2000::1", "2000::2", 2, true);
428 DO_TEST_RANGE_SIMPLE("2000::2", "2000::1", -1, false);
429 /* range too large (> 65536) */
430 DO_TEST_RANGE_SIMPLE("2000::1", "9001::1", -1, false);
432 DO_TEST_NETMASK("192.168.122.1", "192.168.122.2",
433 "255.255.255.0", true);
434 DO_TEST_NETMASK("192.168.122.1", "192.168.122.4",
435 "255.255.255.248", true);
436 DO_TEST_NETMASK("192.168.122.1", "192.168.123.2",
437 "255.255.255.0", false);
438 DO_TEST_NETMASK("192.168.122.1", "192.168.123.2",
439 "255.255.0.0", true);
441 DO_TEST_NETMASK("2000::1:1", "2000::1:1",
442 "ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", true);
443 DO_TEST_NETMASK("2000::1:1", "2000::2:1",
444 "ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", false);
445 DO_TEST_NETMASK("2000::1:1", "2000::2:1",
446 "ffff:ffff:ffff:ffff:ffff:ffff:fff8:0", true);
447 DO_TEST_NETMASK("2000::1:1", "9000::1:1",
448 "ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", false);
450 DO_TEST_MASK_NETWORK("2001:db8:ca2:2::1", 64, "2001:db8:ca2:2::");
452 DO_TEST_WILDCARD("0.0.0.0", true);
453 DO_TEST_WILDCARD("::", true);
454 DO_TEST_WILDCARD("0", true);
455 DO_TEST_WILDCARD("0.0", true);
456 DO_TEST_WILDCARD("0.0.0", true);
457 DO_TEST_WILDCARD("1", false);
458 DO_TEST_WILDCARD("0.1", false);
460 DO_TEST_NUMERIC_FAMILY("0.0.0.0", AF_INET
);
461 DO_TEST_NUMERIC_FAMILY("::", AF_INET6
);
462 DO_TEST_NUMERIC_FAMILY("1", AF_INET
);
463 DO_TEST_NUMERIC_FAMILY("::ffff", AF_INET6
);
464 DO_TEST_NUMERIC_FAMILY("examplehost", -1);
466 DO_TEST_LOCALHOST("127.0.0.1", true);
467 DO_TEST_LOCALHOST("2130706433", true);
468 DO_TEST_LOCALHOST("0177.0.0.01", true);
469 DO_TEST_LOCALHOST("::1", true);
470 DO_TEST_LOCALHOST("0::1", true);
471 DO_TEST_LOCALHOST("0:0:0::1", true);
472 DO_TEST_LOCALHOST("[00:0::1]", false);
473 DO_TEST_LOCALHOST("[::1]", false);
474 DO_TEST_LOCALHOST("128.0.0.1", false);
475 DO_TEST_LOCALHOST("0.0.0.1", false);
476 DO_TEST_LOCALHOST("hello", false);
477 DO_TEST_LOCALHOST("fe80::1:1", false);
479 return ret
== 0 ? EXIT_SUCCESS
: EXIT_FAILURE
;
482 VIR_TEST_MAIN(mymain
)