コード例 #1
0
class PathTransOFPath(Serializable):
    """
    Class used by PathTransportExt to encapsulate a path in data-plane format.
    """
    NAME = "PathTransOFPath"
    MIN_LEN = 2

    def __init__(self, raw=None):  # pragma: no cover
        """
        Initialize an instance of the class PathTransOFPath.

        :param raw:
        :type raw:
        """
        self.src = None
        self.dst = None
        self.path = None
        super().__init__(raw)

    def _parse(self, raw):
        data = Raw(raw, self.NAME, self.MIN_LEN, min_=True)
        src_type = data.pop(1)
        dst_type = data.pop(1)
        self.src = SCIONAddr((src_type, data.get()))
        data.pop(len(self.src))
        self.dst = SCIONAddr((dst_type, data.get()))
        data.pop(len(self.dst))
        padding_len = len(data) % OpaqueField.LEN
        self.path = parse_path(data.pop(len(data) - padding_len))

    @classmethod
    def from_values(cls, src, dst, path):  # pragma: no cover
        inst = cls()
        inst.src = src
        inst.dst = dst
        inst.path = path
        return inst

    def pack(self):  # pragma: no cover
        packed = []
        packed.append(struct.pack("!B", self.src.host.TYPE))
        packed.append(struct.pack("!B", self.dst.host.TYPE))
        packed.append(self.src.pack())
        packed.append(self.dst.pack())
        packed.append(self.path.pack())
        return b"".join(packed)

    def __len__(self):  # pragma: no cover
        return len(self.pack())

    def __str__(self):
        return "%s -> %s\n%s" % (self.src, self.dst, self.path)
コード例 #2
0
class SCIONAddrHdr(Serializable):
    """SCION Address header."""
    NAME = "SCIONAddrHdr"
    BLK_SIZE = 8

    def __init__(self, raw_values=()):  # pragma: no cover
        """
        :param tuple raw:
            Tuple of src addr type, dst addr type, and raw addr bytes.
        """
        super().__init__()
        self.src = None
        self.dst = None
        self._pad_len = None
        self._total_len = None
        if raw_values:
            self._parse(*raw_values)

    def _parse(self, src_type, dst_type, raw):
        data = Raw(raw, self.NAME, self.calc_lens(src_type, dst_type)[0])
        self.src = SCIONAddr((src_type, data.get()))
        data.pop(len(self.src))
        self.dst = SCIONAddr((dst_type, data.get()))
        data.pop(len(self.dst))
        self.update()
        if self.src.host.TYPE == AddrType.SVC:
            raise SCMPBadSrcType("Invalid source type: SVC")

    @classmethod
    def from_values(cls, src, dst):  # pragma: no cover
        """
        src/dst must be a :any:`SCIONAddr`
        """
        inst = cls()
        inst.src = src
        inst.dst = dst
        inst.update()
        return inst

    def pack(self):
        self.update()
        packed = []
        packed.append(self.src.pack())
        packed.append(self.dst.pack())
        packed.append(bytes(self._pad_len))
        raw = b"".join(packed)
        assert len(raw) % self.BLK_SIZE == 0
        assert len(raw) == self._total_len
        return raw

    def validate(self):  # pragma: no cover
        if self.dst.host.TYPE == AddrType.SVC and self.dst.host not in [
                SVCType.BS, SVCType.PS, SVCType.CS, SVCType.SB
        ]:
            raise SCMPBadHost("Invalid dest SVC: %s" % self.dst.host.addr)

    def update(self):
        self._total_len, self._pad_len = self.calc_lens(
            self.src.host.TYPE, self.dst.host.TYPE)

    @classmethod
    def calc_lens(cls, src_type, dst_type):
        try:
            data_len = SCIONAddr.calc_len(src_type)
        except HostAddrInvalidType:
            raise SCMPBadSrcType("Unsupported src address type: %s" %
                                 src_type) from None
        try:
            data_len += SCIONAddr.calc_len(dst_type)
        except HostAddrInvalidType:
            raise SCMPBadDstType("Unsupported dst address type: %s" %
                                 dst_type) from None
        pad_len = calc_padding(data_len, cls.BLK_SIZE)
        total_len = data_len + pad_len
        assert total_len % cls.BLK_SIZE == 0
        return total_len, pad_len

    def reverse(self):
        self.src, self.dst = self.dst, self.src
        self.update()

    def src_type(self):  # pragma: no cover
        return self.src.host.TYPE

    def dst_type(self):  # pragma: no cover
        return self.dst.host.TYPE

    def __len__(self):  # pragma: no cover
        assert self._total_len is not None
        return self._total_len

    def __str__(self):
        return "%s(%sB): Src:<%s> Dst:<%s>" % (self.NAME, len(self), self.src,
                                               self.dst)