Назад | Перейти на главную страницу

Пробуждение по локальной сети в разных подсетях

У меня 3 блока IP и 3 коммутатора Cisco. У каждого коммутатора свой IP-блок - 10.45.100.0/24, 10.45.101.0/24 и 10.45.102.0/24.

У меня ПК на блоке 10.45.100.0/24. Я могу разбудить целые компьютеры (с IP-адресом, Mac-адресом, подсетью, портом) в этом IP-блоке из C #.

Но когда я пытаюсь разбудить другую машину с другого IP-блока, это не работает.

Это проблема сети или проблема с кодом? Как я могу это решить?

Это фундаментальная проблема: WOL работает только внутри подсети, потому что волшебный пакет WOL не является действительным IP-пакетом и, следовательно, не маршрутизируется за пределы локальной сети.

Запись в википедии описывает решение этой проблемы (широковещательные рассылки, направленные на подсеть), но я никогда не видел этого в действии. Другой способ решения проблемы может заключаться в создании прокси-агента WOL, который пересылает пакеты WOL в другие подсети (т. Е. Как пакет UDP).

Если у вас есть три разные подсети, эти подсети не могут взаимодействовать друг с другом без маршрутизатора.

Это 100% преднамеренно и намеренно.

Ваш шлюз по умолчанию с машины, с которой вы пытаетесь выполнить WOL должен Explicity знает, как попасть в эти другие подсети, иначе он отправит ваш пакет в Интернет, где он будет немедленно сброшен вашим провайдером.

Итак, у вас есть два варианта:

  1. Настройте правильную маршрутизацию между подсетями
  2. Уменьшите маску подсети до 255.255.0.0 (/ 16), чтобы все машины находились в одной подсети. Я не рекомендую этого, поскольку я уверен, что есть причина, по которой ваши машины разделены на подсети друг от друга.

Одно из возможных решений: добавьте вторую (даже третью) сетевую карту к вашему управляющему компьютеру, а затем настройте другие IP-адреса для прямого подключения к другим маршрутизаторам. Затем волшебные пакеты будут передавать связанный сетевой адаптер на основе IP-адреса назначения в команде WOL (IP, MAC, подсеть, порт).

Как вы заметили, волшебные пакеты WOL являются подсетями. Вы можете использовать Unicast или Subnet-Directed Broadcast в зависимости от того, что вы можете включить в конфигурации вашей сети / маршрутизатора:

https://technet.microsoft.com/en-us/library/bb632911.aspx

Недостатком этого является то, что направленные широковещательные рассылки обычно не поддерживаются по умолчанию из-за проблем с безопасностью и производительностью. В то время как Unicast обычно зависит от памяти таблицы MAC-адресов, хранящейся в конфигурациях маршрутизатора, которые очищаются, как правило, примерно за четыре часа.

У меня есть решение, но оно работает для фиксированных IP-адресов. Я не знаю, но можно было бы изменить код, чтобы исправить это для динамических адресов.

Все, что вам нужно - отправить волшебный пакет на фиксированный адрес вашего компьютера. Я создал небольшую утилиту.

Моя подсеть 172.17.111.0/24, пакеты отправляются с 172.17.105.0/24

class Program
{
    static readonly Tuple<string, byte[]>[] Addr = {
        new Tuple<string, byte[]>("**-**-30-9D-98-61", new byte[] { 172, 17, 111, 91 }),
        new Tuple<string, byte[]>("**-**-D9-7B-9D-E9", new byte[] { 172, 17, 111, 70 }),
    };

    static void Main(string[] args)
    {
        var id = args.Length > 0 ? int.Parse(args[0]) : 0;

        WolClass client = new WolClass();
        client.Connect(new IPAddress(Addr[id].Item2),  0x9); 
        client.SetClientToBrodcastMode();
        //set sending bites
        int counter = 0;
        //buffer to be send
        byte[] bytes = new byte[1024];   
        //first 6 bytes should be 0xFF
        for (int y = 0; y < 6; y++)
            bytes[counter++] = 0xFF;
        //now repeate MAC 16 times
        for (int y = 0; y < 16; y++)
        {
            int i = 0;
            for (int z = 0; z < 6; z++)
            {
                bytes[counter++] = byte.Parse(Addr[id].Item1.Substring(i, 2), 
                                              NumberStyles.HexNumber);
                i += 3;
            }
        }

        //now send wake up packet
        client.Send(bytes, 1024);
    }
}

public class WolClass : UdpClient
{
    //this is needed to send broadcast packet
    public void SetClientToBrodcastMode()
    {
        if (this.Active)
            this.Client.SetSocketOption(SocketOptionLevel.Socket,
                SocketOptionName.Broadcast, 0);
    }
}

В Linux я использую волк (v0.7.1) для отправки пакетов WOL Magic на определенный широковещательный адрес:

wol -v --host=192.168.2.255 --port=9 a5:bd:dc:fe:38:8c
Waking up a5:bd:dc:fe:38:8c with 192.168.2.255:9...

У моего сервера есть отдельный интерфейс в подсети 192.168.1.0 для общедоступного подключения к Интернету, а мой Wake On LAN узлы находятся в частной подсети 192.168.2.0.

В Windows я использовал WakeMeOnLan (v1.83), чтобы сделать то же самое. Он также поддерживает настраиваемый широковещательный адрес. Версии до 1.68 имели Использовать широковещательный адрес в соответствии с IP-адресом функция, которая могла быть удалена из более поздних версий.

Вероятно, проблема в сети. Вы отправляете широковещательное сообщение, которое, вероятно, заблокировано вашим брандмауэром / маршрутизатором, потому что вы редко разрешаете широковещательному трафику пересекать сети.

Я предполагаю, что вы можете разбудить компьютеры по их индивидуальному IP? Если вы тоже не можете этого сделать, я бы сказал, что ваш брандмауэр полностью блокирует пробуждение по локальной сети.