So here goes the though process: Basically if you input say 192 hosts and subtract 128 you get 64 so 128 is a proper network, and now you have 64 left over for further subnetting. Just run again with new value to continue retrieving the remainders.

Modulous division will determine if the numbers are divisible by their respective octets. If any remainder is found then the number is greater than that larger octet and will need to remove out the lower value first. Simply put modulous division until 0 found or value is less than 256.

(1st octet ignored, 2nd octet > 65536, 3rd octet > 256, 4th octet <= 256)

ex: 22184 % 65536 = 24576 % 256 = 0 -> so third octet

The program has a logic error in that if the given range encompasses a lower CIDR then a higher, then a lower, ex 352h SHOULD be 64, 256, 32 which would be a range like this:

10.0.0.192 - 10.0.2.31 -> 10.0.0.192/26, 10.0.1.0/24, 10.0.2.0/27

instead this will churn out:

10.0.0.192/26, 10.0.1.0/27, 10.0.1.32/27, 10.0.1.64/27, 10.0.1.96/27...

10.0.1.224/27, 10.0.2.0/27

So all ranges are valid, they are just not represented in their lowest form

Each of the nested functions are for calculating the subnet within that block. process is divide the IP by exponents of two up to 256 (which is 0), this tells you all the possible subnets which are legal for that IP. Then take the number of hosts 1 - 256 to tell you how many hosts fit in that range.

v = 352 sIP = '10.0.0.192' sDec = 83886272 eDec = 0 r = '' mask = '' while v > 0: #need to accomodate non-CIDR networks b = GetHostRemainder(sDec, v) #gets the nearest whole network v -= b #calculate sDec and eDec eDec = sDec + v - 1 #get mask and route if v != '1': #anything but a /32 should go here mask = ConvertDecimalToIP(str(v - 1)) r = sIP + '/' + ConvertMaskToCIDR(mask) else: #/32 here, has special entry in ACL mask = '' r = sIP #calculate eIP eIP = ConvertDecimalToIP(eDec) #save data to row[] and append to route[] row = [sIP, eIP, mask, r, sDec, eDec,] route.append(row) row = [] #get next v if b has anything left over if b == 0: #no left overs, all in proper subnet v = 0 else: #hosts remaining, move start IP past range covered sIP = ConvertDecimalToIP(str(sDec + v)) #move b into v and run again. v = b

