diff --git a/main.py b/main.py index d89c969..e9502c2 100644 --- a/main.py +++ b/main.py @@ -3,64 +3,56 @@ import random def intToDotted(ip): # input: ip - # determins dotted decimal format for given ip as int - - # returns list: octets + # returns list octets + octets = [] + while ip != 0: octets.append(ip % 256) ip = math.floor(ip / 256) octets.reverse() + return octets -def printDotted(octets): - # input: list containing octets - - # returns out the dotted decimal format - +def printDotted(ip): + # input: ip as integer + # returns the dotted decimal format # hint: use '.'.join() - #returns prettyfied DD format as string + # returns prettyfied dotted decimal format as string + octets = intToDotted(ip) + return ".".join(str(x) for x in octets) def generateNetwork(): # input: none # generates a random ip and prefix - # the generated prefix should be in the range [8, 30] + # the generated prefix should be in the range [8, 29] # to avoid getting too large and too small networks - # returns dict: {ip:int, prefix:int} - ip = random.randint(0, 2**32-1) - prefix = random.randint(8, 31) #max prefix generated is - # 30, allowing for at least 1 bit to be subnetted and still have hostbits left - ipandprefix = {"ip":ip, "prefix":prefix} - return ipandprefix - + # returns dict: {"ip":ip, "prefix":prefix} -def getNetId(ip, prefix): - snm=(2**prefix-1)<<(32-prefix) - netid = ip&snm - return netid + ip = random.randint(0, 2**32-1) + prefix = random.randint(8, 29) #max prefix generated is + # 29, allowing for at least 1 bit to be subnetted and still have valid hosts left + + ipandprefix = {"ip":ip, "prefix":prefix} + + return ipandprefix def analyseSubnet(ip, prefix): # input: ip as int, prefix as int - + # returns net id, broadcast address + # returns dict: {"nid":netid, "bc":bc} - # prints out net id, broadcast address, - - # and amount of addresses and amount of - # usable adresses for a given subnet + snm=(2**prefix-1)<<(32-prefix) + netid = ip&snm wmask = 0xffffffff >> prefix - bid = ip|wmask + bc = ip|wmask - hostbits = 32 - prefix - hosts = 2**hostbits-2 - print("Useable Hosts: {}".format(hosts)) - ids = {"bid":bid} - return ids - # returns dict: {netid:int, bc:int} + return {"nid":netid, "bc":bc} def newSubnetExercises(ip, prefix): # input: a subnet, consisting of an ip @@ -79,58 +71,85 @@ def newSubnetExercises(ip, prefix): # "split the given network into...." # depending on the type of exercise - # returns dict: {ip: int, prefix:int, newprefix:int} - # newprefx contains the new subnet mask that solves the exercise + # returns dict: {"ip":ip, "prefix":prefix, "newprefix":newprefix} + # newprefix contains the new subnet mask that solves the exercise - aufgabentyp = random.randint(0,1) - bonusaufgabe = random.randint(0,10) - newprefix = random.randint(prefix+1, prefix+5) - - print("Network: {}/{}".format(printDotted(intToDotted(ip)), prefix)) - print("newprefix: {}".format(newprefix)) - if aufgabentyp == 0: - print("Split the Network into {} subnets".format(2**(newprefix-prefix))) - else: - print("Split the network into subnets with {} Hosts".format(2**(32-newprefix))) + nid = analyseSubnet(ip, prefix).get("nid") + newprefix = random.randint(prefix+1, 30) # max 30 to leave 2 hostbits (no empty nets) + listnetwork = -1 #set this to -1, meaning "exercise did not appear" - if bonusaufgabe > 5: - print("What is the Net ID of the given subnet?") - print("What is the start and end of the Subnet") - if bonusaufgabe > 8: - print("What is the Adress of the next subnet?") + print("Exercise:\n") + print("Given Network: {}/{}\n".format(printDotted(nid), prefix)) - subnetdic = {"ip":ip, "prefix":prefix, "newprefix":newprefix} - return subnetdic + # sanity assertions + assert(prefix 1) #must allow for more than 1 hostbit (no usable hosts otherwise) + + if random.random() > 0.5: + #ask user to split into networks, but make sure the amount of networks + #requires to use the specific prefix generated by the exercise + #start is set to at least as much subnets as 1 bit less, but plus one so + #you cannot use one fewer bits for the new prefix + #end is set to exactly the amount of subnets possible with the newprefix + + print("Split the Network into {} subnets".format(random.randint(2**(newprefix-prefix-1)+1,2**(newprefix-prefix)))) + else: + #ask user to split into hosts, but make sure the amount of hosts required + #requires the user to use at least the new prefix generated + #-1 at the start means it's at least enough hosts as 1 hostbit less + # -> since 2 hosts are left, using 1 less hostbit is not allowed + #-2 at the end makes sure the required amount of hosts still fit + # within the specific new prefix + print("Split the network into subnets with {} Hosts".format(random.randint(2**(32-newprefix-1),2**(32-newprefix)-2))) + if random.random() > 0.5: + listnetwork = random.randint(0, 2^(newprefix-prefix)-1) # user may list this network + #make the user list a specific network between 0 and the last + print("\nList the start and end of Subnet {}".format(listnetwork)) + + return {"ip":ip, "prefix":prefix, "newprefix":newprefix, "listnetwork":listnetwork} def listSubnets(ip, prefix, newprefix): - # input: a network range and a subnet prefix to split into DONE + # input: a network range and a subnet prefix, a new prefix for subnetting + # note: sanity check with: assert newprefix > prefix + # this function prints out every possible network + # within the given range, showing net id and bc + # as well as amount of adresses and usable hosts per network + # returns: nothing, this just prints all possible subnets + + hostbits = 32-newprefix + newnets = 2**(newprefix-prefix) + nid = analyseSubnet(ip, prefix).get("nid") - # note: sanity check with: assert newprefix > prefix DONE - # this function prints out every possible network ??? - # within the given range, showing net id and bc DONE - # as well as amount of adresses and usable hosts per network DONE - # returns: nothing, this just prints all possible subnets DONE - nid = getNetId(ip, prefix) - print(newprefix) - hostbits = 32 - newprefix - newnetbits = newprefix - prefix - newnetbits = 2**newnetbits - for i in range(0,newnetbits): - print("subnet", i,":", printDotted(intToDotted(nid +i*2**hostbits))) - if i > 25: - print("and many many more...") + for i in range(0,newnets): + print("Network", i,":", printDotted(nid+i*2**hostbits)) + if i > 8: + #-10 -> we list network 0 to 9 (larger than 8), which is 10 already listed + print("and {} more...".format(newnets-10)) break - if __name__ == '__main__': - ipdic = generateNetwork() - ip = ipdic.get("ip") - prefix = ipdic.get("prefix") - newprefixdic = newSubnetExercises(ip=ip, prefix=prefix) - if input("Press Space and enter to continue") != "": - listSubnets(ip, prefix, newprefixdic.get("newprefix")) # 1. Generate new exercise # 2. wait for user input, noting that the solution # will be shown after after pressing any key # 3. print the solution # 4. exit + + network = generateNetwork() + ip = network.get("ip") + prefix = network.get("prefix") + net = analyseSubnet(ip, prefix) + exercise = newSubnetExercises(ip=ip, prefix=prefix) + newprefix = exercise.get("newprefix") + listnetwork = exercise.get("listnetwork") + + #wait for an enter to continue + input("\nPress Enter to show solution\n") + + print("The original network starts at {} and ends at {}.".format(printDotted(net.get("nid")), printDotted(net.get("bc")))) + print("The new prefix is {}, allowing for {} subnets with {} Hosts each".format(newprefix, 2**(newprefix-prefix), 2**(32-newprefix)-2)) + if(listnetwork >= 0): + subnet=analyseSubnet(net.get("nid")+listnetwork*2**(32-newprefix), newprefix) + print("Network {}: NID: {} BC: {}".format(listnetwork, printDotted(subnet.get("nid")), printDotted(subnet.get("bc")))) + print("\nSubnets:") + listSubnets(ip, prefix, newprefix) \ No newline at end of file