Source code for ipaddresstools.ipaddresstools

#!/usr/bin/env python3
"""
 Script Name: ipaddresstools.py
 Script Type: Python
 Updated By: Benjamin P. Trachtenberg
 Date Written 1/11/2015

 Description:
 Collection of tools for IP Address's

"""
import logging
import re as __re
import ipaddress as __ipaddress
import random as __random

LOGGER = logging.getLogger(__name__)


__mask_conversion = {
    0: {"OCT1": 0, "OCT2": 0, "OCT3": 0, "OCT4": 0, "MASK": "0.0.0.0", "INVMASK": "255.255.255.255",
        "CIDR": "0"},
    1: {"OCT1": 128, "OCT2": 0, "OCT3": 0, "OCT4": 0, "MASK": "128.0.0.0", "INVMASK": "127.255.255.255",
        "CIDR": "1"},
    2: {"OCT1": 192, "OCT2": 0, "OCT3": 0, "OCT4": 0, "MASK": "192.0.0.0", "INVMASK": "63.255.255.255",
        "CIDR": "2"},
    3: {"OCT1": 224, "OCT2": 0, "OCT3": 0, "OCT4": 0, "MASK": "224.0.0.0", "INVMASK": "31.255.255.255",
        "CIDR": "3"},
    4: {"OCT1": 240, "OCT2": 0, "OCT3": 0, "OCT4": 0, "MASK": "240.0.0.0", "INVMASK": "15.255.255.255",
        "CIDR": "4"},
    5: {"OCT1": 248, "OCT2": 0, "OCT3": 0, "OCT4": 0, "MASK": "248.0.0.0", "INVMASK": "7.255.255.255",
        "CIDR": "5"},
    6: {"OCT1": 252, "OCT2": 0, "OCT3": 0, "OCT4": 0, "MASK": "252.0.0.0", "INVMASK": "3.255.255.255",
        "CIDR": "6"},
    7: {"OCT1": 254, "OCT2": 0, "OCT3": 0, "OCT4": 0, "MASK": "254.0.0.0", "INVMASK": "1.255.255.255",
        "CIDR": "7"},
    8: {"OCT1": 255, "OCT2": 0, "OCT3": 0, "OCT4": 0, "MASK": "255.0.0.0", "INVMASK": "0.255.255.255",
        "CIDR": "8"},
    9: {"OCT1": 255, "OCT2": 128, "OCT3": 0, "OCT4": 0, "MASK": "255.128.0.0", "INVMASK": "0.127.255.255",
        "CIDR": "9"},
    10: {"OCT1": 255, "OCT2": 192, "OCT3": 0, "OCT4": 0, "MASK": "255.192.0.0", "INVMASK": "0.63.255.255",
         "CIDR": "10"},
    11: {"OCT1": 255, "OCT2": 224, "OCT3": 0, "OCT4": 0, "MASK": "255.224.0.0", "INVMASK": "0.31.255.255",
         "CIDR": "11"},
    12: {"OCT1": 255, "OCT2": 240, "OCT3": 0, "OCT4": 0, "MASK": "255.240.0.0", "INVMASK": "0.15.255.255",
         "CIDR": "12"},
    13: {"OCT1": 255, "OCT2": 248, "OCT3": 0, "OCT4": 0, "MASK": "255.248.0.0", "INVMASK": "0.7.255.255",
         "CIDR": "13"},
    14: {"OCT1": 255, "OCT2": 252, "OCT3": 0, "OCT4": 0, "MASK": "255.252.0.0", "INVMASK": "0.3.255.255",
         "CIDR": "14"},
    15: {"OCT1": 255, "OCT2": 254, "OCT3": 0, "OCT4": 0, "MASK": "255.254.0.0", "INVMASK": "0.1.255.255",
         "CIDR": "15"},
    16: {"OCT1": 255, "OCT2": 255, "OCT3": 0, "OCT4": 0, "MASK": "255.255.0.0", "INVMASK": "0.0.255.255",
         "CIDR": "16"},
    17: {"OCT1": 255, "OCT2": 255, "OCT3": 128, "OCT4": 0, "MASK": "255.255.128.0", "INVMASK": "0.0.127.255",
         "CIDR": "17"},
    18: {"OCT1": 255, "OCT2": 255, "OCT3": 192, "OCT4": 0, "MASK": "255.255.192.0", "INVMASK": "0.0.63.255",
         "CIDR": "18"},
    19: {"OCT1": 255, "OCT2": 255, "OCT3": 224, "OCT4": 0, "MASK": "255.255.224.0", "INVMASK": "0.0.31.255",
         "CIDR": "19"},
    20: {"OCT1": 255, "OCT2": 255, "OCT3": 240, "OCT4": 0, "MASK": "255.255.240.0", "INVMASK": "0.0.15.255",
         "CIDR": "20"},
    21: {"OCT1": 255, "OCT2": 255, "OCT3": 248, "OCT4": 0, "MASK": "255.255.248.0", "INVMASK": "0.0.7.255",
         "CIDR": "21"},
    22: {"OCT1": 255, "OCT2": 255, "OCT3": 252, "OCT4": 0, "MASK": "255.255.252.0", "INVMASK": "0.0.3.255",
         "CIDR": "22"},
    23: {"OCT1": 255, "OCT2": 255, "OCT3": 254, "OCT4": 0., "MASK": "255.255.254.0", "INVMASK": "0.0.1.255",
         "CIDR": "23"},
    24: {"OCT1": 255, "OCT2": 255, "OCT3": 255, "OCT4": 0, "MASK": "255.255.255.0", "INVMASK": "0.0.0.255",
         "CIDR": "24"},
    25: {"OCT1": 255, "OCT2": 255, "OCT3": 255, "OCT4": 128, "MASK": "255.255.255.128", "INVMASK": "0.0.0.127",
         "CIDR": "25"},
    26: {"OCT1": 255, "OCT2": 255, "OCT3": 255, "OCT4": 192, "MASK": "255.255.255.192", "INVMASK": "0.0.0.63",
         "CIDR": "26"},
    27: {"OCT1": 255, "OCT2": 255, "OCT3": 255, "OCT4": 224, "MASK": "255.255.255.224", "INVMASK": "0.0.0.31",
         "CIDR": "27"},
    28: {"OCT1": 255, "OCT2": 255, "OCT3": 255, "OCT4": 240, "MASK": "255.255.255.240", "INVMASK": "0.0.0.15",
         "CIDR": "28"},
    29: {"OCT1": 255, "OCT2": 255, "OCT3": 255, "OCT4": 248, "MASK": "255.255.255.248", "INVMASK": "0.0.0.7",
         "CIDR": "29"},
    30: {"OCT1": 255, "OCT2": 255, "OCT3": 255, "OCT4": 252, "MASK": "255.255.255.252", "INVMASK": "0.0.0.3",
         "CIDR": "30"},
    31: {"OCT1": 255, "OCT2": 255, "OCT3": 255, "OCT4": 254, "MASK": "255.255.255.254", "INVMASK": "0.0.0.1",
         "CIDR": "31"},
    32: {"OCT1": 255, "OCT2": 255, "OCT3": 255, "OCT4": 255, "MASK": "255.255.255.255", "INVMASK": "0.0.0.0",
         "CIDR": "32"}}

