From c2154c0d362ced8f8b5181799c369e1497c958e1 Mon Sep 17 00:00:00 2001 From: Dan Klein Date: Thu, 27 Aug 2015 10:58:01 +0300 Subject: reverting to dpkt v1.8.6 instead of 1.8.6.2 to avoid importing error of pystone modue --- scripts/external_libs/dpkt-1.8.6/dpkt/bgp.py | 760 +++++++++++++++++++++++++++ 1 file changed, 760 insertions(+) create mode 100644 scripts/external_libs/dpkt-1.8.6/dpkt/bgp.py (limited to 'scripts/external_libs/dpkt-1.8.6/dpkt/bgp.py') diff --git a/scripts/external_libs/dpkt-1.8.6/dpkt/bgp.py b/scripts/external_libs/dpkt-1.8.6/dpkt/bgp.py new file mode 100644 index 00000000..b9fb26a0 --- /dev/null +++ b/scripts/external_libs/dpkt-1.8.6/dpkt/bgp.py @@ -0,0 +1,760 @@ +# $Id: bgp.py 76 2011-01-06 15:51:30Z dugsong $ + +"""Border Gateway Protocol.""" + +import dpkt +import struct, socket + +# Border Gateway Protocol 4 - RFC 4271 +# Communities Attribute - RFC 1997 +# Capabilities - RFC 3392 +# Route Refresh - RFC 2918 +# Route Reflection - RFC 4456 +# Confederations - RFC 3065 +# Cease Subcodes - RFC 4486 +# NOPEER Community - RFC 3765 +# Multiprotocol Extensions - 2858 + +# Message Types +OPEN = 1 +UPDATE = 2 +NOTIFICATION = 3 +KEEPALIVE = 4 +ROUTE_REFRESH = 5 + +# Attribute Types +ORIGIN = 1 +AS_PATH = 2 +NEXT_HOP = 3 +MULTI_EXIT_DISC = 4 +LOCAL_PREF = 5 +ATOMIC_AGGREGATE = 6 +AGGREGATOR = 7 +COMMUNITIES = 8 +ORIGINATOR_ID = 9 +CLUSTER_LIST = 10 +MP_REACH_NLRI = 14 +MP_UNREACH_NLRI = 15 + +# Origin Types +ORIGIN_IGP = 0 +ORIGIN_EGP = 1 +INCOMPLETE = 2 + +# AS Path Types +AS_SET = 1 +AS_SEQUENCE = 2 +AS_CONFED_SEQUENCE = 3 +AS_CONFED_SET = 4 + +# Reserved Communities Types +NO_EXPORT = 0xffffff01L +NO_ADVERTISE = 0xffffff02L +NO_EXPORT_SUBCONFED = 0xffffff03L +NO_PEER = 0xffffff04L + +# Common AFI types +AFI_IPV4 = 1 +AFI_IPV6 = 2 + +# Multiprotocol SAFI types +SAFI_UNICAST = 1 +SAFI_MULTICAST = 2 +SAFI_UNICAST_MULTICAST = 3 + +# OPEN Message Optional Parameters +AUTHENTICATION = 1 +CAPABILITY = 2 + +# Capability Types +CAP_MULTIPROTOCOL = 1 +CAP_ROUTE_REFRESH = 2 + +# NOTIFICATION Error Codes +MESSAGE_HEADER_ERROR = 1 +OPEN_MESSAGE_ERROR = 2 +UPDATE_MESSAGE_ERROR = 3 +HOLD_TIMER_EXPIRED = 4 +FSM_ERROR = 5 +CEASE = 6 + +# Message Header Error Subcodes +CONNECTION_NOT_SYNCHRONIZED = 1 +BAD_MESSAGE_LENGTH = 2 +BAD_MESSAGE_TYPE = 3 + +# OPEN Message Error Subcodes +UNSUPPORTED_VERSION_NUMBER = 1 +BAD_PEER_AS = 2 +BAD_BGP_IDENTIFIER = 3 +UNSUPPORTED_OPTIONAL_PARAMETER = 4 +AUTHENTICATION_FAILURE = 5 +UNACCEPTABLE_HOLD_TIME = 6 +UNSUPPORTED_CAPABILITY = 7 + +# UPDATE Message Error Subcodes +MALFORMED_ATTRIBUTE_LIST = 1 +UNRECOGNIZED_ATTRIBUTE = 2 +MISSING_ATTRIBUTE = 3 +ATTRIBUTE_FLAGS_ERROR = 4 +ATTRIBUTE_LENGTH_ERROR = 5 +INVALID_ORIGIN_ATTRIBUTE = 6 +AS_ROUTING_LOOP = 7 +INVALID_NEXT_HOP_ATTRIBUTE = 8 +OPTIONAL_ATTRIBUTE_ERROR = 9 +INVALID_NETWORK_FIELD = 10 +MALFORMED_AS_PATH = 11 + +# Cease Error Subcodes +MAX_NUMBER_OF_PREFIXES_REACHED = 1 +ADMINISTRATIVE_SHUTDOWN = 2 +PEER_DECONFIGURED = 3 +ADMINISTRATIVE_RESET = 4 +CONNECTION_REJECTED = 5 +OTHER_CONFIGURATION_CHANGE = 6 +CONNECTION_COLLISION_RESOLUTION = 7 +OUT_OF_RESOURCES = 8 + + +class BGP(dpkt.Packet): + __hdr__ = ( + ('marker', '16s', '\xff' * 16), + ('len', 'H', 0), + ('type', 'B', OPEN) + ) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + self.data = self.data[:self.len - self.__hdr_len__] + if self.type == OPEN: + self.data = self.open = self.Open(self.data) + elif self.type == UPDATE: + self.data = self.update = self.Update(self.data) + elif self.type == NOTIFICATION: + self.data = self.notifiation = self.Notification(self.data) + elif self.type == KEEPALIVE: + self.data = self.keepalive = self.Keepalive(self.data) + elif self.type == ROUTE_REFRESH: + self.data = self.route_refresh = self.RouteRefresh(self.data) + + class Open(dpkt.Packet): + __hdr__ = ( + ('v', 'B', 4), + ('asn', 'H', 0), + ('holdtime', 'H', 0), + ('identifier', 'I', 0), + ('param_len', 'B', 0) + ) + __hdr_defaults__ = { + 'parameters': [] + } + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + l = [] + plen = self.param_len + while plen > 0: + param = self.Parameter(self.data) + self.data = self.data[len(param):] + plen -= len(param) + l.append(param) + self.data = self.parameters = l + + def __len__(self): + return self.__hdr_len__ + \ + sum(map(len, self.parameters)) + + def __str__(self): + params = ''.join(map(str, self.parameters)) + self.param_len = len(params) + return self.pack_hdr() + params + + class Parameter(dpkt.Packet): + __hdr__ = ( + ('type', 'B', 0), + ('len', 'B', 0) + ) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + self.data = self.data[:self.len] + + if self.type == AUTHENTICATION: + self.data = self.authentication = self.Authentication(self.data) + elif self.type == CAPABILITY: + self.data = self.capability = self.Capability(self.data) + + class Authentication(dpkt.Packet): + __hdr__ = ( + ('code', 'B', 0), + ) + + class Capability(dpkt.Packet): + __hdr__ = ( + ('code', 'B', 0), + ('len', 'B', 0) + ) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + self.data = self.data[:self.len] + + + class Update(dpkt.Packet): + __hdr_defaults__ = { + 'withdrawn': [], + 'attributes': [], + 'announced': [] + } + + def unpack(self, buf): + self.data = buf + + # Withdrawn Routes + wlen = struct.unpack('>H', self.data[:2])[0] + self.data = self.data[2:] + l = [] + while wlen > 0: + route = RouteIPV4(self.data) + self.data = self.data[len(route):] + wlen -= len(route) + l.append(route) + self.withdrawn = l + + # Path Attributes + plen = struct.unpack('>H', self.data[:2])[0] + self.data = self.data[2:] + l = [] + while plen > 0: + attr = self.Attribute(self.data) + self.data = self.data[len(attr):] + plen -= len(attr) + l.append(attr) + self.attributes = l + + # Announced Routes + l = [] + while self.data: + route = RouteIPV4(self.data) + self.data = self.data[len(route):] + l.append(route) + self.announced = l + + def __len__(self): + return 2 + sum(map(len, self.withdrawn)) + \ + 2 + sum(map(len, self.attributes)) + \ + sum(map(len, self.announced)) + + def __str__(self): + return struct.pack('>H', sum(map(len, self.withdrawn))) + \ + ''.join(map(str, self.withdrawn)) + \ + struct.pack('>H', sum(map(len, self.attributes))) + \ + ''.join(map(str, self.attributes)) + \ + ''.join(map(str, self.announced)) + + class Attribute(dpkt.Packet): + __hdr__ = ( + ('flags', 'B', 0), + ('type', 'B', 0) + ) + + def _get_o(self): + return (self.flags >> 7) & 0x1 + def _set_o(self, o): + self.flags = (self.flags & ~0x80) | ((o & 0x1) << 7) + optional = property(_get_o, _set_o) + + def _get_t(self): + return (self.flags >> 6) & 0x1 + def _set_t(self, t): + self.flags = (self.flags & ~0x40) | ((t & 0x1) << 6) + transitive = property(_get_t, _set_t) + + def _get_p(self): + return (self.flags >> 5) & 0x1 + def _set_p(self, p): + self.flags = (self.flags & ~0x20) | ((p & 0x1) << 5) + partial = property(_get_p, _set_p) + + def _get_e(self): + return (self.flags >> 4) & 0x1 + def _set_e(self, e): + self.flags = (self.flags & ~0x10) | ((e & 0x1) << 4) + extended_length = property(_get_e, _set_e) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + + if self.extended_length: + self.len = struct.unpack('>H', self.data[:2])[0] + self.data = self.data[2:] + else: + self.len = struct.unpack('B', self.data[:1])[0] + self.data = self.data[1:] + + self.data = self.data[:self.len] + + if self.type == ORIGIN: + self.data = self.origin = self.Origin(self.data) + elif self.type == AS_PATH: + self.data = self.as_path = self.ASPath(self.data) + elif self.type == NEXT_HOP: + self.data = self.next_hop = self.NextHop(self.data) + elif self.type == MULTI_EXIT_DISC: + self.data = self.multi_exit_disc = self.MultiExitDisc(self.data) + elif self.type == LOCAL_PREF: + self.data = self.local_pref = self.LocalPref(self.data) + elif self.type == ATOMIC_AGGREGATE: + self.data = self.atomic_aggregate = self.AtomicAggregate(self.data) + elif self.type == AGGREGATOR: + self.data = self.aggregator = self.Aggregator(self.data) + elif self.type == COMMUNITIES: + self.data = self.communities = self.Communities(self.data) + elif self.type == ORIGINATOR_ID: + self.data = self.originator_id = self.OriginatorID(self.data) + elif self.type == CLUSTER_LIST: + self.data = self.cluster_list = self.ClusterList(self.data) + elif self.type == MP_REACH_NLRI: + self.data = self.mp_reach_nlri = self.MPReachNLRI(self.data) + elif self.type == MP_UNREACH_NLRI: + self.data = self.mp_unreach_nlri = self.MPUnreachNLRI(self.data) + + def __len__(self): + if self.extended_length: + attr_len = 2 + else: + attr_len = 1 + return self.__hdr_len__ + \ + attr_len + \ + len(self.data) + + def __str__(self): + if self.extended_length: + attr_len_str = struct.pack('>H', self.len) + else: + attr_len_str = struct.pack('B', self.len) + return self.pack_hdr() + \ + attr_len_str + \ + str(self.data) + + class Origin(dpkt.Packet): + __hdr__ = ( + ('type', 'B', ORIGIN_IGP), + ) + + class ASPath(dpkt.Packet): + __hdr_defaults__ = { + 'segments': [] + } + + def unpack(self, buf): + self.data = buf + l = [] + while self.data: + seg = self.ASPathSegment(self.data) + self.data = self.data[len(seg):] + l.append(seg) + self.data = self.segments = l + + def __len__(self): + return sum(map(len, self.data)) + + def __str__(self): + return ''.join(map(str, self.data)) + + class ASPathSegment(dpkt.Packet): + __hdr__ = ( + ('type', 'B', 0), + ('len', 'B', 0) + ) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + l = [] + for i in range(self.len): + AS = struct.unpack('>H', self.data[:2])[0] + self.data = self.data[2:] + l.append(AS) + self.data = self.path = l + + def __len__(self): + return self.__hdr_len__ + \ + 2 * len(self.path) + + def __str__(self): + as_str = '' + for AS in self.path: + as_str += struct.pack('>H', AS) + return self.pack_hdr() + \ + as_str + + class NextHop(dpkt.Packet): + __hdr__ = ( + ('ip', 'I', 0), + ) + + class MultiExitDisc(dpkt.Packet): + __hdr__ = ( + ('value', 'I', 0), + ) + + class LocalPref(dpkt.Packet): + __hdr__ = ( + ('value', 'I', 0), + ) + + class AtomicAggregate(dpkt.Packet): + def unpack(self, buf): + pass + + def __len__(self): + return 0 + + def __str__(self): + return '' + + class Aggregator(dpkt.Packet): + __hdr__ = ( + ('asn', 'H', 0), + ('ip', 'I', 0) + ) + + class Communities(dpkt.Packet): + __hdr_defaults__ = { + 'list': [] + } + + def unpack(self, buf): + self.data = buf + l = [] + while self.data: + val = struct.unpack('>I', self.data[:4])[0] + if (val >= 0x00000000L and val <= 0x0000ffffL) or \ + (val >= 0xffff0000L and val <= 0xffffffffL): + comm = self.ReservedCommunity(self.data[:4]) + else: + comm = self.Community(self.data[:4]) + self.data = self.data[len(comm):] + l.append(comm) + self.data = self.list = l + + def __len__(self): + return sum(map(len, self.data)) + + def __str__(self): + return ''.join(map(str, self.data)) + + class Community(dpkt.Packet): + __hdr__ = ( + ('asn', 'H', 0), + ('value', 'H', 0) + ) + + class ReservedCommunity(dpkt.Packet): + __hdr__ = ( + ('value', 'I', 0), + ) + + class OriginatorID(dpkt.Packet): + __hdr__ = ( + ('value', 'I', 0), + ) + + class ClusterList(dpkt.Packet): + __hdr_defaults__ = { + 'list': [] + } + + def unpack(self, buf): + self.data = buf + l = [] + while self.data: + id = struct.unpack('>I', self.data[:4])[0] + self.data = self.data[4:] + l.append(id) + self.data = self.list = l + + def __len__(self): + return 4 * len(self.list) + + def __str__(self): + cluster_str = '' + for val in self.list: + cluster_str += struct.pack('>I', val) + return cluster_str + + class MPReachNLRI(dpkt.Packet): + __hdr__ = ( + ('afi', 'H', AFI_IPV4), + ('safi', 'B', SAFI_UNICAST), + ) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + + # Next Hop + nlen = struct.unpack('B', self.data[:1])[0] + self.data = self.data[1:] + self.next_hop = self.data[:nlen] + self.data = self.data[nlen:] + + # SNPAs + l = [] + num_snpas = struct.unpack('B', self.data[:1])[0] + self.data = self.data[1:] + for i in range(num_snpas): + snpa = self.SNPA(self.data) + self.data = self.data[len(snpa):] + l.append(snpa) + self.snpas = l + + if self.afi == AFI_IPV4: + Route = RouteIPV4 + elif self.afi == AFI_IPV6: + Route = RouteIPV6 + else: + Route = RouteGeneric + + # Announced Routes + l = [] + while self.data: + route = Route(self.data) + self.data = self.data[len(route):] + l.append(route) + self.data = self.announced = l + + def __len__(self): + return self.__hdr_len__ + \ + 1 + len(self.next_hop) + \ + 1 + sum(map(len, self.snpas)) + \ + sum(map(len, self.announced)) + + def __str__(self): + return self.pack_hdr() + \ + struct.pack('B', len(self.next_hop)) + \ + str(self.next_hop) + \ + struct.pack('B', len(self.snpas)) + \ + ''.join(map(str, self.snpas)) + \ + ''.join(map(str, self.announced)) + + class SNPA: + __hdr__ = ( + ('len', 'B', 0), + ) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + self.data = self.data[:(self.len + 1) / 2] + + class MPUnreachNLRI(dpkt.Packet): + __hdr__ = ( + ('afi', 'H', AFI_IPV4), + ('safi', 'B', SAFI_UNICAST), + ) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + + if self.afi == AFI_IPV4: + Route = RouteIPV4 + elif self.afi == AFI_IPV6: + Route = RouteIPV6 + else: + Route = RouteGeneric + + # Withdrawn Routes + l = [] + while self.data: + route = Route(self.data) + self.data = self.data[len(route):] + l.append(route) + self.data = self.withdrawn = l + + def __len__(self): + return self.__hdr_len__ + \ + sum(map(len, self.data)) + + def __str__(self): + return self.pack_hdr() + \ + ''.join(map(str, self.data)) + + + class Notification(dpkt.Packet): + __hdr__ = ( + ('code', 'B', 0), + ('subcode', 'B', 0), + ) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + self.error = self.data + + + class Keepalive(dpkt.Packet): + def unpack(self, buf): + pass + + def __len__(self): + return 0 + + def __str__(self): + return '' + + + class RouteRefresh(dpkt.Packet): + __hdr__ = ( + ('afi', 'H', AFI_IPV4), + ('rsvd', 'B', 0), + ('safi', 'B', SAFI_UNICAST) + ) + + +class RouteGeneric(dpkt.Packet): + __hdr__ = ( + ('len', 'B', 0), + ) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + self.data = self.prefix = self.data[:(self.len + 7) / 8] + +class RouteIPV4(dpkt.Packet): + __hdr__ = ( + ('len', 'B', 0), + ) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + tmp = self.data[:(self.len + 7) / 8] + tmp += (4 - len(tmp)) * '\x00' + self.data = self.prefix = tmp + + def __repr__(self): + cidr = '%s/%d' % (socket.inet_ntoa(self.prefix), self.len) + return '%s(%s)' % (self.__class__.__name__, cidr) + + def __len__(self): + return self.__hdr_len__ + \ + (self.len + 7) / 8 + + def __str__(self): + return self.pack_hdr() + \ + self.prefix[:(self.len + 7) / 8] + +class RouteIPV6(dpkt.Packet): + __hdr__ = ( + ('len', 'B', 0), + ) + + def unpack(self, buf): + dpkt.Packet.unpack(self, buf) + tmp = self.data[:(self.len + 7) / 8] + tmp += (16 - len(tmp)) * '\x00' + self.data = self.prefix = tmp + + def __len__(self): + return self.__hdr_len__ + \ + (self.len + 7) / 8 + + def __str__(self): + return self.pack_hdr() + \ + self.prefix[:(self.len + 7) / 8] + + +if __name__ == '__main__': + import unittest + + class BGPTestCase(unittest.TestCase): + def testPack(self): + b1 = BGP(self.bgp1) + self.failUnless(self.bgp1 == str(b1)) + b2 = BGP(self.bgp2) + self.failUnless(self.bgp2 == str(b2)) + b3 = BGP(self.bgp3) + self.failUnless(self.bgp3 == str(b3)) + b4 = BGP(self.bgp4) + self.failUnless(self.bgp4 == str(b4)) + + def testUnpack(self): + b1 = BGP(self.bgp1) + self.failUnless(b1.len == 19) + self.failUnless(b1.type == KEEPALIVE) + self.failUnless(b1.keepalive is not None) + + b2 = BGP(self.bgp2) + self.failUnless(b2.type == UPDATE) + self.failUnless(len(b2.update.withdrawn) == 0) + self.failUnless(len(b2.update.announced) == 1) + self.failUnless(len(b2.update.attributes) == 9) + a = b2.update.attributes[1] + self.failUnless(a.type == AS_PATH) + self.failUnless(a.len == 10) + self.failUnless(len(a.as_path.segments) == 2) + s = a.as_path.segments[0] + self.failUnless(s.type == AS_SET) + self.failUnless(s.len == 2) + self.failUnless(len(s.path) == 2) + self.failUnless(s.path[0] == 500) + + a = b2.update.attributes[6] + self.failUnless(a.type == COMMUNITIES) + self.failUnless(a.len == 12) + self.failUnless(len(a.communities.list) == 3) + c = a.communities.list[0] + self.failUnless(c.asn == 65215) + self.failUnless(c.value == 1) + r = b2.update.announced[0] + self.failUnless(r.len == 22) + self.failUnless(r.prefix == '\xc0\xa8\x04\x00') + + b3 = BGP(self.bgp3) + self.failUnless(b3.type == UPDATE) + self.failUnless(len(b3.update.withdrawn) == 0) + self.failUnless(len(b3.update.announced) == 0) + self.failUnless(len(b3.update.attributes) == 6) + a = b3.update.attributes[0] + self.failUnless(a.optional == False) + self.failUnless(a.transitive == True) + self.failUnless(a.partial == False) + self.failUnless(a.extended_length == False) + self.failUnless(a.type == ORIGIN) + self.failUnless(a.len == 1) + o = a.origin + self.failUnless(o.type == ORIGIN_IGP) + a = b3.update.attributes[5] + self.failUnless(a.optional == True) + self.failUnless(a.transitive == False) + self.failUnless(a.partial == False) + self.failUnless(a.extended_length == True) + self.failUnless(a.type == MP_REACH_NLRI) + self.failUnless(a.len == 30) + m = a.mp_reach_nlri + self.failUnless(m.afi == AFI_IPV4) + self.failUnless(len(m.snpas) == 0) + self.failUnless(len(m.announced) == 1) + p = m.announced[0] + self.failUnless(p.len == 96) + + b4 = BGP(self.bgp4) + self.failUnless(b4.len == 45) + self.failUnless(b4.type == OPEN) + self.failUnless(b4.open.asn == 237) + self.failUnless(b4.open.param_len == 16) + self.failUnless(len(b4.open.parameters) == 3) + p = b4.open.parameters[0] + self.failUnless(p.type == CAPABILITY) + self.failUnless(p.len == 6) + c = p.capability + self.failUnless(c.code == CAP_MULTIPROTOCOL) + self.failUnless(c.len == 4) + self.failUnless(c.data == '\x00\x01\x00\x01') + c = b4.open.parameters[2].capability + self.failUnless(c.code == CAP_ROUTE_REFRESH) + self.failUnless(c.len == 0) + + bgp1 = '\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x13\x04' + bgp2 = '\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x63\x02\x00\x00\x00\x48\x40\x01\x01\x00\x40\x02\x0a\x01\x02\x01\xf4\x01\xf4\x02\x01\xfe\xbb\x40\x03\x04\xc0\xa8\x00\x0f\x40\x05\x04\x00\x00\x00\x64\x40\x06\x00\xc0\x07\x06\xfe\xba\xc0\xa8\x00\x0a\xc0\x08\x0c\xfe\xbf\x00\x01\x03\x16\x00\x04\x01\x54\x00\xfa\x80\x09\x04\xc0\xa8\x00\x0f\x80\x0a\x04\xc0\xa8\x00\xfa\x16\xc0\xa8\x04' + bgp3 = '\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x79\x02\x00\x00\x00\x62\x40\x01\x01\x00\x40\x02\x00\x40\x05\x04\x00\x00\x00\x64\xc0\x10\x08\x00\x02\x01\x2c\x00\x00\x01\x2c\xc0\x80\x24\x00\x00\xfd\xe9\x40\x01\x01\x00\x40\x02\x04\x02\x01\x15\xb3\x40\x05\x04\x00\x00\x00\x2c\x80\x09\x04\x16\x05\x05\x05\x80\x0a\x04\x16\x05\x05\x05\x90\x0e\x00\x1e\x00\x01\x80\x0c\x00\x00\x00\x00\x00\x00\x00\x00\x0c\x04\x04\x04\x00\x60\x18\x77\x01\x00\x00\x01\xf4\x00\x00\x01\xf4\x85' + bgp4 = '\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x2d\x01\x04\x00\xed\x00\x5a\xc6\x6e\x83\x7d\x10\x02\x06\x01\x04\x00\x01\x00\x01\x02\x02\x80\x00\x02\x02\x02\x00' + + unittest.main() -- cgit 1.2.3-korg