Windows 10 игнорирует таблицу маршрутизации

Windows 10 игнорирует таблицу маршрутизации

У меня есть ПК с Windows 10, на котором есть 2 сетевых интерфейса. Один из этих интерфейсов идет в основную локальную сеть, где расположены файловый сервер, DNS и маршрутизатор для интернета. Второй интерфейс — это крошечная локальная сеть, в которой есть PLC и HMI. Они оба физически находятся в одной локальной сети, но в разных подсетях (извините, не могу это изменить, это вне моего контроля).

Итак, у меня есть два физических интерфейса и один логический: eth0: DHCP, 172.16.xy, МАСКА 255.255.255.0, gw по умолчанию 172.16.xz eth1: статический 192.168.1.158, МАСКА 255.255.255.0 статический 192.168.19.158, МАСКА 255.255.255.0

HMI доступен по адресу 192.168.19.135

Теперь, когда я перезагружаю HMI, я запускаю пинг, чтобы увидеть, когда он снова будет доступен. Это должно произойти примерно через 30 секунд. Но я получаю положительный ответ пинга только через 80-90 секунд.

Ping wird ausgeführt für 192.168.19.135 mit 32 Bytes Daten:
Antwort von 192.168.19.158: Zielhost nicht erreichbar.
Zeitüberschreitung der Anforderung.
Zeitüberschreitung der Anforderung.
Zeitüberschreitung der Anforderung.

(извините за немецкий текст, но я думаю, что все равно должно быть понятно, что мы здесь видим) Я получаю другой ответ на первый пинг, чем на второй.

Похоже, что Windows после XP начала делать некую "магию маршрутизации" и просто отправлять данные по маршруту по умолчанию, если они не могут достичь цели по более конкретному маршруту. Похоже, что и другие тоже имелиЭта проблема

Я нашел несколько «решений», которые для меня не являются настоящими решениями (подробнее об этом ниже)

  1. Итак, у ping есть хороший параметр "-S" для определения исходного адреса. И да, это "решает" проблему. Я получаю ответ мгновенно, если HMI работает. Но я использую эту команду в скрипте powershell, и параметр источника для "test-connection" имеет совершенно другое значение. И поскольку я использую это в скрипте, это дает сбой, как только меняется локальный IP.
  2. Я настроил eth0 статически, а не по DHCP, и не определил маршрут по умолчанию. Это также «решило» проблему (думаю, вы можете себе представить, почему это на самом деле не решение)
  3. Я только теоретически исследовал это, но я мог бы установить маршрутизатор на базе Linux с 3 интерфейсами между ПК, локальной сетью и изолированной локальной сетью с ПЛК и HMI и позволить ему выполнять всю маршрутизацию (это наверняка решило бы проблему! Но, честно говоря, нужен ли мне дополнительный компьютер только для того, чтобы обойти неисправную маршрутизацию Windows?)
  4. ´arp -d *´ тоже вроде бы помогает, но нужны повышенные привилегии

Я пробовал добавлять статические маршруты с разными параметрами и метриками. Никаких изменений! Добавление MAC HMI статически не помогает, так как этот MAC может меняться.

Итак, мои вопросы:

  1. есть ли какая-либо документация по этому изменению поведения в Windows?
  2. есть ли способ заставить Windows использовать определенный интерфейс?

решение1

Поэтому, не найдя простого решения, я решил программно обойти проблему, созданную Microsoft, серьезно испортив маршрутизацию в Windows.

Я сейчас использую классический ping с параметром -S вместо командлета test-connection в powershell

Теперь часть моего кода, отвечающая за ping, выглядит так:

$localIPs = (Get-NetIPConfiguration -InterfaceAlias "PLC").IPv4Address.IPAddress

# because this command returns a string, when the interface has a single IP-address but an array of strings if the interface has more than one address, we need to check for this
if ($localIPs.GetType().Name -eq "string") { # only a single IP
  $localIP = $localIPs
}
else { # more than one IP
  $localIP = $localIPs[0] # since it seems that windows does use the ip address as a synonym for the interface, it's not important which of the addresses of that interface we use. So we're just picking the first one
}

$pingcount = 180

do {
  ping $HMI4IP -n 1 -w 1000 -S $localIP | Out-Null # redirect the output of ping to /dev/null
  $pingreply = $?
  $pingcount = $pingcount - 1
}
until ($pingcount -eq '0' -or $pingreply)
if ($pingreply) {
  # code here
}
else {
  exit 1337 # return with an error code, we've not reached our target
}

Для этого мне просто нужно убедиться, что интерфейс, где соединены ПЛК и HMI, называется "PLC". Затем я получаю адрес в виде строки или массива адресов (в зависимости от того, имеет ли интерфейс один или несколько адресов), которые мне нужно обработать (добро пожаловать в динамическую типизацию...). Затем это так же просто, как скормить эти данные ping (потому что Test-Connection пытается быть слишком умным для своего же блага). В $? я получаю true для последней команды, вернувшей успех, и false, если она была неудачной. Так что с этим легко справиться с этого момента.

Насколько я могу судить, у Microsoft нет документации по такому поведению и способам его решения, что, по-моему, весьма печально.

Связанный контент