+ /*calculate length*/
+ new->length=tcph->doff*4;
+ return 1;
+}
+
+int handle_response(struct packet* new, const struct const_packet* old, struct hcon* h1, struct hcon* h2)
+{
+ struct tcphdr *tcph;
+ struct dccp_hdr *dccph;
+ struct dccp_hdr_ext *dccphex;
+ struct dccp_hdr_ack_bits *dccphack;
+ int optlen;
+ u_char* tcpopt;
+ const u_char* dccpopt;
+
+ /*length check*/
+ if(new->length < sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext)
+ + sizeof(struct dccp_hdr_ack_bits)+sizeof(struct dccp_hdr_request)){
+ return 0;
+ }
+
+ /*cast header pointers*/
+ 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));
+
+ /*Process DCCP Options*/
+ dccpopt=old->data + sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext) +
+ sizeof(struct dccp_hdr_ack_bits) + sizeof(struct dccp_hdr_request);
+ optlen=dccph->dccph_doff*4 - sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext)
+ - sizeof(struct dccp_hdr_ack_bits) - sizeof(struct dccp_hdr_request);
+ if(!parse_options(dccpopt,optlen,h1,h2)){
+ return 0;
+ }
+
+ /*Do conversion*/
+ if(h2->state!=OPEN){
+ dbgprintf(0,"Warning: DCCP Response without a Request!!\n");
+ }
+ tcph->ack_seq=htonl(convert_ack(h2,ntohl(dccphack->dccph_ack_nr_low),h1));
+ h1->high_ack=ntohl(tcph->ack_seq);
+ if(yellow){
+ tcph->window=htons(0);
+ }
+ if(h1->state==INIT){
+ tcph->seq=htonl(initialize_hcon(h1, ntohl(dccphex->dccph_seq_low)));
+ }
+ tcph->syn=1;
+ tcph->ack=1;
+ tcph->fin=0;
+ tcph->rst=0;
+
+ /* add Sack-permitted option, if relevant*/
+ if(sack){
+ tcpopt=(u_char*)(new->data + tcph->doff*4);
+ *tcpopt=4;
+ *(tcpopt+1)=2;
+ tcph->doff++;
+ }
+
+ /*calculate length*/
+ new->length=tcph->doff*4;
+ return 1;
+}
+
+int handle_dataack(struct packet* new, const struct const_packet* old, struct hcon* h1, struct hcon* h2)
+{
+ struct tcphdr *tcph;
+ struct dccp_hdr *dccph;
+ struct dccp_hdr_ext *dccphex;
+ struct dccp_hdr_ack_bits *dccphack;
+ int datalength;
+ int optlen;
+ const u_char* pd;
+ u_char* npd;
+ const u_char* dccpopt;
+
+ /*length check*/
+ if(new->length < sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext) + sizeof(struct dccp_hdr_ack_bits)){
+ return 0;
+ }
+
+ /*cast header pointers*/
+ 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));
+
+ /*determine data length*/
+ datalength=old->length - dccph->dccph_doff*4;
+ pd=old->data + dccph->dccph_doff*4;
+
+ /*Process DCCP Options*/
+ dccpopt=old->data + sizeof(struct dccp_hdr) + sizeof(struct dccp_hdr_ext) + sizeof(struct dccp_hdr_ack_bits);
+ optlen=dccph->dccph_doff*4 - sizeof(struct dccp_hdr) - sizeof(struct dccp_hdr_ext) - sizeof(struct dccp_hdr_ack_bits);
+ if(!parse_options(dccpopt,optlen,h1,h2)){
+ return 0;
+ }
+
+ /*Do Conversion*/
+ if(green){
+ tcph->ack_seq=htonl(convert_ack(h2,ntohl(dccphack->dccph_ack_nr_low),h1));
+ }else{
+ tcph->ack_seq=htonl(convert_ack(h2,ntohl(dccphack->dccph_ack_nr_low)+interp_ack_vect((u_char*)dccph),h1));
+ }
+ h1->high_ack=ntohl(tcph->ack_seq);
+ 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),h1);