Проблема создания простого NTP-сервера, который отвечает системному времени сервера - PullRequest
0 голосов
/ 22 февраля 2019

Я пытаюсь создать очень простой сервер NTP (v3), который получает запросы NTP от IP-камер в локальной сети для синхронизации времени.Камеры отключены от интернета, поэтому идея заключается в том, чтобы использовать локальный сервер ПК в качестве NTP-сервера для камер.

Я пробовал два разных подхода.

  1. Запись простой переадресации UDP наизвестный NTP-сервер (например, time.windows.com).Это работает хорошо.
  2. Напишите простой UDP-сервер, прослушивающий порт 123 для входящих запросов NTP, который просто возвращает системное время сервера.Это также работает довольно хорошо для простых нетребовательных клиентов NTP (например, физического сетевого маршрутизатора), но продолжает работать с ошибкой для локальной камеры HIKVISION.

Метод: получить 48-байтовый буфер.Убедитесь, что байт со смещением 0 равен 0x1B.Поверните байт со смещением 0 в 0x1C и запишите текущее время UTC в последние 8 байтов в качестве метки времени NTP.Это отлично работает для большинства клиентов NTP, но не для HIKVISION.

Камера отправляет этот запрос:

1B-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
00-00-00-00-00-00-00-00-61-8C-DE-CA-C3-73-89-DC

Последние 8 байтов отличны от нуля.Если я пытаюсь изменить свое решение для пересылки UDP [1], чтобы последние 8 байтов обнулялись перед пересылкой, камера сообщает об ошибке.Получается, что эти биты важны и, возможно, имеют какое-то криптографическое значение.

Я копался в RFC, чтобы попытаться понять этот бит, но не смог найти объяснения.Любой пример кода, который я смог найти, полностью игнорирует это и идет по простому маршруту.

Итак, вопрос в том ... как интерпретировать завершающие байты запроса NTP и как вернуть правильный ответ NTP?Некоторые примеры кода или ссылки на ресурсы приветствуются.

1 Ответ

0 голосов
/ 26 февраля 2019

См. Приложение A, начиная со страницы 50 https://www.ietf.org/rfc/rfc1305.pdf, для описания формата пакета NTP.Предполагается, что эти последние 8 байтов содержат метку времени ответа сервера - именно поэтому вы добавляете метку времени в эти байты при создании минимального пакета ответа.

Однако, исходя из того факта, что этот клиент поставилзначение в этих последних 8 байтах, похоже, что он хочет использовать механизм, описанный в разделе 5 протокола SNTP (Simple NTP), для https://www.ietf.org/rfc/rfc2030.txt SNTP использует тот же формат пакета, что и NTP, но использует поля в несколькодругой путь.В SNTP значение, которое клиент помещает в байты с 40 по 47, представляет собой текущее представление клиента о времени.(В этом случае это справедливо, AFAICT, эта временная метка где-то около 1951 года.)

Если это то, что пытается сделать этот клиент, то он хочет, чтобы сервер скопировал эти 8 байтов в байты 24-31(поле Originate Timestamp), а затем запишите текущее время сервера в байты 32-39 (метка времени приема) и в байты 40-47 (метка времени передачи) и отправьте его в качестве ответа.Конечно, также продолжайте изменять первый байт на 0x1C в ответе, чтобы указать, что этот пакет исходит от сервера.Вам также следует установить значение Stratum в байте 1 равным вероятному ненулевому значению, например, 3 или 4.

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

Не думаю, что вам нужно усложнять свою логику, особенно обращаясь с этим клиентом.Вероятно, вы можете применить точно такую ​​же логику к пакетам от клиентов, которые помещают нули в последние 8 байтов.Это просто означает, что вы будете копировать нули в поле Originate Timestamp при построении ответов для этих клиентов.

...