2010-10-21 18:11:50 +00:00
|
|
|
/*
|
|
|
|
* sockettest.c: Testing for src/util/network.c APIs
|
|
|
|
*
|
2015-05-22 21:32:02 +00:00
|
|
|
* Copyright (C) 2010-2011, 2014, 2015 Red Hat, Inc.
|
2010-10-21 18:11:50 +00:00
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
2012-09-20 22:30:55 +00:00
|
|
|
* License along with this library. If not, see
|
2012-07-21 10:06:23 +00:00
|
|
|
* <http://www.gnu.org/licenses/>.
|
2010-10-21 18:11:50 +00:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
Split src/util/network.{c,h} into 5 pieces
The src/util/network.c file is a dumping ground for many different
APIs. Split it up into 5 pieces, along functional lines
- src/util/virnetdevbandwidth.c: virNetDevBandwidth type & helper APIs
- src/util/virnetdevvportprofile.c: virNetDevVPortProfile type & helper APIs
- src/util/virsocketaddr.c: virSocketAddr and APIs
- src/conf/netdev_bandwidth_conf.c: XML parsing / formatting
for virNetDevBandwidth
- src/conf/netdev_vport_profile_conf.c: XML parsing / formatting
for virNetDevVPortProfile
* src/util/network.c, src/util/network.h: Split into 5 pieces
* src/conf/netdev_bandwidth_conf.c, src/conf/netdev_bandwidth_conf.h,
src/conf/netdev_vport_profile_conf.c, src/conf/netdev_vport_profile_conf.h,
src/util/virnetdevbandwidth.c, src/util/virnetdevbandwidth.h,
src/util/virnetdevvportprofile.c, src/util/virnetdevvportprofile.h,
src/util/virsocketaddr.c, src/util/virsocketaddr.h: New pieces
* daemon/libvirtd.h, daemon/remote.c, src/conf/domain_conf.c,
src/conf/domain_conf.h, src/conf/network_conf.c,
src/conf/network_conf.h, src/conf/nwfilter_conf.h,
src/esx/esx_util.h, src/network/bridge_driver.c,
src/qemu/qemu_conf.c, src/rpc/virnetsocket.c,
src/rpc/virnetsocket.h, src/util/dnsmasq.h, src/util/interface.h,
src/util/iptables.h, src/util/macvtap.c, src/util/macvtap.h,
src/util/virnetdev.h, src/util/virnetdevtap.c,
tools/virsh.c: Update include files
2011-11-02 15:40:08 +00:00
|
|
|
#include "virsocketaddr.h"
|
2010-10-21 18:11:50 +00:00
|
|
|
#include "testutils.h"
|
2012-12-12 17:59:27 +00:00
|
|
|
#include "virlog.h"
|
2012-12-12 18:06:53 +00:00
|
|
|
#include "viralloc.h"
|
2010-10-21 18:11:50 +00:00
|
|
|
|
2014-02-28 12:16:17 +00:00
|
|
|
VIR_LOG_INIT("tests.sockettest");
|
|
|
|
|
2010-10-21 18:11:50 +00:00
|
|
|
static int testParse(virSocketAddr *addr, const char *addrstr, int family, bool pass)
|
|
|
|
{
|
|
|
|
int rc;
|
|
|
|
|
Santize naming of socket address APIs
The socket address APIs in src/util/network.h either take the
form virSocketAddrXXX, virSocketXXX or virSocketXXXAddr.
Sanitize this so everything is virSocketAddrXXXX, and ensure
that the virSocketAddr parameter is always the first one.
* src/util/network.c, src/util/network.h: Santize socket
address API naming
* src/conf/domain_conf.c, src/conf/network_conf.c,
src/conf/nwfilter_conf.c, src/network/bridge_driver.c,
src/nwfilter/nwfilter_ebiptables_driver.c,
src/nwfilter/nwfilter_learnipaddr.c,
src/qemu/qemu_command.c, src/rpc/virnetsocket.c,
src/util/dnsmasq.c, src/util/iptables.c,
src/util/virnetdev.c, src/vbox/vbox_tmpl.c: Update for
API renaming
2011-11-02 14:06:59 +00:00
|
|
|
rc = virSocketAddrParse(addr, addrstr, family);
|
2010-10-21 18:11:50 +00:00
|
|
|
|
|
|
|
if (rc < 0)
|
|
|
|
return pass ? -1 : 0;
|
|
|
|
else
|
|
|
|
return pass ? 0 : -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int testFormat(virSocketAddr *addr, const char *addrstr, bool pass)
|
|
|
|
{
|
|
|
|
char *newaddrstr;
|
|
|
|
|
Santize naming of socket address APIs
The socket address APIs in src/util/network.h either take the
form virSocketAddrXXX, virSocketXXX or virSocketXXXAddr.
Sanitize this so everything is virSocketAddrXXXX, and ensure
that the virSocketAddr parameter is always the first one.
* src/util/network.c, src/util/network.h: Santize socket
address API naming
* src/conf/domain_conf.c, src/conf/network_conf.c,
src/conf/nwfilter_conf.c, src/network/bridge_driver.c,
src/nwfilter/nwfilter_ebiptables_driver.c,
src/nwfilter/nwfilter_learnipaddr.c,
src/qemu/qemu_command.c, src/rpc/virnetsocket.c,
src/util/dnsmasq.c, src/util/iptables.c,
src/util/virnetdev.c, src/vbox/vbox_tmpl.c: Update for
API renaming
2011-11-02 14:06:59 +00:00
|
|
|
newaddrstr = virSocketAddrFormat(addr);
|
2010-10-21 18:11:50 +00:00
|
|
|
if (!newaddrstr)
|
|
|
|
return pass ? -1 : 0;
|
|
|
|
|
|
|
|
if (STRNEQ(newaddrstr, addrstr)) {
|
2016-05-26 15:01:51 +00:00
|
|
|
virTestDifference(stderr, newaddrstr, addrstr);
|
2010-10-21 18:11:50 +00:00
|
|
|
VIR_FREE(newaddrstr);
|
|
|
|
return pass ? -1 : 0;
|
|
|
|
} else {
|
|
|
|
VIR_FREE(newaddrstr);
|
|
|
|
return pass ? 0 : -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct testParseData {
|
|
|
|
virSocketAddr *addr;
|
|
|
|
const char *addrstr;
|
|
|
|
int family;
|
|
|
|
bool pass;
|
|
|
|
};
|
|
|
|
static int testParseHelper(const void *opaque)
|
|
|
|
{
|
|
|
|
const struct testParseData *data = opaque;
|
|
|
|
return testParse(data->addr, data->addrstr, data->family, data->pass);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct testFormatData {
|
|
|
|
virSocketAddr *addr;
|
|
|
|
const char *addrstr;
|
|
|
|
bool pass;
|
|
|
|
};
|
|
|
|
static int testFormatHelper(const void *opaque)
|
|
|
|
{
|
|
|
|
const struct testFormatData *data = opaque;
|
|
|
|
return testFormat(data->addr, data->addrstr, data->pass);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-05-22 21:32:02 +00:00
|
|
|
static int
|
|
|
|
testRange(const char *saddrstr, const char *eaddrstr,
|
|
|
|
const char *netstr, int prefix, int size, bool pass)
|
2010-10-21 18:11:50 +00:00
|
|
|
{
|
|
|
|
virSocketAddr saddr;
|
|
|
|
virSocketAddr eaddr;
|
2015-05-22 21:32:02 +00:00
|
|
|
virSocketAddr netaddr;
|
2010-10-21 18:11:50 +00:00
|
|
|
|
Santize naming of socket address APIs
The socket address APIs in src/util/network.h either take the
form virSocketAddrXXX, virSocketXXX or virSocketXXXAddr.
Sanitize this so everything is virSocketAddrXXXX, and ensure
that the virSocketAddr parameter is always the first one.
* src/util/network.c, src/util/network.h: Santize socket
address API naming
* src/conf/domain_conf.c, src/conf/network_conf.c,
src/conf/nwfilter_conf.c, src/network/bridge_driver.c,
src/nwfilter/nwfilter_ebiptables_driver.c,
src/nwfilter/nwfilter_learnipaddr.c,
src/qemu/qemu_command.c, src/rpc/virnetsocket.c,
src/util/dnsmasq.c, src/util/iptables.c,
src/util/virnetdev.c, src/vbox/vbox_tmpl.c: Update for
API renaming
2011-11-02 14:06:59 +00:00
|
|
|
if (virSocketAddrParse(&saddr, saddrstr, AF_UNSPEC) < 0)
|
2010-10-21 18:11:50 +00:00
|
|
|
return -1;
|
Santize naming of socket address APIs
The socket address APIs in src/util/network.h either take the
form virSocketAddrXXX, virSocketXXX or virSocketXXXAddr.
Sanitize this so everything is virSocketAddrXXXX, and ensure
that the virSocketAddr parameter is always the first one.
* src/util/network.c, src/util/network.h: Santize socket
address API naming
* src/conf/domain_conf.c, src/conf/network_conf.c,
src/conf/nwfilter_conf.c, src/network/bridge_driver.c,
src/nwfilter/nwfilter_ebiptables_driver.c,
src/nwfilter/nwfilter_learnipaddr.c,
src/qemu/qemu_command.c, src/rpc/virnetsocket.c,
src/util/dnsmasq.c, src/util/iptables.c,
src/util/virnetdev.c, src/vbox/vbox_tmpl.c: Update for
API renaming
2011-11-02 14:06:59 +00:00
|
|
|
if (virSocketAddrParse(&eaddr, eaddrstr, AF_UNSPEC) < 0)
|
2010-10-21 18:11:50 +00:00
|
|
|
return -1;
|
2015-08-08 21:46:41 +00:00
|
|
|
if (netstr && virSocketAddrParse(&netaddr, netstr, AF_UNSPEC) < 0)
|
2015-05-22 21:32:02 +00:00
|
|
|
return -1;
|
2010-10-21 18:11:50 +00:00
|
|
|
|
2015-08-08 21:46:41 +00:00
|
|
|
int gotsize = virSocketAddrGetRange(&saddr, &eaddr,
|
|
|
|
netstr ? &netaddr : NULL, prefix);
|
2010-10-21 18:11:50 +00:00
|
|
|
VIR_DEBUG("Size want %d vs got %d", size, gotsize);
|
test: fix IP address range failure test
This was revealed when I made a cut-paste mistake in an upgrade to
virSocketAddrGetRange(), leading to failure to check for the end
address being outside of the defined network, but a negative test case
that should have caught the error instead returned success.
The problem was that testRange in sockettest.c was written so that
when it expected a failure, even an "unexpected success" would be
considered as an "expected failure" because of the way the check in
testRange was done. testRange had this:
if (gotsize < 0 || gotsize != size) {
return pass ? -1 : 0;
} else {
return pass ? 0 : -1;
}
but all the tests that expected a failure give "-1" as the expected
size. So in a case where we expect a failure, we would have pass ==
false and size == -1. If virSocketAddrGetRange() was incorrectly
*successful* (returned some positive number), then "gotsize != size"
would be, e.g. "276 != -1", so we would take the if clause and, since
pass == false, we would return 0 (success i.e. expected failure).
The solution is that in the case where we expect failure, we should
just ignore size - virSocketAddrGetRange() must return -1 in order for
us to report "expected failure == success".
Part of fix for: https://bugzilla.redhat.com/show_bug.cgi?id=985653
2015-06-01 16:18:01 +00:00
|
|
|
if (pass) {
|
|
|
|
/* fail if virSocketAddrGetRange returns failure, or unexpected size */
|
|
|
|
return (gotsize < 0 || gotsize != size) ? -1 : 0;
|
2010-10-21 18:11:50 +00:00
|
|
|
} else {
|
test: fix IP address range failure test
This was revealed when I made a cut-paste mistake in an upgrade to
virSocketAddrGetRange(), leading to failure to check for the end
address being outside of the defined network, but a negative test case
that should have caught the error instead returned success.
The problem was that testRange in sockettest.c was written so that
when it expected a failure, even an "unexpected success" would be
considered as an "expected failure" because of the way the check in
testRange was done. testRange had this:
if (gotsize < 0 || gotsize != size) {
return pass ? -1 : 0;
} else {
return pass ? 0 : -1;
}
but all the tests that expected a failure give "-1" as the expected
size. So in a case where we expect a failure, we would have pass ==
false and size == -1. If virSocketAddrGetRange() was incorrectly
*successful* (returned some positive number), then "gotsize != size"
would be, e.g. "276 != -1", so we would take the if clause and, since
pass == false, we would return 0 (success i.e. expected failure).
The solution is that in the case where we expect failure, we should
just ignore size - virSocketAddrGetRange() must return -1 in order for
us to report "expected failure == success".
Part of fix for: https://bugzilla.redhat.com/show_bug.cgi?id=985653
2015-06-01 16:18:01 +00:00
|
|
|
/* succeed if virSocketAddrGetRange fails, otherwise fail. */
|
|
|
|
return gotsize < 0 ? 0 : -1;
|
2010-10-21 18:11:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-22 21:32:02 +00:00
|
|
|
|
2010-10-21 18:11:50 +00:00
|
|
|
struct testRangeData {
|
|
|
|
const char *saddr;
|
|
|
|
const char *eaddr;
|
2015-05-22 21:32:02 +00:00
|
|
|
const char *netaddr;
|
|
|
|
int prefix;
|
2010-10-21 18:11:50 +00:00
|
|
|
int size;
|
|
|
|
bool pass;
|
|
|
|
};
|
2015-05-22 21:32:02 +00:00
|
|
|
|
|
|
|
|
2010-10-21 18:11:50 +00:00
|
|
|
static int testRangeHelper(const void *opaque)
|
|
|
|
{
|
|
|
|
const struct testRangeData *data = opaque;
|
2015-05-22 21:32:02 +00:00
|
|
|
return testRange(data->saddr, data->eaddr,
|
|
|
|
data->netaddr, data->prefix,
|
|
|
|
data->size, data->pass);
|
2010-10-21 18:11:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int testNetmask(const char *addr1str, const char *addr2str,
|
|
|
|
const char *netmaskstr, bool pass)
|
|
|
|
{
|
|
|
|
virSocketAddr addr1;
|
|
|
|
virSocketAddr addr2;
|
|
|
|
virSocketAddr netmask;
|
|
|
|
|
Santize naming of socket address APIs
The socket address APIs in src/util/network.h either take the
form virSocketAddrXXX, virSocketXXX or virSocketXXXAddr.
Sanitize this so everything is virSocketAddrXXXX, and ensure
that the virSocketAddr parameter is always the first one.
* src/util/network.c, src/util/network.h: Santize socket
address API naming
* src/conf/domain_conf.c, src/conf/network_conf.c,
src/conf/nwfilter_conf.c, src/network/bridge_driver.c,
src/nwfilter/nwfilter_ebiptables_driver.c,
src/nwfilter/nwfilter_learnipaddr.c,
src/qemu/qemu_command.c, src/rpc/virnetsocket.c,
src/util/dnsmasq.c, src/util/iptables.c,
src/util/virnetdev.c, src/vbox/vbox_tmpl.c: Update for
API renaming
2011-11-02 14:06:59 +00:00
|
|
|
if (virSocketAddrParse(&addr1, addr1str, AF_UNSPEC) < 0)
|
2010-10-21 18:11:50 +00:00
|
|
|
return -1;
|
Santize naming of socket address APIs
The socket address APIs in src/util/network.h either take the
form virSocketAddrXXX, virSocketXXX or virSocketXXXAddr.
Sanitize this so everything is virSocketAddrXXXX, and ensure
that the virSocketAddr parameter is always the first one.
* src/util/network.c, src/util/network.h: Santize socket
address API naming
* src/conf/domain_conf.c, src/conf/network_conf.c,
src/conf/nwfilter_conf.c, src/network/bridge_driver.c,
src/nwfilter/nwfilter_ebiptables_driver.c,
src/nwfilter/nwfilter_learnipaddr.c,
src/qemu/qemu_command.c, src/rpc/virnetsocket.c,
src/util/dnsmasq.c, src/util/iptables.c,
src/util/virnetdev.c, src/vbox/vbox_tmpl.c: Update for
API renaming
2011-11-02 14:06:59 +00:00
|
|
|
if (virSocketAddrParse(&addr2, addr2str, AF_UNSPEC) < 0)
|
2010-10-21 18:11:50 +00:00
|
|
|
return -1;
|
Santize naming of socket address APIs
The socket address APIs in src/util/network.h either take the
form virSocketAddrXXX, virSocketXXX or virSocketXXXAddr.
Sanitize this so everything is virSocketAddrXXXX, and ensure
that the virSocketAddr parameter is always the first one.
* src/util/network.c, src/util/network.h: Santize socket
address API naming
* src/conf/domain_conf.c, src/conf/network_conf.c,
src/conf/nwfilter_conf.c, src/network/bridge_driver.c,
src/nwfilter/nwfilter_ebiptables_driver.c,
src/nwfilter/nwfilter_learnipaddr.c,
src/qemu/qemu_command.c, src/rpc/virnetsocket.c,
src/util/dnsmasq.c, src/util/iptables.c,
src/util/virnetdev.c, src/vbox/vbox_tmpl.c: Update for
API renaming
2011-11-02 14:06:59 +00:00
|
|
|
if (virSocketAddrParse(&netmask, netmaskstr, AF_UNSPEC) < 0)
|
2010-10-21 18:11:50 +00:00
|
|
|
return -1;
|
|
|
|
|
Santize naming of socket address APIs
The socket address APIs in src/util/network.h either take the
form virSocketAddrXXX, virSocketXXX or virSocketXXXAddr.
Sanitize this so everything is virSocketAddrXXXX, and ensure
that the virSocketAddr parameter is always the first one.
* src/util/network.c, src/util/network.h: Santize socket
address API naming
* src/conf/domain_conf.c, src/conf/network_conf.c,
src/conf/nwfilter_conf.c, src/network/bridge_driver.c,
src/nwfilter/nwfilter_ebiptables_driver.c,
src/nwfilter/nwfilter_learnipaddr.c,
src/qemu/qemu_command.c, src/rpc/virnetsocket.c,
src/util/dnsmasq.c, src/util/iptables.c,
src/util/virnetdev.c, src/vbox/vbox_tmpl.c: Update for
API renaming
2011-11-02 14:06:59 +00:00
|
|
|
int ret = virSocketAddrCheckNetmask(&addr1, &addr2, &netmask);
|
2010-10-21 18:11:50 +00:00
|
|
|
|
|
|
|
if (ret <= 0) {
|
|
|
|
return pass ? -1 : 0;
|
|
|
|
} else {
|
|
|
|
return pass ? 0 : -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct testNetmaskData {
|
|
|
|
const char *addr1;
|
|
|
|
const char *addr2;
|
|
|
|
const char *netmask;
|
|
|
|
bool pass;
|
|
|
|
};
|
|
|
|
static int testNetmaskHelper(const void *opaque)
|
|
|
|
{
|
|
|
|
const struct testNetmaskData *data = opaque;
|
|
|
|
return testNetmask(data->addr1, data->addr2, data->netmask, data->pass);
|
|
|
|
}
|
|
|
|
|
2014-03-20 10:31:37 +00:00
|
|
|
|
|
|
|
|
|
|
|
static int testMaskNetwork(const char *addrstr,
|
|
|
|
int prefix,
|
|
|
|
const char *networkstr)
|
|
|
|
{
|
|
|
|
virSocketAddr addr;
|
|
|
|
virSocketAddr network;
|
|
|
|
char *gotnet = NULL;
|
|
|
|
|
|
|
|
/* Intentionally fill with garbage */
|
|
|
|
memset(&network, 1, sizeof(network));
|
|
|
|
|
|
|
|
if (virSocketAddrParse(&addr, addrstr, AF_UNSPEC) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (virSocketAddrMaskByPrefix(&addr, prefix, &network) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (!(gotnet = virSocketAddrFormat(&network)))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (STRNEQ(networkstr, gotnet)) {
|
|
|
|
VIR_FREE(gotnet);
|
|
|
|
fprintf(stderr, "Expected %s, got %s\n", networkstr, gotnet);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
VIR_FREE(gotnet);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct testMaskNetworkData {
|
|
|
|
const char *addr1;
|
|
|
|
int prefix;
|
|
|
|
const char *network;
|
|
|
|
};
|
|
|
|
static int testMaskNetworkHelper(const void *opaque)
|
|
|
|
{
|
|
|
|
const struct testMaskNetworkData *data = opaque;
|
|
|
|
return testMaskNetwork(data->addr1, data->prefix, data->network);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-06-06 13:50:01 +00:00
|
|
|
static int testWildcard(const char *addrstr,
|
|
|
|
bool pass)
|
|
|
|
{
|
|
|
|
virSocketAddr addr;
|
|
|
|
|
|
|
|
if (virSocketAddrParse(&addr, addrstr, AF_UNSPEC) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (virSocketAddrIsWildcard(&addr))
|
|
|
|
return pass ? 0 : -1;
|
|
|
|
return pass ? -1 : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct testWildcardData {
|
|
|
|
const char *addr;
|
|
|
|
bool pass;
|
|
|
|
};
|
|
|
|
static int testWildcardHelper(const void *opaque)
|
|
|
|
{
|
|
|
|
const struct testWildcardData *data = opaque;
|
|
|
|
return testWildcard(data->addr, data->pass);
|
|
|
|
}
|
2010-10-21 18:11:50 +00:00
|
|
|
|
2014-10-07 04:07:30 +00:00
|
|
|
struct testNumericData {
|
2013-10-09 13:10:02 +00:00
|
|
|
const char *addr;
|
2014-10-07 04:07:30 +00:00
|
|
|
int expected;
|
2013-10-09 13:10:02 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static int
|
2014-10-07 04:07:30 +00:00
|
|
|
testNumericHelper(const void *opaque)
|
2013-10-09 13:10:02 +00:00
|
|
|
{
|
2014-10-07 04:07:30 +00:00
|
|
|
const struct testNumericData *data = opaque;
|
2013-10-09 13:10:02 +00:00
|
|
|
|
2014-10-07 04:07:30 +00:00
|
|
|
if (virSocketAddrNumericFamily(data->addr) != data->expected)
|
|
|
|
return -1;
|
|
|
|
return 0;
|
2013-10-09 13:10:02 +00:00
|
|
|
}
|
|
|
|
|
2014-10-07 04:07:31 +00:00
|
|
|
struct testIsLocalhostData {
|
|
|
|
const char *addr;
|
|
|
|
bool result;
|
|
|
|
};
|
|
|
|
|
|
|
|
static int
|
|
|
|
testIsLocalhostHelper(const void *opaque)
|
|
|
|
{
|
|
|
|
const struct testIsLocalhostData *data = opaque;
|
|
|
|
|
|
|
|
if (virSocketAddrIsNumericLocalhost(data->addr) != data->result)
|
|
|
|
return -1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-10-21 18:11:50 +00:00
|
|
|
static int
|
2011-04-29 16:21:20 +00:00
|
|
|
mymain(void)
|
2010-10-21 18:11:50 +00:00
|
|
|
{
|
|
|
|
int ret = 0;
|
|
|
|
/* Some of our tests deliberately test failure cases, so
|
|
|
|
* register a handler to stop error messages cluttering
|
|
|
|
* up display
|
|
|
|
*/
|
2016-05-26 15:02:00 +00:00
|
|
|
virTestQuiesceLibvirtErrors(false);
|
2010-10-21 18:11:50 +00:00
|
|
|
|
|
|
|
#define DO_TEST_PARSE_AND_FORMAT(addrstr, family, pass) \
|
|
|
|
do { \
|
|
|
|
virSocketAddr addr; \
|
|
|
|
struct testParseData data = { &addr, addrstr, family, pass }; \
|
|
|
|
memset(&addr, 0, sizeof(addr)); \
|
2016-05-26 15:01:50 +00:00
|
|
|
if (virTestRun("Test parse " addrstr " family " #family, \
|
|
|
|
testParseHelper, &data) < 0) \
|
2010-10-21 18:11:50 +00:00
|
|
|
ret = -1; \
|
|
|
|
struct testFormatData data2 = { &addr, addrstr, pass }; \
|
2016-05-26 15:01:50 +00:00
|
|
|
if (virTestRun("Test format " addrstr " family " #family, \
|
|
|
|
testFormatHelper, &data2) < 0) \
|
2010-10-21 18:11:50 +00:00
|
|
|
ret = -1; \
|
|
|
|
} while (0)
|
|
|
|
|
qemu: Reformat listen address prior to checking
Currently, a listen address for a SPICE server can be specified. Later,
when the domain is migrated, we need to relocate the graphics which
involves telling new destination to the SPICE server. However, we can't
just assume the listen address is the new location, because the listen
address can be ANYCAST (0.0.0.0 for IPv4, :: for IPv6). In which case,
we want to pass the remote hostname. But there are some troubles with
ANYCAST. In both IPv4 and IPv6 it has many ways for specifying such
address. For instance, in IPv4: 0, 0.0, 0.0.0, 0.0.0.0. The number of
variations gets bigger in IPv6 world. Hence, in order to check for
ANYCAST address sanely, we should take the provided listen address,
parse it and format back in it's full form. Which is exactly what this
patch does.
2013-06-05 15:05:50 +00:00
|
|
|
#define DO_TEST_PARSE_AND_CHECK_FORMAT(addrstr, addrformated, family, pass) \
|
2016-05-26 15:01:50 +00:00
|
|
|
do { \
|
|
|
|
virSocketAddr addr; \
|
|
|
|
struct testParseData data = { &addr, addrstr, family, true}; \
|
|
|
|
memset(&addr, 0, sizeof(addr)); \
|
|
|
|
if (virTestRun("Test parse " addrstr " family " #family, \
|
|
|
|
testParseHelper, &data) < 0) \
|
|
|
|
ret = -1; \
|
|
|
|
struct testFormatData data2 = { &addr, addrformated, pass }; \
|
|
|
|
if (virTestRun("Test format " addrstr " family " #family, \
|
|
|
|
testFormatHelper, &data2) < 0) \
|
|
|
|
ret = -1; \
|
qemu: Reformat listen address prior to checking
Currently, a listen address for a SPICE server can be specified. Later,
when the domain is migrated, we need to relocate the graphics which
involves telling new destination to the SPICE server. However, we can't
just assume the listen address is the new location, because the listen
address can be ANYCAST (0.0.0.0 for IPv4, :: for IPv6). In which case,
we want to pass the remote hostname. But there are some troubles with
ANYCAST. In both IPv4 and IPv6 it has many ways for specifying such
address. For instance, in IPv4: 0, 0.0, 0.0.0, 0.0.0.0. The number of
variations gets bigger in IPv6 world. Hence, in order to check for
ANYCAST address sanely, we should take the provided listen address,
parse it and format back in it's full form. Which is exactly what this
patch does.
2013-06-05 15:05:50 +00:00
|
|
|
} while (0)
|
|
|
|
|
2015-05-22 21:32:02 +00:00
|
|
|
#define DO_TEST_RANGE(saddr, eaddr, netaddr, prefix, size, pass) \
|
2010-10-21 18:11:50 +00:00
|
|
|
do { \
|
2015-05-22 21:32:02 +00:00
|
|
|
struct testRangeData data \
|
|
|
|
= { saddr, eaddr, netaddr, prefix, size, pass }; \
|
2016-05-26 15:01:50 +00:00
|
|
|
if (virTestRun("Test range " saddr " -> " eaddr "(" netaddr \
|
|
|
|
"/" #prefix") size " #size, \
|
|
|
|
testRangeHelper, &data) < 0) \
|
2010-10-21 18:11:50 +00:00
|
|
|
ret = -1; \
|
|
|
|
} while (0)
|
|
|
|
|
2015-08-08 21:46:41 +00:00
|
|
|
#define DO_TEST_RANGE_SIMPLE(saddr, eaddr, size, pass) \
|
|
|
|
do { \
|
|
|
|
struct testRangeData data \
|
|
|
|
= { saddr, eaddr, NULL, 0, size, pass }; \
|
2016-05-26 15:01:50 +00:00
|
|
|
if (virTestRun("Test range " saddr " -> " eaddr "size " #size, \
|
|
|
|
testRangeHelper, &data) < 0) \
|
2015-08-08 21:46:41 +00:00
|
|
|
ret = -1; \
|
|
|
|
} while (0)
|
|
|
|
|
2016-05-26 15:01:50 +00:00
|
|
|
#define DO_TEST_NETMASK(addr1, addr2, netmask, pass) \
|
|
|
|
do { \
|
|
|
|
struct testNetmaskData data = { addr1, addr2, netmask, pass }; \
|
|
|
|
if (virTestRun("Test netmask " addr1 " + " addr2 " in " netmask, \
|
|
|
|
testNetmaskHelper, &data) < 0) \
|
|
|
|
ret = -1; \
|
2010-10-21 18:11:50 +00:00
|
|
|
} while (0)
|
|
|
|
|
2016-05-26 15:01:50 +00:00
|
|
|
#define DO_TEST_MASK_NETWORK(addr1, prefix, network) \
|
|
|
|
do { \
|
|
|
|
struct testMaskNetworkData data = { addr1, prefix, network }; \
|
|
|
|
if (virTestRun("Test mask network " addr1 " / " #prefix " == " network, \
|
|
|
|
testMaskNetworkHelper, &data) < 0) \
|
|
|
|
ret = -1; \
|
2014-03-20 10:31:37 +00:00
|
|
|
} while (0)
|
|
|
|
|
2013-06-06 13:50:01 +00:00
|
|
|
#define DO_TEST_WILDCARD(addr, pass) \
|
|
|
|
do { \
|
|
|
|
struct testWildcardData data = { addr, pass}; \
|
2016-05-26 15:01:50 +00:00
|
|
|
if (virTestRun("Test wildcard " addr, \
|
|
|
|
testWildcardHelper, &data) < 0) \
|
2013-06-06 13:50:01 +00:00
|
|
|
ret = -1; \
|
|
|
|
} while (0)
|
|
|
|
|
2014-10-07 04:07:30 +00:00
|
|
|
#define DO_TEST_NUMERIC_FAMILY(addr, pass) \
|
2013-10-09 13:10:02 +00:00
|
|
|
do { \
|
2014-10-07 04:07:30 +00:00
|
|
|
struct testNumericData data = { addr, pass }; \
|
2016-05-26 15:01:50 +00:00
|
|
|
if (virTestRun("Test Numeric Family" addr, \
|
2014-10-07 04:07:30 +00:00
|
|
|
testNumericHelper, &data) < 0) \
|
2013-10-09 13:10:02 +00:00
|
|
|
ret = -1; \
|
|
|
|
} while (0)
|
|
|
|
|
2014-10-07 04:07:31 +00:00
|
|
|
#define DO_TEST_LOCALHOST(addr, pass) \
|
|
|
|
do { \
|
|
|
|
struct testIsLocalhostData data = { addr, pass }; \
|
2016-05-26 15:01:50 +00:00
|
|
|
if (virTestRun("Test localhost " addr, \
|
2014-10-07 04:07:31 +00:00
|
|
|
testIsLocalhostHelper, &data) < 0) \
|
|
|
|
ret = -1; \
|
|
|
|
} while (0)
|
2010-10-21 18:11:50 +00:00
|
|
|
|
|
|
|
DO_TEST_PARSE_AND_FORMAT("127.0.0.1", AF_UNSPEC, true);
|
|
|
|
DO_TEST_PARSE_AND_FORMAT("127.0.0.1", AF_INET, true);
|
|
|
|
DO_TEST_PARSE_AND_FORMAT("127.0.0.1", AF_INET6, false);
|
|
|
|
DO_TEST_PARSE_AND_FORMAT("127.0.0.1", AF_UNIX, false);
|
|
|
|
DO_TEST_PARSE_AND_FORMAT("127.0.0.256", AF_UNSPEC, false);
|
|
|
|
|
qemu: Reformat listen address prior to checking
Currently, a listen address for a SPICE server can be specified. Later,
when the domain is migrated, we need to relocate the graphics which
involves telling new destination to the SPICE server. However, we can't
just assume the listen address is the new location, because the listen
address can be ANYCAST (0.0.0.0 for IPv4, :: for IPv6). In which case,
we want to pass the remote hostname. But there are some troubles with
ANYCAST. In both IPv4 and IPv6 it has many ways for specifying such
address. For instance, in IPv4: 0, 0.0, 0.0.0, 0.0.0.0. The number of
variations gets bigger in IPv6 world. Hence, in order to check for
ANYCAST address sanely, we should take the provided listen address,
parse it and format back in it's full form. Which is exactly what this
patch does.
2013-06-05 15:05:50 +00:00
|
|
|
DO_TEST_PARSE_AND_CHECK_FORMAT("127.0.0.2", "127.0.0.2", AF_INET, true);
|
|
|
|
DO_TEST_PARSE_AND_CHECK_FORMAT("127.0.0.2", "127.0.0.3", AF_INET, false);
|
|
|
|
DO_TEST_PARSE_AND_CHECK_FORMAT("0", "0.0.0.0", AF_INET, true);
|
|
|
|
DO_TEST_PARSE_AND_CHECK_FORMAT("127", "0.0.0.127", AF_INET, true);
|
|
|
|
DO_TEST_PARSE_AND_CHECK_FORMAT("127", "127.0.0.0", AF_INET, false);
|
|
|
|
DO_TEST_PARSE_AND_CHECK_FORMAT("127.2", "127.0.0.2", AF_INET, true);
|
|
|
|
DO_TEST_PARSE_AND_CHECK_FORMAT("127.2", "127.2.0.0", AF_INET, false);
|
|
|
|
DO_TEST_PARSE_AND_CHECK_FORMAT("1.2.3", "1.2.0.3", AF_INET, true);
|
|
|
|
DO_TEST_PARSE_AND_CHECK_FORMAT("1.2.3", "1.2.3.0", AF_INET, false);
|
|
|
|
|
2010-10-21 18:11:50 +00:00
|
|
|
DO_TEST_PARSE_AND_FORMAT("::1", AF_UNSPEC, true);
|
|
|
|
DO_TEST_PARSE_AND_FORMAT("::1", AF_INET, false);
|
|
|
|
DO_TEST_PARSE_AND_FORMAT("::1", AF_INET6, true);
|
|
|
|
DO_TEST_PARSE_AND_FORMAT("::1", AF_UNIX, false);
|
|
|
|
DO_TEST_PARSE_AND_FORMAT("::ffff", AF_UNSPEC, true);
|
|
|
|
|
2015-08-08 21:46:41 +00:00
|
|
|
/* tests that specify a network that should contain the range */
|
2015-05-22 21:32:02 +00:00
|
|
|
DO_TEST_RANGE("192.168.122.1", "192.168.122.1", "192.168.122.1", 24, 1, true);
|
|
|
|
DO_TEST_RANGE("192.168.122.1", "192.168.122.20", "192.168.122.22", 24, 20, true);
|
2015-08-08 21:46:41 +00:00
|
|
|
/* start of range is "network address" */
|
2015-05-22 21:32:02 +00:00
|
|
|
DO_TEST_RANGE("192.168.122.0", "192.168.122.254", "192.168.122.1", 24, -1, false);
|
2015-08-08 21:46:41 +00:00
|
|
|
/* end of range is "broadcast address" */
|
2015-05-22 21:32:02 +00:00
|
|
|
DO_TEST_RANGE("192.168.122.1", "192.168.122.255", "192.168.122.1", 24, -1, false);
|
|
|
|
DO_TEST_RANGE("192.168.122.0", "192.168.122.255", "192.168.122.1", 16, 256, true);
|
2015-08-08 21:46:41 +00:00
|
|
|
/* range is reversed */
|
2015-05-22 21:32:02 +00:00
|
|
|
DO_TEST_RANGE("192.168.122.20", "192.168.122.1", "192.168.122.1", 24, -1, false);
|
2015-08-08 21:46:41 +00:00
|
|
|
/* start address outside network */
|
2015-05-22 21:32:02 +00:00
|
|
|
DO_TEST_RANGE("10.0.0.1", "192.168.122.20", "192.168.122.1", 24, -1, false);
|
2015-08-08 21:46:41 +00:00
|
|
|
/* end address outside network and range reversed */
|
2015-05-22 21:32:02 +00:00
|
|
|
DO_TEST_RANGE("192.168.122.20", "10.0.0.1", "192.168.122.1", 24, -1, false);
|
2015-08-08 21:46:41 +00:00
|
|
|
/* entire range outside network */
|
2015-05-22 21:32:02 +00:00
|
|
|
DO_TEST_RANGE("172.16.0.50", "172.16.0.254", "1.2.3.4", 8, -1, false);
|
2015-08-08 21:46:41 +00:00
|
|
|
/* end address outside network */
|
2015-05-22 21:32:02 +00:00
|
|
|
DO_TEST_RANGE("192.168.122.1", "192.168.123.20", "192.168.122.22", 24, -1, false);
|
|
|
|
DO_TEST_RANGE("192.168.122.1", "192.168.123.20", "192.168.122.22", 23, 276, true);
|
|
|
|
|
|
|
|
DO_TEST_RANGE("2000::1", "2000::1", "2000::1", 64, 1, true);
|
|
|
|
DO_TEST_RANGE("2000::1", "2000::2", "2000::1", 64, 2, true);
|
2015-08-08 21:46:41 +00:00
|
|
|
/* range reversed */
|
2015-05-22 21:32:02 +00:00
|
|
|
DO_TEST_RANGE("2000::2", "2000::1", "2000::1", 64, -1, false);
|
2015-08-08 21:46:41 +00:00
|
|
|
/* range too large (> 65536) */
|
2015-05-22 21:32:02 +00:00
|
|
|
DO_TEST_RANGE("2000::1", "9001::1", "2000::1", 64, -1, false);
|
2010-10-21 18:11:50 +00:00
|
|
|
|
2015-08-08 21:46:41 +00:00
|
|
|
/* tests that *don't* specify a containing network
|
|
|
|
* (so fewer things can be checked)
|
|
|
|
*/
|
|
|
|
DO_TEST_RANGE_SIMPLE("192.168.122.1", "192.168.122.1", 1, true);
|
|
|
|
DO_TEST_RANGE_SIMPLE("192.168.122.1", "192.168.122.20", 20, true);
|
|
|
|
DO_TEST_RANGE_SIMPLE("192.168.122.0", "192.168.122.255", 256, true);
|
|
|
|
/* range is reversed */
|
|
|
|
DO_TEST_RANGE_SIMPLE("192.168.122.20", "192.168.122.1", -1, false);
|
|
|
|
/* range too large (> 65536) */
|
|
|
|
DO_TEST_RANGE_SIMPLE("10.0.0.1", "192.168.122.20", -1, false);
|
|
|
|
/* range reversed */
|
|
|
|
DO_TEST_RANGE_SIMPLE("192.168.122.20", "10.0.0.1", -1, false);
|
|
|
|
DO_TEST_RANGE_SIMPLE("172.16.0.50", "172.16.0.254", 205, true);
|
|
|
|
DO_TEST_RANGE_SIMPLE("192.168.122.1", "192.168.123.20", 276, true);
|
|
|
|
|
|
|
|
DO_TEST_RANGE_SIMPLE("2000::1", "2000::1", 1, true);
|
|
|
|
DO_TEST_RANGE_SIMPLE("2000::1", "2000::2", 2, true);
|
|
|
|
/* range reversed */
|
|
|
|
DO_TEST_RANGE_SIMPLE("2000::2", "2000::1", -1, false);
|
|
|
|
/* range too large (> 65536) */
|
|
|
|
DO_TEST_RANGE_SIMPLE("2000::1", "9001::1", -1, false);
|
|
|
|
|
2010-10-21 18:11:50 +00:00
|
|
|
DO_TEST_NETMASK("192.168.122.1", "192.168.122.2",
|
|
|
|
"255.255.255.0", true);
|
|
|
|
DO_TEST_NETMASK("192.168.122.1", "192.168.122.4",
|
|
|
|
"255.255.255.248", true);
|
|
|
|
DO_TEST_NETMASK("192.168.122.1", "192.168.123.2",
|
|
|
|
"255.255.255.0", false);
|
|
|
|
DO_TEST_NETMASK("192.168.122.1", "192.168.123.2",
|
|
|
|
"255.255.0.0", true);
|
|
|
|
|
|
|
|
DO_TEST_NETMASK("2000::1:1", "2000::1:1",
|
|
|
|
"ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", true);
|
|
|
|
DO_TEST_NETMASK("2000::1:1", "2000::2:1",
|
|
|
|
"ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", false);
|
|
|
|
DO_TEST_NETMASK("2000::1:1", "2000::2:1",
|
|
|
|
"ffff:ffff:ffff:ffff:ffff:ffff:fff8:0", true);
|
|
|
|
DO_TEST_NETMASK("2000::1:1", "9000::1:1",
|
|
|
|
"ffff:ffff:ffff:ffff:ffff:ffff:ffff:0", false);
|
|
|
|
|
2014-03-20 10:31:37 +00:00
|
|
|
DO_TEST_MASK_NETWORK("2001:db8:ca2:2::1", 64, "2001:db8:ca2:2::");
|
|
|
|
|
2013-06-06 13:50:01 +00:00
|
|
|
DO_TEST_WILDCARD("0.0.0.0", true);
|
|
|
|
DO_TEST_WILDCARD("::", true);
|
|
|
|
DO_TEST_WILDCARD("0", true);
|
|
|
|
DO_TEST_WILDCARD("0.0", true);
|
|
|
|
DO_TEST_WILDCARD("0.0.0", true);
|
|
|
|
DO_TEST_WILDCARD("1", false);
|
|
|
|
DO_TEST_WILDCARD("0.1", false);
|
|
|
|
|
2014-10-07 04:07:30 +00:00
|
|
|
DO_TEST_NUMERIC_FAMILY("0.0.0.0", AF_INET);
|
|
|
|
DO_TEST_NUMERIC_FAMILY("::", AF_INET6);
|
|
|
|
DO_TEST_NUMERIC_FAMILY("1", AF_INET);
|
|
|
|
DO_TEST_NUMERIC_FAMILY("::ffff", AF_INET6);
|
|
|
|
DO_TEST_NUMERIC_FAMILY("examplehost", -1);
|
2013-10-09 13:10:02 +00:00
|
|
|
|
2014-10-07 04:07:31 +00:00
|
|
|
DO_TEST_LOCALHOST("127.0.0.1", true);
|
|
|
|
DO_TEST_LOCALHOST("2130706433", true);
|
|
|
|
DO_TEST_LOCALHOST("0177.0.0.01", true);
|
|
|
|
DO_TEST_LOCALHOST("::1", true);
|
|
|
|
DO_TEST_LOCALHOST("0::1", true);
|
|
|
|
DO_TEST_LOCALHOST("0:0:0::1", true);
|
|
|
|
DO_TEST_LOCALHOST("[00:0::1]", false);
|
|
|
|
DO_TEST_LOCALHOST("[::1]", false);
|
|
|
|
DO_TEST_LOCALHOST("128.0.0.1", false);
|
|
|
|
DO_TEST_LOCALHOST("0.0.0.1", false);
|
|
|
|
DO_TEST_LOCALHOST("hello", false);
|
|
|
|
DO_TEST_LOCALHOST("fe80::1:1", false);
|
|
|
|
|
2014-03-17 09:38:38 +00:00
|
|
|
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
2010-10-21 18:11:50 +00:00
|
|
|
}
|
|
|
|
|
2017-03-29 14:45:42 +00:00
|
|
|
VIR_TEST_MAIN(mymain)
|