সরাসরি পর্বে যান
পর্ব ১৬ · ৬২-এর মধ্যে · মডিউল ৩

IPv4 ঠিকানা আর header — class থেকে CIDR

IPv4 Addressing & Header — Classful, CIDR, Special Ranges & Fragmentation

Taught in Bangla, this lesson explains what an IPv4 address identifies, binary and decimal conversion by octet, network and host parts in the classful era, CIDR prefixes, masks, network and broadcast addresses, special-purpose ranges, how addresses are allocated from IANA down to your device, every field of the IPv4 header, fragmentation and reassembly numericals, and checking IPv4 settings on Linux, Windows and containers.

এই পর্বে যা শিখবেন

  • IPv4 ঠিকানা আসলে কী চেনায়, আর binary ↔ দশমিক রূপান্তর হাতে করা
  • Class A/B/C/D/E-এর পরীক্ষার ক্লাসিক টেবিল, আর classful ব্যবস্থা কেন অপচয়ী ছিল
  • CIDR-এর /n, subnet mask, network ও broadcast ঠিকানা, ব্যবহারযোগ্য host আর /31, /32-এর ব্যতিক্রম
  • বিশেষ ঠিকানাগুলো, ঠিকানা বণ্টনের শিকল (IANA → RIR → ISP), ঠিকানার ঘাটতি আর route aggregation
  • IPv4 header-এর প্রতিটি ঘর, fragmentation-এর পূর্ণ হিসাব আর Path MTU Discovery

১ · IPv4 ঠিকানা কী চেনায় — বাড়ি নয়, দরজা

পর্ব ১৫-এ দেখেছেন, network স্তরের কাজ হলো packet-কে নেটওয়ার্কের পর নেটওয়ার্ক পেরিয়ে গন্তব্যে পৌঁছানো। পৌঁছাতে হলে প্রথমে দরকার ঠিকানা। ইন্টারনেটের সবচেয়ে প্রচলিত ঠিকানা-ব্যবস্থা হলো IPv4 — Internet Protocol-এর চতুর্থ সংস্করণ, যার মান ১৯৮১ সালের RFC 791. চল্লিশ বছরেরও বেশি পরে, IPv6 (পর্ব ২১) থাকা সত্ত্বেও, আজও ইন্টারনেটের বড় অংশ IPv4-এর ওপর চলে।

মহল্লার ঠিকানার কথা ভাবুন: “রোড ৭, বাড়ি ২৩”। ডাকপিয়ন আগে রোড খোঁজেন, তারপর সেই রোডে বাড়ির নম্বর। রোড নম্বর হলো network অংশ, বাড়ির নম্বর host অংশ। এবার ধরুন একটি কোনার বাড়ি, যার এক গেট রোড ৭-এ, আরেক গেট রোড ৮-এ। এই বাড়ির ঠিকানা দুটি — প্রতিটি গেটের জন্য একটি। Router ঠিক এমন কোনার বাড়ি: প্রতিটি নেটওয়ার্কের দিকে তার একটি করে “গেট” (interface), আর প্রতিটি গেটের নিজস্ব IP ঠিকানা।

এখান থেকেই প্রথম গুরুত্বপূর্ণ কথা: IP ঠিকানা একটি host-কে নয়, host-এর একটি interface-কে চেনায়। কয়েকটি উদাহরণ:

  • আপনার ল্যাপটপে Wi-Fi আর Ethernet দুটোই চালু থাকলে ল্যাপটপের দুটি IPv4 ঠিকানা থাকতে পারে — দুই interface-এ দুটি।
  • বাসার Wi-Fi router-এর ভেতরের দিকে একটি ঠিকানা (যেমন 192.168.0.1), আর ISP-র দিকে আরেকটি।
  • প্রতিটি Linux, Windows বা macOS মেশিনে একটি কাল্পনিক loopback interface থাকে, যার ঠিকানা 127.0.0.1.

আরেকটি সূক্ষ্মতা: IP ঠিকানা বলে যন্ত্রটি কোথায় যুক্ত, যন্ত্রটি কে তা নয়। একই ল্যাপটপ বাসা থেকে অফিসে নিয়ে গেলে নতুন নেটওয়ার্ক থেকে নতুন ঠিকানা পায় (সাধারণত DHCP দিয়ে — পর্ব ১৮)। এর বিপরীতে MAC ঠিকানা (পর্ব ১২) NIC-এর সাথে বাঁধা পরিচয়ের মতো, যদিও আধুনিক ফোন গোপনীয়তার জন্য তা-ও বদলায়।

মূল ধারণা

IPv4 ঠিকানা = ৩২ বিটের একটি সংখ্যা, যা একটি network interface-এর অবস্থান জানায়। এর শুরুর কিছু বিট বলে কোন নেটওয়ার্ক (network অংশ), বাকি বিট বলে সেই নেটওয়ার্কের কোন interface (host অংশ)। কোথায় ভাগ হবে, তা বলে দেয় prefix বা mask — যা এই পর্বের মূল বিষয়।

৩২ বিট আর dotted decimal

৩২ বিটের একটি সংখ্যা মনে রাখা মানুষের পক্ষে কঠিন: 11000000101010000000101001001101. তাই বিটগুলোকে ৮টি করে চার ভাগে ভাগ করা হয়। প্রতিটি ভাগকে বলে octet (৮ বিট = ১ বাইট)। প্রতিটি octet-কে দশমিকে লিখে মাঝে বিন্দু দিলে পাওয়া যায় dotted decimal রূপ:

binary   11000000 . 10101000 . 00001010 . 01001101
decimal     192   .    168   .     10   .     77      =  192.168.10.77
hex          c0        a8         0a         4d       =  0xc0a80a4d
integer  192×2^24 + 168×2^16 + 10×2^8 + 77           =  3232238157

প্রতিটি octet ৮ বিট, তাই এর মান ০ থেকে ২৫৫. মোট ঠিকানা 232 = ৪,২৯,৪৯,৬৭,২৯৬ — প্রায় ৪২৯ কোটি। ১৯৮০-র দশকে সংখ্যাটি বিশাল মনে হয়েছিল; আজ পৃথিবীর মানুষের সংখ্যাই এর চেয়ে বেশি, আর একেকজনের হাতে ফোন, ল্যাপটপ, স্মার্ট টিভি। ঠিকানার ঘাটতির গল্প অংশ ৬-এ।

২ · Binary ↔ দশমিক — octet-এর হিসাব হাতে

Subnet-এর সব হিসাব আসলে binary-র হিসাব। তাই আগে octet-কে binary-তে আর binary-কে দশমিকে আনার অভ্যাস করে নিই। একটি octet-এর ৮টি বিটের স্থানীয় মান (বাঁ থেকে ডানে):

বিট৭৬৫৪৩২১০
মান১২৮৬৪৩২১৬৮৪২১
7701001101
17210101100

দশমিক → binary (বিয়োগ পদ্ধতি): বাঁ দিক থেকে প্রতিটি স্থানীয় মান নিয়ে প্রশ্ন করুন — “এটি বাকি সংখ্যা থেকে বিয়োগ করা যায়?” যায় হলে বিট ১, বিয়োগ করুন; না গেলে বিট ০. যেমন ৭৭: ১২৮ যায় না (০); ৬৪ যায় — বাকি ১৩ (১); ৩২ না (০); ১৬ না (০); ৮ যায় — বাকি ৫ (১); ৪ যায় — বাকি ১ (১); ২ না (০); ১ যায় — বাকি ০ (১)। ফল 01001101.

Binary → দশমিক: যে বিটগুলো ১, শুধু তাদের মান যোগ করুন। 10101100 = ১২৮ + ৩২ + ৮ + ৪ = ১৭২. আরও দুটি নিজে মিলিয়ে দেখুন: ২০০ = 11001000 (১২৮ + ৬৪ + ৮), আর 11110000 = ২৪০.

Mask-এর হিসাবে বারবার আসে এমন octet, যেখানে বাঁ দিক থেকে কয়েকটি বিট টানা ১ আর বাকি সব ০. এই আটটি মান মুখস্থ রাখলে পরীক্ষায় অনেক সময় বাঁচে:

টানা ১-এর সংখ্যাBinaryদশমিকBlock size (২৫৬ − মান)
১10000000128১২৮
২11000000192৬৪
৩11100000224৩২
৪11110000240১৬
৫11111000248৮
৬11111100252৪
৭11111110254২
৮11111111255১

শেষ কলামের “block size” পরের অংশে কাজে লাগবে: mask-এর যে octet-এ ১ আর ০ মিশেছে, সেই octet-এ নেটওয়ার্কগুলো ঠিক block size-এর গুণিতকে শুরু হয়। Binary আর সংখ্যা-পদ্ধতির ভিত্তি ঝালাই করতে চাইলে দেখুন Computer Fundamentals-এর সংখ্যা পদ্ধতির পর্ব, আর AND/OR দিয়ে বিট বাছাইয়ের কৌশল C-এর bitwise পর্বে।

শুরুর শূন্য নিয়ে সাবধান: 192.168.010.077 দেখতে নিরীহ, কিন্তু পুরোনো কিছু parser (যেমন C-এর inet_aton-এর ঐতিহ্যবাহী আচরণ) শুরুতে ০ থাকা octet-কে octal ধরে — তখন 010 মানে ৮ আর 077 মানে ৬৩! একই ঠিকানা দুই প্রোগ্রাম দুইভাবে পড়লে নিরাপত্তা-যাচাই ফাঁকি খেতে পারে, আর বাস্তবে কয়েকটি জনপ্রিয় library-তে এ ধরনের ত্রুটি পাওয়া গেছে বলে জানা যায়। নিরাপদ অভ্যাস: শুরুর শূন্য ছাড়া লিখুন, আর ঠিকানা পড়তে কঠোর (strict) parser ব্যবহার করুন — যেমন inet_pton, যা শুধু স্বাভাবিক dotted decimal মানে।

৩ · Network অংশ, host অংশ আর classful যুগ

কেন ঠিকানাকে দুই ভাগে ভাগ করা? কারণ router প্রতিটি host-এর জন্য আলাদা নিয়ম রাখতে পারে না — ইন্টারনেটে শত কোটি interface. Router-এর routing table-এ থাকে শুধু নেটওয়ার্কের তালিকা: “192.168.10.x-এর সব ঠিকানা এই দিকে”। ডাকঘরের বাছাই-কর্মী যেমন প্রথমে জেলা দেখে বস্তা ঠিক করেন, বাড়ির নম্বর দেখেন শুধু শেষ ডাকঘর। ঠিকানার শুরুর অংশ (network অংশ) দেখে পথ, শেষের অংশ (host অংশ) দেখে শেষ ধাপের ডেলিভারি।

১৯৮১ সালের RFC 791 ঠিক করেছিল, ঠিকানার প্রথম কয়েকটি বিট দেখেই বোঝা যাবে network অংশ কত বড় — এটিই classful addressing. আলাদা কোনো mask লাগত না; ঠিকানা নিজেই নিজের ভাগ বলে দিত। পরে class D যুক্ত হয় multicast-এর জন্য (১৯৮০-র দশকের দ্বিতীয়ার্ধে, RFC 988 ও RFC 1112), আর class E রাখা হয় ভবিষ্যৎ বা পরীক্ষামূলক কাজের জন্য। এক প্রতিষ্ঠানের ভেতরে নেটওয়ার্ককে আরও ভাগ করার নিয়ম — subnetting — আসে ১৯৮৫ সালের RFC 950-এ।

এবার সেই টেবিল, যা বিশ্ববিদ্যালয়, চাকরি বা ইন্টারভিউর পরীক্ষায় বারবার আসে:

Classশুরুর বিটপ্রথম octetDefault maskNetwork / host বিটনেটওয়ার্কের সংখ্যাপ্রতি নেটওয়ার্কে host
A00–127255.0.0.0 (/8)৮ / ২৪27 = ১২৮ (ব্যবহারযোগ্য ১২৬)224 − 2 = ১,৬৭,৭৭,২১৪
B10128–191255.255.0.0 (/16)১৬ / ১৬214 = ১৬,৩৮৪216 − 2 = ৬৫,৫৩৪
C110192–223255.255.255.0 (/24)২৪ / ৮221 = ২০,৯৭,১৫২28 − 2 = ২৫৪
D1110224–239নেইপুরোটা group ঠিকানাMulticast — একসাথে একটি দলের সবাইকে (পর্ব ২৬)
E1111240–255নেই—সংরক্ষিত, পরীক্ষামূলক; সাধারণ ব্যবহারে নেই

সংখ্যাগুলো কোথা থেকে এলো? Class A-তে network অংশ ৮ বিট, কিন্তু প্রথম বিট বাঁধা (০), তাই স্বাধীন বিট ৭টি — 27 = ১২৮টি নেটওয়ার্ক। এর মধ্যে 0.x.x.x (“এই নেটওয়ার্ক”) আর 127.x.x.x (loopback) সংরক্ষিত, তাই ব্যবহারযোগ্য ১২৬টি। Class B-তে network অংশ ১৬ বিট, প্রথম দুটি বাঁধা (১০), স্বাধীন ১৪ — 214. Class C-তে ২৪ − ৩ = ২১. Host অংশ h বিট হলে ঠিকানা 2hটি, কিন্তু সব-০ (নেটওয়ার্কের নিজের নাম) আর সব-১ (broadcast) বাদ — তাই 2h − 2. পুরো ঠিকানা-ভান্ডারের অর্ধেক class A, এক-চতুর্থাংশ B, এক-অষ্টমাংশ C, আর D ও E প্রতিটি ১৬ ভাগের এক ভাগ।

দ্রুত class চেনা: শুধু প্রথম octet দেখুন। 10.20.30.40 → ১০, তাই A. 172.20.5.9 → ১৭২, ১২৮–১৯১-এর মধ্যে, তাই B. 203.0.113.200 → C. 224.0.0.5 → D (এটি OSPF router-দের multicast ঠিকানা, পর্ব ২৪)।

