← Back to team overview

libgse team mailing list archive

[RFC/Patch] No dynamic allocation mode in encapsulation context

 

Dear GSE team,

Here is a RFC for a small patch to support a "no dynamic allocation" mode in encapsulation context. This work has been done at Thales Alenia Space, which is the only holder
of the copyrights on this patch.

Currently, there are some underlying allocations done during encapsulation
of a packet (when creating the virtual fragment containing the output
GSE packet), and memory clean-up (in case of error handling). Such behaviour may be inappropriate in some cases (e.g. tight memory management), or may simply decrease
performances of the library.

This patch allows one to allocate all the virtual fragments needed at program start. Then, the library will never allocate another fragment and will only use the ones provided by the user (this implies the 'no-copy' mode). In a similar way, memory allocated for fragments will not be released by the library,
even in case of error.

This patch proposes such modifications for encapsulation only. It does not support refragmentation, nor extension headers, which will still trigger dynamic
memory allocations.
As for the 'no-copy' mode, all 'no-alloc'-related functions have been prefixed with '_no_allocation'. This is to be discussed, as it should be possible to merge both 'no-copy' and 'no-allocation' mode into a single mode. Furthemore, some virtual fragments management functions have been introduced, to allow one to allocate and free a virtual fragment, or affect a buffer to a pre-allocated
fragment.

A simple non-regression test has been added (completely copied from the existing one, and only adapted to not handle refragmentation/extension headers and use
the '_no_allocated' functions).

Here is a small&quick&dirty benchmark realised as followed:
 1. Get a 0-filled, fixed-length packet.
2. Encapsulate it into a 2001 bytes long BBFrame, with eventual fragmentation of packet, in which case the remaining fragment will fill a 'new' BBFrame.
 3. Repeat previous steps N times.

You may find the code for theses tests in attachment (eval_gse_trunk.c for the
trunk version of GSE, eval_gse_no_alloc.c for the patched version).

The total processor time used by the N loops is measured with the clock()
function, which is then used to approximate the ellapsed time, and to
calculate the rate and throughput.

Here are the results, obtained for N=1E6 loops:

* Packet size: 1500 Bytes
 + Trunk GSE:
Rate: 1.28 Gbps
PPS: 106 kpps
 + Patched GSE:
Rate: 2.19 Gbps
PPS: 183 kpps

* Packet size: 185 Bytes
 + Trunk GSE:
Rate: 312 Mbps
PPS: 211 kpps
 + Patched GSE:
Rate: 1.85 Gbps
PPS: 1.25 Mpps

* Packet size: 40 Bytes
 + Trunk GSE:
Rate: 67 Mbps
PPS: 210 kpps
 + Patched GSE:
Rate: 508 Mbps
PPS: 1.59 Mpps

As you can see, there is roughly a x1.5 to x8 improvement, depending on packet
size.

I await your comment on this patch.

Regards,
Audric Schiltknecht
# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: audric.schiltknecht@xxxxxxxxxxxxxxxxxxxx-\
#   20130319160857-re22eemibj42xi7g
# target_branch: http://bazaar.launchpad.net/~opensand-\
#   maintainers/libgse/trunk/
# testament_sha1: ab76f0d6a82eef3168a07cf30bf66817dea621ae
# timestamp: 2013-07-25 12:02:07 +0200
# base_revision_id: audric.schiltknecht@xxxxxxxxxxxxxxxxxxxx-\
#   20130306110240-svj9ix11czibbyag
# 
# Begin patch
=== modified file '.bzrignore'
--- .bzrignore	2012-10-03 15:59:10 +0000
+++ .bzrignore	2013-03-11 14:09:17 +0000
@@ -48,6 +48,7 @@
 src/encap/test/test_refrag_robust
 test/non_regression_tests
 test/test_encap_deencap
+test/non_regression_tests_no_alloc
 debian/files
 debian/libgse
 debian/libgse-dbg

=== modified file 'src/common/virtual_fragment.c'
--- src/common/virtual_fragment.c	2012-10-01 12:20:36 +0000
+++ src/common/virtual_fragment.c	2013-03-11 13:37:16 +0000
@@ -289,6 +289,92 @@
   return status;
 }
 
+gse_status_t gse_allocate_vfrag(gse_vfrag_t **vfrag, int alloc_vbuf)
+{
+  int status = GSE_STATUS_OK;
+  gse_vbuf_t *vbuf = NULL;
+
+  if(vfrag == NULL)
+  {
+    status = GSE_STATUS_NULL_PTR;
+    goto error;
+  }
+
+  if (alloc_vbuf)
+  {
+    vbuf = malloc(sizeof(gse_vbuf_t));
+    if(vbuf == NULL)
+    {
+      status = GSE_STATUS_MALLOC_FAILED;
+      goto error;
+    }
+
+    vbuf->vfrag_count = 0;
+  }
+
+  *vfrag = malloc(sizeof(gse_vfrag_t));
+  if(*vfrag == NULL)
+  {
+    status = GSE_STATUS_MALLOC_FAILED;
+    goto free_vbuf;
+  }
+
+  (*vfrag)->vbuf = vbuf;
+
+  return status;
+
+free_vbuf:
+  free(vbuf);
+error:
+  *vfrag = NULL;
+  return status;
+}
+
+gse_status_t gse_affect_buf_vfrag(gse_vfrag_t *vfrag, unsigned char *buffer,
+                                  unsigned int head_offset, unsigned int trail_offset,
+                                  unsigned int data_length)
+{
+  int status = GSE_STATUS_OK;
+  gse_vbuf_t *vbuf;           
+                               
+  if(vfrag == NULL || buffer == NULL)
+  {
+    status = GSE_STATUS_NULL_PTR;
+    goto error;
+  }
+
+  vbuf = vfrag->vbuf;
+  if(vbuf == NULL)
+  {
+    status = GSE_STATUS_NULL_PTR;
+    goto error;
+  }
+
+  vbuf->start = buffer;
+  vbuf->length = head_offset + data_length + trail_offset;
+  vbuf->end = vbuf->start + vbuf->length;
+  vbuf->vfrag_count = 0;
+
+  vfrag->start = (vbuf->start + head_offset);
+  vfrag->length = data_length;
+  vfrag->end = vfrag->start + vfrag->length;
+  assert((vfrag->end) <= (vfrag->vbuf->end));
+  assert((vfrag->end) >= (vfrag->vbuf->start));
+  assert((vbuf->end - vfrag->end) == (int)trail_offset);
+  if((vfrag->end) > (vfrag->vbuf->end) ||
+     (vfrag->end) < (vfrag->vbuf->start) ||
+     (vbuf->end - vfrag->end) != (int)trail_offset)
+  {
+    status = GSE_STATUS_INTERNAL_ERROR;
+    goto error;
+  }
+  vbuf->vfrag_count++;
+
+error:
+  return status;
+}
+
+
 gse_status_t gse_free_vfrag(gse_vfrag_t **vfrag)
 {
   gse_status_t status = GSE_STATUS_OK;
@@ -323,6 +409,42 @@
   return status;
 }
 
+gse_status_t gse_free_vfrag_no_alloc(gse_vfrag_t **vfrag, int reset, int free_vbuf)
+{
+  gse_status_t status = GSE_STATUS_OK;
+
+  if(vfrag == NULL || *vfrag == NULL)
+  {
+    status = GSE_STATUS_NULL_PTR;
+    goto error;
+  }
+
+  if(reset)
+  {
+    if((*vfrag)->vbuf->vfrag_count == 0)
+    {
+      status = GSE_STATUS_FRAG_NBR;
+      goto error;
+    }
+
+    (*vfrag)->vbuf->vfrag_count--;
+  }
+  else
+  {
+    if(free_vbuf)
+    {
+      free((*vfrag)->vbuf);
+      (*vfrag)->vbuf = NULL;
+    }
+
+    free(*vfrag);
+    *vfrag = NULL;
+  }
+
+error:
+  return status;
+}
+
 gse_status_t gse_duplicate_vfrag(gse_vfrag_t **vfrag, gse_vfrag_t *father,
                                  size_t length)
 {
@@ -379,6 +501,57 @@
   return status;
 }
 
+gse_status_t gse_duplicate_vfrag_no_alloc(gse_vfrag_t **vfrag, gse_vfrag_t *father,
+                                          size_t length)
+{
+  gse_status_t status = GSE_STATUS_OK;
+
+  if(father == NULL || vfrag == NULL)
+  {
+    status = GSE_STATUS_NULL_PTR;
+    goto error;
+  }
+
+  if(father->vbuf == NULL)
+  {
+    status = GSE_STATUS_NULL_PTR;
+    goto error;
+  }
+
+  /* If the father is empty it is not duplicated */
+  if(father->length == 0)
+  {
+    status = GSE_STATUS_EMPTY_FRAG;
+    goto error;
+  }
+
+  /* There can be only two accesses to a virtual buffer to avoid multiple
+   * accesses from duplicated virtual fragments */
+  if(gse_get_vfrag_nbr(father) >= 2)
+  {
+    status = GSE_STATUS_FRAG_NBR;
+    goto error;
+  }
+
+  (*vfrag)->vbuf = father->vbuf;
+  (*vfrag)->start = father->start;
+  (*vfrag)->length = MIN(length, father->length);
+
+  (*vfrag)->end = (*vfrag)->start + (*vfrag)->length;
+  assert(((*vfrag)->end) <= ((*vfrag)->vbuf->end));
+  assert(((*vfrag)->end) >= ((*vfrag)->vbuf->start));
+  if(((*vfrag)->end) > ((*vfrag)->vbuf->end) ||
+     ((*vfrag)->end) < ((*vfrag)->vbuf->start))
+  {
+    status = GSE_STATUS_INTERNAL_ERROR;
+    goto error;
+  }
+  (*vfrag)->vbuf->vfrag_count++;
+
+error:
+  return status;
+}
+
 gse_status_t gse_shift_vfrag(gse_vfrag_t *vfrag, int start_shift, int end_shift)
 {
   gse_status_t status = GSE_STATUS_OK;

=== modified file 'src/common/virtual_fragment.h'
--- src/common/virtual_fragment.h	2012-10-01 12:20:36 +0000
+++ src/common/virtual_fragment.h	2013-03-11 13:37:16 +0000
@@ -207,6 +207,57 @@
                                        unsigned int data_length);
 
 /**
+ *  @brief   Create an empty virtual fragment - No allocation mode
+ *
+ *  @param   vfrag         OUT: The virtual fragment on success,
+ *                              NULL on error
+ *  @param   alloc_vbuf    Wheter to allocate the virtual buffer container or
+ *                         not (only the container, does not allocate the buffer
+ *                         itself).
+ *
+ *  @return
+ *                         - success/informative code among:
+ *                           - \ref GSE_STATUS_OK
+ *                         - warning/error code among:
+ *                           - \ref GSE_STATUS_NULL_PTR
+ *                           - \ref GSE_STATUS_BUFF_LENGTH_NULL
+ *                           - \ref GSE_STATUS_MALLOC_FAILED
+ *
+ *  @ingroup gse_virtual_fragment
+ */
+gse_status_t gse_allocate_vfrag(gse_vfrag_t **vfrag, int alloc_vbuf);
+
+/**
+ *  @brief   Affect a buffer to an allocated virtual fragment - No allocation
+ *  mode
+ *
+ *  The virtual buffer containing the fragment will contain the allocated
+ *  memory of the buffer.\n
+ *  The allocated space in the buffer must at least be
+ *  max_length + head_offset + trail_offset.\n
+ *  All length are expressed in bytes.\n
+ *
+ *  @param   vfrag        OUT: The virtual fragment on success,
+ *                             NULL on error
+ *  @param   buffer       The buffer to transform
+ *  @param   head_offset  The offset applied before the data in the buffer
+ *  @param   trail_offset The offset applied after the data in the buffer
+ *  @param   data_length  The length of the data in the buffer
+ *
+ *  @return
+ *                        - success/informative code among:
+ *                          - \ref GSE_STATUS_OK
+ *                        - warning/error code among:
+ *                          - \ref GSE_STATUS_NULL_PTR
+ *                          - \ref GSE_STATUS_MALLOC_FAILED
+ *                          - \ref GSE_STATUS_INTERNAL_ERROR
+ *
+ *  @ingroup gse_virtual_fragment
+ */
+gse_status_t gse_affect_buf_vfrag(gse_vfrag_t *vfrag, unsigned char *buffer,
+                                  unsigned int head_offset, unsigned int trail_offset,
+                                  unsigned int data_length);
+/**
  *  @brief   Free a virtual fragment
  *
  *  @param   vfrag         IN: The virtual fragment that will be destroyed
@@ -224,6 +275,26 @@
 gse_status_t gse_free_vfrag(gse_vfrag_t **vfrag);
 
 /**
+ *  @brief   Free a virtual fragment - No allocation mode
+ *
+ *  @param   vfrag         IN: The virtual fragment that will be destroyed
+ *                         OUT: NULL
+ *  @param   reset         If true, only reset the virtual fragment, do not free
+ *                         allocated memory
+ *  @param   free_vbuf     If true, free allocated memory for the virtual
+ *                         buffer.
+ *  @return
+ *                         - success/informative code among:
+ *                           - \ref GSE_STATUS_OK
+ *                         - warning/error code among:
+ *                           - \ref GSE_STATUS_NULL_PTR
+ *                           - \ref GSE_STATUS_FRAG_NBR
+ *
+ *  @ingroup gse_virtual_fragment
+ */
+gse_status_t gse_free_vfrag_no_alloc(gse_vfrag_t **vfrag, int reset, int free_vbuf);
+
+/**
  *  @brief   Create a virtual fragment from an existing one
  *
  *  In case of warning or error, the virtual fragment is unchanged.
@@ -247,6 +318,33 @@
  */
 gse_status_t gse_duplicate_vfrag(gse_vfrag_t **vfrag, gse_vfrag_t *father, size_t length);
 
+
+/**
+ *  @brief   Create a virtual fragment from an existing one - No allocation mode
+ *
+ *  In case of warning or error, the virtual fragment is unchanged.
+ *  @warning If the father length is smaller than the wanted length, the length
+ *           of the duplicated fragment will be the father length.
+ *
+ *  @param   vfrag        The duplicated virtual fragment
+ *  @param   father       The virtual fragment which will be duplicated
+ *  @param   length       The length of the duplicated virtual fragment (in bytes)
+ *
+ *  @return
+ *                        - success/informative code among:
+ *                          - \ref GSE_STATUS_OK
+ *                        - warning/error code among:
+ *                          - \ref GSE_STATUS_NULL_PTR
+ *                          - \ref GSE_STATUS_EMPTY_FRAG
+ *                          - \ref GSE_STATUS_FRAG_NBR
+ *                          - \ref GSE_STATUS_MALLOC_FAILED
+ *
+ *  @ingroup gse_virtual_fragment
+ */
+gse_status_t gse_duplicate_vfrag_no_alloc(gse_vfrag_t **vfrag,
+                                          gse_vfrag_t *father,
+                                          size_t length);
+
 /**
  *  @brief   Shift the virtual fragment
  *

=== modified file 'src/encap/encap.c'
--- src/encap/encap.c	2012-10-03 15:59:10 +0000
+++ src/encap/encap.c	2013-03-19 16:08:57 +0000
@@ -87,6 +87,23 @@
   void *opaque;          /**< User specific data for extension callback */
 };
 
+/** Encapsulation mode
+ *
+ * Choose how to get the encapsulated packet:
+ * \li LEGACY:   legacy mode (duplicate the buffer into a newly created virtual
+ *               fragment).
+ * \li NO_COPY:  zero copy mode (share the buffer with a newly created
+ *               virtual fragment).
+ * \li NO_ALLOC: no allocation mode (share the buffer with a user provided,
+ *               already allocated, virtual fragment)
+ */
+enum encap_mode
+{
+  LEGACY,
+  NO_COPY,
+  NO_ALLOC
+};
+
 
 
 /****************************************************************************
@@ -173,7 +190,7 @@
 /**
  *  @brief   Get a GSE packet from the encapsulation context structure
  *
- *  @param   copy             Activate copy or not
+ *  @param   mode             The encapsulation mode.
  *  @param   packet           OUT: The GSE packet on success,
  *                                 NULL on error
  *  @param   encap            The encapsulation context structure
@@ -203,7 +220,7 @@
  *                              - \ref GSE_STATUS_FRAG_NBR
  *                              - \ref GSE_STATUS_EXTENSION_CB_FAILED
  */
-static gse_status_t gse_encap_get_packet_common(int copy, gse_vfrag_t **packet,
+static gse_status_t gse_encap_get_packet_common(int mode, gse_vfrag_t **packet,
                                                 gse_encap_t *encap,
                                                 size_t desired_length,
                                                 uint8_t qos);
@@ -395,20 +412,26 @@
 error:
   return status;
 free_pdu:
-  gse_free_vfrag(&pdu);
+  gse_free_vfrag_no_alloc(&pdu, 1, 0);
   return status;
 }
 
 gse_status_t gse_encap_get_packet(gse_vfrag_t **packet, gse_encap_t *encap,
                                   size_t length, uint8_t qos)
 {
-  return gse_encap_get_packet_common(0, packet, encap, length, qos);
+  return gse_encap_get_packet_common(NO_COPY, packet, encap, length, qos);
 }
 
 gse_status_t gse_encap_get_packet_copy(gse_vfrag_t **packet, gse_encap_t *encap,
                                        size_t length, uint8_t qos)
 {
-  return gse_encap_get_packet_common(1, packet, encap, length, qos);
+  return gse_encap_get_packet_common(LEGACY, packet, encap, length, qos);
+}
+
+gse_status_t gse_encap_get_packet_no_alloc(gse_vfrag_t **packet, gse_encap_t *encap,
+                                           size_t length, uint8_t qos)
+{
+  return gse_encap_get_packet_common(NO_ALLOC, packet, encap, length, qos);
 }
 
 gse_status_t gse_encap_set_extension_callback(gse_encap_t *encap,
@@ -586,7 +609,7 @@
   return htonl(crc);
 }
 
-static gse_status_t gse_encap_get_packet_common(int copy, gse_vfrag_t **packet,
+static gse_status_t gse_encap_get_packet_common(int mode, gse_vfrag_t **packet,
                                                 gse_encap_t *encap,
                                                 size_t desired_length,
                                                 uint8_t qos)
@@ -727,7 +750,10 @@
     {
       goto packet_null;
     }
-    memcpy(encap_ctx->vfrag->start, extensions, tot_ext_length);
+    if(tot_ext_length > 0)
+    {
+      memcpy(encap_ctx->vfrag->start, extensions, tot_ext_length);
+    }
 
     /* Can the PDU be completely encapsulated ? */
     header_length = gse_compute_header_length(GSE_PDU_COMPLETE, encap_ctx->label_type);
@@ -821,27 +847,28 @@
   }
 
   /* Code depending on copy parameter */
-  if(copy)
+  switch(mode)
   {
-    /* Create a new fragment */
-    status = gse_create_vfrag_with_data(packet, desired_length,
-                                        encap->head_offset,
-                                        encap->trail_offset,
-                                        encap_ctx->vfrag->start,
-                                        desired_length);
-    if(status != GSE_STATUS_OK)
-    {
-      goto packet_null;
-    }
+    case LEGACY:
+      /* Create a new fragment */
+      status = gse_create_vfrag_with_data(packet, desired_length,
+                                          encap->head_offset,
+                                          encap->trail_offset,
+                                          encap_ctx->vfrag->start,
+                                          desired_length);
+      break;
+    case NO_COPY:
+      /* Duplicate the fragment */
+      status = gse_duplicate_vfrag(packet, encap_ctx->vfrag, desired_length);
+      break;
+    case NO_ALLOC:
+      /* Duplicate the fragment - no allocation */
+      status = gse_duplicate_vfrag_no_alloc(packet, encap_ctx->vfrag, desired_length);
+      break;
   }
-  else
+  if(status != GSE_STATUS_OK)
   {
-    /* Duplicate the fragment */
-    status = gse_duplicate_vfrag(packet, encap_ctx->vfrag, desired_length);
-    if(status != GSE_STATUS_OK)
-    {
-      goto packet_null;
-    }
+    goto packet_null;
   }
 
   encap_ctx->frag_nbr++;
