]> sjero.net Git - dccp2tcp/blob - dccp2tcp.c
Option to only show Ack Vectors/SACKS with loss
[dccp2tcp] / dccp2tcp.c
1 /******************************************************************************
2 Author: Samuel Jero
3
4 Date: 5/2011
5
6 Description: Program to convert a DCCP flow to a TCP flow for DCCP analysis via
7                 tcptrace.
8
9 Notes:
10         1)Supports only a single DCCP contection per capture
11         2)Source Port!=Destination Port
12         3)DCCP MUST use 48 bit sequence numbers
13         4)Checksums are not computed (they are zeroed)
14         5)Only implements those packet types normally used in a session
15         6)DCCP Ack packets show up as TCP packets containing one byte
16         7)Very little error checking of packet headers
17 ******************************************************************************/
18 #include "dccp2tcp.h"
19
20
21 int debug=0;    /*set to 1 to turn on debugging information*/
22 int yellow=0;   /*tcptrace yellow line as currently acked packet*/
23 int green=0;    /*tcptrace green line as currently acked packet*/
24 int sack=0;             /*add TCP SACKS*/
25
26 pcap_t*                 in;                     /*libpcap input file discriptor*/
27 pcap_dumper_t   *out;   /*libpcap output file discriptor*/
28 struct seq_num  *s1;    /*sequence number structure for side one of connection*/
29 struct seq_num  *s2;    /*sequence number structure for side two of connection*/
30
31
32
33 void PcapSavePacket(struct pcap_pkthdr *h, u_char *data);
34 void process_packets();
35 void handle_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes);
36 int convert_packet(struct pcap_pkthdr *h, u_char **nptr, int *nlength, const u_char **optr, int *length);
37 unsigned int interp_ack_vect(u_char* hdr);
38 u_int32_t initialize_seq(struct seq_num **seq, __be16 source, __be32 initial);
39 u_int32_t add_new_seq(struct seq_num *seq, __be32 num, int size, enum dccp_pkt_type type);
40 u_int32_t convert_ack(struct seq_num *seq, __be32 num);
41 int acked_packet_size(struct seq_num *seq, __be32 num);
42 void ack_vect2sack(struct seq_num *seq, struct tcphdr *tcph, u_char* tcpopts, u_char* dccphdr, __be32 dccpack);
43
44
45 /*Parse commandline options and open files*/
46 int main(int argc, char *argv[])
47 {
48         char ebuf[200];
49         char *erbuffer=ebuf;
50         char *dfile=NULL;
51         char *tfile=NULL;
52
53         /*parse commandline options*/
54         if(argc<3 || argc > 9){
55                 dbgprintf(0, "Usage: dccp2tcp dccp_file tcp_file [-d] [-y] [-g] [-s]\n");
56                 exit(1);
57         }
58
59         /*loop through commandline options*/
60         for(int i=1; i < argc; i++){
61                 if(argv[i][0]!='-'){
62                         if(dfile==NULL){ /*assign first non-dash argument to the dccp file*/
63                                 dfile=argv[i];
64                         }else{
65                                 if(tfile==NULL){
66                                         tfile=argv[i]; /*assign second non-dash argument to the dccp file*/
67                                 }else{
68                                         dbgprintf(0,"Usage: dccp2tcp dccp_file tcp_file [-d] [-y] [-g] [-s]\n");
69                                         exit(1);
70                                 }
71                         }
72                 }else{
73                         if(argv[i][1]=='d' && strlen(argv[i])==2){ /*debug option*/
74                                 debug++;
75                         }
76                         if(argv[i][1]=='y' && strlen(argv[i])==2){ /*yellow option*/
77                                 yellow=1;
78                         }
79                         if(argv[i][1]=='g' && strlen(argv[i])==2){ /*green option*/
80                                 green=1;
81                         }
82                         if(argv[i][1]=='s' && strlen(argv[i])==2){ /*sack option*/
83                                 sack++;
84                         }
85                 }
86         }
87         
88         if(dfile==NULL || tfile==NULL){
89                 dbgprintf(0,"Usage: dccp2tcp dccp_file tcp_file [-d] [-y] [-g] [-s]\n");
90                 exit(1);
91         }
92
93         /*all options validated*/
94
95         if(debug){
96                 dbgprintf(1,"Debug On\n");
97                 if(green){
98                         dbgprintf(1,"Tcptrace green line at highest acknowledgment\n");
99                 }else{
100                         dbgprintf(1,"Tcptrace green line at highest acknowledged acknowledgment\n");
101                 }
102                 if(yellow){
103                         dbgprintf(1,"Tcptrace yellow line at highest acknowledgment\n");
104                 }else{
105                         dbgprintf(1,"Tcptrace yellow line window value (a made up number)\n");
106                 }
107                 if(sack){
108                         dbgprintf(1,"Adding TCP SACKS\n");
109                 }
110                 dbgprintf(1,"Input file: %s\n", dfile);
111                 dbgprintf(1,"Output file: %s\n", tfile);
112         }
113
114         /*attempt to open input file*/
115         in=pcap_open_offline(dfile, erbuffer);
116         if(in==NULL){
117                 dbgprintf(0,"Error opening input file\n");
118                 exit(1);
119         }
120
121         /*attempt to open output file*/
122         out=pcap_dump_open(in,tfile);
123         if(out==NULL){
124                 dbgprintf(0,"Error opening output file\n");
125                 exit(1);
126         }
127
128         /*process packets*/
129         u_char *user=(u_char*)out;
130         pcap_loop(in, -1, handle_packet, user); 
131         
132         /*close files*/
133         pcap_close(in);
134         pcap_dump_close(out);
135 return 0;
136 }
137
138
139 /*call back function for pcap_loop--do basic packet handling*/
140 void handle_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes)
141 {
142         u_char                          *ndata;
143         u_char                          *nptr;
144         int                                     length;
145         int                                     nlength;
146         struct pcap_pkthdr      nh;
147         int                                     link_type;
148
149         /*Determine the link type for this packet*/
150         link_type=pcap_datalink(in);
151
152         /*create new libpcap header*/
153         memcpy(&nh, h, sizeof(struct pcap_pkthdr));
154         length=h->caplen;
155         nlength=MAX_PACKET;
156
157         /*create buffer for new packet*/
158         nptr=ndata=malloc(MAX_PACKET);
159         if(ndata==NULL){
160                 dbgprintf(0,"Error: Couldn't allocate Memory\n");
161                 exit(1);
162         }
163
164         /*make sure the packet is all zero*/
165         memset(nptr, 0, MAX_PACKET);
166         
167         /*do all the fancy conversions*/
168         if(!do_encap(link_type, &nh, &nptr, &nlength, &bytes, &length)){
169                 free(ndata);
170                 return;
171         }
172
173         /*save packet*/
174         pcap_dump(user,&nh, ndata);
175
176         free(ndata);
177 return;
178 }
179
180
181 /*do all the dccp to tcp conversions*/
182 int convert_packet(struct pcap_pkthdr *h, u_char **nptr, int *nlength, const u_char **optr, int *length)
183 {       
184         u_char* ncur=*nptr;
185         const u_char* ocur=*optr;
186         struct tcphdr *tcph;
187         struct dccp_hdr *dccph;
188         struct dccp_hdr_ext *dccphex;
189         struct dccp_hdr_ack_bits *dccphack;
190         int datalength;
191         int     len=0;
192         const u_char* pd;
193         u_char* npd;
194         u_char* tcpopt;
195
196         /*cast header pointers*/
197         tcph=(struct tcphdr*)ncur;
198         tcpopt=ncur+ sizeof(struct tcphdr);
199         dccph=(struct dccp_hdr*)ocur;
200         dccphex=(struct dccp_hdr_ext*)(ocur+sizeof(struct dccp_hdr));
201         dccphack=(struct dccp_hdr_ack_bits*)(ocur+ sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext));
202
203         dbgprintf(2,"Sequence Number: %llu\n", (unsigned long long)(((unsigned long)ntohs(dccph->dccph_seq)<<32) + ntohl(dccphex->dccph_seq_low)));
204
205         /*determine data length*/
206         datalength=*length - dccph->dccph_doff*4;
207         pd=*optr + dccph->dccph_doff*4;
208
209         /*set tcp standard features*/
210         tcph->source=dccph->dccph_sport;
211         tcph->dest=dccph->dccph_dport;
212         tcph->doff=5;
213         tcph->check=htonl(0);
214         tcph->urg_ptr=0;
215
216         /*Adjust TCP advertised window size*/
217         if(!yellow){
218                 tcph->window=htons(30000);
219         }
220
221         /*Only accept the first connection*/
222         if(s1 && s2 && dccph->dccph_sport!=s1->addr && dccph->dccph_dport!=s1->addr){
223                 return 0;
224         }
225
226         /*make changes by packet type*/
227         if(dccph->dccph_type==DCCP_PKT_REQUEST){//DCCP REQUEST -->TCP SYN
228                 dbgprintf(2,"Packet Type: Request\n");
229                 if(!s1){
230                         if(yellow){
231                                 tcph->window=htons(0);
232                         }
233                         tcph->ack_seq=htonl(0);
234                         tcph->seq=htonl(initialize_seq(&s1, dccph->dccph_sport, ntohl(dccphex->dccph_seq_low)));
235                         tcph->syn=1;
236                         tcph->ack=0;
237                         tcph->fin=0;
238                         tcph->rst=0;
239
240                         /* add Sack-permitted option, if relevant*/
241                         if(sack){
242                                 *tcpopt=4;
243                                 tcpopt++;
244                                 *tcpopt=2;
245                                 tcph->doff++;
246                         }
247
248                         /*calculate length*/
249                         len=tcph->doff*4;
250                 }
251         }
252
253         if(dccph->dccph_type==DCCP_PKT_RESPONSE){//DCCP RESPONSE-->TCP SYN,ACK
254                 dbgprintf(2,"Packet Type: Response\n");
255                 if(s1 && !s2){
256                         tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
257                         if(yellow){
258                                 tcph->window=htons(0);
259                         }
260                         tcph->seq=htonl(initialize_seq(&s2, dccph->dccph_sport, ntohl(dccphex->dccph_seq_low)));
261                         tcph->syn=1;
262                         tcph->ack=1;
263                         tcph->fin=0;
264                         tcph->rst=0;
265
266                         /* add Sack-permitted option, if relevant*/
267                         if(sack){
268                                 *tcpopt=4;
269                                 *(tcpopt+1)=2;
270                                 tcph->doff++;
271                         }
272
273                         /*calculate length*/
274                         len=tcph->doff*4;
275                 }
276         }
277
278         if(dccph->dccph_type==DCCP_PKT_DATA){//DCCP DATA----Never seen in packet capture
279                 dbgprintf(0,"DCCP Data packet not yet implemented\n");
280                 exit(1);
281         }
282
283         if(dccph->dccph_type==DCCP_PKT_DATAACK){//DCCP DATAACK-->TCP ACK with data
284                 dbgprintf(2,"Packet Type: DataAck\n");
285                 if(s1 && s2 && dccph->dccph_sport==s1->addr){ //determine which side of connection is sending this packet
286                         if(green){
287                                 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
288                         }else{
289                                 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
290                         }
291                         tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),datalength, dccph->dccph_type));
292                         if(yellow){
293                                 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s2, ntohl(dccphack->dccph_ack_nr_low)));
294                         }
295                         if(sack){
296                                 if(sack!=2 || interp_ack_vect((u_char*)dccph)){
297                                         ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
298                                 }
299                         }
300                 }else if(s1 && s2 && dccph->dccph_sport==s2->addr){
301                         if(green){
302                                 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
303                         }else{
304                                 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
305                         }
306                         tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),datalength,dccph->dccph_type));
307                         if(yellow){
308                                 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s1, ntohl(dccphack->dccph_ack_nr_low)));
309                         }
310                         if(sack){
311                                 if(sack!=2 || interp_ack_vect((u_char*)dccph)){
312                                         ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
313
314                                 }
315                         }
316                 }
317
318                 tcph->syn=0;
319                 tcph->ack=1;
320                 tcph->fin=0;
321                 tcph->rst=0;
322
323                 /*copy data*/
324                 npd=*nptr + tcph->doff*4;
325                 memcpy(npd, pd, datalength);
326
327                 /*calculate length*/
328                 len= tcph->doff*4 + datalength;
329         }
330
331         if(dccph->dccph_type==DCCP_PKT_ACK){ //DCCP ACK -->TCP ACK with no data
332                 dbgprintf(2,"Packet Type: Ack\n");
333                 if(s1 && s2 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet
334                         if(green){
335                                 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
336                         }else{
337                                 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
338                         }
339                         tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
340                         if(yellow){
341                                 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*1400);
342                                 if(-interp_ack_vect((u_char*)dccph)*1400 > 65535){
343                                         printf("Note: TCP Window Overflow @ %d.%d\n", (int)h->ts.tv_sec, (int)h->ts.tv_usec);
344                                 }
345                         }
346                         if(sack){
347                                 if(sack!=2 || interp_ack_vect((u_char*)dccph)){
348                                         ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
349                                 }
350                         }
351                 }else if(s1 && s2 && dccph->dccph_sport==s2->addr){
352                         if(green){
353                                 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
354                         }else{
355                                 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
356                         }
357                         tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
358                         if(yellow){
359                                 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*1400);
360                                 if(-interp_ack_vect((u_char*)dccph)*1400 > 65535){
361                                         printf("Note: TCP Window Overflow @ %d.%d\n", (int)h->ts.tv_sec, (int)h->ts.tv_usec);
362                                 }
363                         }
364                         if(sack){
365                                 if(sack!=2 || interp_ack_vect((u_char*)dccph)){
366                                         ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
367                                 }
368                         }
369                 }
370
371                 tcph->syn=0;
372                 tcph->ack=1;
373                 tcph->fin=0;
374                 tcph->rst=0;
375
376                 /*calculate length*/
377                 len=tcph->doff*4 + 1;
378         }
379
380         if(dccph->dccph_type==DCCP_PKT_CLOSEREQ){//DCCP CLOSEREQ----Never seen in packet capture
381                 dbgprintf(0,"DCCP CloseReq not yet implemented\n");
382                 exit(1);
383         }
384
385         if(dccph->dccph_type==DCCP_PKT_CLOSE){//DCCP CLOSE-->TCP FIN,ACK
386                 dbgprintf(2,"Packet Type: Close\n");
387                 if(s1 && s2 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet
388                         if(green){
389                                 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
390                         }else{
391                                 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
392                         }
393                         tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
394                         if(yellow){
395                                 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s2, ntohl(dccphack->dccph_ack_nr_low)));
396                         }
397                         if(sack){
398                                 if(sack!=2 || interp_ack_vect((u_char*)dccph)){
399                                         ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
400                                 }
401                         }
402                 }else if(s1 && s2 && dccph->dccph_sport==s2->addr){
403                         if(green){
404                                 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
405                         }else{
406                                 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
407                         }
408                         tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
409                         if(yellow){
410                                 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s1, ntohl(dccphack->dccph_ack_nr_low)));
411                         }
412                         if(sack){
413                                 if(sack!=2 || interp_ack_vect((u_char*)dccph)){
414                                         ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
415                                 }
416                         }
417                 }
418
419                 tcph->syn=0;
420                 tcph->ack=1;
421                 tcph->fin=1;
422                 tcph->rst=0;
423
424                 /*calculate length*/
425                 len=tcph->doff*4;
426         }
427
428         if(dccph->dccph_type==DCCP_PKT_RESET){//DCCP RESET-->TCP FIN,ACK (only seen at end of connection as CLOSE ACK)
429                 dbgprintf(2,"Packet Type: Reset\n");
430                 if(s1 && s2 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet
431                         if(green){
432                                 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
433                         }else{
434                                 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
435                         }
436                         tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
437                         if(yellow){
438                                 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s2, ntohl(dccphack->dccph_ack_nr_low)));
439                         }
440                         if(sack){
441                                 if(sack!=2 || interp_ack_vect((u_char*)dccph)){
442                                         ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
443                                 }
444                         }
445                 }else if(s1 && s2 && dccph->dccph_sport==s2->addr){
446                         if(green){
447                                 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
448                         }else{
449                                 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
450                         }
451                         tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
452                         if(yellow){
453                                 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s1, ntohl(dccphack->dccph_ack_nr_low)));
454                         }
455                         if(sack){
456                                 if(sack!=2 || interp_ack_vect((u_char*)dccph)){
457                                         ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
458                                 }
459                         }
460                 }
461
462                 tcph->syn=0;
463                 tcph->ack=1;
464                 tcph->fin=1;
465                 tcph->rst=0;
466
467                 /*calculate length*/
468                 len=tcph->doff*4;
469         }
470
471         if(dccph->dccph_type==DCCP_PKT_SYNC){//DCCP SYNC
472                 dbgprintf(2,"Packet Type: Sync\n");
473                 if(s1 && s2 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet
474                         if(green){
475                                 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
476                         }else{
477                                 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
478                         }
479                         tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),0,dccph->dccph_type));
480                         if(yellow){
481                                 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s2, ntohl(dccphack->dccph_ack_nr_low)));
482                         }else{
483                                 tcph->window=htons(0);
484                         }
485                         if(sack){
486                                 if(sack!=2 || interp_ack_vect((u_char*)dccph)){
487                                         ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
488                                 }
489                         }
490                 }else if(s1 && s2 && dccph->dccph_sport==s2->addr){
491                         if(green){
492                                 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
493                         }else{
494                                 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
495                         }
496                         tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),0,dccph->dccph_type));
497                         if(yellow){
498                                 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s1, ntohl(dccphack->dccph_ack_nr_low)));
499                         }else{
500                                 tcph->window=htons(0);
501                         }
502                         if(sack){
503                                 if(sack!=2 || interp_ack_vect((u_char*)dccph)){
504                                         ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
505                                 }
506                         }
507                 }
508
509                 tcph->syn=0;
510                 tcph->ack=1;
511                 tcph->fin=0;
512                 tcph->rst=0;
513
514                 /*calculate length*/
515                 len=tcph->doff*4;
516         }
517
518         if(dccph->dccph_type==DCCP_PKT_SYNCACK){//DCCP SYNACK
519                 dbgprintf(2,"Packet Type: SyncAck\n");
520                 if(s1 && s2 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet
521                         if(green){
522                                 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
523                         }else{
524                                 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
525                         }
526                         tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),0,dccph->dccph_type));
527                         if(yellow){
528                                 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s2, ntohl(dccphack->dccph_ack_nr_low)));
529                         }else{
530                                 tcph->window=htons(0);
531                         }
532                         if(sack){
533                                 if(sack!=2 || interp_ack_vect((u_char*)dccph)){
534                                         ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low));
535                                 }
536                         }
537                 }else if(s1 && s2 && dccph->dccph_sport==s2->addr){
538                         if(green){
539                                 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
540                         }else{
541                                 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
542                         }
543                         tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),0,dccph->dccph_type));
544                         if(yellow){
545                                 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s1, ntohl(dccphack->dccph_ack_nr_low)));
546                         }else{
547                                 tcph->window=htons(0);
548                         }
549                         if(sack){
550                                 if(sack!=2 || interp_ack_vect((u_char*)dccph)){
551                                         ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
552                                 }
553                         }
554                 }
555
556                 tcph->syn=0;
557                 tcph->ack=1;
558                 tcph->fin=0;
559                 tcph->rst=0;
560
561                 /*calculate length*/
562                 len=tcph->doff*4;
563         }
564
565         if(dccph->dccph_type==DCCP_PKT_INVALID){//DCCP INVALID----Never seen in packet capture
566                 dbgprintf(0,"Invalid DCCP Packet!!\n");
567                 return 0;
568         }
569
570         *nlength=len;
571 return 1;
572 }
573
574
575 /*Parse Ack Vector Options
576  * Returns the Number of packets since last recorded loss*/
577 unsigned int interp_ack_vect(u_char* hdr)
578 {
579         int hdrlen=((struct dccp_hdr*)hdr)->dccph_doff*4;
580         //struct dccp_hdr_ext* e=(struct dccp_hdr_ext*)hdr + sizeof(struct dccp_hdr);
581         int optlen;
582         int len;
583         int tmp;
584         int bp=0;
585         int additional=0;
586         u_char* opt;
587         u_char* cur;
588
589         /*setup pointer to DCCP options and determine how long the options are*/
590         optlen=hdrlen-sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext) - sizeof(struct dccp_hdr_ack_bits);
591         opt=hdr + sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext) + sizeof(struct dccp_hdr_ack_bits);
592
593         /*parse options*/
594         while(optlen > 0){
595                 len=*(opt+1);
596
597                 /*One byte options (no length)*/
598                 if(*opt< 32){
599                         optlen--;
600                         opt++;
601                         continue;
602                 }
603
604                 /*Ack Vector Option*/
605                 if(*opt==38 || *opt==39){
606                         tmp=len-2;
607                         cur=opt+2;
608                         /*loop through Vector*/
609                         while(tmp > 0){
610                                 /*ack vector works BACKWARDS through time*/
611
612                                 /*keep track of total packets recieved and if
613                                 a packet is lost, subtract all packets received
614                                 after that*/
615                                 if((*cur & 0xC0)==0xC0 || (*cur & 0xC0)==0x40){ //lost packet
616                                         bp+=(*cur & 0x3F)+1;
617                                         additional= -bp;
618                                 }
619                                         
620                                 if((*cur & 0xC0)==0x00){ //received packet
621                                         bp+= (*cur & 0x3F)+1;
622                                 }
623                                 tmp--;
624                                 cur++;
625                         }
626                 }
627                 
628                 optlen-=len;
629                 opt+=len;
630         }
631
632         dbgprintf(2,"Ack vector adding: %i\n", additional);
633 return additional;
634 }
635
636
637 /* Setup Sequence Number Structure*/
638 u_int32_t initialize_seq(struct seq_num **seq, __be16 source, __be32 initial)
639 {
640         /*allocate structure*/
641         *seq=(struct seq_num*)malloc(sizeof(struct seq_num));
642         if(*seq==NULL){
643                 dbgprintf(0,"Can't Allocate Memory!\n");
644                 exit(1);
645         }
646
647         /*set default values*/
648         (*seq)->cur=0;
649         (*seq)->addr=source;
650         (*seq)->size=TBL_SZ;
651         
652         /*allocate table*/
653         (*seq)->table=(struct tbl*)malloc(sizeof(struct tbl)*TBL_SZ);
654         if((*seq)->table==NULL){
655                 dbgprintf(0,"Can't Allocate Memory!\n");
656                 exit(1);
657         }
658
659         /*add first sequence number*/
660         (*seq)->table[0].old=initial;
661         (*seq)->table[0].new=initial;
662         (*seq)->table[0].type=DCCP_PKT_REQUEST;
663         (*seq)->table[0].size=0;
664 return initial;
665 }
666
667
668 /*Convert Sequence Numbers*/
669 u_int32_t add_new_seq(struct seq_num *seq, __be32 num, int size, enum dccp_pkt_type type)
670 {
671         int prev;
672         if(seq==NULL){
673                 dbgprintf(0,"ERROR NULL POINTER!\n");
674                 exit(1);
675         }
676         
677         /*account for missing packets*/
678         while(seq->table[seq->cur].old +1 < num && seq->table[seq->cur].old +1 > 0){
679                 prev=seq->cur;
680                 dbgprintf(1,"Missing Packet: %X\n",seq->table[prev].new+1);
681                 seq->cur=(seq->cur+1)%(seq->size);/*find next available table slot*/
682                 seq->table[seq->cur].old=seq->table[prev].old+1;
683                 seq->table[seq->cur].new=seq->table[prev].new + seq->table[prev].size;
684                 seq->table[seq->cur].size=size;
685                 seq->table[seq->cur].type=type;
686         }
687
688         prev=seq->cur;
689         seq->cur=(seq->cur+1)%(seq->size);/*find next available table slot*/
690         seq->table[seq->cur].old=num;
691         seq->table[seq->cur].size=size;
692         seq->table[seq->cur].type=type;
693         if(seq->table[prev].type==DCCP_PKT_REQUEST || seq->table[prev].type==DCCP_PKT_RESPONSE){
694                 seq->table[seq->cur].new=seq->table[prev].new + seq->table[prev].size;
695                 seq->table[seq->cur].size=1;
696                 return seq->table[prev].new + seq->table[prev].size+1;
697         }
698         if(type==DCCP_PKT_DATA || type==DCCP_PKT_DATAACK || type==DCCP_PKT_ACK){
699                 seq->table[seq->cur].new=seq->table[prev].new + seq->table[prev].size;
700                 return seq->table[seq->cur].new+1;
701         }
702         if(type==DCCP_PKT_SYNC || type==DCCP_PKT_SYNCACK){
703                 seq->table[seq->cur].new=seq->table[prev].new + seq->table[prev].size;
704                 return seq->table[seq->cur].new;
705         }
706         seq->table[seq->cur].new=seq->table[prev].new + seq->table[prev].size;
707 return seq->table[seq->cur].new +1;
708 }
709
710
711 /*Convert Ack Numbers*/
712 u_int32_t convert_ack(struct seq_num *seq, __be32 num)
713 {
714         if(seq==NULL){
715                 dbgprintf(0,"ERROR NULL POINTER!\n");
716                 exit(1);
717         }
718
719         /*loop through table looking for the DCCP ack number*/
720         for(int i=0; i < seq->size; i++){
721                 if(seq->table[i].old==num){
722                         return  seq->table[i].new + seq->table[i].size + 1; /*TCP acks the sequence number plus 1*/
723                 }
724         }
725         
726         dbgprintf(1, "Error: Address Not Found! looking for: %X\n", num);
727 return 0;
728 }
729
730
731 /* Get size of packet being acked*/
732 int acked_packet_size(struct seq_num *seq, __be32 num)
733 {
734         if(seq==NULL){
735                 dbgprintf(0,"ERROR NULL POINTER!\n");
736                 exit(1);
737         }
738
739         /*loop through table looking for the DCCP ack number*/
740         for(int i=0; i < seq->size; i++){
741                 if(seq->table[i].old==num){
742                         return  seq->table[i].size;
743                 }
744         }
745         
746         dbgprintf(1, "Error: Address Not Found! looking for: %X\n", num);
747 return 0;
748 }
749
750
751 /*Ack Vector to SACK Option*/
752 void ack_vect2sack(struct seq_num *seq, struct tcphdr *tcph, u_char* tcpopts, u_char* dccphdr, __be32 dccpack)
753 {
754         int hdrlen=((struct dccp_hdr*)dccphdr)->dccph_doff*4;
755         int optlen;
756         int len;
757         int tmp;
758         __be32 bp;
759         u_char* temp;
760         u_char* opt;
761         u_char* cur;
762         u_char* tlen;
763         u_int32_t bL=0;
764         u_int32_t bR;
765         u_int32_t* pL;
766         u_int32_t* pR;
767         int num_blocks;
768         int cont;
769         int isopt;
770         
771         /*setup pointer to DCCP options and determine how long the options are*/
772         optlen=hdrlen-sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext) - sizeof(struct dccp_hdr_ack_bits);
773         opt=dccphdr + sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext) + sizeof(struct dccp_hdr_ack_bits);
774
775         /*setup tcp pointers*/
776         num_blocks=2;
777         *tcpopts=5;
778         tlen=tcpopts+1;
779         temp=tlen;
780         temp++;
781         pL=(u_int32_t*)temp;
782         pR=pL+1;
783
784         /*setup tcp control variables*/
785         bp=dccpack;
786         cont=0;
787         *tlen=2;
788         isopt=0;
789
790         /*parse options*/
791         while(optlen > 0){
792                 len=*(opt+1);
793
794                 /*One byte options (no length)*/
795                 if(*opt< 32){
796                         optlen--;
797                         opt++;
798                         continue;
799                 }
800
801                 /*Ack Vector Option*/
802                 if(*opt==38 || *opt==39){
803                         tmp=len-2;
804                         cur=opt+2;
805                         /*loop through Vector*/
806                         while(tmp > 0){
807                                 /*ack vector works BACKWARDS through time*/
808
809                                 if((*cur & 0xC0)==0xC0 || (*cur & 0xC0)==0x40){ //lost packet
810                                         if(cont){ /*end a SACK run, if one is started*/
811                                                 bR=convert_ack(seq, bp);
812                                                 cont=0;
813                                                 num_blocks--;
814                                                 *pR=htonl(bR);
815                                                 *pL=htonl(bL);
816                                                 tcph->doff+=2;
817                                                 *tlen+=8;
818                                                 pL=pR+1;
819                                                 pR=pL+1;                        
820                                         }
821                                         bp= bp - (*cur & 0x3F)- 1;
822                                 }
823                                         
824                                 if((*cur & 0xC0)==0x00){ //received packet
825                                         if(!cont){ /*if no SACK run and we can start another one, do so*/
826                                                 if(num_blocks>0){
827                                                         bL=convert_ack(seq, bp);
828                                                         isopt=1;
829                                                         cont=1;
830
831                                                 }
832                                         }
833                                         bp =  bp -(*cur & 0x3F)- 1;
834                                 }
835                                 tmp--;
836                                 cur++;
837                         }
838                 }
839                 
840                 optlen-=len;
841                 opt+=len;
842         }
843
844         /*if we are in the middle of a SACK run, close it*/
845         if(cont){
846                 bR=convert_ack(seq, bp);
847                 *pR=htonl(bR);
848                 *pL=htonl(bL);
849                 tcph->doff+=2;
850                 *tlen+=8;
851                 cont=0;
852         }
853
854         /*adjust length if the option is actually added*/
855         if(isopt){
856                 tcph->doff+=1;
857         }
858 return;
859 }
860
861 /*Debug Printf*/
862 void dbgprintf(int level, const char *fmt, ...)
863 {
864     va_list args;
865     if(debug>=level){
866         va_start(args, fmt);
867         vfprintf(stderr, fmt, args);
868         va_end(args);
869     }
870 }