class TFTP::Protocol::Packet

Used to decode incoming packets TFTP packets have a simple structure: the port number from the encapsulating UDP datagram doubles as a ‘transfer ID’,

allowing multiple, simultaneous transfers betweent the same hosts

The first 2 bytes of the payload are an integral ‘opcode’ from 1-5, in network byte order The opcodes are: Read ReQuest, Write ReQuest, DATA, ACK, and ERROR Depending on the opcode, different fields can follow. All fields are either 16-bit integers in network byte order,

or null-terminated strings

Constants

OPCODES

Attributes

block_no[R]
data[R]
filename[R]
opcode[R]

Public Class Methods

new(data) click to toggle source
# File lib/em-tftp.rb, line 45
def initialize(data)
  raise TFTP::Error, "TFTP packet too small (#{data.size} bytes)" if data.size < 4
  raise TFTP::Error, "TFTP packet too large (#{data.size} bytes)" if data.size > 516
  @opcode = OPCODES[data.getbyte(1)]
  if opcode == :data
    @block_no = (data.getbyte(2) << 8) + data.getbyte(3)
    @data = data[4..-1]
  elsif opcode == :rrq || opcode == :wrq
    @filename, _mode = data[2..-1].unpack("Z*Z*") # mode is ignored
  elsif opcode == :error
    @err_code = (data.getbyte(2) << 8) + data.getbyte(3)
    @err_msg  = data[4..-2] # don't include null terminator
    if @err_msg.size == 0
      @err_msg = ERROR_MESSAGES[@err_code] || "Unknown error"
    end
    raise TFTP::Error, @err_msg
  elsif opcode == :ack
    @block_no = (data.getbyte(2) << 8) + data.getbyte(3)
  else
    raise TFTP::Error, "Unknown TFTP packet type (opcode #{data.getbyte(1)})"
  end
end