[Winpcap-users] pcap_stats_ex

Antonio Ocampo antonio.ocampo at gmail.com
Tue Nov 28 22:16:23 GMT 2006


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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.winpcap.org/pipermail/winpcap-users/attachments/20061128/a12d8aaa/attachment-0001.htm


More information about the Winpcap-users mailing list