@@ -855,7 +882,14 @@
   /* Go to the next FIFO element if the initial fragment is empty */
   if(encap_ctx->vfrag->length <= 0)
   {
-    status = gse_free_vfrag(&(encap_ctx->vfrag));
+    if(mode == NO_ALLOC)
+    {
+      status = gse_free_vfrag_no_alloc(&(encap_ctx->vfrag), 1, 0);
+    }
+    else
+    {
+      status = gse_free_vfrag(&(encap_ctx->vfrag));
+    }
     if(status != GSE_STATUS_OK)
     {
       goto free_packet;
@@ -869,13 +903,24 @@
 
   return status;
 free_packet:
-  gse_free_vfrag(packet);
+  if(mode == NO_ALLOC)
+  {
+    gse_free_vfrag_no_alloc(packet, 1, 0);
+  }
+  else
+  {
+    gse_free_vfrag(packet);
+  }
 packet_null:
   if(extensions != NULL)
   {
     free(extensions);
   }
 error:
-  *packet = NULL;
+  if(mode != NO_ALLOC)
+  {
+    *packet = NULL;
+  }
   return status;
 }
+

=== modified file 'src/encap/encap.h'
--- src/encap/encap.h	2012-10-01 12:20:36 +0000
+++ src/encap/encap.h	2013-03-11 13:37:16 +0000
@@ -249,6 +249,49 @@
                                        size_t desired_length, uint8_t qos);
 
 /**
+ *  @brief   Get a GSE packet from the encapsulation context structure -
+ *           No allocation mode
+ *
+ *  This function should not be called if the previous GSE packet has not
+ *  been destroyed (with gse_free_vfrag_no_alloc) except for the first packet.
+ *
+ *  @param   packet          OUT: The GSE packet on success,
+ *                                NULL on error or warning
+ *  @param   encap           The encapsulation context structure
+ *  @param   desired_length  The desired length for the packet (in bytes)
+ *  @param   qos             The QoS of the packet
+ *
+ *  @return
+ *                           - success/informative code among:
+ *                             - \ref GSE_STATUS_OK
+ *                           - warning/error code among:
+ *                             - \ref GSE_STATUS_NULL_PTR
+ *                             - \ref GSE_STATUS_INVALID_QOS
+ *                             - \ref GSE_STATUS_FIFO_EMPTY
+ *                             - \ref GSE_STATUS_PTHREAD_MUTEX
+ *                             - \ref GSE_STATUS_LENGTH_TOO_HIGH
+ *                             - \ref GSE_STATUS_LENGTH_TOO_SMALL
+ *                             - \ref GSE_STATUS_PTHREAD_MUTEX
+ *                             - \ref GSE_STATUS_INTERNAL_ERROR;
+ *                             - \ref GSE_STATUS_PTR_OUTSIDE_BUFF
+ *                             - \ref GSE_STATUS_FRAG_PTRS
+ *                             - \ref GSE_STATUS_INVALID_GSE_LENGTH
+ *                             - \ref GSE_STATUS_BUFF_LENGTH_NULL
+ *                             - \ref GSE_STATUS_MULTIPLE_VBUF_ACCESS
+ *                             - \ref GSE_STATUS_DATA_TOO_LONG
+ *                             - \ref GSE_STATUS_MALLOC_FAILED
+ *                             - \ref GSE_STATUS_EMPTY_FRAG
+ *                             - \ref GSE_STATUS_FRAG_NBR
+ *                             - \ref GSE_STATUS_EXTENSION_CB_FAILED
+ *
+ *  @ingroup gse_encap
+ */
+gse_status_t gse_encap_get_packet_no_alloc(gse_vfrag_t **packet, gse_encap_t *encap,
+                                           size_t desired_length, uint8_t qos);
+gse_status_t gse_encap_get_packet_no_alloc_old(gse_vfrag_t *packet, gse_encap_t *encap,
+                                           size_t desired_length, uint8_t qos);
+
+/**
  *  @brief  Set the callback that build header extensions
  *
  *  @param  encap     The encapsulation context
@@ -266,5 +309,4 @@
                                               gse_encap_build_header_ext_cb_t callback,
                                               void *opaque);
 
-
 #endif

=== modified file 'test/Makefile.am'
--- test/Makefile.am	2012-05-29 09:13:59 +0000
+++ test/Makefile.am	2013-03-11 14:09:17 +0000
@@ -8,7 +8,8 @@
 
 noinst_PROGRAMS = \
 	test_encap_deencap \
-	non_regression_tests
+	non_regression_tests \
+	non_regression_tests_no_alloc
 
 TESTS = \
 	test_encap_deencap.sh
@@ -16,7 +17,8 @@
 EXTRA_DIST = \
 	encap_deencap_max_pdu_length.pcap \
 	test_encap_deencap.sh \
-	non_regression_tests.sh
+	non_regression_tests.sh \
+	non_regression_tests_no_alloc.sh
 
 INCLUDES = \
 	-I$(top_srcdir)/src/common \
@@ -34,3 +36,8 @@
 non_regression_tests_LDADD = \
 	$(top_builddir)/src/libgse.la \
 	-lpcap
+
+non_regression_tests_no_alloc_SOURCES = non_regression_tests_no_alloc.c
+non_regression_tests_no_alloc_LDADD = \
+	$(top_builddir)/src/libgse.la \
+	-lpcap

=== added file 'test/non_regression_tests_no_alloc.c'
--- test/non_regression_tests_no_alloc.c	1970-01-01 00:00:00 +0000
+++ test/non_regression_tests_no_alloc.c	2013-03-11 14:09:17 +0000
@@ -0,0 +1,1251 @@
+/*
+ *
+ * This piece of software is an implementation of the Generic Stream
+ * Encapsulation (GSE) standard defined by ETSI for Linux (or other
+ * Unix-compatible OS). The library may be used to add GSE
+ * encapsulation/de-encapsulation capabilities to an application.
+ *
+ *
+ * Copyright © 2011 TAS
+ *
+ *
+ * This file is part of the GSE library.
+ *
+ *
+ * The GSE library is free software : you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY, without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ *
+ */
+
+/****************************************************************************/
+/**
+ *   @file          non_regression_tests.c
+ *
+ *          Project:     GSE LIBRARY
+ *
+ *          Company:     THALES ALENIA SPACE
+ *
+ *          Module name: TESTS
+ *
+ *   @brief         GSE non regression tests
+ *
+ *   @author        Julien BERNARD / Viveris Technologies
+ *
+ * Introduction
+ * ------------
+ *
+ * The program takes a flow of IP packets as input (in the PCAP format) and
+ * tests the GSE library with them.
+ *
+ * Details
+ * -------
+ *
+ * The program encapsulates the flow of IP packet and then deencapsulates
+ * the GSE packets.
+ * Between encapsulation and deencapsulation, the GSE packets can be
+ * refragmented if the option is activated
+ *
+ *
+ * Checks
+ * ------
+ *
+ * The program input IP packets with deencapsulated IP packets.
+ *
+ * The program compares the GSE packets generated with the ones given as input
+ * to the program if the save option is deactivated.
+ * If the refragmentation is activated it also compares the refragmented GSE
+ * packets with the ones given as input to the program.
+ *
+ * Output
+ * ------
+ *
+ * The program outputs the GSE packets in a PCAP packet if the save option is
+ * activated.
+ * If the refragmentation is activated it also outputs the refragmented GSE
+ * packets
+ *
+ */
+/****************************************************************************/
+
+/****************************************************************************
+ *
+ *   INCLUDES
+ *
+ *****************************************************************************/
+
+/* system includes */
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <string.h>
+#include <net/ethernet.h>
+#include <stdint.h>
+
+/* include for the PCAP library */
+#include <pcap.h>
+
+/* GSE includes */
+#include "constants.h"
+#include "encap.h"
+#include "deencap.h"
+#include "refrag.h"
+
+/****************************************************************************
+ *
+ *   MACROS AND CONSTANTS
+ *
+ *****************************************************************************/
+
+/** A very simple maximum macro */
+#define MAX(x, y)  (((x) > (y)) ? (x) : (y))
+
+/** A very simple minimum macro */
+#define MIN(x, y)  (((x) < (y)) ? (x) : (y))
+
+/** The program usage */
+#define TEST_USAGE \
+"GSE test application: test the GSE library with a flow of IP packets\n\n\
+usage: test [--verbose (-v) LEVEL] [-h] [-s] [--label-type LT] [-r REFRAG_FILENAME] -c FRAG_FILENAME -i FLOW\n\
+  --verbose        Print DEBUG information level 1\n\
+  LEVEL            The DEBUG level [0, 2]\n\
+  -h               Print this usage and exit\n\
+  -s               Save output packets instead of compare them\n\
+  -r               Activate refragmentation\n\
+  LT               The label_type (0, 1, 2, 3) (default: 0)\n\
+  REFRAG_FILENAME  Save the refragmented packets or compare them\n\
+                   with the reference packets stored in refrag_file (PCAP format)\n\
+  FRAG_FILENAME    Save the fragmented packets or compare them\n\
+                   with the reference packets stored in frag_file (PCAP format)\n\
+  FLOW             Flow of Ethernet frames to encapsulate (PCAP format)\n"
+
+/** The length of the Linux Cooked Sockets header */
+#define LINUX_COOKED_HDR_LEN  16
+
+/** Number of FIFOs */
+#define QOS_NBR 10
+/** Size of FIFOs */
+#define FIFO_SIZE 100
+/** Maximum number of fragments for one PDU */
+#define PKT_NBR_MAX 1000
+/** Protocol to put in the protocol type field */
+#define PROTOCOL 9029
+
+/** DEBUG macro */
+#define DEBUG(verbose, format, ...) \
+  do { \
+    if(verbose > -1) \
+      printf(format, ##__VA_ARGS__); \
+  } while(0)
+
+#define DEBUG_L2(verbose, format, ...) \
+  do { \
+    if(verbose > 1) \
+      printf(format, ##__VA_ARGS__); \
+  } while(0)
+
+static const size_t frag_length[20] = {
+  128,  0,    1024, 256,  2048, 4096, 16,   64,   1024, 512,
+  256,  512,  4096, 64,   128,  1024, 2048, 512,  256,  1024,
+  };
+
+static const size_t refrag_length[20] = {
+  64,   1024, 512,  128,  32,   512,  16,   16,   256,  32,
+  128,  128,  2048, 16,   64,   512,  16,   128,  128,  64,
+  };
+
+
+
+/****************************************************************************
+ *
+ *   PROTOTYPES OF PRIVATE FUNCTIONS
+ *
+ *****************************************************************************/
+
+static int test_encap_deencap(int verbose, uint8_t label_type, int save,
+                              char *src_filename,
+                              char *frag_filename,
+                              char *refrag_filename);
+static int open_pcap(char *filename, int verbose, pcap_t **handle,
+                     uint32_t *link_len);
+static int get_gse_packets(int verbose,
+                           int save,
+                           gse_vfrag_t **vfrag_pkt,
+                           gse_encap_t **encap,
+                           pcap_t **frag_handle,
+                           pcap_dumper_t **frag_dumper,
+                           uint32_t link_len_frag,
+                           uint32_t link_len_src,
+                           unsigned char *link_layer_head,
+                           int frag_length_idx,
+                           uint8_t qos,
+                           unsigned long pkt_nbr);
+#if 0
+static int refrag(int verbose,
+                  int save,
+                  gse_vfrag_t **vfrag_pkt,
+                  gse_vfrag_t **refrag_pkt,
+                  pcap_t **refrag_handle,
+                  pcap_dumper_t **refrag_dumper,
+                  uint32_t link_len_refrag,
+                  uint32_t link_len_src,
+                  unsigned char *link_layer_head,
+                  int refrag_length_idx,
+                  uint8_t qos,
+                  unsigned long pkt_nbr);
+static int deencap_pkt(int verbose,
+                       gse_vfrag_t *vfrag_pkt,
+                       gse_vfrag_t *refrag_pkt,
+                       gse_deencap_t **deencap,
+                       pcap_t **cmp_handle,
+                       uint32_t link_len_cmp,
+                       unsigned long rcv_pkt_nbr,
+                       unsigned long *rcv_tot_nbr,
+                       unsigned long pdu_counter);
+#endif
+static int compare_packets(int verbose,
+                           unsigned char *pkt1, int pkt1_size,
+                           unsigned char *pkt2, int pkt2_size);
+
+
+/****************************************************************************
+ *
+ *   PUBLIC FUNCTIONS
+ *
+ *****************************************************************************/
+
+/**
+ * @brief Main function for the GSE test program
+ *
+ * @param argc  the number of program arguments
+ * @param argv  the program arguments
+ * @return      the unix return code:
+ *               \li 0 in case of success,
+ *               \li 1 in case of failure
+ */
+int main(int argc, char *argv[])
+{
+  char *src_filename = NULL;
+  char *frag_filename = NULL;
+  char *refrag_filename = NULL;
+  char *label_type = 0;
+  int save = 0;
+  int refrag = 0;
+  int failure = 1;
+  int verbose = 0;
+  int ref;
+
+  for(ref = argc; (ref > 0 && argc > 1); ref--)
+  {
+    if(!(strcmp(argv[1], "--verbose")) || !(strcmp(argv[1], "-v")))
+    {
+      verbose = 1;
+      argv += 1;
+      argc -= 1;
+      if(argc > 1 && argv[1][0] != '-')
+      {
+        verbose = atoi(argv[1]);
+        if((verbose < 0)  || (verbose > 2))
+        {
+          fprintf(stderr, "Wrong verbose value\n");
+          fprintf(stderr, TEST_USAGE);
+          goto quit;
+        }
+        argv += 1;
+        argc -= 1;
+      }
+    }
+    else if(!strcmp(argv[1], "--label-type"))
+    {
+      if(!argv[2])
+      {
+        fprintf(stderr, "Missing LT\n");
+        fprintf(stderr, TEST_USAGE);
+        goto quit;
+      }
+      label_type = argv[2];
+      if(atoi(label_type) < 0 && atoi(label_type) > 3)
+      {
+        fprintf(stderr, "Bad Label Type\n");
+        goto quit;
+      }
+      argv += 2;
+      argc -= 2;
+    }
+    else if(!strcmp(argv[1], "-c"))
+    {
+      if(!argv[2])
+      {
+        fprintf(stderr, "Missing FRAG_FILENAME\n");
+        fprintf(stderr, TEST_USAGE);
+        goto quit;
+      }
+      frag_filename = argv[2];
+      argv += 2;
+      argc -= 2;
+    }
+    else if(!strcmp(argv[1], "-i"))
+    {
+      if(!argv[2])
+      {
+        fprintf(stderr, "Missing FLOW\n");
+        fprintf(stderr, TEST_USAGE);
+        goto quit;
+      }
+      src_filename = argv[2];
+      argv += 2;
+      argc -= 2;
+    }
+    else if(!strcmp(argv[1], "-h"))
+    {
+      fprintf(stderr, TEST_USAGE);
+      goto quit;
+    }
+    else if(!strcmp(argv[1], "-r"))
+    {
+      if(!argv[2])
+      {
+        fprintf(stderr, "Missing REFRAG_FILENAME\n");
+        fprintf(stderr, TEST_USAGE);
+        goto quit;
+      }
+      refrag = 1;
+      refrag_filename = argv[2];
+      argv += 2;
+      argc -= 2;
+    }
+    else if(!strcmp(argv[1], "-s"))
+    {
+      save = 1;
+      argv += 1;
+      argc -= 1;
+    }
+    else
+    {
+      fprintf(stderr, "unknown option %s\n", argv[1]);
+      fprintf(stderr, TEST_USAGE);
+       goto quit;
+     }
+  }
+
+  if(!src_filename || !frag_filename)
+  {
+    fprintf(stderr, "missing mandatory options\n");
+    fprintf(stderr, TEST_USAGE);
+    goto quit;
+  }
+
+  failure = test_encap_deencap(verbose,
+                               (label_type ? atoi(label_type):0),
+                               save, src_filename, frag_filename,
+                               refrag_filename);
+
+quit:
+  return failure;
+}
+
+/****************************************************************************
+ *
+ *   PRIVATE FUNCTIONS
+ *
+ *****************************************************************************/
+
+/**
+ * @brief Test the GSE library with a flow of IP or GSE packets to encapsulate
+ *
+ * @param verbose       0 for no debug messages, 1 for debug, 2 for more debug
+ * @param label_type    the label type
+ * @param src_filename  The name of the PCAP file that contains the source packets
+ * @param gse_frag_filename  The name of the PCAP file that contains the reference packets
+ *                      used for comparison
+ * @return              0 in case of success, 1 otherwise
+ */
+static int test_encap_deencap(int verbose, uint8_t label_type, int save,
+                              char *src_filename,
+                              char *frag_filename,
+                              char *refrag_filename)
+{
+  pcap_t *src_handle;
+  pcap_t *frag_handle = NULL;
+  pcap_t *refrag_handle = NULL;
+  pcap_t *cmp_handle;
+  pcap_dumper_t *frag_dumper = NULL;
+  pcap_dumper_t *refrag_dumper = NULL;
+  char errbuf[PCAP_ERRBUF_SIZE];
+  uint32_t link_len_src;
+  uint32_t link_len_frag = 0;
+  uint32_t link_len_refrag = 0;
+  uint32_t link_len_cmp;
+  struct pcap_pkthdr header;
+  unsigned char *packet;
+  unsigned char link_layer_head[MAX(ETHER_HDR_LEN, LINUX_COOKED_HDR_LEN)];
+  int is_failure = 1;
+  unsigned long counter;
+  unsigned long pkt_nbr = 0;
+  unsigned long tot_nbr = 0;
+  unsigned long rcv_pkt_nbr = 0;
+  unsigned long rcv_tot_nbr = 0;
+  unsigned long pdu_counter;
+  gse_encap_t *encap = NULL;
+  gse_vfrag_t *vfrag_pkt = NULL;
+  //gse_vfrag_t *refrag_pkt = NULL;
+  gse_vfrag_t *pdu = NULL;
+  uint8_t qos = 0;
+  gse_status_t status;
+  int frag_length_idx = 0;
+  //int refrag_length_idx = 0;
+  unsigned char *buffer;
+
+  uint8_t label[6] = {
+    0, 1, 2, 3, 4, 5,
+    };
+
+  if(!save)
+  {
+    if(refrag_filename != NULL)
+    {
+      DEBUG(verbose, "Compare fragmented packets with those in %s\n"
+                     "Compare refragmented packets with those in %s\n",
+            frag_filename, refrag_filename);
+    }
+    else
+    {
+      DEBUG(verbose, "Compare fragmented packets with those in %s\n",
+            frag_filename);
+    }
+  }
+  else
+  {
+    if(refrag_filename != NULL)
+    {
+      DEBUG(verbose, "Save fragmented packets in %s\n"
+                     "Save refragmented packets in %s\n",
+                     frag_filename, refrag_filename);
+    }
+    else
+    {
+      DEBUG(verbose, "Save fragmented packets in %s\n", frag_filename);
+    }
+  }
+  /* open the source dump file */
+  if(open_pcap(src_filename, verbose, &src_handle, &link_len_src) != 0)
+  {
+    goto error;
+  }
+
+  if(!save)
+  {
+    /* open the comparison dump file for fragmented packets */
+    if(open_pcap(frag_filename, verbose, &frag_handle, &link_len_frag) != 0)
+    {
+      goto close_input;
+    }
+
+    if(refrag_filename != NULL)
+    {
+      /* open the comparison dump file for refragmented packets */
+      if(open_pcap(refrag_filename, verbose, &refrag_handle, &link_len_refrag) != 0)
+      {
+        goto close_frag_handle;
+      }
+    }
+  }
+  else /* Create PCAP file to store GSE packets */
+  {
+    /* open the dump file to store fragmented packets */
+    frag_dumper = pcap_dump_open(src_handle, frag_filename);
+    if(frag_dumper == NULL)
+    {
+      DEBUG(verbose, "failed to open the refragment pcap dump: %s\n", errbuf);
+      goto close_input;
+    }
+
+    if(refrag_filename != NULL)
+    {
+      /* open the dump file to store refragmented packets */
+      refrag_dumper = pcap_dump_open(src_handle, refrag_filename);
+      if(refrag_dumper == NULL)
+      {
+        DEBUG(verbose, "failed to open the refragment pcap dump: %s\n", errbuf);
+        goto close_frag_handle;
+      }
+    }
+  }
+
+  /* open the comparison dump file for received pdu */
+  if(open_pcap(src_filename, verbose, &cmp_handle, &link_len_cmp) != 0)
+  {
+    goto close_refrag_handle;
+  }
+
+  /* Initialize the GSE library */
+  status = gse_encap_init(QOS_NBR, FIFO_SIZE, &encap);
+  if(status != GSE_STATUS_OK)
+  {
+    DEBUG(verbose, "Error %#.4x when initializing encapsulation (%s)\n", status,
+          gse_get_status(status));
+    goto close_comparison;
+  }
+
+  /* Allocate in/out vfrag */
+  status = gse_allocate_vfrag(&pdu, 1);
+  if(status != GSE_STATUS_OK)
+  {
+    DEBUG(verbose, "Error %#.4x when initializing PDU vfrag (%s)\n", status,
+          gse_get_status(status));
+    goto release_lib;
+  }
+  status = gse_allocate_vfrag(&vfrag_pkt, 0);
+  if(status != GSE_STATUS_OK)
+  {
+    DEBUG(verbose, "Error %#.4x when initializing packet vfrag (%s)\n", status,
+          gse_get_status(status));
+    goto release_lib;
+  }
+
+  /* for each packet in the dump */
+  counter = 0;
+  pdu_counter = 0;
+  while((packet = (unsigned char *) pcap_next(src_handle, &header)) != NULL)
+  {
+    unsigned char *in_packet;
+    size_t in_size;
+    int ret = 0;
+
+    counter++;
+
+    /* check Ethernet frame length */
+    if(header.len <= link_len_src || header.len != header.caplen)
+    {
+      DEBUG(verbose, "PDU #%lu: bad PCAP packet (len = %d, caplen = %d)\n",
+             counter, header.len, header.caplen);
+      goto release_lib;
+    }
+    if(counter == 1)
+    {
+      memcpy(link_layer_head, packet, link_len_src);
+    }
+
+    in_packet = packet + link_len_src;
+    in_size = header.len - link_len_src;
+
+    buffer = malloc(in_size + GSE_MAX_HEADER_LENGTH + GSE_MAX_TRAILER_LENGTH);
+    memcpy(buffer + GSE_MAX_HEADER_LENGTH, in_packet, in_size);
+
+    /* Encapsulate the input packets, use in_packet and in_size as
+       input */
+    status = gse_affect_buf_vfrag(pdu, buffer, GSE_MAX_HEADER_LENGTH, GSE_MAX_TRAILER_LENGTH, in_size);
+    /*
+    status = gse_create_vfrag_with_data(&pdu, in_size,
+                                        GSE_MAX_HEADER_LENGTH,
+                                        GSE_MAX_TRAILER_LENGTH,
+                                        in_packet, in_size);
+    */
+    if(status != GSE_STATUS_OK)
+    {
+      DEBUG(verbose, "Error %#.4x when creating virtual fragment #%lu (%s)\n",
+            status, counter, gse_get_status(status));
+      goto release_lib;
+    }
+
+    status = gse_encap_receive_pdu(pdu, encap, label, label_type, PROTOCOL, qos);
+    if(status != GSE_STATUS_OK)
+    {
+      DEBUG(verbose, "Error %#.4x when receiving PDU #%lu (%s)\n", status, counter,
+            gse_get_status(status));
+      goto release_lib;
+    }
+
+    DEBUG_L2(verbose, "\nPDU #%lu received from source file\n", counter);
+
+    pkt_nbr = 0; /* number of packets received in the FIFO */
+    tot_nbr = 0; /* number of fragments (frag_nbr + nbr refragmentation) */
+    rcv_pkt_nbr = 0;
+    rcv_tot_nbr = 0;
+    /* Encapsulate and deencapsulate GSE packets while a complete PDU has not been received */
+    do
+    {
+      /* Get a GSE packet in the FIFO */
+      ret = get_gse_packets(verbose,
+                         save,
+                         &vfrag_pkt,
+                         &encap,
+                         &frag_handle,
+                         &frag_dumper,
+                         link_len_frag,
+                         link_len_src,
+                         link_layer_head,
+                         frag_length_idx,
+                         qos,
+                         pkt_nbr);
+
+      frag_length_idx = (frag_length_idx + 1) % 20;
+
+      if (ret == 0)
+      {
+        pkt_nbr++;
+        tot_nbr ++;
+        status = gse_free_vfrag_no_alloc(&vfrag_pkt, 1, 0);
+        if(status != GSE_STATUS_OK)
+        {
+          DEBUG(verbose, "Error %#.4x when freeing packet #%lu (%s)\n",
+                status, pkt_nbr + 1, gse_get_status(status));
+          goto release_lib;
+        }
+      }
+
+    } while(ret == 0);
+    pdu_counter++;
+
+    DEBUG(verbose, "PDU #%lu: %lu packet(s), FIFO %d\n",
+          pdu_counter, pkt_nbr, qos);
+
+    qos = (qos + 1) % QOS_NBR;
+  }
+
+  /* everything went fine */
+  is_failure = 0;
+
+release_lib:
+  status = gse_encap_release(encap);
+  if(status != GSE_STATUS_OK)
+  {
+    is_failure = 1;
+    DEBUG(verbose, "Error %#.4x when releasing encapsulation (%s)\n", status, gse_get_status(status));
+  }
+close_comparison:
+  pcap_close(cmp_handle);
+close_refrag_handle:
+  if(refrag_filename != NULL)
+  {
+    if(!save)
+    {
+      pcap_close(refrag_handle);
+    }
+    else
+    {
+      if(refrag_dumper != NULL)
+      {
+        pcap_dump_close(refrag_dumper);
+      }
+    }
+  }
+close_frag_handle:
+  if(!save)
+  {
+    pcap_close(frag_handle);
+  }
+  else
+  {
+    if(frag_dumper != NULL)
+    {
+      pcap_dump_close(frag_dumper);
+    }
+  }
+close_input:
+  pcap_close(src_handle);
+
+error:
+  return is_failure;
+}
+
+/**
+ * @brief Open a PCAP file and check link layer parameters
+ *
+ * @param filename  The file name
+ * @param verbose   0 for no debug messages, 1 for debug, 2 for more debug
+ * @param link_len  Link layer length
+ * @return          0 on success, 1 on failure
+ */
+static int open_pcap(char *filename, int verbose, pcap_t **handle,
+                     uint32_t *link_len)
+{
+  char errbuf[PCAP_ERRBUF_SIZE];
+  int link_layer_type;
+  int is_failure = 1;
+
+  *handle = pcap_open_offline(filename, errbuf);
+  if(*handle == NULL)
+  {
+    DEBUG(verbose, "failed to open the PCAP file: %s\n", errbuf);
+    goto error;
+  }
+
+  /* link layer in the dump must be supported */
+  link_layer_type = pcap_datalink(*handle);
+  if(link_layer_type != DLT_EN10MB &&
+     link_layer_type != DLT_LINUX_SLL &&
+     link_layer_type != DLT_RAW)
+  {
+    DEBUG(verbose, "link layer type %d not supported in dump (supported = "
+           "%d, %d, %d)\n", link_layer_type, DLT_EN10MB, DLT_LINUX_SLL,
+           DLT_RAW);
+    goto close_input;
+  }
+
+  if(link_layer_type == DLT_EN10MB)
+    *link_len = ETHER_HDR_LEN;
+  else if(link_layer_type == DLT_LINUX_SLL)
+    *link_len = LINUX_COOKED_HDR_LEN;
+  else /* DLT_RAW */
+    *link_len = 0;
+
+  is_failure = 0;
+  return is_failure;
+
+close_input:
+  pcap_close(*handle);
+error:
+  return is_failure;
+}
+
+/**
+ * @brief Get a GSE packet in the FIFO and compare or save it
+ *
+ * @param verbose          0 for no debug messages, 1 for debug, 2 for more debug
+ * @param save             the save flag
+ * @param vfrag_pkt        OUT: the virtual fragment which will contain the GSE packet
+ * @param encap            the encapsulation context
+ * @param frag_length_idx  the index on fragment length
+ * @param frag_handle      the PCAP file which contains the GSE packets to compare
+ * @pram  frag_dumper      the PCAP dump file used to store the GSE packets
+ * @param link_len_frag    link layer length for fragmented packets
+ * @param link_layer_head  header written in front of the packets for the PCAP file
+ * @param qos              the qos value used to identify the FIFO
+ * @param pkt_nbr          the number of packet got in FIFO
+ * @return                 0 on success, -1 if FIFO is empty and 1 on failure
+ */
+static int get_gse_packets(int verbose,
+                           int save,
+                           gse_vfrag_t **vfrag_pkt,
+                           gse_encap_t **encap,
+                           pcap_t **frag_handle,
+                           pcap_dumper_t **frag_dumper,
+                           uint32_t link_len_frag,
+                           uint32_t link_len_src,
+                           unsigned char *link_layer_head,
+                           int frag_length_idx,
+                           uint8_t qos,
+                           unsigned long pkt_nbr)
+{
+  struct pcap_pkthdr frag_header;
+  unsigned char *frag_packet;
+  struct ether_header *eth_header;
+  struct pcap_pkthdr header;
+  gse_status_t status;
+
+  /* Get a packet in the FIFO */
+  status = gse_encap_get_packet_no_alloc(vfrag_pkt, *encap,
+                                         frag_length[frag_length_idx], qos);
+  if((status != GSE_STATUS_OK) && (status != GSE_STATUS_FIFO_EMPTY))
+  {
+    DEBUG(verbose, "Error %#.4x when getting packet #%lu (%s)\n",
+          status, pkt_nbr + 1, gse_get_status(status));
+    goto free_packet;
+  }
+  if(status == GSE_STATUS_OK)
+  {
+    DEBUG_L2(verbose, "Packet #%lu got in FIFO %u\n", pkt_nbr + 1, qos);
+    /* If the save option is deactivated, the packet is compared with a reference given as input */
+    if(!save)
+    {
+      frag_packet = (unsigned char *) pcap_next(*frag_handle, &frag_header);
+      if(frag_packet == NULL)
+      {
+        DEBUG(verbose, "packet #%lu: no packet available for comparison\n", pkt_nbr + 1);
+        goto free_packet;
+      }
+
+      /* compare the output fragmented packets with the ones given by the user */
+      if(frag_header.caplen <= link_len_frag)
+      {
+        DEBUG(verbose, "packet #%lu: packet available for comparison but too small\n",
+              pkt_nbr + 1);
+        goto free_packet;
+      }
+
+      if(!compare_packets(verbose, gse_get_vfrag_start(*vfrag_pkt),
+                          gse_get_vfrag_length(*vfrag_pkt),
+                          frag_packet + link_len_frag,
+                          frag_header.caplen - link_len_frag))
+      {
+        DEBUG(verbose, "packet #%lu: fragmented packet is not as attended\n", pkt_nbr + 1);
+        goto free_packet;
+      }
+    }
+    else /* The save option is activated */
+    {
+      if(*frag_dumper != NULL)
+      {
+        header.len = link_len_src + gse_get_vfrag_length(*vfrag_pkt);
+        header.caplen = header.len;
+        unsigned char output_frag[gse_get_vfrag_length(*vfrag_pkt) + link_len_src];
+        memcpy(output_frag + link_len_src, gse_get_vfrag_start(*vfrag_pkt),
+               gse_get_vfrag_length(*vfrag_pkt));
+        if(link_len_src != 0)
+        {
+          /* Copy link layer header from source packet */
+          memcpy(output_frag, link_layer_head, link_len_src);
+          if(link_len_src == ETHER_HDR_LEN) /* Ethernet only */
+          {
+            eth_header = (struct ether_header *) output_frag;
+            eth_header->ether_type = 0x162f; /* unused Ethernet ID ? */
+          }
+          else if(link_len_src == LINUX_COOKED_HDR_LEN) /* Linux Cooked Sockets only */
+          {
+            output_frag[LINUX_COOKED_HDR_LEN - 2] = 0x16;
+            output_frag[LINUX_COOKED_HDR_LEN - 1] = 0x2f;
+          }
+        }
+        pcap_dump((u_char *) (*frag_dumper), &header, output_frag);
+      }
+      else
+      {
+        DEBUG(verbose, "Fragment dumper missing\n");
+        goto free_packet;
+      }
+    }
+  }
+  else
+  {
+    DEBUG_L2(verbose, "FIFO %u empty\n", qos);
+    return -1;
+  }
+
+  return 0;
+
+free_packet:
+  status = gse_free_vfrag_no_alloc(vfrag_pkt, 0, 1);
+  if(status != GSE_STATUS_OK)
+  {
+    DEBUG(verbose, "Error %#.4x when destroying packet (%s)\n", status, gse_get_status(status));
+  }
+  return 1;
+}
+
+#if 0
+/**
+ * @brief Refragment a GSE packet and compare or save it
+ *
+ * @param verbose            0 for no debug messages, 1 for debug, 2 for more debug
+ * @param save               the save flag
+ * @param vfrag_pkt          IN: the virtual fragment which contains the GSE packet
+ *                           OUT: the virtual fragment which contains the first
+ *                                refragmented GSE packet
+ * @param refrag_pkt         OUT: the virtual fragment which contains the second
+ *                                refragmented GSE packet
+ * @param refrag_length_idx  the index on fragment length
+ * @param refrag_handle      the PCAP file which contains the GSE packets to compare
+ * @param refrag_dumper      the PCAP dumper file used to store the GSE packets
+ * @param link_len_refrag    link layer length for fragmented packets
+ * @param link_layer_head    header written in front of the packets for the PCAP file
+ * @param qos                the qos value used to identify the FIFO
+ * @param pkt_nbr            the number of packet got in FIFO
+ * @return                   0 on success, 1 on failure
+ */
+static int refrag(int verbose,
+                  int save,
+                  gse_vfrag_t **vfrag_pkt,
+                  gse_vfrag_t **refrag_pkt,
+                  pcap_t **refrag_handle,
+                  pcap_dumper_t **refrag_dumper,
+                  uint32_t link_len_refrag,
+                  uint32_t link_len_src,
+                  unsigned char *link_layer_head,
+                  int refrag_length_idx,
+                  uint8_t qos,
+                  unsigned long pkt_nbr)
+{
+  unsigned char *refrag_packet;
+  struct pcap_pkthdr refrag_header;
+  struct ether_header *eth_header;
+  struct pcap_pkthdr header;
+  gse_status_t status;
+
+  /* Refragment the GSE packet */
+  status = gse_refrag_packet(*vfrag_pkt, refrag_pkt,
+                             0, 0, qos, refrag_length[refrag_length_idx]);
+  if((status != GSE_STATUS_OK) && (status != GSE_STATUS_REFRAG_UNNECESSARY))
+  {
+    DEBUG(verbose, "Error %#.4x when refragmenting packet #%lu (%s)\n",
+          status, pkt_nbr, gse_get_status(status));
+    goto free_packets;
+  }
+
+  /* If the save option is deactivated, the packets are compared with the references
+   * given as input */
+  if(!save)
+  {
+    // First fragment
+    refrag_packet = (unsigned char *) pcap_next(*refrag_handle, &refrag_header);
+    if(refrag_packet == NULL)
+    {
+      DEBUG(verbose, "packet #%lu: no packet available for comparison\n", pkt_nbr);
+      goto free_packets;
+    }
+
+    /* compare the output refragmented packets with the ones given by the user */
+    if(refrag_header.caplen <= link_len_refrag)
+    {
+      DEBUG(verbose, "packet #%lu: packet available for comparison but too small\n",
+            pkt_nbr);
+      goto free_packets;
+    }
+
+    if(!compare_packets(verbose, gse_get_vfrag_start(*vfrag_pkt),
+                        gse_get_vfrag_length(*vfrag_pkt),
+                        refrag_packet + link_len_refrag,
+                        refrag_header.caplen - link_len_refrag))
+    {
+      DEBUG(verbose, "packet #%lu: first refragmented packet is not as attended\n", pkt_nbr);
+      goto free_packets;
+    }
+
+    /* If the packet has been refragmented */
+    if(*refrag_pkt != NULL)
+    {
+      DEBUG_L2(verbose, "packet #%lu has been refragmented\n", pkt_nbr);
+      // Second fragment
+      refrag_packet = (unsigned char *) pcap_next(*refrag_handle, &refrag_header);
+      if(refrag_packet == NULL)
+      {
+        DEBUG(verbose, "packet #%lu: no packet available for comparison\n", pkt_nbr);
+        goto free_packets;
+      }
+
+      /* compare the output refragmented packets with the ones given by the user */
+      if(refrag_header.caplen <= link_len_refrag)
+      {
+        DEBUG(verbose, "packet #%lu: packet available for comparison but too small\n", pkt_nbr);
+        goto free_packets;
+      }
+
+      if(!compare_packets(verbose, gse_get_vfrag_start(*refrag_pkt),
+                          gse_get_vfrag_length(*refrag_pkt),
+                          refrag_packet + link_len_refrag,
+                          refrag_header.caplen - link_len_refrag))
+      {
+        DEBUG(verbose, "packet #%lu: second refragmented packet is not as attended\n",
+              pkt_nbr);
+        goto free_packets;
+      }
+    }
+  }
+  else /* The save option is activated */
+  {
+    if(*refrag_dumper != NULL)
+    {
+      unsigned char output_refrag_first[gse_get_vfrag_length(*vfrag_pkt) + link_len_src];
+      //first fragment
+      header.len = link_len_src + gse_get_vfrag_length(*vfrag_pkt);
+      header.caplen = header.len;
+      memcpy(output_refrag_first + link_len_src,
+             gse_get_vfrag_start(*vfrag_pkt),
+             gse_get_vfrag_length(*vfrag_pkt));
+      if(link_len_src != 0)
+      {
+        //Copy link layer header from source packet
+        memcpy(output_refrag_first, link_layer_head, link_len_src);
+        if(link_len_src == ETHER_HDR_LEN) /* Ethernet only */
+        {
+          eth_header = (struct ether_header *) output_refrag_first;
+          eth_header->ether_type = 0x162f; /* unused Ethernet ID ? */
+        }
+        else if(link_len_src == LINUX_COOKED_HDR_LEN) /* Linux Cooked Sockets only */
+        {
+          output_refrag_first[LINUX_COOKED_HDR_LEN - 2] = 0x16;
+          output_refrag_first[LINUX_COOKED_HDR_LEN - 1] = 0x2f;
+        }
+      }
+      pcap_dump((u_char *) (*refrag_dumper), &header, output_refrag_first);
+
+      /* If the packet has been refragmented */
+      if(*refrag_pkt != NULL)
+      {
+        /* second fragment */
+        unsigned char output_refrag_second[gse_get_vfrag_length(*refrag_pkt) + link_len_src];
+        memcpy(output_refrag_second + link_len_src, gse_get_vfrag_start(*refrag_pkt),
+               gse_get_vfrag_length(*refrag_pkt));
+        header.len = link_len_src + gse_get_vfrag_length(*refrag_pkt);
+        header.caplen = header.len;
+        if(link_len_src != 0)
+        {
+          /* Copy link layer header from source packet */
+          memcpy(output_refrag_second, link_layer_head, link_len_src);
+          if(link_len_src == ETHER_HDR_LEN) /* Ethernet only */
+          {
+            eth_header = (struct ether_header *) output_refrag_second;
+            eth_header->ether_type = 0x162f; /* unused Ethernet ID ? */
+          }
+          else if(link_len_src == LINUX_COOKED_HDR_LEN) /* Linux Cooked Sockets only */
+          {
+            output_refrag_second[LINUX_COOKED_HDR_LEN - 2] = 0x16;
+            output_refrag_second[LINUX_COOKED_HDR_LEN - 1] = 0x2f;
+          }
+        }
+        pcap_dump((u_char *) (*refrag_dumper), &header, output_refrag_second);
+      }
+    }
+    else
+    {
+      DEBUG(verbose, "Fragment dumper missing\n");
+      goto free_packets;
+    }
+  }
+
+  return 0;
+
+free_packets:
+  status = gse_free_vfrag_no_alloc(&vfrag_pkt, 0, 1);
+  if(status != GSE_STATUS_OK)
+  {
+    DEBUG(verbose, "Error %#.4x when destroying packet (%s)\n", status, gse_get_status(status));
+  }
+  status = gse_free_vfrag_no_alloc(&refrag_pkt, 0, 1);
+  if(status != GSE_STATUS_OK)
+  {
+    DEBUG(verbose, "Error %#.4x when destroying packet (%s)\n", status, gse_get_status(status));
+  }
+  return 1;
+}
+
+/**
+ * @brief Deencapsulate one or two GSE packets
+ *
+ * @param verbose         0 for no debug messages, 1 for debug, 2 for more debug
+ * @param save            the save flag
+ * @param vfrag_pkt       IN: the virtual fragment which contains a first refragmented
+ *                            GSE packet
+ * @param vfrag_pkt       IN: the virtual fragment which contains a second refragmented
+ *                            GSE packet
+ * @param deencap         the deencapsulation context
+ * @param cmp_handle      the PCAP file which contains the GSE packets to compare
+ * @param link_len_cmp    link layer length for fragmented packets
+ * @return                0 on success, -1 if a PDU is received, 1 on failure
+ */
+static int deencap_pkt(int verbose,
+                       gse_vfrag_t *vfrag_pkt,
+                       gse_vfrag_t *refrag_pkt,
+                       gse_deencap_t **deencap,
+                       pcap_t **cmp_handle,
+                       uint32_t link_len_cmp,
+                       unsigned long rcv_pkt_nbr,
+                       unsigned long *rcv_tot_nbr,
+                       unsigned long pdu_counter)
+{
+  uint8_t rcv_label[6];
+  uint8_t label_type;
+  uint16_t protocol;
+  uint16_t gse_length;
+  unsigned char *cmp_packet;
+  struct pcap_pkthdr cmp_header;
+  int j;
+  int is_failure = 1;
+  gse_vfrag_t *rcv_pdu = NULL;
+
+  gse_status_t status= GSE_STATUS_OK;
+
+  /* Deencap the GSE packet of the first fragment of the refragmented packet */
+  status = gse_deencap_packet(vfrag_pkt, *deencap, &label_type, rcv_label,
+                              &protocol, &rcv_pdu, &gse_length);
+  if((status != GSE_STATUS_OK) && (status != GSE_STATUS_PDU_RECEIVED))
+  {
+    DEBUG(verbose, "Error %#.4x when deencapsulating packet #%lu (fragment 1) (%s)\n",
+          status, rcv_pkt_nbr + 1, gse_get_status(status));
+    goto free_packets;
+  }
+  vfrag_pkt = NULL;
+  DEBUG_L2(verbose, "GSE packet #%lu (fragment 1) received, packet length = %d\n",
+           *rcv_tot_nbr + 1, gse_length);
+  *rcv_tot_nbr = *rcv_tot_nbr + 1;
+
+  /* Deencapsulate the second fragment if the packet has been refragmented */
+  if((refrag_pkt != NULL) && (status != GSE_STATUS_PDU_RECEIVED))
+  {
+    status = gse_deencap_packet(refrag_pkt, *deencap, &label_type, rcv_label,
+                                &protocol, &rcv_pdu, &gse_length);
+    if((status != GSE_STATUS_OK) && (status != GSE_STATUS_PDU_RECEIVED))
+    {
+      DEBUG(verbose, "Error %#.4x when deencapsulating packet #%lu (fragment 2) (%s)\n",
+            status, rcv_pkt_nbr + 1, gse_get_status(status));
+      goto free_refrag;
+    }
+    DEBUG_L2(verbose, "GSE packet #%lu (fragment 2) received, packet length = %d\n",
+             *rcv_tot_nbr + 1, gse_length);
+    *rcv_tot_nbr = *rcv_tot_nbr + 1;
+  }
+
+  /* A complete PDU has been received */
+  if(status == GSE_STATUS_PDU_RECEIVED)
+  {
+    cmp_packet = (unsigned char *) pcap_next(*cmp_handle, &cmp_header);
+    if(cmp_packet == NULL)
+    {
+      DEBUG(verbose, "PDU #%lu: no PDU available for comparison\n", pdu_counter);
+      goto free_pdu;
+    }
+
+    /* compare the output packets with the ones given by the user */
+    if(cmp_header.caplen <= link_len_cmp)
+    {
+      DEBUG(verbose, "PDU #%lu: PDU available for comparison but too small\n",
+            pdu_counter);
+      goto free_pdu;
+    }
+
+    if(!compare_packets(verbose, gse_get_vfrag_start(rcv_pdu), gse_get_vfrag_length(rcv_pdu),
+                        cmp_packet + link_len_cmp, cmp_header.caplen - link_len_cmp))
+    {
+      DEBUG(verbose, "PDU #%lu: generated PDU is not as attended\n", pdu_counter);
+      goto free_pdu;
+    }
+
+    DEBUG_L2(verbose, "Complete PDU #%lu:\nLabel Type: %d | Protocol: %#.4x | Label: %.2d",
+             pdu_counter, label_type, protocol, rcv_label[0]);
+    for(j = 1; j < gse_get_label_length(label_type); j++)
+    {
+      DEBUG_L2(verbose, ":%.2d", rcv_label[j]);
+    }
+    DEBUG_L2(verbose, " (in hexa)\n");
+
+    if(rcv_pdu != NULL)
+    {
+      status = gse_free_vfrag(&rcv_pdu);
+      if(status != GSE_STATUS_OK)
+      {
+        DEBUG(verbose, "Error %#.4x when destroying pdu (%s)\n", status, gse_get_status(status));
+        goto free_pdu;
+      }
+    }
+    is_failure = -1;
+  }
+  else
+  {
+    is_failure = 0;
+  }
+
+  return is_failure;
+
+free_packets:
+  status = gse_free_vfrag(&vfrag_pkt);
+  if(status != GSE_STATUS_OK)
+  {
+    DEBUG(verbose, "Error %#.4x when destroying packet (%s)\n", status, gse_get_status(status));
+  }
+free_refrag:
+  status = gse_free_vfrag(&refrag_pkt);
+  if(status != GSE_STATUS_OK)
+  {
+    DEBUG(verbose, "Error %#.4x when destroying packet (%s)\n", status, gse_get_status(status));
+  }
+  return is_failure;
+free_pdu:
+  status = gse_free_vfrag(&rcv_pdu);
+  if(status != GSE_STATUS_OK)
+  {
+    DEBUG(verbose, "Error %#.4x when destroying PDU (%s)\n", status, gse_get_status(status));
+  }
+  return is_failure;
+}
+#endif
+
+
+/**
+ * @brief Compare two network packets and print differences if any
+ *
+ * @param verbose   0 for no debug messages, 1 for debug, 2 for more debug
+ * @param pkt1      The first packet
+ * @param pkt1_size The size of the first packet
+ * @param pkt2      The second packet
+ * @param pkt2_size The size of the second packet
+ * @return          Whether the packets are equal or not
+ */
+static int compare_packets(int verbose,
+                           unsigned char *pkt1, int pkt1_size,
+                           unsigned char *pkt2, int pkt2_size)
+{
+  int valid = 1;
+  int min_size;
+  int i, j, k;
+  char str1[4][7], str2[4][7];
+  char sep1, sep2;
+
+  min_size = pkt1_size > pkt2_size ? pkt2_size : pkt1_size;
+
+  /* do not compare more than 180 bytes to avoid huge output */
+  min_size = MIN(180, min_size);
+
+  /* if packets are equal, do not print the packets */
+  if(pkt1_size == pkt2_size && memcmp(pkt1, pkt2, pkt1_size) == 0)
+    goto skip;
+
+  /* packets are different */
+  valid = 0;
+
+  DEBUG(verbose, "------------------------------ Compare ------------------------------\n");
+
+  if(pkt1_size != pkt2_size)
+  {
+    DEBUG(verbose, "packets have different sizes (%d != %d), compare only the %d "
+           "first bytes\n", pkt1_size, pkt2_size, min_size);
+  }
+
+  j = 0;
+  for(i = 0; i < min_size; i++)
+  {
+    if(pkt1[i] != pkt2[i])
+    {
+      sep1 = '#';
+      sep2 = '#';
+    }
+    else
+    {
+      sep1 = '[';
+      sep2 = ']';
+    }
+
+    sprintf(str1[j], "%c0x%.2x%c", sep1, pkt1[i], sep2);
+    sprintf(str2[j], "%c0x%.2x%c", sep1, pkt2[i], sep2);
+
+    /* make the output human readable */
+    if(j >= 3 || (i + 1) >= min_size)
+    {
+      for(k = 0; k < 4; k++)
+      {
+        if(k < (j + 1))
+          DEBUG(verbose, "%s  ", str1[k]);
+        else /* fill the line with blanks if nothing to print */
+          DEBUG(verbose, "        ");
+      }
+
+      DEBUG(verbose, "      ");
+
+      for(k = 0; k < (j + 1); k++)
+        DEBUG(verbose, "%s  ", str2[k]);
+
+      DEBUG(verbose, "\n");
+
+      j = 0;
+    }
+    else
+    {
+      j++;
+    }
+  }
+
+  DEBUG(verbose, "----------------------- packets are different -----------------------\n");
+
+  return valid;
+
+skip:
+  return valid;
+}

=== added file 'test/non_regression_tests_no_alloc.sh'
--- test/non_regression_tests_no_alloc.sh	1970-01-01 00:00:00 +0000
+++ test/non_regression_tests_no_alloc.sh	2013-03-11 14:09:17 +0000
@@ -0,0 +1,58 @@
+#!/bin/bash
+
+APP="non_regression_tests_no_alloc"
+
+SCRIPT="$0"
+if [ "x$MAKELEVEL" != "x" ] ; then
+    BASEDIR="${srcdir}"
+else
+    BASEDIR=$( dirname "${SCRIPT}" )
+fi
+BASEDIR_APP=$( dirname "${SCRIPT}" )
+
+# Try to determinate the path of the executable
+if [ ! -x "${BASEDIR_APP}/${APP}" ] ; then
+    if [ x"${builddir}" != "x" ] ; then
+        APP="${builddir}/test/${APP}"
+    else
+        APP="${srcdir}/${APP}"
+    fi
+else
+    APP="${BASEDIR_APP}/${APP}"
+fi
+
+gse_args=" -r ${BASEDIR}/refragmented.pcap -c ${BASEDIR}/fragmented.pcap -i ${BASEDIR}/source.pcap"
+gse_args_label3=" -r ${BASEDIR}/refragmented_label_3.pcap -c ${BASEDIR}/fragmented_label_3.pcap -i ${BASEDIR}/source.pcap --label-type 1"
+gse_args_label0=" -r ${BASEDIR}/refragmented_label_0.pcap -c ${BASEDIR}/fragmented_label_0.pcap -i ${BASEDIR}/source.pcap --label-type 2"
+
+
+ARGS=( \
+  "${gse_args}" \
+  "${gse_args_label0}" \
+  "${gse_args_label3}" \
+  )
+
+DESCRIPTION=( \
+  "GSE test: " \
+  "GSE test with LT='01': " \
+  "GSE test with LT='11': " \
+  )
+
+GREEN="\\033[1;32m"
+NORMAL="\\033[0;39m"
+RED="\\033[1;31m"
+BLUE="\\033[1;34m"
+BLUE_U="\\033[4;34m"
+
+/bin/echo -e ""
+/bin/echo -e "${BLUE}${BLUE_U}Run tests in `pwd`${NORMAL}\n"
+
+for index in "${!ARGS[@]}"; do
+  /bin/echo -e -n "${BLUE}${DESCRIPTION[$index]}${NORMAL}"
+  ${APP} ${ARGS[$index]} || (/bin/echo -e "${RED} FAIL${NORMAL}" && ${APP} --verbose 2 ${ARGS[$index]})
+  if [ "$?" -ne "0" ]; then
+    exit 1
+  fi
+  /bin/echo -e "${GREEN} SUCCESS${NORMAL}"
+done
+

=== modified file 'test/samples/internet_trafic/Makefile.am'
--- test/samples/internet_trafic/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/internet_trafic/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/icmp+tcp/Makefile.am'
--- test/samples/ipv4/icmp+tcp/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/icmp+tcp/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/icmp/Makefile.am'
--- test/samples/ipv4/icmp/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/icmp/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/ipv4/icmp/Makefile.am'
--- test/samples/ipv4/ipv4/icmp/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/ipv4/icmp/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/ipv4/udp/Makefile.am'
--- test/samples/ipv4/ipv4/udp/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/ipv4/udp/Makefile.am	2013-03-11 14:09:17 +0000
@@ -8,7 +8,8 @@
 	rtp
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/ipv4/udp/rtp/mp3/Makefile.am'
--- test/samples/ipv4/ipv4/udp/rtp/mp3/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/ipv4/udp/rtp/mp3/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/ipv4/udp/rtp/video1/Makefile.am'
--- test/samples/ipv4/ipv4/udp/rtp/video1/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/ipv4/udp/rtp/video1/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/ipv4/udp/rtp/video2/Makefile.am'
--- test/samples/ipv4/ipv4/udp/rtp/video2/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/ipv4/udp/rtp/video2/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/ipv4/udplite/Makefile.am'
--- test/samples/ipv4/ipv4/udplite/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/ipv4/udplite/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/ipv6/icmp/Makefile.am'
--- test/samples/ipv4/ipv6/icmp/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/ipv6/icmp/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/ipv6/udp/Makefile.am'
--- test/samples/ipv4/ipv6/udp/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/ipv6/udp/Makefile.am	2013-03-11 14:09:17 +0000
@@ -8,7 +8,8 @@
 	rtp
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/ipv6/udp/rtp/video1/Makefile.am'
--- test/samples/ipv4/ipv6/udp/rtp/video1/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/ipv6/udp/rtp/video1/Makefile.am	2013-03-11 14:09:17 +0000
@@ -8,7 +8,8 @@
 	extension
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/ipv6/udp/rtp/video1/extension/Makefile.am'
--- test/samples/ipv4/ipv6/udp/rtp/video1/extension/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/ipv6/udp/rtp/video1/extension/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/ipv6/udp/rtp/video2/Makefile.am'
--- test/samples/ipv4/ipv6/udp/rtp/video2/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/ipv6/udp/rtp/video2/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/ipv6/udplite/Makefile.am'
--- test/samples/ipv4/ipv6/udplite/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/ipv6/udplite/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/udp/Makefile.am'
--- test/samples/ipv4/udp/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/udp/Makefile.am	2013-03-11 14:09:17 +0000
@@ -8,7 +8,8 @@
 	rtp
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/udp/rtp/h323/Makefile.am'
--- test/samples/ipv4/udp/rtp/h323/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/udp/rtp/h323/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/udp/rtp/misc/Makefile.am'
--- test/samples/ipv4/udp/rtp/misc/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/udp/rtp/misc/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/udp/rtp/mp3/Makefile.am'
--- test/samples/ipv4/udp/rtp/mp3/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/udp/rtp/mp3/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/udp/rtp/rtp_rtp_icmp/Makefile.am'
--- test/samples/ipv4/udp/rtp/rtp_rtp_icmp/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/udp/rtp/rtp_rtp_icmp/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/udp/rtp/video1/Makefile.am'
--- test/samples/ipv4/udp/rtp/video1/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/udp/rtp/video1/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/udp/rtp/video2/Makefile.am'
--- test/samples/ipv4/udp/rtp/video2/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/udp/rtp/video2/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/udp/rtp/video3/Makefile.am'
--- test/samples/ipv4/udp/rtp/video3/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/udp/rtp/video3/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/udp/rtp/voip+video/Makefile.am'
--- test/samples/ipv4/udp/rtp/voip+video/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/udp/rtp/voip+video/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/udp/rtp/voip/Makefile.am'
--- test/samples/ipv4/udp/rtp/voip/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/udp/rtp/voip/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/udplite/Makefile.am'
--- test/samples/ipv4/udplite/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/udplite/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4fragmented/Makefile.am'
--- test/samples/ipv4fragmented/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4fragmented/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv6/icmp/Makefile.am'
--- test/samples/ipv6/icmp/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv6/icmp/Makefile.am	2013-03-11 14:09:17 +0000
@@ -8,7 +8,8 @@
 	extension
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv6/icmp/extension/Makefile.am'
--- test/samples/ipv6/icmp/extension/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv6/icmp/extension/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv6/ipv6/icmp/Makefile.am'
--- test/samples/ipv6/ipv6/icmp/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv6/ipv6/icmp/Makefile.am	2013-03-11 14:09:17 +0000
@@ -8,7 +8,8 @@
 	extension
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv6/ipv6/icmp/extension/Makefile.am'
--- test/samples/ipv6/ipv6/icmp/extension/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv6/ipv6/icmp/extension/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv6/ipv6/udp/Makefile.am'
--- test/samples/ipv6/ipv6/udp/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv6/ipv6/udp/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv6/ipv6/udplite/Makefile.am'
--- test/samples/ipv6/ipv6/udplite/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv6/ipv6/udplite/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv6/udp/Makefile.am'
--- test/samples/ipv6/udp/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv6/udp/Makefile.am	2013-03-11 14:09:17 +0000
@@ -9,7 +9,8 @@
 	rtp
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv6/udp/extension/Makefile.am'
--- test/samples/ipv6/udp/extension/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv6/udp/extension/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv6/udp/rtp/audio_vlc/Makefile.am'
--- test/samples/ipv6/udp/rtp/audio_vlc/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv6/udp/rtp/audio_vlc/Makefile.am	2013-03-11 14:09:17 +0000
@@ -8,7 +8,8 @@
 	extension 
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv6/udp/rtp/audio_vlc/extension/Makefile.am'
--- test/samples/ipv6/udp/rtp/audio_vlc/extension/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv6/udp/rtp/audio_vlc/extension/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv6/udp/rtp/video1/Makefile.am'
--- test/samples/ipv6/udp/rtp/video1/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv6/udp/rtp/video1/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv6/udp/rtp/video2/Makefile.am'
--- test/samples/ipv6/udp/rtp/video2/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv6/udp/rtp/video2/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv6/udplite/Makefile.am'
--- test/samples/ipv6/udplite/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv6/udplite/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

# Begin bundle
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
/**
 * @file     eval_gse.c
 * @author   Audric Schiltknecht / Viveris Technologies
 * @date     01 mars 2013
 * @version  1.0
 * @brief    Evaluate libgse encapsulation performance
 */

#include <gse/constants.h>
#include <gse/encap.h>
#include <gse/virtual_fragment.h>
#include <gse/header_fields.h>

#include <strings.h>
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#include <unistd.h>
#include <time.h>

#define MIN(x, y)  (((x) < (y)) ? (x) : (y))

#define IP_PAYLOAD_LENGTH 40

#define BBFRAME_LENGTH 2001

#define NB_ITER 1E6

#define QOS_NR 1
#define FIFO_SIZE 1

#define PROTOCOL_TYPE 0x0800
#define QOS_VALUE 0

#define GSE_MIN_PACKET_LENGTH 12
#define GSE_MAX_PACKET_LENGTH (4095 + 2)

unsigned char ip_payload[IP_PAYLOAD_LENGTH];
unsigned char bbframe[BBFRAME_LENGTH];

unsigned char buffer[IP_PAYLOAD_LENGTH + GSE_MAX_HEADER_LENGTH + GSE_MAX_TRAILER_LENGTH];

uint8_t label[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };

int main(void)
{
	gse_encap_t *encap_context;
	gse_vfrag_t *in_vfrag, *out_vfrag;
	gse_status_t status;

	int size;
	size_t vfrag_length;
	unsigned char *gse_packet;
	int nb_fragment = 0;

	long long iter;

	uint8_t end_indicator;
	bool is_end;

	clock_t clock_start, total_tics;

	// Defining payload
	memset(ip_payload, 0x42, IP_PAYLOAD_LENGTH);

	// Initialize encap context
	status = gse_encap_init(QOS_NR, FIFO_SIZE, &encap_context);
	if (status != GSE_STATUS_OK)
	{
		fprintf(stderr, "Fail to initialize encapsulation library: %s\n",
		        gse_get_status(status));
		return 1;
	}

	// Initialize input vfrag
	status = gse_allocate_vfrag(&in_vfrag, 1);
	if (status != GSE_STATUS_OK)
	{
		fprintf(stderr, "Fail to create input vfrag: %s\n",
				gse_get_status(status));
		return 1;
	}

	// Initialize output vfrag
	status = gse_allocate_vfrag(&out_vfrag, 0);
	if (status != GSE_STATUS_OK)
	{
		fprintf(stderr, "Fail to create input vfrag: %s\n",
				gse_get_status(status));
		return 1;
	}

	size = BBFRAME_LENGTH;
	clock_start = clock();
	for (iter = 0 ; iter < NB_ITER ; ++iter)
	{
		//printf("Iter #%d\n", iter);
		// Initialize input buffer for vfrag
		bzero(buffer, IP_PAYLOAD_LENGTH + GSE_MAX_HEADER_LENGTH + GSE_MAX_TRAILER_LENGTH);
		memcpy(buffer + GSE_MAX_HEADER_LENGTH, ip_payload, IP_PAYLOAD_LENGTH);


		// Feed IP payload to GSE compressor
		status = gse_affect_buf_vfrag(in_vfrag, buffer, GSE_MAX_HEADER_LENGTH, GSE_MAX_TRAILER_LENGTH, IP_PAYLOAD_LENGTH);
		if (status != GSE_STATUS_OK)
		{
			fprintf(stderr, "Fail to copy data into input vfrag: %s\n",
			        gse_get_status(status));
			// in_vfrag is automatically freed in case of error
			goto free_context;
		}

		// Put PDU into encap context
		// One copy: label value
		status = gse_encap_receive_pdu(in_vfrag, encap_context, label,
		                               GSE_LT_NO_LABEL, PROTOCOL_TYPE, QOS_VALUE);
		if (status != GSE_STATUS_OK)
		{
			fprintf(stderr, "Fail to receive PDU: %s\n",
			        gse_get_status(status));
			// in_vfrag is automatically freed in case of error
			goto free_context;
		}

		// Fill BBFrames until no more encapsulated PDU
		do
		{
			// Get GSE packet
			status = gse_encap_get_packet_no_alloc(&out_vfrag, encap_context, MIN(size, GSE_MAX_PACKET_LENGTH), QOS_VALUE);
			if (status != GSE_STATUS_OK)
			{
				fprintf(stderr, "Fail to retrieve GSE packet: %s\n",
				        gse_get_status(status));
				goto free_context;
			}

			vfrag_length = gse_get_vfrag_length(out_vfrag);

			// Get pointer on packet start
			gse_packet = gse_get_vfrag_start(out_vfrag);

			// One copy here
			memcpy(bbframe + BBFRAME_LENGTH - size, gse_packet, vfrag_length);

			size -= vfrag_length;
			if (size <= GSE_MIN_PACKET_LENGTH)
				// BBFrame full, start new one
				size = BBFRAME_LENGTH;

			// Test if packet contains 'E' bit
			status = gse_get_end_indicator(gse_packet, &end_indicator);
			if (status != GSE_STATUS_OK)
			{
				fprintf(stderr, "Fail to retrieve GSE end indicator: %s\n",
				        gse_get_status(status));
				goto free_context;
			}

			// Is packet complete, or is it first fragment ?
			// (nb: only at most 2 fragments per packet)
			is_end = ((end_indicator & 0x01) == 0x01);
			if (!is_end)
				nb_fragment++;

			// Free vfrag before next call to gse_encap_get_packet() per
			// libgse requirement
			gse_free_vfrag_no_alloc(&out_vfrag, 1, 0);

		} while (is_end != true);
	}
	total_tics = clock() - clock_start;

	printf("NB iter: %e\n", NB_ITER);
	printf("Nb fragment: %d\n", nb_fragment);
	printf("Tics: %d - %e seconds\n", (int)total_tics, ((double)total_tics) / CLOCKS_PER_SEC);
	printf("Tics / loop: %f - %e seconds\n", ((double)total_tics / NB_ITER), (((double)total_tics)/NB_ITER)/CLOCKS_PER_SEC);

free_context:
	status = gse_free_vfrag_no_alloc(&in_vfrag, 0, 0);
			if (status != GSE_STATUS_OK)
			{
				fprintf(stderr, "Fail to retrieve GSE end indicator: %s\n",
				        gse_get_status(status));
			}
	status = gse_free_vfrag_no_alloc(&out_vfrag, 0, 1);
			if (status != GSE_STATUS_OK)
			{
				fprintf(stderr, "Fail to retrieve GSE end indicator: %s\n",
				        gse_get_status(status));
			}
	// Release context
	gse_encap_release(encap_context);

	return status;
}
/**
 * @file     eval_gse.c
 * @author   Audric Schiltknecht / Viveris Technologies
 * @date     01 mars 2013
 * @version  1.0
 * @brief    Evaluate libgse encapsulation performance
 */

#include <gse/constants.h>
#include <gse/encap.h>
#include <gse/virtual_fragment.h>
#include <gse/header_fields.h>

#include <strings.h>
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#include <unistd.h>
#include <time.h>

#define MIN(x, y)  (((x) < (y)) ? (x) : (y))

#define IP_PAYLOAD_LENGTH 40

#define BBFRAME_LENGTH 2001

#define NB_ITER 1E6

#define QOS_NR 1
#define FIFO_SIZE 1

#define PROTOCOL_TYPE 0x0800
#define QOS_VALUE 0

#define GSE_MIN_PACKET_LENGTH 12
#define GSE_MAX_PACKET_LENGTH (4095 + 2)

unsigned char ip_payload[IP_PAYLOAD_LENGTH];
unsigned char bbframe[BBFRAME_LENGTH];

uint8_t label[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };

int main(void)
{
	gse_encap_t *encap_context;
	gse_vfrag_t *in_vfrag, *out_vfrag;
	gse_status_t status;

	int size;
	size_t vfrag_length;
	unsigned char *gse_packet;
	int nb_fragment = 0;

	long long iter;

	uint8_t end_indicator;
	bool is_end;

	clock_t clock_start, total_tics;

	// Zero-ing payload
	bzero(ip_payload, IP_PAYLOAD_LENGTH);

	// Initialize encap context
	status = gse_encap_init(QOS_NR, FIFO_SIZE, &encap_context);
	if (status != GSE_STATUS_OK)
	{
		fprintf(stderr, "Fail to initialize encapsulation library: %s\n",
		        gse_get_status(status));
		return 1;
	}

	size = BBFRAME_LENGTH;
	clock_start = clock();
	for (iter = 0 ; iter < NB_ITER ; ++iter)
	{
		//printf("Iter #%d\n", iter);

		// Initialize input vfrag
		// It currently cannot be done outside of the loop,
		// since there is no other way to "reset" a vfrag,
		// and calling gse_free_vfrag() release the allocated memory...
		// One vfrag-allocation here:
		//  - One for the vfrag structure
		//  - One for the vbuf structure
		//  - One for the vbuf buffer
		status = gse_create_vfrag(&in_vfrag,
								  GSE_MAX_PDU_LENGTH,
								  GSE_MAX_HEADER_LENGTH,
								  GSE_MAX_TRAILER_LENGTH);
		if (status != GSE_STATUS_OK)
		{
			fprintf(stderr, "Fail to create input vfrag: %s\n",
					gse_get_status(status));
			return 1;
		}

		// Feed IP payload to GSE compressor
		// One copy here
		status = gse_copy_data(in_vfrag, ip_payload, IP_PAYLOAD_LENGTH);
		if (status != GSE_STATUS_OK)
		{
			fprintf(stderr, "Fail to copy data into input vfrag: %s\n",
			        gse_get_status(status));
			// in_vfrag is automatically freed in case of error
			goto free_context;
		}

		// Put PDU into encap context
		// One copy: label value
		status = gse_encap_receive_pdu(in_vfrag, encap_context, label,
		                               GSE_LT_NO_LABEL, PROTOCOL_TYPE, QOS_VALUE);
		if (status != GSE_STATUS_OK)
		{
			fprintf(stderr, "Fail to receive PDU: %s\n",
			        gse_get_status(status));
			// in_vfrag is automatically freed in case of error
			goto free_context;
		}

		// Fill BBFrames until no more encapsulated PDU
		do
		{
			// Get GSE packet
			// One allocation here (out_vfrag)
			// One copy (for extensions, even if there is none (memcpy(size=0))
			// One free here (in_vfrag if PDU is complete)
			status = gse_encap_get_packet(&out_vfrag, encap_context, MIN(size, GSE_MAX_PACKET_LENGTH), QOS_VALUE);
			if (status != GSE_STATUS_OK)
			{
				fprintf(stderr, "Fail to retrieve GSE packet: %s\n",
				        gse_get_status(status));
				goto free_context;
			}

			vfrag_length = gse_get_vfrag_length(out_vfrag);

			// Get pointer on packet start
			gse_packet = gse_get_vfrag_start(out_vfrag);

			// One copy here
			memcpy(bbframe + BBFRAME_LENGTH - size, gse_packet, vfrag_length);

			size -= vfrag_length;
			if (size <= GSE_MIN_PACKET_LENGTH)
				// BBFrame full, start new one
				size = BBFRAME_LENGTH;

			// Test if packet contains 'E' bit
			status = gse_get_end_indicator(gse_packet, &end_indicator);
			if (status != GSE_STATUS_OK)
			{
				fprintf(stderr, "Fail to retrieve GSE end indicator: %s\n",
				        gse_get_status(status));
				goto free_context;
			}

			// Is packet complete, or is it first fragment ?
			// (nb: only at most 2 fragments per packet)
			is_end = ((end_indicator & 0x01) == 0x01);
			if (!is_end)
				nb_fragment++;

			// Free vfrag before next call to gse_encap_get_packet() per
			// libgse requirement
			// One free here if packet is not fragmented
			gse_free_vfrag(&out_vfrag);

		} while (is_end != true);
	}
	total_tics = clock() - clock_start;

	printf("NB iter: %e\n", NB_ITER);
	printf("Nb fragment: %d\n", nb_fragment);
	printf("Tics: %d - %e seconds\n", (int)total_tics, ((double)total_tics) / CLOCKS_PER_SEC);
	printf("Tics / loop: %f - %e seconds\n", ((double)total_tics / NB_ITER), (((double)total_tics)/NB_ITER)/CLOCKS_PER_SEC);

free_context:
	// Release context
	gse_encap_release(encap_context);

	return status;
}
# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: audric.schiltknecht@xxxxxxxxxxxxxxxxxxxx-\
#   20130319160857-re22eemibj42xi7g
# target_branch: http://bazaar.launchpad.net/~opensand-\
#   maintainers/libgse/trunk/
# testament_sha1: ab76f0d6a82eef3168a07cf30bf66817dea621ae
# timestamp: 2013-07-25 12:02:07 +0200
# base_revision_id: audric.schiltknecht@xxxxxxxxxxxxxxxxxxxx-\
#   20130306110240-svj9ix11czibbyag
# 
# Begin patch
=== modified file '.bzrignore'
--- .bzrignore	2012-10-03 15:59:10 +0000
+++ .bzrignore	2013-03-11 14:09:17 +0000
@@ -48,6 +48,7 @@
 src/encap/test/test_refrag_robust
 test/non_regression_tests
 test/test_encap_deencap
+test/non_regression_tests_no_alloc
 debian/files
 debian/libgse
 debian/libgse-dbg

=== modified file 'src/common/virtual_fragment.c'
--- src/common/virtual_fragment.c	2012-10-01 12:20:36 +0000
+++ src/common/virtual_fragment.c	2013-03-11 13:37:16 +0000
@@ -289,6 +289,92 @@
   return status;
 }
 
+gse_status_t gse_allocate_vfrag(gse_vfrag_t **vfrag, int alloc_vbuf)
+{
+  int status = GSE_STATUS_OK;
+  gse_vbuf_t *vbuf = NULL;
+
+  if(vfrag == NULL)
+  {
+    status = GSE_STATUS_NULL_PTR;
+    goto error;
+  }
+
+  if (alloc_vbuf)
+  {
+    vbuf = malloc(sizeof(gse_vbuf_t));
+    if(vbuf == NULL)
+    {
+      status = GSE_STATUS_MALLOC_FAILED;
+      goto error;
+    }
+
+    vbuf->vfrag_count = 0;
+  }
+
+  *vfrag = malloc(sizeof(gse_vfrag_t));
+  if(*vfrag == NULL)
+  {
+    status = GSE_STATUS_MALLOC_FAILED;
+    goto free_vbuf;
+  }
+
+  (*vfrag)->vbuf = vbuf;
+
+  return status;
+
+free_vbuf:
+  free(vbuf);
+error:
+  *vfrag = NULL;
+  return status;
+}
+
+gse_status_t gse_affect_buf_vfrag(gse_vfrag_t *vfrag, unsigned char *buffer,
+                                  unsigned int head_offset, unsigned int trail_offset,
+                                  unsigned int data_length)
+{
+  int status = GSE_STATUS_OK;
+  gse_vbuf_t *vbuf;           
+                               
+  if(vfrag == NULL || buffer == NULL)
+  {
+    status = GSE_STATUS_NULL_PTR;
+    goto error;
+  }
+
+  vbuf = vfrag->vbuf;
+  if(vbuf == NULL)
+  {
+    status = GSE_STATUS_NULL_PTR;
+    goto error;
+  }
+
+  vbuf->start = buffer;
+  vbuf->length = head_offset + data_length + trail_offset;
+  vbuf->end = vbuf->start + vbuf->length;
+  vbuf->vfrag_count = 0;
+
+  vfrag->start = (vbuf->start + head_offset);
+  vfrag->length = data_length;
+  vfrag->end = vfrag->start + vfrag->length;
+  assert((vfrag->end) <= (vfrag->vbuf->end));
+  assert((vfrag->end) >= (vfrag->vbuf->start));
+  assert((vbuf->end - vfrag->end) == (int)trail_offset);
+  if((vfrag->end) > (vfrag->vbuf->end) ||
+     (vfrag->end) < (vfrag->vbuf->start) ||
+     (vbuf->end - vfrag->end) != (int)trail_offset)
+  {
+    status = GSE_STATUS_INTERNAL_ERROR;
+    goto error;
+  }
+  vbuf->vfrag_count++;
+
+error:
+  return status;
+}
+
+
 gse_status_t gse_free_vfrag(gse_vfrag_t **vfrag)
 {
   gse_status_t status = GSE_STATUS_OK;
@@ -323,6 +409,42 @@
   return status;
 }
 
+gse_status_t gse_free_vfrag_no_alloc(gse_vfrag_t **vfrag, int reset, int free_vbuf)
+{
+  gse_status_t status = GSE_STATUS_OK;
+
+  if(vfrag == NULL || *vfrag == NULL)
+  {
+    status = GSE_STATUS_NULL_PTR;
+    goto error;
+  }
+
+  if(reset)
+  {
+    if((*vfrag)->vbuf->vfrag_count == 0)
+    {
+      status = GSE_STATUS_FRAG_NBR;
+      goto error;
+    }
+
+    (*vfrag)->vbuf->vfrag_count--;
+  }
+  else
+  {
+    if(free_vbuf)
+    {
+      free((*vfrag)->vbuf);
+      (*vfrag)->vbuf = NULL;
+    }
+
+    free(*vfrag);
+    *vfrag = NULL;
+  }
+
+error:
+  return status;
+}
+
 gse_status_t gse_duplicate_vfrag(gse_vfrag_t **vfrag, gse_vfrag_t *father,
                                  size_t length)
 {
@@ -379,6 +501,57 @@
   return status;
 }
 
+gse_status_t gse_duplicate_vfrag_no_alloc(gse_vfrag_t **vfrag, gse_vfrag_t *father,
+                                          size_t length)
+{
+  gse_status_t status = GSE_STATUS_OK;
+
+  if(father == NULL || vfrag == NULL)
+  {
+    status = GSE_STATUS_NULL_PTR;
+    goto error;
+  }
+
+  if(father->vbuf == NULL)
+  {
+    status = GSE_STATUS_NULL_PTR;
+    goto error;
+  }
+
+  /* If the father is empty it is not duplicated */
+  if(father->length == 0)
+  {
+    status = GSE_STATUS_EMPTY_FRAG;
+    goto error;
+  }
+
+  /* There can be only two accesses to a virtual buffer to avoid multiple
+   * accesses from duplicated virtual fragments */
+  if(gse_get_vfrag_nbr(father) >= 2)
+  {
+    status = GSE_STATUS_FRAG_NBR;
+    goto error;
+  }
+
+  (*vfrag)->vbuf = father->vbuf;
+  (*vfrag)->start = father->start;
+  (*vfrag)->length = MIN(length, father->length);
+
+  (*vfrag)->end = (*vfrag)->start + (*vfrag)->length;
+  assert(((*vfrag)->end) <= ((*vfrag)->vbuf->end));
+  assert(((*vfrag)->end) >= ((*vfrag)->vbuf->start));
+  if(((*vfrag)->end) > ((*vfrag)->vbuf->end) ||
+     ((*vfrag)->end) < ((*vfrag)->vbuf->start))
+  {
+    status = GSE_STATUS_INTERNAL_ERROR;
+    goto error;
+  }
+  (*vfrag)->vbuf->vfrag_count++;
+
+error:
+  return status;
+}
+
 gse_status_t gse_shift_vfrag(gse_vfrag_t *vfrag, int start_shift, int end_shift)
 {
   gse_status_t status = GSE_STATUS_OK;

=== modified file 'src/common/virtual_fragment.h'
--- src/common/virtual_fragment.h	2012-10-01 12:20:36 +0000
+++ src/common/virtual_fragment.h	2013-03-11 13:37:16 +0000
@@ -207,6 +207,57 @@
                                        unsigned int data_length);
 
 /**
+ *  @brief   Create an empty virtual fragment - No allocation mode
+ *
+ *  @param   vfrag         OUT: The virtual fragment on success,
+ *                              NULL on error
+ *  @param   alloc_vbuf    Wheter to allocate the virtual buffer container or
+ *                         not (only the container, does not allocate the buffer
+ *                         itself).
+ *
+ *  @return
+ *                         - success/informative code among:
+ *                           - \ref GSE_STATUS_OK
+ *                         - warning/error code among:
+ *                           - \ref GSE_STATUS_NULL_PTR
+ *                           - \ref GSE_STATUS_BUFF_LENGTH_NULL
+ *                           - \ref GSE_STATUS_MALLOC_FAILED
+ *
+ *  @ingroup gse_virtual_fragment
+ */
+gse_status_t gse_allocate_vfrag(gse_vfrag_t **vfrag, int alloc_vbuf);
+
+/**
+ *  @brief   Affect a buffer to an allocated virtual fragment - No allocation
+ *  mode
+ *
+ *  The virtual buffer containing the fragment will contain the allocated
+ *  memory of the buffer.\n
+ *  The allocated space in the buffer must at least be
+ *  max_length + head_offset + trail_offset.\n
+ *  All length are expressed in bytes.\n
+ *
+ *  @param   vfrag        OUT: The virtual fragment on success,
+ *                             NULL on error
+ *  @param   buffer       The buffer to transform
+ *  @param   head_offset  The offset applied before the data in the buffer
+ *  @param   trail_offset The offset applied after the data in the buffer
+ *  @param   data_length  The length of the data in the buffer
+ *
+ *  @return
+ *                        - success/informative code among:
+ *                          - \ref GSE_STATUS_OK
+ *                        - warning/error code among:
+ *                          - \ref GSE_STATUS_NULL_PTR
+ *                          - \ref GSE_STATUS_MALLOC_FAILED
+ *                          - \ref GSE_STATUS_INTERNAL_ERROR
+ *
+ *  @ingroup gse_virtual_fragment
+ */
+gse_status_t gse_affect_buf_vfrag(gse_vfrag_t *vfrag, unsigned char *buffer,
+                                  unsigned int head_offset, unsigned int trail_offset,
+                                  unsigned int data_length);
+/**
  *  @brief   Free a virtual fragment
  *
  *  @param   vfrag         IN: The virtual fragment that will be destroyed
@@ -224,6 +275,26 @@
 gse_status_t gse_free_vfrag(gse_vfrag_t **vfrag);
 
 /**
+ *  @brief   Free a virtual fragment - No allocation mode
+ *
+ *  @param   vfrag         IN: The virtual fragment that will be destroyed
+ *                         OUT: NULL
+ *  @param   reset         If true, only reset the virtual fragment, do not free
+ *                         allocated memory
+ *  @param   free_vbuf     If true, free allocated memory for the virtual
+ *                         buffer.
+ *  @return
+ *                         - success/informative code among:
+ *                           - \ref GSE_STATUS_OK
+ *                         - warning/error code among:
+ *                           - \ref GSE_STATUS_NULL_PTR
+ *                           - \ref GSE_STATUS_FRAG_NBR
+ *
+ *  @ingroup gse_virtual_fragment
+ */
+gse_status_t gse_free_vfrag_no_alloc(gse_vfrag_t **vfrag, int reset, int free_vbuf);
+
+/**
  *  @brief   Create a virtual fragment from an existing one
  *
  *  In case of warning or error, the virtual fragment is unchanged.
@@ -247,6 +318,33 @@
  */
 gse_status_t gse_duplicate_vfrag(gse_vfrag_t **vfrag, gse_vfrag_t *father, size_t length);
 
+
+/**
+ *  @brief   Create a virtual fragment from an existing one - No allocation mode
+ *
+ *  In case of warning or error, the virtual fragment is unchanged.
+ *  @warning If the father length is smaller than the wanted length, the length
+ *           of the duplicated fragment will be the father length.
+ *
+ *  @param   vfrag        The duplicated virtual fragment
+ *  @param   father       The virtual fragment which will be duplicated
+ *  @param   length       The length of the duplicated virtual fragment (in bytes)
+ *
+ *  @return
+ *                        - success/informative code among:
+ *                          - \ref GSE_STATUS_OK
+ *                        - warning/error code among:
+ *                          - \ref GSE_STATUS_NULL_PTR
+ *                          - \ref GSE_STATUS_EMPTY_FRAG
+ *                          - \ref GSE_STATUS_FRAG_NBR
+ *                          - \ref GSE_STATUS_MALLOC_FAILED
+ *
+ *  @ingroup gse_virtual_fragment
+ */
+gse_status_t gse_duplicate_vfrag_no_alloc(gse_vfrag_t **vfrag,
+                                          gse_vfrag_t *father,
+                                          size_t length);
+
 /**
  *  @brief   Shift the virtual fragment
  *

=== modified file 'src/encap/encap.c'
--- src/encap/encap.c	2012-10-03 15:59:10 +0000
+++ src/encap/encap.c	2013-03-19 16:08:57 +0000
@@ -87,6 +87,23 @@
   void *opaque;          /**< User specific data for extension callback */
 };
 
