Class: PacketGen::Header::TFTP
- Defined in:
- lib/packetgen/header/tftp.rb
Overview
A TFTP (Trivial File Transfer Protocol, RFC 1350) header consists of:
-
an #opcode (
BinStruct::Int16Enum
), -
and a body. Its content depends on opcode.
Specialized subclasses exists to handle Read Request, Write Request, DATA, ACK and ERROR packets.
TFTP parsing
When parsing, only first packet (read or write request) should be decoded as TFTP packet, as others uses custom UDP ports.
So, to decode subsequent TFTP packets, a method #decode! is provided for this purpose. This method takes a single array argument. This array should contain all subsequent TFTP packets (others packet types may also be included in this array: they won’t be modified). #decode!
will modify array in-place by replacing UDP packets by TFTP ones (if decoded as TFTP packets):
# packets is an array of packets: TFTP::RRQ, UDP (should be TFTP::DATA), UDP (not a TFTP packet) and UDP (TFTP::ACK)
packets.map { |pkt| pkt.headers.last.class.to_s }.join(',') # => TFTP::RRQ,UDP,UDP,UDP
# Here, decoding TFTP packets
packets[0].tftp.decode!(packets[1..-1])
packets.map { |pkt| pkt.headers.last.class.to_s }.join(',') # => TFTP::RRQ,TFTP::DATA,UDP,TFTP::ACK
Defined Under Namespace
Classes: ACK, DATA, ERROR, RRQ, WRQ
Constant Summary collapse
- OPCODES =
Known opcodes
{ 'RRQ' => 1, 'WRQ' => 2, 'DATA' => 3, 'ACK' => 4, 'Error' => 5 }.freeze
Instance Attribute Summary collapse
-
#body ⇒ String, Headerable
TFTP body, if opcode is unknown.
-
#opcode ⇒ Integer
16-bit operation code.
Instance Method Summary collapse
-
#added_to_packet(packet) ⇒ void
Callback called when a TFTP header is added to a packet Here, add
#tftp
method as a shortcut to existing #tftp(rrq|wrq|data|ack|error). -
#decode!(ary) ⇒ void
Decode subsequent TFTP packets to this one.
-
#human_opcode ⇒ String
Get human readable opcode.
-
#initialize(options = {}) ⇒ TFTP
constructor
A new instance of TFTP.
- #old_read ⇒ Object
-
#read(str) ⇒ TFTP
Populate object from binary string.
Methods inherited from Base
bind, calculate_and_set_length, #header_id, inherited, #ip_header, #ll_header
Methods included from PacketGen::Headerable
included, #method_name, #packet, #packet=, #parse?, #protocol_name, #to_s
Constructor Details
#initialize(options = {}) ⇒ TFTP
Returns a new instance of TFTP.
72 73 74 75 76 77 78 79 80 |
# File 'lib/packetgen/header/tftp.rb', line 72 def initialize(={}) type = protocol_name.sub(/^.*::/, '') opcode = OPCODES[type] if (self.class != TFTP) && !opcode.nil? super({ opcode: opcode }.merge()) else super end end |
Instance Attribute Details
#body ⇒ String, Headerable
TFTP body, if opcode is unknown
70 |
# File 'lib/packetgen/header/tftp.rb', line 70 define_attr :body, BinStruct::String |
#opcode ⇒ Integer
16-bit operation code
65 |
# File 'lib/packetgen/header/tftp.rb', line 65 define_attr :opcode, BinStruct::Int16Enum, enum: OPCODES |
Instance Method Details
#added_to_packet(packet) ⇒ void
This method returns an undefined value.
Callback called when a TFTP header is added to a packet Here, add #tftp
method as a shortcut to existing #tftp(rrq|wrq|data|ack|error).
135 136 137 138 139 |
# File 'lib/packetgen/header/tftp.rb', line 135 def added_to_packet(packet) return if packet.respond_to?(:tftp) packet.instance_eval("def tftp(arg=nil); header(#{self.class}, arg); end") # def tftp(arg=nil); header(TFTP, arg); end end |
#decode!(ary) ⇒ void
This method returns an undefined value.
Decode subsequent TFTP packets to this one. Packets are modified in place in ary
.
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/packetgen/header/tftp.rb', line 105 def decode!(ary) client_tid = packet.udp.sport server_tid = nil ary.each do |pkt| next unless pkt.is?('UDP') if server_tid.nil? next unless pkt.udp.dport == client_tid server_tid = pkt.udp.sport else tids = [server_tid, client_tid] ports = [pkt.udp.sport, pkt.udp.dport] next unless (tids - ports).empty? end decode_tftp_packet(pkt) end end |
#human_opcode ⇒ String
Get human readable opcode
126 127 128 |
# File 'lib/packetgen/header/tftp.rb', line 126 def human_opcode self[:opcode].to_human end |
#old_read ⇒ Object
83 |
# File 'lib/packetgen/header/tftp.rb', line 83 alias old_read read |