for(a=d->addresses;a;a=a->next) { switch(a->addr->sa_family) { case AF_INET:
printf(\地址类型: AF_INET\\n\打印网络地址类型 if (a->addr)//打印IP地址 printf(\地址 : %s\\n\
iptos(((struct sockaddr_in *)a->addr)->sin_addr.s_addr)); if (a->netmask)//打印掩码 printf(\掩码 : %s\\n\
iptos(((struct sockaddr_in *)a->netmask)->sin_addr.s_addr)); if (a->broadaddr)//打印广播地址 printf(\广播地址: %s\\n\
iptos(((struct sockaddr_in *)a->broadaddr)->sin_addr.s_addr)); if (a->dstaddr)//目的地址 printf(\
iptos(((struct sockaddr_in *)a->dstaddr)->sin_addr.s_addr)); break; default:
printf(\break; }}}
2.选择一个网卡准备获取数据包:
获得网卡的信息后就可以算则其中一个网卡打开准备接受数据包。打开网卡的功能是通过pcap_open_ live()来实现的。它的函数原型定义如下: pcap_t3pcap_open_live(char3device,intsnaplen,intpromisc,intto_ms,char3ebuf) 在正常情况下网卡只接受去往它的包而去往其他主机的数据包则被忽略,相反当网卡处于混杂模式时它将接收所有的流经它的数据包,这就意味着在共享介质的情况下可以捕获到其它主机的数据包。大部分的包捕获程序都将混杂模式设为默认。 部分主要代码如下: // 打开网卡设备
if ((adhandle= pcap_open_live(d->name,// 设备名称
- 6 -
65536,// 捕获全部的数据包 1,// 设置网卡为混杂模式 1000,// 读超时为1秒 errbuf// 错误缓存 )) == NULL)
{fprintf(stderr,\不能打开网卡. %s 不被Winpcap支持\\n\// 释放设备列表 pcap_freealldevs(alldevs); return -1;}
// 检测链接层,只支持以太网模式 if(pcap_datalink(adhandle) != DLT_EN10MB) {fprintf(stderr,\此程序只能运行在以太网上.\\n\// 释放设备列表 pcap_freealldevs(alldevs); return -1;}
if(d->addresses != NULL) {// 返回接口的第一个地址的掩码
netmask=((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr;} else
{// 如果没有掩码,则默认设置为C类 netmask=0xffffff;}
3.选择一个过滤包类型(数据包的过滤设定)
通过设置数据流过滤规则(filter)来实现。数据包过滤处理是嗅探技术中的难点和重点,Win2 pcap提供了最强大的数据流过滤引擎。它采用了 一种高效的方法来捕获网络数据流的某些数据且常常和系统的捕获机制相集成。过滤数据的函数 是pcap-compile()和pcap_setfilter()来实现的。 部分主要程序代码如下; // 选择过滤包类型
int protocol_type; // 0->ip 1->tcp 2->udp 3->icmp
printf(\请选择监听的数据包协议类型(0->ip 1->tcp 2->udp 3->icmp) : \
- 7 -
scanf(\switch(protocol_type) {case 0:
strcpy(packet_filter,\break; case 1:
strcpy(packet_filter,\break; case 2:
strcpy(packet_filter,\break; case 3:
strcpy(packet_filter,\break; default: break;} // 编译过滤器
if (pcap_compile(adhandle, &fcode, packet_filter, 1, netmask) <0 ) { fprintf(stderr,\不能编译过滤器. 请检测语法.\\n\// 释放设备列表 pcap_freealldevs(alldevs); return -1;} //设置过滤器
if (pcap_setfilter(adhandle, &fcode)<0) { fprintf(stderr,\设置过滤器出错.\\n\pcap_freealldevs(alldevs); return -1; }
- 8 -
4.捕获所选择的数据包
使用pcap_next_ex()从网络接口中读取一个数据包,该函数第一个参数是接口句柄,后两个参数由函数返回,分别为数据包的相关信息和数据 包本身 。函数返回1表示正常接收一个数据包,返回0表示超时,-1表示发生错误。每捕获到一个数据包,就调用PacketHandler()函数对数据包进行后续解析处理。 部分主要程序代码如下: ①主函数代码: //循环捕获数据包
while((res=Pcap_next_ex(adhandle,&header,&Pkt--data))>=0) {//接收超时继续循环 if(res==0)continue; //处理收到的数据包 PacketHandler();} ②调用函数代码:
// 包处理回调函数,对于每个嗅探到的数据包
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data) {ip_header *ih; u_int ip_len; // 返回IP首部的位置 ih = (ip_header *) (pkt_data + 14); //以太网的首部长度是14 // IP首部长度
ip_len = (ih->ver_ihl & 0xf) * 4;
printf(\ \ // 输出源地址IP和目的地址IP
printf(\ \ih->saddr.byte1, ih->saddr.byte2, ih->saddr.byte3, ih->saddr.byte4,
- 9 -
ih->daddr.byte1, ih->daddr.byte2, ih->daddr.byte3, ih->daddr.byte4 );
decode_ip((char*)(pkt_data+14+ip_len),ih->proto); printf(\// 协议识别函数
char *check_protocol(int iProtocol) {for(int i=0; i int decode_tcp(char *tcpbuf) { tcp_header *ptcpheader; int i; // 转换成TCP首部格式 ptcpheader = (tcp_header*)tcpbuf; // 输出源端口和目的端口 printf(\ Port : %d-->%d %unsigned char FlagMask = 1; // 输出标志位 for(i=0;i<6;i++) {if((ptcpheader->th_flag) & FlagMask) {printf(\else - 10 - 百度搜索“70edu”或“70教育网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,70教育网,提供经典综合文库开发基于winPcap的嗅探器(2)在线全文阅读。
相关推荐: