15 คะแนน โดย xguru 2020-12-28 | 2 ความคิดเห็น | แชร์ทาง WhatsApp
  • บทความที่สรุปสิ่งที่ได้เรียนรู้ระหว่างการสร้างพาร์เซอร์ IPv4+v6 แบบรวดเร็วให้อ่านง่าย

  • รูปแบบมาตรฐาน (Canonical)

→ v4 : 192.168.0.1 , Dotted Quad ของไบต์ 1 ไบต์แต่ละตัว

→ v6 : 1:2:3:4:5:6:7:8 , Colon-Hex ของไบต์ 2 ไบต์แต่ละตัว

[IPv6]

  • เพราะมักมี 0 อยู่ตรงกลางจำนวนมาก จึงใช้ :: เพื่อตัด 0 ออกตั้งแต่ 1 กลุ่มขึ้นไป

→ 1:2::3:4 = 1:2:0:0:0:0:3:4

  • 32 บิตสุดท้ายสามารถเขียนด้วยรูปแบบ Dotted Quad ของ v4 ได้

→ 1:2:3:4:5:6:77.77.88.88 = 1:2:3:4:5:6:4d4d:5858

→ fe80::1.2.3.4 = fe80:0:0:0:0:0:102:304

  • มีกรณีที่ :: อยู่ต้นหรือท้าย ทำให้ซับซ้อนขึ้นอีกเล็กน้อย

→ ::1 = 0:0:0:0:0:0:0:1

→ 1:: = 1:0:0:0:0:0:0:0

→ :: = 0:0:0:0:0:0:0:0

  • ทุกฟิลด์ของ IPv6 Colon-Hex เป็นเลขฐาน 16 ยาว 4 หลัก และตัด 0 ด้านหน้าออกได้

→ :: = 0000:0000:0000:0000:0000:0000:0000:0000

[IPv4]

  • จุดที่น่าสนใจคือ ก่อนที่การเขียน Dotted Quad สำหรับ 32 บิตท้ายใน IPv6 จะถูกทำให้เป็นทางการ ก็ไม่เคยมีการทำให้เป็นมาตรฐานในเอกสารใดเลย

→ ดังนั้นมาตรฐานโดยพฤตินัย (de-facto) ในวงการจึงมักเป็นคำถามว่า “4.2BSD ตีความได้ไหม?” และ “เมื่อ OS อื่นคัดลอก 4.2BSD มา พวกเขาคงอะไรไว้บ้าง”

  • แต่ 4.2BSD ค่อนข้างแปลก (whacky)

→ 192.168.140.255 = 3232271615 เหมือนกัน

→ กล่าวคือ ถ้าเข้า http://3232271615 ใน Chrome ก็จะโหลด http://192.168.140.255 เพราะมันเป็นตัวเลข 4 ไบต์!

→ แบบเลขฐาน 8 อย่าง http://0300.0250.0214.0377 ก็ใช้ได้

→ ถ้าอย่างนั้นแบบเลขฐาน 16 อย่าง https://0xc0.0xa8.0x8c.0xff ก็แน่นอนว่าเป็นที่อยู่เดียวกันทั้งหมด

  • CIDR (Classless Inter-Domain Routing) ก็มีผลกับที่อยู่ IP เช่นกัน

→ รูปแบบคลาส C อย่าง 192.168.140.255 ถ้าเขียนเป็นคลาส B จะเป็น http://192.168.36095 และถ้าเขียนเป็นคลาส A จะเป็น http://192.11046143

→ นี่จึงเป็นเหตุผลว่าทำไม ping 127.1 จึงเท่ากับ 127.0.0.1 ได้ ไม่ใช่การตัด 0 ซ้ำแบบ IPv6 แต่หมายถึงโฮสต์ตัวที่ 1 ของเครือข่ายคลาส A หมายเลข 127 หรือก็คือตัวเลข 24 บิตค่า 1

  • จะมี 0 นำหน้าได้กี่ตัวในตัวเลขของแต่ละ Quad?

001.002.003.004 ? 0000000001.0000000002.0000000003.000000004 ?

→ (Chrome รองรับ http://0000000001.0000000002.0000000003.000000004 ด้วย)

→ แล้วตอนนี้ควรอ่านตัวเลขเหล่านี้เป็นเลขฐาน 8 หรือเลขฐาน 16? : การติดตั้งใช้งานสมัยใหม่เลิกใช้ฐาน 8/16 ไปแล้ว และจัดการ 0 นำหน้าเป็นเลขฐาน 10

  • ปัญหาเรื่อง 0 นำหน้านี้ส่งผลถึง IPv6 ด้วย

000001::00001.00002.00003.00004 = 1::1.2.3.4, or 1::102:304

→ พาร์เซอร์สมัยใหม่ส่วนใหญ่ใช้ไลบรารี “parse integer” กันอยู่แล้ว จึงมักยอมรับ 0 นำหน้าจำนวนมากทั้งหมด

สรุปคือ ถ้าจะพาร์สที่อยู่ IP ให้ครอบคลุมทั้งหมด ก็ต้องคำนึงถึงเรื่องชวนปวดหัวพวกนี้ทั้งหมด แต่...

พาร์เซอร์ของผู้เขียนรองรับประมาณนี้

  • รองรับรูปแบบ v4 แบบดั้งเดิมที่เป็นจำนวนเต็มคั่นด้วยจุด และยอมให้มี 0 นำหน้าได้ไม่จำกัด

  • ไม่รองรับรูปแบบคลาส A/B และเลขฐาน 8/16

  • ไม่รองรับการเขียนทุกอย่างด้วยตัวเลข unit32 เพียงตัวเดียว

  • สำหรับ IPv6 รองรับทั้งรูปแบบ colon-hex มาตรฐาน, รูปแบบย่อ ::, และการต่อ IPv4 เข้าที่ 32 บิตสุดท้าย (โดย IPv4 นี้ใช้กฎด้านบน) แต่ละฟิลด์มี 0 นำหน้าได้ไม่จำกัด

  • ตอนแรกผู้เขียนใส่วิธีต่อที่อยู่ IPv4 ไว้ท้ายสุดเพื่อช่วยย้ายจาก IPv4 ไป IPv6 ได้ง่ายขึ้น แต่ในความเป็นจริงแทบไม่ค่อยพบเห็น จึงแม้จะรองรับอยู่ แต่ก็คิดว่าไม่ได้มีประโยชน์นัก

2 ความคิดเห็น

 
minhoryang 2020-12-28

โอ้ น่าสนุกดีนะ! เห็นเทคนิคหลายอย่างที่เหมาะกับการบิดแพลงตอนโจมตีอยู่เยอะเลย!

 
galadbran 2020-12-28

รู้สึกว่าแค่จะเขียนรูปแบบที่อยู่ IP ถ้าต้องใช้กฎที่ซับซ้อนขนาดนี้ มันก็เป็นการสิ้นเปลืองทรัพยากรคอมพิวเตอร์โดยใช่เหตุหรือเปล่านะ ^^;;