mask_conversion = __mask_conversion


[docs]def ucast_ip_mask(ip_addr_and_mask, return_tuple=True): """ Function to check if a address is unicast and that the CIDR mask is good :type ip_addr_and_mask: String :param ip_addr_and_mask: String format 192.168.1.1/24 :type return_tuple: Boolean :param return_tuple: True or False :rtype: Tuple, or Boolean :returns: Tuple, or Boolean """ regex_ucast_ip_and_mask = __re.compile(r'^((22[0-3])|(2[0-1][0-9])|(1[0-9][0-9])|([1-9]?[0-9]))\.((25[0-5])|' r'(2[0-4][0-9])|(1[0-9][0-9])|([1-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|' r'(1[0-9][0-9])|([1-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|' r'([1-9]?[0-9]))/((3[0-2])|([1-2]?[0-9]))$') if return_tuple: # pragma: no cover while not regex_ucast_ip_and_mask.match(ip_addr_and_mask): print("Not a good unicast IP and CIDR mask combo.") print("Please try again.") ip_addr_and_mask = input("Please enter a unicast IP address and mask in the follwing format x.x.x.x/x: ") ip_cidr_split = ip_addr_and_mask.split("/") ip_addr = ip_cidr_split[0] cidr = ip_cidr_split[1] return ip_addr, cidr elif not return_tuple: if not regex_ucast_ip_and_mask.match(ip_addr_and_mask): return False else: return True
[docs]def ucast_ip(ip_addr, return_tuple=True): """ Function to check if a address is unicast :type ip_addr: String :param ip_addr: String format 192.168.1.1 :type return_tuple: Boolean :param return_tuple: True or False :rtype: Tuple, or Boolean :returns: Tuple, or Boolean """ regex_ucast_ip = __re.compile(r'^((22[0-3])|(2[0-1][0-9])|(1[0-9][0-9])|([1-9]?[0-9]))\.((25[0-5])|' r'(2[0-4][0-9])|(1[0-9][0-9])|([1-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|' r'(1[0-9][0-9])|([1-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|' r'([1-9]?[0-9]))$') if return_tuple: # pragma: no cover while not regex_ucast_ip.match(ip_addr): print("Not a good unicast IP.") print("Please try again.") ip_addr = input("Please enter a unicast IP address in the following format x.x.x.x: ") return ip_addr elif not return_tuple: if not regex_ucast_ip.match(ip_addr): return False else: return True
[docs]def mcast_ip_mask(ip_addr_and_mask, return_tuple=True): """ Function to check if a address is multicast and that the CIDR mask is good :type ip_addr_and_mask: String :param ip_addr_and_mask: String format 239.0.0.0/24 :type return_tuple: Boolean :param return_tuple: True or False :rtype: Tuple, or Boolean :returns: Tuple, or Boolean """ regex_mcast_ip_and_mask = __re.compile(r'^(((2[2-3][4-9])|(23[0-3]))\.((25[0-5])|(2[0-4][0-9])|' r'(1[0-9][0-9])|([1-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|' r'([1-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|' r'([1-9]?[0-9]))/((3[0-2])|([1-2][0-9])|[3-9]))$') if return_tuple: # pragma: no cover while not regex_mcast_ip_and_mask.match(ip_addr_and_mask): print("Not a good multicast IP and CIDR mask combo.") print("Please try again.") ip_addr_and_mask = input("Please enter a multicast IP address and mask in the follwing format x.x.x.x/x: ") ip_cidr_split = ip_addr_and_mask.split("/") ip_addr = ip_cidr_split[0] cidr = ip_cidr_split[1] return ip_addr, cidr elif not return_tuple: if not regex_mcast_ip_and_mask.match(ip_addr_and_mask): return False else: return True
[docs]def mcast_ip(ip_addr, return_tuple=True): """ Function to check if a address is multicast :type ip_addr: String :param ip_addr: String format 239.1.1.1 :type return_tuple: Boolean :param return_tuple: True or False :rtype: Tuple, or Boolean :returns: Tuple, or Boolean """ regex_mcast_ip = __re.compile(r'^(((2[2-3][4-9])|(23[0-3]))\.((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|([1-9]?[0-9]' r'))\.((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|([1-9]?[0-9]))\.((25[0-5])|(2[0-4]' r'[0-9])|(1[0-9][0-9])|([1-9]?[0-9])))$') if return_tuple: # pragma: no cover while not regex_mcast_ip.match(ip_addr): print("Not a good multicast IP.") print("Please try again.") ip_addr = input("Please enter a multicast IP address in the following format x.x.x.x: ") return ip_addr elif not return_tuple: if not regex_mcast_ip.match(ip_addr): return False else: return True
[docs]def ip_mask(ip_addr_and_mask, return_tuple=True): """ Function to check if a address and CIDR mask is good :type ip_addr_and_mask: String :param ip_addr_and_mask: String format 192.168.1.1/24 :type return_tuple: Boolean :param return_tuple: True or False :rtype: Tuple, or Boolean :returns: Tuple, or Boolean """ regex_ip_and_mask = __re.compile(r'^((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|([1-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])' r'|(1[0-9][0-9])|([1-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|([1-9]?' r'[0-9]))\.((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|([1-9]?[0-9]))/((3[0-2])|' r'([1-2]?[0-9]))$') if return_tuple: # pragma: no cover while not regex_ip_and_mask.match(ip_addr_and_mask): print("Not a good IP and CIDR mask combo.") print("Please try again.") ip_addr_and_mask = input("Please enter a IP address and mask in the follwing format x.x.x.x/x: ") ip_cidr_split = ip_addr_and_mask.split("/") ip_addr = ip_cidr_split[0] cidr = ip_cidr_split[1] return ip_addr, cidr elif not return_tuple: if not regex_ip_and_mask.match(ip_addr_and_mask): # pragma: no cover return False else: return True
[docs]def ip(ip_addr, return_tuple=True): """ Function to check if a address is good :type ip_addr: String :param ip_addr: String format 192.168.1.1 :type return_tuple: Boolean :param return_tuple: True or False :rtype: Tuple, or Boolean :returns: Tuple, or Boolean """ regex_ip = __re.compile(r'^((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|([1-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|' r'(1[0-9][0-9])|([1-9]?[0-9]))\.((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|([1-9]?[0-9])' r')\.((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|([1-9]?[0-9]))$') if return_tuple: # pragma: no cover while not regex_ip.match(ip_addr): print("Not a good IP.") print("Please try again.") ip_addr = input("Please enter a IP address in the following format x.x.x.x: ") return ip_addr elif not return_tuple: if not regex_ip.match(ip_addr): return False else: return True
[docs]def cidr_check(cidr, return_cidr=True): """ Function to verify a good CIDR value :type cidr: Integer :param cidr: 30 :type return_cidr: Boolean :param return_cidr: True or False :rtype: String :returns: String """ try: if int(cidr) < 0 or int(cidr) > 32: good_cidr = False else: good_cidr = True if return_cidr: while not good_cidr: # pragma: no cover print(f"Sorry the CIDR value {cidr} is not a valid value must be a value of 0 to 32. " f"Please try again.") cidr = input("What is the mask for in CIDR format?: ") if int(cidr) < 0 or int(cidr) > 32: good_cidr = False else: good_cidr = True return cidr elif not return_cidr: return good_cidr except ValueError: # pragma: no cover LOGGER.critical('Function cidr_check expected a number but got {cidr}'.format(cidr=cidr)) raise ValueError("The input needs to be a number!!")
[docs]def get_neighbor_ip(ip_addr, cidr="30"): """ Function to figure out the IP's between neighbors address :type ip_addr: String :param ip_addr: String format 192.168.1.1 :type cidr: String :param cidr: CIDR value of 30, or 31 :rtype: Tuple :returns: returns Our IP and the Neighbor IP in a tuple """ our_octet = None neighbor_octet = None try: ip_addr_split = ip_addr.split(".") max_counter = 0 if int(cidr) == 30: ranger = 4 elif int(cidr) == 31: ranger = 2 while max_counter < 256: try: if int(ip_addr_split[3]) >= max_counter and int(ip_addr_split[3]) < (max_counter + ranger): if ranger == 4: our_octet = max_counter + 1 neighbor_octet = max_counter + 2 break elif ranger == 2: our_octet = max_counter neighbor_octet = max_counter + 1 break max_counter += ranger # pragma: no cover except UnboundLocalError: # pragma: no cover print("The mask between the neighbors must be 30, or 31") exit("BAD NEIGHBOR MASK") if int(ip_addr_split[3]) == our_octet: our_ip_addr = f'{ip_addr_split[0]}.{ip_addr_split[1]}.{ip_addr_split[2]}.{our_octet}' neighbor_ip_addr = f'{ip_addr_split[0]}.{ip_addr_split[1]}.{ip_addr_split[2]}.{neighbor_octet}' elif int(ip_addr_split[3]) == neighbor_octet: neighbor_ip_addr = f'{ip_addr_split[0]}.{ip_addr_split[1]}.{ip_addr_split[2]}.{our_octet}' our_ip_addr = f'{ip_addr_split[0]}.{ip_addr_split[1]}.{ip_addr_split[2]}.{neighbor_octet}' else: # pragma: no cover our_ip_addr = f'{ip_addr_split[0]}.{ip_addr_split[1]}.{ip_addr_split[2]}.{our_octet}' neighbor_ip_addr = f'{ip_addr_split[0]}.{ip_addr_split[1]}.{ip_addr_split[2]}.{neighbor_octet}' return our_ip_addr, neighbor_ip_addr except IndexError: # pragma: no cover LOGGER.critical('Function get_neighbor_ip IndexError ip_addr {ip_addr} cidr {cidr}'.format(ip_addr=ip_addr, cidr=cidr)) raise IndexError("You have entered invalid input, you must enter a ipv4 address")
[docs]def whole_subnet_maker(ip_addr, cidr): """ Function to return a whole subnet value from a IP address and CIDR pair :type ip_addr: String :param ip_addr: String format 192.168.1.1 :type cidr: String :param cidr: CIDR value of 0 to 32 :rtype: String :returns: returns the corrected whole subnet """ if ucast_ip(ip_addr, False) == False and mcast_ip(ip_addr, False) == False: # pragma: no cover LOGGER.critical('Function whole_subnet_maker ip_addr {ip_addr}'.format(ip_addr=ip_addr)) raise ValueError("Not a good ipv4 address") if not cidr_check(cidr, False): # pragma: no cover LOGGER.critical('Function whole_subnet_maker cidr {cidr}'.format(cidr=cidr)) raise ValueError("Not a good CIDR value should be 0 to 32") def subnet_corrector(octet, cidr): """ Function to correct a octet for a subnet """ cidr_int = int(cidr) octet_int = int(octet) if cidr_int >= 24: cidr_int = __mask_conversion[cidr_int]["OCT4"] elif cidr_int >= 16: cidr_int = __mask_conversion[cidr_int]["OCT3"] elif cidr_int >= 8: cidr_int = __mask_conversion[cidr_int]["OCT2"] elif cidr_int >= 1: cidr_int = __mask_conversion[cidr_int]["OCT1"] cidr_count = 0 cidr_v = 256 - cidr_int cidr_2 = 256 - cidr_int while cidr_count < 300: if octet_int >= cidr_count and octet_int <= cidr_2: cidr_int = cidr_count cidr_count = cidr_2 cidr_2 = cidr_2 + cidr_v return str(cidr_int) ip_addr_split = ip_addr.split(".") if int(cidr) >= 24: octet = subnet_corrector(ip_addr_split[3], cidr) completed = f'{ip_addr_split[0]}.{ip_addr_split[1]}.{ip_addr_split[2]}.{octet}' return completed elif int(cidr) >= 16: octet = subnet_corrector(ip_addr_split[2], cidr) completed = f'{ip_addr_split[0]}.{ip_addr_split[1]}.{octet}.0' return completed elif int(cidr) >= 8: octet = subnet_corrector(ip_addr_split[1], cidr) completed = f'{ip_addr_split[0]}.{octet}.0.0' return completed elif int(cidr) >= 1: octet = subnet_corrector(ip_addr_split[0], cidr) completed = f'{octet}.0.0.0' return completed else: # pragma: no cover return "0.0.0.0"
[docs]def subnet_range(ip_net, cidr): """ Function to return a subnet range value from a IP address and CIDR pair :type ip_net: String :param ip_net: String format 192.168.1.1 :type cidr: String :param cidr: CIDR value of 1 to 32 :rtype: Dict :returns: returns a dictionary of info """ subnets_dict = dict() subnet = whole_subnet_maker(ip_net, cidr) subnets_dict['IP'] = ip_net subnets_dict['NET'] = subnet subnets_dict['CIDR'] = f'{whole_subnet_maker(ip_net, cidr)}/{cidr}' if int(cidr) >= 24: subnet_split = subnet.split('.') first_ip = int(subnet_split[3]) + 1 last_ip = (int(subnet_split[3]) + 1) + (253 - int(__mask_conversion[int(cidr)]['OCT4'])) bcast_ip = (int(subnet_split[3]) + 1) + (254 - int(__mask_conversion[int(cidr)]['OCT4'])) temp = f'{subnet_split[0]}.{subnet_split[1]}.{subnet_split[2]}.' subnets_dict['RANGE'] = f'{temp}{first_ip} to {temp}{last_ip}' subnets_dict['BCAST'] = f'{temp}{bcast_ip}' subnets_dict['MASK'] = __mask_conversion[int(cidr)]['MASK'] subnets_dict['INVMASK'] = __mask_conversion[int(cidr)]['INVMASK'] subnets_dict['CIDRVAL'] = __mask_conversion[int(cidr)]['CIDR'] elif int(cidr) >= 16: subnet_split = subnet.split('.') first_ip = int(subnet_split[2]) last_ip = (int(subnet_split[2]) + 1) + (254 - int(__mask_conversion[int(cidr)]['OCT3'])) bcast_ip = (int(subnet_split[2]) + 1) + (254 - int(__mask_conversion[int(cidr)]['OCT3'])) temp = f'{subnet_split[0]}.{subnet_split[1]}.' subnets_dict['RANGE'] = f'{temp}{first_ip}.1 to {temp}{last_ip}.254' subnets_dict['BCAST'] = f'{temp}{bcast_ip}.255' subnets_dict['MASK'] = __mask_conversion[int(cidr)]['MASK'] subnets_dict['INVMASK'] = __mask_conversion[int(cidr)]['INVMASK'] subnets_dict['CIDRVAL'] = __mask_conversion[int(cidr)]['CIDR'] elif int(cidr) >= 8: subnet_split = subnet.split('.') first_ip = int(subnet_split[1]) last_ip = (int(subnet_split[1]) + 1) + (254 - int(__mask_conversion[int(cidr)]['OCT2'])) bcast_ip = (int(subnet_split[1]) + 1) + (254 - int(__mask_conversion[int(cidr)]['OCT2'])) temp = f'{subnet_split[0]}.' subnets_dict['RANGE'] = f'{temp}{first_ip}.0.1 to {temp}{last_ip}.255.254' subnets_dict['BCAST'] = f'{temp}{bcast_ip}.255.255' subnets_dict['MASK'] = __mask_conversion[int(cidr)]['MASK'] subnets_dict['INVMASK'] = __mask_conversion[int(cidr)]['INVMASK'] subnets_dict['CIDRVAL'] = __mask_conversion[int(cidr)]['CIDR'] elif int(cidr) >= 1: subnet_split = subnet.split('.') first_ip = int(subnet_split[0]) last_ip = (int(subnet_split[0]) + 1) + (254 - int(__mask_conversion[int(cidr)]['OCT1'])) bcast_ip = (int(subnet_split[0]) + 1) + (254 - int(__mask_conversion[int(cidr)]['OCT1'])) subnets_dict['RANGE'] = f'{first_ip}.0.0.1 to {last_ip}.255.255.254' subnets_dict['BCAST'] = f'{bcast_ip}.255.255.255' subnets_dict['MASK'] = __mask_conversion[int(cidr)]['MASK'] subnets_dict['INVMASK'] = __mask_conversion[int(cidr)]['INVMASK'] subnets_dict['CIDRVAL'] = __mask_conversion[int(cidr)]['CIDR'] return subnets_dict
[docs]def all_subnets_possible(ip_net, cidr): """ Function to return every subnet a ip can belong to with a longer prefix :type ip_net: String :param ip_net: String format 192.168.1.1 :type cidr: String :param cidr: CIDR value of 0 to 32 :rtype: List :returns: A List of subnets """ return all_subnets_longer_prefix(ip_net, cidr)
[docs]def all_subnets_longer_prefix(ip_net, cidr): """ Function to return every subnet a ip can belong to with a longer prefix :type ip_net: String :param ip_net: String format 192.168.1.1 :type cidr: String :param cidr: CIDR value of 0 to 32 :rtype: List :returns: A List of subnets """ subnets_list = list() while int(cidr) <= 32: try: subnets_list.append(f'{whole_subnet_maker(ip_net, cidr)}/{cidr}') except Exception as e: # pragma: no cover LOGGER.critical('Function all_subnets_longer_prefix {e}'.format(e=e)) pass cidr = str(int(cidr) + 1) return subnets_list
[docs]def all_subnets_shorter_prefix(ip_net, cidr, include_default=False): """ Function to return every subnet a ip can belong to with a shorter prefix :type ip_net: String :param ip_net: String format 192.168.1.1 :type cidr: String :param cidr: CIDR value of 0 to 32 :type include_default: Boolean :param include_default: True or False :rtype: List :returns: A List of subnets """ subnets_list = list() if include_default: while int(cidr) >= 0: # pragma: no cover try: subnets_list.append(f'{whole_subnet_maker(ip_net, cidr)}/{cidr}') except Exception as e: LOGGER.critical('Function all_subnets_shorter_prefix {e}'.format(e=e)) cidr = str(int(cidr) - 1) else: while int(cidr) > 0: try: subnets_list.append(f'{whole_subnet_maker(ip_net, cidr)}/{cidr}') except Exception as e: # pragma: no cover LOGGER.critical('Function all_subnets_shorter_prefix {e}'.format(e=e)) cidr = str(int(cidr) - 1) return subnets_list
[docs]def all_ip_address_in_subnet(ip_net, cidr): """ Function to return every ip in a subnet :type ip_net: String :param ip_net: String format 192.168.1.1 :type cidr: String :param cidr: CIDR value of 0 to 32 :rtype: List :returns: A List of IPv4 Address's """ ip_address_list = list() if not ip_mask(f'{ip_net}/{cidr}', return_tuple=False): # pragma: no cover network = f'{ip_net}/{cidr}' LOGGER.critical('{network} is not a valid IPv4 network'.format(network=network)) raise ValueError(f'{network} is not a valid IPv4 network') else: ip_net = whole_subnet_maker(ip_net, cidr) net = __ipaddress.ip_network(f'{ip_net}/{cidr}') for single_ip in net: ip_address_list.append(str(single_ip)) return ip_address_list
[docs]def number_check(check, return_number=True): """ Function to verify item entered is a number :type check: Anything :param check: What to check :type return_number: Boolean :param return_number: True or False :rtype: Boolean :returns: Check return_number for return options """ try: int(check) good = True except ValueError: LOGGER.critical('Function number_check ValueError {check}'.format(check=check)) good = False if return_number: # pragma: no cover while not good: print("That is not a number.") print("Please try again.") check = input("Please enter a number?: ") try: int(check) good = True except ValueError: LOGGER.critical('Function number_check ValueError {check}'.format(check=check)) good = False return check else: return good
[docs]def random_cidr_mask(lowest_mask=16): """ Function to generate a random CIDR value :type lowest_mask: Integer :param lowest_mask: An integer value for the lowest mask you want it to generate :rtype: String :return: A string of a random CIDR mask """ if lowest_mask < 33: return str(__random.randrange(lowest_mask, 33)) else: LOGGER.critical('{lowest_mask} must be 32 or less.'.format(lowest_mask=lowest_mask)) raise ValueError(f'{lowest_mask} must be 32 or less.')
[docs]def random_ucast_ip(): """ Function to generate a random unicast ip address :rtype: String :return: A unicast IP Address """ first_octet = str(__random.randrange(1, 224)) def get_other_octetes(): return str(__random.randrange(0, 255)) return f'{first_octet}.{get_other_octetes()}.{get_other_octetes()}.{get_other_octetes()}'
[docs]def random_mcast_ip(): """ Function to generate a random multicast ip address :rtype: String :return: A multicast IP Address """ first_octet = str(__random.randrange(224, 240)) def get_other_octetes(): return str(__random.randrange(0, 255)) return f'{first_octet}.{get_other_octetes()}.{get_other_octetes()}.{get_other_octetes()}'
[docs]def random_ucast_ip_mask(lowest_mask=16): """ Function to generate a random unicast ip address and cidr mask pair in the following format X.X.X.X/X :type lowest_mask: Integer :param lowest_mask: An integer value for the lowest mask you want it to generate :rtype: String :return: A unicast IP Address and CIDR pair in the following format X.X.X.X/X """ return f'{random_ucast_ip()}/{random_cidr_mask(lowest_mask)}'
[docs]def random_mcast_ip_mask(lowest_mask=16): """ Function to generate a random multicast ip address and cidr mask pair in the following format X.X.X.X/X :type lowest_mask: Integer :param lowest_mask: An integer value for the lowest mask you want it to generate :rtype: String :return: A multicast IP Address and CIDR pair in the following format X.X.X.X/X """ return f'{random_mcast_ip()}/{random_cidr_mask(lowest_mask)}'