Skip to content

Instantly share code, notes, and snippets.

@ijinjay
Last active August 29, 2015 14:02
Show Gist options
  • Save ijinjay/fa6538375d276b88a96f to your computer and use it in GitHub Desktop.
Save ijinjay/fa6538375d276b88a96f to your computer and use it in GitHub Desktop.
#include <iostream>
#include <stdlib.h>
using namespace std;
typedef unsigned char u_char;
typedef unsigned short u_short;
// pcap header
typedef struct pcap_file_header {
__int32_t magic; // 标志位,默认为16进制的 0xa1b2c3d4
__int16_t version_major; // 主版本号,默认为Ox2。返回写入被打开文件所使用的pcap函数的主版本号
__int16_t version_minor; // 副版本号,默认为0x04
__int32_t timezone; // 区域时间
__int32_t sigfigs; // 精确时间戳
__int32_t slaplen; // 数据包最大长度,设置所抓获的数据包的最大长度,如果所有数据包都要抓获,设为65535
__int32_t linktype; // 链路层类型, 数据值与链路层对应表:
} pcap;
// package data header
typedef struct package_header {
__int32_t timesecond; // Seconds
__int32_t timeSS; // MicroSeconds
__int32_t pLength; // Length of portion present
__int32_t length; // Length this packet
} package;
// ip address
typedef struct ip_address {
u_char byte1;
u_char byte2;
u_char byte3;
u_char byte4;
} ip_address;
// ipv4 header
typedef struct ip_header {
u_char ver_ihl; //版本(4bit) + 首部长度(4bit)
u_char tos; // 服务类型(type of service)
__int16_t tlen; // 总长
__int16_t identification; // 标志
__int16_t flags_fo; // 标志位(3bits)+ 段偏移量(13bits)
u_char ttl; // 存活时间
u_char proto; // 协议
/* 0 保留字段,用于IPv6(跳跃点到跳跃点选项)
* 6 TCP协议
*/
__int16_t crc; // 首部校验和
ip_address saddr; // 源地址
ip_address daddr; // 目的地址
// u_int op_pad; // 选项与填充
} ip_header;
// UDP header
typedef struct UDP_header {
u_short sport; // 源端口
u_short dport; // 目的端口
u_short len; // UDP数据包长度
u_short crc; // 校验和
} UDP_header;
/*TCP头定义,共20个字节*/
typedef struct _TCP_HEADER {
u_short m_sSourPort; // 源端口号16bit
u_short m_sDestPort; // 目的端口号16bit
unsigned int m_uiSequNum; // 序列号32bit
unsigned int m_uiAcknowledgeNum; // 确认号32bit
u_short m_sHeaderLenAndFlag; // 前4位:TCP头长度;中6位:保留;后6位:标志位
u_short m_sWindowSize; // 窗口大小16bit
u_short m_sCheckSum; // 检验和16bit
u_short m_surgentPointer; // 紧急数据偏移量16bit
} TCP_header;
// MAC header
typedef struct _MAC_FRAME_HEADER
{
char m_cDstMacAddress[6]; //目的mac地址
char m_cSrcMacAddress[6]; //源mac地址
u_short m_cType; //上一层协议类型,如0x0800代表上一层是IP协议,0x0806为arp
} MAC_header;
// MAC tail
typedef struct _MAC_FRAME_TAIL
{
unsigned int m_sCheckSum; //数据帧尾校验和
} MAC_tail;
// print ip address
void printIP(ip_address ip) {
printf("ip_address:\n%d.%d.%d.%d\n", ip.byte1, ip.byte2, ip.byte3, ip.byte4);
}
// ip address & port
typedef struct ip_port {
ip_address sadd;
u_short sport;
ip_address dadd;
u_short dport;
} ip_port;
int main(){
pcap pcap_header;
package package_header;
int iPosition = 0;
// 打开文件
if (FILE *fp = fopen("baidu.pcap", "r")) {
fseek( fp, 0, SEEK_END);
// 文件长度
long fileLen = ftell(fp);
printf("File Length is %ld\n", fileLen);
fseek( fp, 0, SEEK_SET);
// 将文件放入缓冲区
char *buffer = (char *)malloc(fileLen);
fread( (void*)buffer, 1, fileLen, fp);
fclose(fp);
// 解析pcap头文件信息
memcpy( (void*)&pcap_header, (void*)(buffer), sizeof(pcap));
printf("pcap header info: \nmaigc\t%x\nmajor_v\t%u\nminor_v\t%u\nt_zone\t%u\nsigfigs\t%u\nsnaplen\t%u\nl_type\t%u\n",
pcap_header.magic, pcap_header.version_major, pcap_header.version_minor, pcap_header.timezone, pcap_header.sigfigs, pcap_header.slaplen, pcap_header.linktype);
// 写入新文件
FILE *f = fopen("handle1.pcap", "wb+");
fwrite((void *)&pcap_header, sizeof(char), sizeof(pcap), f);
// 解析数据包
iPosition = 24;
int packageNum = 1;
while (iPosition < fileLen){
// 数据包头信息
memcpy((void *)&package_header, (void *)(buffer+iPosition), sizeof(package));
printf("%d\tpackage header info:\ntimesecond:\t%u\ntimeMicro:\t%u\nportLength:\t%u\npacketLength:\t%u\n",
packageNum, package_header.timesecond, package_header.timeSS, package_header.pLength, package_header.length);
iPosition += 16;
// 数据部分信息
int pLength = (int)package_header.length;
char *pData = (char *)malloc(pLength - 14);
memcpy((void *)pData, (void *)(buffer+iPosition+14), pLength - 14);
// ip头
ip_header ip_headerData;
memcpy((void *)&ip_headerData, (void *)pData, sizeof(ip_headerData));
if ((int)ip_headerData.proto == 6) {
fwrite((void *)&package_header, sizeof(char), sizeof(package), f);
fwrite((void *)(buffer + iPosition), sizeof(char), pLength, f);
}
iPosition += pLength;
packageNum ++;
}
fclose(f);
}
return 0;
}
#include <iostream>
using namespace std;
#include <stdlib.h>
typedef unsigned char u_char;
typedef unsigned short u_short;
// pcap header
typedef struct pcap_file_header {
__int32_t magic; // 标志位,默认为16进制的 0xa1b2c3d4
__int16_t version_major; // 主版本号,默认为Ox2。返回写入被打开文件所使用的pcap函数的主版本号
__int16_t version_minor; // 副版本号,默认为0x04
__int32_t timezone; // 区域时间
__int32_t sigfigs; // 精确时间戳
__int32_t slaplen; // 数据包最大长度,设置所抓获的数据包的最大长度,如果所有数据包都要抓获,设为65535
__int32_t linktype; // 链路层类型, 数据值与链路层对应表:
} pcap;
// package data header
typedef struct package_header {
__int32_t timesecond; // Seconds
__int32_t timeSS; // MicroSeconds
__int32_t pLength; // Length of portion present
__int32_t length; // Length this packet
} package;
// ip address
typedef struct ip_address {
u_char byte1;
u_char byte2;
u_char byte3;
u_char byte4;
} ip_address;
// ipv4 header
typedef struct ip_header {
u_char ver_ihl; //版本(4bit) + 首部长度(4bit)
u_char tos; // 服务类型(type of service)
__int16_t tlen; // 总长
__int16_t identification; // 标志
__int16_t flags_fo; // 标志位(3bits)+ 段偏移量(13bits)
u_char ttl; // 存活时间
u_char proto; // 协议
__int16_t crc; // 首部校验和
ip_address saddr; // 源地址
ip_address daddr; // 目的地址
// u_int op_pad; // 选项与填充
} ip_header;
/*TCP头定义,共20个字节*/
typedef struct _TCP_HEADER {
u_short m_sSourPort; // 源端口号16bit
u_short m_sDestPort; // 目的端口号16bit
unsigned int m_uiSequNum; // 序列号32bit
unsigned int m_uiAcknowledgeNum; // 确认号32bit
u_short m_sHeaderLenAndFlag; // 前4位:TCP头长度;中6位:保留;后6位:标志位
u_short m_sWindowSize; // 窗口大小16bit
u_short m_sCheckSum; // 检验和16bit
u_short m_surgentPointer; // 紧急数据偏移量16bit
} TCP_header;
// ip address & port
typedef struct ip_port {
ip_address sadd;
u_short sport;
ip_address dadd;
u_short dport;
} ip_port;
// print ip address
void printIP(ip_address ip) {
printf("%d.%d.%d.%d\n", ip.byte1, ip.byte2, ip.byte3, ip.byte4);
}
// print ip & port
void printIpPort(ip_port ipPort){
printIP(ipPort.sadd);
printf("source port:%d\n", ipPort.sport);
printIP(ipPort.dadd);
printf("destination port:%d\n", ipPort.dport);
}
// hash table
typedef struct node {
ip_port ipport;
struct node *next;
} node;
#define TABSIZE 3571
static node *hashTable[TABSIZE];
void initHashTable(){
for (int i = 0; i < TABSIZE; ++i) {
hashTable[i] = NULL;
}
}
size_t ip2hex(ip_address ip){
return (size_t)(ip.byte1 << 24) + (size_t)(ip.byte2 << 16) + (size_t)(ip.byte3 << 8) + (size_t)(ip.byte4);
}
int hash_ip_port(ip_port ipPort) {
return (((size_t)ip2hex(ipPort.sadd) * 59) ^ ((size_t)ip2hex(ipPort.dadd)) ^ ((size_t)(ipPort.sport) << 16) ^ ((size_t)(ipPort.dport)))%TABSIZE;
}
void insertHashTable(ip_port ipPort){
int index = hash_ip_port(ipPort);
if (hashTable[index] == NULL) {
hashTable[index] = (node *)malloc(sizeof(node));
hashTable[index]->ipport = ipPort;
hashTable[index]->next = NULL;
}
else {
node *tempNode = hashTable[index];
while (tempNode != NULL) {
tempNode = tempNode->next;
}
tempNode = (node *)malloc(sizeof(node));
tempNode->ipport = ipPort;
tempNode->next = NULL;
}
}
void printHashTable(){
int k = 0;
for (int i = 0; i < TABSIZE; ++i) {
if (hashTable[i] != NULL) {
printf("Table index %d\n", i);
int j = 0;
node* tempNode = hashTable[i];
while (tempNode != NULL) {
printIpPort(tempNode->ipport);
tempNode = tempNode->next;
j ++;
}
printf("---\t%d\n", j);
k ++;
}
}
printf("No. = %d\n", k);
}
int main(int argc, char const *argv[]) {
// pcap_header
pcap pcap_header;
int iPosition = 0;
if (FILE *fp = fopen("/Users/jinjay/Code/Pcap/Parse/Parse/handle.pcap", "r+")) {
fseek( fp, 0, SEEK_END);
// 文件长度
long fileLen = ftell(fp);
printf("File Length is %ld\n", fileLen);
fseek( fp, 0, SEEK_SET);
// 将文件放入缓冲区
char *buffer = (char *)malloc(fileLen);
fread( (void*)buffer, 1, fileLen, fp);
fclose(fp);
memcpy((void *)&pcap_header, (void *)buffer, sizeof(pcap));
iPosition = 24;
// 读tcp数据
initHashTable();
while (iPosition < fileLen) {
// 数据包头信息
package package_header;
memcpy((void *)&package_header, (void *)(buffer+iPosition), sizeof(package));
// printf("package header info:\ntimesecond:\t%u\ntimeMicro:\t%u\nportLength:\t%u\npacketLength:\t%u\n",
// package_header.timesecond, package_header.timeSS, package_header.pLength, package_header.length);
iPosition += 16;
// 数据部分信息
int pLength = (int)package_header.pLength;
// 14个字节
char *pData = (char *)malloc(pLength - 14);
memcpy((void *)pData, (void *)(buffer + iPosition + 14), pLength - 14);
// ip头
ip_header ip_headerData;
memcpy((void *)&ip_headerData, (void *)pData, sizeof(ip_headerData));
// tcp头
TCP_header tcpHeader;
memcpy((void *)&tcpHeader, (void *)(pData + sizeof(ip_header)), sizeof(tcpHeader));
ip_port ipPort;
ipPort.sadd = ip_headerData.saddr;
ipPort.dadd = ip_headerData.daddr;
ipPort.sport = tcpHeader.m_sSourPort;
ipPort.dport = tcpHeader.m_sDestPort;
printIpPort(ipPort);
// printf("%d\n", hash_ip_port(ipPort));
iPosition += pLength;
// printf("pacage length is %d\n", iPosition);
insertHashTable(ipPort);
}
printHashTable();
}
printf("End\n");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment