linux 网卡收数据线程,[转载]linux下利用多线程循环抓取指定网卡上的数据包

用到了Libpcap 多线程,信号,临界资源,ioctl获取网卡信息。代码如下

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define IP_Swap_32(x) ( (

((x)>>24) |

(((x)>>8)&0xff00) ) |

( ((x)<<24) |

(((x)<<8)&0xff0000) )

)

#define Max_Cap_Loop 100

#define MAXINTERFACES 16

unsigned char Count=0; //累计抓包次数

unsigned long Packet=0; //每次抓包个数

unsigned long TotalCap=0; //总包数

unsigned long TotalDrop=0;//总丢弃数

pthread_t Time; //计时,每次抓30秒

pthread_t Loop_Packet; //循环抓包

pthread_mutex_t

mut; //临界区信号量,到指定时间后Count自增,并重新启动抓包线程

char Filter[8096];

unsigned long CapTime=0;

pcap_if_t *alldevs;

struct pcap_stat p_s; //状态

pcap_t *adhandle; //运行时句柄

char errbuf[PCAP_ERRBUF_SIZE];

struct bpf_program fp;

bpf_u_int32 maskp;

bpf_u_int32 netp;

struct InterfaceInfo{

char *in_name;

char *description;

unsigned char ip[4];

unsigned char mask[4];

};

struct Turple{

unsigned char proto;

unsigned char sip[4];

unsigned char dip[4];

unsigned short sport;

unsigned short dport; } turple;

InterfaceInfo net_interface[MAXINTERFACES];

int count_interface=0;

int timeup=0;

void sig_handle(int sig)

{

if (SIGINT == sig) {

timeup=-1;

printf("n- END -n");

}

}

void callback(u_char *param,const pcap_pkthdr *header,const

u_char *pkt_data)

{

char timestr[16];

//tm

*ltime=localtime(&header->ts.tv_sec);

time_t

dtime=header->ts.tv_sec;

u_int len=header->len;

u_int caplen=header->caplen;

printf("Time:%s Len:%4d,Captured:%4d

",ctime(&dtime),len,caplen);

//for(int

i=0;icaplen;i++)

//printf("%02x",pkt_data[i]);//return;

if(pkt_data[12]==0x08

&& pkt_data[13]==0x00)

{

turple.proto=pkt_data[23];

memcpy(turple.sip,(const

void*)&pkt_data[26],8);

memcpy(&turple.sport,(const

void *)&pkt_data[34],4);

turple.sport=turple.sport>>8|turple.sport<<8;

turple.dport=turple.dport>>8|turple.dport<<8;

printf("%d.%d.%d.%d:%d->%d.%d.%d.%d:%d|%dn",

turple.sip[0],turple.sip[1],turple.sip[2],turple.sip[3],turple.sport,

turple.dip[0],turple.dip[1],turple.dip[2],turple.dip[3],turple.dport,turple.proto);

}

//printf("n");

}

void CountTime(void)

{

for(;;)

{

sleep(CapTime);

Count++;

pthread_mutex_lock(&mut);

timeup=1;

pthread_mutex_unlock(&mut);

}

}

int InitCap(char *filterstring)