+/** Encapsulation mode
+ *
+ * Choose how to get the encapsulated packet:
+ * \li LEGACY:   legacy mode (duplicate the buffer into a newly created virtual
+ *               fragment).
+ * \li NO_COPY:  zero copy mode (share the buffer with a newly created
+ *               virtual fragment).
+ * \li NO_ALLOC: no allocation mode (share the buffer with a user provided,
+ *               already allocated, virtual fragment)
+ */
+enum encap_mode
+{
+  LEGACY,
+  NO_COPY,
+  NO_ALLOC
+};
+
 
 
 /****************************************************************************
@@ -173,7 +190,7 @@
 /**
  *  @brief   Get a GSE packet from the encapsulation context structure
  *
- *  @param   copy             Activate copy or not
+ *  @param   mode             The encapsulation mode.
  *  @param   packet           OUT: The GSE packet on success,
  *                                 NULL on error
  *  @param   encap            The encapsulation context structure
@@ -203,7 +220,7 @@
  *                              - \ref GSE_STATUS_FRAG_NBR
  *                              - \ref GSE_STATUS_EXTENSION_CB_FAILED
  */
-static gse_status_t gse_encap_get_packet_common(int copy, gse_vfrag_t **packet,
+static gse_status_t gse_encap_get_packet_common(int mode, gse_vfrag_t **packet,
                                                 gse_encap_t *encap,
                                                 size_t desired_length,
                                                 uint8_t qos);
@@ -395,20 +412,26 @@
 error:
   return status;
 free_pdu:
-  gse_free_vfrag(&pdu);
+  gse_free_vfrag_no_alloc(&pdu, 1, 0);
   return status;
 }
 
 gse_status_t gse_encap_get_packet(gse_vfrag_t **packet, gse_encap_t *encap,
                                   size_t length, uint8_t qos)
 {
-  return gse_encap_get_packet_common(0, packet, encap, length, qos);
+  return gse_encap_get_packet_common(NO_COPY, packet, encap, length, qos);
 }
 
 gse_status_t gse_encap_get_packet_copy(gse_vfrag_t **packet, gse_encap_t *encap,
                                        size_t length, uint8_t qos)
 {
-  return gse_encap_get_packet_common(1, packet, encap, length, qos);
+  return gse_encap_get_packet_common(LEGACY, packet, encap, length, qos);
+}
+
+gse_status_t gse_encap_get_packet_no_alloc(gse_vfrag_t **packet, gse_encap_t *encap,
+                                           size_t length, uint8_t qos)
+{
+  return gse_encap_get_packet_common(NO_ALLOC, packet, encap, length, qos);
 }
 
 gse_status_t gse_encap_set_extension_callback(gse_encap_t *encap,
@@ -586,7 +609,7 @@
   return htonl(crc);
 }
 