def GetHostRemainder(decIP, h): #input int decIP is the decimal IP of the first address in a range # int v is the number of hosts(IPs) in a provided range #output b is the remaining number of hosts minus a proper subnet #get the regular notation of the IP address into a list ip = [decIP/256/65536, (decIP/65536)%256,(decIP/256)%256, decIP%256] def CalcFourth(v): b = 0 if ip[3] % 2 == 0: if ip[3] % 4 == 0: if ip[3] % 8 == 0: if ip[3] % 16 == 0: if ip[3] % 32 == 0: if ip[3] % 64 == 0: if ip[3] % 128 == 0: if ip[3] % 256 == 0: #ip is 0 since 0/x = 0 special condition if v == 256: mh = 256 elif v >= 128: mh = 128 elif v >= 64: mh = 64 elif v >= 32: mh = 32 elif v >= 16: mh = 16 elif v >= 8: mh = 8 elif v >= 4: mh = 4 elif v >= 2: mh = 2 else: mh = v else: #ip is 128 if v >= 128: mh = 128 elif v >= 64: mh = 64 elif v >= 32: mh = 32 elif v >= 16: mh = 16 elif v >= 8: mh = 8 elif v >= 4: mh = 4 elif v >= 2: mh = 2 else: mh = v else: #ip is multiple of 64 if v >= 64: mh = 64 elif v >= 32: mh = 32 elif v >= 16: mh = 16 elif v >= 8: mh = 8 elif v >= 4: mh = 4 elif v >= 2: mh = 2 else: mh = v else: #ip is multiple of 32 if v >= 32: mh = 32 elif v >= 16: mh = 16 elif v >= 8: mh = 8 elif v >= 4: mh = 4 elif v >= 2: mh = 2 else: mh = v else: #ip is multiple of 16 if v >= 16: mh = 16 elif v >= 8: mh = 8 elif v >= 4: mh = 4 elif v >= 2: mh = 2 else: mh = v else: #ip is multiple of 8 if v >= 8: mh = 8 elif v >= 4: mh = 4 elif v >= 2: mh = 2 else: mh = v else: #ip is multiple of 4 if v >= 4: mh = 4 elif v >= 2: mh = 2 else: mh = v else: #ip is multiple of 2 if v >= 2: mh = 2 else: mh = v else: #ip = odd number mh = 1 b = mh return b def CalcThird(v): b = 0 if ip[2] % 2 == 0: if ip[2] % 4 == 0: if ip[2] % 8 == 0: if ip[2] % 16 == 0: if ip[2] % 32 == 0: if ip[2] % 64 == 0: if ip[2] % 128 == 0: if ip[2] % 256 == 0: #ip is 0 since 0/x = 0 special condition v /= 256 if v == 256: mh = 256 elif v >= 128: mh = 128 elif v >= 64: mh = 64 elif v >= 32: mh = 32 elif v >= 16: mh = 16 elif v >= 8: mh = 8 elif v >= 4: mh = 4 elif v >= 2: mh = 2 else: mh = v else: #ip is 128 v /= 256 if v >= 128: mh = 128 elif v >= 64: mh = 64 elif v >= 32: mh = 32 elif v >= 16: mh = 16 elif v >= 8: mh = 8 elif v >= 4: mh = 4 elif v >= 2: mh = 2 else: mh = v else: #ip is multiple of 64 v /= 256 if v >= 64: mh = 64 elif v >= 32: mh = 32 elif v >= 16: mh = 16 elif v >= 8: mh = 8 elif v >= 4: mh = 4 elif v >= 2: mh = 2 else: mh = v else: #ip is multiple of 32 v /= 256 if v >= 32: mh = 32 elif v >= 16: mh = 16 elif v >= 8: mh = 8 elif v >= 4: mh = 4 elif v >= 2: mh = 2 else: mh = v else: #ip is multiple of 16 v /= 256 if v >= 16: mh = 16 elif v >= 8: mh = 8 elif v >= 4: mh = 4 elif v >= 2: mh = 2 else: mh = v else: #ip is multiple of 8 v /= 256 if v >= 8: mh = 8 elif v >= 4: mh = 4 elif v >= 2: mh = 2 else: mh = v else: #ip is multiple of 4 v /= 256 if v >= 4: mh = 4 elif v >= 2: mh = 2 else: mh = v else: #ip is multiple of 2 v /= 256 if v >= 2: mh = 2 else: mh = v else: #ip = odd number mh = 1 b = mh * 256 return b def CalcSecond(v): b = 0 if ip[1] % 2 == 0: if ip[1] % 4 == 0: if ip[1] % 8 == 0: if ip[1] % 16 == 0: if ip[1] % 32 == 0: if ip[1] % 64 == 0: if ip[1] % 128 == 0: if ip[1] % 256 == 0: #ip is 0 since 0/x = 0 special condition v /= 65536 if v == 256: mh = 256 elif v >= 128: mh = 128 elif v >= 64: mh = 64 elif v >= 32: mh = 32 elif v >= 16: mh = 16 elif v >= 8: mh = 8 elif v >= 4: mh = 4 elif v >= 2: mh = 2 else: mh = v else: #ip is 128 v /= 65536 if v >= 128: mh = 128 elif v >= 64: mh = 64 elif v >= 32: mh = 32 elif v >= 16: mh = 16 elif v >= 8: mh = 8 elif v >= 4: mh = 4 elif v >= 2: mh = 2 else: mh = v else: #ip is multiple of 64 v /= 65536 if v >= 64: mh = 64 elif v >= 32: mh = 32 elif v >= 16: mh = 16 elif v >= 8: mh = 8 elif v >= 4: mh = 4 elif v >= 2: mh = 2 else: mh = v else: #ip is multiple of 32 v /= 65536 if v >= 32: mh = 32 elif v >= 16: mh = 16 elif v >= 8: mh = 8 elif v >= 4: mh = 4 elif v >= 2: mh = 2 else: mh = v else: #ip is multiple of 16 v /= 65536 if v >= 16: mh = 16 elif v >= 8: mh = 8 elif v >= 4: mh = 4 elif v >= 2: mh = 2 else: mh = v else: #ip is multiple of 8 v /= 65536 if v >= 8: mh = 8 elif v >= 4: mh = 4 elif v >= 2: mh = 2 else: mh = v else: #ip is multiple of 4 v /= 65536 if v >= 4: mh = 4 elif v >= 2: mh = 2 else: mh = v else: #ip is multiple of 2 v /= 65536 if v >= 2: mh = 2 else: mh = v else: #ip = odd number mh = 1 b = mh * 65536 return b if h <= 256: #Can only fill 4th octet b = h - CalcFourth(h) elif h <= 65536: #Possibly 3rd octet if h % 256 == 0: #definately 3rd octet b = h - CalcThird(h) else: #need to fill 4th octet first b = h - CalcFourth(h % 256) else: #Possibly 2nd octect if h % 65536 == 0: #definately 2nd octet b = h - CalcSecond(h) else: #need to fill at least 3rd octect first if (h % 65536) % 256 == 0: #definately 3rd octet b = h - CalcThird(h % 65536) else: #need to fill 4th octet first b = h - CalcFourth((h % 65536) % 256) return b

Anyway, I am down for a totally simpler concept but right now, this was the best I could figure out with no error, its just not providing the most efficient subnets, which will ultimately mean more entries in our router ACLs... If I add in the extra step to check for the condition referenced, I forsee having to add in many more lines of code. So if there is a simpler method, by all means. Why did I stick with decimal? because I didnt see any immediate benefit to going to binary. If that notion would drastically simplify the code then again, Im all ears.

I am posting this for two reasons, one its not quite where it should be (so not working all the way) and two so the internet would have some record at least one way to tackle this concept. I did tons of googling and all I got was either how to do this by hand (which its much different to tell a computer how to error check than a person) or people saying: "why are you doing this? for homework? just go to xyz site and use their tool". While I am sure I could attack their website to do what I wanted, is that really the most efficient? I think not. Basically the first part of this program pulls down the IP lists from the RIRs (ARIN, RIPE, etc)... but all it has is the start IP address and the number of addresses used, ex: 192.168.1.0 | 256. So I need to take just that information there and explode it out to give me, the first IP, last IP, reverse mask, CIDR, start decimal, and end decimal. I can then take this output and do other things with it.

Again, any input is appreciated!