{

if(pcap_findalldevs(&alldevs,errbuf)==

-1)

{

pcap_freealldevs(alldevs);

fprintf(stderr,"Error in

pcap_findalldevs:%sn",errbuf);

return -1;

}

pcap_if_t *d;

int iCount=0;

for(d=alldevs;d;d=d->next)

{

net_interface[count_interface].in_name=(char

*)malloc(strlen(d->name)+1);

memcpy(net_interface[count_interface].in_name,d->name,strlen(d->name)+1);

if(d->description)

{

net_interface[count_interface].description=(char

*)malloc(strlen(d->description)+1);

memcpy(net_interface[count_interface].description,d->description,strlen(d->description)+1);

}

else

net_interface[count_interface].description="No

description"; memset(net_interface[count_interface].ip,0,4);

pcap_lookupnet(d->name,&netp,&maskp,errbuf);

net_interface[count_interface].mask[0]=maskp>>24;

net_interface[count_interface].mask[1]=maskp>>16;

net_interface[count_interface].mask[2]=maskp>>8;

net_interface[count_interface].mask[3]=maskp;

count_interface++;

iCount++;

}

if(iCount==0)

{

pcap_freealldevs(alldevs);

printf("nNo interface found!

Make sure Libpcap is working");

return -2;

}

pcap_freealldevs(alldevs);

return 0;

}

int InitCap_m(void)

{

register int fd, interface;

struct ifreq buf[MAXINTERFACES];

struct ifconf ifc;

if ((fd = socket(AF_INET, SOCK_DGRAM, 0))

>= 0)

{

ifc.ifc_len = sizeof buf;

ifc.ifc_buf = (caddr_t)

buf;

if (!ioctl(fd, SIOCGIFCONF,

(char *) &ifc))

{

interface =

ifc.ifc_len / sizeof(struct ifreq);

//printf("interface num is interface=%dnn",

interface);

while (interface-- > 0)

{

for(int

i=0;i

if((strcmp(buf[interface].ifr_name,net_interface[i].in_name))==0)

{

if

(!(ioctl(fd, SIOCGIFADDR, (char *)

&buf[interface])))

{

unsigned

long v;

v=*((unsigned

long*)&(((struct

sockaddr_in*)(&buf[interface].ifr_addr))->sin_addr));

memcpy(net_interface[i].ip,(unsigned

char *)(&v),4);

}

else

{

char

str[256] = "";

sprintf(str,

"cpm: ioctl device %s",

buf[interface].ifr_name);

perror(str);

close(fd);

return

-1;

}

}

}//end of

while

}

else

{ perror("cpm:

ioctl");

close(fd);

return

-1;

}

}

else

{ perror("cpm: socket");

return -1;

}

close(fd);

return 0;

}

int show_choose_dev(void)

{

int iChoose;

int iCount=count_interface;

for(int

i=0;i

{

printf("%d.%s(%s)

ip_addr:%d.%d.%d.%d,netmask:%d.%d.%d.%dn",

i+1,net_interface[i].in_name,net_interface[i].description,

net_interface[i].ip[0],net_interface[i].ip[1],net_interface[i].ip[2],net_interface[i].ip[3],

net_interface[i].mask[0],net_interface[i].mask[1],net_interface[i].mask[2],net_interface[i].mask[3]

);

}

printf("Choose an

interface(1-%d):",iCount);

scanf("%d",&iChoose);

printf("Your Choose:%dn",iChoose);

if(iChoose<1||iChoose>iCount)

{

printf("nInterface number out

of range.n");

return -1;

}

printf("nStart to sniffer on

%s..n",net_interface[iChoose-1].in_name);

return iChoose; }

int StartCap(int dev_num)

{

int iChoose=dev_num;

adhandle=pcap_open_live(net_interface[iChoose-1].in_name,65535,1,1000,errbuf);

if(adhandle==NULL)

{

fprintf(stderr,"nUnable to

open the adapter.n");

return

-1; }

maskp=(bpf_u_int32)(IP_Swap_32(*((unsigned

long*)(&(net_interface[iChoose-1].mask)))));

if(pcap_compile(adhandle,&fp,Filter,0,maskp)==-1)

{

fprintf(stderr,"Error calling

pcap_compilen");

pcap_close(adhandle);

return -1;

}

if(pcap_setfilter(adhandle,&fp)==-1)

{

pcap_close(adhandle);

fprintf(stderr,"Error setting

filtern");

return -1;

}

pcap_loop(adhandle,1000000,callback,NULL);

//printf("close========================================================================n");

//pcap_close(adhandle);//pcap_breakloop函数会关闭句柄故再次关闭会导致重复释放

return 0;

}

int main(int argc,char *argv[])

{

int create_thread_retval;

if(argc<=1

||argc>3)

{

printf("t Usage:%s

cap_time(seconds) "filter"n",argv[0]);

return -1;

}

memset(Filter,0,8096);

memcpy(Filter,argv[2],strlen(argv[2]));

CapTime=atol(argv[1]);

//printf("%d,%s,%dn",argc,Filter,CapTime);

signal(SIGINT, sig_handle);//register ctrl+c

to system

if(CapTime<=0||CapTime>0xffffff)

{

printf("Please input acceptable

timen");

return -1;

}

//printf("-n");

if(InitCap(Filter)!=0)

{

printf("Initiation capture

failed!n");

return -1;

}

if(InitCap_m()!=0)

{

printf("Get network interface

failed!n");

return -1;

}

int dev_num=show_choose_dev();

printf("main process starting:n");

if((create_thread_retval=pthread_create(&Time,NULL,(void*(*)(void*))CountTime,NULL))!=0)

{

printf("Create 'Count_Time'

thread failed!n");

return -1;

}

if((create_thread_retval=pthread_create(&Loop_Packet,NULL,(void*(*)(void*))StartCap,(void*)dev_num))!=0)

{

printf("Create 'Packet_Capture'

thread failed!n");

return -1;

}

while(timeup!=-1)

{

while(timeup==1)

{

pthread_mutex_lock(&mut);

printf("_%d#

capture finished==|++",Count);

timeup=0;

pcap_stats(adhandle,&p_s);

TotalCap+=p_s.ps_recv,

TotalDrop+=p_s.ps_drop;

printf("recv:%u,drop:%u,T_Cap=%u,T_Drop=%unn",p_s.ps_recv,p_s.ps_drop,TotalCap,TotalDrop);

pcap_breakloop(adhandle);

if((create_thread_retval=pthread_create(&Loop_Packet,NULL,(void*(*)(void*))StartCap,(void*)dev_num))!=0)

{

printf("Create

'Packet_Capture' thread failed!n");

return

-1;

}

pthread_mutex_unlock(&mut);

}

}

return 0;

}

文件存为file.cpp

编译+连接

gcc -lpcap -lpthread -lstdc++ -x c++ file.cpp

或者 g++ -lpcap -lpthread file.cpp

运行

[root@localhost experience]# ./a.out 5 "ip and host

218.199.87.171 and host ! 218.199.87.157 and udp port 9991"

1.eth0(No description)

ip_addr:192.168.0.10,netmask:128.255.255.255

2.eth1(No description)

ip_addr:218.199.87.171,netmask:128.255.255.255

3.any(Pseudo-device that captures on all interfaces)

ip_addr:0.0.0.0,netmask:0.0.0.0

4.lo(No description) ip_addr:127.0.0.1,netmask:0.0.0.255

Choose an interface(1-4):2

- END -

^[[A

Your Choose:0

Interface number out of range.

main process starting:

[root@localhost experience]# ./a.out 5 "ip and host 218.199.87.171

and host ! 218.199.87.157 and

tcp" 1.eth0(No description)

ip_addr:192.168.0.10,netmask:128.255.255.255

2.eth1(No description)

ip_addr:218.199.87.171,netmask:128.255.255.255

3.any(Pseudo-device that captures on all interfaces)

ip_addr:0.0.0.0,netmask:0.0.0.0

4.lo(No description) ip_addr:127.0.0.1,netmask:0.0.0.255

Choose an interface(1-4):2

Your Choose:2

Start to sniffer on eth1..

main process starting:

_1# capture finished==|++recv:0,drop:0,T_Cap=0,T_Drop=0

_2# capture finished==|++recv:1,drop:0,T_Cap=1,T_Drop=0

_3# capture finished==|++recv:0,drop:0,T_Cap=1,T_Drop=0

_4# capture finished==|++recv:1,drop:0,T_Cap=2,T_Drop=0

_5# capture finished==|++recv:1,drop:0,T_Cap=3,T_Drop=0

_6# capture finished==|++recv:1,drop:0,T_Cap=4,T_Drop=0

Time:Wed Dec 23 21:39:09 2009

Len: 74,Captured: 74

218.199.87.171:35757->152.46.7.222:80|6

Time:Wed Dec 23 21:39:09 2009

Len: 74,Captured: 74

218.199.87.171:35757->152.46.7.222:80|6

Time:Wed Dec 23 21:39:09 2009

Len: 74,Captured: 74

218.199.87.171:35757->152.46.7.222:80|6

Time:Wed Dec 23 21:39:09 2009

Len: 74,Captured: 74

218.199.87.171:35757->152.46.7.222:80|6

Time:Wed Dec 23 21:39:09 2009

Len: 74,Captured: 74

218.199.87.171:35757->152.46.7.222:80|6

Time:Wed Dec 23 21:39:09 2009

Len: 74,Captured: 74 Time:Wed Dec 23 21:39:09

2009

Len: 74,Captured: 74

218.199.87.171:35757->152.46.7.222:80|6

218.199.87.171:35757->152.46.7.222:80|6

Time:Wed Dec 23 21:39:09 2009

Len: 74,Captured: 74

152.46.7.222:80->218.199.87.171:35757|6

Time:Wed Dec 23 21:39:09 2009

Len: 66,Captured: 66

218.199.87.171:35757->152.46.7.222:80|6

Time:Wed Dec 23 21:39:09 2009

Len: 579,Captured: 579

218.199.87.171:35757->152.46.7.222:80|6

Time:Wed Dec 23 21:39:09 2009

Len: 66,Captured: 66

152.46.7.222:80->218.199.87.171:35757|6

Time:Wed Dec 23 21:39:09 2009

Len:1514,Captured:1514

152.46.7.222:80->218.199.87.171:35757|6

Time:Wed Dec 23 21:39:09 2009

Len: 66,Captured: 66

218.199.87.171:35757->152.46.7.222:80|6

Time:Wed Dec 23 21:39:09 2009

Len:1514,Captured:1514

152.46.7.222:80->218.199.87.171:35757|6

Time:Wed Dec 23 21:39:09 2009

Len: 66,Captured: 66

218.199.87.171:35757->152.46.7.222:80|6

Time:Wed Dec 23 21:39:09 2009

Len:1514,Captured:1514

152.46.7.222:80->218.199.87.171:35757|6

Time:Wed Dec 23 21:39:09 2009

Len: 66,Captured: 66

218.199.87.171:35757->152.46.7.222:80|6

Time:Wed Dec 23 21:39:09 2009

Len: 680,Captured: 680

152.46.7.222:80->218.199.87.171:35757|6

Time:Wed Dec 23 21:39:09 2009

Len: 66,Captured: 66

218.199.87.171:35757->152.46.7.222:80|6

_7# capture finished==|++recv:14,drop:0,T_Cap=18,T_Drop=0

_8# capture finished==|++recv:1,drop:0,T_Cap=19,T_Drop=0

_9# capture finished==|++recv:1,drop:0,T_Cap=20,T_Drop=0

Time:Wed Dec 23 21:39:24 2009

Len: 66,Captured: 66

152.46.7.222:80->218.199.87.171:35757|6

Time:Wed Dec 23 21:39:24 2009

Len: 66,Captured: 66 Time:Wed Dec 23 21:39:24

2009

Len: 66,Captured: 66

152.46.7.222:80->218.199.87.171:35757|6

Time:Wed Dec 23 21:39:24 2009

Len: 66,Captured: 66

152.46.7.222:80->218.199.87.171:35757|6

152.46.7.222:80->218.199.87.171:35757|6

Time:Wed Dec 23 21:39:24 2009

Len: 66,Captured: 66

218.199.87.171:35757->152.46.7.222:80|6

_10# capture finished==|++recv:3,drop:0,T_Cap=23,T_Drop=0

Time:Wed Dec 23 21:39:27 2009

Len: 74,Captured: 74

218.199.87.171:35478->121.195.178.52:80|6

Time:Wed Dec 23 21:39:27 2009

Len: 74,Captured: 74

218.199.87.171:35478->121.195.178.52:80|6

Time:Wed Dec 23 21:39:27 2009

Len: 74,Captured: 74

121.195.178.52:80->218.199.87.171:35478|6

Time:Wed Dec 23 21:39:27 2009

Len: 66,Captured: 66

218.199.87.171:35478->121.195.178.52:80|6

Time:Wed Dec 23 21:39:27 2009

Len: 849,Captured: 849

218.199.87.171:35478->121.195.178.52:80|6

Time:Wed Dec 23 21:39:27 2009

Len: 66,Captured: 66

121.195.178.52:80->218.199.87.171:35478|6

Time:Wed Dec 23 21:39:27 2009

Len: 307,Captured: 307

121.195.178.52:80->218.199.87.171:35478|6

Time:Wed Dec 23 21:39:27 2009

Len: 66,Captured: 66

218.199.87.171:35478->121.195.178.52:80|6

Time:Wed Dec 23 21:39:27 2009

Len: 818,Captured: 818

218.199.87.171:35478->121.195.178.52:80|6

Time:Wed Dec 23 21:39:27 2009

Len: 323,Captured: 323

121.195.178.52:80->218.199.87.171:35478|6

Time:Wed Dec 23 21:39:27 2009

Len: 66,Captured: 66

218.199.87.171:35478->121.195.178.52:80|6

_11# capture finished==|++recv:11,drop:0,T_Cap=34,T_Drop=0

_12# capture finished==|++recv:1,drop:0,T_Cap=35,T_Drop=0

Time:Wed Dec 23 21:39:38 2009

Len: 66,Captured: 66

218.199.87.171:35757->152.46.7.222:80|6

Time:Wed Dec 23 21:39:38 2009

Len: 66,Captured: 66

218.199.87.171:35757->152.46.7.222:80|6

Time:Wed Dec 23 21:39:38 2009

Len: 66,Captured: 66

218.199.87.171:35757->152.46.7.222:80|6

Time:Wed Dec 23 21:39:38 2009

Len: 74,Captured: 74

218.199.87.171:44727->123.125.51.20:80|6

Time:Wed Dec 23 21:39:38 2009

Len: 66,Captured: 66

152.46.7.222:80->218.199.87.171:35757|6

Time:Wed Dec 23 21:39:38 2009

Len: 74,Captured: 74

123.125.51.20:80->218.199.87.171:44727|6

Time:Wed Dec 23 21:39:38 2009

Len: 66,Captured: 66

218.199.87.171:44727->123.125.51.20:80|6

Time:Wed Dec 23 21:39:38 2009

Len: 743,Captured: 743

218.199.87.171:44727->123.125.51.20:80|6

Time:Wed Dec 23 21:39:38 2009

Len: 66,Captured: 66

123.125.51.20:80->218.199.87.171:44727|6

Time:Wed Dec 23 21:39:38 2009

Len: 233,Captured: 233

123.125.51.20:80->218.199.87.171:44727|6

Time:Wed Dec 23 21:39:38 2009

Len: 66,Captured: 66

218.199.87.171:44727->123.125.51.20:80|6

Time:Wed Dec 23 21:39:38 2009

Len: 66,Captured: 66

123.125.51.20:80->218.199.87.171:44727|6

Time:Wed Dec 23 21:39:38 2009

Len: 66,Captured: 66

218.199.87.171:44727->123.125.51.20:80|6

Time:Wed Dec 23 21:39:38 2009

Len: 66,Captured: 66

123.125.51.20:80->218.199.87.171:44727|6

_13# capture finished==|++recv:12,drop:0,T_Cap=47,T_Drop=0

- END -

(按 CTRL+C)

由于线程和主进程争用资源 导致显示不是严格按序号

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值