/*
		                  LCRZO
                             Network library
             Copyright(c) 1999,2000,2001,2002 Laurent Constantin
                                  -----

  Main server    : http://www.laurentconstantin.com/
  Backup servers : http://go.to/laurentconstantin/
                   http://laurentconstantin.est-la.com/
                   http://laurentconstantin.free.fr/
                   http://lauconstantin.multimania.com/
  [my current email address is on the web servers]

                                  -----
  This file is part of Lcrzo.

  Lcrzo is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  Lcrzo is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details (http://www.gnu.org).

------------------------------------------------------------------------
*/

/* -- Note about comments and variable names --
   In versions 1.00 up to 2.08, lcrzo was only written in French (my
   mother tongue). Since version 3.00, lcrzo is written in English, but
   most of comments and variable names are still in French.
   In future versions, I'll try to translate everything into English,
   but as you may guess, that's a quite big work...
   So, for the moment, here are some word translation, if you want to
   be able to understand what's going on in the functions :
     afficher - print     ;  ajouter - add         ;  copie - copy
     dernier - last       ;  donnee - data         ;  ecrire - write
     entete - header      ;  envoye - sent         ;  ferme - close
     fichier - file       ;  lire - read           ;  masque - mask 
     nboct - byte number  ;  ouvre, ouvrir - open  ;  paq, paquet - packet
     plage - range        ;  premier - first       ;  recu - received
     reseau - network     ;  retour - return       ;  taille - size
     tunnel - pipe

*/
 
#include "lcrzo_incl.h"

