NETWIB_DAT(3)

NAME
netwib - section dat

HTML DOC
If you have a browser, read netwib-5.39.0-doc_html.tgz which is easier to read than this manpage.

PRESENTATION
This manpage contains a concatenation of includes for section DAT.

MODULE TYPES
/* integer of 8 bits */
typedef NETWIBDEF_TYPE_INT8 netwib_int8;
typedef NETWIBDEF_TYPE_UINT8 netwib_uint8;
/* integer of 16 bits */
typedef NETWIBDEF_TYPE_INT16 netwib_int16;
typedef NETWIBDEF_TYPE_UINT16 netwib_uint16;
/* integer of 32 bits */
typedef NETWIBDEF_TYPE_INT32 netwib_int32;
typedef NETWIBDEF_TYPE_UINT32 netwib_uint32;
/* integer of 64 bits */
#if NETWIBDEF_TYPE_INT64_FAKE == 0
  /* define the type */
  typedef NETWIBDEF_TYPE_INT64 netwib_int64;
  typedef NETWIBDEF_TYPE_UINT64 netwib_uint64;
  #define NETWIB_INT64_FAKE 0
#else
  /* define a fake structure allowing easy storage, but unusable for math */
  typedef struct {
    netwib_uint32 high;
    netwib_uint32 low;
  } netwib_uint64;
  typedef netwib_uint64 netwib_int64;
  #define NETWIB_INT64_FAKE 1
#endif
/* maximum size integer on the computer */
#if NETWIB_INT64_FAKE == 0
  typedef netwib_int64 netwib_intmax;
  typedef netwib_uint64 netwib_uintmax;
  #define NETWIB_INTMAX_BITS 64
#else
  typedef netwib_int32 netwib_intmax;
  typedef netwib_uint32 netwib_uintmax;
  #define NETWIB_INTMAX_BITS 32
#endif
/* size of pointers on the computer */
#if NETWIBDEF_ARCH_BITS == 32
  typedef netwib_int32 netwib_intptr;
  typedef netwib_uint32 netwib_uintptr;
  #define NETWIB_INTPTR_BITS 32
#elif NETWIBDEF_ARCH_BITS == 64
  typedef netwib_int64 netwib_intptr;
  typedef netwib_uint64 netwib_uintptr;
  #define NETWIB_INTPTR_BITS 64
#else
  #error "Unknown value for NETWIBDEF_ARCH_BITS"
#endif
/* char */
typedef char netwib_char;
/* byte */
typedef unsigned char netwib_byte;
/* pointer */
typedef void* netwib_ptr;
typedef const void* netwib_constptr;
/* data */
typedef netwib_byte* netwib_data;
typedef const netwib_byte* netwib_constdata;
/* string */
typedef netwib_char* netwib_string;
typedef const netwib_char* netwib_conststring;
/* boolean */
typedef enum {
  NETWIB_FALSE = 0,
  NETWIB_TRUE = !NETWIB_FALSE
} netwib_bool;
/* comparison */
typedef enum {
  NETWIB_CMP_LT = -1,
  NETWIB_CMP_EQ = 0,
  NETWIB_CMP_GT = +1
} netwib_cmp;
/* netwib contains several enum. User can define its own values
   starting from 10000 */
#define NETWIB_ENUM_USER_BEGIN 10000
/*-------------------------------------------------------------*/
/***************************************************************
 * Note about return values :                                  *
 * Every function returns a "netwib_err" which indicates :     *
 *   - NETWIB_ERR_OK  : everything went fine                   *
 *   - NETWIB_ERR_xyz : something strange occurred...          *
 ***************************************************************/
/*-------------------------------------------------------------*/
/***************************************************************
 * Note about parameters :                                     *
 * Some functions can accept NULL as parameter. This indicates *
 * the corresponding parameter is not needed.                  *
 * However this special case needs resources and specific      *
 * instruction paths. So, this is not supported for parameters *
 * such as netwib_ring, netwib_ips, etc. If you think we       *
 * missed one function needing this features, please contact   *
 * us.                                                         *
 ***************************************************************/

MODULE PTR
/*-------------------------------------------------------------*/
/* Name : netwib_ptr_malloc
   Description :
     Allocate a memory array.
   Input parameter(s) :
     allocsize : size of this array
   Input/output parameter(s) :
   Output parameter(s) :
     *pptr : pointer which will be malloced (so, the
             memory will have to be freed by the
             user with 'netwib_ptr_free(pptr)').
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_ptr_malloc(netwib_uint32 allocsize,
                             netwib_ptr *pptr);
/*-------------------------------------------------------------*/
/* Name : netwib_ptr_realloc
   Description :
     Reallocate a memory array.
   Input parameter(s) :
     newallocsize : new size of this array
   Input/output parameter(s) :
   Output parameter(s) :
     *pptr : pointer which will be reallocated (so, the
             memory will have to be freed by the
             user with 'netwib_ptr_free(pptr)').
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_ptr_realloc(netwib_uint32 newallocsize,
                              netwib_ptr *pptr);
/*-------------------------------------------------------------*/
/* Name : netwib_ptr_free
   Description :
     Free a memory array.
   Input parameter(s) :
     *pptr : pointer to the memory to free
   Input/output parameter(s) :
   Output parameter(s) :
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_ptr_free(netwib_ptr *pptr);

MODULE BUF
/*-------------------------------------------------------------*/
/***************************************************************
 * A netwib_buf is the standard memory storage used in netwib. *
 *                                                             *
 * A netwib_buf points to an array (static or malloced) which  *
 * starts at 'first' and finishes at 'last'.                   *
 * The memory contains user data between 'begin' and 'end'.    *
 *    ---------------------------------------------------      *
 *    |       |               data              |       |      *
 *    |F|     |B|                               |E|     |L     *
 *    ---------------------------------------------------      *
 *   First   Begin                              End    Last    *
 *     0       x                                 y   totalsize *
 *                                                             *
 * Data between 'first and begin', and data between 'end and   *
 * last' may be corrupted when working on the buffer. To avoid *
 * this, use netwib_buf_init_ext_buf and work on the new buffer*
 ***************************************************************/
/*-------------------------------------------------------------*/
typedef struct {
  netwib_uint32 flags;       /* see below */
  netwib_data totalptr;      /* ptr to first */
  netwib_uint32 totalsize;   /* last - first */
  netwib_uint32 beginoffset; /* begin - first */
  netwib_uint32 endoffset;   /* end - first */
} netwib_buf;
typedef const netwib_buf netwib_constbuf;
/*-------------------------------------------------------------*/
/***************************************************************
 * Field "flags" is a bit field indicating some information    *
 * about a netwib_buf.                                         *
 ***************************************************************/
/* If totalptr points :
     0x0001 : to an allocated memory
    ~0x0001 : to an external array (stack array or array which
              does not need to be freed)
   Those two modes corresponds to the two ways to initialize a
   netwib_buf :
     - netwib_buf_init_malloc : it internally allocates memory
       and eventually reallocate it if more is needed. At the
       end, function netwib_buf_close must be called to free
       memory.
     - netwib_buf_init_ext_xyz : buffer does not contain memory,
       but points on an external array. At the end, function
       netwib_buf_close does not need to be called to free
       memory (no closing function is needed).
   This flag should not be directly modified by user.
 */
#define NETWIB_BUF_FLAGS_ALLOC 0x00000001u
/* In the following case :
     - flag NETWIB_BUF_FLAGS_ALLOC is unset, and
     - there is no sufficient space in the array
   we can :
     0x0002 : allocate memory and store array content in it
              (the array is no more used)
    ~0x0002 : return a space limitation error
   This flag is very useful to optimize code. When we know in
   most cases our code will need 80 bytes, we use an array
   of 80 bytes. In the rare cases where it is not sufficient,
   an allocated pointer is created. Like this for most
   frequently encountered cases, there is no need to allocate.
   Once allocated, it works like if it was allocated from beginning.
   Once allocated, the external array is no more used.
   Once allocated, flag NETWIB_BUF_FLAGS_ALLOC is automatically
   set.
   If array size is greater than 2k, it's not really advantageous
   to use this flag, because copying 2k needs almost the same time
   as a malloc and free.
   This is generally used with netwib_buf_init_ext_arrayempty.
   This flag defaults to false. It has to be explicitly set
   by user.
 */
#define NETWIB_BUF_FLAGS_CANALLOC 0x00000002u
/* If functions are :
     0x0004 : allowed to slide data (shrunk space between First
              and Begin), when there is no sufficient space
              between End and Last for appending
    ~0x0004 : not allowed to slide
   This flag defaults to false. It has to be explicitly set
   by user.
*/
#define NETWIB_BUF_FLAGS_CANSLIDE 0x00000004u
/* Sometimes, a buffer contains sensitive data such as a password,
   so we want to do a memset on this data when it is no more needed.
   This flags says that buffer contains sensitive data. Buffer will
   be wiped with memset(.0.) during:
     netwib_buf_close(),
     netwib__buf_reinit(),
     netwib__buf_erase(),
     netwib_bufpool_buf_close(),
     netwib_bufpool_close(),
     and all functions using above ones.
   It is developer's task to set this flag each time a buffer may
   contain sensitive data.
   Netwib supports a feature to transfer this flag (also known as
   tainting in other languages). For example, when a sensitive
   buffer is copied to another buffer, this one also becomes
   sensitive.
   Once buffer is closed, the flag is unset, so user has to set
   it each time sensitive data is initialized. The closing
   functions are:
     netwib_buf_close(),
     netwib_bufpool_buf_close(),
     netwib_bufpool_close().
   WARNING:
   This feature was conceived for PASSWORDS or cryptographic KEYS
   stored in a netwib_buf. It cannot help for other types such
   as a netwib_string, a netwib_ring or a netwib_ip.
   This feature was conceived for buffer manipulation functions,
   such as netwib_buf_append_buf, and not in functions unrelated
   to passwords or keys, such as netwib_pkt_... or
   netwib_sniff_... When a function supports this feature, it is
   indicated in its help comment before the prototype (.h file).
   Perhaps one day, I will expand this feature to erase other kind
   of data, but this is not the case currently.
   To sum up, don't expect this feature to be the Solution for
   your sensitive data management, but only a small step towards it.
   END OF WARNING.
   This flag defaults to false. It has to be explicitly set
   by user.
*/
#define NETWIB_BUF_FLAGS_SENSITIVE 0x00000008u
/* data is sensitive, but readonly (such as a password stored
   in a static string which cannot be wiped, but can be
   transfered when buffer is copied)
*/
#define NETWIB_BUF_FLAGS_SENSITIVE_READONLY 0x00000010u
/* to transfer the sensitive flag to the second buffer */
#define netwib__buf_transfersensitive(pbuf1,pbuf2) { if ((pbuf1) != NULL && (pbuf2) != NULL) { if ((pbuf1)->flags & NETWIB_BUF_FLAGS_SENSITIVE) { (pbuf2)->flags |= NETWIB_BUF_FLAGS_SENSITIVE; } } }
/* to wipe a local array used in parallel of a buffer */
#define netwib__localarray_wipe(arr) netwib_c_memset((arr),0,sizeof(arr))
#define netwib__localarray_ifbuf_wipe(pbuf,arr) { if ((pbuf) != NULL && ((pbuf)->flags & NETWIB_BUF_FLAGS_SENSITIVE)) netwib__localarray_wipe(arr); }
/* number of used bits */
#define NETWIB_BUF_FLAGS_USEDBITS 5
/*-------------------------------------------------------------*/
/***************************************************************
 * Type netwib_bufext is exactly the same as netwib_buf. It    *
 * permits to easily determine which kind of buffer is needed  *
 * by a function :                                             *
 *  - Functions having an output parameter of type netwib_buf  *
 *    must be called with the buffer previously initialized :  *
 *    they will append data to it                              *
 *  - Functions having an output parameter of type             *
 *    netwib_bufext will initialize it.                        *
 * Example :                                                   *
 *  An IP4 packet might contain an IP4 option. There is no     *
 *  need to allocate/copy data for this option, because it is  *
 *  simply contained in the input packet (at offset            *
 *  20==sizeof(ip4hdr)). So in this case a netwib_bufext is    *
 *  used.                                                      *
 ***************************************************************/
typedef netwib_buf netwib_bufext;
/*-------------------------------------------------------------*/
/* Name : netwib_buf_init_malloc
   Description :
     Initialize a buf. Its memory dynamically grows.
   Input parameter(s) :
     allocsize : allocated size. If 0, a
                 default value is used.
   Input/output parameter(s) :
   Output parameter(s) :
     *pbuf : netwib_buf initialized
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_buf_init_malloc(netwib_uint32 allocs,
                                  netwib_buf *pbuf);
#define netwib_buf_init_mallocdefault(pbuf) netwib_buf_init_malloc(1024,pbuf)
/*-------------------------------------------------------------*/
/* Name : netwib_buf_init_ext_array
   Description :
     Initialize a buf. Its memory corresponds to an external
     fixed size array.
   Input parameter(s) :
     array : external array
     arraysize : external array size
     beginoffset : offset of begin in this array
     endoffset : offset of end in this array
   Input/output parameter(s) :
   Output parameter(s) :
     *pbuf : netwib_bufext initialized
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_buf_init_ext_array(netwib_constptr array,
                                     netwib_uint32 arraysize,
                                     netwib_uint32 beginoffset,
                                     netwib_uint32 endoffset,
                                     netwib_bufext *pbuf);
#define netwib_buf_init_ext_arrayempty(array,arraysize,pbuf) netwib_buf_init_ext_array(array,arraysize,0,0,pbuf)
#define netwib_buf_init_ext_arrayfilled(array,arraysize,pbuf) netwib_buf_init_ext_array(array,arraysize,0,arraysize,pbuf)
#define netwib_buf_init_ext_arraysizeofempty(array,pbuf) netwib_buf_init_ext_arrayempty(array,sizeof(array),pbuf)
#define netwib_buf_init_ext_arraysizeoffilled(array,pbuf) netwib_buf_init_ext_arrayfilled(array,sizeof(array),pbuf)
/* A buffer containing no data */
#define netwib_buf_init_ext_empty(pbuf) netwib_buf_init_ext_array(NULL,0,0,0,pbuf)
/*-------------------------------------------------------------*/
/* Name : netwib_buf_init_ext_storagearray
   Description :
     Initialize a buf. Its memory corresponds to an external
     fixed size array or to nothing. When data is added, it may
     be allocated. A call to netwib_buf_close() will have to be done.
   Input parameter(s) :
     array : external array
     arraysize : external array size
     beginoffset : offset of begin in this array
     endoffset : offset of end in this array
   Input/output parameter(s) :
   Output parameter(s) :
     *pbuf : netwib_bufext initialized
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_buf_init_ext_storagearray(netwib_constptr array,
                                            netwib_uint32 arraysize,
                                            netwib_bufext *pbuf);
/* An empty buffer, allocated on first append */
#define netwib_buf_init_ext_storage(pbuf) netwib_buf_init_ext_storagearray(NULL,0,pbuf)
/* An empty array, allocated if not sufficiently big */
#define netwib_buf_init_ext_storagearraysizeof(array,pbuf) netwib_buf_init_ext_storagearray(array,sizeof(array),pbuf)
/*-------------------------------------------------------------*/
/* Name : netwib_buf_init_ext_buf
   Description :
     Initialize a buf. Its memory corresponds to an external
     buffer.
   Input parameter(s) :
     *pbuf : netwib_buf containing data
   Input/output parameter(s) :
   Output parameter(s) :
     *pbuf : netwib_bufext initialized
   Normal return values :
     NETWIB_ERR_OK : ok
   This function supports NETWIB_BUF_FLAGS_SENSITIVE.
*/
netwib_err netwib_buf_init_ext_buf(netwib_constbuf *pbufin,
                                   netwib_bufext *pbuf);
