Class: PacketFu::TCPHeader

Inherits:
Struct
  • Object
show all
Includes:
StructFu
Defined in:
lib/packetfu/protos/tcp/header.rb

Overview

TCPHeader is a complete TCP struct, used in TCPPacket. Most IP traffic is TCP-based, by volume.

For more on TCP packets, see www.networksorcery.com/enp/protocol/tcp.htm

Header Definition

Int16        :tcp_src       Default: random 
Int16        :tcp_dst
Int32        :tcp_seq       Default: random
Int32        :tcp_ack
TcpHlen      :tcp_hlen      Default: 5           # Must recalc as options are set. 
TcpReserved  :tcp_reserved  Default: 0
TcpEcn       :tcp_ecn
TcpFlags     :tcp_flags
Int16        :tcp_win,      Default: 0           # WinXP's default syn packet
Int16        :tcp_sum,      Default: calculated  # Must set this upon generation.
Int16        :tcp_urg
TcpOptions   :tcp_opts
String       :body

See also TcpHlen, TcpReserved, TcpEcn, TcpFlags, TcpOpts

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from StructFu

#clone, #set_endianness, #sz, #typecast

Methods inherited from Struct

#force_binary

Constructor Details

#initialize(args = {}) ⇒ TCPHeader

Returns a new instance of TCPHeader.



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/packetfu/protos/tcp/header.rb', line 41

def initialize(args={})
  @random_seq = rand(0xffffffff)
  @random_src = rand_port
  super(
    Int16.new(args[:tcp_src] || tcp_calc_src),
    Int16.new(args[:tcp_dst]),
    Int32.new(args[:tcp_seq] || tcp_calc_seq),
    Int32.new(args[:tcp_ack]),
    TcpHlen.new(:hlen => (args[:tcp_hlen] || 5)),
    TcpReserved.new(args[:tcp_reserved] || 0),
    TcpEcn.new(args[:tcp_ecn]),
    TcpFlags.new(args[:tcp_flags]),
    Int16.new(args[:tcp_win] || 0x4000),
    Int16.new(args[:tcp_sum] || 0),
    Int16.new(args[:tcp_urg]),
    TcpOptions.new.read(args[:tcp_opts]),
    StructFu::String.new.read(args[:body])
  )
end

Instance Attribute Details

#bodyObject

Returns the value of attribute body

Returns:

  • (Object)

    the current value of body



33
34
35
# File 'lib/packetfu/protos/tcp/header.rb', line 33

def body
  @body
end

#flavorObject

Returns the value of attribute flavor.



61
62
63
# File 'lib/packetfu/protos/tcp/header.rb', line 61

def flavor
  @flavor
end

#tcp_ackObject

Getter for the TCP ackowlegement number.



33
34
35
# File 'lib/packetfu/protos/tcp/header.rb', line 33

def tcp_ack
  @tcp_ack
end

#tcp_dstObject

Getter for the TCP destination port.



33
34
35
# File 'lib/packetfu/protos/tcp/header.rb', line 33

def tcp_dst
  @tcp_dst
end

#tcp_ecnObject

Getter for the ECN bits.



33
34
35
# File 'lib/packetfu/protos/tcp/header.rb', line 33

def tcp_ecn
  @tcp_ecn
end

#tcp_flagsObject

Returns the value of attribute tcp_flags

Returns:

  • (Object)

    the current value of tcp_flags



33
34
35
# File 'lib/packetfu/protos/tcp/header.rb', line 33

def tcp_flags
  @tcp_flags
end

#tcp_hlenObject

Getter for the TCP Header Length value.



33
34
35
# File 'lib/packetfu/protos/tcp/header.rb', line 33

def tcp_hlen
  @tcp_hlen
end

#tcp_optsObject

Getter for TCP Options.



33
34
35
# File 'lib/packetfu/protos/tcp/header.rb', line 33

def tcp_opts
  @tcp_opts
end

#tcp_reservedObject

Getter for the TCP Reserved field.



33
34
35
# File 'lib/packetfu/protos/tcp/header.rb', line 33

def tcp_reserved
  @tcp_reserved
end

#tcp_seqObject

Getter for the TCP sequence number.



33
34
35
# File 'lib/packetfu/protos/tcp/header.rb', line 33

def tcp_seq
  @tcp_seq
end

#tcp_srcObject

Getter for the TCP source port.



33
34
35
# File 'lib/packetfu/protos/tcp/header.rb', line 33

def tcp_src
  @tcp_src
end

#tcp_sumObject

Getter for the TCP checksum.



33
34
35
# File 'lib/packetfu/protos/tcp/header.rb', line 33

def tcp_sum
  @tcp_sum
end

#tcp_urgObject

Getter for the TCP urgent field.



33
34
35
# File 'lib/packetfu/protos/tcp/header.rb', line 33

def tcp_urg
  @tcp_urg
end

#tcp_winObject

Getter for the TCP window size number.



33
34
35
# File 'lib/packetfu/protos/tcp/header.rb', line 33

def tcp_win
  @tcp_win
end

Instance Method Details

#bits_to_sObject

Helper function to create the string for Hlen, Reserved, ECN, and Flags.



64
65
66
67
68
69
70
71
72
73
# File 'lib/packetfu/protos/tcp/header.rb', line 64

def bits_to_s
  bytes = []
  bytes[0] = (self[:tcp_hlen].to_i << 4) +
    (self[:tcp_reserved].to_i << 1) +
    self[:tcp_ecn].n.to_i
  bytes[1] = (self[:tcp_ecn].c.to_i << 7) +
    (self[:tcp_ecn].e.to_i << 6) +
    self[:tcp_flags].to_i
  bytes.pack("CC")
end

#rand_portObject

Generates a random high port. This is affected by packet flavor.



