Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
NETWIB_DAT(3)		   Library Functions Manual		 NETWIB_DAT(3)

NAME
       netwib -	section	dat

HTML DOC
       If  you have a browser, read netwib-5.38.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 :
	   - some Unixes (Solaris, HP-UX) need 0xf....fLL
	   - Windows does not support LL
	*/
       #if defined NETWIBDEF_SYSNAME_Unix
	 #define NETWIB_UINT_LL(x) (x ## LLU)
	 #define NETWIB_INT_LL(x) (x ##	LL)
       #elif defined NETWIBDEF_SYSNAME_Windows
	 #define NETWIB_UINT_LL(x) (x)
	 #define NETWIB_INT_LL(x) (x)
       #else
	 #error	"Unknown value for NETWIBDEF_SYSNAME"
       #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)

				  14/02/2010			 NETWIB_DAT(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=netwib538_dat&sektion=3&manpath=FreeBSD+Ports+15.0>

home | help