Class: PacketGen::Header::TFTP
- Inherits:
-
Base
- Object
- Types::Fields
- Base
- PacketGen::Header::TFTP
- Defined in:
- lib/packetgen/header/tftp.rb
Overview
A TFTP (Trivial File Transfer Protocol, RFC 1350) header consists of:
-
a #opcode (Types::Int16Enum),
-
and a body. Its content depends on opcode.
Specialized subclasses exists to handle Read Request, Write Request, DATA, ACK and ERROR packets.
Create a TFTP header
# standalone
tftp = PacketGen::Header::TFTP.new
# in a packet
pkt = PacketGen.gen('IP').add('UDP').add('TFTP')
# access to TFTP header
pkt.tftp # => PacketGen::Header::TFTP
TFTP attributes
tftp.opcode = 'RRQ'
tftp.opcode = 1
tftp.body.read 'this is a body'
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
-
#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
Methods inherited from Types::Fields
#[], #[]=, #bits_on, define_bit_fields_on, define_field, define_field_after, define_field_before, #fields, fields, inherited, #inspect, #offset_of, #optional?, #optional_fields, #present?, remove_bit_fields_on, remove_field, #sz, #to_h, #to_s, update_field
Constructor Details
#initialize(options = {}) ⇒ TFTP
Returns a new instance of TFTP.
69 70 71 72 73 74 75 76 77 |
# File 'lib/packetgen/header/tftp.rb', line 69 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
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).
132 133 134 135 136 |
# File 'lib/packetgen/header/tftp.rb', line 132 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
.
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/packetgen/header/tftp.rb', line 102 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
123 124 125 |
# File 'lib/packetgen/header/tftp.rb', line 123 def human_opcode self[:opcode].to_human end |
#old_read ⇒ Object
80 |
# File 'lib/packetgen/header/tftp.rb', line 80 alias old_read read |