Perform IP Subnetting and Binary Conversion in the Linux Terminal

CompTIABeginner
Practice Now

Introduction

In this lab, you will master the essential skills of IP address subnetting and binary conversion using the Linux command line. By leveraging the Python interactive interpreter, you will gain hands-on experience with the fundamental calculations that underpin computer networking, moving beyond theoretical knowledge to practical application in a terminal environment.

You will begin by converting IP addresses from the familiar dotted-decimal notation to their 32-bit binary form and back again. The lab will then guide you through translating CIDR subnet masks into their binary and dotted-decimal equivalents. Finally, you will apply these skills to identify the network and host portions of a given IP address and calculate the total number of usable hosts and subnets available within a specific CIDR block.

Perform IP and Subnet Mask Conversions in Python

In this step, you will use the Python interactive interpreter to perform several key networking conversions. You will learn how to convert IP addresses between dotted-decimal and binary formats, and how to translate CIDR subnet masks into their full binary and dotted-decimal representations. This will all be done in a single, continuous session to streamline the process.

An IPv4 address is a 32-bit number. To make it readable for humans, it's represented as four 8-bit numbers, called octets, separated by dots (e.g., 192.168.1.10). Each of these octets can be converted to an 8-bit binary number.

  1. First, let's open the terminal and start the Python interactive interpreter. The LabEx environment has Python pre-installed. Type python3 and press Enter.

    python3
    

    You will see a new prompt, >>>, which indicates you are now inside the Python interpreter.

    Python 3.10.x (...)
    Type "help", "copyright", "credits" or "license" for more information.
    >>>
    

Convert an IP Address from Dotted Decimal to Binary

  1. Let's practice converting a single decimal number to its binary form. We'll use Python's built-in bin() function. For example, to convert the number 192, type the following at the Python prompt:

    bin(192)
    

    Python will return the binary representation, prefixed with 0b to indicate that it's a binary number.

    '0b11000000'
    

    The binary equivalent of 192 is 11000000.

  2. Now, let's apply this to a full IP address, for example, 192.168.1.10. We need to convert each octet (192, 168, 1, and 10) individually. A critical rule in IP addressing is that each octet must be represented by exactly 8 bits. If a binary number has fewer than 8 bits, you must add leading zeros to pad it.

    Let's convert each part:

    • For 192: bin(192) gives '0b11000000'. This is already 8 bits: 11000000.
    • For 168: bin(168) gives '0b10101000'. This is also 8 bits: 10101000.
    • For 1: bin(1) gives '0b1'. We must pad this to 8 bits: 00000001.
    • For 10: bin(10) gives '0b1010'. We must pad this to 8 bits: 00001010.

    By combining these, you get the full 32-bit binary representation of the IP address 192.168.1.10:

    11000000.10101000.00000001.00001010

Convert a Binary IP Address back to Dotted Decimal

  1. Now we will perform the reverse operation. To convert a binary number to a decimal, we will use Python's int() function. This function can take two arguments: the first is the number as a string, and the second is the base of that number. Since we are converting from binary (base-2), we will always use 2 as the second argument.

    Let's try converting a single binary octet, 10101000, to decimal.

    int('10101000', 2)
    

    Python will execute the conversion and display the decimal result.

    168
    
  2. Now, let's convert the full 32-bit binary IP address from the previous step: 11000000.10101000.00000001.00001010. You will need to convert each 8-bit octet one by one.

    • Convert the first octet: int('11000000', 2) which results in 192.
    • Convert the second octet: int('10101000', 2) which results in 168.
    • Convert the third octet: int('00000001', 2) which results in 1.
    • Convert the fourth octet: int('00001010', 2) which results in 10.

    By combining these results with dots, you get the original dotted decimal IP address: 192.168.1.10. This confirms that your conversions in both directions are correct.

Translate a CIDR Subnet Mask to its Binary and Dotted Decimal Form

A subnet mask is a 32-bit number that distinguishes the network portion of an IP address from the host portion. CIDR (Classless Inter-Domain Routing) notation is a shorthand way to represent a subnet mask.

