Example #1
0
    def test_validate_ip_address_with_leading_zero(self):
        ip_addr = '1.1.1.01'
        expected_msg = ("'%(data)s' is not an accepted IP address, "
                        "'%(ip)s' is recommended")
        msg = attributes._validate_ip_address(ip_addr)
        self.assertEqual(expected_msg % {
            "data": ip_addr,
            "ip": '1.1.1.1'
        }, msg)

        ip_addr = '1.1.1.011'
        msg = attributes._validate_ip_address(ip_addr)
        self.assertEqual(expected_msg % {
            "data": ip_addr,
            "ip": '1.1.1.11'
        }, msg)

        ip_addr = '1.1.1.09'
        msg = attributes._validate_ip_address(ip_addr)
        self.assertEqual(expected_msg % {
            "data": ip_addr,
            "ip": '1.1.1.9'
        }, msg)

        ip_addr = "fe80:0:0:0:0:0:0:0001"
        msg = attributes._validate_ip_address(ip_addr)
        self.assertIsNone(msg)
Example #2
0
def _validate_gbproutes(data, valid_values=None):
    # Shamelessly copied from Neutron, will pass even if nexthop is valid
    if not isinstance(data, list):
        msg = _("Invalid data format for hostroute: '%s'") % data
        LOG.debug(msg)
        return msg

    expected_keys = ['destination', 'nexthop']
    hostroutes = []
    for hostroute in data:
        msg = attr._verify_dict_keys(expected_keys, hostroute)
        if msg:
            LOG.debug(msg)
            return msg
        msg = attr._validate_subnet(hostroute['destination'])
        if msg:
            LOG.debug(msg)
            return msg
        if hostroute['nexthop'] is not None:
            msg = attr._validate_ip_address(hostroute['nexthop'])
        if msg:
            LOG.debug(msg)
            return msg
        if hostroute in hostroutes:
            msg = _("Duplicate hostroute '%s'") % hostroute
            LOG.debug(msg)
            return msg
        hostroutes.append(hostroute)
def _validate_gbproutes(data, valid_values=None):
    # Shamelessly copied from Neutron, will pass even if nexthop is valid
    if not isinstance(data, list):
        msg = _("Invalid data format for hostroute: '%s'") % data
        LOG.debug(msg)
        return msg

    expected_keys = ['destination', 'nexthop']
    hostroutes = []
    for hostroute in data:
        msg = attr._verify_dict_keys(expected_keys, hostroute)
        if msg:
            LOG.debug(msg)
            return msg
        msg = attr._validate_subnet(hostroute['destination'])
        if msg:
            LOG.debug(msg)
            return msg
        if hostroute['nexthop']:
            msg = attr._validate_ip_address(hostroute['nexthop'])
        if msg:
            LOG.debug(msg)
            return msg
        if hostroute in hostroutes:
            msg = _("Duplicate hostroute '%s'") % hostroute
            LOG.debug(msg)
            return msg
        hostroutes.append(hostroute)
Example #4
0
def _validate_allowed_address_pairs(address_pairs, valid_values=None):
    unique_check = {}
    for address_pair in address_pairs:
        # mac_address is optional, if not set we use the mac on the port
        if 'mac_address' in address_pair:
            msg = attr._validate_mac_address(address_pair['mac_address'])
            if msg:
                raise webob.exc.HTTPBadRequest(msg)
        if 'ip_address' not in address_pair:
            raise AllowedAddressPairsMissingIP()

        mac = address_pair.get('mac_address')
        ip_address = address_pair['ip_address']
        if (mac, ip_address) not in unique_check:
            unique_check[(mac, ip_address)] = None
        else:
            raise DuplicateAddressPairInRequest(mac_address=mac,
                                                ip_address=ip_address)

        invalid_attrs = set(address_pair.keys()) - set(
            ['mac_address', 'ip_address'])
        if invalid_attrs:
            msg = (_("Unrecognized attribute(s) '%s'") % ', '.join(
                set(address_pair.keys()) - set(['mac_address', 'ip_address'])))
            raise webob.exc.HTTPBadRequest(msg)

        if '/' in ip_address:
            msg = attr._validate_subnet(ip_address)
        else:
            msg = attr._validate_ip_address(ip_address)
        if msg:
            raise webob.exc.HTTPBadRequest(msg)
