/*en    Laurent Constantin's network library (lcrzo)
                 lcrzo_sniff module

  Functions herein allow to sniff network packets.
*/
/*fr    Bibliotheque reseau de Laurent Constantin (lcrzo)
                 Module lcrzo_sniff

  Les fonctions presentes dans ce module permettent de sniffer 
  le reseau.
*/

/*-------------------------------------------------------------*/
/*en definition of a lcrzo_sniff. You should not use its 
   fields directly. */
/*fr definition d'un lcrzo_sniff. Vous ne devriez pas utiliser
   directement ses champs. */
typedef struct
{ void *ppcapt;
  lcrzo_list seenippackets;
  lcrzo_list waitingippackets;
  lcrzo_list seentcppackets;
  lcrzo_list waitingtcppackets;
  lcrzo_uint16 para_ipreastimeout1;
  lcrzo_uint16 para_ipreastimeout2;
  lcrzo_uint16 para_tcpreortimeout1;
  lcrzo_uint16 para_tcpreortimeout2;
  lcrzo_int32 linktype;
  lcrzo_int16 snifftype;
  lcrzo_bool dataend;
  lcrzo_data storeddata;
  lcrzo_int32 storeddatasize;
  int pcapfd;
} lcrzo_sniff;

/*-------------------------------------------------------------*/
/*EN************************************************************
 * Note about sniff filters :                                  *
 * Filters permit to select network packets we sniff.          *
 * Basic elements of a bpf filter are :                        *
 *    host 1.2.3.4                                             *
 *    net 192.168.10                                           *
 *    net 192.168.10.0 mask 255.255.255.0                      *
 *    net 192.168.10.0/24                                      *
 *    port 21                                                  *
 *    dst host 1.2.3.4                                         *
 *    src port 2345                                            *
 *    ether host a:b:c:d:e:f ("ether a:b:c:d:e:f" is not working)
 *    ether src aa:bb:cc:dd:ee:ff                              *
 *    ip                                                       *
 *    arp                                                      *
 *    rarp                                                     *
 *    tcp                                                      *
 *    icmp                                                     *
 *    udp                                                      *
 * Here are filter examples :                                  *
 *    host 1.2.3.4                                             *
 *    net 192.168 and icmp                                     *
 *    host 1.2.3.4 or dst port 80                              *
 *    (udp or tcp) and not host 1.2.3.4                        *
 ***************************************************************/
/*FR************************************************************
 * Note sur les filtres de sniff :                             *
 * Les filtres permettent de selectionner les paquets que l'on *
 * accepte de sniffer                                          *
 * Les elements de base d'un filtre bpf sont de la forme :     *
 *    host 1.2.3.4                                             *
 *    net 192.168.10                                           *
 *    net 192.168.10.0 mask 255.255.255.0                      *
 *    net 192.168.10.0/24                                      *
 *    port 21                                                  *
 *    dst host 1.2.3.4                                         *
 *    src port 2345                                            *
 *    ether host a:b:c:d:e:f ("ether a:b:c:d:e:f" marche pas)  *
 *    ether src aa:bb:cc:dd:ee:ff                              *
 *    ip                                                       *
 *    arp                                                      *
 *    rarp                                                     *
 *    tcp                                                      *
 *    icmp                                                     *
 *    udp                                                      *
 * Un filtre complet est donc par exemple :                    *
 *    host 1.2.3.4                                             *
 *    net 192.168 and icmp                                     *
 *    host 1.2.3.4 or dst port 80                              *
 *    (udp or tcp) and not host 1.2.3.4                        *
 ***************************************************************/

/*-------------------------------------------------------------*/
/*EN************************************************************
 * Note about LCRZO_SNIFF_TYPE_xx :                            *
 * The sniff functions can return several kinds of packets :   *
 *   LCRZO_SNIFF_TYPE_NORMAL :                                 *
 *    - return all the packets, as they are on the network     *
 *   LCRZO_SNIFF_TYPE_IPREAS :                                 *
 *    - reassemble fragmented IP packets                       *
 *    - remove duplicate IP packets                            *
 *    - do nothing with other packets                          *
 *   LCRZO_SNIFF_TYPE_TCPREOR :                                *
 *    - reassemble fragmented IP packets                       *
 *    - remove duplicate IP packets                            *
 *    - reorder sequences of TCP packets                       *
 *    - do nothing with other packets                          *
 ***************************************************************/
/*FR************************************************************
 * Note sur LCRZO_SNIFF_TYPE_xx :                              *
 * Les fonctions de sniff peuvent retourner differents types   *
 * de paquets :                                                *
 *   LCRZO_SNIFF_TYPE_NORMAL :                                 *
 *    - retourne tous les paquets comme ils transitent sur le  *
 *      reseau                                                 *
 *   LCRZO_SNIFF_TYPE_IPREAS :                                 *
 *    - reassemble les paquets IP fragmentes                   *
 *    - supprime les paquets IP en double                      *
 *    - ne fait rien avec les autres paquets                   *
 *   LCRZO_SNIFF_TYPE_TCPREOR :                                *
 *    - reassemble les paquets IP fragmentes                   *
 *    - supprime les paquets IP en double                      *
 *    - ne fait rien avec les autres paquets                   *
 *    - reordonne les sequences TCP                            *
 ***************************************************************/
