📄 dump.pm
字号:
return undef if ($new <= $last); $self->[$___sDataAwaiting]++; $self->_pcapNext;}sub _getNextAwaitingFrame { my $self = shift; $self->isModeOnline ? $self->_getNextAwaitingFrameOnline : $self->_getNextAwaitingFrameOffline;}# XXX: need more work#sub _getNextAwaitingFrames { #my $self = shift; #my $last = $self->[$___sDataAwaiting]; #my $new = $self->_sRetrieve; #my $diff = $new - $last; #return [] if $diff <= 0; # Nothing awaiting #$self->[$___sDataAwaiting] += $diff; #my $frames = []; #while ($diff--) { #push @$frames, $self->_pcapNext; #} #$frames;#}sub _nextTimeoutHandle { my $self = shift; # Handle timeout my $thisTime = gettimeofday() if $self->[$__timeoutOnNext]; $self->[$___firstTime] = $thisTime unless $self->[$___firstTime]; if ($self->[$__timeoutOnNext] && $self->[$___firstTime]) { if (($thisTime - $self->[$___firstTime]) > $self->[$__timeoutOnNext]) { $self->[$__timeout] = 1; $self->[$___firstTime] = 0; $self->cgDebugPrint(1, "Timeout occured"); return undef; } } 1;}sub _nextTimeoutReset { shift->[$___firstTime] = 0 }sub next { my $self = shift; unless ($self->[$__isRunning]) { croak("You MUST call start() method before using next() method\n"); } $self->_nextTimeoutHandle or return undef; my $frame = $self->_getNextAwaitingFrame; $self->_nextTimeoutReset if $frame; $frame ? do { $self->[$__nextFrame] = $frame } : undef;}sub nextAll { my $self = shift; while ($self->next) {} }sub write { my $self = shift; my ($frame) = @_; unless ($self->isModeWriter) { croak("Dump is not in writer mode\n"); } # Rebuild the frame without possible layer 2 my $new; $new .= $frame->l3->raw if $frame->l3; $new .= $frame->l4->raw if $frame->l4; $new .= $frame->l7->raw if $frame->l7; # Create pcap header my ($sec, $usec) = split('\.', $frame->timestamp); my $hdr = { len => length($new), caplen => length($new), tv_sec => $sec, tv_usec => $usec, }; Net::Pcap::pcap_dump($self->[$___dumper], $hdr, $new); Net::Pcap::dump_flush($self->[$___dumper]);}# XXX: broken for now#sub nextAll { #my $self = shift; #$self->_nextTimeoutHandle or return []; #my $frames = $self->_getNextAwaitingFrames; #$self->_nextTimeoutReset if @$frames; #$frames;#}sub timeoutReset { shift->[$__timeout] = 0 }sub framesFor { my $self = shift; my ($f) = @_; my $l2Key = ($f->l2 && $f->l2->getKeyReverse($f)) || 'all'; my $l3Key = ($f->l3 && $f->l3->getKeyReverse($f)) || 'all'; my $l4Key = ($f->l4 && $f->l4->getKeyReverse($f)) || 'all'; my $aref = $self->[$__framesSorted]->{$l2Key}{$l3Key}{$l4Key}; $aref ? @$aref : ();}## Other accessors#sub framesSorted { my $self = shift; my ($f) = @_; if ($f) { # Wipe headers, since if not, framesFor() will not be able to find them. # Because if you create a Frame from L3, no headers are set for L2, but # the Dump will have them and store them into the l2Key. if ($self->env->desc && ! $self->[$__noLayerWipe]) { $f->l2(undef) if ref($self->env->desc) =~ /L3|L4/; $f->l3(undef) if ref($self->env->desc) =~ /L4/; } my $l2Key = ($f->l2 && $f->l2->getKey($f)) || 'all'; my $l3Key = ($f->l3 && $f->l3->getKey($f)) || 'all'; my $l4Key = ($f->l4 && $f->l4->getKey($f)) || 'all'; push @{$self->[$__framesSorted]->{$l2Key}{$l3Key}{$l4Key}}, $f; #燱e store a second time for ICMP messages if ($f->isIcmp) { my $l3Key = ($f->l3 && $f->l3->is.':'.$f->l3->dst) || 'all'; push @{$self->[$__framesSorted]->{$l2Key}{$l3Key}{$l4Key}}, $f; } } $self->[$__framesSorted];}1;__END__=head1 NAMENet::Packet::Dump - a tcpdump-like object providing frame capturing and more=head1 SYNOPSIS require Net::Packet::Dump; use Net::Packet::Consts qw(:dump); # # Example live capture (sniffer like) # # Instanciate object my $dump = Net::Packet::Dump->new( mode => NP_DUMP_MODE_ONLINE, file => 'live.pcap', filter => 'tcp', promisc => 1, noStore => 1, keepTimestamp => 1, unlinkOnClean => 0, overwrite => 1, ); # Start capture $dump->start; while (1) { if (my $frame = $dump->next) { print $frame->l2->print, "\n" if $frame->l2; print $frame->l3->print, "\n" if $frame->l3; print $frame->l4->print, "\n" if $frame->l4; print $frame->l7->print, "\n" if $frame->l7; } } # Cleanup $dump->stop; $dump->clean; # # Example offline analysis # my $dump2 = Net::Packet::Dump->new( mode => NP_DUMP_MODE_OFFLINE, file => 'existant-file.pcap', unlinkOnClean => 0, ); # Analyze the .pcap file, build an array of Net::Packet::Frame's $dump2->start; $dump2->nextAll; # Browses captured frames for ($dump2->frames) { # Do what you want print $_->l2->print, "\n" if $_->l2; print $_->l3->print, "\n" if $_->l3; print $_->l4->print, "\n" if $_->l4; print $_->l7->print, "\n" if $_->l7; } # Cleanup $dump2->stop; $dump2->clean; # # Example writing mode # my $dump3 = Net::Packet::Dump->new( mode => NP_DUMP_MODE_WRITER, file => 'write.pcap', overwrite => 1, ); $dump3->start; # Build or capture some frames here my $frame = Net::Packet::Frame->new; # Write them $dump3->write($frame); # Cleanup $dump3->stop; $dump3->clean;=head1 DESCRIPTIONThis module is the capturing part of Net::Packet framework. It is basically a tcpdump process. When a capture starts, the tcpdump process is forked, and saves all traffic to a .pcap file. The parent process can call B<next> or B<nextAll> to convert captured frames from .pcap file to B<Net::Packet::Frame>s.Then, you can call B<recv> method on your sent frames to see if a corresponding reply is waiting in the B<frames> array attribute of B<Net::Packet::Dump>.By default, if you use this module to analyze frames you've sent (very likely ;)), and you've sent those frames at layer 4 (using B<Net::Packet::DescL4>) (for example), lower layers will be wiped on storing in B<frames> array. This behaviour can be disabled by using B<noLayerWipe> attribute.Since B<Net::Packet> 3.00, it is also possible to create complete .pcap files, thanks to the writer mode (see B<SYNOPSIS>).=head1 ATTRIBUTES=over 4=item B<dev>By default, this attribute is set to B<dev> found in default B<$Env> object. You can overwrite it by specifying another one in B<new> constructor.=item B<env>Stores a B<Net::Packet::Env> object. It is used in B<start> method, for example. The default is to use the global B<$Env> object created when using B<Net::Packet::Env>.=item B<file>Where to save captured frames. By default, a random name file is chosen, named like `netpacket-tmp-$$.@{[getRandom32bitsInt()]}.pcap'.=item B<filter>A pcap filter to restrain what to capture. It also works in offline mode, to analyze only what you want, and not all traffic. Default to capture all traffic. WARNING: every time a packet passes this filter, and the B<next> method is called, the internal counter used by b<timeoutOnNext> is reset. So the B<timeout> attribute can only be used if you know exactly that the filter will only catch what you want and not perturbating traffic.=item B<overwrite>If the B<file> exists, setting this to 1 will overwrite it. Default to not overwrite it.=item B<timeoutOnNext>Each time B<next> method is called, an internal counter is incremented if no frame has been captured. When a frame is captured (that is, a frame passed the pcap filter), the B<timeout> attribute is reset to 0. When the counter reaches the value of B<timeoutOnNext>, the B<timeout> attribute is set to 1, meaning no frames have been captured during the specified amount of time. Default to 3 seconds.=item B<timeout>Is auto set to 1 when a timeout has occured. It is not reset to 0 automatically, you need to do it yourself.=item B<promisc>If you want to capture in promiscuous mode, set it to 1. Default to 0.=item B<link>This attribute tells which datalink type is used for .pcap files.=item B<nextFrame>This one stores a pointer to the latest received frame after a call to B<next> method. If a B<next> call is done, and no frame is received, this attribute is set to undef.=item B<isRunning>When the capturing process is running (B<start> has been called), this is set to 1. So, when B<start> method has been called, it is set to 1, and when B<stop> method is called, set to 0.=item B<unlinkOnClean>When the B<clean> method is called, and this attribute is set to 1, the B<file> is deleted from disk. Set it to 0 to avoid this behaviour. BEWARE: default to 1.=item B<noStore>If you set this attribute to 1, frames will not be stored in B<frames> array. It is used in sniffer-like programs, in order to avoid memory exhaustion by keeping all captured B<Net::Packet::Frame> into memory. Default is to store frames.=item B<noLayerWipe>As explained in DESCRIPTION, if you send packets at layer 4, layer 2 and 3 are not keeped when stored in B<frames>. The same is true when sending at layer 3 (layer 2 is not kept). Default to wipe those layers. WARNING: if you set it to 1, and you need the B<recv> method from B<Net::Packet::Frame>, it will fail. In fact, this is a speed improvements, that is in order to find matching frame for your request, they are stored in a hash, using layer as keys (B<getKey> and B<getKeyReverse> are used to get keys from each layer. So, if you do not wipe layers, a key will be used to store the frame, but another will be used to search for it, and no match will be found. This is a current limitation I'm working on to remove.=item B<mode>When you crate a B<Net::Packet::Dump>, you have 3 possible modes : online, offline and writer. You need to load constants from B<Net::Packet::Consts> to have access to that (see B<SYNOPSIS>). The three constants are:NP_DUMP_MODE_ONLINENP_DUMP_MODE_OFFLINENP_DUMP_MODE_WRITERDefault behaviour is to use online mode.=item B<keepTimestamp>Sometimes, when frames are captured and saved to a .pcap file, timestamps sucks. That is, you send a frame, and receive the reply, but your request appear to have been sent after the reply. So, to correct that, you can use B<Net::Packet> framework own timestamping system. The default is 0. Set it manually to 1 if you need original .pcap frames timestamps.=item B<frames> [is an arrayref]Stores all analyzed frames found in a pcap file in this arrayref.=item B<framesSorted> [is an hashref]Stores all analyzed frames found in a pcap file in this hashref, using keys to store and search related frames request/replies.=back=head1 METHODS=over 4=item B<new>Object contructor. Default values for attributes:dev: $Env->devenv: $Envfile: "netpacket-tmp-$$.@{[getRandom32bitsInt()]}.pcap"filter: ''overwrite: 0timeout: 0promisc: 0timeoutOnNext: 3isRunning: 0unlinkOnClean: 1noStore: 0noLayerWipe: 0mode: NP_DUMP_MODE_ONLINEkeepTimestamp: 0=item B<isModeOnline>=item B<isModeOffline>=item B<isModeWriter>Returns 1 if B<Net::Packet::Dump> object is respectively set to online, offline or writer mode. 0 otherwise.=item B<start>You MUST manually call this method to start frame capture, whatever mode you are in. In online mode, it will fork a tcpdump-like process to save captured frames to a .pcap file. It will not overwrite an existing file by default, use B<overwrite> attribute for that. In offline mode, it will only provide analyzing methods. In writer mode, it will only provide writing methods for frames. It will set B<isRunning> attribute to 1 when called.=item B<stop>You MUST manually call this method to stop the process. In online mode, it will not remove the generated .pcap file, you MUST call B<clean> method. In offline mode, it will to nothing. In writer mode, it will call B<Net::Pcap::dump_close> method. Then, it will set B<isRunning> attribute to 0.=item B<isFather>=item B<isSon>These methods will tell you if your current process is respectively the father, or son process of B<Net::Packet::Dump> object.=item B<clean>You MUST call this method manually. It will never be called by B<Net::Packet> framework. This method will remove the generated .pcap file in online mode if the B<unlinkOnClean> attribute is set to 1. In other modes, it will do nothing.=item B<getStats>Tries to get packet statistics on an open descriptor. It returns a reference to a hash that has to following fields: B<ps_recv>, B<ps_drop>, B<ps_ifdrop>.=item B<flush>Will removed all analyzed frames from B<frames> array and B<framesSorted> hash. Use it with caution, because B<recv> from B<Net::Packet::Frame> relies on those.=item B<next>Returns the next captured frame; undef if none found in .pcap file. In all cases, B<nextFrame> attribute is set (either to the captured frame or undef). Each time this method is run, a comparison is done to see if no frame has been captured during B<timeoutOnNext> amount of seconds. If so, B<timeout> attribute is set to 1 to reflect the pending timeout. When a frame is received, it is stored in B<frames> arrayref, and in B<framesSorted> hashref, used to quickly B<recv> it (see B<Net::Packet::Frame>), and internal counter for time elapsed since last received packet is reset.=item B<nextAll>Calls B<next> method until it returns undef (meaning no new frame waiting to be analyzed from pcap file).=item B<write> (scalar)In writer mode, this method takes a B<Net::Packet::Frame> as a parameter, and writes it to the .pcap file. Works only in writer mode.=item B<timeoutReset>Used to reset manually the B<timeout> attribute. This is a helper method.=item B<framesFor> (scalar)You pass a B<Net::Packet::Frame> has parameter, and it returns an array of all frames relating to the connection. For example, when you send a TCP SYN packet, this method will return TCP packets relating to the used source/destination IP, source/destination port, and also related ICMP packets.=item B<framesSorted> (scalar)Method mostly used internally to store in a hashref a captured frame. This is used to retrieve it quickly on B<recv> call.=back=head1 AUTHORPatrice E<lt>GomoRE<gt> Auffret=head1 COPYRIGHT AND LICENSECopyright (c) 2004-2006, Patrice E<lt>GomoRE<gt> AuffretYou may distribute this module under the terms of the Artistic license.See LICENSE.Artistic file in the source distribution archive.=head1 RELATED MODULESL<NetPacket>, L<Net::RawIP>, L<Net::RawSock>=cut
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -