前回の話のおさらい。
libpcapではpcap_loopやpcap_dispatchによって各フレームに対してpcap_handlerを処理させる。
pcap_handlerでは第3引数であるu_char *dataを、ネットワーク層プロトコル番号(Ethernet)->トランスポート層プロトコル番号(IP)->DCCPシーケンス番号の順にアクセスしていくことになる。
で、補足。linuxの場合だと以下のヘッダファイルをincludeすると楽。
[code]
#include
#include
#include
#include
[/code]
こうすると、
[code]
struct ether_header *ether_hdr =
(struct ether_header *)data;
/* htons(ether_hdr->ether_type) = ETHERTYPE_IP なら */
int index = sizeof(struct ether_header);
struct ip *ip_hdr = (struct ip *)&data[index];
/* (ip_hdr->ip_p) = IPPROTO_DCCP なら */
index += sizeof(struct ip);
struct dccp_hdr *dccp = (struct dccp_hdr *)&data[index];
[/code]
でdccp構造体まで下れる。後は、dccp->dccph_xでシーケンス番号拡張の有無を確認し、拡張されるようであれば、
[code]
index += sizeof(struct dccp_hdr);
struct dccp_hdr_ext *dccp_hdr_ext =
(struct dccp_hdr_ext *)&data[index];
[/code]
でさらに下る。あとはdccp->dccph_seqとdccp_ext->dccph_seq_lowを処理するとDCCPのシーケンス番号が出るはず(スループット測定にシーケンス番号が必要かどうか分からないけれど)。
もしかしたらip_hdr->ip_pのエンディアンを直さなきゃいけないかもしれない。
と、こんな風にヘッダファイルをincludeすると各レイヤのプロトコル処理が楽になる、という補足。前回に数行で済むとか書いたけど、それは間違いだった。
加えてipの送信元・あて先アドレス、DCCPの送信元・あて先アドレスでフィルタリングできるようにして、802.11(と、その下のprism2header)にも対応するのが、今、自分の書いているコード。