1 /******************************************************************************
2 Utility to convert a DCCP flow to a TCP flow for DCCP analysis via
5 Copyright (C) 2013 Samuel Jero <sj323707@ohio.edu>
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 Author: Samuel Jero <sj323707@ohio.edu>
24 1)DCCP MUST use 48 bit sequence numbers
25 2)DCCP Ack packets show up as TCP packets containing one byte
26 ******************************************************************************/
30 #define DCCP2TCP_VERSION 1.6
31 #define COPYRIGHT_YEAR 2013
34 int debug=0; /*set to 1 to turn on debugging information*/
35 int yellow=0; /*tcptrace yellow line as currently acked packet*/
36 int green=0; /*tcptrace green line as currently acked packet*/
37 int sack=0; /*add TCP SACKS*/
40 pcap_t* in; /*libpcap input file discriptor*/
41 pcap_dumper_t *out; /*libpcap output file discriptor*/
42 struct connection *chead; /*connection list*/
45 void handle_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes);
46 int handle_request(struct packet* new, const struct const_packet* old, struct hcon* h1, struct hcon* h2);
47 int handle_response(struct packet* new, const struct const_packet* old, struct hcon* h1, struct hcon* h2);
48 int handle_dataack(struct packet* new, const struct const_packet* old, struct hcon* h1, struct hcon* h2);
49 int handle_ack(struct packet* new, const struct const_packet* old, struct hcon* h1, struct hcon* h2);
50 int handle_closereq(struct packet* new, const struct const_packet* old, struct hcon* h1, struct hcon* h2);
51 int handle_close(struct packet* new, const struct const_packet* old, struct hcon* h1, struct hcon* h2);
52 int handle_reset(struct packet* new, const struct const_packet* old, struct hcon* h1, struct hcon* h2);
53 int handle_sync(struct packet* new, const struct const_packet* old, struct hcon* h1, struct hcon* h2);
54 int handle_syncack(struct packet* new, const struct const_packet* old, struct hcon* h1, struct hcon* h2);
55 int handle_data(struct packet* new, const struct const_packet* old, struct hcon* h1, struct hcon* h2);
56 int parse_options(const u_char* opt_start, int len, struct hcon* A, struct hcon* B);
57 int process_feature(const u_char* feat, int len, int confirm, int L, struct hcon* A, struct hcon* B);
58 void ack_vect2sack(struct hcon *seq, struct tcphdr *tcph, u_char* tcpopts, u_char* dccphdr,
59 __be32 dccpack, struct hcon* o_hcn);
64 /*Parse commandline options and open files*/
65 int main(int argc, char *argv[])
72 /*parse commandline options*/
77 /*loop through commandline options*/
78 for(int i=1; i < argc; i++){
79 if(argv[i][0]!='-' || (argv[i][0]=='-' && strlen(argv[i])==1)){
80 if(dfile==NULL || argv[i][0]=='-'){
81 /*assign first non-dash (or only dash) argument to the dccp file*/
85 tfile=argv[i]; /*assign second non-dash argument to the dccp file*/
91 if(argv[i][1]=='d' && strlen(argv[i])==2){ /* -d */
94 if(argv[i][1]=='y' && strlen(argv[i])==2){ /* -y */
97 if(argv[i][1]=='g' && strlen(argv[i])==2){ /* -g */
100 if(argv[i][1]=='s' && strlen(argv[i])==2){ /* -s */
103 if(argv[i][1]=='h' && strlen(argv[i])==2){ /* -h */
106 if(argv[i][1]=='V' && strlen(argv[i])==2){ /* -V */
112 if(dfile==NULL || tfile==NULL){
116 /*all options validated*/
119 dbgprintf(1,"Debug On\n");
121 dbgprintf(1,"Tcptrace green line at highest acknowledgment\n");
123 dbgprintf(1,"Tcptrace green line at highest acknowledged acknowledgment\n");
126 dbgprintf(1,"Tcptrace yellow line at highest acknowledgment\n");
128 dbgprintf(1,"Tcptrace yellow line window value (a made up number)\n");
131 dbgprintf(1,"Adding TCP SACKS\n");
133 dbgprintf(1,"Input file: %s\n", dfile);
134 dbgprintf(1,"Output file: %s\n", tfile);
137 /*attempt to open input file*/
138 in=pcap_open_offline(dfile, erbuffer);
140 dbgprintf(0,"Error opening input file\n");
144 /*attempt to open output file*/
145 out=pcap_dump_open(in,tfile);
147 dbgprintf(0,"Error opening output file\n");
153 u_char *user=(u_char*)out;
154 pcap_loop(in, -1, handle_packet, user);
158 pcap_dump_close(out);
160 /*Delete all connections*/
161 cleanup_connections();
166 /*call back function for pcap_loop--do basic packet handling*/
167 void handle_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes)
170 struct pcap_pkthdr nh;
173 struct const_packet old;
175 /*Determine the link type for this packet*/
176 link_type=pcap_datalink(in);
178 /*create new libpcap header*/
179 memcpy(&nh, h, sizeof(struct pcap_pkthdr));
181 /*Setup packet structs*/
183 old.length=h->caplen;
188 new.length=MAX_PACKET;
192 /*create buffer for new packet*/
193 new.data=ndata=malloc(MAX_PACKET);
195 dbgprintf(0,"Error: Couldn't allocate Memory\n");
199 /*make sure the packet is all zero*/
200 memset(new.data, 0, MAX_PACKET);
202 /*do all the fancy conversions*/
203 if(!do_encap(link_type, &new, &old)){
209 pcap_dump(user,&nh, ndata);
215 /*do all the dccp to tcp conversions*/
216 int convert_packet(struct packet *new, const struct const_packet* old)
219 struct dccp_hdr *dccph;
220 struct dccp_hdr_ext *dccphex;
221 struct hcon *h1=NULL;
222 struct hcon *h2=NULL;
225 if(!new || !old || !new->data || !old->data || !new->h || !old->h){
226 dbgprintf(0,"Error: Convert Packet Function given bad data!\n");
230 if(old->length < (sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext))
231 || new->length < sizeof(struct dccp_hdr)){
232 dbgprintf(0, "Error: DCCP Packet Too short!\n");
236 /*cast header pointers*/
237 tcph=(struct tcphdr*)new->data;
238 dccph=(struct dccp_hdr*)old->data;
239 dccphex=(struct dccp_hdr_ext*)(old->data+sizeof(struct dccp_hdr));
241 dbgprintf(2,"Sequence Number: %llu\n", (unsigned long long)
242 (((unsigned long)ntohs(dccph->dccph_seq)<<32) + ntohl(dccphex->dccph_seq_low)));
244 /*Ensure packet is at least as large as DCCP header*/
245 if(old->length < dccph->dccph_doff*4){
246 dbgprintf(0, "Error: DCCP Header truncated\n");
251 if(get_host(new->src_id, new->dest_id, new->id_len, dccph->dccph_sport,
252 dccph->dccph_dport, dccph->dccph_type,&h1, &h2)){
253 dbgprintf(0,"Error: Can't Get Hosts!\n");
256 if(h1==NULL || h2==NULL){
257 dbgprintf(0, "Error: Can't Get Hosts!\n");
260 if(h1->state==IGNORE || h2->state==IGNORE){
261 dbgprintf(2, "Ignoring packet between %i and %i\n",
262 ntohs(dccph->dccph_sport), ntohs(dccph->dccph_dport));
266 /*set TCP standard features*/
267 tcph->source=dccph->dccph_sport;
268 tcph->dest=dccph->dccph_dport;
270 tcph->check=htonl(0);
273 /*Adjust TCP advertised window size*/
275 tcph->window=htons(30000);
278 /*Process DCCP Packet Types*/
279 switch(dccph->dccph_type){
280 case DCCP_PKT_REQUEST:
281 dbgprintf(2,"Packet Type: Request\n");
282 if(!handle_request(new, old, h1, h2)){
286 case DCCP_PKT_RESPONSE:
287 dbgprintf(2,"Packet Type: Response\n");
288 if(!handle_response(new,old,h1,h2)){
293 if(!handle_data(new,old,h1,h2)){
297 case DCCP_PKT_DATAACK:
298 dbgprintf(2,"Packet Type: DataAck\n");
299 if(!handle_dataack(new,old,h1,h2)){
304 dbgprintf(2,"Packet Type: Ack\n");
305 if(!handle_ack(new,old,h1,h2)){
309 case DCCP_PKT_CLOSEREQ:
310 dbgprintf(2,"Packet Type: CloseReq\n");
311 if(!handle_closereq(new,old,h1,h2)){
316 dbgprintf(2,"Packet Type: Close\n");
317 if(!handle_close(new,old,h1,h2)){
322 dbgprintf(2,"Packet Type: Reset\n");
323 if(!handle_reset(new,old,h1,h2)){
328 dbgprintf(2,"Packet Type: Sync\n");
329 if(!handle_sync(new,old,h1,h2)){
333 case DCCP_PKT_SYNCACK:
334 dbgprintf(2,"Packet Type: SyncAck\n");
335 if(!handle_syncack(new,old,h1,h2)){
340 dbgprintf(0,"Invalid DCCP Packet!!\n");
345 /*Compute TCP checksums*/
346 if(new->id_len==IP4_ADDR_LEN){
348 tcph->check=ipv4_pseudohdr_chksum(new->data,
349 new->length, new->dest_id, new->src_id, 6);
350 }else if(new->id_len==IP6_ADDR_LEN){
352 tcph->check=ipv6_pseudohdr_chksum(new->data,
353 new->length, new->dest_id, new->src_id, 6);
356 dbgprintf(2,"Unknown ID Length, can't do checksums\n");
362 int handle_request(struct packet* new, const struct const_packet* old, struct hcon* h1, struct hcon* h2)
365 struct dccp_hdr *dccph;
366 struct dccp_hdr_ext *dccphex;
370 const u_char* dccpopt;
373 if(new->length < sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext)+sizeof(struct dccp_hdr_request)){
377 /*cast header pointers*/
378 tcph=(struct tcphdr*)new->data;
379 dccph=(struct dccp_hdr*)old->data;
380 dccphex=(struct dccp_hdr_ext*)(old->data+sizeof(struct dccp_hdr));
382 /*determine data length*/
383 datalength=old->length - dccph->dccph_doff*4;
385 /*Process DCCP Options*/
386 dccpopt=old->data + sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext)+sizeof(struct dccp_hdr_request);
387 optlen=dccph->dccph_doff*4 - sizeof(struct dccp_hdr)-sizeof(struct dccp_hdr_ext)-sizeof(struct dccp_hdr_request);
388 if(!parse_options(dccpopt,optlen,h1,h2)){
394 tcph->window=htons(0);
396 tcph->ack_seq=htonl(0);
398 tcph->seq=htonl(initialize_hcon(h1, ntohl(dccphex->dccph_seq_low)));
400 tcph->seq=htonl(add_new_seq(h1, ntohl(dccphex->dccph_seq_low),datalength, dccph->dccph_type));
407 /* add Sack-permitted option, if relevant*/
409 tcpopt=(u_char*)(new->data + tcph->doff*4);
417 new->length=tcph->doff*4;
421 int handle_response(struct packet* new, const struct const_packet* old, struct hcon* h1, struct hcon* h2)
424 struct dccp_hdr *dccph;
425 struct dccp_hdr_ext *dccphex;
426 struct dccp_hdr_ack_bits *dccphack;
429 const u_char* dccpopt;
432 if(new->length < sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext)
433 + sizeof(struct dccp_hdr_ack_bits)+sizeof(struct dccp_hdr_request)){
437 /*cast header pointers*/
438 tcph=(struct tcphdr*)new->data;
439 dccph=(struct dccp_hdr*)old->data;
440 dccphex=(struct dccp_hdr_ext*)(old->data+sizeof(struct dccp_hdr));
441 dccphack=(struct dccp_hdr_ack_bits*)(old->data+ sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext));
443 /*Process DCCP Options*/
444 dccpopt=old->data + sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext) +
445 sizeof(struct dccp_hdr_ack_bits) + sizeof(struct dccp_hdr_request);
446 optlen=dccph->dccph_doff*4 - sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext)
447 - sizeof(struct dccp_hdr_ack_bits) - sizeof(struct dccp_hdr_request);
448 if(!parse_options(dccpopt,optlen,h1,h2)){
454 dbgprintf(0,"Warning: DCCP Response without a Request!!\n");
456 tcph->ack_seq=htonl(convert_ack(h2,ntohl(dccphack->dccph_ack_nr_low),h1));
457 h1->high_ack=ntohl(tcph->ack_seq);
459 tcph->window=htons(0);
462 tcph->seq=htonl(initialize_hcon(h1, ntohl(dccphex->dccph_seq_low)));
469 /* add Sack-permitted option, if relevant*/
471 tcpopt=(u_char*)(new->data + tcph->doff*4);
478 new->length=tcph->doff*4;
482 int handle_dataack(struct packet* new, const struct const_packet* old, struct hcon* h1, struct hcon* h2)
485 struct dccp_hdr *dccph;
486 struct dccp_hdr_ext *dccphex;
487 struct dccp_hdr_ack_bits *dccphack;
492 const u_char* dccpopt;
495 if(new->length < sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext) + sizeof(struct dccp_hdr_ack_bits)){
499 /*cast header pointers*/
500 tcph=(struct tcphdr*)new->data;
501 dccph=(struct dccp_hdr*)old->data;
502 dccphex=(struct dccp_hdr_ext*)(old->data+sizeof(struct dccp_hdr));
503 dccphack=(struct dccp_hdr_ack_bits*)(old->data+ sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext));
505 /*determine data length*/
506 datalength=old->length - dccph->dccph_doff*4;
507 pd=old->data + dccph->dccph_doff*4;
509 /*Process DCCP Options*/
510 dccpopt=old->data + sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext) + sizeof(struct dccp_hdr_ack_bits);
511 optlen=dccph->dccph_doff*4 - sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext) - sizeof(struct dccp_hdr_ack_bits);
512 if(!parse_options(dccpopt,optlen,h1,h2)){
518 tcph->ack_seq=htonl(convert_ack(h2,ntohl(dccphack->dccph_ack_nr_low),h1));
520 tcph->ack_seq=htonl(convert_ack(h2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph),h1));
522 h1->high_ack=ntohl(tcph->ack_seq);
523 tcph->seq=htonl(add_new_seq(h1, ntohl(dccphex->dccph_seq_low),datalength, dccph->dccph_type));
525 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(h2, ntohl(dccphack->dccph_ack_nr_low)));
528 if(sack!=2 || interp_ack_vect((u_char*)dccph)){
529 ack_vect2sack(h2, tcph, (u_char*)tcph + tcph->doff*4, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low),h1);
538 npd=new->data + tcph->doff*4;
539 memcpy(npd, pd, datalength);
542 new->length=tcph->doff*4 + datalength;
546 int handle_ack(struct packet* new, const struct const_packet* old, struct hcon* h1, struct hcon* h2)
549 struct dccp_hdr *dccph;
550 struct dccp_hdr_ext *dccphex;
551 struct dccp_hdr_ack_bits *dccphack;
553 const u_char* dccpopt;
556 if(new->length < sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext) + sizeof(struct dccp_hdr_ack_bits)){
560 /*cast header pointers*/
561 tcph=(struct tcphdr*)new->data;
562 dccph=(struct dccp_hdr*)old->data;
563 dccphex=(struct dccp_hdr_ext*)(old->data+sizeof(struct dccp_hdr));
564 dccphack=(struct dccp_hdr_ack_bits*)(old->data+ sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext));
566 /*Process DCCP Options*/
567 dccpopt=old->data + sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext) + sizeof(struct dccp_hdr_ack_bits);
568 optlen=dccph->dccph_doff*4 - sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext) - sizeof(struct dccp_hdr_ack_bits);
569 if(!parse_options(dccpopt,optlen,h1,h2)){
575 tcph->ack_seq=htonl(convert_ack(h2,ntohl(dccphack->dccph_ack_nr_low),h1));
577 tcph->ack_seq=htonl(convert_ack(h2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph),h1));
579 h1->high_ack=ntohl(tcph->ack_seq);
580 tcph->seq=htonl(add_new_seq(h1, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
582 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*1400);
583 if(-interp_ack_vect((u_char*)dccph)*1400 > 65535){
584 dbgprintf(0,"Note: TCP Window Overflow @ %d.%d\n", (int)old->h->ts.tv_sec, (int)old->h->ts.tv_usec);
588 if(sack!=2 || interp_ack_vect((u_char*)dccph)){
589 ack_vect2sack(h2, tcph, (u_char*)tcph + tcph->doff*4, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low),h1);
599 new->length=tcph->doff*4 + 1;
603 int handle_closereq(struct packet* new, const struct const_packet* old, struct hcon* h1, struct hcon* h2)
606 struct dccp_hdr *dccph;
607 struct dccp_hdr_ext *dccphex;
608 struct dccp_hdr_ack_bits *dccphack;
610 const u_char* dccpopt;
613 if(new->length < sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext) + sizeof(struct dccp_hdr_ack_bits)){
617 /*cast header pointers*/
618 tcph=(struct tcphdr*)new->data;
619 dccph=(struct dccp_hdr*)old->data;
620 dccphex=(struct dccp_hdr_ext*)(old->data+sizeof(struct dccp_hdr));
621 dccphack=(struct dccp_hdr_ack_bits*)(old->data+ sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext));
623 /*Process DCCP Options*/
624 dccpopt=old->data + sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext) + sizeof(struct dccp_hdr_ack_bits);
625 optlen=dccph->dccph_doff*4 - sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext) - sizeof(struct dccp_hdr_ack_bits);
626 if(!parse_options(dccpopt,optlen,h1,h2)){
632 tcph->ack_seq=htonl(convert_ack(h2,ntohl(dccphack->dccph_ack_nr_low),h1));
634 tcph->ack_seq=htonl(convert_ack(h2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph),h1));
636 h1->high_ack=ntohl(tcph->ack_seq);
637 tcph->seq=htonl(add_new_seq(h1, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
639 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(h2, ntohl(dccphack->dccph_ack_nr_low)));
642 if(sack!=2 || interp_ack_vect((u_char*)dccph)){
643 ack_vect2sack(h2, tcph, (u_char*)tcph + tcph->doff*4, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low),h1);
653 new->length=tcph->doff*4;
657 int handle_close(struct packet* new, const struct const_packet* old, struct hcon* h1, struct hcon* h2)
660 struct dccp_hdr *dccph;
661 struct dccp_hdr_ext *dccphex;
662 struct dccp_hdr_ack_bits *dccphack;
664 const u_char* dccpopt;
667 if(new->length < sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext) + sizeof(struct dccp_hdr_ack_bits)){
671 /*cast header pointers*/
672 tcph=(struct tcphdr*)new->data;
673 dccph=(struct dccp_hdr*)old->data;
674 dccphex=(struct dccp_hdr_ext*)(old->data+sizeof(struct dccp_hdr));
675 dccphack=(struct dccp_hdr_ack_bits*)(old->data+ sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext));
677 /*Process DCCP Options*/
678 dccpopt=old->data + sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext) + sizeof(struct dccp_hdr_ack_bits);
679 optlen=dccph->dccph_doff*4 - sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext) - sizeof(struct dccp_hdr_ack_bits);
680 if(!parse_options(dccpopt,optlen,h1,h2)){
685 update_state(h1,CLOSE);
687 tcph->ack_seq=htonl(convert_ack(h2,ntohl(dccphack->dccph_ack_nr_low),h1));
689 tcph->ack_seq=htonl(convert_ack(h2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph),h1));
691 h1->high_ack=ntohl(tcph->ack_seq);
692 tcph->seq=htonl(add_new_seq(h1, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
694 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(h2, ntohl(dccphack->dccph_ack_nr_low)));
697 if(sack!=2 || interp_ack_vect((u_char*)dccph)){
698 ack_vect2sack(h2, tcph, (u_char*)tcph + tcph->doff*4, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low),h1);
708 new->length=tcph->doff*4;
712 int handle_reset(struct packet* new, const struct const_packet* old, struct hcon* h1, struct hcon* h2)
715 struct dccp_hdr *dccph;
716 struct dccp_hdr_ext *dccphex;
717 struct dccp_hdr_ack_bits *dccphack;
719 const u_char* dccpopt;
722 if(new->length < sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext) + sizeof(struct dccp_hdr_ack_bits)){
726 /*cast header pointers*/
727 tcph=(struct tcphdr*)new->data;
728 dccph=(struct dccp_hdr*)old->data;
729 dccphex=(struct dccp_hdr_ext*)(old->data+sizeof(struct dccp_hdr));
730 dccphack=(struct dccp_hdr_ack_bits*)(old->data+ sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext));
732 /*Process DCCP Options*/
733 dccpopt=old->data + sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext) + sizeof(struct dccp_hdr_ack_bits);
734 optlen=dccph->dccph_doff*4 - sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext) - sizeof(struct dccp_hdr_ack_bits);
735 if(!parse_options(dccpopt,optlen,h1,h2)){
740 if(h2->state==CLOSE){
741 update_state(h1,CLOSE);
744 tcph->ack_seq=htonl(convert_ack(h2,ntohl(dccphack->dccph_ack_nr_low),h1));
746 tcph->ack_seq=htonl(convert_ack(h2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph),h1));
748 h1->high_ack=ntohl(tcph->ack_seq);
749 tcph->seq=htonl(add_new_seq(h1, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type));
751 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(h2, ntohl(dccphack->dccph_ack_nr_low)));
754 if(sack!=2 || interp_ack_vect((u_char*)dccph)){
755 ack_vect2sack(h2, tcph, (u_char*)tcph + tcph->doff*4, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low),h1);
765 new->length=tcph->doff*4;
769 int handle_sync(struct packet* new, const struct const_packet* old, struct hcon* h1, struct hcon* h2)
772 struct dccp_hdr *dccph;
773 struct dccp_hdr_ext *dccphex;
774 struct dccp_hdr_ack_bits *dccphack;
776 const u_char* dccpopt;
779 if(new->length < sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext) + sizeof(struct dccp_hdr_ack_bits)){
783 /*cast header pointers*/
784 tcph=(struct tcphdr*)new->data;
785 dccph=(struct dccp_hdr*)old->data;
786 dccphex=(struct dccp_hdr_ext*)(old->data+sizeof(struct dccp_hdr));
787 dccphack=(struct dccp_hdr_ack_bits*)(old->data+ sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext));
789 /*Process DCCP Options*/
790 dccpopt=old->data + sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext) + sizeof(struct dccp_hdr_ack_bits);
791 optlen=dccph->dccph_doff*4 - sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext) - sizeof(struct dccp_hdr_ack_bits);
792 if(!parse_options(dccpopt,optlen,h1,h2)){
798 tcph->ack_seq=htonl(convert_ack(h2,ntohl(dccphack->dccph_ack_nr_low),h1));
800 tcph->ack_seq=htonl(convert_ack(h2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph),h1));
802 h1->high_ack=ntohl(tcph->ack_seq);
803 tcph->seq=htonl(add_new_seq(h1, ntohl(dccphex->dccph_seq_low),0,dccph->dccph_type));
805 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(h2, ntohl(dccphack->dccph_ack_nr_low)));
807 tcph->window=htons(0);
810 if(sack!=2 || interp_ack_vect((u_char*)dccph)){
811 ack_vect2sack(h2, tcph, (u_char*)tcph + tcph->doff*4, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low),h1);
821 new->length=tcph->doff*4;
825 int handle_syncack(struct packet* new, const struct const_packet* old, struct hcon* h1, struct hcon* h2)
828 struct dccp_hdr *dccph;
829 struct dccp_hdr_ext *dccphex;
830 struct dccp_hdr_ack_bits *dccphack;
832 const u_char* dccpopt;
835 if(new->length < sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext) + sizeof(struct dccp_hdr_ack_bits)){
839 /*cast header pointers*/
840 tcph=(struct tcphdr*)new->data;
841 dccph=(struct dccp_hdr*)old->data;
842 dccphex=(struct dccp_hdr_ext*)(old->data+sizeof(struct dccp_hdr));
843 dccphack=(struct dccp_hdr_ack_bits*)(old->data+ sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext));
845 /*Process DCCP Options*/
846 dccpopt=old->data + sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext) + sizeof(struct dccp_hdr_ack_bits);
847 optlen=dccph->dccph_doff*4 - sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext) - sizeof(struct dccp_hdr_ack_bits);
848 if(!parse_options(dccpopt,optlen,h1,h2)){
854 tcph->ack_seq=htonl(convert_ack(h2,ntohl(dccphack->dccph_ack_nr_low),h1));
856 tcph->ack_seq=htonl(convert_ack(h2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph),h1));
858 h1->high_ack=ntohl(tcph->ack_seq);
859 tcph->seq=htonl(add_new_seq(h1, ntohl(dccphex->dccph_seq_low),0,dccph->dccph_type));
861 tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(h2, ntohl(dccphack->dccph_ack_nr_low)));
863 tcph->window=htons(0);
866 if(sack!=2 || interp_ack_vect((u_char*)dccph)){
867 ack_vect2sack(h2, tcph, (u_char*)tcph + tcph->doff*4, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low),h1);
877 new->length=tcph->doff*4;
881 int handle_data(struct packet* new, const struct const_packet* old, struct hcon* h1, struct hcon* h2)
884 struct dccp_hdr *dccph;
885 struct dccp_hdr_ext *dccphex;
890 const u_char* dccpopt;
893 if(new->length < sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext)){
897 /*cast header pointers*/
898 tcph=(struct tcphdr*)new->data;
899 dccph=(struct dccp_hdr*)old->data;
900 dccphex=(struct dccp_hdr_ext*)(old->data+sizeof(struct dccp_hdr));
902 /*determine data length*/
903 datalength=old->length - dccph->dccph_doff*4;
904 pd=old->data + dccph->dccph_doff*4;
906 /*Process DCCP Options*/
907 dccpopt=old->data + sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext);
908 optlen=dccph->dccph_doff*4 - sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext);
909 if(!parse_options(dccpopt,optlen,h1,h2)){
914 tcph->ack_seq=htonl(h1->high_ack);
915 tcph->seq=htonl(add_new_seq(h1, ntohl(dccphex->dccph_seq_low),datalength, dccph->dccph_type));
922 npd=new->data + tcph->doff*4;
923 memcpy(npd, pd, datalength);
926 new->length=tcph->doff*4 + datalength;
930 int parse_options(const u_char* opt_start, int len, struct hcon* A, struct hcon* B)
936 /*setup pointer to DCCP options and determine how long the options are*/
942 /*One byte options (no length)*/
949 /*Check option length*/
952 dbgprintf(0, "Warning: Option would extend into packet data\n");
956 dbgprintf(0, "Warning: Bad Option!\n");
960 /*Ack Vector Option*/
961 if(*opt==38 || *opt==39){
962 if(B->type==UNKNOWN){
964 dbgprintf(1,"Half-connection from port %i to %i probably using CCID 2\n",
965 ntohs(B->port),ntohs(A->port));
971 if(B->type==UNKNOWN){
973 dbgprintf(1,"Half-connection from port %i to %i probably using CCID 3\n",
974 ntohs(B->port),ntohs(A->port));
978 /*Feature negotation*/
981 if(!process_feature(opt+2,length-2,FALSE,TRUE,A,B)){
987 if(!process_feature(opt+2,length-2,TRUE,TRUE,A,B)){
993 if(!process_feature(opt+2,length-2,FALSE,FALSE,A,B)){
999 if(!process_feature(opt+2,length-2,TRUE,FALSE,A,B)){
1011 int process_feature(const u_char* feat, int len, int confirm, int L, struct hcon* A, struct hcon* B)
1035 dbgprintf(1,"Half-connection from port %i to %i using CCID %i\n",
1036 ntohs(B->port),ntohs(A->port), *val);
1039 dbgprintf(1,"Half-connection from port %i to %i using CCID %i\n",
1040 ntohs(A->port),ntohs(B->port), *val);
1045 /*Short sequence nums*/
1046 if(confirm==TRUE && *val==1){
1049 dbgprintf(0,"Error: DCCP is trying to turn on short sequence numbers\n"
1050 " for the connection between %i and %i. We do not support this.\n"
1051 " This connection will be ignored.",ntohs(A->port),ntohs(B->port));
1059 /*Ack Vector to SACK Option*/
1060 void ack_vect2sack(struct hcon *hcn, struct tcphdr *tcph, u_char* tcpopts, u_char* dccphdr,
1061 __be32 dccpack, struct hcon* o_hcn)
1063 int hdrlen=((struct dccp_hdr*)dccphdr)->dccph_doff*4;
1080 /*setup pointer to DCCP options and determine how long the options are*/
1081 optlen=hdrlen-sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext) - sizeof(struct dccp_hdr_ack_bits);
1082 opt=dccphdr + sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext) + sizeof(struct dccp_hdr_ack_bits);
1088 /*setup tcp pointers*/
1094 pL=(u_int32_t*)temp;
1097 /*setup tcp control variables*/
1106 /*One byte options (no length)*/
1115 dbgprintf(0, "Warning: Option would extend into packet data\n");
1119 /*Ack Vector Option*/
1120 if(*opt==38 || *opt==39){
1123 /*loop through Vector*/
1125 /*ack vector works BACKWARDS through time*/
1127 if((*cur & 0xC0)==0xC0 || (*cur & 0xC0)==0x40){ //lost packet
1128 if(cont){ /*end a SACK run, if one is started*/
1129 bR=convert_ack(hcn, bp,o_hcn);
1139 bp= bp - (*cur & 0x3F)- 1;
1142 if((*cur & 0xC0)==0x00){ //received packet
1143 if(!cont){ /*if no SACK run and we can start another one, do so*/
1145 bL=convert_ack(hcn, bp, o_hcn);
1151 bp = bp -(*cur & 0x3F)- 1;
1162 /*if we are in the middle of a SACK run, close it*/
1164 bR=convert_ack(hcn, bp,o_hcn);
1172 /*adjust length if the option is actually added*/
1181 dbgprintf(0, "dccp2tcp version %.1f\n",DCCP2TCP_VERSION);
1182 dbgprintf(0, "Copyright (C) %i Samuel Jero <sj323707@ohio.edu>\n",COPYRIGHT_YEAR);
1183 dbgprintf(0, "This program comes with ABSOLUTELY NO WARRANTY.\n");
1184 dbgprintf(0, "This is free software, and you are welcome to\n");
1185 dbgprintf(0, "redistribute it under certain conditions.\n");
1189 /*Usage information for program*/
1192 dbgprintf(0,"Usage: dccp2tcp [-d] [-h] [-V] [-y] [-g] [-s] dccp_file tcp_file\n");
1193 dbgprintf(0, " -d Debug. May be repeated for aditional verbosity.\n");
1194 dbgprintf(0, " -V Version information\n");
1195 dbgprintf(0, " -h Help\n");
1196 dbgprintf(0, " -y Yellow line is highest ACK\n");
1197 dbgprintf(0, " -g Green line is highest ACK\n");
1198 dbgprintf(0, " -s convert ACK Vectors to SACKS\n");
1203 void dbgprintf(int level, const char *fmt, ...)
1207 va_start(args, fmt);
1208 vfprintf(stderr, fmt, args);