class ReassembleTcp::TcpConnection

TCP connection object

Attributes

syn[R]
timestamp_range[R]

Public Class Methods

new(pkt) click to toggle source

@param [PacketFu::TCPPacket] pkt SYN packet

# File lib/reassemble_tcp/tcp_connection.rb, line 10
def initialize(pkt)
  raise ArgumentError, "#{pkt} is not PacketFu::TCPPacket." unless pkt.kind_of? PacketFu::TCPPacket
  raise ArgumentError, "#{pkt} is not TCP packet." unless pkt.is_tcp?
  raise ArgumentError, "#{pkt} is not SYN packet." unless pkt.tcp_flags[:syn] == 1

  @syn = pkt
  @timestamp_range = (@syn.timestamp .. Float::INFINITY)
  @stream_array = []
end

Public Instance Methods

<<(pkt)
Alias for: append
append(pkt) click to toggle source
# File lib/reassemble_tcp/tcp_connection.rb, line 61
def append(pkt)
  raise ArgumentError, "#{pkt} is not matched with this connection" unless match?(pkt)
  if pkt.tcp_flags[:fin] == 1 || pkt.tcp_flags[:rst] == 1
    # FIN or RST packet is treated as end of the TCP stream.
    # and it determines time range of the TCP stream.
    # FIN packet is not included int Streams
    @timestamp_range = (@syn.timestamp .. pkt.timestamp)
    return
  end
  dir = direction(pkt)
  # store packets into packet stream
  pkt_stm = @stream_array.find{|stm| stm.match? dir, pkt }
  if pkt_stm.nil?
    @stream_array << PacketStream.new(dir, pkt)
  else
    pkt_stm.append(dir, pkt)
  end
end
Also aliased as: <<
direction(pkt) click to toggle source
# File lib/reassemble_tcp/tcp_connection.rb, line 46
def direction(pkt)
  raise ArgumentError, "#{pkt} is not matched with this connection" unless match?(pkt)
  return :send if send?(pkt)
  return :recv if recv?(pkt)
  raise "error"
end
dst_ip() click to toggle source
# File lib/reassemble_tcp/tcp_connection.rb, line 38
def dst_ip
  @syn.ip_dst_readable
end
dst_port() click to toggle source
# File lib/reassemble_tcp/tcp_connection.rb, line 42
def dst_port
  @syn.tcp_dport
end
match?(pkt) click to toggle source
# File lib/reassemble_tcp/tcp_connection.rb, line 53
def match?(pkt)
  raise ArgumentError, "#{pkt} is not TCP packet." unless pkt.is_tcp?
  # target packet is the same source and destination
  return false unless (send?(pkt) || recv?(pkt))
  # target packet is in connection's time range
  return @timestamp_range.include? pkt.timestamp
end
recv?(pkt) click to toggle source
# File lib/reassemble_tcp/tcp_connection.rb, line 25
def recv?(pkt)
  ((@syn.tcp_sport == pkt.tcp_dport and @syn.ip_src == pkt.ip_dst) and
   (@syn.tcp_dport == pkt.tcp_sport and @syn.ip_dst == pkt.ip_src))
end
send?(pkt) click to toggle source
# File lib/reassemble_tcp/tcp_connection.rb, line 20
def send?(pkt)
  ((@syn.tcp_dport == pkt.tcp_dport and @syn.ip_dst == pkt.ip_dst) and
   (@syn.tcp_sport == pkt.tcp_sport and @syn.ip_src == pkt.ip_src))
end
src_ip() click to toggle source
# File lib/reassemble_tcp/tcp_connection.rb, line 30
def src_ip
  @syn.ip_src_readable
end
src_port() click to toggle source
# File lib/reassemble_tcp/tcp_connection.rb, line 34
def src_port
  @syn.tcp_sport
end
tcpdata() { |range, direction, data| ... } click to toggle source

@yieldparam [Range] time time range of stream data @yieldparam [Symbol] direction :send or :recv @yieldparam [String] data reassembled TCP data

# File lib/reassemble_tcp/tcp_connection.rb, line 84
def tcpdata(&block)
  arr = []
  @stream_array.sort_by{|pstm| pstm.last_timestamp }.each do |s|
    next if s.data.nil? || s.data.empty?
    if block.nil?
      arr << [s.range, s.direction, s.data]
    else
      yield s.range, s.direction, s.data
    end
  end
  return arr
end