IPy-IPv 4とIPv 6アドレス処理モジュール学習ノート

99737 ワード

日常的なネットワーク計画では,IPアドレスの割当て計画に関する問題が多く,手動割当てであれば,量が多い場合,エラーが発生しやすい.IPyというpythonモジュールを利用することで、iPアドレスの割り当てなどの操作を容易に行うことができます.
以下はIPyモジュール学習の記録です.
IPyモジュールの概要
主な用途:
IPy-IPv 4およびIPv 6アドレスおよびネットワークを処理するクラスおよびツール.
IPy関連:
IPyソース:https://github.com/autocracy/python-ipy/
IPyクラスとメソッド
IPyには主に以下の種類と方法があります.
dir(IPy)
Out[8]: 
['INT_TYPES',  
 'IP',
 'IPSet',
 'IPV6_MAP_MASK',
 'IPV6_TEST_MAP',
 'IPint',
 'IPv4ranges',
 'IPv6ranges',
 'MAX_IPV4_ADDRESS',
 'MAX_IPV6_ADDRESS',
 'STR_TYPES',
 '_BitTable',
 '__builtins__',
 '__cached__',
 '__doc__',
 '__file__',
 '__loader__',
 '__name__',
 '__package__',
 '__spec__',
 '__version__',
 '_checkNetaddrWorksWithPrefixlen',
 '_checkNetmask',
 '_checkPrefix',
 '_count0Bits',
 '_count1Bits',
 '_countFollowingZeros',
 '_intToBin',
 '_ipVersionToLen',
 '_netmaskToPrefixlen',
 '_parseAddressIPv6',
 '_prefixlenToNetmask',
 '_remove_subprefix',
 'bisect',
 'collections',
 'intToIp',
 'parseAddress',
 'sys',
 'types',
 'xrange']