For example, a CIDR notation of /24 means that the first 24 bits of the 32-bit subnet mask are 1s, and the remaining bits are 0s.

  1. Let's determine the binary and dotted decimal representation for a /24 subnet mask.

    • Binary: A /24 mask has 24 consecutive 1s followed by 32 - 24 = 8 0s. When broken into octets, it looks like this: 11111111.11111111.11111111.00000000
  2. Now, let's convert this binary mask to its dotted decimal form. The first octet is all ones, 11111111.

    int('11111111', 2)
    

    The output will be 255. The last octet is all zeros, 00000000.

    int('00000000', 2)
    

    The output will be 0. Therefore, a /24 subnet mask is 255.255.255.0 in dotted decimal notation.

  3. Let's try a more complex example, like /26.

    • Binary: A /26 mask has 26 1s followed by 32 - 26 = 6 0s. 11111111.11111111.11111111.11000000
    • The first three octets are all 1s, which we know is 255. Let's convert the last octet, 11000000, to decimal.
    int('11000000', 2)
    

    The output will be 192. So, a /26 subnet mask is 255.255.255.192 in dotted decimal notation.

  4. Once you are finished with the conversions, you can leave the Python interpreter and return to the regular terminal prompt by typing exit() and pressing Enter.

    exit()
    

You have now mastered two-way conversion between dotted decimal and binary IP addresses, and CIDR subnet masks, a crucial skill for any network professional.

Identify Network and Host Portions for an IP Address

In this step, you will apply your knowledge of subnet masks to identify the network and host portions of a given IP address. The primary function of a subnet mask is to tell a computer which part of an IP address identifies the network and which part identifies the specific device (host) on that network.

This is achieved through a bitwise logical AND operation. The computer takes the IP address (in binary) and the subnet mask (in binary) and performs an AND operation on them. The result is the Network Address.

The rules for a bitwise AND are simple:

  • 1 AND 1 = 1
  • 1 AND 0 = 0
  • 0 AND 1 = 0
  • 0 AND 0 = 0

Essentially, the result is 1 only if both corresponding bits are 1.

Let's use a practical example to see this in action. We will determine the network address for the IP address 192.168.1.74 with a /26 subnet mask (255.255.255.192). Instead of doing this manually in the interpreter, we'll write a small Python script to perform the calculation.

  1. First, create a new Python script file named network_calc.py in your project directory using the nano editor.

    nano ~/project/network_calc.py
    
  2. Inside the nano editor, copy and paste the following Python code. This script defines the IP and mask, performs the AND operation on each octet, and prints the result.

    ## Define the IP address and subnet mask octets
    ip = [192, 168, 1, 74]
    mask = [255, 255, 255, 192]
    
    ## Calculate the network address using a bitwise AND
    network_addr = [ip[i] & mask[i] for i in range(4)]
    
    ## Format the output strings
    ip_str = ".".join(map(str, ip))
    network_str = ".".join(map(str, network_addr))
    
    print(f"IP Address:      {ip_str}")
    print(f"Subnet Mask:     /26 (255.255.255.192)")
    print(f"Network Address: {network_str}")
    
  3. Save the file and exit nano by pressing Ctrl+O, then Enter, and finally Ctrl+X.

  4. Now, run your script from the terminal.

    python3 ~/project/network_calc.py
    

    You will see the following output, which clearly shows the result of the AND operation:

    IP Address:      192.168.1.74
    Subnet Mask:     /26 (255.255.255.192)
    Network Address: 192.168.1.64
    

From this output, we can identify the different portions:

  • Network Portion: The /26 mask indicates that the first 26 bits are the network portion. The calculated Network Address (192.168.1.64) is the identifier for this specific network.
  • Host Portion: The remaining 32 - 26 = 6 bits are the host portion. These 6 bits identify the specific device (.74) within the 192.168.1.64 network.

You have successfully used a script to find the network address and can now conceptually distinguish between the network and host portions of an IP address.

Calculate Usable Hosts and Subnets for a Given CIDR

In this final step, you'll learn how to perform two essential subnetting calculations: determining the number of usable host IP addresses within a subnet and finding out how many subnets can be created from a larger network block. These calculations are fundamental for network planning and design.