Classful ব্যবস্থা কেন ভেঙে পড়ল

সমস্যাটা ছিল মাপের — অনেকটা দর্জির দোকানে শুধু তিনটি সাইজের জামা থাকার মতো: ছোট, বিশাল আর দৈত্যাকার। একটি বিশ্ববিদ্যালয়ের ২,০০০ যন্ত্রের জন্য class C (২৫৪ host) খুব ছোট, তাই দেওয়া হতো class B (৬৫,৫৩৪ host). ব্যবহার হতো ২,০০০ ÷ ৬৫,৫৩৪ ≈ ৩%, বাকি প্রায় ৯৭% ঠিকানা অলস পড়ে থাকত — অথচ অন্য কেউ সেগুলো ব্যবহার করতে পারত না। ১৯৯০-এর দশকের শুরুতে IETF সতর্ক করেছিল যে class B ফুরিয়ে আসছে।

বিকল্প ছিল ২,০০০ যন্ত্রের জন্য ৮টি class C দেওয়া। তাতে অপচয় কমে, কিন্তু নতুন সমস্যা: ইন্টারনেটের প্রতিটি বড় router-এর routing table-এ এই প্রতিষ্ঠানের জন্য একটির বদলে ৮টি লাইন। Routing table-এর দ্রুত বৃদ্ধি তখনকার router-এর মেমরি আর CPU-র জন্য বাস্তব হুমকি ছিল। অর্থাৎ classful ব্যবস্থায় একসাথে দুটি রোগ — ঠিকানার অপচয় আর routing table-এর স্ফীতি। দুটির একটিই ওষুধ এলো: CIDR.

৪ · CIDR — prefix /n, mask, network আর broadcast

CIDR (Classless Inter-Domain Routing, উচ্চারণ “সাইডার”) এসেছে ১৯৯৩ সালের দিকে RFC 1519-এ, আর ২০০৬ সালে RFC 4632 তাকে হালনাগাদ করে। মূল কথা একটাই: network আর host অংশের সীমা আর class দিয়ে বাঁধা নয় — যেকোনো বিটের পরে হতে পারে। সীমা কোথায়, তা ঠিকানার পাশে লিখে দেওয়া হয়:

192.168.10.77/26
প্রথম ২৬ বিট network অংশ · বাকি ৩২ − ২৬ = ৬ বিট host অংশ

স্ল্যাশের পরের সংখ্যাকে বলে prefix length. একই তথ্য আরেকভাবে লেখা যায় subnet mask দিয়ে — ৩২ বিটের একটি সংখ্যা, যার প্রথম nটি বিট ১, বাকি সব ০. /26-এর mask: ২৬টি ১, তারপর ৬টি ০ = 11111111.11111111.11111111.11000000 = 255.255.255.192. Linux লেখে prefix (/26), Windows-এর ipconfig দেখায় dotted mask, আর macOS-এর ifconfig mask দেখায় hex-এ (0xffffffc0) — তিনটিই একই জিনিস।

চারটি সূত্র — আর কেন কাজ করে

  • Network ঠিকানা = ঠিকানা AND mask. Mask-এর যেখানে ১, সেখানে ঠিকানার বিট টিকে থাকে; যেখানে ০, সেখানে বিট মুছে ০ হয়। অর্থাৎ host অংশ সব-০ — এটি নেটওয়ার্কের “নাম”, routing table-এ এটিই লেখা থাকে।
  • Broadcast ঠিকানা = network ঠিকানা OR (NOT mask). Host অংশের সব বিট ১. এই ঠিকানায় পাঠানো packet ওই নেটওয়ার্কের সবার জন্য।
  • ব্যবহারযোগ্য পরিসর = network + ১ থেকে broadcast − ১.
  • ব্যবহারযোগ্য host-এর সংখ্যা = 2h − 2, যেখানে h = ৩২ − n. মোট ঠিকানা 2h, তার দুটি (সব-০ আর সব-১) সংরক্ষিত।

এবার একটি উদাহরণ ধাপে ধাপে। “পরে” চেপে দেখুন 192.168.10.77/26 থেকে কীভাবে network, broadcast আর host-এর পরিসর বের হয়:

হিসাবের খাতা (প্রথম তিন octet 192.168.10 অপরিবর্তিত)
Prefix
শেষ octet (77)
Mask-এর শেষ octet
Network
Broadcast
ব্যবহারযোগ্য
  1. Prefix পড়া। /26 মানে প্রথম ২৬ বিট network অংশ, বাকি h = ৩২ − ২৬ = ৬ বিট host অংশ। প্রথম তিন octet-এ ২৪ বিট — সেগুলো পুরোটাই network অংশ, তাই 192.168.10 যেমন আছে থাকবে। কাজ শুধু শেষ octet নিয়ে।
  2. শেষ octet binary-তে। ৭৭ = ৬৪ + ৮ + ৪ + ১, তাই 01001101. পুরো ঠিকানার বিট এখন ২৪টি (প্রথম তিন octet) + এই ৮টি।
  3. Mask তৈরি। ২৬টি ১-এর মধ্যে ২৪টি প্রথম তিন octet-এ (255.255.255), বাকি ২টি শেষ octet-এর বাঁ দিকে: 11000000 = ১৯২. তাই mask 255.255.255.192, আর block size ২৫৬ − ১৯২ = ৬৪.
  4. সীমারেখা টানা। শেষ octet-এর প্রথম ২ বিট (01) network অংশের শেষ দুটি বিট, পরের ৬ বিট (001101) host অংশ। “│” চিহ্নটি এই সীমা দেখাচ্ছে।
  5. AND করে network. 01001101 AND 11000000 = 01000000 = ৬৪. Host অংশের সব বিট ০ হয়ে গেল — network ঠিকানা 192.168.10.64.
  6. Host বিট সব ১ করে broadcast. 01-এর পরে ছয়টি ১: 01111111 = ১২৭. Broadcast ঠিকানা 192.168.10.127.
  7. পরিসর আর সংখ্যা। প্রথম ব্যবহারযোগ্য .65, শেষ .126; মোট 26 − 2 = ৬২টি host. শর্টকাট: block size ৬৪, তাই নেটওয়ার্কগুলো শুরু হয় 0, 64, 128, 192-তে; ৭৭ পড়েছে 64–127-এর ঘরে। পরীক্ষায় দুই পদ্ধতিতে মিলিয়ে নিলে ভুলের ঝুঁকি কমে।

সাধারণ prefix-গুলোর একটি টেবিল মনে রাখা কাজের:

PrefixMaskমোট ঠিকানাব্যবহারযোগ্য hostসাধারণ ব্যবহার
/8255.0.0.0১,৬৭,৭৭,২১৬১,৬৭,৭৭,২১৪পুরোনো class A মাপ; 10.0.0.0/8
/16255.255.0.0৬৫,৫৩৬৬৫,৫৩৪বড় ক্যাম্পাস, cloud VPC
/24255.255.255.0২৫৬২৫৪বাসা বা ছোট অফিসের LAN
/25255.255.255.128১২৮১২৬অফিসের বিভাগ, VLAN, সার্ভার-ঘর (পর্ব ১৭)
/26255.255.255.192৬৪৬২
/27255.255.255.224৩২৩০
/28255.255.255.240১৬১৪
/29255.255.255.248৮৬
/30255.255.255.252৪২দুই router-এর মাঝের point-to-point link (প্রচলিত)
/31255.255.255.254২২ (ব্যতিক্রম)Point-to-point link, RFC 3021
/32255.255.255.255১১ (ব্যতিক্রম)একটিমাত্র host-এর route, router-এর loopback ঠিকানা

/31 আর /32 — সূত্রের ব্যতিক্রম

সূত্র অনুযায়ী /31-এ 21 − 2 = ০টি host — অর্থহীন। কিন্তু দুই router-এর মাঝের একটি তারের (point-to-point link) দুই প্রান্তে ঠিক দুটি interface; সেখানে broadcast-এর দরকারই নেই, কারণ “সবাই” মানে তো অন্য প্রান্তের একজন। প্রচলিত /30 দিলে ৪টি ঠিকানার ২টি নষ্ট হয়। তাই ২০০০ সালের RFC 3021 নিয়ম দেয়: point-to-point link-এ /31 ব্যবহার করা যায়, আর দুটি ঠিকানাই host-এর। বড় ISP-তে হাজার হাজার এমন link থাকলে এতে ঠিকানার অর্ধেক বাঁচে। /32 মানে একটিমাত্র ঠিকানা — একটি নির্দিষ্ট host-এর route, বা router-এর কাল্পনিক loopback interface-এর ঠিকানা, যা কোনো একটি তারের ওপর নির্ভর করে না।

“Classless” মানে কী? CIDR-এর যুগে class আর কোনো সিদ্ধান্তে কাজে লাগে না — 172.20.5.9 প্রথম octet দেখে “class B”, কিন্তু 172.16.0.0/12 ব্লকের অংশ হিসেবে তার prefix /12, আর একটি অফিস তাকে /24 বা /27-ও বানাতে পারে। Class-এর টেবিল এখন মূলত ইতিহাস আর পরীক্ষার বিষয়, আর পুরোনো কিছু কনফিগারেশনে “default mask” হিসেবে টিকে আছে। Cisco-র ACL আর OSPF কনফিগারেশনে আরেকটি রূপও দেখবেন — wildcard mask, যা mask-এর উল্টো (/26-এর জন্য 0.0.0.63); এটি vendor-এর রীতি, IP-র মান নয়।

হাতে করা হিসাব যন্ত্রে মেলানো যাক। নিচের calculator কয়েকটি CIDR ইনপুটের জন্য binary, mask, network, broadcast, ব্যবহারযোগ্য পরিসর, class আর বিশেষ-ব্লকের নাম ছাপে — Run চাপুন:

// IPv4 calculator: CIDR -> binary, mask, network, broadcast, hosts, class, label.
const toInt = s => s.split(".").reduce((a, o) => a * 256 + Number(o), 0);
const toIp = n => [24, 16, 8, 0].map(s => (n >>> s) & 255).join(".");
const bin = n => toIp(n).split(".").map(o => (+o).toString(2).padStart(8, "0")).join(".");
const maskOf = p => (p === 0 ? 0 : (0xffffffff << (32 - p)) >>> 0);
const SPECIAL = [["0.0.0.0/8", "this network"], ["10.0.0.0/8", "private (RFC 1918)"],
  ["100.64.0.0/10", "shared CGNAT (RFC 6598)"], ["127.0.0.0/8", "loopback"],
  ["169.254.0.0/16", "link-local"], ["172.16.0.0/12", "private (RFC 1918)"],
  ["192.0.2.0/24", "documentation TEST-NET-1"], ["192.168.0.0/16", "private (RFC 1918)"],
  ["198.51.100.0/24", "documentation TEST-NET-2"], ["203.0.113.0/24", "documentation TEST-NET-3"],
  ["224.0.0.0/4", "multicast"], ["240.0.0.0/4", "reserved"]];
const inside = (ip, c) => { const [a, p] = c.split("/"); return ((ip & maskOf(+p)) >>> 0) === toInt(a); };
function classOf(ip) {
  const f = ip >>> 24;
  return f < 128 ? "A (default /8)" : f < 192 ? "B (default /16)" : f < 224 ? "C (default /24)"
       : f < 240 ? "D (multicast, no mask)" : "E (reserved)";
}
function calc(cidr) {
  const [a, p] = cidr.split("/"), ip = toInt(a), pre = +p, m = maskOf(pre);
  const net = (ip & m) >>> 0, bc = (net | ~m) >>> 0;
  const hosts = pre >= 31 ? 2 ** (32 - pre) : 2 ** (32 - pre) - 2;   // /31, /32: no net/bcast
  const first = pre >= 31 ? net : net + 1, last = pre >= 31 ? bc : bc - 1;
  const label = (SPECIAL.find(([c]) => inside(ip, c)) || [0, "public (global)"])[1];
  console.log(`=== ${cidr}  class ${classOf(ip)}  ->  ${label}`);
  console.log(`  address  ${bin(ip)}`);
  console.log(`  mask     ${bin(m)}  = ${toIp(m)}`);
  console.log(`  network  ${toIp(net)}   broadcast ${pre >= 31 ? "(none)" : toIp(bc)}`);
  console.log(`  usable   ${toIp(first)} - ${toIp(last)}   hosts = ${hosts}`);
}
["192.168.10.77/26", "203.0.113.200/28", "172.20.5.9/12", "198.51.100.9/31",
 "100.72.1.5/10", "192.0.2.1/32"].forEach(calc);

আউটপুট:

=== 192.168.10.77/26  class C (default /24)  ->  private (RFC 1918)
  address  11000000.10101000.00001010.01001101
  mask     11111111.11111111.11111111.11000000  = 255.255.255.192
  network  192.168.10.64   broadcast 192.168.10.127
  usable   192.168.10.65 - 192.168.10.126   hosts = 62
=== 203.0.113.200/28  class C (default /24)  ->  documentation TEST-NET-3
  address  11001011.00000000.01110001.11001000
  mask     11111111.11111111.11111111.11110000  = 255.255.255.240
  network  203.0.113.192   broadcast 203.0.113.207
  usable   203.0.113.193 - 203.0.113.206   hosts = 14
=== 172.20.5.9/12  class B (default /16)  ->  private (RFC 1918)
  address  10101100.00010100.00000101.00001001
  mask     11111111.11110000.00000000.00000000  = 255.240.0.0
  network  172.16.0.0   broadcast 172.31.255.255
  usable   172.16.0.1 - 172.31.255.254   hosts = 1048574
=== 198.51.100.9/31  class C (default /24)  ->  documentation TEST-NET-2
  address  11000110.00110011.01100100.00001001
  mask     11111111.11111111.11111111.11111110  = 255.255.255.254
  network  198.51.100.8   broadcast (none)
  usable   198.51.100.8 - 198.51.100.9   hosts = 2