/*-------------------------------------------------------------*/
/* Name : netwib_buf_init_ext_string
   Description :
     Initialize a buf. Its memory corresponds to an external
     preset string.
   Input parameter(s) :
     str : external string
   Input/output parameter(s) :
   Output parameter(s) :
     *pbuf : netwib_bufext initialized
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_buf_init_ext_string(netwib_conststring str,
                                      netwib_bufext *pbuf);
/*-------------------------------------------------------------*/
/* Name : netwib_buf_append_xyz
   Description :
     Add data to a buf.
   Input parameter(s) :
     data : data to add
     datasize : size of data to add
     str : string to add
     c : character to add
   Input/output parameter(s) :
     *pbuf : netwib_buf updated
   Output parameter(s) :
   Normal return values :
     NETWIB_ERR_OK : ok
   The netwib_buf_append_buf function supports NETWIB_BUF_FLAGS_SENSITIVE.
*/
netwib_err netwib_buf_append_data(netwib_constdata data,
                                  netwib_uint32 datasize,
                                  netwib_buf *pbuf);
netwib_err netwib_buf_append_string(netwib_conststring str,
                                    netwib_buf *pbuf);
netwib_err netwib_buf_append_buf(netwib_constbuf *pbuftoappend,
                                 netwib_buf *pbuf);
netwib_err netwib_buf_append_byte(netwib_byte b,
                                  netwib_buf *pbuf);
/*-------------------------------------------------------------*/
/* Name : netwib_buf_prepend_buf
   Description :
     Prepend data to a buf.
   Input parameter(s) :
   Input/output parameter(s) :
     *pbuf : netwib_buf updated
   Output parameter(s) :
   Normal return values :
     NETWIB_ERR_OK : ok
   Note :
     Parameter canslide has no effect on this function (this is
     logical).
   This function supports NETWIB_BUF_FLAGS_SENSITIVE.
*/
netwib_err netwib_buf_prepend_buf(netwib_constbuf *pbuftoprepend,
                                  netwib_buf *pbuf);
/*-------------------------------------------------------------*/
/* Name : netwib_buf_ref_string
   Description :
     Get pointers to data stored in buf (between begin and end).
     If buffer internal storage does not end with '\0',
     a new one is added. So, we can have NETWIB_ERR_DATANOSPACE
     if there is no room for the '\0'.
   Input parameter(s) :
     *pbuf : buffer
   Input/output parameter(s) :
   Output parameter(s) :
     *pstr : pointer to start of string
   Normal return values :
     NETWIB_ERR_OK : ok
     NETWIB_ERR_DATANOSPACE : no room for the '\0'
*/
netwib_err netwib_buf_ref_string(netwib_buf *pbuf,
                                 netwib_string *pstr);
/*-------------------------------------------------------------*/
/* Name : netwib_constbuf_ref_string
   Description :
     Some as netwib_buf_ref_string except it does not modify
     the buffer to add the '\0'.
   Input parameter(s) :
     *pbuf : buffer
   Input/output parameter(s) :
   Output parameter(s) :
     *pstr : pointer to start of string
   Normal return values :
     NETWIB_ERR_OK : ok
     NETWIB_ERR_DATANOSPACE : the char after endoffset is not a '\0'
*/
netwib_err netwib_constbuf_ref_string(netwib_constbuf *pbuf,
                                      netwib_string *pstr);
/* to use at begin of a function to manage a local buffer */
#define netwib__constbuf_ref_string(pbuf, str, bufstorage, func) { netwib_err bufstorageret; bufstorageret = netwib_constbuf_ref_string(pbuf, &str); if (bufstorageret != NETWIB_ERR_OK) { if (bufstorageret == NETWIB_ERR_DATANOSPACE) { netwib_data bufstoragearray[512]; netwib_buf bufstorage; netwib_er(netwib_buf_init_ext_storagearraysizeof(bufstoragearray, &bufstorage)); netwib_er(netwib_buf_append_buf(pbuf, &bufstorage)); netwib_er(netwib_buf_append_byte(0, &bufstorage)); bufstorage.endoffset--; bufstorageret = func; netwib_er(netwib_buf_close(&bufstorage)); } return(bufstorageret); } }
/*-------------------------------------------------------------*/
/* Name : netwib_buf_wantspace
   Description :
     Request space in a buffer (from end to last).
     When buffer is initialized as malloced memory, it is
     possible to obtain unlimited space. Otherwise, we cannot
     obtain more space than array size (unless flag
     NETWIB_BUF_FLAGS_CANALLOC is set).
   Input parameter(s) :
     wantedspace : wanted space
   Input/output parameter(s) :
     *pbuf : buffer
   Output parameter(s) :
     *pdata : pointer to end (endoffset)
   Normal return values :
     NETWIB_ERR_OK : ok
     NETWIB_ERR_DATANOSPACE : there is less than wantedspace
*/
netwib_err netwib_buf_wantspace(netwib_buf *pbuf,
                                netwib_uint32 wantedspace,
                                netwib_data *pdata);
/*-------------------------------------------------------------*/
/* Name : netwib_buf_wishspace
   Description :
     Request space in a buffer (from end to last).
     When buffer is initialized as malloced memory, it is
     possible to obtain unlimited space. Otherwise, we cannot
     obtain more space than array size (unless flag
     NETWIB_BUF_FLAGS_CANALLOC is set).
   Input parameter(s) :
     wantedspace : wanted space
   Input/output parameter(s) :
     *pbuf : buffer
   Output parameter(s) :
     *pdata : pointer to end (endoffset)
     *pobtainedspace : obtained space (from end to last)
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_buf_wishspace(netwib_buf *pbuf,
                                netwib_uint32 wantedspace,
                                netwib_data *pdata,
                                netwib_uint32 *pobtainedspace);
/*-------------------------------------------------------------*/
/* Name : netwib_buf_cmp
   Description :
     Compare two netwib_buf.
   Input parameter(s) :
     *pbuf1 : netwib_buf to compare with buf2
     *pbuf2 : netwib_buf to compare with buf1
   Input/output parameter(s) :
   Output parameter(s) :
     *pcmp :
       NETWIB_CMP_LT : buf1<buf2
       NETWIB_CMP_EQ : if buf1 and buf2 are equal
       NETWIB_CMP_GT : buf1>buf2
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_buf_cmp(netwib_constbuf *pbuf1,
                          netwib_constbuf *pbuf2,
                          netwib_cmp *pcmp);
/* ignore case */
netwib_err netwib_buf_casecmp(netwib_constbuf *pbuf1,
                              netwib_constbuf *pbuf2,
                              netwib_cmp *pcmp);
/* compare to a string */
netwib_err netwib_buf_cmp_string(netwib_constbuf *pbuf1,
                                 netwib_conststring string2,
                                 netwib_cmp *pcmp);
netwib_err netwib_buf_casecmp_string(netwib_constbuf *pbuf1,
                                     netwib_conststring string2,
                                     netwib_cmp *pcmp);
/*-------------------------------------------------------------*/
/* Name : netwib_buf_shift
   Description :
     Shift data in a buf.
   Input parameter(s) :
     offset : offset
     truncbegend : truncate on begin/end edges (otherwise,
                   truncate only on first/last edges)
   Input/output parameter(s) :
     *pbuf : netwib_buf updated
   Output parameter(s) :
   Normal return values :
     NETWIB_ERR_OK : ok
   Examples :
     buf contains         "   data  "
     shift(buf,-1,0) =>   "  data   "
     shift(buf,-1,1) =>   "   ata   " (d is truncated)
     shift(buf,+1,0) =>   "    data "
     shift(buf,+4,0) =>   "       data" (if buffer is malloced)
     shift(buf,+4,0) =>   "       da" (if buffer is external)
     shift(buf,+1,1) =>   "    dat  " (a is truncated)
   Note :
     Flag NETWIB_BUF_FLAGS_CANSLIDE has no effect on this
     function (this is logical).
*/
netwib_err netwib_buf_shift(netwib_buf *pbuf,
                            netwib_int32 offset,
                            netwib_bool truncbegend);
/*-------------------------------------------------------------*/
/* Name : netwib_buf_close
   Description :
     Close buf, eventually freeing data it contains.
   Input parameter(s) :
   Input/output parameter(s) :
     *pbuf : buffer closed
   Output parameter(s) :
   Normal return values :
     NETWIB_ERR_OK : ok
   Note :
     This function is only needed for a buffer initialized
     with netwib_buf_init_malloc, or if flag
     NETWIB_BUF_FLAGS_CANALLOC is set.
*/
netwib_err netwib_buf_close(netwib_buf *pbuf);
/*-------------------------------------------------------------*/
/* Frequently needed defines */
#define netwib__buf_reinit(pbuf) { (pbuf)->beginoffset = 0; (pbuf)->endoffset = 0; if (((pbuf)->flags & NETWIB_BUF_FLAGS_SENSITIVE) && !((pbuf)->flags & NETWIB_BUF_FLAGS_SENSITIVE_READONLY)) { netwib_c_memset((pbuf)->totalptr, 0, (pbuf)->totalsize); } }
#define netwib__buf_erase(pbuf) { if (((pbuf)->flags & NETWIB_BUF_FLAGS_SENSITIVE) && !((pbuf)->flags & NETWIB_BUF_FLAGS_SENSITIVE_READONLY)) { netwib_c_memset((pbuf)->totalptr+(pbuf)->beginoffset, 0, (pbuf)->endoffset-(pbuf)->beginoffset); } (pbuf)->endoffset = (pbuf)->beginoffset; }
#define netwib__buf_ref_data_ptr(pbuf) ((pbuf)->totalptr + (pbuf)->beginoffset)
#define netwib__buf_ref_data_size(pbuf) ((pbuf)->endoffset -(pbuf)->beginoffset)
#define netwib__buf_ref_data_sizenull(pbuf) ((pbuf)!=NULL?netwib__buf_ref_data_size(pbuf):0)

MODULE BUFPOOL
/*-------------------------------------------------------------*/
/***************************************************************
 * A netwib_bufpool permits to obtain and release memory,      *
 * without having to malloc and free it : this is done once.   *
 * This is mainly advantageous for programs needing to allocate*
 * and free frequently. For programs allocating memory and then*
 * only freeing it at the end, function netwib_buf_init_malloc *
 * is more appropriated.                                       *
 ***************************************************************/
/*-------------------------------------------------------------*/
typedef struct netwib_bufpool netwib_bufpool;
/*-------------------------------------------------------------*/
/* Name : netwib_bufpool_init
   Description :
     Initialize a netwib_bufpool.
   Input parameter(s) :
     mt : for multithread access
   Input/output parameter(s) :
     **ppbufpool : bufpool initialized
   Output parameter(s) :
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_bufpool_init(netwib_bool mt,
                               netwib_bufpool **ppbufpool);
#define netwib_bufpool_initdefault(ppbufpool) netwib_bufpool_init(NETWIB_FALSE,ppbufpool)
/*-------------------------------------------------------------*/
/* Name : netwib_bufpool_close
   Description :
     Close a netwib_bufpool.
   Input parameter(s) :
   Input/output parameter(s) :
     **ppbufpool : bufpool closed
   Output parameter(s) :
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_bufpool_close(netwib_bufpool **ppbufpool);
/*-------------------------------------------------------------*/
/* Name : netwib_bufpool_buf_init
   Description :
     Give a buffer pointer to user.
   Input parameter(s) :
   Input/output parameter(s) :
     *pbufpool : bufpool
   Output parameter(s) :
     *ppbuf : pointer obtained
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_bufpool_buf_init(netwib_bufpool *pbufpool,
                                   netwib_buf **ppbuf);
/*-------------------------------------------------------------*/
/* Name : netwib_bufpool_buf_close
   Description :
     The user indicates he does not need the buffer anymore.
   Input parameter(s) :
   Input/output parameter(s) :
     *pbufpool : bufpool
     *ppbuf : pointer to close
   Output parameter(s) :
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_bufpool_buf_close(netwib_bufpool *pbufpool,
                                    netwib_buf **ppbuf);

MODULE C
/*-------------------------------------------------------------*/
/* do not forget to add "#include <string.h>" at the beginning of
   the file to use those defines */
/* copies n bytes from memory area src to memory area dest (no overlap) */
#define netwib_c_memcpy(dest,src,n) memcpy(dest,src,n)
/* copies n bytes from memory area src to memory area dest */
#define netwib_c_memmove(dest,src,n) memmove(dest,src,n)
/* fills the first n bytes of the memory area pointed to by s with
   the constant byte c */
#define netwib_c_memset(d,c,n) memset(d,c,n)
/* compares the first n bytes of the memory areas s1 and s2 */
#define netwib_c_memcmp(s1,s2,n) memcmp(s1,s2,n)
/* scans the first n bytes of the memory area pointed to by s for
   the character c */
#define netwib_c_memchr(s,c,n) memchr(s,c,n)
/*-------------------------------------------------------------*/
/* do not forget to add "#include <string.h>" at the beginning of
   the file to use those defines */
/* compares the two strings s1 and s2 */
#define netwib_c_strcmp(s1,s2) strcmp(s1,s2)
/* compares the first n characters of strings s1 and s2 */
#define netwib_c_strncmp(s1,s2,n) strncmp(s1,s2,n)
/* returns a pointer to the first occurrence of the character c in
   the string s */
#define netwib_c_strchr(s,c) strchr(s,c)
/* returns a pointer to the last occurrence of the character c in
   the string s */
#define netwib_c_strrchr(s,c) strrchr(s,c)
/* finds the first occurrence of the needle in the string haystack */
#define netwib_c_strstr(haystack,needle) strstr(haystack,needle)
/* calculates the length of the initial segment of s which consists
   entirely of characters in accept */
#define netwib_c_strspn(s,accept) strcspn(s,accept)
/* calculates the length of the initial segment of s which consists
   entirely of characters not in reject */
#define netwib_c_strcspn(s,reject) strcspn(s,reject)
/* locates the first occurrence in the string s of any of the
   characters in the string accept */
#define netwib_c_strpbrk(s,accept) strpbrk(s,accept)
/* calculates the length of the string s, not including the
   terminating `\0' character */
#define netwib_c_strlen(s) strlen(s)
/* copies the string pointed to be src to the array pointed
   to by dest (you need to take care about overflows) */
#define netwib_c_strcpy(dest,src) strcpy(dest,src)
/* append the string pointed to be src to the array pointed
   to by dest (you need to take care about overflows) */
#define netwib_c_strcat(dest,src) strcat(dest,src)
/*-------------------------------------------------------------*/
/* we create those functions because they might not exists on
   every system */
/* compares the two strings s1 and s2, ignoring the case of the
   characters */
int netwib_c_strcasecmp(netwib_conststring s1,
                        netwib_conststring s2);
/* compares the first n characters of strings s1 and s2, ignoring
   the case of the characters */
int netwib_c_strncasecmp(netwib_conststring s1,
                         netwib_conststring s2,
                         netwib_uint32 n);
/* compares the first n bytes of the memory areas s1 and s2,
   ignoring the case of the characters */
int netwib_c_memcasecmp(netwib_constdata s1,
                        netwib_constdata s2,
                        netwib_uint32 n);
/* finds the first occurrence of the needle in the string haystack,
   ignoring the case of the characters */
netwib_string netwib_c_strcasestr(netwib_conststring haystack,
                                  netwib_conststring needle);
/* finds the start of the first occurrence of the substring needle
   of length needlelen in the memory area haystack of length haystacklen */
netwib_data netwib_c_memmem(netwib_constdata haystack,
                            netwib_uint32 haystacklen,
                            netwib_constdata needle,
                            netwib_uint32 needlelen);
/* idem, with case */
netwib_data netwib_c_memcasemem(netwib_constdata haystack,
                                netwib_uint32 haystacklen,
                                netwib_constdata needle,
                                netwib_uint32 needlelen);

MODULE C2
/* non standard functions */
/*-------------------------------------------------------------*/
/* CHARACTER FUNCTIONS */
/*-------------------------------------------------------------*/
/* warning : param is called several times. Use those functions with care.
   For example, they are not suitable for "netwib_c2_isalnum(c++)". */
