X-Git-Url: http://sjero.net/git/?a=blobdiff_plain;f=dccp2tcp.c;h=651d98bcce0965012b317e0f7e631fb516d4d6f2;hb=55e57e4b5e5b61dccb62b4ed4b23240c0283feb7;hp=193df2c46d678e21dfbff1dc1124a98b87fbd9a9;hpb=a9d2edbab427f8e7e412db7a1bf9ecc26de679c3;p=dccp2tcp diff --git a/dccp2tcp.c b/dccp2tcp.c index 193df2c..651d98b 100644 --- a/dccp2tcp.c +++ b/dccp2tcp.c @@ -1,19 +1,18 @@ /****************************************************************************** Author: Samuel Jero -Date: 4/2011 +Date: 7/2011 Description: Program to convert a DCCP flow to a TCP flow for DCCP analysis via tcptrace. Notes: - 1)Supports only a single DCCP contection per capture - 2)Source Port!=Destination Port - 3)DCCP MUST use 48 bit sequence numbers - 4)Checksums are not computed (they are zeroed) - 5)Only implements those packet types normally used in a session - 6)DCCP Ack packets show up as TCP packets containing one byte - 7)Very little error checking of packet headers + 1)CCID2 ONLY + 2)DCCP MUST use 48 bit sequence numbers + 3)Checksums are not computed (they are zeroed) + 4)Only implements those packet types normally used in a session + 5)DCCP Ack packets show up as TCP packets containing one byte + 6)Very little error checking of packet headers ******************************************************************************/ #include "dccp2tcp.h" @@ -23,23 +22,22 @@ int yellow=0; /*tcptrace yellow line as currently acked packet*/ int green=0; /*tcptrace green line as currently acked packet*/ int sack=0; /*add TCP SACKS*/ -pcap_t* in; /*libpcap input file discriptor*/ -pcap_dumper_t *out; /*libpcap output file discriptor*/ -struct seq_num *s1; /*sequence number structure for side one of connection*/ -struct seq_num *s2; /*sequence number structure for side two of connection*/ +pcap_t* in; /*libpcap input file discriptor*/ +pcap_dumper_t *out; /*libpcap output file discriptor*/ +struct connection *chead; /*connection list*/ void PcapSavePacket(struct pcap_pkthdr *h, u_char *data); void process_packets(); void handle_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes); -void convert_packet(struct pcap_pkthdr *h, u_char **ndata, int *nlength, const u_char **odata, int *length); +int convert_packet(struct packet *new, const struct const_packet* old); unsigned int interp_ack_vect(u_char* hdr); -u_int32_t initialize_seq(struct seq_num **seq, __be16 source, __be32 initial); -u_int32_t add_new_seq(struct seq_num *seq, __be32 num, int size, enum dccp_pkt_type type); -u_int32_t convert_ack(struct seq_num *seq, __be32 num); -int acked_packet_size(struct seq_num *seq, __be32 num); -void ack_vect2sack(struct seq_num *seq, struct tcphdr *tcph, u_char* tcpopts, u_char* dccphdr, __be32 dccpack); +u_int32_t initialize_seq(struct host *seq, __be16 source, __be32 initial); +u_int32_t add_new_seq(struct host *seq, __be32 num, int size, enum dccp_pkt_type type); +u_int32_t convert_ack(struct host *seq, __be32 num); +int acked_packet_size(struct host *seq, __be32 num); +void ack_vect2sack(struct host *seq, struct tcphdr *tcph, u_char* tcpopts, u_char* dccphdr, __be32 dccpack); /*Parse commandline options and open files*/ @@ -80,7 +78,7 @@ int main(int argc, char *argv[]) green=1; } if(argv[i][1]=='s' && strlen(argv[i])==2){ /*sack option*/ - sack=1; + sack++; } } } @@ -126,6 +124,7 @@ int main(int argc, char *argv[]) } /*process packets*/ + chead=NULL; u_char *user=(u_char*)out; pcap_loop(in, -1, handle_packet, user); @@ -140,32 +139,37 @@ return 0; void handle_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes) { u_char *ndata; - u_char *nptr; - int length; - int nlength; struct pcap_pkthdr nh; + int link_type; + struct packet new; + struct const_packet old; + + /*Determine the link type for this packet*/ + link_type=pcap_datalink(in); /*create new libpcap header*/ memcpy(&nh, h, sizeof(struct pcap_pkthdr)); - length=h->caplen; - nlength=MAX_PACKET; + + /*Setup packet structs*/ + old.h=h; + old.length=h->caplen; + old.data=bytes; + new.h=&nh; + new.length=MAX_PACKET; /*create buffer for new packet*/ - nptr=ndata=malloc(MAX_PACKET); + new.data=ndata=malloc(MAX_PACKET); if(ndata==NULL){ dbgprintf(0,"Error: Couldn't allocate Memory\n"); exit(1); } /*make sure the packet is all zero*/ - memset(nptr, 0, MAX_PACKET); + memset(new.data, 0, MAX_PACKET); /*do all the fancy conversions*/ - if(eth_ip_encap_pre(&nh, &nptr, &nlength, &bytes, &length)<0){ - return; - } - convert_packet(&nh, &nptr, &nlength, &bytes, &length); - if(eth_ip_encap_post(&nh, &ndata, &nlength)<0){ + if(!do_encap(link_type, &new, &old)){ + free(ndata); return; } @@ -178,34 +182,54 @@ return; /*do all the dccp to tcp conversions*/ -void convert_packet(struct pcap_pkthdr *h, u_char **ndata, int *nlength, const u_char **odata, int *length) +int convert_packet(struct packet *new, const struct const_packet* old) { - u_char* ncur=*ndata; - const u_char* ocur=*odata; - struct tcphdr *tcph; - struct dccp_hdr *dccph; - struct dccp_hdr_ext *dccphex; - struct dccp_hdr_ack_bits *dccphack; - int datalength; - int len=0; - const u_char* pd; - u_char* npd; - u_char* tcpopt; + struct tcphdr *tcph; + struct dccp_hdr *dccph; + struct dccp_hdr_ext *dccphex; + struct dccp_hdr_ack_bits *dccphack; + struct host *h1=NULL; + struct host *h2=NULL; + int datalength; + int len=0; + const u_char* pd; + u_char* npd; + u_char* tcpopt; + + /*Safety checks*/ + if(!new || !old || !new->data || !old->data || !new->h || !old->h){ + dbgprintf(0,"Error: Convert Packet Function given bad data!\n"); + exit(1); + return 0; + } + if(old->length < sizeof(struct dccp_hdr) || new->length < sizeof(struct dccp_hdr)){ + dbgprintf(0, "Error: Convert Packet Function given packet of wrong size!\n"); + return 0; + } /*cast header pointers*/ - tcph=(struct tcphdr*)ncur; - tcpopt=ncur+ sizeof(struct tcphdr); - dccph=(struct dccp_hdr*)ocur; - dccphex=(struct dccp_hdr_ext*)(ocur+sizeof(struct dccp_hdr)); - dccphack=(struct dccp_hdr_ack_bits*)(ocur+ sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext)); + tcph=(struct tcphdr*)new->data; + dccph=(struct dccp_hdr*)old->data; + dccphex=(struct dccp_hdr_ext*)(old->data+sizeof(struct dccp_hdr)); + dccphack=(struct dccp_hdr_ack_bits*)(old->data+ sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext)); dbgprintf(2,"Sequence Number: %llu\n", (unsigned long long)(((unsigned long)ntohs(dccph->dccph_seq)<<32) + ntohl(dccphex->dccph_seq_low))); + /*Get Hosts*/ + if(get_host(new->src_id, new->dest_id, dccph->dccph_sport, dccph->dccph_dport, &h1, &h2)){ + dbgprintf(0,"Error: Can't Get Hosts!\n"); + return 0; + } + if(h1==NULL || h2==NULL){ + dbgprintf(0, "Error: Can't Get Hosts!\n"); + return 0; + } + /*determine data length*/ - datalength=*length - dccph->dccph_doff*4; - pd=*odata + dccph->dccph_doff*4; + datalength=old->length - dccph->dccph_doff*4; + pd=old->data + dccph->dccph_doff*4; - /*set tcp standard features*/ + /*set TCP standard features*/ tcph->source=dccph->dccph_sport; tcph->dest=dccph->dccph_dport; tcph->doff=5; @@ -217,20 +241,15 @@ void convert_packet(struct pcap_pkthdr *h, u_char **ndata, int *nlength, const u tcph->window=htons(30000); } - /*Only accept the first connection*/ - if(s1 && s2 && dccph->dccph_sport!=s1->addr && dccph->dccph_dport!=s1->addr){ - return; - } - /*make changes by packet type*/ if(dccph->dccph_type==DCCP_PKT_REQUEST){//DCCP REQUEST -->TCP SYN dbgprintf(2,"Packet Type: Request\n"); - if(!s1){ + if(h1->state==INIT){ if(yellow){ tcph->window=htons(0); } tcph->ack_seq=htonl(0); - tcph->seq=htonl(initialize_seq(&s1, dccph->dccph_sport, ntohl(dccphex->dccph_seq_low))); + tcph->seq=htonl(initialize_seq(h1, dccph->dccph_sport, ntohl(dccphex->dccph_seq_low))); tcph->syn=1; tcph->ack=0; tcph->fin=0; @@ -238,6 +257,7 @@ void convert_packet(struct pcap_pkthdr *h, u_char **ndata, int *nlength, const u /* add Sack-permitted option, if relevant*/ if(sack){ + tcpopt=(u_char*)(new->data + tcph->doff*4); *tcpopt=4; tcpopt++; *tcpopt=2; @@ -251,12 +271,12 @@ void convert_packet(struct pcap_pkthdr *h, u_char **ndata, int *nlength, const u if(dccph->dccph_type==DCCP_PKT_RESPONSE){//DCCP RESPONSE-->TCP SYN,ACK dbgprintf(2,"Packet Type: Response\n"); - if(s1 && !s2){ - tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low))); + if(h2->state==OPEN && h1->state==INIT){ + tcph->ack_seq=htonl(convert_ack(h2,ntohl(dccphack->dccph_ack_nr_low))); if(yellow){ tcph->window=htons(0); } - tcph->seq=htonl(initialize_seq(&s2, dccph->dccph_sport, ntohl(dccphex->dccph_seq_low))); + tcph->seq=htonl(initialize_seq(h1, dccph->dccph_sport, ntohl(dccphex->dccph_seq_low))); tcph->syn=1; tcph->ack=1; tcph->fin=0; @@ -264,6 +284,7 @@ void convert_packet(struct pcap_pkthdr *h, u_char **ndata, int *nlength, const u /* add Sack-permitted option, if relevant*/ if(sack){ + tcpopt=(u_char*)(new->data + tcph->doff*4); *tcpopt=4; *(tcpopt+1)=2; tcph->doff++; @@ -281,31 +302,18 @@ void convert_packet(struct pcap_pkthdr *h, u_char **ndata, int *nlength, const u if(dccph->dccph_type==DCCP_PKT_DATAACK){//DCCP DATAACK-->TCP ACK with data dbgprintf(2,"Packet Type: DataAck\n"); - if(s1 && s2 && dccph->dccph_sport==s1->addr){ //determine which side of connection is sending this packet - if(green){ - tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low))); - }else{ - tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph))); - } - tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),datalength, dccph->dccph_type)); - if(yellow){ - tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s2, ntohl(dccphack->dccph_ack_nr_low))); - } - if(sack){ - ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) ); - } - }else if(s1 && s2 && dccph->dccph_sport==s2->addr){ - if(green){ - tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low))); - }else{ - tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph))); - } - tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),datalength,dccph->dccph_type)); - if(yellow){ - tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s1, ntohl(dccphack->dccph_ack_nr_low))); - } - if(sack){ - ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) ); + if(green){ + tcph->ack_seq=htonl(convert_ack(h2,ntohl(dccphack->dccph_ack_nr_low))); + }else{ + tcph->ack_seq=htonl(convert_ack(h2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph))); + } + tcph->seq=htonl(add_new_seq(h1, ntohl(dccphex->dccph_seq_low),datalength, dccph->dccph_type)); + if(yellow){ + tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(h2, ntohl(dccphack->dccph_ack_nr_low))); + } + if(sack){ + if(sack!=2 || interp_ack_vect((u_char*)dccph)){ + ack_vect2sack(h2, tcph, (u_char*)tcph + tcph->doff*4, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) ); } } @@ -315,7 +323,7 @@ void convert_packet(struct pcap_pkthdr *h, u_char **ndata, int *nlength, const u tcph->rst=0; /*copy data*/ - npd=*ndata + tcph->doff*4; + npd=new->data + tcph->doff*4; memcpy(npd, pd, datalength); /*calculate length*/ @@ -324,37 +332,21 @@ void convert_packet(struct pcap_pkthdr *h, u_char **ndata, int *nlength, const u if(dccph->dccph_type==DCCP_PKT_ACK){ //DCCP ACK -->TCP ACK with no data dbgprintf(2,"Packet Type: Ack\n"); - if(s1 && s2 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet - if(green){ - tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low))); - }else{ - tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph))); - } - tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type)); - if(yellow){ - tcph->window=htons(-interp_ack_vect((u_char*)dccph)*1400); - if(-interp_ack_vect((u_char*)dccph)*1400 > 65535){ - printf("Note: TCP Window Overflow @ %d.%d\n", (int)h->ts.tv_sec, (int)h->ts.tv_usec); - } - } - if(sack){ - ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) ); - } - }else if(s1 && s2 && dccph->dccph_sport==s2->addr){ - if(green){ - tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low))); - }else{ - tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph))); - } - tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type)); - if(yellow){ - tcph->window=htons(-interp_ack_vect((u_char*)dccph)*1400); - if(-interp_ack_vect((u_char*)dccph)*1400 > 65535){ - printf("Note: TCP Window Overflow @ %d.%d\n", (int)h->ts.tv_sec, (int)h->ts.tv_usec); - } + if(green){ + tcph->ack_seq=htonl(convert_ack(h2,ntohl(dccphack->dccph_ack_nr_low))); + }else{ + tcph->ack_seq=htonl(convert_ack(h2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph))); + } + tcph->seq=htonl(add_new_seq(h1, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type)); + if(yellow){ + tcph->window=htons(-interp_ack_vect((u_char*)dccph)*1400); + if(-interp_ack_vect((u_char*)dccph)*1400 > 65535){ + printf("Note: TCP Window Overflow @ %d.%d\n", (int)old->h->ts.tv_sec, (int)old->h->ts.tv_usec); } - if(sack){ - ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) ); + } + if(sack){ + if(sack!=2 || interp_ack_vect((u_char*)dccph)){ + ack_vect2sack(h2, tcph, (u_char*)tcph + tcph->doff*4, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) ); } } @@ -374,31 +366,19 @@ void convert_packet(struct pcap_pkthdr *h, u_char **ndata, int *nlength, const u if(dccph->dccph_type==DCCP_PKT_CLOSE){//DCCP CLOSE-->TCP FIN,ACK dbgprintf(2,"Packet Type: Close\n"); - if(s1 && s2 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet - if(green){ - tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low))); - }else{ - tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph))); - } - tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type)); - if(yellow){ - tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s2, ntohl(dccphack->dccph_ack_nr_low))); - } - if(sack){ - ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) ); - } - }else if(s1 && s2 && dccph->dccph_sport==s2->addr){ - if(green){ - tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low))); - }else{ - tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph))); - } - tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type)); - if(yellow){ - tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s1, ntohl(dccphack->dccph_ack_nr_low))); - } - if(sack){ - ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) ); + update_state(h1,CLOSE); + if(green){ + tcph->ack_seq=htonl(convert_ack(h2,ntohl(dccphack->dccph_ack_nr_low))); + }else{ + tcph->ack_seq=htonl(convert_ack(h2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph))); + } + tcph->seq=htonl(add_new_seq(h1, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type)); + if(yellow){ + tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(h2, ntohl(dccphack->dccph_ack_nr_low))); + } + if(sack){ + if(sack!=2 || interp_ack_vect((u_char*)dccph)){ + ack_vect2sack(h2, tcph, (u_char*)tcph + tcph->doff*4, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) ); } } @@ -412,32 +392,22 @@ void convert_packet(struct pcap_pkthdr *h, u_char **ndata, int *nlength, const u } if(dccph->dccph_type==DCCP_PKT_RESET){//DCCP RESET-->TCP FIN,ACK (only seen at end of connection as CLOSE ACK) + if(h2->state==CLOSE){ + update_state(h1,CLOSE); + } dbgprintf(2,"Packet Type: Reset\n"); - if(s1 && s2 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet - if(green){ - tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low))); - }else{ - tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph))); - } - tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type)); - if(yellow){ - tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s2, ntohl(dccphack->dccph_ack_nr_low))); - } - if(sack){ - ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) ); - } - }else if(s1 && s2 && dccph->dccph_sport==s2->addr){ - if(green){ - tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low))); - }else{ - tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph))); - } - tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type)); - if(yellow){ - tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s1, ntohl(dccphack->dccph_ack_nr_low))); - } - if(sack){ - ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) ); + if(green){ + tcph->ack_seq=htonl(convert_ack(h2,ntohl(dccphack->dccph_ack_nr_low))); + }else{ + tcph->ack_seq=htonl(convert_ack(h2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph))); + } + tcph->seq=htonl(add_new_seq(h1, ntohl(dccphex->dccph_seq_low),1,dccph->dccph_type)); + if(yellow){ + tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(h2, ntohl(dccphack->dccph_ack_nr_low))); + } + if(sack){ + if(sack!=2 || interp_ack_vect((u_char*)dccph)){ + ack_vect2sack(h2, tcph, (u_char*)tcph + tcph->doff*4, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) ); } } @@ -452,35 +422,20 @@ void convert_packet(struct pcap_pkthdr *h, u_char **ndata, int *nlength, const u if(dccph->dccph_type==DCCP_PKT_SYNC){//DCCP SYNC dbgprintf(2,"Packet Type: Sync\n"); - if(s1 && s2 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet - if(green){ - tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low))); - }else{ - tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph))); - } - tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),0,dccph->dccph_type)); - if(yellow){ - tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s2, ntohl(dccphack->dccph_ack_nr_low))); - }else{ - tcph->window=htons(0); - } - if(sack){ - ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) ); - } - }else if(s1 && s2 && dccph->dccph_sport==s2->addr){ - if(green){ - tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low))); - }else{ - tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph))); - } - tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),0,dccph->dccph_type)); - if(yellow){ - tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s1, ntohl(dccphack->dccph_ack_nr_low))); - }else{ - tcph->window=htons(0); - } - if(sack){ - ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) ); + if(green){ + tcph->ack_seq=htonl(convert_ack(h2,ntohl(dccphack->dccph_ack_nr_low))); + }else{ + tcph->ack_seq=htonl(convert_ack(h2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph))); + } + tcph->seq=htonl(add_new_seq(h1, ntohl(dccphex->dccph_seq_low),0,dccph->dccph_type)); + if(yellow){ + tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(h2, ntohl(dccphack->dccph_ack_nr_low))); + }else{ + tcph->window=htons(0); + } + if(sack){ + if(sack!=2 || interp_ack_vect((u_char*)dccph)){ + ack_vect2sack(h2, tcph, (u_char*)tcph + tcph->doff*4, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) ); } } @@ -495,35 +450,20 @@ void convert_packet(struct pcap_pkthdr *h, u_char **ndata, int *nlength, const u if(dccph->dccph_type==DCCP_PKT_SYNCACK){//DCCP SYNACK dbgprintf(2,"Packet Type: SyncAck\n"); - if(s1 && s2 && dccph->dccph_sport==s1->addr){//determine which side of connection is sending this packet - if(green){ - tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low))); - }else{ - tcph->ack_seq=htonl(convert_ack(s2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph))); - } - tcph->seq=htonl(add_new_seq(s1, ntohl(dccphex->dccph_seq_low),0,dccph->dccph_type)); - if(yellow){ - tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s2, ntohl(dccphack->dccph_ack_nr_low))); - }else{ - tcph->window=htons(0); - } - if(sack){ - ack_vect2sack(s2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low)); - } - }else if(s1 && s2 && dccph->dccph_sport==s2->addr){ - if(green){ - tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low))); - }else{ - tcph->ack_seq=htonl(convert_ack(s1,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph))); - } - tcph->seq=htonl(add_new_seq(s2, ntohl(dccphex->dccph_seq_low),0,dccph->dccph_type)); - if(yellow){ - tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(s1, ntohl(dccphack->dccph_ack_nr_low))); - }else{ - tcph->window=htons(0); - } - if(sack){ - ack_vect2sack(s1, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) ); + if(green){ + tcph->ack_seq=htonl(convert_ack(h2,ntohl(dccphack->dccph_ack_nr_low))); + }else{ + tcph->ack_seq=htonl(convert_ack(h2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph))); + } + tcph->seq=htonl(add_new_seq(h1, ntohl(dccphex->dccph_seq_low),0,dccph->dccph_type)); + if(yellow){ + tcph->window=htons(-interp_ack_vect((u_char*)dccph)*acked_packet_size(h2, ntohl(dccphack->dccph_ack_nr_low))); + }else{ + tcph->window=htons(0); + } + if(sack){ + if(sack!=2 || interp_ack_vect((u_char*)dccph)){ + ack_vect2sack(h2, tcph, (u_char*)tcph + tcph->doff*4, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low)); } } @@ -538,15 +478,16 @@ void convert_packet(struct pcap_pkthdr *h, u_char **ndata, int *nlength, const u if(dccph->dccph_type==DCCP_PKT_INVALID){//DCCP INVALID----Never seen in packet capture dbgprintf(0,"Invalid DCCP Packet!!\n"); - exit(1); + return 0; } - *nlength=len; -return; + new->length=len; +return 1; } -/*Parse Ack Vector Options*/ +/*Parse Ack Vector Options + * Returns the Number of packets since last recorded loss*/ unsigned int interp_ack_vect(u_char* hdr) { int hdrlen=((struct dccp_hdr*)hdr)->dccph_doff*4; @@ -593,6 +534,10 @@ unsigned int interp_ack_vect(u_char* hdr) if((*cur & 0xC0)==0x00){ //received packet bp+= (*cur & 0x3F)+1; } + + if(((*cur& 0xC0)!= 0xC0) && ((*cur& 0xC0)!= 0x00) && ((*cur& 0xC0)!= 0x40)){ + dbgprintf(1, "Warning: Invalid Ack Vector!! (Linux will handle poorly!) -- %X\n", *cur); + } tmp--; cur++; } @@ -608,38 +553,31 @@ return additional; /* Setup Sequence Number Structure*/ -u_int32_t initialize_seq(struct seq_num **seq, __be16 source, __be32 initial) +u_int32_t initialize_seq(struct host *seq, __be16 source, __be32 initial) { - /*allocate structure*/ - *seq=(struct seq_num*)malloc(sizeof(struct seq_num)); - if(*seq==NULL){ - dbgprintf(0,"Can't Allocate Memory!\n"); - exit(1); - } - /*set default values*/ - (*seq)->cur=0; - (*seq)->addr=source; - (*seq)->size=TBL_SZ; + seq->cur=0; + seq->size=TBL_SZ; /*allocate table*/ - (*seq)->table=(struct tbl*)malloc(sizeof(struct tbl)*TBL_SZ); - if((*seq)->table==NULL){ + seq->table=(struct tbl*)malloc(sizeof(struct tbl)*TBL_SZ); + if(seq->table==NULL){ dbgprintf(0,"Can't Allocate Memory!\n"); exit(1); } /*add first sequence number*/ - (*seq)->table[0].old=initial; - (*seq)->table[0].new=initial; - (*seq)->table[0].type=DCCP_PKT_REQUEST; - (*seq)->table[0].size=0; + seq->table[0].old=initial; + seq->table[0].new=initial; + seq->table[0].type=DCCP_PKT_REQUEST; + seq->table[0].size=0; + update_state(seq,OPEN); return initial; } /*Convert Sequence Numbers*/ -u_int32_t add_new_seq(struct seq_num *seq, __be32 num, int size, enum dccp_pkt_type type) +u_int32_t add_new_seq(struct host *seq, __be32 num, int size, enum dccp_pkt_type type) { int prev; if(seq==NULL){ @@ -647,6 +585,11 @@ u_int32_t add_new_seq(struct seq_num *seq, __be32 num, int size, enum dccp_pkt_t exit(1); } + if(seq->table==NULL){ + dbgprintf(1, "Warning: Connection uninitialized\n"); + return initialize_seq(seq, 0, num); + } + /*account for missing packets*/ while(seq->table[seq->cur].old +1 < num && seq->table[seq->cur].old +1 > 0){ prev=seq->cur; @@ -682,13 +625,18 @@ return seq->table[seq->cur].new +1; /*Convert Ack Numbers*/ -u_int32_t convert_ack(struct seq_num *seq, __be32 num) +u_int32_t convert_ack(struct host *seq, __be32 num) { if(seq==NULL){ dbgprintf(0,"ERROR NULL POINTER!\n"); exit(1); } + if(seq->table==NULL){ + dbgprintf(1, "Warning: Connection uninitialized\n"); + initialize_seq(seq, 0, num); + } + /*loop through table looking for the DCCP ack number*/ for(int i=0; i < seq->size; i++){ if(seq->table[i].old==num){ @@ -702,13 +650,18 @@ return 0; /* Get size of packet being acked*/ -int acked_packet_size(struct seq_num *seq, __be32 num) +int acked_packet_size(struct host *seq, __be32 num) { if(seq==NULL){ dbgprintf(0,"ERROR NULL POINTER!\n"); exit(1); } + if(seq->table==NULL){ + dbgprintf(1, "Warning: Connection uninitialized\n"); + initialize_seq(seq, 0, num); + } + /*loop through table looking for the DCCP ack number*/ for(int i=0; i < seq->size; i++){ if(seq->table[i].old==num){ @@ -722,7 +675,7 @@ return 0; /*Ack Vector to SACK Option*/ -void ack_vect2sack(struct seq_num *seq, struct tcphdr *tcph, u_char* tcpopts, u_char* dccphdr, __be32 dccpack) +void ack_vect2sack(struct host *seq, struct tcphdr *tcph, u_char* tcpopts, u_char* dccphdr, __be32 dccpack) { int hdrlen=((struct dccp_hdr*)dccphdr)->dccph_doff*4; int optlen; @@ -746,7 +699,7 @@ void ack_vect2sack(struct seq_num *seq, struct tcphdr *tcph, u_char* tcpopts, u_ opt=dccphdr + sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext) + sizeof(struct dccp_hdr_ack_bits); /*setup tcp pointers*/ - num_blocks=2; + num_blocks=4; *tcpopts=5; tlen=tcpopts+1; temp=tlen;