自己动手写网络抓包工具Word下载.docx

上传人:b****6 文档编号:20166123 上传时间:2023-01-17 格式:DOCX 页数:10 大小:18.70KB
下载 相关 举报
自己动手写网络抓包工具Word下载.docx_第1页
第1页 / 共10页
自己动手写网络抓包工具Word下载.docx_第2页
第2页 / 共10页
自己动手写网络抓包工具Word下载.docx_第3页
第3页 / 共10页
自己动手写网络抓包工具Word下载.docx_第4页
第4页 / 共10页
自己动手写网络抓包工具Word下载.docx_第5页
第5页 / 共10页
点击查看更多>>
下载资源
资源描述

自己动手写网络抓包工具Word下载.docx

《自己动手写网络抓包工具Word下载.docx》由会员分享,可在线阅读,更多相关《自己动手写网络抓包工具Word下载.docx(10页珍藏版)》请在冰豆网上搜索。

自己动手写网络抓包工具Word下载.docx

=~IFF_PROMISC;

现在我们可以抓到本网段的所有IP数据包了,但是问题也来了:

那么多的数据,怎么处理?

CPU可能会被严重占用,而且绝大多数的数据我们可能根本就不敢兴趣!

那怎么办呢?

用if语句?

可能要n多个,而且丝毫不会降低内核的繁忙程度。

最好的办法就是告诉内核,把不感兴趣的数据过滤掉,不要往应用层送。

BPF就为此而生。

BPF(BerkeleyPacketFilter)是一种类是汇编的伪代码语言,它也有命令代码和操作数。

例如,如果我们只对用户192.168.1.4的数据感兴趣,可以用tcpdump的-d选项生成BPF代码如下:

$tcpdump-dhost192.168.1.4

(000)ldh[12]

(001)jeq#0x800jt2jf6

(002)ld[26]

(003)jeq#0xc0a80104jt12jf4

(004)ld[30]

(005)jeq#0xc0a80104jt12jf13

(006)jeq#0x806jt8jf7

(007)jeq#0x8035jt8jf13

(008)ld[28]

(009)jeq#0xc0a80104jt12jf10

(010)ld[38]

(011)jeq#0xc0a80104jt12jf13

(012)ret#96

(013)ret#0

其中第一列代表行号,第二列是命令代码,后面是操作数。

下面我们采用汇编注释的方式简单的解释一下:

(000)ldh[12];

loadh?

?

(2bytes)fromABSoffset12(theTYPEofethernetheader)

(001)jeq#0x800jt2jf6;

compareandjump,jumptoline2iftrue;

elsejumptoline6

(002)ld[26];

loadword(4bytes)fromABSoffset26(srcIPaddressofIPheader)

(003)jeq#0xc0a80104jt12jf4;

compareandjump,jumptoline12iftrue,elsejumptoline4

(004)ld[30];

loadword(4bytes)fromABSoffset30(dstIPaddressofIPheader)

(005)jeq#0xc0a80104jt12jf13;

seeline3

(006)jeq#0x806jt8jf7;

comparewithARP,seeline1

(007)jeq#0x8035jt8jf13;

comparewithRARP,seeline1

(008)ld[28];

srcIPaddressforotherprotocols

(009)jeq#0xc0a80104jt12jf10

(010)ld[38];

dstIPaddressforotherprotocols

(011)jeq#0xc0a80104jt12jf13

(012)ret#96;

return96bytestouserapplication

(013)ret#0;

dropthepacket

但是这样的伪代码我们是无法在应用程序里使用的,所以tcpdum提供了一个-dd选项来输出一段等效的C代码:

$tcpdump-ddhost192.168.1.4

{0x28,0,0,0x0000000c},

{0x15,0,4,0x00000800},

{0x20,0,0,0x0000001a},

{0x15,8,0,0xc0a80104},

{0x20,0,0,0x0000001e},

{0x15,6,7,0xc0a80104},

{0x15,1,0,0x00000806},

{0x15,0,5,0x00008035},

{0x20,0,0,0x0000001c},

{0x15,2,0,0xc0a80104},

{0x20,0,0,0x00000026},

{0x15,0,1,0xc0a80104},

{0x6,0,0,0x00000060},

{0x6,0,0,0x00000000},

该代码对应的数据结构是structsock_filter,该结构在linux/filter.h中定义如下:

structsock_filter//Filterblock

{

__u16code;

//Actualfiltercode

__u8jt;

//Jumptrue

__u8jf;

//Jumpfalse

__u32k;

//Genericmultiusefield

};

code对应命令代码;

jt是jumpiftrue后面的操作数,注意这里用的是相对行偏移,如2就表示向前跳转2行,而不像伪代码中使用绝对行号;

jf为jumpiffalse后面的操作数;

k对应伪代码中第3列的操作数。

了解了BPF伪代码和结构,我们就可以自己定制更加简单有效的BPFfilter了,如上例中的6-11行不是针对IP协议的,而我们的套接字已经指定只读取IP数据了,所以就可以把他们删除,不过要注意,行偏移也要做相应的修改。

另外,tcpdump默认只返回96字节的数据,但对大部分应用来说,96字节是远远不够的,所以tcpdump提供了-s选项用于指定返回的数据长度。

OK,下面我们就来看看怎样把过滤器安装到套接口上吧:

$tcpdumpip-d-s2048host192.168.1.2

(000)ldh[12]

(001)jeq#0x800jt2jf7

(002)ld[26]

(003)jeq#0xc0a80102jt6jf4

(004)ld[30]

(005)jeq#0xc0a80102jt6jf7

