/*
		                  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"

/*-------------------------------------------------------------*/
#if LCRZODEF_LIBPCAPINSTALLED==1
 #include <pcap.h>
 #include "sysdep/lcrzo_priv_sniff_nextmnormal.c"
 #include "sysdep/lcrzo_priv_sniff_nextmreasip.c"
 #include "sysdep/lcrzo_priv_sniff_nextmreortcp.c"
#endif

/*-------------------------------------------------------------*/
#if LCRZODEF_LIBPCAPINSTALLED==1
int lcrzo_priv_global_set_errmsglcrzo_filter(lcrzo_conststring bad);
int lcrzo_priv_global_set_errmsglcrzo_filter(lcrzo_conststring bad)
{ int ret;
  lcrzo_int16 language;
  lcrzo_string msg;

  lcrzo_er(lcrzo_global_get_language(&language));
  if ( language==LCRZO_GLOBAL_LANG_FR ) 
  { ret=lcrzo_string_initm_text("Le mauvais filtre est : ", &msg);
  }
  else
  { ret=lcrzo_string_initm_text("The bad filter is : ", &msg);
  }
  if (ret==LCRZO_ERR_OK)
  { ret=lcrzo_string_appendm_text(bad, &msg);
    if (ret==LCRZO_ERR_OK)
    { ret=lcrzo_priv_global_set_errmsglcrzo(msg);
    }
    lcrzo_string_free(msg);
  }

  return(ret);
}
#endif

/*-------------------------------------------------------------*/
#if LCRZODEF_LIBPCAPINSTALLED==1
int lcrzo_priv_affdebugsniff(lcrzo_sniff *psniff);
int lcrzo_priv_affdebugsniff(lcrzo_sniff *psniff)
{ printf("lcrzo_priv_paqipvus:\n");
  lcrzo_epr(lcrzo_list_loop_all(&(psniff->seenippackets),
				&lcrzo_priv_affpaqipvus, NULL));
  printf("lcrzo_priv_waitingippackets:\n");
  lcrzo_epr(lcrzo_list_loop_all(&(psniff->waitingippackets),
				&lcrzo_priv_affpaqipattente, NULL));
  printf("lcrzo_priv_paqtcpvus:\n");
  lcrzo_epr(lcrzo_list_loop_all(&(psniff->seentcppackets),
				&lcrzo_priv_affpaqtcpvus, NULL));
  printf("lcrzo_priv_waitingtcppackets:\n");
  lcrzo_epr(lcrzo_list_loop_all(&(psniff->waitingtcppackets),
				&lcrzo_priv_affpaqtcpattente, NULL));
  return(LCRZO_ERR_OK);
}
#endif

/*-------------------------------------------------------------*/
#include "sysdep/lcrzo_priv_wait_sniff_wait.c"
#include "sysdep/lcrzo_priv_wait_sniff_read.c"

/*-------------------------------------------------------------*/
#include "sysdep/lcrzo_sniff_init.c"
#include "sysdep/lcrzo_sniff_close.c"

/*-------------------------------------------------------------*/
int lcrzo_sniff_nextm(lcrzo_sniff *psniff,
 		      lcrzo_time *pmaxwaitingtime, 
		      lcrzo_data *pdataout,
		      lcrzo_int32 *pdataoutsize)
#if LCRZODEF_LIBPCAPINSTALLED==1
{ lcrzo_wait waitread;
  lcrzo_bool mayread;

  /* parameter verification */
  if (psniff==NULL) return(LCRZO_ERR_PANULLPTR);

  lcrzo_er(lcrzo_wait_init_sniff_read(psniff, &waitread));
  lcrzo_er(lcrzo_wait_wait1(&waitread, pmaxwaitingtime, &mayread));
  lcrzo_er(lcrzo_wait_close(&waitread));
  if (!mayread) return(LCRZO_ERR_OKTEMPDATAEND);

  /* exit with data */ 
 lcrzo_er(lcrzo_priv_storeddata_extract(&(psniff->storeddata),
					 &(psniff->storeddatasize), 
                                         psniff->dataend,
					 pdataout, pdataoutsize));

  return(LCRZO_ERR_OK);
}
#else
{ return (LCRZO_ERR_IEUNIMPLEMENTED);
  /* just for the compiler warning */
  psniff=psniff;
  pmaxwaitingtime=pmaxwaitingtime;
  pdataout=pdataout;
  pdataoutsize=pdataoutsize;
}
#endif

