*: Reject Binary Represented IP Addresses

As a default, netaddr.valid_ipv4() uses the "aton" rule for its validation,
so valid_ipv4('2') and valid_ipv4('1.2.3') returns True.
It may cause unexpected behaviors.

This commit replaces netaddr.valid_ipv4() to ryu.lib.ip.valid_ipv4(),
which is wrapper of netaddr.valid_ipv4(), and use "pton" rule in the method.
So, address representation like '2' or '1.2.3' will be rejected.

Signed-off-by: Satoshi Fujimoto <satoshi.fujimoto7@gmail.com>
This commit is contained in:
Satoshi Fujimoto 2017-11-06 14:53:46 +09:00 committed by FUJITA Tomonori
parent 8185637767
commit 2599aef3bf
18 changed files with 69 additions and 76 deletions

View File

@ -45,6 +45,7 @@ from ryu.controller import ofp_event
from ryu.controller.handler import HANDSHAKE_DISPATCHER, DEAD_DISPATCHER
from ryu.lib.dpid import dpid_to_str
from ryu.lib import ip
LOG = logging.getLogger('ryu.controller.controller')
@ -110,9 +111,9 @@ def _split_addr(addr):
addr, port = pair
if addr.startswith('[') and addr.endswith(']'):
addr = addr.lstrip('[').rstrip(']')
if not netaddr.valid_ipv6(addr):
if not ip.valid_ipv6(addr):
raise e
elif not netaddr.valid_ipv4(addr):
elif not ip.valid_ipv4(addr):
raise e
return addr, int(port, 0)

View File