=== 100.72.1.5/10  class A (default /8)  ->  shared CGNAT (RFC 6598)
  address  01100100.01001000.00000001.00000101
  mask     11111111.11000000.00000000.00000000  = 255.192.0.0
  network  100.64.0.0   broadcast 100.127.255.255
  usable   100.64.0.1 - 100.127.255.254   hosts = 4194302
=== 192.0.2.1/32  class C (default /24)  ->  documentation TEST-NET-1
  address  11000000.00000000.00000010.00000001
  mask     11111111.11111111.11111111.11111111  = 255.255.255.255
  network  192.0.2.1   broadcast (none)
  usable   192.0.2.1 - 192.0.2.1   hosts = 1

প্রথম ব্লক stepper-এর উত্তরের সাথে হুবহু মেলে: network 192.168.10.64, broadcast .127, ৬২টি host. দ্বিতীয়টি documentation ব্লকের একটি /28 — ২০০ পড়েছে ১৯২–২০৭-এর ঘরে (block size ১৬), ব্যবহারযোগ্য ১৪টি। তৃতীয়টি দেখায় class আর prefix-এর বিচ্ছেদ: প্রথম octet ১৭২ বলে “class B (default /16)”, অথচ /12 দিয়ে network দাঁড়াল 172.16.0.0 আর broadcast 172.31.255.255 — RFC 1918-এর পুরো 172.16.0.0/12 ব্লক। কোডে খেয়াল করুন >>> 0: JavaScript-এর bitwise অপারেশন ৩২ বিটের signed সংখ্যা দেয়, তাই ১২৮-এর বেশি প্রথম octet-এর ঠিকানা ঋণাত্মক হয়ে যেত; >>> 0 সেটিকে আবার unsigned করে। AI-এর লেখা subnet কোডে এই ভুলটি খুব সাধারণ।

একটি নেটওয়ার্ককে ছোট ছোট ভাগে ভাগ করা (subnetting), প্রতিটি বিভাগকে মাপমতো আলাদা prefix দেওয়া (VLSM) আর সেসব হিসাবের ধাপে ধাপে অনুশীলন পাবেন পরের পর্ব — পর্ব ১৭-এ।

৫ · বিশেষ ঠিকানা — সবার জন্য নয় এমন ব্লক

৪২৯ কোটি ঠিকানার সবগুলো সাধারণ host-এর জন্য নয়। কিছু ব্লক নির্দিষ্ট কাজে সংরক্ষিত; এদের পূর্ণ তালিকা রাখে IANA-র “IPv4 Special-Purpose Address Registry” (RFC 6890 এর কাঠামো দেয়)। যেগুলো সবচেয়ে বেশি দেখবেন:

ব্লকনামকী কাজে, কী নিয়ম
0.0.0.0/8“এই নেটওয়ার্ক”0.0.0.0 উৎস হিসেবে বসে যখন যন্ত্রের এখনো ঠিকানা নেই (DHCP-র প্রথম বার্তা, পর্ব ১৮)। সার্ভার কোডে 0.0.0.0-তে bind মানে “সব interface-এ শুনব”, আর routing table-এ 0.0.0.0/0 মানে default route (পর্ব ২২)। গন্তব্য হিসেবে বৈধ নয়।
127.0.0.0/8Loopbackযন্ত্রের নিজের দিকে ফেরানো; কখনো তারে বের হয় না। সাধারণত 127.0.0.1 ব্যবহার হয়, যদিও পুরো /8 (প্রায় ১.৬৮ কোটি ঠিকানা) এই কাজে সংরক্ষিত।
169.254.0.0/16Link-localDHCP সার্ভার না পেলে যন্ত্র নিজেই এখান থেকে একটি ঠিকানা বেছে নেয় (RFC 3927; Windows একে APIPA বলে)। শুধু একই link-এ চলে, router পার হয় না। নিজের ল্যাপটপে 169.254.x.x দেখলে প্রথমে সন্দেহ করুন — DHCP পায়নি।
10.0.0.0/8
172.16.0.0/12
192.168.0.0/16
Private (RFC 1918)যেকোনো প্রতিষ্ঠান বা বাসা নিজের ভেতরে অনুমতি ছাড়াই ব্যবহার করতে পারে; ইন্টারনেটে route হয় না। লক্ষ করুন মাঝেরটি /12 — 172.16 থেকে 172.31 পর্যন্ত, 172.32 নয়। Public ইন্টারনেটে যাওয়ার কৌশল NAT — পর্ব ১৯।
100.64.0.0/10Shared / CGNAT (RFC 6598)ISP-এর নিজস্ব NAT (carrier-grade NAT)-এর ভেতরের দিকের জন্য, ২০১২ সালে সংরক্ষিত। আপনার router-এর WAN ঠিকানা 100.64–100.127 দিয়ে শুরু হলে বুঝবেন আপনি ISP-র NAT-এর পেছনে আছেন।
192.0.2.0/24
198.51.100.0/24
203.0.113.0/24
Documentation (RFC 5737)বই, টিউটোরিয়াল আর উদাহরণের জন্য (TEST-NET-1, ২, ৩)। কখনো আসল নেটওয়ার্কে বসে না, তাই কেউ উদাহরণ কপি করলেও অন্যের সার্ভারে ভুল করে আঘাত লাগে না। এই কোর্সের উদাহরণে এগুলোই ব্যবহার করা হয়।
224.0.0.0/4Multicast (পুরোনো class D)একটি দলের সবার জন্য; যেমন 224.0.0.1 = একই link-এর সব host. বিস্তারিত পর্ব ২৬।
240.0.0.0/4সংরক্ষিত (পুরোনো class E)সাধারণ ব্যবহারে নেই; বেশিরভাগ OS আর router এগুলো গ্রহণই করে না।
255.255.255.255Limited broadcast“এই link-এর সবাই”; router কখনো পার করে না। ঠিকানা না জানা অবস্থায় DHCP এটি ব্যবহার করে।

একটি নেটওয়ার্কের নিজস্ব broadcast ঠিকানাকে (যেমন 192.168.10.127) বলে directed broadcast — দূরের কেউ এই ঠিকানায় পাঠালে সেই নেটওয়ার্কের সবার কাছে যাওয়ার কথা। ১৯৯০-এর দশকে আক্রমণকারীরা এর অপব্যবহার করে একটি ছোট অনুরোধকে শত শত উত্তরে বড় করত (“smurf” ধরনের amplification). প্রতিরক্ষা হিসেবে ১৯৯৯ সালের RFC 2644 নিয়ম করে যে router ডিফল্টভাবে directed broadcast পার করবে না — আজকের প্রায় সব router এটাই মানে।

Private ঠিকানা “গোপন” বা “নিরাপদ” নয় — শুধু ইন্টারনেটে route হয় না, এটুকুই। একই 192.168.0.0/24 ঢাকা আর চট্টগ্রামের লাখো বাসায় একসাথে চলছে। নিরাপত্তা আসে firewall আর ঠিকমতো কনফিগার করা সেবা থেকে (পর্ব ৪৯), ঠিকানার ধরন থেকে নয়।

৬ · কে ঠিকানা দেয় — IANA থেকে আপনার ফোন পর্যন্ত

দুই প্রতিষ্ঠান একই public ঠিকানা ব্যবহার করলে ইন্টারনেট বুঝবে না packet কার কাছে যাবে। তাই public ঠিকানা বণ্টন হয় একটি স্তরভিত্তিক শিকলে — ওপর থেকে নিচে বড় ব্লক ভেঙে ছোট ব্লকে:

IANA  (পুরো IPv4 ভান্ডার; বড় ব্লক /8 আকারে দিত)
  │
  ├── AFRINIC   আফ্রিকা
  ├── APNIC     এশিয়া-প্রশান্ত মহাসাগরীয় অঞ্চল (বাংলাদেশসহ)
  ├── ARIN      উত্তর আমেরিকা
  ├── LACNIC    লাতিন আমেরিকা ও ক্যারিবীয় অঞ্চল
  └── RIPE NCC  ইউরোপ, মধ্যপ্রাচ্য ও মধ্য এশিয়ার অংশ
        │
        ├── ISP, মোবাইল অপারেটর, ডেটা সেন্টার (সদস্য বা LIR) — যেমন একটি /22
        │     │
        │     └── গ্রাহক: একটি অফিস /29, বাসার router-এর WAN-এ একটি ঠিকানা
        └── কিছু দেশে মাঝখানে জাতীয় সংস্থা (NIR), যেমন জাপানের JPNIC

সবার ওপরে IANA (Internet Assigned Numbers Authority), যার কাজ এখন ICANN-এর একটি অঙ্গ-প্রতিষ্ঠান পরিচালনা করে। IANA ঠিকানা দেয় পাঁচটি RIR (Regional Internet Registry)-কে। বাংলাদেশ পড়ে APNIC-এর অঞ্চলে; দেশের ISP আর মোবাইল অপারেটররা সাধারণত APNIC-এর সদস্য হয়ে সরাসরি ঠিকানার ব্লক নেয় বলে জানা যায়।

ঠিকানা ফুরিয়ে যাওয়া

২০১১ সালের ফেব্রুয়ারিতে IANA তার শেষ পাঁচটি /8 ব্লক পাঁচ RIR-কে একটি করে দিয়ে দেয় — কেন্দ্রীয় ভান্ডার শূন্য। এরপর প্রতিটি RIR একে একে নিজের “শেষ ব্লক”-এর কঠোর নীতিতে চলে যায়: APNIC প্রায় সাথে সাথেই, ২০১১ সালের এপ্রিলে; RIPE NCC ২০১২ সালে (আর ২০১৯ সালের শেষে জানায় যে সাধারণ বরাদ্দের মতো ঠিকানা আর নেই); ARIN ২০১৫ সালে — তারিখগুলো RIR-গুলোর ঘোষণা অনুযায়ী, বিস্তারিত তাদের ওয়েবসাইটে মিলিয়ে নিন। আজ নতুন প্রতিষ্ঠান সাধারণত অপেক্ষা-তালিকা থেকে খুব ছোট ব্লক পায়, বা অন্যের কাছ থেকে কেনে।

ঘাটতি সামলানোর তিনটি পথ বাস্তবে চলছে:

  • NAT আর CGNAT: একটি public ঠিকানার পেছনে অনেক private যন্ত্র — বাসায় router, আর ISP পর্যায়ে carrier-grade NAT (পর্ব ১৯)। বাংলাদেশসহ অনেক দেশে মোবাইল ডেটা ব্যবহারকারীরা সাধারণত CGNAT-এর পেছনে থাকেন বলে ধারণা করা হয়।
  • ঠিকানার বাজার: RIR-গুলোর নীতি মেনে ব্লক হস্তান্তর (transfer) আর ভাড়া দেওয়া এখন বৈধ ব্যবসা (ভাবনার প্রশ্ন ৪ দেখুন)।
  • IPv6: ১২৮ বিটের ঠিকানা — স্থায়ী সমাধান, পর্ব ২১-এ।

Route aggregation — একটি লাইনে চারটি নেটওয়ার্ক

CIDR-এর দ্বিতীয় বড় উপহার হলো route aggregation (supernetting নামেও পরিচিত): পাশাপাশি কয়েকটি ব্লককে একটি ছোট prefix দিয়ে একসাথে ঘোষণা করা। ধরুন একটি ISP পেয়েছে 198.18.0.0/22 (উদাহরণের জন্য benchmarking-এর সংরক্ষিত ব্লক 198.18.0.0/15 থেকে নেওয়া), আর চারটি গ্রাহককে দিয়েছে একটি করে /24:

198.18.0.0/24   তৃতীয় octet  0 = 000000 00
198.18.1.0/24   তৃতীয় octet  1 = 000000 01
198.18.2.0/24   তৃতীয় octet  2 = 000000 10
198.18.3.0/24   তৃতীয় octet  3 = 000000 11
                                 ──────
প্রথম 16 + 6 = 22 বিট চারটিতেই এক   →   একটি route: 198.18.0.0/22

ইন্টারনেটের বাকি সবাইকে ISP চারটি নয়, একটি route জানায়: “198.18.0.0/22 আমার দিকে”। ভেতরে কোন /24 কোন গ্রাহকের, তা শুধু ISP জানে — ঠিক যেমন বিদেশের ডাকঘর শুধু “বাংলাদেশ” দেখে বস্তা পাঠায়, জেলা-থানা দেখে দেশের ভেতরের ডাকঘর। শর্ত দুটি: ব্লকগুলো পাশাপাশি হতে হবে, আর শুরুটা block size-এর গুণিতকে (aligned). যেমন 198.18.1.0/24 আর 198.18.2.0/24 পাশাপাশি হলেও একটি /23 হয় না — তৃতীয় octet ১ (00000001) আর ২ (00000010) সপ্তম বিটেই আলাদা; /23 হতে পারে 0–1 বা 2–3 জোড়া।

কোনো গ্রাহক (ধরুন 198.18.2.0/24) অন্য ISP-তে চলে গেলে নতুন ISP শুধু সেই /24 ঘোষণা করে। তখন router-দের কাছে দুটি মিলে যাওয়া route থাকে — /22 আর /24 — আর তারা বেছে নেয় যেটি বেশি নির্দিষ্ট (লম্বা prefix). এই নিয়মের নাম longest prefix match; এর পুরো কৌশল পর্ব ২২-এ, আর ISP-দের মধ্যে route ঘোষণার protocol BGP পর্ব ২৫-এ। Aggregation না থাকলে বিশ্বের routing table অনেক আগেই অচল হয়ে যেত; তবু আজ পুরো ইন্টারনেটের IPv4 routing table-এ প্রায় দশ লাখের কাছাকাছি prefix আছে বলে বিভিন্ন পরিমাপে দেখা যায়।

৭ · IPv4 header — ঘর ধরে ধরে

