Package dpkt :: Module bgp
[hide private]
[frames] | no frames]

Source Code for Module dpkt.bgp

  1  # $Id: bgp.py 76 2011-01-06 15:51:30Z dugsong $ 
  2  # -*- coding: utf-8 -*- 
  3  """Border Gateway Protocol.""" 
  4  from __future__ import print_function 
  5  from __future__ import absolute_import 
  6   
  7  import struct 
  8  import socket 
  9   
 10  from . import dpkt 
 11  from .decorators import deprecated 
 12   
 13   
 14  # Border Gateway Protocol 4 - RFC 4271 
 15  # Communities Attribute - RFC 1997 
 16  # Capabilities - RFC 3392 
 17  # Route Refresh - RFC 2918 
 18  # Route Reflection - RFC 4456 
 19  # Confederations - RFC 3065 
 20  # Cease Subcodes - RFC 4486 
 21  # NOPEER Community - RFC 3765 
 22  # Multiprotocol Extensions - 2858 
 23   
 24  # Message Types 
 25  OPEN = 1 
 26  UPDATE = 2 
 27  NOTIFICATION = 3 
 28  KEEPALIVE = 4 
 29  ROUTE_REFRESH = 5 
 30   
 31  # Attribute Types 
 32  ORIGIN = 1 
 33  AS_PATH = 2 
 34  NEXT_HOP = 3 
 35  MULTI_EXIT_DISC = 4 
 36  LOCAL_PREF = 5 
 37  ATOMIC_AGGREGATE = 6 
 38  AGGREGATOR = 7 
 39  COMMUNITIES = 8 
 40  ORIGINATOR_ID = 9 
 41  CLUSTER_LIST = 10 
 42  MP_REACH_NLRI = 14 
 43  MP_UNREACH_NLRI = 15 
 44   
 45  # Origin Types 
 46  ORIGIN_IGP = 0 
 47  ORIGIN_EGP = 1 
 48  INCOMPLETE = 2 
 49   
 50  # AS Path Types 
 51  AS_SET = 1 
 52  AS_SEQUENCE = 2 
 53  AS_CONFED_SEQUENCE = 3 
 54  AS_CONFED_SET = 4 
 55   
 56  # Reserved Communities Types 
 57  NO_EXPORT = 0xffffff01 
 58  NO_ADVERTISE = 0xffffff02 
 59  NO_EXPORT_SUBCONFED = 0xffffff03 
 60  NO_PEER = 0xffffff04 
 61   
 62  # Common AFI types 
 63  AFI_IPV4 = 1 
 64  AFI_IPV6 = 2 
 65   
 66  # Multiprotocol SAFI types 
 67  SAFI_UNICAST = 1 
 68  SAFI_MULTICAST = 2 
 69  SAFI_UNICAST_MULTICAST = 3 
 70   
 71  # OPEN Message Optional Parameters 
 72  AUTHENTICATION = 1 
 73  CAPABILITY = 2 
 74   
 75  # Capability Types 
 76  CAP_MULTIPROTOCOL = 1 
 77  CAP_ROUTE_REFRESH = 2 
 78   
 79  # NOTIFICATION Error Codes 
 80  MESSAGE_HEADER_ERROR = 1 
 81  OPEN_MESSAGE_ERROR = 2 
 82  UPDATE_MESSAGE_ERROR = 3 
 83  HOLD_TIMER_EXPIRED = 4 
 84  FSM_ERROR = 5 
 85  CEASE = 6 
 86   
 87  # Message Header Error Subcodes 
 88  CONNECTION_NOT_SYNCHRONIZED = 1 
 89  BAD_MESSAGE_LENGTH = 2 
 90  BAD_MESSAGE_TYPE = 3 
 91   
 92  # OPEN Message Error Subcodes 
 93  UNSUPPORTED_VERSION_NUMBER = 1 
 94  BAD_PEER_AS = 2 
 95  BAD_BGP_IDENTIFIER = 3 
 96  UNSUPPORTED_OPTIONAL_PARAMETER = 4 
 97  AUTHENTICATION_FAILURE = 5 
 98  UNACCEPTABLE_HOLD_TIME = 6 
 99  UNSUPPORTED_CAPABILITY = 7 