-static gse_status_t gse_encap_get_packet_common(int copy, gse_vfrag_t **packet,
+static gse_status_t gse_encap_get_packet_common(int mode, gse_vfrag_t **packet,
                                                 gse_encap_t *encap,
                                                 size_t desired_length,
                                                 uint8_t qos)
@@ -727,7 +750,10 @@
     {
       goto packet_null;
     }
-    memcpy(encap_ctx->vfrag->start, extensions, tot_ext_length);
+    if(tot_ext_length > 0)
+    {
+      memcpy(encap_ctx->vfrag->start, extensions, tot_ext_length);
+    }
 
     /* Can the PDU be completely encapsulated ? */
     header_length = gse_compute_header_length(GSE_PDU_COMPLETE, encap_ctx->label_type);
@@ -821,27 +847,28 @@
   }
 
   /* Code depending on copy parameter */
-  if(copy)
+  switch(mode)
   {
-    /* Create a new fragment */
-    status = gse_create_vfrag_with_data(packet, desired_length,
-                                        encap->head_offset,
-                                        encap->trail_offset,
-                                        encap_ctx->vfrag->start,
-                                        desired_length);
-    if(status != GSE_STATUS_OK)
-    {
-      goto packet_null;
-    }
+    case LEGACY:
+      /* Create a new fragment */
+      status = gse_create_vfrag_with_data(packet, desired_length,
+                                          encap->head_offset,
+                                          encap->trail_offset,
+                                          encap_ctx->vfrag->start,
+                                          desired_length);
+      break;
+    case NO_COPY:
+      /* Duplicate the fragment */
+      status = gse_duplicate_vfrag(packet, encap_ctx->vfrag, desired_length);
+      break;
+    case NO_ALLOC:
+      /* Duplicate the fragment - no allocation */
+      status = gse_duplicate_vfrag_no_alloc(packet, encap_ctx->vfrag, desired_length);
+      break;
   }
