1# encoding: utf-8
2"""
3aggregator.py
4
5Created by Thomas Mangin on 2012-07-14.
6Copyright (c) 2009-2017 Exa Networks. All rights reserved.
7License: 3-clause BSD. (See the COPYRIGHT file)
8"""
9
10import sys
11
12from exabgp.bgp.message.open.asn import ASN
13from exabgp.protocol.ip import IPv4
14
15from exabgp.bgp.message.update.attribute.attribute import Attribute
16
17
18# =============================================================== AGGREGATOR (7)
19#
20
21
22@Attribute.register()
23class Aggregator(Attribute):
24    ID = Attribute.CODE.AGGREGATOR
25    FLAG = Attribute.Flag.TRANSITIVE | Attribute.Flag.OPTIONAL
26    CACHING = True
27
28    __slots__ = ['asn', 'speaker', '_str']
29
30    def __init__(self, asn, speaker):
31        self.asn = asn
32        self.speaker = speaker
33        self._str = None
34
35    def __eq__(self, other):
36        return (
37            self.ID == other.ID and self.FLAG == other.FLAG and self.asn == other.asn and self.speaker == other.speaker
38        )
39
40    def __ne__(self, other):
41        return not self.__eq__(other)
42
43    def pack(self, negotiated):
44        if negotiated.asn4:
45            return self._attribute(self.asn.pack(True) + self.speaker.pack())
46        elif self.asn.asn4():
47            return self._attribute(self.asn.trans().pack() + self.speaker.pack()) + Aggregator4(
48                self.asn, self.speaker
49            ).pack(negotiated)
50        else:
51            return self._attribute(self.asn.pack() + self.speaker.pack())
52
53    def __len__(self):
54        raise RuntimeError('size can be 6 or 8 - we can not say - or can we ?')
55
56    def __repr__(self):
57        if not self._str:
58            self._str = '%s:%s' % (self.asn, self.speaker)
59        return self._str
60
61    def json(self):
62        return '{ "asn" : %d, "speaker" : "%d" }' % (self.asn, self.speaker)
63
64    @classmethod
65    def unpack(cls, data, negotiated):
66        if negotiated.asn4:
67            return cls(ASN.unpack(data[:4]), IPv4.unpack(data[-4:]))
68        return cls(ASN.unpack(data[:2]), IPv4.unpack(data[-4:]))
69
70
71# ============================================================== AGGREGATOR (18)
72#
73
74
75@Attribute.register()
76class Aggregator4(Aggregator):
77    ID = Attribute.CODE.AS4_AGGREGATOR
78
79    if sys.version_info[0] < 3:
80        __slots__ = ['pack']
81
82    def pack(self, negotiated):
83        return self._attribute(self.asn.pack(True) + self.speaker.pack())
84