]> sjero.net Git - dccp2tcp/blob - dccp2tcp.c
94bc7dd7bd1be7e78189cd978394a1124f6c7558
[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=1;
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                                 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
297                         }
298                 }else if(s1 && s2 && dccph->dccph_sport==s2->addr){
299                         if(green){
300                                 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
301                         }else{
302                                 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
303                         }
304                         tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),datalength,dccph->dccph_type));
305                         if(yellow){
306                                 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s1, ntohl(dccphack->dccph_ack_nr_low)));
307                         }
308                         if(sack){
309                                 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
310                         }
311                 }
312
313                 tcph->syn=0;
314                 tcph->ack=1;
315                 tcph->fin=0;
316                 tcph->rst=0;
317
318                 /*copy data*/
319                 npd=*nptr + tcph->doff*4;
320                 memcpy(npd, pd, datalength);
321
322                 /*calculate length*/
323                 len= tcph->doff*4 + datalength;
324         }
325
326         if(dccph->dccph_type==DCCP_PKT_ACK){ //DCCP ACK -->TCP ACK with no data
327                 dbgprintf(2,"Packet Type: Ack\n");
328                 if(s1 && s2 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet
329                         if(green){
330                                 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
331                         }else{
332                                 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
333                         }
334                         tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
335                         if(yellow){
336                                 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*1400);
337                                 if(-interp_ack_vect((u_char*)dccph)*1400 > 65535){
338                                         printf("Note: TCP Window Overflow @ %d.%d\n", (int)h->ts.tv_sec, (int)h->ts.tv_usec);
339                                 }
340                         }
341                         if(sack){
342                                 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
343                         }
344                 }else if(s1 && s2 && dccph->dccph_sport==s2->addr){
345                         if(green){
346                                 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
347                         }else{
348                                 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
349                         }
350                         tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
351                         if(yellow){
352                                 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*1400);
353                                 if(-interp_ack_vect((u_char*)dccph)*1400 > 65535){
354                                         printf("Note: TCP Window Overflow @ %d.%d\n", (int)h->ts.tv_sec, (int)h->ts.tv_usec);
355                                 }
356                         }
357                         if(sack){
358                                 ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
359                         }
360                 }
361
362                 tcph->syn=0;
363                 tcph->ack=1;
364                 tcph->fin=0;
365                 tcph->rst=0;
366
367                 /*calculate length*/
368                 len=tcph->doff*4 + 1;
369         }
370
371         if(dccph->dccph_type==DCCP_PKT_CLOSEREQ){//DCCP CLOSEREQ----Never seen in packet capture
372                 dbgprintf(0,"DCCP CloseReq not yet implemented\n");
373                 exit(1);
374         }
375
376         if(dccph->dccph_type==DCCP_PKT_CLOSE){//DCCP CLOSE-->TCP FIN,ACK
377                 dbgprintf(2,"Packet Type: Close\n");
378                 if(s1 && s2 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet
379                         if(green){
380                                 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
381                         }else{
382                                 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
383                         }
384                         tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
385                         if(yellow){
386                                 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s2, ntohl(dccphack->dccph_ack_nr_low)));
387                         }
388                         if(sack){
389                                 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
390                         }
391                 }else if(s1 && s2 && dccph->dccph_sport==s2->addr){
392                         if(green){
393                                 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
394                         }else{
395                                 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
396                         }
397                         tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
398                         if(yellow){
399                                 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s1, ntohl(dccphack->dccph_ack_nr_low)));
400                         }
401                         if(sack){
402                                 ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
403                         }
404                 }
405
406                 tcph->syn=0;
407                 tcph->ack=1;
408                 tcph->fin=1;
409                 tcph->rst=0;
410
411                 /*calculate length*/
412                 len=tcph->doff*4;
413         }
414
415         if(dccph->dccph_type==DCCP_PKT_RESET){//DCCP RESET-->TCP FIN,ACK (only seen at end of connection as CLOSE ACK)
416                 dbgprintf(2,"Packet Type: Reset\n");
417                 if(s1 && s2 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet
418                         if(green){
419                                 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
420                         }else{
421                                 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
422                         }
423                         tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
424                         if(yellow){
425                                 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s2, ntohl(dccphack->dccph_ack_nr_low)));
426                         }
427                         if(sack){
428                                 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
429                         }
430                 }else if(s1 && s2 && dccph->dccph_sport==s2->addr){
431                         if(green){
432                                 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
433                         }else{
434                                 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
435                         }
436                         tcph->seq=htonl(add_new_seq(s2, 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(s1, ntohl(dccphack->dccph_ack_nr_low)));
439                         }
440                         if(sack){
441                                 ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
442                         }
443                 }
444
445                 tcph->syn=0;
446                 tcph->ack=1;
447                 tcph->fin=1;
448                 tcph->rst=0;
449
450                 /*calculate length*/
451                 len=tcph->doff*4;
452         }
453
454         if(dccph->dccph_type==DCCP_PKT_SYNC){//DCCP SYNC
455                 dbgprintf(2,"Packet Type: Sync\n");
456                 if(s1 && s2 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet
457                         if(green){
458                                 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
459                         }else{
460                                 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
461                         }
462                         tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),0,dccph->dccph_type));
463                         if(yellow){
464                                 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s2, ntohl(dccphack->dccph_ack_nr_low)));
465                         }else{
466                                 tcph->window=htons(0);
467                         }
468                         if(sack){
469                                 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
470                         }
471                 }else if(s1 && s2 && dccph->dccph_sport==s2->addr){
472                         if(green){
473                                 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
474                         }else{
475                                 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
476                         }
477                         tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),0,dccph->dccph_type));
478                         if(yellow){
479                                 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s1, ntohl(dccphack->dccph_ack_nr_low)));
480                         }else{
481                                 tcph->window=htons(0);
482                         }
483                         if(sack){
484                                 ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
485                         }
486                 }
487
488                 tcph->syn=0;
489                 tcph->ack=1;
490                 tcph->fin=0;
491                 tcph->rst=0;
492
493                 /*calculate length*/
494                 len=tcph->doff*4;
495         }
496
497         if(dccph->dccph_type==DCCP_PKT_SYNCACK){//DCCP SYNACK
498                 dbgprintf(2,"Packet Type: SyncAck\n");
499                 if(s1 && s2 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet
500                         if(green){
501                                 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)));
502                         }else{
503                                 tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
504                         }
505                         tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),0,dccph->dccph_type));
506                         if(yellow){
507                                 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s2, ntohl(dccphack->dccph_ack_nr_low)));
508                         }else{
509                                 tcph->window=htons(0);
510                         }
511                         if(sack){
512                                 ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low));
513                         }
514                 }else if(s1 && s2 && dccph->dccph_sport==s2->addr){
515                         if(green){
516                                 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)));
517                         }else{
518                                 tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph)));
519                         }
520                         tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),0,dccph->dccph_type));
521                         if(yellow){
522                                 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s1, ntohl(dccphack->dccph_ack_nr_low)));
523                         }else{
524                                 tcph->window=htons(0);
525                         }
526                         if(sack){
527                                 ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) );
528                         }
529                 }
530
531                 tcph->syn=0;
532                 tcph->ack=1;
533                 tcph->fin=0;
534                 tcph->rst=0;
535
536                 /*calculate length*/
537                 len=tcph->doff*4;
538         }
539
540         if(dccph->dccph_type==DCCP_PKT_INVALID){//DCCP INVALID----Never seen in packet capture
541                 dbgprintf(0,"Invalid DCCP Packet!!\n");
542                 return 0;
543         }
544
545         *nlength=len;
546 return 1;
547 }
548
549
550 /*Parse Ack Vector Options*/
551 unsigned int interp_ack_vect(u_char* hdr)
552 {
553         int hdrlen=((struct dccp_hdr*)hdr)->dccph_doff*4;
554         //struct dccp_hdr_ext* e=(struct dccp_hdr_ext*)hdr + sizeof(struct dccp_hdr);
555         int optlen;
556         int len;
557         int tmp;
558         int bp=0;
559         int additional=0;
560         u_char* opt;
561         u_char* cur;
562
563         /*setup pointer to DCCP options and determine how long the options are*/
564         optlen=hdrlen-sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext) - sizeof(struct dccp_hdr_ack_bits);
565         opt=hdr + sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext) + sizeof(struct dccp_hdr_ack_bits);
566
567         /*parse options*/
568         while(optlen > 0){
569                 len=*(opt+1);
570
571                 /*One byte options (no length)*/
572                 if(*opt< 32){
573                         optlen--;
574                         opt++;
575                         continue;
576                 }
577
578                 /*Ack Vector Option*/
579                 if(*opt==38 || *opt==39){
580                         tmp=len-2;
581                         cur=opt+2;
582                         /*loop through Vector*/
583                         while(tmp > 0){
584                                 /*ack vector works BACKWARDS through time*/
585
586                                 /*keep track of total packets recieved and if
587                                 a packet is lost, subtract all packets received
588                                 after that*/
589                                 if((*cur & 0xC0)==0xC0 || (*cur & 0xC0)==0x40){ //lost packet
590                                         bp+=(*cur & 0x3F)+1;
591                                         additional= -bp;
592                                 }
593                                         
594                                 if((*cur & 0xC0)==0x00){ //received packet
595                                         bp+= (*cur & 0x3F)+1;
596                                 }
597                                 tmp--;
598                                 cur++;
599                         }
600                 }
601                 
602                 optlen-=len;
603                 opt+=len;
604         }
605
606         dbgprintf(2,"Ack vector adding: %i\n", additional);
607 return additional;
608 }
609
610
611 /* Setup Sequence Number Structure*/
612 u_int32_t initialize_seq(struct seq_num **seq, __be16 source, __be32 initial)
613 {
614         /*allocate structure*/
615         *seq=(struct seq_num*)malloc(sizeof(struct seq_num));
616         if(*seq==NULL){
617                 dbgprintf(0,"Can't Allocate Memory!\n");
618                 exit(1);
619         }
620
621         /*set default values*/
622         (*seq)->cur=0;
623         (*seq)->addr=source;
624         (*seq)->size=TBL_SZ;
625         
626         /*allocate table*/
627         (*seq)->table=(struct tbl*)malloc(sizeof(struct tbl)*TBL_SZ);
628         if((*seq)->table==NULL){
629                 dbgprintf(0,"Can't Allocate Memory!\n");
630                 exit(1);
631         }
632
633         /*add first sequence number*/
634         (*seq)->table[0].old=initial;
635         (*seq)->table[0].new=initial;
636         (*seq)->table[0].type=DCCP_PKT_REQUEST;
637         (*seq)->table[0].size=0;
638 return initial;
639 }
640
641
642 /*Convert Sequence Numbers*/
643 u_int32_t add_new_seq(struct seq_num *seq, __be32 num, int size, enum dccp_pkt_type type)
644 {
645         int prev;
646         if(seq==NULL){
647                 dbgprintf(0,"ERROR NULL POINTER!\n");
648                 exit(1);
649         }
650         
651         /*account for missing packets*/
652         while(seq->table[seq->cur].old +1 < num && seq->table[seq->cur].old +1 > 0){
653                 prev=seq->cur;
654                 dbgprintf(1,"Missing Packet: %X\n",seq->table[prev].new+1);
655                 seq->cur=(seq->cur+1)%(seq->size);/*find next available table slot*/
656                 seq->table[seq->cur].old=seq->table[prev].old+1;
657                 seq->table[seq->cur].new=seq->table[prev].new + seq->table[prev].size;
658                 seq->table[seq->cur].size=size;
659                 seq->table[seq->cur].type=type;
660         }
661
662         prev=seq->cur;
663         seq->cur=(seq->cur+1)%(seq->size);/*find next available table slot*/
664         seq->table[seq->cur].old=num;
665         seq->table[seq->cur].size=size;
666         seq->table[seq->cur].type=type;
667         if(seq->table[prev].type==DCCP_PKT_REQUEST || seq->table[prev].type==DCCP_PKT_RESPONSE){
668                 seq->table[seq->cur].new=seq->table[prev].new + seq->table[prev].size;
669                 seq->table[seq->cur].size=1;
670                 return seq->table[prev].new + seq->table[prev].size+1;
671         }
672         if(type==DCCP_PKT_DATA || type==DCCP_PKT_DATAACK || type==DCCP_PKT_ACK){
673                 seq->table[seq->cur].new=seq->table[prev].new + seq->table[prev].size;
674                 return seq->table[seq->cur].new+1;
675         }
676         if(type==DCCP_PKT_SYNC || type==DCCP_PKT_SYNCACK){
677                 seq->table[seq->cur].new=seq->table[prev].new + seq->table[prev].size;
678                 return seq->table[seq->cur].new;
679         }
680         seq->table[seq->cur].new=seq->table[prev].new + seq->table[prev].size;
681 return seq->table[seq->cur].new +1;
682 }
683
684
685 /*Convert Ack Numbers*/
686 u_int32_t convert_ack(struct seq_num *seq, __be32 num)
687 {
688         if(seq==NULL){
689                 dbgprintf(0,"ERROR NULL POINTER!\n");
690                 exit(1);
691         }
692
693         /*loop through table looking for the DCCP ack number*/
694         for(int i=0; i < seq->size; i++){
695                 if(seq->table[i].old==num){
696                         return  seq->table[i].new + seq->table[i].size + 1; /*TCP acks the sequence number plus 1*/
697                 }
698         }
699         
700         dbgprintf(1, "Error: Address Not Found! looking for: %X\n", num);
701 return 0;
702 }
703
704
705 /* Get size of packet being acked*/
706 int acked_packet_size(struct seq_num *seq, __be32 num)
707 {
708         if(seq==NULL){
709                 dbgprintf(0,"ERROR NULL POINTER!\n");
710                 exit(1);
711         }
712
713         /*loop through table looking for the DCCP ack number*/
714         for(int i=0; i < seq->size; i++){
715                 if(seq->table[i].old==num){
716                         return  seq->table[i].size;
717                 }
718         }
719         
720         dbgprintf(1, "Error: Address Not Found! looking for: %X\n", num);
721 return 0;
722 }
723
724
725 /*Ack Vector to SACK Option*/
726 void ack_vect2sack(struct seq_num *seq, struct tcphdr *tcph, u_char* tcpopts, u_char* dccphdr, __be32 dccpack)
727 {
728         int hdrlen=((struct dccp_hdr*)dccphdr)->dccph_doff*4;
729         int optlen;
730         int len;
731         int tmp;
732         __be32 bp;
733         u_char* temp;
734         u_char* opt;
735         u_char* cur;
736         u_char* tlen;
737         u_int32_t bL=0;
738         u_int32_t bR;
739         u_int32_t* pL;
740         u_int32_t* pR;
741         int num_blocks;
742         int cont;
743         int isopt;
744         
745         /*setup pointer to DCCP options and determine how long the options are*/
746         optlen=hdrlen-sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext) - sizeof(struct dccp_hdr_ack_bits);
747         opt=dccphdr + sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext) + sizeof(struct dccp_hdr_ack_bits);
748
749         /*setup tcp pointers*/
750         num_blocks=2;
751         *tcpopts=5;
752         tlen=tcpopts+1;
753         temp=tlen;
754         temp++;
755         pL=(u_int32_t*)temp;
756         pR=pL+1;
757
758         /*setup tcp control variables*/
759         bp=dccpack;
760         cont=0;
761         *tlen=2;
762         isopt=0;
763
764         /*parse options*/
765         while(optlen > 0){
766                 len=*(opt+1);
767
768                 /*One byte options (no length)*/
769                 if(*opt< 32){
770                         optlen--;
771                         opt++;
772                         continue;
773                 }
774
775                 /*Ack Vector Option*/
776                 if(*opt==38 || *opt==39){
777                         tmp=len-2;
778                         cur=opt+2;
779                         /*loop through Vector*/
780                         while(tmp > 0){
781                                 /*ack vector works BACKWARDS through time*/
782
783                                 if((*cur & 0xC0)==0xC0 || (*cur & 0xC0)==0x40){ //lost packet
784                                         if(cont){ /*end a SACK run, if one is started*/
785                                                 bR=convert_ack(seq, bp);
786                                                 cont=0;
787                                                 num_blocks--;
788                                                 *pR=htonl(bR);
789                                                 *pL=htonl(bL);
790                                                 tcph->doff+=2;
791                                                 *tlen+=8;
792                                                 pL=pR+1;
793                                                 pR=pL+1;                        
794                                         }
795                                         bp= bp - (*cur & 0x3F)- 1;
796                                 }
797                                         
798                                 if((*cur & 0xC0)==0x00){ //received packet
799                                         if(!cont){ /*if no SACK run and we can start another one, do so*/
800                                                 if(num_blocks>0){
801                                                         bL=convert_ack(seq, bp);
802                                                         isopt=1;
803                                                         cont=1;
804
805                                                 }
806                                         }
807                                         bp =  bp -(*cur & 0x3F)- 1;
808                                 }
809                                 tmp--;
810                                 cur++;
811                         }
812                 }
813                 
814                 optlen-=len;
815                 opt+=len;
816         }
817
818         /*if we are in the middle of a SACK run, close it*/
819         if(cont){
820                 bR=convert_ack(seq, bp);
821                 *pR=htonl(bR);
822                 *pL=htonl(bL);
823                 tcph->doff+=2;
824                 *tlen+=8;
825                 cont=0;
826         }
827
828         /*adjust length if the option is actually added*/
829         if(isopt){
830                 tcph->doff+=1;
831         }
832 return;
833 }
834
835 /*Debug Printf*/
836 void dbgprintf(int level, const char *fmt, ...)
837 {
838     va_list args;
839     if(debug>=level){
840         va_start(args, fmt);
841         vfprintf(stderr, fmt, args);
842         va_end(args);
843     }
844 }