Cómo controlar el modo de hibridación
La función ioctl se usa comúnmente para establecer configuraciones en programas comunes. Vale la pena comprender esta función porque se usa ampliamente. El siguiente
es el código de implementación para configurar el modo espurio de la tarjeta de red:
#include
#include
# incluir
#include
#include
int set_all_promisc()
{ struct ifreq ifaces[16];
struct ifconf param ;
int sock, i;
param.ifc_len = sizeof(ifaces);
param = socket(PF_INET, SOCK_DGRAM , IPPROTO_IP);
if (sock <= 0)
devuelve 0;
if (ioctl(sock, SIOCGIFCONF, ?m))
devuelve 0;
for (i = 0; i < param.ifc_len / sizeof(struct ifreq); i++) {
if (ioctl(sock, SIOCGIFFLAGS, ifaces + i))
Devuelve 0;
ifaces[i].ifr_flags |= IFF_PROMISC /* Si se restaura el modo NIC, cambie |= a &=~ */
if (ioctl(sock, SIOCSIFFLAGS, ifaces + i))
devuelve 0;
}
p> devuelve 1;
}
II. Establecer el modo espurio en el espacio del kernel
1. En kernel-2.2.x
dispositivo de estructura estática *sniffer_dev = NULL;
static unsigned short old_flags, old_gflags;
int init_module ( void ) /* Inicialización del módulo*/
{
. .. ...
sniffer_dev = dev_get("eth0");
if ( sniffer_dev ! = NULL )
{
/* Gracias por su apoyo a la seguridad de whnet*/
old_flags = sniffer_dev->flags;
old_gflags = sniffer_dev-& gt;gflags;
/*
* Ver dev_change_flags() en net/core/dev.
c
* ->El propósito de gflags es evitar configurar el modo promiscuo varias veces y no tiene otro significado especial
*/
/* Establecer modo promiscuo * /
sniffer_dev->flags |= IFF_PROMISC;
sniffer_dev->gflags |= IFF_PROMISC;
start_bh_atomic();
/* Tenga en cuenta que esta devolución de llamada todavía informa eth0: modo callejero establecido. */
sniffer_dev->set_multicast_list( sniffer_dev );
end_bh_atomic();
}
......
devuelve 0;
}
void cleanup_module(void)
{
......
if (sniffer_dev != NULL)
{
/*Restaurar modo original*/
sniffer_dev>flags = old_flags;
sniffer_dev>gflags = old_gflags;
start_bh_ atomic();
sniffer_dev>set_multicast_list( sniffer_dev );
end_bh_atomic();
}
......
}
2. En kernel-2.4.x
Hay muchos cambios en, primero cambie la estructura del dispositivo de estructura a struct net_device, luego cambie la función dev_get
para probar si el dispositivo de red existe y cambie la función que establece el modo promiscuo de la red real a p>
end_bh_atomic() .
void dev_set_promiscuity(struct net_device *dev, int inc);
Entre ellos, el modo mixto se establece de acuerdo con el valor de inc o se restaura el modo establecido originalmente, y el El modo original se restaura contando. La ventaja de esto es que no entrará en conflicto con otros programas y no restaurará el modo original como las dos implementaciones anteriores. Los dos métodos anteriores para restaurar el modo original se pueden restaurar por completo, independientemente de si otros programas también han configurado el modo mixto. Ahora puede restaurar el modo original contando y solo configurarlo en modo normal cuando los conteos sumen cero.
Los comentarios del código fuente de Linux son los siguientes:
/**
* dev_set_promiscuity - Actualiza el recuento de promiscuidad en el dispositivo
* @dev: Dispositivo
* @inc: Modificador
*
* Agrega o elimina promiscuidad de un dispositivo. La interfaz seguirá siendo promiscua mientras el recuento en el dispositivo
* permanezca por encima de cero. Una vez que el recuento llegue a cero,
* el dispositivo reanudará las operaciones de filtrado normales. Si el valor inc
* es negativo, el dispositivo descartará la promiscuidad.
*/
El código de implementación para configurar el modo promiscuo de la tarjeta de red es el siguiente:
struct net_device *sniffer_dev = NULL;
int dev_flags = 0 ;
int init_module (void) /* Inicialización del módulo*/
Inicialización del módulo.
{
......
sniffer_dev = dev_get_by_name("eth0");
if (sniffer_dev ! = NULL )
{
dev_flags = 1;
dev_set_promiscuity(sniffer_dev, 1);
dev_put(sniffer_dev);
sniffer_dev = NULL;
}
......
devuelve 0;
}
void cleanup_module(void)
{
......
if (dev_flags)
{ p> p>
sniffer_dev = dev_get_by_name("eth0");
if (sniffer_dev != NULL)
{
dev_flags = 0;
dev_set_promiscuity(sniffer_dev, -1); /*Tenga en cuenta el segundo parámetro aquí**
dev_put(sniffer_dev);
sniffer_dev = NULL;
}
}
......
}