-
Notifications
You must be signed in to change notification settings - Fork 63
/
utils.h
193 lines (154 loc) · 5.58 KB
/
utils.h
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
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
#ifndef UTILS_H
#define UTILS_H
#include "types.h"
#include "config.h"
#define IP4VERSION 4
#define IP6VERSION 6
/**
* Splits the packet to two IP fragments on position payload_offset.
* payload_offset indicates the position relatively to start of IP payload
* (start of transport header)
*/
int ip4_frag(const uint8_t *pkt, uint32_t pktlen,
uint32_t payload_offset,
uint8_t *frag1, uint32_t *f1len,
uint8_t *frag2, uint32_t *f2len);
/**
* Splits the packet to two TCP segments on position payload_offset
* payload_offset indicates the position relatively to start of TCP payload.
*/
// int tcp4_frag(const uint8_t *pkt, uint32_t pktlen,
// uint32_t payload_offset,
// uint8_t *seg1, uint32_t *s1len,
// uint8_t *seg2, uint32_t *s2len);
int tcp_frag(const uint8_t *pkt, uint32_t pktlen,
uint32_t payload_offset,
uint8_t *seg1, uint32_t *s1len,
uint8_t *seg2, uint32_t *s2len);
/**
* Splits the raw packet payload to ip header and ip payload.
*/
int ip4_payload_split(uint8_t *pkt, uint32_t buflen,
struct iphdr **iph, uint32_t *iph_len,
uint8_t **payload, uint32_t *plen);
static inline int netproto_version(const uint8_t *pkt, uint32_t buflen) {
if (pkt == NULL || buflen == 0)
return -1;
return (*pkt) >> 4;
}
/**
* Splits the raw packet payload to ip header, tcp header and tcp payload.
*/
int tcp4_payload_split(uint8_t *pkt, uint32_t buflen,
struct iphdr **iph, uint32_t *iph_len,
struct tcphdr **tcph, uint32_t *tcph_len,
uint8_t **payload, uint32_t *plen);
/**
* Splits the raw packet payload to ip header and ip payload.
*/
int ip6_payload_split(uint8_t *pkt, uint32_t buflen,
struct ip6_hdr **iph, uint32_t *iph_len,
uint8_t **payload, uint32_t *plen);
/**
* Splits the raw packet payload to ip header, tcp header and tcp payload.
*/
int tcp6_payload_split(uint8_t *pkt, uint32_t buflen,
struct ip6_hdr **iph, uint32_t *iph_len,
struct tcphdr **tcph, uint32_t *tcph_len,
uint8_t **payload, uint32_t *plen);
int tcp_payload_split(uint8_t *pkt, uint32_t buflen,
void **iph, uint32_t *iph_len,
struct tcphdr **tcph, uint32_t *tcph_len,
uint8_t **payload, uint32_t *plen);
/**
* Splits the raw packet payload to ip header, udp header and udp payload.
*/
int udp4_payload_split(uint8_t *pkt, uint32_t buflen,
struct iphdr **iph, uint32_t *iph_len,
struct udphdr **udph,
uint8_t **payload, uint32_t *plen);
int udp6_payload_split(uint8_t *pkt, uint32_t buflen,
struct ip6_hdr **iph, uint32_t *iph_len,
struct udphdr **udph,
uint8_t **payload, uint32_t *plen);
int udp_payload_split(uint8_t *pkt, uint32_t buflen,
void **iph, uint32_t *iph_len,
struct udphdr **udph,
uint8_t **payload, uint32_t *plen);
void tcp4_set_checksum(struct tcphdr *tcph, struct iphdr *iph);
void ip4_set_checksum(struct iphdr *iph);
void ip6_set_checksum(struct ip6_hdr *iph);
void tcp6_set_checksum(struct tcphdr *tcph, struct ip6_hdr *iph);
int set_ip_checksum(void *iph, uint32_t iphb_len);
int set_tcp_checksum(struct tcphdr *tcph, void *iph, uint32_t iphb_len);
void z_function(const char *str, int *zbuf, size_t len);
/**
* Shifts data left delta bytes. Fills delta buffer with zeroes.
*/
void shift_data(uint8_t *data, uint32_t dlen, uint32_t delta);
struct failing_strategy {
unsigned int strategy;
uint8_t faking_ttl;
uint32_t randseq_offset;
};
struct fake_type {
#define FAKE_PAYLOAD_RANDOM 0
#define FAKE_PAYLOAD_DATA 1
// In default mode all other options will be skipped.
#define FAKE_PAYLOAD_DEFAULT 2
int type;
// Length of the final fake message.
// Pass 0 in RANDOM mode to make it random
uint16_t fake_len;
// Payload of the fake message of fake_len length.
// Will be omitted in RANDOM mode.
const char *fake_data;
unsigned int sequence_len;
// If non-0 the packet send will be delayed for n milliseconds
unsigned int seg2delay;
// faking strategy of the fake packet.
// Does not support bitmask, pass standalone strategy.
// Pass 0 if you don't want any faking procedures.
struct failing_strategy strategy;
};
/**
* Invalidates the raw packet. The function aims to invalid the packet
* in such way as it will be accepted by DPI, but dropped by target server
*
* Does not support bitmask, pass standalone strategy.
*/
int fail_packet(struct failing_strategy strategy, uint8_t *payload, uint32_t *plen, uint32_t avail_buflen);
/**
* Shifts the payload right and pushes zeroes before it. Useful for TCP TLS faking.
*/
int seqovl_packet(uint8_t *payload, uint32_t *plen, uint32_t seq_delta);
static inline struct failing_strategy args_default_failing_strategy(const struct section_config_t *section) {
struct failing_strategy fl_strat = {
.strategy = (unsigned int)section->faking_strategy,
.faking_ttl = section->faking_ttl,
.randseq_offset = (uint32_t)section->fakeseq_offset
};
return fl_strat;
}
static inline struct fake_type args_default_fake_type(const struct section_config_t *section) {
struct fake_type f_type = {
.sequence_len = section->fake_sni_seq_len,
.strategy = args_default_failing_strategy(section),
};
switch (section->fake_sni_type) {
case FAKE_PAYLOAD_RANDOM:
f_type.type = FAKE_PAYLOAD_RANDOM;
break;
case FAKE_PAYLOAD_CUSTOM:
f_type.type = FAKE_PAYLOAD_CUSTOM;
f_type.fake_data = section->fake_custom_pkt;
f_type.fake_len = section->fake_custom_pkt_sz;
break;
default:
f_type.type = FAKE_PAYLOAD_CUSTOM;
f_type.fake_data = section->fake_sni_pkt;
f_type.fake_len = section->fake_sni_pkt_sz;
}
return f_type;
}
#endif /* UTILS_H */