예전부터 네트워크 프로그램을 많이 작성을 하면서 pcap 라이브러리를 이용해서 패킷캡쳐를 했었다.
http://luca.ntop.org/Ring.pdf

하지만 우연한 기회에 위의 논문에서 PF_RING이라는 방식으로 패킷을 캡쳐하면 패킷 캡쳐 효율이 보다 좋다는 것을 알게 되었다. 대부분 응용프로그램을 감시하는 프로그램에서는 기존의 방식으로도 충분하겠지만, 100M 이상의 네트워크를 처리하거나, 네트워크에서 모니터링을 목적으로 만든 장비에서는 중요한 항목이 될수 있으므로 관심을 가지게 되었다.
그래서 공개된 소스로 원리를 파악하고 기존의 프로그램을 업데이트의 필요성을 느끼게 되었다.
일단 아래의 사이트에서 PF_RING 커널 모듈을 따라서 설치하면 쉽게 설치를 할수 있다.
http://www.ntop.org/get-started/download/
kernel-devel 패키지가 설치가 되어 있는 경우라면 쉽게 컴파일을 해서 pf_ring.ko 파일 만들기가 되므로, insmod 명령어로 커널에 모듈로 올리면 된다.
[root@localhost PF_RING]# lsmod |grep pf_ring
pf_ring 365711 0
그리고 SVN 서버에서 usermode 프로그램 예제도 같이 들어가 있어서 소스도 확인을 할수 있고, 또한 샘플 프로그램도 확인이 가능하다. 그리고 pf_ring 을 사용하는 tcpdump 프로그램도 들어가 있는 것을 확인할 수 있다.
[root@localhost examples]# ./pcount
Capturing from eth0
=========================
Absolute Stats: [48 pkts rcvd][0 pkts dropped]
Total Pkts=48/Dropped=0.0 %
48 pkts [49.7 pkt/sec] - 2880 bytes [0.02 Mbit/sec]
=========================
=========================
Absolute Stats: [108 pkts rcvd][0 pkts dropped]
Total Pkts=108/Dropped=0.0 %
108 pkts [54.9 pkt/sec] - 6716 bytes [0.03 Mbit/sec]
=========================
Actual Stats: 108 pkts [1000.1 ms][107.98 pkt/sec]
=========================
=========================
Absolute Stats: [158 pkts rcvd][0 pkts dropped]
Total Pkts=158/Dropped=0.0 %
158 pkts [53.3 pkt/sec] - 10032 bytes [0.03 Mbit/sec]
=========================
Actual Stats: 50 pkts [1000.1 ms][50.00 pkt/sec]
=========================
소스를 확인해보면 기존의 라이브러리 대신에 소스에 포함되어 있는 pfring과 pcap 라이브러리를 사용해서 컴파일을 하면 된다.
[root@localhost userland]# ldd examples/pcount
linux-vdso.so.1 => (0x00007fffaf179000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003664800000)
libc.so.6 => /lib64/libc.so.6 (0x0000003664000000)
/lib64/ld-linux-x86-64.so.2 (0x0000003663800000)
[root@localhost userland]# ls -al libpcap/libpcap.a
-rw-r--r-- 1 root root 401912 2012-04-18 18:19 libpcap/libpcap.a
[root@localhost userland]# ls -al lib/libpfring.a
-rw-r--r-- 1 root root 172836 2012-04-18 18:18 lib/libpfring.a
[root@localhost userland]# cd examples/
[root@localhost examples]# touch pcount.c
[root@localhost examples]# make
gcc -O2 -Wall -I../../kernel -I../../kernel/plugins -I../lib -I../libpcap-1.1.1-ring -D HAVE_ZERO -O2 -c pcount.c -o pcount.o
gcc -O2 -Wall -I../../kernel -I../../kernel/plugins -I../lib -I../libpcap-1.1.1-ring -D HAVE_ZERO -O2 pcount.o ../libpcap-1.1.1-ring/libpcap.a ../lib/libpfring.a -lpthread -L../libpcap -lpcap -o pcount