TEST_F(FlowTest, AckNumbersAreCorrect) { using std::placeholders::_1; vector<EthernetII> packets = three_way_handshake(29, 60, "1.2.3.4", 22, "4.3.2.1", 25); // Server's ACK number is 9898 packets[1].rfind_pdu<TCP>().ack_seq(9898); // Client's ACK number is 1717 packets[2].rfind_pdu<TCP>().ack_seq(1717); StreamFollower follower; follower.new_stream_callback(bind(&FlowTest::on_new_stream, this, _1)); for (size_t i = 0; i < packets.size(); ++i) { follower.process_packet(packets[i]); } Stream& stream = follower.find_stream(IPv4Address("1.2.3.4"), 22, IPv4Address("4.3.2.1"), 25); EXPECT_EQ(1717U, stream.client_flow().ack_tracker().ack_number()); EXPECT_EQ(9898U, stream.server_flow().ack_tracker().ack_number()); }
TEST_F(FlowTest, StreamFollower_RSTClosesStream) { using std::placeholders::_1; vector<EthernetII> packets = three_way_handshake(29, 60, "1.2.3.4", 22, "4.3.2.1", 25); StreamFollower follower; follower.new_stream_callback(bind(&FlowTest::on_new_stream, this, _1)); for (size_t i = 0; i < packets.size(); ++i) { follower.process_packet(packets[i]); } Stream stream = follower.find_stream(IPv4Address("1.2.3.4"), 22, IPv4Address("4.3.2.1"), 25); IP server_packet = IP("1.2.3.4", "4.3.2.1") / TCP(22, 25); server_packet.rfind_pdu<TCP>().flags(TCP::RST); stream.process_packet(server_packet); EXPECT_EQ(Flow::RST_SENT, stream.server_flow().state()); EXPECT_TRUE(stream.is_finished()); }
TEST_F(FlowTest, StreamFollower_TCPOptions) { using std::placeholders::_1; vector<EthernetII> packets = three_way_handshake(29, 60, "1.2.3.4", 22, "4.3.2.1", 25); // Client's mss is 1220 packets[0].rfind_pdu<TCP>().mss(1220); // Server's mss is 1460 packets[1].rfind_pdu<TCP>().mss(1460); // Server supports SACK packets[1].rfind_pdu<TCP>().sack_permitted(); StreamFollower follower; follower.new_stream_callback(bind(&FlowTest::on_new_stream, this, _1)); for (size_t i = 0; i < packets.size(); ++i) { follower.process_packet(packets[i]); } Stream& stream = follower.find_stream(IPv4Address("1.2.3.4"), 22, IPv4Address("4.3.2.1"), 25); EXPECT_EQ(1220, stream.client_flow().mss()); EXPECT_EQ(1460, stream.server_flow().mss()); EXPECT_FALSE(stream.client_flow().sack_permitted()); EXPECT_TRUE(stream.server_flow().sack_permitted()); }
int main(int argc, char* argv[]) { if (argc != 2) { cout << "Usage: " << argv[0] << " <interface>" << endl; return 1; } try { // Construct the sniffer configuration object SnifferConfiguration config; // Get packets as quickly as possible config.set_immediate_mode(true); // Only capture TCP traffic sent from/to port 80 config.set_filter("tcp port 80"); // Construct the sniffer we'll use Sniffer sniffer(argv[1], config); cout << "Starting capture on interface " << argv[1] << endl; // Now construct the stream follower StreamFollower follower; // We just need to specify the callback to be executed when a new // stream is captured. In this stream, you should define which callbacks // will be executed whenever new data is sent on that stream // (see on_new_connection) follower.new_stream_callback(&on_new_connection); // Now start capturing. Every time there's a new packet, call // follower.process_packet sniffer.sniff_loop([&](PDU& packet) { follower.process_packet(packet); return true; }); } catch (exception& ex) { cerr << "Error: " << ex.what() << endl; return 1; } }