バックナンバーはこちら。
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
ネットワーク上のパケットを見るためにパケットキャプチャハンドルを取得のAPI
今回は、ネットワーク上のパケットを見るためにパケットキャプチャハンドルを取得について。
- pcap_findalldevs:ネットワークデバイスのリストの構築。
- pcap_open_live:ネットワーク上のパケットを見るためにパケットキャプチャハンドルを取得。 ← これ
- pcap_next_ex:次のパケットを読み込んで、成功/失敗の指示を返す。
イメージ的にはopen、close系のopen側なのかな?
そうだね。
FILEを制御するためのファイルポインタを取得するのにfopenをするノリと一緒だ。
じゃー、一撃で終わるな予感!
うーん、どうだろうねー?
APIの型
APIの型はこれだ。
pcap_t * pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, char *errbuf)
引数はこうなる。
device:デバイス名。
snaplen:取得したいパケットの最大長。
promisc:インタフェースをプロミスキャスモードで動作させるかの指定。0以外を指定すれば、プロミスキャスモードになる。
to_ms:読み出しタイムアウト
errbuf:エラー時のエラー文章
各種引数説明
うーん、デバイス名は前回のpcap_findalldevsで取得したデバイスリストにあったnameメンバのことだろうけど、
それ以外は・・・。わからんな。
「snaplen:取得したいパケットの最大長。」
ってのはどこの最大長?
まぁIPパケット長と思って良いかな。
キャプチャする際に負荷を下げたい場合に利用されるようだが、
現状は最大長の65535を指定しておけば良いよ。
プロミスキャスモードってなに?
分からない用語はWikipediaから
プロミスキャス・モード (promiscuous mode)とは、コンピュータ・ネットワークのネットワークカードが持つ動作モードの一つである。「プロミスキャス」は「無差別の」という意味を持ち、自分宛のデータパケットでない信号も取り込んで処理をすることを示す。
Wikipediaより
んー?
つまり、自分宛て以外も受けるってことは・・・。
あれ?
普通は受けないの?
無関係なパケットもハンドリングしてたら負荷が上がる一方なんで、
基本的には自分宛のみを受信する。
ただ、こんかいはパケットキャプチャするんで、プロミスキャスモードにしておく必要はある。
自IPのみで良いならFalseを指定してみるのもあり。
ようわからんから、プロミスキャスモードにしておこう。
to_ms:読み出しタイムアウト
ってなんだろ?
あー、受信が有るまで待つんだけど、
ずーっと待たれても困るんで、
ここでタイムアウト時間を設定するところだね。
タイムアウトが来るまで待っちゃうってこと?
受信が全くない場合はね。
タイムアウト無しでも良いけど、
受信してする動作させたい場合は、
ある程度のタイムアウト待ちをしてた方が処理としては効率が良い。
ここらへんは、スレッドの仕様に踏み込む必要があるんだけど、
一言で言うと、
「waitで寝た状態から受信で起きて一気に動作した方が効率が良い」
スレッドの性格ってことかー。
エラーの種類
最後の「errbuf:エラー時のエラー文章」
はそのまんまなんだろうなーっと思う反面、具体的には何があるの?
以下の種類があるみたいだね。
(ソースコード潜って拾ってきた)
PCAP_WARNING:”Generic warning”
PCAP_WARNING_TSTAMP_TYPE_NOTSUP:”That type of time stamp is not supported by that device”
PCAP_WARNING_PROMISC_NOTSUP:”That device doesn’t support promiscuous mode”
PCAP_ERROR:”Generic error”
PCAP_ERROR_BREAK:”Loop terminated by pcap_breakloop”
PCAP_ERROR_NOT_ACTIVATED:”The pcap_t has not been activated”
PCAP_ERROR_ACTIVATED:”The setting can’t be changed after the pcap_t is activated”
PCAP_ERROR_NO_SUCH_DEVICE:”No such device exists”
PCAP_ERROR_RFMON_NOTSUP:”That device doesn’t support monitor mode”
PCAP_ERROR_NOT_RFMON:”That operation is supported only in monitor mode”
PCAP_ERROR_PERM_DENIED:”You don’t have permission to capture on that device”
PCAP_ERROR_IFACE_NOT_UP:”That device is not up”
PCAP_ERROR_CANTSET_TSTAMP_TYPE:”That device doesn’t support setting the time stamp type”
PCAP_ERROR_PROMISC_PERM_DENIED:”You don’t have permission to capture in promiscuous mode on that device”
PCAP_ERROR_TSTAMP_PRECISION_NOTSUP:”That device doesn’t support that time stamp precision”
おー!
エラー出たら、これみればOKだね。
まとめ
まとめだよ。
- ネットワーク上のパケットを見るためにパケットキャプチャハンドルを取得のAPIの説明
- open/close系のAPI。
- パケット長はとりあえず最大の65535。
- プロミスキャスもとりあえず有効でOK。
- タイムアウトはそこそこの値を入れておいた方が処理効率が上がる。
- スレッドの性格。
- 各種エラー。
バックナンバーはこちら。
コメント