Introduction to IPv4 subnetting including python program for subnetting

in stemng •  7 years ago 

Today I felt like sharing a little piece of tool I constantly use whenever I am documenting my network or carrying out network planning. I am an engineer with a team playing spirit but whenever I want to get things done quickly, I do it alone and on my own and most of the time, the tool that enables me carry out quick planning and documenting tasks is this simple python app and it is already making me lazy!


[credit:Creative commons images. Creative Commons 3 - CC BY-SA 3.0 license. Author: Nick Youngson]

What is subnetting? For beginner in networking, subnetting can be a very difficult subject to understand but most people understand it when it with proper explanation. So this is my proper explanation... Subnetting is the process of "giving birth" to new IP address by a parent IP address. That is the definition of subnetting in its most basic form. In the networking world, an IP address alone could mean anything or better still, meaningless but when it is coupled with a subnet mask, its meaning is complete.

What then is a subnet mask? A subnet mask is a 32-bit number (not address) which is used to identify the network and broadcast of an IP address. All IP addresses belongs to a network and in that network, a message (broadcast) meant for all the members of such network is sent to the broadcast IP address, hence, an IP address is as important as its subnet mask. If you have seen an IP address in a production environment it is either written as for example, 192.168.1.1/24 or 192.168.1.1 255.255.255.0. The two representations means the same thing and completely describes the IP address 192.168.1.1

Classful Subnetting


All the operations and statements made about IP addresses in this work will strictly be referring to IPv4 unless otherwise stated.

IP addresses are divided into 5 classes which are, class A, class B, class C, class D and class E IP addresses. Class D addresses are used for communications only meant for a group of devices, this form of communication is known as multicast. An example of class D IP address is 224.0.0.9 which is an address used only by devices running a particular routing protocol (Routing information protocol to be precise, RIP) to share routing information. Class E is an address reserved for research purposes, hence, the focus of this work will be on class A to C addresses only.


[Ranges of classes of IP addresses. Credit: Wikimedia. CC1.0 license. Author:Skyrocket2005]

Classful subnetting simply means the identification of IP addresses based on their default subnet masks. Class A IP addresses has a default subnet mask of 255.0.0.0 or /8. Class A IP addresses ranges from 1.0.0.0 to 126.0.0.0. Wait, where did the "8" come from? Remember I said the default subnet mask of class A is 255.0.0.0, this number converted to binary would give me 11111111.00000000.00000000.00000000. If we count the number of 1s in the binary form, we would get 8, hence /8 is the same as 255.0.0.0.

Class B has a default subnet mask of 255.255.0.0 or /16. There I go again, where did the 16 come from? Same as the above operation, the binary version of 255.255.0.0 would be 11111111.11111111.00000000.00000000. When we count the number of 1s in the binary representation, we would get 16. Our devices are digital in nature, so forgive me if I go "binary" in the cause of explaining digital concepts.

I'm sure we have all figured out the default class C subnet mask ..., OK let's just do it together. The default class C subnet mask is 255.255.255.0 or /24. When we convert the above number to binary we would have 11111111.11111111.11111111.00000000 which contains 24 1s. Now you know where the /24 attached to the IP address you receive from your hotspot device, hence, your phone is also a subnetting machine!

Octets


All IP addresses contains three dots (.) and at least four numbers anything short from that is no longer an IP address. Octets here doesn't mean a group of eight musicians but a unit of digital information which consists of eight bits. In the representation of subnet mask in their respective binary form above, I represented 0 as 00000000, this is because the unit of information in IP world is in 8-bits. hence, the number 1 would mean 00000001.


[All valid IP address contains four octets. Credit: Wikimedia. Creative commons license. Author: unknown]

This subheading though short is very important because all subnetting operations are carried out based on octets. An IP address contains four octets for example 192.168.2.1, "192" belongs to the first octet, "168" belongs to the second octet, "2" belongs to the third octet while "1" belongs to the fourth octet, the same is applicable to every IP address.

All subnetting operations are performed on subnet masks not the IP address. As already stated, the IP address have little or no meaning without a subnet mask accompanying it. With a good grasp of subnetting concept, one can easily list all the members of a given network by just looking at the subnet mask. For example, the address 192.168.1.1/24 has a maximum of 253 users that communicate using the IP address 192.168.1.255 and a network address of 192.168.1.1. I will explain this concept shortly.

