2 Implementación del programa sniffer de red
Programado en entorno C, el código fuente es el siguiente:
/* 2 de junio de 2002
* Proyecto de calificación de graduación del equipo 19 de Bby*/
#includes
#includes
// Se debe agregar la ruta y el archivo de encabezado paquete32 debe ser incluido h.
#Include "..\..\Include\packet32.h "
#Include "..\..\Include\ntddndis.h "
#Definir el número máximo de adaptadores 10
//Prototipo
//Outsourcing
Paquetes de impresión anulados(Paquete LP Paquete LP);
//Lista de dispositivos
char Lista de adaptadores[Max _ Num _ Adapter][1024];
//Inicio del programa principal
int main( )
{
//Definir un puntero al puntero del dispositivo de estructura del adaptador
Adaptador LP Adaptador LP = 0;
// Defina un puntero al puntero del paquete de estructura del paquete.
LPPACKET lpPacket
int I;
DWORD dwErrorCode
DWORD dwVersion
DWORD dwWindowsMajorVersion
//Cadena Unicode (WinNT)
Nombre del adaptador WCHAR[8192]; //Lista de dispositivos del adaptador de red
WCHAR *temp, *temp 1;
//Cadena ASCII (Win9x)
char adaptor namea[8192]; //Lista de dispositivos del adaptador de red
char *tempa, *temp 1a;
int AdapterNum=0, Open
Longitud del adaptador ULONG;
char buffer [256000]; //Buffer para guardar datos del controlador
struct bpf _ stat stat
//Obtener el nombre de la tarjeta de red local
AdapterLength = 4096
printf("Aplicación de prueba Packet.dll. Versión de la biblioteca: %s \n ", paquete obtener versión());
printf("Adaptador instalado:\ n ");
I = 0;
El siguiente código se utiliza para obtener los nombres de los adaptadores de red de diferentes versiones:
Los nombres de las tarjetas de red en Win9x y WinNT están implementados en ASCII y UNICODE respectivamente, por lo que primero se debe obtener el número de versión del sistema operativo local.
dw version = GetVersion();
dwWindowsMajorVersion =(DWORD)(LOBYTE(LOWORD(dw version)));
El primero que se usa aquí El La función Packet.dll es Packet GetAdapternames (PT STR pStr, PULONG BufferSize), que suele ser la primera función que se comunica con el controlador y se llama. Coloca el nombre del adaptador de red instalado en el sistema local del usuario en el búfer PSTR. BufferSize es la longitud del búfer:
If (!(dwVersion & gt= 0x80000000. & ampdwWindowsMajorVersion & gt= 4))
{ // es Windows NT.
//No se puede encontrar la lista de dispositivos.
if(PacketGetAdapterNames(AdapterName, & ampAdapterLength)==FALSE){
printf("¡No se puede recuperar la lista de adaptadores!\n ");
return - 1;
La implementación de un rastreador de red simple proviene de: Bookmark Paper Network.
}
//Buscar lista de dispositivos
temp = AdapterName
temp 1 = nombre del adaptador;
mientras ((*temp!='\0')||(*(temp-1)!='\0'))
{
if (*temp== '\0 ')
{
memcpy(AdapterList, temp1, (temp-temp 1)* 2);
temp 1 = temp+1;
i++;
}
temp++;
}
//Lista de adaptadores de pantalla
núm adaptador = I;
for(I = 0;i wprintf(L"\n%d- %s\n ",i+1,lista de adaptadores);
printf(" \ n ");
}
De lo contrario, es Windows 9x y el método para obtener el nombre del adaptador es el mismo que en WinNT.
{
if(PacketGetAdapterNames(adaptername, & ampAdapterLength)==FALSE){
printf("¡No se puede recuperar la lista de adaptadores!\n ");
La implementación de un rastreador de red simple en este artículo proviene de
return-1;
}
tempa = AdapterNamea p >
temp 1a = nombre del adaptadora;
And ((*tempa!='\0')||(*(tempa-1)!='\0'))
{
if (*tempa=='\0 ')
{
memcpy(AdapterList, temp1a, tempa-temp 1a);
temp 1a = tempa+1
i++
}
tempa++; p >
núm adaptador = I;
for(I = 0;i printf("\n%d- %s\n ",i+1,lista de adaptadores);
printf(" \ n ");
}
El siguiente código permite al usuario seleccionar el número de adaptador de red a monitorear:
// Seleccione el dispositivo
Do
{
printf("Seleccione el número del adaptador a abrir:");
scanf( "%d ",& open);
if (open>adapter number)
printf("\nEl número debe ser menor que %d",adapter num);
} while(open & gtadapter num);
Luego, abra el dispositivo seleccionado, que se puede configurar en modo "mixto" o "directo". El código es el siguiente:
//Abre el dispositivo
Adaptador LP = paquete Adaptador abierto(lista de adaptadores[Open-1]);
//Cuando el dispositivo no se puede abrir, aparece un error Se muestra el mensaje:
if (!Adaptador LP | |(Adaptador LP-> hFile == valor de identificador no válido))
{
código de error dw = GetLastError();
printf("No se puede abrir el adaptador, código de error: %lx\n ", código de error dw
return-1; p>}
Utilice el siguiente código para configurar la tarjeta de red en modo "promiscuo":
Aquí se utiliza la función Packet SethwFilter (objeto adaptador LPAdapter, filtro ULONG), que establece un filtro de hardware para paquetes entrantes. Devuelve VERDADERO si la operación es exitosa. AdapterObject es un puntero al dispositivo de la tarjeta de red donde se encuentra el filtro; el filtro constante del filtro se define en el archivo de encabezado ntddndis.h, que incluye:
Ndis-Packet-Type-Promiscuos: establece el modo mixto, cada pase Los paquetes de datos entrantes serán aceptados por la tarjeta de red;
Dirección de tipo de paquete NDIS: solo acepta paquetes de datos enviados directamente a la tarjeta de red del host;
NDIS -Packet-Type-Broadcast: Solo se aceptan paquetes de difusión;
NDIS-Group-Type-Multicast: Solo se aceptan paquetes de multidifusión del grupo al que pertenece el host;
NDIS -Grupo-Tipo-Todo-Multidifusión: Aceptar por grupo de multidifusión.
//Configura el adaptador de red en modo promiscuo
//Si la configuración del modo promiscuo falla, se mostrará un error:
if(PacketSetHwFilter(lpAdapter , NDIS _ paquete_type_mixed)==FALSE){
Una implementación de un rastreador de red simple de: bookmarkpaper.com.
printf("Advertencia: ¡No se puede configurar el modo promiscuo! \n "
}
Luego coloque un búfer de 512 K en el controlador:
>La función Packet Set Buff(LP Adapter Adapter Object, int dim) se utiliza aquí para configurar el búfer del controlador de la tarjeta de red a la que apunta el objeto adaptador. Si tiene éxito, devuelve TRUE. Dim es el tamaño del nuevo búfer. Cuando se establece, los datos del búfer antiguo se descartarán y los paquetes almacenados se perderán.
Nota: La configuración adecuada del tamaño del búfer del controlador afectará el rendimiento del proceso de interceptación de paquetes. La configuración debe garantizar una velocidad de ejecución rápida y sin pérdida de paquetes. La configuración aquí es 512000 bytes.
//Establezca un búfer de 512 K en el controlador
//Cuando no se pueda configurar el búfer, aparecerá un error:
if(PacketSetBuff(lpAdapter , 512000)==FALSE){
printf("¡No se puede configurar el búfer del kernel!\n ");
return-1;
} p >
Packet setreadtime out (objeto adaptador de adaptador LP, int timeout) se utiliza para establecer el valor de tiempo de espera para la operación de lectura de la tarjeta de red especificada por el objeto adaptador. El tiempo de espera está en milisegundos, 0 significa que no hay tiempo de espera. Cuando no hay ningún paquete de datos, la lectura no volverá.
//Establecer un tiempo de espera de lectura de 1 segundo
//Establecer un tiempo de espera de operación de lectura de 1 segundo.
if(PacketSetReadTimeout(adaptador LP, 1000)==FALSE){
printf("Advertencia: ¡No se puede establecer el tiempo de espera de lectura! \ n "); > }
A continuación, ubique el dispositivo, el código es el siguiente:
La función PacketAllocatePacket(Void) utilizada aquí asignará una estructura de paquete en la memoria y le devolverá un puntero. pero el campo Buffer de esta estructura aún no se ha configurado, por lo que es necesario volver a llamar a la función PacketInitPacket para inicializarlo.
//Asignar e inicializar una estructura de paquete, que se utilizará para
//recibir paquetes.
//Cuando falla el posicionamiento, se generará un error:
if((Paquete LP = PacketAllocatePacket())= = NULL){
printf( " \ nError: No se puede asignar la estructura LPPACKET );
return(-1);
}
Luego puede inicializar el dispositivo y comenzar a aceptar paquetes de red :
Utilice la función PACKET init PACKET (LP PACKET LP PACKET, PVOID Buffer, UINT Longitud) para inicializar la estructura del paquete. LpPacket es el puntero que se inicializará. búfer que contiene los datos del paquete. La longitud es la longitud del búfer.
Tenga en cuenta que el búfer asociado con la estructura del paquete almacena los paquetes interceptados por el controlador de captura de paquetes y el número de paquetes está limitado por el. Límite de tamaño de búfer. El tamaño máximo de búfer es la cantidad de datos que la aplicación puede leer del controlador a la vez, por lo que configurar un búfer grande puede reducir la cantidad de llamadas al sistema y mejorar la eficiencia de la interceptación.
PacketInitPacket(lpPacket, (char*)buffer, 256000);
A continuación, es el bucle principal para la interceptación de paquetes:
//Bucle de captura principal
Aquí se utiliza la función paquete de recepción de paquetes (objeto adaptador lpadapter, LPPACKET lpPacket, BOOLEAN Sync), que aceptará (interceptará) un conjunto de paquetes. Estos parámetros incluyen un puntero a una estructura de adaptador que especifica la tarjeta de red para la interceptación de paquetes, una estructura de paquete para contener el paquete y un indicador que indica si se debe ejecutar en modo síncrono o asíncrono. Cuando la operación es sincrónica, la función bloquea el programa; cuando la operación es asincrónica, la función no bloquea el programa y se debe llamar al proceso de PacketWaitPacket para verificar si se completó correctamente. Generalmente se utiliza el modo síncrono.
//Hasta que haya un teclado para escribir:
Y (!kbhit())
{
//Capturar paquete paquete de captura.
//Cuando falla la captura de paquetes, se mostrará un error:
if(PacketReceivePacket(LP adaptor, lpPacket, TRUE)==FALSE){
printf ("Error: PacketReceivePacket falló");
Una implementación simple de rastreador de red proviene de: Bookmark Paper Network.
return(-1);
}
//Imprime los datos en el paquete y llama a la función personalizada PrintPackets().
imprimir paquetes(paquete LP);
}
Finalmente imprima los datos estadísticos, el código es el siguiente:
El La función packagegetstats utilizada aquí (objeto adaptador lpadapter, estructura bpf_star*s) puede obtener los valores de dos variables internas del controlador: la cantidad de paquetes de datos recibidos por la tarjeta de red especificada desde que se llamó PacketOpenAdapter y la cantidad de datos; paquetes que la tarjeta de red recibió pero que fueron descartados por el kernel. El controlador copia estos dos valores en la estructura bpf_stat proporcionada por la aplicación.
//Imprimir estadísticas de captura
//Obtener estadísticas
//Cuando el estado no se puede leer desde el kernel, se mostrará un error: p>
if(PacketGetStats(lpAdapter, & ampstat)==FALSE){
printf("Advertencia: ¡No se pueden obtener estadísticas del kernel!\n ");
}
//Imprimir "XX paquete interceptado; XX paquete de datos descartado":
Otro
printf("\n\n%d datos han sido recibidos Packet. \n%d paquetes perdidos", stat.bs_recv, stat. bs_drop);
Aquí, la función paquete libre de paquetes (paquete LP lpPacket) se utiliza para liberar la estructura a la que apunta el paquete LP:
//Liberar espacio
paquete libre de paquetes (paquete LP);
Utilice el adaptador de cierre de paquete de función (adaptador lpAdapter LP) para liberar la estructura del adaptador LP adaptador y ciérrelo Puntero de tarjeta de red:
//Apague el adaptador y salga
//Apague el dispositivo y salga.
adaptador de cierre de paquete(adaptador LP);
return(0);
}//Fin del programa principal
Sin detalles aquí Describe el código de la función personalizada PrintPackets() utilizada para imprimir datagramas.
3 Conclusión
Al escribir el rastreador de red, el propósito es que todos sepan la importancia de la administración de la red, presten siempre atención a la seguridad de la información de la red y hagan un buen trabajo. en cifrado y descifrado de información.