Example #5
0
def _validate_allowed_address_pairs(address_pairs, valid_values=None):
    unique_check = {}
    if len(address_pairs) > cfg.CONF.max_allowed_address_pair:
        raise AllowedAddressPairExhausted(quota=cfg.CONF.max_allowed_address_pair)

    for address_pair in address_pairs:
        # mac_address is optional, if not set we use the mac on the port
        if "mac_address" in address_pair:
            msg = attr._validate_mac_address(address_pair["mac_address"])
            if msg:
                raise webob.exc.HTTPBadRequest(msg)
        if "ip_address" not in address_pair:
            raise AllowedAddressPairsMissingIP()

        mac = address_pair.get("mac_address")
        ip_address = address_pair["ip_address"]
        if (mac, ip_address) not in unique_check:
            unique_check[(mac, ip_address)] = None
        else:
            raise DuplicateAddressPairInRequest(mac_address=mac, ip_address=ip_address)

        invalid_attrs = set(address_pair.keys()) - set(["mac_address", "ip_address"])
        if invalid_attrs:
            msg = _("Unrecognized attribute(s) '%s'") % ", ".join(
                set(address_pair.keys()) - set(["mac_address", "ip_address"])
            )
            raise webob.exc.HTTPBadRequest(msg)

        if "/" in ip_address:
            msg = attr._validate_subnet(ip_address)
        else:
            msg = attr._validate_ip_address(ip_address)
        if msg:
            raise webob.exc.HTTPBadRequest(msg)
Example #6
0
def _validate_allowed_address_pairs(address_pairs, valid_values=None):
    unique_check = {}
    for address_pair in address_pairs:
        # mac_address is optional, if not set we use the mac on the port
        if 'mac_address' in address_pair:
            msg = attr._validate_mac_address(address_pair['mac_address'])
            if msg:
                raise webob.exc.HTTPBadRequest(msg)
        if 'ip_address' not in address_pair:
            raise AllowedAddressPairsMissingIP()

        mac = address_pair.get('mac_address')
        ip_address = address_pair['ip_address']
        if (mac, ip_address) not in unique_check:
            unique_check[(mac, ip_address)] = None
        else:
            raise DuplicateAddressPairInRequest(mac_address=mac,
                                                ip_address=ip_address)

        invalid_attrs = set(address_pair.keys()) - set(['mac_address',
                                                        'ip_address'])
        if invalid_attrs:
            msg = (_("Unrecognized attribute(s) '%s'") %
                   ', '.join(set(address_pair.keys()) -
                             set(['mac_address', 'ip_address'])))
            raise webob.exc.HTTPBadRequest(msg)

        if '/' in ip_address:
            msg = attr._validate_subnet(ip_address)
        else:
            msg = attr._validate_ip_address(ip_address)
        if msg:
            raise webob.exc.HTTPBadRequest(msg)
Example #7
0
    def test_validate_ip_address_with_leading_zero(self):
        ip_addr = "1.1.1.01"
        expected_msg = "'%(data)s' is not an accepted IP address, " "'%(ip)s' is recommended"
        msg = attributes._validate_ip_address(ip_addr)
        self.assertEqual(expected_msg % {"data": ip_addr, "ip": "1.1.1.1"}, msg)

        ip_addr = "1.1.1.011"
        msg = attributes._validate_ip_address(ip_addr)
        self.assertEqual(expected_msg % {"data": ip_addr, "ip": "1.1.1.11"}, msg)

        ip_addr = "1.1.1.09"
        msg = attributes._validate_ip_address(ip_addr)
        self.assertEqual(expected_msg % {"data": ip_addr, "ip": "1.1.1.9"}, msg)

        ip_addr = "fe80:0:0:0:0:0:0:0001"
        msg = attributes._validate_ip_address(ip_addr)
        self.assertIsNone(msg)