#define netwib_c2_isalnum(c) ( netwib_c2_isalpha(c) || netwib_c2_isdigit(c) )
#define netwib_c2_isalpha(c) ( netwib_c2_islower(c) || netwib_c2_isupper(c) )
#define netwib_c2_isdigit(c) ( ((c)>='0') && ((c)<='9') )
#define netwib_c2_islower(c) ( ((c)>='a') && ((c)<='z') )
#define netwib_c2_isupper(c) ( ((c)>='A') && ((c)<='Z') )
#define netwib_c2_isxdigit(c) ( netwib_c2_isdigit(c) || ( ((c)>='a') && ((c)<='f') ) || ( ((c)>='A') && ((c)<='F') ) )
#define netwib_c2_isprint(c) ( (c)>=32 && (c)<=126 )
#define netwib_c2_isprint2(c) ( netwib_c2_isprint(c) || (c)=='\t' || (c)=='\r' || (c)=='\n' )
#define netwib_c2_isspace(c) ( (c)==' ' || (c)=='\t' || (c)=='\n' || (c)=='\r' || (c)=='\f' || (c)=='\v')
/*-------------------------------------------------------------*/
/* Warning : first 2 functions change the parameter */
#define netwib_c2_lower(c) if (netwib_c2_isupper(c)) { c += 'a' - 'A'; }
#define netwib_c2_upper(c) if (netwib_c2_islower(c)) { c -= 'a' - 'A'; }
/* Warning : param is called several times */
#define netwib_c2_lc(c) ((netwib_char)(netwib_c2_isupper(c)?((c)+'a'-'A'):(c)))
#define netwib_c2_uc(c) ((netwib_char)(netwib_c2_islower(c)?((c)-'a'+'A'):(c)))
/*-------------------------------------------------------------*/
/* 0->16 to '0'->'F' without error checking */
#define netwib_c2_16toc(x) (char)(((x)<=9)?('0'+(x)):('a'+(x)-10))
#define netwib_c2_16toC(x) (char)(((x)<=9)?('0'+(x)):('A'+(x)-10))
/* '0'->'F' to 0->16 without error checking */
#define netwib_c2_cto16(x) (((x)>='0'&&(x)<='9')?((x)-'0'):(((x)>='a'&&(x)<='f')?(10+(x)-'a'):(10+(x)-'A')))
/* 0->9 to '0'->'9' without error checking */
#define netwib_c2_9toc(x) (char)('0'+(x))
/* '0'->'9' to 0->9 without error checking */
#define netwib_c2_cto9(x) ((x)-'0')
/*-------------------------------------------------------------*/
/* '0'->'F' to 0->16 with error checking */
#define netwib_c2_cto16_if(c,quartet) if ((c) >= '0' && (c) <= '9') { quartet = (c) - '0'; } else if ((c) >= 'a' && (c) <= 'f') { quartet = 10 + (c) - 'a'; } else if ((c) >= 'A' && (c) <= 'F') { quartet = 10 + (c) - 'A'; }
/* '0'->'9' to 0->9 with error checking */
#define netwib_c2_cto9_if(c,digit) if ((c) >= '0' && (c) <= '9') { digit = (c) - '0'; }
/*-------------------------------------------------------------*/
/* INTEGER FUNCTIONS */
/*-------------------------------------------------------------*/
/* byte extract from uint16, uint32 or uint64 */
#define netwib_c2_uint16_0(x) (netwib_byte)(((x)>>8)&0xFF)
#define netwib_c2_uint16_1(x) (netwib_byte)((x)&0xFF)
#define netwib_c2_uint32_0(x) (netwib_byte)(((x)>>24)&0xFF)
#define netwib_c2_uint32_1(x) (netwib_byte)(((x)>>16)&0xFF)
#define netwib_c2_uint32_2(x) (netwib_byte)(((x)>>8)&0xFF)
#define netwib_c2_uint32_3(x) (netwib_byte)((x)&0xFF)
#if NETWIB_INT64_FAKE == 0
 #define netwib_c2_uint64_0(x) (netwib_byte)(((x)>>56)&0xFF)
 #define netwib_c2_uint64_1(x) (netwib_byte)(((x)>>48)&0xFF)
 #define netwib_c2_uint64_2(x) (netwib_byte)(((x)>>40)&0xFF)
 #define netwib_c2_uint64_3(x) (netwib_byte)(((x)>>32)&0xFF)
 #define netwib_c2_uint64_4(x) (netwib_byte)(((x)>>24)&0xFF)
 #define netwib_c2_uint64_5(x) (netwib_byte)(((x)>>16)&0xFF)
 #define netwib_c2_uint64_6(x) (netwib_byte)(((x)>>8)&0xFF)
 #define netwib_c2_uint64_7(x) (netwib_byte)((x)&0xFF)
 #define netwib_c2_uint64_32high(x) (netwib_uint32)((x)>>32)
 #define netwib_c2_uint64_32low(x) (netwib_uint32)((x)&0xFFFFFFFFu)
#else
 #define netwib_c2_uint64_0(x) netwib_c2_uint32_0((x).high)
 #define netwib_c2_uint64_1(x) netwib_c2_uint32_1((x).high)
 #define netwib_c2_uint64_2(x) netwib_c2_uint32_2((x).high)
 #define netwib_c2_uint64_3(x) netwib_c2_uint32_3((x).high)
 #define netwib_c2_uint64_4(x) netwib_c2_uint32_0((x).low)
 #define netwib_c2_uint64_5(x) netwib_c2_uint32_1((x).low)
 #define netwib_c2_uint64_6(x) netwib_c2_uint32_2((x).low)
 #define netwib_c2_uint64_7(x) netwib_c2_uint32_3((x).low)
 #define netwib_c2_uint64_32high(x) ((x).high)
 #define netwib_c2_uint64_32low(x) ((x).low)
#endif
/*-------------------------------------------------------------*/
/* recomposition of uint16 or uint32 */
#define netwib_c2_uint16_2(a,b) (netwib_uint16)((((netwib_byte)(a))<<8)|((netwib_byte)(b)))
#define netwib_c2_uint32_4(a,b,c,d) (netwib_uint32)((((netwib_byte)(a))<<24)|(((netwib_byte)(b))<<16)|(((netwib_byte)(c))<<8)|((netwib_byte)(d)))
#if NETWIB_INT64_FAKE == 0
 #define netwib_c2_uint64_8(a,b,c,d,e,f,g,h) (netwib_uint64)((((netwib_uint64)((netwib_byte)(a)))<<56)|(((netwib_uint64)((netwib_byte)(b)))<<48)|(((netwib_uint64)((netwib_byte)(c)))<<40)|(((netwib_uint64)((netwib_byte)(d)))<<32)|(((netwib_uint64)((netwib_byte)(e)))<<24)|(((netwib_uint64)((netwib_byte)(f)))<<16)|(((netwib_uint64)((netwib_byte)(g)))<<8)|((netwib_uint64)((netwib_byte)(h))))
#endif
/* other 64 bit version defines are in uint64.h */
/*-------------------------------------------------------------*/
/* left and right rotation */
#define netwib_c2_uint8_ror(x,n) ((netwib_uint8)( (netwib_uint8)((x)>>(n)) | (netwib_uint8)((x)<<(8-(n))) ))
#define netwib_c2_uint8_rol(x,n) ((netwib_uint8)( (netwib_uint8)((x)<<(n)) | (netwib_uint8)((x)>>(8-(n))) ))
#define netwib_c2_uint16_ror(x,n) ((netwib_uint16)( (netwib_uint16)((x)>>(n)) | (netwib_uint16)((x)<<(16-(n))) ))
#define netwib_c2_uint16_rol(x,n) ((netwib_uint16)( (netwib_uint16)((x)<<(n)) | (netwib_uint16)((x)>>(16-(n))) ))
#define netwib_c2_uint32_ror(x,n) ((netwib_uint32)( (netwib_uint32)((x)>>(n)) | (netwib_uint32)((x)<<(32-(n))) ))
#define netwib_c2_uint32_rol(x,n) ((netwib_uint32)( (netwib_uint32)((x)<<(n)) | (netwib_uint32)((x)>>(32-(n))) ))
/* 64 bit version defines are in uint64.h */

MODULE BUFENC
/*-------------------------------------------------------------*/
typedef enum {
  NETWIB_ENCODETYPE_DATA = 1,        /* exact data */
  NETWIB_ENCODETYPE_HEXA0,           /* hexadecimal */
  NETWIB_ENCODETYPE_HEXA1,           /* hexadecimal */
  NETWIB_ENCODETYPE_HEXA2,           /* hexadecimal */
  NETWIB_ENCODETYPE_HEXA4,           /* hexadecimal */
  NETWIB_ENCODETYPE_MIXED0,          /* mixed */
  NETWIB_ENCODETYPE_MIXED1,          /* mixed */
  NETWIB_ENCODETYPE_TEXT,            /* printable text */
  NETWIB_ENCODETYPE_BASE64,          /* base64 */
  NETWIB_ENCODETYPE_QUOTED,          /* quoted */
  NETWIB_ENCODETYPE_NOTHING = 100,   /* print nothing */
  NETWIB_ENCODETYPE_SYNTH,           /* print a synthetic form */
  /* wrap to 80 columns (or less) */
  NETWIB_ENCODETYPE_DATA_WRAP = 300, /* data */
  NETWIB_ENCODETYPE_HEXA0_WRAP,      /* hexa (32 bytes per line) */
  NETWIB_ENCODETYPE_HEXA1_WRAP,      /* hexa (16 bytes per line) */
  NETWIB_ENCODETYPE_HEXA2_WRAP,      /* hexa (32 bytes per line) */
  NETWIB_ENCODETYPE_HEXA4_WRAP,      /* hexa (32 bytes per line) */
  NETWIB_ENCODETYPE_MIXED0_WRAP,     /* mixed (16 bytes per line) */
  NETWIB_ENCODETYPE_MIXED1_WRAP,     /* mixed (16 bytes per line) */
  NETWIB_ENCODETYPE_TEXT_WRAP,       /* printable text */
  NETWIB_ENCODETYPE_BASE64_WRAP,     /* base64 */
  NETWIB_ENCODETYPE_ARRAY1 = 400,    /* array (4 bytes per line) */
  NETWIB_ENCODETYPE_ARRAY4,          /* array (4 bytes per line) */
  NETWIB_ENCODETYPE_ARRAY8,          /* array (4 bytes per line) */
  NETWIB_ENCODETYPE_ARRAY16,         /* array (4 bytes per line) */
  NETWIB_ENCODETYPE_ARRAY32,         /* array (4 bytes per line) */
  NETWIB_ENCODETYPE_DUMP,            /* dump (16 bytes per line) */
  NETWIB_ENCODETYPE_MIXED0H_WRAP,    /* mixed (8 bytes per line) */
  NETWIB_ENCODETYPE_MIXED1H_WRAP,    /* mixed (8 bytes per line) */
  NETWIB_ENCODETYPE_LOWERCASE,       /* lower case */
  NETWIB_ENCODETYPE_UPPERCASE,       /* upper case */
  /* aliases */
  NETWIB_ENCODETYPE_HEXA = NETWIB_ENCODETYPE_HEXA1,
  NETWIB_ENCODETYPE_MIXED = NETWIB_ENCODETYPE_MIXED1,
  NETWIB_ENCODETYPE_HEXA_WRAP = NETWIB_ENCODETYPE_HEXA1_WRAP,
  NETWIB_ENCODETYPE_MIXED_WRAP = NETWIB_ENCODETYPE_MIXED1_WRAP,
  NETWIB_ENCODETYPE_ARRAY = NETWIB_ENCODETYPE_ARRAY8,
  NETWIB_ENCODETYPE_MIXEDH_WRAP = NETWIB_ENCODETYPE_MIXED1H_WRAP,
  /* for transition */
  NETWIB_ENCODETYPE_TRANSITION_INIT = 500,
  NETWIB_ENCODETYPE_TRANSITION_END
} netwib_encodetype;
/*-------------------------------------------------------------*/
/* Examples :
NETWIB_ENCODETYPE_HEXA0  : 01020304050607080910...
NETWIB_ENCODETYPE_HEXA1  : 01 02 03 04 05 06 07 08 09 10 ...
NETWIB_ENCODETYPE_HEXA2  : 0102 0304 0506 0708 0910 ...
NETWIB_ENCODETYPE_HEXA4  : 01020304 05060708 0910...
NETWIB_ENCODETYPE_MIXED0 : 'abc' 112233445566
NETWIB_ENCODETYPE_MIXED1 : 'abc' 11 22 33 44 55 66
NETWIB_ENCODETYPE_HEXA0_WRAP :
0102030405060708091011121314151617181920212223242526272829303132
NETWIB_ENCODETYPE_HEXA1_WRAP :
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16
NETWIB_ENCODETYPE_HEXA2_WRAP :
0102 0304 0506 0708 0910 1112 1314 1516 1718 1920 2122 2324 2526 2728 2930 3132
NETWIB_ENCODETYPE_HEXA4_WRAP :
01020304 05060708 09101112 13141516 17181920 21222324 25262728 29303132
NETWIB_ENCODETYPE_MIXED0_WRAP :
NETWIB_ENCODETYPE_MIXED1_WRAP :
NETWIB_ENCODETYPE_ARRAY1 :
|1|0|0|0|0|1|1|0|0|1|0|0|0|1|1|0|1|1|0|0|0|1|1|0|0|0|1|0|0|1|1|0|
NETWIB_ENCODETYPE_ARRAY4 :
|__0x1__|__0x6__|_______________|_______________|_______________|
NETWIB_ENCODETYPE_ARRAY8 :
|____0x80=128___|____0x11=17____|____0x80=128___|____0x11=17____|
NETWIB_ENCODETYPE_ARRAY16 :
|_________0x6162=24930__________|_________0x6364=25444__________|
NETWIB_ENCODETYPE_ARRAY32 :
|_____________________0x61626364=1633837924_____________________|
NETWIB_ENCODETYPE_DUMP :
61 62 63 64  65 66 67 68  69 6a 6b 6c  6d 6e 6f 70  # abcdefghijklmnop
NETWIB_ENCODETYPE_MIXED0H_WRAP :
NETWIB_ENCODETYPE_MIXED1H_WRAP :
NETWIB_ENCODETYPE_QUOTED :
"abc d \\ \t \n \r \" \x00 z"
*/
/*-------------------------------------------------------------*/
/* Name : netwib_buf_encode
   Description :
     Append a encoded buffer.
   Input parameter(s) :
     *pbuftoencode : buffer to encode
     encodetype : decoding type
   Input/output parameter(s) :
     *pbuf : netwib_buf updated
   Output parameter(s) :
   Normal return values :
     NETWIB_ERR_OK : ok
   This function supports NETWIB_BUF_FLAGS_SENSITIVE.
*/
netwib_err netwib_buf_encode(netwib_constbuf *pbuftoencode,
                             netwib_encodetype encodetype,
                             netwib_buf *pbuf);
