#概要
Cで対象のインターフェイスから受信フレームを取得する方法を解説します。
###環境構築
CentOSを想定しています。
コンパイラ(gcc)やパケットを取得するためのlibpcapというライブラリを使用します。
yum -y update
yum install -y gcc vim wget tar flex byacc
wget http://www.tcpdump.org/release/libpcap-1.8.1.tar.gz
tar zxvf libpcap-1.8.1.tar.gz
cd libpcap-1.8.1
./configure
make -j 8
make install
###ソースコード
pcap_open_live()で初期設定を行い、
pcap_loop()でパケット取得のループを開始します。
pcap_loop()にコールバック関数を登録するとパケット受信毎に
コールバック関数がコールされます。
get_pkt.c
#include <pcap.h>
#include <stdio.h>
#include <stdlib.h>
#define DPCP_RCV_MAXSIZE 68
#define DPCP_PROMSCS_MODE 1
#define DPCP_RCV_TIMEOUT 1000
#define DPCP_NOLIMIT_LOOP -1
void start_pktfunc( u_char *,const struct pcap_pkthdr * ,const u_char *);
int main( void ){
pcap_t *pd = NULL;
char ebuf[PCAP_ERRBUF_SIZE];
if( (pd = pcap_open_live( "eth0" , // インターフェイス名
DPCP_RCV_MAXSIZE , // 最大受信サイズ(最初の68byteまで受信する)
DPCP_PROMSCS_MODE , // 自分宛以外のパケットも処理の対象にする
DPCP_RCV_TIMEOUT , // タイムアウト時間(ミリ秒)
ebuf )) == NULL ){
// error
exit(-1);
}
if( pcap_loop( pd ,
DPCP_NOLIMIT_LOOP , // エラーが発生するまで取得を続ける
start_pktfunc, // パケット受信した時のCallBack関数
NULL // CallBack関数へ渡す引数
) < 0 ){
// error
exit(-1);
}
pcap_close(pd);
return 0;
}
void start_pktfunc( u_char *user, // pcap_loop関数の第4引数
const struct pcap_pkthdr *h , // 受信したPacketの補足情報
const u_char *p // 受信したpacketへのポインタ
){
// packet処理
printf("receive packet¥n");
}
###コンパイル、実行
gcc -Wall -o get_pkt get_pkt.c -lpcap -L/usr/local/lib/
export LD_LIBRARY_PATH=/usr/local/lib/
./libpcap
packet処理については、
C言語でフレーム内容を見る(Etherヘッダ)
IPヘッダを理解する
を参照して頂ければと思います。