[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 *)∈
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