tcpflow  1.6.1
About: tcpflow is a TCP/IP packet demultiplexer that captures data transmitted as part of TCP connections (flows), and stores the data in a way that is convenient for protocol analysis and debugging.
  Fossies Dox: tcpflow-1.6.1.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

Loading...
Searching...
No Matches
tcpip.cpp
Go to the documentation of this file.
1/*
2 * This file is part of tcpflow by Simson Garfinkel,
3 * originally by Jeremy Elson <jelson@circlemud.org>
4 *
5 * Modified by Greg Drew to add support for creating a packet time / data index
6 * which allows mapping bytes in the flow back to their relative arrival time.
7 * This is very useful in reassembling inherently bidirectional conversations
8 * such as chat or telnet sessions. --GDD
9 *
10 * This source code is under the GNU Public License (GPL). See
11 * LICENSE for details.
12 *
13 */
14
15#include "tcpflow.h"
16#include "tcpip.h"
17#include "tcpdemux.h"
18
19#include <iostream>
20#include <sstream>
21#include <vector>
22#include <string>
23
24#pragma GCC diagnostic ignored "-Weffc++"
25#pragma GCC diagnostic ignored "-Wshadow"
26
27
28/* Create a new tcp object.
29 *
30 * Creating a new object creates a new passive TCP/IP decoder.
31 * It will *NOT* append to a flow that is already on the disk or in memory.
32 *
33 * called from tcpdemux::create_tcpip()
34 */
35tcpip::tcpip(tcpdemux &demux_,const flow &flow_,be13::tcp_seq isn_):
36 demux(demux_),myflow(flow_),dir(unknown),isn(isn_),nsn(0),
37 syn_count(0),fin_count(0),fin_size(0),pos(0),
38 flow_pathname(),fd(-1),file_created(false),
39 flow_index_pathname(),idx_file(),
40 seen(new recon_set()),
41 last_byte(),
42 last_packet_number(),out_of_order_count(0),violations(0)
43{
44}
45
46
48{
49 if(seen) return seen->size();
50 return 0;
51}
52
54{
55 if(seen){
56 for(recon_set::const_iterator it = seen->begin(); it!=seen->end(); it++){
57 std::cerr << *it << ", ";
58 }
59 std::cerr << std::endl;
60 }
61}
62
63void tcpip::dump_xml(class dfxml_writer *xreport,const std::string &xmladd)
64{
65 static const std::string fileobject_str("fileobject");
66 static const std::string filesize_str("filesize");
67 static const std::string filename_str("filename");
68 static const std::string tcpflow_str("tcpflow");
69
70 xreport->push(fileobject_str);
71 if(flow_pathname.size()) xreport->xmlout(filename_str,flow_pathname);
72
73 xreport->xmlout(filesize_str,last_byte);
74
75 std::stringstream attrs;
76 attrs << "startime='" << dfxml_writer::to8601(myflow.tstart) << "' ";
77 attrs << "endtime='" << dfxml_writer::to8601(myflow.tlast) << "' ";
78 if(myflow.has_mac_daddr()) attrs << "mac_daddr='" << macaddr(myflow.mac_daddr) << "' ";
79 if(myflow.has_mac_saddr()) attrs << "mac_saddr='" << macaddr(myflow.mac_saddr) << "' ";
80 attrs << "family='" << (int)myflow.family << "' ";
81 attrs << "src_ipn='" << ipaddr_prn(myflow.src, myflow.family) << "' ";
82 attrs << "dst_ipn='" << ipaddr_prn(myflow.dst, myflow.family) << "' ";
83 attrs << "srcport='" << myflow.sport << "' ";
84 attrs << "dstport='" << myflow.dport << "' ";
85 attrs << "packets='" << myflow.packet_count << "' ";
86 if(out_of_order_count) attrs << "out_of_order_count='" << out_of_order_count << "' ";
87 if(violations) attrs << "violations='" << violations << "' ";
88 attrs << "len='" << myflow.len << "' ";
89 if(myflow.len != myflow.caplen) attrs << "caplen='" << myflow.caplen << "' ";
90 xreport->xmlout(tcpflow_str,"",attrs.str(),false);
91 if(xmladd.size()>0) xreport->xmlout("",xmladd,"",false);
92 xreport->pop();
93 xreport->flush();
94}
95
96
97/**
98 * Destructor is called when flow is closed.
99 * It implements "after" processing.
100 * This should only be called from remove_flow() or remove_all_flows()
101 * when a flow is deleted.
102 */
104{
105 assert(fd<0); // file must be closed
106 delete seen; // no need to check to see if seen is null or not.
107}
108
109#pragma GCC diagnostic warning "-Weffc++"
110#pragma GCC diagnostic warning "-Wshadow"
111
112
113/****************************************************************
114 ** SAVE FILE MANAGEMENT
115 ****************************************************************
116 *
117 * Unlike the tcp/ip object, which is created once, the file can be opened, closed, and
118 * re-opened depending on the availability of file handles.
119 *
120 * Closing the file does not delete the tcp/ip object.
121 */
122
123
124/* Closes the file belonging to a flow.
125 * Does not take tcpip out of flow database.
126 * Does not change pos.
127 */
129{
130 if (fd>=0){
131 struct timeval times[2];
132 times[0] = myflow.tstart;
133 times[1] = myflow.tstart;
134
135 DEBUG(5) ("%s: closing file in tcpip::close_file", flow_pathname.c_str());
136 /* close the file and remember that it's closed */
137#if defined(HAVE_FUTIMES)
138 /* fix microseconds if they are invalid */
139 for ( int i=0; i<2; i++){
140 if ( times[i].tv_usec < 0 || times[i].tv_usec >= 1000000 ){
141 times[i].tv_usec = 0;
142 }
143 }
144 if (futimes(fd,times)){
145 fprintf(stderr,"%s: futimes(fd=%d,[%ld:%ld,%ld:%ld])\n",
146 strerror(errno),fd,
147 times[0].tv_sec,times[1].tv_usec,
148 times[1].tv_sec,times[1].tv_usec);
149 }
150#elif defined(HAVE_FUTIMENS)
151 struct timespec tstimes[2];
152 for(int i=0;i<2;i++){
153 tstimes[i].tv_sec = times[i].tv_sec;
154 tstimes[i].tv_nsec = times[i].tv_usec * 1000;
155 }
156 if(futimens(fd,tstimes)){
157 perror("futimens(fd=%d)",fd);
158 }
159#endif
160 close(fd);
161 fd = -1;
162 demux.open_flows.erase(this); // we are no longer open
163 }
164 // Also close the flow_index file, if flow indexing is in use --GDD
165 if(demux.opt.output_packet_index && idx_file.is_open()){
166 idx_file.close();
167 }
168 //std::cerr << "close_file1 " << *this << "\n";
169}
170
171/*
172 * Opens the file transcript file (creating file if necessary).
173 * Called by store_packet()
174 * Does not change pos.
175 */
176
178{
179 int create_idx_needed = false;
180 if(fd<0){
181 //std::cerr << "open_file0 " << ct << " " << *this << "\n";
182 /* If we don't have a filename, create the flow */
183 if(flow_pathname.size()==0) {
184 flow_pathname = myflow.new_filename(&fd,O_RDWR|O_BINARY|O_CREAT|O_EXCL,0666);
185 file_created = true; // remember we made it
186 create_idx_needed = true; // We created a new stream, so we need to create a new flow file. --GDD
187 DEBUG(5) ("%s: created new file",flow_pathname.c_str());
188 } else {
189 /* open an existing flow */
190 fd = demux.retrying_open(flow_pathname,O_RDWR | O_BINARY | O_CREAT,0666);
191 lseek(fd,pos,SEEK_SET);
192 DEBUG(5) ("%s: opening existing file", flow_pathname.c_str());
193 }
194
195 /* If the file isn't open at this point, there's a problem */
196 if (fd < 0 ) {
197 /* we had some problem opening the file -- set FINISHED so we
198 * don't keep trying over and over again to reopen it
199 */
200 perror(flow_pathname.c_str());
201 return -1;
202 }
203 /* Remember that we have this open */
206 //std::cerr << "open_file1 " << *this << "\n";
207 }
209 //Open the file for the flow index. We don't do this if the flow file could not be
210 // opened. The file must be opened for append, in case this is a reopen. The filename
211 // standard is the flow name followed by ".findx", which google currently says does not
212 // conflict with anything major.
214 DEBUG(10)("opening index file: %s",flow_index_pathname.c_str());
215 if(create_idx_needed){
216 //New flow file, even if there was an old one laying around --GDD
217 idx_file.open(flow_index_pathname.c_str(),std::ios::trunc|std::ios::in|std::ios::out);
218 }else{
219 //Use existing flow file --GDD
220 idx_file.open(flow_index_pathname.c_str(),std::ios::ate|std::ios::in|std::ios::out);
221 }
222 if(idx_file.bad()){
223 perror(flow_index_pathname.c_str());
224 // Be nice and be sure the flow has been closed in the demultiplexer.
225 // demux.close_tcpip_fd(this); Need to fix this. Also, when called, it will
226 // have to differentiate the fact that the open fd cound only needs to be
227 // decremented by one and not by 2.--GDD
228 return -1;
229 }
230
231 }
232 return 0;
233}
234
235
236
237/*************************************************************************/
238
239/* print the contents of this packet to the console.
240 * This is nice for immediate satisfaction, but it can't handle
241 * out of order packets, etc.
242 */
243void tcpip::print_packet(const u_char *data, uint32_t length)
244{
245 /* green, blue, read */
246 const char *color[3] = { "\033[0;32m", "\033[0;34m", "\033[0;31m" };
247
249 uint64_t max_bytes_per_flow = (uint64_t)demux.opt.max_bytes_per_flow;
250
251 if(last_byte > max_bytes_per_flow) return; /* too much has been printed */
252 if(length > max_bytes_per_flow - last_byte){
253 length = max_bytes_per_flow - last_byte; /* can only output this much */
254 if(length==0) return;
255 }
256 }
257
258#ifdef HAVE_PTHREAD
259 if(semlock){
260 if(sem_wait(semlock)){
261 fprintf(stderr,"%s: attempt to acquire semaphore failed: %s\n",progname,strerror(errno));
262 exit(1);
263 }
264 }
265#endif
266
267 if(flow_pathname.size()==0) flow_pathname = myflow.filename(0, false);
268 if (demux.opt.use_color) fputs(dir==dir_cs ? color[1] : color[2], stdout);
269 if (demux.opt.suppress_header == 0 && demux.opt.output_json == 0){
270 printf("%s: ", flow_pathname.c_str());
271 if(demux.opt.output_hex) putchar('\n');
272 }
273
274 size_t written = 0;
275 if(demux.opt.output_hex){
276 const size_t bytes_per_line = 32;
277 size_t max_spaces = 0;
278 for(u_int i=0;i<length;i+=bytes_per_line){
279 size_t spaces=0;
280
281 /* Print the offset */
282 char b[64];
283 size_t count = snprintf(b,sizeof(b),"%04x: ",(int)i);
284 if(fwrite(b,1,count,stdout)!=count){
285 perror("fwrite");
286 }
287 spaces += count;
288
289 /* Print the hext bytes */
290 for(size_t j=0;j<bytes_per_line && i+j<length ;j++){
291 unsigned char ch = data[i+j];
292 fprintf(stdout,"%02x",ch); spaces += 2;
293 if(j%2==1){
294 fputc(' ',stdout);
295 spaces += 1;
296 }
297 }
298 /* space out to where the ASCII region is */
299 if(spaces>max_spaces) max_spaces=spaces;
300 for(;spaces<max_spaces;spaces++){
301 fputc(' ',stdout);
302 }
303 putchar(' ');
304 /* Print the ascii */
305 for(size_t j=0;j<bytes_per_line && i+j<length;j++){
306 unsigned char ch = data[i+j];
307 if(ch>=' ' && ch<='~') fputc(ch,stdout);
308 else fputc('.',stdout);
309 }
310 fputc('\n',stdout);
311 }
312 written = length; // just fake it.
313 } else if (demux.opt.output_json) {
314 // {
315 // "src_host": "192.168.0.1",
316 // "src_port": 1234,
317 // "dst_host": "1.1.1.1",
318 // "dst_port": 80,
319 // "payload" : [...]
320 // }
321
322 std::string hoststr = std::string();
323
324 putchar('{');
325 printf("\"src_host\":\"");
326
327 size_t src_pos = 0;
328 size_t src_end_pos = 0;
329 size_t src_pos_counter = 0;
330
331 size_t pathname_len = flow_pathname.length();
332 for(size_t i = 0; i < pathname_len; ++i) {
333 if(flow_pathname[i] == '.') {
334 src_pos_counter++;
335 printf("%d%s", atoi(hoststr.c_str()), (src_pos_counter != 4 ? "." : ""));
336 hoststr.clear();
337 } else {
338 hoststr = hoststr + flow_pathname[i];
339 }
340 if(src_pos_counter == 4) {
341 src_pos = i;
342 break;
343 }
344 }
345 src_end_pos = src_pos;
346 for(;src_end_pos < pathname_len; ++src_end_pos) {
347 if(flow_pathname[src_end_pos] == '-') {
348 break;
349 }
350 }
351 printf("\",\"src_port\":%d,\"dst_host\":\"", atoi(flow_pathname.substr(src_pos + 1, src_end_pos - src_pos).c_str()));
352
353 size_t dst_pos = src_end_pos + 1;
354 size_t dst_end_pos = dst_pos;
355 size_t dst_pos_counter = 0;
356
357 for(size_t i = dst_pos; i < pathname_len; ++i) {
358 if(flow_pathname[i] == '.') {
359 dst_pos_counter++;
360 printf("%d%s", atoi(hoststr.c_str()), (dst_pos_counter != 4 ? "." : ""));
361 hoststr.clear();
362 } else {
363 hoststr = hoststr + flow_pathname[i];
364 }
365 if(dst_pos_counter == 4) {
366 dst_pos = i;
367 break;
368 }
369 }
370 dst_end_pos = dst_pos;
371 for(;dst_end_pos < pathname_len; ++dst_end_pos) {
372 if(flow_pathname[dst_end_pos] == '-') {
373 break;
374 }
375 }
376 printf("\",\"dst_port\":%d,\"payload\": [", atoi(flow_pathname.substr(dst_pos + 1, dst_end_pos - dst_pos).c_str()));
377
378 for(size_t i = 0; i < length; ++i) {
379 printf("%d%s", data[i], (i != length - 1 ? "," : "]}"));
380 }
381 } else if (demux.opt.output_strip_nonprint) {
382 for(const u_char *cc = data;cc<data+length;cc++){
383 if(isprint(*cc) || (*cc=='\n') || (*cc=='\r')){
384 int ret = fputc(*cc,stdout);
385 if(ret==EOF){
386 std::cerr << "EOF on write to stdout\n";
387 exit(1);
388
389 }
390 }
391 else fputc('.',stdout);
392 written += 1; // treat even unprintable characters as "written". It
393 // really means "processed"
394 }
395 } else {
396 written = fwrite(data,1,length,stdout);
397 if(length != written) std::cerr << "\nwrite error to stdout (" << length << "!=" << written << ") \n";
398 }
399
400 last_byte += length;
401
402 if (demux.opt.use_color) printf("\033[0m");
403
404 if (! demux.opt.console_output_nonewline) putchar('\n');
405 fflush(stdout);
406
407#ifdef HAVE_PTHREAD
408 if(semlock){
409 if(sem_post(semlock)){
410 fprintf(stderr,"%s: attempt to post semaphore failed: %s\n",progname,strerror(errno));
411 exit(1);
412 }
413 }
414#endif
415}
416
417/*
418 * extend_file_and_insert():
419 * A handy function for inserting in the middle or beginning of a file.
420 *
421 * Based on:
422 * http://stackoverflow.com/questions/10467711/c-write-in-the-middle-of-a-binary-file-without-overwriting-any-existing-content
423 */
424
425static int shift_file(int fd, size_t inslen)
426{
427 enum { BUFFERSIZE = 64 * 1024 };
428 char buffer[BUFFERSIZE];
429 struct stat sb;
430
431 DEBUG(100)("shift_file(%d,%d)",fd,(int)inslen);
432
433 if (fstat(fd, &sb) != 0) return -1;
434
435 /* Move data after offset up by inslen bytes */
436 size_t bytes_to_move = sb.st_size;
437 off_t read_end_offset = sb.st_size;
438 while (bytes_to_move != 0) {
439 ssize_t bytes_this_time = bytes_to_move < BUFFERSIZE ? bytes_to_move : BUFFERSIZE ;
440 ssize_t rd_off = read_end_offset - bytes_this_time;
441 ssize_t wr_off = rd_off + inslen;
442 lseek(fd, rd_off, SEEK_SET);
443 if (read(fd, buffer, bytes_this_time) != bytes_this_time)
444 return -1;
445 lseek(fd, wr_off, SEEK_SET);
446 if (write(fd, buffer, bytes_this_time) != bytes_this_time)
447 return -1;
448 bytes_to_move -= bytes_this_time;
449 }
450 return 0;
451}
452
453#pragma GCC diagnostic ignored "-Weffc++"
454void update_seen(recon_set *seen,uint64_t pos,uint32_t length)
455{
456 if(seen){
457 (*seen) += boost::icl::discrete_interval<uint64_t>::closed(pos,pos+length-1);
458 }
459}
460
461/* store the contents of this packet to its place in its file
462 * This has to handle out-of-order packets as well as writes
463 * past the 4GiB boundary.
464 *
465 * 2012-10-24 Originally this code simply computed the 32-bit offset
466 * from the beginning of the file using the isn. The new version tracks
467 * nsn (the expected next sequence number for the open file).
468 *
469 * A relative seek before the beginning of the file means that we need
470 * to insert. A relative seek more than max_seek means that we have a
471 * different flow that needs to be separately handled.
472 *
473 * called from tcpdemux::process_tcp_packet()
474 */
475void tcpip::store_packet(const u_char *data, uint32_t length, int32_t delta,struct timeval ts)
476{
477 if(length==0) return; // no need to do anything
478
479 uint32_t insert_bytes=0;
480 uint64_t offset = pos+delta; // where the data will go in absolute byte positions (first byte is pos=0)
481
482 if((int64_t)offset < 0){
483 /* We got bytes before the beginning of the TCP connection.
484 * Either this is a protocol violation,
485 * or else we never saw a SYN and we got the ISN wrong.
486 */
487 if(syn_count>0){
488 DEBUG(2)("packet received with offset %" PRId64 "; ignoring",offset);
489 violations++;
490 return;
491 }
492 insert_bytes = -offset; // open up this much space
493 offset = 0; // and write the data here
494 }
495
496 /* reduce length to write if it goes beyond the number of bytes per flow,
497 * but remember to seek out to the actual position after the truncated write...
498 */
499 uint32_t wlength = length; // length to write
500 if (demux.opt.max_bytes_per_flow >= 0){
501 uint64_t max_bytes_per_flow = (uint64_t)demux.opt.max_bytes_per_flow;
502
503 if(offset >= max_bytes_per_flow){
504 wlength = 0;
505 }
506 if(offset < max_bytes_per_flow && offset+length > max_bytes_per_flow){
507 DEBUG(2) ("packet truncated by max_bytes_per_flow on %s", flow_pathname.c_str());
508 wlength = max_bytes_per_flow - offset;
509 }
510 }
511
512 /* if we don't have a file open for this flow, try to open it.
513 * return if the open fails. Note that we don't have to explicitly
514 * save the return value because open_tcpfile() puts the file pointer
515 * into the structure for us.
516 */
517 if (fd < 0) {
518 if (open_file()) {
519 DEBUG(1)("unable to open TCP file %s fd=%d wlength=%d",
520 flow_pathname.c_str(),fd,(int)wlength);
521 return;
522 }
523 }
524
525 /* Shift the file now if we were going shift it */
526
527 if(insert_bytes>0){
528 if(fd>=0) shift_file(fd,insert_bytes);
529 isn -= insert_bytes; // it's really earlier
530 lseek(fd,(off_t)0,SEEK_SET); // put at the beginning
531 pos = 0;
532 nsn = isn+1;
534 DEBUG(25)("%s: insert(0,%d); lseek(%d,0,SEEK_SET) out_of_order_count=%" PRId64,
535 flow_pathname.c_str(), insert_bytes,
537
538 /* TK: If we have seen packets, everything in the recon set needs to be shifted as well.*/
539 delete seen;
540 seen = 0;
541 }
542
543 /* if we're not at the correct point in the file, seek there */
544 if (offset != pos) {
545 /* Check for a keepalive */
546 if(delta == -1 && length == 1) {
547 DEBUG(25)("%s: RFC1122 keepalive detected and ignored",flow_pathname.c_str());
548 return;
549 }
550
551 if(fd>=0) lseek(fd,(off_t)delta,SEEK_CUR);
552 if(delta<0) out_of_order_count++; // only increment for backwards seeks
553 DEBUG(25)("%s: lseek(%d,%d,SEEK_CUR) offset=%" PRId64 " pos=%" PRId64 " out_of_order_count=%" PRId64,
554 flow_pathname.c_str(), fd,(int)delta,offset,pos,out_of_order_count);
555 pos += delta; // where we are now
556 nsn += delta; // what we expect the nsn to be now
557 }
558
559 /* write the data into the file */
560 DEBUG(25) ("%s: %s write %ld bytes @%" PRId64,
561 flow_pathname.c_str(),
562 fd>=0 ? "will" : "won't",
563 (long) wlength, offset);
564
565 if(fd>=0){
566 if ((uint32_t)write(fd,data, wlength) != wlength) {
567 DEBUG(1) ("write to %s failed: ", flow_pathname.c_str());
568 if (debug >= 1) perror("");
569 }
570 // Write to the index file if needed. Note, index file is sorted before close, so no need to jump around --GDD
571 if (demux.opt.output_packet_index && idx_file.is_open()) {
572 idx_file << offset << "|" << ts.tv_sec << "." << std::setw(6) << std::setfill('0') << ts.tv_usec << "|"
573 << wlength << "\n";
574 if (idx_file.bad()){
575 DEBUG(1)("write to index file %s failed: ",flow_index_pathname.c_str());
576 if(debug >= 1){
577 perror("");
578 }
579 }
580 }
581 if(wlength != length){
582 off_t p = lseek(fd,length-wlength,SEEK_CUR); // seek out the space we didn't write
583 DEBUG(100)(" lseek(%" PRId64 ",SEEK_CUR)=%" PRId64,(int64_t)(length-wlength),(int64_t)p);
584 }
585 }
586
587 /* Update the database of bytes that we've seen */
588 if(seen) update_seen(seen,pos,length);
589
590 /* Update the position in the file and the next expected sequence number */
591 pos += length;
592 nsn += length; // expected next sequence number
593
595
596 if(debug>=100){
597 uint64_t rpos = lseek(fd,(off_t)0,SEEK_CUR);
598 DEBUG(100)(" pos=%" PRId64 " lseek(fd,0,SEEK_CUR)=%" PRId64,pos,rpos);
599 assert(pos==rpos);
600 }
601
602#ifdef DEBUG_REOPEN_LOGIC
603 /* For debugging, force this connection closed */
604 demux.close_tcpip_fd(this);
605#endif
606}
607
608/*
609 * Compare two index strings and return the result. Called by
610 * the vector::sort in sort_index.
611 * --GDD
612 */
613bool tcpip::compare(std::string a, std::string b){
614 std::stringstream ss_a(a),ss_b(b);
615 long a_l,b_l;
616
617 ss_a >> a_l;
618 ss_b >> b_l;
619 return a_l < b_l;
620}
621
622/*
623 * Sort an index file (presumably from this object) if file indexing is
624 * turned on and the file exists. Index files may be out of order due
625 * to the arrival of out of order packets. It is cheaper to reorder them
626 * one time at the end of processing than it is to continually keep them
627 * in order.
628 * --GDD
629 */
630void tcpip::sort_index(std::fstream *ix_file) {
631
632 std::vector<std::string> idx;
633 std::string line;
634
636 if (!(idx_file.good() && idx_file.is_open())) {
637 DEBUG(5)("Skipping index file sort. Unusual behavior.\n");
638 return; //Nothing to do
639 }
640 //Make sure we are at the beginning.
641 ix_file->clear();
642 ix_file->seekg(0);
643 do {
644 *ix_file >> line;
645 if (!ix_file->eof()) {
646 idx.push_back(line);
647 }
648 } while (ix_file->good());
649 std::sort(idx.begin(), idx.end(), &tcpip::compare);
650 ix_file->clear();
651 ix_file->seekg(0);
652 for (std::vector<std::string>::iterator s = idx.begin(); s != idx.end();
653 s++) {
654 *ix_file << *s << "\n";
655 }
656 }
657}
658
659/*
660 * Convenience function to cause the local index file to be sorted.
661 * --GDD
662 */
664 tcpip::sort_index(&(this->idx_file));
665}
666
667#pragma GCC diagnostic ignored "-Weffc++"
668#pragma GCC diagnostic ignored "-Wshadow"
669
670/* Note --- Turn off warning so that creating the seen() map doesn't throw an error */
671//#pragma GCC diagnostic ignored "-Weffc++"
ipaddr dst
Definition: tcpip.h:98
ipaddr src
Definition: tcpip.h:97
sa_family_t family
Definition: tcpip.h:101
uint16_t dport
Definition: tcpip.h:100
uint16_t sport
Definition: tcpip.h:99
Definition: tcpip.h:156
uint64_t len
Definition: tcpip.h:183
uint64_t packet_count
Definition: tcpip.h:185
uint8_t mac_saddr[6]
Definition: tcpip.h:180
bool has_mac_daddr()
Definition: tcpip.h:196
std::string new_filename(int *fd, int flags, int mode)
Definition: flow.cpp:167
struct timeval tstart
Definition: tcpip.h:181
uint8_t mac_daddr[6]
Definition: tcpip.h:179
uint64_t caplen
Definition: tcpip.h:184
std::string filename(uint32_t connection_count, bool)
Definition: flow.cpp:54
bool has_mac_saddr()
Definition: tcpip.h:200
struct timeval tlast
Definition: tcpip.h:182
void push_back(T *node)
void erase(T *node)
bool console_output_nonewline
Definition: tcpdemux.h:109
int64_t max_bytes_per_flow
Definition: tcpdemux.h:114
bool suppress_header
Definition: tcpdemux.h:116
bool output_strip_nonprint
Definition: tcpdemux.h:117
bool output_packet_index
Definition: tcpdemux.h:122
int retrying_open(const std::string &filename, int oflag, int mask)
Definition: tcpdemux.cpp:121
intrusive_list< tcpip > open_flows
Definition: tcpdemux.h:139
options opt
Definition: tcpdemux.h:146
void close_tcpip_fd(tcpip *)
unsigned int max_open_flows
Definition: tcpdemux.h:134
recon_set * seen
Definition: tcpip.h:317
void sort_index()
Definition: tcpip.cpp:663
class tcpdemux & demux
Definition: tcpip.h:295
uint32_t seen_bytes()
Definition: tcpip.cpp:47
uint64_t out_of_order_count
Definition: tcpip.h:320
void dump_seen()
Definition: tcpip.cpp:53
uint64_t last_byte
Definition: tcpip.h:318
uint64_t violations
Definition: tcpip.h:321
dir_t dir
Definition: tcpip.h:299
flow myflow
Definition: tcpip.h:298
int fd
Definition: tcpip.h:309
void dump_xml(class dfxml_writer *xmlreport, const std::string &xmladd)
Definition: tcpip.cpp:63
int open_file()
Definition: tcpip.cpp:177
uint64_t pos
Definition: tcpip.h:305
void store_packet(const u_char *data, uint32_t length, int32_t delta, struct timeval ts)
Definition: tcpip.cpp:475
uint32_t syn_count
Definition: tcpip.h:302
std::string flow_pathname
Definition: tcpip.h:308
tcpip(const tcpip &t)
std::fstream idx_file
Definition: tcpip.h:314
bool file_created
Definition: tcpip.h:310
intrusive_list< tcpip >::iterator it
Definition: tcpip.h:324
@ dir_cs
Definition: tcpip.h:280
void close_file()
Definition: tcpip.cpp:128
be13::tcp_seq isn
Definition: tcpip.h:300
be13::tcp_seq nsn
Definition: tcpip.h:301
virtual ~tcpip()
Definition: tcpip.cpp:103
void print_packet(const u_char *data, uint32_t length)
Definition: tcpip.cpp:243
std::string flow_index_pathname
Definition: tcpip.h:313
static bool compare(std::string a, std::string b)
Definition: tcpip.cpp:613
#define O_BINARY
static int debug
uint32_t tcp_seq
dfxml_writer * xreport
Definition: tcpflow.cpp:242
const char * progname
Definition: tcpflow.cpp:70
#define SEEK_SET
Definition: tcpflow.h:202
std::string macaddr(const uint8_t *addr)
Definition: util.cpp:61
#define DEBUG(message_level)
Definition: tcpflow.h:273
void update_seen(recon_set *seen, uint64_t pos, uint32_t length)
Definition: tcpip.cpp:454
static int shift_file(int fd, size_t inslen)
Definition: tcpip.cpp:425