mirror of
https://github.com/mfontanini/libtins
synced 2026-01-28 12:44:25 +01:00
Compare commits
31 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f46dee9f19 | ||
|
|
5b082a82b2 | ||
|
|
07012648fb | ||
|
|
ce409dbc7e | ||
|
|
16e77146ab | ||
|
|
a87c4a64f5 | ||
|
|
9e61286a59 | ||
|
|
8da102fb48 | ||
|
|
750c3556d9 | ||
|
|
28663b0e93 | ||
|
|
731e36e373 | ||
|
|
608b48f25c | ||
|
|
de247fcbc8 | ||
|
|
7bc4d38470 | ||
|
|
a926b75224 | ||
|
|
064439236c | ||
|
|
0c40a0714b | ||
|
|
d74520768b | ||
|
|
3385df9cc9 | ||
|
|
18c31b20f5 | ||
|
|
7387912ca1 | ||
|
|
0d52763a61 | ||
|
|
86b505f998 | ||
|
|
62a803c55c | ||
|
|
0573808aeb | ||
|
|
22b4435c81 | ||
|
|
b803959e11 | ||
|
|
2f16497bf8 | ||
|
|
78aa7d1787 | ||
|
|
ba2216e6e9 | ||
|
|
74e3d909e6 |
20
CHANGES.md
20
CHANGES.md
@@ -1,3 +1,23 @@
|
|||||||
|
##### v4.3 - Fri Sep 18 03:08:33 UTC 2020
|
||||||
|
|
||||||
|
- Assign a PDUType to `Dot11ControlTA` (#420)
|
||||||
|
|
||||||
|
- Don't consider IPv6 ESP header a normal extension header (#374)
|
||||||
|
|
||||||
|
- Don't include non-existing headers when installed without libpcap (#382)
|
||||||
|
|
||||||
|
- Add `IPv6Address::is_local_unicast` (#369)
|
||||||
|
|
||||||
|
- Fix memory leak in `PacketWriter` (#343)
|
||||||
|
|
||||||
|
- Fix memory leaks in `OfflinePacketFilter` (#343)
|
||||||
|
|
||||||
|
- Fix detection of new TCP stream (#335)
|
||||||
|
|
||||||
|
- Introduce `TCP::has_flags` (#334)
|
||||||
|
|
||||||
|
- Fix padding calculations in RadioTapWriter (#333)
|
||||||
|
|
||||||
##### v4.2 - Fri Mar 8 04:15:13 UTC 2019
|
##### v4.2 - Fri Mar 8 04:15:13 UTC 2019
|
||||||
|
|
||||||
- Updated location of installed CMake files in unix systems (#331)
|
- Updated location of installed CMake files in unix systems (#331)
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ ENDIF(LIBTINS_BUILD_SHARED)
|
|||||||
|
|
||||||
# The version number.
|
# The version number.
|
||||||
SET(TINS_VERSION_MAJOR 4)
|
SET(TINS_VERSION_MAJOR 4)
|
||||||
SET(TINS_VERSION_MINOR 2)
|
SET(TINS_VERSION_MINOR 3)
|
||||||
SET(TINS_VERSION_PATCH 0)
|
SET(TINS_VERSION_PATCH 0)
|
||||||
SET(LIBTINS_VERSION "${TINS_VERSION_MAJOR}.${TINS_VERSION_MINOR}")
|
SET(LIBTINS_VERSION "${TINS_VERSION_MAJOR}.${TINS_VERSION_MINOR}")
|
||||||
|
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ bool Scanner::callback(PDU& pdu) {
|
|||||||
cout << "Port: " << setw(5) << tcp.sport() << " closed\n";
|
cout << "Port: " << setw(5) << tcp.sport() << " closed\n";
|
||||||
}
|
}
|
||||||
// Is SYN flag on? Then port is open!
|
// 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";
|
cout << "Port: " << setw(5) << tcp.sport() << " open\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ private:
|
|||||||
const IP& ip = pdu.rfind_pdu<IP>();
|
const IP& ip = pdu.rfind_pdu<IP>();
|
||||||
const TCP& tcp = pdu.rfind_pdu<TCP>();
|
const TCP& tcp = pdu.rfind_pdu<TCP>();
|
||||||
// We'll only close a connection when seeing a SYN|ACK
|
// 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
|
// Create an ethernet header flipping the addresses
|
||||||
EthernetII packet(eth.src_addr(), eth.dst_addr());
|
EthernetII packet(eth.src_addr(), eth.dst_addr());
|
||||||
// Do the same for IP
|
// Do the same for IP
|
||||||
|
|||||||
@@ -97,6 +97,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
class TINS_API Dot11ControlTA : public Dot11Control {
|
class TINS_API Dot11ControlTA : public Dot11Control {
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* \brief This PDU's flag.
|
||||||
|
*/
|
||||||
|
static const PDU::PDUType pdu_flag = PDU::DOT11_CONTROL_TA;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Getter for the target address field.
|
* \brief Getter for the target address field.
|
||||||
*/
|
*/
|
||||||
@@ -109,6 +114,15 @@ public:
|
|||||||
* \param addr The new target address.
|
* \param addr The new target address.
|
||||||
*/
|
*/
|
||||||
void target_addr(const address_type& addr);
|
void target_addr(const address_type& addr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Check whether this PDU matches the specified flag.
|
||||||
|
* \param flag The flag to match
|
||||||
|
* \sa PDU::matches_flag
|
||||||
|
*/
|
||||||
|
bool matches_flag(PDUType flag) const {
|
||||||
|
return flag == pdu_flag || Dot11::matches_flag(flag);
|
||||||
|
}
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* \brief Constructor for creating a 802.11 control frame TA PDU
|
* \brief Constructor for creating a 802.11 control frame TA PDU
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ public:
|
|||||||
|
|
||||||
addr_list_type(const addresses_type& addresses = addresses_type())
|
addr_list_type(const addresses_type& addresses = addresses_type())
|
||||||
: addresses(addresses) {
|
: addresses(addresses) {
|
||||||
std::fill(reserved, reserved + sizeof(reserved), 0);
|
std::fill(reserved, reserved + sizeof(reserved), static_cast<uint8_t>(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
static addr_list_type from_option(const option& opt);
|
static addr_list_type from_option(const option& opt);
|
||||||
@@ -199,7 +199,7 @@ public:
|
|||||||
|
|
||||||
naack_type(uint8_t code = 0, uint8_t status = 0)
|
naack_type(uint8_t code = 0, uint8_t status = 0)
|
||||||
: code(code), status(status) {
|
: code(code), status(status) {
|
||||||
std::fill(reserved, reserved + 4, 0);
|
std::fill(reserved, reserved + 4, static_cast<uint8_t>(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
static naack_type from_option(const option& opt);
|
static naack_type from_option(const option& opt);
|
||||||
@@ -323,7 +323,7 @@ public:
|
|||||||
* The key_hash member will be 0-initialized.
|
* The key_hash member will be 0-initialized.
|
||||||
*/
|
*/
|
||||||
rsa_sign_type() {
|
rsa_sign_type() {
|
||||||
std::fill(key_hash, key_hash + sizeof(key_hash), 0);
|
std::fill(key_hash, key_hash + sizeof(key_hash), static_cast<uint8_t>(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
static rsa_sign_type from_option(const option& opt);
|
static rsa_sign_type from_option(const option& opt);
|
||||||
@@ -489,7 +489,7 @@ public:
|
|||||||
|
|
||||||
timestamp_type(uint64_t timestamp = 0)
|
timestamp_type(uint64_t timestamp = 0)
|
||||||
: timestamp(timestamp) {
|
: timestamp(timestamp) {
|
||||||
std::fill(reserved, reserved + sizeof(reserved), 0);
|
std::fill(reserved, reserved + sizeof(reserved), static_cast<uint8_t>(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
static timestamp_type from_option(const option& opt);
|
static timestamp_type from_option(const option& opt);
|
||||||
|
|||||||
@@ -174,9 +174,9 @@ public:
|
|||||||
option_identifier(OptionNumber number, OptionClass op_class,
|
option_identifier(OptionNumber number, OptionClass op_class,
|
||||||
small_uint<1> copied)
|
small_uint<1> copied)
|
||||||
#if TINS_IS_LITTLE_ENDIAN
|
#if TINS_IS_LITTLE_ENDIAN
|
||||||
: number(number), op_class(op_class), copied(copied) {}
|
: number(static_cast<uint8_t>(number)), op_class(static_cast<uint8_t>(op_class)), copied(copied) {}
|
||||||
#else
|
#else
|
||||||
: copied(copied), op_class(op_class), number(number) {}
|
: copied(copied), op_class(static_cast<uint8_t>(op_class)), number(static_cast<uint8_t>(number)) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -230,6 +230,14 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool is_multicast() const;
|
bool is_multicast() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Return true if this is a Link-Local unicast IPv6 address.
|
||||||
|
*
|
||||||
|
* This method returns true if this address is in the address range
|
||||||
|
* fe80::/10, false otherwise
|
||||||
|
*/
|
||||||
|
bool is_local_unicast() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Returns the size of an IPv6 Address.
|
* \brief Returns the size of an IPv6 Address.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -236,7 +236,7 @@ public:
|
|||||||
* \return The LLC frame format.
|
* \return The LLC frame format.
|
||||||
*/
|
*/
|
||||||
uint8_t type() {
|
uint8_t type() {
|
||||||
return type_;
|
return static_cast<uint8_t>(type_);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -245,7 +245,7 @@ public:
|
|||||||
* \return The sender send sequence number if format is INFORMATION else 0.
|
* \return The sender send sequence number if format is INFORMATION else 0.
|
||||||
*/
|
*/
|
||||||
uint8_t send_seq_number() {
|
uint8_t send_seq_number() {
|
||||||
return (type() == INFORMATION) ? (control_field.info.send_seq_num) : 0;
|
return static_cast<uint8_t>((type() == INFORMATION) ? (control_field.info.send_seq_num) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -179,6 +179,7 @@ public:
|
|||||||
IPSEC_ESP,
|
IPSEC_ESP,
|
||||||
PKTAP,
|
PKTAP,
|
||||||
MPLS,
|
MPLS,
|
||||||
|
DOT11_CONTROL_TA,
|
||||||
UNKNOWN = 999,
|
UNKNOWN = 999,
|
||||||
USER_DEFINED_PDU = 1000
|
USER_DEFINED_PDU = 1000
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -288,7 +288,7 @@ public:
|
|||||||
* \code
|
* \code
|
||||||
* TCP tcp = ...;
|
* TCP tcp = ...;
|
||||||
* if(tcp.flags() == (TCP::SYN | TCP::ACK)) {
|
* if(tcp.flags() == (TCP::SYN | TCP::ACK)) {
|
||||||
* // It's a SYN+ACK!
|
* // It's a SYN+ACK, but not SYN+ACK+ECN!
|
||||||
* }
|
* }
|
||||||
* \endcode
|
* \endcode
|
||||||
*
|
*
|
||||||
@@ -296,6 +296,22 @@ public:
|
|||||||
*/
|
*/
|
||||||
small_uint<12> flags() const;
|
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 */
|
/* Setters */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -49,16 +49,19 @@
|
|||||||
#include <tins/ipv6.h>
|
#include <tins/ipv6.h>
|
||||||
#include <tins/mpls.h>
|
#include <tins/mpls.h>
|
||||||
#include <tins/packet_sender.h>
|
#include <tins/packet_sender.h>
|
||||||
#include <tins/packet_writer.h>
|
|
||||||
#include <tins/pdu.h>
|
#include <tins/pdu.h>
|
||||||
#include <tins/radiotap.h>
|
#include <tins/radiotap.h>
|
||||||
#include <tins/rawpdu.h>
|
#include <tins/rawpdu.h>
|
||||||
#include <tins/snap.h>
|
#include <tins/snap.h>
|
||||||
#include <tins/sniffer.h>
|
|
||||||
#include <tins/tcp.h>
|
#include <tins/tcp.h>
|
||||||
#include <tins/udp.h>
|
#include <tins/udp.h>
|
||||||
#include <tins/utils.h>
|
#include <tins/utils.h>
|
||||||
|
#if defined(TINS_HAVE_PCAP)
|
||||||
|
#include <tins/packet_writer.h>
|
||||||
|
#include <tins/sniffer.h>
|
||||||
|
#include <tins/ppi.h>
|
||||||
#include <tins/tcp_stream.h>
|
#include <tins/tcp_stream.h>
|
||||||
|
#endif
|
||||||
#include <tins/crypto.h>
|
#include <tins/crypto.h>
|
||||||
#include <tins/pdu_cacher.h>
|
#include <tins/pdu_cacher.h>
|
||||||
#include <tins/rsn_information.h>
|
#include <tins/rsn_information.h>
|
||||||
@@ -75,7 +78,7 @@
|
|||||||
#include <tins/pdu_allocator.h>
|
#include <tins/pdu_allocator.h>
|
||||||
#include <tins/ipsec.h>
|
#include <tins/ipsec.h>
|
||||||
#include <tins/ip_reassembler.h>
|
#include <tins/ip_reassembler.h>
|
||||||
#include <tins/ppi.h>
|
|
||||||
#include <tins/pdu_iterator.h>
|
#include <tins/pdu_iterator.h>
|
||||||
|
|
||||||
#endif // TINS_TINS_H
|
#endif // TINS_TINS_H
|
||||||
|
|||||||
@@ -204,8 +204,8 @@ IPv6::IPv6(const uint8_t* buffer, uint32_t total_sz) {
|
|||||||
bool IPv6::is_extension_header(uint8_t header_id) {
|
bool IPv6::is_extension_header(uint8_t header_id) {
|
||||||
return header_id == HOP_BY_HOP || header_id == DESTINATION_ROUTING_OPTIONS
|
return header_id == HOP_BY_HOP || header_id == DESTINATION_ROUTING_OPTIONS
|
||||||
|| header_id == ROUTING || header_id == FRAGMENT || header_id == AUTHENTICATION
|
|| header_id == ROUTING || header_id == FRAGMENT || header_id == AUTHENTICATION
|
||||||
|| header_id == SECURITY_ENCAPSULATION || header_id == DESTINATION_OPTIONS
|
|| header_id == DESTINATION_OPTIONS || header_id == MOBILITY
|
||||||
|| header_id == MOBILITY || header_id == NO_NEXT_HEADER;
|
|| header_id == NO_NEXT_HEADER;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t IPv6::get_padding_size(const ext_header& header) {
|
uint32_t IPv6::get_padding_size(const ext_header& header) {
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ namespace Tins {
|
|||||||
|
|
||||||
const IPv6Address loopback_address = "::1";
|
const IPv6Address loopback_address = "::1";
|
||||||
const AddressRange<IPv6Address> multicast_range = IPv6Address("ff00::") / 8;
|
const AddressRange<IPv6Address> multicast_range = IPv6Address("ff00::") / 8;
|
||||||
|
const AddressRange<IPv6Address> local_unicast_range = IPv6Address("fe80::") / 10;
|
||||||
|
|
||||||
IPv6Address IPv6Address::from_prefix_length(uint32_t prefix_length) {
|
IPv6Address IPv6Address::from_prefix_length(uint32_t prefix_length) {
|
||||||
IPv6Address address;
|
IPv6Address address;
|
||||||
@@ -138,6 +139,10 @@ bool IPv6Address::is_multicast() const {
|
|||||||
return multicast_range.contains(*this);
|
return multicast_range.contains(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IPv6Address::is_local_unicast() const {
|
||||||
|
return local_unicast_range.contains(*this);
|
||||||
|
}
|
||||||
|
|
||||||
ostream& operator<<(ostream& os, const IPv6Address& addr) {
|
ostream& operator<<(ostream& os, const IPv6Address& addr) {
|
||||||
return os << addr.to_string();
|
return os << addr.to_string();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,11 +37,14 @@ using std::string;
|
|||||||
namespace Tins {
|
namespace Tins {
|
||||||
|
|
||||||
OfflinePacketFilter::OfflinePacketFilter(const OfflinePacketFilter& other) {
|
OfflinePacketFilter::OfflinePacketFilter(const OfflinePacketFilter& other) {
|
||||||
*this = other;
|
string_filter_ = other.string_filter_;
|
||||||
|
init(string_filter_, pcap_datalink(other.handle_), pcap_snapshot(other.handle_));
|
||||||
}
|
}
|
||||||
|
|
||||||
OfflinePacketFilter& OfflinePacketFilter::operator=(const OfflinePacketFilter& other) {
|
OfflinePacketFilter& OfflinePacketFilter::operator=(const OfflinePacketFilter& other) {
|
||||||
string_filter_ = other.string_filter_;
|
string_filter_ = other.string_filter_;
|
||||||
|
pcap_freecode(&filter_);
|
||||||
|
pcap_close(handle_);
|
||||||
init(string_filter_, pcap_datalink(other.handle_), pcap_snapshot(other.handle_));
|
init(string_filter_, pcap_datalink(other.handle_), pcap_snapshot(other.handle_));
|
||||||
return* this;
|
return* this;
|
||||||
}
|
}
|
||||||
@@ -58,8 +61,14 @@ void OfflinePacketFilter::init(const string& pcap_filter,
|
|||||||
link_type,
|
link_type,
|
||||||
snap_len
|
snap_len
|
||||||
);
|
);
|
||||||
|
if (!handle_) {
|
||||||
|
throw pcap_open_failed();
|
||||||
|
}
|
||||||
if (pcap_compile(handle_, &filter_, pcap_filter.c_str(), 1, 0xffffffff) == -1) {
|
if (pcap_compile(handle_, &filter_, pcap_filter.c_str(), 1, 0xffffffff) == -1) {
|
||||||
throw invalid_pcap_filter(pcap_geterr(handle_));
|
string error(pcap_geterr(handle_));
|
||||||
|
pcap_freecode(&filter_);
|
||||||
|
pcap_close(handle_);
|
||||||
|
throw invalid_pcap_filter(error.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -86,8 +86,9 @@ void PacketWriter::init(const string& file_name, int link_type) {
|
|||||||
}
|
}
|
||||||
dumper_ = pcap_dump_open(handle_, file_name.c_str());
|
dumper_ = pcap_dump_open(handle_, file_name.c_str());
|
||||||
if (!dumper_) {
|
if (!dumper_) {
|
||||||
|
string error(pcap_geterr(handle_));
|
||||||
pcap_close(handle_);
|
pcap_close(handle_);
|
||||||
throw pcap_error(pcap_geterr(handle_));
|
throw pcap_error(error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -257,6 +257,10 @@ small_uint<12> TCP::flags() const {
|
|||||||
return (header_.res1 << 8) | header_.flags_8;
|
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) {
|
void TCP::set_flag(Flags tcp_flag, small_uint<1> value) {
|
||||||
switch (tcp_flag) {
|
switch (tcp_flag) {
|
||||||
case FIN:
|
case FIN:
|
||||||
|
|||||||
@@ -127,19 +127,19 @@ void Flow::advance_sequence(uint32_t seq) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Flow::update_state(const TCP& tcp) {
|
void Flow::update_state(const TCP& tcp) {
|
||||||
if ((tcp.flags() & TCP::FIN) != 0) {
|
if (tcp.has_flags(TCP::FIN)) {
|
||||||
state_ = FIN_SENT;
|
state_ = FIN_SENT;
|
||||||
}
|
}
|
||||||
else if ((tcp.flags() & TCP::RST) != 0) {
|
else if (tcp.has_flags(TCP::RST)) {
|
||||||
state_ = RST_SENT;
|
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
|
#ifdef TINS_HAVE_ACK_TRACKER
|
||||||
ack_tracker_ = AckTracker(tcp.ack_seq());
|
ack_tracker_ = AckTracker(tcp.ack_seq());
|
||||||
#endif // TINS_HAVE_ACK_TRACKER
|
#endif // TINS_HAVE_ACK_TRACKER
|
||||||
state_ = ESTABLISHED;
|
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
|
// This is the server's state, sending it's first SYN|ACK
|
||||||
#ifdef TINS_HAVE_ACK_TRACKER
|
#ifdef TINS_HAVE_ACK_TRACKER
|
||||||
ack_tracker_ = AckTracker(tcp.ack_seq());
|
ack_tracker_ = AckTracker(tcp.ack_seq());
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ Stream::Stream(PDU& packet, const timestamp_type& ts)
|
|||||||
}
|
}
|
||||||
const TCP& tcp = packet.rfind_pdu<TCP>();
|
const TCP& tcp = packet.rfind_pdu<TCP>();
|
||||||
// If this is not the first packet of a stream (SYN), then it's a partial stream
|
// 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) {
|
void Stream::process_packet(PDU& packet, const timestamp_type& ts) {
|
||||||
|
|||||||
@@ -84,7 +84,9 @@ void StreamFollower::process_packet(PDU& packet, const timestamp_type& ts) {
|
|||||||
if (iter == streams_.end()) {
|
if (iter == streams_.end()) {
|
||||||
// Start tracking if they're either SYNs or they contain data (attach
|
// Start tracking if they're either SYNs or they contain data (attach
|
||||||
// to an already running flow).
|
// to an already running flow).
|
||||||
if (tcp->flags() == TCP::SYN || (attach_to_flows_ && tcp->find_pdu<RawPDU>() != 0)) {
|
// Start on client's SYN, not on server's SYN+ACK
|
||||||
|
const bool is_syn = tcp->has_flags(TCP::SYN) && !tcp->has_flags(TCP::ACK);
|
||||||
|
if (is_syn || (attach_to_flows_ && tcp->find_pdu<RawPDU>() != 0)) {
|
||||||
iter = streams_.insert(make_pair(identifier, Stream(packet, ts))).first;
|
iter = streams_.insert(make_pair(identifier, Stream(packet, ts))).first;
|
||||||
iter->second.setup_flows_callbacks();
|
iter->second.setup_flows_callbacks();
|
||||||
if (on_new_connection_) {
|
if (on_new_connection_) {
|
||||||
@@ -93,7 +95,7 @@ void StreamFollower::process_packet(PDU& packet, const timestamp_type& ts) {
|
|||||||
else {
|
else {
|
||||||
throw callback_not_set();
|
throw callback_not_set();
|
||||||
}
|
}
|
||||||
if (tcp->flags() != TCP::SYN) {
|
if (!is_syn) {
|
||||||
// assume the connection is established
|
// assume the connection is established
|
||||||
iter->second.client_flow().state(Flow::ESTABLISHED);
|
iter->second.client_flow().state(Flow::ESTABLISHED);
|
||||||
iter->second.server_flow().state(Flow::ESTABLISHED);
|
iter->second.server_flow().state(Flow::ESTABLISHED);
|
||||||
|
|||||||
@@ -230,7 +230,7 @@ bool TCPStream::generic_process(uint32_t& my_seq,
|
|||||||
|
|
||||||
bool TCPStream::update(IP* ip, TCP* tcp) {
|
bool TCPStream::update(IP* ip, TCP* tcp) {
|
||||||
if (!syn_ack_sent_) {
|
if (!syn_ack_sent_) {
|
||||||
if (tcp->flags() == (TCP::SYN | TCP::ACK)) {
|
if (tcp->has_flags(TCP::SYN | TCP::ACK)) {
|
||||||
server_seq_ = tcp->seq() + 1;
|
server_seq_ = tcp->seq() + 1;
|
||||||
client_seq_ = tcp->ack_seq();
|
client_seq_ = tcp->ack_seq();
|
||||||
syn_ack_sent_ = true;
|
syn_ack_sent_ = true;
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ struct RadioTapFlags {
|
|||||||
} TINS_END_PACK;
|
} TINS_END_PACK;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void align_buffer(const uint8_t* buffer_start, const uint8_t*& buffer, uint32_t size, size_t n) {
|
void align_buffer(const uint8_t* buffer_start, const uint8_t*& buffer, size_t n) {
|
||||||
uint32_t offset = (buffer - buffer_start) & (n - 1);
|
uint32_t offset = (buffer - buffer_start) & (n - 1);
|
||||||
if (offset) {
|
if (offset) {
|
||||||
offset = n - offset;
|
offset = n - offset;
|
||||||
@@ -278,7 +278,7 @@ bool RadioTapParser::advance_to_next_field() {
|
|||||||
if (current_bit_ < MAX_RADIOTAP_FIELD) {
|
if (current_bit_ < MAX_RADIOTAP_FIELD) {
|
||||||
const uint8_t* radiotap_start = start_ - sizeof(uint32_t);
|
const uint8_t* radiotap_start = start_ - sizeof(uint32_t);
|
||||||
// Skip and align the buffer
|
// Skip and align the buffer
|
||||||
align_buffer(radiotap_start, current_ptr_, end_ - radiotap_start,
|
align_buffer(radiotap_start, current_ptr_,
|
||||||
RADIOTAP_METADATA[current_bit_].alignment);
|
RADIOTAP_METADATA[current_bit_].alignment);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,11 +41,12 @@ namespace Tins {
|
|||||||
namespace Utils {
|
namespace Utils {
|
||||||
|
|
||||||
uint32_t calculate_padding(uint32_t alignment, uint32_t offset) {
|
uint32_t calculate_padding(uint32_t alignment, uint32_t offset) {
|
||||||
return offset % alignment;
|
uint32_t extra = offset % alignment;
|
||||||
|
return extra == 0 ? 0 : alignment - extra;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t get_bit(uint32_t value) {
|
uint32_t get_bit(uint32_t value) {
|
||||||
return log(value) / log(2);
|
return round(log2(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
RadioTapWriter::RadioTapWriter(vector<uint8_t>& buffer)
|
RadioTapWriter::RadioTapWriter(vector<uint8_t>& buffer)
|
||||||
@@ -54,7 +55,7 @@ RadioTapWriter::RadioTapWriter(vector<uint8_t>& buffer)
|
|||||||
|
|
||||||
void RadioTapWriter::write_option(const RadioTap::option& option) {
|
void RadioTapWriter::write_option(const RadioTap::option& option) {
|
||||||
const uint32_t bit = get_bit(option.option());
|
const uint32_t bit = get_bit(option.option());
|
||||||
if (bit > RadioTapParser::MAX_RADIOTAP_FIELD) {
|
if (bit >= RadioTapParser::MAX_RADIOTAP_FIELD) {
|
||||||
throw malformed_option();
|
throw malformed_option();
|
||||||
}
|
}
|
||||||
const bool is_empty = buffer_.empty();
|
const bool is_empty = buffer_.empty();
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ private:
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void ActiveTestRunner::add_test() {
|
void ActiveTestRunner::add_test() {
|
||||||
tests_.emplace_back(new T(packet_sender_, configuration_));
|
tests_.emplace_back(std::unique_ptr<T>(new T(packet_sender_, configuration_)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // TINS_ACTIVE_TEST_RUNNER_H
|
#endif // TINS_ACTIVE_TEST_RUNNER_H
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ const uint8_t DHCPTest::expected_packet[] = {
|
|||||||
TEST_F(DHCPTest, DefaultConstructor) {
|
TEST_F(DHCPTest, DefaultConstructor) {
|
||||||
DHCP dhcp;
|
DHCP dhcp;
|
||||||
EXPECT_EQ(dhcp.htype(), 1);
|
EXPECT_EQ(dhcp.htype(), 1);
|
||||||
EXPECT_EQ(dhcp.hlen(), (const size_t)EthernetII::address_type::address_size);
|
EXPECT_EQ(dhcp.hlen(), (size_t)EthernetII::address_type::address_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(DHCPTest, CopyConstructor) {
|
TEST_F(DHCPTest, CopyConstructor) {
|
||||||
@@ -280,7 +280,7 @@ TEST_F(DHCPTest, ConstructorFromBuffer) {
|
|||||||
|
|
||||||
EXPECT_EQ(dhcp1.opcode(), DHCP::DISCOVER);
|
EXPECT_EQ(dhcp1.opcode(), DHCP::DISCOVER);
|
||||||
EXPECT_EQ(dhcp1.htype(), 1);
|
EXPECT_EQ(dhcp1.htype(), 1);
|
||||||
ASSERT_EQ(dhcp1.hlen(), (const size_t)EthernetII::address_type::address_size);
|
ASSERT_EQ(dhcp1.hlen(), (size_t)EthernetII::address_type::address_size);
|
||||||
EXPECT_EQ(dhcp1.hops(), 0x1f);
|
EXPECT_EQ(dhcp1.hops(), 0x1f);
|
||||||
EXPECT_EQ(dhcp1.xid(), 0x3fab23deU);
|
EXPECT_EQ(dhcp1.xid(), 0x3fab23deU);
|
||||||
EXPECT_EQ(dhcp1.secs(), 0x9f1a);
|
EXPECT_EQ(dhcp1.secs(), 0x9f1a);
|
||||||
|
|||||||
@@ -759,4 +759,27 @@ TEST_F(RadioTapTest, RadioTapWritingEmptyBuffer) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(RadioTapTest, RadioTapWritingInvalidOption) {
|
||||||
|
vector<uint8_t> buffer(4, 0);
|
||||||
|
RadioTapWriter writer(buffer);
|
||||||
|
uint8_t foo = 0;
|
||||||
|
RadioTap::option option((RadioTap::PresentFlags)(1 << RadioTapParser::MAX_RADIOTAP_FIELD), sizeof(foo), &foo);
|
||||||
|
EXPECT_THROW(writer.write_option(option), malformed_option);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RadioTapTest, RadioTapWriterAlignment) {
|
||||||
|
vector<uint8_t> buffer(4, 0);
|
||||||
|
RadioTapWriter writer(buffer);
|
||||||
|
uint8_t flags = 10;
|
||||||
|
uint8_t xchannel[sizeof(RadioTap::xchannel_type)] = {
|
||||||
|
1, 2, 3, 4, 5, 6, 7, 8
|
||||||
|
};
|
||||||
|
writer.write_option(RadioTap::option(RadioTap::FLAGS, sizeof(flags), &flags));
|
||||||
|
writer.write_option(RadioTap::option(RadioTap::XCHANNEL, sizeof(xchannel), xchannel));
|
||||||
|
vector<uint8_t> expected = {
|
||||||
|
2, 0, 4, 0, 10, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8
|
||||||
|
};
|
||||||
|
EXPECT_EQ(buffer, expected);
|
||||||
|
}
|
||||||
|
|
||||||
#endif // TINS_HAVE_DOT11
|
#endif // TINS_HAVE_DOT11
|
||||||
|
|||||||
Reference in New Issue
Block a user