/* only the main ones are defined */
#define netwib_buf_encode_data(pbuftoencode,pbuf) netwib_buf_encode(pbuftoencode,NETWIB_ENCODETYPE_DATA,pbuf)
#define netwib_buf_encode_hexa(pbuftoencode,pbuf) netwib_buf_encode(pbuftoencode,NETWIB_ENCODETYPE_HEXA,pbuf)
#define netwib_buf_encode_mixed(pbuftoencode,pbuf) netwib_buf_encode(pbuftoencode,NETWIB_ENCODETYPE_MIXED,pbuf)
#define netwib_buf_encode_text(pbuftoencode,pbuf) netwib_buf_encode(pbuftoencode,NETWIB_ENCODETYPE_TEXT,pbuf)
#define netwib_buf_encode_base64(pbuftoencode,pbuf) netwib_buf_encode(pbuftoencode,NETWIB_ENCODETYPE_BASE64,pbuf)
#define netwib_buf_encode_quoted(pbuftoencode,pbuf) netwib_buf_encode(pbuftoencode,NETWIB_ENCODETYPE_QUOTED,pbuf)
#define netwib_buf_encode_dump(pbuftoencode,pbuf) netwib_buf_encode(pbuftoencode,NETWIB_ENCODETYPE_DUMP,pbuf)
#define netwib_buf_encode_lowercase(pbuftoencode,pbuf) netwib_buf_encode(pbuftoencode,NETWIB_ENCODETYPE_LOWERCASE,pbuf)
#define netwib_buf_encode_uppercase(pbuftoencode,pbuf) netwib_buf_encode(pbuftoencode,NETWIB_ENCODETYPE_UPPERCASE,pbuf)
/*-------------------------------------------------------------*/
typedef struct {
  netwib_encodetype last;
  netwib_bool containnl;
} netwib_encodetype_context;
/* Name : netwib_buf_encode_transition
   Description :
     Append a transition between two data.
     First call has to be done with NETWIB_ENCODETYPE_TRANSITION_INIT.
   Input parameter(s) :
     encodetype : next encoding type
   Input/output parameter(s) :
     *pctx : context
     *pbuf : netwib_buf updated
   Output parameter(s) :
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_buf_encode_transition(netwib_encodetype_context *pctx,
                                        netwib_encodetype encodetype,
                                        netwib_buf *pbuf);
#define netwib_buf_encode_transition_init(pctx) netwib_buf_encode_transition(pctx,NETWIB_ENCODETYPE_TRANSITION_INIT,NULL)
#define netwib_buf_encode_transition_end(pctx,pbuf) netwib_buf_encode_transition(pctx,NETWIB_ENCODETYPE_TRANSITION_END,pbuf)

MODULE BUFDEC
/*-------------------------------------------------------------*/
/***************************************************************
 * An hexadecimal string is for example:                       *
 *  010A 0b00Ff                                                *
 ***************************************************************/
/*-------------------------------------------------------------*/
/***************************************************************
 * A mixed string permits to represent data as a clear form    *
 * using hexadecimal and text.                                 *
 * Hexadecimal is used without "0x" or "0h"                    *
 * Text is included between apostrophes "'"                    *
 * The character ' is ''                                       *
 * For example :                                               *
 *   'hello' : data "hello"                                    *
 *   'a' 'b' : data "ab"                                       *
 *   41 'b'  : data "Ab" (because 'A'==0x41)                   *
 *   'man'00 : data "man" ending with 0x00                     *
 *   'a''b'  : data "a'b"                                      *
 * Real examples :                                             *
 *  'hello' 0D 0A 'this is after a newline'                    *
 *  'one' 09 'two' 0D 0A                                       *
 ***************************************************************/
/*-------------------------------------------------------------*/
typedef enum {
  NETWIB_DECODETYPE_DATA = 1,        /* exact data */
  NETWIB_DECODETYPE_HEXA,            /* hexadecimal */
  NETWIB_DECODETYPE_MIXED,           /* mixed */
  NETWIB_DECODETYPE_BASE64           /* base64 */
} netwib_decodetype;
/*-------------------------------------------------------------*/
/* Name : netwib_buf_decode
   Description :
     Append a decoded buffer.
   Input parameter(s) :
     *pbuftodecode : buffer to decode
     decodetype : decoding type
   Input/output parameter(s) :
     *pbuf : netwib_buf updated
   Output parameter(s) :
   Normal return values :
     NETWIB_ERR_OK : ok
   This function supports NETWIB_BUF_FLAGS_SENSITIVE.
*/
netwib_err netwib_buf_decode(netwib_constbuf *pbuftodecode,
                             netwib_decodetype decodetype,
                             netwib_buf *pbuf);
#define netwib_buf_decode_data(pbuftodecode,pbuf) netwib_buf_decode(pbuftodecode,NETWIB_DECODETYPE_DATA,pbuf)
#define netwib_buf_decode_hexa(pbuftodecode,pbuf) netwib_buf_decode(pbuftodecode,NETWIB_DECODETYPE_HEXA,pbuf)
#define netwib_buf_decode_mixed(pbuftodecode,pbuf) netwib_buf_decode(pbuftodecode,NETWIB_DECODETYPE_MIXED,pbuf)
#define netwib_buf_decode_base64(pbuftodecode,pbuf) netwib_buf_decode(pbuftodecode,NETWIB_DECODETYPE_BASE64,pbuf)
/*-------------------------------------------------------------*/
/***************************************************************
 * A quoted string is for example:                             *
 *   hello "hello" "hel\nlo" "abc d \\ \n \" \x00 z"           *
 * It is particularly adapted to decode program's parameters,  *
 * which can be enclosed, or not, between '"' character.       *
 * It is special :                                             *
 *  - decoding stops after first valid parameter               *
 *  - pbuftodecode is updated                                  *
 * Specifications:                                             *
 *   General :                                                 *
 *     Leading spaces or tabulations are ignored.              *
 *     Ending spaces, tabulations, NL or LF are ignored.       *
 *     Buffer pbuftodecode has beginoffset updated to point    *
 *     past the decoded string (after optional ending spaces). *
 *     When end is reached, without reading data, error        *
 *     NETWIB_ERR_DATAEND is returned.                         *
 *   Quoted strings (ex : "aa", "a\nb") :                      *
 *     Char '\' can be used before any char. It means the      *
 *     char following, except for sequences \a(alarm bell)     *
 *     \b(backspace) \t(tab) \n(NL) \r(LF) and                 *
 *     \x(hexa code of a character).                           *
 *     All chars, including NL and LF, are read till finding   *
 *     the last ". If it is not found, error                   *
 *     NETWIB_ERR_DATANOTAVAIL is returned (nothing is saved   *
 *     in pbuf).                                               *
 *   Unquoted strings (ex : aa, a\b)                           *
 *     Char '\' only means char '\'.                           *
 *     Read is stopped when a space, tab, NL or LF is found,   *
 *     or when end of pbuftodecode is reached.                 *
 ***************************************************************/
/*-------------------------------------------------------------*/
/* Name : netwib_buf_decode_quoted
   Description :
     Append a decoded buffer.
   Input parameter(s) :
     *pbuftodecode : buffer to decode
     decodetype : decoding type
   Input/output parameter(s) :
     *pbuf : netwib_buf updated
   Output parameter(s) :
   Normal return values :
     NETWIB_ERR_OK : ok
   This function supports NETWIB_BUF_FLAGS_SENSITIVE.
*/
netwib_err netwib_buf_decode_quoted(netwib_buf *pbuftodecode,
                                    netwib_buf *pbuf);

MODULE FMT
/*-------------------------------------------------------------*/
/* Name : netwib_buf_append_fmt
   Description :
     Add data to a buf.
   Input parameter(s) :
     fmt : format as explained below
   Input/output parameter(s) :
     *pbuf : netwib_buf updated
   Output parameter(s) :
   Normal return values :
     NETWIB_ERR_OK : ok
   This function supports NETWIB_BUF_FLAGS_SENSITIVE.
*/
/***************************************************************
 * Netwib provides a kind of printf format. It is not          *
 * compatible with standard printf, but it corresponds to      *
 * netwib usage.                                               *
 *   %% : %                                                    *
 *   %c : char                                                 *
 *   %s : string                                               *
 *   %p : pointer                                              *
 *   %{type} : special type                                    *
 *   %{generalformat;type:specificformat} : special type with  *
 *                                          a format           *
 *   %{generalformat;type} : special type with a format        *
 *   %{type:specificformat} : special type with a format       *
 * generalformat :                                             *
 *   - expressed as a regexp : "[lcr].[1-9][0-9]{0,1}"         *
 *       'lcr' : left, center, right                           *
 *       '.'   : padding character                             *
 *       '0-9' : minimum size                                  *
 *   - default value : "l 0"                                   *
 * type :                                                      *
 *   - uint32, uint16, uint8, uintmax, uintptr, uint64, byte   *
 *      - specificformat expressed as                          *
 *        "[#]{0,1}[0-9]{0,2}[bouxX]{0,1}"                     *
 *         '#' : add 'b' before binary numbers                 *
 *               add '0' before octal numbers                  *
 *               add '0x' before hexadecimal numbers           *
 *         '0-9' : total size (minimum value)                  *
 *         'bouxX' : binary, octal, decimal, hexadecimal       *
 *      - default value for specificformat : "u"               *
 *   - int32, int16, int8, intmax, intptr, int64               *
 *      - specificformat expressed as "[+]{0,1}[0-9]{0,2}"     *
 *         '+' : add a '+' before positive numbers             *
 *         '0-9' : total size (minimum value)                  *
 *      - default value for specificformat : ""                *
 *   - bool                                                    *
 *      - specificformat expressed as "[0tTyYsS]{0,1}"         *
 *         '0' : 0/1                                           *
 *         't' : true/false                                    *
 *         'T' : TRUE/FALSE                                    *
 *         'y' : yes/no                                        *
 *         'Y' : YES/NO                                        *
 *         's' : set/unset                                     *
 *         'S' : SET/UNSET                                     *
 *      - default value for specificformat : "t"               *
 *   - cmp                                                     *
 *      - specificformat expressed as "[=0e]{0,1}"             *
 *         '=' : <  =  >                                       *
 *         '0' : -  0  +                                       *
 *         'e' : lt eq gt                                      *
 *      - default value for specificformat : "="               *
 *   - c(char), s(char*), p(void*)                             *
 *      no specificformat                                      *
 *   - buf(netwib_buf*)                                        *
 *      no specificformat                                      *
 *   - eth(netwib_eth*), ip(netwib_ip*), port(netwib_port)     *
 *      no specificformat                                      *
 *   - eths(netwib_eths*), ips(netwib_ips*),                   *
 *     ports(netwib_ports*)                                    *
 *      no specificformat                                      *
 * examples :                                                  *
 *     %{uint32} : decimal                                     *
 *     %{int32} : decimal                                      *
 *     %{uint32:b} : binary                                    *
 *     %{uint32:o} : octal                                     *
 *     %{uint32:x} : hexadecimal                               *
 *     %{uint32:08X} : hexadecimal                             *
 *     %{c_20;uint32} : decimal centered in a 20 bytes block   *
 *                      padded with _                          *
 ***************************************************************/
netwib_err netwib_buf_append_fmt(netwib_buf *pbuf,
                                 netwib_conststring fmt,
                                 ...);
/*-------------------------------------------------------------*/
/* Name : netwib_buf_decode_fmt
   Description :
     Decode data from a buf.
   Input parameter(s) :
     *pbuf : netwib_buf
     fmt : format as explained above
   Input/output parameter(s) :
   Output parameter(s) :
     *pnumset : number of items set (decoded)
   Normal return values :
     NETWIB_ERR_OK : ok
     NETWIB_ERR_NOTCONVERTED : not decoded
   This function supports NETWIB_BUF_FLAGS_SENSITIVE.
*/
/***************************************************************
 * Netwib provides a kind of sscanf format. It is not          *
 * compatible with standard sscanf, but it corresponds to      *
 * netwib usage.                                               *
 *   %% : %                                                    *
 *   %c : char                                                 *
 *   %s : string                                               *
 *   %p : pointer                                              *
 *   %$ : end of string (if present, must be last)             *
 *   %{type} : special type                                    *
 *   %{generalformat;type:specificformat} : special type with  *
 *                                          a format           *
 *   %{generalformat;type} : special type with a format        *
 *   %{type:specificformat} : special type with a format       *
 * generalformat :                                             *
 *   - expressed as a regexp : "[*]{0,1}[lcr].[1-9][0-9]{0,1}" *
 *     or "[*]{0,1}"                                           *
 *       '*'   : suppresses assignment (skip field)            *
 *       'lcr' : left, center, right                           *
 *       '.'   : padding character                             *
 *       '0-9' : minimum size                                  *
 *   - default value : "l 0"                                   *
 * type :                                                      *
 *   They have the same meaning as for netwib_buf_append_fmt,  *
 *   but are always pointers :                                 *
 *   - uint32 : netwib_uint32*                                 *
 *   - uint16 : netwib_uint16*                                 *
 *   - uint8  : netwib_uint8*                                  *
 *   - uintmax: netwib_uintmax*                                *
 *   - uintptr: netwib_uintptr*                                *
 *   - uint64 : netwib_uint64*                                 *
 *   - byte   : netwib_byte*                                   *
 *   - bool   : netwib_bool*                                   *
 *   - int32  : netwib_int32*                                  *
 *   - int16  : netwib_int16*                                  *
 *   - int8   : netwib_int8*                                   *
 *   - cmp    : netwib_cmp*                                    *
 *   - c      : char*                                          *
 *   - s      : char[] (must be big enough : use buf instead)  *
 *   - p      : netwib_ptr* (or void**)                        *
 *   - buf    : netwib_buf*                                    *
 *   - eth    : netwib_eth*                                    *
 *   - ip     : netwib_ip*                                     *
 *   - port   : netwib_port*                                   *
 *   - eths   : netwib_eths*                                   *
 *   - ips    : netwib_ips*                                    *
 *   - ports  : netwib_ports*                                  *
 * specificformat :                                            *
 *   For "s" and "buf", the default behavior is to stop when a *
 *   space is encountered. By using "glob" as specificformat,  *
 *   every char is stored in the buffer (including leading and *
 *   ending spaces).                                           *
 ***************************************************************/
netwib_err netwib_buf_decode_fmt(netwib_constbuf *pbuf,
                                 netwib_conststring fmt,
                                 ...);

MODULE CHECKSUM
/*-------------------------------------------------------------*/
/* Name : netwib_checksum_buf
   Description :
     Compute the checksum of a buffer.
   Input parameter(s) :
     *pbuf : buffer input data
   Input/output parameter(s) :
   Output parameter(s) :
     *pchecksum : checksum of data stored in *pbuf.
                  Note : this checksum is in host byte order
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_checksum_buf(netwib_constbuf *pbuf,
                               netwib_uint16 *pchecksum);
/*-------------------------------------------------------------*/
netwib_err netwib_checksum_init(netwib_uint32 *ptmpchecksum);
netwib_err netwib_checksum_update_buf(netwib_constbuf *pbuf,
                                      netwib_uint32 *ptmpchecksum);
netwib_err netwib_checksum_update_data(netwib_constdata data,
                                       netwib_uint32 datasize,
                                       netwib_uint32 *ptmpchecksum);
netwib_err netwib_checksum_close(netwib_uint32 tmpchecksum,
                                 netwib_uint16 *pchecksum);

MODULE REGEXP
/*-------------------------------------------------------------*/
/***************************************************************
 * Do a "man regexp" if you don't know what is a "regular      *
 * expression").                                               *
 ***************************************************************/
/*-------------------------------------------------------------*/
/* Name : netwib_buf_search_re
   Description :
     Search a regular expression in a string.
   Input parameter(s) :
     *pbuf : buffer containing input data
     regularexpression : searched regular expression.
                         For example : "a.", "f[A-Z]", etc.
     casesensitive : NETWIB_TRUE if the search has to be case
                     sensitive
   Input/output parameter(s) :
   Output parameter(s) :
     *pfound : buffer set with found data
   Normal return values :
     NETWIB_ERR_OK : the searched element was found
     NETWIB_ERR_NOTFOUND : the searched element wasn't found
   This function supports NETWIB_BUF_FLAGS_SENSITIVE.
*/
netwib_err netwib_buf_search_re(netwib_constbuf *pbuf,
                                netwib_constbuf *pregularexpression,
                                netwib_bool casesensitive,
                                netwib_bufext *pfound);
/*-------------------------------------------------------------*/
/***************************************************************
 * A netwib_regexp contains an array of found data during a    *
 * a regular expression search.                                *
 * The element at index 0 defines the location of the          *
 * global expression.                                          *
 * Elements at index 1, 2, etc. define the found string        *
 * between '(' and ')'.                                        *
 *                                                             *
 * For example, if the data is "houses" and the regular        *
 * expression is "o(.(s))", then :                             *
 *   re.numset = 3                                             *
 *   re.array[0] = "ous"                                       *
 *   re.array[1] = "us"                                        *
 *   re.array[2] = "s"                                         *
 *   re.array[3..63] not initialized                           *
 ***************************************************************/
