¿Cómo volver a agregar contenido de rastreo de printf?
La función principal de winpcap es recibir datos, pero no impide la transmisión de datos originales. Por ejemplo, si detectamos que un servidor de juego remoto nos envía datos de nivel. el juego, winpcap solo puede detectarlo y conocer toda su información, pero no puede modificarlo. Si desea modificarlo, necesita otros conocimientos. Aquí primero veremos un programa rastreador.
#include "pcap .h" unsigned long destIP; //dirección IP de destino de 32 bits
}IP_HEADER;
struct //definir TCP pseudo-primero
{ p>
unsigned long saddr; //dirección de origen
unsigned long daddr; //dirección de destino
char mbz;
char ptcl; // tipo de protocolo
unsigned short tcpl; //longitud de TCP
}PSD_HEADER;
typedef struct _tcphdr // Definir encabezado TCP
{
USHORT th_sport; //puerto de origen de 16 bits
USHORT th_dport; //puerto de destino de 16 bits
unsigned int th_seq; //número de secuencia de 32 bits
unsigned int th_ ack; //número de confirmación de 32 bits
unsigned char th_lenres; //longitud del encabezado de 4 bits/6 bits palabra reservada
char unsigned th_flag
USHORT th_win; //tamaño de ventana de 16 bits
USHORT th_sum //suma de comprobación de 16 bits
USHORT th_urp; //Desplazamiento de datos de emergencia de 16 bits
}TCP_HEADER;
void package_handler(u_char *dumpfile, const struct pcap_ pkthdr *header, const u_char *pkt_data )
{
IP_HEADER * ipheader
TCP_HEADER * tcp_header
ET_HEADER * et_header; p>
SOCKADDR_IN saddr;
iplen corto sin firmar;
deporte corto sin firmar
int destPort
int datasize;
int len;
char buf[1024]={0};
et_header=(ET_HEADER *)pkt_data;
ipheader =(IP_HEADER *)(pkt_data+14);
if(ipheader->proto=6)
{
iplen=(ipheader->h_verlen & 0xf)>>2;
tcp_header =(TCP_HEADER *)( ipheader+iplen
);sport=ntohs(tcp_header->th_sport);
destPort=ntohs(tcp_header->th_dport);
addr.sin_addr.un.S_addr=ipheader->sourceIP;
saddr.sin_addr.S_un.S_addr=ipheader->destIP;
datasize=tcp_header->th_lenres>.>2;
len=ntohs(ipheader- >total_len)-iplen-datasize;
if(len>0)
{
memcpy(buf,(BYTE *)tcp_header+ datasize,len);
printf("%s(%d)->%s(%d) bandera: SYN =%x ACK=%x\n los datos son: %s \n\n ",
inet_ntoa(*((IN_ADDR *)&(addr.sin_addr ))),
deporte,
inet_ntoa(*((IN_ADDR *)&(saddr.sin_addr )),
destPort,
tcp_header->th_flag,
ntohl( tcp_header->th_seq),
ntohl(tcp_header- >th_ack),
buf
);
}
else
{
printf("%s(%d)-> ;%s(%d) bandera:%d SYN =%x ACK=%x\n\n ",
inet_ntoa(*( (IN_ADDR *)&(addr.sin_addr))),
deporte,
inet_ntoa(*((IN_ADDR *)& ;(saddr.sin_addr))),
destPort,
tcp_header->th_flag,
ntohl(tcp_header->th_seq),
ntohl(tcp_header->.th_ack) p>
);
}
}
}
principal(int argc, char **argv) p>
{
pcap_if_t *alldevs;
pcap_if_t *d;
int inum;
int i=0;
char package_filter[] = "tcp";
char errbuf[PCAP_ERRBUF_SIZE];
if (pcap_findalldevs(&alldevs , errbuf) == -1)
{
fprintf(stderr, "Error en pcap_findalldevs:%s\n", errbuf);
exit(1);
}
for(d=alldevs; d; d= d->siguiente)
{
printf(
"%d.%s", ++i, d->nombre);
if (d->descripción)
printf(" (%s)\n", d->descripción);
else
printf(" (No hay descripción disponible)\n");
}
if (i==0)
{
printf("/n¡No se encontraron interfaces! Asegúrese de que WinPcap esté instalado.");
Devuelve -1;
p>}
printf("Ingrese el número del rastreador. Intervalo (1-%d):",i);
scanf(" %d" , &inum);
if(inum < 1 || inum > i)
{
printf("\nmandy, ingresa el número del rastreador .\n");
/* Liberar lista de dispositivos*/
pcap_freealldevs(alldevs);
return -1;
}
/* Saltar al adaptador seleccionado*/
for(d=alldevs, i=0; i< inum-1;d=d->next, i++);
p>strcpy( NombreInterfaz, d->nombre );
/* Adaptador abierto*/
if (( adhandle= pcap_open_live(d->nombre, // nombre del dispositivo
65536, // Parte del paquete a capturar
// 65536 significa que el paquete completo será capturado en todos los MAC
1. , // modo espurio (distinto de cero significa espurio)
2000, // tiempo de espera de lectura
errbuf // buffer de error
))) == NULL )
{
fprintf(stderr,"\nNo se puede abrir el adaptador. %s no es compatible con WinPcap\n", d->name); p>
/* Liberar la lista de dispositivos */
pcap_freealldevs(alldevs);
return -1;
}
// Compile el filtro
printf("/nDetectará %s de los datos de esta red\n" , d->description);
/*En este punto, ya no se requiere la lista de dispositivos . Libéralo*/
pcap_freealldevs(alldevs);
pcap_loop(adhandle, 0, paquete_handler, NULL);
pcap_close(adhandle);
Devuelve 0;
}
Descripción del programa
pcap_findalldevs(&alldevs, errbuf) se utiliza para buscar todos los adaptadores de red de la máquina, incluidos los enrutadores. tarjeta de red de computadora, etc.
, si todos están enumerados, el formato de datos del tipo pcap_if_t es:
struct pcap_if {
struct pcap_if *next;
char * name /* To; Nombre pasado a "pcap_open_live()" */
char *description /* Descripción textual de la interfaz, o NULL */
struct pcap_addr * direcciones;
bpf_u_int32 flags; /*PCAP_IF_interface flags*//p>
};
El siguiente campo representa los datos del siguiente adaptador de red disponible (si lo hay), el nombre representa el nombre de este adaptador, que se utilizará en el campo pcap_addr como se indica en los comentarios. Los parámetros se usarán en la función pcap_open_live, que es el foco de este programa. Cuando seleccionamos un adaptador de red, podemos llamarlo así
if ((adhandle= pcap_open_live(d->name. , // Nombre del adaptador
65536, //El número máximo de bytes capturados; cuando se establece en 65536, se capturarán todos los datos
1, //Establezca el modo de captura, cuando se establece en 1, para modo mixto
2000, //Configuración de tiempo de espera, intente configurarlo lo más grande posible
errbuf //El búfer utilizado para guardar información de error cuando se se produce un error.
)) == NULL)
Aquí está el tercer valor. Generalmente lo configuramos en 1. Cuando se establece en 1, significa que todos los datos fluyen hacia él. la red se puede monitorear, esto se debe a que después de recibir un dato, la puerta de enlace LAN lo enviará a todos los usuarios de la red interna y verificará en la computadora de cada usuario si la dirección física de los datos es la dirección de destino, y luego enviar los datos a los usuarios de la red interna. La computadora de cada usuario verificará la dirección física de destino de los datos. Si es la misma que la suya, será aceptada; de lo contrario, no se procesará. Establezca en 1 para representar el modo mixto, en el que los datos no son propios. También se aceptará dirección física. Imagínese, cuando configura el adaptador de red en modo mixto, puede incluso ver lo que sus colegas dicen al mundo exterior, qué páginas web están visitando, etc. Sobre esta base, puede hacer muchas cosas. volver a Ir al programa, el programa enumerará todos sus adaptadores de red al principio de la lista, por ejemplo en mi máquina, la lista es la siguiente:
Aquí conozco los míos 2 (los demás son míos) Sé que estoy usando 2 aquí (las otras son las tarjetas de red virtuales de mi máquina virtual y no se usan aquí cuando seleccionamos el índice del adaptador, el programa guardará el nombre de nuestro adaptador en la variable InterfaceName para). Usar más tarde
for(d=alldevs, i=0; i< inum-1;d=d->next, i++
strcpy (NombreInterfaz, d->nombre); );
Abra el adaptador y configure el modo de escucha
if ((adhandle= pcap_open_live(d->name, // nombre del dispositivo
65536, / / a La porción del paquete capturado.
// 65536 significa que el paquete completo será capturado en todos los MAC
1, // Modo promiscuo (distinto de cero significa promiscuo) < / p>
2000, // Tiempo de espera de lectura
errbuf // Búfer de error
)) == NULL)
Después de ejecutar correctamente la función, que devuelve un identificador al adaptador en winpcap, que la función pcap_loop utilizará para manejar errores en los paquetes recibidos.
La función de bucle se utiliza para procesar los datos recibidos en la función de devolución de llamada, consulte la estructura de la función pcap_loop
int pcap_loop(pcap_t *, int, pcap_handler, u_char *);
El primer parámetro son los datos devueltos por pcap_open_live, el segundo parámetro es la dirección de la función de devolución de llamada que procesa los datos. El tercer parámetro representa el bit de bandera, normalmente lo configuramos en NULL.
Está bien, siempre que comprenda la parte anterior, no importa si no la comprende por un tiempo. Puede considerarlo como la declaración inicial de un programa rastreador. de la mayoría de los programas es así Sí, la memorización de memoria también es posible. La clave es mirar la función de devolución de llamada. header, const u_char *pkt_data)
dumpfile: es la dirección del archivo, cuando necesitamos almacenar los datos interceptados en un archivo para su uso
header: refleja la longitud, el tiempo y otros información del paquete de datos
pkt_data. p>pkt_data: representa una dirección de encabezado de paquete específica. En nuestro ejemplo, es una combinación de encabezado Ethernet, encabezado IP, encabezado TCP y datos, que también es el foco de nuestro procesamiento.
Vuelva a visitar la fórmula.
Datos interceptados = encabezado Ethernet (14 bytes) + encabezado ip + encabezado tcp + datos
Dado que los primeros 14 bytes representan el encabezado Ethernet, es natural encontrar los 14 de Ethernet Dirección de encabezado IP de -byte debajo del encabezado de red
et_header=(ET_HEADER *)pkt_data;
ipheader=(IP_HEADER *)(pkt_data+14);
En el encabezado de IP, veremos el significado de varias posiciones clave
unsigned char h_verlen; longitud del encabezado, número de versión de IP de 4 dígitos, aquí hay datos de 8 bytes, las primeras 4 palabras La estrofa representa el número de versión, generalmente ipv4 o ipv6. Los últimos 4 bytes representan la longitud del encabezado ip, pero aquí la palabra doble se usa como unidad básica, es decir, suponiendo que aquí sea 8, entonces la longitud de la ip. el encabezado debe ser 8 * 4 = 32 palabras
unsigned short total_len; representa el tamaño de los tres bloques del encabezado ip, el encabezado tcp y los datos específicos Al establecer un protocolo de enlace de tres vías. conexión, no hay datos aquí. La fórmula correspondiente es: La longitud de esta parte de los datos es 0. Podemos restar este valor de la longitud del encabezado ip y la longitud del encabezado tcp para obtener la longitud específica. datos
IP de origen larga sin firmar; dirección IP de origen de 32 bits, que se envía La dirección de los datos
dirección IP de destino larga sin firmar de 32 bits, es decir, la IP; dirección que recibe los datos
destIP larga sin firmar; dirección IP de destino de 32 bits, es decir, la dirección IP que contiene los datos.
Dirección IP de datos
Código iplen=(ipheader->h_verlen &0xf)>>2; es decir, primero establezca la versión de datos correcta en 0 y multiplique el valor obtenido por 4 (desplazamiento a la izquierda 2 bits) ,
posición del encabezado tcp = posición del encabezado ip + longitud del encabezado ip, código tcp_ header=(TCP_HHEADER=(TCP_HEADER=(TCP_HEADER)) header=(TCP_HEADER *)(ipheader+iplen); Eso es todo. Obtener Después del encabezado tcp, echemos un vistazo al significado de los campos clave en el encabezado tcp
USHORT th_sport; el puerto de origen para enviar estos datos. Tenga en cuenta que en la visualización específica, se procesa como local. orden de bytes El siguiente propósito El puerto también es
USHORT th_dport; puerto de destino de 16 bits
unsigned int th_seq; capítulo
unsigned int th_ack; total_len representa la longitud de todo el mensaje de datos ip Resta el valor de longitud del encabezado ip y el valor de longitud del encabezado tcp para obtener la longitud de los datos.
ipheader->total_len, obtiene la longitud de los datos
ipheader->total_len p>
datasize=tcp_header->th_lenres>>2;
len=ntohs (ipheader->total_len)-iplen-datasize;
Al emparejar el encabezado tcp y el encabezado ip, debería poder comprender el código anterior rápidamente; tenga en cuenta el significado de estos campos
Bien, hemos completado un programa rastreador simple. Si lo ha depurado en el winpcap de la máquina, también puede echar un vistazo al tráfico de datos de red actual de su máquina para ver qué se puede investigar.