Here are the key formulas:

  • Number of Usable Hosts: The formula is 2^n - 2, where n is the number of host bits (the 0s in the subnet mask). We subtract 2 because the first address in a subnet (where all host bits are 0) is reserved as the Network Address, and the last address (where all host bits are 1) is reserved as the Broadcast Address. Neither can be assigned to a device.
  • Number of Subnets: This is calculated when you divide a larger network (e.g., a /24) into smaller ones (e.g., /26). The formula is 2^m, where m is the number of bits you "borrowed" from the original host portion to create the new, more specific subnet mask.

Let's enhance our network_calc.py script to perform these calculations for us.

  1. First, open the network_calc.py file again using the nano editor.

    nano ~/project/network_calc.py
    
  2. Delete the existing content and replace it with the following Python code. This new version focuses on calculating host and subnet counts based on a given CIDR prefix.

    ## Define the CIDR prefix and the base network prefix
    cidr_prefix = 26
    base_prefix = 24 ## The original network we are subnetting from (e.g., a /24)
    
    ## --- Calculations ---
    
    ## 1. Calculate host bits
    host_bits = 32 - cidr_prefix
    
    ## 2. Calculate usable hosts
    ## The ** operator is for exponentiation (power of)
    if host_bits > 0:
        total_hosts = 2**host_bits
        usable_hosts = total_hosts - 2
    else:
        total_hosts = 1
        usable_hosts = 1 ## For /31 and /32, rules are different, but we simplify here
    
    ## 3. Calculate subnet bits borrowed
    subnet_bits = cidr_prefix - base_prefix
    
    ## 4. Calculate number of subnets
    if subnet_bits >= 0:
        num_subnets = 2**subnet_bits
    else:
        num_subnets = "N/A (Prefix is smaller than base)"
    
    
    ## --- Output ---
    print(f"--- Subnet Calculations for a /{cidr_prefix} Network ---")
    print(f"Host Bits: {host_bits}")
    print(f"Total Hosts per Subnet: 2^{host_bits} = {total_hosts}")
    print(f"Usable Hosts per Subnet: {total_hosts} - 2 = {usable_hosts}")
    print("") ## Adds a blank line for readability
    print(f"--- Subnetting from a /{base_prefix} Network ---")
    print(f"Subnet Bits Borrowed: {subnet_bits}")
    print(f"Number of Subnets Created: 2^{subnet_bits} = {num_subnets}")
    
  3. Save the file and exit nano by pressing Ctrl+O, Enter, and Ctrl+X.

  4. Run the updated script from your terminal.

    python3 ~/project/network_calc.py
    
  5. The script will now output the calculated values:

    --- Subnet Calculations for a /26 Network ---
    Host Bits: 6
    Total Hosts per Subnet: 2^6 = 64
    Usable Hosts per Subnet: 64 - 2 = 62
    
    --- Subnetting from a /24 Network ---
    Subnet Bits Borrowed: 2
    Number of Subnets Created: 2^2 = 4
    

This output clearly shows that for a /26 network, there are 6 host bits, which allows for 2^6 = 64 total addresses. After reserving the network and broadcast addresses, you are left with 62 usable hosts. It also shows that if you started with a /24 network, you borrowed 2 bits to create the /26 mask, which results in 2^2 = 4 possible subnets.

Summary

In this lab, you learned how to perform fundamental IP address and subnetting calculations directly within the Linux terminal. You utilized the Python interactive interpreter as a powerful tool to convert IP addresses from the human-readable dotted-decimal format to their 32-bit binary equivalent, and then back again. This included converting each octet individually and ensuring correct 8-bit padding. You also practiced translating CIDR subnet mask notation into its full binary and dotted-decimal forms.

Building upon these conversion skills, you applied them to essential network analysis tasks. You learned how to distinguish between the network and host portions of an IP address by using the subnet mask. Finally, you performed the necessary calculations to determine the number of usable host addresses and the total number of subnets available for a network based on its given CIDR prefix, solidifying your understanding of IP subnetting principles.