15 ポイント 投稿者 xguru 2020-12-28 | 2件のコメント | WhatsAppで共有
  • 高速な IPv4+v6 パーサーを作りながら学んだことを、読みやすく整理した記事

  • 正式な(Canonical)表現

→ v4 : 192.168.0.1 、1バイトごとの Dotted Quad

→ v6 : 1:2:3:4:5:6:7:8 、2バイトごとの Colon-Hex

[IPv6]

  • 途中に 0 が多く現れるため、:: を使うと 1 個以上の 0 を省略可能

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

  • 最後の 32 ビットは v4 の Dotted Quad 方式で表現可能

→ 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 の各フィールドはすべて 4 桁の 16 進数で、先頭の 0 は省略可能

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

[IPv4]

  • 面白いことに、IPv6 で最後の 32 ビットを Dotted Quad で表す形式が正式化される前は、どの文書でも標準化されたことがなかった

→ そのため、業界の事実上の標準(de-facto)は「4.2BSD で解釈できるか?」「他の OS が 4.2BSD をコピーしたとき何を引き継いだか?」だった

  • ただし 4.2BSD は少し変わっている

→ 192.168.140.255 は 3232271615 と同じ

→ つまり、Chrome で http://3232271615 にアクセスすると 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 が成り立つ。IPv6 のように連続した 0 を省略したのではなく、クラス A ネットワーク 127 の 1 番目のホストを意味する。つまり 24 ビット整数の 1

  • 各 Quad の数値の先頭に 0 は何個まで許されるのか?

→ 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 進数は処理しない

  • uint32 の数値 1 個で全体を表す形式も処理しない

  • IPv6 は正式な colon-hex 方式、:: の短縮表記、そして最後の 32 ビットに IPv4 を付ける形式まで許容(この IPv4 には前述の規則を適用)。各フィールドの先頭 0 の個数は無制限

  • 当初は IPv4 から IPv6 への移行を容易にするため、末尾に IPv4 アドレスを付ける方式を入れたが、実際にはあまり見かけない。そのためサポートはしているものの、あまり有用ではないと考えている

2件のコメント

 
minhoryang 2020-12-28

おお、面白いですね! 攻撃時にひねって使いやすそうな手法がたくさん見えますね!

 
galadbran 2020-12-28

IPアドレスの表記にこんなに複雑なルールを使わなければならないなら、無駄なコンピューティングリソースの浪費ではないかという気がしますね ^^;;