Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


added network server files
[palacios.git] / misc / network_servers / vtl / test / vtl_ack_test.cc
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <sys/types.h>
4 #include <sys/stat.h>
5 #include <sys/poll.h>
6 #include <fcntl.h>
7
8 #include "vtl.h"
9 #include "vtl_harness.h"
10
11 DEBUG_DECLARE();
12
13
14
15 /* Connection List Handling */
16 struct VTL_CON g_vtl_cons[MAX_VTL_CONS];
17 int g_first_vtl;
18 int g_last_vtl;
19 int g_num_vtl_cons;
20
21 int add_vtl_con(RawEthernetPacket * pkt);
22 int find_vtl_con(RawEthernetPacket * pkt);
23
24 /* Packet Handlers */
25 int handle_local_tcp_pkt(RawEthernetPacket * pkt, iface_t * dev);
26 int handle_remote_tcp_pkt(RawEthernetPacket * pkt);
27
28 /* Packet functions */
29 int make_ack_pkt(RawEthernetPacket * pkt, int vcon_i);
30 int init_ack_template(RawEthernetPacket * pkt);
31
32
33 unsigned short ip_id_ctr = 1;
34
35 int main(int argc, char ** argv) {
36   RawEthernetPacket pkt;
37   RawEthernetPacket ack_pkt;
38   int i = 0;
39   iface_t * dev;
40   unsigned long src_addr;
41
42   debug_init("./vtl.log");
43
44   JRLDBG("Starting VTP Daemon\n");
45
46   for (i = 0; i < MAX_VTL_CONS; i++) {
47     g_vtl_cons[i].con_model.type = TCP_MODEL;
48     g_vtl_cons[i].in_use = false;
49     g_vtl_cons[i].next = -1;
50     g_vtl_cons[i].prev = -1;
51   }
52
53   g_last_vtl = -1;
54   g_first_vtl = -1;
55
56   g_num_vtl_cons = 0;
57
58   src_addr = ToIPAddress(argv[2]);
59   dev = if_connect(argv[1]);
60
61   while (if_read_pkt(dev, &pkt) != -1) {
62
63
64
65     if (is_tcp_pkt(&pkt)) {
66       if (GET_IP_SRC(pkt.data) == src_addr) {
67         handle_local_tcp_pkt(&pkt, dev);
68       } else if (GET_IP_DST(pkt.data) == src_addr) {
69         if (GET_IP_ID(pkt.data) == ip_id_ctr -1) {
70           continue;
71         }
72         handle_remote_tcp_pkt(&pkt);
73         printf("Remote tcp packet\n");
74       }
75     }
76   }
77
78
79   fclose(logfile);
80
81
82   return(0);
83 }
84
85
86 int handle_local_tcp_pkt(RawEthernetPacket * pkt, iface_t * dev) {
87   printf("local tcp pkt\n");
88   RawEthernetPacket ack_pkt;
89
90   int index = find_vtl_con(pkt);
91
92   if (index != -1) {
93     // packet in the system
94     sync_model(&(g_vtl_cons[index].con_model), pkt);
95
96
97     // dbg_dump_model(&(g_vtl_cons[index].con_model));
98     if (GET_TCP_DATA_LEN(pkt->data) > 0) {
99       create_empty_pkt(&(g_vtl_cons[index].con_model), &ack_pkt, INBOUND_PKT);
100       dbg_print_pkt_info(&ack_pkt);
101       if_write_pkt(dev, &ack_pkt);
102       
103     }
104   } else {
105     if (is_syn_pkt(pkt)) {
106       int index = -1;
107
108       index = add_vtl_con(pkt);
109       printf("Connection added at %d\n", index);
110
111       
112     }
113   }
114
115   return 0;
116
117 }
118
119 int handle_remote_tcp_pkt(RawEthernetPacket * pkt) {
120   int index;
121
122   index = find_vtl_con(pkt);
123
124   if (index != -1) {
125     sync_model(&(g_vtl_cons[index].con_model), pkt);
126     g_vtl_cons[index].con_model.model.ip_model.dst.ip_id = ip_id_ctr++;
127   }
128
129   return 0;
130 }
131
132
133
134 int find_vtl_con(RawEthernetPacket * pkt) {
135   int index = -1;
136   int i = 0;
137
138
139   FOREACH_VTL_CON(i,g_vtl_cons) {
140     if (is_model_pkt(&(g_vtl_cons[i].con_model), pkt)) {
141       index = i;
142       break;
143     }
144   }
145   return index;
146 }
147
148
149
150 int add_vtl_con(RawEthernetPacket * pkt) {
151   int i;
152   
153   for (i = 0; i < MAX_VTL_CONS; i++) {
154     if (!(g_vtl_cons[i].in_use)) {
155       JRLDBG("Adding connection in slot %d\n", i);
156
157       initialize_model(&(g_vtl_cons[i].con_model), pkt);
158       g_vtl_cons[i].in_use = true;
159       
160       dbg_dump_model(&(g_vtl_cons[i].con_model));
161
162       if (g_first_vtl == -1)
163         g_first_vtl = i;
164
165       g_vtl_cons[i].prev = g_last_vtl;
166       g_vtl_cons[i].next = -1;
167
168       if (g_last_vtl != -1) {
169         g_vtl_cons[g_last_vtl].next = i;
170       }
171       
172       g_last_vtl = i;
173
174       g_num_vtl_cons++;
175       return 0;
176     }
177   }
178   return -1;
179 }
180
181
182
183 /*
184
185
186 int handle_tcp_pkt(RawEthernetPacket *pkt) {
187
188
189     unsigned short ip_pkt_len = 0;
190     // unsigned char ip_hdr_len = (*(pkt->data + ETH_HDR_LEN) & 0x0f) << 2;
191     unsigned char ip_hdr_len = IP_HDR_LEN(pkt->data);
192     unsigned short * ip_pkt_len_ptr = (unsigned short *)(pkt->data + ETH_HDR_LEN + 2); 
193     ip_pkt_len = ntohs(*ip_pkt_len_ptr);
194     
195     JRLDBG("IP Header Length = %d(%x)\n", ip_hdr_len, *(pkt->data + ETH_HDR_LEN));
196     JRLDBG("IP Packet Length = %hu\n", ip_pkt_len);
197     
198     if (is_syn_pkt(pkt) == 0) {
199       // we don't mess with connection establishment
200       int vcon_i;
201       unsigned long  payload_len = 0;
202       unsigned short tcp_hdr_len = 0;
203       struct in_addr tmp;
204       
205       
206       tcp_hdr_len = (*(pkt->data + ETH_HDR_LEN + ip_hdr_len + 12) & 0xf0) >> 2;
207       payload_len = ip_pkt_len  - (ip_hdr_len + tcp_hdr_len);
208       
209       if ((payload_len == 0) && (is_ack_pkt(pkt) == 1)) {
210         // we just kill empty acks. 
211         //return 0;
212       }
213       
214       vcon_i = find_remote_vtp_con(pkt);
215       
216       // Create ACK and send it.
217       make_ack_pkt(pkt, vcon_i);
218       
219       g_vtl_cons[vcon_i].ack_template.VtpSerialize(vtp_in_fd, &tmp);
220       
221     } else {
222       if(is_ack_pkt(pkt) == 1) {
223         int vcon_i = find_remote_vtp_con(pkt);
224         struct in_addr tmp;
225         make_ack_pkt(pkt, vcon_i);
226         
227         g_vtl_cons[vcon_i].ack_template.VtpSerialize(vtp_in_fd, &tmp);
228       }
229 #ifdef DEBUG 
230       unsigned long * seq_num_ptr ;
231       unsigned long seq_num = 0;
232       unsigned long  payload_len = 0;
233       unsigned short tcp_hdr_len = 0;
234       unsigned long ack = 0;
235       
236       JRLDBG("Packet is a Syn Packet\n");
237       
238       seq_num_ptr = (unsigned long *)(pkt->data + ETH_HDR_LEN + ip_hdr_len + 4);
239       seq_num = ntohl(*seq_num_ptr);
240       JRLDBG("Sequence Number = %lu\n", seq_num);
241       
242       tcp_hdr_len = (*(pkt->data + ETH_HDR_LEN + ip_hdr_len + 12) & 0xf0) >> 2;
243       payload_len = ip_pkt_len  - (ip_hdr_len + tcp_hdr_len);
244       
245       JRLDBG("TCP Header Length = %hu\n", tcp_hdr_len);
246       JRLDBG("Payload Length = %lu\n", payload_len);
247       
248       
249       
250       ack = (payload_len > 0) ? (seq_num + payload_len) : (seq_num + 1);
251       JRLDBG("Ack Num = %lu\n", ack);
252 #endif
253     }
254
255   return 0;
256 }
257
258 int handle_rem_tcp_pkt(RawEthernetPacket * pkt) {
259   unsigned long * seq_num_ptr;
260   unsigned long seq_num;
261   unsigned char ip_hdr_len = IP_HDR_LEN(pkt->data);
262   
263   seq_num_ptr = (unsigned long *)(pkt->data + ETH_HDR_LEN + ip_hdr_len + 4);
264   seq_num = ntohl(*seq_num_ptr);
265   JRLDBG("Received Packet, SeqNum = %lu\n", seq_num);
266
267   if (is_syn_pkt(pkt) == 1) {
268     // syn packet
269     seq_num++;
270     add_vtp_con(pkt, seq_num);
271     JRLDBG("Received Syn Packet, SeqNum = %lu\n", seq_num);
272   } else {
273     unsigned short ip_pkt_len = 0;
274     unsigned short * ip_pkt_len_ptr = (unsigned short *)(pkt->data + ETH_HDR_LEN + 2); 
275     unsigned long  payload_len = 0;
276     unsigned short tcp_hdr_len = 0;
277     int i_vcon = find_vtp_con(pkt);
278     
279     ip_pkt_len = ntohs(*ip_pkt_len_ptr);
280
281     tcp_hdr_len = (*(pkt->data + ETH_HDR_LEN + ip_hdr_len + 12) & 0xf0) >> 2;
282
283     if (tcp_hdr_len > 20) {
284       unsigned long ts = get_tcp_timestamp(pkt->data + ETH_HDR_LEN + ip_hdr_len + 20, tcp_hdr_len - 20);
285       JRLDBG("TCP Timestamp = %lu(%lu)\n", ts, (unsigned long)ntohl(ts));
286       g_vtl_cons[i_vcon].tcp_timestamp = ts;
287     }
288
289     payload_len = ip_pkt_len  - (ip_hdr_len + tcp_hdr_len);
290     seq_num += payload_len;
291     JRLDBG("Received Data Packet, SeqNum = %lu\n", seq_num);
292     g_vtl_cons[i_vcon].rem_seq_num = seq_num;
293     JRLDBG("Remote Sequence Number (con: %d) = %lu\n", i_vcon, seq_num);
294
295 #if 0
296     {
297       int offset = 0;
298       unsigned short tcp_cksum = 0;
299       // Zero Ack Field
300       *(unsigned long *)(pkt->data + ETH_HDR_LEN + ip_hdr_len + 8) = 0;
301       
302       // Zero Ack Flag
303       offset = ETH_HDR_LEN + ip_hdr_len + 13;
304       *(pkt->data + offset) &= 0xef;
305       
306       // Zero TCP chksum
307       *(unsigned short *)(pkt->data + ETH_HDR_LEN + ip_hdr_len + 16) = 0;
308       
309       // Get TCP chksum
310       tcp_cksum = get_tcp_checksum(pkt, ip_pkt_len - ip_hdr_len);
311       
312       // Set TCP chksum
313       *(unsigned short *)(pkt->data + ETH_HDR_LEN + ip_hdr_len + 16) = tcp_cksum;
314     }
315 #endif 
316
317
318   }
319   return 0;
320 }
321
322
323
324 int make_ack_pkt(RawEthernetPacket * pkt, int vcon_i) {
325   unsigned long * seq_num_ptr ;
326   unsigned long seq_num = 0;
327   unsigned long rem_seq_num = 0;
328   unsigned long  payload_len = 0;
329   unsigned short tcp_hdr_len = 0;
330   unsigned long ack = 0;
331   unsigned long local_ts = 0;
332   unsigned short tcp_cksum = 0;
333   unsigned char ip_hdr_len = IP_HDR_LEN(pkt->data);
334   unsigned short ip_pkt_len = *(unsigned short *)(pkt->data + ETH_HDR_LEN + 2);
335   RawEthernetPacket * ack_pkt = &(g_vtl_cons[vcon_i].ack_template);
336   unsigned short ack_ip_pkt_len = *(unsigned short *)(ack_pkt->data + ETH_HDR_LEN + 2);
337   unsigned char ack_ip_hdr_len = IP_HDR_LEN(ack_pkt->data);
338
339   ip_pkt_len = ntohs(ip_pkt_len);
340   ack_ip_pkt_len = ntohs(ack_ip_pkt_len);
341
342   seq_num_ptr = (unsigned long *)(pkt->data + ETH_HDR_LEN + ip_hdr_len + 4);
343   seq_num = ntohl(*seq_num_ptr);
344   JRLDBG("Sequence Number = %lu\n", seq_num);
345
346   tcp_hdr_len = (*(pkt->data + ETH_HDR_LEN + ip_hdr_len + 12) & 0xf0) >> 2;
347
348   if (is_syn_pkt(pkt) == 1) {
349     ack = seq_num + 1;
350   } else {    
351     payload_len = ip_pkt_len  - (ip_hdr_len + tcp_hdr_len);
352     
353     JRLDBG("TCP Header Length = %hu\n", tcp_hdr_len);
354     JRLDBG("Payload Length = %lu\n", payload_len);
355     
356     ack = seq_num + payload_len;
357     JRLDBG("Ack Num = %lu\n", ack);
358   }
359
360   // Set IP id 
361   g_vtl_cons[vcon_i].ip_id--;
362   *(unsigned short *)(ack_pkt->data + ETH_HDR_LEN + 4) = htons(g_vtl_cons[vcon_i].ip_id);
363
364   // Recompute IP checksum
365   *(unsigned short *)(ack_pkt->data + ETH_HDR_LEN + 10) = 0;
366   *(unsigned short *)(ack_pkt->data + ETH_HDR_LEN + 10) = get_ip_checksum(ack_pkt);
367
368   //return 0;
369   // Set Sequence Number
370   rem_seq_num = htonl(g_vtl_cons[vcon_i].rem_seq_num);
371   *(unsigned long *)(ack_pkt->data + ETH_HDR_LEN + ack_ip_hdr_len + 4) = rem_seq_num;
372  
373   // Set ACK Number
374   ack = htonl(ack);
375   *(unsigned long *)(ack_pkt->data + ETH_HDR_LEN + ack_ip_hdr_len + 8) = ack;
376
377   // Set TCP Timestamp option
378   local_ts = get_tcp_timestamp(pkt->data + ETH_HDR_LEN + ack_ip_hdr_len + 20, tcp_hdr_len - 20);
379
380  //  We use this for debugging:
381   //  If the TCPDump trace shows timestamps with the value of '5' then they are our packets
382   // 
383   
384   *(unsigned long *)(ack_pkt->data + ETH_HDR_LEN + ack_ip_hdr_len + 24) = g_vtl_cons[vcon_i].tcp_timestamp;
385 //  *(unsigned long *)(ack_pkt->data + ETH_HDR_LEN + ip_hdr_len + 24) = htonl(5);
386
387
388   *(unsigned long *)(ack_pkt->data + ETH_HDR_LEN + ack_ip_hdr_len + 28) = local_ts;
389
390   // Zero TCP chksum
391   *(unsigned short *)(ack_pkt->data + ETH_HDR_LEN + ack_ip_hdr_len + 16) = 0;
392
393   // Get TCP chksum
394   tcp_cksum = get_tcp_checksum(ack_pkt, ack_ip_pkt_len - ack_ip_hdr_len);
395
396   // Set TCP chksum
397   *(unsigned short *)(ack_pkt->data + ETH_HDR_LEN + ack_ip_hdr_len + 16) = tcp_cksum;
398
399   return 0;
400 }
401
402
403
404
405
406 // Connection List Handling //
407
408
409
410 int init_ack_template(RawEthernetPacket * pkt) {
411   // We assume here that the ethernet and ip headers are ok, except for ip pkt length
412   // TCP is mostly right because its pulled off of a syn packet
413   // we need to zero the data, and reset the syn flag.
414
415   unsigned short IP_PACKET_LEN = 52;
416   unsigned short TCP_HEADER_LEN = 32;
417   unsigned char ip_hdr_len = IP_HDR_LEN(pkt->data);
418   unsigned short ip_pkt_len = 0;
419   unsigned short tcp_hdr_len = 0;
420   unsigned short payload_len = 0;
421   unsigned short * ip_pkt_len_ptr = (unsigned short *)(pkt->data + ETH_HDR_LEN + 2); 
422   unsigned int offset = 0;
423   unsigned short ip_chksum = 0;
424
425   JRLDBG("--> Initializing ACK Template <--\n");
426
427   ip_pkt_len = ntohs(*ip_pkt_len_ptr);
428   JRLDBG("ip_pkt_len = %hu\n", ip_pkt_len);
429   
430   tcp_hdr_len = (*(pkt->data + ETH_HDR_LEN + ip_hdr_len + 12) & 0xf0) >> 2;
431   payload_len = ip_pkt_len  - (ip_hdr_len + tcp_hdr_len);
432   JRLDBG("tcp_hdr_len = %hu\n", tcp_hdr_len);
433   JRLDBG("payload_len = %hu\n", payload_len);
434
435   // set only the ack flags
436   offset = ETH_HDR_LEN + ip_hdr_len + 13;
437   *(pkt->data + offset)  |= 0x10;
438   *(pkt->data + offset)  &= 0xd0;
439
440   // set up tcp options
441   offset = ETH_HDR_LEN + ip_hdr_len + 20;
442   *(pkt->data + offset) = 0x01;
443   offset++;
444   *(pkt->data + offset) = 0x01;
445   offset++;
446   *(pkt->data + offset) = 0x08;
447   offset++;
448   *(pkt->data + offset) = 0x0a;
449
450   // Set Header Lengths
451   // IP HEADER = 20 (same)
452   // IP PACKET LEN = 52
453   // TCP Header len = 32
454   
455   ip_pkt_len = htons(IP_PACKET_LEN);
456   memcpy(pkt->data + ETH_HDR_LEN + 2, &ip_pkt_len, 2);
457   tcp_hdr_len = (TCP_HEADER_LEN << 2);
458   *(pkt->data + ETH_HDR_LEN + ip_hdr_len + 12) &= 0x0f;
459   *(pkt->data + ETH_HDR_LEN + ip_hdr_len + 12) |= tcp_hdr_len;
460
461   JRLDBG("Setting TEMPLATE TCPLEN = %2x\n", *(pkt->data + ETH_HDR_LEN +ip_hdr_len + 12));
462
463   // Set IP Header chksum
464   *(unsigned short *)(pkt->data + ETH_HDR_LEN + 10) = 0;
465   ip_chksum = get_ip_checksum(pkt);
466   *(unsigned short *)(pkt->data + ETH_HDR_LEN + 10) = ip_chksum;
467
468
469   // Set RawEthernetPacket size
470   pkt->set_size(IP_PACKET_LEN + ETH_HDR_LEN);
471   pkt->set_type("et");
472
473   JRLDBG("--> ACK Template Initialized <--\n");
474
475
476   return 0;
477 }
478
479 */