/*-------------------------------------------------------------*/
#if LCRZODEF_LIBPCAPINSTALLED==1
int lcrzo_sniff_loop(const lcrzo_device device,
		     lcrzo_int32 nbmaxoct,
		     lcrzo_int16 snifftype,
		     const char *filter, 
		     lcrzo_time *pmaxwaitingtime, 
		     int (*pfonc)(lcrzo_constdata tab,
				  lcrzo_int32 nboct,
				  void *pinfos),
		     void *pinfos)
{ lcrzo_sniff sniff;
  int retour;
  lcrzo_data ptr;
  lcrzo_int32 ptrsize;

  /*parameters verification*/
  if (pfonc==NULL) return(LCRZO_ERR_PANULLPTR);

  lcrzo_er(lcrzo_sniff_init(device, nbmaxoct, snifftype, filter, &sniff));
  retour=lcrzo_sniff_nextm(&sniff, pmaxwaitingtime, &ptr, &ptrsize);
  /*lorsque l'on est bloquant, on ne doit sortir qu'avec LCRZO_ERR_OK*/
  while( retour==LCRZO_ERR_OK || retour==LCRZO_ERR_OKTEMPDATAEND )
  { retour=(*pfonc)(ptr, ptrsize, pinfos);
    lcrzo_data_free(ptr);
    if ( retour!=LCRZO_ERR_OK )
    { lcrzo_er(lcrzo_sniff_close(&sniff));
      return(retour);
    }
    retour=lcrzo_sniff_nextm(&sniff, pmaxwaitingtime, &ptr, &ptrsize);
  }
  /*atteint en cas d'erreur*/
  lcrzo_er(lcrzo_sniff_close(&sniff));
  return (retour);
}
#else
int lcrzo_sniff_loop(const lcrzo_device device,
		     lcrzo_int32 nbmaxoct,
		     int snifftype,
		     const char *filter, 
		     lcrzo_time *pmaxwaitingtime, 
		     int (*pfonc)(lcrzo_constdata tab,
				  lcrzo_int32 nboct,
				  void *pinfos),
		     void *pinfos)
{ return(lcrzo_priv_checkpcapincluded("lcrzo_sniff_loop"));
  /* just for the compiler warning */
  device=device;
  nbmaxoct=nbmaxoct;
  snifftype=snifftype;
  filter=filter;
  pmaxwaitingtime=pmaxwaitingtime;
  pfonc=pfonc;
  pinfos=pinfos;
}
#endif

/*-------------------------------------------------------------*/
int lcrzo_sniff_set_ipreas1timeout(lcrzo_sniff *psniff,
				   lcrzo_uint16 timeout)
{ if (psniff==NULL) return(LCRZO_ERR_PANULLPTR);
  psniff->para_ipreastimeout1=timeout;
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_sniff_set_ipreas2timeout(lcrzo_sniff *psniff,
				   lcrzo_uint16 timeout)
{ if (psniff==NULL) return(LCRZO_ERR_PANULLPTR);
  psniff->para_ipreastimeout2=timeout;
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_sniff_set_tcpreor1timeout(lcrzo_sniff *psniff,
				    lcrzo_uint16 timeout)
{ if (psniff==NULL) return(LCRZO_ERR_PANULLPTR);
  psniff->para_tcpreortimeout1=timeout;
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_sniff_set_tcpreor2timeout(lcrzo_sniff *psniff,
				    lcrzo_uint16 timeout)
{ if (psniff==NULL) return(LCRZO_ERR_PANULLPTR);
  psniff->para_tcpreortimeout2=timeout;
  return(LCRZO_ERR_OK);
}


/*-------------------------------------------------------------*/
int lcrzo_sniff_get_ipreas1timeout(lcrzo_sniff *psniff,
				   lcrzo_uint16 *ptimeout)
{ if (ptimeout!=NULL) *ptimeout=psniff->para_ipreastimeout1;
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_sniff_get_ipreas2timeout(lcrzo_sniff *psniff,
				   lcrzo_uint16 *ptimeout)
{ if (ptimeout!=NULL) *ptimeout=psniff->para_ipreastimeout2;
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_sniff_get_tcpreor1timeout(lcrzo_sniff *psniff,
				    lcrzo_uint16 *ptimeout)
{ if (ptimeout!=NULL) *ptimeout=psniff->para_tcpreortimeout1;
  return(LCRZO_ERR_OK);
}

/*-------------------------------------------------------------*/
int lcrzo_sniff_get_tcpreor2timeout(lcrzo_sniff *psniff,
				    lcrzo_uint16 *ptimeout)
{ if (ptimeout!=NULL) *ptimeout=psniff->para_tcpreortimeout2;
  return(LCRZO_ERR_OK);
}


