バックナンバーはこちら。
https://www.simulationroom999.com/blog/In-vehicle-network-backnumber/
はじめに
npcapのキャプチャ処理APIについて
登場人物
博識フクロウのフクさん

イラストACにて公開の「kino_k」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=iKciwKA9&area=1
エンジニア歴8年の太郎くん

イラストACにて公開の「しのみ」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=uCKphAW2&area=1
npcapのキャプチャ処理API

今回はnpcapのキャプチャ処理APIについて。
- pcap_datalink:デバイスのリンクタイプ取得
- pcap_compile:フィルタ文字列をコンパイルしてbpf_program構造体を取得
- pcap_setfilter:bpf_program構造体を元にパケットフィルタ有効化
- pcap_loop:キャプチャ処理 ← これ

以前やった、pktdump_exというサンプルプログラムの時はpcap_next_exというAPIだったけどね。
pcap_next_exの話

まぁできることはpcap_next_exと一緒なんだけど、
違いはコールバック関数を登録して、
パケット受信毎にハンドリングするって感じだねー。
pcap_loopの注意点

注意点とかはある?

pcap_loopを呼び出したら、
指定パケット数の受信が終わらないと基本的には関数からは戻ってこない。
pcap_breakloopを呼び出すことでキャプチャを停止して戻ってくる。
ここが注意点かな。

pcap_next_exより使い方が難しい感じになるのかな?

うーん、どうかなー?
あんまり変わらないか、ちょっと楽になるんじゃないかなー。

というと?

pcap_next_exを使っても、結局はpcap_loopとpcap_breakloopと同等の仕掛けを使うことになると思うんだよねー。
まぁpcap_next_exで一時的にキャプチャしたいとかだと別だけど、
今回みたいに、一回開始したらずっとキャプチャこと受信し続けるタイプだと同じ実装になると思うよ。

おー!
そこまで読み込めてるのか?!
すごいな!
pcap_loop API仕様

pcap_loopのAPI仕様はこれ。
int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)

各引数はこれ。
p:パケットディスクリプタ
cnt:処理したいパケット数。0指定で無制限。
callback:パケット受信毎に呼ばれるコールバック関数
user:コールバック時に一緒に渡したいユーザパラメータ

コールバック関数の型はこれ。
typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *, const u_char *);

コールバック関数の引数としてわたってくるのはこれ。
u_char * : pcap_loopのuserで渡した情報
const struct pcap_pkthdr * : pcap_pkthdr構造体へのポインタ
const u_char * : 受信パケットの先頭ポインタ

pcap_pkthdr構造体も書き出しておこう。
ちなみにnpcap-SDKの
Include\pcap\pcap.h
で定義されてるよ。
struct pcap_pkthdr {
struct timeval ts; /* time stamp */
bpf_u_int32 caplen; /* length of portion present */
bpf_u_int32 len; /* length this packet (off wire) */
};
余談

良く調べてるねー。

何となく掘り下げ方が分かってきた感じかな。

ちなみに、コールバック関数を設定する際にユーザパラメータを設定するんだけど
これって割と一般的な手法なの?

まぁ一般的と言えば一般的かな。
スレッドなんかも似たようなことしてるね。

コールバック関数が呼ばれた際に
誰が呼び出したかをはっきりさせたいとかが動機なのかな?

それもあるけど、
上位から管理する構造体を渡してコンテキストを維持するのが目的かな?

コンテキスト?

日本語にすると「文脈」って意味になる。
処理の状態を記憶するものと思っても差し支えないかな。

あー、スレッド毎の個別の状態を持たせたい時に使えそう。
関数としては同一なんだけど、
スレッドとしては別になってる時とか。

そうそう。
そういうのを総じてコンテキストって呼んだりする。
まとめ

まとめだよ。
- npcapのキャプチャ処理APIについて説明。
- pcap_next_exの方が分かり易いが、結局はpcap_loopと同等の実装になり易いため最初からpcap_loopにしておくのもあり。
- pcap_loopにはコンテキスト維持用にユーザパラメータを渡すことができる。
バックナンバーはこちら。
コメント