Строка имени файла в запросе на чтение DHCP/BOOTP/TFTP с дополнительными символами
При создании базового решения для развертывания образа 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) из RRQ TFTP, но это не сработало при запросе TFTP для файла BCD (находится в "Boot\BCD").
Когда я могу правильно извлечь имя файла (каждый файл, каждый раз), есть ли какие-либо другие опции, которые я должен передать обратно (например, опции 93, 94 и 97 (архитектура системы, версия идентификатора сети, UUID/GUID) или опция 253 (замечено в Wireshark с использованием другого решения DHCP/TFTP)?
1 ответ
Мне пришлось использовать метод string.SubString():
string filestring = Encoding.ASCII.GetString(tmpbytes);
int pos = filestring.IndexOf("?");
filestring = filstring.SubString(0, pos-1);
удалить ненужный символ из массива tmpbytes.
Опции 93, 94 и 97 теперь передаются обратно в запрошенных опциях сообщения сообщения DHCPOFFER. И реализация DHCP, и TFTP теперь работают как положено.