Skip to content

simplify tcp flag checks, fix stream_follower #334

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 15, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/portscan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ bool Scanner::callback(PDU& pdu) {
cout << "Port: " << setw(5) << tcp.sport() << " closed\n";
}
// Is SYN flag on? Then port is open!
else if(tcp.flags() == (TCP::SYN | TCP::ACK)) {
else if(tcp.has_flags(TCP::SYN | TCP::ACK)) {
cout << "Port: " << setw(5) << tcp.sport() << " open\n";
}
}
Expand Down
2 changes: 1 addition & 1 deletion examples/tcp_connection_close.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class tcp_connection_closer {
const IP& ip = pdu.rfind_pdu<IP>();
const TCP& tcp = pdu.rfind_pdu<TCP>();
// We'll only close a connection when seeing a SYN|ACK
if (tcp.flags() == (TCP::SYN | TCP::ACK)) {
if (tcp.has_flags(TCP::SYN | TCP::ACK)) {
// Create an ethernet header flipping the addresses
EthernetII packet(eth.src_addr(), eth.dst_addr());
// Do the same for IP
Expand Down
18 changes: 17 additions & 1 deletion include/tins/tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -288,13 +288,29 @@ class TINS_API TCP : public PDU {
* \code
* TCP tcp = ...;
* if(tcp.flags() == (TCP::SYN | TCP::ACK)) {
* // It's a SYN+ACK!
* // It's a SYN+ACK, but not SYN+ACK+ECN!
* }
* \endcode
*
* \return The value of the flags field.
*/
small_uint<12> flags() const;

/**
* \brief Check if the given flags are set.
*
* \code
* TCP tcp = ...;
* if(tcp.has_flags(TCP::SYN | TCP::ACK)) {
* // It's a SYN+ACK, but it also possible that other flags are set!
* // it is equivalent to: (tpc.flags() & (TCP::SYN | TCP::ACK)) == (TCP::SYN | TCP::ACK)
* }
* \endcode
*
* \param check_flags
* \return true if all check_flags are set
*/
bool has_flags(small_uint<12> check_flags) const;

/* Setters */

Expand Down
4 changes: 4 additions & 0 deletions src/tcp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,10 @@ small_uint<12> TCP::flags() const {
return (header_.res1 << 8) | header_.flags_8;
}

bool TCP::has_flags(small_uint<12> check_flags) const {
return (flags() & check_flags) == check_flags;
}

void TCP::set_flag(Flags tcp_flag, small_uint<1> value) {
switch (tcp_flag) {
case FIN:
Expand Down
8 changes: 4 additions & 4 deletions src/tcp_ip/flow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,19 +127,19 @@ void Flow::advance_sequence(uint32_t seq) {
}

void Flow::update_state(const TCP& tcp) {
if ((tcp.flags() & TCP::FIN) != 0) {
if (tcp.has_flags(TCP::FIN)) {
state_ = FIN_SENT;
}
else if ((tcp.flags() & TCP::RST) != 0) {
else if (tcp.has_flags(TCP::RST)) {
state_ = RST_SENT;
}
else if (state_ == SYN_SENT && (tcp.flags() & TCP::ACK) != 0) {
else if (state_ == SYN_SENT && tcp.has_flags(TCP::ACK)) {
#ifdef TINS_HAVE_ACK_TRACKER
ack_tracker_ = AckTracker(tcp.ack_seq());
#endif // TINS_HAVE_ACK_TRACKER
state_ = ESTABLISHED;
}
else if (state_ == UNKNOWN && (tcp.flags() & TCP::SYN) != 0) {
else if (state_ == UNKNOWN && tcp.has_flags(TCP::SYN)) {
// This is the server's state, sending it's first SYN|ACK
#ifdef TINS_HAVE_ACK_TRACKER
ack_tracker_ = AckTracker(tcp.ack_seq());
Expand Down
2 changes: 1 addition & 1 deletion src/tcp_ip/stream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ Stream::Stream(PDU& packet, const timestamp_type& ts)
}
const TCP& tcp = packet.rfind_pdu<TCP>();
// If this is not the first packet of a stream (SYN), then it's a partial stream
is_partial_stream_ = tcp.flags() != TCP::SYN;
is_partial_stream_ = !tcp.has_flags(TCP::SYN);
}

void Stream::process_packet(PDU& packet, const timestamp_type& ts) {
Expand Down
5 changes: 3 additions & 2 deletions src/tcp_ip/stream_follower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ void StreamFollower::process_packet(PDU& packet, const timestamp_type& ts) {
if (iter == streams_.end()) {
// Start tracking if they're either SYNs or they contain data (attach
// to an already running flow).
if (tcp->flags() == TCP::SYN || (attach_to_flows_ && tcp->find_pdu<RawPDU>() != 0)) {
const bool is_syn = tcp->has_flags(TCP::SYN);
if (is_syn || (attach_to_flows_ && tcp->find_pdu<RawPDU>() != 0)) {
iter = streams_.insert(make_pair(identifier, Stream(packet, ts))).first;
iter->second.setup_flows_callbacks();
if (on_new_connection_) {
Expand All @@ -93,7 +94,7 @@ void StreamFollower::process_packet(PDU& packet, const timestamp_type& ts) {
else {
throw callback_not_set();
}
if (tcp->flags() != TCP::SYN) {
if (!is_syn) {
// assume the connection is established
iter->second.client_flow().state(Flow::ESTABLISHED);
iter->second.server_flow().state(Flow::ESTABLISHED);
Expand Down
2 changes: 1 addition & 1 deletion src/tcp_stream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ bool TCPStream::generic_process(uint32_t& my_seq,

bool TCPStream::update(IP* ip, TCP* tcp) {
if (!syn_ack_sent_) {
if (tcp->flags() == (TCP::SYN | TCP::ACK)) {
if (tcp->has_flags(TCP::SYN | TCP::ACK)) {
server_seq_ = tcp->seq() + 1;
client_seq_ = tcp->ack_seq();
syn_ack_sent_ = true;
Expand Down