@ -21,6 +21,7 @@ import netaddr
from ryu.base import app_manager
from ryu.lib import hub
from ryu.lib import ip
from . import ofp_event
@ -39,7 +40,7 @@ def register_switch_address(addr, interval=None):
:param interval: Interval in seconds to try to connect to switch
"""
assert len(addr) == 2
assert netaddr.valid_ipv4(addr[0]) or netaddr.valid_ipv6(addr[0])
assert ip.valid_ipv4(addr[0]) or ip.valid_ipv6(addr[0])
ofp_handler = app_manager.lookup_service_brick(ofp_event.NAME)
_TMP_ADDRESSES[addr] = interval

View File

@ -16,8 +16,7 @@
import logging
import os
import netaddr
from ryu.lib import ip
# We don't bother to use cfg.py because monkey patch needs to be
@ -116,7 +115,7 @@ if HUB_TYPE == 'eventlet':
assert backlog is None
assert spawn == 'default'
if netaddr.valid_ipv6(listen_info[0]):
if ip.valid_ipv6(listen_info[0]):
self.server = eventlet.listen(listen_info,
family=socket.AF_INET6)
elif os.path.isdir(os.path.dirname(listen_info[0])):
@ -142,7 +141,7 @@ if HUB_TYPE == 'eventlet':
class StreamClient(object):
def __init__(self, addr, timeout=None, **ssl_args):
assert netaddr.valid_ipv4(addr[0]) or netaddr.valid_ipv6(addr[0])
assert ip.valid_ipv4(addr[0]) or ip.valid_ipv6(addr[0])
self.addr = addr
self.timeout = timeout
self.ssl_args = ssl_args

View File

@ -566,7 +566,7 @@ class MrtPeer(stringify.StringifyMixin):
return cls(bgp_id, ip_addr, as_num, type_), buf[offset:]
def serialize(self):
if netaddr.valid_ipv6(self.ip_addr):
if ip.valid_ipv6(self.ip_addr):
# Sets Peer IP Address family bit to IPv6
self.type |= self.IP_ADDR_FAMILY_BIT
ip_addr = ip.text_to_bin(self.ip_addr)
@ -923,11 +923,9 @@ class Bgp4MpStateChangeMrtMessage(Bgp4MpMrtMessage):
def serialize(self):
# fixup
if (netaddr.valid_ipv4(self.peer_ip)
and netaddr.valid_ipv4(self.local_ip)):
if ip.valid_ipv4(self.peer_ip) and ip.valid_ipv4(self.local_ip):
self.afi = self.AFI_IPv4
elif (netaddr.valid_ipv6(self.peer_ip)
and netaddr.valid_ipv6(self.local_ip)):
elif ip.valid_ipv6(self.peer_ip) and ip.valid_ipv6(self.local_ip):
self.afi = self.AFI_IPv6
else:
raise ValueError(
@ -1013,11 +1011,9 @@ class Bgp4MpMessageMrtMessage(Bgp4MpMrtMessage):
def serialize(self):
# fixup
if (netaddr.valid_ipv4(self.peer_ip)
and netaddr.valid_ipv4(self.local_ip)):
if ip.valid_ipv4(self.peer_ip) and ip.valid_ipv4(self.local_ip):
self.afi = self.AFI_IPv4
elif (netaddr.valid_ipv6(self.peer_ip)
and netaddr.valid_ipv6(self.local_ip)):
elif ip.valid_ipv6(self.peer_ip) and ip.valid_ipv6(self.local_ip):
self.afi = self.AFI_IPv6
else:
raise ValueError(

View File

@ -4771,7 +4771,7 @@ class BGPPathAttributeMpReachNLRI(_PathAttribute):
if not isinstance(next_hop, (list, tuple)):
next_hop = [next_hop]
for n in next_hop:
if not netaddr.valid_ipv4(n) and not netaddr.valid_ipv6(n):
if not ip.valid_ipv4(n) and not ip.valid_ipv6(n):
raise ValueError('Invalid address for next_hop: %s' % n)
# Note: For the backward compatibility, stores the first next_hop
# address and all next_hop addresses separately.
@ -4890,7 +4890,7 @@ class BGPPathAttributeMpReachNLRI(_PathAttribute):
@next_hop.setter
def next_hop(self, addr):
if not netaddr.valid_ipv4(addr) and not netaddr.valid_ipv6(addr):
if not ip.valid_ipv4(addr) and not ip.valid_ipv6(addr):
raise ValueError('Invalid address for next_hop: %s' % addr)
self._next_hop = addr
self.next_hop_list[0] = addr
@ -4904,7 +4904,7 @@ class BGPPathAttributeMpReachNLRI(_PathAttribute):
if not isinstance(addr_list, (list, tuple)):
addr_list = [addr_list]
for addr in addr_list:
if not netaddr.valid_ipv4(addr) and not netaddr.valid_ipv6(addr):
if not ip.valid_ipv4(addr) and not ip.valid_ipv6(addr):
raise ValueError('Invalid address for next_hop: %s' % addr)
self._next_hop = addr_list[0]
self._next_hop_list = addr_list

View File

@ -540,7 +540,7 @@ class InterfaceLinkParams(stringify.StringifyMixin):
self.unreserved_bw = unreserved_bw
self.admin_group = admin_group
self.remote_as = remote_as
assert netaddr.valid_ipv4(remote_ip)
assert ip.valid_ipv4(remote_ip)
self.remote_ip = remote_ip
self.average_delay = average_delay
self.min_delay = min_delay
@ -1501,7 +1501,7 @@ class _ZebraInterfaceAddress(_ZebraMessageBody):
if isinstance(prefix, (IPv4Prefix, IPv6Prefix)):
prefix = prefix.prefix
self.prefix = prefix
assert netaddr.valid_ipv4(dest) or netaddr.valid_ipv6(dest)
assert ip.valid_ipv4(dest) or ip.valid_ipv6(dest)
self.dest = dest
@classmethod
@ -1524,7 +1524,7 @@ class _ZebraInterfaceAddress(_ZebraMessageBody):
(self.family, # fixup
body_bin) = _serialize_zebra_family_prefix(self.prefix)
if netaddr.valid_ipv4(self.dest):
if ip.valid_ipv4(self.dest):
body_bin += addrconv.ipv4.text_to_bin(self.dest)
elif ip.valid_ipv6(self.prefix):
body_bin += addrconv.ipv6.text_to_bin(self.dest)
@ -1731,8 +1731,7 @@ class _ZebraIPRoute(_ZebraMessageBody):
nexthops = nexthops or []
if from_zebra:
for nexthop in nexthops:
assert (netaddr.valid_ipv4(nexthop)
or netaddr.valid_ipv6(nexthop))
assert ip.valid_ipv4(nexthop) or ip.valid_ipv6(nexthop)
else:
for nexthop in nexthops:
assert isinstance(nexthop, _NextHop)
@ -2099,7 +2098,7 @@ class _ZebraIPNexthopLookup(_ZebraMessageBody):
def __init__(self, addr, metric=None, nexthops=None):
super(_ZebraIPNexthopLookup, self).__init__()
assert netaddr.valid_ipv4(addr) or netaddr.valid_ipv6(addr)
assert ip.valid_ipv4(addr) or ip.valid_ipv6(addr)
self.addr = addr
self.metric = metric
nexthops = nexthops or []
@ -2206,7 +2205,7 @@ class _ZebraIPImportLookup(_ZebraMessageBody):
if isinstance(prefix, (IPv4Prefix, IPv6Prefix)):
prefix = prefix.prefix
else:
assert netaddr.valid_ipv4(prefix) or netaddr.valid_ipv6(prefix)
assert ip.valid_ipv4(prefix) or ip.valid_ipv6(prefix)
self.prefix = prefix
self.metric = metric
nexthops = nexthops or []
@ -2251,7 +2250,7 @@ class _ZebraIPImportLookup(_ZebraMessageBody):
else:
raise ValueError('Invalid prefix: %s' % self.prefix)
if netaddr.valid_ipv4(self.prefix) or netaddr.valid_ipv6(self.prefix):
if ip.valid_ipv4(self.prefix) or ip.valid_ipv6(self.prefix):
buf = self.PREFIX_CLS.text_to_bin(self.prefix)
else:
raise ValueError('Invalid prefix: %s' % self.prefix)
@ -2415,7 +2414,7 @@ class _ZebraIPNexthopLookupMRib(_ZebraMessageBody):
def __init__(self, addr, distance=None, metric=None, nexthops=None):
super(_ZebraIPNexthopLookupMRib, self).__init__()
assert netaddr.valid_ipv4(addr) or netaddr.valid_ipv6(addr)
assert ip.valid_ipv4(addr) or ip.valid_ipv6(addr)
self.addr = addr
self.distance = distance
self.metric = metric
@ -2846,16 +2845,14 @@ class _ZebraBfdDestination(_ZebraMessageBody):
super(_ZebraBfdDestination, self).__init__()
self.pid = pid
self.dst_family = dst_family
assert (netaddr.valid_ipv4(dst_prefix) or
netaddr.valid_ipv6(dst_prefix))
assert ip.valid_ipv4(dst_prefix) or ip.valid_ipv6(dst_prefix)
self.dst_prefix = dst_prefix
self.min_rx_timer = min_rx_timer
self.min_tx_timer = min_tx_timer
self.detect_mult = detect_mult
self.multi_hop = multi_hop
self.src_family = src_family
assert (netaddr.valid_ipv4(src_prefix) or
netaddr.valid_ipv6(src_prefix))
assert ip.valid_ipv4(src_prefix) or ip.valid_ipv6(src_prefix)
self.src_prefix = src_prefix
self.multi_hop_count = multi_hop_count
self.ifname = ifname
@ -2902,12 +2899,12 @@ class _ZebraBfdDestination(_ZebraMessageBody):
multi_hop_count, ifname)
def _serialize_family_prefix(self, prefix):
if netaddr.valid_ipv4(prefix):
if ip.valid_ipv4(prefix):
family = socket.AF_INET
return (family,
struct.pack(self._FAMILY_FMT, family)
+ addrconv.ipv4.text_to_bin(prefix))
elif netaddr.valid_ipv6(prefix):
elif ip.valid_ipv6(prefix):
family = socket.AF_INET6
return (family,
struct.pack(self._FAMILY_FMT, family)
@ -2988,13 +2985,11 @@ class ZebraBfdDestinationDeregister(_ZebraMessageBody):
super(ZebraBfdDestinationDeregister, self).__init__()
self.pid = pid
self.dst_family = dst_family
assert (netaddr.valid_ipv4(dst_prefix) or
netaddr.valid_ipv6(dst_prefix))
assert ip.valid_ipv4(dst_prefix) or ip.valid_ipv6(dst_prefix)
self.dst_prefix = dst_prefix
self.multi_hop = multi_hop
self.src_family = src_family
assert (netaddr.valid_ipv4(src_prefix) or
netaddr.valid_ipv6(src_prefix))
assert ip.valid_ipv4(src_prefix) or ip.valid_ipv6(src_prefix)
self.src_prefix = src_prefix
self.multi_hop_count = multi_hop_count
self.ifname = ifname
@ -3039,12 +3034,12 @@ class ZebraBfdDestinationDeregister(_ZebraMessageBody):
multi_hop_count, ifname)
def _serialize_family_prefix(self, prefix):
if netaddr.valid_ipv4(prefix):
if ip.valid_ipv4(prefix):
family = socket.AF_INET
return (family,
struct.pack(self._FAMILY_FMT, family)
+ addrconv.ipv4.text_to_bin(prefix))
elif netaddr.valid_ipv6(prefix):
elif ip.valid_ipv6(prefix):
family = socket.AF_INET6
return (family,
struct.pack(self._FAMILY_FMT, family)
@ -3327,7 +3322,7 @@ class _ZebraMplsLabels(_ZebraMessageBody):
if isinstance(prefix, (IPv4Prefix, IPv6Prefix)):
prefix = prefix.prefix
self.prefix = prefix
assert netaddr.valid_ipv4(gate_addr) or netaddr.valid_ipv6(gate_addr)
assert ip.valid_ipv4(gate_addr) or ip.valid_ipv6(gate_addr)
self.gate_addr = gate_addr
if _is_frr_version_ge(_FRR_VERSION_3_0):
assert ifindex is not None

View File

@ -30,6 +30,7 @@ import six
from ryu.lib import hub
from ryu.lib import sockopt
from ryu.lib import ip
from ryu.lib.hub import Timeout
from ryu.lib.packet.bgp import RF_IPv4_UC
from ryu.lib.packet.bgp import RF_IPv6_UC
@ -410,7 +411,7 @@ class Activity(object):
The socket is bound to `bind_address` if specified.
"""
LOG.debug('Connect TCP called for %s:%s', peer_addr[0], peer_addr[1])
if netaddr.valid_ipv4(peer_addr[0]):
if ip.valid_ipv4(peer_addr[0]):
family = socket.AF_INET
else:
family = socket.AF_INET6

