ポン酢ブログ(β)

The harder you work, the luckier you get. - Gary Player

pcapをパースする(その3・IP/ICMP編)

これまで以下の記事でEthernetフレームやARPのパケットをpcapファイルからパースするために必要なフォーマットについて解説していきました.

pcapをパースする(その2・ARP編) - ポン酢ブログ(β)

pcapをパースする(その1・ヘッダ編) - ポン酢ブログ(β)

引き続き,IPやICMPをパースしてみたいと思います.

IPパケット

IPパケットは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  |Type of Service|          Total Length         |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |         Identification        |Flags|      Fragment Offset    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |  Time to Live |    Protocol   |         Header Checksum       |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                       Source Address                          |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Destination Address                        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Options                    |    Padding    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

今回のパースは,Golangの準標準パッケージであるnetを使ってみる練習がてら,パースをそれに任せてみました.

実際にパースをする場合は,Parseを呼び,そこに[]byteでパケットを入れてあげれば大丈夫です.

気づきとしては,socket.NativeEndianには動作するOSのbinary.ByteOrderが入っており,それを使って処理していました.

実装はこちらになっていて,パースしたあとにその後ろの[]byteを返すようになっています.

ICMPパケット

IPパケットまでパースできたので,関連するICMPパケットについてもパースしていきたいと思います.ICMPはRFC 792で策定されています.普段pingコマンド等で馴染みのある人もいるのではないでしょうか.

ICMPのメッセージには多くの種類があり,こちらが参考になります.

今回のパースも,Golangの準標準パッケージであるnetを使ってみる練習がてら,パースをそれに任せてみました.実際にパースと言っても,structに値をマッピングしていく形になります.パッケージでの実装を参考にしながら使っていきますが,internalでメッセージのタイプが隠れていたため,仕方なく同じものを自分て定義しそれを使っています.

実際の実装部分です.

自作のものとつなげていく

自作しているpcapのパーサーでは,Packetインターフェースを作り,それを満たすように各データを格納しています.そして,実際にに読み込んでいる部分はこちらになります.

実際にファイルを読み込ませてみると,パースできていることがわかります.

f:id:atpons:20191120135452p:plain

実はこの他にも追加した機能があるのですが,それはまた別の機会に説明します.