100   
101  # UPDATE Message Error Subcodes 
102  MALFORMED_ATTRIBUTE_LIST = 1 
103  UNRECOGNIZED_ATTRIBUTE = 2 
104  MISSING_ATTRIBUTE = 3 
105  ATTRIBUTE_FLAGS_ERROR = 4 
106  ATTRIBUTE_LENGTH_ERROR = 5 
107  INVALID_ORIGIN_ATTRIBUTE = 6 
108  AS_ROUTING_LOOP = 7 
109  INVALID_NEXT_HOP_ATTRIBUTE = 8 
110  OPTIONAL_ATTRIBUTE_ERROR = 9 
111  INVALID_NETWORK_FIELD = 10 
112  MALFORMED_AS_PATH = 11 
113   
114  # Cease Error Subcodes 
115  MAX_NUMBER_OF_PREFIXES_REACHED = 1 
116  ADMINISTRATIVE_SHUTDOWN = 2 
117  PEER_DECONFIGURED = 3 
118  ADMINISTRATIVE_RESET = 4 
119  CONNECTION_REJECTED = 5 
120  OTHER_CONFIGURATION_CHANGE = 6 
121  CONNECTION_COLLISION_RESOLUTION = 7 
122  OUT_OF_RESOURCES = 8 
123 124 125 -class BGP(dpkt.Packet):
126 """Border Gateway Protocol. 127 128 BGP is an inter-AS routing protocol. 129 See more about the BGP on \ 130 https://en.wikipedia.org/wiki/Border_Gateway_Protocol 131 132 Attributes: 133 __hdr__: Header fields of BGP. 134 #TODO 135 """ 136 137 __hdr__ = ( 138 ('marker', '16s', '\xff' * 16), 139 ('len', 'H', 0), 140 ('type', 'B', OPEN) 141 ) 142
143 - def unpack(self, buf):
144 dpkt.Packet.unpack(self, buf) 145 self.data = self.data[:self.len - self.__hdr_len__] 146 if self.type == OPEN: 147 self.data = self.open = self.Open(self.data) 148 elif self.type == UPDATE: 149 self.data = self.update = self.Update(self.data) 150 elif self.type == NOTIFICATION: 151 self.data = self.notifiation = self.Notification(self.data) 152 elif self.type == KEEPALIVE: 153 self.data = self.keepalive = self.Keepalive(self.data) 154 elif self.type == ROUTE_REFRESH: 155 self.data = self.route_refresh = self.RouteRefresh(self.data)
156
157 - class Open(dpkt.Packet):
158 __hdr__ = ( 159 ('v', 'B', 4), 160 ('asn', 'H', 0), 161 ('holdtime', 'H', 0), 162 ('identifier', 'I', 0), 163 ('param_len', 'B', 0) 164 ) 165 __hdr_defaults__ = { 166 'parameters': [] 167 } 168
169 - def unpack(self, buf):
170 dpkt.Packet.unpack(self, buf) 171 l = [] 172 plen = self.param_len 173 while plen > 0: 174 param = self.Parameter(self.data) 175 self.data = self.data[len(param):] 176 plen -= len(param) 177 l.append(param) 178 self.data = self.parameters = l
179
180 - def __len__(self):
181 return self.__hdr_len__ + sum(map(len, self.parameters))
182
183 - def __bytes__(self):
184 params = b''.join(map(bytes, self.parameters)) 185 self.param_len = len(params) 186 return self.pack_hdr() + params
187
188 - class Parameter(dpkt.Packet):
189 __hdr__ = ( 190 ('type', 'B', 0), 191 ('len', 'B', 0) 192 ) 193
194 - def unpack(self, buf):
195 dpkt.Packet.unpack(self, buf) 196 self.data = self.data[:self.len] 197 198 if self.type == AUTHENTICATION: 199 self.data = self.authentication = self.Authentication(self.data) 200 elif self.type == CAPABILITY: 201 self.data = self.capability = self.Capability(self.data)
202
203 - class Authentication(dpkt.Packet):
204 __hdr__ = ( 205 ('code', 'B', 0), 206 )
207
208 - class Capability(dpkt.Packet):
209 __hdr__ = ( 210 ('code', 'B', 0), 211 ('len', 'B', 0) 212 ) 213
214 - def unpack(self, buf):
215 dpkt.Packet.unpack(self, buf) 216 self.data = self.data[:self.len]
217
218 - class Update(dpkt.Packet):
219 __hdr_defaults__ = { 220 'withdrawn': [], 221 'attributes': [], 222 'announced': [] 223 } 224
225 - def unpack(self, buf):
226 self.data = buf 227 228 # Withdrawn Routes 229 wlen = struct.unpack('>H', self.data[:2])[0] 230 self.data = self.data[2:] 231 l = [] 232 while wlen > 0: 233 route = RouteIPV4(self.data) 234 self.data = self.data[len(route):] 235 wlen -= len(route) 236 l.append(route) 237 self.withdrawn = l 238 239 # Path Attributes 240 plen = struct.unpack('>H', self.data[:2])[0] 241 self.data = self.data[2:] 242 l = [] 243 while plen > 0: 244 attr = self.Attribute(self.data) 245 self.data = self.data[len(attr):] 246 plen -= len(attr) 247 l.append(attr) 248 self.attributes = l 249 250 # Announced Routes 251 l = [] 252 while self.data: 253 route = RouteIPV4(self.data) 254 self.data = self.data[len(route):] 255 l.append(route) 256 self.announced = l
257
258 - def __len__(self):
259 return 2 + sum(map(len, self.withdrawn)) + \ 260 2 + sum(map(len, self.attributes)) + \ 261 sum(map(len, self.announced))
262
263 - def __bytes__(self):
264 return struct.pack('>H', sum(map(len, self.withdrawn))) + \ 265 b''.join(map(bytes, self.withdrawn)) + \ 266 struct.pack('>H', sum(map(len, self.attributes))) + \ 267 b''.join(map(bytes, self.attributes)) + \ 268 b''.join(map(bytes, self.announced))
269
270 - class Attribute(dpkt.Packet):
271 __hdr__ = ( 272 ('flags', 'B', 0), 273 ('type', 'B', 0) 274 ) 275 276 @property
277 - def optional(self):
278 return (self.flags >> 7) & 0x1
279 280 @optional.setter
281 - def optional(self, o):
282 self.flags = (self.flags & ~0x80) | ((o & 0x1) << 7)
283 284 @property
285 - def transitive(self):
286 return (self.flags >> 6) & 0x1
287 288 @transitive.setter
289 - def transitive(self, t):
290 self.flags = (self.flags & ~0x40) | ((t & 0x1) << 6)
291 292 @property
293 - def partial(self):
294 return (self.flags >> 5) & 0x1
295 296 @partial.setter
297 - def partial(self, p):
298 self.flags = (self.flags & ~0x20) | ((p & 0x1) << 5)
299 300 @property
301 - def extended_length(self):
302 return (self.flags >> 4) & 0x1
303 304 @extended_length.setter
305 - def extended_length(self, e):
306 self.flags = (self.flags & ~0x10) | ((e & 0x1) << 4)
307
308 - def unpack(self, buf):
309 dpkt.Packet.unpack(self, buf) 310 311 if self.extended_length: 312 self.len = struct.unpack('>H', self.data[:2])[0] 313 self.data = self.data[2:] 314 else: 315 self.len = struct.unpack('B', self.data[:1])[0] 316 self.data = self.data[1:] 317 318 self.data = self.data[:self.len] 319 320 if self.type == ORIGIN: 321 self.data = self.origin = self.Origin(self.data) 322 elif self.type == AS_PATH: 323 self.data = self.as_path = self.ASPath(self.data) 324 elif self.type == NEXT_HOP: 325 self.data = self.next_hop = self.NextHop(self.data) 326 elif self.type == MULTI_EXIT_DISC: 327 self.data = self.multi_exit_disc = self.MultiExitDisc(self.data) 328 elif self.type == LOCAL_PREF: 329 self.data = self.local_pref = self.LocalPref(self.data) 330 elif self.type == ATOMIC_AGGREGATE: 331 self.data = self.atomic_aggregate = self.AtomicAggregate(self.data) 332 elif self.type == AGGREGATOR: 333 self.data = self.aggregator = self.Aggregator(self.data) 334 elif self.type == COMMUNITIES: 335 self.data = self.communities = self.Communities(self.data) 336 elif self.type == ORIGINATOR_ID: 337 self.data = self.originator_id = self.OriginatorID(self.data) 338 elif self.type == CLUSTER_LIST: 339 self.data = self.cluster_list = self.ClusterList(self.data) 340 elif self.type == MP_REACH_NLRI: 341 self.data = self.mp_reach_nlri = self.MPReachNLRI(self.data) 342 elif self.type == MP_UNREACH_NLRI: 343 self.data = self.mp_unreach_nlri = self.MPUnreachNLRI(self.data)
344
345 - def __len__(self):
346 if self.extended_length: 347 attr_len = 2 348 else: 349 attr_len = 1 350 return self.__hdr_len__ + attr_len + len(self.data)
351
352 - def __bytes__(self):
353 if self.extended_length: 354 attr_len_str = struct.pack('>H', self.len) 355 else: 356 attr_len_str = struct.pack('B', self.len) 357 return self.pack_hdr() + attr_len_str + bytes(self.data)
358
359 - class Origin(dpkt.Packet):
360 __hdr__ = ( 361 ('type', 'B', ORIGIN_IGP), 362 )
363
364 - class ASPath(dpkt.Packet):
365 __hdr_defaults__ = { 366 'segments': [] 367 } 368
369 - def unpack(self, buf):
370 self.data = buf 371 l = [] 372 while self.data: 373 seg = self.ASPathSegment(self.data) 374 self.data = self.data[len(seg):] 375 l.append(seg) 376 self.data = self.segments = l
377
378 - def __len__(self):
379 return sum(map(len, self.data))
380
381 - def __bytes__(self):
382 return b''.join(map(bytes, self.data))
383
384 - class ASPathSegment(dpkt.Packet):
385 __hdr__ = ( 386 ('type', 'B', 0), 387 ('len', 'B', 0) 388 ) 389
390 - def unpack(self, buf):
391 dpkt.Packet.unpack(self, buf) 392 l = [] 393 for i in range(self.len): 394 AS = struct.unpack('>H', self.data[:2])[0] 395 self.data = self.data[2:] 396 l.append(AS) 397 self.data = self.path = l
398
399 - def __len__(self):
400 return self.__hdr_len__ + 2 * len(self.path)
401
402 - def __bytes__(self):
403 as_str = b'' 404 for AS in self.path: 405 as_str += struct.pack('>H', AS) 406 return self.pack_hdr() + as_str
407
408 - class NextHop(dpkt.Packet):
409 __hdr__ = ( 410 ('ip', 'I', 0), 411 )
412
413 - class MultiExitDisc(dpkt.Packet):
414 __hdr__ = ( 415 ('value', 'I', 0), 416 )
417
418 - class LocalPref(dpkt.Packet):
419 __hdr__ = ( 420 ('value', 'I', 0), 421 )
422
423 - class AtomicAggregate(dpkt.Packet):
424 - def unpack(self, buf):
425 pass
426
427 - def __len__(self):
428 return 0
429
430 - def __bytes__(self):
431 return b''
432
433 - class Aggregator(dpkt.Packet):
434 __hdr__ = ( 435 ('asn', 'H', 0), 436 ('ip', 'I', 0) 437 )
438
439 - class Communities(dpkt.Packet):
440 __hdr_defaults__ = { 441 'list': [] 442 } 443
444 - def unpack(self, buf):
445 self.data = buf 446 l = [] 447 while self.data: 448 val = struct.unpack('>I', self.data[:4])[0] 449 if (0x00000000 <= val <= 0x0000ffff) or (0xffff0000 <= val <= 0xffffffff): 450 comm = self.ReservedCommunity(self.data[:4]) 451 else: 452 comm = self.Community(self.data[:4]) 453 self.data = self.data[len(comm):] 454 l.append(comm) 455 self.data = self.list = l
456
457 - def __len__(self):
458 return sum(map(len, self.data))
459
460 - def __bytes__(self):
461 return b''.join(map(bytes, self.data))
462
463 - class Community(dpkt.Packet):
464 __hdr__ = ( 465 ('asn', 'H', 0), 466 ('value', 'H', 0) 467 )
468
469 - class ReservedCommunity(dpkt.Packet):
470 __hdr__ = ( 471 ('value', 'I', 0), 472 )
473
474 - class OriginatorID(dpkt.Packet):
475 __hdr__ = ( 476 ('value', 'I', 0), 477 )
478
479 - class ClusterList(dpkt.Packet):
480 __hdr_defaults__ = { 481 'list': [] 482 } 483
484 - def unpack(self, buf):
485 self.data = buf 486 l = [] 487 while self.data: 488 id = struct.unpack('>I', self.data[:4])[0] 489 self.data = self.data[4:] 490 l.append(id) 491 self.data = self.list = l
492
493 - def __len__(self):
494 return 4 * len(self.list)
495
496 - def __bytes__(self):
497 cluster_str = b'' 498 for val in self.list: 499 cluster_str += struct.pack('>I', val) 500 return cluster_str
501
502 - class MPReachNLRI(dpkt.Packet):
503 __hdr__ = ( 504 ('afi', 'H', AFI_IPV4), 505 ('safi', 'B', SAFI_UNICAST), 506 ) 507
508 - def unpack(self, buf):
509 dpkt.Packet.unpack(self, buf) 510 511 # Next Hop 512 nlen = struct.unpack('B', self.data[:1])[0] 513 self.data = self.data[1:] 514 self.next_hop = self.data[:nlen] 515 self.data = self.data[nlen:] 516 517 # SNPAs 518 l = [] 519 num_snpas = struct.unpack('B', self.data[:1])[0] 520 self.data = self.data[1:] 521 for i in range(num_snpas): 522 snpa = self.SNPA(self.data) 523 self.data = self.data[len(snpa):] 524 l.append(snpa) 525 self.snpas = l 526 527 if self.afi == AFI_IPV4: 528 Route = RouteIPV4 529 elif self.afi == AFI_IPV6: 530 Route = RouteIPV6 531 else: 532 Route = RouteGeneric 533 534 # Announced Routes 535 l = [] 536 while self.data: 537 route = Route(self.data) 538 self.data = self.data[len(route):] 539 l.append(route) 540 self.data = self.announced = l
541
542 - def __len__(self):
543 return self.__hdr_len__ + \ 544 1 + len(self.next_hop) + \ 545 1 + sum(map(len, self.snpas)) + \ 546 sum(map(len, self.announced))
547
548 - def __bytes__(self):
549 return self.pack_hdr() + \ 550 struct.pack('B', len(self.next_hop)) + \ 551 bytes(self.next_hop) + \ 552 struct.pack('B', len(self.snpas)) + \ 553 b''.join(map(bytes, self.snpas)) + \ 554 b''.join(map(bytes, self.announced))
555
556 - class SNPA(object):
557 __hdr__ = ( 558 ('len', 'B', 0), 559 ) 560
561 - def unpack(self, buf):
562 dpkt.Packet.unpack(self, buf) 563 self.data = self.data[:(self.len + 1) // 2]
564
565 - class MPUnreachNLRI(dpkt.Packet):
566 __hdr__ = ( 567 ('afi', 'H', AFI_IPV4), 568 ('safi', 'B', SAFI_UNICAST), 569 ) 570
571 - def unpack(self, buf):
572 dpkt.Packet.unpack(self, buf) 573 574 if self.afi == AFI_IPV4: 575 Route = RouteIPV4 576 elif self.afi == AFI_IPV6: 577 Route = RouteIPV6 578 else: 579 Route = RouteGeneric 580 581 # Withdrawn Routes 582 l = [] 583 while self.data: 584 route = Route(self.data) 585 self.data = self.data[len(route):] 586 l.append(route) 587 self.data = self.withdrawn = l
588
589 - def __len__(self):
590 return self.__hdr_len__ + sum(map(len, self.data))
591
592 - def __bytes__(self):
593 return self.pack_hdr() + b''.join(map(bytes, self.data))
594
595 - class Notification(dpkt.Packet):
596 __hdr__ = ( 597 ('code', 'B', 0), 598 ('subcode', 'B', 0), 599 ) 600
601 - def unpack(self, buf):
602 dpkt.Packet.unpack(self, buf) 603 self.error = self.data
604
605 - class Keepalive(dpkt.Packet):
606 - def unpack(self, buf):
607 pass
608
609 - def __len__(self):
610 return 0
611
612 - def __bytes__(self):
613 return b''
614
615 - class RouteRefresh(dpkt.Packet):
616 __hdr__ = ( 617 ('afi', 'H', AFI_IPV4), 618 ('rsvd', 'B', 0), 619 ('safi', 'B', SAFI_UNICAST) 620 )
621
622 623 -class RouteGeneric(dpkt.Packet):
624 __hdr__ = ( 625 ('len', 'B', 0), 626 ) 627
628 - def unpack(self, buf):
629 dpkt.Packet.unpack(self, buf) 630 self.data = self.prefix = self.data[:(self.len + 7) // 8]
631
632 633 -class RouteIPV4(dpkt.Packet):
634 __hdr__ = ( 635 ('len', 'B', 0), 636 ) 637
638 - def unpack(self, buf):
639 dpkt.Packet.unpack(self, buf) 640 tmp = self.data[:(self.len + 7) // 8] 641 tmp += (4 - len(tmp)) * b'\x00' 642 self.data = self.prefix = tmp
643
644 - def __repr__(self):
645 cidr = '%s/%d' % (socket.inet_ntoa(self.prefix), self.len) 646 return '%s(%s)' % (self.__class__.__name__, cidr)
647
648 - def __len__(self):
649 return self.__hdr_len__ + (self.len + 7) // 8
650
651 - def __bytes__(self):
652 return self.pack_hdr() + self.prefix[:(self.len + 7) // 8]
653
654 655 -class RouteIPV6(dpkt.Packet):
656 __hdr__ = ( 657 ('len', 'B', 0), 658 ) 659
660 - def unpack(self, buf):
661 dpkt.Packet.unpack(self, buf) 662 tmp = self.data[:(self.len + 7) // 8] 663 tmp += (16 - len(tmp)) * b'\x00' 664 self.data = self.prefix = tmp
665
666 - def __len__(self):
667 return self.__hdr_len__ + (self.len + 7) // 8
668
669 - def __bytes__(self):
670 return self.pack_hdr() + self.prefix[:(self.len + 7) // 8]
671 672 673 __bgp1 = b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x13\x04' 674 __bgp2 = b'\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' 675 __bgp3 = b'\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' 676 __bgp4 = b'\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'
677 678 679 -def test_pack():
680 assert (__bgp1 == bytes(BGP(__bgp1))) 681 assert (__bgp2 == bytes(BGP(__bgp2))) 682 assert (__bgp3 == bytes(BGP(__bgp3))) 683 assert (__bgp4 == bytes(BGP(__bgp4)))
684
685 686 -def test_unpack():
687 b1 = BGP(__bgp1) 688 assert (b1.len == 19) 689 assert (b1.type == KEEPALIVE) 690 assert (b1.keepalive is not None) 691 692 b2 = BGP(__bgp2) 693 assert (b2.type == UPDATE) 694 assert (len(b2.update.withdrawn) == 0) 695 assert (len(b2.update.announced) == 1) 696 assert (len(b2.update.attributes) == 9) 697 a = b2.update.attributes[1] 698 assert (a.type == AS_PATH) 699 assert (a.len == 10) 700 assert (len(a.as_path.segments) == 2) 701 s = a.as_path.segments[0] 702 assert (s.type == AS_SET) 703 assert (s.len == 2) 704 assert (len(s.path) == 2) 705 assert (s.path[0] == 500) 706 707 a = b2.update.attributes[6] 708 assert (a.type == COMMUNITIES) 709 assert (a.len == 12) 710 assert (len(a.communities.list) == 3) 711 c = a.communities.list[0] 712 assert (c.asn == 65215) 713 assert (c.value == 1) 714 r = b2.update.announced[0] 715 assert (r.len == 22) 716 assert (r.prefix == b'\xc0\xa8\x04\x00') 717 718 b3 = BGP(__bgp3) 719 assert (b3.type == UPDATE) 720 assert (len(b3.update.withdrawn) == 0) 721 assert (len(b3.update.announced) == 0) 722 assert (len(b3.update.attributes) == 6) 723 a = b3.update.attributes[0] 724 assert (a.optional == False) 725 assert (a.transitive == True) 726 assert (a.partial == False) 727 assert (a.extended_length == False) 728 assert (a.type == ORIGIN) 729 assert (a.len == 1) 730 o = a.origin 731 assert (o.type == ORIGIN_IGP) 732 a = b3.update.attributes[5] 733 assert (a.optional == True) 734 assert (a.transitive == False) 735 assert (a.partial == False) 736 assert (a.extended_length == True) 737 assert (a.type == MP_REACH_NLRI) 738 assert (a.len == 30) 739 m = a.mp_reach_nlri 740 assert (m.afi == AFI_IPV4) 741 assert (len(m.snpas) == 0) 742 assert (len(m.announced) == 1) 743 p = m.announced[0] 744 assert (p.len == 96) 745 746 b4 = BGP(__bgp4) 747 assert (b4.len == 45) 748 assert (b4.type == OPEN) 749 assert (b4.open.asn == 237) 750 assert (b4.open.param_len == 16) 751 assert (len(b4.open.parameters) == 3) 752 p = b4.open.parameters[0] 753 assert (p.type == CAPABILITY) 754 assert (p.len == 6) 755 c = p.capability 756 assert (c.code == CAP_MULTIPROTOCOL) 757 assert (c.len == 4) 758 assert (c.data == b'\x00\x01\x00\x01') 759 c = b4.open.parameters[2].capability 760 assert (c.code == CAP_ROUTE_REFRESH) 761 assert (c.len == 0)
762 763 764 if __name__ == '__main__': 765 test_pack() 766 test_unpack() 767 print('Tests Successful...') 768