diff --git a/src/flow.cpp b/src/flow.cpp index ed9ddb51..5a8f093d 100644 --- a/src/flow.cpp +++ b/src/flow.cpp @@ -42,6 +42,7 @@ void flow::usage() std::cout << " %K - (connection_number / 1000) % 1000\n"; std::cout << " %M - (connection_number / 1000000) % 1000\n"; std::cout << " %G - (connection_number / 1000000000) % 1000\n"; + std::cout << " %S - session ID\n"; std::cout << " %% - Output a '%'\n"; std::cout << "\n"; std::cout << "Default value is: '"<< flow::filename_template <<"'\n"; @@ -135,6 +136,9 @@ std::string flow::filename(uint32_t connection_count, bool is_pcap) case 'c': // connection_count if connection_count >0 if(connection_count>0) ss << connection_count; break; + case 'S': // session ID + ss << std::setfill('0') << std::setw(20) << session_id; + break; case '#': // always output connection count ss << connection_count; break; diff --git a/src/tcpdemux.cpp b/src/tcpdemux.cpp index 071485f6..95534b0d 100644 --- a/src/tcpdemux.cpp +++ b/src/tcpdemux.cpp @@ -37,7 +37,7 @@ tcpdemux::tcpdemux(): outdir("."),flow_counter(0),packet_counter(0), xreport(0),pwriter(0),max_open_flows(),max_fds(get_max_fds()-NUM_RESERVED_FDS), flow_map(),open_flows(),saved_flow_map(),flow_fd_cache_map(0), - saved_flows(),start_new_connections(false),opt(),fs() + saved_flows(),start_new_connections(false),opt(),fs(),unique_id(0) { tcp_processor = &tcpdemux::process_tcp; } @@ -553,12 +553,28 @@ int tcpdemux::process_tcp(const ipaddr &src, const ipaddr &dst,sa_family_t famil /* Don't process if this is not a SYN and there is no data. */ if(syn_set==false && tcp_datalen==0) return 0; + + /* Check if this is the server->client flow related to a client->server flow that is being demultiplexed */ + flow_addr reverse_flow(dst,src,ntohs(tcp_header->th_dport),ntohs(tcp_header->th_sport),family); + tcpip *reverse_tcp = find_tcpip(reverse_flow); + uint64_t uid; + if (reverse_tcp) + { + /* We found a matching client->server flow. Copy its session ID */ + uid = reverse_tcp->myflow.session_id; + } + else + { + /* Assign a new unique ID */ + uid = unique_id++; + } /* Create a new connection. * delta will be 0, because it's a new connection! */ be13::tcp_seq isn = syn_set ? seq : seq-1; tcp = create_tcpip(this_flow, isn, pi); + tcp->myflow.session_id = uid; } /* Now tcp is valid */ diff --git a/src/tcpdemux.h b/src/tcpdemux.h index 7d81d1c4..9afdc0d9 100644 --- a/src/tcpdemux.h +++ b/src/tcpdemux.h @@ -138,6 +138,7 @@ class tcpdemux { pcap_writer *pwriter; // where we should write packets unsigned int max_open_flows; // how large did it ever get? unsigned int max_fds; // maximum number of file descriptors for this tcpdemux + uint64_t unique_id; // next unique id to assign flow_map_t flow_map; // db of open tcpip objects, indexed by flow intrusive_list open_flows; // the tcpip flows with open files in access order diff --git a/src/tcpip.h b/src/tcpip.h index b24d6437..de1d79a9 100644 --- a/src/tcpip.h +++ b/src/tcpip.h @@ -182,6 +182,7 @@ public:; uint64_t len; // off-wire length uint64_t caplen; // captured length uint64_t packet_count; // packet count + uint64_t session_id; // session unique id (used to match client->server and server->client flows // return a filename for a flow based on the template and the connection count std::string filename(uint32_t connection_count, bool);