<div>Hi for all</div>
<div> </div>
<div>When i add this line to my code</div>
<div> </div>
<div>pcap_stats_ex(descriptor,estadisticas);</div>
<div> </div>
<div>it crashed :(</div>
<div> </div>
<div>
<p>#ifndef WIN32<br> #include <sys/socket.h><br> #include <netinet/in.h><br>#else<br> #include <winsock.h><br>#endif</p>
<p>#include <stdlib.h><br>#include <time.h><br>#include <math.h><br>#include "pcap.h"</p>
<p> </p>
<p>/* Convierte una dirección IPv4 numérica a cadena*/<br>char *iptos(u_long in)<br>{<br> static char output[12][3*4+3+1];<br> static int res;<br> u_char *p;</p>
<p> p = (u_char *)&in;<br> res = (res + 1 == 12 ? 0 : res + 1);<br> sprintf(output[res], "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);<br> return output[res];<br>}</p>
<p><br>#ifndef __MINGW32__ /* Cygnus no soporta IPv6 */<br>/* Convierte una dirección IPv6 numérica a cadena*/</p>
<p>char* ip6tos(struct sockaddr *sockaddr, char *address, int addrlen)<br>{<br> socklen_t sockaddrlen;</p>
<p> #ifdef WIN32<br> sockaddrlen = sizeof(struct sockaddr_in6);<br> #else<br> sockaddrlen = sizeof(struct sockaddr_storage);<br> #endif</p>
<p> if(getnameinfo(sockaddr,sockaddrlen,address,addrlen,NULL,0, NI_NUMERICHOST)!= 0)<br> address = NULL;</p>
<p> return address;<br>}<br>#endif /* __MINGW32__ */</p>
<p><br>/* Imprime la informacion disponible de una interfaz dada */</p>
<p>void describe(pcap_if_t *d, int n)<br>{<br> pcap_addr_t *a;<br> char ip6str[128];</p>
<p> printf("%d. %s\n",n,d->name);</p>
<p> if (d->description)<br> printf("\tDescripcion: %s\n",d->description); <br> <br> else<br> printf("\tDescripcion no disponible\n");<br> <br> printf("\tLoopback: %s\n",(d->flags & PCAP_IF_LOOPBACK)? "Si":"No"); /* Loopback Address*/
<br> <br> for(a=d->addresses;a;a=a->next) /* direcciones IP */<br> {<br> printf("\tFamilia de direcciones: #%d\n",a->addr->sa_family);<br> <br> switch(a->addr->sa_family)<br> {
<br> case AF_INET:<br> printf("\tNombre de la familia de direcciones : AF_INET\n");<br> if (a->addr) printf("\tDireccion: %s\n",iptos(((struct sockaddr_in *)a->addr)->sin_addr.s_addr));
<br> if (a->netmask)printf("\tMascara de Subred: %s\n",iptos(((struct sockaddr_in *)a->netmask)->sin_addr.s_addr));<br> if (a->broadaddr) printf("\tDireccion de Broadcast: %s\n",iptos(((struct sockaddr_in *)a->broadaddr)->sin_addr.s_addr));
<br> if (a->dstaddr) printf("\tDireccion de Destino: %s\n",iptos(((struct sockaddr_in *)a->dstaddr)->sin_addr.s_addr));<br> break;</p>
<p> case AF_INET6:<br> printf("\tNombre de la familia de direcciones : AF_INET6\n"); <br> #ifndef __MINGW32__ /* Cygnus no soporta IPv6 */<br> if (a->addr) printf("\tDireccion: %s\n", ip6tos(a->addr, ip6str, sizeof(ip6str)));
<br> #endif<br> break;</p>
<p> default: <br> printf("\tNombre desconocido de la familia de direcciones\n");<br> break;<br> }<br> }<br> <br> printf("\n");<br>}</p>
<p><br>/* Funciones principales */</p>
<p>int id_nic,cantidad_paquetes;<br>pcap_if_t *nics,*d;<br>struct pcap_stat *estadisticas;<br>char buffer_error[PCAP_ERRBUF_SIZE];<br>double retardo[65536];</p>
<p>void reconoce_nics_y_elige_una()<br>{<br> int i;<br> <br> system("cls");</p>
<p> /* Captura la lista de NICs */<br> if(pcap_findalldevs(&nics, buffer_error) == -1)<br> {<br> printf("Error en la captura de NICs: %s\n", buffer_error);<br> exit(1);<br> }</p>
<p> printf("\nLas NICs encontradas son:\n\n");</p>
<p> for(i=0,d=nics; d; d=d->next,++i) /* Imprime la información de las NICs detectadas*/<br> describe(d,i+1);</p>
<p> if(i==0)<br> {<br> puts("\nNo se encontraron NICs! Verifica que Winpcap este instalado...");<br> exit(1);<br> }</p>
<p> while(1)<br> {<br> printf("\nIngrese el numero de interface de la cual desea capturar los paquetes (1-%d): ",i);<br> scanf("%d", &id_nic);</p>
<p> if(id_nic < 1 || id_nic > i)<br> puts("El numero de interface esta fuera del rango.");</p>
<p> else<br> break;<br> }<br>}</p>
<p><br>void captura_y_almacena_paquetes()<br>{<br> struct pcap_pkthdr *cabecera;<br> struct tm *tiempo_cabecera,*tiempo;<br> struct bpf_program codigo_filtro;<br> const u_char *paquete;<br> pcap_t *descriptor;
<br> u_int mascara_de_red;<br> char timestr[16],filtro[20]="ip",nombre[30]="paquetes.txt";<br> int i,num_paquete,res;<br> int *puntero;<br> FILE *buffer;</p>
<p> for(d=nics, i=0; i< id_nic-1 ;d=d->next, i++); /* Ubico la NIC deseada */</p>
<p> /* Abro el dispositivo de red y su adaptador*/<br> <br> if ((descriptor= pcap_open_live(d->name, /* nombre de la NIC */<br> 65536, /* garantiza que capturo el paquete completo*/<br> 1, /* modo promiscuo (un valor diferente de cero) */
<br> 1000, /* timeout */<br> buffer_error /* almacena los posibles errores */<br> )) == NULL)<br> {<br> printf("\nNo se puede abrir el adaptador porque %s no es soportado por WinPcap\n", d->name);
<br> pcap_freealldevs(nics); /* Libero la lista de NICs */<br> exit(1);<br> }<br> <br> mascara_de_red=((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr;</p>
<p> /* Compilo el filtro */<br> if (pcap_compile(descriptor,&codigo_filtro,filtro,1,mascara_de_red) <0 )<br> {<br> printf("\nNo se puede compilar el filtro.\n");<br> pcap_freealldevs(nics); <br>
exit(1);<br> }</p>
<p> /* Aplico el filtro */<br> if (pcap_setfilter(descriptor,&codigo_filtro)<0)<br> {<br> printf("\nError aplicando el filtro.\n");<br> pcap_freealldevs(nics); <br> exit(1);<br> }<br> <br> printf("Ingrese el numero maximo de paquetes a capturar: ");
<br> scanf("%d",&cantidad_paquetes);<br> system("pause");<br> system("cls");<br> printf("\nCapturando paquetes de %s...\n\n", d->description);</p>
<p> <br> buffer=fopen(nombre,"w"); /* Abro el buffer de almacenamiento de los paquetes */<br> pcap_freealldevs(nics); /* Libero la lista de NICs porque ya no la necesito */</p>
<p> for(num_paquete=1;num_paquete<=cantidad_paquetes && (res = pcap_next_ex(descriptor, &cabecera, &paquete)) >= 0;++num_paquete)<br> {<br> if(res == 0) /* Pasó timeout */<br> {<br> /*fprintf(buffer,"Pasando de la zona de Kernel a la de usuario...\n\n");*/
<br> --num_paquete; /* No incrementa la cuenta si no se ha capturado algun paquete */<br> continue;<br> }</p>
<p> /* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
<br> DEBO HALLAR EL TIEMPO CON PRECISIÓN DE MILISEGUNDOS */<br> <br> retardo[num_paquete]=(num_paquete*239)%129;<br> /* <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<</*
<br> <br> <br> /* convierte el timestamp a un formato entendible */<br> tiempo_cabecera=localtime(&cabecera->ts.tv_sec);<br> strftime( timestr, sizeof timestr, "%H:%M:%S", tiempo_cabecera);
<br> <br> /*Imprimo el número de paquete y su marca de tiempo*/<br> fprintf(buffer,"%d %s.%.6d\n",num_paquete,timestr,cabecera->ts.tv_usec);<br> <br> /*Se imprime el timestamp con precision de microsegundos*/
<br>/* 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);*/</p>
<p> for (i=1; i <= cabecera->caplen ; i++) /*Imprimo el paquete*/<br> {<br> fprintf(buffer,"%02X ", paquete[i-1]);<br> if ( (i & 15) == 0) fprintf(buffer,"\n");<br> }</p>
<p> fprintf(buffer,"100\n\n\n"); /* el 100 sirve como delimitador de paquete */<br> }</p>
<p> puts("al menos llegas");<br> pcap_stats_ex(descriptor,estadisticas);<br> puts("y aca?");<br> pcap_close(descriptor);<br> fclose(buffer);<br>}</p>
<p><br>void interpreta_paquetes()<br>{<br> char entrada[30]="paquetes.txt",salida[30]="resultados.txt";<br> FILE *buffer,*res;<br> char tiempo[50],c,temp[50];<br> int flag=0,num_paquete,aux,i,byte[65536]; /* variables auxiliares */
<br> int proto,ldatos,lip,servicio,lpaquete,lcabecera; /* caracteristicas del paquete */</p>
<p> buffer=fopen(entrada,"r");<br> res=fopen(salida,"w");<br> <br> while(fscanf(buffer,"%d %s\n",&num_paquete,tiempo)==2)<br> {<br> /* lectura del paquete almacenado en el buffer */
<br> for(i=0;fscanf(buffer,"%X",&aux)==1 && aux!=256;++i)<br> byte[i]=aux;<br> <br> lpaquete=i;<br> fprintf(res,"Paquete %d recibido a las %s de longitud %d:\n\n",num_paquete,tiempo,lpaquete);
<br> fprintf(res,"MAC de destino: %02X-%02X-%02X-%02X-%02X-%02X\n",byte[0],byte[1],byte[2],byte[3],byte[4],byte[5]);<br> fprintf(res,"MAC de origen : %02X-%02X-%02X-%02X-%02X-%02X\n",byte[6],byte[7],byte[8],byte[9],byte[10],byte[11]);
<br> <br>/* Si el campo Type=0x0800=2048 se trata de un paquete IP */<br> if(byte[12]*256+byte[13]!=2048)<br> {<br> flag=1;<br> continue;<br> }<br> <br> fprintf(res,"IPv%d\n",byte[14]/16);
<br> lcabecera=(byte[14]%16)*4;<br> fprintf(res,"Longitud de la cabecera: %d bytes\n",lcabecera);<br> servicio=byte[15]; /* Aquí falta una tabla */<br> lip=byte[16]*16+byte[17];<br> fprintf(res,"Longitud total: %d bytes\n",lip);
<br> ldatos=lip-lcabecera;<br> proto=byte[23];<br> <br> switch(proto)<br> {<br> case 1: fprintf(res,"Protocolo ICMP\n");<br> break;<br>
<br> case 2: fprintf(res,"Protocolo IGMP\n");<br> break;</p>
<p> case 4: fprintf(res,"Protocolo IP\n");<br> break;<br> <br> case 6: fprintf(res,"Protocolo TCP\n");<br> break;
</p>
<p> case 17: fprintf(res,"Protocolo UDP\n");<br> break;</p>
<p> case 41: fprintf(res,"Protocolo IPv6\n");<br> break;<br> <br> case 46: fprintf(res,"Protocolo RSVP\n");<br> break;
<br> <br> case 58: fprintf(res,"Protocolo ICMPv6\n");<br> break;</p>
<p> case 89: fprintf(res,"Protocolo OSPF\n");<br> break;<br> <br> default: fprintf(res,"Otro protocolo\n");<br> }<br>
<br> fprintf(res,"Direccion IP de origen : %d.%d.%d.%d\n",byte[26],byte[27],byte[28],byte[29]);<br> fprintf(res,"Direccion IP de destino: %d.%d.%d.%d\n",byte[30],byte[31],byte[32],byte[33]);
<br> fprintf(res,"Puerto de origen : %d\n",byte[34]*256+byte[35]);<br> fprintf(res,"Puerto de destino: %d\n",byte[36]*256+byte[37]);<br> <br> fprintf(res,"\n\n");<br>
}<br> <br> if(flag==1) fprintf(res,"El filtro no funciona!!!");<br> fclose(buffer);<br> fclose(res);<br>}</p>
<p><br><br>int main()<br>{<br> reconoce_nics_y_elige_una();<br> puts("ya elegiste");<br> captura_y_almacena_paquetes();<br> puts("ya almacenaste");<br> interpreta_paquetes();<br> return 0;
<br>}</p>
<p> </p>
<p>Please help me. I need some statistics about packets.</p>
<p>Best regards.</p></div>
<div> </div>