0

Regarding the RFC of TFTP (Trivial File Transfer Protocol), the RRQ/WRQ (Read\write requests) packet has this format:

    2 bytes     string    1 byte     string   1 byte
    ------------------------------------------------
    | Opcode |  Filename  |   0  |    Mode    |   0 |
    ------------------------------------------------

Mode can be either "netascii", "octet" (equivalent to binary) or "mail". The thing is netascii is 8 letters, octet has 5 and mail has 4.

I am creating my packet in my client like this:

paq = struct.pack('!H'+str(len(fileName))+'sB'+str(len(mode))+'sB', 02, fileName, 0, mode, 0)

And then I send the packet to the server so the server knows what to expect (A read in case of an RRQ or a write otherwise).

The thing is, I don't know how to unpack the packet if I don't know the string lengths on the server's side... Only the client knows the file length and the mode length, since he makes the packet.

Should I send the lengths to the server before the RRQ/WRQ packet so I know the format to use when unpacking? Is there another way?

Thank you!

5
  • The strings are terminated by a 0 byte. Search for that byte and then extract the string up to it. Commented May 22, 2018 at 21:04
  • You can't use unpack() to extract the fields, except for the Opcode. Commented May 22, 2018 at 21:05
  • Are you sure the mode is binari? I'd expect it to be binary, since the designers of TFTP spoke English. Commented May 22, 2018 at 21:06
  • @Barmar actually there are three modes which are "netascii", "octet" (equivalent to binary), and "mail". Problem still the same.. different lenghts. How would you extract the string until it finds a 0? Commented May 22, 2018 at 21:14
  • If the packet is in p, p[2:p.find('\0')] is the filename Commented May 22, 2018 at 21:18

1 Answer 1

1

If the received packet is in the byte array p, you can search for the 0 delimiters with find().

opcode = p[0:2].decode('ASCII')
nameEnd = p.find(b'\0', start=2)
filename = p[2:nameEnd].decode('ASCII')
modeEnd = p.find(b'\0', start=nameEnd+1)
mode = p[nameEnd+1:modeEnd].decode('ASCII')
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks a lot! I really appreciate it! I knew how to use the packet[ : ] thing but I didn't know it could be combined with .find() method! I really appreciate your help!
Why wouldn't you be able to combine it with find()? It's just numbers, it doesn't matter how you get the numbers.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.