1 // -*- mode: c++; c-basic-offset: 4 -*-
2 #ifndef CLICK_TOIPSUMDUMP_HH
3 #define CLICK_TOIPSUMDUMP_HH
4 #include <click/element.hh>
5 #include <click/task.hh>
6 #include <click/straccum.hh>
7 #include <click/notifier.hh>
8 #include "ipsumdumpinfo.hh"
9 CLICK_DECLS
10 
11 /*
12 =c
13 
14 ToIPSummaryDump(FILENAME [, I<keywords>])
15 
16 =s traces
17 
18 writes packet summary information to an ASCII file
19 
20 =d
21 
22 Writes summary information about incoming packets to FILENAME in a simple
23 ASCII format---each line corresponds to a packet.  The FIELDS keyword
24 argument determines what information is written.  Writes to standard output if
25 FILENAME is a single dash `C<->'.  The BINARY keyword argument writes a packed
26 binary format to save space.
27 
28 ToIPSummaryDump uses packets' extra-length and extra-packet-count annotations.
29 
30 ToIPSummaryDump can optionally be used as a filter: it pushes received packets
31 to its output if that output exists.
32 
33 Keyword arguments are:
34 
35 =over 8
36 
37 =item FIELDS
38 
39 Space-separated list of field names. Each line of the summary dump will
40 contain those fields. Valid field names, with examples, are:
41 
42    timestamp    Packet timestamp: '996033261.451094' (either
43 		microsecond or nanosecond precision, depending
44 		on how Click was compiled)
45    ts_sec       Seconds portion of timestamp: '996033261'
46    ts_usec      Microseconds portion of timestamp: '451094'
47    ts_usec1     Packet timestamp in microseconds
48                 (ts_sec*1e6 + ts_usec): '996033261451094'
49    ip_src       IP source address: '192.150.187.37'
50    ip_dst       IP destination address: '192.168.1.100'
51    ip_frag      IP fragment: 'F' (1st frag), 'f' (2nd or
52                 later frag), '!' (nonfrag with DF), or
53 		'.' (normal nonfrag)
54    ip_fragoff   IP fragmentation offset: '0', '0+', '0!'
55                 ('+' adds MF, '!' adds DF; offset in bytes)
56    ip_len       IP length: '132'
57    ip_proto     IP protocol: '10', or 'I' for ICMP, 'T' for
58                 TCP, 'U' for UDP
59    ip_hl        IP header length in bytes: '20'
60    ip_id        IP ID: '48759'
61    ip_tos       IP type of service: '29'
62    ip_dscp      IP Differentiated Services code point: '29'
63    ip_ecn       IP ECN capability: 'no', 'ect1', 'ect2', 'ce'
64    ip_ttl       IP time-to-live: '254'
65    ip_sum       IP checksum: '43812'
66    ip_opt       IP options (see below)
67    sport        TCP/UDP source port: '22'
68    dport        TCP/UDP destination port: '2943'
69    tcp_seq      TCP sequence number: '93167339'
70    tcp_ack      TCP acknowledgement number: '93178192'
71    tcp_off      TCP offset in bytes: '20'
72    tcp_flags    TCP flags: 'SA', '.'
73    tcp_opt      TCP options (see below)
74    tcp_ntopt    TCP options except NOP, EOL and timestamp
75                 (see below)
76    tcp_sack     TCP SACK options (see below)
77    tcp_window   TCP receive window: '480'
78    tcp_urp      TCP urgent pointer: '0'
79    udp_len      UDP length: '34'
80    icmp_type    ICMP type: '0'
81    icmp_code    ICMP code: '2'
82    icmp_type_name  ICMP type, named if available: 'echo',
83                 '200'
84    icmp_code_name  ICMP code, named if available:
85                 'sourcequench', '0'
86    icmp_flowid  ICMP flow identifier, in network order: '256'
87    icmp_seq     ICMP sequence number, in network order: '0'
88    icmp_nextmtu  ICMP next-hop MTU (unreach.needfrag only):
89                 '256'
90    payload      Payload (not including IP/TCP/UDP headers,
91                 for this fragment), in a string
92    payload_len  Payload length: '34'
93    payload_md5  Payload MD5 checksum (in ASCII output,
94                 expressed using 22 chars from [A-Za-z0-9_@])
95    payload_md5_hex  Payload MD5 checksum (in ASCII output,
96                 expressed using 32 hexadecimal digits)
97    ip_capture_len  Portion of IP length that contains
98                 actual packet data (as opposed to the extra
99 		length annotation): '34'
100    count        Number of packets: '1'
101    direction    Link number (PAINT_ANNO): '2', or '>'/'L'
102                 for paint 0, '<'/'R'/'X' for paint 1
103    link, paint  Like 'direction', but always numeric
104    aggregate    Aggregate number (AGGREGATE_ANNO): '973'
105    first_timestamp   Packet "first timestamp" (FIRST_
106                 TIMESTAMP_ANNO): '996033261.451094'
107    eth_src      Ethernet source: '00-0A-95-A6-D9-BC'
108    eth_dst      Ethernet source: '00-0A-95-A6-D9-BC'
109    wire_len     Packet wire length: '54'
110 
111 If a field does not apply to a particular packet -- for example, 'C<sport>' on
112 an ICMP packet -- ToIPSummaryDump prints a single dash for that value.
113 
114 Default FIELDS is 'ip_src ip_dst'. You may also use spaces instead of
115 underscores, in which case you must quote field names that contain a space --
116 for example, 'C<ip_src ip_dst "tcp seq">'.
117 
118 =item HEADER
119 
120 Boolean. If true, then print any 'C<!>' header lines at the beginning
121 of the dump to describe the dump format. Default is true.
122 
123 =item VERBOSE
124 
125 Boolean. If true, then print out a couple comments at the beginning of the
126 dump describing the hostname and starting time, in addition to the 'C<!data>'
127 line describing the dumped fields. Ignored if HEADER is false. Default is
128 false.
129 
130 =item BANNER
131 
132 String. If supplied, prints a 'C<!creator "BANNER">' comment at the beginning
133 of the dump. Ignored if HEADER is false.
134 
135 =item BINARY
136 
137 Boolean. If true, then output packet records in a binary format (explained
138 below). Defaults to false.
139 
140 =item MULTIPACKET
141 
142 Boolean. If true, and the FIELDS option doesn't contain 'C<count>', then
143 generate multiple summary entries for packets with nonzero extra-packets
144 annotations. For example, if MULTIPACKET is true, and a packet has
145 extra-packets annotation 1, then ToIPSummaryDump will generate 2 lines for
146 that packet in the dump. False by default.
147 
148 =item BAD_PACKETS
149 
150 Boolean. If true, then print 'C<!bad MESSAGE>' lines for packets with bad IP,
151 TCP, or UDP headers, as well as normal output.  The 'C<!bad>' line immediately
152 precedes the corresponding packet.  Output will contain dashes 'C<->' in place
153 of data from bad headers.  Default is false.
154 
155 =item CAREFUL_TRUNC
156 
157 Boolean.  If true, then print 'C<!bad truncated IP length>' lines for packets
158 whose data plus extra length annotation is less than their IP length.
159 B<Tcpdump> prints 'C<truncated-ip - N bytes missing>' for such packets.
160 Actual packet output immediately follows the 'C<!bad>' line.  Default is true.
161 
162 =item EXTRA_LENGTH
163 
164 Boolean.  If false, then ignore extra length annotations.  Defaults to true.
165 
166 =back
167 
168 =e
169 
170 Here are a couple lines from the start of a sample verbose dump.
171 
172   !IPSummaryDump 1.3
173   !creator "aciri-ipsumdump -i wvlan0"
174   !host no.lcdf.org
175   !runtime 996022410.322317 (Tue Jul 24 17:53:30 2001)
176   !data ip_src ip_dst
177   63.250.213.167 192.150.187.106
178   63.250.213.167 192.150.187.106
179 
180 The end of the dump may contain a comment 'C<!drops N>', meaning that C<N>
181 packets were dropped before they could be entered into the dump.
182 
183 A 'C<!flowid>' comment can specify source and destination addresses and ports
184 for packets that otherwise don't have one.  Its arguments are 'C<!flowid SRC
185 SPORT DST DPORT [PROTO]>'.
186 
187 Any packet line may contain fewer fields than specified in the 'C<!data>'
188 line, down to one field. Missing fields are treated as 'C<->'.
189 
190 =n
191 
192 The 'C<len>' and 'C<payload_len>' fields use the extra length
193 annotation. The 'C<count>' field uses the extra packets annotation.
194 
195 The characters corresponding to TCP flags are as follows:
196 
197    Flag name  Character  Value
198    ---------  ---------  -----
199    FIN        F          0x01
200    SYN        S          0x02
201    RST        R          0x04
202    PSH        P          0x08
203    ACK        A          0x10
204    URG        U          0x20
205    ECE        E          0x40
206    CWR        C          0x80
207    NS         N          0x100
208 
209 The 'C<W>' character is also acceptable for CWR.  Old IP summary dumps might
210 contain an unsigned integer, representing the flags byte, or might use 'C<X>'
211 and 'C<Y>' for ECE and CWR, respectively.
212 
213 Verson 1.0 of the IPSummaryDump file format expressed fragment offsets in
214 8-byte units, not bytes. Fields in old dumps were sometimes quoted and
215 contained spaces instead of underscores. In Version 1.2 files payload MD5
216 checksums were sometimes incorrect.
217 
218 =head1 IP OPTIONS
219 
220 Single IP option fields have the following representations.
221 
222     EOL, NOP        Not written, but FromIPSummaryDump
223                     understands 'eol' and 'nop'
224 
225     RR              'rr{10.0.0.1,20.0.0.2}+5' (addresses
226                     inside the braces come before the
227 		    pointer; '+5' means there is space for
228 		    5 more addresses after the pointer)
229 
230     SSRR, LSRR      'ssrr{1.0.0.1,1.0.0.2^1.0.0.3}'
231                     ('^' indicates the pointer)
232 
233     TS              'ts{1,10000,!45}+2++3' (timestamps only
234                     [type 0]; timestamp values 1, 10000,
235 		    and 45 [but 45 has the "nonstandard
236 		    timestamp" bit set]; the option has
237 		    room for 2 more timestamps; the
238 		    overflow counter is set to 3)
239 
240 		    'ts.ip{1.0.0.1=1,1.0.0.2=2}+5'
241 		    (timestamps with IP addresses [type 1])
242 
243 		    'ts.preip{1.0.0.1=1^1.0.0.2,1.0.0.3}'
244 		    (prespecified IP addresses [type 3];
245 		    the caret is the pointer)
246 
247     Other options   '98' (option 98, no data),
248                     '99=0:5:10' (option with data, data
249 		    octets separated by colons)
250 
251 Multiple options are separated by semicolons. (No single option will ever
252 contain a semicolon.) Any invalid option causes the entire field to be
253 replaced by a single question mark 'C<?>'. A period 'C<.>' is used for packets
254 with no options (except possibly EOL and NOP).
255 
256 =head1 TCP OPTIONS
257 
258 Single TCP option fields have the following representations.
259 
260     EOL, NOP        Not written, but FromIPSummaryDump
261                     understands 'eol' and 'nop'
262     MSS             'mss1400'
263     Window scale    'wscale10'
264     SACK permitted  'sackok'
265     SACK            'sack95-98'; each SACK block
266                     is listed separately
267     Timestamp       'ts669063908:38382731'
268     Other options   '98' (option 98, no data),
269                     '99=0:5:10' (option with data, data
270 		    octets separated by colons)
271 
272 Multiple options are separated by semicolons. (No single option will ever
273 contain a semicolon.) Any invalid option causes the entire field to be
274 replaced by a single question mark 'C<?>'. A period 'C<.>' is used for packets
275 with no options (except possibly EOL and NOP).
276 
277 =head1 BINARY FORMAT
278 
279 Binary IPSummaryDump files begin with several ASCII lines, just like regular
280 files. The line 'C<!binary>' indicates that the rest of the file, starting
281 immediately after the newline, consists of binary records. Each record looks
282 like this:
283 
284    +---------------+------------...
285    |X|record length|    data
286    +---------------+------------...
287     <---4 bytes--->
288 
289 The initial word of data contains the record length in bytes. (All numbers in
290 the file are stored in network byte order.) The record length includes the
291 initial word itself, so the minimum valid record length is 4. The high-order
292 bit 'C<X>' is the metadata indicator. It is zero for regular packets and one
293 for metadata lines.
294 
295 Regular packet records have binary fields stored in the order indicated by
296 the 'C<!data>' line, as follows:
297 
298    Field Name    Length  Description
299    timestamp	    8	 timestamp sec + usec
300    utimestamp	    8	 timestamp sec + usec
301    ntimestamp	    8	 timestamp sec + nsec
302    ts_sec, ts_usec  4	 timestamp sec/usec
303    ts_usec1         8    timestamp in usec
304    ip_src           4    IP source address
305    ip_dst           4    IP destination address
306    sport            2    source port
307    dport            2    destination port
308    ip_len           4    IP length field
309    ip_proto         1    IP protocol
310    ip_id            2    IP ID
311    ip_tos           1    IP TOS
312    ip_ttl           1    IP TTL
313    ip_frag          1    fragment descriptor
314                          ('F', 'f', or '.')
315    ip_fragoff       2    IP fragment offset field
316    ip_opt           ?    IP options
317    tcp_seq          4    TCP sequence number
318    tcp_ack          4    TCP ack number
319    tcp_flags        1    TCP flags
320    tcp_opt          ?    TCP options
321    tcp_ntopt        ?    TCP non-timestamp options
322    tcp_sack         ?    TCP SACK options
323    udp_len          4    UDP length
324    payload_len      4    payload length
325    payload_md5     16    payload MD5 checksum
326    payload_md5_hex 16    payload MD5 checksum
327    ip_capture_len   4    IP capture length
328    count            4    packet count
329    first_timestamp  8    timestamp sec + usec
330    eth_src          6    Ethernet source address
331    eth_dst          6    Ethernet destination address
332 
333 Each field is Length bytes long. Variable-length fields have Length 'C<?>' in
334 the table; in a packet record, these fields consist of a single length byte,
335 followed by that many bytes of data.
336 
337 The data stored in a metadata record is just an ASCII string, ending with
338 newline, same as in a regular ASCII IPSummaryDump file. 'C<!bad>' records, for
339 example, are stored this way.
340 
341 =h flush write-only
342 
343 Flush all internal buffers to disk.
344 
345 =a
346 
347 FromIPSummaryDump, FromDump, ToDump */
348 
349 class ToIPSummaryDump : public Element, public IPSummaryDumpInfo { public:
350 
351     ToIPSummaryDump() CLICK_COLD;
352     ~ToIPSummaryDump() CLICK_COLD;
353 
class_name() const354     const char *class_name() const	{ return "ToIPSummaryDump"; }
port_count() const355     const char *port_count() const	{ return "1/0-1"; }
processing() const356     const char *processing() const	{ return "a/h"; }
flags() const357     const char *flags() const		{ return "S2"; }
358 
359     int configure(Vector<String> &, ErrorHandler *) CLICK_COLD;
360     int initialize(ErrorHandler *) CLICK_COLD;
361     void cleanup(CleanupStage) CLICK_COLD;
362     void add_handlers() CLICK_COLD;
363 
364     void push(int, Packet *);
365     bool run_task(Task *);
366 
filename() const367     String filename() const		{ return _filename; }
output_count() const368     uint32_t output_count() const	{ return _output_count; }
369     void add_note(const String &);
370     void write_line(const String &);
371 
372   private:
373 
374     String _filename;
375     FILE *_f;
376     Vector<const IPSummaryDump::FieldWriter *> _fields;
377     Vector<const IPSummaryDump::FieldWriter *> _prepare_fields;
378     bool _verbose : 1;
379     bool _bad_packets : 1;
380     bool _careful_trunc : 1;
381     bool _multipacket : 1;
382     bool _active : 1;
383     bool _binary : 1;
384     bool _header : 1;
385     bool _extra_length : 1;
386     int32_t _binary_size;
387     uint32_t _output_count;
388     Task _task;
389     NotifierSignal _signal;
390 
391     StringAccum _sa;
392     StringAccum _bad_sa;
393 
394     String _banner;
395 
396     bool summary(Packet* p, StringAccum& sa, StringAccum* bad_sa) const;
397     void write_packet(Packet* p, int multipacket);
398     static int flush_handler(const String &, Element *, void *, ErrorHandler *);
399 
400 };
401 
402 CLICK_ENDDECLS
403 #endif
404