/*-------------------------------------------------------------*/
/* We cannot have more than 64 parenthesis. This should be
   sufficient in all cases, but you may want to increase it,
   and recompile netwib.
 */
#define NETWIB_REGEXP_MAXLEN 64
typedef struct {
  netwib_uint32 numset; /* number of buffers set */
  netwib_bufext array[NETWIB_REGEXP_MAXLEN];
} netwib_regexp;
/*-------------------------------------------------------------*/
/* Name : netwib_buf_search_regexp
   Description :
     Search a regular expression in a string.
   Input parameter(s) :
     *pbuf : buffer containing input data
     regularexpression : searched regular expression.
                         For example : "a.", "f[A-Z]", etc.
     casesensitive : NETWIB_TRUE if the search has to be case
                     sensitive
   Input/output parameter(s) :
   Output parameter(s) :
     *pfound : netwib_regexp containing the found data
   Normal return values :
     NETWIB_ERR_OK : the searched regular expression was found
     NETWIB_ERR_NOTFOUND : the searched regexp wasn't found
   This function supports NETWIB_BUF_FLAGS_SENSITIVE.
*/
netwib_err netwib_buf_search_regexp(netwib_constbuf *pbuf,
                                    netwib_constbuf *pregularexpression,
                                    netwib_bool casesensitive,
                                    netwib_regexp *pfound);

MODULE RING
/*-------------------------------------------------------------*/
/***************************************************************
 * A netwib_ring is a double linked ring containing pointers.  *
 * For example, a ring containing 3 items looks like this :    *
 *                                                             *
 * ,________________________________________________________.  *
 * | ,----------------------------------------------------. |  *
 * | |  ._______.   .________.   .________.   .________.  | |  *
 * | `->|       |-->|        |-->|        |-->|        |--' |  *
 * |    | start |   |  ptr1  |   |  ptr2  |   |  ptr3  |    |  *
 * `----|_______|<--|________|<--|________|<--|________|<---'  *
 *                                                             *
 * The ring contains pointers (ptr1, ptr2 and ptr3 in the      *
 * example).                                                   *
 *                                                             *
 * When an item is removed from the ring, its associated       *
 * information stored in the pointer can be :                  *
 *  - left untouched : user will have to free the pointer and  *
 *    its information                                          *
 *  - erased : the information is lost : a function of type    *
 *    netwib_ring_erase_pf has to be called                    *
 * For example, a user might want to store allocated memory    *
 * containing a netwib_buf. Then when the ring is closed, the  *
 * netwib_buf_close function has to be called and the memory   *
 * has to be freed.                                            *
 ***************************************************************/
/*-------------------------------------------------------------*/
typedef struct netwib_ring netwib_ring;
typedef const netwib_ring netwib_constring;
/*-------------------------------------------------------------*/
/* This prototype defines a function erasing the item pitem */
typedef netwib_err (*netwib_ring_erase_pf)(netwib_ptr pitem);
/* This prototype defines a function duplicating an item */
typedef netwib_err (*netwib_ring_duplicate_pf)(netwib_constptr pitem,
                                               netwib_ptr *pdupofitem);
/* This prototype defines a function comparing two items
    - if iteminf<itemsup, *pcmp is set to NETWIB_CMP_LT
    - if iteminf>itemsup, *pcmp is set to NETWIB_CMP_GT
    - if iteminf==itemsup, *pcmp is set to NETWIB_CMP_EQ
   The parameter pinfos will be set with optional information
   given when calling the function.
 */
typedef netwib_err (*netwib_ring_compare_pf)(netwib_constptr piteminf,
                                             netwib_constptr pitemsup,
                                             netwib_ptr pinfos,
                                             netwib_cmp *pcmp);
/* This prototype defines a function detecting if an item
   matches a criteria
    - if it matches, *pbool is set to NETWIB_TRUE
    - if it does not matches, *pbool is set to NETWIB_FALSE
   The parameter pinfos will be set with optional information
   given when calling the function.
 */
typedef netwib_err (*netwib_ring_criteria_pf)(netwib_constptr pitem,
                                              netwib_ptr pinfos,
                                              netwib_bool *pbool);
/*-------------------------------------------------------------*/
/* Name : netwib_ring_init
   Description :
     Initialize a netwib_ring.
   Input parameter(s) :
     *pfunc_erase : function needed to erase items
                    This can be NULL
     *pfunc_duplicate : function needed to duplicate items
                        This can be NULL
   Input/output parameter(s) :
   Output parameter(s) :
     **ppring : netwib_ring allocated and initialized
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_ring_init(netwib_ring_erase_pf pfunc_erase,
                            netwib_ring_duplicate_pf pfunc_duplicate,
                            netwib_ring **ppring);
/*-------------------------------------------------------------*/
/* Name : netwib_ring_close
   Description :
     Destroy a netwib_ring.
   Input parameter(s) :
     eraseitems : if true, function pfunc_erase (set in
                  netwib_ring_init) is called
   Input/output parameter(s) :
     **ppring : netwib_ring to destroy
   Output parameter(s) :
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_ring_close(netwib_ring **ppring,
                             netwib_bool eraseitems);
/*-------------------------------------------------------------*/
/* Types to control a netwib_ring */
typedef enum {
  NETWIB_RING_CTLTYPE_COUNT = 1   /* count number of items */
} netwib_ring_ctltype;
netwib_err netwib_ring_ctl_set(netwib_ring *pring,
                               netwib_ring_ctltype type,
                               netwib_ptr p,
                               netwib_uint32 ui);
netwib_err netwib_ring_ctl_get(netwib_ring *pring,
                               netwib_ring_ctltype type,
                               netwib_ptr p,
                               netwib_uint32 *pui);
/*-------------------------------------------------------------*/
/* netwib_err f(netwib_ring *pring, netwib_uint32 *pnumberofitems); */
#define netwib_ring_ctl_get_count(pring,pnumberofitems) netwib_ring_ctl_get(pring,NETWIB_RING_CTLTYPE_COUNT,NULL,pnumberofitems)
/*-------------------------------------------------------------*/
/* Name : netwib_ring_add_first
   Description :
     Add an item to the netwib_ring.
   Input parameter(s) :
     pitem : pointer to an allocated memory containing the item
   Input/output parameter(s) :
     *pring : netwib_ring where to work
   Output parameter(s) :
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_ring_add_first(netwib_ring *pring,
                                 netwib_constptr pitem);
netwib_err netwib_ring_add_last(netwib_ring *pring,
                                netwib_constptr pitem);
/*-------------------------------------------------------------*/
/* Name : netwib_ring_del_criteria
   Description :
     Del items matching a criterion.
   Input parameter(s) :
     pfunc_criteria : function used to decide to del an item
                      If this function is NULL, no criterion is
                      applied.
   Input/output parameter(s) :
     *pring : netwib_ring where to work
     pinfos : optional parameter (can be NULL) which will be
              used as the parameter for pfunc_criteria.
              This may be used to send information to *pfunc_criteria.
   Output parameter(s) :
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_ring_del_criteria(netwib_ring *pring,
                                    netwib_ring_criteria_pf pfunc_criteria,
                                    netwib_ptr pinfos,
                                    netwib_bool eraseitems);
#define netwib_ring_del_all(pring,eraseitems) netwib_ring_del_criteria(pring,NULL,NULL,eraseitems)
/*-------------------------------------------------------------*/
/* Name : netwib_ring_del_duplicate
   Description :
     Del duplicate items from a netwib_ring.
   Input parameter(s) :
     pfunc_compare : function used to compare two items
   Input/output parameter(s) :
     *pring : netwib_ring where to work
     pinfos : optional parameter (can be NULL) which will be
              used as the parameter for pfunc_compare.
              This may be used to send information to *pfunc_compare.
   Output parameter(s) :
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_ring_del_duplicate(netwib_ring *pring,
                                     netwib_ring_compare_pf pfunc_compare,
                                     netwib_ptr pinfos,
                                     netwib_bool eraseitems);
/*-------------------------------------------------------------*/
/* Name : netwib_ring_sort
   Description :
     Sort items of the netwib_ring.
   Input parameter(s) :
     pfunc_compare : function used to compare two items
   Input/output parameter(s) :
     *pring : netwib_ring where to work
     pinfos : optional parameter (can be NULL) which will be
              used as the parameter for *pfunc_compare.
              This may be used to send information to *pfunc_compare.
   Output parameter(s) :
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_ring_sort(netwib_ring *pring,
                            netwib_ring_compare_pf pfunc_compare,
                            netwib_ptr pinfos);
/*-------------------------------------------------------------*/
/* Name : netwib_ring_group
   Description :
     Group items of the netwib_ring.
   Input parameter(s) :
     pfunc_compare : function used to compare two items
   Input/output parameter(s) :
     *pring : netwib_ring where to work
     pinfos : optional parameter (can be NULL) which will be
              used as the parameter for *pfunc_compare.
              This may be used to send information to *pfunc_compare.
   Output parameter(s) :
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_ring_group(netwib_ring *pring,
                             netwib_ring_compare_pf pfunc_compare,
                             netwib_ptr pinfos);

MODULE RINGI
/*-------------------------------------------------------------*/
/***************************************************************
 * A netwib_ring_index is used to loop through a ring.         *
 *                                                             *
 * When the ring is only read, several indexes                 *
 * can simultaneously loop through the ring.                   *
 *                                                             *
 * However, when the ring is edited, strange behavior can      *
 * occur when a netwib_ring_index_xyz function is called,      *
 * depending on function used to edit the ring:                *
 *  - netwib_ring_index_next,                                  *
 *    netwib_ring_index_previous,                              *
 *    netwib_ring_index_this_value,                            *
 *    netwib_ring_index_this_replace,                          *
 *    netwib_ring_index_this_del:                              *
 *      No problem.                                            *
 *  - netwib_ring_index_add_before,                            *
 *    netwib_ring_index_add_after,                             *
 *    netwib_ring_add_first,                                   *
 *    netwib_ring_add_last,                                    *
 *    netwib_ring_index_add_ring_xyz:                          *
 *      The added item(s) may be returned or not returned,     *
 *      depending on the insertion position relative to the    *
 *      index position.                                        *
 *  - netwib_ring_sort,                                        *
 *    netwib_ring_group:                                       *
 *      The reordered items may be returned twice or never     *
 *      returned. There is no way to know.                     *
 *  - netwib_ring_del_criteria,                                *
 *    netwib_ring_del_duplicate:                               *
 *      You should not use them because if the item pointed by *
 *      the index is deleted, it will cause an access to freed *
 *      memory. You may use them only if you are sure to not   *
 *      delete the current item.                               *
 *      However, after netwib_ring_index_this_del, you must    *
 *      not use them because there is not way to know if they  *
 *      will delete internal items.                            *
 ***************************************************************/
/*-------------------------------------------------------------*/
typedef struct netwib_ring_index netwib_ring_index;
/*-------------------------------------------------------------*/
/* Name : netwib_ring_index_init
   Description :
     Initialize a netwib_ring_index used to loop through
     a netwib_ring.
   Input parameter(s) :
   Input/output parameter(s) :
   Output parameter(s) :
     **ppringindex : netwib_ring_index allocated and initialized
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_ring_index_init(netwib_constring *pring,
                                  netwib_ring_index **ppringindex);
/*-------------------------------------------------------------*/
/* Name : netwib_ring_index_close
   Description :
     Close a netwib_ringindex.
   Input parameter(s) :
   Input/output parameter(s) :
     **ppringindex : netwib_ring_index closed
   Output parameter(s) :
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_ring_index_close(netwib_ring_index **ppringindex);
/*-------------------------------------------------------------*/
/* Types to control a netwib_ring_index */
typedef enum {
  NETWIB_RING_INDEX_CTLTYPE_REWIND = 1,  /* position at beginning */
  NETWIB_RING_INDEX_CTLTYPE_INDEX        /* reset with index pos */
} netwib_ring_index_ctltype;
/* Those functions permit to set/get parameters (pointer and
   integer) about a netwib_ring_index. It should not be used directly,
   but by the defines.
*/
netwib_err netwib_ring_index_ctl_set(netwib_ring_index *pringindex,
                                     netwib_ring_index_ctltype type,
                                     netwib_ptr p,
                                     netwib_uint32 ui);
netwib_err netwib_ring_index_ctl_get(netwib_ring_index *pringindex,
                                     netwib_ring_index_ctltype type,
                                     netwib_ptr p,
                                     netwib_uint32 *pui);
/*-------------------------------------------------------------*/
/* netwib_err f(netwib_ring_index *pringindex); */
#define netwib_ring_index_ctl_set_rewind(pringindex) netwib_ring_index_ctl_set(pringindex,NETWIB_RING_INDEX_CTLTYPE_REWIND,NULL,0)
/* netwib_err f(netwib_ring_index *pringindex,netwib_ring_index *pringindexref);*/
#define netwib_ring_index_ctl_set_index(pringindex,pringindexref) netwib_ring_index_ctl_set(pringindex,NETWIB_RING_INDEX_CTLTYPE_INDEX,pringindexref,0)
/*-------------------------------------------------------------*/
/* Name : netwib_ring_index_next_criteria
   Description :
     Get the next item in the ring.
   Input parameter(s) :
     pfunc_criteria : function used to decide to remove an item
                      If this function is NULL, no criterion is
                      applied.
   Input/output parameter(s) :
     *pringindex : netwib_ring_index
     pinfos : optional parameter (can be NULL) which will be
              used as the parameter for pfunc_criteria.
              This may be used to send information to *pfunc_criteria.
   Output parameter(s) :
     *ppitem : pointer to the memory containing the item
   Normal return values :
     NETWIB_ERR_OK : ok
     NETWIB_ERR_DATAEND : end of the ring reached
*/
netwib_err netwib_ring_index_next_criteria(netwib_ring_index *pringindex,
                                           netwib_ring_criteria_pf pfunc_criteria,
                                           netwib_ptr pinfos,
                                           netwib_ptr *ppitem);
#define netwib_ring_index_next(pringindex,ppitem) netwib_ring_index_next_criteria(pringindex,NULL, NULL,ppitem)
netwib_err netwib_ring_index_previous_criteria(netwib_ring_index *pringindex,
                                               netwib_ring_criteria_pf pfunc_criteria,
                                               netwib_ptr pinfos,
                                               netwib_ptr *ppitem);
#define netwib_ring_index_previous(pringindex,ppitem) netwib_ring_index_previous_criteria(pringindex,NULL, NULL,ppitem)
/*-------------------------------------------------------------*/
/* Name : netwib_ring_index_add_before
   Description :
     Add an item in the ring.
   Input parameter(s) :
   Input/output parameter(s) :
     *pringindex : netwib_ring_index
   Output parameter(s) :
     *ppitem : pointer to the memory containing the item
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_ring_index_add_before(netwib_ring_index *pringindex,
                                        netwib_constptr pitem);
netwib_err netwib_ring_index_add_after(netwib_ring_index *pringindex,
                                       netwib_constptr pitem);
/*-------------------------------------------------------------*/
/* Name : netwib_ring_index_this_value
   Description :
     Re-give the last value.
   Input parameter(s) :
   Input/output parameter(s) :
     *pringindex : netwib_ring_index
   Output parameter(s) :
     *ppitem : pointer to the memory containing the item
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_ring_index_this_value(netwib_ring_index *pringindex,
                                        netwib_ptr *ppitem);
/*-------------------------------------------------------------*/
/* Name : netwib_ring_index_this_del
   Description :
     Delete the last given value by a netwib_ring_index_next
     function.
   Input parameter(s) :
     eraseitem : if true, function pfunc_erase (set in
                 netwib_hash_init) is called to erase the
                 item located at position
   Input/output parameter(s) :
     *pringindex : netwib_ring_index
   Output parameter(s) :
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_ring_index_this_del(netwib_ring_index *pringindex,
                                      netwib_bool eraseitem);
/*-------------------------------------------------------------*/
/* Name : netwib_ring_index_this_replace
   Description :
     Replace value, but keep the same key.
   Input parameter(s) :
     pitem : pointer to an allocated memory containing the item
     erasepreviousitem : if true, function pfunc_erase (set in
                         netwib_ring_init) is called to erase the
                         item previously located in the ring
   Input/output parameter(s) :
     *pringindex : netwib_ring_index
   Output parameter(s) :
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_ring_index_this_replace(netwib_ring_index *pringindex,
                                          netwib_constptr pitem,
                                          netwib_bool erasepreviousitem);
/*-------------------------------------------------------------*/
/* Name : netwib_ring_index_add_ring_criteria
   Description :
     Add a ring within another ring. Only items matching a
     criterion are added.
   Input parameter(s) :
     *pringindex : ring is added after this index
     *pringtoadd : netwib_ring to add in pring
     pfunc_criteria : function used to decide to add an item
                      If this function is NULL, no criterion is
                      applied.
     duplicateitems : if true, function pfunc_duplicate (set in
                      netwib_ring_init) is called to duplicate
                      items
   Input/output parameter(s) :
     *pring : netwib_ring where to work
     pinfos : optional parameter (can be NULL) which will be
              used as the parameter for pfunc_criteria.
              This may be used to send information to *pfunc_criteria.
   Output parameter(s) :
   Normal return values :
     NETWIB_ERR_OK : ok
   Note :
     If an error occurs during addition, ring will only
     contain partial data.
*/
netwib_err netwib_ring_index_add_ring_criteria(netwib_ring_index *pringindex,
                                               netwib_ring *pringtoadd,
                                               netwib_ring_criteria_pf pfunc_criteria,
                                               netwib_ptr pinfos,
                                               netwib_bool duplicateitems);
