/* Copyright (C) 1989, 1991-2005 Free Software Foundation. Este programa es software libre; puede redistribuirse y/o ser modificado bajo los términos de la Licencia Pública General de GNU tal como es publicada por la Free Software Foundation; ya sea por la versión 2 de l a Licencia, o(a su elección) cualquier versión posterior. Este programa se distribA; aún sin la garantía implícita de COMERCIABILIDAD o IDONEIDAD PARA UN FIN DETERMINADO. Vea la Licencia Pública General de GNU para más detalles. Debió haber recibido una copia de la Licencia Pública General de GNU junto con este programa; si no es así, escriba a la Free Software Foundation, Inc., 51 Franklin Street, Quinto Piso, Boston, MA 02110-1301, USA. Autor: Eliseo Ortiz Valdez Fecha:28-Agosto-2007 Objetivo: Educativo Compilar: gcc -o filter_sniff filter_sniff.c -lpcap */ #include #include #include #include #include #include #include #include #include #include #include char * tipo_protocolo(int num){ int num_proto = num; switch(num_proto){ case 1: return "ICMP"; break; case 2: return "IGMP"; break; case 6: return "TCP"; break; case 8: return "EGP"; break; case 17: return "UDP"; break; case 88: return "IGRP"; break; default: return "DESCONOCIDO"; break; } } char * tipo_off(int off){ int num_off = off; switch (num_off) { case 128: return "Reservado"; break; case 64: return "Deshabilitado"; break; case 32: return "Mas Fragmentos"; break; default: return "Desconodido"; break; } } void manejador_callback(u_char *u, const struct pcap_pkthdr *h, const u_char *pd ){ /* ---> desde /usr/include/net/ethernet.h */ struct ether_header *ethp; ethp = (struct ether_header*) pd; /* -----> /usr/include/netinet/ip.h */ struct ip *packip; packip = (struct ip *)(pd+sizeof(struct ether_header)); /*-------------------------------> /usr/include/netinet/tcp.h*/ struct tcphdr *packtcp = (struct tcphdr *)(pd+sizeof(struct ether_header)+sizeof(struct ip)); char *data; data = (char *)(pd+sizeof(struct ether_header)+sizeof(struct ip)+sizeof(struct tcphdr)); int i; printf("\n"); printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); printf("MAC ORIGEN: %s\n",ether_ntoa(ethp->ether_shost)); printf("MAC DESTINO: %s\n", ether_ntoa(ethp->ether_dhost)); printf("El tamano de la cabezera ethernet es: %d\n",ETHER_HDR_LEN); switch(ntohs(ethp->ether_type)){ case ETHERTYPE_IP: printf("Protocolo ether tipo IP %02x\n",ETHERTYPE_IP); break; case ETHERTYPE_ARP: printf("Protocolo ether tipo ARP:%02x\n",ETHERTYPE_ARP); break; case ETHERTYPE_REVARP: printf("Protocolo ether tipo RARP: %02x \n", ETHERTYPE_REVARP); break; default: printf("Procotolo desconocido\n"); break; } //imprimimos la cabezera ip printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); printf("++++++++++++++++++++++++++++++++++++++++++++++++ CABECERA IP ++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); printf("+Version IP: %d ++ Longitud de la cabecera IP: %d ++ Tipo de Servicio: %d ++ Longitud Total: %d+\n", packip->ip_v, packip->ip_hl,packip->ip_tos,packip->ip_len); printf("+Identificador: %d ++ Fragmento Offset: %s +\n", packip->ip_id,tipo_off(packip->ip_off)); printf("+Tiempo de Vida: %d ++ Protocolo: %s ++ Checksum: %d +\n",packip->ip_ttl,tipo_protocolo(packip->ip_p),packip->ip_sum); printf("+IP Origen: %s ++ IP Destino: %s +\n", inet_ntoa(packip->ip_src), inet_ntoa(packip->ip_dst)); printf("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); //integridad de datos, se obtiene realizando el complemento a uno de todas las cabezeras de 16 bits.. //imprimimos cabecera tcp printf("-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+--+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n"); printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- CABECERA TCP +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n"); printf("+Puerto origen: %d ++ Puerto Destino: %d ++ Num. de Secuencia: %d ++ Secuencia ACK: %d +\n",ntohs(packtcp->source),ntohs(packtcp->dest),packtcp->seq, packtcp->ack_seq); if (packtcp->urg) printf("+ FLAG URG +\n"); if (packtcp->ack) printf("+ FLAG ACK +\n"); if (packtcp->psh) printf("+ FLAG PSH +\n"); if (packtcp->rst) printf("+ FLAG RST +\n"); if (packtcp->syn) printf("+ FLAG SYN +\n"); if (packtcp->fin) printf("+ FLAG FIN +\n"); printf("+Ventana: %d bytes ++ Checksum: %d ++ Puntero Urgente: %d +\n",ntohs(packtcp->window),ntohs(packtcp->check),packtcp->urg_ptr); printf("+DATA\n"); for(i=0; i < ntohs(packip->ip_len)-sizeof(struct ip)-sizeof(struct tcphdr); i++) printf("%c", *(data + i)); printf("-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+--+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n"); printf("\n\n"); } int main (int argc, char *argv[]) { int num_packs = atoi(argv[4]); char *dev; char errbuf[PCAP_ERRBUF_SIZE]; int ret; bpf_u_int32 netp; bpf_u_int32 maskp; pcap_t *manejador_pcap; char filter[] = ""; struct bpf_program fp; // bsd packet filter... if (argc < 4){ fprintf(stderr,"Forma de uso %s -proto [tcp|ip|arp] -num [numero de paquetes]\n", argv[0]); } if ((dev = pcap_lookupdev(errbuf)) == NULL ) { printf("ERROR %s\n", errbuf); exit(-1); } if ((ret = pcap_lookupnet(dev,&netp,&maskp,errbuf)) == -1){ printf("Error %s\n",errbuf); exit(-1); } if ((manejador_pcap = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf)) == NULL){ fprintf(stderr, "No se pudo abrir el dispositivo: %s: %s\n",dev,errbuf); } strncat(filter,argv[2],7); printf("La expresion es: %s\n\n",filter); if (pcap_compile(manejador_pcap, &fp, filter,0,netp)){ fprintf(stderr,"No se puede analizar el filtro %s: %s\n",filter,pcap_geterr(manejador_pcap)); return(-1); } if (pcap_setfilter(manejador_pcap, &fp) == -1){ fprintf(stderr,"No se puede instalar el filtro %s: %s\n", filter,pcap_geterr(manejador_pcap)); return(-1); } pcap_loop(manejador_pcap,num_packs,manejador_callback,NULL); }