File Coverage

blib/lib/File/PCAP/Writer.pm
Criterion Covered Total %
statement 40 43 93.0
branch 3 6 50.0
condition 4 7 57.1
subroutine 9 9 100.0
pod 2 2 100.0
total 58 67 86.5


line stmt bran cond sub pod time code
1             package File::PCAP::Writer;
2              
3 4     4   66047 use 5.006;
  4         23  
4 4     4   20 use strict;
  4         7  
  4         73  
5 4     4   18 use warnings;
  4         16  
  4         100  
6              
7 4     4   20 use Carp;
  4         8  
  4         270  
8              
9             =head1 NAME
10              
11             File::PCAP::Writer - write PCAP files with pure Perl
12              
13             =head1 VERSION
14              
15             Version v0.1.0
16              
17             =cut
18              
19 4     4   1845 use version; our $VERSION = qv('v0.1.0');
  4         7427  
  4         22  
20              
21              
22             =head1 SYNOPSIS
23              
24             This module writes PCAP files that can be read with tcpdump or wireshark.
25              
26             use File::PCAP::Writer;
27              
28             my $fpw = File::PCAP::Writer->new( {
29             fname => 'file.pcap',
30             dlt => 1,
31             } );
32              
33             $fpw->packet( $tsec, $usec, $blen, $plen, $buf );
34              
35             =head1 SUBROUTINES/METHODS
36              
37             =head2 new( $args )
38              
39             Create a new File::PCAP::Writer object.
40              
41             Parameter I<< $args >> is a reference to a hash, that may contain the
42             following keys:
43              
44             =over 4
45              
46             =item fname
47              
48             The corresponding value is the name of the PCAP file.
49             It defaults to C<< file.pcap >> if the key is omitted.
50              
51             The file is created and filled with a global PCAP header.
52             It can be immediately read by tcpdump.
53              
54             =item dlt
55              
56             The corresponding value is the data link type that is written in the global
57             PCAP header.
58             It defaults to 1 (LINKTYPE_ETHERNET) if the key is omitted.
59              
60             See L<< http://www.tcpdump.org/linktypes.html >> for more information about
61             link-layer header type values.
62              
63             Note that this is only a hint for tcpdump or wireshark at the type
64             of packets to expect in the PCAP file.
65             You are responsible to add datagram packets that match the link-layer header
66             type in the global PCAP header.
67              
68             =back
69              
70             =cut
71              
72             sub new {
73 6     6 1 1205 my ($self,$args) = @_;
74 6   33     31 my $type = ref($self) || $self;
75              
76 6   50     21 my $fname = $args->{fname} || "file.pcap";
77 6   100     26 my $dlt = $args->{dlt} || 1;
78              
79 6         24 $self = bless {
80             fname => $fname,
81             dlt => $dlt,
82             }, $type;
83              
84 6         26 $self->_init();
85              
86 6         38 return $self;
87             } # new()
88              
89             =head2 packet( $tsec, $usec, $blen, $plen, $buf )
90              
91             Write a new datagram record at the end of the PCAP file.
92              
93             The arguments are:
94              
95             =over 4
96              
97             =item I<< $tsec >>
98              
99             The date and time for this packets.
100             This value is in seconds since January 1, 1970 00:00:00 GMT.
101              
102             =item I<< $usec >>
103              
104             The microseconds when this packet was captured as an offset to I<< $tsec >>.
105              
106             =item I<< $blen >>
107              
108             The number of bytes of the packet data saved in the file.
109              
110             =item I<< $plen >>
111              
112             The length of the packet as it appeared on the network.
113              
114             =item I<< $buf >>
115              
116             The actual packet data as a blob.
117             This buffer should contain at least I<< $blen >> bytes.
118              
119             Note that this packet data should match the link-layer type in the global
120             PCAP header.
121              
122             =back
123              
124             =cut
125              
126             sub packet {
127 5     5 1 16 my ($self,$tsec,$usec,$blen,$plen,$buf) = @_;
128 5         11 my $fname = $self->{fname};
129 5 50       184 if (open(my $fh, '>>', $fname)) {
130 5         29 my $header = pack("LLLL", $tsec, $usec, $blen, $plen);
131 5         14 binmode $fh;
132 5         54 print $fh $header;
133 5         14 print $fh $buf;
134 5         111 close $fh;
135             }
136             else {
137 0         0 croak "Can't write packet data to file '$fname'";
138             }
139             } # packet()
140              
141             # internal functions
142              
143             # _init() - initialize the object
144             #
145             sub _init {
146 6     6   25 my ($self) = @_;
147              
148 6 50       32 if ($self->{fname}) {
149 6         19 $self->_write_pcap_global_header();
150             }
151             else {
152 0         0 croak "Need a filename to write PCAP data";
153             }
154             } # _init()
155              
156             # _write_pcap_global_header() - writes a PCAP global header to the file
157             # named in $self->{fname}
158             #
159             # This function writes a global header with PCAP version 2.4,
160             # the timezone is set to GMT(UTC), the accuracy of the timestamps is
161             # set to 0, the snapshot length to 65535
162             # The link-layer header type is set to $self->{dlt} or 1 (Ethernet).
163             #
164             sub _write_pcap_global_header {
165 6     6   15 my ($self) = @_;
166 6         14 my $dlt = $self->{dlt};
167 6         13 my $fname = $self->{fname};
168 6 50       625 if (open(my $fh, '>', $fname)) {
169 6         61 my $header = pack("LSSlLLL", 0xa1b2c3d4, 2, 4, 0, 0, 65535, $dlt);
170 6         21 binmode $fh;
171 6         93 print $fh $header;
172 6         445 close $fh;
173             }
174             else {
175 0           croak "Can't write global header to file '$fname'";
176             }
177             } # _write_pcap_global_header()
178              
179             =head1 DIAGNOSTICS
180              
181             =over 4
182              
183             =item Can't write global header to file '$fname'
184              
185             The program can't write to file I<< $fname >>.
186             This is the name of the file for the PCAP data.
187             If I<< $fname >> is C<< file.pcap >> than you probably have
188             not specified a file name explicitely.
189              
190             This message appears at the time when the File::PCAP::Writer object
191             is created. It often hints at problems with file permissions.
192              
193             =item Can't write packet data to file '$fname'
194              
195             The program can't write to file I<< $fname >>.
196             This is the name of the file for the PCAP data.
197             If I<< $fname >> is C<< file.pcap >> than you probably have
198             not specified a file name explicitely.
199              
200             This message appears when new packet data shall be written.
201             It often hints at problems with a lack of disk space.
202              
203             =item Need a filename to write PCAP data
204              
205             Since there is a default value for the filename,
206             you probably have it overwritten with an empty filename
207             when calling C<< new() >>.
208              
209             =back
210              
211             =head1 AUTHOR
212              
213             Mathias Weidner, C<< >>
214              
215             =head1 BUGS
216              
217             Please report any bugs or feature requests to C, or through
218             the web interface at L. I will be notified, and then you'll
219             automatically be notified of progress on your bug as I make changes.
220              
221              
222              
223              
224             =head1 SUPPORT
225              
226             You can find documentation for this module with the perldoc command.
227              
228             perldoc File::PCAP::Writer
229              
230              
231             You can also look for information at:
232              
233             =over 4
234              
235             =item * RT: CPAN's request tracker (report bugs here)
236              
237             L
238              
239             =item * AnnoCPAN: Annotated CPAN documentation
240              
241             L
242              
243             =item * CPAN Ratings
244              
245             L
246              
247             =item * Search CPAN
248              
249             L
250              
251             =back
252              
253              
254             =head1 ACKNOWLEDGEMENTS
255              
256              
257             =head1 LICENSE AND COPYRIGHT
258              
259             Copyright 2017 Mathias Weidner.
260              
261             This program is free software; you can redistribute it and/or modify it
262             under the terms of the the Artistic License (2.0). You may obtain a
263             copy of the full license at:
264              
265             L
266              
267             Any use, modification, and distribution of the Standard or Modified
268             Versions is governed by this Artistic License. By using, modifying or
269             distributing the Package, you accept this license. Do not use, modify,
270             or distribute the Package, if you do not accept this license.
271              
272             If your Modified Version has been derived from a Modified Version made
273             by someone other than you, you are nevertheless required to ensure that
274             your Modified Version complies with the requirements of this license.
275              
276             This license does not grant you the right to use any trademark, service
277             mark, tradename, or logo of the Copyright Holder.
278              
279             This license includes the non-exclusive, worldwide, free-of-charge
280             patent license to make, have made, use, offer to sell, sell, import and
281             otherwise transfer the Package with respect to any patent claims
282             licensable by the Copyright Holder that are necessarily infringed by the
283             Package. If you institute patent litigation (including a cross-claim or
284             counterclaim) against any party alleging that the Package constitutes
285             direct or contributory patent infringement, then this Artistic License
286             to you shall terminate on the date that such litigation is filed.
287              
288             Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
289             AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
290             THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
291             PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
292             YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
293             CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
294             CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
295             EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
296              
297              
298             =cut
299              
300             # vim: set sw=4 ts=4 et:
301             1; # End of File::PCAP::Writer