*程序3.
*程序名:AnalyzeIPv6_WinPcap.cpp
*本程序通过使用WinPcap来捕获IPv6数据包,并解析IPv6数据包头(包括IPv6数据包中的TCP,UDP,ICMPv6数据包)
*/
#include "iostream"
#include "stdlib.h"
#include "stdio.h"
#include "pcap.h"
#include "string"
#include "winsock2.h"
using namespace std;
#pragma comment(lib,"wpcap.lib")
#pragma comment(lib,"ws2_32.lib")
#define ETHHEADERSIZE 14
#define ETH_IP 0x86DD
//以太帧头结构体
typedef struct ethhdr {
unsigned char DestMac[6];
unsigned char SrcMac[6];
unsigned char Etype[2];
}ETHHEADER,*PETHHEADER;
//IPv4包头结构体
typedef struct ip_header {
u_char ver_ihl; //Version (4 bits) + Internet header length (4 bits)
u_char tos; //Type of service
u_short tlen; //Total length
u_short identification; //Identification
u_short flags_fo; //Flags (3 bits) + Fragment offset (13 bits)
u_char ttl; //Time to live
u_char proto; //Protocol
u_short crc; //Header checksum
u_char ip_src[4]; //Source address
u_char ip_dst[4]; //Destination address
u_int op_pad; //Option + Padding
}*PIP_HEADER;
//IPv6包头结构体
typedef struct ipv6_header {
u_char ver_tf;
u_char traffic;
u_short label;
u_char length[2];
u_char next_header;
u_char limits;
u_char Srcv6[16];
u_char Destv6[16];
}*PIPv6_HEADER;
//TCP包头结构体
typedef struct tcp_header {
u_char SourPort[2];
u_char DestPort[2];
DWORD SeqNo;
DWORD AckNo;
BYTE HLen;
BYTE Flag;
WORD Window;
WORD ChkSum;
WORD UrgPtr;
}TCP_HEADER,*PTCP_HEADER;
//UDP包头结构体
typedef struct udp_header {
u_short sport; //Source port
u_short dport; //Destination port
u_short len; //Datagram length;
u_short crc; //Checksum
}UDP_HEADER,*PUDP_HEADER;
//ICMPv6包头结构体
typedef struct icmpv6 {
u_char type;
u_char code;
u_short check_sum;
u_short label;
u_short num;
u_char con[33];
}*PICMPv6;
void InitAdapter(); //初始化网络适配器
void dispatcher_handler(u_char*,const pcap_pkthdr*,const u_char *);//解析IPv6数据包格式
void CloseAdapter(); //关闭网络适配器
FILE *fp;
pcap_if_t *alldevs,*d;
char errbuf[PCAP_ERRBUF_SIZE];
pcap_t *adhandle;
void main() {
int count=0,number;
cout<<"Please enter the number of packet sended:"<>number;
InitAdapter();
fp=fopen("f:\\000\\ipv6.txt","w");
while(count<=number) {
pcap_loop(adhandle,1,dispatcher_handler,NULL); //捕获数据报
count++;
}
CloseAdapter();
}
void InitAdapter() {
int i;
if(pcap_findalldevs(&alldevs,errbuf)==-1) { //寻找网络适配器
cout<<"Error in pcap_findalldevs!";
return;
}
for(d=alldevs,i=0;i<0;d=d->next,i++);
if((adhandle=pcap_open_live(d->name,65535,1,20,errbuf))==NULL) { //打开选取的网络适配器
cout<<"Unable to open the adapter!";
pcap_freealldevs(alldevs);
return;
}
if(pcap_datalink(adhandle)!=DLT_EN10MB) { //判断网络是否为10MB以太网
cout<<"This program works only on Ethernet network!";
pcap_freealldevs(alldevs);
return;
}
}
void dispatcher_handler(u_char *,const pcap_pkthdr *header,const u_char *pkt_data) {
PETHHEADER eth_header=(PETHHEADER)pkt_data;
PIP_HEADER ip_header=(PIP_HEADER)(pkt_data+14);
static u_char buf1[33];
if(eth_header->Etype[0]==0x86 && eth_header->Etype[1]==0xDD) { //以太帧头中封装的是纯IPv6数据包
fprintf(fp,"MAC帧头:\n");
fprintf(fp,"%02X%02X\n",eth_header->Etype[0],eth_header->Etype[1]); //以太帧头中的协议类型,对纯IPv6是0x86DD
PIPv6_HEADER ipv6=(PIPv6_HEADER)(pkt_data+14);
PTCP_HEADER tcp=(PTCP_HEADER)(pkt_data+54);
PUDP_HEADER udp=(PUDP_HEADER)(pkt_data+54);
PICMPv6 icmp=(PICMPv6)(pkt_data+54);
memcpy(buf1,icmp->con,32);
for(int i=0;i<5;i++)
fprintf(fp,"%02X-",eth_header->DestMac[i]); //目的MAC地址
fprintf(fp,"%02X\n",eth_header->DestMac[5]);
for(i=0;i<5;i++)
fprintf(fp,"%02X-",eth_header->SrcMac[i]); //源MAC地址
fprintf(fp,"%02X\n",eth_header->SrcMac[5]);
fprintf(fp,"IPv6包头:\n");
fprintf(fp,"Edition:%d ",ipv6->ver_tf>>4); //IP版本号
fprintf(fp,"Pack Length:%d ",ipv6->length[0]*256+ipv6->length[1]);//数据包长度
fprintf(fp,"Next header:%d ",ipv6->next_header); //下一包头类型
fprintf(fp,"Limit:%d\n",ipv6->limits); //跳数限制
fprintf(fp,"Source IPv6:");
for(i=0;i<14;i++) {
fprintf(fp,"%X",ipv6->Srcv6[0+i]); //源IPv6地址
i++;
fprintf(fp,"%X:",ipv6->Srcv6[0+i]);
}
fprintf(fp,"%X%X\n",ipv6->Srcv6[14],ipv6->Srcv6[15]);
fprintf(fp,"Destination IPv6:");
for(i=0;i<14;i++) {
fprintf(fp,"%X",ipv6->Destv6[0+i]); //目的IPv6地址
i++;
fprintf(fp,"%X:",ipv6->Destv6[0+i]);
}
fprintf(fp,"%X%X\n",ipv6->Destv6[14],ipv6->Destv6[15]);
if(ipv6->next_header==6) { //判断下一包头的类型,6表示为TCP数据包
fprintf(fp,"Sport:%d ",tcp->SourPort[0]*256+tcp->SourPort[1]); //源端口号
fprintf(fp,"Dport:%d ",tcp->DestPort[0]*256+tcp->DestPort[1]); //目的端口号
if(tcp->Flag&1==1)
fprintf(fp,"FIN");
else if((tcp->Flag&2)==2)
fprintf(fp,"SYN");
else if((tcp->Flag&4)==4)
fprintf(fp,"RST");
else if((tcp->Flag&8)==8)
fprintf(fp,"PSH");
else if((tcp->Flag&16)==16)
fprintf(fp,"ACK");
else if((tcp->Flag&32)==32)
fprintf(fp,"URG");
fprintf(fp,"\n");
}
else if(ipv6->next_header==0x3a) { //判断下一包头的类型,0x3a表示为ICMPv6数据包
fprintf(fp,"Type:%d ",icmp->type);
fprintf(fp,"content:%s\n",buf1);
}
else if(ipv6->next_header==0x17) { //判断下一包头的类型,17表示为UDP数据包
fprintf(fp,"Sport:%d ",ntohs(udp->sport));
fprintf(fp,"Dport:%d ",ntohs(udp->dport));
fprintf(fp,"Length:%d ",ntohs(udp->len));
fprintf(fp,"crc:%d\n",ntohs(udp->crc));
}
fprintf(fp,"**************************************\n");
}
if(eth_header->Etype[0]==0x08 && eth_header->Etype[1]==0x00) { //以太帧头中封装的是IPv4数据包
PIPv6_HEADER ipv6=(PIPv6_HEADER)(pkt_data+34);
PTCP_HEADER tcp=(PTCP_HEADER)(pkt_data+74);
PUDP_HEADER udp=(PUDP_HEADER)(pkt_data+74);
PICMPv6 icmp=(PICMPv6)(pkt_data+74);
memcpy(buf1,icmp->con,32);
if(ip_header->proto==0x29) { //IPv4包头中的Proto字段值为0x29,表示上层数据包为IPv6数据包
//显示以太帧头数据
fprintf(fp,"MAC帧头:\n");
fprintf(fp,"目的MAC地址:");
for(int i=0;i<5;i++)
fprintf(fp,"%02X-",eth_header->DestMac[i]); //目的MAC地址
fprintf(fp,"%02X ",eth_header->DestMac[5]);
fprintf(fp,"源MAC地址:");
for(i=0;i<5;i++)
fprintf(fp,"%02X-",eth_header->SrcMac[i]); //源MAC地址
fprintf(fp,"%02X 类型:",eth_header->SrcMac[5]);
fprintf(fp,"%02X%02X\n",eth_header->Etype[0],eth_header->Etype[1]);//上层协议类型
//显示IPv4包头数据
fprintf(fp,"IPv4包头:\n");
fprintf(fp,"源IPv4地址:");
for(i=0;i<3;i++)
fprintf(fp,"%d.",ip_header->ip_src[i]); //源IPv4地址
fprintf(fp,"%d 目的IPv4地址:",ip_header->ip_src[3]);
for(i=0;i<3;i++)
fprintf(fp,"%d.",ip_header->ip_dst[i]); //目的IPv4地址
fprintf(fp,"%d\n",ip_header->ip_dst[3]);
//显示IPv6包头数据
fprintf(fp,"IPv6包头:\n");
fprintf(fp,"Edition:%d ",ipv6->ver_tf>>4); //IP包版本
fprintf(fp,"Pack Length:%d ",ipv6->length[0]*256+ipv6->length[1]);//数据包长度
fprintf(fp,"Next header:%d ",ipv6->next_header); //下一头部协议类型
fprintf(fp,"Limit:%d\n",ipv6->limits); //跳数限制
fprintf(fp,"Source IPv6:");
for(i=0;i<14;i++) {
fprintf(fp,"%X",ipv6->Srcv6[0+i]); //源IPv6地址
i++;
fprintf(fp,"%X:",ipv6->Srcv6[0+i]);
}
fprintf(fp,"%X%X\n",ipv6->Srcv6[14],ipv6->Srcv6[15]);
fprintf(fp,"Destination IPv6:");
for(i=0;i<14;i++) {
fprintf(fp,"%X",ipv6->Destv6[0+i]); //目的IPv6地址
i++;
fprintf(fp,"%X:",ipv6->Destv6[0+i]);
}
fprintf(fp,"%X%X\n",ipv6->Destv6[14],ipv6->Destv6[15]);
if(ipv6->next_header==6) { //IPv6包头中封装的上层数据类型,值为6表示TCP包
fprintf(fp,"Sport:%d ",tcp->SourPort[0]*256+tcp->SourPort[1]); //源端口号
fprintf(fp,"Dport:%d ",tcp->DestPort[0]*256+tcp->DestPort[1]); //目的端口号
if(tcp->Flag&1==1)
fprintf(fp,"FIN");
else if((tcp->Flag&2)==2)
fprintf(fp,"SYN");
else if((tcp->Flag&4)==4)
fprintf(fp,"RST");
else if((tcp->Flag&8)==8)
fprintf(fp,"PSH");
else if((tcp->Flag&16)==16)
fprintf(fp,"ACK");
else if((tcp->Flag&32)==32)
fprintf(fp,"URG");
fprintf(fp,"\n");
}
else if(ipv6->next_header==0x3a) { //IPv6包头中封装的上层数据类型,值为0x3a表示ICMPv6包
fprintf(fp,"Type:%d ",icmp->type);
fprintf(fp,"content:%s\n",buf1);
}
else if(ipv6->next_header==0x17) { //IPv6包头中封装的上层数据类型,值为17表示UDP包
fprintf(fp,"Sport:%d ",ntohs(udp->sport));
fprintf(fp,"Dport:%d ",ntohs(udp->dport));
fprintf(fp,"Length:%d ",ntohs(udp->len));
fprintf(fp,"crc:%d\n",ntohs(udp->crc));
}
fprintf(fp,"**************************************\n");
}
}
}
void CloseAdapter() {
fclose(fp);
pcap_freealldevs(alldevs);
pcap_close(adhandle);
} ...
IP6
最新推荐文章于 2024-07-23 23:01:53 发布