MasaのITC Life

夢は起業家!全てにおいて凡人だけど頑張ることだけはいっちょ前!

プログラミング

【C言語】Raw SocketでICMPパケットを扱ってみた!

投稿日:2019年6月8日 更新日:

今回はICMPパケットに絞ってみていこうと思います。

ICMPはタイプとコードの値を持っています。タイプによっては複数のコードを持つものもあります。なので、タイプやコードの値を表示するだけなら、icmp構造体のメンバにアクセスすらだけで済みます。またicmp構造体はLinuxの場合、/usr/include/netinet/ip_icmp.hに定義されています。



今回はタイプやコードの値に応じて、その値が何を示すのか、名前みたいなものまで表示してみます。オプションのIDやSequesnce Numberまでは表示していません。



やっていることはシンプルで、指定したインターフェースを通るパケットの中身を確認します。まずはethernetヘッダのプロトコルタイプを見ます。もしそれが、IPなら次はIPヘッダのプロトコルを見ます。そして、それがICMPであれば、ICMPパケットを表示します。ICMP構造体で各要素が定義されているので、メンバアクセスをして、標準出力していきます。あとは、タイプやコードの名前の格納先アドレスを示すポインタ配列を自分で用意して、表示していくだけです。

ICMPパケットをキャプチャするコードはこちらです。

実行結果はこんな感じです。traceroute してみます。指定したインターフェースを通る( 受信もしくは送信 )パケットがキャプチャされます。



tracerouteをしている最中に流れたパケットの一部を表示しています。実行画面は、データの受けて側です。また、全てのパケットにデータサイズは表示します。もしパケットにICMPが含まれていたら、その中身もチェックします。

tracerouteはOSにもよりますが、Linuxの場合はUDPデータに、使われていないポート番号で送信します。なので、もしデータが受けて側に届いたら、タイプ3(到達不能メッセージ)のコード3(ポート到達不能)を返します。windowsで動かしたら、ping同様、tracertにエコー要求が使われるので、受けて側はエコー応答を返すかと思います。

最後まで読んでいただきありがとうございました。

-プログラミング

Copyright© MasaのITC Life , 2023 All Rights Reserved Powered by STINGER.