#define netwib_ring_index_add_ring_all(pringindex,pringtoadd,duplicateitems) netwib_ring_index_add_ring_criteria(pringindex,pringtoadd,NULL,NULL,duplicateitems)

MODULE HASH
/*-------------------------------------------------------------*/
/***************************************************************
 * A netwib_hash is an associative array : data is related to  *
 * a key. It's not possible to have two identical keys.        *
 *                                                             *
 * The hash contains pointers.                                 *
 *                                                             *
 * When an item is removed from the hash, its associated       *
 * information stored in the pointer can be :                  *
 *  - left untouched : user will have to free the pointer and  *
 *    its information                                          *
 *  - erased : the information is lost : a function of type    *
 *    netwib_hash_erase_pf has to be called                    *
 * For example, a user might want to store allocated memory    *
 * containing a netwib_buf. Then when the hash is closed, the  *
 * netwib_buf_close function has to be called and the memory   *
 * has to be freed.                                            *
 ***************************************************************/
/*-------------------------------------------------------------*/
typedef struct netwib_hash netwib_hash;
typedef const netwib_hash netwib_consthash;
/*-------------------------------------------------------------*/
/* This prototype defines a function erasing the item pitem */
typedef netwib_err (*netwib_hash_erase_pf)(netwib_ptr pitem);
/* This prototype defines a function duplicating an item */
typedef netwib_err (*netwib_hash_duplicate_pf)(netwib_constptr pitem,
                                               netwib_ptr *pdupofitem);
/* This prototype defines a function detecting if an item
   matches a criteria
    - if it matches, *pbool is set to NETWIB_TRUE
    - if it does not matches, *pbool is set to NETWIB_FALSE
   The parameter pinfos will be set with optional information
   given when calling the function.
 */
typedef netwib_err (*netwib_hash_criteria_pf)(netwib_constbuf *pkey,
                                              netwib_constptr pitem,
                                              netwib_ptr pinfos,
                                              netwib_bool *pbool);
/*-------------------------------------------------------------*/
/* Name : netwib_hash_init
   Description :
     Initialize a netwib_hash.
   Input parameter(s) :
     *pfunc_erase : function needed to erase items
                    This can be NULL
     *pfunc_duplicate : function needed to duplicate items
                        This can be NULL
   Input/output parameter(s) :
   Output parameter(s) :
     **pphash : netwib_hash allocated and initialized
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_hash_init(netwib_hash_erase_pf pfunc_erase,
                            netwib_hash_duplicate_pf pfunc_duplicate,
                            netwib_hash **pphash);
/*-------------------------------------------------------------*/
/* Name : netwib_hash_close
   Description :
     Destroy a netwib_hash.
   Input parameter(s) :
     eraseitems : if true, function pfunc_erase (set in
                  netwib_hash_init) is called
   Input/output parameter(s) :
     **pphash : netwib_hash to destroy
   Output parameter(s) :
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_hash_close(netwib_hash **pphash,
                             netwib_bool eraseitems);
/*-------------------------------------------------------------*/
/* Types to control a netwib_hash */
typedef enum {
  NETWIB_HASH_CTLTYPE_COUNT = 1   /* count number of items */
} netwib_hash_ctltype;
netwib_err netwib_hash_ctl_set(netwib_hash *phash,
                               netwib_hash_ctltype type,
                               netwib_ptr p,
                               netwib_uint32 ui);
netwib_err netwib_hash_ctl_get(netwib_hash *phash,
                               netwib_hash_ctltype type,
                               netwib_ptr p,
                               netwib_uint32 *pui);
/*-------------------------------------------------------------*/
/* netwib_err f(netwib_hash *phash, netwib_uint32 *pnumberofitems); */
#define netwib_hash_ctl_get_count(phash,pnumberofitems) netwib_hash_ctl_get(phash,NETWIB_HASH_CTLTYPE_COUNT,NULL,pnumberofitems)
/*-------------------------------------------------------------*/
/* Name : netwib_hash_add
   Description :
     Add an item to the netwib_hash. Is the key already exists,
     it is overwritten.
   Input parameter(s) :
     *pkey : key to store
     pitem : pointer to an allocated memory containing the item
     erasepreviousitem : if true, function pfunc_erase (set in
                         netwib_hash_init) is called to erase the
                         item previously located in the hash
   Input/output parameter(s) :
     *phash : netwib_hash where to work
   Output parameter(s) :
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_hash_add(netwib_hash *phash,
                           netwib_constbuf *pkey,
                           netwib_constptr pitem,
                           netwib_bool erasepreviousitem);
/*-------------------------------------------------------------*/
/* Name : netwib_hash_add_hash_criteria
   Description :
     Add a hash into the netwib_hash. Existing keys
     are overwritten.
   Input parameter(s) :
     pfunc_criteria : function used to decide to add an item
                      If this function is NULL, no criterion is
                      applied.
     erasepreviousitems : if true, function pfunc_erase (set in
                          netwib_hash_init) is called to erase the
                          items previously located in the hash
   Input/output parameter(s) :
     *phash : netwib_hash where to work
     *phashtoadd : netwib_hash to add
     pinfos : optional parameter (can be NULL) which will be
              used as the parameter for pfunc_criteria.
              This may be used to send information to *pfunc_criteria.
   Output parameter(s) :
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_hash_add_hash_criteria(netwib_hash *phash,
                                         netwib_hash *phashtoadd,
                                         netwib_hash_criteria_pf pfunc_criteria,
                                         netwib_ptr pinfos,
                                         netwib_bool erasepreviousitems);
#define netwib_hash_add_hash_all(phash,phashtoadd,erasepreviousitems) netwib_hash_add_hash_criteria(phash,phashtoadd,NULL,NULL,erasepreviousitems)
/*-------------------------------------------------------------*/
/* Name : netwib_hash_contains
   Description :
     Check if a key is in the hash.
   Input parameter(s) :
     *phash : netwib_hash where to work
     *pkey : key to obtain
   Input/output parameter(s) :
   Output parameter(s) :
     *pyes : true if key is found
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_hash_contains(netwib_hash *phash,
                                netwib_constbuf *pkey,
                                netwib_bool *pyes);
/*-------------------------------------------------------------*/
/* Name : netwib_hash_value
   Description :
     Get the value of an item.
   Input parameter(s) :
     *phash : netwib_hash where to work
     *pkey : key to obtain
   Input/output parameter(s) :
   Output parameter(s) :
     *ppitem : pointer to the memory containing the item
   Normal return values :
     NETWIB_ERR_OK : ok
     NETWIB_ERR_NOTFOUND : key not found
*/
netwib_err netwib_hash_value(netwib_hash *phash,
                             netwib_constbuf *pkey,
                             netwib_ptr *ppitem);
/*-------------------------------------------------------------*/
/* Name : netwib_hash_del
   Description :
     Remove an item from the netwib_hash.
   Input parameter(s) :
     *pkey : key to del
     eraseitem : if true, function pfunc_erase (set in
                 netwib_hash_init) is called to erase the
                 item located at position
   Input/output parameter(s) :
     *phash : netwib_hash where to work
   Output parameter(s) :
   Normal return values :
     NETWIB_ERR_OK : ok
     NETWIB_ERR_NOTFOUND : key not found
*/
netwib_err netwib_hash_del(netwib_hash *phash,
                           netwib_constbuf *pkey,
                           netwib_bool eraseitem);
/*-------------------------------------------------------------*/
/* Name : netwib_hash_del_criteria
   Description :
     Del items matching a criterion.
   Input parameter(s) :
     pfunc_criteria : function used to decide to del an item
                      If this function is NULL, no criterion is
                      applied.
   Input/output parameter(s) :
     *phash : netwib_hash where to work
     pinfos : optional parameter (can be NULL) which will be
              used as the parameter for pfunc_criteria.
              This may be used to send information to *pfunc_criteria.
   Output parameter(s) :
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_hash_del_criteria(netwib_hash *phash,
                                    netwib_hash_criteria_pf pfunc_criteria,
                                    netwib_ptr pinfos,
                                    netwib_bool eraseitems);
#define netwib_hash_del_all(phash,eraseitems) netwib_hash_del_criteria(phash,NULL,NULL,eraseitems)

MODULE HASHI
/*-------------------------------------------------------------*/
/***************************************************************
 * A netwib_hash_index is used to loop through a hash.         *
 *                                                             *
 * When the hash is only read, several indexes                 *
 * can simultaneously loop through the hash.                   *
 *                                                             *
 * However, when the hash is edited, strange behavior can      *
 * occur when a netwib_hash_index_xyz function is called,      *
 * depending on function used to edit the hash:                *
 *  - netwib_hash_contains,                                    *
 *    netwib_hash_value,                                       *
 *    netwib_hash_index_next                                   *
 *    netwib_hash_index_this_value,                            *
 *    netwib_hash_index_this_replace,                          *
 *    netwib_hash_index_this_del:                              *
 *      No problem.                                            *
 *  - netwib_hash_add,                                         *
 *    netwib_hash_add_hash_criteria:                           *
 *      The added item(s) may be returned or not returned,     *
 *      depending on the (unpredictable) insertion position    *
 *      relative to the index position.                        *
 *  - netwib_hash_del,                                         *
 *    netwib_hash_del_criteria:                                *
 *      You should not use them because if the item pointed by *
 *      the index is deleted, it will cause an access to freed *
 *      memory. You may use them only if you are sure to not   *
 *      delete the current item.                               *
 *      However, after netwib_hash_index_this_del, you must    *
 *      not use them because there is not way to know if they  *
 *      will delete internal items.                            *
 ***************************************************************/
/*-------------------------------------------------------------*/
typedef struct netwib_hash_index netwib_hash_index;
/*-------------------------------------------------------------*/
/* Name : netwib_hash_index_init
   Description :
     Initialize a netwib_hash_index used to loop through
     a netwib_hash.
   Input parameter(s) :
   Input/output parameter(s) :
   Output parameter(s) :
     **pphashindex : netwib_hash_index allocated and initialized
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_hash_index_init(netwib_consthash *phash,
                                  netwib_hash_index **pphashindex);
/*-------------------------------------------------------------*/
/* Name : netwib_hash_index_close
   Description :
     Close a netwib_hashindex.
   Input parameter(s) :
   Input/output parameter(s) :
     **pphashindex : netwib_hash_index closed
   Output parameter(s) :
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_hash_index_close(netwib_hash_index **pphashindex);
/*-------------------------------------------------------------*/
/* Types to control a netwib_hash_index */
typedef enum {
  NETWIB_HASH_INDEX_CTLTYPE_REWIND = 1,  /* position at beginning */
  NETWIB_HASH_INDEX_CTLTYPE_INDEX        /* reset with index pos */
} netwib_hash_index_ctltype;
/* Those functions permit to set/get parameters (pointer and
   integer) about a netwib_hash_index. It should not be used directly,
   but by the defines.
*/
netwib_err netwib_hash_index_ctl_set(netwib_hash_index *phashindex,
                                     netwib_hash_index_ctltype type,
                                     netwib_ptr p,
                                     netwib_uint32 ui);
netwib_err netwib_hash_index_ctl_get(netwib_hash_index *phashindex,
                                     netwib_hash_index_ctltype type,
                                     netwib_ptr p,
                                     netwib_uint32 *pui);
/*-------------------------------------------------------------*/
/* netwib_err f(netwib_hash_index *phashindex); */
#define netwib_hash_index_ctl_set_rewind(phashindex) netwib_hash_index_ctl_set(phashindex,NETWIB_HASH_INDEX_CTLTYPE_REWIND,NULL,0)
/* netwib_err f(netwib_hash_index *phashindex,netwib_hash_index *phashindexref);*/
#define netwib_hash_index_ctl_set_index(phashindex,phashindexref) netwib_hash_index_ctl_set(phashindex,NETWIB_HASH_INDEX_CTLTYPE_INDEX,phashindexref,0)
/*-------------------------------------------------------------*/
/* Name : netwib_hash_index_next_criteria
   Description :
     Get the next item in the hash.
   Input parameter(s) :
     pfunc_search : function used to match the item
   Input/output parameter(s) :
     *phashindex : netwib_hash_index
     pinfos : optional parameter (can be NULL) which will be
              used as the second parameter for *pfunc_search.
              This may be used to send information to *pfunc_search.
   Output parameter(s) :
     *pkey : found key
     *ppitem : found item
   Normal return values :
     NETWIB_ERR_OK : ok
     NETWIB_ERR_DATAEND : end of the hash reached
*/
netwib_err netwib_hash_index_next_criteria(netwib_hash_index *phashindex,
                                           netwib_hash_criteria_pf pfunc_search,
                                           netwib_ptr pinfos,
                                           netwib_buf *pkey,
                                           netwib_ptr *ppitem);
#define netwib_hash_index_next(phashindex,pkey,ppitem) netwib_hash_index_next_criteria(phashindex,NULL,NULL,pkey,ppitem)
/*-------------------------------------------------------------*/
/* Name : netwib_hash_index_this_value
   Description :
     Re-give the last value.
   Input parameter(s) :
   Input/output parameter(s) :
     *phashindex : netwib_hash_index
   Output parameter(s) :
     *pkey : found key
     *ppitem : found item
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_hash_index_this_value(netwib_hash_index *phashindex,
                                        netwib_buf *pkey,
                                        netwib_ptr *ppitem);
/*-------------------------------------------------------------*/
/* Name : netwib_hash_index_this_del
   Description :
     Delete the last given value by a netwib_hash_index_next
     function.
   Input parameter(s) :
     eraseitem : if true, function pfunc_erase (set in
                 netwib_hash_init) is called to erase the
                 item located at position
   Input/output parameter(s) :
     *phashindex : netwib_hash_index
   Output parameter(s) :
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_hash_index_this_del(netwib_hash_index *phashindex,
                                      netwib_bool eraseitem);
/*-------------------------------------------------------------*/
/* Name : netwib_hash_index_this_replace
   Description :
     Replace value, but keep the same key.
   Input parameter(s) :
     pitem : pointer to an allocated memory containing the item
     erasepreviousitem : if true, function pfunc_erase (set in
                         netwib_hash_init) is called to erase the
                         item previously located in the hash
   Input/output parameter(s) :
     *phashindex : netwib_hash_index
   Output parameter(s) :
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_hash_index_this_replace(netwib_hash_index *phashindex,
                                          netwib_constptr pitem,
                                          netwib_bool erasepreviousitem);

MODULE TLV
/*-------------------------------------------------------------*/
/* We need a forward declaration for netwib_eth, netwib_ip4 and
   netwib_port.
*/
#include "../net/types.h"
/*-------------------------------------------------------------*/
/***************************************************************
 * This module permits to store TLV in a netwib_buf. A TLV is  *
 * a data block containing :                                   *
 *  - Type : netwib_tlvtype                                    *
 *  - Length : length of value                                 *
 *  - Value : value of type 'type'                             *
 ***************************************************************/
