+1

IPv4 & Classless Inter Domain Routing - IPv4 và phương pháp CIDR

I. Từ Classful networking đến Classless networking

image.png

Trong lịch sử mạng máy tính, việc quản lý địa chỉ IP đã trải qua hai giai đoạn chính: Classful networking và Classless Inter Domain Routing (CIDR). Sự chuyển đổi từ Classful networking sang CIDR là một bước tiến quan trọng trong việc tối ưu hóa việc sử dụng địa chỉ IP và giải quyết vấn đề cạn kiệt địa chỉ IP.

1. Nhắc lại Classful networking

Classful networking, được giới thiệu vào những năm 1980, là phương pháp đầu tiên trong việc phân loại địa chỉ IP. Dựa trên cấu trúc của địa chỉ IP, hệ thống này chia địa chỉ IP thành 5 lớp (A, B, C, D, và E), mỗi lớp có một phạm vi địa chỉ cố định và một số lượng địa chỉ nhất định. Lớp A dành cho mạng lớn với số lượng host lớn; lớp B cho mạng vừa và nhỏ; và lớp C cho mạng nhỏ. Lớp D dành cho multicast, và lớp E dành cho mục đích nghiên cứu.

Mặc dù hệ thống classful giúp tổ chức và quản lý địa chỉ IP dễ dàng hơn, nhưng nó cũng dẫn đến sự lãng phí địa chỉ IP nghiêm trọng. Do phân chia cố định, nhiều tổ chức nhận được nhiều địa chỉ IP hơn mức họ cần, trong khi số lượng địa chỉ IP có sẵn lại có hạn.

2. Sự ra đời của CIDR

Để giải quyết vấn đề này, Classless Inter Domain Routing (CIDR) được giới thiệu vào đầu những năm 1990. CIDR loại bỏ sự phân chia cố định của địa chỉ IP và cho phép phân chia linh hoạt hơn dựa trên nhu cầu thực tế của tổ chức.

CIDR mang lại nhiều lợi ích đáng kể so với hệ thống classful trước đó. Nó giúp giảm đáng kể sự lãng phí địa chỉ IP, tăng khả năng mở rộng và linh hoạt trong việc quản lý địa chỉ. CIDR cũng cải thiện hiệu quả của bảng định tuyến bằng cách giảm số lượng mục nhập cần thiết thông qua kỹ thuật "supernetting", giúp đơn giản hóa quản lý mạng và tăng hiệu suất định tuyến.

II. Cách hoạt động của IPv4 theo phương pháp CIDR

1. Định dạng

CIDR là một phương pháp cho phép phân chia linh hoạt các địa chỉ IP thành các mạng con có kích thước khác nhau, thay vì phải tuân theo các lớp cố định A, B, hoặc C như trước đây. CIDR sử dụng ký hiệu "slash" (ví dụ, /24/24, /16/16), hay còn gọi là subnet mask (mặt nạ mạng/mặt nạ mạng phụ) để chỉ định số bit được sử dụng cho phần mạng của địa chỉ. Phần còn lại của các bit sau dấu slash được sử dụng cho các địa chỉ host trong mạng đó.

Ví dụ, địa chỉ CIDR 192.168.1.0/24192.168.1.0/24 có phần subnet mask /24/24 chỉ ra rằng 2424 bit đầu tiên là phần mạng (network ID) và 3224=832-24=8 bit cuối cùng là phần dành cho các địa chỉ host (host ID).

2. Một số công thức trong tính toán địa chỉ IP theo CIDR

Với subnet mask là \n, chúng ta có các công thức sau:

Số lượng mạng con

Number of subnets=2n– No. of bits in default mask\text{Number of subnets}=2^{n – \text{ No. of bits in default mask}}

Trong đó, giá trị "No. of bits in default mask" chỉ số lượng bit mặc định trong mask mặc định tương ứng với từng lớp, quy ước như sau:

  • Lớp A: 88
  • Lớp B: 1616
  • Lớp C: 2424

Địa chỉ mạng con / Địa chỉ mạng

