前回のコメントでlibpcapの使い方を知りたいということだったので、簡単なlibpcapプログラムを書いた。
“test.pcap”ファイルの各フレームの受信時間と、データリンク層プロトコル番号を表示する。
- pcap_open_offlineでpcapファイルを開く
- pcap_datalinkでデータリンク層プロトコル番号を取得する
- pcap_loopで各フレームに対してpcap_handlerを行う
pcap_loopの第2引数は処理するフレーム数であり-1でEOFまで処理を行う(はず)。
もしdatalinkがEthernet(1)であれば、handlerのdataにはEthernetフレーム以上が入っているので、ネットワーク層プロトコル番号(Ethernet)->トランスポート層プロトコル番号(IP)->DCCPシーケンス番号の順にアクセスする。
[code] typedef struct { void if (user->start_flag == 0) printf(“%lu.”, ts.tv_sec); int char *errbuf = NULL; user_hdr *user = (user_hdr *)malloc(sizeof(user_hdr)); pcap_loop(pcap, free(user); return 0; 後はTCPもしくはDCCPのシーケンス番号が欲しければ10〜20行くらい書けば表示できる。ただしDCCPの場合はext seqがあるので少し面倒。 書いた後で思ったが、かなり行数少ない。シーケンス図やスループット図を描く為ならEtherealよりお勧めだなー。
#include
#include
u_int32_t datalink;
int start_flag;
struct timeval start_ts;
} user_hdr;
my_handler(u_char *_user,
const struct pcap_pkthdr *pkthdr,
const u_char *data)
{
user_hdr *user = (user_hdr *)_user;
{
user->start_ts = pkthdr->ts;
user->start_flag = 1;
}
struct timeval ts;
timersub(&pkthdr->ts,
&user->start_ts,
&ts);
printf(“%06lu “, ts.tv_usec);
printf(“%u “, user->datalink);
printf(“\n”);
}
main()
{
const char *fname = “test.pcap”;
pcap_t *pcap = pcap_open_offline(fname, errbuf);
user->datalink = pcap_datalink(pcap);
user->start_flag = 0;
-1,
(pcap_handler)my_handler,
(u_char *)user);
}
[/code]
うわー、ありがとう。
なかなかそちらへ行けなくなってしまったのでありがたい。
これはきっと役に立つ
ピンバック: cialis