-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathicmp.h
More file actions
99 lines (77 loc) · 2.84 KB
/
icmp.h
File metadata and controls
99 lines (77 loc) · 2.84 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
#ifndef ICMP_H
#define ICMP_H
#include "utils.h"
struct RawIcmpPacket {
int8 type;
int8 code;
int16 checksum;
int8 data[];
} packed; // tells the compiler to DO NOT ADD PADDING BYTES inside the structure
struct IcmpPacket {
type packet_type;
int16 payload_size;
const int8* payload;
} packed;
class IcmpBuilder {
private:
IcmpPacket* icmpPacket;
int8* rawIcmpBuffer;
int16 raw_icmp_buffer_size;
int8* eval_icmp(IcmpPacket* icmp){
if(!icmp) return nullptr;
RawIcmpPacket raw_icmp;
switch (icmp->packet_type)
{
case type::ECHO :
raw_icmp.type = 8;
raw_icmp.code = 0;
break;
case type::ECHOREPLY :
raw_icmp.type = 0;
raw_icmp.code = 0;
break;
default:
return nullptr;
}
int16 full_size = sizeof(RawIcmpPacket) + icmp->payload_size;
raw_icmp_buffer_size = full_size;
int8* buffer = (int8 *)malloc((int)full_size); // malloc gives contiguous memory guaranteed without constructors
cout<<"Raw ICMP Buffer size : "<< raw_icmp_buffer_size << "\n";
assert(buffer);
memset(buffer, 0, full_size);
memcpy(buffer, &raw_icmp, sizeof(RawIcmpPacket));
memcpy(buffer + sizeof(RawIcmpPacket), icmp->payload, icmp->payload_size);
int16 check = utils::checksum(buffer, full_size);
RawIcmpPacket* raw_ptr = (RawIcmpPacket *)buffer;
raw_ptr->checksum = check;
return buffer;
}
public:
IcmpBuilder(type packet_type, int16 size, const int8* payload){
icmpPacket = new IcmpPacket();
assert(icmpPacket);
icmpPacket->packet_type = packet_type;
icmpPacket->payload_size = size;
icmpPacket->payload = payload;
rawIcmpBuffer = eval_icmp(icmpPacket);
assert(rawIcmpBuffer);
}
~IcmpBuilder() { delete icmpPacket; free(rawIcmpBuffer); }
type get_packet_type() { return icmpPacket->packet_type; }
int16 get_payload_size() const { return icmpPacket->payload_size; }
int16 get_raw_icmp_buffer_size() const { return raw_icmp_buffer_size; }
const int8* get_raw_icmp_buffer() const { return rawIcmpBuffer; }
const IcmpPacket* get_icmp_packet() const { return icmpPacket; }
void show_icmp() const {
if(!icmpPacket) return;
cout<<"Packet Type:\t "
<<(icmpPacket->packet_type == type::ECHO? "echo" : (icmpPacket->packet_type == type::ECHOREPLY? "echo-reply" : "unknown"))
<<"\nPayload Size:\t "<<icmpPacket->payload_size
<<"\nPayload:\n";
if(icmpPacket->payload) utils::printhex(icmpPacket->payload, icmpPacket->payload_size, 0);
cout<<"\nRaw icmp buffer: \n";
utils::printhex(rawIcmpBuffer, raw_icmp_buffer_size);
cout<<"\n";
}
};
#endif