LPF

Linuxでパケットをキャプチャーするためには、BPFに似たLinux Packet Filterという仕組みを使う。これは基本的にBSDのBPFと似たものだがBPF のように機能が豊富ではない。

まず、 struct sock_fprogtcpdump -ddを用いて 作成したstruct sock_filterを代入する(以下)。

	struct sock_filter code[] {
	    { 0x28, 0, 0, 0x0000000c },
	    { 0x15, 0, 1, 0x00000800 },
	    { 0x6, 0, 0, 0x00000060 },
	    { 0x6, 0, 0, 0x00000000 }
	};
	struct sock_fprog filter;
	filter.len = 4; /* number of code[] */
	 filter.filter = code;
次に
	sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP));
のようにしてraw socketを開きsetsockopt()でフィルター を登録する。
	if( setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) < 0 ) {
		perror("setsockopt");
		close(sock);
		exit(EXIT_FAILURE);
	}
後はrecvfrom()などを使用してキャプチャーできる。 ただ、実際はキャプチャーするためには、ネットワークカードを 以下のようにpromiscuos modeにする必要がある。
	struct ifreq    ethreq;

	/* promiscuos mode */
	strncpy(ethreq.ifr_name,"eth0",IFNAMSIZ);
	if (ioctl(sock,SIOCGIFFLAGS,ðreq)==-1) {
		perror("ioctl");
		close(sock);
		exit(EXIT_FAILURE);
	}
	ethreq.ifr_flags|=IFF_PROMISC;
	if (ioctl(sock,SIOCSIFFLAGS,ðreq)==-1) {
		perror("ioctl");
		close(sock);
		exit(EXIT_FAILURE);
	}
具体的には このようなコードになるでしょう。 Last modified: Fri Jun 29 16:33:11 JST 2001