-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathprobe.c
301 lines (263 loc) · 6.35 KB
/
probe.c
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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
/*
* G O R D O N
* Detecting TCP variants on the internet
*---------------------------------------
*
* Probe.c : Base program. Registers nfqueue callback
* Arguments : <target> URL of the target host
* <qd1> First queuing delay to be emulated in ns
* <qd2> Second queuing delay to be emulated in ns
* <trans-time> No. of packets after which the delay must be changed
*
* Example : sudo iptables -I INPUT -p tcp -s 137.132.83.98 -m state --state ESTABLISHED -j NFQUEUE --queue-num 0
* ./prober www.facebook.com 5000 8000 1000
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <linux/types.h>
#include <linux/netfilter.h> /* for NF_ACCEPT */
#include <libnetfilter_queue/libnetfilter_queue.h>
#include <linux/tcp.h>
#include <linux/ip.h>
#include <sys/time.h>
#include <string.h>
#include <pthread.h>
#include <math.h>
#define OWD 125
#define DROPPOINT 40
int drop = 1;
int acceptWindow = 0;
int dropWindow = 0;
uint dropSeq = 0;
int cap = 500;
int done = 0;
int emuDrop=10000;
uint32_t randomSeq=0;
int nextVal=0;
char buffSize[6];
int buff[250];
int indx = 0;
int ss=1;
int maxseq=0;
//struct timespec start, end;
char* itoa(int n, char *number)
{
int digit, i=0, j=0, temp = n;
i=0;
while(temp!=0){
digit = temp%10;
number[i] = (char) (digit+48);
temp /= 10;
i++;
}
while(j<i/2){
temp=number[j];
number[j]=number[i-j-1];
number[i-j-1]=temp;
j++;
}
return number;
}
void split( char string[], int start, int end){
char str[10];
int i=0;
for(i=0; i<(end-start); i++){
str[i]=string[start+i];
}
strcpy(buffSize, str);
return;
}
int getBuff(){
char filename[] = "/proc/net/netfilter/nfnetlink_queue";
FILE *file = fopen(filename, "r");
fseek(file, 0, SEEK_SET);
if (file != NULL) {
char stats [60];
fgets(stats,sizeof stats,file);
//printf("\n%s", stats);
split(stats, 12, 18);
}
return atoi(buffSize);
}
void destroySession( struct nfq_handle *h, struct nfq_q_handle *qh ){
system("sudo killall wget");
nfq_destroy_queue(qh);
#ifdef INSANE
/* normally, applications SHOULD NOT issue this command, since
* it detaches other programs/sockets from AF_INET, too ! */
//printf("unbinding from AF_INET\n");
nfq_unbind_pf(h, AF_INET);
#endif
nfq_close(h);
}
static int cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg,
struct nfq_data *nfa, void *data)
{
unsigned char *pkt;
struct nfqnl_msg_packet_hdr *header;
uint32_t id = 0;
uint32_t tseq = 0;
header = nfq_get_msg_packet_hdr(nfa);
id = ntohl(header->packet_id);
unsigned int ret = nfq_get_payload(nfa, &pkt);
unsigned int by = 0;
for (int i = 24; i < 28; i++) {
by = (unsigned int) pkt[i];
tseq += by << 8*(24-i);
}
if(tseq == randomSeq){
return nfq_set_verdict(qh, id, NF_ACCEPT, 0, NULL);
}
else if(acceptWindow < cap){
if(acceptWindow == emuDrop){
ss=0;
acceptWindow++;
randomSeq = tseq;
return nfq_set_verdict(qh, id, NF_DROP, 0, NULL);
}
else{
acceptWindow++;
return nfq_set_verdict(qh, id, NF_ACCEPT, 0, NULL);
}
}
else if(tseq == dropSeq){
nextVal = acceptWindow + dropWindow;
//clock_gettime(CLOCK_MONOTONIC_RAW, &end);
//__uint64_t delta_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000;
//printf("took %lu\n", delta_us);
//if(delta_us>OWD*5000)
// done=-1;
//else
done=1;
return nfq_set_verdict(qh, id, NF_ACCEPT, 0, NULL);
}
else{
if(drop == 1){
drop=0;
//clock_gettime(CLOCK_MONOTONIC_RAW, &start);
dropSeq=tseq;
}
dropWindow++;
//buff[dropWindow]=getBuff();
//printf("\n%d %d ", counter, getBuff());
return nfq_set_verdict(qh, id, NF_DROP, 0, NULL);
}
}
int getWinSize( char line[] ){
char num[4];
int i=0, j=0;
for(i=0;i<6;i++){
if(line[i]==' ')
break;
}
for(j=0;j<4;j++){
num[j]=line[i+j+1];
}
return atoi(num);
}
int main(int argc, char **argv)
{
struct nfq_handle *h;
struct nfq_q_handle *qh;
int fd;
int rv;
char buf[4096] __attribute__ ((aligned));
int lastWindow;
int inputting = 0;
char outfile[30] = "../Data/windows.csv";
FILE *ofile = fopen(outfile, "rw");
int lastAccept=0;
char line [128];
while (fgets(line, sizeof line, ofile) != NULL)
{
indx++;
lastWindow = atoi(line);
if(inputting==0){
if(getWinSize(line)>DROPPOINT){
emuDrop = lastAccept;
inputting=1;
}
}
lastAccept=lastWindow;
}
cap=atoi(line);
if(cap==0){
cap=lastWindow;
}
h = nfq_open();
if (!h) {
//fprintf(stderr, "error during nfq_open()\n");
exit(1);
}
//printf("unbinding existing nf_queue handler for AF_INET (if any)\n");
if (nfq_unbind_pf(h, AF_INET) < 0) {
fprintf(stderr, "error during nfq_unbind_pf()\n");
exit(1);
}
//printf("binding nfnetlink_queue as nf_queue handler for AF_INET\n");
if (nfq_bind_pf(h, AF_INET) < 0) {
fprintf(stderr, "error during nfq_bind_pf()\n");
exit(1);
}
//printf("binding this socket to queue '0'\n");
qh = nfq_create_queue(h, 0, &cb, NULL);
if (!qh) {
fprintf(stderr, "error during nfq_create_queue()\n");
exit(1);
}
//printf("setting copy_packet mode\n");
if (nfq_set_mode(qh, NFQNL_COPY_PACKET, 0xffff) < 0) {
fprintf(stderr, "can't set packet_copy mode\n");
exit(1);
}
fd = nfq_fd(h);
int counter=0;
/*
argv[1] - target URL
argv[2] - first delay
argv[3] - second delay
argv[4] - switch point
*/
int delay=atoi(argv[2]);
int nextDelay=atoi(argv[3]);
int switchPoint=atoi(argv[4]);
char get[] ="wget -U Mozilla ";
//'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:62.0) Gecko/20100101 Firefox/62.0' ";
strcat(get, argv[1]);
strcat(get,"&"); //echo $!");
system(get);
while ((rv = recv(fd, buf, sizeof(buf), 0)) && rv >= 0 && done==0){
usleep(delay);
nfq_handle_packet(h, buf, rv);
if(counter>switchPoint) delay=nextDelay;
counter++;
}
destroySession(h, qh);
if(done==-1)
exit(0);
fseek(ofile, 0, SEEK_END);
//unsuccessful run
if(done==6){
for(int i=0; i<dropWindow; i++){
printf("\n%f %d", (indx*1.0)+(i*1.0/dropWindow), buff[i]);
}
}
char number[5];
char window[5];
char in[5];
char cmd[]="echo ";
//write data to windows.csv
itoa(nextVal, number);
strcat(cmd, number);
strcat(cmd," ");
itoa(nextVal-acceptWindow, window);
strcat(cmd, window);
strcat(cmd," ");
itoa(indx, in);
strcat(cmd, in);
strcat(cmd, " >> ../Data/windows.csv");
system(cmd);
return 0;
}