Search code examples
c#dhcptftp

Filename string in DHCP/BOOTP/TFTP Read Request presenting extra characters


While building a basic Windows Image deployment solution (using WinPE and custom applications built in C#), I came across a problem of 2 Computers not being on the same subnet/IP segment (no static IP Address or DHCP Servers & DNS/Routing tables). To combat this I have written a basic but successful DHCP solution and extended it to TFTP for remote boot in C#.

This application was implemented using guidance in RFCs 1350, 4578, and has the beginnings of negotiation referenced in RFC 2347. I have managed to write a routine that sends the requested files to the remote application.

I have utilized the Wireshark application to examine my outgoing messages, and found that the DHCPOFFER and DHCPACK responses were malformed. These have been corrected, but leaving me with an issue with the TFTP implementation.

The client machine is requesting the provided boot file name, but appending extra bytes to the name before the 0 byte signifying the end of the file name string. Please see below excerpt from my code for extracting the file name from the TFTP Read Request (RRQ) message:

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)
        }
}

Where 'datagram' is a byte array received using a UDP Socket.

Code for converting the string to byte array to pass in the DHCPOFFER/ACK message:

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;
            }
    }

when using Encoding.ASCII.getString(tmpbytes[]) in console.WriteLine(), I ampresented with 'pxeboot.n12?'. Pre Wireshark and messaging correction, I was able to correctly extract the boot file name (in this case pxeboot.n12) from the TFTP RRQ, but it would fail on TFTP request for the BCD file (located in "Boot\BCD").

When I am able to extract the filename correctly (every file, every time), is there any other options that I should be passing back (i.e. option 93, 94 and 97 (System Architecture, Network ID version, UUID/GUID) or option 253 (noticed in Wireshark using another DHCP/TFTP solution)?


Solution

  • I have had to utilize the string.SubString() method:

    string filestring = Encoding.ASCII.GetString(tmpbytes); int pos = filestring.IndexOf("?"); filestring = filstring.SubString(0, pos-1);

    to remove the unwanted character from tmpbytes array.

    Options 93, 94 & 97 are now passed back in the DHCPOFFER message post options requested. Both DHCP and TFTP implementation now working as expected.