A story that was convenient when I tried using the python ip address module

NetOpsCoding Advent Calendar 2015 This is the article on the 21st day. I'm sorry I misunderstood the schedule ...

When a network engineer writes a script, I think that the IP address may be manipulated or calculated in the script. When calculating in the same way as a normal numerical value, the IP address of the character string type should be parsed and converted to an Int weighted for each digit, and so on. can not. In addition, ipv6 has a large number of digits, and in some cases it cannot be processed by simple parsing such as abbreviated notation, so it is a little troublesome to implement it by yourself.

This time, I will introduce the ipaddress module that makes it very easy to handle the troublesome IP address! Obviously for those who know, I didn't know this convenience until recently, so I'll share it for those who don't yet.

1. About the ipaddress module

The ipaddress module is a standard module officially implemented from python 3.3. (PEP3144) It is based on the ipaddr module developed by Google. Of course, you can use the ipaddr module in almost the same way, but this time, let's use the ip address that is installed as a standard module and does not require installation.

2. Environment

3. Functions in the ipaddress module

The ipaddress module has functions dedicated to v4 / v6 such as ʻIPv4Address () and ʻIPv6Address (), but functions such as ʻip_address ()` that include these are prepared and arguments. You can use it without worrying about whether it is v4 or v6. The ipaddress module uses the following three types of functions.

As the function name suggests, ip corresponds to ʻip_address (), network address corresponds to ʻip_network (), and Interface address corresponds to ʻip_interface ()`.

Use this function to create an ipv4 / v6 type object. Furthermore, various conversions and calculations can be performed by using optional functions. The functions that are convenient and often used personally are as follows.

function function
*.version Object is v4/v6 Determine which information you have. 4 for v4, 6 for v6
*.compressed v4 is equivalent,v6 returns a shorthand string
*.exploded v4 is equivalent,v6 returns a string with 0 not omitted
*.is_link_local True if it is a link-local reserved address in RFC3927
.with_with_prefixlen prefix Returns a long-format address as a string(10.10.10.1/24 mag)
.with_with_netmask Returns a network mask format address as a string type(10.10.10.1 255.255.255.0 mag)

You can also use various operators. When incrementing the IP address, simply add the +, - operators to the ip address module and describe the value, and the digit ups and downs will be handled arbitrarily.

The following is a sample execution example.

sample_ipaddress.py


#! /usr/bin/env python
# -*- coding: utf-8 -*-

import ipaddress

if __name__ == "__main__":

    ip = ipaddress.ip_address('10.2.3.4')
    nw = ipaddress.ip_network('10.0.0.0/8')

    if ip in nw: #It is possible to determine whether it is included in the network address with one line of ip in network
        print ("%s is included %s ."%(ip, nw))
    else :
        print ("%s isn't included %s ."%(ip, nw))

    print ("="*15)

    ip = ipaddress.ip_address('10.2.3.255')
    ipv6 = ipaddress.ip_address('fd00:260:301:104::104:1')
    ex_ipv6 = ipaddress.ip_address('fd00:0260:0301:0104:0000:0000:0104:1')
    
    #ipv4/v6 Check which address is stored
    print ("%s  is IPv%d"%(ip,ip.version))
    print ("%s  is IPv%d"%(ipv6,ipv6.version))
    print ("="*15)
    #Address increment
    ip = ip + 1
    ipv6 = ipv6 -2
    print ("increment ipv4 : %s"%ip)
    print ("decrement ipv6 : %s"%ipv6)
    print ("="*15)

    #Abbreviated and non-abbreviated conversion of ipv6
    print ("exploded ipv6 : %s"%ipv6.exploded)
    print ("compressed ipv6 : %s"%ex_ipv6.compressed)
    print ("="*15)

    #Determining if it is a link local address
    print ("%s is linklocal : %s"%(ipv6,ipv6.is_link_local))

    ipv6_ll = ipaddress.ip_address('fe80::104:1')
    print ("%s is linklocal : %s"%(ipv6_ll,ipv6_ll.is_link_local))
% python3 ipaddress_sample.py
10.2.3.4 is included 10.0.0.0/8 .
===============
10.2.3.255  is IPv4
fd00:260:301:104::104:1  is IPv6
===============
increment ipv4 : 10.2.4.0
decrement ipv6 : fd00:260:301:104::103:ffff
===============
exploded ipv6 : fd00:0260:0301:0104:0000:0000:0103:ffff
compressed ipv6 : fd00:260:301:104::104:1
===============
fd00:260:301:104::103:ffff is linklocal : False
fe80::104:1 is linklocal : True

As you can see from the above, the ip_address and ip_network functions determine the processing of ipv4 / v6. If you use this module, you can save a lot of time and effort to separate the processing cases between ipv4 and ipv6.

4. For example, you can use it at such times (in your case)

This module was very useful for me at such times

In such a case. The ipaddress module plays an active part in the interface and BGP mapping phase by parsing the config and extracting the information. Suppose you parse a config like the one below

ios-xr.conf



interface TenGigE0/0/0/0
 ipv4 address 10.10.10.10 255.255.255.0
 ipv6 nd suppress-ra
 ipv6 address fe80::222:1 link-local
 ipv6 address fd00:260:301:222::222:1/64
!

....Snip....

