IP6

 *程序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);
} ...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值