Commit 34af6c5a authored by Sander Steffann's avatar Sander Steffann
Browse files

Fix LCAF handling of prefixes

parent f9212bcf
from IPy import IP
def make_prefix(address, prefix_len):
if prefix_len is None:
return address
if isinstance(address, IP):
# Convert address to prefix
prefix = address.make_net(prefix_len)
# Check that we didn't clear bits in the address
if prefix.ip != address.ip:
raise ValueError("invalid prefix length %s for %r"
% (address._prefixlen, address))
return prefix
else:
raise ValueError('Need an IP address to make a prefix')
......@@ -3,8 +3,9 @@ Created on 6 jan. 2013
@author: sander
'''
from IPy import IP, _checkNetaddrWorksWithPrefixlen
from IPy import IP
from bitstring import BitArray, ConstBitStream, Bits
from pylisp.utils import make_prefix
def read_afi_address_from_bitstream(bitstream, prefix_len=None):
......@@ -50,29 +51,23 @@ def read_afi_address_from_bitstream(bitstream, prefix_len=None):
# IPv4 address
address_int = bitstream.read('uint:32')
address = IP(address_int, ipversion=4)
if prefix_len is not None:
address = make_prefix(address, prefix_len)
elif afi == 2:
# IPv6 address
address_int = bitstream.read('uint:128')
address = IP(address_int, ipversion=6)
if prefix_len is not None:
address = make_prefix(address, prefix_len)
elif afi == 16387:
from pylisp.utils.lcaf import LCAFAddress
address = LCAFAddress.from_bytes(bitstream)
address = LCAFAddress.from_bytes(bitstream, prefix_len)
else:
raise ValueError('Unable to handle AFI {0}'.format(afi))
if isinstance(address, IP) and prefix_len is not None:
# WARNING: Huge Ugly Hack
address._prefixlen = prefix_len
if not _checkNetaddrWorksWithPrefixlen(address.ip,
address._prefixlen,
address._ipversion):
raise ValueError("%s has invalid prefix length (%s)"
% (repr(address), address._prefixlen))
return address
......
......@@ -3,11 +3,12 @@ Created on 12 jan. 2013
@author: sander
'''
from pylisp.utils.lcaf.base import LCAFAddress
from pylisp.utils.lcaf import type_registry
from bitstring import BitArray
from pylisp.utils import make_prefix
from pylisp.utils.afi import read_afi_address_from_bitstream, \
get_bitstream_for_afi_address
from bitstring import BitArray
from pylisp.utils.lcaf import type_registry
from pylisp.utils.lcaf.base import LCAFAddress
class LCAFAFIListAddress(LCAFAddress):
......@@ -21,10 +22,12 @@ class LCAFAFIListAddress(LCAFAddress):
super(LCAFAFIListAddress, self).sanitize()
@classmethod
def _from_data_bytes(cls, data):
def _from_data_bytes(cls, data, prefix_len=None):
addresses = []
while data.pos != data.len:
address = read_afi_address_from_bitstream(data)
if prefix_len is not None:
address = make_prefix(address, prefix_len)
addresses.append(address)
lcaf = cls(addresses=addresses)
lcaf.sanitize()
......
......@@ -3,11 +3,12 @@ Created on 12 jan. 2013
@author: sander
'''
from pylisp.utils.lcaf.base import LCAFAddress
from pylisp.utils.lcaf import type_registry
from bitstring import BitArray
from pylisp.utils import make_prefix
from pylisp.utils.afi import read_afi_address_from_bitstream, \
get_bitstream_for_afi_address
from bitstring import BitArray
from pylisp.utils.lcaf import type_registry
from pylisp.utils.lcaf.base import LCAFAddress
class LCAFAutonomousSystemAddress(LCAFAddress):
......@@ -22,9 +23,11 @@ class LCAFAutonomousSystemAddress(LCAFAddress):
super(LCAFAutonomousSystemAddress, self).sanitize()
@classmethod
def _from_data_bytes(cls, data):
def _from_data_bytes(cls, data, prefix_len=None):
asn = data.read('uint:32')
address = read_afi_address_from_bitstream(data)
if prefix_len is not None:
address = make_prefix(address, prefix_len)
lcaf = cls(asn=asn,
address=address)
lcaf.sanitize()
......
......@@ -3,9 +3,9 @@ Created on 6 jan. 2013
@author: sander
'''
from pylisp.packet.ip.protocol import ProtocolElement
from abc import ABCMeta, abstractmethod
from bitstring import ConstBitStream, BitArray, Bits
from pylisp.packet.ip.protocol import ProtocolElement
class LCAFAddress(ProtocolElement):
......@@ -23,7 +23,7 @@ class LCAFAddress(ProtocolElement):
pass
@classmethod
def from_bytes(cls, bitstream):
def from_bytes(cls, bitstream, prefix_len=None):
'''
Look at the type of the message, instantiate the correct class and
let it parse the message.
......@@ -61,7 +61,7 @@ class LCAFAddress(ProtocolElement):
raise ValueError("Can't handle LCAF type {0}".format(type_nr))
# Let the specific class handle it from now on
return type_class._from_data_bytes(data)
return type_class._from_data_bytes(data, prefix_len)
def to_bytes(self):
'''
......@@ -93,7 +93,7 @@ class LCAFAddress(ProtocolElement):
@classmethod
@abstractmethod
def _from_data_bytes(cls, data):
def _from_data_bytes(cls, data, prefix_len=None):
'''
The LCAF header has been parsed, now parse the data
'''
......
......@@ -3,11 +3,12 @@ Created on 12 jan. 2013
@author: sander
'''
from pylisp.utils.lcaf.base import LCAFAddress
from pylisp.utils.lcaf import type_registry
from bitstring import BitArray
from pylisp.utils import make_prefix
from pylisp.utils.afi import read_afi_address_from_bitstream, \
get_bitstream_for_afi_address
from bitstring import BitArray
from pylisp.utils.lcaf import type_registry
from pylisp.utils.lcaf.base import LCAFAddress
class LCAFGeoAddress(LCAFAddress):
......@@ -61,13 +62,15 @@ class LCAFGeoAddress(LCAFAddress):
super(LCAFGeoAddress, self).sanitize()
@classmethod
def _from_data_bytes(cls, data):
def _from_data_bytes(cls, data, prefix_len=None):
(north, latitude_degrees, latitude_minutes,
latitude_seconds) = data.readlist('bool, uint:15, 2*uint:8')
(east, longitude_degrees, longitude_minutes,
longitude_seconds) = data.readlist('bool, uint:15, 2*uint:8')
altitude = data.read('int:32')
address = read_afi_address_from_bitstream(data)
if prefix_len is not None:
address = make_prefix(address, prefix_len)
lcaf = cls(north=north,
latitude_degrees=latitude_degrees,
latitude_minutes=latitude_minutes,
......
......@@ -3,11 +3,12 @@ Created on 12 jan. 2013
@author: sander
'''
from pylisp.utils.lcaf.base import LCAFAddress
from pylisp.utils.lcaf import type_registry
from bitstring import BitArray
from pylisp.utils import make_prefix
from pylisp.utils.afi import read_afi_address_from_bitstream, \
get_bitstream_for_afi_address
from bitstring import BitArray
from pylisp.utils.lcaf import type_registry
from pylisp.utils.lcaf.base import LCAFAddress
class LCAFInstanceAddress(LCAFAddress):
......@@ -22,9 +23,11 @@ class LCAFInstanceAddress(LCAFAddress):
super(LCAFInstanceAddress, self).sanitize()
@classmethod
def _from_data_bytes(cls, data):
def _from_data_bytes(cls, data, prefix_len=None):
instance_id = data.read('uint:32')
address = read_afi_address_from_bitstream(data)
if prefix_len is not None:
address = make_prefix(address, prefix_len)
lcaf = cls(instance_id=instance_id,
address=address)
lcaf.sanitize()
......
......@@ -3,9 +3,9 @@ Created on 12 jan. 2013
@author: sander
'''
from pylisp.utils.lcaf.base import LCAFAddress
from pylisp.utils.lcaf import type_registry
from bitstring import BitArray
from pylisp.utils.lcaf import type_registry
from pylisp.utils.lcaf.base import LCAFAddress
class LCAFNullAddress(LCAFAddress):
......@@ -18,7 +18,7 @@ class LCAFNullAddress(LCAFAddress):
super(LCAFNullAddress, self).sanitize()
@classmethod
def _from_data_bytes(cls, data):
def _from_data_bytes(cls, data, prefix_len=None):
lcaf = cls()
lcaf.sanitize()
return lcaf
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment