-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathadaptor.cpp
More file actions
161 lines (153 loc) · 5.64 KB
/
adaptor.cpp
File metadata and controls
161 lines (153 loc) · 5.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#include "adaptor.hpp"
#include <unordered_set>
#include <fstream>
#include <iostream>
#include <pcap.h>
#include "pipesketch.cpp"
Adaptor::Adaptor(std::string filename, uint64_t buffersize) {
// cur-当前数据包 cnt-数据包个数 ptr-前一个数据包
unsigned long test = 0;
data = (adaptor_t*)calloc(1, sizeof(adaptor_t));
data->databuffer = (unsigned char*)calloc(buffersize, sizeof(unsigned char));//分配1乘sizeof(char)个字节即1个字节的空间
data->ptr = data->databuffer;
data->cnt = 0;
data->cur = 0;
//Read pcap file
std::string path = filename;
char errbuf[PCAP_ERRBUF_SIZE];
pcap_t* pfile = pcap_open_offline(filename.c_str(), errbuf);//把string类对象转换成和c兼容的char *类型
if (pfile == NULL) {
std::cout << "[Error] Fail to open pcap file" << std::endl;
exit(-1);
}
unsigned char* p = data->databuffer;
//pcpp::RawPacket rawPacket;
const u_char* rawpkt; // raw packet
struct pcap_pkthdr hdr;//数据包捕获
//检测数据包中各个字段的字节数
struct ip* ip_hdr;
while ((rawpkt = pcap_next(pfile, &hdr)) != NULL) {
int status = 1;
int eth_len = ETH_LEN;
// std::cout << "eth_len" << eth_len <<std::endl;
// error checking (Ethernet level)检查网络层
if (eth_len == 14) {
struct ether_header* eth_hdr = (struct ether_header*)rawpkt;
if (ntohs(eth_hdr->ether_type) == ETHERTYPE_VLAN) {
eth_len = 18;
}
else if (ntohs(eth_hdr->ether_type) != ETH_P_IP) {
status = -1;
}
}
else if (eth_len == 4) {
if (ntohs(*(uint16_t*)(rawpkt + 2)) != ETH_P_IP) {
status = -1;
}
}
else if (eth_len != 0) {
// unkown ethernet header length
status = -1;
}
int pkt_len = (hdr.caplen < MAX_CAPLEN) ? hdr.caplen : MAX_CAPLEN;
uint32_t len = pkt_len;
// error checking (IP level)
ip_hdr = (struct ip*)(rawpkt);//+eth_len
// i) IP header length check
if ((int)len < (ip_hdr->ip_hl << 2)) {
status = -1;
}
// ii) IP version check
if (ip_hdr->ip_v != 4) {
status = -1;
}
// iii) IP checksum check
if (IP_CHECK && in_chksum_ip((unsigned short*)ip_hdr, ip_hdr->ip_hl << 2)) {
status = -1;
}
// error checking (TCP/UDP/ICMP layer test)
struct tcphdr* tcp_hdr;
if (ip_hdr->ip_p == IPPROTO_TCP) {
// see if the TCP header is fully captured
tcp_hdr = (struct tcphdr*)((uint8_t*)ip_hdr + (ip_hdr->ip_hl << 2));
if ((int)len < (ip_hdr->ip_hl << 2) + (tcp_hdr->doff << 2)) {
status = -1;
}
} else if (ip_hdr->ip_p == IPPROTO_UDP) {
// see if the UDP header is fully captured
if ((int)len < (ip_hdr->ip_hl << 2) + 8) {
status = -1;
}
} else if (ip_hdr->ip_p == IPPROTO_ICMP) {
// see if the ICMP header is fully captured
if ((int)len < (ip_hdr->ip_hl << 2) + 8) {
status = -1;
}
}
if (status == 1) {
// assign the fields
uint16_t srcport, dstport, iplen;
iplen = ntohs(ip_hdr->ip_len);
if (ip_hdr->ip_p == IPPROTO_TCP) {
// TCP
tcp_hdr = (struct tcphdr*)((uint8_t*)ip_hdr + (ip_hdr->ip_hl << 2));
srcport = ntohs(tcp_hdr->source);
dstport = ntohs(tcp_hdr->dest);
}
else if (ip_hdr->ip_p == IPPROTO_UDP) {
// UDP
struct udphdr* udp_hdr = (struct udphdr*)((uint8_t*)ip_hdr + (ip_hdr->ip_hl << 2));
srcport = ntohs(udp_hdr->source);
dstport = ntohs(udp_hdr->dest);
} else {
// Other L4
srcport = 0;
dstport = 0;
}
int srcip = ntohl(ip_hdr->ip_src.s_addr);
int dstip = ntohl(ip_hdr->ip_dst.s_addr);
uint8_t protocol = (uint8_t)(ip_hdr->ip_p);
memcpy(p, &srcip, sizeof(uint32_t));
memcpy(p+sizeof(uint32_t), &dstip, sizeof(uint32_t));
memcpy(p+sizeof(uint32_t)*2, &srcport, sizeof(uint16_t));
memcpy(p+sizeof(uint16_t)*5, &dstport, sizeof(uint16_t));
memcpy(p+sizeof(uint32_t)*3, &protocol, sizeof(uint8_t));
memcpy(p+sizeof(uint8_t)*13, &iplen, sizeof(uint16_t));//16->8
p += sizeof(uint8_t)*13+sizeof(uint16_t);
data->cnt++;
test += iplen;
}
}
std::cout << "[Message] Read " << data->cnt << " items" << std::endl;
std::cout << "[Message] Test = " << test << std::endl;
pcap_close(pfile);
// free(p);
}
Adaptor::~Adaptor() {
free(data->databuffer);
free(data);
}
int Adaptor::GetNext(tuple_t* t) {
if (data->cur >= data->cnt) {
return -1;
}
//src_ip和dst_ip为32bits,src_port,dst_port,protocol为16bits size为总字节数
t->key.src_ip = *((uint32_t*)data->ptr);
t->key.dst_ip = *((uint32_t*)(data->ptr+4));
t->key.src_port = *((uint16_t*)(data->ptr+8));
t->key.dst_port = *((uint16_t*)(data->ptr+10));
t->key.protocol = *((uint8_t*)(data->ptr+12));
t->size = *((uint16_t*)(data->ptr+13));
data->cur++;
data->ptr += 15;
return 1;
}
void Adaptor::Reset() {
data->cur = 0;
data->ptr = data->databuffer;
}
uint32_t Adaptor::GetDataSize() {
return data->cnt;
}
//只处理IPv6
//https://blog.csdn.net/wh357589873/article/details/51700482