[Winpcap-users] pcap_stats_ex

Gianluca Varenni gianluca.varenni at cacetech.com
Tue Nov 28 23:03:41 GMT 2006


Pcap_stats_ex expects you (i.e. the caller) to allocate the pcap_stat structure. The right code should be something like

struct pcap_stat estadisticas;

pcap_stats_ex(descriptor,&estadisticas);

Hope it helps
GV



  ----- Original Message ----- 
  From: Antonio Ocampo 
  To: winpcap-users at winpcap.org 
  Sent: Tuesday, November 28, 2006 2:16 PM
  Subject: [Winpcap-users] pcap_stats_ex


  Hi for all

  When i add this line to my code

  pcap_stats_ex(descriptor,estadisticas);

  it crashed :(

  #ifndef WIN32
   #include <sys/socket.h>
   #include <netinet/in.h>
  #else
   #include <winsock.h>
  #endif

  #include <stdlib.h>
  #include <time.h>
  #include <math.h>
  #include "pcap.h"



  /* Convierte una dirección IPv4 numérica a cadena*/
  char *iptos(u_long in)
  {
   static char output[12][3*4+3+1];
   static int res;
   u_char *p;

   p = (u_char *)&in;
   res = (res + 1 == 12 ? 0 : res + 1);
   sprintf(output[res], "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
   return output[res];
  }


  #ifndef __MINGW32__ /* Cygnus no soporta IPv6 */
  /* Convierte una dirección IPv6 numérica a cadena*/

  char* ip6tos(struct sockaddr *sockaddr, char *address, int addrlen)
  {
   socklen_t sockaddrlen;

   #ifdef WIN32
   sockaddrlen = sizeof(struct sockaddr_in6);
   #else
   sockaddrlen = sizeof(struct sockaddr_storage);
   #endif

   if(getnameinfo(sockaddr,sockaddrlen,address,addrlen,NULL,0, NI_NUMERICHOST)!= 0)
       address = NULL;

   return address;
  }
  #endif /* __MINGW32__ */


  /* Imprime la informacion disponible de una interfaz dada */

  void describe(pcap_if_t *d, int n)
  {
    pcap_addr_t *a;
    char ip6str[128];

    printf("%d. %s\n",n,d->name);

    if (d->description)
     printf("\tDescripcion: %s\n",d->description);    
    
    else
     printf("\tDescripcion no disponible\n");
    
    printf("\tLoopback: %s\n",(d->flags & PCAP_IF_LOOPBACK)? "Si":"No"); /* Loopback Address*/ 
    
    for(a=d->addresses;a;a=a->next)     /* direcciones IP */
    {
      printf("\tFamilia de direcciones: #%d\n",a->addr->sa_family);
    
      switch(a->addr->sa_family)
      { 
        case AF_INET:
          printf("\tNombre de la familia de direcciones : AF_INET\n");
          if (a->addr) printf("\tDireccion: %s\n",iptos(((struct sockaddr_in *)a->addr)->sin_addr.s_addr)); 
          if (a->netmask)printf("\tMascara de Subred: %s\n",iptos(((struct sockaddr_in *)a->netmask)->sin_addr.s_addr));
          if (a->broadaddr) printf("\tDireccion de Broadcast: %s\n",iptos(((struct sockaddr_in *)a->broadaddr)->sin_addr.s_addr)); 
          if (a->dstaddr) printf("\tDireccion de Destino: %s\n",iptos(((struct sockaddr_in *)a->dstaddr)->sin_addr.s_addr));
          break;

     case AF_INET6:
          printf("\tNombre de la familia de direcciones : AF_INET6\n");   
          #ifndef __MINGW32__ /* Cygnus no soporta IPv6 */
          if (a->addr) printf("\tDireccion: %s\n", ip6tos(a->addr, ip6str, sizeof(ip6str))); 
          #endif
       break;

     default:              
          printf("\tNombre desconocido de la familia de direcciones\n");
          break;
      }
    }
    
    printf("\n");
  }


  /* Funciones principales */

  int id_nic,cantidad_paquetes;
  pcap_if_t *nics,*d;
  struct pcap_stat *estadisticas;
  char buffer_error[PCAP_ERRBUF_SIZE];
  double retardo[65536];

  void reconoce_nics_y_elige_una()
  {
      int i;
      
      system("cls");

      /* Captura la lista de NICs */
   if(pcap_findalldevs(&nics, buffer_error) == -1)
   {
    printf("Error en la captura de NICs: %s\n", buffer_error);
    exit(1);
   }

   printf("\nLas NICs encontradas son:\n\n");

   for(i=0,d=nics; d; d=d->next,++i) /* Imprime la información de las NICs detectadas*/
    describe(d,i+1);

   if(i==0)
   {
    puts("\nNo se encontraron NICs! Verifica que Winpcap este instalado...");
    exit(1);
   }

   while(1)
   {
        printf("\nIngrese el numero de interface de la cual desea capturar los paquetes (1-%d): ",i);
     scanf("%d", &id_nic);

     if(id_nic < 1 || id_nic > i)
         puts("El numero de interface esta fuera del rango.");

     else
         break;
      }
  }


  void captura_y_almacena_paquetes()
  {
      struct pcap_pkthdr *cabecera;
      struct tm *tiempo_cabecera,*tiempo;
      struct bpf_program codigo_filtro;
      const u_char *paquete;
      pcap_t *descriptor; 
      u_int mascara_de_red;
      char timestr[16],filtro[20]="ip",nombre[30]="paquetes.txt";
      int i,num_paquete,res;
      int *puntero;
      FILE *buffer;

      for(d=nics, i=0; i< id_nic-1 ;d=d->next, i++); /* Ubico la NIC deseada */

   /* Abro el dispositivo de red y su adaptador*/
   
   if ((descriptor= pcap_open_live(d->name, /* nombre de la NIC */
          65536,       /* garantiza que capturo el paquete completo*/
          1,        /* modo promiscuo (un valor diferente de cero) */ 
          1000,       /* timeout */
          buffer_error  /* almacena los posibles errores */
          )) == NULL)
   {
    printf("\nNo se puede abrir el adaptador porque %s no es soportado por WinPcap\n", d->name); 
    pcap_freealldevs(nics); /* Libero la lista de NICs */
    exit(1);
   }
   
   mascara_de_red=((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr;

      /* Compilo el filtro */
      if (pcap_compile(descriptor,&codigo_filtro,filtro,1,mascara_de_red) <0 )
   {
    printf("\nNo se puede compilar el filtro.\n");
    pcap_freealldevs(nics);    
    exit(1);
   }

   /* Aplico el filtro */
   if (pcap_setfilter(descriptor,&codigo_filtro)<0)
   {
    printf("\nError aplicando el filtro.\n");
    pcap_freealldevs(nics);    
    exit(1);
   }
   
      printf("Ingrese el numero maximo de paquetes a capturar: "); 
   scanf("%d",&cantidad_paquetes);
   system("pause");
      system("cls");
      printf("\nCapturando paquetes de %s...\n\n", d->description);

      
      buffer=fopen(nombre,"w");   /* Abro el buffer de almacenamiento de los paquetes */
      pcap_freealldevs(nics);     /* Libero la lista de NICs porque ya no la necesito */

      for(num_paquete=1;num_paquete<=cantidad_paquetes && (res = pcap_next_ex(descriptor, &cabecera, &paquete)) >= 0;++num_paquete)
   {
    if(res == 0) /* Pasó timeout */
    {
      /*fprintf(buffer,"Pasando de la zona de Kernel a la de usuario...\n\n");*/ 
      --num_paquete; /* No incrementa la cuenta si no se ha capturado algun paquete */
            continue;
          }

          /* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 
              DEBO HALLAR EL TIEMPO CON PRECISIÓN DE MILISEGUNDOS */
              
              retardo[num_paquete]=(num_paquete*239)%129;
          /* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<</* 
          
          
          /* convierte el timestamp a un formato entendible */
          tiempo_cabecera=localtime(&cabecera->ts.tv_sec);
          strftime( timestr, sizeof timestr, "%H:%M:%S", tiempo_cabecera); 
          
          /*Imprimo el número de paquete y su marca de tiempo*/
          fprintf(buffer,"%d %s.%.6d\n",num_paquete,timestr,cabecera->ts.tv_usec);
          
          /*Se imprime el timestamp con precision de microsegundos*/ 
  /*        fprintf(buffer,"Paquete #%d capturado a las %s.%.6d de %d bytes de longitud \n\n", num_paquete, timestr, cabecera->ts.tv_usec, cabecera->len);*/

    for (i=1; i <= cabecera->caplen ; i++) /*Imprimo el paquete*/
    {
     fprintf(buffer,"%02X ", paquete[i-1]);
     if ( (i & 15) == 0) fprintf(buffer,"\n");
    }

    fprintf(buffer,"100\n\n\n"); /* el 100 sirve como delimitador de paquete */
   }

      puts("al menos llegas");
      pcap_stats_ex(descriptor,estadisticas);
      puts("y aca?");
      pcap_close(descriptor);
      fclose(buffer);
  }


  void interpreta_paquetes()
  {
      char entrada[30]="paquetes.txt",salida[30]="resultados.txt";
      FILE *buffer,*res;
      char tiempo[50],c,temp[50];
      int flag=0,num_paquete,aux,i,byte[65536];          /* variables auxiliares */ 
      int proto,ldatos,lip,servicio,lpaquete,lcabecera;  /* caracteristicas del paquete */

      buffer=fopen(entrada,"r");
      res=fopen(salida,"w");
      
      while(fscanf(buffer,"%d %s\n",&num_paquete,tiempo)==2)
      {
           /* lectura del paquete almacenado en el buffer */ 
          for(i=0;fscanf(buffer,"%X",&aux)==1 && aux!=256;++i)
           byte[i]=aux;
          
          lpaquete=i;
          fprintf(res,"Paquete %d recibido a las %s de longitud %d:\n\n",num_paquete,tiempo,lpaquete); 
          fprintf(res,"MAC de destino: %02X-%02X-%02X-%02X-%02X-%02X\n",byte[0],byte[1],byte[2],byte[3],byte[4],byte[5]);
          fprintf(res,"MAC de origen : %02X-%02X-%02X-%02X-%02X-%02X\n",byte[6],byte[7],byte[8],byte[9],byte[10],byte[11]); 
          
  /* Si el campo Type=0x0800=2048 se trata de un paquete IP */
          if(byte[12]*256+byte[13]!=2048)
          {
              flag=1;
              continue;
          }
          
          fprintf(res,"IPv%d\n",byte[14]/16); 
          lcabecera=(byte[14]%16)*4;
          fprintf(res,"Longitud de la cabecera: %d bytes\n",lcabecera);
          servicio=byte[15];  /* Aquí falta una tabla */
          lip=byte[16]*16+byte[17];
          fprintf(res,"Longitud total: %d bytes\n",lip); 
          ldatos=lip-lcabecera;
          proto=byte[23];
          
          switch(proto)
          {
              case 1:     fprintf(res,"Protocolo ICMP\n");
                          break;
                          
              case 2:     fprintf(res,"Protocolo IGMP\n");
                          break;

              case 4:     fprintf(res,"Protocolo IP\n");
                          break;
                          
              case 6:     fprintf(res,"Protocolo TCP\n");
                          break; 

              case 17:    fprintf(res,"Protocolo UDP\n");
                          break;

              case 41:    fprintf(res,"Protocolo IPv6\n");
                          break;
                          
              case 46:    fprintf(res,"Protocolo RSVP\n");
                          break; 
                          
              case 58:    fprintf(res,"Protocolo ICMPv6\n");
                          break;

              case 89:    fprintf(res,"Protocolo OSPF\n");
                          break;
                          
              default:    fprintf(res,"Otro protocolo\n");
          }
          
          fprintf(res,"Direccion IP de origen : %d.%d.%d.%d\n",byte[26],byte[27],byte[28],byte[29]);
          fprintf(res,"Direccion IP de destino: %d.%d.%d.%d\n",byte[30],byte[31],byte[32],byte[33]); 
          fprintf(res,"Puerto de origen : %d\n",byte[34]*256+byte[35]);
          fprintf(res,"Puerto de destino: %d\n",byte[36]*256+byte[37]);
          
          fprintf(res,"\n\n");
      }
      
      if(flag==1) fprintf(res,"El filtro no funciona!!!");
      fclose(buffer);
      fclose(res);
  }



  int main()
  {
      reconoce_nics_y_elige_una();
      puts("ya elegiste");
      captura_y_almacena_paquetes();
      puts("ya almacenaste");
      interpreta_paquetes();
      return 0; 
  }



  Please help me. I need some statistics about packets.

  Best regards.




------------------------------------------------------------------------------


  _______________________________________________
  Winpcap-users mailing list
  Winpcap-users at winpcap.org
  https://www.winpcap.org/mailman/listinfo/winpcap-users
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.winpcap.org/pipermail/winpcap-users/attachments/20061128/335fd425/attachment-0001.htm


More information about the Winpcap-users mailing list