router bgp 64540
 neighbor 10.10.10.200
  remote-as 64601
  description "TEST-BGP-CONFIGURE"
  address-family ipv4 unicast
   route-policy as64601-sample in
   route-policy as64601-sample out
   next-hop-self
   soft-reconfiguration inbound always
  !
 !
 neighbor fd00:260:301:222::333:123
  remote-as 64601
  description "TEST-IPV6-BGP-CONFIGURE"
  address-family ipv6 unicast
   route-policy as64601-sample in
   route-policy as64601-sample out
   next-hop-self
   soft-reconfiguration inbound always
  !
 !

This time, I will omit the method of parsing this config well because it is not the main point. First, parse the Interface config and retain the Interface information. Next, the Neighbor information is extracted, and if the Neighbor address is included in the Interface information, it is associated with the Interface.

For the mapping part, the same code was presented as a sample in the above, but It is possible to distinguish with just this description. (Since the perspective part is omitted, the IP is directly hitting the same address as the config)

    neighbor = ipaddress.ip_address('fd00:260:301:222::333:123') #Neighbor IP
    interface = ipaddress.ip_interface('fd00:260:301:222::222:1/64') #Interface IP

    # interface.Compare after converting to network network address with network
    if neighbor in interface.network:
        print ("%s is included %s ."%(neighbor, interface))
    else :
        print ("%s isn't included %s ."%(neighbor, interface))

Execution result.log


fd00:260:301:222::333:123 is included fd00:260:301:222::222:1/64 .

5. Summary

When you look for these useful modules, they are often installed as standard or are made by third parties. It's okay to implement it with difficulty, but in fact it was possible to implement it immediately using more convenient functions. Often there is. It's not a bad thing to implement everything yourself, but if you find something convenient and suitable for your purpose, it's much faster to implement it. Don't be too enthusiastic about mounting, and make sure to "investigate".

It may be obvious, but I will write it here as a self-discipline (laugh)

Recommended Posts

A story that was convenient when I tried using the python ip address module
A story that didn't work when I tried to log in with the Python requests module
I tried using the Datetime module by Python
A story that I was addicted to when I made SFTP communication with python
Miscellaneous notes that I tried using python for the matter
I tried using the python module Kwant for quantum transport calculation
The story that a hash error came out when using Pipenv
The story of making a module that skips mail with python
When I tried to scrape using requests in python, I was addicted to SSLError, so a workaround memo
[Python] I tried to make a simple program that works on the command line using argparse.
When I tried to run Python, it was skipped to the Microsoft Store
A story I was addicted to when inserting from Python to a PostgreSQL table
vprof --I tried using the profiler for Python
I tried reading a CSV file using Python
I tried adding a Python3 module in C
A super introduction to Django by Python beginners! Part 2 I tried using the convenient functions of the template
The story of IPv6 address that I want to keep at a minimum
I tried using the Python library "pykakasi" that can convert kanji to romaji.
A story that Seaborn was easy, convenient and impressed
A story that I was addicted to at np.where
[Python] I tried running a local server using flask
A memo that I touched the Datastore with python
I tried drawing a pseudo fractal figure using Python
I tried using Python (3) instead of a scientific calculator
What I was addicted to when using Python tornado
A story that got stuck when trying to upgrade the Python version on GCE
I tried to score the syntax that was too humorous and humorous using the COTOHA API.
There is a pattern that the program did not stop when using Python threading
The story when I was using IntelliJ on Linux and could not input Japanese
A story that I was very convinced when I wrote the code for the Monty Hall problem and calculated the winning percentage
[Python] I tried using OpenPose
A story that stumbled when I made a chatbot with Transformer
I tried using the Python library from Ruby with PyCall
A story that stumbled when using pip in a proxy environment
I tried "a program that removes duplicate statements in Python"
Solve the Japanese problem when using the CSV module in Python.
[Python] I tried collecting data using the API of wikipedia
I tried to make a stopwatch using tkinter in python
I got "ModuleNotFoundError: No module named'azure'" when running a program using Azure SDK for Python
I wrote a Python script that exports all my posts using the Qiita API v2
A story that makes it easy to estimate the living area using Elasticsearch and Python
When I tried the AtCoder Beginner Contest, it was a terrible result, so I look back
A story that went missing when I specified a path starting with a tilde (~) in python open
The story I was addicted to when I specified nil as a function argument in Go
When writing to a csv file with python, a story that I made a mistake and did not meet the delivery date
A story that I was addicted to calling Lambda from AWS Lambda.
The story that the version of python 3.7.7 was not adapted to Heroku
I tried running the Python Package Repository (Warehouse) that supports PyPI
I made a Line-bot using Python!
Movement that changes direction in the coordinate system I tried Python 3
The story that the Homebrew environment was blown away when Anaconda was installed
When I tried to use pip with python, I was told that XML_SetHashSalt could not be found.
I tried to make a regular expression of "amount" using Python
A story that I fixed when I got Lambda logs from Cloudwatch Logs
A story that struggled to handle the Python package of PocketSphinx
I tried to make a regular expression of "time" using Python
[Python] A memo that I tried to get started with asyncio
Note that I was addicted to accessing the DB with Python's mysql.connector using a web application.
I tried to make a regular expression of "date" using Python
[Ev3dev] Create a program that captures the LCD (screen) using python
I tried using Thonny (Python / IDE)