/*-------------------------------------------------------------*/
typedef enum {
  NETWIB_TLVTYPE_BUF = 1,     /* data */
  NETWIB_TLVTYPE_UINT,        /* netwib_uint32 16 or 8 */
  NETWIB_TLVTYPE_ETH,         /* netwib_eth */
  NETWIB_TLVTYPE_IP,          /* netwib_ip */
  NETWIB_TLVTYPE_END = 100,   /* end */
  /* start of free numbers for user */
  NETWIB_TLVTYPE_USER_BEGIN = NETWIB_ENUM_USER_BEGIN
} netwib_tlvtype;
/*-------------------------------------------------------------*/
/* Name : netwib_tlv_append_xyz
   Description :
     Add a TLV to a buf.
   Input parameter(s) :
     ...
   Input/output parameter(s) :
     *pbuf : netwib_buf updated
   Output parameter(s) :
   Normal return values :
     NETWIB_ERR_OK : ok
   The netwib_tlv_append_buf function supports NETWIB_BUF_FLAGS_SENSITIVE.
*/
netwib_err netwib_tlv_append_buf(netwib_constbuf *pbuf,
                                 netwib_buf *ptlv);
netwib_err netwib_tlv_append_uint32(netwib_uint32 ui,
                                    netwib_buf *ptlv);
netwib_err netwib_tlv_append_uint64(netwib_uint64 ui,
                                    netwib_buf *ptlv);
netwib_err netwib_tlv_append_eth(netwib_consteth *peth,
                                 netwib_buf *ptlv);
netwib_err netwib_tlv_append_ip(netwib_constip *pip,
                                netwib_buf *ptlv);
/*-------------------------------------------------------------*/
/* Name : netwib_tlv_append_end
   Description :
     Indicates the end of data. It is for example used after
     several netwib_tlv_append_data to indicates the end of data.
   Input parameter(s) :
   Input/output parameter(s) :
     *pbuf : netwib_buf updated
   Output parameter(s) :
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_tlv_append_end(netwib_buf *ptlv);
/*-------------------------------------------------------------*/
/* Name : netwib_tlv_append_newtype
   Description :
     Add a user defined TLV.
   Input parameter(s) :
     type : type
     *pvalue : buffer containing the value
   Input/output parameter(s) :
     *pbuf : netwib_buf updated
   Output parameter(s) :
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_tlv_append_newtype(netwib_tlvtype type,
                                     netwib_constbuf *pvalue,
                                     netwib_buf *ptlv);
/*-------------------------------------------------------------*/
/* Name : netwib_tlv_xyzpend_tlv
   Description :
     Add a predefined TLV.
   Input parameter(s) :
     *pnewtlv : buffer containing the preformed tlv
   Input/output parameter(s) :
     *pbuf : netwib_buf updated
   Output parameter(s) :
   Normal return values :
     NETWIB_ERR_OK : ok
   Both functions supports NETWIB_BUF_FLAGS_SENSITIVE.
*/
netwib_err netwib_tlv_append_tlv(netwib_constbuf *pnewtlv,
                                 netwib_buf *ptlv);
netwib_err netwib_tlv_prepend_tlv(netwib_constbuf *pnewtlv,
                                  netwib_buf *ptlv);
/*-------------------------------------------------------------*/
/* Name : netwib_tlv_entry_typelen
   Description :
     Obtain type and length of current TLV.
   Input parameter(s) :
     *pbuf : netwib_buf containing the TLV
   Input/output parameter(s) :
   Output parameter(s) :
     *ptype : type
     *plength : length
     *pskipsize : size to skip this entry
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_tlv_entry_typelen(netwib_constbuf *ptlv,
                                    netwib_tlvtype *ptype,
                                    netwib_uint32 *plength,
                                    netwib_uint32 *pskipsize);
/*-------------------------------------------------------------*/
/* Name : netwib_tlv_decode_xyz
   Description :
     Decode a TLV from a buf.
   Input parameter(s) :
     *pbuf : netwib_buf containing the TLV
   Input/output parameter(s) :
     ...
   Output parameter(s) :
     *pskipsize : size to skip this entry
   Normal return values :
     NETWIB_ERR_OK : ok
   The netwib_tlv_decode_buf function supports NETWIB_BUF_FLAGS_SENSITIVE.
*/
netwib_err netwib_tlv_decode_buf(netwib_constbuf *ptlv,
                                 netwib_bufext *pbuf,
                                 netwib_uint32 *pskipsize);
netwib_err netwib_tlv_decode_uint32(netwib_constbuf *ptlv,
                                    netwib_uint32 *pui,
                                    netwib_uint32 *pskipsize);
netwib_err netwib_tlv_decode_uint64(netwib_constbuf *ptlv,
                                    netwib_uint64 *pui,
                                    netwib_uint32 *pskipsize);
netwib_err netwib_tlv_decode_eth(netwib_constbuf *ptlv,
                                 netwib_eth *peth,
                                 netwib_uint32 *pskipsize);
netwib_err netwib_tlv_decode_ip(netwib_constbuf *ptlv,
                                netwib_ip *pip,
                                netwib_uint32 *pskipsize);
/*-------------------------------------------------------------*/
/* Name : netwib_tlv_decode_newtype
   Description :
     Decode a user defined TLV from a buf.
   Input parameter(s) :
     *pbuf : netwib_buf containing the TLV
   Input/output parameter(s) :
   Output parameter(s) :
     *ptype : type
     *plength : length
     *pvalue : buffer containing the value
     *pskipsize : size to skip this entry
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_tlv_decode_newtype(netwib_constbuf *ptlv,
                                     netwib_tlvtype *ptype,
                                     netwib_uint32 *plength,
                                     netwib_bufext *pvalue,
                                     netwib_uint32 *pskipsize);
/*-------------------------------------------------------------*/
/* Name : netwib_tlv_decode_tlv
   Description :
     Decode a TLV from a buf.
   Input parameter(s) :
     *pbuf : netwib_buf containing the TLV
   Input/output parameter(s) :
   Output parameter(s) :
     *pbuf : netwib_buf containing the first entry
     *pskipsize : size to skip this entry
   Normal return values :
     NETWIB_ERR_OK : ok
   This function supports NETWIB_BUF_FLAGS_SENSITIVE.
*/
netwib_err netwib_tlv_decode_tlv(netwib_constbuf *ptlv,
                                 netwib_bufext *pfirsttlv,
                                 netwib_uint32 *pskipsize);

MODULE ARRAY
/*-------------------------------------------------------------*/
/***************************************************************
 * A netwib_array permits to store a dynamic number of items.  *
 * Those items all have the same size.                         *
 *                                                             *
 * The common implementation of such storage is :              *
 *   p = malloc(numitems*sizeof(item));                        *
 *   p[1] = ...;                                               *
 * However, if sizeof(item) is not a multiple of the processor *
 * size, a bus error occurs on strict processors (Alpha,       *
 * Sparc). For example, storing 5 items of size 3 can be       *
 * represented in memory (start at address 0x76543210) :       *
 *   .- address 0x76543210                                     *
 *   ABCABCABCABCABC                                           *
 * The second item is at address 0x76543213 (0x76543210+3)     *
 * which is invalid and causes a bus error.                    *
 * The second drawback of this common implementation is memory *
 * management is not efficient, because when p contains a lot  *
 * of items, this big buffer has to be reallocated.            *
 *                                                             *
 * Netwib's implementation is different. Instead of creating   *
 * an array of items, netwib creates an array of pointers to   *
 * items. This solves both above problems.                     *
 *                                                             *
 * Usage example:                                              *
 *   netwib_array a;                                           *
 *   struct foobar *pfb;                                       *
 *   netwib_er(netwib_array_init(sizeof(struct foobar),3,&a)); *
 *   pfb = (struct foobar *)a.p[0];                            *
 *   pfb->...;                                                 *
 *   for (i = 0; i < a.size; i++) {                            *
 *     pfb = (struct foobar *)a.p[i];                          *
 *     pfb->...;                                               *
 *   }                                                         *
 *   netwib_er(netwib_array_ctl_set_size(&a, 6));              *
 *   pfb = (struct foobar *)a.p[5];                            *
 *   netwib_er(netwib_array_close(&a));                        *
 ***************************************************************/
/*-------------------------------------------------------------*/
typedef struct {
  netwib_ptr *p;      /* array of pointers to items */
  netwib_uint32 size; /* size of p array (0 -> size-1) */
  netwib_ptr opaque;  /* internal storage is here. Do not use. */
} netwib_array;
typedef const netwib_array netwib_constarray;
/*-------------------------------------------------------------*/
/* Name : netwib_array_init
   Description :
     Initialize a netwib_array.
   Input parameter(s) :
     itemsize : size of items to store
     initialsize : initial number of items to store
   Input/output parameter(s) :
   Output parameter(s) :
     *parray : netwib_array initialized
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_array_init(netwib_uint32 itemsize,
                             netwib_uint32 initialsize,
                             netwib_array *parray);
/*-------------------------------------------------------------*/
/* Name : netwib_array_close
   Description :
     Close a netwib_array.
   Input parameter(s) :
   Input/output parameter(s) :
   Output parameter(s) :
     *parray : netwib_array to close
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_array_close(netwib_array *parray);
/*-------------------------------------------------------------*/
/* Types to control a netwib_array */
typedef enum {
  NETWIB_ARRAY_CTLTYPE_SIZE = 1   /* request an array to grow
                                     or shrink */
} netwib_array_ctltype;
netwib_err netwib_array_ctl_set(netwib_array *parray,
                                netwib_array_ctltype type,
                                netwib_ptr p,
                                netwib_uint32 ui);
netwib_err netwib_array_ctl_get(netwib_array *parray,
                                netwib_array_ctltype type,
                                netwib_ptr p,
                                netwib_uint32 *pui);
/*-------------------------------------------------------------*/
/* netwib_err f(netwib_array *parray, netwib_uint32 newsize); */
#define netwib_array_ctl_set_size(parray,newsize) netwib_array_ctl_set(parray,NETWIB_ARRAY_CTLTYPE_SIZE,NULL,newsize)
#define netwib_array_ctl_get_size(parray,pnewsize) netwib_array_ctl_get(parray,NETWIB_ARRAY_CTLTYPE_SIZE,NULL,pnewsize)

MODULE UINT64
/*-------------------------------------------------------------*/
/***************************************************************
 * Type netwib_uint64, can be represented as:                  *
 *  - a 64 bit integer                                         *
 *  - a structure containing two 32 bit integers               *
 * In the first case, math operations are supported by the     *
 * compiler.                                                   *
 * In the second case, following functions are needed.         *
 ***************************************************************/
/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
 #define netwib__uint64_init_8(a,b,c,d,e,f,g,h,x) x = netwib_c2_uint64_8(a,b,c,d,e,f,g,h)
 #define netwib__uint64_init_32(a,b,x) x = (((netwib_uint64)((netwib_uint32)(a))<<32)|(netwib_uint64)((netwib_uint32)(b)))
#else
 #define netwib__uint64_init_8(a,b,c,d,e,f,g,h,x) (x).high = netwib_c2_uint32_4(a,b,c,d); (x).low = netwib_c2_uint32_4(e,f,g,h)
 #define netwib__uint64_init_32(a,b,x) {(x).high = (a); (x).low = (b);}
#endif
/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
 #define netwib__uint64_init_uint32(a,x) x = ((netwib_uint64)(a))
#else
 #define netwib__uint64_init_uint32(a,x) netwib__uint64_init_32(0,a,x)
#endif
/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
 #define netwib__uint64_init_uintmax(a,x) x = ((netwib_uint64)(a))
#else
 #if NETWIB_INTMAX_BITS == 64
  #define netwib__uint64_init_uintmax(a,x) netwib__uint64_init_32((netwib_uint32)((a)>>32),(netwib_uint32)((a)&0xFFFFFFFFu),x)
 #else
  #define netwib__uint64_init_uintmax(a,x) netwib__uint64_init_uint32(a,x)
 #endif
#endif
/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
 #define netwib__uint64_init_uintptr(a,x) x = ((netwib_uint64)(a))
#else
 #if NETWIB_INTPTR_BITS == 64
  #define netwib__uint64_init_uintptr(a,x) netwib__uint64_init_32((netwib_uint32)((a)>>32),(netwib_uint32)((a)&0xFFFFFFFFu),x)
 #else
  #define netwib__uint64_init_uintptr(a,x) netwib__uint64_init_uint32(a,x)
 #endif
#endif
/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
 #define netwib__int64_init_int32(a,x) x = ((netwib_int64)(netwib_int32)(a))
#else
 #define netwib__int64_init_int32(a,x) { if ((netwib_int32)(a) >= 0) { (x).high = 0; (x).low = (netwib_uint32)(a); } else { (x).high = 0xFFFFFFFFu; (x).low = (netwib_uint32)(netwib_int32)(a); } }
#endif
/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
 #define netwib__int64_init_intmax(a,x) x = ((netwib_int64)(netwib_intmax)(a))
#else
 #if NETWIB_INTMAX_BITS == 64
  #define netwib__int64_init_intmax(a,x) netwib__uint64_init_32((netwib_uint32)((a)>>32),(netwib_uint32)((a)&0xFFFFFFFFu),x)
 #else
  #define netwib__int64_init_intmax(a,x) netwib__int64_init_int32(a,x)
 #endif
#endif
/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
 #define netwib__int64_init_intptr(a,x) x = ((netwib_int64)(netwib_intptr)(a))
#else
 #if NETWIB_INTPTR_BITS == 64
  #define netwib__int64_init_intptr(a,x) netwib__uint64_init_32((netwib_uint32)((a)>>32),(netwib_uint32)((a)&0xFFFFFFFFu),x)
 #else
  #define netwib__int64_init_intptr(a,x) netwib__int64_init_int32(a,x)
 #endif
#endif
/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
 #define netwib__uint32_init_uint64(a,x) x = ((netwib_uint32)(a))
#else
 #define netwib__uint32_init_uint64(a,x) x = ((a).low)
#endif
/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
 #define netwib__uintmax_init_uint64(a,x) x = ((netwib_uintmax)(a))
#else
 #if NETWIB_INTMAX_BITS == 64
  #define netwib__uintmax_init_uint64(a,x) x = (((netwib_uintmax)((netwib_uint32)((a).high))<<32)|(netwib_uint64)((netwib_uint32)((a).low)))
 #else
  #define netwib__uintmax_init_uint64(a,x) x = ((netwib_uintmax)(a).low)
 #endif
#endif
/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
 #define netwib__uintptr_init_uint64(a,x) x = ((netwib_uintptr)(a))
#else
 #if NETWIB_INTPTR_BITS == 64
  #define netwib__uintptr_init_uint64(a,x) x = (((netwib_uintptr)((netwib_uint32)((a).high))<<32)|(netwib_uintptr)((netwib_uint32)((a).low)))
 #else
  #define netwib__uintptr_init_uint64(a,x) x = ((netwib_uintptr)(a).low)
 #endif
#endif
/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
 #define netwib__int32_init_int64(a,x) x = ((netwib_int32)(a))
#else
 #define netwib__int32_init_int64(a,x) x = ((netwib_int32)(a).low)
#endif
/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
 #define netwib__intmax_init_int64(a,x) x = ((netwib_intmax)(a))
#else
 #if NETWIB_INTMAX_BITS == 64
  #define netwib__intmax_init_int64(a,x) x = (((netwib_intmax)((netwib_uint32)((a).high))<<32)|(netwib_uintmax)((netwib_uint32)((a).low)))
 #else
  #define netwib__intmax_init_int64(a,x) x = ((netwib_intmax)(a).low)
 #endif
