On previous post I have written a sample code to validate ip address using the ipaddress module. The sample code is further extended to check for subnets.
Algorithm
1. Get user’s ip_address.
2. IF ip_address does not have ‘/’ or ip_address has ‘/32’ THEN
use ipaddress.ip_address()
ELSE use ipaddress.ip_network() THEN
tell user the ip address belongs to which subnet, and the subnet has how many
hosts and what is the local broadcast address.
ENDIF
ENDIF
3. Ask user if wants to enumerate subnet address
4. IF yes THEN
enumerate the address.
ENDIF
5. IF response is not ‘y’ or ‘n’ THEN
advise user that only ‘y’ or ‘n’ is accepted, keep asking if user wants to
enumerate address.
ELSE IF no THEN
quit to main menu
ENDIF
Here’s the code with some comments.
import ipaddress def response_processor(response,ip,count): network = ipaddress.ip_network(ip, False) if response.lower() == 'y': for host in network.hosts(): print(host) if count == 0: response = 'n' elif response.lower() == 'n': pass else: print("Please use y or n.") count += 1 # to keep track how many times user has been asked to enumerate address. return response.lower() def check_address(ip): if '/' in ip: count = 0 # to check how many times user has been asked to enumerate network. prefix = ip.split('/') if prefix[1] != '32': # skip subnet check if it is a host address i.e. /32 try: # ip is the original user's input. network has host bit reset by ipaddress.ip_network(ip,Strict=False) network = ipaddress.ip_network(ip,False) print("{} is part of {} and this subnet has {} host addresses, broadcast is {}\n".format(ip,network,network.num_addresses,network.broadcast_address)) response = input("Enumerate the address?(y or n):\n") response = response_processor(response,network,count) if response != 'n' or response != 'y': # if user enters an invalid option goes to a loop to keep asking user's choice. while response != 'n': response = input("Enumerate the address?(y or n):\n") response = response_processor(response,network,count) # note the response variable here has changed. except ValueError as errorCode: print(errorCode) else: try: ipaddress.ip_address(prefix[0]) print("{} is a valid host address.".format(ip)) except ValueError as errorCode: print(errorCode) else: try: ipaddress.ip_address(ip) print("{} is a valid ip address.".format(ip)) except ValueError as errorCode: print(errorCode) def main(): ip = input("Please enter an address:(q to quit)\n") while ip != 'q': check_address(ip) ip = input("Please enter an address:(q to quit)\n") if __name__ == '__main__': main()
Test cases
Test 1: ip address with prefix.
Please enter an address:(q to quit)
1.1.1.1
1.1.1.1 is a valid ip address.
Please enter an address:(q to quit)
Test 2: ip address with invalid prefix
Please enter an address:(q to quit)
1.1.1.1/33
'1.1.1.1/33' does not appear to be an IPv4 or IPv6 network
The ipaddress module treats /0 as valid prefix.. however this actually means matching all address with no mask bit set… in the code you can modify to treat /0 as invalid.
Test 3: invalid entry
Please enter an address:(q to quit)
object
'object' does not appear to be an IPv4 or IPv6 address
Please enter an address:(q to quit)
256.0.0.256
'256.0.0.256' does not appear to be an IPv4 or IPv6 address
Please enter an address:(q to quit)
Test 4: ip address with prefix
Please enter an address:(q to quit)
192.168.100.1/29
192.168.100.1/29 is part of 192.168.100.0/29 and this subnet has 8 host addresses, broadcast is 192.168.100.7
Enumerate the address?(y or n):
Test 4a: Enumerate address the first time.
Enumerate the address?(y or n):
y
192.168.100.1
192.168.100.2
192.168.100.3
192.168.100.4
192.168.100.5
192.168.100.6
Please enter an address:(q to quit)
Test 4b: Wrong entry to enumerate address.
Please enter an address:(q to quit)
1.1.1.1/30
1.1.1.1/30 is part of 1.1.1.0/30 and this subnet has 4 host addresses, broadcast is 1.1.1.3
Enumerate the address?(y or n):
Please use y or n.
Enumerate the address?(y or n):
t
Please use y or n.
Enumerate the address?(y or n):
y
1.1.1.1
1.1.1.2
Please enter an address:(q to quit)
first time i enter a whitespace, second time i put in a ‘t’, third time i put in correct response.