-  else
+  if(status != GSE_STATUS_OK)
   {
-    /* Duplicate the fragment */
-    status = gse_duplicate_vfrag(packet, encap_ctx->vfrag, desired_length);
-    if(status != GSE_STATUS_OK)
-    {
-      goto packet_null;
-    }
+    goto packet_null;
   }
 
   encap_ctx->frag_nbr++;
@@ -855,7 +882,14 @@
   /* Go to the next FIFO element if the initial fragment is empty */
   if(encap_ctx->vfrag->length <= 0)
   {
-    status = gse_free_vfrag(&(encap_ctx->vfrag));
+    if(mode == NO_ALLOC)
+    {
+      status = gse_free_vfrag_no_alloc(&(encap_ctx->vfrag), 1, 0);
+    }
+    else
+    {
+      status = gse_free_vfrag(&(encap_ctx->vfrag));
+    }
     if(status != GSE_STATUS_OK)
     {
       goto free_packet;
@@ -869,13 +903,24 @@
 
   return status;
 free_packet:
-  gse_free_vfrag(packet);
+  if(mode == NO_ALLOC)
+  {
+    gse_free_vfrag_no_alloc(packet, 1, 0);
+  }
+  else
+  {
+    gse_free_vfrag(packet);
+  }
 packet_null:
   if(extensions != NULL)
   {
     free(extensions);
   }
 error:
-  *packet = NULL;
+  if(mode != NO_ALLOC)
+  {
+    *packet = NULL;
+  }
   return status;
 }
+

=== modified file 'src/encap/encap.h'
--- src/encap/encap.h	2012-10-01 12:20:36 +0000
+++ src/encap/encap.h	2013-03-11 13:37:16 +0000
@@ -249,6 +249,49 @@
                                        size_t desired_length, uint8_t qos);
 
 /**
+ *  @brief   Get a GSE packet from the encapsulation context structure -
+ *           No allocation mode
+ *
+ *  This function should not be called if the previous GSE packet has not
+ *  been destroyed (with gse_free_vfrag_no_alloc) except for the first packet.
+ *
+ *  @param   packet          OUT: The GSE packet on success,
+ *                                NULL on error or warning
+ *  @param   encap           The encapsulation context structure
+ *  @param   desired_length  The desired length for the packet (in bytes)
+ *  @param   qos             The QoS of the packet
+ *
+ *  @return
+ *                           - success/informative code among:
+ *                             - \ref GSE_STATUS_OK
+ *                           - warning/error code among:
+ *                             - \ref GSE_STATUS_NULL_PTR
+ *                             - \ref GSE_STATUS_INVALID_QOS
+ *                             - \ref GSE_STATUS_FIFO_EMPTY
+ *                             - \ref GSE_STATUS_PTHREAD_MUTEX
+ *                             - \ref GSE_STATUS_LENGTH_TOO_HIGH
+ *                             - \ref GSE_STATUS_LENGTH_TOO_SMALL
+ *                             - \ref GSE_STATUS_PTHREAD_MUTEX
+ *                             - \ref GSE_STATUS_INTERNAL_ERROR;
+ *                             - \ref GSE_STATUS_PTR_OUTSIDE_BUFF
+ *                             - \ref GSE_STATUS_FRAG_PTRS
+ *                             - \ref GSE_STATUS_INVALID_GSE_LENGTH
+ *                             - \ref GSE_STATUS_BUFF_LENGTH_NULL
+ *                             - \ref GSE_STATUS_MULTIPLE_VBUF_ACCESS
+ *                             - \ref GSE_STATUS_DATA_TOO_LONG
+ *                             - \ref GSE_STATUS_MALLOC_FAILED
+ *                             - \ref GSE_STATUS_EMPTY_FRAG
+ *                             - \ref GSE_STATUS_FRAG_NBR
+ *                             - \ref GSE_STATUS_EXTENSION_CB_FAILED
+ *
+ *  @ingroup gse_encap
+ */
+gse_status_t gse_encap_get_packet_no_alloc(gse_vfrag_t **packet, gse_encap_t *encap,
+                                           size_t desired_length, uint8_t qos);
+gse_status_t gse_encap_get_packet_no_alloc_old(gse_vfrag_t *packet, gse_encap_t *encap,
+                                           size_t desired_length, uint8_t qos);
+
+/**
  *  @brief  Set the callback that build header extensions
  *
  *  @param  encap     The encapsulation context
@@ -266,5 +309,4 @@
                                               gse_encap_build_header_ext_cb_t callback,
                                               void *opaque);
 
-
 #endif

=== modified file 'test/Makefile.am'
--- test/Makefile.am	2012-05-29 09:13:59 +0000
+++ test/Makefile.am	2013-03-11 14:09:17 +0000
@@ -8,7 +8,8 @@
 
 noinst_PROGRAMS = \
 	test_encap_deencap \
-	non_regression_tests
+	non_regression_tests \
+	non_regression_tests_no_alloc
 
 TESTS = \
 	test_encap_deencap.sh
@@ -16,7 +17,8 @@
 EXTRA_DIST = \
 	encap_deencap_max_pdu_length.pcap \
 	test_encap_deencap.sh \
-	non_regression_tests.sh
+	non_regression_tests.sh \
+	non_regression_tests_no_alloc.sh
 
 INCLUDES = \
 	-I$(top_srcdir)/src/common \
@@ -34,3 +36,8 @@
 non_regression_tests_LDADD = \
 	$(top_builddir)/src/libgse.la \
 	-lpcap
+
+non_regression_tests_no_alloc_SOURCES = non_regression_tests_no_alloc.c
+non_regression_tests_no_alloc_LDADD = \
+	$(top_builddir)/src/libgse.la \
+	-lpcap

=== added file 'test/non_regression_tests_no_alloc.c'
--- test/non_regression_tests_no_alloc.c	1970-01-01 00:00:00 +0000
+++ test/non_regression_tests_no_alloc.c	2013-03-11 14:09:17 +0000
@@ -0,0 +1,1251 @@
+/*
+ *
+ * This piece of software is an implementation of the Generic Stream
+ * Encapsulation (GSE) standard defined by ETSI for Linux (or other
+ * Unix-compatible OS). The library may be used to add GSE
+ * encapsulation/de-encapsulation capabilities to an application.
+ *
+ *
+ * Copyright © 2011 TAS
+ *
+ *
+ * This file is part of the GSE library.
+ *
+ *
+ * The GSE library is free software : you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY, without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ *
+ */
+
+/****************************************************************************/
+/**
+ *   @file          non_regression_tests.c
+ *
+ *          Project:     GSE LIBRARY
+ *
+ *          Company:     THALES ALENIA SPACE
+ *
+ *          Module name: TESTS
+ *
+ *   @brief         GSE non regression tests
+ *
+ *   @author        Julien BERNARD / Viveris Technologies
+ *
+ * Introduction
+ * ------------
+ *
+ * The program takes a flow of IP packets as input (in the PCAP format) and
+ * tests the GSE library with them.
+ *
+ * Details
+ * -------
+ *
+ * The program encapsulates the flow of IP packet and then deencapsulates
+ * the GSE packets.
+ * Between encapsulation and deencapsulation, the GSE packets can be
+ * refragmented if the option is activated
+ *
+ *
+ * Checks
+ * ------
+ *
+ * The program input IP packets with deencapsulated IP packets.
+ *
+ * The program compares the GSE packets generated with the ones given as input
+ * to the program if the save option is deactivated.
+ * If the refragmentation is activated it also compares the refragmented GSE
+ * packets with the ones given as input to the program.
+ *
+ * Output
+ * ------
+ *
+ * The program outputs the GSE packets in a PCAP packet if the save option is
+ * activated.
+ * If the refragmentation is activated it also outputs the refragmented GSE
+ * packets
+ *
+ */
+/****************************************************************************/
+
+/****************************************************************************
+ *
+ *   INCLUDES
+ *
+ *****************************************************************************/
+
+/* system includes */
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <string.h>
+#include <net/ethernet.h>
+#include <stdint.h>
+
+/* include for the PCAP library */
+#include <pcap.h>
+
+/* GSE includes */
+#include "constants.h"
+#include "encap.h"
+#include "deencap.h"
+#include "refrag.h"
+
+/****************************************************************************
+ *
+ *   MACROS AND CONSTANTS
+ *
+ *****************************************************************************/
+
+/** A very simple maximum macro */
+#define MAX(x, y)  (((x) > (y)) ? (x) : (y))
+
+/** A very simple minimum macro */
+#define MIN(x, y)  (((x) < (y)) ? (x) : (y))
+
+/** The program usage */
+#define TEST_USAGE \
+"GSE test application: test the GSE library with a flow of IP packets\n\n\
+usage: test [--verbose (-v) LEVEL] [-h] [-s] [--label-type LT] [-r REFRAG_FILENAME] -c FRAG_FILENAME -i FLOW\n\
+  --verbose        Print DEBUG information level 1\n\
+  LEVEL            The DEBUG level [0, 2]\n\
+  -h               Print this usage and exit\n\
+  -s               Save output packets instead of compare them\n\
+  -r               Activate refragmentation\n\
+  LT               The label_type (0, 1, 2, 3) (default: 0)\n\
+  REFRAG_FILENAME  Save the refragmented packets or compare them\n\
+                   with the reference packets stored in refrag_file (PCAP format)\n\
+  FRAG_FILENAME    Save the fragmented packets or compare them\n\
+                   with the reference packets stored in frag_file (PCAP format)\n\
+  FLOW             Flow of Ethernet frames to encapsulate (PCAP format)\n"
+
+/** The length of the Linux Cooked Sockets header */
+#define LINUX_COOKED_HDR_LEN  16
+
+/** Number of FIFOs */
+#define QOS_NBR 10
+/** Size of FIFOs */
+#define FIFO_SIZE 100
+/** Maximum number of fragments for one PDU */
+#define PKT_NBR_MAX 1000
+/** Protocol to put in the protocol type field */
+#define PROTOCOL 9029
+
+/** DEBUG macro */
+#define DEBUG(verbose, format, ...) \
+  do { \
+    if(verbose > -1) \
+      printf(format, ##__VA_ARGS__); \
+  } while(0)
+
+#define DEBUG_L2(verbose, format, ...) \
+  do { \
+    if(verbose > 1) \
+      printf(format, ##__VA_ARGS__); \
+  } while(0)
+
+static const size_t frag_length[20] = {
+  128,  0,    1024, 256,  2048, 4096, 16,   64,   1024, 512,
+  256,  512,  4096, 64,   128,  1024, 2048, 512,  256,  1024,
+  };
+
+static const size_t refrag_length[20] = {
+  64,   1024, 512,  128,  32,   512,  16,   16,   256,  32,
+  128,  128,  2048, 16,   64,   512,  16,   128,  128,  64,
+  };
+
+
+
+/****************************************************************************
+ *
+ *   PROTOTYPES OF PRIVATE FUNCTIONS
+ *
+ *****************************************************************************/
+
+static int test_encap_deencap(int verbose, uint8_t label_type, int save,
+                              char *src_filename,
+                              char *frag_filename,
+                              char *refrag_filename);
+static int open_pcap(char *filename, int verbose, pcap_t **handle,
+                     uint32_t *link_len);
+static int get_gse_packets(int verbose,
+                           int save,
+                           gse_vfrag_t **vfrag_pkt,
+                           gse_encap_t **encap,
+                           pcap_t **frag_handle,
+                           pcap_dumper_t **frag_dumper,
+                           uint32_t link_len_frag,
+                           uint32_t link_len_src,
+                           unsigned char *link_layer_head,
+                           int frag_length_idx,
+                           uint8_t qos,
+                           unsigned long pkt_nbr);
+#if 0
+static int refrag(int verbose,
+                  int save,
+                  gse_vfrag_t **vfrag_pkt,
+                  gse_vfrag_t **refrag_pkt,
+                  pcap_t **refrag_handle,
+                  pcap_dumper_t **refrag_dumper,
+                  uint32_t link_len_refrag,
+                  uint32_t link_len_src,
+                  unsigned char *link_layer_head,
+                  int refrag_length_idx,
+                  uint8_t qos,
+                  unsigned long pkt_nbr);
+static int deencap_pkt(int verbose,
+                       gse_vfrag_t *vfrag_pkt,
+                       gse_vfrag_t *refrag_pkt,
+                       gse_deencap_t **deencap,
+                       pcap_t **cmp_handle,
+                       uint32_t link_len_cmp,
+                       unsigned long rcv_pkt_nbr,
+                       unsigned long *rcv_tot_nbr,
+                       unsigned long pdu_counter);
+#endif
+static int compare_packets(int verbose,
+                           unsigned char *pkt1, int pkt1_size,
+                           unsigned char *pkt2, int pkt2_size);
+
+
+/****************************************************************************
+ *
+ *   PUBLIC FUNCTIONS
+ *
+ *****************************************************************************/
+
+/**
+ * @brief Main function for the GSE test program
+ *
+ * @param argc  the number of program arguments
+ * @param argv  the program arguments
+ * @return      the unix return code:
+ *               \li 0 in case of success,
+ *               \li 1 in case of failure
+ */
+int main(int argc, char *argv[])
+{
+  char *src_filename = NULL;
+  char *frag_filename = NULL;
+  char *refrag_filename = NULL;
+  char *label_type = 0;
+  int save = 0;
+  int refrag = 0;
+  int failure = 1;
+  int verbose = 0;
+  int ref;
+
+  for(ref = argc; (ref > 0 && argc > 1); ref--)
+  {
+    if(!(strcmp(argv[1], "--verbose")) || !(strcmp(argv[1], "-v")))
+    {
+      verbose = 1;
+      argv += 1;
+      argc -= 1;
+      if(argc > 1 && argv[1][0] != '-')
+      {
+        verbose = atoi(argv[1]);
+        if((verbose < 0)  || (verbose > 2))
+        {
+          fprintf(stderr, "Wrong verbose value\n");
+          fprintf(stderr, TEST_USAGE);
+          goto quit;
+        }
+        argv += 1;
+        argc -= 1;
+      }
+    }
+    else if(!strcmp(argv[1], "--label-type"))
+    {
+      if(!argv[2])
+      {
+        fprintf(stderr, "Missing LT\n");
+        fprintf(stderr, TEST_USAGE);
+        goto quit;
+      }
+      label_type = argv[2];
+      if(atoi(label_type) < 0 && atoi(label_type) > 3)
+      {
+        fprintf(stderr, "Bad Label Type\n");
+        goto quit;
+      }
+      argv += 2;
+      argc -= 2;
+    }
+    else if(!strcmp(argv[1], "-c"))
+    {
+      if(!argv[2])
+      {
+        fprintf(stderr, "Missing FRAG_FILENAME\n");
+        fprintf(stderr, TEST_USAGE);
+        goto quit;
+      }
+      frag_filename = argv[2];
+      argv += 2;
+      argc -= 2;
+    }
+    else if(!strcmp(argv[1], "-i"))
+    {
+      if(!argv[2])
+      {
+        fprintf(stderr, "Missing FLOW\n");
+        fprintf(stderr, TEST_USAGE);
+        goto quit;
+      }
+      src_filename = argv[2];
+      argv += 2;
+      argc -= 2;
+    }
+    else if(!strcmp(argv[1], "-h"))
+    {
+      fprintf(stderr, TEST_USAGE);
+      goto quit;
+    }
+    else if(!strcmp(argv[1], "-r"))
+    {
+      if(!argv[2])
+      {
+        fprintf(stderr, "Missing REFRAG_FILENAME\n");
+        fprintf(stderr, TEST_USAGE);
+        goto quit;
+      }
+      refrag = 1;
+      refrag_filename = argv[2];
+      argv += 2;
+      argc -= 2;
+    }
+    else if(!strcmp(argv[1], "-s"))
+    {
+      save = 1;
+      argv += 1;
+      argc -= 1;
+    }
+    else
+    {
+      fprintf(stderr, "unknown option %s\n", argv[1]);
+      fprintf(stderr, TEST_USAGE);
+       goto quit;
+     }
+  }
+
+  if(!src_filename || !frag_filename)
+  {
+    fprintf(stderr, "missing mandatory options\n");
+    fprintf(stderr, TEST_USAGE);
+    goto quit;
+  }
+
+  failure = test_encap_deencap(verbose,
+                               (label_type ? atoi(label_type):0),
+                               save, src_filename, frag_filename,
+                               refrag_filename);
+
+quit:
+  return failure;
+}
+
+/****************************************************************************
+ *
+ *   PRIVATE FUNCTIONS
+ *
+ *****************************************************************************/
+
+/**
+ * @brief Test the GSE library with a flow of IP or GSE packets to encapsulate
+ *
+ * @param verbose       0 for no debug messages, 1 for debug, 2 for more debug
+ * @param label_type    the label type
+ * @param src_filename  The name of the PCAP file that contains the source packets
+ * @param gse_frag_filename  The name of the PCAP file that contains the reference packets
+ *                      used for comparison
+ * @return              0 in case of success, 1 otherwise
+ */
+static int test_encap_deencap(int verbose, uint8_t label_type, int save,
+                              char *src_filename,
+                              char *frag_filename,
+                              char *refrag_filename)
+{
+  pcap_t *src_handle;
+  pcap_t *frag_handle = NULL;
+  pcap_t *refrag_handle = NULL;
+  pcap_t *cmp_handle;
+  pcap_dumper_t *frag_dumper = NULL;
+  pcap_dumper_t *refrag_dumper = NULL;
+  char errbuf[PCAP_ERRBUF_SIZE];
+  uint32_t link_len_src;
+  uint32_t link_len_frag = 0;
+  uint32_t link_len_refrag = 0;
+  uint32_t link_len_cmp;
+  struct pcap_pkthdr header;
+  unsigned char *packet;
+  unsigned char link_layer_head[MAX(ETHER_HDR_LEN, LINUX_COOKED_HDR_LEN)];
+  int is_failure = 1;
+  unsigned long counter;
+  unsigned long pkt_nbr = 0;
+  unsigned long tot_nbr = 0;
+  unsigned long rcv_pkt_nbr = 0;
+  unsigned long rcv_tot_nbr = 0;
+  unsigned long pdu_counter;
+  gse_encap_t *encap = NULL;
+  gse_vfrag_t *vfrag_pkt = NULL;
+  //gse_vfrag_t *refrag_pkt = NULL;
+  gse_vfrag_t *pdu = NULL;
+  uint8_t qos = 0;
+  gse_status_t status;
+  int frag_length_idx = 0;
+  //int refrag_length_idx = 0;
+  unsigned char *buffer;
+
+  uint8_t label[6] = {
+    0, 1, 2, 3, 4, 5,
+    };
+
+  if(!save)
+  {
+    if(refrag_filename != NULL)
+    {
+      DEBUG(verbose, "Compare fragmented packets with those in %s\n"
+                     "Compare refragmented packets with those in %s\n",
+            frag_filename, refrag_filename);
+    }
+    else
+    {
+      DEBUG(verbose, "Compare fragmented packets with those in %s\n",
+            frag_filename);
+    }
+  }
+  else
+  {
+    if(refrag_filename != NULL)
+    {
+      DEBUG(verbose, "Save fragmented packets in %s\n"
+                     "Save refragmented packets in %s\n",
+                     frag_filename, refrag_filename);
+    }
+    else
+    {
+      DEBUG(verbose, "Save fragmented packets in %s\n", frag_filename);
+    }
+  }
+  /* open the source dump file */
+  if(open_pcap(src_filename, verbose, &src_handle, &link_len_src) != 0)
+  {
+    goto error;
+  }
+
+  if(!save)
+  {
+    /* open the comparison dump file for fragmented packets */
+    if(open_pcap(frag_filename, verbose, &frag_handle, &link_len_frag) != 0)
+    {
+      goto close_input;
+    }
+
+    if(refrag_filename != NULL)
+    {
+      /* open the comparison dump file for refragmented packets */
+      if(open_pcap(refrag_filename, verbose, &refrag_handle, &link_len_refrag) != 0)
+      {
+        goto close_frag_handle;
+      }
+    }
+  }
+  else /* Create PCAP file to store GSE packets */
+  {
+    /* open the dump file to store fragmented packets */
+    frag_dumper = pcap_dump_open(src_handle, frag_filename);
+    if(frag_dumper == NULL)
+    {
+      DEBUG(verbose, "failed to open the refragment pcap dump: %s\n", errbuf);
+      goto close_input;
+    }
+
+    if(refrag_filename != NULL)
+    {
+      /* open the dump file to store refragmented packets */
+      refrag_dumper = pcap_dump_open(src_handle, refrag_filename);
+      if(refrag_dumper == NULL)
+      {
+        DEBUG(verbose, "failed to open the refragment pcap dump: %s\n", errbuf);
+        goto close_frag_handle;
+      }
+    }
+  }
+
+  /* open the comparison dump file for received pdu */
+  if(open_pcap(src_filename, verbose, &cmp_handle, &link_len_cmp) != 0)
+  {
+    goto close_refrag_handle;
+  }
+
+  /* Initialize the GSE library */
+  status = gse_encap_init(QOS_NBR, FIFO_SIZE, &encap);
+  if(status != GSE_STATUS_OK)
+  {
+    DEBUG(verbose, "Error %#.4x when initializing encapsulation (%s)\n", status,
+          gse_get_status(status));
+    goto close_comparison;
+  }
+
+  /* Allocate in/out vfrag */
+  status = gse_allocate_vfrag(&pdu, 1);
+  if(status != GSE_STATUS_OK)
+  {
+    DEBUG(verbose, "Error %#.4x when initializing PDU vfrag (%s)\n", status,
+          gse_get_status(status));
+    goto release_lib;
+  }
+  status = gse_allocate_vfrag(&vfrag_pkt, 0);
+  if(status != GSE_STATUS_OK)
+  {
+    DEBUG(verbose, "Error %#.4x when initializing packet vfrag (%s)\n", status,
+          gse_get_status(status));
+    goto release_lib;
+  }
+
+  /* for each packet in the dump */
+  counter = 0;
+  pdu_counter = 0;
+  while((packet = (unsigned char *) pcap_next(src_handle, &header)) != NULL)
+  {
+    unsigned char *in_packet;
+    size_t in_size;
+    int ret = 0;
+
+    counter++;
+
+    /* check Ethernet frame length */
+    if(header.len <= link_len_src || header.len != header.caplen)
+    {
+      DEBUG(verbose, "PDU #%lu: bad PCAP packet (len = %d, caplen = %d)\n",
+             counter, header.len, header.caplen);
+      goto release_lib;
+    }
+    if(counter == 1)
+    {
+      memcpy(link_layer_head, packet, link_len_src);
+    }
+
+    in_packet = packet + link_len_src;
+    in_size = header.len - link_len_src;
+
+    buffer = malloc(in_size + GSE_MAX_HEADER_LENGTH + GSE_MAX_TRAILER_LENGTH);
+    memcpy(buffer + GSE_MAX_HEADER_LENGTH, in_packet, in_size);
+
+    /* Encapsulate the input packets, use in_packet and in_size as
+       input */
+    status = gse_affect_buf_vfrag(pdu, buffer, GSE_MAX_HEADER_LENGTH, GSE_MAX_TRAILER_LENGTH, in_size);
+    /*
+    status = gse_create_vfrag_with_data(&pdu, in_size,
+                                        GSE_MAX_HEADER_LENGTH,
+                                        GSE_MAX_TRAILER_LENGTH,
+                                        in_packet, in_size);
+    */
+    if(status != GSE_STATUS_OK)
+    {
+      DEBUG(verbose, "Error %#.4x when creating virtual fragment #%lu (%s)\n",
+            status, counter, gse_get_status(status));
+      goto release_lib;
+    }
+
+    status = gse_encap_receive_pdu(pdu, encap, label, label_type, PROTOCOL, qos);
+    if(status != GSE_STATUS_OK)
+    {
+      DEBUG(verbose, "Error %#.4x when receiving PDU #%lu (%s)\n", status, counter,
+            gse_get_status(status));
+      goto release_lib;
+    }
+
+    DEBUG_L2(verbose, "\nPDU #%lu received from source file\n", counter);
+
+    pkt_nbr = 0; /* number of packets received in the FIFO */
+    tot_nbr = 0; /* number of fragments (frag_nbr + nbr refragmentation) */
+    rcv_pkt_nbr = 0;
+    rcv_tot_nbr = 0;
+    /* Encapsulate and deencapsulate GSE packets while a complete PDU has not been received */
+    do
+    {
+      /* Get a GSE packet in the FIFO */
+      ret = get_gse_packets(verbose,
+                         save,
+                         &vfrag_pkt,
+                         &encap,
+                         &frag_handle,
+                         &frag_dumper,
+                         link_len_frag,
+                         link_len_src,
+                         link_layer_head,
+                         frag_length_idx,
+                         qos,
+                         pkt_nbr);
+
+      frag_length_idx = (frag_length_idx + 1) % 20;
+
+      if (ret == 0)
+      {
+        pkt_nbr++;
+        tot_nbr ++;
+        status = gse_free_vfrag_no_alloc(&vfrag_pkt, 1, 0);
+        if(status != GSE_STATUS_OK)
+        {
+          DEBUG(verbose, "Error %#.4x when freeing packet #%lu (%s)\n",
+                status, pkt_nbr + 1, gse_get_status(status));
+          goto release_lib;
+        }
+      }
+
+    } while(ret == 0);
+    pdu_counter++;
+
+    DEBUG(verbose, "PDU #%lu: %lu packet(s), FIFO %d\n",
+          pdu_counter, pkt_nbr, qos);
+
+    qos = (qos + 1) % QOS_NBR;
+  }
+
+  /* everything went fine */
+  is_failure = 0;
+
+release_lib:
+  status = gse_encap_release(encap);
+  if(status != GSE_STATUS_OK)
+  {
+    is_failure = 1;
+    DEBUG(verbose, "Error %#.4x when releasing encapsulation (%s)\n", status, gse_get_status(status));
+  }
+close_comparison:
+  pcap_close(cmp_handle);
+close_refrag_handle:
+  if(refrag_filename != NULL)
+  {
+    if(!save)
+    {
+      pcap_close(refrag_handle);
+    }
+    else
+    {
+      if(refrag_dumper != NULL)
+      {
+        pcap_dump_close(refrag_dumper);
+      }
+    }
+  }
+close_frag_handle:
+  if(!save)
+  {
+    pcap_close(frag_handle);
+  }
+  else
+  {
+    if(frag_dumper != NULL)
+    {
+      pcap_dump_close(frag_dumper);
+    }
+  }
+close_input:
+  pcap_close(src_handle);
+
+error:
+  return is_failure;
+}
+
+/**
+ * @brief Open a PCAP file and check link layer parameters
+ *
+ * @param filename  The file name
+ * @param verbose   0 for no debug messages, 1 for debug, 2 for more debug
+ * @param link_len  Link layer length
+ * @return          0 on success, 1 on failure
+ */
+static int open_pcap(char *filename, int verbose, pcap_t **handle,
+                     uint32_t *link_len)
+{
+  char errbuf[PCAP_ERRBUF_SIZE];
+  int link_layer_type;
+  int is_failure = 1;
+
+  *handle = pcap_open_offline(filename, errbuf);
+  if(*handle == NULL)
+  {
+    DEBUG(verbose, "failed to open the PCAP file: %s\n", errbuf);
+    goto error;
+  }
+
+  /* link layer in the dump must be supported */
+  link_layer_type = pcap_datalink(*handle);
+  if(link_layer_type != DLT_EN10MB &&
+     link_layer_type != DLT_LINUX_SLL &&
+     link_layer_type != DLT_RAW)
+  {
+    DEBUG(verbose, "link layer type %d not supported in dump (supported = "
+           "%d, %d, %d)\n", link_layer_type, DLT_EN10MB, DLT_LINUX_SLL,
+           DLT_RAW);
+    goto close_input;
+  }
+
+  if(link_layer_type == DLT_EN10MB)
+    *link_len = ETHER_HDR_LEN;
+  else if(link_layer_type == DLT_LINUX_SLL)
+    *link_len = LINUX_COOKED_HDR_LEN;
+  else /* DLT_RAW */
+    *link_len = 0;
+
+  is_failure = 0;
+  return is_failure;
+
+close_input:
+  pcap_close(*handle);
+error:
+  return is_failure;
+}
+
+/**
+ * @brief Get a GSE packet in the FIFO and compare or save it
+ *
+ * @param verbose          0 for no debug messages, 1 for debug, 2 for more debug
+ * @param save             the save flag
+ * @param vfrag_pkt        OUT: the virtual fragment which will contain the GSE packet
+ * @param encap            the encapsulation context
+ * @param frag_length_idx  the index on fragment length
+ * @param frag_handle      the PCAP file which contains the GSE packets to compare
+ * @pram  frag_dumper      the PCAP dump file used to store the GSE packets
+ * @param link_len_frag    link layer length for fragmented packets
+ * @param link_layer_head  header written in front of the packets for the PCAP file
+ * @param qos              the qos value used to identify the FIFO
+ * @param pkt_nbr          the number of packet got in FIFO
+ * @return                 0 on success, -1 if FIFO is empty and 1 on failure
+ */
+static int get_gse_packets(int verbose,
+                           int save,
+                           gse_vfrag_t **vfrag_pkt,
+                           gse_encap_t **encap,
+                           pcap_t **frag_handle,
+                           pcap_dumper_t **frag_dumper,
+                           uint32_t link_len_frag,
+                           uint32_t link_len_src,
+                           unsigned char *link_layer_head,
+                           int frag_length_idx,
+                           uint8_t qos,
+                           unsigned long pkt_nbr)
+{
+  struct pcap_pkthdr frag_header;
+  unsigned char *frag_packet;
+  struct ether_header *eth_header;
+  struct pcap_pkthdr header;
+  gse_status_t status;
+
+  /* Get a packet in the FIFO */
+  status = gse_encap_get_packet_no_alloc(vfrag_pkt, *encap,
+                                         frag_length[frag_length_idx], qos);
+  if((status != GSE_STATUS_OK) && (status != GSE_STATUS_FIFO_EMPTY))
+  {
+    DEBUG(verbose, "Error %#.4x when getting packet #%lu (%s)\n",
+          status, pkt_nbr + 1, gse_get_status(status));
+    goto free_packet;
+  }
+  if(status == GSE_STATUS_OK)
+  {
+    DEBUG_L2(verbose, "Packet #%lu got in FIFO %u\n", pkt_nbr + 1, qos);
+    /* If the save option is deactivated, the packet is compared with a reference given as input */
+    if(!save)
+    {
+      frag_packet = (unsigned char *) pcap_next(*frag_handle, &frag_header);
+      if(frag_packet == NULL)
+      {
+        DEBUG(verbose, "packet #%lu: no packet available for comparison\n", pkt_nbr + 1);
+        goto free_packet;
+      }
+
+      /* compare the output fragmented packets with the ones given by the user */
+      if(frag_header.caplen <= link_len_frag)
+      {
+        DEBUG(verbose, "packet #%lu: packet available for comparison but too small\n",
+              pkt_nbr + 1);
+        goto free_packet;
+      }
+
+      if(!compare_packets(verbose, gse_get_vfrag_start(*vfrag_pkt),
+                          gse_get_vfrag_length(*vfrag_pkt),
+                          frag_packet + link_len_frag,
+                          frag_header.caplen - link_len_frag))
+      {
+        DEBUG(verbose, "packet #%lu: fragmented packet is not as attended\n", pkt_nbr + 1);
+        goto free_packet;
+      }
+    }
+    else /* The save option is activated */
+    {
+      if(*frag_dumper != NULL)
+      {
+        header.len = link_len_src + gse_get_vfrag_length(*vfrag_pkt);
+        header.caplen = header.len;
+        unsigned char output_frag[gse_get_vfrag_length(*vfrag_pkt) + link_len_src];
+        memcpy(output_frag + link_len_src, gse_get_vfrag_start(*vfrag_pkt),
+               gse_get_vfrag_length(*vfrag_pkt));
+        if(link_len_src != 0)
+        {
+          /* Copy link layer header from source packet */
+          memcpy(output_frag, link_layer_head, link_len_src);
+          if(link_len_src == ETHER_HDR_LEN) /* Ethernet only */
+          {
+            eth_header = (struct ether_header *) output_frag;
+            eth_header->ether_type = 0x162f; /* unused Ethernet ID ? */
+          }
+          else if(link_len_src == LINUX_COOKED_HDR_LEN) /* Linux Cooked Sockets only */
+          {
+            output_frag[LINUX_COOKED_HDR_LEN - 2] = 0x16;
+            output_frag[LINUX_COOKED_HDR_LEN - 1] = 0x2f;
+          }
+        }
+        pcap_dump((u_char *) (*frag_dumper), &header, output_frag);
+      }
+      else
+      {
+        DEBUG(verbose, "Fragment dumper missing\n");
+        goto free_packet;
+      }
+    }
+  }
+  else
+  {
+    DEBUG_L2(verbose, "FIFO %u empty\n", qos);
+    return -1;
+  }
+
+  return 0;
+
+free_packet:
+  status = gse_free_vfrag_no_alloc(vfrag_pkt, 0, 1);
+  if(status != GSE_STATUS_OK)
+  {
+    DEBUG(verbose, "Error %#.4x when destroying packet (%s)\n", status, gse_get_status(status));
+  }
+  return 1;
+}
+
+#if 0
+/**
+ * @brief Refragment a GSE packet and compare or save it
+ *
+ * @param verbose            0 for no debug messages, 1 for debug, 2 for more debug
+ * @param save               the save flag
+ * @param vfrag_pkt          IN: the virtual fragment which contains the GSE packet
+ *                           OUT: the virtual fragment which contains the first
+ *                                refragmented GSE packet
+ * @param refrag_pkt         OUT: the virtual fragment which contains the second
+ *                                refragmented GSE packet
+ * @param refrag_length_idx  the index on fragment length
+ * @param refrag_handle      the PCAP file which contains the GSE packets to compare
+ * @param refrag_dumper      the PCAP dumper file used to store the GSE packets
+ * @param link_len_refrag    link layer length for fragmented packets
+ * @param link_layer_head    header written in front of the packets for the PCAP file
+ * @param qos                the qos value used to identify the FIFO
+ * @param pkt_nbr            the number of packet got in FIFO
+ * @return                   0 on success, 1 on failure
+ */
+static int refrag(int verbose,
+                  int save,
+                  gse_vfrag_t **vfrag_pkt,
+                  gse_vfrag_t **refrag_pkt,
+                  pcap_t **refrag_handle,
+                  pcap_dumper_t **refrag_dumper,
+                  uint32_t link_len_refrag,
+                  uint32_t link_len_src,
+                  unsigned char *link_layer_head,
+                  int refrag_length_idx,
+                  uint8_t qos,
+                  unsigned long pkt_nbr)
+{
+  unsigned char *refrag_packet;
+  struct pcap_pkthdr refrag_header;
+  struct ether_header *eth_header;
+  struct pcap_pkthdr header;
+  gse_status_t status;
+
+  /* Refragment the GSE packet */
+  status = gse_refrag_packet(*vfrag_pkt, refrag_pkt,
+                             0, 0, qos, refrag_length[refrag_length_idx]);
+  if((status != GSE_STATUS_OK) && (status != GSE_STATUS_REFRAG_UNNECESSARY))
+  {
+    DEBUG(verbose, "Error %#.4x when refragmenting packet #%lu (%s)\n",
+          status, pkt_nbr, gse_get_status(status));
+    goto free_packets;
+  }
+
+  /* If the save option is deactivated, the packets are compared with the references
+   * given as input */
+  if(!save)
+  {
+    // First fragment
+    refrag_packet = (unsigned char *) pcap_next(*refrag_handle, &refrag_header);
+    if(refrag_packet == NULL)
+    {
+      DEBUG(verbose, "packet #%lu: no packet available for comparison\n", pkt_nbr);
+      goto free_packets;
+    }
+
+    /* compare the output refragmented packets with the ones given by the user */
+    if(refrag_header.caplen <= link_len_refrag)
+    {
+      DEBUG(verbose, "packet #%lu: packet available for comparison but too small\n",
+            pkt_nbr);
+      goto free_packets;
+    }
+
+    if(!compare_packets(verbose, gse_get_vfrag_start(*vfrag_pkt),
+                        gse_get_vfrag_length(*vfrag_pkt),
+                        refrag_packet + link_len_refrag,
+                        refrag_header.caplen - link_len_refrag))
+    {
+      DEBUG(verbose, "packet #%lu: first refragmented packet is not as attended\n", pkt_nbr);
+      goto free_packets;
+    }
+
+    /* If the packet has been refragmented */
+    if(*refrag_pkt != NULL)
+    {
+      DEBUG_L2(verbose, "packet #%lu has been refragmented\n", pkt_nbr);
+      // Second fragment
+      refrag_packet = (unsigned char *) pcap_next(*refrag_handle, &refrag_header);
+      if(refrag_packet == NULL)
+      {
+        DEBUG(verbose, "packet #%lu: no packet available for comparison\n", pkt_nbr);
+        goto free_packets;
+      }
+
+      /* compare the output refragmented packets with the ones given by the user */
+      if(refrag_header.caplen <= link_len_refrag)
+      {
+        DEBUG(verbose, "packet #%lu: packet available for comparison but too small\n", pkt_nbr);
+        goto free_packets;
+      }
+
+      if(!compare_packets(verbose, gse_get_vfrag_start(*refrag_pkt),
+                          gse_get_vfrag_length(*refrag_pkt),
+                          refrag_packet + link_len_refrag,
+                          refrag_header.caplen - link_len_refrag))
+      {
+        DEBUG(verbose, "packet #%lu: second refragmented packet is not as attended\n",
+              pkt_nbr);
+        goto free_packets;
+      }
+    }
+  }
+  else /* The save option is activated */
+  {
+    if(*refrag_dumper != NULL)
+    {
+      unsigned char output_refrag_first[gse_get_vfrag_length(*vfrag_pkt) + link_len_src];
+      //first fragment
+      header.len = link_len_src + gse_get_vfrag_length(*vfrag_pkt);
+      header.caplen = header.len;
+      memcpy(output_refrag_first + link_len_src,
+             gse_get_vfrag_start(*vfrag_pkt),
+             gse_get_vfrag_length(*vfrag_pkt));
+      if(link_len_src != 0)
+      {
+        //Copy link layer header from source packet
+        memcpy(output_refrag_first, link_layer_head, link_len_src);
+        if(link_len_src == ETHER_HDR_LEN) /* Ethernet only */
+        {
+          eth_header = (struct ether_header *) output_refrag_first;
+          eth_header->ether_type = 0x162f; /* unused Ethernet ID ? */
+        }
+        else if(link_len_src == LINUX_COOKED_HDR_LEN) /* Linux Cooked Sockets only */
+        {
+          output_refrag_first[LINUX_COOKED_HDR_LEN - 2] = 0x16;
+          output_refrag_first[LINUX_COOKED_HDR_LEN - 1] = 0x2f;
+        }
+      }
+      pcap_dump((u_char *) (*refrag_dumper), &header, output_refrag_first);
+
+      /* If the packet has been refragmented */
+      if(*refrag_pkt != NULL)
+      {
+        /* second fragment */
+        unsigned char output_refrag_second[gse_get_vfrag_length(*refrag_pkt) + link_len_src];
+        memcpy(output_refrag_second + link_len_src, gse_get_vfrag_start(*refrag_pkt),
+               gse_get_vfrag_length(*refrag_pkt));
+        header.len = link_len_src + gse_get_vfrag_length(*refrag_pkt);
+        header.caplen = header.len;
+        if(link_len_src != 0)
+        {
+          /* Copy link layer header from source packet */
+          memcpy(output_refrag_second, link_layer_head, link_len_src);
+          if(link_len_src == ETHER_HDR_LEN) /* Ethernet only */
+          {
+            eth_header = (struct ether_header *) output_refrag_second;
+            eth_header->ether_type = 0x162f; /* unused Ethernet ID ? */
+          }
+          else if(link_len_src == LINUX_COOKED_HDR_LEN) /* Linux Cooked Sockets only */
+          {
+            output_refrag_second[LINUX_COOKED_HDR_LEN - 2] = 0x16;
+            output_refrag_second[LINUX_COOKED_HDR_LEN - 1] = 0x2f;
+          }
+        }
+        pcap_dump((u_char *) (*refrag_dumper), &header, output_refrag_second);
+      }
+    }
+    else
+    {
+      DEBUG(verbose, "Fragment dumper missing\n");
+      goto free_packets;
+    }
+  }
+
+  return 0;
+
+free_packets:
+  status = gse_free_vfrag_no_alloc(&vfrag_pkt, 0, 1);
+  if(status != GSE_STATUS_OK)
+  {
+    DEBUG(verbose, "Error %#.4x when destroying packet (%s)\n", status, gse_get_status(status));
+  }
+  status = gse_free_vfrag_no_alloc(&refrag_pkt, 0, 1);
+  if(status != GSE_STATUS_OK)
+  {
+    DEBUG(verbose, "Error %#.4x when destroying packet (%s)\n", status, gse_get_status(status));
+  }
+  return 1;
+}
+
+/**
+ * @brief Deencapsulate one or two GSE packets
+ *
+ * @param verbose         0 for no debug messages, 1 for debug, 2 for more debug
+ * @param save            the save flag
+ * @param vfrag_pkt       IN: the virtual fragment which contains a first refragmented
+ *                            GSE packet
+ * @param vfrag_pkt       IN: the virtual fragment which contains a second refragmented
+ *                            GSE packet
+ * @param deencap         the deencapsulation context
+ * @param cmp_handle      the PCAP file which contains the GSE packets to compare
+ * @param link_len_cmp    link layer length for fragmented packets
+ * @return                0 on success, -1 if a PDU is received, 1 on failure
+ */
+static int deencap_pkt(int verbose,
+                       gse_vfrag_t *vfrag_pkt,
+                       gse_vfrag_t *refrag_pkt,
+                       gse_deencap_t **deencap,
+                       pcap_t **cmp_handle,
+                       uint32_t link_len_cmp,
+                       unsigned long rcv_pkt_nbr,
+                       unsigned long *rcv_tot_nbr,
+                       unsigned long pdu_counter)
+{
+  uint8_t rcv_label[6];
+  uint8_t label_type;
+  uint16_t protocol;
+  uint16_t gse_length;
+  unsigned char *cmp_packet;
+  struct pcap_pkthdr cmp_header;
+  int j;
+  int is_failure = 1;
+  gse_vfrag_t *rcv_pdu = NULL;
+
+  gse_status_t status= GSE_STATUS_OK;
+
+  /* Deencap the GSE packet of the first fragment of the refragmented packet */
+  status = gse_deencap_packet(vfrag_pkt, *deencap, &label_type, rcv_label,
+                              &protocol, &rcv_pdu, &gse_length);
+  if((status != GSE_STATUS_OK) && (status != GSE_STATUS_PDU_RECEIVED))
+  {
+    DEBUG(verbose, "Error %#.4x when deencapsulating packet #%lu (fragment 1) (%s)\n",
+          status, rcv_pkt_nbr + 1, gse_get_status(status));
+    goto free_packets;
+  }
+  vfrag_pkt = NULL;
+  DEBUG_L2(verbose, "GSE packet #%lu (fragment 1) received, packet length = %d\n",
+           *rcv_tot_nbr + 1, gse_length);
+  *rcv_tot_nbr = *rcv_tot_nbr + 1;
+
+  /* Deencapsulate the second fragment if the packet has been refragmented */
+  if((refrag_pkt != NULL) && (status != GSE_STATUS_PDU_RECEIVED))
+  {
+    status = gse_deencap_packet(refrag_pkt, *deencap, &label_type, rcv_label,
+                                &protocol, &rcv_pdu, &gse_length);
+    if((status != GSE_STATUS_OK) && (status != GSE_STATUS_PDU_RECEIVED))
+    {
+      DEBUG(verbose, "Error %#.4x when deencapsulating packet #%lu (fragment 2) (%s)\n",
+            status, rcv_pkt_nbr + 1, gse_get_status(status));
+      goto free_refrag;
+    }
+    DEBUG_L2(verbose, "GSE packet #%lu (fragment 2) received, packet length = %d\n",
+             *rcv_tot_nbr + 1, gse_length);
+    *rcv_tot_nbr = *rcv_tot_nbr + 1;
+  }
+
+  /* A complete PDU has been received */
+  if(status == GSE_STATUS_PDU_RECEIVED)
+  {
+    cmp_packet = (unsigned char *) pcap_next(*cmp_handle, &cmp_header);
+    if(cmp_packet == NULL)
+    {
+      DEBUG(verbose, "PDU #%lu: no PDU available for comparison\n", pdu_counter);
+      goto free_pdu;
+    }
+
+    /* compare the output packets with the ones given by the user */
+    if(cmp_header.caplen <= link_len_cmp)
+    {
+      DEBUG(verbose, "PDU #%lu: PDU available for comparison but too small\n",
+            pdu_counter);
+      goto free_pdu;
+    }
+
+    if(!compare_packets(verbose, gse_get_vfrag_start(rcv_pdu), gse_get_vfrag_length(rcv_pdu),
+                        cmp_packet + link_len_cmp, cmp_header.caplen - link_len_cmp))
+    {
+      DEBUG(verbose, "PDU #%lu: generated PDU is not as attended\n", pdu_counter);
+      goto free_pdu;
+    }
+
+    DEBUG_L2(verbose, "Complete PDU #%lu:\nLabel Type: %d | Protocol: %#.4x | Label: %.2d",
+             pdu_counter, label_type, protocol, rcv_label[0]);
+    for(j = 1; j < gse_get_label_length(label_type); j++)
+    {
+      DEBUG_L2(verbose, ":%.2d", rcv_label[j]);
+    }
+    DEBUG_L2(verbose, " (in hexa)\n");
+
+    if(rcv_pdu != NULL)
+    {
+      status = gse_free_vfrag(&rcv_pdu);
+      if(status != GSE_STATUS_OK)
+      {
+        DEBUG(verbose, "Error %#.4x when destroying pdu (%s)\n", status, gse_get_status(status));
+        goto free_pdu;
+      }
+    }
+    is_failure = -1;
+  }
+  else
+  {
+    is_failure = 0;
+  }
+
+  return is_failure;
+
+free_packets:
+  status = gse_free_vfrag(&vfrag_pkt);
+  if(status != GSE_STATUS_OK)
+  {
+    DEBUG(verbose, "Error %#.4x when destroying packet (%s)\n", status, gse_get_status(status));
+  }
+free_refrag:
+  status = gse_free_vfrag(&refrag_pkt);
+  if(status != GSE_STATUS_OK)
+  {
+    DEBUG(verbose, "Error %#.4x when destroying packet (%s)\n", status, gse_get_status(status));
+  }
+  return is_failure;
+free_pdu:
+  status = gse_free_vfrag(&rcv_pdu);
+  if(status != GSE_STATUS_OK)
+  {
+    DEBUG(verbose, "Error %#.4x when destroying PDU (%s)\n", status, gse_get_status(status));
+  }
+  return is_failure;
+}
+#endif
+
+
+/**
+ * @brief Compare two network packets and print differences if any
+ *
+ * @param verbose   0 for no debug messages, 1 for debug, 2 for more debug
+ * @param pkt1      The first packet
+ * @param pkt1_size The size of the first packet
+ * @param pkt2      The second packet
+ * @param pkt2_size The size of the second packet
+ * @return          Whether the packets are equal or not
+ */
+static int compare_packets(int verbose,
+                           unsigned char *pkt1, int pkt1_size,
+                           unsigned char *pkt2, int pkt2_size)
+{
+  int valid = 1;
+  int min_size;
+  int i, j, k;
+  char str1[4][7], str2[4][7];
+  char sep1, sep2;
+
+  min_size = pkt1_size > pkt2_size ? pkt2_size : pkt1_size;
+
+  /* do not compare more than 180 bytes to avoid huge output */
+  min_size = MIN(180, min_size);
+
+  /* if packets are equal, do not print the packets */
+  if(pkt1_size == pkt2_size && memcmp(pkt1, pkt2, pkt1_size) == 0)
+    goto skip;
+
+  /* packets are different */
+  valid = 0;
+
+  DEBUG(verbose, "------------------------------ Compare ------------------------------\n");
+
+  if(pkt1_size != pkt2_size)
+  {
+    DEBUG(verbose, "packets have different sizes (%d != %d), compare only the %d "
+           "first bytes\n", pkt1_size, pkt2_size, min_size);
+  }
+
+  j = 0;
+  for(i = 0; i < min_size; i++)
+  {
+    if(pkt1[i] != pkt2[i])
+    {
+      sep1 = '#';
+      sep2 = '#';
+    }
+    else
+    {
+      sep1 = '[';
+      sep2 = ']';
+    }
+
+    sprintf(str1[j], "%c0x%.2x%c", sep1, pkt1[i], sep2);
+    sprintf(str2[j], "%c0x%.2x%c", sep1, pkt2[i], sep2);
+
+    /* make the output human readable */
+    if(j >= 3 || (i + 1) >= min_size)
+    {
+      for(k = 0; k < 4; k++)
+      {
+        if(k < (j + 1))
+          DEBUG(verbose, "%s  ", str1[k]);
+        else /* fill the line with blanks if nothing to print */
+          DEBUG(verbose, "        ");
+      }
+
+      DEBUG(verbose, "      ");
+
+      for(k = 0; k < (j + 1); k++)
+        DEBUG(verbose, "%s  ", str2[k]);
+
+      DEBUG(verbose, "\n");
+
+      j = 0;
+    }
+    else
+    {
+      j++;
+    }
+  }
+
+  DEBUG(verbose, "----------------------- packets are different -----------------------\n");
+
+  return valid;
+
+skip:
+  return valid;
+}

=== added file 'test/non_regression_tests_no_alloc.sh'
--- test/non_regression_tests_no_alloc.sh	1970-01-01 00:00:00 +0000
+++ test/non_regression_tests_no_alloc.sh	2013-03-11 14:09:17 +0000
@@ -0,0 +1,58 @@
+#!/bin/bash
+
+APP="non_regression_tests_no_alloc"
+
+SCRIPT="$0"
+if [ "x$MAKELEVEL" != "x" ] ; then
+    BASEDIR="${srcdir}"
+else
+    BASEDIR=$( dirname "${SCRIPT}" )
+fi
+BASEDIR_APP=$( dirname "${SCRIPT}" )
+
+# Try to determinate the path of the executable
+if [ ! -x "${BASEDIR_APP}/${APP}" ] ; then
+    if [ x"${builddir}" != "x" ] ; then
+        APP="${builddir}/test/${APP}"
+    else
+        APP="${srcdir}/${APP}"
+    fi
+else
+    APP="${BASEDIR_APP}/${APP}"
+fi
+
+gse_args=" -r ${BASEDIR}/refragmented.pcap -c ${BASEDIR}/fragmented.pcap -i ${BASEDIR}/source.pcap"
+gse_args_label3=" -r ${BASEDIR}/refragmented_label_3.pcap -c ${BASEDIR}/fragmented_label_3.pcap -i ${BASEDIR}/source.pcap --label-type 1"
+gse_args_label0=" -r ${BASEDIR}/refragmented_label_0.pcap -c ${BASEDIR}/fragmented_label_0.pcap -i ${BASEDIR}/source.pcap --label-type 2"
+
+
+ARGS=( \
+  "${gse_args}" \
+  "${gse_args_label0}" \
+  "${gse_args_label3}" \
+  )
+
+DESCRIPTION=( \
+  "GSE test: " \
+  "GSE test with LT='01': " \
+  "GSE test with LT='11': " \
+  )
+
+GREEN="\\033[1;32m"
+NORMAL="\\033[0;39m"
+RED="\\033[1;31m"
+BLUE="\\033[1;34m"
+BLUE_U="\\033[4;34m"
+
+/bin/echo -e ""
+/bin/echo -e "${BLUE}${BLUE_U}Run tests in `pwd`${NORMAL}\n"
+
+for index in "${!ARGS[@]}"; do
+  /bin/echo -e -n "${BLUE}${DESCRIPTION[$index]}${NORMAL}"
+  ${APP} ${ARGS[$index]} || (/bin/echo -e "${RED} FAIL${NORMAL}" && ${APP} --verbose 2 ${ARGS[$index]})
+  if [ "$?" -ne "0" ]; then
+    exit 1
+  fi
+  /bin/echo -e "${GREEN} SUCCESS${NORMAL}"
+done
+

=== modified file 'test/samples/internet_trafic/Makefile.am'
--- test/samples/internet_trafic/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/internet_trafic/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/icmp+tcp/Makefile.am'
--- test/samples/ipv4/icmp+tcp/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/icmp+tcp/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/icmp/Makefile.am'
--- test/samples/ipv4/icmp/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/icmp/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/ipv4/icmp/Makefile.am'
--- test/samples/ipv4/ipv4/icmp/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/ipv4/icmp/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/ipv4/udp/Makefile.am'
--- test/samples/ipv4/ipv4/udp/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/ipv4/udp/Makefile.am	2013-03-11 14:09:17 +0000
@@ -8,7 +8,8 @@
 	rtp
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/ipv4/udp/rtp/mp3/Makefile.am'
--- test/samples/ipv4/ipv4/udp/rtp/mp3/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/ipv4/udp/rtp/mp3/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/ipv4/udp/rtp/video1/Makefile.am'
--- test/samples/ipv4/ipv4/udp/rtp/video1/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/ipv4/udp/rtp/video1/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/ipv4/udp/rtp/video2/Makefile.am'
--- test/samples/ipv4/ipv4/udp/rtp/video2/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/ipv4/udp/rtp/video2/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/ipv4/udplite/Makefile.am'
--- test/samples/ipv4/ipv4/udplite/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/ipv4/udplite/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/ipv6/icmp/Makefile.am'
--- test/samples/ipv4/ipv6/icmp/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/ipv6/icmp/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/ipv6/udp/Makefile.am'
--- test/samples/ipv4/ipv6/udp/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/ipv6/udp/Makefile.am	2013-03-11 14:09:17 +0000
@@ -8,7 +8,8 @@
 	rtp
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/ipv6/udp/rtp/video1/Makefile.am'
--- test/samples/ipv4/ipv6/udp/rtp/video1/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/ipv6/udp/rtp/video1/Makefile.am	2013-03-11 14:09:17 +0000
@@ -8,7 +8,8 @@
 	extension
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/ipv6/udp/rtp/video1/extension/Makefile.am'
--- test/samples/ipv4/ipv6/udp/rtp/video1/extension/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/ipv6/udp/rtp/video1/extension/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/ipv6/udp/rtp/video2/Makefile.am'
--- test/samples/ipv4/ipv6/udp/rtp/video2/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/ipv6/udp/rtp/video2/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/ipv6/udplite/Makefile.am'
--- test/samples/ipv4/ipv6/udplite/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/ipv6/udplite/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/udp/Makefile.am'
--- test/samples/ipv4/udp/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/udp/Makefile.am	2013-03-11 14:09:17 +0000
@@ -8,7 +8,8 @@
 	rtp
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/udp/rtp/h323/Makefile.am'
--- test/samples/ipv4/udp/rtp/h323/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/udp/rtp/h323/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/udp/rtp/misc/Makefile.am'
--- test/samples/ipv4/udp/rtp/misc/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/udp/rtp/misc/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/udp/rtp/mp3/Makefile.am'
--- test/samples/ipv4/udp/rtp/mp3/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/udp/rtp/mp3/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/udp/rtp/rtp_rtp_icmp/Makefile.am'
--- test/samples/ipv4/udp/rtp/rtp_rtp_icmp/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/udp/rtp/rtp_rtp_icmp/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/udp/rtp/video1/Makefile.am'
--- test/samples/ipv4/udp/rtp/video1/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/udp/rtp/video1/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/udp/rtp/video2/Makefile.am'
--- test/samples/ipv4/udp/rtp/video2/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/udp/rtp/video2/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/udp/rtp/video3/Makefile.am'
--- test/samples/ipv4/udp/rtp/video3/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/udp/rtp/video3/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/udp/rtp/voip+video/Makefile.am'
--- test/samples/ipv4/udp/rtp/voip+video/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/udp/rtp/voip+video/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/udp/rtp/voip/Makefile.am'
--- test/samples/ipv4/udp/rtp/voip/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/udp/rtp/voip/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4/udplite/Makefile.am'
--- test/samples/ipv4/udplite/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4/udplite/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv4fragmented/Makefile.am'
--- test/samples/ipv4fragmented/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv4fragmented/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv6/icmp/Makefile.am'
--- test/samples/ipv6/icmp/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv6/icmp/Makefile.am	2013-03-11 14:09:17 +0000
@@ -8,7 +8,8 @@
 	extension
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv6/icmp/extension/Makefile.am'
--- test/samples/ipv6/icmp/extension/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv6/icmp/extension/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv6/ipv6/icmp/Makefile.am'
--- test/samples/ipv6/ipv6/icmp/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv6/ipv6/icmp/Makefile.am	2013-03-11 14:09:17 +0000
@@ -8,7 +8,8 @@
 	extension
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv6/ipv6/icmp/extension/Makefile.am'
--- test/samples/ipv6/ipv6/icmp/extension/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv6/ipv6/icmp/extension/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv6/ipv6/udp/Makefile.am'
--- test/samples/ipv6/ipv6/udp/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv6/ipv6/udp/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv6/ipv6/udplite/Makefile.am'
--- test/samples/ipv6/ipv6/udplite/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv6/ipv6/udplite/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv6/udp/Makefile.am'
--- test/samples/ipv6/udp/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv6/udp/Makefile.am	2013-03-11 14:09:17 +0000
@@ -9,7 +9,8 @@
 	rtp
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv6/udp/extension/Makefile.am'
--- test/samples/ipv6/udp/extension/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv6/udp/extension/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv6/udp/rtp/audio_vlc/Makefile.am'
--- test/samples/ipv6/udp/rtp/audio_vlc/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv6/udp/rtp/audio_vlc/Makefile.am	2013-03-11 14:09:17 +0000
@@ -8,7 +8,8 @@
 	extension 
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv6/udp/rtp/audio_vlc/extension/Makefile.am'
--- test/samples/ipv6/udp/rtp/audio_vlc/extension/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv6/udp/rtp/audio_vlc/extension/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv6/udp/rtp/video1/Makefile.am'
--- test/samples/ipv6/udp/rtp/video1/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv6/udp/rtp/video1/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv6/udp/rtp/video2/Makefile.am'
--- test/samples/ipv6/udp/rtp/video2/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv6/udp/rtp/video2/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

=== modified file 'test/samples/ipv6/udplite/Makefile.am'
--- test/samples/ipv6/udplite/Makefile.am	2012-09-28 15:03:52 +0000
+++ test/samples/ipv6/udplite/Makefile.am	2013-03-11 14:09:17 +0000
@@ -5,7 +5,8 @@
 ################################################################################
 
 TESTS = \
-	$(top_builddir)/test/non_regression_tests.sh
+	$(top_builddir)/test/non_regression_tests.sh \
+	$(top_builddir)/test/non_regression_tests_no_alloc.sh
 
 TESTS_ENVIRONMENT = builddir=$(top_builddir)
 

# Begin bundle
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
/**
 * @file     eval_gse.c
 * @author   Audric Schiltknecht / Viveris Technologies
 * @date     01 mars 2013
 * @version  1.0
 * @brief    Evaluate libgse encapsulation performance
 */

#include <gse/constants.h>
#include <gse/encap.h>
#include <gse/virtual_fragment.h>
#include <gse/header_fields.h>

#include <strings.h>
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#include <unistd.h>
#include <time.h>

#define MIN(x, y)  (((x) < (y)) ? (x) : (y))

#define IP_PAYLOAD_LENGTH 40

#define BBFRAME_LENGTH 2001

#define NB_ITER 1E6

#define QOS_NR 1
#define FIFO_SIZE 1

#define PROTOCOL_TYPE 0x0800
#define QOS_VALUE 0

#define GSE_MIN_PACKET_LENGTH 12
#define GSE_MAX_PACKET_LENGTH (4095 + 2)

unsigned char ip_payload[IP_PAYLOAD_LENGTH];
unsigned char bbframe[BBFRAME_LENGTH];

unsigned char buffer[IP_PAYLOAD_LENGTH + GSE_MAX_HEADER_LENGTH + GSE_MAX_TRAILER_LENGTH];

uint8_t label[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };

int main(void)
{
	gse_encap_t *encap_context;
	gse_vfrag_t *in_vfrag, *out_vfrag;
	gse_status_t status;

	int size;
	size_t vfrag_length;
	unsigned char *gse_packet;
	int nb_fragment = 0;

	long long iter;

	uint8_t end_indicator;
	bool is_end;

	clock_t clock_start, total_tics;

	// Defining payload
	memset(ip_payload, 0x42, IP_PAYLOAD_LENGTH);

	// Initialize encap context
	status = gse_encap_init(QOS_NR, FIFO_SIZE, &encap_context);
	if (status != GSE_STATUS_OK)
	{
		fprintf(stderr, "Fail to initialize encapsulation library: %s\n",
		        gse_get_status(status));
		return 1;
	}

	// Initialize input vfrag
	status = gse_allocate_vfrag(&in_vfrag, 1);
	if (status != GSE_STATUS_OK)
	{
		fprintf(stderr, "Fail to create input vfrag: %s\n",
				gse_get_status(status));
		return 1;
	}

	// Initialize output vfrag
	status = gse_allocate_vfrag(&out_vfrag, 0);
	if (status != GSE_STATUS_OK)
	{
		fprintf(stderr, "Fail to create input vfrag: %s\n",
				gse_get_status(status));
		return 1;
	}

	size = BBFRAME_LENGTH;
	clock_start = clock();
	for (iter = 0 ; iter < NB_ITER ; ++iter)
	{
		//printf("Iter #%d\n", iter);
		// Initialize input buffer for vfrag
		bzero(buffer, IP_PAYLOAD_LENGTH + GSE_MAX_HEADER_LENGTH + GSE_MAX_TRAILER_LENGTH);
		memcpy(buffer + GSE_MAX_HEADER_LENGTH, ip_payload, IP_PAYLOAD_LENGTH);


		// Feed IP payload to GSE compressor
		status = gse_affect_buf_vfrag(in_vfrag, buffer, GSE_MAX_HEADER_LENGTH, GSE_MAX_TRAILER_LENGTH, IP_PAYLOAD_LENGTH);
		if (status != GSE_STATUS_OK)
		{
			fprintf(stderr, "Fail to copy data into input vfrag: %s\n",
			        gse_get_status(status));
			// in_vfrag is automatically freed in case of error
			goto free_context;
		}

		// Put PDU into encap context
		// One copy: label value
		status = gse_encap_receive_pdu(in_vfrag, encap_context, label,
		                               GSE_LT_NO_LABEL, PROTOCOL_TYPE, QOS_VALUE);
		if (status != GSE_STATUS_OK)
		{
			fprintf(stderr, "Fail to receive PDU: %s\n",
			        gse_get_status(status));
			// in_vfrag is automatically freed in case of error
			goto free_context;
		}

		// Fill BBFrames until no more encapsulated PDU
		do
		{
			// Get GSE packet
			status = gse_encap_get_packet_no_alloc(&out_vfrag, encap_context, MIN(size, GSE_MAX_PACKET_LENGTH), QOS_VALUE);
			if (status != GSE_STATUS_OK)
			{
				fprintf(stderr, "Fail to retrieve GSE packet: %s\n",
				        gse_get_status(status));
				goto free_context;
			}

			vfrag_length = gse_get_vfrag_length(out_vfrag);

			// Get pointer on packet start
			gse_packet = gse_get_vfrag_start(out_vfrag);

			// One copy here
			memcpy(bbframe + BBFRAME_LENGTH - size, gse_packet, vfrag_length);

			size -= vfrag_length;
			if (size <= GSE_MIN_PACKET_LENGTH)
				// BBFrame full, start new one
				size = BBFRAME_LENGTH;

			// Test if packet contains 'E' bit
			status = gse_get_end_indicator(gse_packet, &end_indicator);
			if (status != GSE_STATUS_OK)
			{
				fprintf(stderr, "Fail to retrieve GSE end indicator: %s\n",
				        gse_get_status(status));
				goto free_context;
			}

			// Is packet complete, or is it first fragment ?
			// (nb: only at most 2 fragments per packet)
			is_end = ((end_indicator & 0x01) == 0x01);
			if (!is_end)
				nb_fragment++;

			// Free vfrag before next call to gse_encap_get_packet() per
			// libgse requirement
			gse_free_vfrag_no_alloc(&out_vfrag, 1, 0);

		} while (is_end != true);
	}
	total_tics = clock() - clock_start;

	printf("NB iter: %e\n", NB_ITER);
	printf("Nb fragment: %d\n", nb_fragment);
	printf("Tics: %d - %e seconds\n", (int)total_tics, ((double)total_tics) / CLOCKS_PER_SEC);
	printf("Tics / loop: %f - %e seconds\n", ((double)total_tics / NB_ITER), (((double)total_tics)/NB_ITER)/CLOCKS_PER_SEC);

free_context:
	status = gse_free_vfrag_no_alloc(&in_vfrag, 0, 0);
			if (status != GSE_STATUS_OK)
			{
				fprintf(stderr, "Fail to retrieve GSE end indicator: %s\n",
				        gse_get_status(status));
			}
	status = gse_free_vfrag_no_alloc(&out_vfrag, 0, 1);
			if (status != GSE_STATUS_OK)
			{
				fprintf(stderr, "Fail to retrieve GSE end indicator: %s\n",
				        gse_get_status(status));
			}
	// Release context
	gse_encap_release(encap_context);

	return status;
}
/**
 * @file     eval_gse.c
 * @author   Audric Schiltknecht / Viveris Technologies
 * @date     01 mars 2013
 * @version  1.0
 * @brief    Evaluate libgse encapsulation performance
 */

#include <gse/constants.h>
#include <gse/encap.h>
#include <gse/virtual_fragment.h>
#include <gse/header_fields.h>

#include <strings.h>
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#include <unistd.h>
#include <time.h>

#define MIN(x, y)  (((x) < (y)) ? (x) : (y))

#define IP_PAYLOAD_LENGTH 40

#define BBFRAME_LENGTH 2001

#define NB_ITER 1E6

#define QOS_NR 1
#define FIFO_SIZE 1

#define PROTOCOL_TYPE 0x0800
#define QOS_VALUE 0

#define GSE_MIN_PACKET_LENGTH 12
#define GSE_MAX_PACKET_LENGTH (4095 + 2)

unsigned char ip_payload[IP_PAYLOAD_LENGTH];
unsigned char bbframe[BBFRAME_LENGTH];

uint8_t label[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };

int main(void)
{
	gse_encap_t *encap_context;
	gse_vfrag_t *in_vfrag, *out_vfrag;
	gse_status_t status;

	int size;
	size_t vfrag_length;
	unsigned char *gse_packet;
	int nb_fragment = 0;

	long long iter;

	uint8_t end_indicator;
	bool is_end;

	clock_t clock_start, total_tics;

	// Zero-ing payload
	bzero(ip_payload, IP_PAYLOAD_LENGTH);

	// Initialize encap context
	status = gse_encap_init(QOS_NR, FIFO_SIZE, &encap_context);
	if (status != GSE_STATUS_OK)
	{
		fprintf(stderr, "Fail to initialize encapsulation library: %s\n",
		        gse_get_status(status));
		return 1;
	}

	size = BBFRAME_LENGTH;
	clock_start = clock();
	for (iter = 0 ; iter < NB_ITER ; ++iter)
	{
		//printf("Iter #%d\n", iter);

		// Initialize input vfrag
		// It currently cannot be done outside of the loop,
		// since there is no other way to "reset" a vfrag,
		// and calling gse_free_vfrag() release the allocated memory...
		// One vfrag-allocation here:
		//  - One for the vfrag structure
		//  - One for the vbuf structure
		//  - One for the vbuf buffer
		status = gse_create_vfrag(&in_vfrag,
								  GSE_MAX_PDU_LENGTH,
								  GSE_MAX_HEADER_LENGTH,
								  GSE_MAX_TRAILER_LENGTH);
		if (status != GSE_STATUS_OK)
		{
			fprintf(stderr, "Fail to create input vfrag: %s\n",
					gse_get_status(status));
			return 1;
		}

		// Feed IP payload to GSE compressor
		// One copy here
		status = gse_copy_data(in_vfrag, ip_payload, IP_PAYLOAD_LENGTH);
		if (status != GSE_STATUS_OK)
		{
			fprintf(stderr, "Fail to copy data into input vfrag: %s\n",
			        gse_get_status(status));
			// in_vfrag is automatically freed in case of error
			goto free_context;
		}

		// Put PDU into encap context
		// One copy: label value
		status = gse_encap_receive_pdu(in_vfrag, encap_context, label,
		                               GSE_LT_NO_LABEL, PROTOCOL_TYPE, QOS_VALUE);
		if (status != GSE_STATUS_OK)
		{
			fprintf(stderr, "Fail to receive PDU: %s\n",
			        gse_get_status(status));
			// in_vfrag is automatically freed in case of error
			goto free_context;
		}

		// Fill BBFrames until no more encapsulated PDU
		do
		{
			// Get GSE packet
			// One allocation here (out_vfrag)
			// One copy (for extensions, even if there is none (memcpy(size=0))
			// One free here (in_vfrag if PDU is complete)
			status = gse_encap_get_packet(&out_vfrag, encap_context, MIN(size, GSE_MAX_PACKET_LENGTH), QOS_VALUE);
			if (status != GSE_STATUS_OK)
			{
				fprintf(stderr, "Fail to retrieve GSE packet: %s\n",
				        gse_get_status(status));
				goto free_context;
			}

			vfrag_length = gse_get_vfrag_length(out_vfrag);

			// Get pointer on packet start
			gse_packet = gse_get_vfrag_start(out_vfrag);

			// One copy here
			memcpy(bbframe + BBFRAME_LENGTH - size, gse_packet, vfrag_length);

			size -= vfrag_length;
			if (size <= GSE_MIN_PACKET_LENGTH)
				// BBFrame full, start new one
				size = BBFRAME_LENGTH;

			// Test if packet contains 'E' bit
			status = gse_get_end_indicator(gse_packet, &end_indicator);
			if (status != GSE_STATUS_OK)
			{
				fprintf(stderr, "Fail to retrieve GSE end indicator: %s\n",
				        gse_get_status(status));
				goto free_context;
			}

			// Is packet complete, or is it first fragment ?
			// (nb: only at most 2 fragments per packet)
			is_end = ((end_indicator & 0x01) == 0x01);
			if (!is_end)
				nb_fragment++;

			// Free vfrag before next call to gse_encap_get_packet() per
			// libgse requirement
			// One free here if packet is not fragmented
			gse_free_vfrag(&out_vfrag);

		} while (is_end != true);
	}
	total_tics = clock() - clock_start;

	printf("NB iter: %e\n", NB_ITER);
	printf("Nb fragment: %d\n", nb_fragment);
	printf("Tics: %d - %e seconds\n", (int)total_tics, ((double)total_tics) / CLOCKS_PER_SEC);
	printf("Tics / loop: %f - %e seconds\n", ((double)total_tics / NB_ITER), (((double)total_tics)/NB_ITER)/CLOCKS_PER_SEC);

free_context:
	// Release context
	gse_encap_release(encap_context);

	return status;
}