X-Git-Url: http://sjero.net/git/?a=blobdiff_plain;f=dccp2tcp.c;h=dbd90dfc39832683cacbefdefdd7202add5f7f63;hb=55c388bacaff0cff07ddebc423a16c7d728acba3;hp=eb913bf9dc23652d84b97774cda2cd5e61dd7a90;hpb=693b1f41fcb64bcf4872dae265aad082bbe1af1c;p=dccp2tcp diff --git a/dccp2tcp.c b/dccp2tcp.c index eb913bf..dbd90df 100644 --- a/dccp2tcp.c +++ b/dccp2tcp.c @@ -33,7 +33,7 @@ void process_packets(); void handle_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes); 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 host *seq, __be16 source, __be32 initial); +u_int32_t initialize_seq(struct host *seq, __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); @@ -124,12 +124,16 @@ int main(int argc, char *argv[]) } /*process packets*/ + chead=NULL; u_char *user=(u_char*)out; pcap_loop(in, -1, handle_packet, user); /*close files*/ pcap_close(in); pcap_dump_close(out); + + /*Delete all connections*/ + cleanup_connections(); return 0; } @@ -198,16 +202,16 @@ int convert_packet(struct packet *new, const struct const_packet* old) /*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"); + if(old->length < (sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext)) || new->length < sizeof(struct dccp_hdr)){ + dbgprintf(0, "Error: DCCP Packet Too short!\n"); return 0; } /*cast header pointers*/ tcph=(struct tcphdr*)new->data; - tcpopt=new->data + sizeof(struct tcphdr); 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)); @@ -215,15 +219,26 @@ int convert_packet(struct packet *new, const struct const_packet* old) 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)){ + 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 || !h2){ + if(h1==NULL || h2==NULL){ dbgprintf(0, "Error: Can't Get Hosts!\n"); return 0; } + /*Ensure packet is at least as large as DCCP header*/ + if(old->length < dccph->dccph_doff*4){ + dbgprintf(0, "Error: DCCP Header truncated\n"); + return 0; + } + if(dccph->dccph_type!=DCCP_PKT_DATA && + old->length < (sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext) + + sizeof(struct dccp_hdr_ack_bits))){ + dbgprintf(0, "Error: DCCP Packet Too short!\n"); + } + /*determine data length*/ datalength=old->length - dccph->dccph_doff*4; pd=old->data + dccph->dccph_doff*4; @@ -248,7 +263,7 @@ int convert_packet(struct packet *new, const struct const_packet* old) tcph->window=htons(0); } tcph->ack_seq=htonl(0); - tcph->seq=htonl(initialize_seq(h1, dccph->dccph_sport, ntohl(dccphex->dccph_seq_low))); + tcph->seq=htonl(initialize_seq(h1, ntohl(dccphex->dccph_seq_low))); tcph->syn=1; tcph->ack=0; tcph->fin=0; @@ -256,6 +271,7 @@ int convert_packet(struct packet *new, const struct const_packet* old) /* add Sack-permitted option, if relevant*/ if(sack){ + tcpopt=(u_char*)(new->data + tcph->doff*4); *tcpopt=4; tcpopt++; *tcpopt=2; @@ -274,7 +290,7 @@ int convert_packet(struct packet *new, const struct const_packet* old) if(yellow){ tcph->window=htons(0); } - tcph->seq=htonl(initialize_seq(h1, dccph->dccph_sport, ntohl(dccphex->dccph_seq_low))); + tcph->seq=htonl(initialize_seq(h1, ntohl(dccphex->dccph_seq_low))); tcph->syn=1; tcph->ack=1; tcph->fin=0; @@ -282,6 +298,7 @@ int convert_packet(struct packet *new, const struct const_packet* old) /* add Sack-permitted option, if relevant*/ if(sack){ + tcpopt=(u_char*)(new->data + tcph->doff*4); *tcpopt=4; *(tcpopt+1)=2; tcph->doff++; @@ -310,7 +327,7 @@ int convert_packet(struct packet *new, const struct const_packet* old) } if(sack){ if(sack!=2 || interp_ack_vect((u_char*)dccph)){ - ack_vect2sack(h2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) ); + ack_vect2sack(h2, tcph, (u_char*)tcph + tcph->doff*4, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) ); } } @@ -343,7 +360,7 @@ int convert_packet(struct packet *new, const struct const_packet* old) } if(sack){ if(sack!=2 || interp_ack_vect((u_char*)dccph)){ - ack_vect2sack(h2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) ); + ack_vect2sack(h2, tcph, (u_char*)tcph + tcph->doff*4, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) ); } } @@ -375,7 +392,7 @@ int convert_packet(struct packet *new, const struct const_packet* old) } if(sack){ if(sack!=2 || interp_ack_vect((u_char*)dccph)){ - ack_vect2sack(h2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) ); + ack_vect2sack(h2, tcph, (u_char*)tcph + tcph->doff*4, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) ); } } @@ -404,7 +421,7 @@ int convert_packet(struct packet *new, const struct const_packet* old) } if(sack){ if(sack!=2 || interp_ack_vect((u_char*)dccph)){ - ack_vect2sack(h2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) ); + ack_vect2sack(h2, tcph, (u_char*)tcph + tcph->doff*4, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) ); } } @@ -432,7 +449,7 @@ int convert_packet(struct packet *new, const struct const_packet* old) } if(sack){ if(sack!=2 || interp_ack_vect((u_char*)dccph)){ - ack_vect2sack(h2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) ); + ack_vect2sack(h2, tcph, (u_char*)tcph + tcph->doff*4, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low) ); } } @@ -460,7 +477,7 @@ int convert_packet(struct packet *new, const struct const_packet* old) } if(sack){ if(sack!=2 || interp_ack_vect((u_char*)dccph)){ - ack_vect2sack(h2, tcph, tcpopt, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low)); + ack_vect2sack(h2, tcph, (u_char*)tcph + tcph->doff*4, (u_char*)dccph, ntohl(dccphack->dccph_ack_nr_low)); } } @@ -503,7 +520,6 @@ unsigned int interp_ack_vect(u_char* hdr) /*parse options*/ while(optlen > 0){ - len=*(opt+1); /*One byte options (no length)*/ if(*opt< 32){ @@ -512,6 +528,13 @@ unsigned int interp_ack_vect(u_char* hdr) continue; } + /*Check option length*/ + len=*(opt+1); + if(len > optlen){ + dbgprintf(0, "Warning: Option would extend into packet data\n"); + return additional; + } + /*Ack Vector Option*/ if(*opt==38 || *opt==39){ tmp=len-2; @@ -532,7 +555,7 @@ unsigned int interp_ack_vect(u_char* hdr) bp+= (*cur & 0x3F)+1; } - if(((*cur& 0xF0)!= 0xC0) && ((*cur& 0xF0)!= 0x00) && ((*cur& 0xF0)!= 0x40)){ + if(((*cur& 0xC0)!= 0xC0) && ((*cur& 0xC0)!= 0x00) && ((*cur& 0xC0)!= 0x40)){ dbgprintf(1, "Warning: Invalid Ack Vector!! (Linux will handle poorly!)\n"); } tmp--; @@ -550,7 +573,7 @@ return additional; /* Setup Sequence Number Structure*/ -u_int32_t initialize_seq(struct host *seq, __be16 source, __be32 initial) +u_int32_t initialize_seq(struct host *seq, __be32 initial) { /*set default values*/ seq->cur=0; @@ -582,10 +605,20 @@ u_int32_t add_new_seq(struct host *seq, __be32 num, int size, enum dccp_pkt_type exit(1); } + if(seq->table==NULL){ + dbgprintf(1, "Warning: Connection uninitialized\n"); + return initialize_seq(seq, num); + } + /*account for missing packets*/ + if(num - seq->table[seq->cur].old +1 >=100){ + dbgprintf(1,"Missing more than 100 packets!\n"); + } while(seq->table[seq->cur].old +1 < num && seq->table[seq->cur].old +1 > 0){ prev=seq->cur; - dbgprintf(1,"Missing Packet: %X\n",seq->table[prev].new+1); + if(num - seq->table[seq->cur].old +1 <100){ + dbgprintf(1,"Missing Packet: %X\n",seq->table[prev].new+1); + } seq->cur=(seq->cur+1)%(seq->size);/*find next available table slot*/ seq->table[seq->cur].old=seq->table[prev].old+1; seq->table[seq->cur].new=seq->table[prev].new + seq->table[prev].size; @@ -624,6 +657,11 @@ u_int32_t convert_ack(struct host *seq, __be32 num) exit(1); } + if(seq->table==NULL){ + dbgprintf(1, "Warning: Connection uninitialized\n"); + initialize_seq(seq, num); + } + /*loop through table looking for the DCCP ack number*/ for(int i=0; i < seq->size; i++){ if(seq->table[i].old==num){ @@ -644,6 +682,11 @@ int acked_packet_size(struct host *seq, __be32 num) exit(1); } + if(seq->table==NULL){ + dbgprintf(1, "Warning: Connection uninitialized\n"); + initialize_seq(seq, num); + } + /*loop through table looking for the DCCP ack number*/ for(int i=0; i < seq->size; i++){ if(seq->table[i].old==num){ @@ -697,7 +740,6 @@ void ack_vect2sack(struct host *seq, struct tcphdr *tcph, u_char* tcpopts, u_cha /*parse options*/ while(optlen > 0){ - len=*(opt+1); /*One byte options (no length)*/ if(*opt< 32){ @@ -706,6 +748,12 @@ void ack_vect2sack(struct host *seq, struct tcphdr *tcph, u_char* tcpopts, u_cha continue; } + len=*(opt+1); + if(len > optlen){ + dbgprintf(0, "Warning: Option would extend into packet data\n"); + break; + } + /*Ack Vector Option*/ if(*opt==38 || *opt==39){ tmp=len-2;