Once we understand the concept of octets and as already stated, subnetting is carried out on the subnet mask and not on the IP address, the first thing to do is to identify the octet of interest. The octet of interest is the first smallest octet after the number 255. Hence, a subnet mask of say 255.255.0.0, the octet of interest is the third octet which is "0". Consider the subnet mask, 255.252.0.0, the octet of interest is the second octet, 252, since it is the smallest octet after 255.

Classless Subnetting


Do you know the name given to the IP address notation with a slash (/)? It is called Classless Inter-domain Routing notation (CIDR). Did you also know that subnet mask, in giving a meaning to an IP address also determines the number of users a network can contain.


[Different IP address CIDR notation and the maximum users such address can accommodate (second column). Credit: Wikimedia. CC3.0 license. Author: Dario Lanza]

Classless subnetting is the division and identification of IP address that is free from its default masks. I have already stated the default subnet masks of all IP address classes (that concerns us), hence, a subnetted class A IP address could have a class C subnet mask.

Subnetting could be carried out for any IP address be it private or public IP address. In fact, when you go to an internet service provider to request for a connection and bandwidth, providing such services also includes providing internet usable IP address (public IP addresses) and they expect you to know number of available IP addresses in the single subnet mask which they will provide for you. An ISP giving you an IP address say 208.223.1.0/30 is automatically saying "hey, the connection you requested is a point-point connection and you are only entitled to one IP address and one network".

Subnetting can be carried out based on two parameters, these are:

  • Subnetting based on number of hosts per network and
  • Subnetting based on the number of networks.

Let's do a little bit of mathematics...

Subnetting based on the number of hosts or users per network


In this approach, you are concerned with the number of users which will occupy the network you are about to design and implement. Let's say you want to create a network that will contain 20 users and you want to address them using the network address of 192.168.1.0. How do we break this single network address into 20 places?

Users in a network is divided into blocks irrespective of which class the IP address belongs to. Valid IP blocks are 2,4, 16, 32, 64, 128 and 254. Hence, if you want to design a network that will accommodate 20 users, the nearest IP block would be 32 since using 16 will leave 4 users without an address so also a network design that would accommodate 36 users would use IP block of 64. This is just how it is, when these networks are created, any request outside each block range is considered an internetwork request and would require routing which shows that subnetting completely segments addresses that would otherwise be considered as one.

When subnetting based on number of hosts, the steps to take are three which are:

  • Determine the number of users you want to occupy a network and convert this number to binary
  • Reserve the number of this bits in the octet of interest in the subnet mask
  • Obtain the increment and list the networks

For example, we want to subnet the address 192.168.1.0/24 to contain 20 users per network. The first step to take is to convert this 20 to binary which will give us 10100 which is 5 bits. The next step is to convert the subnet mask (/24) to binary. This is very simple because the number 24 means that the first 24 bits of the 32 bit number scheme are 1s. This means that the subnet mask is 11111111.11111111.11111111.00000000 which in decimal means 255.255.255.0.

The octet of interest here is the last octet and to reserve 5 bits in the above binary notation of the subnet mask means to leave the first five 0s and convert every other bit to 1s, hence the new subnet mask would be 11111111.11111111.11111111.11100000.

To obtain the increment, examine the new subnet of interest. Here, the increment is two raised to the power of the position of the last "1" which in this case is in the 6th the position, from the right. Hence, the increment is 26 = 32. Once this is done, we go ahead and list the possible IP addresses in this range which are

Network address (the increment)Broadcast address
192.168.1.0192.168.1.31
192.168.1.32192.168.1.63
192.168.1.64192.168.1.95
192.168.1.96192.168.1.127
192.168.1.128192.168.1.159
192.168.1.160192.168.1.191
192.168.1.192192.168.1.223
192.168.1.224192.168.1.255
192.168.1.256 (invalid)_

Notice the sequence of increment from 0 to 32 to 64 and so on. This implies that we have have created 8 different networks each capable of containing 32 users though the first and the last IP address is reserved for the network ID and broadcast address, hence the valid addresses which can be given to user each of the network is 30. For example, in the first network, the valid users are from 192.168.1.1 to 192.168.1.30, so also in the last network, the valid users are from 192.168.1.225 to 192.168.1.254.

Subnetting based on the number of networks


This approach is not popular but for completeness sake, I will explain the concept. The three steps approach used above still counts.

  • First, determine the number of desired networks and convert this number to binary
  • Reserve number of bits from the above operation and obtain the increment
  • Finally, use the increment to list the networks and host ranges.