ঠিকানা হলো খামের ওপর লেখা তথ্যের একটি অংশ মাত্র। পুরো খামটি — IPv4 header — দেখতে এমন (RFC 791-এর ছবির মতো, প্রতি সারি ৩২ বিট = ৪ বাইট):

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
┌───────┬───────┬───────────┬───┬───────────────────────────────┐
│Version│  IHL  │    DSCP   │ECN│          Total Length         │
├───────┴───────┴───────────┴───┼─────┬─────────────────────────┤
│         Identification        │Flags│     Fragment Offset     │
├───────────────┬───────────────┼─────┴─────────────────────────┤
│      TTL      │    Protocol   │        Header Checksum        │
├───────────────┴───────────────┴───────────────────────────────┤
│                         Source Address                        │
├───────────────────────────────────────────────────────────────┤
│                      Destination Address                      │
├───────────────────────────────────────────────────────────────┤
│                 Options (if IHL > 5) + padding                │
└───────────────────────────────────────────────────────────────┘

Option ছাড়া header পাঁচ সারি = ২০ বাইট। প্রতিটি ঘরের কাজ:

ঘরবিটকাজ
Version৪IPv4-এ সবসময় ৪. প্রাপক প্রথমেই দেখে কোন সংস্করণের নিয়মে বাকিটা পড়বে।
IHL৪Header-এর দৈর্ঘ্য, ৪ বাইটের (৩২ বিট) এককে। সর্বনিম্ন ৫ (= ২০ বাইট), সর্বোচ্চ ১৫ (= ৬০ বাইট)। IHL ৬ মানে header ২৪ বাইট, অর্থাৎ ৪ বাইট option.
DSCP৬অগ্রাধিকারের শ্রেণি (QoS). ০ = সাধারণ; ৪৬ (EF) সাধারণত ভয়েস কলে; ৩৪ (AF41) প্রায়ই ভিডিওতে। পুরোনো নাম “Type of Service” বাইট; ১৯৯৮ সালের RFC 2474 একে নতুন অর্থ দেয়। বিস্তারিত পর্ব ২৬।
ECN২জ্যামের সংকেত: router packet ফেলে না দিয়ে দাগ দিয়ে জানায় “জ্যাম হচ্ছে” (RFC 3168). ০০ = ECN ব্যবহার হচ্ছে না। TCP কীভাবে সাড়া দেয় — পর্ব ৩২।
Total Length১৬Header + ডেটা মিলিয়ে পুরো datagram-এর বাইট; সর্বোচ্চ ৬৫,৫৩৫. Ethernet-এর padding থাকলে কোনটি আসল ডেটা, তা এই ঘর থেকেই বোঝা যায়।
Identification১৬একটি datagram-এর নম্বর; ভাঙা হলে সব টুকরোয় একই নম্বর থাকে, যাতে প্রাপক জোড়া চিনতে পারে।
Flags৩প্রথম বিট সংরক্ষিত (০)। তারপর DF (Don't Fragment) — ১ হলে কেউ ভাঙতে পারবে না; আর MF (More Fragments) — ১ মানে পরে আরও টুকরো আছে।
Fragment Offset১৩এই টুকরোর ডেটা মূল ডেটার কোথা থেকে শুরু, ৮ বাইটের এককে। অংশ ৮-এ পুরো হিসাব।
TTL৮Time To Live — প্রতিটি router ১ কমায়, ০ হলে ফেলে দিয়ে ICMP বার্তা পাঠায়। শুরুর মান OS-ভেদে আলাদা — Linux সাধারণত ৬৪, Windows ১২৮.
Protocol৮ভেতরে কোন protocol — protocol number: ১ = ICMP, ২ = IGMP, ৬ = TCP, ১৭ = UDP, ৪৭ = GRE, ৫০ = ESP (IPsec), ৮৯ = OSPF.
Header Checksum১৬শুধু header-এর checksum, ডেটার নয়। TTL বদলায় বলে প্রতিটি router নতুন করে বসায়। হিসাবের পদ্ধতি পর্ব ০৩-এ একটি packet-এ হাতে করা হয়েছে, আর এর শক্তি-দুর্বলতা পর্ব ০৯-এ।
Source / Destination৩২ + ৩২প্রেরক আর প্রাপকের IPv4 ঠিকানা। NAT ছাড়া পুরো পথে বদলায় না।
Options০–৩২০Record Route, Timestamp, Source Route ইত্যাদি। আজ প্রায় অব্যবহৃত; option-যুক্ত packet অনেক router ধীর পথে প্রক্রিয়া করে, আর source routing নিরাপত্তার কারণে প্রায় সব জায়গায় বন্ধ।

এবার একটি capture করা packet-এর প্রথম ২০ বাইট বাইট ধরে পড়া যাক। এটি একটি container (10.0.2.100) থেকে একটি ওয়েব সার্ভারে (192.0.2.80) পাঠানো TCP সংযোগের প্রথম packet (SYN, পর্ব ২৯)। “পরে” চাপুন:

45 00 00 3c 3a 7c 40 00 40 06 31 8c 0a 00 02 64 c0 00 02 50
এই ধাপে পড়া অংশ
বাইট
Hex
ঘর
মান
  1. প্রথম বাইট দুই ভাগে। 0x45-এর ওপরের ৪ বিট ৪ — IPv4. নিচের ৪ বিট ৫ — IHL, অর্থাৎ ৫ × ৪ = ২০ বাইট header, কোনো option নেই। তাই ডেটা শুরু হবে বাইট ২০ থেকে।
  2. DSCP আর ECN. 0x00 — ওপরের ৬ বিট DSCP ০ (সাধারণ, “best effort”), নিচের ২ বিট ECN ০০ (প্রেরক ECN ব্যবহার করছে না)।
  3. Total Length. 0x003c = ৬০ বাইট। Header ২০, তাই ভেতরের TCP segment ৪০ বাইট — ২০ বাইট TCP header আর ২০ বাইট TCP option (Linux-এর SYN-এ সাধারণত MSS, timestamp, window scale ইত্যাদি থাকে)।
  4. Identification. 0x3a7c = ৩×৪০৯৬ + ১০×২৫৬ + ৭×১৬ + ১২ = ১৪৯৭২. এই packet ভাঙা হলে প্রতিটি টুকরোয় এই নম্বর থাকত।
  5. Flags আর offset. 0x4000-এর binary 0100 0000 0000 0000: প্রথম বিট (সংরক্ষিত) ০, দ্বিতীয় বিট DF = ১, তৃতীয় বিট MF = ০, বাকি ১৩ বিট offset ০. অর্থাৎ “আমাকে ভাঙা যাবে না” — আধুনিক TCP এভাবেই পাঠায়, Path MTU Discovery-র জন্য (অংশ ৮)।
  6. TTL. 0x40 = ৬৪. Linux-এর সাধারণ শুরুর মান — এখান থেকে অনুমান করা যায় প্রেরক সম্ভবত Linux, তবে এটি প্রমাণ নয়; মানটি বদলানো যায়।
  7. Protocol. 0x06 = ৬ = TCP. প্রাপকের IP স্তর ডেটা অংশটি TCP-কে দেবে।
  8. Checksum যাচাই। দশটি ১৬-বিটের word যোগ করলে (checksum-সহ) 0x1fffe; ওপরের ১ ঘুরিয়ে যোগ করলে 0xfffe + 0x1 = 0xffff — header অক্ষত। পদ্ধতিটি পর্ব ০৩-এর মতোই।
  9. দুই ঠিকানা। 0a 00 02 64 = 10.0.2.100 (private, RFC 1918), c0 00 02 50 = 192.0.2.80 (documentation ব্লক)। বাস্তবে private উৎস নিয়ে packet ইন্টারনেটে যেতে পারে না — পথের NAT উৎস বদলে দেবে (পর্ব ১৯)।

এখন উল্টো কাজ: ঘরগুলোর মান দিয়ে header বানানো, checksum হিসাব, আর একটি ভিন্ন capture করা header পড়ে ঘরে ঘরে ভাগ করা। বহু-বাইটের ঘর নেটওয়ার্কে যায় big-endian ক্রমে (বড় বাইট আগে) — একে বলে network byte order; কোডে তাই len >> 8 আগে, len & 255 পরে। (x86-এর মতো little-endian CPU-তে C প্রোগ্রাম এজন্য htons/htonl ডাকে — পর্ব ৪১-এ socket কোডে দেখবেন।)

// IPv4 header: build 20 bytes from fields, then parse hex back into fields.
const sum16 = b => { let s = 0;                           // one's-complement sum
  for (let i = 0; i < b.length; i += 2) s += (b[i] << 8) | b[i + 1];
  while (s > 0xffff) s = (s & 0xffff) + (s >>> 16); return s; };
const hex = b => b.map(x => x.toString(16).padStart(2, "0")).join("");
function build(f) {
  const ip = s => s.split(".").map(Number), frag = (f.df << 14) | (f.mf << 13) | f.off;
  const b = [(4 << 4) | 5, (f.dscp << 2) | f.ecn, f.len >> 8, f.len & 255,
    f.id >> 8, f.id & 255, frag >> 8, frag & 255, f.ttl, f.proto, 0, 0,  // checksum = 0
    ...ip(f.src), ...ip(f.dst)];
  const c = ~sum16(b) & 0xffff; b[10] = c >> 8; b[11] = c & 255; return b;
}
function parse(h) {
  const b = h.match(/../g).map(x => parseInt(x, 16)), u16 = i => (b[i] << 8) | b[i + 1];
  const ihl = b[0] & 15, off = u16(6) & 0x1fff, name = { 1: "ICMP", 6: "TCP", 17: "UDP" };
  console.log(`  version=${b[0] >> 4} IHL=${ihl} (${ihl * 4} B) DSCP=${b[1] >> 2} ECN=${b[1] & 3}` +
              ` total=${u16(2)} B id=0x${u16(4).toString(16)}`);
  console.log(`  DF=${(b[6] >> 6) & 1} MF=${(b[6] >> 5) & 1} offset=${off} (= ${off * 8} B)` +
              ` TTL=${b[8]} protocol=${b[9]} (${name[b[9]] || "?"})`);
  console.log(`  checksum=0x${hex(b.slice(10, 12))} -> ` +
              (sum16(b.slice(0, ihl * 4)) === 0xffff ? "OK" : "BAD"));
  console.log(`  src=${b.slice(12, 16).join(".")} dst=${b.slice(16, 20).join(".")}` +
              ` payload=${u16(2) - ihl * 4} B`);
}
const syn = build({ dscp: 0, ecn: 0, len: 60, id: 0x3a7c, df: 1, mf: 0, off: 0,
                    ttl: 64, proto: 6, src: "10.0.2.100", dst: "192.0.2.80" });
console.log("built:  " + hex(syn).replace(/(....)(?!$)/g, "$1 "));
parse(hex(syn));
const cap = "458805dc8e2120b93911665fc6336407cb007114";       // a captured fragment
console.log("captured: " + cap.replace(/(....)(?!$)/g, "$1 "));
parse(cap);

আউটপুট:

built:  4500 003c 3a7c 4000 4006 318c 0a00 0264 c000 0250
  version=4 IHL=5 (20 B) DSCP=0 ECN=0 total=60 B id=0x3a7c
  DF=1 MF=0 offset=0 (= 0 B) TTL=64 protocol=6 (TCP)
  checksum=0x318c -> OK
  src=10.0.2.100 dst=192.0.2.80 payload=40 B
captured: 4588 05dc 8e21 20b9 3911 665f c633 6407 cb00 7114
  version=4 IHL=5 (20 B) DSCP=34 ECN=0 total=1500 B id=0x8e21
  DF=0 MF=1 offset=185 (= 1480 B) TTL=57 protocol=17 (UDP)
  checksum=0x665f -> OK
  src=198.51.100.7 dst=203.0.113.20 payload=1480 B

প্রথম লাইনের hex stepper-এর capture-এর সাথে বাইট-বাইট মেলে — অর্থাৎ ঘরের মান থেকে ঠিক সেই packet-ই তৈরি হয়েছে, checksum 0x318c সহ। Parser সেটিকে আবার ঘরে ভেঙে একই মান ফিরিয়ে দিল। দ্বিতীয় header একেবারে আলাদা ধরনের: DSCP ৩৪ (0x88-এর ওপরের ৬ বিট — ভিডিওর প্রচলিত শ্রেণি), protocol ১৭ = UDP, TTL ৫৭ (৬৪ থেকে শুরু হলে পথে ৭টি router পেরিয়েছে — অনুমান), আর সবচেয়ে চোখে পড়ার মতো — 0x20b9: DF ০, MF ১, offset ১৮৫. অর্থাৎ এটি একটি বড় UDP datagram-এর মাঝের টুকরো, যার ডেটা মূল ডেটার ১৪৮০ নম্বর বাইট থেকে শুরু। Total length ১৫০০ — MTU ১৫০০-এর link-এ যতটা ধরে।

৮ · Fragmentation আর reassembly — বড় datagram ছোট রাস্তায়

প্রতিটি link একটি সর্বোচ্চ আকারের packet বহন করতে পারে — তার MTU. সাধারণ Ethernet-এ ১৫০০ বাইট, PPPoE-র broadband-এ ১৪৯২, অনেক VPN tunnel-এ আরও কম, আর data center-এর jumbo frame-এ প্রায় ৯০০০. RFC 791 সব host-কে অন্তত ৫৭৬ বাইটের datagram গ্রহণ করতে বলে, আর IPv4-এর জন্য সর্বনিম্ন MTU ৬৮ বাইট। এখন ধরুন একটি ৪০০০ বাইটের datagram (বড় MTU-র একটি link থেকে আসা) এমন একটি router-এ পৌঁছাল, যার পরের link-এর MTU ১৫০০. DF = ০ হলে router সেটিকে টুকরো করে — একে বলে fragmentation. আর গন্তব্যে টুকরো জোড়া লাগানো — reassembly.

কুরিয়ারে একটি বড় আলমারি পাঠাচ্ছেন, কিন্তু পথের একটি ফেরিতে শুধু ছোট বাক্স ওঠে। তখন আলমারি খুলে কয়েকটি বাক্সে ভরা হয়, প্রতিটির গায়ে একই চালান নম্বর (Identification), “কোন অংশ” (offset), আর “আরও বাক্স আছে” কি না (MF). বাক্সগুলো আলাদা গাড়িতে, আলাদা ক্রমে পৌঁছাতে পারে; জোড়া লাগানো হয় শুধু প্রাপকের বাড়িতে — মাঝের কোনো গুদামে নয়।

নিয়মগুলো

  • প্রতিটি টুকরো একটি পূর্ণ IP datagram — নিজস্ব header-সহ; Identification, উৎস, গন্তব্য আর protocol মূলটির মতোই।
  • শেষটি ছাড়া প্রতিটি টুকরোর ডেটা ৮-এর গুণিতক বাইট; offset লেখা হয় ৮ বাইটের এককে।
  • শেষটি ছাড়া সব টুকরোয় MF = ১; শেষটিতে MF = ০.
  • প্রতিটি টুকরোর Total Length আর checksum নিজের মতো। জোড়া লাগায় শুধু চূড়ান্ত গন্তব্য — কারণ টুকরোগুলো ভিন্ন পথে যেতে পারে, আর মাঝের router-কে সরল রাখাই নকশার নীতি।

কেন ৮ বাইটের একক? — ছোট্ট একটি প্রমাণ

Flags আর offset মিলে একটি ১৬-বিটের ঘর: ৩ বিট flag, বাকি ১৩ বিট offset. ১৩ বিটে 213 = ৮১৯২টি মান (০–৮১৯১)। কিন্তু datagram-এর ডেটা হতে পারে প্রায় ৬৫,৫৩৫ বাইট পর্যন্ত। বাইটের এককে offset লিখলে ৮১৯১-এর পরের বাইট চেনানো যেত না। একক u বাইট হলে সর্বোচ্চ ৮১৯১u বাইট চেনানো যায়; ৬৫,৫৩৫ ÷ ৮১৯২ ≈ ৭.৯৯৯৯, তাই দরকার u ≥ ৮, আর ৮ হলো সবচেয়ে ছোট দুইয়ের ঘাত যা চলে। সর্বোচ্চ offset তাই ৮১৯১ × ৮ = ৬৫,৫২৮ বাইট — সর্বোচ্চ ডেটার (৬৫,৫৩৫ − ২০ = ৬৫,৫১৫) চেয়ে বেশি, তাই যথেষ্ট। এর দাম: শেষটি ছাড়া প্রতিটি টুকরোর ডেটা ৮-এর গুণিতক হতেই হবে।

প্রতি টুকরোর ডেটা P = ⌊(MTU − H) ÷ 8⌋ × 8 · টুকরোর সংখ্যা = ⌈D ÷ P⌉ · k-তম টুকরোর offset = k × P ÷ 8

পূর্ণ সমাধান করা উদাহরণ

প্রশ্ন: ৪০০০ বাইটের একটি IPv4 datagram (header ২০ বাইট, option নেই, Identification ধরা যাক 0x1f2e) MTU ১৫০০-এর link-এ পাঠাতে হবে। প্রতিটি টুকরোর Total Length, offset আর MF লিখুন।

সমাধান: ডেটা D = ৪০০০ − ২০ = ৩৯৮০ বাইট। প্রতি টুকরোয় সর্বোচ্চ ডেটা ১৫০০ − ২০ = ১৪৮০; ১৪৮০ ÷ ৮ = ১৮৫, পূর্ণসংখ্যা, তাই P = ১৪৮০. টুকরো = ⌈৩৯৮০ ÷ ১৪৮০⌉ = ⌈২.৬৯⌉ = ৩. ধাপে ধাপে দেখুন:

টুকরোর খাতা (সবগুলোর Identification = 0x1f2e)
এই ধাপে
Total Length
ডেটার বাইট
Offset (×8)
MF
  1. মূল datagram. Total Length ৪০০০, তার ২০ বাইট header, ৩৯৮০ বাইট ডেটা (বাইট ০ থেকে ৩৯৭৯)। DF = ০, তাই router ভাঙতে পারবে। পরের link-এর MTU ১৫০০.
  2. প্রতি টুকরোর মাপ। প্রতিটি টুকরোর নিজের ২০ বাইট header লাগবে, তাই ডেটার জায়গা ১৫০০ − ২০ = ১৪৮০. এটি ৮-এর গুণিতক কি না? ১৪৮০ ÷ ৮ = ১৮৫ — হ্যাঁ। তাই P = ১৪৮০, আর টুকরো লাগবে ৩টি।
  3. টুকরো ১. ডেটা বাইট ০–১৪৭৯, Total Length ১৪৮০ + ২০ = ১৫০০. Offset ০, MF = ১ (আরও আছে)। শুধু এই টুকরোতেই TCP বা UDP header থাকে — কারণ সেটি ডেটার একদম শুরুতে।
  4. টুকরো ২. ডেটা বাইট ১৪৮০–২৯৫৯, Total Length ১৫০০. Offset = ১৪৮০ ÷ ৮ = ১৮৫, MF = ১. খেয়াল করুন, offset-এ বাইট নয়, ৮-এর একক — পরীক্ষায় সবচেয়ে সাধারণ ভুল এখানেই।
  5. টুকরো ৩. বাকি ৩৯৮০ − ২৯৬০ = ১০২০ বাইট, Total Length ১০৪০. Offset = ২৯৬০ ÷ ৮ = ৩৭০, MF = ০ — এটিই শেষ। শেষ টুকরোর ডেটা ৮-এর গুণিতক হওয়ার দরকার নেই (১০২০ নয়ও)। তারে মোট গেল ৪০৪০ বাইট — দুটি বাড়তি header-এর ৪০ বাইট বেশি।
  6. প্রাপক জোড়া লাগাল। টুকরো পৌঁছাল ৩, ১, ২ ক্রমে। প্রাপক (উৎস, গন্তব্য, protocol, Identification) দিয়ে একটি buffer খোলে, offset অনুযায়ী সাজায়: ০ থেকে ১৪৮০ বাইট, তারপর ১৪৮০ থেকে, তারপর ২৯৬০ থেকে — কোথাও ফাঁক নেই, আর শেষটির MF = ০ বলে মোট দৈর্ঘ্য জানা (২৯৬০ + ১০২০ = ৩৯৮০)। ৪০০০ বাইটের datagram আবার তৈরি, এবার ওপরের স্তরে যায়।
  7. একটি টুকরো হারালে। টুকরো ২ পথে হারিয়ে গেলে বাইট ১৪৮০–২৯৫৯-এ ফাঁক থাকে। প্রাপক কিছুক্ষণ অপেক্ষা করে (Linux-এ ডিফল্ট ৩০ সেকেন্ড), তারপর বাকি দুটি টুকরোও ফেলে দেয় আর উৎসকে ICMP “Time Exceeded” (fragment reassembly) জানাতে পারে। IP নিজে আবার পাঠায় না — TCP বা application-কে পুরো ৪০০০ বাইট আবার পাঠাতে হয়।

এবার একই হিসাব কয়েকটি MTU-র জন্য, সাথে প্রাপকের জোড়া লাগানোর যাচাই — এলোমেলো ক্রমে আসা আর একটি টুকরো হারানো, দুই ক্ষেত্রেই:

// IPv4 fragmentation: split one datagram for an MTU, then check reassembly.
const HDR = 20;                                    // IPv4 header without options
function fragment(total, mtu) {
  const data = total - HDR;
  const chunk = Math.floor((mtu - HDR) / 8) * 8;   // non-last pieces: multiple of 8
  const out = [];
  for (let off = 0; off < data; off += chunk) {
    const n = Math.min(chunk, data - off);
    out.push({ total: n + HDR, data: n, off, mf: off + n < data ? 1 : 0 });
  }
  return out;
}
function reassemble(frags, data) {                 // receiver: any arrival order
  const got = [...frags].sort((a, b) => a.off - b.off);
  let next = 0;
  for (const f of got) { if (f.off !== next) return `hole at byte ${next}`; next += f.data; }
  const last = got[got.length - 1];
  return last.mf === 0 && next === data ? `OK, ${next} data bytes` : "last fragment missing";
}
for (const mtu of [1500, 1492, 576]) {
  const fr = fragment(4000, mtu);
  console.log(`--- 4000-byte datagram, MTU ${mtu}: ${fr.length} fragments ---`);
  console.log(" #  total  data  offset(x8)  offset(bytes)  MF");
  fr.forEach((f, i) => console.log(`${String(i + 1).padStart(2)}  ${String(f.total).padStart(5)}` +
    `  ${String(f.data).padStart(4)}  ${String(f.off / 8).padStart(10)}` +
    `  ${String(f.off).padStart(13)}  ${f.mf}`));
  const sent = fr.reduce((s, f) => s + f.total, 0);
  console.log(`bytes on the wire: ${sent} (extra headers: ${sent - 4000})`);
}
const fr = fragment(4000, 1500);
console.log("reassembly, arrival order 3,1,2: " + reassemble([fr[2], fr[0], fr[1]], 3980));
console.log("reassembly, fragment 2 lost:     " + reassemble([fr[0], fr[2]], 3980));

আউটপুট:

--- 4000-byte datagram, MTU 1500: 3 fragments ---
 #  total  data  offset(x8)  offset(bytes)  MF
 1   1500  1480           0              0  1
 2   1500  1480         185           1480  1
 3   1040  1020         370           2960  0
bytes on the wire: 4040 (extra headers: 40)
--- 4000-byte datagram, MTU 1492: 3 fragments ---
 #  total  data  offset(x8)  offset(bytes)  MF
 1   1492  1472           0              0  1
 2   1492  1472         184           1472  1
 3   1056  1036         368           2944  0
bytes on the wire: 4040 (extra headers: 40)
--- 4000-byte datagram, MTU 576: 8 fragments ---
 #  total  data  offset(x8)  offset(bytes)  MF
 1    572   552           0              0  1
 2    572   552          69            552  1
 3    572   552         138           1104  1
 4    572   552         207           1656  1
 5    572   552         276           2208  1
 6    572   552         345           2760  1
 7    572   552         414           3312  1
 8    136   116         483           3864  0
bytes on the wire: 4140 (extra headers: 140)
reassembly, arrival order 3,1,2: OK, 3980 data bytes
reassembly, fragment 2 lost:     hole at byte 1480

MTU ১৫০০-এর টেবিল হাতে করা উত্তরের সাথে হুবহু মেলে: ১৫০০/১৫০০/১০৪০, offset 0/185/370, MF 1/1/0. PPPoE-র ১৪৯২-এ ডেটার জায়গা ১৪৭২ (৮-এর গুণিতক, ১৮৪ × ৮), তাই offset 0/184/368. সবচেয়ে শিক্ষণীয় MTU ৫৭৬: ৫৭৬ − ২০ = ৫৫৬, যা ৮-এর গুণিতক নয়, তাই ডেটা নেমে আসে ৫৫২-এ আর প্রতিটি টুকরো ৫৭৬ নয়, ৫৭২ বাইট — MTU পুরো ভরানো যায় না। ৮টি টুকরোয় বাড়তি header ১৪০ বাইট। শেষ দুই লাইনে প্রাপকের দিক: এলোমেলো ক্রমে আসলেও offset দিয়ে সাজিয়ে ৩৯৮০ বাইট পুরো পাওয়া গেল; কিন্তু টুকরো ২ না এলে ১৪৮০ নম্বর বাইটে “hole” — পুরো datagram বাতিল।

আজ কেন fragmentation এড়ানো হয়

১৯৮৭ সালে Christopher Kent আর Jeffrey Mogul-এর বিখ্যাত প্রবন্ধ “Fragmentation Considered Harmful” যে যুক্তিগুলো দেয়, সেগুলো আজও সত্য:

  • ক্ষতি গুণ হয়: প্রতিটি টুকরো স্বাধীনভাবে p সম্ভাবনায় হারালে n টুকরোর datagram টেকে (১ − p)n সম্ভাবনায়। p = ১% হলে ৩ টুকরোয় datagram হারানোর সম্ভাবনা ≈ ২.৯৭%, ৮ টুকরোয় ≈ ৭.৭৩% — একটি হারালেই সব বৃথা।
  • Port থাকে শুধু প্রথম টুকরোয়: firewall, NAT আর load balancer পরের টুকরোগুলো চিনতে পারে না; অনেকে সেগুলো ফেলে দেয়।
  • প্রাপকের বোঝা আর আক্রমণের সুযোগ: জোড়া লাগাতে মেমরি আর টাইমার লাগে। ১৯৯০-এর দশকে একে অপরের ওপর চেপে বসা (overlapping) টুকরো পাঠিয়ে কিছু OS-কে অচল করার ঘটনা ঘটেছিল (“teardrop” নামে পরিচিত), আর অসমাপ্ত টুকরোর বন্যা দিয়ে reassembly-র মেমরি ভরিয়ে ফেলা যায়। প্রতিরক্ষা: আধুনিক stack overlapping টুকরো বাতিল করে, reassembly-র মেমরিতে সীমা রাখে, আর firewall অস্বাভাবিক টুকরো আটকায়।
  • Identification ফুরিয়ে যাওয়া: ১৬ বিটে মাত্র ৬৫,৫৩৬টি নম্বর; উচ্চ গতিতে একই নম্বর দ্রুত ফিরে আসে, আর ভিন্ন datagram-এর টুকরো ভুল করে জোড়া লাগতে পারে (RFC 4963 এই সমস্যার বর্ণনা দেয়)।

Path MTU Discovery

সমাধান হলো প্রেরক নিজেই শুরু থেকে এমন মাপে পাঠাবে, যা পুরো পথে ভাঙতে হবে না। ১৯৯০ সালের RFC 1191-এর Path MTU Discovery: প্রেরক DF = ১ দিয়ে পাঠায় (stepper-এর SYN-এর মতো)। পথের কোনো router-এর পরের link ছোট হলে সে packet ফেলে দেয় আর প্রেরককে ICMP “Destination Unreachable — Fragmentation Needed” (type 3, code 4) পাঠায়, সাথে পরের link-এর MTU. প্রেরক মাপ কমিয়ে আবার পাঠায়। ICMP-র বার্তাগুলোর বিস্তারিত পর্ব ২০-এ।

PMTUD black hole: কোনো firewall “নিরাপত্তার জন্য” সব ICMP আটকে দিলে প্রেরক কখনো জানতে পারে না যে packet বড়। লক্ষণটি পরিচিত: ওয়েবসাইটের সংযোগ হয় (handshake-এর ছোট packet পার হয়), কিন্তু পাতা লোড হতে হতে আটকে যায় (বড় packet নীরবে হারায়)। সমাধান: ICMP type 3 ঢালাওভাবে আটকানো নয়; সীমান্তে MSS clamping (পর্ব ০৩); আর RFC 4821/8899-এর মতো packetization-layer PMTUD, যা ICMP-র ওপর নির্ভর না করে ধীরে ধীরে মাপ পরীক্ষা করে। IPv6-এ router কখনো ভাঙেই না — শুধু উৎস ভাঙতে পারে (পর্ব ২১)।

আরও গভীরে: Linux-এ reassembly-র অপেক্ষা net.ipv4.ipfrag_time (ডিফল্ট ৩০ সেকেন্ড) আর অসমাপ্ত টুকরোর মোট মেমরি net.ipv4.ipfrag_high_thresh (কয়েক MB) দিয়ে নিয়ন্ত্রিত; সীমা ছাড়ালে নতুন টুকরো ফেলে দেওয়া হয়। Identification-এর মান অনুমানযোগ্য হলে বাইরে থেকে host-এর traffic আন্দাজ করা বা জাল টুকরো ঢোকানো সহজ হয়, তাই আধুনিক kernel এটি গন্তব্যভিত্তিক hash থেকে এলোমেলোভাবে বানায়; আর ২০১৩ সালের RFC 6864 বলে, DF = ১ থাকা (কখনো না-ভাঙা) datagram-এ Identification অনন্য হওয়ার দরকার নেই।

৯ · নিজের মেশিনে IPv4 — Linux, Windows আর container

তত্ত্ব শেষে নিজের চোখে দেখা যাক। নিচের স্ক্রিপ্ট এই পাতার কোড চালানোর container-এ তিনটি কাজ করে: iproute2-এর ip -4 -br addr দিয়ে ঠিকানা দেখায়, kernel-এর নিজের হিসাব /proc/net/fib_trie থেকে (পর্ব ০৬-এর procfs) local আর broadcast ঠিকানা পড়ে, আর bash-এর পূর্ণসংখ্যার হিসাব দিয়ে প্রতিটি ঠিকানার mask, network আর broadcast বের করে। টুল না থাকলে স্ক্রিপ্ট সে কথা জানায়:

to_int() { local IFS=.; set -- $1; echo $(( ($1 << 24) | ($2 << 16) | ($3 << 8) | $4 )); }
to_ip() { echo "$(( $1 >> 24 & 255 )).$(( $1 >> 16 & 255 )).$(( $1 >> 8 & 255 )).$(( $1 & 255 ))"; }
echo "== 1. ip -4 -br addr =="
if command -v ip >/dev/null; then ip -4 -br addr; else echo "  ip নেই"; fi
echo "== 2. /proc/net/fib_trie: local and broadcast entries =="
if [ -r /proc/net/fib_trie ]; then
  awk '/\/32 host LOCAL/ {print "  LOCAL     " p} /\/32 link BROADCAST/ {print "  BROADCAST " p}
       {p = $2}' /proc/net/fib_trie | sort -u
else echo "  /proc/net/fib_trie পড়া যাচ্ছে না"; fi
echo "== 3. network and broadcast, computed in bash =="
if command -v ip >/dev/null; then
  list=$(ip -4 -o addr show | awk '{print $2, $4}')
else list="lo 127.0.0.1/8"; echo "  (ip নেই, উদাহরণ হিসেবে loopback)"; fi
while read -r dev cidr; do
  [ -n "$cidr" ] || continue
  a=$(to_int "${cidr%/*}"); p=${cidr#*/}
  m=$(( p == 0 ? 0 : (0xFFFFFFFF << (32 - p)) & 0xFFFFFFFF ))
  net=$(( a & m )); bc=$(( net | (~m & 0xFFFFFFFF) ))
  echo "  $dev $cidr  mask=$(to_ip $m)  network=$(to_ip $net)  broadcast=$(to_ip $bc)  hosts=$(( p >= 31 ? 1 << (32 - p) : (1 << (32 - p)) - 2 ))"
done <<< "$list"

আসল রানের আউটপুট:

== 1. ip -4 -br addr ==
lo               UNKNOWN        127.0.0.1/8
tap0             UNKNOWN        10.0.2.100/24
== 2. /proc/net/fib_trie: local and broadcast entries ==
  BROADCAST 10.0.2.255
  BROADCAST 127.255.255.255
  LOCAL     10.0.2.100
  LOCAL     127.0.0.1
== 3. network and broadcast, computed in bash ==
  lo 127.0.0.1/8  mask=255.0.0.0  network=127.0.0.0  broadcast=127.255.255.255  hosts=16777214
  tap0 10.0.2.100/24  mask=255.255.255.0  network=10.0.2.0  broadcast=10.0.2.255  hosts=254

১ — container-এ দুটি interface: loopback lo-এ 127.0.0.1/8, আর কাল্পনিক tap0-এ 10.0.2.100/24 — RFC 1918-এর private ঠিকানা (container কীভাবে বাইরে যায়, তা পর্ব ০৬-এ দেখেছেন)। ২ — kernel ঠিকানা বসানোর সাথে সাথে নিজের “local” routing table-এ দুই ধরনের লাইন বানিয়েছে: LOCAL (এই ঠিকানায় আসা packet আমার) আর BROADCAST (10.0.2.255 আর 127.255.255.255 — এগুলো সবার জন্য)। আমরা হাতে যে broadcast ঠিকানা হিসাব করি, kernel-ও ঠিক তা-ই করে রেখেছে। ৩ — bash-এর হিসাব একই ফল দিল: 10.0.2.100/24 → network 10.0.2.0, broadcast 10.0.2.255, ২৫৪টি host; আর loopback-এর /8-এ ১,৬৭,৭৭,২১৪টি — যদিও ব্যবহার হচ্ছে একটি।

Windows-এ একই তথ্য দেয় ipconfig — prefix নয়, dotted mask দেখায়। নিচে একটি সাধারণ ল্যাপটপের উদাহরণ (চালানো যাবে না, শুধু পড়ার জন্য):

PS> ipconfig
Wireless LAN adapter Wi-Fi:
   IPv4 Address. . . . . . . . . . . : 192.168.0.105
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Default Gateway . . . . . . . . . : 192.168.0.1

Ethernet adapter Ethernet:
   Autoconfiguration IPv4 Address. . : 169.254.83.12
   Subnet Mask . . . . . . . . . . . : 255.255.0.0
   Default Gateway . . . . . . . . . :

Wi-Fi adapter স্বাভাবিক: 192.168.0.105/24, default gateway বাসার router. কিন্তু Ethernet adapter-এ “Autoconfiguration” আর 169.254.83.12 — অর্থাৎ তার লাগানো আছে, কিন্তু DHCP সার্ভার উত্তর দেয়নি, তাই Windows link-local ঠিকানা (APIPA) বসিয়েছে আর gateway ফাঁকা। “তার লাগানো, তবু ইন্টারনেট নেই” অভিযোগে প্রথমেই এটি দেখুন। macOS-এ ifconfig en0 একই তথ্য দেয়, mask লেখে hex-এ (netmask 0xffffff00).

১০ · AI-এর যুগে IPv4-এর হিসাব

“192.168.10.77/26-এর broadcast কত?” — AI এক সেকেন্ডে উত্তর দেবে, আর বেশিরভাগ সময় ঠিকও হবে। সমস্যা হলো বাকি সময়টুকু: ভুল উত্তরও একই আত্মবিশ্বাসে আসে। Subnet-এর হিসাব ভাষার মডেলের কাছে আসলে বিটের হিসাব নয়, শব্দের অনুমান — তাই এক-বিট এদিক-ওদিক হওয়া খুব স্বাভাবিক। এই বিষয়ে AI-এর পরিচিত ভুল:

AI-এর ভুলউদাহরণকীভাবে ধরবেন
Subnet-এর ভুল হিসাব/27-এ “৩২টি host” (−২ ভুলে যাওয়া), বা 192.168.10.70-কে /26-এর network বলাNetwork ঠিকানা block size-এর গুণিতক কি না দেখুন; ছোট calculator চালান
Class আর CIDR গুলিয়ে ফেলা“172.20.5.9 class B, তাই mask অবশ্যই 255.255.0.0”Prefix দেওয়া থাকলে class-এর কোনো ভূমিকা নেই
বিশেষ ব্লকের ভুল সীমাPrivate ব্লক “172.16.0.0/16”, বা 169.254-কে private বলাIANA-র special-purpose registry আর RFC 1918 মিলিয়ে দেখুন
Fragment offset বাইটে লেখাদ্বিতীয় টুকরোর offset “1480”Offset ঘর ৮ বাইটের এককে: ১৪৮০ ÷ ৮ = ১৮৫
পুরোনো কমান্ডifconfig, netstat -rnLinux-এ ip addr, ip route, ss; man ip
অনিরাপদ বা ক্ষতিকর পরামর্শ“নিরাপত্তার জন্য সব ICMP বন্ধ করুন”, “কাজ না করলে firewall খুলে দিন”ICMP type 3 বন্ধ করলে PMTUD ভাঙে; ন্যূনতম অনুমতির নীতি মানুন
Vendor-এর রীতিকে মান বলা, বানানো RFCCisco-র wildcard mask-কে “IP-র নিয়ম” বলা; অস্তিত্বহীন RFC নম্বরrfc-editor.org-এ নম্বর আর শিরোনাম খুঁজুন; vendor-এর ডকুমেন্টেশন

AI-কে হিসাব করতে বললে ধাপগুলো দেখাতে বলুন, যাতে আপনি প্রতিটি ধাপ মেলাতে পারেন:

আমি IPv4 addressing শিখছি। ঠিকানা 172.16.45.200/21 নিয়ে: ১. শুধু ফল নয় — যে octet-এ mask ভাঙছে, তার binary লিখে AND আর OR ধাপে ধাপে দেখাও। ২. Mask, network, broadcast, প্রথম ও শেষ ব্যবহারযোগ্য ঠিকানা আর host-সংখ্যা একটি টেবিলে দাও; 2^h − 2-এর h কত ধরলে, স্পষ্ট লেখো। ৩. ঠিকানাটি কোনো বিশেষ ব্লকে (RFC 1918, CGNAT, documentation) পড়ে কি না বলো, আর কোন RFC — শুধু নিশ্চিত হলে উল্লেখ করো। ৪. Linux-এ এটি যাচাইয়ের আধুনিক কমান্ড দাও (ifconfig নয়)। শেষে বলো, আমি কোন সহজ পরীক্ষায় তোমার উত্তর নিজে মিলিয়ে নিতে পারি।

AI-এর দেওয়া IPv4-উত্তর গ্রহণের আগে — চেকলিস্ট

পরীক্ষা ও ইন্টারভিউতে এই বিষয়ে প্রায়ই যা জিজ্ঞেস করা হয়:

  • IPv4 class A, B, C-এর পরিসর আর default mask? — A: 1–126, /8; B: 128–191, /16; C: 192–223, /24; D (224–239) multicast, E (240–255) সংরক্ষিত।
  • 192.168.10.77/26-এর network আর broadcast? — 192.168.10.64 আর 192.168.10.127; ব্যবহারযোগ্য .65–.126, ৬২টি।
  • Private IPv4 ব্লক কোনগুলো? — 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 (RFC 1918).
  • Fragment offset কেন ৮ বাইটের এককে? — ১৩ বিটে ৮১৯২টি মান; ৬৫,৫৩৫ বাইট চেনাতে একক অন্তত ৮ বাইট হতে হয়।
  • Router কেন প্রতিটি hop-এ checksum বদলায়? — TTL কমে বলে header বদলায়, তাই header checksum নতুন করে হিসাব করতে হয়।

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিয়ে নিজে কিছুক্ষণ ভাবুন — তারপর “→ উত্তর” চাপুন।

প্র ০১১৯৯০-এর দশকের শুরুতে classful ব্যবস্থা কোন সংকটে পড়েছিল, আর CIDR কীভাবে ইন্টারনেটকে বাঁচাল?

১৯৮০-র দশকের শেষে ইন্টারনেট গবেষণাগারের গণ্ডি ছেড়ে বিশ্ববিদ্যালয় আর কোম্পানিতে ছড়াচ্ছিল। প্রতিষ্ঠানগুলোর বেশিরভাগের দরকার ছিল কয়েকশো থেকে কয়েক হাজার ঠিকানা — ঠিক সেই মাপ, যার জন্য কোনো class ছিল না। Class C-র ২৫৪ ঠিকানা খুব কম, তাই সবাই class B চাইত; অথচ পুরো ভান্ডারে class B মাত্র ১৬,৩৮৪টি। IETF-এর ভেতরে তখন সতর্কবার্তা ওঠে যে এভাবে চললে কয়েক বছরের মধ্যেই class B ফুরিয়ে যাবে। ঠিকানা নিয়ে করণীয় খুঁজতে একটি কার্যদল (সাধারণত ROAD — Routing and Addressing — নামে উল্লিখিত) কাজ শুরু করে।

বিকল্প ছিল বড় প্রতিষ্ঠানকে অনেকগুলো class C দেওয়া, কিন্তু তাতে দ্বিতীয় সংকট বাড়ত — routing table-এর বিস্ফোরণ। প্রতিটি class C ছিল আলাদা নেটওয়ার্ক, তাই ইন্টারনেটের প্রতিটি মূল router-কে প্রতিটির জন্য আলাদা লাইন মনে রাখতে হতো। তখনকার router-এর মেমরি আর প্রক্রিয়াকরণ-ক্ষমতা এই হারে বাড়ছিল না।

CIDR (১৯৯৩ সালের দিকে RFC 1519) দুই সমস্যাকে একসাথে আক্রমণ করে। প্রথমত, যেকোনো মাপের ব্লক — /20, /22, /27 — দেওয়া সম্ভব হলো, তাই ২,০০০ যন্ত্রের প্রতিষ্ঠান পায় একটি /21 (২,০৪৬ host), class B-র ৬৫,৫৩৪ নয়। দ্বিতীয়ত, ঠিকানা দেওয়া শুরু হলো ভৌগোলিক আর ISP-ভিত্তিক শিকলে, যাতে একটি ISP-র সব গ্রাহকের ব্লক একটি বড় prefix-এর ভেতরে থাকে আর বাইরে মাত্র একটি route ঘোষণা হয়। এর জন্য routing protocol-কেও mask বহন করতে হতো; ইন্টারনেটের ISP-দের মধ্যকার protocol BGP-এর চতুর্থ সংস্করণ (BGP-4) এই ক্ষমতা নিয়েই ব্যাপকভাবে চালু হয়।

CIDR সমস্যার স্থায়ী সমাধান ছিল না — ঠিকানা তো সীমিতই — কিন্তু এটি প্রায় দুই দশক সময় কিনে দিয়েছিল, যার মধ্যে NAT ছড়িয়েছে আর IPv6 তৈরি হয়েছে। প্রকৌশলের ইতিহাসে এটি একটি দুর্লভ উদাহরণ, যেখানে চলমান বিশ্বব্যাপী ব্যবস্থার ভিত্তি বদলানো হয়েছে কোনো “বন্ধ করে নতুন চালু” দিন ছাড়াই।

মূল উপলব্ধি: অনমনীয় সীমা (class) সহজ, কিন্তু বাস্তবের চাহিদা কখনো তিনটি মাপে আসে না। নমনীয় prefix আর শিকলভিত্তিক বণ্টন একসাথে অপচয় আর routing table-এর বোঝা — দুটিই কমায়।

প্র ০২IPv4 ঠিকানা মাত্র ৩২ বিটের কেন? তখনই ১২৮ বিট বেছে নিলে কী হতো?

১৯৭০-এর দশকে TCP/IP যখন নকশা হচ্ছিল, তখন এটি ছিল একটি গবেষণা প্রকল্প — কয়েকটি নেটওয়ার্ক জোড়া লাগানোর পরীক্ষা। Vint Cerf বিভিন্ন সাক্ষাৎকারে বলেছেন বলে জানা যায় যে ৩২ বিট বেছে নেওয়ার সময় তাঁরা ভেবেছিলেন এটি একটি পরীক্ষা, পরে “আসল” সংস্করণে বড় ঠিকানা আসবে; পরীক্ষাটিই যে বিশ্বের ইন্টারনেট হয়ে যাবে, তা কেউ আশা করেননি।

তখনকার প্রেক্ষাপট ভাবুন। লিংকের গতি ছিল কিলোবিট পর্যায়ে, router-এর মেমরি কয়েকশো কিলোবাইট। প্রতিটি packet-এ দুটি ঠিকানা যায়; ১২৮ বিট হলে header-এ শুধু ঠিকানাই হতো ৩২ বাইট, যেখানে ৩২ বিটে ৮ বাইট। ছোট টার্মিনাল-ট্রাফিকের (প্রতিটি অক্ষর আলাদা packet) জন্য এটি বড় অপচয় মনে হতো। আর ৪২৯ কোটি তখন পৃথিবীর জনসংখ্যার কাছাকাছি একটি সংখ্যা, যখন কম্পিউটার ছিল হাতে গোনা কয়েক হাজার।

কিন্তু ঠিকানার ৪২৯ কোটি পুরোটা কখনো ব্যবহারযোগ্য নয়। Class D আর E মিলে এক-অষ্টমাংশ, loopback-এ একটি পুরো /8, আর শিকলভিত্তিক বণ্টনে প্রতিটি স্তরে কিছু ফাঁকা রাখতে হয় — ফোন নম্বরের মতোই, সব নম্বর একসাথে ভরা যায় না। শুরুর দিকে কিছু প্রতিষ্ঠান পুরো /8 পেয়েছিল (১.৬৮ কোটি ঠিকানা), যার বেশিরভাগ বহু বছর অব্যবহৃত ছিল।

১২৮ বিট তখন নিলে NAT হয়তো জন্মাত না, প্রতিটি যন্ত্র সরাসরি ঠিকানাযোগ্য থাকত, আর পরবর্তী ২০ বছরের IPv6 রূপান্তরের খরচ বাঁচত। আবার এমনও হতে পারত যে ভারী header-এর কারণে TCP/IP তখনকার প্রতিযোগীদের কাছে হেরে যেত। প্রকৌশলের সিদ্ধান্ত তার সময়ের সীমাবদ্ধতায় নেওয়া হয়; পরে সেটিকে “ভুল” বলা সহজ, কিন্তু সেটি সফল হয়েছিল বলেই আজ তা বদলানো এত কঠিন।

মূল উপলব্ধি: “অস্থায়ী” নকশা প্রায়ই স্থায়ী হয়ে যায়। সফল কোনো ব্যবস্থার মৌলিক ঘরের আকার (ঠিকানা, ID, counter) ঠিক করার সময় দীর্ঘমেয়াদি বৃদ্ধির কথা ভাবা জরুরি — Identification ঘরের ১৬ বিটও একই শিক্ষার আরেক উদাহরণ।

প্র ০৩Fragmentation একসময় IPv4-এর গুরুত্বপূর্ণ বৈশিষ্ট্য ছিল। আজ সবাই কেন এটি এড়াতে চায়, আর IPv6 কেন router-এর fragmentation বাদ দিল?

১৯৭০-৮০-র দশকে বিভিন্ন নেটওয়ার্কের MTU খুব আলাদা ছিল, আর IP-র লক্ষ্যই ছিল যেকোনো নেটওয়ার্ক জোড়া লাগানো। তাই পথের মাঝে টুকরো করার ক্ষমতা একটি স্বাভাবিক সমাধান মনে হয়েছিল — প্রেরককে পুরো পথের খবর জানতে হবে না।

১৯৮৭ সালে Kent ও Mogul-এর “Fragmentation Considered Harmful” প্রবন্ধ দেখায় যে এর দাম অনেক। একটি টুকরো হারালে পুরো datagram বাতিল, আর ওপরের স্তর (যেমন TCP) পুরোটা আবার পাঠায় — ফলে ক্ষতির হার টুকরোর সংখ্যার সাথে বাড়ে। মাঝের router-এ টুকরো করা CPU-র বাড়তি কাজ, আর প্রাপকের কাছে অসম্পূর্ণ টুকরোর জন্য মেমরি আর টাইমার রাখতে হয়। পরে ইন্টারনেটে NAT আর firewall ছড়ানোর পর সমস্যা আরও বাড়ে: port নম্বর থাকে শুধু প্রথম টুকরোয়, তাই এসব middlebox পরের টুকরোগুলো ঠিকমতো চিনতে পারে না, আর অনেকেই এগুলো ফেলে দেয়।

নিরাপত্তার দিকও আছে। Overlapping টুকরো দিয়ে কিছু পুরোনো OS অচল হয়েছিল, আর একই ডেটার দুই রকম overlapping টুকরো পাঠিয়ে IDS-কে এক রকম আর প্রাপককে আরেক রকম জিনিস দেখানোর কৌশল নিয়েও গবেষণা হয়েছে। প্রতিরক্ষা হিসেবে আধুনিক stack overlapping টুকরো পুরো বাতিল করে, আর IPv6-এর জন্য RFC 5722 তা বাধ্যতামূলক করে।

IPv6-এর নকশাকারীরা তাই সিদ্ধান্ত নেন: router কখনো ভাঙবে না; প্রয়োজনে শুধু উৎস ভাঙবে, আর পথের MTU জানবে PMTUD দিয়ে। প্রতিটি IPv6 link-এর MTU অন্তত ১২৮০ বাইট হতে হবে — যাতে ছোট packet প্রায় সব জায়গায় নিশ্চিন্তে যায়। কিন্তু এতে নির্ভরতা চলে গেছে ICMP-র ওপর; ICMP আটকানো firewall-এর পেছনে PMTUD-এর “black hole” আজও একটি পরিচিত সমস্যা, তাই ICMP-ছাড়া packetization-layer PMTUD (RFC 4821, RFC 8899) আর QUIC-এর মতো protocol-এর নিজস্ব মাপ-যাচাই এসেছে। DNS-ও এই পথে হেঁটেছে: ২০২০ সালের DNS Flag Day UDP উত্তর ১২৩২ বাইটের মধ্যে রাখার পরামর্শ দেয়, বড় হলে TCP.

মূল উপলব্ধি: নেটওয়ার্কের মাঝখানে “বুদ্ধিমান” সমাধান প্রান্তের জন্য অপ্রত্যাশিত সমস্যা তৈরি করে। কাজটি প্রান্তে সরিয়ে দেওয়া (end-to-end নীতি) সাধারণত বেশি টেকসই — যদিও তাতে নতুন নির্ভরতা (যেমন ICMP) আসে, যা নিজেও রক্ষা করতে হয়।

প্র ০৪IPv4 ঠিকানা কি সম্পত্তি? ঠিকানার বাজার, পুরোনো বড় ব্লক আর দেরিতে আসা দেশগুলোর ওপর ঘাটতির প্রভাব কী?

শুরুর দিকে ঠিকানা দেওয়া হতো প্রায় বিনামূল্যে, প্রয়োজন দেখিয়ে। ১৯৮০ আর ১৯৯০-এর দশকের শুরুতে কিছু বিশ্ববিদ্যালয়, প্রযুক্তি কোম্পানি আর সরকারি সংস্থা পুরো /8 ব্লক পেয়েছিল — প্রতিটিতে ১.৬৮ কোটি ঠিকানা। এগুলোকে বলা হয় “legacy” ব্লক। পরে কিছু প্রতিষ্ঠান অংশবিশেষ ফেরত দেয় বা বিক্রি করে; যেমন Stanford বিশ্ববিদ্যালয় তার /8 ফেরত দিয়েছিল আর MIT তার ব্লকের একটি বড় অংশ বিক্রি করেছে বলে প্রতিবেদনে এসেছে।

RIR-গুলোর ভান্ডার শেষ হওয়ার পর ঠিকানা কার্যত একটি বাজারপণ্যে পরিণত হয়েছে। RIR-গুলো নীতি করে দিয়েছে কীভাবে এক সদস্য আরেকজনকে ব্লক হস্তান্তর করতে পারবে, আর মধ্যস্থতাকারী (broker) প্রতিষ্ঠান গড়ে উঠেছে। প্রতি ঠিকানার দাম বিভিন্ন সময়ে কয়েক দশ মার্কিন ডলার পর্যন্ত উঠেছে বলে প্রতিবেদন আছে। দার্শনিক প্রশ্ন থেকেই যায়: ঠিকানা কি মালিকানা, নাকি ব্যবহারের অধিকার? RIR-গুলো সাধারণত দ্বিতীয়টিই বলে — বরাদ্দ হলো রেজিস্ট্রি-তে একটি নিবন্ধন, যার শর্ত আছে।

দেরিতে ইন্টারনেটে বড় হওয়া অঞ্চলগুলোর জন্য এর প্রভাব বাস্তব। যে দেশে ইন্টারনেট ব্যবহারকারী দ্রুত বেড়েছে মূলত ২০১০-এর দশকে, মোবাইল ডেটার মাধ্যমে, তাদের হাতে মাথাপিছু public IPv4 ঠিকানা স্বভাবতই কম। বাংলাদেশসহ এমন অনেক দেশে ISP আর মোবাইল অপারেটররা তাই CGNAT-এর ওপর নির্ভর করে বলে ধারণা করা হয় — একটি public ঠিকানার পেছনে বহু গ্রাহক। এর ফলে নিজের বাসা থেকে সার্ভার চালানো, কিছু অনলাইন গেম বা peer-to-peer অ্যাপ কঠিন হয়, আর কোনো একজন গ্রাহকের অপব্যবহারে পুরো ঠিকানা ব্ল্যাকলিস্টে গেলে অন্যরাও ভোগেন।

মূল উপলব্ধি: প্রযুক্তিগত সম্পদের শুরুর বণ্টন দীর্ঘস্থায়ী অসমতা তৈরি করতে পারে। নেটওয়ার্ক প্রকৌশলীর কাছে IPv4-এর ঘাটতি শুধু হিসাবের বিষয় নয় — খরচ, নকশা (CGNAT, IPv6) আর ব্যবহারকারীর অভিজ্ঞতার প্রশ্ন।

প্র ০৫বিশেষ ঠিকানা আর ঠিকানা লেখার অদ্ভুত রূপ কীভাবে নিরাপত্তার সমস্যা তৈরি করে, আর প্রতিরক্ষা কী?

অনেক ওয়েব অ্যাপ ব্যবহারকারীর দেওয়া URL থেকে ডেটা আনে — যেমন “এই লিংকের ছবিটি দেখান”। আক্রমণকারী যদি সেই URL-এ অ্যাপের ভেতরের ঠিকানা দেয় (127.0.0.1, private ঠিকানা, বা cloud-এর বিশেষ link-local ঠিকানা 169.254.169.254, যেখানে অনেক cloud প্ল্যাটফর্ম সার্ভারের নিজস্ব metadata ও অস্থায়ী পরিচয়পত্র রাখে), তাহলে সার্ভার নিজেই নিজের গোপন সেবায় অনুরোধ পাঠিয়ে ফেলতে পারে। এই ধরনের দুর্বলতাকে বলে SSRF (server-side request forgery); কয়েকটি বড় তথ্য-ফাঁসের ঘটনায় এর ভূমিকা ছিল বলে প্রতিবেদনে এসেছে।

অনেক অ্যাপ সরল নিষেধ-তালিকা দিয়ে আটকানোর চেষ্টা করে — “127.0.0.1 লেখা থাকলে বাতিল”। কিন্তু অংশ ২-এ দেখেছেন, একই ঠিকানা অনেকভাবে লেখা যায়: শুরুতে শূন্য দিলে কিছু parser octal ধরে, কিছু সিস্টেম পুরো ঠিকানাকে একটি দশমিক পূর্ণসংখ্যা হিসেবেও মানে, আবার 127.0.0.0/8-এর যেকোনো ঠিকানাই loopback. যাচাইকারী আর আসল সংযোগকারী যদি ঠিকানা ভিন্নভাবে পড়ে, তবে যাচাই ফাঁকি খায়। DNS-এর নাম দিয়েও একই খেলা হয়: নামটি যাচাইয়ের সময় public ঠিকানা দেয়, সংযোগের সময় private (DNS rebinding).

আরেকটি পরিচিত ভুল সার্ভার bind করা। ডেভেলপার পরীক্ষার জন্য ডেটাবেস বা admin প্যানেল 0.0.0.0-তে চালান — যার মানে “সব interface”, শুধু নিজের মেশিন নয়। Cloud সার্ভারে এতে সেবাটি পুরো ইন্টারনেটে খুলে যায়।

প্রতিরক্ষার নীতি: (১) ঠিকানা নিজে parse না করে কঠোর, মানসম্মত library দিয়ে একটি canonical রূপে আনুন, তারপর prefix ধরে (CIDR) যাচাই করুন; (২) নিষেধ-তালিকার বদলে অনুমোদিত-তালিকা (allowlist) ব্যবহার করুন; (৩) নাম resolve করার পর যে ঠিকানায় আসলে সংযোগ হচ্ছে, সেটিই যাচাই করুন; (৪) cloud-এর metadata সেবার সুরক্ষিত সংস্করণ (যেমন session token চাওয়া) চালু রাখুন আর অ্যাপের বাইরে যাওয়ার পথে নেটওয়ার্ক-নীতি বসান; (৫) শুধু-স্থানীয় সেবা 127.0.0.1-এ bind করুন। এখানে আক্রমণ শুধু ধারণাগতভাবে বলা হলো — উদ্দেশ্য নিজের সিস্টেম রক্ষা।

মূল উপলব্ধি: ঠিকানার নিয়ম (কোন ব্লক কী, কীভাবে লেখা যায়) জানা শুধু পরীক্ষার বিষয় নয় — নিরাপদ কোড লেখার পূর্বশর্ত। একই জিনিসের একাধিক রূপ থাকলে সবসময় canonical রূপে এনে তারপর সিদ্ধান্ত নিতে হয়।

অনুশীলন

খাতা-কলম নিয়ে বসুন — হিসাবগুলো নিজে করে তারপর উত্তর মেলান।

  1. হাতে হিসাব: 172.16.45.200/21 ঠিকানার subnet mask, network ঠিকানা, broadcast ঠিকানা, প্রথম ও শেষ ব্যবহারযোগ্য ঠিকানা আর host-সংখ্যা বের করুন। ঠিকানাটি কোন class-এর, আর কোনো বিশেষ ব্লকে পড়ে কি?

    /21 = ১৬ + ৫, তাই প্রথম দুই octet পুরো network, তৃতীয় octet-এ ৫টি ১: 11111000 = ২৪৮. Mask 255.255.248.0, তৃতীয় octet-এ block size ২৫৬ − ২৪৮ = ৮.

    • তৃতীয় octet ৪৫ = 00101101; AND 11111000 = 00101000 = ৪০. চতুর্থ octet-এর সব বিট host অংশ, তাই ০. Network = 172.16.40.0 (শর্টকাট: ৮-এর গুণিতকে ৪৫-এর নিচের সংখ্যা ৪০)।
    • Host বিট সব ১: তৃতীয় octet 00101111 = ৪৭, চতুর্থ ২৫৫. Broadcast = 172.16.47.255.
    • ব্যবহারযোগ্য 172.16.40.1 – 172.16.47.254, host = 211 − 2 = ২০৪৬.

    প্রথম octet ১৭২, তাই পুরোনো হিসাবে class B — কিন্তু prefix /21, তাই class এখানে অপ্রাসঙ্গিক। ঠিকানাটি RFC 1918-এর private ব্লক 172.16.0.0/12-এর ভেতরে। অংশ ৪-এর calculator-এ "172.16.45.200/21" দিয়ে মিলিয়ে নিতে পারেন — ঠিক এই উত্তরই ছাপে।

  2. ধাপে ধাপে trace (আবার ভাঙা): অংশ ৮-এর উদাহরণের টুকরো ২ (Total Length ১৫০০, offset ১৮৫, MF = ১) পরের পথে MTU ৫৭৬-এর একটি link-এ পৌঁছাল। এটি কয়টি টুকরোয় ভাঙবে? প্রতিটির Total Length, offset আর MF লিখুন।

    এই টুকরোর ডেটা ১৪৮০ বাইট (মূল ডেটার বাইট ১৪৮০–২৯৫৯)। MTU ৫৭৬-এ ডেটার জায়গা ৫৫৬, ৮-এর গুণিতকে নামিয়ে ৫৫২. ১৪৮০ = ৫৫২ + ৫৫২ + ৩৭৬ — ৩টি টুকরো.

    • ২ক: Total Length ৫৭২, offset = ১৮৫ (শুরু একই), MF = ১.
    • ২খ: Total Length ৫৭২, offset = ১৮৫ + ৫৫২ ÷ ৮ = ১৮৫ + ৬৯ = ২৫৪, MF = ১.
    • ২গ: Total Length ৩৭৬ + ২০ = ৩৯৬, offset = ২৫৪ + ৬৯ = ৩২৩, MF = ১.

    দুটি ফাঁদ: offset শূন্য থেকে নয়, মূল datagram-এর হিসাবে — তাই ১৮৫ যোগ হয়। আর শেষ টুকরো ২গ-তেও MF = ১, কারণ এর পরে মূল datagram-এর টুকরো ৩ এখনো আছে। প্রাপক এই নতুন টুকরোগুলো আর আগের টুকরো ১ ও ৩ — সবগুলো একই Identification দিয়ে একসাথে জোড়ে; কে কোন router-এ ভেঙেছে, তা তার জানার দরকার নেই।

  3. আউটপুট অনুমান করুন: অংশ ৪-এর calculator-এর শেষের ঠিকানা-তালিকায় শুধু "192.168.10.130/25" দিলে কোন পাঁচটি লাইন ছাপা হবে? আগে খাতায় লিখুন, তারপর চালিয়ে মিলিয়ে নিন।
    === 192.168.10.130/25  class C (default /24)  ->  private (RFC 1918)
      address  11000000.10101000.00001010.10000010
      mask     11111111.11111111.11111111.10000000  = 255.255.255.128
      network  192.168.10.128   broadcast 192.168.10.255
      usable   192.168.10.129 - 192.168.10.254   hosts = 126

    ১৩০ = ১২৮ + ২ = 10000010. /25-এ শেষ octet-এর শুধু প্রথম বিট network অংশ, তাই network-এর শেষ octet 10000000 = ১২৮, broadcast 11111111 = ২৫৫, host 27 − 2 = ১২৬. লক্ষ করুন, stepper-এর 192.168.10.77/26 আর এই ঠিকানা একই /24-এর ভেতরে, কিন্তু আলাদা subnet-এ — তাই এরা router ছাড়া সরাসরি কথা বলতে পারবে না।

  4. কোড লিখুন: JavaScript-এ একটি ফাংশন sameNetwork(a, b, prefix) লিখুন, যা বলে দুটি IPv4 ঠিকানা একই prefix-এর একই নেটওয়ার্কে কি না। 192.168.10.77 আর 192.168.10.130-এর জন্য /26 আর /24 দিয়ে পরীক্ষা করুন। (Host আসলে প্রতিটি packet পাঠানোর আগে এই সিদ্ধান্তই নেয়: একই নেটওয়ার্ক হলে সরাসরি, না হলে default gateway-এর কাছে।)
    const toInt = s => s.split(".").reduce((a, o) => a * 256 + Number(o), 0);
    const maskOf = p => (p === 0 ? 0 : (0xffffffff << (32 - p)) >>> 0);
    function sameNetwork(a, b, prefix) {
      const m = maskOf(prefix);
      return ((toInt(a) & m) >>> 0) === ((toInt(b) & m) >>> 0);
    }
    console.log(sameNetwork("192.168.10.77", "192.168.10.130", 26));  // false
    console.log(sameNetwork("192.168.10.77", "192.168.10.130", 24));  // true
    console.log(sameNetwork("192.168.10.77", "192.168.10.100", 26));  // true

    দুই ঠিকানাকেই একই mask দিয়ে AND করে network অংশ তুলনা। /26-এ ৭৭-এর network .64 আর ১৩০-এর .128 — আলাদা, তাই false; /24-এ দুটিরই 192.168.10.0 — true. এখানেও >>> 0 জরুরি, নইলে ১২৮-এর বেশি প্রথম octet-এর ঠিকানায় JavaScript ঋণাত্মক সংখ্যা দেবে। prefix === 0-এর আলাদা শাখাও দরকার: JavaScript-এ ৩২ ঘর shift আসলে ০ ঘর shift হয়।

নিজেকে যাচাই করুন

ভুল হলে কারণসহ ব্যাখ্যা পাবেন, আবার চেষ্টাও করতে পারবেন।

ক্রমএকটি CIDR ঠিকানা থেকে network আর broadcast বের করার ধাপগুলো সাজান (▲▼ চেপে সরান)

  1. Prefix থেকে network আর host বিটের সংখ্যা ঠিক করা
  2. যে octet-এ সীমা পড়েছে, সেটি binary-তে লেখা
  3. Prefix থেকে mask তৈরি করা
  4. ঠিকানা AND mask করে network ঠিকানা পাওয়া
  5. Host বিট সব ১ করে broadcast ঠিকানা পাওয়া
  6. Network + ১ থেকে broadcast − ১ পর্যন্ত ব্যবহারযোগ্য পরিসর লেখা

Classful addressing অনুযায়ী 172.20.5.9 ঠিকানাটি কোন class-এর, আর তার default mask কী?

  • Class A, 255.0.0.0
  • Class B, 255.255.0.0
  • Class C, 255.255.255.0
  • Class D, কোনো mask নেই

192.168.10.77/26 ঠিকানার network ঠিকানা কোনটি?

  • 192.168.10.0
  • 192.168.10.64
  • 192.168.10.77
  • 192.168.10.127

একটি /27 নেটওয়ার্কে সর্বোচ্চ কয়টি host ঠিকানা ব্যবহার করা যায়?

  • ২৭
  • ৩২
  • ৩০
  • ৬২

নিচের কোন ঠিকানাটি RFC 1918-এর private ঠিকানা?

  • 172.32.1.1
  • 172.20.1.1
  • 169.254.1.1
  • 100.64.1.1

একটি IPv4 header-এর প্রথম বাইট 0x46. Header-এর দৈর্ঘ্য কত বাইট?

  • ৬ বাইট
  • ২০ বাইট
  • ২৪ বাইট
  • ৭০ বাইট

৪০০০ বাইটের একটি IPv4 datagram (header ২০ বাইট, option নেই) MTU ১৫০০-এর link-এ টুকরো করা হলো। তৃতীয় (শেষ) টুকরোর Fragment Offset ঘরে কোন মান থাকবে?

  • ০
  • ১৮৫
  • ২৯৬০
  • ৩৭০

শব্দকোষ

লেখার মধ্যে ডটেড দাগ দেওয়া শব্দে মাউস রাখুন বা চাপুন — অর্থ দেখাবে। এই পর্বের সব নতুন শব্দ এখানে একসাথে:

মনে রাখুন

  1. IPv4 ঠিকানা ৩২ বিটের, একটি interface-এর অবস্থান চেনায়; dotted decimal-এ চার octet, প্রতিটি ০–২৫৫.
  2. Classful: A (0–127, /8), B (128–191, /16), C (192–223, /24), D multicast, E সংরক্ষিত — বাঁধা মাপের জন্য অপচয় আর routing table-এর স্ফীতি।
  3. CIDR: network = ঠিকানা AND mask, broadcast = host বিট সব ১, host = 2h − 2 (/31 আর /32 ব্যতিক্রম); পাশাপাশি ব্লক একটি prefix-এ aggregate হয়।
  4. বিশেষ ব্লক: 127/8 loopback, 169.254/16 link-local, 10/8 · 172.16/12 · 192.168/16 private, 100.64/10 CGNAT, তিনটি documentation /24; বণ্টন IANA → RIR (বাংলাদেশে APNIC) → ISP.
  5. Header সাধারণত ২০ বাইট; fragmentation-এ offset ৮ বাইটের এককে, শেষটি ছাড়া MF = ১; আজ DF = ১ আর Path MTU Discovery দিয়ে ভাঙা এড়ানো হয়।

পরের পর্বে: একটি /24 হাতে নিয়ে অফিসের পাঁচটি বিভাগকে মাপমতো ভাগ করে দিতে হবে — কোনোটায় ১০০ জন, কোনোটায় মাত্র ২টি router-এর link. Subnetting, CIDR আর VLSM — ধাপে ধাপে হিসাব।

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

এই পর্বটি শেয়ার করুন:
এই পর্বে ভুল পেয়েছেন? জানান