#endif
/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
 #define netwib__intptr_init_int64(a,x) x = ((netwib_intptr)(a))
#else
 #if NETWIB_INTPTR_BITS == 64
  #define netwib__intptr_init_int64(a,x) x = (((netwib_intptr)((netwib_uint32)((a).high))<<32)|(netwib_uintptr)((netwib_uint32)((a).low)))
 #else
  #define netwib__intptr_init_int64(a,x) x = ((netwib_intptr)(a).low)
 #endif
#endif
/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
  #define netwib__uint64_add(a,b,x) x = (netwib_uint64)(a) + (netwib_uint64)(b);
#else
  #define netwib__uint64_add(a,b,x) { netwib_uint32 netwib__uint64_add_tmp, netwib__uint64_add_carry; netwib__uint64_add_tmp = (a).low + (b).low; netwib__uint64_add_carry = (netwib__uint64_add_tmp < (a).low) ? 1 : 0; (x).low = netwib__uint64_add_tmp; (x).high = (a).high + (b).high + netwib__uint64_add_carry; }
#endif
#define netwib__int64_add(a,b,x) netwib__uint64_add(a,b,x)
/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
  #define netwib__uint64_sub(a,b,x) x = (netwib_uint64)(a) - (netwib_uint64)(b);
#else
  #define netwib__uint64_sub(a,b,x) { netwib_uint32 netwib__uint64_add_tmp, netwib__uint64_add_carry; netwib__uint64_add_tmp = (a).low - (b).low; netwib__uint64_add_carry = (netwib__uint64_add_tmp > (a).low) ? 1 : 0; (x).low = netwib__uint64_add_tmp; (x).high = (a).high - (b).high - netwib__uint64_add_carry; }
#endif
#define netwib__int64_sub(a,b,x) netwib__uint64_sub(a,b,x)
/*-------------------------------------------------------------*/
void netwib__uint64_mul_private(netwib_uint64 a,
                                netwib_uint64 b,
                                netwib_uint64 *px);
#if NETWIB_INT64_FAKE == 0
  #define netwib__uint64_mul(a,b,px) *(px) = (netwib_uint64)(a) * (netwib_uint64)(b)
#else
  #define netwib__uint64_mul(a,b,px) netwib__uint64_mul_private(a,b,px)
#endif
#define netwib__int64_mul(a,b,px) netwib__uint64_mul(a,b,px)
/*-------------------------------------------------------------*/
void netwib__uint64_div_private(netwib_uint64 a,
                                netwib_uint64 b,
                                netwib_uint64 *pq,
                                netwib_uint64 *pr);
void netwib__int64_div_private(netwib_int64 a,
                               netwib_int64 b,
                               netwib_int64 *pq,
                               netwib_int64 *pr);
#if NETWIB_INT64_FAKE == 0
  #define netwib__uint64_div(a,b,pq,pr) { netwib_uint64 netwib__uint64_div_tmp; netwib__uint64_div_tmp = (netwib_uint64)(a) / (netwib_uint64)(b); *(pr) = (netwib_uint64)(a) % (netwib_uint64)(b); *(pq) = netwib__uint64_div_tmp; }
  #define netwib__int64_div(a,b,pq,pr) { netwib_int64 netwib__int64_div_tmp; netwib__int64_div_tmp = (netwib_int64)(a) / (netwib_int64)(b); *(pr) = (netwib_int64)(a) % (netwib_int64)(b); *(pq) = netwib__int64_div_tmp; }
#else
  #define netwib__uint64_div(a,b,pq,pr) netwib__uint64_div_private(a,b,pq,pr)
  #define netwib__int64_div(a,b,pq,pr) netwib__int64_div_private(a,b,pq,pr)
#endif
/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
  #define netwib__uint64_inc(x) x = (netwib_uint64)(x) + 1;
#else
  #define netwib__uint64_inc(x) { if ((x).low == 0xFFFFFFFFu) { (x).high++; (x).low = 0; } else { (x).low++; } }
#endif
#define netwib__int64_inc(x) netwib__uint64_inc(x)
/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
  #define netwib__uint64_dec(x) x = (netwib_uint64)(x) - 1;
#else
  #define netwib__uint64_dec(x) { if ((x).low == 0) { (x).high--; (x).low = 0xFFFFFFFFu; } else { (x).low--; } }
#endif
#define netwib__int64_dec(x) netwib__uint64_dec(x)
/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
  #define netwib__uint64_cmp_eq(a,b) ((netwib_uint64)(a) == (netwib_uint64)(b))
  #define netwib__uint64_cmp_ne(a,b) ((netwib_uint64)(a) != (netwib_uint64)(b))
  #define netwib__uint64_cmp_lt(a,b) ((netwib_uint64)(a) < (netwib_uint64)(b))
  #define netwib__uint64_cmp_le(a,b) ((netwib_uint64)(a) <= (netwib_uint64)(b))
  #define netwib__uint64_cmp_gt(a,b) ((netwib_uint64)(a) > (netwib_uint64)(b))
  #define netwib__uint64_cmp_ge(a,b) ((netwib_uint64)(a) >= (netwib_uint64)(b))
  #define netwib__int64_cmp_eq(a,b) ((netwib_int64)(a) == (netwib_int64)(b))
  #define netwib__int64_cmp_ne(a,b) ((netwib_int64)(a) != (netwib_int64)(b))
  #define netwib__int64_cmp_lt(a,b) ((netwib_int64)(a) < (netwib_int64)(b))
  #define netwib__int64_cmp_le(a,b) ((netwib_int64)(a) <= (netwib_int64)(b))
  #define netwib__int64_cmp_gt(a,b) ((netwib_int64)(a) > (netwib_int64)(b))
  #define netwib__int64_cmp_ge(a,b) ((netwib_int64)(a) >= (netwib_int64)(b))
#else
  #define netwib__uint64_cmp_eq(a,b) ( ((a).high == (b).high) && ((a).low == (b).low) )
  #define netwib__uint64_cmp_ne(a,b) ( ((a).high != (b).high) || ((a).low != (b).low) )
  #define netwib__uint64_cmp_lt(a,b) ( ((a).high < (b).high) || ( ((a).high == (b).high) && ((a).low < (b).low) ) )
  #define netwib__uint64_cmp_le(a,b) ( ((a).high < (b).high) || ( ((a).high == (b).high) && ((a).low <= (b).low) ) )
  #define netwib__uint64_cmp_gt(a,b) ( ((a).high > (b).high) || ( ((a).high == (b).high) && ((a).low > (b).low) ) )
  #define netwib__uint64_cmp_ge(a,b) ( ((a).high > (b).high) || ( ((a).high == (b).high) && ((a).low >= (b).low) ) )
  #define netwib__int64_cmp_eq(a,b) ( ((a).high == (b).high) && ((a).low == (b).low) )
  #define netwib__int64_cmp_ne(a,b) ( ((a).high != (b).high) || ((a).low != (b).low) )
  #define netwib__int64_cmp_lt(a,b) ( ((netwib_int32)(a).high < (netwib_int32)(b).high) || ( ((netwib_int32)(a).high == (netwib_int32)(b).high) && ((netwib_int32)(a).low < (netwib_int32)(b).low) ) )
  #define netwib__int64_cmp_le(a,b) ( ((netwib_int32)(a).high < (netwib_int32)(b).high) || ( ((netwib_int32)(a).high == (netwib_int32)(b).high) && ((netwib_int32)(a).low <= (netwib_int32)(b).low) ) )
  #define netwib__int64_cmp_gt(a,b) ( ((netwib_int32)(a).high > (netwib_int32)(b).high) || ( ((netwib_int32)(a).high == (netwib_int32)(b).high) && ((netwib_int32)(a).low > (netwib_int32)(b).low) ) )
  #define netwib__int64_cmp_ge(a,b) ( ((netwib_int32)(a).high > (netwib_int32)(b).high) || ( ((netwib_int32)(a).high == (netwib_int32)(b).high) && ((netwib_int32)(a).low >= (netwib_int32)(b).low) ) )
#endif
/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
  #define netwib__int64_neg(a,x) x = -(netwib_int64)(a);
#else
  #define netwib__int64_neg(a,x) { (x).high = ~(a).high; (x).low = ~(a).low; netwib__uint64_inc(x); }
#endif
/*-------------------------------------------------------------*/
/* For shl, shr, rol and rol, I encountered several problems with gcc
   on 32 bit architectures:
    - x << 64 = zero with "gcc -O"
    - x << 64 = unchanged with "gcc -O2"
   There are also problems under Solaris Sparc, with rol(0).
   I decided to normalize to have a coherent behavior.
*/
#if NETWIB_INT64_FAKE == 0
  #define netwib__uint64_shl(a,n,x) { netwib_uint32 netwib__uint64_shl_n = (n); if (netwib__uint64_shl_n == 0) { (x) = (a); } else if (netwib__uint64_shl_n >= 64) { (x) = 0; } else {(x) = (a) << netwib__uint64_shl_n;} }
#else
  #define netwib__uint64_shl(a,n,x) { netwib_uint32 netwib__uint64_shl_tmp, netwib__uint64_shl_n = n; if (netwib__uint64_shl_n == 0) { (x).high = (a).high; (x).low = (a).low; } else if (netwib__uint64_shl_n >= 64) { (x).high = 0; (x).low = 0; } else if (netwib__uint64_shl_n < 32) { netwib__uint64_shl_tmp = (a).high << netwib__uint64_shl_n | ((a).low >> (32 - netwib__uint64_shl_n)); (x).low = (a).low << netwib__uint64_shl_n; (x).high = netwib__uint64_shl_tmp; } else { netwib__uint64_shl_n -= 32; (x).high = (a).low << netwib__uint64_shl_n ; (x).low = 0; } }
#endif
/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
  #define netwib__uint64_shr(a,n,x) { netwib_uint32 netwib__uint64_shr_n = (n);  if (netwib__uint64_shr_n == 0) { (x) = (a); } else if (netwib__uint64_shr_n >= 64) { (x) = 0; } else { x = (a) >> netwib__uint64_shr_n; } }
#else
  #define netwib__uint64_shr(a,n,x) { netwib_uint32 netwib__uint64_shr_tmp, netwib__uint64_shr_n = n; if (netwib__uint64_shr_n == 0) { (x).high = (a).high; (x).low = (a).low; } else if (netwib__uint64_shr_n >= 64) { (x).high = 0; (x).low = 0; } else if (netwib__uint64_shr_n < 32) { netwib__uint64_shr_tmp = (a).low >> netwib__uint64_shr_n | ((a).high << (32 - netwib__uint64_shr_n)); (x).high = (a).high >> netwib__uint64_shr_n; (x).low = netwib__uint64_shr_tmp; } else { netwib__uint64_shr_n -= 32; (x).low = (a).high >> netwib__uint64_shr_n; (x).high = 0; } }
#endif
/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
  #define netwib__uint64_rol(a,n,x) { netwib_uint32 netwib__uint64_rol_n = (n)%64; if (netwib__uint64_rol_n == 0) { x = (a); } else { x = ((netwib_uint64)( (netwib_uint64)((a)<<netwib__uint64_rol_n) | (netwib_uint64)((a)>>(64-netwib__uint64_rol_n)) )); } }
#else
  #define netwib__uint64_rol(a,n,x) { netwib_uint32 netwib__uint64_rol_tmp, netwib__uint64_rol_n = (n)%64; if (netwib__uint64_rol_n == 0) { (x).high = (a).high; (x).low = (a).low; } else if (netwib__uint64_rol_n < 32) { netwib__uint64_rol_tmp = (a).high << netwib__uint64_rol_n | ((a).low >> (32 - netwib__uint64_rol_n)); (x).low = (a).low << netwib__uint64_rol_n | ((a).high >> (32 - netwib__uint64_rol_n)); (x).high = netwib__uint64_rol_tmp; } else { netwib__uint64_rol_n -= 32; netwib__uint64_rol_tmp = (a).low << netwib__uint64_rol_n | ((a).high >> (32 - netwib__uint64_rol_n)); (x).low = (a).high << netwib__uint64_rol_n | ((a).low >> (32 - netwib__uint64_rol_n)); (x).high = netwib__uint64_rol_tmp; } }
#endif
/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
  #define netwib__uint64_ror(a,n,x) { netwib_uint32 netwib__uint64_ror_n = (n)%64; if (netwib__uint64_ror_n == 0) { x = (a); } else { x = ((netwib_uint64)( (netwib_uint64)((a)>>netwib__uint64_ror_n) | (netwib_uint64)((a)<<(64-netwib__uint64_ror_n)) )); } }
#else
  #define netwib__uint64_ror(a,n,x) { netwib_uint32 netwib__uint64_ror_tmp, netwib__uint64_ror_n = (n)%64; if (netwib__uint64_ror_n == 0) { (x).high = (a).high; (x).low = (a).low; } else if (netwib__uint64_ror_n < 32) { netwib__uint64_ror_tmp = (a).low >> netwib__uint64_ror_n | ((a).high << (32 - netwib__uint64_ror_n)); (x).high = (a).high >> netwib__uint64_ror_n | ((a).low << (32 - netwib__uint64_ror_n)); (x).low = netwib__uint64_ror_tmp; } else { netwib__uint64_ror_n -= 32; netwib__uint64_ror_tmp = (a).high >> netwib__uint64_ror_n | ((a).low << (32 - netwib__uint64_ror_n)); (x).high = (a).low >> netwib__uint64_ror_n | ((a).high << (32 - netwib__uint64_ror_n)); (x).low = netwib__uint64_ror_tmp;} }
#endif
/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
  #define netwib__uint64_and(a,b,x) x = (netwib_uint64)(a) & (netwib_uint64)(b);
#else
  #define netwib__uint64_and(a,b,x) { (x).high = (a).high & (b).high; (x).low = (a).low & (b).low; }
#endif
/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
  #define netwib__uint64_or(a,b,x) x = (netwib_uint64)(a) | (netwib_uint64)(b);
#else
  #define netwib__uint64_or(a,b,x) { (x).high = (a).high | (b).high; (x).low = (a).low | (b).low; }
#endif
/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
  #define netwib__uint64_xor(a,b,x) x = (netwib_uint64)(a) ^ (netwib_uint64)(b);
#else
  #define netwib__uint64_xor(a,b,x) { (x).high = (a).high ^ (b).high; (x).low = (a).low ^ (b).low; }
#endif
/*-------------------------------------------------------------*/
#if NETWIB_INT64_FAKE == 0
  #define netwib__uint64_not(a,x) x = ~(netwib_uint64)(a);
#else
  #define netwib__uint64_not(a,x) { (x).high = ~(a).high; (x).low = ~(a).low; }
#endif
/*-------------------------------------------------------------*/
/* To represent values > 0xFFFFFFFF :
    - gcc/mingw needs 0xf....fLL
    - Microsoft Visual 6 does not support LL
 */
#if defined NETWIBDEF_PROGCC_VISUALC
  #define NETWIB_UINT_LL(x) (x)
  #define NETWIB_INT_LL(x) (x)
#else
  #define NETWIB_UINT_LL(x) (x ## LLU)
  #define NETWIB_INT_LL(x) (x ## LL)
#endif
/*-------------------------------------------------------------*/
/* To initialize a static variable */
#if NETWIB_INT64_FAKE == 0
  #define NETWIB_UINT_STATIC(ahigh,alow) (((netwib_uint64)((netwib_uint32)(ahigh))<<32)|(netwib_uint64)((netwib_uint32)(alow)))
  #define NETWIB_INT_STATIC(ahigh,alow) (((netwib_int64)((netwib_uint32)(ahigh))<<32)|(netwib_uint64)((netwib_uint32)(alow)))
#else
  #define NETWIB_UINT_STATIC(ahigh,alow) {(ahigh), (alow)}
  #define NETWIB_INT_STATIC(ahigh,alow) {(ahigh), (alow)}
#endif

SEE ALSO
netwib(3), netwib_dat(3), netwib_sys(3), netwib_net(3), netwib_pkt(3), netwib_shw(3), netwib_err(3)