Example #8
0
    def test_validate_ip_address(self):
        ip_addr = '1.1.1.1'
        msg = attributes._validate_ip_address(ip_addr)
        self.assertIsNone(msg)

        ip_addr = '1111.1.1.1'
        msg = attributes._validate_ip_address(ip_addr)
        self.assertEqual(msg, "'%s' is not a valid IP address" % ip_addr)

        ip_addr = '1.1.1.1 has whitespace'
        msg = attributes._validate_ip_address(ip_addr)
        self.assertEqual(msg, "'%s' is not a valid IP address" % ip_addr)

        ip_addr = '111.1.1.1\twhitespace'
        msg = attributes._validate_ip_address(ip_addr)
        self.assertEqual(msg, "'%s' is not a valid IP address" % ip_addr)

        ip_addr = '111.1.1.1\nwhitespace'
        msg = attributes._validate_ip_address(ip_addr)
        self.assertEqual(msg, "'%s' is not a valid IP address" % ip_addr)

        for ws in string.whitespace:
            ip_addr = '%s111.1.1.1' % ws
            msg = attributes._validate_ip_address(ip_addr)
            self.assertEqual(msg, "'%s' is not a valid IP address" % ip_addr)

        for ws in string.whitespace:
            ip_addr = '111.1.1.1%s' % ws
            msg = attributes._validate_ip_address(ip_addr)
            self.assertEqual(msg, "'%s' is not a valid IP address" % ip_addr)
Example #9
0
    def test_validate_ip_address(self):
        ip_addr = '1.1.1.1'
        msg = attributes._validate_ip_address(ip_addr)
        self.assertIsNone(msg)

        ip_addr = '1111.1.1.1'
        msg = attributes._validate_ip_address(ip_addr)
        self.assertEqual(msg, "'%s' is not a valid IP address" % ip_addr)

        ip_addr = '1.1.1.1 has whitespace'
        msg = attributes._validate_ip_address(ip_addr)
        self.assertEqual(msg, "'%s' is not a valid IP address" % ip_addr)

        ip_addr = '111.1.1.1\twhitespace'
        msg = attributes._validate_ip_address(ip_addr)
        self.assertEqual(msg, "'%s' is not a valid IP address" % ip_addr)

        ip_addr = '111.1.1.1\nwhitespace'
        msg = attributes._validate_ip_address(ip_addr)
        self.assertEqual(msg, "'%s' is not a valid IP address" % ip_addr)

        for ws in string.whitespace:
            ip_addr = '%s111.1.1.1' % ws
            msg = attributes._validate_ip_address(ip_addr)
            self.assertEqual(msg, "'%s' is not a valid IP address" % ip_addr)

        for ws in string.whitespace:
            ip_addr = '111.1.1.1%s' % ws
            msg = attributes._validate_ip_address(ip_addr)
            self.assertEqual(msg, "'%s' is not a valid IP address" % ip_addr)
Example #10
0
def _validate_nexthops(nexthops):
    seen = []
    for ip in nexthops:
        msg = attr._validate_ip_address(ip)
        if ip in seen:
            msg = _("Duplicate nexthop in rule '%s'") % ip
        seen.append(ip)
        if msg:
            return msg
Example #11
0
def _validate_nexthops(nexthops):
    seen = []
    for ip in nexthops:
        msg = attr._validate_ip_address(ip)
        if ip in seen:
            msg = _("Duplicate nexthop in rule '%s'") % ip
        seen.append(ip)
        if msg:
            return msg
