-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtcp_sniffer.cpp
172 lines (124 loc) · 4.57 KB
/
tcp_sniffer.cpp
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
162
163
164
165
166
167
168
169
170
171
172
#include <iostream>
#include <unistd.h>
#include <net/ethernet.h>
#include <netinet/in.h>
#include <chrono>
#include "tcp_sniffer.h"
#include "logger.h"
namespace tcp_sniffer {
pcap_t *pcap_handler;
void list_interfaces()
{
pcap_if_t *all_devs;
pcap_if_t *current_dev;
char error_buff[PCAP_ERRBUF_SIZE];
int ret;
ret = pcap_findalldevs(&all_devs, error_buff);
if (ret) {
std::cout << "pcap_findalldevs failes: " << error_buff << std::endl;
return;
}
current_dev = all_devs;
while (current_dev) {
printf("%-37s %s\n", current_dev->name, (current_dev->description
? current_dev->description : "(no description)"));
current_dev = current_dev->next;
}
if (all_devs)
pcap_freealldevs(all_devs);
}
void packet_handler(uint8_t *args, const struct pcap_pkthdr *header,
const uint8_t *packet)
{
struct ether_header *ethernet_header;
const uint8_t *ip_header;
const uint8_t *tcp_header;
const uint8_t *payload;
int ethernet_header_length = ETH_HDR_LEN;
int ip_header_length;
int tcp_header_length;
int payload_length;
// std::cout << "entered handler" << std::endl;
auto start = std::chrono::high_resolution_clock::now();
ethernet_header = (struct ether_header*) packet;
if (ntohs(ethernet_header->ether_type) != ETHERTYPE_IP) {
std::cout << "Not an IP packet" << std::endl << std::endl;
return;
}
// std::cout << "Total packet available: " << header->caplen
// << " bytes" << std::endl;
// std::cout << "Expected packet size: " << header->len << " bytes" <<
// std::endl;
ip_header = packet + ethernet_header_length;
ip_header_length = ((*ip_header) & 0x0F) * 4;
// std::cout << "IP header length (IHL) in bytes: " << ip_header_length
// << std::endl;
uint8_t protocol = *(ip_header + 9);
if (protocol != IPPROTO_TCP) {
std::cout << "Not a TCP packet" << std::endl << std::endl;
return;
}
tcp_header = packet + ethernet_header_length + ip_header_length;
tcp_header_length = ((*(tcp_header + 12)) & 0xF0) >> 4;
tcp_header_length = tcp_header_length * 4;
// std::cout << "TCP header length in bytes: " << tcp_header_length <<
// std::endl;
int total_headers_size = ethernet_header_length
+ ip_header_length+tcp_header_length;
// std::cout << "Size of all headers combined: " << total_headers_size
// << " bytes" << std::endl;
payload_length = header->caplen
- (ethernet_header_length + ip_header_length + tcp_header_length);
// std::cout << "Payload size: " << payload_length << " bytes"
// << std::endl;
payload = packet + total_headers_size;
if (payload_length <= 0 || payload_length > 260)
return;
logger::modbus_packet_handler(payload);
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> diff = end - start;
std::cout << "Modbus TCP time: " << diff.count() << "s" << std::endl;
logger::inc_duration(diff);
}
int init(std::string interface)
{
struct bpf_program filter;
char error_buffer[PCAP_ERRBUF_SIZE];
int snapshot_len = 1028;
int promiscuous = 1;
int timeout = 1000;
int res;
pcap_handler = pcap_open_live(interface.c_str(), snapshot_len,
promiscuous, timeout, error_buffer);
if (!pcap_handler) {
std::cout << "Error while opening device" << std::endl;
return 1;
}
// adding filter to capture only tcp packets
//res = pcap_compile(pcap_handler, &filter, "tcp", 0,
// PCAP_NETMASK_UNKNOWN);
//if(res) {
// printf("pcap_compile failed\n");
// pcap_close(pcap_handler);
// return 1;
//}
//res = pcap_setfilter(pcap_handler, &filter);
//if(res) {
// printf("pcap_setfilter failed\n");
// pcap_close(pcap_handler);
// return 1;
//}
return 0;
}
int run()
{
pcap_loop(pcap_handler, -1, packet_handler, NULL);
}
void close_sniffer()
{
if (pcap_handler) {
pcap_breakloop(pcap_handler);
pcap_close(pcap_handler);
}
}
}