-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathip.h
More file actions
125 lines (105 loc) · 4.08 KB
/
ip.h
File metadata and controls
125 lines (105 loc) · 4.08 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
#ifndef IP_H
#define IP_H
#include "icmp.h"
struct IpPacket {
int32 src=0, dest=0;
int16 id=0;
protocol protocol_type;
// const IcmpPacket* icmpPacket; // we would need this only if we use eval_icmp() or to print the icmp packet from ip builder
} packed;
struct RawIpPacket {
int8 ver_ihl;
int8 dscp_ecn;
int16 length;
int16 id;
int16 flags_offset;
int8 ttl;
int8 protocol;
int16 checksum;
int32 src;
int32 dest;
int8 options[];
} packed;
class IpBuilder {
private:
IpPacket* ipPacket;
int8* rawIpBuffer;
int16 ip_packet_size;
int16 raw_ip_buffer_size;
int8* evalIp(IpPacket* ipPacket = nullptr, const int8* rawIcmpBuffer = nullptr, int16 rawIcmpBufferSize = 0){
if(!ipPacket) return nullptr;
RawIpPacket rawIpPacket;
int16 lengthle = 0;
int8* p;
rawIpPacket.protocol = 0;
switch (ipPacket->protocol_type)
{
case protocol::ICMP:
rawIpPacket.protocol = 1;
break;
default:
return nullptr;
}
rawIpPacket.checksum = 0;
rawIpPacket.dscp_ecn = 0;
rawIpPacket.flags_offset = 0;
rawIpPacket.ttl = 250;
rawIpPacket.ver_ihl = (4 << 4) | int(sizeof(RawIpPacket)/4); // division by 4 because ihl is counted in 32-bit words. the RawIpPacket is 20 bytes. so 20/4=5
rawIpPacket.id = utils::endian16(ipPacket->id);
rawIpPacket.src = ipPacket->src;
rawIpPacket.dest = ipPacket->dest;
lengthle = sizeof(RawIpPacket);
if(rawIcmpBuffer && rawIcmpBufferSize > 0){
lengthle += rawIcmpBufferSize; // rawIcmpBufferSize = sizeof(RawIcmpPacket) + ipPacket->icmpPacket->payload_size;
}
rawIpPacket.length = utils::endian16(lengthle);
if(lengthle & 1) ++lengthle; // this one is used for convenience in checksum calculation
raw_ip_buffer_size = lengthle;
cout<<"Raw IP buffer size: "<<lengthle<<"\n";
p = (int8 *)malloc((int)lengthle);
assert(p);
memset(p, 0, lengthle);
memcpy(p, &rawIpPacket, sizeof(RawIpPacket));
if(rawIcmpBuffer && rawIcmpBufferSize > 0){
memcpy(p + sizeof(RawIpPacket), rawIcmpBuffer, rawIcmpBufferSize);
}
RawIpPacket* rawIpPtr = (RawIpPacket *)p;
rawIpPtr->checksum = utils::checksum(p, lengthle);
return p;
}
public:
IpBuilder(enum protocol protcol_type, const int8* src, const int8* dest, const IcmpBuilder* icmpBuilder, int16 _id, int16* cntptr){
int16 id = _id ? _id : (*cntptr)++;
ip_packet_size = sizeof(IpPacket);
ipPacket = new IpPacket();
assert(ipPacket);
ipPacket->protocol_type = protcol_type;
ipPacket->id = id;
ipPacket->src = inet_addr(reinterpret_cast<const char*>(src));
ipPacket->dest = inet_addr(reinterpret_cast<const char*>(dest));
if(!ipPacket->dest) throw invalid_argument("Destination IP is null");
if(ipPacket->dest == INADDR_NONE) throw runtime_error("Invalid Destination IP");
if(icmpBuilder) {
rawIpBuffer = evalIp(ipPacket, icmpBuilder->get_raw_icmp_buffer(), icmpBuilder->get_raw_icmp_buffer_size());
} else {
rawIpBuffer = evalIp(ipPacket);
}
assert(rawIpBuffer);
}
~IpBuilder() { delete ipPacket; free(rawIpBuffer); }
const IpPacket* get_ip_packet() const { return ipPacket; }
const int32 get_dest_ip() const { return ipPacket->dest; }
const int8* get_raw_ip_buffer() const { return rawIpBuffer; }
int16 get_raw_ip_buffer_size() const { return raw_ip_buffer_size; }
void show_ip() const {
if(!ipPacket) return;
printf("protocol:\t 0x%.02hhx\n", (char)ipPacket->protocol_type);
printf("id:\t 0x%.02hhx\n", ipPacket->id);
cout << "src:\t " << utils::convertIpToString(ipPacket->src) << "\n";
cout << "dest:\t " << utils::convertIpToString(ipPacket->dest) << "\n";
cout<<"\nRaw ip buffer: \n";
utils::printhex(rawIpBuffer, raw_ip_buffer_size);
cout<<"\n";
}
};
#endif