Example #12
0
def _validate_ip_or_subnet_or_none(data, valid_values=None):
    if data is None:
        return None
    msg_ip = attr._validate_ip_address(data, valid_values)
    if not msg_ip:
        return
    msg_subnet = attr._validate_subnet(data, valid_values)
    if not msg_subnet:
        return
    return _("%(msg_ip)s and %(msg_subnet)s") % {"msg_ip": msg_ip, "msg_subnet": msg_subnet}
 def test_validate_ip_address_bsd(self):
     # NOTE(yamamoto):  On NetBSD and OS X, netaddr.IPAddress() accepts
     # '1' * 59 as a valid address.  The behaviour is inherited from
     # libc behaviour there.  This test ensures that our validator reject
     # such addresses on such platforms by mocking netaddr to emulate
     # the behaviour.
     ip_addr = '1' * 59
     with mock.patch('netaddr.IPAddress') as ip_address_cls:
         msg = attributes._validate_ip_address(ip_addr)
     ip_address_cls.assert_called_once_with(ip_addr)
     self.assertEqual("'%s' is not a valid IP address" % ip_addr, msg)
Example #14
0
def _validate_ip_or_subnet_or_none(data, valid_values=None):
    if data is None:
        return None
    msg_ip = attr._validate_ip_address(data, valid_values)
    if not msg_ip:
        return
    msg_subnet = attr._validate_subnet(data, valid_values)
    if not msg_subnet:
        return
    return _("%(msg_ip)s and %(msg_subnet)s") % {'msg_ip': msg_ip,
                                                 'msg_subnet': msg_subnet}
Example #15
0
    def test_validate_ip_address(self):
        ip_addr = "1.1.1.1"
        msg = attributes._validate_ip_address(ip_addr)
        self.assertIsNone(msg)

        ip_addr = "1111.1.1.1"
        msg = attributes._validate_ip_address(ip_addr)
        self.assertEqual(msg, "'%s' is not a valid IP address" % ip_addr)

        ip_addr = "1.1.1.1 has whitespace"
        msg = attributes._validate_ip_address(ip_addr)
        self.assertEqual(msg, "'%s' is not a valid IP address" % ip_addr)

        ip_addr = "111.1.1.1\twhitespace"
        msg = attributes._validate_ip_address(ip_addr)
        self.assertEqual(msg, "'%s' is not a valid IP address" % ip_addr)

        ip_addr = "111.1.1.1\nwhitespace"
        msg = attributes._validate_ip_address(ip_addr)
        self.assertEqual(msg, "'%s' is not a valid IP address" % ip_addr)
Example #16
0
 def test_validate_ip_address_bsd(self):
     # NOTE(yamamoto):  On NetBSD and OS X, netaddr.IPAddress() accepts
     # '1' * 59 as a valid address.  The behaviour is inherited from
     # libc behaviour there.  This test ensures that our validator reject
     # such addresses on such platforms by mocking netaddr to emulate
     # the behaviour.
     ip_addr = '1' * 59
     with mock.patch('netaddr.IPAddress') as ip_address_cls:
         msg = attributes._validate_ip_address(ip_addr)
     ip_address_cls.assert_called_once_with(ip_addr)
     self.assertEqual("'%s' is not a valid IP address" % ip_addr, msg)
def _validate_ip_or_subnet_or_none(data, valid_values=None):
    if data is None:
        return None
    msg_ip = attributes._validate_ip_address(data, valid_values)
    if not msg_ip:
        return None
    msg_subnet = attributes._validate_subnet(data, valid_values)
    if not msg_subnet:
        return None
    return _("%(msg_ip)s and %(msg_subnet)s") % {'msg_ip': msg_ip,
                                                 'msg_subnet': msg_subnet}
