【转载】cap,pcap文件中的ipv4数据包转成ipv6数据包
来源:https://blog.csdn.net/mincheat/article/details/78180656
cap , pcap文件结构(解析),网上多得是,这里就不写了。 写这个,主要是工作中正好需要大量的ipv6数据包,但是ipv6数据包不太好找,干脆就直接写个简单的工具,把ipv4转成对应的ipv6,可用于测试。
cpp代码:
// Ipv4ToIpv6_pCap.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <windows.h> #define DLT_EN10MB 1 struct pcap_file_header { UINT32 magic; UINT16 version_major; UINT16 version_minor; UINT32 thiszone; /* gmt to local correction */ UINT32 sigfigs; /* accuracy of timestamps */ UINT32 snaplen; /* max length saved portion of each pkt */ UINT32 linktype; /* data link type (LINKTYPE_*) */ }; struct pcap_pkthdr { struct timeval ts; /* time stamp */ UINT32 caplen; /* length of portion present */ UINT32 len; /* length this packet (off wire) */ }; struct EthernetPacket { char MacDst[6]; ///< 目的网卡物理地址 char MacSrc[6]; ///< 源网卡物理地址 unsigned short PacketType; ///< 包类型, ip或ARP等 }; struct PKT_IP { UINT8 uHeaderLen:4; UINT8 uVersion:4; UINT8 uServType; UINT16 uTotalLen; UINT16 uIdent; UINT16 uFragOffset; UINT8 uTTL; UINT8 uProtocol; UINT16 uCheckSum; UINT32 addSrc; UINT32 addDst; }; struct PKT_IPV6 { union { UINT32 Vfc; struct { UINT8 uClass:4; UINT8 uVersion:4; }; }; UINT16 uPayloadLength; UINT8 uNextHeader; UINT8 uHopLimit; UINT8 addrSrc[16]; UINT8 addrDst[16]; }; inline UINT16 NTOH16(const UINT16& nData) { return ((nData & 0xFF00) >> 8) | ((nData & 0x00FF) << 8); } inline UINT32 NTOH32(const UINT32& nData) { return ((nData & 0xFF000000) >> 24) | ((nData & 0x00FF0000) >> 8) | ((nData & 0x0000FF00) << 8) | ((nData & 0x000000FF) << 24); } int _tmain(int argc, char* argv[]) { if (argc != 3) { printf("arg: inputfile, outputfile! \n"); //getchar(); return -1; } FILE* pFileIn = fopen(argv[1], "rb"); FILE* pFileOut = fopen(argv[2], "wb"); bool bSucces = false; do { if (NULL == pFileIn || NULL == pFileOut) { printf("open file fail \n"); break; } pcap_file_header fileheader; memset(&fileheader, 0, sizeof(pcap_file_header)); fread(&fileheader, 1, sizeof(fileheader), pFileIn); if (DLT_EN10MB != fileheader.linktype) { printf("only support enthernet catch packets! \n"); break; } fwrite(&fileheader, 1, sizeof(fileheader), pFileOut); pcap_pkthdr pkHdr; UINT32 packetTotalCount = 0; UINT32 packetTran = 0; UINT8 packetBuffer[5*1024] = {}; do { if (sizeof(pkHdr) == fread(&pkHdr, 1, sizeof(pkHdr), pFileIn)) { if (pkHdr.caplen != pkHdr.len) { // add //printf("pkHdr.caplen != pkHdr.len packetNum = %d \n", packetTotalCount+1); } if (pkHdr.caplen == fread(packetBuffer, 1, pkHdr.caplen, pFileIn) && pkHdr.caplen > sizeof(EthernetPacket)) { EthernetPacket* pEPacket = (EthernetPacket*)packetBuffer; if (0x08 == pEPacket->PacketType) // ipv4 { // PKT_IP* pIpHdr = (PKT_IP*)(packetBuffer + sizeof(EthernetPacket)); pIpHdr->uTotalLen = NTOH16(pIpHdr->uTotalLen); if (pkHdr.caplen < pIpHdr->uTotalLen + sizeof(EthernetPacket)) // 后面有可能会有补的数据,所以caplen可以会大于后面的值 { printf("len error! packetNum = %d \n", packetTotalCount+1); break; } pEPacket->PacketType = 0xDD86; PKT_IPV6 pktIpv6Hdr; memset(&pktIpv6Hdr, 0, sizeof(pktIpv6Hdr)); pktIpv6Hdr.uVersion = 6; //pktIpv6Hdr.Vfc = CSNTOH32(pktIpv6Hdr.Vfc); UINT16 paylen = pIpHdr->uTotalLen - pIpHdr->uHeaderLen*4; pktIpv6Hdr.uPayloadLength = NTOH16(paylen); pktIpv6Hdr.uNextHeader = pIpHdr->uProtocol; pktIpv6Hdr.uHopLimit = pIpHdr->uTTL; memcpy(pktIpv6Hdr.addrSrc+12, &(pIpHdr->addSrc), 4); memcpy(pktIpv6Hdr.addrDst+12, &(pIpHdr->addDst), 4); pkHdr.caplen = sizeof(EthernetPacket) + sizeof(PKT_IPV6) + paylen; pkHdr.len = pkHdr.caplen; fwrite(&pkHdr, 1, sizeof(pkHdr), pFileOut); // 写pack header fwrite(pEPacket, 1, sizeof(EthernetPacket), pFileOut); // 写ether fwrite(&pktIpv6Hdr, 1, sizeof(PKT_IPV6), pFileOut); // 写ipv6头 UINT8* pOtherData = packetBuffer + sizeof(EthernetPacket) + pIpHdr->uHeaderLen*4; fwrite(pOtherData, 1, paylen, pFileOut); // 写剩下的数据 packetTran++; } else { // 其他包,直接写入 fwrite(&pkHdr, 1, sizeof(pkHdr), pFileOut); fwrite(packetBuffer, 1, pkHdr.caplen, pFileOut); } } else { printf("read packet caplen less packetNum = %d \n", packetTotalCount+1); break; } packetTotalCount++; } else { if (feof(pFileIn)) { //printf("read end! \n"); bSucces = true; } else { printf("Read less data! packetTotalCount = %d \n", packetTotalCount); } break; } } while (true/*!feof(pFileIn)*/); printf("totalPacket = %d, transPacket = %d\n", packetTotalCount, packetTran); } while (false); if (pFileIn) { fclose(pFileIn); } if (pFileOut) { fclose(pFileOut); } if (!bSucces) { printf("Process %s fail! \n", argv[1]); DeleteFileA(argv[2]); } //getchar(); //pcap_file_header return 0; }
另外还有个批处理文件 .bat
@echo off ::cd %~dp0 set inputFolder=E:\work\vsproject\Ipv4ToIpv6_pCap\Debug set outPutFolder=E:\work\vsproject\Ipv4ToIpv6_pCap\Debug\newFolder set exepath=E:\work\vsproject\Ipv4ToIpv6_pCap\Debug\Ipv4ToIpv6_pCap.exe set suffix=_ipv6.cap for /f "delims=\" %%s in ('dir /b /a-d /o-d %inputFolder%\*.pcap,*.cap') do ( echo -------------handle filename = %%s ------------ %exepath% %inputFolder%\%%s %outPutFolder%\%%s%suffix% ) pause

浙公网安备 33010602011771号