Python: How to validate an IP Address with a CIDR notation (import socket)

Question:

I’ve got a script which is using argparse to pull flags from the command line and using socket to validate an IP Address. So far it works if I’m just using the standard IPv4 X.X.X.X format. What I want to do is validate an IP Address that includes a CIDR notation. How can I modify my bit of code to validate the 2-digit integer in the CIDR field (ie: 192.168.2.1/32)

import argparse
import socket

parser = argparse.ArgumentParser()
parser.add_argument("-i", "--ipaddr")
args = parser.parse_args()

# Validate IP Address Given in (-i) argparse
try:
        s = socket.inet_aton(args.ipaddr)
except socket.error:
        print ""
        print("Bad IP Address entered")
        print ""
        sys.exit()
Asked By: Alby

||

Answers:

Python 3

There is an ipaddress module that may do the job.

The constructor of the class Ip4Network handles both 255.255.255.255 and 255.255.255.255/32 (and also IPv6 format, with Ip6Network)

So you may add in your code

import ipaddress

and create an Ip4Network with the code:

try:
    ip_addr = ipaddress.ip_network(args.ipaddr)
except ValueError:
    # handle bad ip

Than, continue with your code on the socket:

socket.inet_aton(str(ip_addr))

you have only to convert it in a string.

Python 2.7

The ipaddress must be installed from the repository (py2-ipaddress) and has some issue between str and bytearray interpretation of string (refer here)

So it works in my experiments if you do:

ipaddress.ip_address(bytearray('192.168.1.1'))
ipaddress.ip_network(u'10.0.0.0/24')

Additional remarks

CIDR

To complete the aswer considering also the comment made by @Dave:

  • ipaddress.ip_network validates against ip address, not CIDR notation.

  • ipaddress.ip_network validates against networks, not CIDR notation.

  • To validate a CIDR notation with host bits set you must set the strict input parameter to False to avoid raise a ValueError('%s has host bits set' % self).

    ipaddress.ip_network('192.168.1.1/24', False)
    # IPv4Network('192.168.1.0/24')
    
Answered By: Matteo Ragni

Turn off strict mode and use ip_network

ipaddress.ip_network('192.168.1.10/24',False)
IPv4Network('192.168.1.10/24')
Answered By: Dave
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.