ทุกอย่างที่คุณทำบนอินเทอร์เน็ตวางอยู่บนโพรโทคอลตัวเดียว และโพรโทคอลตัวนั้น ไม่รับประกันอะไรให้คุณเลยสักอย่าง
ไม่รับประกันว่าข้อมูลจะไปถึง ไม่รับประกันว่าจะไปถึงตามลำดับ ไม่รับประกันว่า ข้อมูลจะไม่เสียหาย และถ้าหายก็ไม่มีใครบอกใครทั้งนั้น
ฟังดูเหมือนของที่ออกแบบมาไม่ดี แต่มันคือเหตุผลเดียวที่อินเทอร์เน็ตขยายมาถึง ทุกวันนี้ได้ หน้านี้อธิบายว่าทำไม
เว็บนี้มีบทความเรื่อง ping, traceroute และ DNS อยู่แล้ว ทั้งสามเรื่องอ้างถึงฟิลด์และพฤติกรรมของ IP อยู่ตลอดโดยไม่เคยกางให้ดู — TTL, การแตกแฟรกเมนต์, บิต DF, หมายเลขโพรโทคอล, เลขวงส่วนตัว หน้านี้คือฐานที่อยู่ใต้ทั้งสามเรื่องนั้น
ถ้ายังไม่เคยดูมาก่อน เริ่มตรงนี้
พิมพ์คำสั่งนี้บนแมคหรือลินุกซ์ เพื่อถามเครื่องว่าถ้าจะส่งไปที่ 8.8.8.8 มันจะส่งออกทางไหน
route -n get 8.8.8.8 # macOS และ BSD
ip route get 8.8.8.8 # Linux
ได้ประมาณนี้
destination: 8.8.8.8
gateway: 192.168.1.1
interface: en0
สามบรรทัดนี้คือการทำงานทั้งหมดของ IP ในหนึ่งภาพ — เครื่องดูปลายทาง เทียบกับตารางของตัวเอง แล้วตัดสินใจว่าจะโยนให้ใครต่อ จบเท่านั้น ไม่มีการติดต่อล่วงหน้า ไม่มีการตกลงอะไรกับใคร
กันยายน 1981 — เอกสารที่ยังใช้อยู่ทุกวันนี้
IP นิยามไว้ใน RFC 791 เผยแพร่เดือนกันยายน 1981 บรรณาธิการคือ Jon Postel ภายใต้ DARPA เอกสารนี้แทนที่ RFC 760 และเอกสารรุ่นก่อนหน้า อีกจำนวนหนึ่ง
สี่สิบกว่าปีผ่านไป แกนกลางยังไม่เปลี่ยน แพ็กเก็ตที่เครื่องคุณส่งออกไป เมื่อกี้มีหน้าตาเหมือนกับที่เอกสารฉบับนั้นอธิบายไว้ทุกฟิลด์
ชื่อ Postel จะโผล่มาเรื่อย ๆ ถ้าอ่านเว็บนี้ต่อ — เขาเป็นบรรณาธิการของ RFC 792 ที่นิยาม ICMP ซึ่งเป็นฐานของ ping และ traceroute ด้วย
แนวคิดการออกแบบ — ทำไมถึงไม่รับประกันอะไรเลย
1. ไม่รับประกันอะไรเลย และเขียนไว้ตรง ๆ
RFC 791 ไม่ได้เลี่ยงเรื่องนี้ มันประกาศไว้ตรง ๆ ว่า
โพรโทคอลอินเทอร์เน็ตไม่ได้ให้บริการสื่อสารที่เชื่อถือได้ ไม่มีการตอบรับ ทั้งแบบปลายทางถึงปลายทางและแบบรายฮอป ไม่มีการควบคุมความผิดพลาดของข้อมูล มีเพียง checksum ของส่วนหัว ไม่มีการส่งซ้ำ ไม่มีการควบคุมปริมาณ
อ่านแล้วเหมือนรายการข้อบกพร่อง แต่มันคือรายการสิ่งที่จงใจไม่ทำ
เหตุผลคือถ้า IP รับประกันเรื่องพวกนี้ อุปกรณ์ทุกตัวระหว่างทางจะต้องจำสถานะ ของทุกการเชื่อมต่อที่วิ่งผ่านมัน เราเตอร์ที่ส่งต่อทราฟฟิกล้านการเชื่อมต่อ ต้องเก็บข้อมูลล้านชุด และถ้ามันรีบูต ทุกอย่างที่วิ่งผ่านมันจะพังหมด
การไม่รับประกันอะไรเลยแปลว่าเราเตอร์ไม่ต้องจำอะไรเลย ตัวไหนพังก็แทนได้ เส้นทางเปลี่ยนกลางคันก็ไม่มีใครเดือดร้อน เพิ่มอุปกรณ์เข้าไปเท่าไหร่ก็ได้
ความน่าเชื่อถือถูกผลักขึ้นไปให้ชั้นบนที่ปลายทางทั้งสองฝั่งจัดการกันเอง — TCP นับลำดับและส่งซ้ำให้ ส่วน UDP ไม่สนใจเลยเพราะบางงานไม่ต้องการ
2. ตัดสินใจทีละฮอป ไม่มีเส้นทางเก็บอยู่ในแพ็กเก็ต
ในหัวแพ็กเก็ตมีแค่ "มาจากไหน" กับ "จะไปไหน" ไม่มีช่องสำหรับเก็บเส้นทาง
เราเตอร์แต่ละตัวจึงตัดสินใจของตัวเองโดยไม่รู้ว่าตัวก่อนหน้าคิดอะไร และไม่สนใจว่าตัวถัดไปจะคิดอะไร มันดูเลขปลายทาง เทียบตาราง เลือกทางออก จบ
นี่คือรากของสองเรื่องที่อธิบายไว้ในบทความอื่นแล้ว — traceroute พิมพ์เส้นทางที่แพ็กเก็ตจริงอาจไม่เคยเดิน เพราะแต่ละแพ็กเก็ตถูกตัดสินใจใหม่ทุกครั้ง และ ping วัดเวลาไปกลับได้แต่บอกไม่ได้ว่าขากลับเดินทางเดียวกับขาไป
3. checksum คุ้มเฉพาะส่วนหัว
ข้อนี้ดูเหมือนความประหยัดแบบขี้เหนียว แต่มีเหตุผลที่ RFC เขียนไว้เอง
checksum ของส่วนหัวเท่านั้น เนื่องจากบางฟิลด์ในส่วนหัวเปลี่ยนค่า (เช่น time to live) จึงต้องคำนวณและตรวจสอบใหม่ทุกจุดที่มีการประมวลผลส่วนหัว
เพราะ TTL ลดลงทุกฮอป checksum จึงต้องคำนวณใหม่ทุกฮอปด้วย ถ้าให้มันคุ้ม ข้อมูลทั้งก้อนด้วย เราเตอร์ทุกตัวจะต้องอ่านทุกไบต์ของทุกแพ็กเก็ตเพื่อคำนวณใหม่ ซึ่งแพงเกินไปมากสำหรับงานที่ต้องทำเป็นล้านครั้งต่อวินาที
ความถูกต้องของข้อมูลจึงเป็นงานของชั้นบนอีกเช่นกัน และ IPv6 ตัด checksum ของส่วนหัวออกไปเลยด้วยเหตุผลเดียวกันคือชั้นบนตรวจอยู่แล้ว
ในหัวแพ็กเก็ตมีอะไรอยู่บ้าง
ยี่สิบไบต์นี้คือทุกอย่างที่เราเตอร์กลางทางต้องรู้ ฟิลด์ที่ควรจำมีไม่กี่ตัว
Version 4 หรือ 6
IHL ความยาวของหัว บอกว่ามี Options ต่อท้ายไหม
Total Length ความยาวทั้งแพ็กเก็ต สูงสุด 65535
Identification ใช้จับคู่ชิ้นส่วนตอนแตกแฟรกเมนต์
Flags มีบิต DF ห้ามแตก และ MF ยังมีชิ้นต่อ
Fragment Offset ชิ้นนี้เป็นข้อมูลตำแหน่งที่เท่าไหร่ของก้อนเดิม
TTL เหลือผ่านได้อีกกี่ฮอป
Protocol ข้างในเป็นอะไร
Header Checksum ตรวจเฉพาะหัว คำนวณใหม่ทุกฮอป
Source มาจากไหน 32 บิต
Destination จะไปไหน 32 บิต
สังเกตว่าไม่มีฟิลด์ไหนเลยที่เกี่ยวกับความน่าเชื่อถือ ไม่มีหมายเลขลำดับ ไม่มีช่องตอบรับ ไม่มีตัวนับการส่งซ้ำ เพราะ IP ไม่ทำเรื่องพวกนั้น
เลขที่อยู่ไม่ใช่เลขสี่ตัว มันคือบิต 32 ตัว
ถ้ามีข้อเดียวที่อยากให้จำจากหน้านี้ ให้เป็นข้อนี้
255.255.255.0 ไม่ใช่ตัวเลขสี่ชุด มันคือ บิต 1 จำนวน 24 ตัวเรียงกัน แล้วตามด้วยบิต 0 อีก 8 ตัว การเขียนเป็นเลขสี่ชุดคั่นจุดเป็นแค่วิธีเขียน ให้คนอ่านง่าย ไม่ใช่สิ่งที่เครื่องเห็น
พอมองเป็นบิตแล้ว /25 /26 /30 จะเข้าใจได้ทันที — มันคือการเลื่อนเส้นแบ่ง ไปทางขวาทีละบิต และทุกครั้งที่เลื่อนไปขวาหนึ่งบิต วงจะเล็กลงครึ่งหนึ่ง
เครื่องใช้เส้นแบ่งนี้ตัดสินคำถามเดียว — ปลายทางอยู่วงเดียวกับฉันไหม
- อยู่วงเดียวกัน → ส่งตรงไปหาเลย
- คนละวง → ส่งให้เกตเวย์แล้วให้มันจัดการต่อ
นั่นแปลว่าสองเครื่องที่ตั้ง mask ไม่ตรงกันจะตอบคำถามนี้ไม่ตรงกัน เครื่องหนึ่งคิดว่าอยู่วงเดียวกันเลยส่งตรง อีกเครื่องคิดว่าคนละวงเลยส่งให้เกตเวย์ ผลคือคุยกันได้ทางเดียว ซึ่งเป็นอาการที่ตามหาสาเหตุยากมากถ้าไม่รู้จัก
เครื่องเลือกทางออกอย่างไร
ตารางเส้นทางจริงของเครื่องที่เขียนบทความนี้ ย่อเหลือแก่น
127.0.0.0/8 -> lo0 ตัวเอง
192.168.1.0/24 -> en0 วงเดียวกัน ส่งตรง
0.0.0.0/0 -> 192.168.1.1 ที่เหลือทั้งจักรวาล
กฎการเลือกมีข้อเดียวคือ prefix ยาวที่สุดที่ตรงกับปลายทางชนะ ยิ่งเจาะจง ยิ่งได้ใช้
- ไป
8.8.8.8→ ตรงเฉพาะ0.0.0.0/0→ ส่งให้เกตเวย์ - ไป
192.168.1.5→ ตรงทั้ง/24และ/0แต่/24ยาวกว่า → ส่งตรง
0.0.0.0/0 คือเส้นทางค่าเริ่มต้น ความหมายจริงของมันคือการยอมรับว่าไม่รู้ — "ปลายทางนี้ฉันไม่รู้จัก ส่งให้คนที่น่าจะรู้มากกว่าฉัน"
และเพราะทุกเครื่องบนเส้นทางคิดแบบเดียวกัน แพ็กเก็ตจึงเดินทางไปได้ทั่วโลก โดยไม่มีใครสักคนรู้เส้นทางทั้งเส้น
Protocol — ฟิลด์ที่บอกว่าข้างในเป็นอะไร
IP ไม่สนใจเลยว่าข้างในเป็นอะไร มันแค่พาไปให้ถึง แล้วปลายทางอ่านเลขนี้ เพื่อส่งต่อให้ถูกคน
1 ICMP ping และ traceroute ใช้ตัวนี้
6 TCP เว็บ อีเมล ssh
17 UDP DNS เป็นหลัก และวิดีโอคอล
58 ICMPv6 ฝั่ง IPv6 ซึ่งทำหน้าที่มากกว่าฝั่ง IPv4 มาก
ถ้าเคยอ่านบทความ DNS มาแล้วจะจำได้ว่าคำตอบที่ใหญ่เกิน จะเปลี่ยนไปใช้ TCP — นั่นคือการเปลี่ยนเลขในฟิลด์นี้จาก 17 เป็น 6 ทั้งที่เป็นการถามเรื่องเดียวกัน
การแตกแฟรกเมนต์ และเหตุผลที่ IPv6 เลิกทำ
แต่ละลิงก์รับแพ็กเก็ตได้ใหญ่ไม่เท่ากัน ค่านั้นเรียกว่า MTU อีเทอร์เน็ตปกติคือ 1500 ไบต์ ส่วนลูปแบ็กในเครื่องเดียวกันใหญ่กว่ามาก
$ ifconfig en0 | grep mtu
... mtu 1500
$ ifconfig lo0 | grep mtu
... mtu 16384
เมื่อแพ็กเก็ตใหญ่เกินลิงก์ IPv4 อนุญาตให้แบ่งเป็นชิ้น ๆ ได้ ทดสอบจริงได้เลย
$ ping -c 1 -s 3000 192.168.1.1
3008 bytes from 192.168.1.1: icmp_seq=0 ttl=64 time=8.961 ms
3008 ไบต์กลับมาครบทั้งที่ลิงก์รับได้ทีละ 1500 — แปลว่ามันถูกแบ่งเป็นสามชิ้น ส่งไป แล้วประกอบกลับที่ปลายทาง
ทั้งสามชิ้นใช้ค่า Identification เดียวกันเพื่อให้รู้ว่าเป็นก้อนเดียวกัน ใช้ Fragment Offset บอกตำแหน่ง และบิต MF เป็น 0 เฉพาะชิ้นสุดท้าย
RFC 791 ระบุชัดว่าประกอบกลับที่ปลายทางเท่านั้น เราเตอร์กลางทางไม่ประกอบให้ ซึ่งทำให้เกิดปัญหาสามข้อ
- ชิ้นเดียวหาย ทั้งก้อนใช้ไม่ได้ ต้องส่งใหม่หมด
- ปลายทางต้องกันหน่วยความจำรอชิ้นที่เหลือ ซึ่งเปิดช่องให้โจมตีได้
- เราเตอร์ที่ต้องแบ่งชิ้นทำงานหนักกว่าการส่งต่อเฉย ๆ มาก
IPv6 จึงเลิกให้เราเตอร์แตกแฟรกเมนต์ ต้นทางต้องหาขนาดที่พอดีเองก่อนส่ง ซึ่งเป็นเหตุผลที่การค้นหา MTU ของเส้นทางสำคัญกว่าเดิมมากบน IPv6
ข้อควรระวังตอนทดสอบ MTU
บทความ ping บอกวิธีหา MTU ด้วยการตั้งบิต DF แล้วไล่ขนาด มีเงื่อนไขที่ควรรู้เพิ่ม — ให้ทดสอบกับปลายทางที่อยู่พ้นเกตเวย์ออกไป ไม่ใช่กับเกตเวย์ในบ้านเอง
ทดสอบจริงบนแมคเครื่องนี้ ยิงไปที่ปลายทางนอกบ้านได้ผลตามคาด
$ ping -c 1 -D -s 1472 8.8.8.8
1480 bytes from 8.8.8.8: icmp_seq=0 ttl=112 time=11.613 ms
$ ping -c 1 -D -s 1473 8.8.8.8
(ไม่มีคำตอบ — ใหญ่เกิน 1500 และห้ามแตก)
แต่ยิงไปที่เกตเวย์ในลิงก์เดียวกัน กลับได้คำตอบทั้งที่ใหญ่เกิน
$ ping -c 1 -D -s 1600 192.168.1.1
1608 bytes from 192.168.1.1: icmp_seq=0 ttl=64 time=7.251 ms
ผลนี้ทำซ้ำได้ และแปลว่าการตั้ง DF ไม่ได้กันการแตกแฟรกเมนต์สำหรับแพ็กเก็ต ที่ใหญ่เกินตั้งแต่ต้นทางไปยังปลายทางในลิงก์เดียวกัน ถ้าทดสอบกับเกตเวย์ แล้วเห็นว่าขนาดใหญ่ ๆ ผ่านหมด อย่าเพิ่งสรุปว่า MTU ของเส้นทางใหญ่ตามนั้น
TTL — ชื่อบอกเวลา แต่ทำงานเป็นจำนวนฮอป
บทความ ping กับ traceroute อธิบาย TTL ว่าเป็นตัวนับจำนวนเราเตอร์ ซึ่งถูกต้องในทางปฏิบัติ แต่ ไม่ใช่สิ่งที่ RFC 791 ตั้งใจตอนแรก
เอกสารเขียนไว้ว่า
ค่านี้มีหน่วยเป็นวินาที แต่เนื่องจากทุกโมดูลที่ประมวลผล datagram ต้องลดค่า TTL ลงอย่างน้อยหนึ่ง แม้จะประมวลผลเสร็จภายในเวลาน้อยกว่าหนึ่งวินาที TTL จึงต้องถูกมองว่าเป็นเพียงขอบเขตบนของเวลาที่ datagram จะมีชีวิตอยู่ได้
แปลว่าเจตนาเดิมคือ "อยู่ในระบบได้ไม่เกินกี่วินาที" แต่กฎที่บังคับให้ลดอย่างน้อย หนึ่งต่อหนึ่งฮอปเสมอ บวกกับความจริงที่ว่าเราเตอร์สมัยใหม่ประมวลผลเสร็จใน เศษเสี้ยวของมิลลิวินาที ทำให้ในทางปฏิบัติมันกลายเป็นตัวนับฮอปไปโดยสมบูรณ์
นี่เป็นตัวอย่างที่ดีของสิ่งที่เกิดขึ้นบ่อยในโพรโทคอลที่อยู่มานาน — ชื่อบอกเจตนาเดิม พฤติกรรมบอกความจริงปัจจุบัน และทั้งสองอย่างไม่ตรงกันแล้ว
ตัวอย่างจริงจากงานจริง
กรณีที่ 1 — mask ที่ตั้งไม่ตรงกัน
เครื่อง A ตั้ง 192.168.1.10/24 เครื่อง B ตั้ง 192.168.1.20/25 อยู่บนสวิตช์ตัวเดียวกัน
อ่านอย่างไร /25 แบ่งวงเดิมครึ่งหนึ่ง ช่วงแรกคือ .0 ถึง .127 ทั้งสองเครื่องอยู่ในช่วงนั้น ดังนั้นทั้งคู่มองว่าอีกฝ่ายอยู่วงเดียวกัน กรณีนี้จึงยังคุยกันได้
แต่ถ้า B เป็น 192.168.1.200/25 เมื่อไหร่ B จะอยู่คนละครึ่ง — A ยังคิดว่าอยู่วงเดียวกันเลยส่งตรง ส่วน B คิดว่าคนละวงเลยส่งให้เกตเวย์ คุยกันได้ทางเดียว
สิ่งที่ยังไม่ได้พิสูจน์ ยังไม่รู้ว่าเครื่องไหนตั้งผิด ต้องดูว่าการออกแบบ วงนี้ตั้งใจให้เป็น /24 หรือ /25 ก่อน
กรณีที่ 2 — ping ได้แต่เข้าเว็บไม่ได้
$ ping -c 2 10.20.30.40
64 bytes from 10.20.30.40: icmp_seq=0 ttl=63 time=2.1 ms
อ่านอย่างไร ping พิสูจน์ว่าชั้น IP ทำงาน — เลขที่อยู่ถูกต้อง เส้นทาง มีอยู่จริง และมีอะไรสักอย่างที่ปลายทางตอบกลับมา
แต่ ICMP ใช้ Protocol เลข 1 ส่วนเว็บใช้เลข 6 การที่เลข 1 ผ่านไม่ได้แปลว่า เลข 6 จะผ่าน ไฟร์วอลล์กรองตามฟิลด์นี้ได้ตรง ๆ
การไล่ต่อคือทดสอบด้วยโพรโทคอลเดียวกับที่แอปพลิเคชันใช้จริง
สิ่งที่ยังไม่ได้พิสูจน์ ยังไม่รู้ว่าถูกกรองหรือบริการไม่ทำงาน ping ตอบได้แม้บริการบนเครื่องนั้นจะตายไปแล้ว
กรณีที่ 3 — เดาระบบปลายทางจาก TTL ที่เหลือ
$ ping -c 1 8.8.8.8
64 bytes from 8.8.8.8: icmp_seq=0 ttl=112 time=11.879 ms
อ่านอย่างไร ค่าตั้งต้นที่พบบ่อยคือ 64, 128 และ 255 เห็น 112 จึงเดาว่าตั้งต้นที่ 128 แล้วผ่านเราเตอร์มา 16 ตัว
สิ่งที่ยังไม่ได้พิสูจน์ เป็นการเดา ไม่ใช่การพิสูจน์ ผู้ดูแลเปลี่ยน ค่าตั้งต้นได้ และเส้นทางขากลับอาจไม่เท่ากับขาไป จำนวนฮอปที่ได้จึงเป็น ของขากลับ ไม่ใช่ของขาไป
กรณีที่ 4 — วงส่วนตัวที่ชนกันตอนต่อ VPN
ออฟฟิศใช้ 192.168.1.0/24 และเน็ตที่บ้านของพนักงานก็ใช้ 192.168.1.0/24
อ่านอย่างไร เมื่อต่อ VPN เครื่องจะมีสองเส้นทางที่ตรงกันพอดี และตามกฎ prefix ยาวที่สุด สองเส้นที่ยาวเท่ากันจะไม่มีตัวชนะที่ชัดเจน ผลคือทราฟฟิกที่ควรวิ่งเข้าออฟฟิศอาจวิ่งไปหาเราเตอร์ที่บ้านแทน
นี่คือเหตุผลที่องค์กรควรเลี่ยงช่วงยอดนิยมอย่าง 192.168.0.0/24 กับ 192.168.1.0/24 แล้วเลือกช่วงที่คนใช้น้อยกว่าใน 10.0.0.0/8
สิ่งที่ยังไม่ได้พิสูจน์ ยังไม่รู้ว่าซอฟต์แวร์ VPN แต่ละตัวจัดการเรื่องนี้ อย่างไร บางตัวใส่เส้นทางที่เจาะจงกว่าเพื่อแย่งชนะ ต้องดู netstat -rn ขณะต่ออยู่จริง
เมื่อ IP ไม่พอ
IP พาไปให้ถึงอย่างเดียว ทุกอย่างที่มากกว่านั้นเป็นงานของชั้นอื่น
- ICMP — แจ้งเรื่องกลับมา เช่น TTL หมด หรือใหญ่เกินและห้ามแตก อ่านต่อที่ ping และ traceroute
- TCP — เพิ่มลำดับ การส่งซ้ำ และการควบคุมปริมาณ ให้ได้ความน่าเชื่อถือ ที่ IP ไม่ให้
- UDP — แทบไม่เพิ่มอะไรเลยนอกจากหมายเลขพอร์ต เหมาะกับงานที่ยอมให้หายได้ อ่านต่อที่ DNS
- ARP และ Neighbor Discovery — แปลงเลข IP เป็นที่อยู่จริงบนสายในลิงก์เดียวกัน
- IPv6 — เลขที่อยู่ยาว 128 บิต ไม่มี checksum ในหัว และไม่ให้เราเตอร์ แตกแฟรกเมนต์
โพรโทคอลที่สัญญาว่าจะไม่รับประกันอะไรเลย กลายเป็นฐานของทุกอย่างที่คุณใช้ ทุกวัน เพราะการไม่รับประกันแปลว่าไม่ต้องจำ และการไม่ต้องจำแปลว่าขยายได้ ไม่มีขีดจำกัด
ทุกครั้งที่มีอะไรบนอินเทอร์เน็ตทำงานได้ นั่นไม่ใช่เพราะ IP รับประกันให้ แต่เพราะมีคนสร้างชั้นบนที่รับมือกับความไม่แน่นอนนั้นได้ดีพอ
อ้างอิง
เอกสารมาตรฐาน
- RFC 791 — Internet Protocol Jon Postel (บรรณาธิการ), DARPA, กันยายน 1981 — แทนที่ RFC 760 เป็นที่มาของทุกคำอ้างในหน้านี้ ทั้งเรื่องที่ IP ไม่รับประกันอะไร นิยาม TTL ที่มีหน่วยเป็นวินาที และการประกอบแฟรกเมนต์ที่ปลายทางเท่านั้น
- RFC 792 — Internet Control Message Protocol Jon Postel, กันยายน 1981 — คู่หูของ RFC 791
- RFC 1122 — Requirements for Internet Hosts สิ่งที่โฮสต์ต้องทำได้จริง
- RFC 1812 — Requirements for IP Version 4 Routers ฝั่งเราเตอร์ รวมถึงกฎการลด TTL
- RFC 1918 — Address Allocation for Private Internets ที่มาของ 10.0.0.0/8, 172.16.0.0/12 และ 192.168.0.0/16
- RFC 4632 — CIDR การเลิกใช้ระบบคลาสและการรวมเส้นทาง
- RFC 8200 — IPv6 Specification รวมถึงเหตุผลที่เราเตอร์ไม่แตกแฟรกเมนต์อีกต่อไป
คู่มือ
man ip,man route,man netstatบนเครื่องที่คุณนั่งอยู่ip route get <ปลายทาง>บนลินุกซ์ และroute -n get <ปลายทาง>บนแมค ซึ่งบอกได้ตรง ๆ ว่าเครื่องจะส่งออกทางไหนสำหรับปลายทางนั้น