223
224
225
# File 'lib/packetfu/protos/tcp/header.rb', line 223

def rand_port
  rand(0xffff - 1025) + 1025
end

#read(str) ⇒ Object

Reads a string to populate the object.



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/packetfu/protos/tcp/header.rb', line 94

def read(str)
  force_binary(str)
  return self if str.nil?
  self[:tcp_src].read(str[0,2])
  self[:tcp_dst].read(str[2,2])
  self[:tcp_seq].read(str[4,4])
  self[:tcp_ack].read(str[8,4])
  self[:tcp_hlen].read(str[12,1])
  self[:tcp_reserved].read(str[12,1])
  self[:tcp_ecn].read(str[12,2])
  self[:tcp_flags].read(str[13,1])
  self[:tcp_win].read(str[14,2])
  self[:tcp_sum].read(str[16,2])
  self[:tcp_urg].read(str[18,2])
  self[:tcp_opts].read(str[20,((self[:tcp_hlen].to_i * 4) - 20)])
  self[:body].read(str[(self[:tcp_hlen].to_i * 4),str.size])
  self
end

#tcp_ack_readableObject



290
291
292
# File 'lib/packetfu/protos/tcp/header.rb', line 290

def tcp_ack_readable
  "0x%08x" % tcp_ack
end

#tcp_calc_hlenObject

Sets and returns the true length of the TCP Header. TODO: Think about making all the option stuff safer.



218
219
220
# File 'lib/packetfu/protos/tcp/header.rb', line 218

def tcp_calc_hlen
  self[:tcp_hlen] = TcpHlen.new(:hlen => ((20 + tcp_opts_len) / 4))
end

#tcp_calc_seqObject

Resets the sequence number to a new random number.



207
# File 'lib/packetfu/protos/tcp/header.rb', line 207

def tcp_calc_seq; @random_seq; end

#tcp_calc_srcObject

Resets the source port to a new random number.



209
# File 'lib/packetfu/protos/tcp/header.rb', line 209

def tcp_calc_src; @random_src; end

#tcp_dportObject

Equivalent to tcp_dst.



257
258
259
# File 'lib/packetfu/protos/tcp/header.rb', line 257

def tcp_dport
  self.tcp_dst.to_i
end

#tcp_dport=(arg) ⇒ Object

Equivalent to tcp_dst=.



262
263
264
# File 'lib/packetfu/protos/tcp/header.rb', line 262

def tcp_dport=(arg)
  self.tcp_dst=(arg)
end

#tcp_flags_dotmapObject Also known as: tcp_flags_readable

Gets a more readable flags list



233
234
235
236
237
238
239
# File 'lib/packetfu/protos/tcp/header.rb', line 233

def tcp_flags_dotmap
  dotmap = tcp_flags.members.map do |flag|
    status = self.tcp_flags.send flag
    status == 0 ? "." : flag.to_s.upcase[0].chr
  end
  dotmap.join
end

#tcp_optionsObject

Gets a more readable option list.



228
229
230
# File 'lib/packetfu/protos/tcp/header.rb', line 228

def tcp_options
 self[:tcp_opts].decode
end

#tcp_options=(arg) ⇒ Object

Sets a more readable option list.



242
243
244
# File 'lib/packetfu/protos/tcp/header.rb', line 242

def tcp_options=(arg)
  self[:tcp_opts].encode arg
end

#tcp_opts_lenObject

Returns the actual length of the TCP options.



212
213
214
# File 'lib/packetfu/protos/tcp/header.rb', line 212

def tcp_opts_len
  self[:tcp_opts].to_s.size
end

#tcp_opts_readableObject



302
303
304
# File 'lib/packetfu/protos/tcp/header.rb', line 302

def tcp_opts_readable
  tcp_options
end

#tcp_recalc(arg = :all) ⇒ Object

Recalculates calculated fields for TCP (except checksum which is at the Packet level).



267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
# File 'lib/packetfu/protos/tcp/header.rb', line 267

def tcp_recalc(arg=:all)
  case arg
  when :tcp_hlen
    tcp_calc_hlen
  when :tcp_src
    @random_tcp_src = rand_port
  when :tcp_sport
    @random_tcp_src = rand_port
  when :tcp_seq
    @random_tcp_seq = rand(0xffffffff) 
  when :all
    tcp_calc_hlen
    @random_tcp_src = rand_port
    @random_tcp_seq = rand(0xffffffff) 
  else
    raise ArgumentError, "No such field `#{arg}'"
  end
end

#tcp_seq_readableObject



294
295
296
# File 'lib/packetfu/protos/tcp/header.rb', line 294

def tcp_seq_readable
  "0x%08x" % tcp_seq
end

#tcp_sportObject

Equivalent to tcp_src.



247
248
249
# File 'lib/packetfu/protos/tcp/header.rb', line 247

def tcp_sport
  self.tcp_src.to_i
end

#tcp_sport=(arg) ⇒ Object

Equivalent to tcp_src=.



252
253
254
# File 'lib/packetfu/protos/tcp/header.rb', line 252

def tcp_sport=(arg)
  self.tcp_src=(arg)
end

#tcp_sum_readableObject



298
299
300
# File 'lib/packetfu/protos/tcp/header.rb', line 298

def tcp_sum_readable
  "0x%04x" % tcp_sum
end

#to_sObject

Returns the object in string form.



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/packetfu/protos/tcp/header.rb', line 76

def to_s
  hdr = self.to_a.map do |x|
    if x.kind_of? TcpHlen
      bits_to_s
    elsif x.kind_of? TcpReserved
      next
    elsif x.kind_of? TcpEcn
      next
    elsif x.kind_of? TcpFlags
      next
    else
      x.to_s
    end
  end
  hdr.flatten.join
end