#define LCRZO_SNIFF_TYPE_NORMAL  1
#define LCRZO_SNIFF_TYPE_IPREAS  2
#define LCRZO_SNIFF_TYPE_TCPREOR 3

/*-------------------------------------------------------------*/
/*en Name : lcrzo_sniff_init
   Description :
     Initialize a lcrzo_sniff.
   Input parameter(s) :
     device : device where we sniff
     maxsniffedsize : maximum size of sniffed packets
     snifftype : type of sniff (see above frame)
     filter : sniff filter ("" to sniff everything)
   Input/output parameter(s) :
   Output parameter(s) :
     *psniff : lcrzo_sniff initialized
   Normal return values :
     LCRZO_ERR_OK : ok
*/
/*fr Nom : lcrzo_sniff_init
   Description :
     Initialise un lcrzo_sniff.
   Parametre(s) d'entree :
     device : device ou l'on sniffe
     maxsniffedsize : taille maximale des donnees sniffees
     snifftype : type de sniff (cf. le cadre ci-dessus)
     filter : filtre de sniff ("" pour tout sniffer)
   Parametre(s) d'entree-sortie :
   Parametre(s) de sortie :
     *psniff : lcrzo_sniff initialise
   Valeurs de retour normales :
     LCRZO_ERR_OK : ok
*/
int lcrzo_sniff_init(lcrzo_constdevice device,
		     lcrzo_int32 maxsniffedsize,
		     lcrzo_int16 snifftype,
		     lcrzo_conststring filter, 
		     lcrzo_sniff *psniff);

/*en Name : lcrzo_sniff_close
   Description :
     Close a lcrzo_sniff.
   Input parameter(s) :
   Input/output parameter(s) :
     *psniff : lcrzo_sniff to close
   Output parameter(s) :
   Normal return values :
     LCRZO_ERR_OK : ok
*/
/*fr Nom : lcrzo_sniff_close
   Description :
     Ferme un lcrzo_sniff.
   Parametre(s) d'entree :
   Parametre(s) d'entree-sortie :
     *psniff : lcrzo_sniff a fermer
   Parametre(s) de sortie :
   Valeurs de retour normales :
     LCRZO_ERR_OK : ok
*/
int lcrzo_sniff_close(lcrzo_sniff *psniff);


/*en Name : lcrzo_sniff_nextm
   Description :
     Sniff one packet from the network.
   Input parameter(s) :
     *pmaxwaitingtime : maximum waiting time (can be a lcrzo_time,
                        LCRZO_WAIT_NODELAY or LCRZO_WAIT_INFINITE)
   Input/output parameter(s) :
     *psniff : lcrzo_sniff to use
   Output parameter(s) :
     *pdataout : pointer which will be malloced (so, the
                 memory will have to be freed by the
                 user with 'free(*pdataout)').
                 The allocated memory will be set with the read data
     *pdataoutsize : reached size of dataout
   Normal return values :
     LCRZO_ERR_OK : ok
     LCRZO_ERR_OKTEMPDATAEND : the function received nothing
                               before pmaxwaitingtime, so it 
                               exited without reading data
*/
/*fr Nom : lcrzo_sniff_nextm
   Description :
     Sniffe un paquet.
   Parametre(s) d'entree :
     *pmaxwaitingtime : temps maximum d'attente (peut etre un
                        lcrzo_time, LCRZO_WAIT_NODELAY ou
                        LCRZO_WAIT_INFINITE)
   Parametre(s) d'entree-sortie :
   Parametre(s) de sortie :
     *pdataout : pointeur qui sera alloue (la memoire
                 devra etre liberee par l'utilisateur 
                 avec 'free(*pdataout)').
                 Cette memoire allouee recevra les donnees lues
     *pdataoutsize : taille atteinte par dataout
   Valeurs de retour normales :
     LCRZO_ERR_OK : ok
     LCRZO_ERR_OKTEMPDATAEND : la fonction n'a pas recu de donnees
                               avant pmaxwaitingtime, donc on 
                               retourne sans donnees.
*/
int lcrzo_sniff_nextm(lcrzo_sniff *psniff,
 		      lcrzo_time *pmaxwaitingtime, 
		      lcrzo_data *pdataout,
		      lcrzo_int32 *pdataoutsize);