Example #18
0
    def test_validate_ip_address(self):
        ip_addr = '1.1.1.1'
        msg = attributes._validate_ip_address(ip_addr)
        self.assertIsNone(msg)

        ip_addr = '1111.1.1.1'
        msg = attributes._validate_ip_address(ip_addr)
        self.assertEqual(msg, "'%s' is not a valid IP address" % ip_addr)

        # Depending on platform to run UTs, this case might or might not be
        # an equivalent to test_validate_ip_address_bsd.
        ip_addr = '1' * 59
        msg = attributes._validate_ip_address(ip_addr)
        self.assertEqual("'%s' is not a valid IP address" % ip_addr, msg)

        ip_addr = '1.1.1.1 has whitespace'
        msg = attributes._validate_ip_address(ip_addr)
        self.assertEqual(msg, "'%s' is not a valid IP address" % ip_addr)

        ip_addr = '111.1.1.1\twhitespace'
        msg = attributes._validate_ip_address(ip_addr)
        self.assertEqual(msg, "'%s' is not a valid IP address" % ip_addr)

        ip_addr = '111.1.1.1\nwhitespace'
        msg = attributes._validate_ip_address(ip_addr)
        self.assertEqual(msg, "'%s' is not a valid IP address" % ip_addr)
    def test_validate_ip_address(self):
        ip_addr = '1.1.1.1'
        msg = attributes._validate_ip_address(ip_addr)
        self.assertIsNone(msg)

        ip_addr = '1111.1.1.1'
        msg = attributes._validate_ip_address(ip_addr)
        self.assertEqual(msg, "'%s' is not a valid IP address" % ip_addr)

        # Depending on platform to run UTs, this case might or might not be
        # an equivalent to test_validate_ip_address_bsd.
        ip_addr = '1' * 59
        msg = attributes._validate_ip_address(ip_addr)
        self.assertEqual("'%s' is not a valid IP address" % ip_addr, msg)

        ip_addr = '1.1.1.1 has whitespace'
        msg = attributes._validate_ip_address(ip_addr)
        self.assertEqual(msg, "'%s' is not a valid IP address" % ip_addr)

        ip_addr = '111.1.1.1\twhitespace'
        msg = attributes._validate_ip_address(ip_addr)
        self.assertEqual(msg, "'%s' is not a valid IP address" % ip_addr)

        ip_addr = '111.1.1.1\nwhitespace'
        msg = attributes._validate_ip_address(ip_addr)
        self.assertEqual(msg, "'%s' is not a valid IP address" % ip_addr)
    def resolve_peer_address(self, ipsec_sitecon, router):
        address = ipsec_sitecon['peer_address']
        # check if address is an ip address or fqdn
        invalid_ip_address = attributes._validate_ip_address(address)
        if invalid_ip_address:
            # resolve fqdn
            try:
                addrinfo = socket.getaddrinfo(address, None)[0]
                ipsec_sitecon['peer_address'] = addrinfo[-1][0]
            except socket.gaierror:
                raise vpnaas.VPNPeerAddressNotResolved(peer_address=address)

        ip_version = netaddr.IPAddress(ipsec_sitecon['peer_address']).version
        self._validate_peer_address(ip_version, router)
Example #21
0
    def resolve_peer_address(self, ipsec_sitecon, router):
        address = ipsec_sitecon['peer_address']
        # check if address is an ip address or fqdn
        invalid_ip_address = attributes._validate_ip_address(address)
        if invalid_ip_address:
            # resolve fqdn
            try:
                addrinfo = socket.getaddrinfo(address, None)[0]
                ipsec_sitecon['peer_address'] = addrinfo[-1][0]
            except socket.gaierror:
                raise vpnaas.VPNPeerAddressNotResolved(peer_address=address)

        ip_version = netaddr.IPAddress(ipsec_sitecon['peer_address']).version
        self._validate_peer_address(ip_version, router)
