Package netaddr :: Module strategy
[hide private]
[frames] | no frames]

Source Code for Module netaddr.strategy

  1  #!/usr/bin/env python 
  2  #----------------------------------------------------------------------------- 
  3  #   Copyright (c) 2008-2009, David P. D. Moss. All rights reserved. 
  4  # 
  5  #   Released under the BSD license. See the LICENSE file for details. 
  6  #----------------------------------------------------------------------------- 
  7  """ 
  8  network address conversion logic, constants and shared strategy objects. 
  9  """ 
 10  import struct as _struct 
 11  import re as _re 
 12  from netaddr.util import BYTES_TO_BITS as _BYTES_TO_BITS 
 13   
 14  #   Check whether we need to use fallback code or not. 
 15  try: 
 16      import socket as _socket 
 17      #   Check for a common bug on Windows and some other socket modules. 
 18      _socket.inet_aton('255.255.255.255') 
 19      from socket import inet_aton as _inet_aton, \ 
 20                         inet_ntoa as _inet_ntoa, \ 
 21                         AF_INET as _AF_INET 
 22  except: 
 23      from netaddr.fallback import inet_aton as _inet_aton, \ 
 24                                   inet_ntoa as _inet_ntoa, \ 
 25                                   AF_INET as _AF_INET 
 26  try: 
 27      import socket as _socket 
 28      #   These might all generate exceptions on different platforms. 
 29      if not _socket.has_ipv6: 
 30          raise Exception('IPv6 disabled') 
 31      _socket.inet_pton 
 32      _socket.AF_INET6 
 33      from socket import inet_pton as _inet_pton, \ 
 34                         inet_ntop as _inet_ntop, \ 
 35                         AF_INET6 as _AF_INET6 
 36  except: 
 37      from netaddr.fallback import inet_pton as _inet_pton, \ 
 38                                   inet_ntop as _inet_ntop, \ 
 39                                   AF_INET6 as _AF_INET6 
 40   
 41  from netaddr import BIG_ENDIAN_PLATFORM, AT_UNSPEC, AT_INET, AT_INET6, \ 
 42                      AT_LINK, AT_EUI64, AT_NAMES, AddrFormatError 
 43   
 44  #----------------------------------------------------------------------------- 
