При создании базового решения для развертывания образа Windows (с использованием WinPE и пользовательских приложений, созданных на C#), я столкнулся с проблемой двух компьютеров, не находящихся в одном сегменте подсети/IP (без статического IP-адреса или DHCP-серверов и DNS/таблиц маршрутизации) . Чтобы бороться с этим, я написал простое, но успешное решение DHCP и расширил его до TFTP для удаленной загрузки на C#.
Это приложение было реализовано с использованием указаний в RFC 1350, 4578, а начало согласования упоминается в RFC 2347. Мне удалось написать процедуру, которая отправляет запрошенные файлы удаленному приложению.
Я использовал приложение Wireshark для проверки исходящих сообщений и обнаружил, что ответы DHCPOFFER и DHCPACK были искажены. Они были исправлены, но у меня осталась проблема с реализацией TFTP.
Клиентский компьютер запрашивает предоставленное имя загрузочного файла, но добавляет дополнительные байты к имени перед 0 байтом, обозначающим конец строки имени файла. См. ниже отрывок из моего кода для извлечения имени файла из сообщения TFTP Read Request (RRQ):
switch(datagram[1]) //position of OpCode Indicator
{
case (byte)TFTP_OpCode.RRQ
{
TidPort = new Random();
var port = TidPort.New(65200, 65350); // Server TX ID & Port
offset = offset + 1;
int strlength = 0;
while (datagram[offset] != (byte)0)
{
strlengeth++;
offset++
}
byte[] tmpbytes = new byte[strlength -1];
Array.Copy(datagram, 2, tmpbytes, 0, strlength -1)
}
}
Где «датаграмма» — это массив байтов, полученный с использованием сокета UDP.
Код для преобразования строки в массив байтов для передачи в сообщении DHCPOFFER/ACK:
switch (option)
{
case BOOTFILE:
{
byte[] tmpbytes = new byte[Encoding.ASCII.GetByteCount("pxeboot.n12")];
tmpbytes = Encoding.ASCII.GetBytes("pxeboot.n12");
_totalLength = tmpbytes.Length + 2;
_option = new byte[_totalLength];
_option[0] = (byte)BOOTFILE;
_option[1] = (byte)tmpbytes.Length;
Array.Copy(tmpbytes, 0, _option, 2, tmpbytes.Length);
Array.Copy(_option, 0, result, optionPosition, _option.Length);
optionPosition = optionPosition + _totalLength;
break;
}
}
при использовании Encoding.ASCII.getString(tmpbytes[]) в console.WriteLine() мне представляется «pxeboot.n12?». До исправления Wireshark и обмена сообщениями мне удалось правильно извлечь имя загрузочного файла (в данном случае pxeboot.n12) из TFTP RRQ, но при запросе TFTP для файла BCD (находящегося в «Boot\BCD») это не удалось.
Когда я могу правильно извлечь имя файла (каждый файл, каждый раз), есть ли какие-либо другие параметры, которые я должен передать обратно (например, параметры 93, 94 и 97 (архитектура системы, версия идентификатора сети, UUID/GUID) или вариант 253 (замечено в Wireshark при использовании другого решения DHCP/TFTP)?