IPv4 Addressing, Subnetting, CIDR — ঠিকানার গণিত
IPv4 Addressing and CIDR
ইন্টারনেটের address-book-এর গণিত — binary fluency থেকে classful-যুগের অপচয়, CIDR-এর বিপ্লব, subnet-splitting-এর হাতে-কলমে walkthrough, আর aggregation-এ যে সঞ্চয়ে আজকের routing table টিকে আছে।
আগে এটা বুঝি
ip-datagram লেসনে আমরা IP header-এর ভেতরে ঢুকেছিলাম — TTL, protocol,
checksum সব দেখেছি। কিন্তু ওই header-এর দুটো field আমরা প্রায় বিনা
অনুসন্ধানে পার করে এসেছি: source address আর destination
address। 192.168.1.20 → 93.184.216.34 — চার-চারটা সংখ্যা, মাঝে
দাগ। এত সরল দেখায়, তাই না?
আজ সেই সরলতার ভেতরে হাত দিয়ে দেখব একটা ৩০ বছরের গল্প — যে ঠিকানা-ব্যবস্থা শুরুতে এতটাই উদারভাবে address বিলিয়েছিল যে ৩০ বছরের মাথায় ইন্টারনেট ঠিকানা ফুরিয়ে যাওয়ার পথে এগোচ্ছিল, আর একটা গণিতের কৌশল — CIDR — কীভাবে সেই বিপর্যয় থেকে পুরো ইন্টারনেটকে টেনে তুলল।
আজকের লেসনের প্রতিশ্রুতি:
- Dotted decimal আর binary-র মধ্যে দ্রুত দুলুনি — কোনো calculator ছাড়াই
- Network address, broadcast, host-range: তিনটাই হাতে বের করা
- একটা subnet-কে ছোট ছোট subnet-এ ভাঙার bit-level walkthrough
- Private address, loopback, link-local — কোনটা কোথায় বৈধ
- আর aggregation-এর সেই জাদু, যা ছাড়া আজকের routing table- গুলো গিগাবাইট আকারে ফুলে উঠত
শেষ পর্যন্ত আপনি নিজের হাতে একটা subnet calculator লিখবেন — যার core গণিত আপনি এতক্ষণে মুখস্থ স্তরে বুঝে ফেলবেন। চলুন শুরু করি সবচেয়ে ছোট ইউনিট থেকে: একটা মাত্র bit।
মূল ধারণা
ঠিকানাটা আসলে ৩২টা বাতি
IPv4 address মানে মূলত ৩২টা bit — চালু-বন্ধের ৩২টা switch।
Machine দেখে শুধু এই ৩২টা bit; dotted decimal (192.168.1.20)
আমাদের মানুষের সুবিধার জন্য বানানো পোশাক। ঐতিহ্য অনুযায়ী ৩২টা
bit-কে চারটা ভাগে ভাগ করা হয় — প্রতি ভাগে ৮টা bit, এক-একটা
byte, আর প্রতিটা byte-কে 0–255-এর decimal
সংখ্যায় লেখা হয়।
৮টা bit-এর প্রতিটার একটা নির্দিষ্ট ওজন আছে — বাঁ দিক থেকে দ্বিগুণ হতে হতে যায়:
| Bit position | ১ম | ২য় | ৩য় | ৪র্থ | ৫ম | ৬ষ্ঠ | ৭ম | ৮ম | |---|---|---|---|---|---|---|---| | Weight | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
এই আটটা weight মুখস্থ হলেই রূপান্তর মনে-মনে করা যায়। উদাহরণ:
192 = 128 + 64 = 11000000; 168 = 128 + 32 + 8 = 10101000;
20 = 16 + 4 = 00010100। পুরো ঠিকানা:
192 .168 .1 .20
11000000 10101000 00000001 00010100উল্টো দিকেও একই নিয়ম: 10101000 দেখলে সরাসরি পড়ুন 128+32+8=168।
Netmask — কোন bit কার
একটা IPv4 ঠিকানার ভেতরে দুইটা অংশ লুকানো আছে: network অংশ (কোন পাড়ায় থাকেন) আর host অংশ (পাড়ার কোন বাড়ি)। এই দুই অংশের সীমারেখা টানে সেই পরিচিত সংখ্যা — netmask:
IP 192.168.1.20 11000000 10101000 00000001 00010100
Netmask 255.255.255.0 11111111 11111111 11111111 00000000
───────────── ────────────────┬─────────────────
network part host partMask-এ যেখানে bit 1, ঠিকানার সেই bit network-এর; mask-এর 0-এর
জায়গায় host। এই নির্দিষ্ট mask-এর আরেকটা নাম — /24: বাঁ দিকের
২৪টা bit network-অংশ। Prefix লেখা আর netmask লেখা একই কথা:
| Prefix | Netmask (decimal) | Mask-এর শেষ octet (binary) |
|---|---|---|
| /8 | 255.0.0.0 | 00000000 |
| /16 | 255.255.0.0 | 00000000 |
| /20 | 255.255.240.0 | 11110000 |
| /24 | 255.255.255.0 | 00000000 |
| /25 | 255.255.255.128 | 10000000 |
| /26 | 255.255.255.192 | 11000000 |
| /30 | 255.255.255.252 | 11111100 |
তিনটা গুরুত্বপূর্ণ ঠিকানা প্রতিটা subnet-এর
একটা ip/prefix-কে তিনটা প্রশ্ন করা যায়, আর উত্তর তিনটাই
AND-operation দিয়ে আসে:
- Network address — এই subnet-এর নামফলক:
ip AND mask - Broadcast address — subnet-এর সবাইকে একসাথে ডাকার ঠিকানা: host-bit সবগুলো 1
- Usable host range — মাঝের যত ঠিকানা সত্যিকারের device নিতে পারে: network+1 থেকে broadcast−1
Host-bit-এর সংখ্যা 32 − prefix হলে মোট host-bit-pattern
2^(32−prefix)-টা, যার প্রথমটা network, শেষটা broadcast — তাই
ব্যবহারযোগ্য:
Concrete উদাহরণ — 192.168.1.20/24:
Network: 192.168.1.0 (ip AND mask → host-bits সব 0)
Broadcast: 192.168.1.255 (host-bits সব 1)
First host: 192.168.1.1
Last host: 192.168.1.254
Usable: 2^8 − 2 = 254Classful যুগ — উদারতার দাম
1981-এর মূল ডিজাইনে (RFC 791) ঠিকানার প্রথম কয়েকটা bit-ই বলে দিত সীমারেখা কোথায় — তিনটা fixed শ্রেণি:
| শ্রেণি | প্রথম bits | Range | Prefix | Networks | Hosts/network |
|---|---|---|---|---|---|
| A | 0… | 0–127 | /8 | 126 | 16,777,214 |
| B | 10… | 128–191 | /16 | 16,384 | 65,534 |
| C | 110… | 192–223 | /24 | 2,097,152 | 254 |
সমস্যাটা কল্পনা করুন: আপনার office-এ ৩০০টা computer। Class C দেয় ২৫৪টা — কম! তাহলে নিতে হয় Class B — ৬৫,৫৩৪টা ঠিকানার একটা block, যার ব্যবহার হচ্ছে ৩০০। ৯৯.৫% নষ্ট। আর ছোট organization- গুলো যদি কয়েকশো Class C নেয়, global router-দের টেবিলে তা হাজার হাজার আলাদা লাইন হয়ে জমে — 1990-এর গোড়ায় routing table-এর বৃদ্ধি এমন গতিতে উঠছিল যে projection বলছিল কয়েক বছরেই router-দের memory শেষ।
CIDR — সীমারেখাকে মুক্তি দিয়ে দেওয়া
1993-এ সমাধান এলো (RFC 1519, পরে RFC 4632): Classless Inter-Domain
Routing। ভাবটা এতটাই সরল যে প্রথমবার পড়লে হতাশ লাগে — “যেখানে
দরকার, ঠিক তত bit-ই network-part ধরা যাক”। প্রথম bits আর তিনটা
শ্রেণির নিয়ম বাতিল; এখন প্রতিটা route-এর সাথেই explicit prefix
(/n) লেখা লাগে। ফলাফল:
- ৩০০-host organization নেয় /23 (৫১০ host) — waste মাত্র ২১০
- ISP তার গ্রাহকদের পাশাপাশি ঠিকানা দিলে সেগুলো একটা prefix-এ bundle করে announce করতে পারে — এটাই route aggregation
- শ্রেণি-নির্ভর hardware/software-এর যুগ শেষ — সবখানে এখন longest-prefix-match engine (routing লেসনে বিস্তারিত)
CIDR ঠিকানা-অপচয় কমিয়েছে আর routing table ছোট রেখেছে — দুইটা সংকট এক ধাক্কায়। এই দ্বিতীয়টার হিসাবটা under-the-hood অংশে সংখ্যা দিয়ে দেখব।
বিশেষ ঠিকানাগুলো চেনা
সব ৩২-bit সংখ্যাই সাধারণ host নয়। এই তালিকাটা চোখে বসানো মূল্যবান —
ip addr বা router config-এর সামনে বসলেই কাজে লাগবে:
| Range | নাম | কাজ |
|---|---|---|
| 0.0.0.0/8 | this-network | 0.0.0.0 = unspecified/default route |
| 10.0.0.0/8 | RFC1918 private | ভেতরের network, ১.৬ কোটি ঠিকানা |
| 127.0.0.0/8 | loopback | পুরো /8-ই নিজের দিকে ঘুরে আসে |
| 169.254.0.0/16 | link-local | DHCP ব্যর্থ হলে self-assigned |
| 172.16.0.0/12 | RFC1918 private | 172.16–172.31, ~১০ লাখ ঠিকানা |
| 192.168.0.0/16 | RFC1918 private | বাড়ির router-এর প্রিয় |
| 100.64.0.0/10 | CGNAT shared | carrier-grade NAT (nat লেসনে) |
| 224.0.0.0/4 | multicast | এক-থেকে-গোষ্ঠী পাঠানো |
| 240.0.0.0/4 | reserved | experimental/ব্যবহার-নিষিদ্ধ |
| 255.255.255.255 | limited broadcast | এই link-এর সবাই |
RFC1918-এর তিনটা range-ই ইচ্ছেমতো যেকোনো ব্যক্তিগত network-এ
ব্যবহারযোগ্য — কারণ এগুলো ইন্টারনেটে route করা হয় না। আপনার
বাড়ির 192.168.1.20 আর প্রতিবেশীর 192.168.1.20 একই ঠিকানা — দোষ
কিছু নেই, কারণ কেউই সরাসরি ইন্টারনেটে পৌঁছায় না। কীভাবে তাহলে
বাইরে যায়? NAT — আজকের শেষ অংশের preview, পূর্ণ লেসন কয়েক ধাপ
পরে।
ভেতরে কী ঘটছে
AND-operation — হার্ডওয়্যার আসলে কী করে
Textbook বলে “network address = ip AND mask”। এই AND-টা ভেতরে কী করে, bit-level-এ দেখুন:
IP 172.16.37.99 10101100 00010000 00100101 01100011
Mask /21 11111111 11111111 11111000 00000000
AND ─────────── 10101100 00010000 00100000 00000000
= 172.16.32.0প্রতিটা column-এ দুটো bit-ই 1 হলে ফল 1, নইলে 0। ফলাফলে লক্ষ্য করুন: প্রথম ২১ bit ঠিকানার হুবহু copy, শেষ ১১ bit সব শূন্য। AND আসলে mask-এর 1-গুলো দিয়ে ঠিকানার অংশ কেটে নেওয়া, বাকিটা মুছে দেওয়া। Broadcast তার দর্পণ-প্রতিবিম্ব: host-bit-গুলো OR দিয়ে সব 1 করা — 172.16.39.255।
এখান থেকেই একটা shortcut: prefix n-এর host-part যদি তৃতীয়
octet-এর ভেতরে থাকে (যেমন /21), network-এর ওই octet = own_octet AND mask_octet, আর broadcast = network + (2^host_bits − 1)। হিসাবটা
octet-এ সীমাবদ্ধ রাখলে মনে-মনেই চলে।
Subnet splitting — /24 ভাঙুন দুই /25
Borrowing-এর মূল ভাব: host-part-এর প্রথম bit-টা কেড়ে নিয়ে network-part-এ যোগ করা। /24-এ host-part ছিল শেষ octet-এর ৮ bit; এক bit কেড়ে নিলে /25 — এবং সেই bit-এর মান (0 বা 1) বলে দেয় কোন অর্ধেক:
মূল: 192.168.1.0/24 host-part: xxxxxxxx (৮ bit)
ভাঙা: 192.168.1.0/25 0xxxxxxx → 0–127
└─ borrowed bit = 0
192.168.1.128/25 1xxxxxxx → 128–255
└─ borrowed bit = 1দুই অর্ধেকের হিসাব সাজানো করে দেখি:
| Subnet A (/25) | Subnet B (/25) | |
|---|---|---|
| Network | 192.168.1.0 | 192.168.1.128 |
| First host | 192.168.1.1 | 192.168.1.129 |
| Last host | 192.168.1.126 | 192.168.1.254 |
| Broadcast | 192.168.1.127 | 192.168.1.255 |
| Usable | 2^7−2 = 126 | 126 |
একই পদ্ধতি চালিয়ে যেকোনো সংখ্যক ভাগ সমান করে করা যায়: /24 → চারটা /26 (প্রতিটায় 62 host) → আটটা /27 (৩০ করে)… প্রতি ধাপে এক bit borrow, ভাগ দ্বিগুণ, মাপ অর্ধেক।
VLSM — ভিন্ন মাপের ভাই
সমান ভাগ বাস্তবে বিরল — sales-এ 120 জন, engineering-এ 55, guest Wi-Fi- এ 18। Variable Length Subnet Mask (VLSM) নিয়ম: সবচেয়ে বড় চাহিদা আগে, সবচেয়ে ছোট block-গুলো পরে, প্রতিটা নতুন block আগেরটার শেষ-ঠিকানার পরে তার নিজের alignment-এ বসে। 192.168.50.0/24 থেকে:
Sales 120 hosts → /25 (126) 192.168.50.0/25 .0–.127
Engineering 55 hosts → /26 (62) 192.168.50.128/26 .128–.191
Guest 18 hosts → /27 (30) 192.168.50.192/27 .192–.223
সঞ্চয় 192.168.50.224/27 .224–.255খেয়াল করুন ক্রমটা কেন জরুরি: ছোট block আগে বসালে বড় block-এর alignment আর জায়গা নাও মিলতে পারে। বড়-আগে হলে বাকিটা স্বাভাবিকেই fit হয়। এই ধারাবাহিক packing-ই cloud-provider-দের VPC design-এর দৈনন্দিন কাজ।
Aggregation — টেবিল ছোট করার গণিত
Splitting-এর উল্টো দিক aggregation: পাশাপাশি, aligned কয়েকটা prefix মিলে একটা ছোট-prefix-এ। একটা ISP-র গ্রাহক-ব্লক ভাবুন — 203.0.112.0/24 থেকে 203.0.119.0/24, মোট আটটা /24:
আলাদা করে announce করলে: ৮টা route-entry (৮ × ২৫৬ = ২,০৪৮ ঠিকানা)
Aggregate করে /21 দিলে: ১টা route-entry (2^11 = ২,০৪৮ ঠিকানা)একটা /21 = আটটা /24, ঠিকানা হিসেবে হুবহু সমান — কিন্তু global routing table-এ জায়গা নেয় ৮-এর বদলে ১ লাইন। আজকের internet- ব্যাপী table-এ প্রায় দশ লাখ route আছে CIDR-aggregation সহ; না থাকলে 1990-এর projection অনুযায়ী তা কোটি লাইন ছাড়িয়ে যেত — কোনো router তা ধরতেই পারত না। CIDR শুধু ঠিকানা বাঁচায়নি, ইন্টারনেটের নেভিগেশন-ব্যবস্থাই চালু রেখেছে।
উদাহরণ
একটা সম্পূর্ণ কাজ — শুরু থেকে শেষ
চলুন একটা realistic প্রশ্ন হাতে সমাধান করি: 172.16.37.99/21 — এর network, broadcast, host-range কী?
ধাপ ১ — সীমারেখা কোথায়: /21 = ২৪-এর আগে শেষ হয়, তাই সীমারেখা তৃতীয় octet-এর ভেতরে। প্রথম দুই octet (172.16) পুরোটাই network-part; শেষ octet (99) পুরোটাই host-part। লড়াই শুধু তৃতীয় octet-এ: 37।
ধাপ ২ — mask-এর তৃতীয় octet: /21 মানে তৃতীয় octet-এ ৫টা bit
network (8+8+5=21): mask-octet 11111000 = 248।
ধাপ ৩ — 37-কে AND করা: 37 = 00100101; 00100101 AND 11111000
= 00100000 = 32। তাহলে network = 172.16.32.0/21।
ধাপ ৪ — block-এর মাপ: host-bits = 32−21 = 11 → block size
2^11 = 2048। তৃতীয় octet-এ এটা মানে ৮-এর ধাপে ৮টা মান (2048 =
৮×256): 32 থেকে 39।
ধাপ ৫ — সব উত্তর:
Network: 172.16.32.0
Broadcast: 172.16.39.255 (তৃতীয় octet 32+7=39, চতুর্থ 255)
First host: 172.16.32.1
Last host: 172.16.39.254
Usable: 2^11 − 2 = 204637-এর ভেতরের 00100-অংশ network-এ চলে গেছে, শেষ তিন bit (101)
host-part — তাই 99-ও, 32-ও একই পাড়ার বাসিন্দা।
দ্বিতীয় কাজ — এক /24-এর পরিকল্পনা
একটা startup-এর দাবি: HQ-তে 100 host, branch-এ 45, lab-এ 12, আর router-to-router link-এ 2। বরাদ্দ: 203.0.113.0/24।
HQ 100 দরকার → /25 দেয় 126 ✓ 203.0.113.0/25 .0–.127
Branch 45 দরকার → /26 দেয় 62 ✓ 203.0.113.128/26 .128–.191
Lab 12 দরকার → /28 দেয় 14 ✓ 203.0.113.192/28 .192–.207
P2P 2 দরকার → /30 দেয় 2 ✓ 203.0.113.208/30 .208–.211
সঞ্চয় .212–.255 (৪৪ ঠিকানা ভবিষ্যতের জন্য)প্রতিটা ধাপে দুইটা সিদ্ধান্ত: (১) কোন prefix চাহিদা মেটায় — ছোটতম
2^(32−n) − 2 ≥ দরকার; (২) সেই মাপের alignment-এ আগের block-এর
পরে বসা। Lab-এর 12-এর জন্য /27 (30) না নিয়ে /28 নেওয়াটাই VLSM-
এর সার-কথা — ঠিকানা একটু একটু করে বাঁচানো, কারণ একদিন এই
সঞ্চয়ই নতুন subnet-এর জন্ম দেয়।
ছবিতে
ঠিকানার অঙ্গসংস্থান
- Network part (/n পর্যন্ত)routing table-এ এই অংশই লেখা — পাড়া চেনার ঠিকানা
- Subnet part (borrow করা bits)host-part থেকে কেড়া bit — ভেতরের ভাগ চেনায়
- Host part (বাকি bits)subnet-এর ভেতরের বাড়ি-নম্বর; সব 0 = নামফলক, সব 1 = broadcast
Splitting-এর ছবি
শেষ octet-এর bit: b b b b b b b b
↑
borrowed bit (/25-এ)
Subnet A 0 0000000 … 0 1111111 192.168.1.0/25
└── host-part ৭ bit ──┘ network .0 broadcast .127
Subnet B 1 0000000 … 1 1111111 192.168.1.128/25
network .128 broadcast .255Classful বনাম CIDR — এক নজরে
Classful: 0… → অনিবার্য /8 (১.৬ কোটি host!)
10… → অনিবার্য /16
110… → অনিবার্য /24
CIDR: যেকোনো ঠিকানা + স্বাধীন /n
203.0.113.0/24 ছোট office
203.0.112.0/21 ISP-র আট-ব্লক bundle
10.34.77.9/13 বড় enterprise-এর ভেতরের regionনিজে চালিয়ে দেখুন
নিজের machine-এর ঠিকানা decode করুন, তারপর হাতে-হাতে drill
ধাপ ১ — নিজের ঠিকানা আনুন:
# Linux
ip -4 addr show
# macOS
ifconfig en0 | grep inetযেমন একটা output: inet 192.168.1.20/24 ... brd 192.168.1.255।
এখন কাগজে হিসাব করুন: network address, first/last host,
usable count। তারপর kernel-এর উত্তরের সাথে মেলান:
# Linux — একই তথ্য route-ভাষায়
ip route show | grep 192.168.1
# macOS
netstat -rn | grep 192.168.1192.168.1.0/24-এর link-route আর brd-value দেখবেন — আপনার
হিসাবের হুবহু প্রতিধ্বনি।
ধাপ ২ — hand-drill set (উত্তরসহ):
প্রশ্ন ১: 168-এর binary? → 128+32+8 → 10101000
প্রশ্ন ২: 10.34.77.9/13 — network, broadcast, usable?
→ তৃতীয় octet mask 248; 77 AND 248 = 72 → network 10.32.0.0,
broadcast 10.39.255.255, usable 2^19−2 = 524,286
প্রশ্ন ৩: /26-এ usable কত, আর এক /24 কয়টা /26 দেয়? → 62; ৪টা
(.0, .64, .128, .192 — প্রতিটা 64-এর multiple)
প্রশ্ন ৪: 192.168.0.0/22-এ 192.168.2.255 কি বৈধ host?
→ হ্যাঁ। /22 বিস্তার .0.0–.3.255; broadcast .3.255; .2.255
সাধারণ host। (/24-মনস্কতার ফাঁদ!)
প্রশ্ন ৫: 203.0.112.0/24 + 203.0.113.0/24 এক /23-এ গুটানো যায়?
→ যায় — প্রথমটার তৃতীয় octet 112 (জোড়, 2-এর multiple)। কিন্তু
203.0.113.0 + 203.0.114.0? → যায় না — 113 বিজোড়, alignment
ভাঙে; দুটোকে /23-এ লিখলে তা আসলে 112–115-এর /22-এর অর্ধেক নয়।
প্রশ্ন ৬: 100.64.13.5 কোন জাতের ঠিকানা? → CGNAT shared-space
(100.64/10) — ব্যক্তিগত নয়, public-ও নয়।
ধাপ ৩ — python-এর ipaddress-কে referee বানান:
আপনার হাতের উত্তর cross-check করুন — মানসিক গণিতের সত্যতা যাচাইয়ে stdlib ব্যবহার করুন (নিজের হিসাবের বদলে নয়):
import ipaddress
drills = [
('192.168.1.20', 24),
('172.16.37.99', 21),
('10.34.77.9', 13),
('203.0.113.199', 25),
]
for ip_text, prefix in drills:
net = ipaddress.ip_network(f'{ip_text}/{prefix}', strict=False)
hosts = sum(1 for _ in net.hosts())
print(f'{str(net):22} broadcast {str(net.broadcast_address):16} '
f'usable {hosts}')প্রতিটা লাইন আপনার ধাপ-২ হিসাবের সাথে মিললে আপনি production-grade subnetting fluency পেয়ে গেছেন। না মিললে — ভালো! ভুলটা এখনই ধরা পড়ল, মিটিং-রুমের whiteboard-এ না।
kernel আপনার interface-এ যে network আর broadcast লেখে, সেটা আপনি কাগজে-কলমে AND-operation দিয়ে যা বের করবেন হুবহু তা-ই — subnetting-এর গণিত theory নয়, আপনার machine এই মুহূর্তে সেটাই চালাচ্ছে।
নিজে বানান
subnetcalc — manual bit-math core, ipaddress শুধু বিচারক
- dotted-decimal ↔ 32-bit integer নিজের হাতে shift/OR দিয়ে লিখুন
- mask বানান শুধু shift আর AND-এ — library নিষেধ
- network = ip AND mask, broadcast = network OR inverted-mask
- first/last host আর usable count বের করে RFC1918/private শনাক্ত করুন
- --split অপশনে n-ভাগ সমান ভাঙা দেখান
- শেষে ipaddress module-কে oracle বানিয়ে নিজের ফল যাচাই করুন
লক্ষ্য: এই লেসনের সব সূত্র একটা CLI-তে জীবন্ত করা — কিন্তু core
গণিতে ipaddress নিষিদ্ধ; সে শুধু শেষে বিচারকের চেয়ারে বসবে।
#!/usr/bin/env python3
import argparse
WEIGHTS = (128, 64, 32, 16, 8, 4, 2, 1)
def ip_to_int(text):
parts = text.split('.')
if len(parts) != 4:
raise SystemExit(f'4টা octet লাগবে: {text}')
value = 0
for p in parts:
n = int(p)
if n > 255 or n < 0:
raise SystemExit(f'octet সীমার বাইরে: {n}')
value = (value << 8) | n # আগেরটা ৮ ঘর উঁচুতে, নতুনটা নিচে
return value
def int_to_ip(value):
return '.'.join(str((value >> s) & 0xFF) for s in (24, 16, 8, 0))
def mask_of(prefix):
if prefix < 0 or prefix > 32:
raise SystemExit('prefix 0..32 হতে হবে')
return (0xFFFFFFFF << (32 - prefix)) & 0xFFFFFFFF if prefix else 0
def analyze(ip_int, prefix):
mask = mask_of(prefix)
network = ip_int & mask # host-bits ধুয়ে ফেলা
broadcast = network | (mask ^ 0xFFFFFFFF) # host-bits সব 1
hb = 32 - prefix
usable = (1 << hb) - 2 if hb >= 2 else 0
first = int_to_ip(network + 1) if hb >= 2 else '-'
last = int_to_ip(broadcast - 1) if hb >= 2 else '-'
o1, _, rest = int_to_ip(network).partition('.')
o2, _, _ = rest.partition('.')
private = (o1 == '10') or (o1 == '192' and rest.startswith('168')) or \
(o1 == '172' and 16 <= int(o2) <= 31)
return network, broadcast, first, last, usable, private
def report(ip_text, prefix):
ip_int = ip_to_int(ip_text)
network, broadcast, first, last, usable, private = analyze(ip_int, prefix)
tag = ', RFC1918-private' if private else ''
print(f'{ip_text}/{prefix}{tag}')
print(f' network {int_to_ip(network)}')
print(f' first-last {first} … {last}')
print(f' broadcast {int_to_ip(broadcast)}')
print(f' usable {usable}')
def split(ip_text, prefix, parts):
ip_int = ip_to_int(ip_text)
network, *_ = analyze(ip_int, prefix)
bits = parts.bit_length() - 1
if 1 << bits != parts or prefix + bits > 32:
raise SystemExit('parts হতে হবে 2-এর power, আর prefix বাড়ানো যায় কি না দেখুন')
size = 1 << (32 - prefix - bits)
for i in range(parts):
report(int_to_ip(network + i * size), prefix + bits)
parser = argparse.ArgumentParser()
parser.add_argument('cidr')
parser.add_argument('--split', type=int, default=0)
args = parser.parse_args()
ip_text, _, pfx = args.cidr.partition('/')
if args.split:
split(ip_text, int(pfx), args.split)
else:
report(ip_text, int(pfx))
# ---- test oracle: stdlib ipaddress আমাদের হাতের গণিত যাচাই করে ----
import ipaddress
for t, p in [('192.168.1.20', 24), ('172.16.37.99', 21),
('10.34.77.9', 13), ('203.0.113.129', 25)]:
ref = ipaddress.ip_network(f'{t}/{p}', strict=False)
mine, *_rest = analyze(ip_to_int(t), p)
assert mine == int(ref.network_address), f'MISMATCH {t}/{p}'
print('oracle: সব মিলেছে ✓')চালান:
python3 subnetcalc.py 172.16.37.99/21
python3 subnetcalc.py 192.168.1.0/24 --split 4প্রত্যাশিত output:
172.16.37.99/21
network 172.16.32.0
first-last 172.16.32.1 … 172.16.39.254
broadcast 172.16.39.255
usable 2046
192.168.1.0/24, RFC1918-private
network 192.168.1.0
first-last 192.168.1.1 … 192.168.1.126
broadcast 192.168.1.127
usable 126
192.168.1.128/25, RFC1918-private
network 192.168.1.128
first-last 192.168.1.129 … 192.168.1.254
broadcast 192.168.1.255
usable 126
oracle: সব মিলেছে ✓নিজে বাড়ান:
--vlsm 120,45,12,2মোড যোগ করুন — example section-এর packing algorithm নিজেই লিখুন, alignment-violation ধরে error দিন- Non-contiguous mask (যেমন 255.0.255.0) ইনপুটে এলে ব্যাখ্যাসহ প্রত্যাখ্যান করুন — কেন CIDR-এ অবৈধ
--aggregateমোড: কয়েকটা prefix ইনপুট নিয়ে বলুন কি এক super-prefix-এ গুটানো সম্ভব, সম্ভব হলে সেটা দিন
বাস্তব সিস্টেমে
এই গণিত আজ কোথায় কোথায়
Cloud-এর VPC planning। AWS-এ VPC-র মাপ হতে হয় /16 থেকে /28-এর
মধ্যে; প্রতিটা availability zone-এর subnet-ও একই সীমায়। Terraform
template-এ cidrsubnet(vpc_cidr, 4, 2)-জাতীয় function-টা আসলে
আজকের borrowing-গণিতের ব্যাখ্যাসহ wrapper — যিনি গণিতটা জানেন, তিনি
template-টাও debug করতে পারেন।
Docker আর VM-দের default। Docker daemon নিজে থেকেই docker0
bridge-এ 172.17.0.0/16 বসায়; আপনার company network যদি ভেতরে
172.16/12 ব্যবহার করে, সেই conflict-টাই “container-এ ping চলে না”-জাতীয়
ticket-এর আসল কারণ — ঠিকানার গণিত না জানলে এই bug-এর গন্ধই পাবেন না।
ISP allocation আর DFZ। প্রতিটা ISP RIPE/ARIN-এর মতো registry থেকে বড় block (যেমন /22) নিয়ে গ্রাহকদের ছোট ছোট ভাগে দেয়, তারপর aggregate করে একটা announcement-এ বিক্রি করে — routing লেসনে দেখব এই announcement-ই BGP-র কাঁচামাল। Global table আজ প্রায় ১০ লাখ route — aggregation ছাড়া সংখ্যাটা অগণনযোগ্য।
Home router-এর factory setting। প্রায় সব বাড়ির router 192.168.1.1/24
নিয়ে জন্মায় — এবং ঠিক এই কারণেই আপনার অফিস VPN-ও 192.168.1.x
হলে দুই পাড়ার ঠিকানা ধাক্কা খায়। পেশাদার setup-এ বাড়িকে অন্য
RFC1918-corner (যেমন 192.168.73.0/24)-এ সরিয়ে নেওয়াই conflict-
proofing।
CGNAT-যুগের shared ঠিকানা। Mobile operator-রা লাখো subscriber- কে 100.64/10-space-এ বসিয়ে তারপর এক handful public IP-তে NAT করে — nat লেসনে এর খরচ-সুবিধা দুই দিকই দেখবেন।
যে ভুলগুলো সবাই করে
“Netmask-এর 1-গুলো যেকোনো জায়গায় বসতে পারে — 255.0.255.0-ও একটা বৈধ mask।”
CIDR-এ mask-এর 1-গুলো অবিচ্ছিন্নভাবে বাঁ দিকেই থাকতে হয় — নইলে “prefix” বলার মতো কোনো সংখ্যাই থাকে না। 255.0.255.0-এর মতো non-contiguous mask পুরনো কিছু software-এ টাইপ করা যেত, কিন্তু তা কোনো বাস্তব routing-গণিতে খাপ খায় না: network/host ভাগ দুই টুকরো হয়ে যায়। আজকের সব OS আর router এমন ইনপুট প্রত্যাখ্যান করে।
“/24 subnet-এ ২৫৬টা host রাখা যায়।”
২৫৬টা হলো মোট ঠিকানা-pattern; তার মধ্যে all-zeros হলো network-এর নামফলক, all-ones হলো broadcast — ব্যবহারযোগ্য ২৫৪। ছোট মাপে এই overhead-এর আনুপাতিক দাম বাড়ে: /29 দেয় ৮-এর বদলে ৬, অর্থাৎ 25% কাটছাঁট। Capacity-planning-এ সবসময় 2^(32−n)−2-ই লিখুন।
“Private ঠিকানা internet-এ কোনোভাবেই যেতে পারে না — এটা প্রযুক্তিগত অসম্ভবতা।”
RFC1918 ঠিকানা-বহনকারী packet-এর কোনো magic-flag নেই — packet হিসেবে তা internet-এ ভেসে যেতে পারেই। তা যায় না কারণ তিনটা সম্মতি: registry-রা এগুলো allocate করে না, ISP-রা ingress-filter করে, আর border router-রা এগুলো NAT করে। নিয়ম ভাঙার দরকার পড়লে (যেমন misconfigured VPN-এ) ভাঙাটা প্রযুক্তিগতভাবে সহজ — এবং বিপজ্জনক।
“Loopback মানে শুধু 127.0.0.1 — অন্য 127.x লিখলে error।”
পুরো 127.0.0.0/8-ই loopback — ping 127.8.8.8 একই machine-এ
ফিরে আসবে। এই জায়গাটা ইচ্ছেমতো বিশাল রাখা: local development-এ একই
port-এ ভিন্ন ভিন্ন fake-host চালাতে এটা কাজে লাগে। শুধু মনে রাখুন
browser-রা *.localhost ছাড়া 127-x-name resolve নাও করতে পারে।
বুঝেছেন কি না দেখুন
1Netmask আর prefix-notation একই তথ্য কীভাবে বহন করে? /20-এর
decimal mask কী?
স্মরণ
/20-এর
decimal mask কী?Prefix বলে কয়টা leading bit network-part — সেই সংখ্যক 1 বাঁ দিকে
বসিয়ে 32-bit বানালেই decimal mask। /20 → ৮+৮+৪: তৃতীয় octet-এ
11110000 = 240 → 255.255.240.0।
2172.16.37.99/21-এর network, broadcast আর usable host count বের
করুন — প্রতিটা ধাপ লিখে।
প্রয়োগ
172.16.37.99/21-এর network, broadcast আর usable host count বের
করুন — প্রতিটা ধাপ লিখে।তৃতীয় octet-এ সীমা: mask-octet 248; 37=00100101 AND 248 =
00100000=32 → network 172.16.32.0; host-bits 11 → block 2048 =
৮ octet-মান → broadcast 172.16.39.255; usable 2^11−2 =
2046।
310.0.0.0/24-কে সমান চার ভাগে ভাঙুন — প্রতিটার range লিখুন। এক
ভাগে usable কত?
প্রয়োগ
10.0.0.0/24-কে সমান চার ভাগে ভাঙুন — প্রতিটার range লিখুন। এক
ভাগে usable কত?দুই bit borrow → চারটা /26: 10.0.0.0/26 (.1–.62), 10.0.0.64/26
(.65–.126), 10.0.0.128/26 (.129–.190), 10.0.0.192/26
(.193–.254)। প্রতিটায় 2^6−2 = 62 host।
4203.0.113.0/24 আর 203.0.114.0/24 এক /23-এ মেলানো যায় না কেন,
অথচ 203.0.112.0/24-এর সাথে মেলে? নিয়মটা সাধারণ ভাষায় বলুন।
যুক্তি
203.0.113.0/24 আর 203.0.114.0/24 এক /23-এ মেলানো যায় না কেন,
অথচ 203.0.112.0/24-এর সাথে মেলে? নিয়মটা সাধারণ ভাষায় বলুন।/23-এর প্রতিটা block তার মাপের (512-এর) multiple-এ শুরু হয় — তৃতীয় octet-এ মানে জোড় সংখ্যা। 112 জোড় → 112+113 এক /23-এর দুই অর্ধেক; 113 বিজোড় → তার /23-সঙ্গী 112 হতে পারে 114 নয়। সাধারণ নিয়ম: ভাঙা-গুটানো সবসময় alignment-মানে “শুরু ঠিকানা block-মাপের multiple” — মেনে চলে।
5Route aggregation কীভাবে global routing table-কে বাঁচায় — একটা
সংখ্যাসহ উদাহরণ দিন। কখন aggregation করা যায় না?
যুক্তি
ISP-র আটটা পাশাপাশি /24 (203.0.112.0–203.0.119.0) এক /21 হলে table-এ ৮-এর জায়গায় ১ লাইন, ঠিকানা-coverage হুবহু এক — এই অনুপাতেই দশ-লাখ-route table টিকে আছে। Aggregation ভাঙে যখন block-গুলো contiguous বা aligned নয়, আর ব্যবহারিকভাবে যখন একটা ভাগ অন্য ISP-র কাছে চলে যায় (deaggregation তখন অনিবার্য)।
6192.168.50.0/24 থেকে তিন department-এর জন্য 120, 60 আর 20 host-
এর subnet plan করুন। ক্রম কেন সেইটাই, ব্যাখ্যাসহ।
ডিজাইন
বড়-আগে: 192.168.50.0/25 (126 ≥ 120), তারপর 192.168.50.128/26 (62 ≥ 60), তারপর 192.168.50.192/27 (30 ≥ 20); বাকি .224–.255 ভবিষ্যতের সঞ্চয়। উল্টো ক্রমে ছোট block আগে বসালে বড় block-এর 128-alignment আর খালি জায়গা একসাথে মেলত না — তাই VLSM-এ descending-order packing নিয়ম।
এরপর কী
এরপর কী
আজ দেখলাম ৩২-bit ঠিকানার পুরো গণিত — আর সেই গণিতের একটা অন্ধকার কোণও: মানুষ যত বাড়ছে, 2^32 ≈ ৪৩ কোটি ঠিকানা তত ছোট হয়ে আসছে। CIDR অপচয় কমিয়েছে, NAT সাময়িকভাবে দিন গড়িয়েছে — কিন্তু সমাধান নয়, বরং জীবন-দীর্ঘায়ু।
পরের লেসনে:
- IPv6: 128-bit ঠিকানা — প্রতি বর্গমিটার পৃথিবীর ভূপৃষ্ঠে হাজার কোটি ঠিকানার হিসাব
- নতুন header-এর দর্শন: কী ফেলে দেওয়া হলো (checksum, router- fragmentation) আর কেন নিরাপদ
::compression-এর নিয়ম, SLAAC, privacy extensions- Transition-এর বাস্তবতা: dual-stack, tunneling, NAT64
আজকের 2^(32−n)−2-এর সংকীর্ণতাই পরের লেসনের 340 অন্ডেসিলিয়ন-
ঠিকানার মোটিভেশন। দেখা হবে 128-bit-এ।
আরও পড়ুন
- RFC 1918 — Address Allocation for Private Internets — Y. Rekhter, B. Moskowitz, D. Karrenberg et al., IETF · Private-range-এর মূল spec — NAT-যুগের ভূমিকা-পত্র
- RFC 4632 — Classless Inter-Domain Routing (CIDR) — V. Fuller, T. Li, IETF · Classful থেকে classless transition-এর official history ও rationale
- Computer Networking: A Top-Down Approach — Network Layer, addressing অধ্যায় — Kurose & Ross · Subnetting আর CIDR-এর পাঠ্যপুস্তক-ধাঁচের ব্যাখ্যা