For example I have the address 206.12.6.0/24 and I want to create just two (2) networks from the address, maybe one for I and my ISP and one for my remote site. The first thing to do is to convert this two to binary which will be equal to 10 (two bits). Converting the subnet mask, /24 (24 1s) to binary we have 11111111.11111111.11111111.00000000.

The next step is to reserve 2 bits in the binary subnet mask and to do this, we replace the first two 0s with 1s hence we have 11111111.11111111.11111111.11000000. The position of the last "1" in the above binary (looking at the last octet which is the octet of interest) is 7th and the value of this "1" in such position is 27 = 128. This value is our increment. Therefore we list the new networks as:

Network address (the increment)Broadcast address
206.12.6.0206.12.6.127
206.12.6.128206.12.6.255
206.12.6.256 (invalid)_

Just as we wanted, we created two valid networks from the given address and the valid hosts within this network are the values between the network address (network ID) and the broadcast address. In this case, the valid hosts for the first network is 206.12.6.1 to 206.12.6.126 while the valid hosts for the second network are 206.12.6.129 and 206.12.6.254, hence each of the created network can accommodate a maximum of 126 users. It is worth stating that as we create more networks, we reduce the number of users.

The Programm



To achieve neatness of code to a little degree, I broke down the code into three modules with the last module being the program itself, importing the remaining three into the main program.

The ipcheck module

To ensure the program does not run into run-time error, I decided to provide a robust code for validating an input of IP address from a user. A valid IP address is one that has four octets with first octet within the range of 1 and 223, the second and third octet within the range of 0 and 225, the last octet within the range of 0 and 254 and is not of the form 169.254.x.x which is windows default IP address in the case of a failed DHCP request which is not a valid IP address.

def ipchecker():
    while True:
        ip=input('enter a valid ip address:\n')
        a=ip.split('.')
        try:
            if ( (len(a)==4) and ( 1<=int(a[0])<=223) and (int(a[0])!=127) and (int(a[0])!=169 or int (a[1])!=254) and (0<= int(a[1])<=255) and (0<=int(a[2]) <=255) and (0<=int(a[3])<=255)):
                print('correct ip address')
                break
        except ValueError:
            print('please enter an integer')
        else:
            if (int(a[0])==127):
                answer=input('this is a loopback ip address do you wish to continue')
                if answer=='yes' or answer=='y':
                    continue
                else:
                    break
            print('bad ip')
            continue
    return ip 

The count module

In other to be able to list the valid IP addresses within each new subnetworks, I created this "count" module which effectively lists only the valid or usable IP address for all the available subnetworks. In the cause of listing this valid networks, it skips both the network address and the broadcast address with option to save this list to a txt file in the parent folder. This module is shown below.

    allAddress=[]
    hostAddress=[]
    finalhostAdd=[]
    for i in range (256):
        allAddress.append(i)
    for i in range(0,255,increament):
        hostAddress.append(allAddress[i+1:i+(increament-1)])
    for i in hostAddress:
        for j in i:
            finalhostAdd.append(str(j))
    #print(finalhostAdd, len(finalhostAdd))
    return finalhostAdd

The program module

This is the main program itself. It starts by importing the two first modules, then request for a class C IP address. Failure to provide a valid class C IP address will make the program to be in an unending loop while an input of a valid class C IP address moves the program to the execution level. This is the program;

#importing neccessary modules
import count
import ipcheck


