C
Network

Cでパケットを受信(監視)する

More than 1 year has passed since last update.


概要

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ヘッダを理解する

を参照して頂ければと思います。