45 -class AddrStrategy(object):
46 """Basic support for common operations performed on each address type""" 47 48 #: Lookup table for struct module format strings. 49 STRUCT_FORMATS = { 50 8 : 'B', # unsigned char 51 16 : 'H', # unsigned short 52 32 : 'I', # unsigned int 53 } 54
55 - def __init__(self, width, word_size, word_sep, word_fmt='%x', 56 addr_type=AT_UNSPEC, word_base=16):
57 """ 58 Constructor. 59 60 @param width: size of address in bits. 61 (e.g. 32 - IPv4, 48 - MAC, 128 - IPv6) 62 63 @param word_size: size of each word. 64 (e.g. 8 - octets, 16 - hextets) 65 66 @param word_sep: separator between each word. 67 (e.g. '.' - IPv4, ':' - IPv6, '-' - EUI-48) 68 69 @param word_fmt: format string for each word. 70 (Default: '%x') 71 72 @param addr_type: address type. 73 (Default: AT_UNSPEC) 74 75 @param word_base: number base used to convert each word using int(). 76 (Default: 16) 77 """ 78 79 self.width = width 80 self.max_int = 2 ** width - 1 81 self.word_size = word_size 82 self.num_words = width / word_size 83 self.max_word = 2 ** word_size - 1 84 self.word_sep = word_sep 85 self.word_fmt = word_fmt 86 self.word_base = word_base 87 self.addr_type = addr_type 88 89 try: 90 self.name = AT_NAMES[addr_type] 91 except KeyError: 92 self.name = AT_NAMES[AT_UNSPEC]
93
94 - def __repr__(self):
95 """@return: executable Python string to recreate equivalent object""" 96 return "%s(%r, %r, %r, %r, %r)" % (self.__class__.__name__, 97 self.width, self.word_size, self.word_sep, self.addr_type, 98 self.word_base)
99 100 #------------------------------------------------------------------------- 101 # Binary methods. 102 #------------------------------------------------------------------------- 103
104 - def valid_bits(self, bits):
105 """ 106 @param bits: A network address in readable binary form. 107 108 @return: C{True} if network address is valid for this address type, 109 C{False} otherwise. 110 """ 111 if not isinstance(bits, (str, unicode)): 112 return False 113 114 bits = bits.replace(self.word_sep, '') 115 116 if len(bits) != self.width: 117 return False 118 119 try: 120 if 0 <= int(bits, 2) <= self.max_int: 121 return True 122 except ValueError: 123 return False 124 return False
125
126 - def bits_to_int(self, bits):
127 """ 128 @param bits: A network address in readable binary form. 129 130 @return: An unsigned integer that is equivalent to value represented 131 by network address in readable binary form. 132 """ 133 if not self.valid_bits(bits): 134 raise ValueError('%r is not a valid binary form string for ' \ 135 'address type!' % bits) 136 137 return int(bits.replace(self.word_sep, ''), 2)
138 139 #------------------------------------------------------------------------- 140 # Integer methods. 141 #------------------------------------------------------------------------- 142
143 - def valid_int(self, int_val):
144 """ 145 @param int_val: An unsigned integer. 146 147 @return: C{True} if integer falls within the boundaries of this 148 address type, C{False} otherwise. 149 """ 150 if not isinstance(int_val, (int, long)): 151 return False 152 153 return 0 <= int_val <= self.max_int
154
155 - def int_to_str(self, int_val):
156 """ 157 @param int_val: An unsigned integer. 158 159 @return: A network address in string form that is equivalent to value 160 represented by an unsigned integer. 161 """ 162 words = self.int_to_words(int_val) 163 tokens = [self.word_fmt % i for i in words] 164 addr = self.word_sep.join(tokens) 165 166 return addr
167
168 - def int_to_bits(self, int_val, word_sep=None):
169 """ 170 @param int_val: An unsigned integer. 171 172 @param word_sep: (optional) the separator to insert between words. 173 Default: None - use default separator for address type. 174 175 @return: A network address in readable binary form that is equivalent 176 to value represented by an unsigned integer. 177 """ 178 bit_words = [] 179 180 for word in self.int_to_words(int_val): 181 bits = [] 182 while word: 183 bits.append(_BYTES_TO_BITS[word&255]) 184 word >>= 8 185 bits.reverse() 186 bit_str = ''.join(bits) or '0'*self.word_size 187 bits = ('0'*self.word_size+bit_str)[-self.word_size:] 188 bit_words.append(bits) 189 190 if word_sep is not None: 191 # Custom separator. 192 if not hasattr(word_sep, 'join'): 193 raise ValueError('Word separator must be a string!') 194 return word_sep.join(bit_words) 195 196 # Default separator. 197 return self.word_sep.join(bit_words)
198
199 - def int_to_bin(self, int_val):
200 """ 201 @param int_val: An unsigned integer. 202 203 @return: A network address in standard binary representation format 204 that is equivalent to integer address value. Essentially a back 205 port of the bin() builtin in Python 2.6.x and higher. 206 """ 207 bit_words = [] 208 209 for word in self.int_to_words(int_val): 210 bits = [] 211 while word: 212 bits.append(_BYTES_TO_BITS[word&255]) 213 word >>= 8 214 bits.reverse() 215 bit_str = ''.join(bits) or '0'*self.word_size 216 bits = ('0'*self.word_size+bit_str)[-self.word_size:] 217 bit_words.append(bits) 218 219 return '0b' + _re.sub(r'^[0]+([01]+)$', r'\1', ''.join(bit_words))
220
221 - def int_to_words(self, int_val, num_words=None, word_size=None):
222 """ 223 @param int_val: An unsigned integer to be divided up into words. 224 225 @param num_words: (optional) number of words expected in return value 226 tuple. Uses address type default if not specified. 227 228 @param word_size: (optional) size/width of individual words (in bits). 229 Uses address type default if not specified. 230 """ 231 if not self.valid_int(int_val): 232 raise IndexError('integer %r is out of bounds!' % hex(int_val)) 233 234 # Set defaults for optional args. 235 if num_words is None: 236 num_words = self.num_words 237 if word_size is None: 238 word_size = self.word_size 239 240 max_word_size = 2 ** word_size - 1 241 242 words = [] 243 for _ in range(num_words): 244 word = int_val & max_word_size 245 words.append(int(word)) 246 int_val >>= word_size 247 248 return tuple(reversed(words))
249
250 - def int_to_packed(self, int_val):
251 """ 252 @param int_val: the integer to be packed. 253 254 @return: a packed string that is equivalent to value represented by an 255 unsigned integer. 256 """ 257 258 words = self.int_to_words(int_val, self.num_words, self.word_size) 259 260 try: 261 fmt = '>%d%s' % (self.num_words, AddrStrategy.STRUCT_FORMATS[ 262 self.word_size]) 263 except KeyError: 264 raise ValueError('unsupported word size: %d!' % self.word_size) 265 266 return _struct.pack(fmt, *words)
267 268 269 #------------------------------------------------------------------------- 270 # Packed string methods. 271 #------------------------------------------------------------------------- 272
273 - def packed_to_int(self, packed_int):
274 """ 275 @param packed_int: a packed string containing an unsigned integer. 276 It is assumed that the string is packed in network byte order. 277 278 @return: An unsigned integer equivalent to value of network address 279 represented by packed binary string. 280 """ 281 try: 282 fmt = '>%d%s' % (self.num_words, AddrStrategy.STRUCT_FORMATS[ 283 self.word_size]) 284 except KeyError: 285 raise ValueError('unsupported word size: %d!' % self.word_size) 286 287 words = list(_struct.unpack(fmt, packed_int)) 288 289 int_val = 0 290 for i, num in enumerate(reversed(words)): 291 word = num 292 word = word << self.word_size * i 293 int_val = int_val | word 294 295 return int_val
296 297 #------------------------------------------------------------------------- 298 # String methods. 299 #------------------------------------------------------------------------- 300
301 - def valid_str(self, addr):
302 """ 303 @param addr: A network address in string form. 304 305 @return: C{True} if network address in string form is valid for this 306 address type, C{False} otherwise. 307 """ 308 if not isinstance(addr, (str, unicode)): 309 return False 310 311 tokens = addr.split(self.word_sep) 312 if len(tokens) != self.num_words: 313 return False 314 315 try: 316 for token in tokens: 317 if not 0 <= int(token, self.word_base) <= \ 318 self.max_word: 319 return False 320 except TypeError: 321 return False 322 except ValueError: 323 return False 324 return True
325
326 - def str_to_int(self, addr):
327 """ 328 @param addr: A network address in string form. 329 330 @return: An unsigned integer equivalent to value represented by network 331 address in string form. 332 """ 333 if not self.valid_str(addr): 334 raise ValueError('%r is not a recognised string representation' \ 335 ' of this address type!' % addr) 336 337 tokens = addr.split(self.word_sep) 338 words = [ int(token, self.word_base) for token in tokens ] 339 340 return self.words_to_int(words)
341 342 #------------------------------------------------------------------------- 343 # Word list methods. 344 #------------------------------------------------------------------------- 345
346 - def valid_words(self, words):
347 """ 348 @param words: A sequence containing integer word values. 349 350 @return: C{True} if word sequence is valid for this address type, 351 C{False} otherwise. 352 """ 353 if not hasattr(words, '__iter__'): 354 return False 355 356 if len(words) != self.num_words: 357 return False 358 359 for i in words: 360 if not isinstance(i, (int, long)): 361 return False 362 363 if not 0 <= i <= self.max_word: 364 return False 365 return True
366
367 - def words_to_int(self, words):
368 """ 369 @param words: A list or tuple containing integer word values. 370 371 @return: An unsigned integer that is equivalent to value represented 372 by word sequence. 373 """ 374 if not self.valid_words(words): 375 raise ValueError('%r is not a valid word list!' % words) 376 377 int_val = 0 378 for i, num in enumerate(reversed(words)): 379 word = num 380 word = word << self.word_size * i 381 int_val = int_val | word 382 383 return int_val
384 385 #-----------------------------------------------------------------------------
386 -class IPv4Strategy(AddrStrategy):
387 """An L{AddrStrategy} for IPv4 address processing."""
388 - def __init__(self):
389 """Constructor.""" 390 super(IPv4Strategy, self).__init__(width=32, word_size=8, 391 word_fmt='%d', word_sep='.', addr_type=AT_INET, word_base=10)
392
393 - def valid_str(self, addr):
394 """ 395 @param addr: An IP address in presentation (string) format. 396 397 @return: C{True} if network address in string form is valid for this 398 address type, C{False} otherwise. 399 """ 400 if addr == '': 401 raise AddrFormatError('Empty strings are not supported!') 402 403 try: 404 _inet_aton(addr) 405 except: 406 return False 407 return True
408
409 - def str_to_int(self, addr):
410 """ 411 @param addr: An IPv4 dotted decimal address in string form. 412 413 @return: An unsigned integer that is equivalent to value represented 414 by the IPv4 dotted decimal address string. 415 """ 416 if addr == '': 417 raise AddrFormatError('Empty strings are not supported!') 418 try: 419 return _struct.unpack('>I', _inet_aton(addr))[0] 420 except: 421 raise AddrFormatError('%r is not a valid IPv4 address string!' \ 422 % addr)
423
424 - def int_to_str(self, int_val):
425 """ 426 @param int_val: An unsigned integer. 427 428 @return: An IPv4 dotted decimal address string that is equivalent to 429 value represented by a 32 bit unsigned integer. 430 """ 431 if self.valid_int(int_val): 432 return _inet_ntoa(_struct.pack('>I', int_val)) 433 else: 434 raise ValueError('%r is not a valid 32-bit unsigned integer!' \ 435 % int_val)
436
437 - def int_to_words(self, int_val, num_words=None, word_size=None):
438 """ 439 @param int_val: An unsigned integer. 440 441 @param num_words: (unused) *** interface compatibility only *** 442 443 @param word_size: (unused) *** interface compatibility only *** 444 445 @return: An integer word (octet) sequence that is equivalent to value 446 represented by an unsigned integer. 447 """ 448 if not self.valid_int(int_val): 449 raise ValueError('%r is not a valid integer value supported ' \ 450 'by this address type!' % int_val) 451 return _struct.unpack('4B', _struct.pack('>I', int_val))
452
453 - def words_to_int(self, octets):
454 """ 455 @param octets: A list or tuple containing integer octets. 456 457 @return: An unsigned integer that is equivalent to value represented 458 by word (octet) sequence. 459 """ 460 if not self.valid_words(octets): 461 raise ValueError('%r is not a valid octet list for an IPv4 ' \ 462 'address!' % octets) 463 return _struct.unpack('>I', _struct.pack('4B', *octets))[0]
464
465 - def int_to_arpa(self, int_val):
466 """ 467 @param int_val: An unsigned integer. 468 469 @return: The reverse DNS lookup for an IPv4 address in network byte 470 order integer form. 471 """ 472 words = ["%d" % i for i in self.int_to_words(int_val)] 473 words.reverse() 474 words.extend(['in-addr', 'arpa', '']) 475 return '.'.join(words)
476 477 #-----------------------------------------------------------------------------
478 -class IPv6Strategy(AddrStrategy):
479 """ 480 An L{AddrStrategy} for IPv6 address processing. 481 482 Implements the operations that can be performed on an IPv6 network address 483 in accordance with RFC 4291. 484 """
485 - def __init__(self):
486 """Constructor.""" 487 super(IPv6Strategy, self).__init__(addr_type=AT_INET6, 488 width=128, word_size=16, word_fmt='%x', word_sep=':')
489
490 - def valid_str(self, addr):
491 """ 492 @param addr: An IPv6 address in string form. 493 494 @return: C{True} if IPv6 network address string is valid, C{False} 495 otherwise. 496 """ 497 if addr == '': 498 raise AddrFormatError('Empty strings are not supported!') 499 500 try: 501 _inet_pton(_AF_INET6, addr) 502 except _socket.error: 503 return False 504 except TypeError: 505 return False 506 except ValueError: 507 return False 508 return True
509
510 - def str_to_int(self, addr):
511 """ 512 @param addr: An IPv6 address in string form. 513 514 @return: The equivalent unsigned integer for a given IPv6 address. 515 """ 516 if addr == '': 517 raise AddrFormatError('Empty strings are not supported!') 518 try: 519 packed_int = _inet_pton(_AF_INET6, addr) 520 return self.packed_to_int(packed_int) 521 except Exception, e: 522 raise AddrFormatError('%r is not a valid IPv6 address string!' \ 523 % addr)
524
525 - def int_to_str(self, int_val, compact=True, word_fmt=None):
526 """ 527 @param int_val: An unsigned integer. 528 529 @param compact: (optional) A boolean flag indicating if compact 530 formatting should be used. If True, this method uses the '::' 531 string to represent the first adjacent group of words with a value 532 of zero. Default: True 533 534 @param word_fmt: (optional) The Python format string used to override 535 formatting for each word. Only applies when compact is False. 536 537 @return: The IPv6 string form equal to the unsigned integer provided. 538 """ 539 try: 540 packed_int = self.int_to_packed(int_val) 541 if compact: 542 # Default return value. 543 return _inet_ntop(_AF_INET6, packed_int) 544 else: 545 # Custom return value. 546 if word_fmt is None: 547 word_fmt = self.word_fmt 548 words = list(_struct.unpack('>8H', packed_int)) 549 tokens = [word_fmt % word for word in words] 550 return self.word_sep.join(tokens) 551 except Exception, e: 552 raise ValueError('%r is not a valid 128-bit unsigned integer!' \ 553 % int_val)
554
555 - def int_to_packed(self, int_val):
556 """ 557 @param int_val: the integer to be packed. 558 559 @return: a packed string that is equivalent to value represented by an 560 unsigned integer (in network byte order). 561 """ 562 # Here we've over-ridden the normal values to get the fastest 563 # possible conversion speeds. Still quite slow versus IPv4 speed ups. 564 num_words = 4 565 word_size = 32 566 567 words = self.int_to_words(int_val, num_words, word_size) 568 569 try: 570 fmt = '>%d%s'% (num_words, AddrStrategy.STRUCT_FORMATS[word_size]) 571 except KeyError: 572 raise ValueError('unsupported word size: %d!' % word_size) 573 574 return _struct.pack(fmt, *words)
575
576 - def packed_to_int(self, packed_int):
577 """ 578 @param packed_int: a packed string containing an unsigned integer. 579 It is assumed that string is packed in network byte order. 580 581 @return: An unsigned integer that is equivalent to value of network 582 address represented by packed binary string. 583 """ 584 # Here we've over-ridden the normal values to get the fastest 585 # conversion speeds. Still quite slow versus IPv4 speed ups. 586 num_words = 4 587 word_size = 32 588 589 try: 590 fmt = '>%d%s'% (num_words, AddrStrategy.STRUCT_FORMATS[word_size]) 591 except KeyError: 592 raise ValueError('unsupported word size: %d!' % word_size) 593 594 words = list(_struct.unpack(fmt, packed_int)) 595 596 int_val = 0 597 for i, num in enumerate(reversed(words)): 598 word = num 599 word = word << word_size * i 600 int_val = int_val | word 601 602 return int_val
603
604 - def int_to_arpa(self, int_val):
605 """ 606 @param int_val: An unsigned integer. 607 608 @return: The reverse DNS lookup for an IPv6 address in network byte 609 order integer form. 610 """ 611 addr = self.int_to_str(int_val, compact=False, word_fmt='%.4x') 612 tokens = list(addr.replace(':', '')) 613 tokens.reverse() 614 # We won't support ip6.int here - see RFC 3152 for details. 615 tokens = tokens + ['ip6', 'arpa', ''] 616 return '.'.join(tokens)
617 618 #-----------------------------------------------------------------------------
619 -class EUI48Strategy(AddrStrategy):
620 """ 621 Implements the operations that can be performed on an IEEE 48-bit EUI 622 (Extended Unique Identifer) a.k.a. a MAC (Media Access Control) layer 2 623 address. 624 625 Supports all common (and some less common MAC string formats including 626 Cisco's 'triple hextet' format and also bare MACs that contain no 627 delimiters. 628 """ 629 # Regular expression to match the numerous different MAC formats. 630 RE_MAC_FORMATS = ( 631 # 2 bytes x 6 (UNIX, Windows, EUI-48) 632 '^' + ':'.join(['([0-9A-F]{1,2})'] * 6) + '$', 633 '^' + '-'.join(['([0-9A-F]{1,2})'] * 6) + '$', 634 635 # 4 bytes x 3 (Cisco) 636 '^' + ':'.join(['([0-9A-F]{1,4})'] * 3) + '$', 637 '^' + '-'.join(['([0-9A-F]{1,4})'] * 3) + '$', 638 639 # 6 bytes x 2 (PostgreSQL) 640 '^' + '-'.join(['([0-9A-F]{5,6})'] * 2) + '$', 641 '^' + ':'.join(['([0-9A-F]{5,6})'] * 2) + '$', 642 643 # 12 bytes (bare, no delimiters) 644 '^(' + ''.join(['[0-9A-F]'] * 12) + ')$', 645 '^(' + ''.join(['[0-9A-F]'] * 11) + ')$', 646 ) 647 # For efficiency, replace each string regexp with its compiled 648 # equivalent. 649 RE_MAC_FORMATS = [_re.compile(_, _re.IGNORECASE) for _ in RE_MAC_FORMATS] 650
651 - def __init__(self, word_fmt='%.2X', word_sep='-'):
652 """ 653 Constructor. 654 655 @param word_sep: separator between each word. 656 (Default: '-') 657 658 @param word_fmt: format string for each hextet. 659 (Default: '%02x') 660 """ 661 super(self.__class__, self).__init__(addr_type=AT_LINK, width=48, 662 word_size=8, word_fmt=word_fmt, word_sep=word_sep)
663 664
665 - def reset(self):
666 """ 667 Resets the internal state of this strategy to safe default values. 668 """ 669 # These are the settings for EUI-48 specific formatting. 670 self.width = 48 671 self.max_int = 2 ** self.width - 1 672 self.word_size = 8 673 self.num_words = self.width / self.word_size 674 self.max_word = 2 ** self.word_size - 1 675 self.word_sep = '-' 676 self.word_fmt = '%.2X' 677 self.word_base = 16 678 self.addr_type = AT_LINK
679
680 - def valid_str(self, addr):
681 """ 682 @param addr: An EUI-48 or MAC address in string form. 683 684 @return: C{True} if MAC address string is valid, C{False} otherwise. 685 """ 686 if not isinstance(addr, (str, unicode)): 687 return False 688 689 for regexp in EUI48Strategy.RE_MAC_FORMATS: 690 match_result = regexp.findall(addr) 691 if len(match_result) != 0: 692 return True 693 return False
694
695 - def str_to_int(self, addr):
696 """ 697 @param addr: An EUI-48 or MAC address in string form. 698 699 @return: An unsigned integer that is equivalent to value represented 700 by EUI-48/MAC string address. 701 """ 702 words = [] 703 if isinstance(addr, (str, unicode)): 704 found_match = False 705 for regexp in EUI48Strategy.RE_MAC_FORMATS: 706 match_result = regexp.findall(addr) 707 if len(match_result) != 0: 708 found_match = True 709 if isinstance(match_result[0], tuple): 710 words = match_result[0] 711 else: 712 words = (match_result[0],) 713 break 714 if not found_match: 715 raise AddrFormatError('%r is not a supported MAC format!' \ 716 % addr) 717 else: 718 raise TypeError('%r is not str() or unicode()!' % addr) 719 720 int_val = None 721 722 if len(words) == 6: 723 # 2 bytes x 6 (UNIX, Windows, EUI-48) 724 int_val = int(''.join(['%.2x' % int(w, 16) for w in words]), 16) 725 elif len(words) == 3: 726 # 4 bytes x 3 (Cisco) 727 int_val = int(''.join(['%.4x' % int(w, 16) for w in words]), 16) 728 elif len(words) == 2: 729 # 6 bytes x 2 (PostgreSQL) 730 int_val = int(''.join(['%.6x' % int(w, 16) for w in words]), 16) 731 elif len(words) == 1: 732 # 12 bytes (bare, no delimiters) 733 int_val = int('%012x' % int(words[0], 16), 16) 734 else: 735 raise AddrFormatError('unexpected word count in MAC address %r!' \ 736 % addr) 737 738 return int_val
739
740 - def int_to_str(self, int_val, word_sep=None, word_fmt=None):
741 """ 742 @param int_val: An unsigned integer. 743 744 @param word_sep: (optional) The separator used between words in an 745 address string. 746 747 @param word_fmt: (optional) A Python format string used to format 748 each word of address. 749 750 @return: A MAC address in string form that is equivalent to value 751 represented by an unsigned integer. 752 """ 753 _word_sep = self.word_sep 754 if word_sep is not None: 755 _word_sep = word_sep 756 757 _word_fmt = self.word_fmt 758 if word_fmt is not None: 759 _word_fmt = word_fmt 760 761 words = self.int_to_words(int_val) 762 tokens = [_word_fmt % i for i in words] 763 addr = _word_sep.join(tokens) 764 765 return addr
766 767 #----------------------------------------------------------------------------- 768 # Shared strategy objects for supported address types. 769 #----------------------------------------------------------------------------- 770 771 #: A shared strategy object supporting all operations on IPv4 addresses. 772 ST_IPV4 = IPv4Strategy() 773 774 #: A shared strategy object supporting all operations on IPv6 addresses. 775 ST_IPV6 = IPv6Strategy() 776 777 #: A shared strategy object supporting all operations on EUI-48/MAC addresses. 778 ST_EUI48 = EUI48Strategy() 779 780 #: A shared strategy object supporting all operations on EUI-64 addresses. 781 ST_EUI64 = AddrStrategy(addr_type=AT_EUI64, width=64, word_size=8, \ 782 word_fmt='%.2X', word_sep='-') 783 784 #----------------------------------------------------------------------------- 785 if __name__ == '__main__': 786 pass 787