View File

@ -18,6 +18,7 @@
import netaddr
from ryu.lib import hub
from ryu.lib import ip
from ryu.lib.packet.bgp import (
BGPFlowSpecTrafficActionCommunity,
BGPFlowSpecVlanActionCommunity,
@ -627,7 +628,7 @@ class BGPSpeaker(object):
networks[ROUTE_FAMILY] = rf
networks[PREFIX] = p
if rf == vrfs.VRF_RF_IPV6 and netaddr.valid_ipv4(next_hop):
if rf == vrfs.VRF_RF_IPV6 and ip.valid_ipv4(next_hop):
# convert the next_hop to IPv4-Mapped IPv6 Address
networks[NEXT_HOP] = \
str(netaddr.IPAddress(next_hop).ipv6())
@ -1353,10 +1354,10 @@ class BGPSpeaker(object):
If the address is IPv4 address, return IPv4 route_family
and the prefix itself.
"""
ip, masklen = prefix.split('/')
if netaddr.valid_ipv6(ip):
addr, masklen = prefix.split('/')
if ip.valid_ipv6(addr):
# normalize IPv6 address
ipv6_prefix = str(netaddr.IPAddress(ip)) + '/' + masklen
ipv6_prefix = str(netaddr.IPAddress(addr)) + '/' + masklen
return vrfs.VRF_RF_IPV6, ipv6_prefix
else:
return vrfs.VRF_RF_IPV4, prefix

View File

@ -44,6 +44,7 @@ from ryu.services.protocols.bgp.rtconf.neighbors import CONNECT_MODE_ACTIVE
from ryu.services.protocols.bgp.utils import stats
from ryu.services.protocols.bgp.bmp import BMPClient
from ryu.lib import sockopt
from ryu.lib import ip
LOG = logging.getLogger('bgpspeaker.core')
@ -369,7 +370,7 @@ class CoreService(Factory, Activity):
sink.enque_outgoing_msg(out_route)
def _set_password(self, address, password):
if netaddr.valid_ipv4(address):
if ip.valid_ipv4(address):
family = socket.AF_INET
else:
family = socket.AF_INET6

View File

@ -38,6 +38,7 @@ from ryu.services.protocols.bgp.utils.bgp import create_v6flowspec_actions
from ryu.services.protocols.bgp.utils.bgp import create_l2vpnflowspec_actions
from ryu.lib import type_desc
from ryu.lib import ip
from ryu.lib.packet.bgp import RF_IPv4_UC
from ryu.lib.packet.bgp import RF_IPv6_UC
from ryu.lib.packet.bgp import RF_IPv4_VPN
@ -790,15 +791,15 @@ class TableCoreManager(object):
pathattrs[BGP_ATTR_TYPE_AS_PATH] = aspath
net = netaddr.IPNetwork(prefix)
ip = str(net.ip)
addr = str(net.ip)
masklen = net.prefixlen
if netaddr.valid_ipv4(ip):
_nlri = IPAddrPrefix(masklen, ip)
if ip.valid_ipv4(addr):
_nlri = IPAddrPrefix(masklen, addr)
if next_hop is None:
next_hop = '0.0.0.0'
p = Ipv4Path
else:
_nlri = IP6AddrPrefix(masklen, ip)
_nlri = IP6AddrPrefix(masklen, addr)
if next_hop is None:
next_hop = '::'
p = Ipv6Path

View File

@ -19,7 +19,7 @@
import logging
import numbers
import netaddr
from ryu.lib import ip
from ryu.services.protocols.bgp.utils.validation import is_valid_ipv4
from ryu.services.protocols.bgp.utils.validation import is_valid_asn
@ -177,8 +177,7 @@ def validate_label_range(label_range):
@validate(name=BGP_SERVER_HOSTS)
def validate_bgp_server_hosts(hosts):
for host in hosts:
if (not netaddr.valid_ipv4(host) and
not netaddr.valid_ipv6(host)):
if not ip.valid_ipv4(host) and not ip.valid_ipv6(host):
raise ConfigTypeError(desc=('Invalid bgp sever hosts '
'configuration value %s' % hosts))

View File

@ -22,6 +22,8 @@ import numbers
import netaddr
from ryu.lib import ip
from ryu.lib.packet.bgp import RF_IPv4_UC
from ryu.lib.packet.bgp import RF_IPv6_UC
from ryu.lib.packet.bgp import RF_IPv4_VPN
@ -160,7 +162,7 @@ def validate_changes(changes):
def valid_ip_address(addr):
if not netaddr.valid_ipv4(addr) and not netaddr.valid_ipv6(addr):
if not ip.valid_ipv4(addr) and not ip.valid_ipv6(addr):
return False
return True

View File

@ -189,7 +189,7 @@ def create_rt_extended_community(value, subtype=2):
subtype=subtype,
as_number=int(global_admin),
local_administrator=local_admin)
elif netaddr.valid_ipv4(global_admin):
elif ip.valid_ipv4(global_admin):
ext_com = BGPIPv4AddressSpecificExtendedCommunity(
subtype=subtype,
ipv4_address=global_admin,

View File

@ -20,7 +20,7 @@ import numbers
import re
import socket
import netaddr
from ryu.lib import ip
def is_valid_mac(mac):
@ -60,7 +60,7 @@ def is_valid_ipv4(ipv4):
- valid address: 10.0.0.1, 192.168.0.1
- invalid address: 11.0.0, 192:168:0:1, etc.
"""
return netaddr.valid_ipv4(ipv4)
return ip.valid_ipv4(ipv4)
def is_valid_ipv4_prefix(ipv4_prefix):
@ -84,7 +84,7 @@ def is_valid_ipv4_prefix(ipv4_prefix):
def is_valid_ipv6(ipv6):
"""Returns True if given `ipv6` is a valid IPv6 address
"""
return netaddr.valid_ipv6(ipv6)
return ip.valid_ipv6(ipv6)
def is_valid_ipv6_prefix(ipv6_prefix):

View File

@ -15,11 +15,11 @@
import ssl
import socket
import netaddr
from ryu import cfg
from ryu.base import app_manager
from ryu.lib import hub
from ryu.lib import ip
from ryu.services.protocols.ovsdb import client
from ryu.services.protocols.ovsdb import event
from ryu.controller import handler
@ -92,7 +92,7 @@ class OVSDB(app_manager.RyuApp):
sock.close()
continue
if netaddr.valid_ipv6(client_address[0]):
if ip.valid_ipv6(client_address[0]):
self.logger.debug(
'New connection from [%s]:%s' % client_address[:2])
else:
@ -164,7 +164,7 @@ class OVSDB(app_manager.RyuApp):
sock.close()
def start(self):
if netaddr.valid_ipv6(self._address):
if ip.valid_ipv6(self._address):
server = hub.listen(
(self._address, self._port), family=socket.AF_INET6)
else:
@ -183,7 +183,7 @@ class OVSDB(app_manager.RyuApp):
self._server = server
if netaddr.valid_ipv6(self._address):
if ip.valid_ipv6(self._address):
self.logger.info(
'Listening on [%s]:%s for clients', self._address, self._port)
else:

View File

@ -21,8 +21,6 @@ import os
import socket
import struct
import netaddr
from ryu import cfg
from ryu.base.app_manager import RyuApp
from ryu.lib import hub
@ -51,8 +49,7 @@ def create_connection(address):
"""
host, _port = address
if (netaddr.valid_ipv4(host)
or netaddr.valid_ipv6(host)):
if ip.valid_ipv4(host) or ip.valid_ipv6(host):
return socket.create_connection(address)
elif os.path.exists(host):
sock = None
@ -268,9 +265,9 @@ class ZClient(RyuApp):
nexthop_list = []
for nexthop in nexthops:
if netaddr.valid_ipv4(nexthop):
if ip.valid_ipv4(nexthop):
nexthop_list.append(zebra.NextHopIPv4(addr=nexthop))
elif netaddr.valid_ipv6(nexthop):
elif ip.valid_ipv6(nexthop):
nexthop_list.append(zebra.NextHopIPv6(addr=nexthop))
else:
raise ValueError('Invalid nexthop: %s' % nexthop)

View File

@ -18,12 +18,12 @@ from __future__ import absolute_import
import logging
import socket
import netaddr
from sqlalchemy import Column
from sqlalchemy import Boolean
from sqlalchemy import Integer
from sqlalchemy import String
from ryu.lib import ip
from ryu.lib.packet import safi as packet_safi
from ryu.lib.packet import zebra
@ -150,9 +150,9 @@ def ip_route_add(session, destination, device=None, gateway='', source='',
dest_addr, dest_prefix_num = destination.split('/')
dest_prefix_num = int(dest_prefix_num)
if netaddr.valid_ipv4(dest_addr) and 0 <= dest_prefix_num <= 32:
if ip.valid_ipv4(dest_addr) and 0 <= dest_prefix_num <= 32:
family = socket.AF_INET
elif netaddr.valid_ipv6(dest_addr) and 0 <= dest_prefix_num <= 128:
elif ip.valid_ipv6(dest_addr) and 0 <= dest_prefix_num <= 128:
family = socket.AF_INET6
else:
LOG.debug('Invalid IP address for "prefix": %s', destination)

View File

@ -23,13 +23,12 @@ import os
import socket
import struct
import netaddr
from ryu import cfg
from ryu.base import app_manager
from ryu.base.app_manager import RyuApp
from ryu.controller.handler import set_ev_cls
from ryu.lib import hub
from ryu.lib import ip
from ryu.lib.packet import zebra
from ryu.services.protocols.zebra import db
@ -169,9 +168,9 @@ def zclient_connection_factory(sock, addr):
def detect_address_family(host):
if netaddr.valid_ipv4(host):
if ip.valid_ipv4(host):
return socket.AF_INET
elif netaddr.valid_ipv6(host):
elif ip.valid_ipv6(host):
return socket.AF_INET6
elif os.path.isdir(os.path.dirname(host)):
return socket.AF_UNIX