Địa chỉ mạng con/Địa chỉ mạng (Subnet address/Network address) được tính bằng kết quả phép toán AND của IP được cho với subnet mask.

Địa chỉ quảng bá

Để tính địa chỉ quảng bá (Broadcast address), chúng ta đặt tất cả các bit trong host ID bằng 11, phần network ID lấy từ địa chỉ IP đã cho.

Số lượng host của mỗi mạng con

Number of hosts per subnet=232n2\text{Number of hosts per subnet} = 2^{32 – n} – 2

Địa chỉ host đầu tiên

First Host Address=Subnet address+1\text{First Host Address} = \text{Subnet address} + 1

Địa chỉ host cuối cùng

Last Host Address=Subnet address+Number of Hosts\text{Last Host Address} = \text{Subnet address} + \text{Number of Hosts}

Ví dụ

image.png

Để hiểu rõ các công thức trên, chúng ta xét ví dụ với địa chỉ IP ở dạng CIDR là 203.178.142.130/27203.178.142.130/27.

Subnet mask có giá trị /27/27. Trước hết đổi sang hệ nhị phân có định dạng:

11001011.10110010.10001110.1000001011001011.10110010.10001110.10000010

Địa chỉ này thuộc lớp C nên:

  • Số lượng mạng con: 22724=82^{27-24}=8
  • Địa chỉ mạng con/Địa chỉ mạng: 203.178.142.128203.178.142.128 (xem hình ảnh)
  • Địa chỉ quảng bá: 11001011.10110010.10001110.10011111=203.178.142.15911001011.10110010.10001110.10011111 = 203.178.142.159
  • Số lượng host mỗi mạng con: 232272=302^{32 – 27} – 2 = 30
  • Địa chỉ host đầu tiên: 203.178.142.128+1=203.178.142.129203.178.142.128 + 1 = 203.178.142.129
  • Địa chỉ host cuối cùng: 203.178.142.128+30=203.178.142.158203.178.142.128 + 30 = 203.178.142.158

Một bộ công thức khác

Ngoài ra bạn đọc có thể tính theo bộ công thức dưới đây có thể rút ngắn thời gian tính toán:

Subnet Number of Hosts = 2 ^ (32 - subnet mask)
Network ID: floor(Host Address/Subnet Number of Hosts) * Subnet Number of Hosts
Broadcast ID: (Network ID + (Subnet Number of Hosts-1))
First Host: Network ID + 1
Last Host: Broadcast ID - 1

Với công thức trên, ta có:

  • Số địa chỉ mạng con của host: 23227=322^{32-27}=32
  • Network ID: floor(130/32)32=128floor(130/32) * 32 = 128 nên địa chỉ mạng con là 203.178.142.128203.178.142.128
  • Broadcast ID: 128+321=159128+32-1=159 nên địa chỉ quảng bá là 203.178.142.159203.178.142.159
  • First Host: 128+1=129128+1=129 nên địa chỉ host đầu tiên là 203.178.142.129203.178.142.129
  • Last Host: 1591=158159-1=158 nên địa chỉ host cuối cùng là 203.178.142.158203.178.142.158

III. Luyện tập

Tính toán

Đề bài: Từ các công thức trong phần II, hãy tính địa chỉ mạng, địa chỉ quảng bá, địa chỉ host đầu tiên, địa chỉ host cuối cùng với mỗi phần sau:

a) 192.168.1.65/28192.168.1.65/28 b) 192.168.20.166/25192.168.20.166/25 c) 192.168.30.14/29192.168.30.14/29 d) 192.168.20.86/30192.168.20.86/30

Lập trình

Viết chương trình thực hiện yêu cầu trong bài tập trên.

Gợi ý lời giải

Hướng giải quyết 1: Lập trình theo công thức

Chương trình Python minh họa:

def ip_to_binary(ip_address):
    # Chuyển địa chỉ IP thành chuỗi nhị phân 32-bit
    binary_ip = ''.join(format(int(x), '08b') for x in ip_address.split('.'))
    return binary_ip

