我正在尝试在所有接口上发送WOL包以唤醒网关(这是DHCP服务器,因此机器还没有IP).
似乎我只能将套接字绑定到IP和端口对......
所以问题是:如何创建一个绑定到没有IP的NIC的套接字(或其他东西)?(任何语言都可以.c#是首选)
@ctacke:我知道WOL是由MAC地址完成的...我的问题是Windows只在NIC上发送UDP广播,Windows认为是主要的NIC(甚至连我的Vista机器上的默认路由都不是NIC) ).我似乎无法找到一种方法将套接字绑定到没有IP地址的接口.(像DHCP客户端这样做)
@Arnout:为什么不呢?客户端知道网关的MAC地址.我只想要像DHCP客户端一样发送WOL数据包... ...(DHCP发现数据包声称来自0.0.0.0)我不介意我是否必须逐字节构造整个数据包...
似乎我找到了解决方案.可以使用winpcap将数据包注入任何接口.并且有.net的好包装:http://www.tamirgal.com/home/dev.aspx?Item = SharpPcap
(我本来希望一个解决方案,不需要安装额外的库......)
更新:以下是我在所有接口上发送WOL数据包的方法:
//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(); } }