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

Source Code for Module dpkt.bgp

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