Changeset 920:5b7a25738a28

Show
Ignore:
Timestamp:
09/12/08 17:57:20 (4 months ago)
Author:
Phil <phil@secdev.org>
Message:

split utils

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • scapy/arch/linux.py

    r919 r920  
    1010from fcntl import ioctl 
    1111import scapy.utils 
     12import scapy.utils6 
    1213from scapy.config import conf 
    1314from scapy.data import * 
     
    204205        tmp = i.split() 
    205206        addr = struct.unpack('4s4s4s4s4s4s4s4s', tmp[0]) 
    206         addr = in6_ptop(':'.join(addr)) 
     207        addr = scapy.utils6.in6_ptop(':'.join(addr)) 
    207208        ret.append((addr, int(tmp[3], 16), tmp[5])) # (addr, scope, iface) 
    208209    return ret 
     
    227228        ret = struct.unpack('4s4s4s4s4s4s4s4s', p) 
    228229        ret = ':'.join(ret) 
    229         return in6_ptop(ret) 
     230        return scapy.utils6.in6_ptop(ret) 
    230231     
    231232    lifaddr = in6_getifaddr()  
  • scapy/arch/unix.py

    r919 r920  
    1010import scapy.config 
    1111import scapy.utils 
     12import scapy.utils6 
    1213import scapy.arch 
    1314 
     
    132133 
    133134            xx = str(a).split('/')[0] 
    134             addr = in6_ptop(xx) 
     135            addr = scapy.utils6.in6_ptop(xx) 
    135136 
    136             scope = in6_getscope(addr) 
     137            scope = scapy.utils6.in6_getscope(addr) 
    137138 
    138139            ret.append((xx, scope, ifname)) 
  • scapy/layers/inet6.py

    r919 r920  
    3232from scapy.supersocket import SuperSocket,L3RawSocket 
    3333from scapy.arch import * 
     34from scapy.utils6 import * 
    3435 
    3536 
     
    565566 
    566567 
    567 # Think before modify it : for instance, FE::1 does exist and is unicast 
    568 # there are many others like that. 
    569 # TODO : integrate Unique Local Addresses 
    570 def in6_getAddrType(addr): 
    571     naddr = inet_pton(socket.AF_INET6, addr) 
    572     paddr = inet_ntop(socket.AF_INET6, naddr) # normalize 
    573     addrType = 0 
    574     # _Assignable_ Global Unicast Address space 
    575     # is defined in RFC 3513 as those in 2000::/3 
    576     if ((struct.unpack("B", naddr[0])[0] & 0xE0) == 0x20): 
    577         addrType = (IPV6_ADDR_UNICAST | IPV6_ADDR_GLOBAL) 
    578         if naddr[:2] == ' \x02': # Mark 6to4 @ 
    579             addrType |= IPV6_ADDR_6TO4 
    580     elif naddr[0] == '\xff': # multicast 
    581         addrScope = paddr[3] 
    582         if addrScope == '2': 
    583             addrType = (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_MULTICAST) 
    584         elif addrScope == 'e': 
    585             addrType = (IPV6_ADDR_GLOBAL | IPV6_ADDR_MULTICAST) 
    586         else: 
    587             addrType = (IPV6_ADDR_GLOBAL | IPV6_ADDR_MULTICAST) 
    588     elif ((naddr[0] == '\xfe') and ((int(paddr[2], 16) & 0xC) == 0x8)): 
    589         addrType = (IPV6_ADDR_UNICAST | IPV6_ADDR_LINKLOCAL) 
    590     elif paddr == "::1": 
    591         addrType = IPV6_ADDR_LOOPBACK 
    592     elif paddr == "::": 
    593         addrType = IPV6_ADDR_UNSPECIFIED 
    594     else: 
    595         # Everything else is global unicast (RFC 3513) 
    596         # Even old deprecated (RFC3879) Site-Local addresses 
    597         addrType = (IPV6_ADDR_GLOBAL | IPV6_ADDR_UNICAST) 
    598  
    599     return addrType 
    600  
    601 def find_ifaddr2(addr, plen, laddr): 
    602     dstAddrType = in6_getAddrType(addr) 
    603      
    604     if dstAddrType == IPV6_ADDR_UNSPECIFIED: # Shouldn't happen as dst addr 
    605         return None 
    606  
    607     if dstAddrType == IPV6_ADDR_LOOPBACK:  
    608         return None 
    609  
    610     tmp = [[]] + map(lambda (x,y,z): (in6_getAddrType(x), x, y, z), laddr) 
    611     def filterSameScope(l, t): 
    612         if (t[0] & dstAddrType & IPV6_ADDR_SCOPE_MASK) == 0: 
    613             l.append(t) 
    614         return l 
    615     sameScope = reduce(filterSameScope, tmp) 
    616      
    617     l =  len(sameScope)  
    618     if l == 1:  # Only one address for our scope 
    619         return sameScope[0][1] 
    620  
    621     elif l > 1: # Muliple addresses for our scope 
    622         stfAddr = filter(lambda x: x[0] & IPV6_ADDR_6TO4, sameScope) 
    623         nativeAddr = filter(lambda x: not (x[0] & IPV6_ADDR_6TO4), sameScope) 
    624  
    625         if not (dstAddrType & IPV6_ADDR_6TO4): # destination is not 6to4 
    626            if len(nativeAddr) != 0: 
    627                return nativeAddr[0][1] 
    628            return stfAddr[0][1] 
    629  
    630         else:  # Destination is 6to4, try to use source 6to4 addr if any 
    631             if len(stfAddr) != 0: 
    632                 return stfAddr[0][1] 
    633             return nativeAddr[0][1] 
    634     else: 
    635         return None 
    636  
    637  
    638 def in6_mactoifaceid(mac, ulbit=None): 
    639     """ 
    640     Compute the interface ID in modified EUI-64 format associated  
    641     to the Ethernet address provided as input. 
    642     value taken by U/L bit in the interface identifier is basically  
    643     the reversed value of that in given MAC address it can be forced 
    644     to a specific value by using optional 'ulbit' parameter. 
    645     """ 
    646     if len(mac) != 17: return None 
    647     m = "".join(mac.split(':')) 
    648     if len(m) != 12: return None 
    649     first = int(m[0:2], 16) 
    650     if ulbit is None or not (ulbit == 0 or ulbit == 1): 
    651         ulbit = [1,'-',0][first & 0x02] 
    652     ulbit *= 2 
    653     first = "%.02x" % ((first & 0xFD) | ulbit) 
    654     eui64 = first + m[2:4] + ":" + m[4:6] + "FF:FE" + m[6:8] + ":" + m[8:12] 
    655     return eui64.upper() 
    656  
    657 def in6_ifaceidtomac(ifaceid): # TODO: finish commenting function behavior 
    658     """ 
    659     Extract the mac address from provided iface ID. Iface ID is provided  
    660     in printable format ("XXXX:XXFF:FEXX:XXXX", eventually compressed). None  
    661     is returned on error. 
    662     """ 
    663     try: 
    664         ifaceid = inet_pton(socket.AF_INET6, "::"+ifaceid)[8:16] 
    665     except: 
    666         return None 
    667     if ifaceid[3:5] != '\xff\xfe': 
    668         return None 
    669     first = struct.unpack("B", ifaceid[:1])[0] 
    670     ulbit = 2*[1,'-',0][first & 0x02] 
    671     first = struct.pack("B", ((first & 0xFD) | ulbit)) 
    672     oui = first + ifaceid[1:3] 
    673     end = ifaceid[5:] 
    674     l = map(lambda x: "%.02x" % struct.unpack("B", x)[0], list(oui+end)) 
    675     return ":".join(l) 
    676  
    677 def in6_addrtomac(addr): 
    678     """ 
    679     Extract the mac address from provided address. None is returned 
    680     on error. 
    681     """ 
    682     mask = inet_pton(socket.AF_INET6, "::ffff:ffff:ffff:ffff") 
    683     x = in6_and(mask, inet_pton(socket.AF_INET6, addr)) 
    684     ifaceid = inet_ntop(socket.AF_INET6, x)[2:] 
    685     return in6_ifaceidtomac(ifaceid) 
    686  
    687 def in6_addrtovendor(addr): 
    688     """ 
    689     Extract the MAC address from a modified EUI-64 constructed IPv6 
    690     address provided and use the IANA oui.txt file to get the vendor. 
    691     The database used for the conversion is the one loaded by Scapy, 
    692     based on Wireshark (/usr/share/wireshark/wireshark/manuf)  None 
    693     is returned on error, "UNKNOWN" if the vendor is unknown. 
    694     """ 
    695     mac = in6_addrtomac(addr) 
    696     if mac is None: 
    697         return None 
    698  
    699     res = conf.manufdb._get_manuf(mac) 
    700     if len(res) == 17 and res.count(':') != 5: # Mac address, i.e. unknown 
    701         res = "UNKNOWN" 
    702  
    703     return res 
    704  
    705 def in6_getLinkScopedMcastAddr(addr, grpid=None, scope=2): 
    706     """ 
    707     Generate a Link-Scoped Multicast Address as described in RFC 4489. 
    708     Returned value is in printable notation. 
    709  
    710     'addr' parameter specifies the link-local address to use for generating 
    711     Link-scoped multicast address IID. 
    712      
    713     By default, the function returns a ::/96 prefix (aka last 32 bits of  
    714     returned address are null). If a group id is provided through 'grpid'  
    715     parameter, last 32 bits of the address are set to that value (accepted  
    716     formats : '\x12\x34\x56\x78' or '12345678' or 0x12345678 or 305419896). 
    717  
    718     By default, generated address scope is Link-Local (2). That value can  
    719     be modified by passing a specific 'scope' value as an argument of the 
    720     function. RFC 4489 only authorizes scope values <= 2. Enforcement 
    721     is performed by the function (None will be returned). 
    722      
    723     If no link-local address can be used to generate the Link-Scoped IPv6 
    724     Multicast address, or if another error occurs, None is returned. 
    725     """ 
    726     if not scope in [0, 1, 2]: 
    727         return None     
    728     try: 
    729         if not in6_islladdr(addr): 
    730             return None 
    731         addr = inet_pton(socket.AF_INET6, addr) 
    732     except: 
    733         warning("in6_getLinkScopedMcastPrefix(): Invalid address provided") 
    734         return None 
    735  
    736     iid = addr[8:] 
    737  
    738     if grpid is None: 
    739         grpid = '\x00\x00\x00\x00' 
    740     else: 
    741         if type(grpid) is str: 
    742             if len(grpid) == 8: 
    743                 try: 
    744                     grpid = int(grpid, 16) & 0xffffffff 
    745                 except: 
    746                     warning("in6_getLinkScopedMcastPrefix(): Invalid group id provided") 
    747                     return None 
    748             elif len(grpid) == 4: 
    749                 try: 
    750                     grpid = struct.unpack("!I", grpid)[0] 
    751                 except: 
    752                     warning("in6_getLinkScopedMcastPrefix(): Invalid group id provided") 
    753                     return None 
    754         grpid = struct.pack("!I", grpid) 
    755  
    756     flgscope = struct.pack("B", 0xff & ((0x3 << 4) | scope)) 
    757     plen = '\xff' 
    758     res = '\x00' 
    759     a = '\xff' + flgscope + res + plen + iid + grpid 
    760  
    761     return inet_ntop(socket.AF_INET6, a) 
    762  
    763 def in6_get6to4Prefix(addr): 
    764     """ 
    765     Returns the /48 6to4 prefix associated with provided IPv4 address 
    766     On error, None is returned. No check is performed on public/private 
    767     status of the address 
    768     """ 
    769     try: 
    770         addr = inet_pton(socket.AF_INET, addr) 
    771         addr = inet_ntop(socket.AF_INET6, '\x20\x02'+addr+'\x00'*10) 
    772     except: 
    773         return None 
    774     return addr 
    775  
    776 def in6_6to4ExtractAddr(addr): 
    777     """ 
    778     Extract IPv4 address embbeded in 6to4 address. Passed address must be 
    779     a 6to4 addrees. None is returned on error. 
    780     """ 
    781     try: 
    782         addr = inet_pton(socket.AF_INET6, addr) 
    783     except: 
    784         return None 
    785     if addr[:2] != " \x02": 
    786         return None 
    787     return inet_ntop(socket.AF_INET, addr[2:6]) 
    788      
    789  
    790 def in6_getLocalUniquePrefix(): 
    791     """ 
    792     Returns a pseudo-randomly generated Local Unique prefix. Function 
    793     follows recommandation of Section 3.2.2 of RFC 4193 for prefix 
    794     generation. 
    795     """ 
    796     # Extracted from RFC 1305 (NTP) : 
    797     # NTP timestamps are represented as a 64-bit unsigned fixed-point number,  
    798     # in seconds relative to 0h on 1 January 1900. The integer part is in the  
    799     # first 32 bits and the fraction part in the last 32 bits. 
    800  
    801     # epoch = (1900, 1, 1, 0, 0, 0, 5, 1, 0)  
    802     # x = time.time() 
    803     # from time import gmtime, strftime, gmtime, mktime 
    804     # delta = mktime(gmtime(0)) - mktime(self.epoch) 
    805     # x = x-delta 
    806  
    807     tod = time.time() # time of day. Will bother with epoch later 
    808     i = int(tod) 
    809     j = int((tod - i)*(2**32)) 
    810     tod = struct.pack("!II", i,j) 
    811     # TODO: Add some check regarding system address gathering 
    812     rawmac = get_if_raw_hwaddr(conf.iface6)[1] 
    813     mac = ":".join(map(lambda x: "%.02x" % ord(x), list(rawmac))) 
    814     # construct modified EUI-64 ID 
    815     eui64 = inet_pton(socket.AF_INET6, '::' + in6_mactoifaceid(mac))[8:]  
    816     import sha 
    817     globalid = sha.new(tod+eui64).digest()[:5] 
    818     return inet_ntop(socket.AF_INET6, '\xfd' + globalid + '\x00'*10) 
    819  
    820 def in6_getRandomizedIfaceId(ifaceid, previous=None): 
    821     """ 
    822     Implements the interface ID generation algorithm described in RFC 3041. 
    823     The function takes the Modified EUI-64 interface identifier generated 
    824     as described in RFC 4291 and an optional previous history value (the 
    825     first element of the output of this function). If no previous interface 
    826     identifier is provided, a random one is generated. The function returns 
    827     a tuple containing the randomized interface identifier and the history 
    828     value (for possible future use). Input and output values are provided in 
    829     a "printable" format as depicted below. 
    830      
    831     ex:  
    832  
    833     >>> in6_getRandomizedIfaceId('20b:93ff:feeb:2d3') 
    834     ('4c61:76ff:f46a:a5f3', 'd006:d540:db11:b092') 
    835  
    836     >>> in6_getRandomizedIfaceId('20b:93ff:feeb:2d3', 
    837                                  previous='d006:d540:db11:b092') 
    838     ('fe97:46fe:9871:bd38', 'eeed:d79c:2e3f:62e') 
    839     """ 
    840  
    841     s = "" 
    842     if previous is None: 
    843         d = "".join(map(chr, range(256))) 
    844         for i in range(8): 
    845             s += random.choice(d) 
    846         previous = s 
    847     s = inet_pton(socket.AF_INET6, "::"+ifaceid)[8:] + previous 
    848     import md5 
    849     s = md5.new(s).digest() 
    850     s1,s2 = s[:8],s[8:] 
    851     s1 = chr(ord(s1[0]) | 0x04) + s1[1:]   
    852     s1 = inet_ntop(socket.AF_INET6, "\xff"*8 + s1)[20:] 
    853     s2 = inet_ntop(socket.AF_INET6, "\xff"*8 + s2)[20:]     
    854     return (s1, s2) 
    855  
    856  
    857 _rfc1924map = [ '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E', 
    858                 'F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T', 
    859                 'U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i', 
    860                 'j','k','l','m','n','o','p','q','r','s','t','u','v','w','x', 
    861                 'y','z','!','#','$','%','&','(',')','*','+','-',';','<','=', 
    862                 '>','?','@','^','_','`','{','|','}','~' ] 
    863  
    864 def in6_ctop(addr): 
    865     """ 
    866     Convert an IPv6 address in Compact Representation Notation  
    867     (RFC 1924) to printable representation ;-) 
    868     Returns None on error. 
    869     """ 
    870     if len(addr) != 20 or not reduce(lambda x,y: x and y,  
    871                                      map(lambda x: x in _rfc1924map, addr)): 
    872         return None 
    873     i = 0 
    874     for c in addr: 
    875         j = _rfc1924map.index(c) 
    876         i = 85*i + j 
    877     res = [] 
    878     for j in range(4): 
    879         res.append(struct.pack("!I", i%2**32)) 
    880         i = i/(2**32) 
    881     res.reverse() 
    882     return inet_ntop(socket.AF_INET6, "".join(res)) 
    883  
    884 def in6_ptoc(addr): 
    885     """ 
    886     Converts an IPv6 address in printable representation to RFC  
    887     1924 Compact Representation ;-)  
    888     Returns None on error. 
    889     """     
    890     try: 
    891         d=struct.unpack("!IIII", inet_pton(socket.AF_INET6, addr)) 
    892     except: 
    893         return None 
    894     res = 0 
    895     m = [2**96, 2**64, 2**32, 1] 
    896     for i in range(4): 
    897         res += d[i]*m[i] 
    898     rem = res 
    899     res = [] 
    900     while rem: 
    901         res.append(_rfc1924map[rem%85]) 
    902         rem = rem/85 
    903     res.reverse() 
    904     return "".join(res) 
    905  
    906      
    907 def in6_isaddr6to4(x): 
    908     """ 
    909     Return True if provided address (in printable format) is a 6to4 
    910     address (being in 2002::/16). 
    911     """ 
    912     x = inet_pton(socket.AF_INET6, x) 
    913     return x[:2] == ' \x02' 
    914  
    915 conf.teredoPrefix = "2001::" # old one was 3ffe:831f (it is a /32) 
    916 conf.teredoServerPort = 3544 
    917  
    918 def in6_isaddrTeredo(x): 
    919     """ 
    920     Return True if provided address is a Teredo, meaning it is under  
    921     the /32 conf.teredoPrefix prefix value (by default, 2001::). 
    922     Otherwise, False is returned. Address must be passed in printable 
    923     format. 
    924     """ 
    925     our = inet_pton(socket.AF_INET6, x)[0:4] 
    926     teredoPrefix = inet_pton(socket.AF_INET6, conf.teredoPrefix)[0:4] 
    927     return teredoPrefix == our 
    928  
    929 def teredoAddrExtractInfo(x): 
    930     """ 
    931     Extract information from a Teredo address. Return value is  
    932     a 4-tuple made of IPv4 address of Teredo server, flag value (int), 
    933     mapped address (non obfuscated) and mapped port (non obfuscated). 
    934     No specific checks are performed on passed address. 
    935     """ 
    936     addr = inet_pton(socket.AF_INET6, x) 
    937     server = inet_ntop(socket.AF_INET, addr[4:8]) 
    938     flag = struct.unpack("!H",addr[8:10])[0] 
    939     mappedport = struct.unpack("!H",strxor(addr[10:12],'\xff'*2))[0]  
    940     mappedaddr = inet_ntop(socket.AF_INET, strxor(addr[12:16],'\xff'*4)) 
    941     return server, flag, mappedaddr, mappedport 
    942  
    943 def in6_iseui64(x): 
    944     """ 
    945     Return True if provided address has an interface identifier part 
    946     created in modified EUI-64 format (meaning it matches *::*:*ff:fe*:*).  
    947     Otherwise, False is returned. Address must be passed in printable 
    948     format. 
    949     """ 
    950     eui64 = inet_pton(socket.AF_INET6, '::ff:fe00:0') 
    951     x = in6_and(inet_pton(socket.AF_INET6, x), eui64) 
    952     return x == eui64 
    953  
    954 def in6_isanycast(x): # RFC 2526 
    955     if in6_iseui64(x): 
    956         s = '::fdff:ffff:ffff:ff80' 
    957         x = in6_and(x, inet_pton(socket.AF_INET6, '::ffff:ffff:ffff:ff80')) 
    958         x = in6_and(x, inet_pton(socket.AF_INET6, s))  
    959         return x == inet_pton(socket.AF_INET6, s) 
    960     else: 
    961         # not EUI-64  
    962         #|              n bits             |    121-n bits    |   7 bits   | 
    963         #+---------------------------------+------------------+------------+ 
    964         #|           subnet prefix         | 1111111...111111 | anycast ID | 
    965         #+---------------------------------+------------------+------------+ 
    966         #                                  |   interface identifier field  | 
    967         warning('in6_isanycast(): TODO not EUI-64') 
    968         return 0 
    969  
    970 def _in6_bitops(a1, a2, operator=0): 
    971     a1 = struct.unpack('4I', a1) 
    972     a2 = struct.unpack('4I', a2) 
    973     fop = [ lambda x,y: x | y, 
    974             lambda x,y: x & y, 
    975             lambda x,y: x ^ y 
    976           ]   
    977     ret = map(fop[operator%len(fop)], a1, a2) 
    978     t = ''.join(map(lambda x: struct.pack('I', x), ret)) 
    979     return t 
    980  
    981 def in6_or(a1, a2): 
    982     """ 
    983     Provides a bit to bit OR of provided addresses. They must be  
    984     passed in network format. Return value is also an IPv6 address 
    985     in network format. 
    986     """ 
    987     return _in6_bitops(a1, a2, 0) 
    988  
    989 def in6_and(a1, a2): 
    990     """ 
    991     Provides a bit to bit AND of provided addresses. They must be  
    992     passed in network format. Return value is also an IPv6 address 
    993     in network format. 
    994     """ 
    995     return _in6_bitops(a1, a2, 1) 
    996  
    997 def in6_xor(a1, a2): 
    998     """ 
    999     Provides a bit to bit XOR of provided addresses. They must be  
    1000     passed in network format. Return value is also an IPv6 address 
    1001     in network format. 
    1002     """ 
    1003     return _in6_bitops(a1, a2, 2) 
    1004  
    1005 def in6_cidr2mask(m): 
    1006     """ 
    1007     Return the mask (bitstring) associated with provided length  
    1008     value. For instance if function is called on 48, return value is 
    1009     '\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'. 
    1010      
    1011     """ 
    1012     if m > 128 or m < 0: 
    1013         raise Scapy_Exception("value provided to in6_cidr2mask outside [0, 128] domain (%d)" % m) 
    1014  
    1015     t = [] 
    1016     for i in xrange(0, 4): 
    1017         t.append(max(0, 2**32  - 2**(32-min(32, m)))) 
    1018         m -= 32 
    1019  
    1020     return ''.join(map(lambda x: struct.pack('!I', x), t)) 
    1021  
    1022 def in6_getnsma(a):  
    1023     """ 
    1024     Return link-local solicited-node multicast address for given 
    1025     address. Passed address must be provided in network format. 
    1026     Returned value is also in network format. 
    1027     """ 
    1028  
    1029     r = in6_and(a, inet_pton(socket.AF_INET6, '::ff:ffff')) 
    1030     r = in6_or(inet_pton(socket.AF_INET6, 'ff02::1:ff00:0'), r) 
    1031     return r 
    1032  
    1033 def in6_getnsmac(a): # return multicast Ethernet address associated with multicast v6 destination 
    1034     """ 
    1035     Return the multicast mac address associated with provided 
    1036     IPv6 address. Passed address must be in network format.  
    1037     """ 
    1038  
    1039     a = struct.unpack('16B', a)[-4:] 
    1040     mac = '33:33:' 
    1041     mac += ':'.join(map(lambda x: '%.2x' %x, a)) 
    1042     return mac 
    1043  
    1044 def in6_getha(prefix):  
    1045     """ 
    1046     Return the anycast address associated with all home agents on a given 
    1047     subnet. 
    1048     """ 
    1049     r = in6_and(inet_pton(socket.AF_INET6, prefix), in6_cidr2mask(64)) 
    1050     r = in6_or(r, inet_pton(socket.AF_INET6, '::fdff:ffff:ffff:fffe')) 
    1051     return inet_ntop(socket.AF_INET6, r) 
    1052  
    1053 def in6_ptop(str):  
    1054     """ 
    1055     Normalizes IPv6 addresses provided in printable format, returning the  
    1056     same address in printable format. (2001:0db8:0:0::1 -> 2001:db8::1) 
    1057     """ 
    1058     return inet_ntop(socket.AF_INET6, inet_pton(socket.AF_INET6, str)) 
    1059  
    1060 def in6_isincluded(addr, prefix, plen): 
    1061     """ 
    1062     Returns True when 'addr' belongs to prefix/plen. False otherwise. 
    1063     """ 
    1064     temp = inet_pton(socket.AF_INET6, addr) 
    1065     pref = in6_cidr2mask(plen) 
    1066     zero = inet_pton(socket.AF_INET6, prefix) 
    1067     return zero == in6_and(temp, pref) 
    1068  
    1069 def in6_isdocaddr(str): 
    1070     """ 
    1071     Returns True if provided address in printable format belongs to 
    1072     2001:db8::/32 address space reserved for documentation (as defined  
    1073     in RFC 3849). 
    1074     """ 
    1075     return in6_isincluded(str, '2001:db8::', 32) 
    1076  
    1077 def in6_islladdr(str): 
    1078     """ 
    1079     Returns True if provided address in printable format belongs to 
    1080     _allocated_ link-local unicast address space (fe80::/10) 
    1081     """ 
    1082     return in6_isincluded(str, 'fe80::', 10) 
    1083  
    1084 def in6_issladdr(str): 
    1085     """ 
    1086     Returns True if provided address in printable format belongs to 
    1087     _allocated_ site-local address space (fec0::/10). This prefix has  
    1088     been deprecated, address being now reserved by IANA. Function  
    1089     will remain for historic reasons. 
    1090     """ 
    1091     return in6_isincluded(str, 'fec0::', 10) 
    1092  
    1093 def in6_isuladdr(str): 
    1094     """ 
    1095     Returns True if provided address in printable format belongs to 
    1096     Unique local address space (fc00::/7). 
    1097     """ 
    1098     return in6_isincluded(str, 'fc::', 7) 
    1099  
    1100 # TODO : we should see the status of Unique Local addresses against 
    1101 #        global address space. 
    1102 #        Up-to-date information is available through RFC 3587.  
    1103 #        We should review function behavior based on its content. 
    1104 def in6_isgladdr(str): 
    1105     """ 
    1106     Returns True if provided address in printable format belongs to 
    1107     _allocated_ global address space (2000::/3). Please note that, 
    1108     Unique Local addresses (FC00::/7) are not part of global address 
    1109     space, and won't match. 
    1110     """ 
    1111     return in6_isincluded(str, '2000::', 3) 
    1112  
    1113 def in6_ismaddr(str): 
    1114     """ 
    1115     Returns True if provided address in printable format belongs to  
    1116     allocated Multicast address space (ff00::/8). 
    1117     """ 
    1118     return in6_isincluded(str, 'ff00::', 8) 
    1119  
    1120 def in6_ismnladdr(str): 
    1121     """ 
    1122     Returns True if address belongs to node-local multicast address 
    1123     space (ff01::/16) as defined in RFC  
    1124     """ 
    1125     return in6_isincluded(str, 'ff01::', 16) 
    1126  
    1127 def in6_ismgladdr(str): 
    1128     """ 
    1129     Returns True if address belongs to global multicast address 
    1130     space (ff0e::/16). 
    1131     """ 
    1132     return in6_isincluded(str, 'ff0e::', 16) 
    1133  
    1134 def in6_ismlladdr(str): 
    1135     """ 
    1136     Returns True if address balongs to link-local multicast address 
    1137     space (ff02::/16) 
    1138     """ 
    1139     return in6_isincluded(str, 'ff02::', 16) 
    1140  
    1141 def in6_ismsladdr(str): 
    1142     """ 
    1143     Returns True if address belongs to site-local multicast address 
    1144     space (ff05::/16). Site local address space has been deprecated. 
    1145     Function remains for historic reasons. 
    1146     """ 
    1147     return in6_isincluded(str, 'ff05::', 16) 
    1148  
    1149 def in6_isaddrllallnodes(str): 
    1150     """ 
    1151     Returns True if address is the link-local all-nodes multicast  
    1152     address (ff02::1).  
    1153     """ 
    1154     return (inet_pton(socket.AF_INET6, "ff02::1") == 
    1155             inet_pton(socket.AF_INET6, str)) 
    1156  
    1157 def in6_isaddrllallservers(str): 
    1158     """ 
    1159     Returns True if address is the link-local all-servers multicast  
    1160     address (ff02::2).  
    1161     """ 
    1162     return (inet_pton(socket.AF_INET6, "ff02::2") == 
    1163             inet_pton(socket.AF_INET6, str)) 
    1164  
    1165  
    1166 def in6_getscope(addr): 
    1167     """ 
    1168     Returns the scope of the address. 
    1169     """ 
    1170     if in6_isgladdr(addr): 
    1171         scope = IPV6_ADDR_GLOBAL 
    1172     elif in6_islladdr(addr): 
    1173         scope = IPV6_ADDR_LINKLOCAL 
    1174     elif in6_issladdr(addr): 
    1175         scope = IPV6_ADDR_SITELOCAL 
    1176     elif in6_ismaddr(addr): 
    1177         scope = IPV6_ADDR_MULTICAST 
    1178     elif addr == '::1': 
    1179         scope = IPV6_ADDR_LOOPBACK 
    1180     else: 
    1181         scope = -1 
    1182     return scope 
     568 
     569 
     570 
    1183571 
    1184572#############################################################################