package Sniffer::Connection; use strict; use base 'Class::Accessor'; use Carp qw(carp croak); use NetPacket::TCP; use Data::Dumper; =head1 NAME Sniffer::Connection - contain basic information about a TCP connection =head1 SYNOPSIS my $conn = Sniffer::Connection->new( tcp => $packet, sent_data => sub { $self->sent_data(@_) }, received_data => sub { $self->received_data(@_) }, closed => sub {}, teardown => sub { $self->closed->($self) }, log => sub { print $_[0] }, )); This module will try to give you the ordered data stream from a TCP connection. You supply callbacks for the data. The data is returned as the ACK-packets are seen for it. As the TCP-reordering is cooked out by me, it likely has bugs, but I have used this module for sniffing some out-of-order TCP connection. =cut use vars qw($VERSION); $VERSION = '0.23'; my @callbacks = qw(sent_data received_data closed teardown log); __PACKAGE__->mk_accessors(qw( src_port dest_port src_host dest_host status last_ack window last_activity sequence_start ack_start ), @callbacks); sub new { my($class,%args) = @_; my $packet = delete $args{tcp}; # Set up dummy callbacks as the default for (@callbacks) { $args{$_} ||= sub {}; }; #$args{last_ack} ||= { src => undef, dest => undef }; $args{window} ||= { src => {}, dest => {} }; # will contain unacknowledged tcp packets my $self = $class->SUPER::new(\%args); if ($packet) { $self->handle_packet($packet); }; $self; }; =head2 C<< $conn->init_from_packet TCP >> Initializes the connection data from a packet. =cut sub init_from_packet { my ($self, $tcp) = @_; $self->sequence_start( $tcp->{seqnum} ); $self->ack_start( $tcp->{acknum} ); $self->src_port($tcp->{src_port}); $self->dest_port($tcp->{dest_port}); }; =head2 C<< $conn->handle_packet TCP [, TIMESTAMP] >> Handles a packet and updates the status according to the packet. The optional TIMESTAMP parameter allows you to attach a timestamp (in seconds since the epoch) to the packet if you have a capture file with timestamps. It defaults to the value of C