/*-------------------------------------------------------------*/
int lcrzo_ipopt_init_noop(lcrzo_ipopt ipopt,
			  lcrzo_uint8 *pnboctipopt)
{
  if (ipopt!=NULL)
  { ipopt[0]=1; /*noop*/
    ipopt[1]=1; /*noop*/
    ipopt[2]=1; /*noop*/
    ipopt[3]=1; /*noop*/
  }
  if (pnboctipopt!=NULL) *pnboctipopt=4; /*une ligne complete*/
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_priv_ipopt_init_srr(lcrzo_ipl ipl1,
			      lcrzo_ipl ipl2,
			      lcrzo_ipl ipl3,
			      lcrzo_ipl ipl4,
			      lcrzo_ipl ipl5,
			      lcrzo_ipl ipl6,
			      lcrzo_ipl ipl7,
			      lcrzo_ipl ipl8,
			      lcrzo_ipl ipl9,
			      lcrzo_uint8 nbiplaffectes,
			      lcrzo_uint8 typesr,
			      lcrzo_ipopt ipopt,
			      lcrzo_uint8 *pnboctipopt);
int lcrzo_priv_ipopt_init_srr(lcrzo_ipl ipl1,
			      lcrzo_ipl ipl2,
			      lcrzo_ipl ipl3,
			      lcrzo_ipl ipl4,
			      lcrzo_ipl ipl5,
			      lcrzo_ipl ipl6,
			      lcrzo_ipl ipl7,
			      lcrzo_ipl ipl8,
			      lcrzo_ipl ipl9,
			      lcrzo_uint8 nbiplaffectes,
			      lcrzo_uint8 typesr,
			      lcrzo_ipopt ipopt,
			      lcrzo_uint8 *pnboctipopt)
{ lcrzo_ipa ipa;
  int i;

  /*verification des parametres*/
  if (nbiplaffectes==0)
  { if (pnboctipopt!=NULL) *pnboctipopt=0; 
    return(LCRZO_ERR_OK);
  }
  if (nbiplaffectes>9)
    return(LCRZO_ERR_SPOPTMAX10);

  /*taille totale*/
  if (pnboctipopt!=NULL) *pnboctipopt=(lcrzo_uint8)((nbiplaffectes+1)*4);

  /*if ipopt is NULL, we can exit now*/
  if (ipopt==NULL) return(LCRZO_ERR_OK);

  /*remplissage des routes*/
  for ( i=1 ; i<=nbiplaffectes ; i++ )
  { /*affecte l'ipa de travail*/
    switch(i)
    { case 1: lcrzo_er(lcrzo_ipa_init_ipl(ipl1, ipa)); break;
      case 2: lcrzo_er(lcrzo_ipa_init_ipl(ipl2, ipa)); break;
      case 3: lcrzo_er(lcrzo_ipa_init_ipl(ipl3, ipa)); break;
      case 4: lcrzo_er(lcrzo_ipa_init_ipl(ipl4, ipa)); break;
      case 5: lcrzo_er(lcrzo_ipa_init_ipl(ipl5, ipa)); break;
      case 6: lcrzo_er(lcrzo_ipa_init_ipl(ipl6, ipa)); break;
      case 7: lcrzo_er(lcrzo_ipa_init_ipl(ipl7, ipa)); break;
      case 8: lcrzo_er(lcrzo_ipa_init_ipl(ipl8, ipa)); break;
      case 9: lcrzo_er(lcrzo_ipa_init_ipl(ipl9, ipa)); break;
    }

    /*on copie l'adresse dans l'option*/
    ipopt[i*4-1]=ipa[0];
    ipopt[i*4]=ipa[1];
    ipopt[i*4+1]=ipa[2];
    ipopt[i*4+2]=ipa[3];
  }

  /*remplissage des entetes et du padding*/
  ipopt[0]=typesr;
  ipopt[1]=(lcrzo_uint8)( 3 + nbiplaffectes*4);
  ipopt[2]=4;
  ipopt[3+nbiplaffectes*4]=1;

  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_ipopt_init_lsrr(lcrzo_ipl ipl1,
			 lcrzo_ipl ipl2,
			 lcrzo_ipl ipl3,
			 lcrzo_ipl ipl4,
			 lcrzo_ipl ipl5,
			 lcrzo_ipl ipl6,
			 lcrzo_ipl ipl7,
			 lcrzo_ipl ipl8,
			 lcrzo_ipl ipl9,
			 lcrzo_uint8 nbiplaffectes,
			 lcrzo_ipopt ipopt,
			 lcrzo_uint8 *pnboctipopt)
{
  return(lcrzo_priv_ipopt_init_srr(ipl1,
				   ipl2,
				   ipl3,
				   ipl4,
				   ipl5,
				   ipl6,
				   ipl7,
				   ipl8,
				   ipl9,
				   nbiplaffectes,
				   131,
				   ipopt,
				   pnboctipopt));
}

/*-------------------------------------------------------------*/
int lcrzo_ipopt_init_ssrr(lcrzo_ipl ipl1,
			 lcrzo_ipl ipl2,
			 lcrzo_ipl ipl3,
			 lcrzo_ipl ipl4,
			 lcrzo_ipl ipl5,
			 lcrzo_ipl ipl6,
			 lcrzo_ipl ipl7,
			 lcrzo_ipl ipl8,
			 lcrzo_ipl ipl9,
			 lcrzo_uint8 nbiplaffectes,
			 lcrzo_ipopt ipopt,
			 lcrzo_uint8 *pnboctipopt)
{
  return(lcrzo_priv_ipopt_init_srr(ipl1,
				   ipl2,
				   ipl3,
				   ipl4,
				   ipl5,
				   ipl6,
				   ipl7,
				   ipl8,
				   ipl9,
				   nbiplaffectes,
				   137,
				   ipopt,
				   pnboctipopt));
}

/*-------------------------------------------------------------*/
int lcrzo_ipopt_init_rr(lcrzo_uint8 nbroutesaenregistrer,
		       lcrzo_ipopt ipopt,
		       lcrzo_uint8 *pnboctipopt)
{
  /*si nbroutesaenregistrer est superieur a 9 (15-sizeof(lczro_hdrip)/4)*/
  if ( nbroutesaenregistrer > 9 )
    return(LCRZO_ERR_SPOPTMAX10);
  if ( nbroutesaenregistrer == 0 )
  { if (pnboctipopt!=NULL) *pnboctipopt=0; 
    return(LCRZO_ERR_OK);
  }

  if (ipopt!=NULL)
  { /*mise a zero des zones a remplir*/
    memset(ipopt+3, 0, nbroutesaenregistrer*4);
    /*remplissage des entetes et du padding*/
    ipopt[0]=7;
    ipopt[1]=(lcrzo_uint8)( 3 + nbroutesaenregistrer*4 );
    ipopt[2]=4;
    ipopt[3+nbroutesaenregistrer*4]=1;
  }

  /*taille totale*/
  if (pnboctipopt!=NULL)
  { *pnboctipopt=(lcrzo_uint8)( (nbroutesaenregistrer+1)*4 );
  }
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_ipopt_init_time(lcrzo_uint8 nbtimestampsaenregistrer,
			 lcrzo_ipopt ipopt,
			 lcrzo_uint8 *pnboctipopt)
{
  /*si nbtimestampsaenregistrer est superieur a 9 (15-sizeof(lczro_hdrip)/4)*/
  if ( nbtimestampsaenregistrer > 9 )
    return(LCRZO_ERR_SPOPTMAX10);
  if ( nbtimestampsaenregistrer == 0 )
  { if (pnboctipopt!=NULL) *pnboctipopt=0; 
    return(LCRZO_ERR_OK);
  }

  if (ipopt!=NULL)
  { /*mise a zero des zones a remplir*/
    memset(ipopt+4, 0, nbtimestampsaenregistrer*4);
    /*remplissage des entetes*/
    ipopt[0]=68;
    ipopt[1]=(lcrzo_uint8)( (nbtimestampsaenregistrer+1)*4 );
    ipopt[2]=5;
    ipopt[3]=0;
  }

  /*taille totale*/
  if (pnboctipopt!=NULL)
  { *pnboctipopt=(lcrzo_uint8)( (nbtimestampsaenregistrer+1)*4 );
  }
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_ipopt_init_timeip(lcrzo_uint8 nbiptimestampsaenregistrer,
			   lcrzo_ipopt ipopt,
			   lcrzo_uint8 *pnboctipopt)
{
  /*il n'y a pas la place d'en mettre plus de 4*/
  if ( nbiptimestampsaenregistrer > 4 )
    return(LCRZO_ERR_SPOPTMAX10);
  if ( nbiptimestampsaenregistrer == 0 )
  { if (pnboctipopt!=NULL) *pnboctipopt=0; 
    return(LCRZO_ERR_OK);
  }

  if (ipopt!=NULL)
  { /*mise a zero des zones a remplir*/
    memset(ipopt+4, 0, nbiptimestampsaenregistrer*8);
    /*remplissage des entetes*/
    ipopt[0]=68;
    ipopt[1]=(lcrzo_uint8)( (2*nbiptimestampsaenregistrer+1)*4 );
    ipopt[2]=5;
    ipopt[3]=1;
  }

  /*taille totale*/
  if (pnboctipopt!=NULL)
  { *pnboctipopt=(lcrzo_uint8)( (2*nbiptimestampsaenregistrer+1)*4 );
  }
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_ipopt_init_timeipp(lcrzo_ipl ipl1,
			    lcrzo_ipl ipl2,
			    lcrzo_ipl ipl3,
			    lcrzo_ipl ipl4,
			    lcrzo_uint8 nbiplaffectes,
			    lcrzo_ipopt ipopt,
			    lcrzo_uint8 *pnboctipopt)
{ lcrzo_ipa ipa;
  int i;

  /*verification des parametres*/
  if (nbiplaffectes==0)
  { if (pnboctipopt!=NULL) *pnboctipopt=0; 
    return(LCRZO_ERR_OK);
  }
  if (nbiplaffectes>4)
    return(LCRZO_ERR_SPOPTMAX10);

  /*taille totale*/
  if (pnboctipopt!=NULL) *pnboctipopt=(lcrzo_uint8)( (2*nbiplaffectes+1)*4 );

  /*if ipopt is NULL, we can exit now*/
  if (ipopt==NULL) return(LCRZO_ERR_OK);

  /*remplissage des routes*/
  for ( i=1 ; i<=nbiplaffectes ; i++ )
  { /*affecte l'ipa de travail*/
    switch(i)
    { case 1: lcrzo_er(lcrzo_ipa_init_ipl(ipl1, ipa)); break;
      case 2: lcrzo_er(lcrzo_ipa_init_ipl(ipl2, ipa)); break;
      case 3: lcrzo_er(lcrzo_ipa_init_ipl(ipl3, ipa)); break;
      case 4: lcrzo_er(lcrzo_ipa_init_ipl(ipl4, ipa)); break;
    }

    /*on copie l'adresse dans l'option*/
    ipopt[(i-1)*8+4]=ipa[0];
    ipopt[(i-1)*8+5]=ipa[1];
    ipopt[(i-1)*8+6]=ipa[2];
    ipopt[(i-1)*8+7]=ipa[3];
    /*on laisse la place du timestamp*/
    memset(ipopt+i*8, 0, 4);
  }

  /*remplissage des entetes et du padding*/
  ipopt[0]=68;
  ipopt[1]=(lcrzo_uint8)( (2*nbiplaffectes+1)*4);
  ipopt[2]=5;
  ipopt[3]=3;

  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_ipopt_init_mixed(const char * mixed,
			   lcrzo_ipopt ipopt,
			   lcrzo_uint8 *pipoptsize)
{ lcrzo_int32 ipoptsize;

  lcrzo_er(lcrzo_data_init_mixed(mixed, LCRZO_IPOPT_MAXBYTES,
				 ipopt, &ipoptsize));
  if (pipoptsize!=NULL) *pipoptsize=(lcrzo_uint8)ipoptsize;
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_ipopt_init_stdin(const char * message,
		      const char * defaultmixed,
		      lcrzo_ipopt ipopt,
		      lcrzo_uint8 *pipoptsize)
{ lcrzo_data data;
  lcrzo_int32 datasize;

  /* just for the compiler warning */
  data=NULL;
  datasize=0;

  while (LCRZO_TRUE)
  { lcrzo_er(lcrzo_data_initm_mixed_stdin(message, defaultmixed, 
					  &data, &datasize));
    if (datasize>LCRZO_IPOPT_MAXBYTES) datasize=1;
    if ( ! (datasize%4) ) break;
    lcrzo_data_free(data);
  }
  lcrzo_er(lcrzo_data_init_data(data, datasize, LCRZO_IPOPT_MAXBYTES, 
				ipopt, NULL));
  lcrzo_data_free(data);
  if (pipoptsize!=NULL) *pipoptsize=(lcrzo_uint8)datasize;

  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_priv_ipopt_passeoptionsuivante(const lcrzo_uint8 *poption,
					  lcrzo_uint8 nboctoption,
					  lcrzo_uint8 *poptionsuiv,
					  lcrzo_uint8 *pnboctoptionsuiv);
int lcrzo_priv_ipopt_passeoptionsuivante(const lcrzo_uint8 *poption,
					  lcrzo_uint8 nboctoption,
					  lcrzo_uint8 *poptionsuiv,
					  lcrzo_uint8 *pnboctoptionsuiv)
{
  /*quand la taille est nulle, c'est fini*/
  if ( nboctoption==0 )
  { *pnboctoptionsuiv=0;
    return(LCRZO_ERR_OK);
  }

  /*option nulle ou noop */
  if ( poption[0]==0 || poption[0]==1 )
  { *pnboctoptionsuiv=(lcrzo_uint8)( nboctoption-1 );
    memcpy(poptionsuiv, poption+1, *pnboctoptionsuiv);
    return(LCRZO_ERR_OK);
  }
  /*option a 3 champs*/  
  else
  { /*taille trop courte ou trop longue: erreur*/
    if ( nboctoption<=2 || poption[1]<=2 || poption[1]>nboctoption )
    { *pnboctoptionsuiv=nboctoption;
      memcpy(poptionsuiv, poption, nboctoption);
      return(LCRZO_ERR_OKNOTDECODED);
    }
    /*on saute l'option courante*/
    *pnboctoptionsuiv=(lcrzo_uint8)( nboctoption-poption[1] );
    memcpy(poptionsuiv, poption+poption[1], *pnboctoptionsuiv);
    return(LCRZO_ERR_OK);
  }
  return(LCRZO_ERR_OKNOTDECODED);
}

/*-------------------------------------------------------------*/
int lcrzo_ipopt_decode_1null(const lcrzo_ipopt ipopt,
			    lcrzo_uint8 nboctipopt)
{
  /*parameters verification*/
  if (ipopt==NULL && nboctipopt) return(LCRZO_ERR_PANULLPTRSIZE);

  if (nboctipopt==0)
    return(LCRZO_ERR_OKNOTDECODED);
  if (ipopt[0]==0)
    return(LCRZO_ERR_OK);
  return(LCRZO_ERR_OKNOTDECODED);
}

/*-------------------------------------------------------------*/
int lcrzo_ipopt_decode_1noop(const lcrzo_ipopt ipopt,
			    lcrzo_uint8 nboctipopt)
{
  /*parameters verification*/
  if (ipopt==NULL && nboctipopt) return(LCRZO_ERR_PANULLPTRSIZE);
  if (nboctipopt==0)
    return(LCRZO_ERR_OKNOTDECODED);
  if (ipopt[0]==1)
    return(LCRZO_ERR_OK);
  return(LCRZO_ERR_OKNOTDECODED);
}

/*-------------------------------------------------------------*/
int lcrzo_ipopt_decode_1lsrr(const lcrzo_ipopt ipopt,
			    lcrzo_uint8 nboctipopt,
			    lcrzo_uint8 *pnbiplaffectes,
			    lcrzo_uint8 *ppointeur,
			    lcrzo_ipl *pipl1,
			    lcrzo_ipl *pipl2,
			    lcrzo_ipl *pipl3,
			    lcrzo_ipl *pipl4,
			    lcrzo_ipl *pipl5,
			    lcrzo_ipl *pipl6,
			    lcrzo_ipl *pipl7,
			    lcrzo_ipl *pipl8,
			    lcrzo_ipl *pipl9)
{ lcrzo_ipa ipa;
  lcrzo_uint8 nbiplaffectes;
  int i;

  /*parameters verification*/
  if (ipopt==NULL && nboctipopt) return(LCRZO_ERR_PANULLPTRSIZE);

  /*taille nulle : erreur*/
  if (nboctipopt==0)
    return(LCRZO_ERR_OKNOTDECODED);

  /*ce n'est pas l'option cherchee*/
  if (ipopt[0]!=131)
    return(LCRZO_ERR_OKNOTDECODED);

  /*taille trop courte ou trop longue: erreur*/
  if ( nboctipopt<=2 || ipopt[1]<=2 || ipopt[1]>nboctipopt )
    return(LCRZO_ERR_OKNOTDECODED);
   
  /*si la taille n'est pas de la forme 4*i+3 : erreur*/
  if ( (ipopt[1]-3) % 4 )    
    return(LCRZO_ERR_OKNOTDECODED);

  /*on affecte les ipli*/
  nbiplaffectes=(lcrzo_uint8)( (ipopt[1]-3)/4 );
  if (pnbiplaffectes!=NULL) *pnbiplaffectes=nbiplaffectes;
  if (ppointeur!=NULL) *ppointeur=ipopt[2];
  for ( i=1 ; i<=nbiplaffectes ; i++ )
  { ipa[0]=ipopt[4*i-1];
    ipa[1]=ipopt[4*i];
    ipa[2]=ipopt[4*i+1];
    ipa[3]=ipopt[4*i+2];
    switch(i)
    { case 1: lcrzo_er(lcrzo_ipl_init_ipa(ipa, pipl1)); break;
      case 2: lcrzo_er(lcrzo_ipl_init_ipa(ipa, pipl2)); break;
      case 3: lcrzo_er(lcrzo_ipl_init_ipa(ipa, pipl3)); break;
      case 4: lcrzo_er(lcrzo_ipl_init_ipa(ipa, pipl4)); break;
      case 5: lcrzo_er(lcrzo_ipl_init_ipa(ipa, pipl5)); break;
      case 6: lcrzo_er(lcrzo_ipl_init_ipa(ipa, pipl6)); break;
      case 7: lcrzo_er(lcrzo_ipl_init_ipa(ipa, pipl7)); break;
      case 8: lcrzo_er(lcrzo_ipl_init_ipa(ipa, pipl8)); break;
      case 9: lcrzo_er(lcrzo_ipl_init_ipa(ipa, pipl9)); break;
      default: return(LCRZO_ERR_OKNOTDECODED); 
    }
  }
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_ipopt_decode_1ssrr(const lcrzo_ipopt ipopt,
			    lcrzo_uint8 nboctipopt,
			    lcrzo_uint8 *pnbiplaffectes,
			    lcrzo_uint8 *ppointeur,
			    lcrzo_ipl *pipl1,
			    lcrzo_ipl *pipl2,
			    lcrzo_ipl *pipl3,
			    lcrzo_ipl *pipl4,
			    lcrzo_ipl *pipl5,
			    lcrzo_ipl *pipl6,
			    lcrzo_ipl *pipl7,
			    lcrzo_ipl *pipl8,
			    lcrzo_ipl *pipl9)
{ lcrzo_ipa ipa;
  lcrzo_uint8 nbiplaffectes;
  int i;

  /*parameters verification*/
  if (ipopt==NULL && nboctipopt) return(LCRZO_ERR_PANULLPTRSIZE);

  /*taille nulle : erreur*/
  if (nboctipopt==0)
    return(LCRZO_ERR_OKNOTDECODED);

  /*ce n'est pas l'option cherchee*/
  if (ipopt[0]!=137)
    return(LCRZO_ERR_OKNOTDECODED);

  /*taille trop courte ou trop longue: erreur*/
  if ( nboctipopt<=2 || ipopt[1]<=2 || ipopt[1]>nboctipopt )
    return(LCRZO_ERR_OKNOTDECODED);
   
  /*si la taille n'est pas de la forme 4*i+3 : erreur*/
  if ( (ipopt[1]-3) % 4 )    
    return(LCRZO_ERR_OKNOTDECODED);

  /*on affecte les ipli*/
  nbiplaffectes=(lcrzo_uint8)( (ipopt[1]-3)/4 );
  if (pnbiplaffectes!=NULL) *pnbiplaffectes=nbiplaffectes;
  if (ppointeur!=NULL) *ppointeur=ipopt[2];
  for ( i=1 ; i<=nbiplaffectes ; i++ )
  { ipa[0]=ipopt[4*i-1];
    ipa[1]=ipopt[4*i];
    ipa[2]=ipopt[4*i+1];
    ipa[3]=ipopt[4*i+2];
    switch(i)
    { case 1: lcrzo_er(lcrzo_ipl_init_ipa(ipa, pipl1)); break;
      case 2: lcrzo_er(lcrzo_ipl_init_ipa(ipa, pipl2)); break;
      case 3: lcrzo_er(lcrzo_ipl_init_ipa(ipa, pipl3)); break;
      case 4: lcrzo_er(lcrzo_ipl_init_ipa(ipa, pipl4)); break;
      case 5: lcrzo_er(lcrzo_ipl_init_ipa(ipa, pipl5)); break;
      case 6: lcrzo_er(lcrzo_ipl_init_ipa(ipa, pipl6)); break;
      case 7: lcrzo_er(lcrzo_ipl_init_ipa(ipa, pipl7)); break;
      case 8: lcrzo_er(lcrzo_ipl_init_ipa(ipa, pipl8)); break;
      case 9: lcrzo_er(lcrzo_ipl_init_ipa(ipa, pipl9)); break;
      default: return(LCRZO_ERR_OKNOTDECODED); 
    }
  }
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_ipopt_decode_1rr(const lcrzo_ipopt ipopt,
			  lcrzo_uint8 nboctipopt,
			  lcrzo_uint8 *pnbiplaffectes,
			  lcrzo_uint8 *ppointeur,
			  lcrzo_ipl *pipl1,
			  lcrzo_ipl *pipl2,
			  lcrzo_ipl *pipl3,
			  lcrzo_ipl *pipl4,
			  lcrzo_ipl *pipl5,
			  lcrzo_ipl *pipl6,
			  lcrzo_ipl *pipl7,
			  lcrzo_ipl *pipl8,
			  lcrzo_ipl *pipl9)
{ lcrzo_ipa ipa;
  lcrzo_uint8 nbiplaffectes;
  int i;

  /*parameters verification*/
  if (ipopt==NULL && nboctipopt) return(LCRZO_ERR_PANULLPTRSIZE);

  /*taille nulle : erreur*/
  if (nboctipopt==0)
    return(LCRZO_ERR_OKNOTDECODED);

  /*ce n'est pas l'option cherchee*/
  if (ipopt[0]!=7)
    return(LCRZO_ERR_OKNOTDECODED);

  /*taille trop courte ou trop longue: erreur*/
  if ( nboctipopt<=2 || ipopt[1]<=2 || ipopt[1]>nboctipopt )
    return(LCRZO_ERR_OKNOTDECODED);
   
  /*si la taille n'est pas de la forme 4*i+3 : erreur*/
  if ( (ipopt[1]-3) % 4 )    
    return(LCRZO_ERR_OKNOTDECODED);

  /*on affecte les ipli*/
  nbiplaffectes=(lcrzo_uint8)( (ipopt[1]-3)/4 );
  if (pnbiplaffectes!=NULL) *pnbiplaffectes=nbiplaffectes;
  if (ppointeur!=NULL) *ppointeur=ipopt[2];
  for ( i=1 ; i<=nbiplaffectes ; i++ )
  { ipa[0]=ipopt[4*i-1];
    ipa[1]=ipopt[4*i];
    ipa[2]=ipopt[4*i+1];
    ipa[3]=ipopt[4*i+2];
    switch(i)
    { case 1: lcrzo_er(lcrzo_ipl_init_ipa(ipa, pipl1)); break;
      case 2: lcrzo_er(lcrzo_ipl_init_ipa(ipa, pipl2)); break;
      case 3: lcrzo_er(lcrzo_ipl_init_ipa(ipa, pipl3)); break;
      case 4: lcrzo_er(lcrzo_ipl_init_ipa(ipa, pipl4)); break;
      case 5: lcrzo_er(lcrzo_ipl_init_ipa(ipa, pipl5)); break;
      case 6: lcrzo_er(lcrzo_ipl_init_ipa(ipa, pipl6)); break;
      case 7: lcrzo_er(lcrzo_ipl_init_ipa(ipa, pipl7)); break;
      case 8: lcrzo_er(lcrzo_ipl_init_ipa(ipa, pipl8)); break;
      case 9: lcrzo_er(lcrzo_ipl_init_ipa(ipa, pipl9)); break;
      default: return(LCRZO_ERR_OKNOTDECODED); 
    }
  }
  return(LCRZO_ERR_OK);
}

int lcrzo_ipopt_decode_1time(const lcrzo_ipopt ipopt,
			    lcrzo_uint8 nboctipopt,
			    lcrzo_uint8 *pnbtimestampaffectes,
			    lcrzo_uint8 *ppointeur,
			    lcrzo_uint8 *poverflow,
			    lcrzo_uint8 *pflag,
			    lcrzo_uint32 *ptimestamp1,
			    lcrzo_uint32 *ptimestamp2,
			    lcrzo_uint32 *ptimestamp3,
			    lcrzo_uint32 *ptimestamp4,
			    lcrzo_uint32 *ptimestamp5,
			    lcrzo_uint32 *ptimestamp6,
			    lcrzo_uint32 *ptimestamp7,
			    lcrzo_uint32 *ptimestamp8,
			    lcrzo_uint32 *ptimestamp9)
{ lcrzo_uint8 nbtimestampaffectes;
  int i;
  lcrzo_uint32 heure;

  /*parameters verification*/
  if (ipopt==NULL && nboctipopt) return(LCRZO_ERR_PANULLPTRSIZE);

  /*taille nulle : erreur*/
  if (nboctipopt==0)
    return(LCRZO_ERR_OKNOTDECODED);

  /*ce n'est pas l'option cherchee*/
  if (ipopt[0]!=68)
    return(LCRZO_ERR_OKNOTDECODED);

  /*taille trop courte ou trop longue: erreur*/
  if ( nboctipopt<=3 || ipopt[1]<=3 || ipopt[1]>nboctipopt )
    return(LCRZO_ERR_OKNOTDECODED);
   
  /*si la taille n'est pas de la forme 4*i : erreur*/
  if ( ipopt[1] % 4 )    
    return(LCRZO_ERR_OKNOTDECODED);

  /*si le flag est different de 0, autre type*/
  if ( ipopt[3]&0xF )
    return(LCRZO_ERR_OKNOTDECODED);

  /*on affecte les timestamp*/
  nbtimestampaffectes=(lcrzo_uint8)( ipopt[1]/4 - 1 );
  if (pnbtimestampaffectes!=NULL) *pnbtimestampaffectes=nbtimestampaffectes;
  if (ppointeur!=NULL) *ppointeur=ipopt[2];
  if (poverflow!=NULL) *poverflow=(lcrzo_uint8)( ipopt[3]>>4 );
  if (pflag!=NULL) *pflag=(lcrzo_uint8)( ipopt[3]&0xF );
  for ( i=1 ; i<=nbtimestampaffectes ; i++ )
  { heure = ipopt[4*i]<<24 | ipopt[4*i+1]<<16 |
	   ipopt[4*i+2]<<8 | ipopt[4*i+3] ;
    switch(i)
    { case 1: if (ptimestamp1!=NULL) *ptimestamp1=heure; break;
      case 2: if (ptimestamp2!=NULL) *ptimestamp2=heure; break;
      case 3: if (ptimestamp3!=NULL) *ptimestamp3=heure; break;
      case 4: if (ptimestamp4!=NULL) *ptimestamp4=heure; break;
      case 5: if (ptimestamp5!=NULL) *ptimestamp5=heure; break;
      case 6: if (ptimestamp6!=NULL) *ptimestamp6=heure; break;
      case 7: if (ptimestamp7!=NULL) *ptimestamp7=heure; break;
      case 8: if (ptimestamp8!=NULL) *ptimestamp8=heure; break;
      case 9: if (ptimestamp9!=NULL) *ptimestamp9=heure; break;
      default: return(LCRZO_ERR_OKNOTDECODED); 
    }
  }

  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_ipopt_decode_1timeip(const lcrzo_ipopt ipopt,
			      lcrzo_uint8 nboctipopt,
			      lcrzo_uint8  *pnbtimestampaffectes,
			      lcrzo_uint8  *ppointeur,
			      lcrzo_uint8  *poverflow,
			      lcrzo_uint8  *pflag,
			      lcrzo_ipl    *pipl1,
			      lcrzo_uint32 *ptimestamp1,
			      lcrzo_ipl    *pipl2,
			      lcrzo_uint32 *ptimestamp2,
			      lcrzo_ipl    *pipl3,
			      lcrzo_uint32 *ptimestamp3,
			      lcrzo_ipl    *pipl4,
			      lcrzo_uint32 *ptimestamp4)
{ lcrzo_uint8 nbtimestampaffectes;
  int i;
  lcrzo_uint32 heure;
  lcrzo_ipa ipa;

  /*parameters verification*/
  if (ipopt==NULL && nboctipopt) return(LCRZO_ERR_PANULLPTRSIZE);

  /*taille nulle : erreur*/
  if (nboctipopt==0)
    return(LCRZO_ERR_OKNOTDECODED);

  /*ce n'est pas l'option cherchee*/
  if (ipopt[0]!=68)
    return(LCRZO_ERR_OKNOTDECODED);

  /*taille trop courte ou trop longue: erreur*/
  if ( nboctipopt<=3 || ipopt[1]<=3 || ipopt[1]>nboctipopt )
    return(LCRZO_ERR_OKNOTDECODED);
   
  /*si la taille n'est pas de la forme 4*i : erreur*/
  if ( ipopt[1] % 4 )    
    return(LCRZO_ERR_OKNOTDECODED);

  /*si le flag est different de 1 ou 3, c'est un autre type*/
  if ( (ipopt[3]&0xF)!=1 && (ipopt[3]&0xF)!=3 )
    return(LCRZO_ERR_OKNOTDECODED);

  /*on affecte les timestamp*/
  nbtimestampaffectes=(lcrzo_uint8)( (ipopt[1]-4)/8 );
  if (pnbtimestampaffectes!=NULL) *pnbtimestampaffectes=nbtimestampaffectes;
  if (ppointeur!=NULL) *ppointeur=ipopt[2];
  if (poverflow!=NULL) *poverflow=(lcrzo_uint8)( ipopt[3]>>4 );
  if (pflag!=NULL) *pflag=(lcrzo_uint8)( ipopt[3]&0xF );
  for ( i=1 ; i<=nbtimestampaffectes ; i++ )
  { ipa[0]=ipopt[8*i-4];
    ipa[1]=ipopt[8*i-3];
    ipa[2]=ipopt[8*i-2];
    ipa[3]=ipopt[8*i-1];
    heure = ipopt[8*i]<<24 | ipopt[8*i+1]<<16 |
	   ipopt[8*i+2]<<8 | ipopt[8*i+3] ;
    switch(i)
    { case 1:
        lcrzo_er(lcrzo_ipl_init_ipa(ipa, pipl1));
        if (ptimestamp1!=NULL) *ptimestamp1=heure;
	break;
      case 2:
        lcrzo_er(lcrzo_ipl_init_ipa(ipa, pipl2));
        if (ptimestamp2!=NULL) *ptimestamp2=heure;
        break;
      case 3:
        lcrzo_er(lcrzo_ipl_init_ipa(ipa, pipl3)); 
        if (ptimestamp3!=NULL) *ptimestamp3=heure;
        break;
      case 4:
        lcrzo_er(lcrzo_ipl_init_ipa(ipa, pipl4));
        if (ptimestamp4!=NULL) *ptimestamp4=heure;
        break;
      default: return(LCRZO_ERR_OKNOTDECODED); 
    }
  }

  return(LCRZO_ERR_OK);
}


/*-------------------------------------------------------------*/
int lcrzo_ipopt_decode_noop(const lcrzo_ipopt ipopt,
			   lcrzo_uint8 nboctipopt,
			   lcrzo_uint8 *pnboctetsnoop)
{ lcrzo_ipopt tabtravail;
  lcrzo_uint8 nbocttravail, nboctetsnoop;
  int retour;

  /*parameters verification*/
  if (ipopt==NULL && nboctipopt) return(LCRZO_ERR_PANULLPTRSIZE);
  lcrzo_ipopt_verifbof(nboctipopt);

  /*initialisation du tableau de travail*/
  memcpy(tabtravail, ipopt, nboctipopt);
  nbocttravail=nboctipopt;

  /*on parcourt*/
  nboctetsnoop=0;
  while (nbocttravail)
  { /*on cherche a decoder*/
    retour=lcrzo_ipopt_decode_1noop(tabtravail, nbocttravail);
    if (retour==LCRZO_ERR_OK ) nboctetsnoop++;
    /*on passe a l'option suivante*/
    lcrzo_er(lcrzo_priv_ipopt_passeoptionsuivante(tabtravail, nbocttravail,
						   tabtravail,
						   &nbocttravail));
  }

  /*pas de noop*/
  if (nboctetsnoop==0)
    return(LCRZO_ERR_OKNOTDECODED);

  if (pnboctetsnoop!=NULL) *pnboctetsnoop=nboctetsnoop;
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_ipopt_decode_lsrr(const lcrzo_ipopt ipopt,
			   lcrzo_uint8 nboctipopt,
			   lcrzo_uint8 *pnbiplaffectes,
			   lcrzo_uint8 *ppointeur,
			   lcrzo_ipl *pipl1,
			   lcrzo_ipl *pipl2,
			   lcrzo_ipl *pipl3,
			   lcrzo_ipl *pipl4,
			   lcrzo_ipl *pipl5,
			   lcrzo_ipl *pipl6,
			   lcrzo_ipl *pipl7,
			   lcrzo_ipl *pipl8,
			   lcrzo_ipl *pipl9)
{ lcrzo_ipopt tabtravail;
  lcrzo_uint8 nbocttravail;
  int retour;

  /*parameters verification*/
  if (ipopt==NULL && nboctipopt) return(LCRZO_ERR_PANULLPTRSIZE);
  lcrzo_ipopt_verifbof(nboctipopt);

  /*initialisation du tableau de travail*/
  memcpy(tabtravail, ipopt, nboctipopt);
  nbocttravail=nboctipopt;

  /*on parcours jusqu'a trouver une option lsrr*/
  while (nbocttravail)
  { /*on cherche a decoder*/
    retour=lcrzo_ipopt_decode_1lsrr(tabtravail, nbocttravail,
				   pnbiplaffectes,
				   ppointeur,
				   pipl1, pipl2, pipl3, pipl4, pipl5,
				   pipl6, pipl7, pipl8, pipl9);
    if (retour==LCRZO_ERR_OK ) return(LCRZO_ERR_OK);
    /*on passe a l'option suivante*/
    lcrzo_er(lcrzo_priv_ipopt_passeoptionsuivante(tabtravail, nbocttravail,
						   tabtravail,
						   &nbocttravail));
  }

  /*on a rien trouve*/
  return(LCRZO_ERR_OKNOTDECODED);
}

/*-------------------------------------------------------------*/
int lcrzo_ipopt_decode_ssrr(const lcrzo_ipopt ipopt,
			   lcrzo_uint8 nboctipopt,
			   lcrzo_uint8 *pnbiplaffectes,
			   lcrzo_uint8 *ppointeur,
			   lcrzo_ipl *pipl1,
			   lcrzo_ipl *pipl2,
			   lcrzo_ipl *pipl3,
			   lcrzo_ipl *pipl4,
			   lcrzo_ipl *pipl5,
			   lcrzo_ipl *pipl6,
			   lcrzo_ipl *pipl7,
			   lcrzo_ipl *pipl8,
			   lcrzo_ipl *pipl9)
{ lcrzo_ipopt tabtravail;
  lcrzo_uint8 nbocttravail;
  int retour;

  /*parameters verification*/
  if (ipopt==NULL && nboctipopt) return(LCRZO_ERR_PANULLPTRSIZE);
  lcrzo_ipopt_verifbof(nboctipopt);

  /*initialisation du tableau de travail*/
  memcpy(tabtravail, ipopt, nboctipopt);
  nbocttravail=nboctipopt;

  /*on parcours jusqu'a trouver une option lsrr*/
  while (nbocttravail)
  { /*on cherche a decoder*/
    retour=lcrzo_ipopt_decode_1ssrr(tabtravail, nbocttravail,
				   pnbiplaffectes,
				   ppointeur,
				   pipl1, pipl2, pipl3, pipl4, pipl5,
				   pipl6, pipl7, pipl8, pipl9);
    if (retour==LCRZO_ERR_OK ) return(LCRZO_ERR_OK);
    /*on passe a l'option suivante*/
    lcrzo_er(lcrzo_priv_ipopt_passeoptionsuivante(tabtravail, nbocttravail,
						   tabtravail,
						   &nbocttravail));
  }

  /*on a rien trouve*/
  return(LCRZO_ERR_OKNOTDECODED);
}

/*-------------------------------------------------------------*/
int lcrzo_ipopt_decode_rr(const lcrzo_ipopt ipopt,
			 lcrzo_uint8 nboctipopt,
			 lcrzo_uint8 *pnbiplaffectes,
			 lcrzo_uint8 *ppointeur,
			 lcrzo_ipl *pipl1,
			 lcrzo_ipl *pipl2,
			 lcrzo_ipl *pipl3,
			 lcrzo_ipl *pipl4,
			 lcrzo_ipl *pipl5,
			 lcrzo_ipl *pipl6,
			 lcrzo_ipl *pipl7,
			 lcrzo_ipl *pipl8,
			 lcrzo_ipl *pipl9)
{ lcrzo_ipopt tabtravail;
  lcrzo_uint8 nbocttravail;
  int retour;

  /*parameters verification*/
  if (ipopt==NULL && nboctipopt) return(LCRZO_ERR_PANULLPTRSIZE);
  lcrzo_ipopt_verifbof(nboctipopt);

  /*initialisation du tableau de travail*/
  memcpy(tabtravail, ipopt, nboctipopt);
  nbocttravail=nboctipopt;

  /*on parcours jusqu'a trouver une option lsrr*/
  while (nbocttravail)
  { /*on cherche a decoder*/
    retour=lcrzo_ipopt_decode_1rr(tabtravail, nbocttravail,
				 pnbiplaffectes,
				 ppointeur,
				 pipl1, pipl2, pipl3, pipl4, pipl5,
				 pipl6, pipl7, pipl8, pipl9);
    if (retour==LCRZO_ERR_OK ) return(LCRZO_ERR_OK);
    /*on passe a l'option suivante*/
    lcrzo_er(lcrzo_priv_ipopt_passeoptionsuivante(tabtravail, nbocttravail,
						   tabtravail,
						   &nbocttravail));
  }

  /*on a rien trouve*/
  return(LCRZO_ERR_OKNOTDECODED);
}

/*-------------------------------------------------------------*/
int lcrzo_ipopt_decode_time(const lcrzo_ipopt ipopt,
			   lcrzo_uint8 nboctipopt,
			   lcrzo_uint8 *pnbtimestampaffectes,
			   lcrzo_uint8 *ppointeur,
			   lcrzo_uint8 *poverflow,
			   lcrzo_uint8 *pflag,
			   lcrzo_uint32 *ptimestamp1,
			   lcrzo_uint32 *ptimestamp2,
			   lcrzo_uint32 *ptimestamp3,
			   lcrzo_uint32 *ptimestamp4,
			   lcrzo_uint32 *ptimestamp5,
			   lcrzo_uint32 *ptimestamp6,
			   lcrzo_uint32 *ptimestamp7,
			   lcrzo_uint32 *ptimestamp8,
			   lcrzo_uint32 *ptimestamp9)
{ lcrzo_ipopt tabtravail;
  lcrzo_uint8 nbocttravail;
  int retour;

  /*parameters verification*/
  if (ipopt==NULL && nboctipopt) return(LCRZO_ERR_PANULLPTRSIZE);
  lcrzo_ipopt_verifbof(nboctipopt);

  /*initialisation du tableau de travail*/
  memcpy(tabtravail, ipopt, nboctipopt);
  nbocttravail=nboctipopt;

  /*on parcours jusqu'a trouver une option lsrr*/
  while (nbocttravail)
  { /*on cherche a decoder*/
    retour=lcrzo_ipopt_decode_1time(tabtravail, nbocttravail,
				   pnbtimestampaffectes, ppointeur,
				   poverflow, pflag,
				   ptimestamp1, ptimestamp2, ptimestamp3,
				   ptimestamp4, ptimestamp5, ptimestamp6,
				   ptimestamp7, ptimestamp8, ptimestamp9);
    if (retour==LCRZO_ERR_OK ) return(LCRZO_ERR_OK);
    /*on passe a l'option suivante*/
    lcrzo_er(lcrzo_priv_ipopt_passeoptionsuivante(tabtravail, nbocttravail,
						   tabtravail,
						   &nbocttravail));
  }

  /*on a rien trouve*/
  return(LCRZO_ERR_OKNOTDECODED);
}

/*-------------------------------------------------------------*/
int lcrzo_ipopt_decode_timeip(const lcrzo_ipopt ipopt,
			     lcrzo_uint8 nboctipopt,
			     lcrzo_uint8  *pnbtimestampaffectes,
			     lcrzo_uint8  *ppointeur,
			     lcrzo_uint8  *poverflow,
			     lcrzo_uint8  *pflag,
			     lcrzo_ipl    *pipl1,
			     lcrzo_uint32 *ptimestamp1,
			     lcrzo_ipl    *pipl2,
			     lcrzo_uint32 *ptimestamp2,
			     lcrzo_ipl    *pipl3,
			     lcrzo_uint32 *ptimestamp3,
			     lcrzo_ipl    *pipl4,
			     lcrzo_uint32 *ptimestamp4)
{ lcrzo_ipopt tabtravail;
  lcrzo_uint8 nbocttravail;
  int retour;

  /*parameters verification*/
  if (ipopt==NULL && nboctipopt) return(LCRZO_ERR_PANULLPTRSIZE);
  lcrzo_ipopt_verifbof(nboctipopt);

  /*initialisation du tableau de travail*/
  memcpy(tabtravail, ipopt, nboctipopt);
  nbocttravail=nboctipopt;

  /*on parcours jusqu'a trouver une option lsrr*/
  while (nbocttravail)
  { /*on cherche a decoder*/
    retour=lcrzo_ipopt_decode_1timeip(tabtravail, nbocttravail,
				     pnbtimestampaffectes, ppointeur,
				     poverflow, pflag,
				     pipl1, ptimestamp1,
				     pipl2, ptimestamp2,
				     pipl3, ptimestamp3,
				     pipl4, ptimestamp4);
    if (retour==LCRZO_ERR_OK ) return(LCRZO_ERR_OK);
    /*on passe a l'option suivante*/
    lcrzo_er(lcrzo_priv_ipopt_passeoptionsuivante(tabtravail, nbocttravail,
						   tabtravail,
						   &nbocttravail));
  }

  /*on a rien trouve*/
  return(LCRZO_ERR_OKNOTDECODED);
}


/*-------------------------------------------------------------*/
int lcrzo_ipopt_decode_unknown(const lcrzo_ipopt ipopt,
			       lcrzo_uint8 nboctipopt,
			       lcrzo_ipopt ipoptinconnue,
			       lcrzo_uint8 *pnboctipoptinconnue)
{ lcrzo_ipopt tabtravail;
  lcrzo_uint8 nbocttravail, nboctipoptinconnue;
  int optionreconnue, retour;
 
  /*parameters verification*/
  if (ipopt==NULL && nboctipopt) return(LCRZO_ERR_PANULLPTRSIZE);
  lcrzo_ipopt_verifbof(nboctipopt);

  /*initialisation du tableau de travail*/
  memcpy(tabtravail, ipopt, nboctipopt);
  nbocttravail=nboctipopt;

  /*on parcourt*/
  nboctipoptinconnue=0;
  while (nbocttravail)
  { optionreconnue=0;
    /*on regarde si l'option courante est reconnue*/
    retour=lcrzo_ipopt_decode_1null(tabtravail, nbocttravail);
    if (retour==LCRZO_ERR_OK) optionreconnue=1;
    if (!optionreconnue)
    { retour=lcrzo_ipopt_decode_1noop(tabtravail, nbocttravail);
      if (retour==LCRZO_ERR_OK) optionreconnue=1;
    }
    if (!optionreconnue)
    { retour=lcrzo_ipopt_decode_1lsrr(tabtravail, nbocttravail, NULL,NULL,
				     NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
				     NULL);
      if (retour==LCRZO_ERR_OK) optionreconnue=1;
    }
    if (!optionreconnue)
    { retour=lcrzo_ipopt_decode_1ssrr(tabtravail, nbocttravail, NULL,NULL,
				     NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
				     NULL);
      if (retour==LCRZO_ERR_OK) optionreconnue=1;
    }
    if (!optionreconnue)
    { retour=lcrzo_ipopt_decode_1rr(tabtravail, nbocttravail, NULL,NULL,
				   NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
				   NULL);
      if (retour==LCRZO_ERR_OK) optionreconnue=1;
    }
    if (!optionreconnue)
    { retour=lcrzo_ipopt_decode_1time(tabtravail, nbocttravail, NULL,NULL,
				     NULL,NULL,NULL,NULL,NULL,NULL,NULL,
				     NULL,NULL,NULL,NULL);
      if (retour==LCRZO_ERR_OK) optionreconnue=1;
    }
    if (!optionreconnue)
    { retour=lcrzo_ipopt_decode_1timeip(tabtravail, nbocttravail, NULL,
				       NULL,NULL,NULL,NULL,NULL,NULL,
				       NULL,NULL,NULL,NULL,NULL);
      if (retour==LCRZO_ERR_OK) optionreconnue=1;
    }

    /*si l'option courante n'est pas reconnue*/
    if (!optionreconnue)
    { /*erreur : on met toute la fin*/
      if ( nbocttravail<=2 || tabtravail[1]<=2 || tabtravail[1]>nbocttravail )
      { if (ipoptinconnue!=NULL)
	{ memcpy(ipoptinconnue + nboctipoptinconnue, 
		 tabtravail, nbocttravail);
	}
        nboctipoptinconnue=(lcrzo_uint8)( nboctipoptinconnue+nbocttravail );
	if (pnboctipoptinconnue!=NULL)
	{ *pnboctipoptinconnue=nboctipoptinconnue;
	}
        return(LCRZO_ERR_OK);
      }      
      /*sinon, on concatene*/
      else
      { if (ipoptinconnue!=NULL)
	{ memcpy(ipoptinconnue + nboctipoptinconnue, 
		 tabtravail, tabtravail[1]);
	}
        nboctipoptinconnue=(lcrzo_uint8)( nboctipoptinconnue+tabtravail[1] );
      }
    }

    /*on passe a l'option suivante*/
    lcrzo_er(lcrzo_priv_ipopt_passeoptionsuivante(tabtravail, nbocttravail,
						   tabtravail,
						   &nbocttravail));
  }

  /*on a tout reconnu*/
  if (nboctipoptinconnue==0)
    return(LCRZO_ERR_OKNOTDECODED);
  /*sinon, on affecte le nombre avant de quitter*/
  if (pnboctipoptinconnue!=NULL) *pnboctipoptinconnue=nboctipoptinconnue;
  return(LCRZO_ERR_OK);
}

