Net bsd advent calendar 2015 bpf
- 3. BPFによるキャプチャの準備
1. fd = open(“/dev/bpf”, O_RDWR); で、スペシャルファイルをオープンする。
2. ioctl(fd, BIOCSBLEN, &len); で、バッファサイズを設定する。
バッファには複数パケットの情報が詰めて書き込まれる。
インタフェースを指定する前に設定する必要がある。
3. ioctl(fd, BIOCSSEESENT, &onoff); で送信方向をキャプチャするか指定。
受信方向については常にキャプチャされる。デフォルトは送信方向もキャプチャ。
※FreeBSDではBIOCSDIECTIONを使う。送信方向のみキャプチャもできる。
4. ioctl(fd, BIOCSETIF, &ifreq); で対象インタフェース名を指定。
ifreq.ifr_nameにインタフェース名を書き込んでおく。
5. 必要に応じて ioctl(fd, BIOCPROMISC, NULL); しておく。
- 4. パケットの受信
1. read(fd, buf, buflen); する。buflenはBIOCSBLENと同じ値でないとエラーになる。
2. bufの中身はstruct bpf_hdr + パケットデータ、が収まるだけ連続している。
3. パケットデータのサイズは bh_caplenにホストバイトオーダで書かれている。
bpf_hdr bpf_hdr bpf_hdr bpf_hdr
struct bpf_hdr {
struct bpf_timeval bh_tstamp; /* time stamp */
uint32_t bh_caplen; /* length of captured portion */
uint32_t bh_datalen; /* original length of packet */
uint16_t bh_hdrlen; /* length of bpf header (this struct
plus alignment padding) */
};