+ /*Do conversion*/
+ tcph->ack_seq=htonl(h1->high_ack);
+ tcph->seq=htonl(add_new_seq(h1, ntohl(dccphex->dccph_seq_low),datalength, dccph->dccph_type));
+ tcph->syn=0;
+ tcph->ack=1;
+ tcph->fin=0;
+ tcph->rst=0;
+
+ /*copy data*/
+ npd=new->data + tcph->doff*4;
+ memcpy(npd, pd, datalength);
+
+ /*calculate length*/
+ new->length=tcph->doff*4 + datalength;
+ return 1;
+}
+
+int parse_options(const u_char* opt_start, int len, const struct const_packet* pkt,
+ struct hcon* A, struct hcon* B)
+{
+ int optlen;
+ int length;
+ const u_char* opt;
+ char buf1[100];
+ char buf2[100];
+
+ /*setup pointer to DCCP options and determine how long the options are*/
+ optlen=len;
+ opt=opt_start;
+
+ /*parse options*/
+ while(optlen > 0){
+ /*One byte options (no length)*/
+ if(*opt< 32){
+ optlen--;
+ opt++;
+ continue;
+ }
+
+ /*Check option length*/
+ length=*(opt+1);
+ if(length > optlen){
+ dbgprintf(0, "Warning: Option would extend into packet data\n");
+ return 0;
+ }
+ if(length < 2){
+ dbgprintf(0, "Warning: Bad Option!\n");
+ return 0;
+ }
+
+ /*Ack Vector Option*/
+ if(*opt==38 || *opt==39){
+ if(B->type==UNKNOWN){
+ B->type=CCID2;
+ if(pkt->print_id){
+ dbgprintf(1,"Half-connection from %s:%i to %s:%i probably using CCID 2\n",
+ pkt->print_id(buf1,100,pkt->dest_id,pkt->id_len),ntohs(B->port),
+ pkt->print_id(buf2,100,pkt->src_id,pkt->id_len), ntohs(A->port));
+ }else{
+ dbgprintf(1,"Half-connection from port %i to %i probably using CCID 2\n",
+ ntohs(B->port),ntohs(A->port));
+ }
+ }
+ }
+
+ /*NDP Count Option*/
+ if(*opt==37){
+ if(B->type==UNKNOWN){
+ B->type=CCID3;
+ if(pkt->print_id){
+ dbgprintf(1,"Half-connection from %s:%i to %s:%i probably using CCID 3\n",
+ pkt->print_id(buf1,100,pkt->dest_id,pkt->id_len),ntohs(B->port),
+ pkt->print_id(buf2,100,pkt->src_id,pkt->id_len), ntohs(A->port));
+ }else{
+ dbgprintf(1,"Half-connection from port %i to %i probably using CCID 3\n",
+ ntohs(B->port),ntohs(A->port));
+ }
+ }
+ }
+
+ /*Feature negotation*/
+ if(*opt==32){
+ /*Change L*/
+ if(!process_feature(opt+2,length-2,FALSE,TRUE,pkt,A,B)){
+ return 0;
+ }
+ }
+ if(*opt==33){
+ /*Confirm L*/
+ if(!process_feature(opt+2,length-2,TRUE,TRUE,pkt,A,B)){
+ return 0;
+ }
+ }
+ if(*opt==34){
+ /*Change R*/
+ if(!process_feature(opt+2,length-2,FALSE,FALSE,pkt,A,B)){
+ return 0;
+ }
+ }
+ if(*opt==35){
+ /*Confirm R*/
+ if(!process_feature(opt+2,length-2,TRUE,FALSE,pkt,A,B)){
+ return 0;
+ }