(006)ret#2048

(007)ret#0

structsock_filterbpf_code[]={

{0x28,0,0,0x0000000c},

{0x15,0,5,0x00000800},

{0x20,0,0,0x0000001a},

{0x15,2,0,0xc0a80102},

{0x20,0,0,0x0000001e},

{0x15,0,1,0xc0a80102},

{0x6,0,0,0x00000800},

{0x6,0,0,0x00000000}

structsock_fprogfilter;

filter.len=sizeof(bpf_code)/sizeof(bpf_code[0]);

filter.filter=bpf_code;

setsockopt(sock,SOL_SOCKET,SO_ATTACH_FILTER,&

filter,sizeof(filter));

最后加上信号处理器,以便能在程序退出前恢复网卡的工作模式。

到现在我们已经可以看到一个小聚规模抓包小工具了,呵呵,麻雀虽小,但也五脏俱全啊!

下面给出完整的代码。

#include&

lt;

sys/types.h&

gt;

sys/time.h&

sys/ioctl.h&

sys/socket.h&

linux/types.h&

netinet/in.h&

netinet/udp.h&

netinet/ip.h&

netpacket/packet.h&

net/ethernet.h&

arpa/inet.h&

string.h&

signal.h&

net/if.h&

stdio.h&

sys/uio.h&

fcntl.h&

unistd.h&

linux/filter.h&

stdlib.h&

#defineETH_HDR_LEN14

#defineIP_HDR_LEN20

#defineUDP_HDR_LEN8

#defineTCP_HDR_LEN20

staticintsock;

voidsig_handler(intsig)

structifreqethreq;

if(sig==SIGTERM)

printf("

SIGTERMrecieved,exiting...\n"

);

elseif(sig==SIGINT)

SIGINTrecieved,exiting...\n"

elseif(sig==SIGQUIT)

SIGQUITrecieved,exiting...\n"

//turnoffthePROMISCOUSmode

if(ioctl(sock,SIOCGIFFLAGS,&

ethreq)!

=-1){

}

close(sock);

exit(0);

intmain(intargc,char**argv){

intn;

charbuf[2048];

unsignedchar*ethhead;

unsignedchar*iphead;

structsigactionsighandle;

#if0

$tcpdumpip-s2048-dhost192.168.1.2

(001)jeq#0x800jt2jf7

(003)jeq#0xc0a80102jt6jf4

(005)jeq#0xc0a80102jt6jf7

(007)ret#0

#endif

{0x15,0,5,0x00000800},

{0x15,2,0,0xc0a80102},

{0x15,0,1,0xc0a80102},

{0x6,0,0,0x00000800},

sighandle.sa_flags=0;

sighandle.sa_handler=sig_handler;

sigemptyset(&

sighandle.sa_mask);

//sigaddset(&

sighandle.sa_mask,SIGTERM);

sighandle.sa_mask,SIGINT);

sighandle.sa_mask,SIGQUIT);

sigaction(SIGTERM,&

sighandle,NULL);

sigaction(SIGINT,&

sigaction(SIGQUIT,&

//AF_PACKETallowsapplicationtoreadpecketfromandwritepackettonetworkdevice

//SOCK_DGRAMthepacketexcludeethernetheader

//SOCK_RAWrawdatafromthedeviceincludingethernetheader

//ETH_P_IPallIPpackets

if((sock=socket(AF_PACKET,SOCK_RAW,htons(ETH_P_IP)))==-1){

perror("

socket"

exit

(1);

ethreq)==-1){

ioctl"

if(ioctl(sock,SIOCSIFFLAGS,&

//attachthebpffilter

if(setsockopt(sock,SOL_SOCKET,SO_ATTACH_FILTER,&

filter,sizeof(filter))==-1){

setsockopt"

while

(1){

n=recvfrom(sock,buf,sizeof(buf),0,NULL,NULL);

if(n&

(ETH_HDR_LEN+IP_HDR_LEN+UDP_HDR_LEN)){

invalidpacket\n"

continue;

%dbytesrecieved\n"

n);

ethhead=buf;

Ethernet:

MAC[%02X:

%02X:

%02X]"

ethhead[0],ethhead[1],ethhead[2],

ethhead[3],ethhead[4],ethhead[5]);

-&

[%02X:

ethhead[6],ethhead[7],ethhead[8],

ethhead[9],ethhead[10],ethhead[11]);

type[%04x]\n"

(ntohs(ethhead[12]|ethhead[13]&

&

8)));

iphead=ethhead+ETH_HDR_LEN;

//headerlengthas32-bit

IP:

Version:

%dHeaderLen:

%d[%d]"

(*iphead&

4),(*iphead&

0x0f),(*iphead&

0x0f)*4);

TotalLen%d"

(iphead[2]&

8|iphead[3]));

IP[%d.%d.%d.%d]"

iphead[12],iphead[13],iphead[14],iphead[15]);

[%d.%d.%d.%d]"

iphead[16],iphead[17],iphead[18],iphead[19]);

%d"

iphead[9]);

if(iphead[9]==IPPROTO_TCP)

[TCP]"

elseif(iphead[9]==IPPROTO_UDP)

[UDP]"

elseif(iphead[9]==IPPROTO_ICMP)

[ICMP]"

elseif(iphead[9]==IPPROTO_IGMP)

[IGMP]"

else

[OTHERS]"

PORT[%d]-&

[%d]\n"

(iphead[20]&

8|iphead[21]),(iphead[22]&

8|iphead[23]));

本文来自CSDN博客,转载请标明出处:

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 幼儿教育 > 幼儿读物

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1