使用WinPcap抓取各种包

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

使用WinPcap抓取各种包

使用WinPcap抓各种包

#include<stdio.h> 

#include<iostream> 

#defineHAVE_REMOTE 

#include"pcap.h" 

#include"remote-ext.h" 

 

#pragmacomment(lib,"Ws2_32.lib") 

#pragmacomment(lib,"wpcap.lib") 

 

usingnamespace std; 

 

FILE*fp; 

 

//以太网协议格式的定义 

typedefstructether_header { 

   u_char ether_dhost[6];     // 目标地址 

   u_char ether_shost[6];     // 源地址 

   u_short ether_type;        // 以太网类型 

}ether_header; 

 

//用户保存4字节的IP地址 

typedefstructip_address { 

   u_char byte1; 

   u_char byte2; 

   u_char byte3; 

   u_char byte4; 

}ip_address; 

 

 

//用于保存IPV4的首部 

typedefstructip_header{ 

#ifdefWORDS_BIGENDIAN 

    u_char ip_version : 4, header_length :4; 

#else 

   u_char header_length : 4, ip_version : 4; 

#endif 

 

   u_char ver_ihl;    // 版本以及首部长度,各4位 

   u_char tos;        // 服务质量 

   u_short tlen;      // 总长度 

   u_short identification;     //身份识别 

   u_short offset;        // 分组偏移 

   u_char ttl;        // 生命周期 

   u_char proto;      // 协议类型 

   u_short checksum;      // 包头测验码 

   ip_address saddr;  //源IP地址 

   ip_address daddr;  //目的IP地址 

   u_int op_pad;      //可选填充字段 

}ip_header; 

 

//保存TCP首部 

typedefstructtcp_header { 

   u_short sport; 

   u_short dport; 

   u_int sequence;    // 序列码 

   u_int ack;                 // 回复码 

 

#ifdefWORDS_BIGENDIAN 

    u_char offset : 4, reserved : 4;       //偏移预留 

#else 

   u_char reserved : 4, offset : 4;       // 预留偏移 

#endif 

     

   u_char flags;              // 标志 

   u_short windows;           // 窗口大小 

   u_short checksum;          // 校验和 

   u_short urgent_pointer;    // 紧急指针 

}tcp_header; 

 

typedefstructudp_header { 

   u_int32_t sport;           // 源端口 

   u_int32_t dport;           // 目标端口 

   u_int8_t zero;             // 保留位 

   u_int8_t proto;            // 协议标识 

   u_int16_t datalen;         // UDP数据长度 

}udp_header; 

 

typedefstructicmp_header { 

   u_int8_t type;             // ICMP类型 

   u_int8_t code;             // 代码 

   u_int16_t checksum;        // 校验和 

   u_int16_t identification;  // 标识 

   u_int16_t sequence;        // 序列号 

   u_int32_t init_time;       // 发起时间戳 

   u_int16_t recv_time;       // 接受时间戳 

   u_int16_t send_time;       // 传输时间戳 

}icmp_header; 

 

typedefstructarp_header {  

   u_int16_t arp_hardware_type; 

   u_int16_t arp_protocol_type; 

   u_int8_t arp_hardware_length; 

   u_int8_t arp_protocol_length; 

   u_int16_t arp_operation_code; 

   u_int8_t arp_source_ethernet_address[6]; 

   u_int8_t arp_source_ip_address[4]; 

   u_int8_t arp_destination_ethernet_address[6]; 

   u_int8_t arp_destination_ip_address[4]; 

}arp_header; 

 

