c# - traves - ¿Cómo enviar un paquete WOL(o cualquier cosa) a través de un dispositivo que no tiene una dirección IP?
tipos de paquetes de datos (4)
Estoy intentando enviar un paquete WOL en todas las interfaces para activar la puerta de enlace (que es el servidor DHCP, por lo que la máquina aún no tendrá una IP).
Y parece que solo puedo vincular tomas a IP y pares de puertos ...
Entonces la pregunta es: ¿cómo se puede crear un socket (u otra cosa) que esté vinculado a una NIC que no tenga IP? (Cualquier languge está bien. Se prefiere c #)
@ctacke: Sé que WOL se hace por dirección MAC ... Mi problema es que Windows solo envía difusiones UDP en la NIC lo que Windows considera que es la NIC principal (que ni siquiera es la NIC con la ruta predeterminada en mi máquina Vista ) Y parece que no puedo encontrar la manera de vincular un socket a una interfaz que no tiene una dirección IP. (al igual que los clientes de DHCP hacen esto)
@Arnout: ¿Por qué no? Los clientes conocen la dirección MAC de la puerta de enlace. Solo quiero enviar un paquete WOL como lo hace un cliente DHCP ... (DHCP descubre que los paquetes provienen de 0.0.0.0) No me importa si tengo que construir todo el paquete byte por byte ...
.NET funciona como una máquina virtual (el CLR), por lo que abstrae gran parte de la máquina real subyacente. Por ejemplo, solo proporciona interfaces para redes TCP y UDP, que es mucho más alta en la pila de protocolos de red de la que está hablando. Es posible que pueda encontrar un componente de un tercero que brinde acceso a una interfaz de nivel inferior, pero no contaría con eso (en el pasado busqué .NET y Java).
Para acceder a ese nivel bajo en la pila de protocolos de red, probablemente necesite codificar en C las llamadas al sistema operativo relevante. Puede encontrar esto más fácil en Python, y puede encontrar esta funcionalidad ya implementada en las bibliotecas de Python o de terceros. Por ejemplo, sugiero echar un vistazo a las bibliotecas de redes Twisted. Esa fue una de las razones por las que cambié a Python durante gran parte de mi trabajo.
Los mejores deseos.
WOL está hecho por MAC, no por IP. Aquí hay un ejemplo .
Parece que he encontrado una solución. Uno puede usar winpcap para inyectar paquetes a cualquier interfaz. Y hay un buen contenedor para .net: http://www.tamirgal.com/home/dev.aspx?Item=SharpPcap
(Hubiera preferido una solución que no requiere la instalación de bibliotecas adicionales ...)
ACTUALIZACIÓN: Esto es lo que surgió para enviar un paquete WOL en todas las interfaces:
//You need SharpPcap for this to work
private void WakeFunction(string MAC_ADDRESS)
{
/* Retrieve the device list */
Tamir.IPLib.PcapDeviceList devices = Tamir.IPLib.SharpPcap.GetAllDevices();
/*If no device exists, print error */
if (devices.Count < 1)
{
Console.WriteLine("No device found on this machine");
return;
}
foreach (NetworkDevice device in devices)
{
//Open the device
device.PcapOpen();
//A magic packet is a broadcast frame containing anywhere within its payload: 6 bytes of ones
//(resulting in hexadecimal FF FF FF FF FF FF), followed by sixteen repetitions
byte[] bytes = new byte[120];
int counter = 0;
for (int y = 0; y < 6; y++)
bytes[counter++] = 0xFF;
//now repeat MAC 16 times
for (int y = 0; y < 16; y++)
{
int i = 0;
for (int z = 0; z < 6; z++)
{
bytes[counter++] =
byte.Parse(MAC_ADDRESS.Substring(i, 2),
NumberStyles.HexNumber);
i += 2;
}
}
byte[] etherheader = new byte[54];//If you say so...
var myPacket = new Tamir.IPLib.Packets.UDPPacket(EthernetFields_Fields.ETH_HEADER_LEN, etherheader);
//Ethernet
myPacket.DestinationHwAddress = "FFFFFFFFFFFFF";//it''s buggy if you don''t have lots of "F"s... (I don''t really understand it...)
try { myPacket.SourceHwAddress = device.MacAddress; }
catch { myPacket.SourceHwAddress = "0ABCDEF"; }//whatever
myPacket.EthernetProtocol = EthernetProtocols_Fields.IP;
//IP
myPacket.DestinationAddress = "255.255.255.255";
try { myPacket.SourceAddress = device.IpAddress; }
catch { myPacket.SourceAddress = "0.0.0.0"; }
myPacket.IPProtocol = IPProtocols_Fields.UDP;
myPacket.TimeToLive = 50;
myPacket.Id = 100;
myPacket.Version = 4;
myPacket.IPTotalLength = bytes.Length - EthernetFields_Fields.ETH_HEADER_LEN; //Set the correct IP length
myPacket.IPHeaderLength = IPFields_Fields.IP_HEADER_LEN;
//UDP
myPacket.SourcePort = 9;
myPacket.DestinationPort = 9;
myPacket.UDPLength = UDPFields_Fields.UDP_HEADER_LEN;
myPacket.UDPData = bytes;
myPacket.ComputeIPChecksum();
myPacket.ComputeUDPChecksum();
try
{
//Send the packet out the network device
device.PcapSendPacket(myPacket);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
device.PcapClose();
}
}
WOL es un protocolo muy flexible que se puede implementar de múltiples maneras.
Los más comunes son:
- Enviar un WOL como la carga útil de un paquete de Ethernet.
- Enviar un WOL como la carga útil de un paquete UDP (para el enrutamiento a través de la red).
Una vez que aterriza en la red local, pasa a todos los hosts de la red que utilizan la dirección MAC de difusión.
Para un paquete de Ethernet, la estructura es:
- MAC de destino: FF: FF: FF: FF: FF: FF (Transmisión)
- Una carga útil de paquete mágico
Para un paquete UDP, la estructura es:
- MAC de destino: FF: FF: FF: FF: FF: FF (Transmisión)
- Puerto UDP: 9
- Una carga útil de paquete mágico
La carga útil mágica consiste en:
- El flujo de sincronización: FFFFFFFFFFFF (eso es 6 pares o 6 bytes de FF)
- 16 copias de la MAC de la computadora a la que estás apuntando a WOL
- Una frase de contraseña opcional de 0, 4 o 6 bytes.
Para recibir paquetes WOL de Internet (a través de un firewall / enrutador):
- Configure el puerto 9 del enrutador para reenviar a IP 255.255.255.255 (IP de difusión)
- Establezca la IP de destino: la IP externa del enrutador
Nota: Esto solo se puede lograr utilizando el ejemplo de UDP porque los paquetes de Ethernet carecen de la capa de IP necesaria para que el paquete se enrute a través de Internet. IE, los paquetes de Ethernet son la opción de solo red local. El problema con el envío de paquetes WOL a través de UDP es la seguridad porque debe configurar el enrutador para habilitar la transmisión IP (255.255.255.255). Permitir la transmisión por IP generalmente se considera una mala idea debido al riesgo adicional de ataque interno dentro de la red (Ping flooding, cache spoofing, etc.).
Para obtener más información sobre el protocolo, incluida una captura de muestra, consulte este sitio .
Si desea una herramienta de línea de comandos rápida y sucia que genere paquetes WOL (y se ejecuta en Debian, Linux mint o Ubuntu), puede instalar una herramienta que ya lo haga.
Simplemente instale usando la línea de comando con:
sudo apt-get install wakeonlan
Actualizar:
Aquí hay un ejemplo de trabajo que genera un paquete WakeOnLan usando la versión actual de SharpPcap.
using System;
using System.Collections.Generic;
using System.Net.NetworkInformation;
using PacketDotNet;
using SharpPcap;
namespace SharpPcap.Test.Example9
{
public class DumpTCP
{
public static void Main(string[] args)
{
// Print SharpPcap version
string ver = SharpPcap.Version.VersionString;
Console.WriteLine("SharpPcap {0}, Example9.SendPacket.cs/n", ver);
// Retrieve the device list
var devices = CaptureDeviceList.Instance;
// If no devices were found print an error
if(devices.Count < 1)
{
Console.WriteLine("No devices were found on this machine");
return;
}
Console.WriteLine("The following devices are available on this machine:");
Console.WriteLine("----------------------------------------------------");
Console.WriteLine();
int i = 0;
// Print out the available devices
foreach(var dev in devices)
{
Console.WriteLine("{0}) {1}",i,dev.Description);
i++;
}
Console.WriteLine();
Console.Write("-- Please choose a device to send a packet on: ");
i = int.Parse( Console.ReadLine() );
var device = devices[i];
Console.Write("What MAC address are you sending the WOL packet to: ");
string response = Console.ReadLine().ToLower().Replace(":", "-");
//Open the device
device.Open();
EthernetPacket ethernet = new EthernetPacket(PhysicalAddress.Parse(
"ff-ff-ff-ff-ff-ff"), PhysicalAddress.Parse("ff-ff-ff-ff-ff-ff"),
EthernetPacketType.WakeOnLan);
ethernet.PayloadPacket = new WakeOnLanPacket(
PhysicalAddress.Parse(response));
byte[] bytes = ethernet.BytesHighPerformance.Bytes;
try
{
//Send the packet out the network device
device.SendPacket(bytes);
Console.WriteLine("-- Packet sent successfuly.");
}
catch(Exception e)
{
Console.WriteLine("-- "+ e.Message );
}
//Close the pcap device
device.Close();
Console.WriteLine("-- Device closed.");
Console.Write("Hit ''Enter'' to exit...");
Console.ReadLine();
}
}
}
Nota: Esta es una aplicación de consola de envío de paquetes Wake-On-Lan completamente funcional construida en el Example09 que se puede encontrar en la fuente SharpPcap.
Las bibliotecas utilizadas en este ejemplo que no se pueden encontrar en .NET Framework son:
using PacketDotNet;
Esta biblioteca (.dll) viene empaquetada con SharpPcap. Es responsable de la construcción y el análisis de todos los paquetes dentro de SharpPcap. Aquí es donde reside la clase WakeOnLan.
Nota: El código de construcción / análisis del paquete se incluyó originalmente en SharpPcap.dll. Se migró a su propia versión porque SharpPcap está destinado a ser un contenedor para winpcap. Muchos de sus usuarios se ocupan de diseñar protocolos y / o manejar paquetes de redes sin procesar.
using SharpPcap;
SharpPcap contiene todo el código del wrapper winpcap (windows) / libpcap (* nix). Es necesario seleccionar la interfaz y enviar los paquetes reales a través del cable.