diff --git a/PCAPasp_CNL113443.tpd b/PCAPasp_CNL113443.tpd
new file mode 100644
index 0000000000000000000000000000000000000000..aebba3f8f25a7c7c4e3e3bf9e658b3a679d08eeb
--- /dev/null
+++ b/PCAPasp_CNL113443.tpd
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (c) 2014 Ericsson
+
+  All rights reserved. This program and the accompanying materials
+  are made available under the terms of the Eclipse Public License v1.0
+  which accompanies this distribution, and is available at
+  http://www.eclipse.org/legal/epl-v10.html
+
+
+   File:               PCAPasp_CNL113443.tpd
+   Description:        tpd project file
+   Rev:                R7A
+   Prodnr:             CNL 113 443
+
+ -->
+<TITAN_Project_File_Information version="1.0">
+  <ProjectName>PCAPasp_CNL113443</ProjectName>
+  <Folders>
+    <FolderResource projectRelativePath="src" relativeURI="src"/>
+  </Folders>
+  <Files>
+    <FileResource projectRelativePath="src/PCAPasp_PT.cc" relativeURI="src/PCAPasp_PT.cc"/>
+    <FileResource projectRelativePath="src/PCAPasp_PT.hh" relativeURI="src/PCAPasp_PT.hh"/>
+    <FileResource projectRelativePath="src/PCAPasp_PortType.ttcn" relativeURI="src/PCAPasp_PortType.ttcn"/>
+    <FileResource projectRelativePath="src/PCAPasp_Types.ttcn" relativeURI="src/PCAPasp_Types.ttcn"/>
+  </Files>
+  <ActiveConfiguration>Default</ActiveConfiguration>
+  <Configurations>
+    <Configuration name="Default">
+      <ProjectProperties>
+        <MakefileSettings>
+          <generateInternalMakefile>true</generateInternalMakefile>
+          <GNUMake>true</GNUMake>
+          <incrementalDependencyRefresh>true</incrementalDependencyRefresh>
+          <targetExecutable>bin/PCAPasp_CNL113443</targetExecutable>
+          <linkerLibraries>
+            <listItem>pcap</listItem>
+          </linkerLibraries>
+        </MakefileSettings>
+        <LocalBuildSettings>
+          <workingDirectory>bin</workingDirectory>
+        </LocalBuildSettings>
+        <NamingCoventions>
+          <enableProjectSpecificSettings>true</enableProjectSpecificSettings>
+          <function>.*</function>
+          <formalParameter>.*</formalParameter>
+        </NamingCoventions>
+      </ProjectProperties>
+    </Configuration>
+  </Configurations>
+</TITAN_Project_File_Information>
diff --git a/doc/PCAPasp_CNL113443_1551.doc b/doc/PCAPasp_CNL113443_1551.doc
new file mode 100644
index 0000000000000000000000000000000000000000..a88c1d6e66148cdc9c40949a333a30243d256555
Binary files /dev/null and b/doc/PCAPasp_CNL113443_1551.doc differ
diff --git a/doc/PCAPasp_CNL113443_PRI.doc b/doc/PCAPasp_CNL113443_PRI.doc
new file mode 100644
index 0000000000000000000000000000000000000000..609480774bd48d1e4e8dc227e5ffba686109fe65
Binary files /dev/null and b/doc/PCAPasp_CNL113443_PRI.doc differ
diff --git a/src/PCAPasp_PT.cc b/src/PCAPasp_PT.cc
new file mode 100644
index 0000000000000000000000000000000000000000..091a53eb61a6dd05daf660415201b40f3b605d02
--- /dev/null
+++ b/src/PCAPasp_PT.cc
@@ -0,0 +1,2805 @@
+/******************************************************************************
+* Copyright (c) 2005, 2014  Ericsson AB
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+*   Antal Wuh.Hen.Chang - initial implementation and initial documentation
+*   Adam Delic
+*   Andrea Darabos
+*   Endre Kulcsar
+*   Gabor Szalai
+*   Tibor Szabo
+******************************************************************************/
+//
+//  File:               PCAPasp_PT.cc
+//  Description:        PCAP test port source file
+//  Rev:                R7A
+//  Prodnr:             CNL 113 443
+//
+
+#include "PCAPasp_PT.hh"
+
+#include <TTCN3.hh>
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+//#include <openssl/md5.h>
+//#include <openssl/hmac.h>
+//#include <openssl/aes.h>
+//#include <openssl/sha.h>
+//#include <openssl/bn.h>
+
+
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+#include <netinet/if_ether.h>
+
+
+#include "memory.h"
+
+
+
+using namespace PCAPasp__Types;
+namespace PCAPasp__PortType{
+static const u_int16_t c_infinite = 0xFFFF;
+static bool logging = false;
+static bool noFilter = false;
+static Protocol_data p_data;
+static PCAPasp__PT *act_pt;
+
+
+INTEGER default_getMsgLen(const OCTETSTRING &stream, const BOOLEAN& /*conn__closed*/,
+                          const Transport &/*stream__transport*/){
+  return stream.lengthof();
+}
+
+INTEGER default_getMsgStartPos(const OCTETSTRING &/*stream*/, const BOOLEAN& /*conn__closed*/,
+                          const Transport &/*stream__transport*/){
+  return 0;
+}
+
+static tf__getMsgLen def_getMsgLen_ref=default_getMsgLen;
+static tf__getMsgStartPos def_getMsgStartPos_ref=default_getMsgStartPos;
+
+void genlog(const char *fmt, ...) {
+	TTCN_Logger::begin_event(TTCN_DEBUG);
+	va_list ap;
+	va_start(ap, fmt);
+	TTCN_Logger::log_event_va_list(fmt, ap);
+	va_end(ap); 
+	TTCN_Logger::end_event(); 
+}
+
+INTEGER f_null_ICV(const OCTETSTRING& /*ipheader*/, const OCTETSTRING& /*ipdata*/, OCTETSTRING& /*user__data*/)
+{
+return 0;
+}
+
+BOOLEAN f_null_encryption(const OCTETSTRING& /*ipheader*/, const OCTETSTRING& ipdata, OCTETSTRING& decrypted__data, OCTETSTRING&/* user__data*/)
+{
+int ret_len=ipdata.lengthof();
+int start_pos=0;
+if(ret_len>9){
+  int pad_len=((const unsigned char*)ipdata)[ret_len-1];
+  ret_len-=9+pad_len;  // spi_length+seq_no_length+pad_length_length = 4+4+1
+  if(ret_len<0){
+    ret_len=ipdata.lengthof();
+  } else {
+    start_pos=8;// skip spi+seq_no
+  }
+}
+decrypted__data = OCTETSTRING(ret_len,(const unsigned char*)ipdata+start_pos);
+return TRUE;
+}
+
+ESP_obj::ESP_obj(PCAPasp__Types::ASP__PCAP__ESP__Setup data){
+  spi=data.spi().get_long_long_val();
+  if(data.icv__function().ispresent()){
+    icv_fv=data.icv__function();
+  } else {
+    icv_fv=f_null_ICV;
+  }
+  if(data.icv__function__user__data().ispresent()){
+    icv_data=data.icv__function__user__data();
+  } else {
+    icv_data=OCTETSTRING(0,NULL);
+  }
+  if(data.esp__decrypt__function().ispresent()){
+    decrypt_fv=data.esp__decrypt__function();
+  } else {
+    decrypt_fv=f_null_encryption;
+  }
+  if(data.esp__decrypt__function__user__data().ispresent()){
+    decrypt_data=data.esp__decrypt__function__user__data();
+  } else {
+    decrypt_data=OCTETSTRING(0,NULL);
+  }
+  struct in_addr tmp;
+  if(data.sourceIP().ispresent() && inet_aton((const char *)data.sourceIP()(),&tmp)){
+    ip_port=std::string((const char *)&tmp,sizeof(tmp));
+  } else {
+    ip_port=std::string(0,sizeof(tmp));
+  }
+  if(data.destinationIP().ispresent() && inet_aton((const char *)data.destinationIP()(),&tmp)){
+    ip_port+=std::string((const char *)&tmp,sizeof(tmp));
+  } else {
+    ip_port+=std::string(0,sizeof(tmp));
+  }
+  u_int16_t tmp2;
+  if(data.sourcePort().ispresent()){
+    tmp2=htons(data.sourcePort()());
+  } else {
+    tmp2=0;
+  }
+  ip_port+=std::string((const char *)&tmp2,sizeof(tmp2));
+  if(data.destinationPort().ispresent()){
+    tmp2=htons(data.destinationPort()());
+  } else {
+    tmp2=0;
+  }
+  ip_port+=std::string((const char *)&tmp2,sizeof(tmp2));
+  mode=data.mode();
+}
+ESP_obj::~ESP_obj(){}
+
+
+ESP_handler::ESP_handler(){}
+ESP_handler::~ESP_handler(){
+  clean_up();
+}
+bool ESP_handler::setup_esp(PCAPasp__Types::ASP__PCAP__ESP__Setup data){
+  std::map<unsigned int, ESP_obj*>::iterator it=spi_ESP_obj_map.find(data.spi().get_long_long_val());
+  if(data.mode() == PCAPasp__Types::ESP__mode::ESP__DELETE){
+    if(it==spi_ESP_obj_map.end()){
+      return false;
+    }
+    address_ESP_obj_map.erase((it->second)->ip_port);
+    for (std::list<ESP_obj*>::iterator it2=ESP_OBJ_list.begin(); it2 != ESP_OBJ_list.end(); ++it2){
+      if(*it2 == it->second) {
+        ESP_OBJ_list.erase(it2);
+        break;
+      }
+    }
+    delete it->second;
+    spi_ESP_obj_map.erase(it);
+    return true;
+  } else {
+    if(it!=spi_ESP_obj_map.end()){
+      return false;
+    }
+    ESP_obj* new_esp=new ESP_obj(data);
+    if(address_ESP_obj_map.find(new_esp->ip_port)!=address_ESP_obj_map.end()){
+      delete new_esp;
+      return false;
+    }
+    address_ESP_obj_map[new_esp->ip_port]=new_esp;
+    spi_ESP_obj_map[new_esp->spi]=new_esp;
+    ESP_OBJ_list.push_back(new_esp);
+    return true;
+  }
+
+  return false;
+}
+bool ESP_handler::find_esp(unsigned int spi, ESP_obj *& esp){
+  std::map<unsigned int, ESP_obj*>::iterator it=spi_ESP_obj_map.find(spi);
+  if(it==spi_ESP_obj_map.end()){
+    return false;
+  }
+  esp=it->second;
+  return true;
+}
+bool ESP_handler::esp_exists(struct in_addr *ip_src, unsigned int port_src,struct in_addr *ip_dst,unsigned int port_dst,unsigned int /*proto*/){
+  u_int16_t p_src=port_src;
+  u_int16_t p_dst=port_dst;
+  if(address_ESP_obj_map.find(std::string((const char *)ip_src,sizeof(ip_src))+
+                              std::string((const char *)ip_dst,sizeof(ip_dst))+
+                              std::string((const char *)&p_src,sizeof(p_src))+
+                              std::string((const char *)&p_dst,sizeof(p_dst))
+                                                                      )!=address_ESP_obj_map.end()){
+    return true;
+  }
+  if(address_ESP_obj_map.find(std::string((const char *)ip_src,sizeof(ip_src))+
+                              std::string((const char *)ip_dst,sizeof(ip_dst))+
+                              std::string(2,'\0')+
+                              std::string((const char *)&p_dst,sizeof(p_dst))
+                                                                      )!=address_ESP_obj_map.end()){
+    return true;
+  }
+  if(address_ESP_obj_map.find(std::string((const char *)ip_src,sizeof(ip_src))+
+                              std::string((const char *)ip_dst,sizeof(ip_dst))+
+                              std::string((const char *)&p_src,sizeof(p_src))+
+                              std::string(2,'\0')
+                                                                      )!=address_ESP_obj_map.end()){
+    return true;
+  }
+  if(address_ESP_obj_map.find(std::string(4,'\0')+
+                              std::string((const char *)ip_dst,sizeof(ip_dst))+
+                              std::string(2,'\0')+
+                              std::string((const char *)&p_dst,sizeof(p_dst))
+                                                                      )!=address_ESP_obj_map.end()){
+    return true;
+  }
+  if(address_ESP_obj_map.find(std::string(4,'\0')+
+                              std::string((const char *)ip_dst,sizeof(ip_dst))+
+                              std::string(2,'\0')+
+                              std::string((const char *)&p_dst,sizeof(p_dst))
+                                                                      )!=address_ESP_obj_map.end()){
+    return true;
+  }
+  
+  return false;
+}
+void ESP_handler::clean_up(){
+  spi_ESP_obj_map.clear();
+  address_ESP_obj_map.clear();
+  for (std::list<ESP_obj*>::iterator it=ESP_OBJ_list.begin(); it != ESP_OBJ_list.end(); ++it){
+    delete *it;
+  }
+  ESP_OBJ_list.clear();
+}
+
+bool ESP_handler::match_esp(struct in_addr *ip_src, unsigned int port_src,struct in_addr *ip_dst,unsigned int port_dst,const ESP_obj *esp){
+  u_int16_t p_src=port_src;
+  u_int16_t p_dst=port_dst;
+  return (esp->ip_port.substr(0,4)==std::string(4,'\0') || esp->ip_port.substr(0,4)==std::string((const char *)ip_src,sizeof(ip_src))) &&
+         (esp->ip_port.substr(4,4)==std::string(4,'\0') || esp->ip_port.substr(4,4)==std::string((const char *)ip_dst,sizeof(ip_dst))) &&
+         (esp->ip_port.substr(8,2)==std::string(2,'\0') || esp->ip_port.substr(8,2)==std::string((const char *)&p_src,sizeof(p_src))) &&
+         (esp->ip_port.substr(8,2)==std::string(2,'\0') || esp->ip_port.substr(8,2)==std::string((const char *)&p_dst,sizeof(p_dst)));
+}
+
+////////////////////////////////////////////////////////////
+// Constructor
+////////////////////////////////////////////////////////////
+PCAPasp__PT::PCAPasp__PT(const char *par_port_name)
+	: PCAPasp__PT_BASE(par_port_name)
+{
+  capture_file = NULL;
+  packet_filter = new char[1]; packet_filter[0] = '\0';
+  logging = false;
+  handle = NULL;
+  dumpfile = NULL;
+  
+  
+  //for debugging:
+  peer_list_tcp.setType(true);
+  peer_list_udp.setType(false);
+  peer_list_sctp.setType(false);
+}
+
+
+////////////////////////////////////////////////////////////
+// Destructor
+////////////////////////////////////////////////////////////
+PCAPasp__PT::~PCAPasp__PT()
+{
+  if (capture_file) delete [] capture_file;
+  if (packet_filter) delete [] packet_filter;
+}
+
+
+////////////////////////////////////////////////////////////
+// set_parameter
+////////////////////////////////////////////////////////////
+void PCAPasp__PT::set_parameter(const char *parameter_name,
+	const char *parameter_value)
+{
+  //Capturing related parameters
+  if (strcmp("capture_file", parameter_name) == 0) {
+    if (capture_file) delete [] capture_file;
+    capture_file = new char[strlen(parameter_value) + 1];
+    strcpy(capture_file, parameter_value);
+  }
+  else if (strcmp("packet_filter", parameter_name) == 0) {
+    if (packet_filter) delete [] packet_filter;
+    packet_filter = new char[strlen(parameter_value) + 1];
+    strcpy(packet_filter, parameter_value);
+  }
+  else if (strcmp("logging", parameter_name) == 0) {
+    
+    if (strcasecmp(parameter_value, "TRUE") == 0) {
+      logging = true;
+    }
+    else logging = false;
+  }
+  else if (strcmp("noFilter", parameter_name) == 0) {
+    
+    if (strcasecmp(parameter_value, "TRUE") == 0) {
+      noFilter = true;
+    }
+    else noFilter = false;
+  }
+  else
+    TTCN_warning("PCAP Test Port(%s): Invalid parameter: %s.",port_name ,parameter_name);
+}
+
+
+////////////////////////////////////////////////////////////
+// Event_Handler
+////////////////////////////////////////////////////////////
+void PCAPasp__PT::Event_Handler(const fd_set */*read_fds*/, const fd_set */*write_fds*/, const fd_set */*error_fds*/, double /*time_since_last_call*/)
+{
+  const u_char* packet;
+  packet = pcap_next( handle, &header);
+  
+  if (packet == NULL)
+    TTCN_error("PCAP can't capture");
+  if (capture)
+    pcap_dump((u_char*)dumpfile, &header, packet);
+}
+
+
+////////////////////////////////////////////////////////////
+// user_map
+////////////////////////////////////////////////////////////
+void PCAPasp__PT::user_map(const char */*system_port*/)
+{
+  if( geteuid() != 0 ) TTCN_warning ( "You must be root to be able to use the test port in capturing mode!");
+  capture = 0;
+  settings = 0;
+        
+  if (capture_file!=NULL){
+    if (dump_reader.open(capture_file)==false) {
+      TTCN_error("Failed to open capture file \"%s\"", capture_file);
+      return;
+    }
+    else {
+      log("Capture file \"%s\" was opened", capture_file);
+    }
+  }
+  
+  if (packet_filter!=NULL){
+    if (dump_reader.setFilter(packet_filter)==false) {
+      TTCN_error("Failed to set the packet filter %s", packet_filter);
+      return;
+    } else {
+      log("Filter \"%s\" was applied", packet_filter);
+    }
+  }
+}
+
+
+////////////////////////////////////////////////////////////
+// user_unmap
+////////////////////////////////////////////////////////////
+void PCAPasp__PT::user_unmap(const char */*system_port*/)
+{
+  peer_list_tcp.log_stat();
+  Uninstall_Handler();
+  if (handle) pcap_close( handle);
+  if (dumpfile) pcap_dump_close( dumpfile);
+}
+
+void PCAPasp__PT::user_start()
+{
+
+}
+
+void PCAPasp__PT::user_stop()
+{
+
+}
+
+
+////////////////////////////////////////////////////////////
+// outgoing_send
+////////////////////////////////////////////////////////////
+void PCAPasp__PT::outgoing_send(const PCAPasp__Types::ASP__PCAP__ESP__Setup& send_par){
+  PCAPasp__Types::ASP__PCAP__ESP__Setup__Resp ret_val;
+  if(esp.setup_esp(send_par)){
+    ret_val.status__code()=PCAPasp__Types::ESP__Status::ESP__OK;
+    ret_val.status__message()=OMIT_VALUE;
+  } else {
+    ret_val.status__code()=PCAPasp__Types::ESP__Status::ESP__SETUP__ERROR;
+    ret_val.status__message()="Failed to register the ESP";
+  }
+  incoming_message(ret_val);
+}
+
+void PCAPasp__PT::outgoing_send(const PCAPasp__Types::ASP__PCAP__Capture& send_par)
+{
+  PCAPasp__Types::ASP__PCAP__ConfigResp myStatus;
+  fd_set readfds;
+  
+  myStatus.status() = CommandStatus::INVALID;
+  myStatus.errorMessage() = OMIT_VALUE;
+
+  if( send_par.command() == CaptureControl::START ) {
+    myStatus.command() = CommandId::STARTCMD;
+    if (settings) {
+      if (capture) {
+        myStatus.errorMessage() = CommandError::CAPTURING__HAS__ALREADY__STARTED;
+      }
+      else {
+        myStatus.status() = CommandStatus::VALID;
+	capture = 1;
+	FD_ZERO( &readfds);
+	FD_SET( pcap_fileno( handle), &readfds ); 
+	Install_Handler( &readfds, NULL, NULL, 0.0 );
+     }
+   }
+   else {
+     myStatus.errorMessage() = CommandError::THERE__IS__NO__FILTER__SET;
+   }	
+ }
+ 
+ else if( send_par.command() == CaptureControl::STOP ) {
+   myStatus.command() = CommandId::STOPCMD;
+   if (capture) {
+     myStatus.status() = CommandStatus::CommandStatus::VALID;
+     capture = 0;
+   }
+   else {
+     myStatus.errorMessage() = CommandError::CAPTURING__HAS__NOT__STARTED;
+   }
+ }
+ incoming_message( myStatus );
+}
+
+////////////////////////////////////////////////////////////
+// outgoing_send
+////////////////////////////////////////////////////////////
+void PCAPasp__PT::outgoing_send(const PCAPasp__Types::ASP__PCAP__ConfigReq& send_par) {
+
+  struct bpf_program filter;
+  char errbuf[PCAP_ERRBUF_SIZE];
+  bpf_u_int32 mask;
+  bpf_u_int32 net;
+    
+  CHARSTRING myInterface;
+  CHARSTRING myFilter;
+  INTEGER myMask;
+  PCAPasp__Types::ASP__PCAP__ConfigResp myStatus;
+
+  myStatus.command() = CommandId::FILTERCMD;
+  myStatus.status() = CommandStatus::INVALID;
+  myStatus.errorMessage() = OMIT_VALUE;
+
+  if (capture) {
+    myStatus.errorMessage() = CommandError::PORT__IS__ALREADY__CAPTURING;
+  }
+  else {
+    settings = 0;
+
+    Uninstall_Handler();
+    if( dumpfile != NULL){
+           pcap_dump_close( dumpfile);
+           dumpfile = NULL;
+    }
+
+    if (send_par.interface().ispresent()) myInterface = send_par.interface();
+    else myInterface = "eth0";
+
+    if (send_par.filter().ispresent()) myFilter = send_par.filter();
+    else myFilter = "";
+
+    if (send_par.mask().ispresent()) myMask = send_par.mask();
+    else myMask = 0xffffff;
+
+    char* myFilterString = new char[strlen(myFilter) + 1];
+    strcpy(myFilterString, (const char*)myFilter);
+
+    if( pcap_lookupnet( myInterface, &net, &mask, errbuf) == -1){
+           myStatus.errorMessage() = CommandError::ERROR__LOOKING__NET__UP;
+    }
+    else {
+      handle = pcap_open_live( myInterface, 1514, 1, 0, errbuf);	
+      if( handle == NULL ){
+             myStatus.errorMessage() = CommandError::ERROR__LIVE__OPENING;
+      }
+      else if( pcap_compile( handle, &filter, myFilterString, 0, myMask) == -1){
+             myStatus.errorMessage() = CommandError::ERROR__COMPILING__FILTER;
+      }
+      else if( pcap_setfilter( handle, &filter) == -1 ){
+             myStatus.errorMessage() = CommandError::ERROR__SETTING__FILTER;
+      }
+      else if( pcap_setnonblock( handle, 1, errbuf) == -1 ){
+             myStatus.errorMessage() = CommandError::ERROR__SETTING__NONBLOCK__MODE;
+      }
+      else {
+        dumpfile = pcap_dump_open( handle, (const char*)send_par.filename());
+        if( dumpfile == NULL) {
+          myStatus.errorMessage() = CommandError::ERROR__OPENING__OUTPUT__FILE;
+        }
+        else {
+          settings = 1;
+          myStatus.status() = CommandStatus::CommandStatus::VALID;
+        }
+      }
+    }
+    
+    if (myFilterString) delete [] myFilterString;
+  }
+  incoming_message( myStatus );
+}
+
+////////////////////////////////////////////////////////////
+// outgoing_send
+////////////////////////////////////////////////////////////
+void PCAPasp__PT::outgoing_send(const PCAPasp__Types::ASP__PCAP__DumpReaderFilter& send_par)
+{
+    PCAPasp__Types::ASP__PCAP__DumpFilterResp respStatus;
+    struct in_addr srcIp;
+    struct in_addr destIp;
+    in_addr_t addr;
+    bool srcIpAll = false;
+    int trueFlag = 1;
+    memset(&srcIp, 0, sizeof(srcIp));
+    respStatus.status() = CommandStatus::CommandStatus::VALID;
+    respStatus.errorMessage() = OMIT_VALUE;
+
+        if (strcmp(send_par.localIp(), "*")==0)
+        {
+          srcIpAll = true;
+        }
+        else
+        {
+          addr = inet_addr( send_par.localIp() );
+	  
+	  if (addr != (in_addr_t)-1)
+		  memcpy(&(srcIp.s_addr), &addr, sizeof(addr));
+	  else{
+	      trueFlag = 0;
+	      respStatus.status() = CommandStatus::INVALID;
+	      respStatus.errorMessage() = DumpFilterError::WRONG__SOURCE__IP;
+	  }
+        }
+	
+	addr = inet_addr( send_par.remoteIp() );
+	
+	if (addr != (in_addr_t)-1)
+		memcpy(&(destIp.s_addr), &addr, sizeof(addr));
+	else{
+	    trueFlag = 0;
+	    respStatus.status() = CommandStatus::INVALID;
+	    respStatus.errorMessage() = DumpFilterError::WRONG__DESTINATION__IP;
+	}
+	
+	if( trueFlag ){
+          for (int i=0; i<send_par.remotePorts().size_of(); i++) {
+            int port = (int) ( send_par.remotePorts()[i] );
+            filter_table.addEntry((int)send_par.messageType(), srcIp, srcIpAll, destIp, (unsigned int) port);
+          }
+	}
+	
+    incoming_message( respStatus );
+}
+
+////////////////////////////////////////////////////////////
+// outgoing_send
+////////////////////////////////////////////////////////////
+void PCAPasp__PT::outgoing_send(const PCAPasp__Types::ASP__PCAP__MessageReq& send_par)
+{
+  PCAPasp__Types::ASP__PCAP__MessageResp incoming_msg;
+  TCPSegment* seg = NULL;
+  bool ready_message = false;
+  bool no_more_message = false;
+  
+  do {
+    Peer* act_peer;
+    for (int i=0; i<peer_list_tcp.length(); i++) {
+      act_peer = peer_list_tcp.elementAt(i);
+      int embedded_length=0;
+      if (act_peer->tcp_buf.length > 0) { // is there anything in the buffer?
+log("peer_list_tcp, peer %d", i);
+        embedded_length=act_peer->get_msg_len();
+log("peer_list_tcp, embedded_length %d", embedded_length);
+        if(embedded_length>0){
+          if (send_par.nextMessage() == act_peer->protocol_type || send_par.nextMessage() == -1) {
+            ready_message=true;
+            incoming_msg.status() = Status::VALID__MESSAGE;
+            incoming_msg.timeStamp() = act_peer->tcp_buf.timestamp;
+            incoming_msg.contentLength() = embedded_length;
+            incoming_msg.sourcePort() = act_peer->port_src;
+            incoming_msg.destinationPort() = act_peer->port_dst;
+            incoming_msg.sourceIP() = inet_ntoa(act_peer->ip_src);
+            incoming_msg.destinationIP() = inet_ntoa(act_peer->ip_dst);
+            incoming_msg.msgtype()=act_peer->protocol_type;
+            incoming_msg.nextMessage()=OCTETSTRING(embedded_length,act_peer->tcp_buf.get_read_data());
+            incoming_message(incoming_msg);
+          }
+          act_peer->tcp_buf.set_pos(act_peer->tcp_buf.get_pos()+embedded_length);
+          act_peer->tcp_buf.cut();
+        }
+      } // if peer's buffer > 0
+      if(embedded_length<=0 && act_peer->tcp_buf.closed && !act_peer->tcp_buf.close_sent){
+        act_peer->tcp_buf.close_sent=true;
+          ASP__PCAP__ConnectionClosed apcc_msg;
+          apcc_msg.protocol() = act_peer->protocol_type;
+          apcc_msg.destinationPort() = act_peer->port_dst;
+          apcc_msg.destinationIP() = inet_ntoa(act_peer->ip_dst);
+          apcc_msg.sourcePort() = act_peer->port_src;
+          apcc_msg.sourceIP() = inet_ntoa(act_peer->ip_src);
+          incoming_message(apcc_msg);
+      }
+      if(ready_message) break;
+    } // for each tcp peer
+
+
+    if (!ready_message) //if no requested message was found we iterate through the UDP streams as well.
+    for (int i=0; i<peer_list_udp.length(); i++) {
+      act_peer = peer_list_udp.elementAt(i);
+      
+      if (act_peer->tcp_buf.length > 0) { // is there anything in the buffer?
+        int embedded_length=act_peer->get_msg_len();
+        if(embedded_length>0){
+          if (send_par.nextMessage() == act_peer->protocol_type || send_par.nextMessage() == -1) {
+            ready_message=true;
+            incoming_msg.status() = Status::VALID__MESSAGE;
+            incoming_msg.timeStamp() = act_peer->tcp_buf.timestamp;
+            incoming_msg.contentLength() = embedded_length;
+            incoming_msg.sourcePort() = act_peer->port_src;
+            incoming_msg.destinationPort() = act_peer->port_dst;
+            incoming_msg.sourceIP() = inet_ntoa(act_peer->ip_src);
+            incoming_msg.destinationIP() = inet_ntoa(act_peer->ip_dst);
+            incoming_msg.msgtype()=act_peer->protocol_type;
+            incoming_msg.nextMessage()=OCTETSTRING(embedded_length,act_peer->tcp_buf.get_data());
+            incoming_message(incoming_msg);
+          }
+          act_peer->tcp_buf.set_pos(embedded_length);
+          act_peer->tcp_buf.cut();
+        }
+      } // if peer's buffer > 0
+      if(ready_message) break;
+    } // for each udp peer
+
+    if (!ready_message) //if no requested message was found we iterate through the SCTP streams as well.
+    for (int i=0; i<peer_list_sctp.length(); i++) {
+      act_peer = peer_list_sctp.elementAt(i);
+      
+      if (act_peer->has_message()) { // is there anything in the buffer?
+        int embedded_length=act_peer->get_first_sctp_data_len();
+        if(embedded_length>0){
+          if (send_par.nextMessage() == act_peer->protocol_type || send_par.nextMessage() == -1) {
+            ready_message=true;
+            incoming_msg.status() = Status::VALID__MESSAGE;
+            incoming_msg.timeStamp() = act_peer->get_first_sctp_timestamp();
+            incoming_msg.contentLength() = embedded_length;
+            incoming_msg.sourcePort() = act_peer->port_src;
+            incoming_msg.destinationPort() = act_peer->port_dst;
+            incoming_msg.sourceIP() = inet_ntoa(act_peer->ip_src);
+            incoming_msg.destinationIP() = inet_ntoa(act_peer->ip_dst);
+            incoming_msg.msgtype()=act_peer->protocol_type;
+            incoming_msg.nextMessage()=OCTETSTRING(embedded_length,act_peer->get_first_sctp_data());
+            incoming_message(incoming_msg);
+          }
+          act_peer->delete_first_sctp_message();
+        }
+      } // if peer's buffer > 0
+      if(ready_message) break;
+    } // for each sctp peer
+
+    if (!ready_message) {
+      
+      act_pt=this;
+      seg = getNextFilteredSegment();
+      if (seg) { 
+      
+        seg->log();
+        
+        if (seg->seg_type == SCTP_SEG && seg->fin) { //PCAP_ASP_ConnectionClosed must be sent to TTCN in case a TCP connection is terminated
+          ASP__PCAP__ConnectionClosed apcc_msg;
+          apcc_msg.protocol() = seg->protocol_type;
+          apcc_msg.destinationPort() = seg->port_dst;
+          apcc_msg.destinationIP() = inet_ntoa(seg->ip_dst);
+          apcc_msg.sourcePort() = seg->port_src;
+          apcc_msg.sourceIP() = inet_ntoa(seg->ip_src);
+          incoming_message(apcc_msg);
+        }
+        
+        if (seg->seg_type == TCP_SEG) {
+            INTEGER port_dst = seg->port_dst;
+            INTEGER port_src = seg->port_src;
+            CHARSTRING ip_src = inet_ntoa(seg->ip_src);
+            CHARSTRING ip_dst = inet_ntoa(seg->ip_dst);
+          if (!peer_list_tcp.sendSegmentToPeer(seg)) {
+            //We detected a lost segment.
+            //Note that, the source and destination directions are exchanged
+            //because the lost segment was in other direction than the acknowledgment
+            //via we detected it.
+            ASP__PCAP__Error ape;
+            ape.errorType() = PCAPError::LOST__SEGMENT;
+            ape.sourcePort() = port_dst;
+            ape.destinationPort() = port_src;
+            ape.sourceIP() = ip_dst;
+            ape.destinationIP() = ip_src;
+            incoming_message(ape);
+          }
+        }
+        else if (seg->seg_type == UDP_SEG) {
+          peer_list_udp.sendSegmentToPeer(seg);
+        } 
+        else if (seg->seg_type == SCTP_SEG) {
+            INTEGER port_dst = seg->port_dst;
+            INTEGER port_src = seg->port_src;
+            CHARSTRING ip_src = inet_ntoa(seg->ip_src);
+            CHARSTRING ip_dst = inet_ntoa(seg->ip_dst);
+          if (!peer_list_sctp.sendSegmentToPeer(seg)) {
+            //We detected a lost segment.
+            //Note that, the source and destination directions are exchanged
+            //because the lost segment was in other direction than the acknowledgment
+            //via we detected it.
+            ASP__PCAP__Error ape;
+            ape.errorType() = PCAPError::LOST__SEGMENT;
+            ape.sourcePort() = port_dst;
+            ape.destinationPort() = port_src;
+            ape.sourceIP() = ip_dst;
+            ape.destinationIP() = ip_src;
+            incoming_message(ape);
+          }
+        }
+      }
+      else no_more_message = true;
+    }
+    
+  } while (!no_more_message && !ready_message);
+  
+  //No more messages in the dump file
+  if (no_more_message) {
+    incoming_msg.status() = Status::NO__MESSAGE;
+    incoming_msg.timeStamp() = OMIT_VALUE;
+    incoming_msg.contentLength() = OMIT_VALUE;
+    incoming_msg.sourcePort() = OMIT_VALUE;
+    incoming_msg.destinationPort() = OMIT_VALUE;
+    incoming_msg.sourceIP() = OMIT_VALUE;
+    incoming_msg.destinationIP() = OMIT_VALUE;
+    incoming_msg.msgtype()= OMIT_VALUE;
+    incoming_msg.nextMessage() = OMIT_VALUE;
+    incoming_message(incoming_msg);
+    if (logging){
+     log("stream buffers:");
+     peer_list_tcp.dump();
+     peer_list_udp.dump();
+    }
+  }
+}
+
+void PCAPasp__PT::outgoing_send(const PCAPasp__Types::ASP__PACP__SetupProtocol& send_par){
+  p_data.add_protocol(send_par.protocol__id(),
+  send_par.getMsgLen__function().ispresent()?send_par.getMsgLen__function()():default_getMsgLen,
+  send_par.getMsgStartPos__function().ispresent()?send_par.getMsgStartPos__function()():default_getMsgStartPos
+
+                      );
+}
+
+
+
+////////////////////////////////////////////////////////////
+// getNextFilteredSegment
+////////////////////////////////////////////////////////////
+TCPSegment* PCAPasp__PT::getNextFilteredSegment()
+{
+  TCPSegment* seg = NULL;
+  int protocol_type;
+  bool found = false;
+  bool last = false;
+  
+  do {
+    seg = dump_reader.getNextSegment();
+    if (seg) {
+      protocol_type = filter_table.filter(seg);
+      log("Check protocol");
+      if (protocol_type != NO_PROTOCOL) {
+      log("found protocol");
+        seg->protocol_type = protocol_type;
+        found = true;
+      }
+      else {
+      log("no protocol");
+        delete seg; seg = NULL;
+      }
+    }
+    else {
+      last = true;
+    }
+  }
+  while (!found && !last);
+  return seg;
+}
+
+void PCAPasp__PT::log(const char *fmt, ...) { 
+  TTCN_Logger::begin_event(TTCN_DEBUG);
+  TTCN_Logger::log_event("PCAPasp_PT: ");
+  va_list ap;
+  va_start(ap, fmt);
+  TTCN_Logger::log_event_va_list(fmt, ap);
+  va_end(ap); 
+  TTCN_Logger::end_event(); 
+}
+
+
+
+////////////////////////////////////////////////////////////
+// TCPSegment implementation
+////////////////////////////////////////////////////////////
+TCPSegment::TCPSegment()
+{
+  payload = NULL;
+  length = 0;
+  syn = false; fin = false;
+  seq_num = 0;
+  ack_num = 0;
+  seg_type = TCP_SEG;
+  protocol_type = NO_PROTOCOL;
+  timestamp = 0.0;
+}
+
+TCPSegment::~TCPSegment()
+{
+  if (payload) delete [] payload;
+}
+
+void TCPSegment::put(char* buf, size_t size)
+{
+  if (size>0) {
+    if (payload) delete [] payload;
+    payload = new unsigned char[size];
+    memcpy(payload, buf, size);
+    length = size;
+  }
+  else {
+    if (payload) delete [] payload;
+    payload = NULL;
+    length = 0;
+  }
+}
+
+void TCPSegment::log(const char *fmt, ...) {
+	TTCN_Logger::begin_event(TTCN_DEBUG);
+	TTCN_Logger::log_event("TCPSegment: ");
+	va_list ap;
+	va_start(ap, fmt);
+	TTCN_Logger::log_event_va_list(fmt, ap);
+	va_end(ap); 
+	TTCN_Logger::end_event(); 
+}
+
+void TCPSegment::log() {
+  TTCN_Logger::begin_event(TTCN_DEBUG);
+  TTCN_Logger::log_event("-=> TCPSegment object: \n");
+  TTCN_Logger::log_event("address %p ¦n", this);
+  TTCN_Logger::log_event("IP src: %s ", inet_ntoa(ip_src));
+  TTCN_Logger::log_event("dst: %s\n", inet_ntoa(ip_dst));
+  TTCN_Logger::log_event("Port src: %d dst: %d\n", port_src, port_dst);
+  switch (seg_type) {
+    case UDP_SEG:
+      TTCN_Logger::log_event("UDP segment len:%zu\n", length);
+      break;
+    case TCP_SEG:
+      TTCN_Logger::log_event("TCP segment len:%zu seq:%lu ack:%lu", length, seq_num, ack_num);
+      if (syn) TTCN_Logger::log_event(" SYN\n"); else TTCN_Logger::log_event("\n");
+      break;
+  }
+  u_char* dataptr = (u_char*) payload;
+  for (u_int i=1; i<length+1; i++) {
+    TTCN_Logger::log_event("%.2x ", dataptr[i-1]);
+    if (i%16==0) TTCN_Logger::log_event("\n");
+  }
+  TTCN_Logger::log_event("\n");
+  TTCN_Logger::end_event();
+}
+
+
+////////////////////////////////////////////////////////////
+// DumpReader implementation
+////////////////////////////////////////////////////////////
+DumpReader::DumpReader () {
+  fp = NULL;
+  frameCounter = 1;
+}
+
+DumpReader::~DumpReader() {
+  if (fp) pcap_close(fp);
+}
+
+bool DumpReader::open(char* fname) {
+  if ( (fp = pcap_open_offline(fname, errbuf) ) == NULL) {
+    TTCN_warning("Error message received: %s", errbuf);
+    return false;
+  }
+  return true;
+}
+
+bool DumpReader::getNext() {
+  if (fp) {
+    genlog("DumpReader: Frame: %d", frameCounter); frameCounter++;
+    int res = pcap_next_ex( fp, &actHeader, &actData);
+    if ( res >= 0) return true;
+    else {
+        if(res == -1) {
+          TTCN_warning("Error reading the packets: %s", pcap_geterr(fp));
+        }
+      return false;
+    }
+  }
+  else {
+    TTCN_warning("No capture file is set");
+    return false;
+  }
+}
+
+bool DumpReader::setFilter(char* filter_script, bpf_u_int32 netmask) {
+  if (strlen(filter_script) != 0) {
+    if(pcap_compile(fp, &BPFcode, filter_script, 1, netmask)<0) {
+      TTCN_warning("Unable to compile the filter. check the syntax: %s", filter_script);
+      return false;
+    }
+    if(pcap_setfilter(fp, &BPFcode)<0) {
+      TTCN_warning("Error setting the filter: %s", filter_script);
+      return false;
+    }
+  }
+  return true;
+}
+
+bool DumpReader::getNextEthernet() {
+  bool ether_found = false;
+  while (!ether_found) {
+    if (this->getNext())
+    {
+      struct ::ether_header* ether_ptr;
+      ether_ptr = (struct ::ether_header *) actData;
+      if ( ntohs (ether_ptr->ether_type) == ETHERTYPE_IP )
+      {
+        ether_found = true;
+	actEthernetHeader = ether_ptr;
+	actEthernetData = (u_char*) actData;
+	actEthernetData += sizeof(struct ::ether_header);
+        return true;
+      }
+      else if ( ntohs (ether_ptr->ether_type) == PCAP_ETHERTYPE_VLAN8021Q )
+      {
+        struct vlan_header* vlan_ptr;
+        vlan_ptr = (struct vlan_header*) ((u_char*)actData + sizeof(struct ::ether_header));
+        if (ntohs(vlan_ptr->vlan_type) == ETHERTYPE_IP)
+        {
+          ether_found = true;
+	  actEthernetHeader = ether_ptr;
+	  actEthernetData = (u_char*) actData;
+	  actEthernetData += sizeof(struct ::ether_header) + sizeof(vlan_header);
+          return true;
+        }
+        else TTCN_warning("Not an IP datagram in VLAN 802.1Q packet");
+      }
+      else
+      {
+        TTCN_warning("Not an IP datagram or unknown Ethernet header");
+      }
+    }
+    else break;
+  }
+  return false;
+}
+
+
+bool DumpReader::getNextIP() {
+  free_ptr = false;
+  while (true) {
+    u_int hlen,version;
+    unsigned int len;
+    if (this->getNextEthernet()) {
+      struct ip_header* ip_ptr;
+      ip_ptr = (struct ip_header *) actEthernetData;
+      len = ntohs(ip_ptr->ip_len);
+      hlen = IP_HL(ip_ptr);
+      version = IP_V(ip_ptr);
+
+      /* It must be IPv4 */
+      if (version == 4) {
+        /* make sure that the packet is at least as long as the min IP header */
+        if (actHeader->caplen > sizeof(struct ip_header)) {
+        
+          /* check and see if we got everything.  NOTE: we must use
+           * ip_total_len after this, because we may have captured bytes
+           * beyond the end of the packet (e.g. ethernet padding). */
+          if (actHeader->caplen >= len) {
+            /* IP_sec decoding */
+            if(ip_ptr->ip_p == IPPROTO_ESP){
+              if((len-hlen*4)>10) {  // minimum size of the ESP 
+                unsigned int spi=(((unsigned int)actEthernetData[hlen*4])<<24)+(((unsigned int)actEthernetData[hlen*4+1])<<16)+(((unsigned int)actEthernetData[hlen*4+2])<<8)+actEthernetData[hlen*4+3];
+                ESP_obj *espobj;
+                if(act_pt->esp.find_esp(spi,espobj)){
+                  int icv_len=espobj->icv_fv.invoke(OCTETSTRING(hlen*4,(const unsigned char*)actEthernetData),
+                                                 OCTETSTRING(len-hlen*4,(const unsigned char*)actEthernetData+hlen*4),
+                                                 espobj->icv_data);
+                  if(icv_len>=0){ // valid ICV
+                    int proto=*((const unsigned char*)actEthernetData+len-icv_len);
+                    OCTETSTRING decrypted_data;
+                    if(espobj->decrypt_fv.invoke(OCTETSTRING(hlen*4,(const unsigned char*)actEthernetData),
+                                              OCTETSTRING(len-hlen*4-icv_len-1,(const unsigned char*)actEthernetData+hlen*4),
+                                              decrypted_data,
+                                              espobj->decrypt_data)){ 
+                      ip_ptr->ip_p=proto;
+                      ip_ptr->ip_len=htons(hlen*4+decrypted_data.lengthof());
+                      unsigned char* dataptr=(unsigned char*)actEthernetData+hlen*4;
+                      memcpy(actEthernetData+hlen*4,(const unsigned char*)decrypted_data,decrypted_data.lengthof());
+                      if(!act_pt->esp.match_esp(&(ip_ptr->ip_src),(dataptr[0]<<8)+dataptr[1],&(ip_ptr->ip_dst),(dataptr[2]<<8)+dataptr[3],espobj)){
+                        // The ESP registered for different address
+                        PCAPasp__Types::ASP__PCAP__ESP__Report ret_val;
+                        ret_val.status__code()=PCAPasp__Types::ESP__Status::ESP__WRONG__SPI;
+                        ret_val.spi().set_long_long_val(spi);
+                        ret_val.destinationIP()=inet_ntoa(ip_ptr->ip_dst);
+                        ret_val.destinationPort()=OMIT_VALUE;
+                        ret_val.sourceIP()=inet_ntoa(ip_ptr->ip_src);
+                        ret_val.sourcePort()=OMIT_VALUE;
+                        ret_val.payload__transport()=-1;
+                        act_pt->inc_msg(ret_val);
+
+                      }
+                    } else { // decrypt failed
+                      PCAPasp__Types::ASP__PCAP__ESP__Report ret_val;
+                      ret_val.status__code()=PCAPasp__Types::ESP__Status::ESP__DECRYPT__ERROR;
+                      ret_val.spi().set_long_long_val(spi);
+                      ret_val.destinationIP()=inet_ntoa(ip_ptr->ip_dst);
+                      ret_val.destinationPort()=OMIT_VALUE;
+                      ret_val.sourceIP()=inet_ntoa(ip_ptr->ip_src);
+                      ret_val.sourcePort()=OMIT_VALUE;
+                      ret_val.payload__transport()=-1;
+                      act_pt->inc_msg(ret_val);
+                    }
+                  } else {
+                    PCAPasp__Types::ASP__PCAP__ESP__Report ret_val;
+                    ret_val.status__code()=PCAPasp__Types::ESP__Status::ESP__ICV__ERROR;
+                    ret_val.spi().set_long_long_val(spi);
+                    ret_val.destinationIP()=inet_ntoa(ip_ptr->ip_dst);
+                    ret_val.destinationPort()=OMIT_VALUE;
+                    ret_val.sourceIP()=inet_ntoa(ip_ptr->ip_src);
+                    ret_val.sourcePort()=OMIT_VALUE;
+                    ret_val.payload__transport()=-1;
+                    act_pt->inc_msg(ret_val);
+                  }
+                } else { // no esp data found
+                  PCAPasp__Types::ASP__PCAP__ESP__Report ret_val;
+                  ret_val.status__code()=PCAPasp__Types::ESP__Status::ESP__NOT__DEFINED;
+                  ret_val.spi().set_long_long_val(spi);
+                  ret_val.destinationIP()=inet_ntoa(ip_ptr->ip_dst);
+                  ret_val.destinationPort()=OMIT_VALUE;
+                  ret_val.sourceIP()=inet_ntoa(ip_ptr->ip_src);
+                  ret_val.sourcePort()=OMIT_VALUE;
+                  ret_val.payload__transport()=-1;
+                  act_pt->inc_msg(ret_val);
+                }
+              }
+            } else {
+// Needs more test
+/*              unsigned char* dataptr=(unsigned char*)actEthernetData+hlen*4;
+              if(act_pt->esp.esp_exists( &(ip_ptr->ip_src),(dataptr[0]<<8)+dataptr[1],&(ip_ptr->ip_dst),(dataptr[2]<<8)+dataptr[3],ip_ptr->ip_p)){
+                // ESP data registered for this address
+                  PCAPasp__Types::ASP__PCAP__ESP__Report ret_val;
+                  ret_val.status__code()=PCAPasp__Types::ESP__Status::NOT__ESP__PACKET;
+                  ret_val.spi()=-1;
+                  ret_val.destinationIP()=inet_ntoa(ip_ptr->ip_dst);
+                  ret_val.destinationPort()=OMIT_VALUE;
+                  ret_val.sourceIP()=inet_ntoa(ip_ptr->ip_src);
+                  ret_val.sourcePort()=OMIT_VALUE;
+                  ret_val.payload__transport()=-1;
+                  act_pt->inc_msg(ret_val);
+              }*/
+            }
+          
+            if (!(ntohs(ip_ptr->ip_off) & (IP_OFFMASK | IP_MF))) { // no fragmentation
+            
+              /* We found it! */
+              actIPHeader = ip_ptr;
+	      actIPData = (u_char*) actEthernetData+(hlen << 2);
+              TTCN_warning("whole IP datagramm");
+              return true;
+            }
+            else{
+              actIPHeader = ip_ptr;
+	      actIPData = (u_char*) actEthernetData+(hlen << 2);
+              TTCN_warning("fragfmented IP datagramm");
+              if(fragment_buffer.add_ip_fragment(&actIPHeader,&actIPData)){
+                free_ptr = true;
+              TTCN_warning("last fragfment IP datagramm");
+                return true;
+              }
+            }
+          }
+          else TTCN_warning("Captured only %d bytes of %d-byte IP datagram", actHeader->caplen, len);
+        }
+        else TTCN_warning("Received truncated IP datagram!");
+      }
+      else TTCN_warning("Unknown IP version: %d",version);
+    }
+    else break;
+  }
+  return false;
+}
+
+TCPSegment* DumpReader::getNextSegment() {
+  bool segment_found = false;
+  TCPSegment* ret_seg = NULL;
+  while (!segment_found) {
+    if (getNextIP()) {
+      /* we're only looking for TCP or UDP; throw away everything else */
+      if (actIPHeader->ip_p == IPPROTO_TCP) {
+        segment_found = true;
+        actTCPHeader = (struct tcphdr *) actIPData;
+        
+        // calculate the total length of the TCP header including options
+        u_int tcp_header_len = TCP_OFF(actTCPHeader) * 4;
+        actTCPData = (u_char*) actTCPHeader + tcp_header_len;
+        
+        // compute the length of the TCP payload
+        u_int ip_total_len = ntohs(actIPHeader->ip_len);
+        u_int ip_header_len = IP_HL(actIPHeader) * 4;
+        u_int tcp_total_len = ip_total_len - ip_header_len;
+        u_int tcp_data_len = tcp_total_len - tcp_header_len;
+        
+        // we return with the needed information
+        ret_seg = new TCPSegment();
+        ret_seg->seg_type = TCP_SEG;
+        ret_seg->ip_src = actIPHeader->ip_src;
+        ret_seg->ip_dst = actIPHeader->ip_dst;
+        ret_seg->port_src = ntohs(actTCPHeader->th_sport);
+        ret_seg->port_dst = ntohs(actTCPHeader->th_dport);
+        ret_seg->seq_num = ntohl(actTCPHeader->th_seq);
+        ret_seg->ack_num = ntohl(actTCPHeader->th_ack);
+        if (actTCPHeader->th_flags & TH_SYN) ret_seg->syn = true;
+        if (actTCPHeader->th_flags & TH_FIN) ret_seg->fin = true;
+        ret_seg->put((char*)actTCPData,(size_t)tcp_data_len);
+        ret_seg->timestamp = (double)actHeader->ts.tv_sec + (double)actHeader->ts.tv_usec/1000000.0;
+        if(free_ptr){
+          free_ptr=false;
+          Free(actIPHeader);
+          Free(actIPData);
+        }
+        return ret_seg;
+      }
+      else if (actIPHeader->ip_p == IPPROTO_UDP) {
+        segment_found = true;
+        actUDPHeader = (struct udphdr *) actIPData;
+        actUDPData = ((u_char*) (actUDPHeader))+8;
+        
+        // compute the length of the UDP payload
+        u_int udp_total_len = ntohs(actUDPHeader->uh_ulen);
+        u_int udp_data_len = udp_total_len-8;
+        
+        // we return with the necessery information
+        ret_seg = new TCPSegment();
+        ret_seg->seg_type = UDP_SEG;
+        ret_seg->ip_src = actIPHeader->ip_src;
+        ret_seg->ip_dst = actIPHeader->ip_dst;
+        ret_seg->port_src = ntohs(actUDPHeader->uh_sport);
+        ret_seg->port_dst = ntohs(actUDPHeader->uh_dport);
+        ret_seg->put((char*) actUDPData, (size_t) udp_data_len);
+        ret_seg->timestamp = (double)actHeader->ts.tv_sec + (double)actHeader->ts.tv_usec/1000000.0;
+        if(free_ptr){
+          free_ptr=false;
+          Free(actIPHeader);
+          Free(actIPData);
+        }
+        return ret_seg;
+      }
+      else if (actIPHeader->ip_p == IPPROTO_SCTP) {
+        segment_found = true;
+        actSCTPHeader = (struct sctphdr *) actIPData;
+        
+        u_int sctp_header_len = 12;
+        actSCTPData = (u_char*) actSCTPHeader + sctp_header_len;
+        
+        // compute the length of the SCTP payload
+        u_int ip_total_len = ntohs(actIPHeader->ip_len);
+        u_int ip_header_len = IP_HL(actIPHeader) * 4;
+        u_int sctp_total_len = ip_total_len - ip_header_len;
+        u_int sctp_data_len = sctp_total_len - sctp_header_len;
+
+        ret_seg = new TCPSegment();
+        ret_seg->seg_type = SCTP_SEG;
+        ret_seg->ip_src = actIPHeader->ip_src;
+        ret_seg->ip_dst = actIPHeader->ip_dst;
+        ret_seg->port_src = ntohs(actSCTPHeader->sh_sport);
+        ret_seg->port_dst = ntohs(actSCTPHeader->sh_dport);
+        ret_seg->put((char*) actSCTPData, (size_t) sctp_data_len);
+        ret_seg->timestamp = (double)actHeader->ts.tv_sec + (double)actHeader->ts.tv_usec/1000000.0;
+        if(free_ptr){
+          free_ptr=false;
+          Free(actIPHeader);
+          Free(actIPData);
+        }
+        return ret_seg;
+      }
+    }
+    else break;
+  }
+  return NULL;
+}
+
+
+////////////////////////////////////////////////////////////
+// TCPBuffer implementation
+////////////////////////////////////////////////////////////
+TCPBuffer::TCPBuffer()
+{
+  length = 0;
+  buffer = NULL;
+  read_poi = buffer;
+  total_length = 0;
+  lost_length = 0;
+  closed = false;
+  close_sent = false;
+}
+
+TCPBuffer::~TCPBuffer()
+{
+  if (buffer) delete [] buffer;
+}
+
+void TCPBuffer::clear()
+{
+  log("cleared");
+  length = 0;
+  if (buffer) delete [] buffer;
+  buffer = NULL; read_poi = buffer;
+  closed = false;
+  close_sent = false;
+}
+
+bool TCPBuffer::ack(TCPSegment* segment)
+{
+  if (segment != NULL) {
+    if (segment->seg_type == TCP_SEG) {
+      //If an acknowledgement arrives that is larger than the last 
+      //stored byte in the buffer, than a TCP segment must have been lost previously.
+      //Because it would prevent the assembly of the stream,
+      //we hop the gap - that was created by the lost segment - by clearing the buffer
+      //It doesn't contain a valid message, because it would have already been processed then.
+      //and setting it to sequence number of the acknowledgement.
+      if (segment->ack_num > (seq_num + length+ closed)?1:0) {
+        TTCN_warning("Lost TCP segment detected!: Current sequence number: %lu, size: %zu, acknowledgement number: %lu, closed: %s", seq_num, length, segment->ack_num, closed?"true":"false");
+        // - The buffer should be cleared.
+        // - Saved segments must be dropped if their seq_num is smaller than the ack_num -> this one goes to the Peer class
+        clear();
+        lost_length+=(segment->ack_num-seq_num-length);
+        total_length+=(segment->ack_num-seq_num-length);
+        seq_num = segment->ack_num;
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
+void TCPBuffer::log_stat(){
+  log("Total processed octets, including lost octets: %lu",total_length);
+  log("Total lost octets: %lu",lost_length);
+  if(total_length>0){
+    log("Quality of the recovered stream: %lu%%",(total_length-lost_length)*100/total_length);
+  } else {
+    log("Quality of the recovered stream: N/A");
+  }
+}
+
+bool TCPBuffer::put(TCPSegment* segment)
+{
+  if (segment != NULL) {
+  
+    switch (segment->seg_type) {
+    
+      case TCP_SEG: {
+        log("tcp segment is: seq:%lu size:%ld fin:%s\n", seq_num, length, segment->fin?"yes":"no");
+        if (segment->fin) {closed=true;}
+        if ( (segment->seq_num <= seq_num + length ) && 
+             (segment->seq_num >= seq_num) &&
+             (segment->length > 0) ) { //The segment can be appended
+          size_t old_pos = get_pos();
+          size_t new_size = segment->seq_num - seq_num + segment->length;
+          unsigned char* tmp_buf = new unsigned char[new_size];
+          size_t from_orig_buffer = segment->seq_num - seq_num;
+          memcpy(tmp_buf, buffer, from_orig_buffer);
+          memcpy( (tmp_buf + from_orig_buffer), segment->payload, segment->length);
+          if (buffer) delete [] buffer;
+          buffer = tmp_buf;
+          length = new_size;
+          read_poi = buffer + old_pos;
+          timestamp = segment->timestamp;
+          total_length+=segment->length;
+          if (logging){
+          log("tcp segment is appended: seq:%lu size:%ld old_pos:%lu from_orig:%lu\n", seq_num, length, old_pos, from_orig_buffer);
+          }
+          if (segment) {
+            delete segment;
+            segment = NULL;
+          }
+          return true;
+        }
+        else return false;
+      }
+      break;
+
+      case UDP_SEG: {
+        if (segment->length>0) {
+          size_t old_pos = get_pos();
+          size_t new_size = length + segment->length;
+          char* tmp_buf = new char[new_size];
+          memcpy(tmp_buf, buffer, length);
+          memcpy(tmp_buf + length, segment->payload, segment->length);
+          delete [] buffer;
+          buffer = (unsigned char*) tmp_buf;
+          length = new_size;
+          read_poi = buffer + old_pos;
+          timestamp = segment->timestamp;
+          if (segment) {
+            delete segment;
+            segment = NULL;
+          }
+          if (logging) {
+          log("udp segment is appended: seq:%lu size:%ld\n", seq_num, length);
+          }
+          return true;
+        }
+        else return false;
+      }
+      break;
+    }
+  }
+  else return false;
+  return false;
+}
+
+void TCPBuffer::rewind()
+{
+  read_poi = buffer;
+}
+
+size_t TCPBuffer::get_pos()
+{
+  return read_poi - buffer;
+}
+
+void TCPBuffer::set_pos(size_t pos)
+{
+  if (pos > length) read_poi = buffer + length;
+  else read_poi = buffer + pos;
+}
+
+size_t TCPBuffer::get_len()
+{
+  return length;
+}
+
+unsigned char* TCPBuffer::get_data()
+{
+  return buffer;
+}
+
+size_t TCPBuffer::get_read_len()
+{
+  return length - get_pos();
+}
+
+unsigned char* TCPBuffer::get_read_data()
+{
+  return read_poi;
+}
+
+void TCPBuffer::cut()
+{
+  size_t new_size = get_read_len();
+  int seq_offset = get_pos();
+  char* tmp_buf = new char[new_size];
+  if (new_size) memcpy(tmp_buf, read_poi, new_size);
+  delete [] buffer;
+  seq_num = seq_num + seq_offset;
+  buffer = (unsigned char*) tmp_buf;
+  read_poi = buffer;
+  length = new_size;
+  if (logging) {
+    log("buffer is cut: seq:%lu size:%ld\n", seq_num, length);
+    dump();
+  }
+}
+
+void TCPBuffer::cut(size_t cut_bytes) {
+  if (cut_bytes > get_len()) cut_bytes = get_len();
+  size_t new_size = get_len()-cut_bytes;
+  int seq_offset = cut_bytes;
+  char* tmp_buf = new char[new_size];
+  if (new_size) memcpy(tmp_buf, buffer+cut_bytes, new_size);
+  delete [] buffer;
+  seq_num = seq_num + seq_offset;
+  buffer = (unsigned char*) tmp_buf;
+  read_poi = buffer;
+  length = new_size;
+  if (logging) {
+    log("buffer is cut: seq:%lu size:%ld\n", seq_num, length);
+    dump();
+  }
+}
+
+void TCPBuffer::log(const char *fmt, ...) { 
+	TTCN_Logger::begin_event(TTCN_DEBUG);
+	TTCN_Logger::log_event("TCPBuffer: ");
+	va_list ap;
+	va_start(ap, fmt);
+	TTCN_Logger::log_event_va_list(fmt, ap);
+	va_end(ap); 
+	TTCN_Logger::end_event(); 
+}
+
+void TCPBuffer::dump() {
+  TTCN_Logger::begin_event(TTCN_DEBUG);
+  TTCN_Logger::log_event("TCPBuffer: seq:%lu size:%d\n", seq_num, (int) length);
+  unsigned char* dataptr = buffer;
+  for (u_int i=1; i<length+1; i++) {
+    TTCN_Logger::log_event("%.2x ", dataptr[i-1]);
+    if (i%16==0) TTCN_Logger::log_event("\n");
+  }
+  TTCN_Logger::log_event("\n");
+  TTCN_Logger::end_event();
+}
+
+
+////////////////////////////////////////////////////////////
+// Vector implementation
+////////////////////////////////////////////////////////////
+template < class Type > Vector < Type >::Vector () {
+  size = 0;
+  actual = 0;
+  ar = NULL;
+}
+
+template < class Type > Vector < Type >::Vector (Vector < Type > &a) {
+  ar = new Type *[size = a.size];
+  for (int i = 0; i < a.size; i++)
+    ar[i] = a.ar[i];
+}
+
+template < class Type > Vector < Type >::~Vector () {
+  if (ar)
+    delete[]ar;
+}
+
+template < class Type > Vector < Type > &Vector < Type >::operator = (Vector < Type > &a) {
+  if (this != &a) {
+    if (ar)
+      delete[]ar;
+    ar = new Type *[size = a.size];
+    for (int i = 0; i < a.size; i++)
+      ar[i] = a.ar[i];
+  }
+  return *this;
+}
+
+template < class Type > Type & Vector < Type >::operator[](int idx) {
+  if (idx >= size) {
+    Type **nar = new Type *[idx + 1];
+    if (ar) {
+      for (int i = 0; i < size; i++)
+	nar[i] = ar[i];
+      for (int j = size; j <= idx; j++)
+	nar[j] = NULL;
+      delete[]ar;
+    }
+    size = idx + 1;
+    ar = nar;
+  }
+  actual = idx;
+  return *ar[idx];
+}
+
+template < class Type > Type * Vector < Type >::elementAt (int idx) {
+  actual = idx;
+  return &((*this)[idx]);
+}
+
+template < class Type > bool Vector < Type >::removeElementAt (int idx) {
+  if ((idx < size) && size > 1) {
+    Type **nar = new Type *[size - 1];
+    if (ar) {
+      for (int i = 0; i < idx; i++)
+	nar[i] = ar[i];
+      for (int j = idx; j < size - 1; j++)
+	nar[j] = ar[j + 1];
+      delete[]ar;
+    }
+    size = size - 1;
+    ar = nar;
+    actual = idx - 1;
+    return true;
+  }
+  else {
+    if (idx >= size)
+      return false;
+    if (size == 1) {
+      delete ar;
+      ar = NULL;
+      size = 0;
+      return true;
+    }
+  }
+  return false;
+}
+
+template < class Type > bool Vector < Type >::remove (int idx) {
+  return removeElementAt (idx);
+}
+
+template < class Type > int Vector < Type >::length () {
+  return size;
+}
+
+template < class Type > void Vector < Type >::append (Type * ptr) {
+  Type **nar = new Type *[size + 1];
+  if (ar) {
+    for (int i = 0; i < size; i++)
+      nar[i] = ar[i];
+    delete[]ar;
+  }
+  ar = nar;
+  ar[size] = ptr;
+  actual = size;
+  size++;
+}
+
+template < class Type > void Vector < Type >::addElement (Type * ptr) {
+  append (ptr);
+}
+
+template < class Type > bool Vector < Type >::remove (Type * ptr) {
+  for (int i = 0; i < size; i++) {
+    if (ar[i] == ptr && ptr != NULL) {
+      return removeElementAt (i);
+    }
+  }
+  return false;
+}
+
+template < class Type > bool Vector < Type >::removeElement (Type * ptr) {
+  return remove (ptr);
+}
+
+template < class Type > bool Vector < Type >::removeCurrent () {
+  return removeElementAt (actual);
+}
+
+template < class Type > bool Vector < Type >::removeRef (Type * ptr) {
+  return remove (ptr);
+}
+
+template < class Type > int Vector < Type >::find (Type * ptr) {
+  for (int i = 0; i < size; i++) {
+    if (ar[i] == ptr) {
+      actual = i;
+      return i;
+    }
+  }
+  return -1;
+}
+
+template < class Type > Type * Vector < Type >::first () {
+  if (ar) {
+    actual = 0;
+    return ar[0];
+  }
+  else
+    return NULL;
+}
+
+template < class Type > Type * Vector < Type >::last () {
+  if (ar) {
+    actual = size - 1;
+    return ar[size - 1];
+  }
+  else
+    return NULL;
+}
+
+template < class Type > Type * Vector < Type >::next () {
+  if (ar) {
+    actual++;
+    if (actual < size)
+      return ar[actual];
+    else {
+      actual = 0;
+      return NULL;
+    }
+  }
+  else
+    return NULL;
+}
+
+template < class Type > Type * Vector < Type >::current () {
+  if (ar) {
+    if (actual < size) {
+      return ar[actual];
+    }  else
+    return NULL;
+  }
+  else
+    return NULL;
+}
+
+template < class Type > Type * Vector < Type >::prev () {
+  if (ar) {
+    if ((actual > 1) && (actual < size)) {
+      actual--;
+      return ar[actual];
+    }
+  }
+  else
+    return NULL;
+}
+
+template < class Type > bool Vector < Type >::isEmpty () {
+  if (size == 0){
+    return true;}
+  return false;
+}
+
+template < class Type > void Vector < Type >::destruct () {
+  if (ar)
+    for (int i = 0; i < size; i++) {
+      delete ar[i];
+    }
+  if (ar) delete[]ar;
+  size = 0; actual = 0;
+  ar = NULL;
+}
+
+
+////////////////////////////////////////////////////////////
+// Peer implementation
+////////////////////////////////////////////////////////////
+Peer::Peer()
+{
+  protocol_type = NO_PROTOCOL;
+  out_of_sync = true;
+  is_sctp = false;
+}
+
+Peer::Peer(TCPSegment* segment)
+{
+  if (segment != NULL) {
+    port_src = segment->port_src;
+    port_dst = segment->port_dst;
+    ip_src = segment->ip_src;
+    ip_dst = segment->ip_dst;
+    if(segment->seg_type!=SCTP_SEG){
+      is_sctp=false;
+      if (segment->syn) {
+        tcp_buf.seq_num = segment->seq_num + 1;
+      }
+      else {
+        tcp_buf.seq_num = segment->seq_num;
+      }
+    } else {
+//      stream_list.add_segment_to_stream(segment);
+      is_sctp= true;
+    }
+    protocol_type = segment->protocol_type;
+    transport_type = segment->seg_type;
+    out_of_sync = true;
+    log("created");
+  }
+}
+
+Peer::~Peer()
+{
+  seg_list.destruct();
+}
+
+void Peer::reset()
+{
+  tcp_buf.clear();
+  seg_list.destruct();
+  out_of_sync = true;
+  log("reset");
+}
+
+void Peer::init(TCPSegment* segment)
+{
+  if (segment != NULL) {
+    port_src = segment->port_src;
+    port_dst = segment->port_dst;
+    ip_src = segment->ip_src;
+    ip_dst = segment->ip_dst;
+    if(segment->seg_type!=SCTP_SEG){
+      is_sctp=false;
+      if (segment->syn) {
+        tcp_buf.seq_num = segment->seq_num + 1;
+      }
+      else {
+        tcp_buf.seq_num = segment->seq_num;
+      }
+    } else {
+//      stream_list.add_segment_to_stream(segment);
+      is_sctp= true;
+    }
+    protocol_type = segment->protocol_type;
+    transport_type = segment->seg_type;
+    out_of_sync = true;
+    tcp_buf.put(segment);
+    log("initialized");
+  }
+}
+
+bool Peer::compare(TCPSegment* segment)
+{
+  if (segment != NULL)
+    if ( (port_src == segment->port_src) && (port_dst == segment->port_dst) )
+      if (memcmp(&ip_src,&(segment->ip_src),sizeof(struct in_addr))==0)
+        if (memcmp(&ip_dst,&(segment->ip_dst),sizeof(struct in_addr))==0)
+          return true;
+
+
+  return false;
+}
+
+bool Peer::sentBy(TCPSegment* segment)
+{
+  if (segment != NULL)
+    if ( (port_src == segment->port_dst) && (port_dst == segment->port_src) )
+      if (memcmp(&ip_src,&(segment->ip_dst),sizeof(struct in_addr))==0)
+        if (memcmp(&ip_dst,&(segment->ip_src),sizeof(struct in_addr))==0)
+          return true;
+
+  return false;
+}
+
+int Peer::get_msg_len(){
+  if(is_sctp){
+    if(has_message()){
+      return get_first_sctp_data_len();
+    }
+  } else if(!out_of_sync){
+    tf__getMsgLen getlen=p_data.get_f_getMsgLen(protocol_type);
+    return getlen.invoke(
+        OCTETSTRING(tcp_buf.get_read_len(),tcp_buf.get_read_data()),
+        tcp_buf.closed,
+        transport_type
+      );
+  }
+  return -1;
+}
+
+bool Peer::ack(TCPSegment* segment)
+{
+  if (segment != NULL) {
+    //In case the acknowledgment is larger than the last stored byte
+    //the tcp_buf.ack clears the buffer and sets the seq_num to the ack_num
+    if(!is_sctp){
+      if (!tcp_buf.ack(segment)) {
+        TCPSegment* seg;
+
+        log("acknowledgement recovering: out of sync");
+        out_of_sync = true;
+        //First we locate that saved segment which has the smallest seq_num
+        TCPSegment* first_saved_segment = NULL;
+        int first_saved_segment_idx = 0;
+
+        if (seg_list.length() > 0) {
+
+          for (int i=0; i<seg_list.length(); i++) {
+            seg = seg_list.elementAt(i);
+            if (first_saved_segment) {
+              if (seg->seq_num < first_saved_segment->seq_num) {
+                first_saved_segment = seg;
+                first_saved_segment_idx = i;
+              }
+            }
+            else {
+              first_saved_segment = seg;
+              first_saved_segment_idx = i;
+            }
+          }
+
+          //Then we put it into the buffer:
+          if (first_saved_segment) {
+            seg_list.removeElementAt(first_saved_segment_idx);
+            tcp_buf.seq_num = first_saved_segment->seq_num;
+            tcp_buf.put(first_saved_segment);
+
+            //Next we try to put every other saved segments into the buffer
+            //if there is any
+            if (!seg_list.isEmpty()) {
+              log("number of unprocessed segments: %d", seg_list.length());
+              //Let's try to put the unprocessed segments into the buffer:
+              bool successful_insertion = false;
+              do {
+                successful_insertion = false;
+                TCPSegment* seg = NULL;
+                for (int i=0; i<seg_list.length(); i++) {
+                  seg = seg_list.elementAt(i);
+                  log("Trying to insert: seq_num: %lu, length: %d", seg->seq_num, seg->length);
+                  if (tcp_buf.put(seg)) {
+                    log("unprocessed segment inserted");
+                    successful_insertion = true;
+                    //delete seg; seg = NULL;
+                    seg_list.removeElementAt(i);
+                  }
+                  // If we won't be able to put it, we drop it
+                  else if (seg->seq_num < tcp_buf.seq_num) {
+                    TTCN_warning("Unprocessed segment dropped during ack recovering: IP src: %s, dst: %s; Port src: %d, dst: %d seq: %lu",
+                    inet_ntoa(seg->ip_src),
+                    inet_ntoa(seg->ip_dst),
+                    seg->port_src,
+                    seg->port_dst,
+                    seg->seq_num
+                    );
+                    seg_list.removeElementAt(i);
+                    delete seg; seg = NULL;
+                  }
+                }
+              }
+              while (successful_insertion && seg_list.length());
+            }
+          }
+          tcp_buf.dump();
+          log("out_of_sync: %d",out_of_sync);
+          log("protocol_type: %d",protocol_type);
+          if (out_of_sync ) {
+            out_of_sync = !tryToResync();
+            log("out_of_sync: %d",out_of_sync);
+            tcp_buf.dump();
+          }
+        }
+        else {
+          tcp_buf.seq_num = segment->ack_num;
+          TCPSegment* seg = NULL;
+          for (int i=0; i<seg_list.length(); i++) {
+            seg = seg_list.elementAt(i);
+            if (seg->seq_num < tcp_buf.seq_num) {
+              TTCN_warning("Unprocessed segment dropped during ack recovering: IP src: %s, dst: %s; Port src: %d, dst: %d seq: %lu",
+              inet_ntoa(seg->ip_src),
+              inet_ntoa(seg->ip_dst),
+              seg->port_src,
+              seg->port_dst,
+              seg->seq_num
+              );
+              seg_list.removeElementAt(i);
+              delete seg; seg = NULL;
+            }
+          }
+        }
+        return false;
+      }
+    } else {
+      stream_list.ack(segment);
+    }
+  }
+  return true;
+}
+
+void Peer::put(TCPSegment* segment)
+{
+  if (segment != NULL) {
+    if (compare(segment) && ((segment->length > 0) || segment->fin)) {
+      if(is_sctp){
+        stream_list.add_segment_to_stream(segment);
+        delete segment;
+        segment = NULL;
+      } else {
+        if (tcp_buf.put(segment)) {
+          log("segment inserted");
+          if (!seg_list.isEmpty()) {
+            log("number of unprocessed segments: %d", seg_list.length());
+            //Let's try to put the unprocessed segments into the buffer:
+            bool successful_insertion = false;
+            do {
+              successful_insertion = false;
+              TCPSegment* seg = NULL;
+              for (int i=0; i<seg_list.length(); i++) {
+                seg = seg_list.elementAt(i);
+                log("Trying to insert: seq_num: %lu, length: %d", seg->seq_num, seg->length);
+                if (tcp_buf.put(seg)) {
+                  log("unprocessed segment inserted");
+                  successful_insertion = true;
+                  seg_list.removeElementAt(i);
+                }
+                // If we won't be able to put it, we drop it
+                else if (seg->seq_num < tcp_buf.seq_num) {
+                  TTCN_warning("Unprocessed TCP segment is dropped: IP src: %s, dst: %s; Port src: %d, dst: %d seq: %lu",
+                    inet_ntoa(seg->ip_src),
+                    inet_ntoa(seg->ip_dst),
+                    seg->port_src,
+                    seg->port_dst,
+                    seg->seq_num
+                  );
+                  seg_list.removeElementAt(i);
+                  delete seg; seg = NULL;
+                }
+              }
+            }
+            while (successful_insertion && seg_list.length());
+          }
+          tcp_buf.dump();
+          log("out_of_sync: %d",out_of_sync);
+          log("protocol_type: %d",protocol_type);
+          if (out_of_sync ) {
+            out_of_sync = !tryToResync();
+            log("out_of_sync: %d",out_of_sync);
+            tcp_buf.dump();
+          }
+        }
+        else {
+          if (segment->seq_num < tcp_buf.seq_num) {
+            TTCN_warning("TCP segment is dropped: IP src: %s, dst: %s; Port src: %d, dst: %d seq: %lu",
+              inet_ntoa(segment->ip_src),
+              inet_ntoa(segment->ip_dst),
+              segment->port_src,
+              segment->port_dst,
+              segment->seq_num
+            );
+            delete segment; segment = NULL;
+          }
+          else if (segment->length > 0) {
+            log("segment saved as unprocessed");
+            seg_list.addElement(segment);
+          } else {delete segment; segment = NULL;}
+        }
+      } // is_sctp
+    } else {delete segment; segment = NULL;} // end of if (compare(segment) && (segment->length > 0))
+  } // end of if (segment != NULL)
+}
+
+
+
+bool Peer::tryToResync()
+{
+  log("trying to resync");
+  bool found = false;
+  if (tcp_buf.get_read_len()>0) {
+    tf__getMsgStartPos getstartpos=p_data.get_f_getMsgStartPos(protocol_type);
+    int startpos=getstartpos.invoke(
+        OCTETSTRING(tcp_buf.get_read_len(),tcp_buf.get_read_data()),
+        tcp_buf.closed,
+        transport_type
+      );
+    if(startpos>=0){
+      found=true;
+      tcp_buf.set_pos(tcp_buf.get_pos()+startpos);
+      log("syncronized, Protocol: %d, position %d",protocol_type,startpos);
+    } else {
+      log("not syncronized, Protocol: %d, position %d",protocol_type,startpos);
+    }
+  }
+  return found;
+}
+
+bool Peer::has_message(){
+  return stream_list.has_message();
+}
+unsigned char* Peer::get_first_sctp_data(){
+  return stream_list.get_first_sctp_data();
+}
+size_t Peer::get_first_sctp_data_len(){
+  return stream_list.get_first_sctp_data_len();
+}
+double Peer::get_first_sctp_timestamp(){
+  return stream_list.get_first_sctp_timestamp();
+}
+void Peer::delete_first_sctp_message(){
+  return stream_list.delete_first_sctp_message();
+}
+
+void Peer::log_stat(){
+  log("Connection statistic:");
+  if(is_sctp){
+    stream_list.log_stat();
+  } else {
+    tcp_buf.log_stat();
+  }
+}
+
+
+void Peer::dump() {
+  if(is_sctp){
+    stream_list.dump();
+  } else {
+    log("prot_type: %d, seg_list_length: %d", protocol_type, seg_list.length());
+    tcp_buf.dump();
+  }
+}
+
+void Peer::log(const char *fmt, ...) {
+  if (logging) {
+    TTCN_Logger::begin_event(TTCN_DEBUG);
+    TTCN_Logger::log_event("Peer (%d->%d): ", port_src, port_dst);
+    va_list ap;
+    va_start(ap, fmt);
+    TTCN_Logger::log_event_va_list(fmt, ap);
+    va_end(ap); 
+    TTCN_Logger::end_event();
+  }
+}
+
+
+////////////////////////////////////////////////////////////
+// PeerList implementation
+////////////////////////////////////////////////////////////
+PeerList::PeerList()
+{
+  tcp = true;
+}
+
+PeerList::~PeerList()
+{
+  peer_list.destruct();
+}
+
+bool PeerList::sendSegmentToPeer(TCPSegment* segment)
+{
+  bool ret = true;
+  if (segment!=NULL) {
+    //If it is a TCP segment, we examine if the acknowledgement
+    //number of the segment in order to detect lost segments
+    if (segment->seg_type == TCP_SEG || segment->seg_type == SCTP_SEG) {
+      Peer* other_peer;
+      other_peer = getOtherPeer(segment);
+      if (other_peer)
+        if (!other_peer->ack(segment))
+          ret = false;
+    }
+      
+    //Sending the segment to the destination peer
+    Peer* act_peer;
+    act_peer = getPeer(segment);
+    if (act_peer) {
+      if (segment->syn) {
+        // We have detected this stream already, and now it is
+        // re-initialized
+        log("sendSegmentToPeer: re-initialization");
+        act_peer->reset();
+        act_peer->init(segment);
+      }
+      else {
+        // We have already detected this stream and now we send it
+        // the actual segment
+        log("sendSegmentToPeer: sending to corresponding peer");
+        act_peer->put(segment);
+      }
+    }
+    else {
+      // We haven't detected this stream yet, therefore we must create the 
+      // Peer object that will handle this.
+      log("sendSegmentToPeer: creating new stream");
+      addPeer(segment);
+    }
+  }
+  return ret; // return false if there is an acknoledgement mismatch
+}
+
+void PeerList::addPeer(TCPSegment* segment)
+{
+  Peer* new_peer;
+  new_peer = new Peer(segment);
+  peer_list.addElement(new_peer);
+  new_peer->put(segment);
+}
+
+Peer* PeerList::getPeer(TCPSegment* segment)
+{
+  Peer* peer_poi = NULL;
+  for (int i=0; i<peer_list.length(); i++) {
+    peer_poi = peer_list.elementAt(i);
+    if (peer_poi->compare(segment)) return peer_poi;
+  }
+  return NULL;
+}
+
+void PeerList::log_stat(){
+  Peer* peer_poi = NULL;
+  for (int i=0; i<peer_list.length(); i++) {
+    peer_poi = peer_list.elementAt(i);
+    peer_poi->log_stat();
+  }
+}
+
+
+Peer* PeerList::getOtherPeer(TCPSegment* segment)
+{
+  Peer* peer_poi = NULL;
+  for (int i=0; i<peer_list.length(); i++) {
+    peer_poi = peer_list.elementAt(i);
+    if (peer_poi->sentBy(segment)) return peer_poi;
+  }
+  return NULL;
+}
+
+void PeerList::setType(bool t) {
+  tcp = t;
+}
+
+Peer* PeerList::elementAt(int i) {
+  return peer_list.elementAt(i);
+}
+
+int PeerList::length() {
+  return peer_list.size;
+}
+
+void PeerList::dump() {
+  log("#of peers: %d",peer_list.size);
+  Peer* peer_poi;
+  for (int i=0; i<peer_list.length(); i++) {
+    peer_poi = peer_list.elementAt(i);
+    peer_poi->dump();
+  }
+}
+
+void PeerList::log(const char *fmt, ...) {
+  
+  if (logging) {
+    TTCN_Logger::begin_event(TTCN_DEBUG);
+    TTCN_Logger::log_event("PeerList (");
+    if (tcp)
+      TTCN_Logger::log_event("TCP");
+    else
+      TTCN_Logger::log_event("UDP or SCTP");
+    TTCN_Logger::log_event("): ");
+    va_list ap;
+    va_start(ap, fmt);
+    TTCN_Logger::log_event_va_list(fmt, ap);
+    va_end(ap); 
+    TTCN_Logger::end_event();
+  }
+}
+
+
+////////////////////////////////////////////////////////////
+// FilterEntry implementation
+////////////////////////////////////////////////////////////
+FilterEntry::FilterEntry(int protocol, struct in_addr sip, bool sip_all, struct in_addr dip, unsigned int rport)
+{
+  protocol_type = protocol;
+  ip_src = sip;
+  ip_src_all = sip_all;
+  ip_dst = dip;
+  port_dst = rport;
+}
+
+FilterEntry::~FilterEntry() {
+}
+
+bool FilterEntry::compare(TCPSegment* seg) {
+  if (seg != NULL) {
+    if ( (port_dst == seg->port_dst) )
+    {
+      if (ip_src_all)
+        if (memcmp(&ip_dst,&(seg->ip_dst),sizeof(struct in_addr))==0)
+          return true;
+        else return false;
+      else if (memcmp(&ip_src,&(seg->ip_src),sizeof(struct in_addr))==0)
+        if (memcmp(&ip_dst,&(seg->ip_dst),sizeof(struct in_addr))==0)
+          return true;
+        else return false;
+      else return false;
+    }
+    else if ( (port_dst == seg->port_src) )
+    {
+      if (ip_src_all)
+        if (memcmp(&ip_dst,&(seg->ip_src),sizeof(struct in_addr))==0)
+          return true;
+        else return false;
+      else if (memcmp(&ip_src,&(seg->ip_dst),sizeof(struct in_addr))==0)
+        if (memcmp(&ip_dst,&(seg->ip_src),sizeof(struct in_addr))==0)
+          return true;
+        else return false;
+      else return false;
+    }
+    else return false;
+  }
+  else return false;
+}
+
+void FilterEntry::log(const char *fmt, ...) { 
+  TTCN_Logger::begin_event(TTCN_DEBUG);
+  TTCN_Logger::log_event("FilterEntry: ");
+  va_list ap;
+  va_start(ap, fmt);
+  TTCN_Logger::log_event_va_list(fmt, ap);
+  va_end(ap); 
+  TTCN_Logger::end_event();
+}
+
+
+////////////////////////////////////////////////////////////
+// FilterTable implementation
+////////////////////////////////////////////////////////////
+FilterTable::FilterTable() {}
+
+FilterTable::~FilterTable()
+{
+  entry_list.destruct();
+}
+
+void FilterTable::addEntry(int protocol, struct in_addr sip, bool sip_all, struct in_addr dip, unsigned int rport)
+{
+  FilterEntry* new_entry;
+  new_entry = new FilterEntry(protocol, sip, sip_all, dip, rport);
+  entry_list.addElement(new_entry);
+  log("adding prot: %d, rPort:%d, sIP:%s", protocol, rport, inet_ntoa(sip));
+  log(" dIP:%s", inet_ntoa(dip));
+}
+
+int FilterTable::filter(TCPSegment* segment)
+{
+  if (segment) {
+    if (noFilter) return 1;
+    FilterEntry* entry_poi = NULL;
+    for (int i=0; i<entry_list.length(); i++) {
+      entry_poi = entry_list.elementAt(i);
+      if (entry_poi->compare(segment)) return entry_poi->protocol_type;
+    }
+  }
+  return NO_PROTOCOL;
+}
+
+void FilterTable::log(const char *fmt, ...) {
+  if (logging) {
+    TTCN_Logger::begin_event(TTCN_DEBUG);
+    TTCN_Logger::log_event("FilterTable: ");
+    va_list ap;
+    va_start(ap, fmt);
+    TTCN_Logger::log_event_va_list(fmt, ap);
+    va_end(ap); 
+    TTCN_Logger::end_event();
+  }
+}
+
+
+////////////////////////////////////////////////////////////
+// Fragment implementation
+////////////////////////////////////////////////////////////
+IP_fragment::IP_fragment(){
+  id=0;
+  buffer=NULL;
+  header=NULL;
+  buffer_len=0;
+  data_len=0;
+}
+
+IP_fragment::~IP_fragment(){
+  if(buffer) Free(buffer);
+  if(header) Free(header);
+  holes.destruct();
+}
+
+void IP_fragment::clear(){
+  if(buffer) Free(buffer);
+  if(header) Free(header);
+  id=0;
+  buffer=NULL;
+  header=NULL;
+  buffer_len=0;
+  data_len=0;
+  holes.destruct();
+}
+
+bool IP_fragment::add_fragment(struct ip_header* IPHeader,
+                             u_char* IPData){
+  Holes_list new_holes;
+  u_int16_t fr_first=(ntohs(IPHeader->ip_off) & IP_OFFMASK)<<3;
+  u_int16_t fr_len=ntohs(IPHeader->ip_len)-(IP_HL(IPHeader)<<2);
+  u_int16_t fr_last=fr_first+fr_len-1;
+               
+  if(holes.isEmpty()){ // first arrived fragment
+   id=IPHeader->ip_id;
+    Hole* new_hole=new Hole(0,c_infinite);
+    holes.append(new_hole);
+  }
+  if(buffer_len<fr_last){
+    buffer=(u_char*)Realloc(buffer,(fr_last+1)*sizeof(u_char));
+    buffer_len=fr_last+1;
+  }
+  memcpy(buffer+fr_first,IPData,fr_len);
+
+  if(!fr_first){ // first fragment, store header
+    header=(ip_header*)Malloc(sizeof(ip_header));
+    memcpy(header,IPHeader,sizeof(ip_header));
+  }
+  
+  Hole* hole_ptr=holes.first();
+  while(hole_ptr){
+    if(fr_first<=hole_ptr->last && fr_last>=hole_ptr->first){
+      holes.removeCurrent();
+      if(fr_first>hole_ptr->first){
+        Hole* new_hole=new Hole(hole_ptr->first,fr_first-1);
+        new_holes.append(new_hole);
+      }
+      if(fr_last<hole_ptr->last && (ntohs(IPHeader->ip_off) & IP_MF)){
+        Hole* new_hole=new Hole(fr_last+1,hole_ptr->last);
+        new_holes.append(new_hole);
+      }
+      delete hole_ptr;
+    }
+    hole_ptr=holes.next();
+  }
+  if(!new_holes.isEmpty ()){
+    for(int a=0;a<new_holes.length();a++) holes.append(&new_holes[a]);
+  }
+  
+  return holes.isEmpty ();
+}
+
+
+bool IP_fragment::get_fragment(struct ip_header** IPHeader,
+                             u_char** IPData){
+  if(header){
+    *IPHeader=(ip_header*)Malloc(sizeof(ip_header));
+    memcpy(*IPHeader,header,sizeof(ip_header));
+  } 
+  if(buffer_len){
+    (*IPHeader)->ip_len=htons(buffer_len+(IP_HL(*IPHeader)<<2));
+    *IPData=(u_char*)Malloc(buffer_len*sizeof(u_char));
+    memcpy(*IPData,buffer,buffer_len*sizeof(u_char));
+  }
+  return header && holes.isEmpty();
+}
+
+IP_fragments::IP_fragments(){
+}
+
+IP_fragments::~IP_fragments(){
+ clear();
+}
+
+void IP_fragments::clear(){
+  packet_list.destruct();
+}
+
+bool IP_fragments::check(){
+  return !packet_list.isEmpty();
+}
+
+bool IP_fragments::add_ip_fragment(struct ip_header** IPHeader,
+                             u_char** IPData){
+  int packed_id;
+  for(packed_id=0;packed_id<packet_list.length();packed_id++){
+    if(packet_list[packed_id].id==(*IPHeader)->ip_id) break;
+  }
+
+  if(packed_id==packet_list.length()){
+    IP_fragment* new_fr=new IP_fragment;
+    packet_list.append(new_fr);
+  }
+
+  if(packet_list[packed_id].add_fragment(*IPHeader,*IPData)){
+    packet_list[packed_id].get_fragment(IPHeader,IPData);
+    IP_fragment* fr= &packet_list[packed_id];
+    packet_list.removeElementAt(packed_id);
+    delete fr;
+    return true;
+  }
+  return false;
+
+}
+
+void decode_sctp(TCPSegment* segment, SCTP_chunk_list& list){
+
+  unsigned char* payload=segment->payload;
+  int length=segment->length;
+  int type;
+  unsigned char flags;
+  int idx=0;
+  size_t chunk_length;
+  while(length>0){
+    type=payload[0];
+    flags=payload[1];
+    chunk_length=((size_t)(payload[2])<<8)+payload[3];
+    switch(type){
+      case 0: // Data
+genlog("Data segment");
+        list.append(new SCTP_chunk);
+        list.current()->type=type;
+genlog("Data segment flags %Xd",flags);
+        list.current()->flags=flags;
+        list.current()->length=chunk_length;
+        list.current()->data.data.tsn=(payload[4]<<24)+(payload[5]<<16)+(payload[6]<<8)+payload[7];
+genlog("Data segment tsn %Xd",list.current()->data.data.tsn);
+        list.current()->data.data.sid=(payload[8]<<8)+payload[9];
+genlog("Data segment sid %Xd",list.current()->data.data.sid);
+        list.current()->data.data.ssn=(payload[10]<<8)+payload[11];
+genlog("Data segment ssn %Xd",list.current()->data.data.ssn);
+        list.current()->data.data.ppid=(payload[12]<<24)+(payload[13]<<16)+(payload[14]<<8)+payload[15];
+genlog("Data segment ppid %Xd",list.current()->data.data.ppid);
+        list.current()->data.data.begin=(flags&0x02);
+genlog("Data segment begin %Xd",list.current()->data.data.begin);
+        list.current()->data.data.end=(flags&0x01);
+genlog("Data segment end %Xd",list.current()->data.data.end);
+        list.current()->data.data.length=chunk_length-16;
+genlog("Data segment length %d",list.current()->data.data.length);
+        list.current()->data.data.data=payload+16;
+        idx++;
+        break;
+      case 3: // SACK
+        list.append(new SCTP_chunk);
+        list.current()->type=type;
+        list.current()->flags=flags;
+        list.current()->length=chunk_length;
+        list.current()->data.ack_tsn=(payload[4]<<24)+(payload[5]<<16)+(payload[6]<<8)+payload[7];
+        idx++;
+        break;
+      default:
+        break;
+    }
+    chunk_length=((chunk_length+3)/4)*4;
+    length-=chunk_length;
+    payload+=chunk_length;
+  }
+}
+
+SCTP_Stream_list::SCTP_Stream_list(){
+acked_tsn=0;
+}
+
+SCTP_Stream_list::~SCTP_Stream_list(){
+  streams.destruct();
+}
+
+void SCTP_Stream_list::add_segment_to_stream(TCPSegment* segment){
+genlog("SCTP_Stream_list::add_segment_to_stream");
+  SCTP_chunk_list chunk_list;
+  decode_sctp(segment, chunk_list);
+  for(int i=0;i<chunk_list.length();i++){
+    if(chunk_list[i].type==0){ // SCTP data chunk
+genlog("SCTP_Stream_list::add_segment_to_stream SCTP data chunk");
+      if(acked_tsn<chunk_list[i].data.data.tsn){
+        if(!add_to_stream(chunk_list[i].data.data, segment->timestamp)){
+          add_stream(chunk_list[i].data.data,segment->timestamp);
+        }
+      }
+    }
+  }
+  chunk_list.destruct();
+genlog("SCTP_Stream_list::add_segment_to_stream end");
+}
+
+void SCTP_Stream_list::ack(TCPSegment* segment){
+genlog("SCTP_Stream_list::ack");
+  SCTP_chunk_list chunk_list;
+  decode_sctp(segment, chunk_list);
+  for(int i=0;i<chunk_list.length();i++){
+    if(chunk_list[i].type==3){
+      if(acked_tsn<chunk_list[i].data.ack_tsn){
+        acked_tsn=chunk_list[i].data.ack_tsn;
+        for(int k=0;k<streams.length();k++){
+          streams[k].ack_message(chunk_list[i].data.ack_tsn);
+        }
+      }
+    }
+  }
+  chunk_list.destruct();
+genlog("SCTP_Stream_list::ack end");
+}
+
+
+bool SCTP_Stream_list::add_to_stream(SCTP_data_chunk &data, double timestamp){
+genlog("SCTP_Stream_list::add_to_stream");
+  for(int i=0;i<streams.length();i++){
+    if(streams[i].stream_id==data.sid){
+      streams[i].add_segment(data,timestamp);
+genlog("SCTP_Stream_list::add_to_stream true");
+      return true;
+     }
+  }
+genlog("SCTP_Stream_list::add_to_stream false");
+  return false;
+}
+
+bool SCTP_Stream_list::has_message(){
+genlog("SCTP_Stream_list::has_message");
+  for(int i=0;i<streams.length();i++){
+    if(streams[i].has_message()){
+genlog("SCTP_Stream_list::has_message true");
+      return true;
+    }
+  }
+genlog("SCTP_Stream_list::has_message false");
+  return false;
+}
+
+unsigned char* SCTP_Stream_list::get_first_sctp_data(){
+  int idx=0;
+  double timestamp=-1.0;
+  for(int i=0;i<streams.length();i++){
+    if(streams[i].has_message() && (timestamp==-1.0 || timestamp>streams[i].get_first_ts())){
+      timestamp=streams[i].get_first_ts();
+      idx=i;
+    }
+  }
+  return streams[idx].get_first_message_data();
+}
+
+size_t SCTP_Stream_list::get_first_sctp_data_len(){
+  int idx=0;
+  double timestamp=-1.0;
+  for(int i=0;i<streams.length();i++){
+    if(streams[i].has_message() && (timestamp==-1.0 || timestamp>streams[i].get_first_ts())){
+      timestamp=streams[i].get_first_ts();
+      idx=i;
+    }
+  }
+  return streams[idx].get_first_message_data_len();
+}
+
+
+double SCTP_Stream_list::get_first_sctp_timestamp(){
+//  int idx=0;
+  double timestamp=-1.0;
+  for(int i=0;i<streams.length();i++){
+    if(streams[i].has_message() && (timestamp==-1.0 || timestamp>streams[i].get_first_ts())){
+      timestamp=streams[i].get_first_ts();
+//      idx=i;
+    }
+  }
+  return timestamp;
+}
+
+void SCTP_Stream_list::delete_first_sctp_message(){
+  int idx=0;
+  double timestamp=-1.0;
+  for(int i=0;i<streams.length();i++){
+    if(streams[i].has_message() && (timestamp==-1.0 || timestamp>streams[i].get_first_ts())){
+      timestamp=streams[i].get_first_ts();
+      idx=i;
+    }
+  }
+  streams[idx].delete_first_message();
+}
+
+void SCTP_Stream_list::add_stream(SCTP_data_chunk &data, double timestamp){
+  SCTP_stream *new_stream= new SCTP_stream;
+  streams.append(new_stream);
+  new_stream->add_segment(data,timestamp);
+}
+
+
+void SCTP_Stream_list::log_stat(){
+}
+
+void SCTP_Stream_list::dump(){
+}
+
+SCTP_stream::SCTP_stream(){
+  stream_id=0;
+
+
+}
+
+SCTP_stream::~SCTP_stream(){
+  message_list.destruct();
+}
+
+void SCTP_stream::add_segment(SCTP_data_chunk &data, double timestamp){
+genlog("SCTP_stream::add_segment");  
+  int data_idx=get_idx(data.ssn);
+  SCTP_message *message;
+  if(data_idx==-1){
+    message=new SCTP_message;
+    message_list.addElement(message);
+  } else {
+    message=message_list.elementAt(data_idx);
+  }
+  stream_id=data.sid;
+  message->add_segment(data,timestamp);
+genlog("SCTP_stream::add_segment end");  
+}
+
+bool SCTP_stream::has_message(){
+  int data_idx=find_first_message();
+  if(data_idx!=-1) return message_list[data_idx].complete;
+  return false;
+}
+
+double SCTP_stream::get_first_ts(){
+  int data_idx=find_first_message();
+  if(data_idx!=-1) return message_list[data_idx].timestamp;
+  return 0.0;
+}
+
+unsigned char*  SCTP_stream::get_first_message_data(){
+  int data_idx=find_first_message();
+  if(data_idx!=-1) return message_list[data_idx].data;
+  return NULL;
+}
+
+size_t  SCTP_stream::get_first_message_data_len(){
+  int data_idx=find_first_message();
+  if(data_idx!=-1) return message_list[data_idx].length;
+  return 0;
+}
+
+int SCTP_stream::find_first_message(){
+  unsigned int ssn=0;
+  int idx=-1;
+  for(int i=0;i<message_list.length();i++){
+    if(idx==-1 || ssn>message_list[i].ssn){
+      ssn=message_list[i].ssn;
+      idx=i;
+    }
+  }
+  return idx;
+}
+
+void SCTP_stream::delete_first_message(){
+  int data_idx=find_first_message();
+  if(data_idx!=-1) {
+    delete message_list.elementAt(data_idx);
+    message_list.remove(data_idx);
+  }
+}
+
+void SCTP_stream::ack_message(unsigned int ack_tsn){
+  SCTP_message *message=message_list.first();
+  while(message){
+    if(!message->complete && (message->last_cons_tsn<ack_tsn)){
+      delete message;
+      message_list.removeCurrent();
+    }
+    message=message_list.next();
+  }
+}
+
+int SCTP_stream::get_idx(unsigned int ssn){
+genlog("SCTP_stream::get_idx");  
+
+  for(int i=0;i<message_list.length();i++){
+    if(ssn==message_list[i].ssn){
+genlog("SCTP_stream::get_idx ret: %d",i);  
+      return i;
+    }
+  }
+genlog("SCTP_stream::get_idx ret -1");  
+  return -1;
+}
+
+SCTP_message::SCTP_message(){
+  complete=false;
+  first_rcvd=false;
+  last_rcvd=false;
+  ssn=0;
+
+  last_cons_tsn=0;
+  ppid=0;
+  fragments=NULL;
+  length=0;
+  data=NULL;
+  timestamp=0.0;
+}
+
+SCTP_message::~SCTP_message(){
+  free_segments();
+  Free(data);
+}
+
+void SCTP_message::add_segment(SCTP_data_chunk &chunk, double time_stamp){
+  if(complete) return;
+  if(fragments==NULL){ // first received segment
+    if(chunk.begin && chunk.end){ // complete
+      complete=true;
+      first_rcvd=true;
+      last_rcvd=true;
+      ssn=chunk.ssn;
+      ppid=chunk.ppid;
+      first_tsn=chunk.tsn;
+      last_tsn=chunk.tsn;
+      last_cons_tsn=chunk.tsn;
+      length=chunk.length;
+      timestamp=time_stamp;
+      data= (unsigned char*)Malloc(length*sizeof(unsigned char));
+      memcpy(data,chunk.data,length);
+      return;
+    } else {
+      ssn=chunk.ssn;
+      ppid=chunk.ppid;
+      fragments=new SCTP_data_fragment_list;
+    }
+  } 
+  if(chunk.begin){
+    first_rcvd=true;
+    first_tsn=chunk.tsn;
+  }
+  if(chunk.end){
+    last_rcvd=true;
+    last_tsn=chunk.tsn;
+  }
+  if(get_idx(chunk.tsn)==-1){
+    SCTP_data_fragment *fragment=new SCTP_data_fragment(chunk);
+    fragments->addElement(fragment);
+  }
+  if(first_rcvd && last_cons_tsn<chunk.tsn){
+    if(last_cons_tsn==0) last_cons_tsn=first_tsn;
+    while(get_idx(last_cons_tsn+1)!=-1){
+      last_cons_tsn++;
+    }
+  }
+  if(first_rcvd && last_rcvd && last_cons_tsn==last_tsn){
+    size_t curr_length=0;
+    for(unsigned int curr_tsn=first_tsn;curr_tsn<=last_tsn;curr_tsn++){
+      int idx=get_idx(curr_tsn);
+      data= (unsigned char*)Realloc(data,(curr_length+fragments->elementAt(idx)->length)*sizeof(unsigned char));
+      memcpy(data+curr_length,fragments->elementAt(idx)->data,fragments->elementAt(idx)->length);
+      curr_length+=fragments->elementAt(idx)->length;
+    }
+    length=curr_length;
+    complete=true;
+    timestamp=time_stamp;
+    free_segments();
+  }
+}
+
+void SCTP_message::free_segments(){
+  if(fragments){
+    fragments->destruct();
+    delete fragments;
+    fragments=NULL;
+  }
+}
+
+int SCTP_message::get_idx(unsigned int tsn){
+  if(fragments){
+    for(int i=0;i<fragments->length();i++){
+      if(fragments->elementAt(i)->tsn==tsn) return i;
+    }
+  }
+  return -1;
+}
+
+SCTP_data_fragment::SCTP_data_fragment(SCTP_data_chunk &chunk){
+  begin=chunk.begin;
+  end=chunk.end;
+  tsn=chunk.tsn;
+  length=chunk.length;
+      data= (unsigned char*)Malloc(length*sizeof(unsigned char));
+      memcpy(data,chunk.data,length);
+}
+
+SCTP_data_fragment::~SCTP_data_fragment(){
+Free(data);
+}
+
+Protocol_data::Protocol_data(){
+}
+
+Protocol_data::~Protocol_data(){
+  data_list.destruct();
+}
+
+void Protocol_data::add_protocol(const int id, const tf__getMsgLen& f_getMsgLen, const tf__getMsgStartPos& f_getMsgStartPos){
+  int idx=get_idx(id);
+  protocol_def *def;
+  if(idx==-1){
+    def=new protocol_def;
+    data_list.append(def);
+  } else {
+    def=data_list.elementAt(idx);
+  }
+  def->id=id;
+  def->f_getMsgLen=f_getMsgLen;
+  def->f_getMsgStartPos=f_getMsgStartPos;
+}
+
+int Protocol_data::get_idx(int id){
+  protocol_def *def;
+  for(int i=0; i<data_list.length();i++){
+    def=data_list.elementAt(i);
+    if(def->id==id) return i;
+  }
+  
+  return -1;
+}
+
+const tf__getMsgLen& Protocol_data::get_f_getMsgLen(int id){
+  int idx=get_idx(id);
+  if(idx==-1) return def_getMsgLen_ref;
+  protocol_def *def=data_list.elementAt(idx);
+  return def->f_getMsgLen;
+}
+
+const tf__getMsgStartPos& Protocol_data::get_f_getMsgStartPos(int id){
+  int idx=get_idx(id);
+  if(idx==-1) return def_getMsgStartPos_ref;
+  protocol_def *def=data_list.elementAt(idx);
+  return def->f_getMsgStartPos;
+}
+
+}// namespace
diff --git a/src/PCAPasp_PT.hh b/src/PCAPasp_PT.hh
new file mode 100644
index 0000000000000000000000000000000000000000..c407b8373784225f554836002c8347c5046b3d1f
--- /dev/null
+++ b/src/PCAPasp_PT.hh
@@ -0,0 +1,691 @@
+/******************************************************************************
+* Copyright (c) 2005, 2014  Ericsson AB
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+*   Antal Wuh.Hen.Chang - initial implementation and initial documentation
+*   Adam Delic
+*   Andrea Darabos
+*   Endre Kulcsar
+*   Gabor Szalai
+*   Tibor Szabo
+******************************************************************************/
+//
+//  File:		PCAPasp_PT.hh
+//  Description:	PCAP port header
+//  Rev:                R7A
+//  Prodnr:             CNL 113 443
+
+#ifndef PCAPasp_PT_HH
+#define PCAPasp_PT_HH
+
+#include "PCAPasp_PortType.hh"
+
+#include <pcap.h>
+#include <netinet/in.h>
+#include <list>
+#include <string>
+#include <map>
+
+#ifndef IPPROTO_SCTP
+#define IPPROTO_SCTP 132
+#endif
+
+
+
+////////////////////////////////////////////////////////////
+// TCPSegment class
+////////////////////////////////////////////////////////////
+
+#define TCP_SEG 0
+#define UDP_SEG 1
+#define SCTP_SEG 2
+
+#define NO_PROTOCOL 0
+#define DIAMETER_PROTOCOL 1
+#define LDAP_PROTOCOL 2
+#define RADIUS_PROTOCOL 3
+#define SIP_PROTOCOL 4
+
+#define PCAP_ETHERTYPE_VLAN8021Q 0x8100
+struct ether_header;
+class SCTP_Stream_list;
+
+namespace PCAPasp__PortType{
+class TCPSegment {
+
+  public:
+    //Stream identifiers:
+    unsigned int port_src;
+    unsigned int port_dst;
+    struct in_addr ip_src;
+    struct in_addr ip_dst;
+
+    int seg_type;       // Can be TCP_SEG or UDP_SEG or SCTP_SEG
+    bool syn;           // True if it's a SYN TCP segment
+    bool fin;           // True it it's a FIN TCP segment
+    unsigned long int seq_num;     // Sequence number for TCP_SEG
+    unsigned long int ack_num;     // Acknowledgement number for TCP_SEG
+    
+    unsigned char* payload;     // Payload buffer for TCP and UDP
+    size_t length;     // Length of the payload buffer
+    
+    double timestamp;
+    int protocol_type;  // DIA,LDAP,RADIUS, NONE    
+    
+  public:
+    TCPSegment();
+    ~TCPSegment();
+    void put(char* buf, size_t size);
+    void log(const char *fmt, ...);
+    void log();
+};
+
+class ESP_obj{
+  public:
+  ESP_obj(PCAPasp__Types::ASP__PCAP__ESP__Setup);
+  ~ESP_obj();
+  unsigned int spi;
+  int mode; // 1-transport, 2-tunnel
+  std::string ip_port;  // concatenation of src_ip, dst_ip, src_port,dst_port
+                        // converted to octet strem in netwotk byte order
+                        // If any of them are not specified, represented as 0
+  PCAPasp__Types::tf__ICV__check  icv_fv;
+  OCTETSTRING icv_data;
+  PCAPasp__Types::tf__ESP__decrypt  decrypt_fv;
+  OCTETSTRING decrypt_data;
+};
+
+class ESP_handler{
+  public:
+   ESP_handler();
+   ~ ESP_handler();
+   
+   std::list<ESP_obj*> ESP_OBJ_list;
+   std::map<unsigned int, ESP_obj*>  spi_ESP_obj_map;
+   std::map<std::string, ESP_obj*> address_ESP_obj_map;
+   
+   bool setup_esp(PCAPasp__Types::ASP__PCAP__ESP__Setup);  // add or delete ESP
+   void clean_up();
+   // Finds the ESP object for the spi
+   bool find_esp(unsigned int spi, ESP_obj *& esp);
+
+
+   // Retrun true if there is a registered SPI for the addresses
+   bool esp_exists(struct in_addr *ip_src, unsigned int port_src,struct in_addr *ip_dst,unsigned int port_dst,unsigned int proto);
+
+   bool match_esp(struct in_addr *ip_src, unsigned int port_src,struct in_addr *ip_dst,unsigned int port_dst,const ESP_obj *esp);
+};
+
+////////////////////////////////////////////////////////////
+// DumpReader class
+////////////////////////////////////////////////////////////
+
+#ifndef ETHER_ADDR_LEN
+#define ETHER_ADDR_LEN 6
+#endif
+
+#ifndef u_int8_t
+#define u_int8_t uint8_t
+#endif
+#ifndef u_int16_t
+#define u_int16_t uint16_t
+#endif
+#ifndef u_int32_t
+#define u_int32_t uint32_t
+#endif
+
+struct vlan_header {
+        u_int16_t       vlan_head;
+        u_int16_t       vlan_type;
+};
+
+struct ip_header {
+	u_int8_t	ip_vhl;		/* header length, version */
+#define IP_V(ip)	(((ip)->ip_vhl & 0xf0) >> 4)
+#define IP_HL(ip)	((ip)->ip_vhl & 0x0f)
+	u_int8_t	ip_tos;		/* type of service */
+	u_int16_t	ip_len;		/* total length */
+	u_int16_t	ip_id;		/* identification */
+	u_int16_t	ip_off;		/* fragment offset field */
+#define	IP_DF 0x4000			/* dont fragment flag */
+#define	IP_MF 0x2000			/* more fragments flag */
+#define	IP_OFFMASK 0x1fff		/* mask for fragmenting bits */
+	u_int8_t	ip_ttl;		/* time to live */
+	u_int8_t	ip_p;		/* protocol */
+	u_int16_t	ip_sum;		/* checksum */
+	struct in_addr  ip_src;
+        struct in_addr  ip_dst;	        /* source and dest address */
+};
+
+/*
+ * TCP header.
+ * Per RFC 793, September, 1981.
+ */
+struct tcphdr {
+ u_int16_t	th_sport;		/* source port */
+ u_int16_t	th_dport;		/* destination port */
+ u_int32_t	th_seq;			/* sequence number */
+ u_int32_t	th_ack;			/* acknowledgement number */
+ u_int8_t       th_off;                 /* data offset + reserved */
+ #define TCP_OFF(tcp)	(((tcp)->th_off & 0xf0) >> 4)
+
+ u_char	th_flags;
+ #define	TH_FIN	0x01
+ #define	TH_SYN	0x02
+ #define	TH_RST	0x04
+ #define	TH_PUSH	0x08
+ #define	TH_ACK	0x10
+ #define	TH_URG	0x20
+ #define	TH_ECE	0x40
+ #define	TH_CWR	0x80
+ #define	TH_FLAGS	(TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
+		    
+ u_int16_t	th_win;			/* window */
+ u_int16_t	th_sum;			/* checksum */
+ u_int16_t	th_urp;			/* urgent pointer */
+};
+
+struct udphdr {
+ u_short uh_sport;               /* source port */
+ u_short uh_dport;               /* destination port */
+ u_short uh_ulen;                /* udp length */
+ u_short uh_sum;                 /* udp checksum */
+};
+
+struct sctphdr {
+ u_short sh_sport;               /* source port */
+ u_short sh_dport;               /* destination port */
+ u_int32_t	sh_vtag;			/* verification tag */
+ u_int32_t	sh_sum;			/* checksum */
+};
+////////////////////////////////////////////////////////////
+// Vector template
+////////////////////////////////////////////////////////////
+
+template < class Type > class Vector
+{
+
+public:
+  int size;
+  int actual;
+  Type **ar;
+
+public:
+  Vector ();
+  Vector (Vector & a);
+  ~Vector ();
+  Vector & operator = (Vector & a);
+  Type & operator[](int idx);
+  Type *elementAt (int idx);
+  bool removeElementAt (int idx);
+  int length ();
+  void append (Type * ptr);
+  void addElement (Type * ptr);
+  bool remove (Type * ptr);
+  bool removeCurrent();
+  bool remove (int idx);
+  bool removeElement (Type * ptr);
+  bool removeRef (Type * ptr);
+  int find (Type * ptr);
+  Type *first ();
+  Type *last ();
+  Type *next ();
+  Type *current ();
+  Type *prev ();
+  bool isEmpty ();
+  void destruct ();
+};
+
+class protocol_def{
+public:
+  int id;
+  PCAPasp__Types::tf__getMsgLen f_getMsgLen;
+  PCAPasp__Types::tf__getMsgStartPos f_getMsgStartPos;
+  protocol_def(){};
+  ~protocol_def(){};
+};
+
+typedef Vector <protocol_def> protocol_def_list;
+
+class Protocol_data {
+  public:
+    protocol_def_list data_list;
+    Protocol_data();
+    ~Protocol_data();
+    
+    void add_protocol(const int id, const PCAPasp__Types::tf__getMsgLen& f_getMsgLen, const PCAPasp__Types::tf__getMsgStartPos& f_getMsgStartPos);
+    int get_idx(int id);
+    const PCAPasp__Types::tf__getMsgLen& get_f_getMsgLen(int id);
+    const PCAPasp__Types::tf__getMsgStartPos& get_f_getMsgStartPos(int id);
+};
+
+class Hole {
+public:
+        u_int16_t first;
+        u_int16_t last;
+        
+        inline Hole() {};
+        inline Hole(u_int16_t f, u_int16_t l){first=f;last=l;};
+        inline ~Hole() {};
+};
+
+typedef Vector <Hole> Holes_list;
+
+class IP_fragment {
+public:
+        
+        IP_fragment();
+        ~IP_fragment();
+        void clear();
+        bool add_fragment(struct ip_header* IPHeader,
+                            u_char* IPData);
+        bool get_fragment(struct ip_header** IPHeader,
+                            u_char** IPData);
+        u_int16_t  id;
+
+private:
+        u_char*    buffer;
+        ip_header* header;
+        u_int16_t  buffer_len;
+        u_int16_t  data_len;
+        Holes_list holes;
+};
+
+typedef Vector <IP_fragment> IP_fragment_list;
+
+class IP_fragments {
+public:
+        IP_fragments();
+        ~IP_fragments();
+        
+        void clear();           // clear the IP fragments 
+        bool check();           // check wheter IP fragments exist
+        bool add_ip_fragment(struct ip_header** IPHeader,
+                             u_char** IPData);
+                                // put the IP fragment in the buffer
+                                // if an IP packet completly reassembled with
+                                // the fragment returns true and set the 
+                                // pointers. They must be freed later!!
+private:
+        IP_fragment_list packet_list;
+};
+
+
+class DumpReader {
+
+public:
+        DumpReader();
+        ~DumpReader();
+	
+	bool open(char* fname);		// Tries to open a capture file
+	bool setFilter(char* filter_script, bpf_u_int32 netmask = 0xffffff);
+        TCPSegment* getNextSegment();
+	
+private:
+	char errbuf[PCAP_ERRBUF_SIZE];	// Buffer for PCAP error messages
+	pcap_t *fp; 			// Descriptor of an open capture instance.
+	char* captureFilter;            // filter script
+	struct bpf_program BPFcode;     // compiled filter
+        
+        // pointers to the read packets
+	struct pcap_pkthdr* actHeader;
+     	const u_char* actData;
+	struct ether_header* actEthernetHeader;
+	u_char* actEthernetData;
+	struct ip_header* actIPHeader;
+	u_char* actIPData;
+	struct tcphdr* actTCPHeader;
+	u_char* actTCPData;
+        struct udphdr* actUDPHeader;
+        u_char* actUDPData;
+
+        struct sctphdr* actSCTPHeader;
+        u_char* actSCTPData;
+
+        bool free_ptr;
+        IP_fragments fragment_buffer;
+	
+	int frameCounter;
+
+	bool getNext();                 // Next PCAP packet from
+	bool getNextEthernet();         // Next ethernet packet containing IP
+	bool getNextIP();               // Next non fragmented IP datagram
+
+};
+
+////////////////////////////////////////////////////////////
+// TCPBuffer class
+////////////////////////////////////////////////////////////
+
+class TCPBuffer {
+
+  public:
+
+    unsigned long int seq_num;
+    size_t length;
+    unsigned char* buffer;
+    unsigned char* read_poi;
+    double timestamp;
+    unsigned long int total_length;
+    unsigned long int lost_length;
+    bool closed;
+    bool close_sent;
+    
+    
+  public:
+    TCPBuffer();
+    ~TCPBuffer();
+    void clear();
+    bool put(TCPSegment* segment);
+    bool ack(TCPSegment* segment);
+    
+    void rewind();
+    size_t get_pos();
+    void set_pos(size_t pos);
+    size_t get_len();
+    unsigned char* get_data();
+    size_t get_read_len();
+    unsigned char* get_read_data();
+    void cut();
+    void cut(size_t cut_bytes);
+    void log(const char *fmt, ...);
+    void dump();
+    void log_stat();
+    
+};
+
+
+struct SCTP_data_chunk{
+  unsigned int tsn;
+  unsigned int sid;
+  unsigned int ssn;
+  unsigned int ppid;
+  bool begin;
+  bool end;
+  unsigned int length;
+  unsigned char* data;
+};
+
+
+struct SCTP_chunk{
+  unsigned int type;
+  unsigned int flags;
+  unsigned int length;
+  union{
+    SCTP_data_chunk data;
+    unsigned int ack_tsn;
+  } data;
+};
+
+typedef Vector <SCTP_chunk> SCTP_chunk_list;
+
+class SCTP_data_fragment{
+public:
+  bool begin;
+  bool end;
+  unsigned int tsn;
+  unsigned int length;
+  unsigned char* data;
+
+  SCTP_data_fragment(SCTP_data_chunk &);
+  ~SCTP_data_fragment();  
+};
+
+typedef Vector <SCTP_data_fragment> SCTP_data_fragment_list;
+
+class SCTP_message{
+public:
+  SCTP_message();
+  ~SCTP_message();
+
+  bool complete;
+  bool first_rcvd;
+  bool last_rcvd;
+  unsigned int ssn;
+  unsigned int first_tsn;
+  unsigned int last_tsn;
+  unsigned int last_cons_tsn;
+  unsigned int ppid;
+  SCTP_data_fragment_list *fragments;
+  size_t length;
+  unsigned char* data;
+  double timestamp;
+
+  void add_segment(SCTP_data_chunk &chunk, double time_stamp);
+  void free_segments();
+  int get_idx(unsigned int tsn);
+};
+
+typedef Vector <SCTP_message> SCTP_message_list;
+
+class SCTP_stream{
+public:
+  SCTP_stream();
+  ~SCTP_stream();
+  
+  unsigned int stream_id;
+//  unsigned int low_ssn;
+//  unsigned int high_ssn;
+  SCTP_message_list message_list;
+  
+  void add_segment(SCTP_data_chunk &data, double timestamp);
+  bool has_message();
+  double get_first_ts();
+  unsigned char* get_first_message_data();
+  size_t get_first_message_data_len();
+  void delete_first_message();
+  void ack_message(unsigned int ack_tsn);
+  
+  int get_idx(unsigned int ssn);
+  int find_first_message();
+};
+
+typedef Vector <SCTP_stream> list_of_SCTP_stream;
+
+class SCTP_Stream_list{
+public:
+
+  list_of_SCTP_stream streams;
+  unsigned int acked_tsn;
+
+  SCTP_Stream_list();
+  ~SCTP_Stream_list();
+  
+
+  bool has_message();
+  unsigned char* get_first_sctp_data();
+  size_t get_first_sctp_data_len();
+  double get_first_sctp_timestamp();
+  void delete_first_sctp_message();
+  bool add_to_stream(SCTP_data_chunk &data, double timestamp);
+  void add_stream(SCTP_data_chunk &data, double timestamp);
+  void add_segment_to_stream(TCPSegment* segment);
+  void ack(TCPSegment* segment);
+  void log_stat();
+  void dump();
+};
+
+
+////////////////////////////////////////////////////////////
+// Peer class
+////////////////////////////////////////////////////////////
+
+typedef Vector <TCPSegment> SegmentList;
+
+class Peer {
+  
+  public:
+    //Data that idientify the stream:
+    u_short port_src;
+    u_short port_dst;
+    struct in_addr ip_src;
+    struct in_addr ip_dst;
+    
+    TCPBuffer tcp_buf; 		//Buffer for the processed bytes
+    SegmentList seg_list; 	//List for the icoming segments that haven't been processed yet.
+    int protocol_type;          //Protocol type of the peer. Type are defined in TCPSegment.hh
+    bool out_of_sync;
+    int transport_type;
+    
+    // SCTP stuff
+    bool is_sctp;
+    SCTP_Stream_list stream_list;
+  
+  public:
+    Peer();
+    Peer(TCPSegment* segment);
+    ~Peer();
+    void reset();
+    void init(TCPSegment* segment);
+    bool compare(TCPSegment* segment);
+    bool sentBy(TCPSegment* segment); //Returns true if the segment was sent by this Peer
+    void put(TCPSegment* segment);
+    bool ack(TCPSegment* segment);
+
+    
+    int get_msg_len();
+    bool tryToResync();
+
+    // SCTP stuff
+    bool has_message();
+    unsigned char* get_first_sctp_data();
+    size_t get_first_sctp_data_len();
+    double get_first_sctp_timestamp();
+    void delete_first_sctp_message();
+
+    
+    void log(const char *fmt, ...);
+    void dump();
+    void log_stat();
+};
+
+////////////////////////////////////////////////////////////
+// PeerList class
+////////////////////////////////////////////////////////////
+
+typedef Vector <Peer> Peers;
+
+class PeerList {
+
+  public:
+    Peers peer_list;
+    bool tcp;
+    
+  public:
+    PeerList();
+    ~PeerList();
+    void addPeer(TCPSegment* segment);
+    Peer* getPeer(TCPSegment* segment);
+    Peer* getOtherPeer(TCPSegment* segment);
+    bool sendSegmentToPeer(TCPSegment* segment); //Returns false if lost segment is detected
+    void setType(bool t);
+    Peer* elementAt(int i);
+    int length();
+    void log(const char *fmt, ...);
+    void dump();
+    void log_stat();
+};
+
+////////////////////////////////////////////////////////////
+// FilterEntry class
+////////////////////////////////////////////////////////////
+
+class FilterEntry {
+
+  public:
+    int protocol_type;
+    struct in_addr ip_src;
+    struct in_addr ip_dst;
+    unsigned int port_dst;
+    bool ip_src_all;
+
+  public:
+    FilterEntry(int protocol, struct in_addr sip, bool sip_all, struct in_addr dip, unsigned int rport);
+    ~FilterEntry();
+    bool compare(TCPSegment* seg);
+    void log(const char *fmt, ...);
+};
+
+////////////////////////////////////////////////////////////
+// FilterTable class
+////////////////////////////////////////////////////////////
+
+typedef Vector <FilterEntry> FilterEntries;
+
+class FilterTable {
+
+  public:
+    FilterEntries entry_list;
+    
+  public:
+    FilterTable();
+    ~FilterTable();
+    void addEntry(int protocol, struct in_addr sip, bool sip_all, struct in_addr dip, unsigned int rport);
+    int filter(TCPSegment* segment);
+    void log(const char *fmt, ...);
+};
+
+
+
+
+////////////////////////////////////////////////////////////
+// PCAPasp_PT class
+////////////////////////////////////////////////////////////
+class PCAPasp__PT : public PCAPasp__PT_BASE {
+
+public:
+	PCAPasp__PT(const char *par_port_name = NULL);
+	~PCAPasp__PT();
+
+	void set_parameter(const char *parameter_name,
+		const char *parameter_value);
+
+	void Event_Handler(const fd_set *read_fds,
+		const fd_set *write_fds, const fd_set *error_fds,
+		double time_since_last_call);
+  ESP_handler esp;      
+  void inc_msg(const PCAPasp__Types::ASP__PCAP__ESP__Report& data) {incoming_message(data);};
+         
+protected:
+	void user_map(const char *system_port);
+	void user_unmap(const char *system_port);
+
+	void user_start();
+	void user_stop();
+               
+	void outgoing_send(const PCAPasp__Types::ASP__PCAP__Capture& send_par);
+	void outgoing_send(const PCAPasp__Types::ASP__PCAP__ConfigReq& send_par);
+	void outgoing_send(const PCAPasp__Types::ASP__PCAP__MessageReq& send_par);
+        void outgoing_send(const PCAPasp__Types::ASP__PCAP__DumpReaderFilter& send_par);
+        void outgoing_send(const PCAPasp__Types::ASP__PACP__SetupProtocol& send_par);
+        void outgoing_send(const PCAPasp__Types::ASP__PCAP__ESP__Setup& send_par);
+        
+        TCPSegment* getNextFilteredSegment();
+        void log(const char *fmt, ...);
+	
+        // Variables for capturing mode
+	int capture;
+	int settings;
+	pcap_t *handle;
+	struct pcap_pkthdr header;
+	pcap_dumper_t *dumpfile;
+        // For test port parameters
+        char* capture_file;
+        char* packet_filter;
+        
+        
+        // Inner components
+        DumpReader dump_reader;   // I/f for PCAP dump files
+        PeerList peer_list_tcp;   // Peer buffer list for TCP streams
+        PeerList peer_list_udp;   // Peer buffer list for UDP streams
+        PeerList peer_list_sctp;   // Peer buffer list for SCTP streams
+        FilterTable filter_table; // Stream filter table
+
+};
+
+}
+#endif
diff --git a/src/PCAPasp_PortType.ttcn b/src/PCAPasp_PortType.ttcn
new file mode 100644
index 0000000000000000000000000000000000000000..a53e5a8331421661463e69b923cbfe8c99763376
--- /dev/null
+++ b/src/PCAPasp_PortType.ttcn
@@ -0,0 +1,44 @@
+/******************************************************************************
+* Copyright (c) 2005, 2014  Ericsson AB
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+*   Antal Wuh.Hen.Chang - initial implementation and initial documentation
+*   Adam Delic
+*   Andrea Darabos
+*   Endre Kulcsar
+*   Gabor Szalai
+*   Tibor Szabo
+******************************************************************************/
+//
+//  File:               PCAPasp_PortType.ttcn
+//  Description:        PCAP testport port definition file
+//  Rev:                R7A
+//  Prodnr:             CNL 113 443
+//
+
+module PCAPasp_PortType
+{
+  import from PCAPasp_Types all;
+//  import from RADIUSmsg_Types all;
+//  import from SIPmsg_Types all;
+
+  type port PCAPasp_PT message {
+    out ASP_PCAP_Capture;
+    out ASP_PCAP_ConfigReq;
+    in  ASP_PCAP_ConfigResp;
+    out ASP_PCAP_MessageReq;
+    in  ASP_PCAP_MessageResp;
+    out ASP_PCAP_DumpReaderFilter;
+    in  ASP_PCAP_DumpFilterResp;
+    out ASP_PACP_SetupProtocol;
+    in  ASP_PCAP_ConnectionClosed;
+    in  ASP_PCAP_Error;
+    out ASP_PCAP_ESP_Setup;
+    in  ASP_PCAP_ESP_Setup_Resp;
+    in  ASP_PCAP_ESP_Report;
+  }
+}
diff --git a/src/PCAPasp_Types.ttcn b/src/PCAPasp_Types.ttcn
new file mode 100644
index 0000000000000000000000000000000000000000..cf0195821eb3a96c6a46e510806018785894433a
--- /dev/null
+++ b/src/PCAPasp_Types.ttcn
@@ -0,0 +1,174 @@
+/******************************************************************************
+* Copyright (c) 2005, 2014  Ericsson AB
+* All rights reserved. This program and the accompanying materials
+* are made available under the terms of the Eclipse Public License v1.0
+* which accompanies this distribution, and is available at
+* http://www.eclipse.org/legal/epl-v10.html
+*
+* Contributors:
+*   Antal Wuh.Hen.Chang - initial implementation and initial documentation
+*   Adam Delic
+*   Andrea Darabos
+*   Endre Kulcsar
+*   Gabor Szalai
+*   Tibor Szabo
+******************************************************************************/
+//
+//  File:               PCAPasp_Types.ttcn
+//  Description:        PCAP testport type definition file
+//  Rev:                R7A
+//  Prodnr:             CNL 113 443
+//
+
+module PCAPasp_Types
+{
+
+
+  //******************************* for Capture Mode *********************************
+  
+  type enumerated CaptureControl { START, STOP };
+  
+  type record ASP_PCAP_Capture {
+  
+    CaptureControl 	command
+  }
+  
+  type record ASP_PCAP_ConfigReq {
+  
+    charstring 	interface 	optional,
+    integer 	mask		optional,
+    charstring 	filter		optional,
+    charstring 	filename
+  }
+  
+  type enumerated CommandId { FILTERCMD, STARTCMD, STOPCMD };
+  type enumerated CommandStatus { VALID, INVALID };
+  type enumerated CommandError { CAPTURING_HAS_ALREADY_STARTED, THERE_IS_NO_FILTER_SET, CAPTURING_HAS_NOT_STARTED, PORT_IS_ALREADY_CAPTURING, ERROR_LOOKING_NET_UP, ERROR_LIVE_OPENING, ERROR_COMPILING_FILTER, ERROR_SETTING_FILTER, ERROR_SETTING_NONBLOCK_MODE, ERROR_OPENING_OUTPUT_FILE };
+  
+  type record ASP_PCAP_ConfigResp {
+  
+    CommandId		command,
+    CommandStatus 	status,
+    CommandError  	errorMessage	optional
+  }
+
+  //******************************* for DumpReader Mode *********************************
+    
+  type integer RequestedProtocol; // -1 Any protocol or greater than 0
+  
+  type record ASP_PCAP_MessageReq {
+    RequestedProtocol	nextMessage
+  }
+
+  
+  type enumerated Status { VALID_MESSAGE, NO_MESSAGE };
+  type record ASP_PCAP_MessageResp {
+    Status		status,
+    float		timeStamp       optional,
+    integer		contentLength   optional,
+    charstring          destinationIP   optional,
+    integer		destinationPort optional,
+    charstring          sourceIP        optional,
+    integer             sourcePort      optional,
+    ProtocolMsgType     msgtype         optional,
+    octetstring		nextMessage	optional
+  }
+  
+  type integer ProtocolMsgType; // greater than 0
+  type record of integer IntegerArrayType;
+  type record ASP_PCAP_DumpReaderFilter {
+    
+    ProtocolMsgType	messageType,
+    charstring		remoteIp,
+    charstring		localIp,
+    IntegerArrayType	remotePorts
+  }
+
+  type enumerated DumpFilterError { WRONG_SOURCE_IP, WRONG_DESTINATION_IP };  
+  type record ASP_PCAP_DumpFilterResp {
+
+    CommandStatus 	status,
+    DumpFilterError  	errorMessage	optional
+  }
+  
+  type record ASP_PCAP_ConnectionClosed {
+  
+    RequestedProtocol protocol,
+    charstring destinationIP,
+    integer destinationPort,
+    charstring sourceIP,
+    integer sourcePort
+  }
+  
+  type enumerated PCAPError { LOST_SEGMENT }
+  type record ASP_PCAP_Error {
+    PCAPError errorType,
+    charstring destinationIP,
+    integer destinationPort,
+    charstring sourceIP,
+    integer sourcePort
+  }
+  
+  type integer Transport // TCP_Transport(0), UDP_Transport(1), SCTP_Transport(2)
+
+  type function tf_getMsgLen(in octetstring stream, in boolean conn_closed,
+                             in Transport stream_transport) return integer;
+  type function tf_getMsgStartPos(in octetstring stream, boolean conn_closed,
+                             in Transport stream_transport) return integer;
+  
+  type record ASP_PACP_SetupProtocol {
+    ProtocolMsgType    protocol_id,
+    tf_getMsgLen       getMsgLen_function optional,
+    tf_getMsgStartPos  getMsgStartPos_function optional
+  }
+
+  // ESP related stuff
+
+  // function intended to check the Integrity Check Value. 
+  // Return value:
+  //  ICV length in octets 
+  //  -1 if the check failed
+  type function tf_ICV_check(in octetstring ipheader, in octetstring ipdata, inout octetstring user_data) return integer;
+
+  // Decryption function  
+  type function tf_ESP_decrypt(in octetstring ipheader, in octetstring ipdata,
+                             out octetstring decrypted_data, inout octetstring user_data) return boolean;
+
+
+  type enumerated ESP_mode { ESP_DELETE (0), // Remove the associated ESP mode
+                             ESP_TRANSPORT_MODE (1),
+                             ESP_ENCAPSULATION (2) }  // The encapsulation node is not implemented yet.
+
+
+  // The SA lookup will be done based on SPI value
+  // The IP and port filed used only for checking.
+  type record ASP_PCAP_ESP_Setup {
+    integer spi,
+    ESP_mode mode,
+    charstring destinationIP optional,
+    integer destinationPort optional,
+    charstring sourceIP optional,
+    integer sourcePort optional,
+    tf_ICV_check  icv_function optional,    // if omit, no ICV present
+    octetstring   icv_function_user_data optional,
+    tf_ESP_decrypt esp_decrypt_function optional,  // if omit, NULL encription
+    octetstring   esp_decrypt_function_user_data optional
+  }
+  
+  type record ASP_PCAP_ESP_Setup_Resp{
+    ESP_Status  status_code,
+    charstring  status_message optional
+  }
+  
+  type enumerated ESP_Status { ESP_OK, ESP_NOT_DEFINED, NOT_ESP_PACKET, ESP_WRONG_SPI, ESP_ICV_ERROR, ESP_DECRYPT_ERROR, ESP_SETUP_ERROR}
+  
+  type record ASP_PCAP_ESP_Report{
+    ESP_Status   status_code,
+    integer spi,
+    charstring destinationIP,
+    integer destinationPort optional,  // The port number can be encrypted
+    charstring sourceIP,
+    integer sourcePort optional,
+    Transport payload_transport
+  }
+}