voidtcp_protocol_packet_handle( 

   u_char *argument,  

   conststructpcap_pkthdr *packet_header,  

   constu_char *packet_content  

) { 

   structtcp_header*tcp_protocol; 

   u_short sport; 

   u_short dport; 

   int header_length; 

   u_short windows; 

   u_short urgent_pointer; 

   u_int sequence; 

   u_int acknowledgement; 

   u_short checksum; 

   u_char flags; 

 

    printf("===========TCP Protocol===========\n"); 

 

    tcp_protocol = (structtcp_header*)(packet_content + 14 + 20); 

    sport = ntohs(tcp_protocol->sport); 

    dport = ntohs(tcp_protocol->dport); 

    header_length = tcp_protocol->offset *4; 

    sequence =ntohl(tcp_protocol->sequence); 

    acknowledgement =ntohl(tcp_protocol->ack); 

    windows =ntohs(tcp_protocol->windows); 

    urgent_pointer =ntohs(tcp_protocol->urgent_pointer); 

    flags = tcp_protocol->flags; 

    checksum =ntohs(tcp_protocol->checksum); 

 

    fprintf(fp,"%d0%d%d%c%d", header_length, sport, dport,flags, windows); 

 

   switch(dport) { 

   default: 

       break; 

    } 

 

   if(flags & 0x08) printf("PSH"); 

   if(flags & 0x10) printf("ACK"); 

   if(flags & 0x02) printf("SYN"); 

   if(flags & 0x20) printf("URG"); 

   if(flags & 0x01) printf("FIN"); 

   if(flags & 0x04) printf("RST"); 

    printf("\n"); 

 

voidudp_protocol_packet_handle( 

   u_char *argument, 

   conststructpcap_pkthdr *packet_header, 

   constu_char *packet_content 

) { 

   structudp_header*udp_protocol; 

   u_short sport; 

   u_short dport; 

   u_short datalen; 

     

    udp_protocol = (structudp_header*)(packet_content + 14 + 20); 

    sport = ntohs(udp_protocol->sport); 

    dport = ntohs(udp_protocol->dport); 

    datalen =ntohs(udp_protocol->datalen); 

 

    fprintf(fp,"0%d%d%d",datalen, sport, dport); 

 

voidarp_protocol_packet_handle( 

   u_char *argument, 

   conststructpcap_pkthdr *packet_header, 

   constu_char *packet_content 

) { 

   structarp_header*arp_protocol;    

   u_short protocol_type;    

   u_short hardware_type;    

   u_short operation_code;    

   u_char hardware_length;    

   u_char protocol_length;    

 

   structtm* ltime; 

   char timestr[16]; 

   time_t local_tv_sec; 

    local_tv_sec =packet_header->ts.tv_sec; 

    ltime = localtime(&local_tv_sec); 

    strftime(timestr,sizeof(timestr),"%H:%M:%S", ltime); 

 

    printf("--------   ARP协议    --------\n");    

    arp_protocol = (structarp_header*)(packet_content + 14);    

    hardware_type =ntohs(arp_protocol->arp_hardware_type);    

    protocol_type =ntohs(arp_protocol->arp_protocol_type);    

    operation_code =ntohs(arp_protocol->arp_operation_code);    

    hardware_length =arp_protocol->arp_hardware_length;    

    protocol_length =arp_protocol->arp_protocol_length; 

     

    fprintf(fp,"%d%s", protocol_length, timestr); 

 

   switch (operation_code)    

    { 

       case 1:    

            printf("ARP请求协议\n");    

           break;    

       case 2:    

            printf("ARP应答协议\n");    

           break;    

       case 3:    

            printf("RARP请求协议\n");    

           break;    

       case 4:    

            printf("RARP应答协议\n");    

           break;    

       default:    

           break;    

    }    

 

 

 

voidicmp_protocol_packet_handle( 

   u_char *argument, 

   conststructpcap_pkthdr *packet_header, 

   constu_char *packet_content 

) { 

   structicmp_header*icmp_protocol; 

   u_short type; 

   u_short datalen; 

   u_int init_time; 

   u_int recv_time; 

   u_int send_time; 

 

    icmp_protocol = (structicmp_header*)(packet_content + 14 + 20); 

    datalen =sizeof(icmp_protocol); 

    type = icmp_protocol->type; 

    init_time =icmp_protocol->init_time; 

    recv_time =icmp_protocol->recv_time; 

    send_time =icmp_protocol->send_time; 

  

    fprintf(fp,"%d%c%d%d%d", datalen, type, init_time,recv_time, send_time); 

 

//  printf("===========ICMPProtocol==========\n"); 

 

   switch(icmp_protocol->type) { 

   case 8: 

       //回显请求报文 

       break; 

   case 0: 

       //回显应答报文 

       break; 

   default: 

       break; 

    } 

 

voidip_protocol_packet_handle( 

   u_char *argument,  

   conststructpcap_pkthdr *packet_header,  

   constu_char *packet_content  

) { 

   structip_header*ip_protocol; 

   u_int header_length; 

   u_char tos; 

   u_short checksum; 

     

   ip_address saddr; 

   ip_address daddr; 

   u_char ttl; 

   u_short tlen; 

   u_short identification; 

   u_short offset; 

 

    printf("===========IP Protocol===========\n"); 

 

    ip_protocol = (structip_header*)(packet_content + 14); 

    header_length =ip_protocol->header_length * 4; 

    checksum =ntohs(ip_protocol->checksum); 

    tos = ip_protocol->tos; 

    offset =ntohs(ip_protocol->offset); 

 

    saddr = ip_protocol->saddr; 

    daddr = ip_protocol->daddr; 

    ttl = ip_protocol->ttl; 

    identification =ip_protocol->identification; 

    tlen = ip_protocol->tlen; 

    offset = ip_protocol->offset; 

 

    fprintf(fp,"%d%d%c%d%d%d", saddr, daddr, ttl,identification, tlen, offset); 

 

   switch(ip_protocol->proto) { 

   case 6: 

        tcp_protocol_packet_handle(argument,packet_header,packet_content); 

       break; 

   case 17: 

        udp_protocol_packet_handle(argument,packet_header,packet_content); 

       break; 

   case 1: 

        icmp_protocol_packet_handle(argument,packet_header,packet_content); 

       break; 

   default: 

       break; 

    } 

}  

 

 

voidethernet_protocol_packet_handle ( 

   u_char *argument,  

   conststructpcap_pkthdr *packet_header,  

   constu_char *packet_content 

) { 

   u_short ethernet_type;     // 以太网类型 

   structether_header*ethernet_protocol;    // 以太网协议变量 

   u_char *mac_string;        // 以太网地址 

 

    ethernet_protocol = (structether_header*)packet_content;      //获取以太网数据内容 

    printf("Ethernet type is : \n"); 

    ethernet_type =ntohs(ethernet_protocol->ether_type);   //获取以太网类型 

   printf("   %04x\n", ethernet_type); 

 

     

 

   switch(ethernet_type) { 

   case 0x0800: 

        printf("The network layer is IP protocol\n"); 

       break; 

   case 0x0806: 

        printf("The network layer is ARP protocol\n"); 

       break; 

   default: 

       break; 

    } 

 

   // 获取以太网源地址 

//  printf("MAC Source Address is :\n"); 

    mac_string =ethernet_protocol->ether_shost; 

     

    fprintf(fp,"%02x:%02x:%02x:%02x:%02x:%02x",  

        *mac_string, 

        *(mac_string + 1), 

        *(mac_string + 2), 

        *(mac_string + 3), 

        *(mac_string + 4), 

        *(mac_string + 5) 

        ); 

 

   // 获取以太网目的地址 

//  printf("MAC Target Address is :\n"); 

    mac_string = ethernet_protocol->ether_dhost; 

    fprintf(fp,"%02x:%02x:%02x:%02x:%02x:%02x",  

        *mac_string, 

        *(mac_string + 1), 

        *(mac_string + 2), 

        *(mac_string + 3), 

        *(mac_string + 4), 

        *(mac_string + 5) 

        ); 

 

    fprintf(fp,"%d",sizeof(packet_content)); 

 

   switch(ethernet_type) { 

   case 0x0800: 

        ip_protocol_packet_handle(argument,packet_header,packet_content); 

       break; 

   default: 

       break; 

    } 

 

intmain() { 

   pcap_if_t *alldevs; 

   pcap_if_t *d; 

   pcap_t *adhandle; 

   char errbuf[PCAP_ERRBUF_SIZE]; 

   int inum; 

   int i = 0; 

   u_int netmask; 

   char packet_filter[] ="ip and tcp"; 

   structbpf_programfcode; 

   int res; 

   structpcap_pkthdr*header; 

   structtm *ltime; 

   constu_char *pkt_data; 

   time_t local_tv_sec; 

   char timestr[16]; 

   ip_header *ih; 

 

   // 获得设备列表pcap_findalldevs_ex() 

 

   if(pcap_findalldevs_ex(PCAP_SRC_IF_STRING,NULL, &alldevs, errbuf)== -1) { 

        fprintf(stderr,"Errorin pcap_findalldevs: %s\n", errbuf); 

        exit(1); 

    } 

 

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

        printf("%d. %s", ++i, d->name); 

       if(d->description) { 

            printf("(%s)\n", d->description); 

        } 

       else { 

            printf("No description available\n"); 

        } 

    } 

     

   if(0 == i) { 

        printf("\nNo interface found!Make sure WinPcap is installed\n"); 

       return -1; 

    } 

 

    printf("Enter the interface number(1-%d):",i); 

    scanf_s("%d", &inum); 

   if(inum < 1 || inum > i) { 

        printf("\nInterface number out of range.\n"); 

        pcap_freealldevs(alldevs); 

       return -1; 

    } 

 

   for(d = alldevs, i = 0; i < inum-1; d=d->next, i++); 

   // 跳转到该设备,打开适配器 

 

   // 设备名,要捕捉的数据包的部分(65536保证能捕获到不同数据链路层上的每个数据包的全部内容),混杂模式,读取超时时间,错误缓冲池 

   if((adhandle = pcap_open_live(d->name, 65536, 1, 1000, errbuf)) ==NULL) { 

        fprintf(stderr,"\nUnableto open the adapter.%s is not supported by WinPcap\n", errbuf); 

        pcap_freealldevs(alldevs); 

       return -1; 

    } 

   // 检查数据链路层(只考虑了以太网) 

   if(pcap_datalink(adhandle) !=DLT_EN10MB) { 

        fprintf(stderr,"\nThisprogram works only on Ethernet networks.\n"); 

        pcap_freealldevs(alldevs); 

       return -1; 

    } 

 

   if(d->addresses !=NULL){ 

       //获得接口的第一个地址的掩码 

        netmask = ((structsockaddr_in*)(d->addresses->netmask))->sin_addr.S_un.S_addr; 

    } 

   else { 

        netmask = 0xffffff; 

    } 

/*

    //编译过滤器

    if(pcap_compile(adhandle, &fcode,packet_filter, 1, netmask) < 0) {

        fprintf(stderr, "\nUnable tocompile the packet filter.Check the syntax\n");

        pcap_freealldevs(alldevs);

        return -1;

    }

    

    //设置过滤器

    

    if(pcap_setfilter(adhandle, &fcode)< 0) {

        fprintf(stderr, "\nError settingthe filter.\n");

        pcap_freealldevs(alldevs);

        return -1;

    }

    printf("\nlistenting on %s...\n",d->description);

*/ 

    fp = freopen("in.txt","w",stdin); 

 

   while((res = pcap_next_ex(adhandle, &header, &pkt_data)) >= 0){  

 

       //请求超时 

       if(0 == res) { 

           continue; 

        } 

 

       //分析数据包 

        ethernet_protocol_packet_handle(NULL, header, pkt_data); 

 

       //将时间戳转换成可识别的格式 

        local_tv_sec =header->ts.tv_sec; 

        ltime =localtime(&local_tv_sec); 

        strftime(timestr,sizeof(timestr),"%H:%M:%S", ltime); 

        ih = (ip_header *)(pkt_data + 14);//以太网头部长度 

 

       //输出时间和IP信息 

        printf("%s.%.6d len:%d ", timestr, header->ts.tv_usec,header->len); 

 

        printf("%d.%d.%d.%d -> %d.%d.%d.%d\n", 

            ih->saddr.byte1, 

            ih->saddr.byte2, 

            ih->saddr.byte3, 

            ih->saddr.byte4, 

            ih->daddr.byte1, 

            ih->daddr.byte2, 

            ih->daddr.byte3, 

            ih->daddr.byte4); 

    } 

 

     

   if(-1 == res) { 

        printf("Error reading the packet:%s\n",pcap_geterr(adhandle)); 

       return -1; 

    } 

    pcap_freealldevs(alldevs); 

 

    fclose(fp); 

    fclose(stdin); 

 

   return 0; 

 

 

 

 

 

 

 

 

 

           

给我老师的人工智能教程打call!http://blog.csdn.net/jiangjunshow
这里写图片描述
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值