Example #22
0
 def _get_nexthop(self, address, connection_id):
     # check if address is an ip address or fqdn
     invalid_ip_address = attributes._validate_ip_address(address)
     if invalid_ip_address:
         ip_addr = self._resolve_fqdn(address)
         if not ip_addr:
             self._record_connection_status(connection_id, constants.ERROR, force_status_update=True)
             raise vpnaas.VPNPeerAddressNotResolved(peer_address=address)
     else:
         ip_addr = address
     routes = self._execute(["ip", "route", "get", ip_addr])
     if routes.find("via") >= 0:
         return routes.split(" ")[2]
     return address
Example #23
0
 def _get_nexthop(self, address, connection_id):
     # check if address is an ip address or fqdn
     invalid_ip_address = attributes._validate_ip_address(address)
     if invalid_ip_address:
         ip_addr = self._resolve_fqdn(address)
         if not ip_addr:
             self._record_connection_status(connection_id, constants.ERROR,
                                            updated_pending_status=True)
             raise vpnaas.VPNPeerAddressNotResolved(peer_address=address)
     else:
         ip_addr = address
     routes = self._execute(['ip', 'route', 'get', ip_addr])
     if routes.find('via') >= 0:
         return routes.split(' ')[2]
     return address
Example #24
0
def _validate_port_dict(values):
    if not isinstance(values, dict):
        msg = _("%s is not a valid dictionary") % values
        LOG.debug(msg)
        return msg
    port_id = values.get('port_id')
    fixed_ip = values.get('fixed_ip_address')
    msg = attr._validate_uuid(port_id)
    if msg:
        return msg
    if fixed_ip is None:
        return
    msg = attr._validate_ip_address(fixed_ip)
    if msg:
        return msg
Example #25
0
 def _get_nexthop(self, address, connection_id):
     # check if address is an ip address or fqdn
     invalid_ip_address = attributes._validate_ip_address(address)
     if invalid_ip_address:
         ip_addr = self._resolve_fqdn(address)
         if not ip_addr:
             self._record_connection_status(connection_id, constants.ERROR,
                                            force_status_update=True)
             raise vpnaas.VPNPeerAddressNotResolved(peer_address=address)
     else:
         ip_addr = address
     routes = self._execute(['ip', 'route', 'get', ip_addr])
     if routes.find('via') >= 0:
         return routes.split(' ')[2]
     return address
Example #26
0
def _validate_port_dict(values):
    if not isinstance(values, dict):
        msg = _("%s is not a valid dictionary") % values
        LOG.debug(msg)
        return msg
    port_id = values.get('port_id')
    fixed_ip = values.get('fixed_ip_address')
    msg = attr._validate_uuid(port_id)
    if msg:
        return msg
    if fixed_ip is None:
        return
    msg = attr._validate_ip_address(fixed_ip)
    if msg:
        return msg
Example #27
0
def _validate_portforwardings(data, valid_values=None):
    if not isinstance(data, list):
        msg = _("Invalid data format for portforwarding: '%s'") % data
        raise webob.exc.HTTPBadRequest(msg)
#        LOG.debug(msg)
#        return msg

    expected_keys = ['protocol', 'outside_port', 'inside_addr', 'inside_port']
    portfwds = []
    for portfwd in data:
        msg = attributes._verify_dict_keys(expected_keys, portfwd)
        if msg:
            raise webob.exc.HTTPBadRequest(msg)
#            LOG.debug(msg)
#            return msg
#raise InvalidInput(portfwd=portfwd, msg=msg)
        msg = attributes._validate_range(portfwd['outside_port'], (0, 65535))
        if msg:
            raise webob.exc.HTTPBadRequest(msg)
#            LOG.debug(msg)
#            return msg
#raise InvalidPortValue(port=portfwd['outside_port'], msg=msg)
        msg = attributes._validate_ip_address(portfwd['inside_addr'])
        if msg:
            raise webob.exc.HTTPBadRequest(msg)
#            LOG.debug(msg)
#            return msg
        msg = attributes._validate_range(portfwd['inside_port'], (0, 65535))
        if msg:
            raise webob.exc.HTTPBadRequest(msg)