def Subnetor():

    while True:
        # collecting valid ip address from users
        ip = ipcheck.ipchecker()
        # checks
        ipchecks = bin(int(ip.split('.')[0])).split('b')[1]
        ipcut = str(ipchecks[:3])
        if ipcut=='110':
            #cutting out the last octet
            ipsplit = ip.split('.')
            realip = str(ipsplit[0]+'.'+ipsplit[1]+'.'+ipsplit[2]+'.')
            #cutting out the last octet for operations on class c ip addresses
            lastoct=int(ip.split('.')[3])

            #getting the last octet for class c subnets mainly
            lastsub=0
            ipblocks = [2, 4, 16, 32, 64, 128, 254]
            ipblockselector = 0
            selector = int(input('enter number of users per network:\n'))
            for i in ipblocks:
                if i >= selector:
                    ipblockselector=i
                    break
            if ipblockselector==2:
                lastsub=252
            elif ipblockselector==4:
                lastsub=248
            elif ipblockselector==16:
                lastsub=240
            elif ipblockselector==32:
                lastsub=224
            elif ipblockselector==64:
                lastsub=192
            elif ipblockselector==128:
                lastsub=128
            elif ipblockselector==254:
                lastsub=0


            subnet='255.255.255.'+str(lastsub)
            subnetsplit=subnet.split('.')

            binsubnet=[]
            for i in subnetsplit:
                binsubnet.append(bin(int(i)).split('b')[1])
            binsubjoin=''.join(binsubnet)
            cidr=binsubjoin.count('1')

            print('you needed a network that can accommodate  '+ str(selector) +'  nodes in a network\n\nyou would probably use this subnet mask:\n' +subnet +' = /' +str(cidr))
            while True:
                option=input('wanna go ahead and print the ip address (y/n)?:\t')
                if option=='y':
                    subSplit = subnet.split('.')

                    if (0 <= int(subSplit[1]) < 255):
                        print('subnetting in the second octet')
                        binoctet = bin(int(subSplit[1])).split('b')[1]
                        print(binoctet)
                        increament = 256-int(subSplit[1])
                        print(increament)
                        count.counts(increament)

                    elif (  0<=int(subSplit[2])<255  ):
                        print('subnetting in the third octet')
                        binoctet = bin(int(subSplit[2])).split('b')[1]
                        #print(binoctet)
                        increament = 256 - int(subSplit[2])
                        #print(increament)
                        count.counts(increament)

                    elif (  0<=int(subSplit[3])<255  ):
                        print('subnetting in the last octet')
                        binoctet = bin(int(subSplit[3])).split('b')[1]
                        #print(binoctet)
                        increament = 256 - int(subSplit[3])
                        #print(increament)
                        iplist=count.counts(increament)

                        file1=open("text3.txt", "w")
                        filewriteoption=input('\n wanna push the ip addresses to a file? (y/n):')
                        for ip in iplist:
                            if int(ip)>lastoct:
                                print(realip+str(ip))
                                str1=realip+str(ip)
                                if filewriteoption=='y':
                                    file1.writelines(str1)
                        file1.close()
                        if filewriteoption=='y':
                            print('\n file writing done! check text3.txt your pc\n')


                else:
                    print('thank you for using my application bye\n')
                    import time
                    time.sleep(2)
                    print('exiting.......')
                    exit()
        elif ipcut!='110':
            print('...But enter a class C ip address')
Subnetor()

Running the program

To run the program, you only need to enter the IP address and the desired number of users per network and then follow the prompt. Once a valid IP address and users has been provided, it asks if you want to save this list, depending on your answer, the program will proceed as required. A screen shot of the program from my command prompt application is shown below. Notice, I used the IP address and the 20 users just as the first subnetting operation I explained above.

python.PNG

Observe how the program popped up the subnet mask based on the entered number of users. Also, the program excludes the network and the broadcast of all the subnetworks. This can be seen as 192.168.1.0 (Network address of the first subnet), 192.168.1.31 (broadcast address of the first subnet), and 192.168.1.32 (Network address of the first subnet) were all excluded from the list, this corresponds to our result from the first method of subnetting.

Thank you for your time!!!

REFERENCES


  1. Subnetwork -Wikipedia
  2. Classless inter domain routing -Wikipedia
  3. The Use of Octets in Computers and Networking -lifewire
  4. IP subnetting - The basic concepts -searchnetworking


If you write STEM (Science, Technology, Engineering, and Mathematics) related posts, consider joining #steemSTEM on steemit chat or discord here. If you are from Nigeria, you may want to include the #stemng tag in your post. You can visit this blog by @stemng for more details. You can also check this blog post by @steemstem here and this guidelines here for help on how to be a member of @steemstem. Please also check this blog post from @steemstem on proper use of images devoid of copyright issues here.

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  

Hi @henrychidiebere!

Your post was upvoted by utopian.io in cooperation with steemstem - supporting knowledge, innovation and technological advancement on the Steem Blockchain.

Contribute to Open Source with utopian.io

Learn how to contribute on our website and join the new open source economy.

Want to chat? Join the Utopian Community on Discord https://discord.gg/h52nFrV

Nice article bro! I never knew about the program. Can you explain more. I will dm you

Nice article bro! I never knew about the program. Can you explain more. I will dm you