/*-------------------------------------------------------------*/
/*en Name : lcrzo_sniff_loop
   Description :
     Call a function for each sniffed packet.
   Input parameter(s) :
     device : device where we sniff
     maxsniffedsize : maximum size of sniffed packets
     filter : sniff filter ("" to sniff everything)
     beblocking : if we want to block until receiving data
     snifftype : type of sniff (see above frame)
     pfunc : memory address of the function which will be called
             for each sniffed packet. For
             each call, the first/second parameter ('data',
	     'datasize') will be set
             with the packet, and the third parameter ('pinfos')
             will be set with the optional parameter below.
   Input/output parameter(s) :
     pinfos : optional parameter (can be NULL) which will be
              used as the second parameter for *pfunc. This may be
              used to send information to *pfunc.
   Output parameter(s) :
   Normal return values :
     LCRZO_ERR_OK : ok
*/
/*fr Nom : lcrzo_sniff_loop
   Description :
     Appelle une fonction chaque paquet sniffe.
   Parametre(s) d'entree :
     device : device ou l'on sniffe
     maxsniffedsize : taille maximale des donnees sniffees
     filter : filtre de sniff ("" pour tout sniffer)
     beblocking : si on veut bloquer jusqu'a recevoir des donnees
     snifftype : type de sniff (cf. le cadre ci-dessus)
     pfunc : adresse memoire de la fonction appelee pour chaque
             paquet sniffe. Lors de chaque appel, le
	     premier/second parametre ('data', 'datasize') est 
             affecte avec le paquet sniffe, et le troisieme
             parametre ('pinfos') est affecte avec la valeur 
             de pinfos ci-dessous.
   Parametre(s) d'entree-sortie :
     pinfos : parametre optionnel (peut mettre NULL) qui sera
              passe en deuxieme parametre de pfunc. Il peut 
              servir a envoyer des informations a pfunc.
   Parametre(s) de sortie :
   Valeurs de retour normales :
     LCRZO_ERR_OK : ok
*/
int lcrzo_sniff_loop(lcrzo_constdevice device,
		     lcrzo_int32 maxsniffedsize, 
		     lcrzo_int16 snifftype,
		     lcrzo_conststring filter, 
		     lcrzo_time *pmaxwaitingtime, 
		     int (*pfunc)(lcrzo_constdata data,
				  lcrzo_int32 datasize,
				  void *pinfos),
		     void *pinfos);


/*-------------------------------------------------------------*/
/*EN************************************************************
 * Note about the following functions :                        *
 * The default values are correct for most applications.       *
 * You should modify their parameters only if you know         *
 * what you are doing.                                         *
 ***************************************************************/
/*FR************************************************************
 * Note sur les fonctions suivantes :                          *
 * Les valeurs par defaut sont correctes pour la majorite des  *
 * applications.                                               *
 * Vous ne devriez modifier les parametres que si vous savez   *
 * ce que vous faites.                                         *
 ***************************************************************/
/*en with LCRZO_SNIFF_TYPE_IPREAS, how long to keep 
   seen packets */
/*fr avec LCRZO_SNIFF_TYPE_IPREAS, duree durant laquelle
   les paquets vus doivent etre gardes */
int lcrzo_sniff_set_ipreas1timeout(lcrzo_sniff *psniff,
				   lcrzo_uint16 timeout);
int lcrzo_sniff_get_ipreas1timeout(lcrzo_sniff *psniff,
				   lcrzo_uint16 *ptimeout);

/*en with LCRZO_SNIFF_TYPE_IPREAS, how long to keep 
   waiting packets*/
/*fr avec LCRZO_SNIFF_TYPE_IPREAS, duree durant laquelle
   les paquets en attente de traitement doivent etre gardes */
int lcrzo_sniff_set_ipreas2timeout(lcrzo_sniff *psniff,
				   lcrzo_uint16 timeout);
int lcrzo_sniff_get_ipreas2timeout(lcrzo_sniff *psniff,
				   lcrzo_uint16 *ptimeout);

/*en with LCRZO_SNIFF_TYPE_TCPREOR, how long to keep 
   seen packets */
/*fr avec LCRZO_SNIFF_TYPE_TCPREOR, duree durant laquelle
   les paquets vus doivent etre gardes */
int lcrzo_sniff_set_tcpreor1timeout(lcrzo_sniff *psniff,
				    lcrzo_uint16 timeout);
int lcrzo_sniff_get_tcpreor1timeout(lcrzo_sniff *psniff,
				    lcrzo_uint16 *ptimeout);

/*en with LCRZO_SNIFF_TYPE_TCPREOR, how long to keep 
   waiting packets*/
/*fr avec LCRZO_SNIFF_TYPE_TCPREOR, duree durant laquelle
   les paquets en attente de traitement doivent etre gardes */
int lcrzo_sniff_set_tcpreor2timeout(lcrzo_sniff *psniff,
				    lcrzo_uint16 timeout);
int lcrzo_sniff_get_tcpreor2timeout(lcrzo_sniff *psniff,
				    lcrzo_uint16 *ptimeout);