#            LOG.debug(msg)
#            return msg
#raise InvalidPortValue(portfwd['inside_port'], msg=msg)
        msg = attributes._validate_values(portfwd['protocol'].upper(),
                                          ('TCP', 'UDP'))
        if msg:
            raise webob.exc.HTTPBadRequest(msg)
#            LOG.debug(msg)
#            return msg
#raise InvalidProtocol(protocol=portfwd['protocol'].upper(), msg=msg)
        if portfwd in portfwds:
            raise DuplicatePortforwardingRuleInRequest(portfwds=portfwds)
Example #28
0
def _validate_allowed_address_pairs(address_pairs, valid_values=None):
    unique_check = {}
    if len(address_pairs) > cfg.CONF.max_allowed_address_pair:
        raise AllowedAddressPairExhausted(
            quota=cfg.CONF.max_allowed_address_pair)

    for address_pair in address_pairs:
        # mac_address is optional, if not set we use the mac on the port
        if 'mac_address' in address_pair:
            msg = attr._validate_mac_address(address_pair['mac_address'])
            if msg:
                raise webob.exc.HTTPBadRequest(msg)
        if 'ip_address' not in address_pair:
            raise AllowedAddressPairsMissingIP()

        mac = address_pair.get('mac_address')
        ip_address = address_pair['ip_address']
        if (mac, ip_address) not in unique_check:
            unique_check[(mac, ip_address)] = None
        else:
            raise DuplicateAddressPairInRequest(mac_address=mac,
                                                ip_address=ip_address)

        invalid_attrs = set(address_pair.keys()) - set(['mac_address',
                                                        'ip_address'])
        if invalid_attrs:
            msg = (_("Unrecognized attribute(s) '%s'") %
                   ', '.join(set(address_pair.keys()) -
                             set(['mac_address', 'ip_address'])))
            raise webob.exc.HTTPBadRequest(msg)

        if (netaddr.IPNetwork(ip_address).prefixlen == 0):
            raise AllowedAddressPairsZeroPrefixNotAllowed()
        elif '/' in ip_address:
            msg = attr._validate_subnet(ip_address)
        else:
            msg = attr._validate_ip_address(ip_address)
        if msg:
            raise webob.exc.HTTPBadRequest(msg)
Example #29
0
    def test_validate_ip_address(self):
        ip_addr = "1.1.1.1"
        msg = attributes._validate_ip_address(ip_addr)
        self.assertIsNone(msg)

        ip_addr = "1111.1.1.1"
        msg = attributes._validate_ip_address(ip_addr)
        self.assertEqual("'%s' is not a valid IP address" % ip_addr, msg)

        # Depending on platform to run UTs, this case might or might not be
        # an equivalent to test_validate_ip_address_bsd.
        ip_addr = "1" * 59
        msg = attributes._validate_ip_address(ip_addr)
        self.assertEqual("'%s' is not a valid IP address" % ip_addr, msg)

        ip_addr = "1.1.1.1 has whitespace"
        msg = attributes._validate_ip_address(ip_addr)
        self.assertEqual("'%s' is not a valid IP address" % ip_addr, msg)

        ip_addr = "111.1.1.1\twhitespace"
        msg = attributes._validate_ip_address(ip_addr)
        self.assertEqual("'%s' is not a valid IP address" % ip_addr, msg)

        ip_addr = "111.1.1.1\nwhitespace"
        msg = attributes._validate_ip_address(ip_addr)
        self.assertEqual("'%s' is not a valid IP address" % ip_addr, msg)

        for ws in string.whitespace:
            ip_addr = "%s111.1.1.1" % ws
            msg = attributes._validate_ip_address(ip_addr)
            self.assertEqual("'%s' is not a valid IP address" % ip_addr, msg)

        for ws in string.whitespace:
            ip_addr = "111.1.1.1%s" % ws
            msg = attributes._validate_ip_address(ip_addr)
            self.assertEqual("'%s' is not a valid IP address" % ip_addr, msg)