中にはIPint,IP,IPSetの3種類がある.
一般的にIPクラスが使用され、IPクラスはIPintの代わりに、IPクラスはIPintクラスを継承します.
INT_TYPES,IPV6_MAP_MASK,IPV6_TEST_MAP,IPv4ranges, IPv6ranges,MAX_IPV4_ADDRESS,MAX_IPV6_ADDRESS,STR_TYPESこれはすべて定義された定数です.
IPintクラスclass IPint(object):
返される整数のIPアドレスを処理します.
IPクラスはIPintから継承されるため,IPintクラスにおけるメソッドはIPクラスにおいても同様に適用される.
次に、一般的な方法を記録します.
__init__(self, data, ipversion=0, make_net=0)
  • dataは、一般的なIPv 4およびIPv 6アドレスの様々な表現形態であってもよい.接頭辞表示、IPセグメント表示、小数点マスク表示、単一IPなどをサポートします.10進数の進数、2進数のアドレスなどを入力することもできます.
  • ipversionはアドレスのバージョンを作成することができます.バージョンは4または6で、他のエラーを入力します.
  • mask_NetがTureであれば,マスクを指定することでIPアドレスを割り当てることができる.

  • テストは次のとおりです.
    >>> print(IP('127.0.0.0/8'))
    127.0.0.0/8
    >>> print(IP('127.0.0.0/255.0.0.0'))
    127.0.0.0/8
    >>> print(IP('127.0.0.0-127.255.255.255'))
    127.0.0.0/8
    >>> print(IP('127.0.0.1/255.0.0.0', make_net=True))
    127.0.0.0/8
    [39]: from IPy import IPint
    ip = IPint('192.168.1.0/24',make_net=True)
    ip
    Out[41]: IPint('192.168.1.0/24')
    for x in ip:
        print(x)
        
    3232235776
    3232235777  #         IP  。
    3232235778
    3232235779
    3232235780
    ...
    

    一般的な方法:
    #     IP  
    ip = IPint('192.168.1.0/24')
    ip.int() #         IP  
    Out[52]: 3232235776
    ip.version() #  ip    
    Out[53]: 4
    ip.prefixlen() #      
    Out[54]: 24
    ip.net()  #         IP  
    Out[55]: 3232235776
    ip.broadcast() #          
    Out[56]: 3232236031
    -----------------------------------------
    
    _printPrefix(self, want): #    want    
    ip._printPrefix(0) #want == 0,None,      
    Out[58]: ''
    ip._printPrefix(1) #want == 1,          
    Out[59]: '/24'
    ip._printPrefix(2) #want == 2,        
    Out[60]: '/255.255.255.0'
    ip._printPrefix(3) #want == 3,            
    Out[61]: '-192.168.1.255'
        
    ipv6 = IPint('2003::/64')
    
    ipv6._printPrefix
    Out[70]: <bound method IPint._printPrefix of IPint('2003::/64')>
    ipv6._printPrefix(0)
    Out[71]: ''
    ipv6._printPrefix(1)
    Out[72]: '/64'
    ipv6._printPrefix(2)
    Out[73]: '/ffff:ffff:ffff:ffff:0000:0000:0000:0000'
    ipv6._printPrefix(3)
    Out[74]: '-2003:0000:0000:0000:ffff:ffff:ffff:ffff'
    
    --------------------------------------
    #   IP             。
    ipv6.strBin() #  IPv4  IPv6 2       
    Out[79]: '00100000000000110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
    ipv6.strCompressed() #          ,    IPv6   
    Out[80]: '2003::/64'
    ipv6.strDec() #  10       
    Out[81]: '42550872755692912415807417417958686720'
    ipv6.strFullsize() #           。
    Out[82]: '2003:0000:0000:0000:0000:0000:0000:0000/64'
    ipv6.strHex() #  16       
    Out[83]: '0x20030000000000000000000000000000'
    ipv6.strNetmask() #      
    Out[84]: '/64'
    ipv6.strNormal(wantprefixlen = None) #      wantprefixlen       
    ipv6.strNormal(wantprefixlen = 0) #     
    Out[92]: '2003:0:0:0:0:0:0:0'
    ipv6.strNormal((wantprefixlen = 1) #      
    Out[93]: '2003:0:0:0:0:0:0:0/64'
    ipv6.strNormal((wantprefixlen = 2) #      
    Out[94]: '2003:0:0:0:0:0:0:0/ffff:ffff:ffff:ffff:0000:0000:0000:0000'
    ipv6.strNormal(3) #     
    Out[95]: '2003:0:0:0:0:0:0:0-2003:0000:0000:0000:ffff:ffff:ffff:ff
     ---------------------------------------
                   
    ip.iptype() #  IP     
    Out[98]: 'PRIVATE'
    ip2 = IPint('1.1.1.1')
    ip2.iptype()
    Out[100]: 'PUBLIC'
    print(IP('127.0.0.1').iptype())
    Out[101]: LOOPBACK
    print(IP('::1').iptype())
    Out[102]: LOOPBACK
    print(IP('2001:0658:022a:cafe:0200::1').iptype())
    Out[103]: ALLOCATED RIPE NCC
    -----------------------------------------
                   
    ip.netmask() #         
    Out[104]: 4294967040
    ip.strNetmask() #          
    Out[105]: '255.255.255.0'
    ip.len()  #       
    Out[106]: 256
    IP('10.1.1.0/28').len()
    Out[108]: 16
                  
    ----------------------------------------
    ip.__getitem__(1) #       i   。
    Out[120]: 3232235777
    ip.__getitem__(2)
    Out[121]: 3232235778
    ip.__getitem__(3)
    Out[122]: 3232235779
                  
    ip
    Out[124]: IPint('192.168.1.0/24')
    ip.__contains__('192.168.1.1') #              
    Out[125]: True
    ip.__contains__('192.168.2.1')
    Out[126]: False   
    '192.168.1.1' in ip
    Out[127]: True
    '192.168.3.1' in ip
    Out[128]: False
    
    ------------------------------------------
    #    IP           IP                    
    def overlaps(self, item):
    #     ,  0;
    #             IP       1.
    #              IP       -1.                    
    IP('192.168.1.0/24').overlaps('192.168.1.254')
    Out[131]: 1
    IP('192.168.1.0/24').overlaps('192.168.2.254')
    Out[132]: 0
    IP('192.168.1.0/24').overlaps('192.168.0.0/16')
    Out[134]: -1
                 
    ----------------------------------------
    #       IP        ,IPv4    IPv6  ,         。           
    #  self < other,  -1,   self == other,  0,  self > other,  1.
    
    ip
    Out[158]: IPint('192.168.1.0/24')
    ip2
    Out[159]: IPint('1.1.1.1')
    ip3
    Out[160]: IP('192.0.0.0/8')
    ipv6
    Out[161]: IPint('2003::/64')
    ip4 = IP('192.168.1.0/24')
    ip.__cmp__(ip4)
    Out[163]: 0
    ip.__cmp__(ip3)
    Out[166]: 1
    ip.__cmp__(ipv6)
    Out[168]: -1
    ip > ip2
    Out[177]: True
    ip < ip2
    Out[178]: False
    ip == i
                  
    

    IPクラス、class IP(IPint):
    IPクラスはIPintから継承されるので、IPクラスはIPintのすべての方法を有する.
    IPクラスは主にIPアドレスとネットワークを処理する.IPクラスは,IPintと比較して整数型の値ではなく,ネットワーク形式の文字列を返す.
    ipint = IPint('192.168.1.0/24')
    ip = IP('192.168.1.0/24')
    ipint.net() 
    Out[197]: 3232235776
    ip.net()   #      
    Out[198]: IP('192.168.1.0')
    ip.broadcast() #      
    Out[199]: IP('192.168.1.255')
    ipint.broadcast()
    Out[200]: 3232236031
    ip.netmask()  #      
    Out[201]: IP('255.255.255.0')
    ip.reverseName()
    Out[207]: '1.168.192.in-addr.arpa.'
    ip.reverseNames()  #            。
    Out[208]: ['1.168.192.in-addr.arpa.']
    IP('213.221.112.224/30').reverseNames()
    
    Out[209]: 
    ['224.112.221.213.in-addr.arpa.',
     '225.112.221.213.in-addr.arpa.',
     '226.112.221.213.in-addr.arpa.',
     '227.112.221.213.in-addr.arpa.']
    IP('::1:2').reverseNames()
    Out[211]: ['2.0.0.0.1.ip6.arpa.']
    IP('213.221.112.224/30').reverseName() #              ,     。
    Out[217]: '224-227.112.221.213.in-addr.arpa.'
    
    IP('10.1.1.1').make_net(24) #    IP  ,      ,    IP    
    Out[231]: IP('10.1.1.0/24')
    ip
    Out[235]: IP('192.168.1.0/24')
    ip.__getitem__(1) #        i   
    Out[236]: IP('192.168.1.1')
    
    

    IPSetクラス、IPSet(collections.MutableSet):
    ネットワークセグメントの要約に使用できます.
    IPSetは、IPインスタンスのオブジェクトのみを受信する.
    IPSetの値はリストに存在します.
    from IPy import IPSet
    from IPy import IP
    ipset = IPSet() #     IPSet  
    ipset.add(IP('192.168.1.0/24')) # IPSet         
    ipset
    Out[301]: IPSet([IP('192.168.1.0/24')])
    ipset.add([IP('192.168.2.0/24'),IP('192.168.3.0/24')])
    ipset  #           
    Out[303]: IPSet([IP('192.168.1.0/24'), IP('192.168.2.0/23')])
    ipset.add(IP('192.168.0.0/16'))
    ipset#             
    Out[308]: IPSet([IP('192.168.0.0/16')])  
    ipset.discard(IP('192.168.1.0/24')) #           
    ipset
    Out[310]: IPSet([IP('192.168.0.0/24'), IP('192.168.2.0/23'), IP('192.168.4.0/22'), IP('192.168.8.0/21'), IP('192.168.16.0/20'), IP('192.168.32.0/19'), IP('192.168.64.0/18'), IP('192.168.128.0/17')])
    n [317]: ipset2 = IPSet()
    
    ipset2.add(IP('192.168.1.0/24'))
    ipset2
    Out[319]: IPSet([IP('192.168.1.0/24')])
    ipset.isdisjoint(ipset2) #                    
    Out[320]: True
    ipset3 = IPSet()
    ipset3.add(IP('192.168.2.0/24'))
    ipset.isdisjoint(ipset3)
    Out[323]: False
    ipset.__contains__(IP('192.168.2.0/24')) #                
    Out[335]: True
    

    IPyの他の一般的な方法:
    def _parseAddressIPv6(ipstr): # IPv6              
    ipv6 = IPy._parseAddressIPv6('1080:200C::1')
    ipv6
    Out[345]: 21932911918296378927538433929194242049
    IP(ipv6) 
    Out[346]: IP('1080:200c::1')
        
    def parseAddress(ipstr, ipversion=0):#  IP  
    IPy.parseAddress('192.168.1.1')
    Out[348]: (3232235777, 4)
    IPy.parseAddress('123.132')#      0  
    Out[349]: (2072248320, 4)
    
    IPy.intToIp(3232235777, version=4)
    Out[351]: '192.168.1.1'
    
    def intToIp(ip, version): #    IP        IP  
    IPy.intToIp(3232235777, version=6)
    Out[352]: '0000:0000:0000:0000:0000:0000:c0a8:0101'
        
    def _intToBin(val): # int          
    IPy._intToBin(13241)
    Out[360]: '11001110111001'
    

    IPyで書かれたウィジェット:
    指定されたマスクと割り当てられた個数のIPv 4またはIPv 6アドレスを一括して割り当てます.
    次のプログラムでは、最初のIPv 4またはIPv 6アドレスを指定し、マスクを指定し、生成するセグメントの数を指定することで、プログラムによってアドレスを一括して割り当てることができます.
    アドレス出力フォーマットは、必要に応じて柔軟に定義できます.
    # -*- coding: utf-8 -*-
    """
    Created on Sun Dec  1 21:51:11 2019
    
    @author: cao
    """
    
    import IPy
    
    def get_ip_list(begin_ip, count, netmask):
        ip_list = '' #       IP  
        begin_ip = IPy.IP(begin_ip)
        ip_list += str(begin_ip) + '
    '
    # ip_ if begin_ip.version() == 4: for i in range(count): ip = IPy.IP(begin_ip) new_ip = IPy.IP(ip.ip + 2 ** (32 - netmask)) begin_ip = str(new_ip) ip_list += begin_ip + '
    '
    else: for i in range(count): ipv6 = IPy.IP(begin_ip) new_ipv6 = IPy.IP(ipv6.ip + 2 ** (128 - netmask)) begin_ip = str(new_ipv6) ip_list += begin_ip + '
    '
    return ip_list if __name__ == "__main__": ipv6_list = get_ip_list(begin_ip = '2002::', count=10, netmask=64) print(' IPv6 :') print('============================') print(ipv6_list) ipv6_list2 = get_ip_list(begin_ip = 'FD00:0:2e3f::', count=10, netmask=127) print(' IPv6 :') print('============================') print(ipv6_list2) ip_list = get_ip_list(begin_ip='192.168.1.0', count=10,netmask=24) print(' IPv4 :') print('============================') print(ip_list) ip_list2 = get_ip_list(begin_ip='192.168.2.0', count = 10, netmask=30) print(' IPv4 :') print('============================') print(ip_list2)

    プログラムの実行結果:
          IPv6  :
    ============================
    2002::
    2002:0:0:1::
    2002:0:0:2::
    2002:0:0:3::
    2002:0:0:4::
    2002:0:0:5::
    2002:0:0:6::
    2002:0:0:7::
    2002:0:0:8::
    2002:0:0:9::
    2002:0:0:a::
    
          IPv6  :
    ============================
    fd00:0:2e3f::
    fd00:0:2e3f::2
    fd00:0:2e3f::4
    fd00:0:2e3f::6
    fd00:0:2e3f::8
    fd00:0:2e3f::a
    fd00:0:2e3f::c
    fd00:0:2e3f::e
    fd00:0:2e3f::10
    fd00:0:2e3f::12
    fd00:0:2e3f::14
    
          IPv4  :
    ============================
    192.168.1.0
    192.168.2.0
    192.168.3.0
    192.168.4.0
    192.168.5.0
    192.168.6.0
    192.168.7.0
    192.168.8.0
    192.168.9.0
    192.168.10.0
    192.168.11.0
    
          IPv4 :
    ============================
    192.168.2.0
    192.168.2.4
    192.168.2.8
    192.168.2.12
    192.168.2.16
    192.168.2.20
    192.168.2.24
    192.168.2.28
    192.168.2.32
    192.168.2.36
    192.168.2.40
    

    一括生成されたIPアドレスを直接Excelテーブルにコピーしたり、ファイルにコピーしたりして、後続の一括生成ネットワークデバイス構成などとして使用することができます.
    マスクが64ビットのIPv 6アドレスを固定形式で一括して割り当てます.
    ネットワーク計画において、IPv 6アドレスをトラフィックに割り当てる必要がある場合、マスクはすべて64であると仮定する.IPv 6に対応するゲートウェイアドレスも指定する必要があります.
    次のプログラムでは、最初のIPv 6アドレスを指定し、countがどのくらいのアドレスを割り当てる必要があるかを指定します.指定された数のIPv 6アドレスが印刷され、各アドレスに対応する指定されたゲートウェイアドレスが間違っています.
    # -*- coding: utf-8 -*-
    """
    Created on Tue Nov 26 16:04:36 2019
    
    @author: cao
    """
    
    #        ,     64   
    
    import IPy
    
    
    #      ,       4 ,      
    #                。     。
    def add_0(tmp):
        if len(tmp) == 3:
            tmp = '0' + tmp
        elif len(tmp) == 2:
            tmp = '00' + tmp
        elif len(tmp) == 1:
            tmp = '000' + tmp
        else:
            pass
        return tmp
    
    #    IPv6  ,    0   
    def ipv6_format(ipv6):
        tmp_ip = ''
        for i in ipv6.split(':'):
            if(len(i) == 0):
                continue
            if(i == '0'): 
                tmp_ip += '0:'
                continue
            tmp_ip += add_0(i) + ':'
        return tmp_ip + ':'
    
    #      IPv6       
    def ipv6_GW(ipv6_list):
        ip_list_gw = ''
        for ip_net in ipv6_list.split('
    '
    ): if(len(ip_net) == 0): break ip_list_gw += ip_net + 'FFFF
    '
    return ip_list_gw if __name__ == "__main__": begin_ip = 'FD00:0:0004:009B::' ipv6_count = 10 ipv6_list = begin_ip + '
    '
    # ipv6_gw = '' # for i in range(ipv6_count): ipv6 = IPy.IP(begin_ip) new_ipv6 = str.upper(str(IPy.IP(ipv6.ip + 2**64))) begin_ip = ipv6_format(new_ipv6) ipv6_list += begin_ip + '
    '
    print(ipv6_list) ipv6_gw = ipv6_GW(ipv6_list) print(ipv6_gw)

    プログラムの実行結果:
    FD00:0:0004:009B::
    FD00:0:0004:009C::
    FD00:0:0004:009D::
    FD00:0:0004:009E::
    FD00:0:0004:009F::
    FD00:0:0004:00A0::
    FD00:0:0004:00A1::
    FD00:0:0004:00A2::
    FD00:0:0004:00A3::
    FD00:0:0004:00A4::
    FD00:0:0004:00A5::
    
    FD00:0:0004:009B::FFFF
    FD00:0:0004:009C::FFFF
    FD00:0:0004:009D::FFFF
    FD00:0:0004:009E::FFFF
    FD00:0:0004:009F::FFFF
    FD00:0:0004:00A0::FFFF
    FD00:0:0004:00A1::FFFF
    FD00:0:0004:00A2::FFFF
    FD00:0:0004:00A3::FFFF
    FD00:0:0004:00A4::FFFF
    FD00:0:0004:00A5::FFFF
    

    希望の住所を入手したら、直接Excelテーブルにコピーしたり、直接ファイルに書き込んだりすることができます.後続のバッチ生成構成に使用します.
    出力されるIPv 6アドレスフォーマット、またはIPv 4アドレスフォーマットについては、必要に応じて柔軟に制御できます.
    参考資料:
    https://pypi.org/project/IPy/
    IPyソース:https://github.com/autocracy/python-ipy/
    https://zhuanlan.zhihu.com/p/64791275