def calculate_network_info(ip, subnet_mask):
    # Chuyển địa chỉ IP và subnet mask sang nhị phân
    binary_ip = ip_to_binary(ip)
    binary_subnet_mask = '1' * int(subnet_mask) + '0' * (32 - int(subnet_mask))

    # Tìm địa chỉ mạng và broadcast ID
    network_id = binary_ip[:int(subnet_mask)] + '0' * (32 - int(subnet_mask))
    broadcast_id = binary_ip[:int(subnet_mask)] + '1' * (32 - int(subnet_mask))

    # Tìm địa chỉ host đầu tiên và cuối cùng
    first_host = network_id[:-1] + '1'
    last_host = broadcast_id[:-1] + '0'

    # Chuyển đổi các địa chỉ từ nhị phân sang thập phân
    network_address = '.'.join(str(int(network_id[i:i+8], 2)) for i in range(0, 32, 8))
    broadcast_address = '.'.join(str(int(broadcast_id[i:i+8], 2)) for i in range(0, 32, 8))
    first_host_address = '.'.join(str(int(first_host[i:i+8], 2)) for i in range(0, 32, 8))
    last_host_address = '.'.join(str(int(last_host[i:i+8], 2)) for i in range(0, 32, 8))

    return network_address, broadcast_address, first_host_address, last_host_address

# a) 192.168.1.65/28
network_info_a = calculate_network_info('192.168.1.65', '28')
print("a) Network Address:", network_info_a[0])
print("   Broadcast Address:", network_info_a[1])
print("   First Host Address:", network_info_a[2])
print("   Last Host Address:", network_info_a[3])

# b) 192.168.20.166/25
network_info_b = calculate_network_info('192.168.20.166', '25')
print("\nb) Network Address:", network_info_b[0])
print("   Broadcast Address:", network_info_b[1])
print("   First Host Address:", network_info_b[2])
print("   Last Host Address:", network_info_b[3])

# c) 192.168.30.14/29
network_info_c = calculate_network_info('192.168.30.14', '29')
print("\nc) Network Address:", network_info_c[0])
print("   Broadcast Address:", network_info_c[1])
print("   First Host Address:", network_info_c[2])
print("   Last Host Address:", network_info_c[3])

# d) 192.168.20.86/30
network_info_d = calculate_network_info('192.168.20.86', '30')
print("\nd) Network Address:", network_info_d[0])
print("   Broadcast Address:", network_info_d[1])
print("   First Host Address:", network_info_d[2])
print("   Last Host Address:", network_info_d[3])

Hướng giải quyết 2: Sử dụng thư viện hỗ trợ

Chương trình Python minh họa:

import ipaddress

def calculate_network_info(ip, subnet_mask):
    network = ipaddress.ip_interface(ip + '/' + subnet_mask)
    network_address = network.network.network_address
    broadcast_address = network.network.broadcast_address
    first_host = network.network.network_address + 1
    last_host = network.network.broadcast_address - 1
    return network_address, broadcast_address, first_host, last_host

# a) 192.168.1.65/28
network_info_a = calculate_network_info('192.168.1.65', '28')
print("a) Network Address:", network_info_a[0])
print("   Broadcast Address:", network_info_a[1])
print("   First Host Address:", network_info_a[2])
print("   Last Host Address:", network_info_a[3])

# b) 192.168.20.166/25
network_info_b = calculate_network_info('192.168.20.166', '25')
print("\nb) Network Address:", network_info_b[0])
print("   Broadcast Address:", network_info_b[1])
print("   First Host Address:", network_info_b[2])
print("   Last Host Address:", network_info_b[3])

# c) 192.168.30.14/29
network_info_c = calculate_network_info('192.168.30.14', '29')
print("\nc) Network Address:", network_info_c[0])
print("   Broadcast Address:", network_info_c[1])
print("   First Host Address:", network_info_c[2])
print("   Last Host Address:", network_info_c[3])

# d) 192.168.20.86/30
network_info_d = calculate_network_info('192.168.20.86', '30')
print("\nd) Network Address:", network_info_d[0])
print("   Broadcast Address:", network_info_d[1])
print("   First Host Address:", network_info_d[2])
print("   Last Host Address:", network_info_d[3])

Tài liệu tham khảo


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí