Как отправить пакет WOL (или что-то вообще) через ник, который не имеет IP-адреса?
Я пытаюсь отправить пакет WOL на все интерфейсы, чтобы разбудить шлюз (который является сервером DHCP, поэтому у машины еще не будет IP).
И кажется, что я могу привязать сокеты только к парам IP и портов...
Итак, вопрос таков: как создать сокет (или что-то еще), связанный с сетевым адаптером, у которого нет IP? (Любой язык в порядке. C# предпочтительнее)
@ctacke: Я знаю, что WOL выполняется по MAC-адресу... Моя проблема заключается в том, что Windows отправляет только широковещательные пакеты UDP на сетевую карту, которую Windows считает основной сетевой картой (которая даже не является сетевой картой с маршрутом по умолчанию на моем компьютере с Vista). И я не могу найти способ привязать сокет к интерфейсу, который не имеет IP-адрес. (как это делают клиенты DHCP)
@Arnout: почему бы и нет? Клиенты знают MAC-адрес шлюза. Я просто хочу отправить пакет WOL, как изначально делает DHCP-клиент...(DHCP обнаруживает, что пакеты обнаруживают, что он получен с 0.0.0.0) Я не возражаю, если мне придется создавать весь пакет байт за байтом...
4 ответа
Кажется, я нашел решение. Можно использовать 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();
}
}
WOL - это очень гибкий протокол, который может быть реализован несколькими различными способами.
Наиболее распространенными являются:
- Отправка WOL в качестве полезной нагрузки пакета Ethernet.
- Отправка WOL в качестве полезной нагрузки пакета UDP (для маршрутизации по сети).
Как только он попадает в локальную сеть, он передается всем хостам в сети, используя широковещательный MAC-адрес.
Для пакета Ethernet структура имеет вид:
- MAC-адрес получателя: FF:FF:FF:FF:FF:FF (трансляция)
- Магический пакет полезной нагрузки
Для пакета UDP структура имеет вид:
- MAC-адрес получателя: FF:FF:FF:FF:FF:FF (трансляция)
- Порт UDP: 9
- Магический пакет полезной нагрузки
Магическая полезная нагрузка состоит из:
- Поток синхронизации: FFFFFFFFFFFF (это 6 пар или 6 байтов FF)
- 16 копий MAC-адреса компьютера, на который вы посылаете WOL
- Необязательный пароль 0, 4 или 6 байтов.
Для получения пакетов WOL из Интернета (через брандмауэр / маршрутизатор):
- Сконфигурируйте порт 9 маршрутизатора для пересылки на IP 255.255.255.255 (Broadcast IP)
- Установите IP-адрес получателя: внешний IP-адрес маршрутизатора.
Примечание. Этого можно достичь только на примере UDP, поскольку в пакетах Ethernet отсутствует уровень IP, необходимый для маршрутизации пакета через Интернет. IE, пакеты Ethernet являются опцией только для локальной сети. Проблема с отправкой пакетов WOL через UDP связана с безопасностью, поскольку необходимо настроить маршрутизатор для включения IP-вещания (255.255.255.255). Включение широковещательной рассылки по IP обычно считается плохой идеей из-за дополнительного риска внутренней атаки в сети (переполнение Ping, подмена кэша и т. Д.).
Для получения дополнительной информации о протоколе, включая образец захвата, посетите этот сайт.
Если вам нужен быстрый и грязный инструмент командной строки, который генерирует пакеты WOL (а вы работаете в Debian, Linux Mint или Ubuntu), вы можете установить инструмент, который уже делает это.
Просто установите с помощью командной строки:
sudo apt-get install wakeonlan
Обновить:
Вот рабочий пример, который генерирует пакет WakeOnLan с использованием текущей версии 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();
}
}
}
Примечание. Это полнофункциональное консольное приложение для отправки пакетов Wake-On-Lan, созданное на примере Example09, которое можно найти в источнике SharpPcap.
Библиотеки, используемые в этом примере, которые не могут быть найдены в.NET Framework:
using PacketDotNet;
Эта библиотека (.dll) поставляется в комплекте с SharpPcap. Он отвечает за всю конструкцию пакета и его разбор в SharpPcap. Здесь находится класс WakeOnLan.
Примечание. Код создания / синтаксического анализа пакета изначально был включен в SharpPcap.dll. Он был перенесен в свою собственную библиотеку, поскольку SharpPcap предназначен для работы с winpcap. Многие из его пользователей занимаются разработкой протоколов и / или обработкой необработанных сетевых пакетов.
using SharpPcap;
SharpPcap содержит весь код оболочки winpcap(windows)/libpcap(*nix). Нужно выбрать интерфейс и отправить фактические пакеты по проводам.
.NET работает как виртуальная машина (CLR), поэтому он абстрагирует большую часть базовой машины. Например, он предоставляет только интерфейсы для сетей TCP и UDP, которые в стеке сетевых протоколов намного выше того, что вы обсуждаете. Возможно, вам удастся найти сторонний компонент, который предоставляет доступ к низкоуровневому интерфейсу, но я бы на это не рассчитывал (в прошлом я смотрел на.NET и Java).
Для доступа к этому минимуму в стеке сетевых протоколов вам, вероятно, потребуется кодировать на C соответствующие системные вызовы ОС. Вы можете найти это проще всего в Python, и вы можете обнаружить, что эта функция уже реализована в библиотеках Python или сторонних. Например, я предлагаю взглянуть на сетевые библиотеки Twisted. Это была одна из причин, по которой я переключился на Python для большей части моей работы.
С наилучшими пожеланиями.