mirror of
https://github.com/mfontanini/libtins
synced 2026-01-23 10:45:57 +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 |
70
CHANGES.md
70
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
|
||||
|
||||
- Updated location of installed CMake files in unix systems (#331)
|
||||
@@ -232,7 +252,7 @@
|
||||
|
||||
- Move implementations on utils.h to utils.cpp
|
||||
|
||||
- Add ICMPv6 Multicast Listener Query Messages support
|
||||
- Add ICMPv6 Multicast Listener Query Messages support
|
||||
|
||||
- Add ICMPv6 Multicast Listener Report Message support
|
||||
|
||||
@@ -376,7 +396,7 @@
|
||||
|
||||
- Added RadioTap channel map type
|
||||
|
||||
- Made rsn_information() a const member function to make Dot11ManagementFrame
|
||||
- Made rsn_information() a const member function to make Dot11ManagementFrame
|
||||
immutable
|
||||
|
||||
- Ensure HAVE_CXX11 is checked when defining TINS_IS_CXX11
|
||||
@@ -426,7 +446,7 @@ its value.
|
||||
|
||||
- Removed obsolete autotools files.
|
||||
|
||||
- Fixed exception thrown when an interface didn't have an IP address
|
||||
- Fixed exception thrown when an interface didn't have an IP address
|
||||
on NetworkInterface.
|
||||
|
||||
- Added NetworkInterface::is_loopback.
|
||||
@@ -470,7 +490,7 @@ conversion on integral constant.
|
||||
|
||||
- Added DataLinkType class.
|
||||
|
||||
- IPv4Address now uses inet_pton when constructing from string.
|
||||
- IPv4Address now uses inet_pton when constructing from string.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
@@ -491,8 +511,8 @@ conversion on integral constant.
|
||||
- Packets can now be constructed from a PDU pointer and take ownership
|
||||
of it.
|
||||
|
||||
- All protocols now set the next layer protocol flag, regardless if
|
||||
it was already set. This was not done in some protocols,
|
||||
- All protocols now set the next layer protocol flag, regardless if
|
||||
it was already set. This was not done in some protocols,
|
||||
like EthernetII, and as a consequence if the network layer protocol
|
||||
was replaced by other, the packet would be serialized incorrectly.
|
||||
|
||||
@@ -533,7 +553,7 @@ TCPStreamFollower::follow_streams.
|
||||
|
||||
- Added DHCP::hostname to extract the hostname options.
|
||||
|
||||
- Removed extra qualifier on SessionKeys::decrypt_unicast which
|
||||
- Removed extra qualifier on SessionKeys::decrypt_unicast which
|
||||
produced compilation errors on some platforms.
|
||||
|
||||
- PacketSender::send now uses PDU::matches_flag to match specific
|
||||
@@ -549,9 +569,9 @@ PDU types.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
##### v2.0 - Thu Jan 23 11:09:38 ART 2014
|
||||
##### v2.0 - Thu Jan 23 11:09:38 ART 2014
|
||||
|
||||
- DNSResourceRecord was removed. Now DNS records are added using
|
||||
- DNSResourceRecord was removed. Now DNS records are added using
|
||||
DNS::Resource.
|
||||
|
||||
- tins.h now includes ppi.h.
|
||||
@@ -560,21 +580,21 @@ DNS::Resource.
|
||||
|
||||
- Added PDUOption<>::to<> which converts a PDUOption to a specific type.
|
||||
|
||||
- Layer 3 packets sent using PacketSender::send_recv for which the
|
||||
- Layer 3 packets sent using PacketSender::send_recv for which the
|
||||
answer is a different PDU type.
|
||||
|
||||
- ICMP::gateway now uses IPv4Address.
|
||||
|
||||
- Added support for ICMP address mask request/reply.
|
||||
|
||||
- Fixed bug in PacketSender when using send_recv and a layer 2 PDU. The
|
||||
interface in which the packet was sent was not the default_interface
|
||||
- Fixed bug in PacketSender when using send_recv and a layer 2 PDU. The
|
||||
interface in which the packet was sent was not the default_interface
|
||||
set when the sender was constructed.
|
||||
|
||||
- IP packets sent using PacketSender::send_recv now match ICMP
|
||||
- IP packets sent using PacketSender::send_recv now match ICMP
|
||||
responses.
|
||||
|
||||
- Added support for ICMP timestamp request/reply packets.
|
||||
- Added support for ICMP timestamp request/reply packets.
|
||||
ICMP::matches_response now works with these types of packets as well.
|
||||
|
||||
- Added support for reassembling of fragmented IP packets via the
|
||||
@@ -582,20 +602,20 @@ IPv4Reassembler class.
|
||||
|
||||
- Fragmented IP packet's inner_pdu PDUs are not decoded now.
|
||||
|
||||
- Added 1000ms as the default read timeout used when calling
|
||||
- Added 1000ms as the default read timeout used when calling
|
||||
pcap_open_live. Added BaseSniffer::set_timeout to modify this parameter.
|
||||
|
||||
- Added the --disable-dot11 configure switch.
|
||||
|
||||
- Added support for IPSec.
|
||||
|
||||
- Fixed bug triggered when ifaddrs::ifa_addr was null in
|
||||
- Fixed bug triggered when ifaddrs::ifa_addr was null in
|
||||
NetworkInterface::addresses.
|
||||
|
||||
- Added another overload of Utils::route_entries which returns the
|
||||
result either than storing it in a parameter.
|
||||
|
||||
- Added ARP monitor, WPS detector, DNS queries sniffer and DNS spoofer
|
||||
- Added ARP monitor, WPS detector, DNS queries sniffer and DNS spoofer
|
||||
examples.
|
||||
|
||||
- Added another Sniffer constructor which doesn't expect the maximum
|
||||
@@ -614,10 +634,10 @@ doesn't work well on some linux distributions.
|
||||
|
||||
- Added PPI PDU class.
|
||||
|
||||
- Fixed a bug in EthernetII triggered when the size of the whole frame
|
||||
- Fixed a bug in EthernetII triggered when the size of the whole frame
|
||||
was lower than 60 bytes.
|
||||
|
||||
- Added AddressRange class and IPv4Address, IPv6Address and
|
||||
- Added AddressRange class and IPv4Address, IPv6Address and
|
||||
HWAddress<>::operator/.
|
||||
|
||||
- Added is_broadcast, is_multicast and is_unicast to IPv4, IPv6
|
||||
@@ -627,7 +647,7 @@ and HWAddress.
|
||||
|
||||
- Done some optimizations on TCP's constructor from buffer.
|
||||
|
||||
- Added helper functions to Dot11Data to retrieve the source,
|
||||
- Added helper functions to Dot11Data to retrieve the source,
|
||||
destination and BSSID addresses.
|
||||
|
||||
- Fixed bugs in DNS triggered when parsing MX and unknown records.
|
||||
@@ -647,7 +667,7 @@ types.
|
||||
|
||||
- Added WPA2Decrypter class.
|
||||
|
||||
- IEEE 802.11 frames are not parsed if the RadioTap FAILED_FCS flag
|
||||
- IEEE 802.11 frames are not parsed if the RadioTap FAILED_FCS flag
|
||||
is on.
|
||||
|
||||
- RadioTap now calculates its size everytime it's serialized.
|
||||
@@ -664,13 +684,13 @@ v1.0 - Tue Apr 23 20:40:57 ART 2013
|
||||
- Link layer protocol PDUs now don't hold a NetworkInterface. This led
|
||||
to changes in their constructors.
|
||||
|
||||
- Removed the obsolete PDU* parameter taken by several classes'
|
||||
- Removed the obsolete PDU* parameter taken by several classes'
|
||||
constructors.
|
||||
|
||||
- IP now sets the sender's address automatically when no link layer
|
||||
PDU is used.
|
||||
|
||||
- IP, TCP and UDP now calculate the checksum everytime they're
|
||||
- IP, TCP and UDP now calculate the checksum everytime they're
|
||||
serialized.
|
||||
|
||||
- Added PDU::rfind_pdu.
|
||||
@@ -681,7 +701,7 @@ serialized.
|
||||
|
||||
- PacketSender is now movable.
|
||||
|
||||
- Added an overload of add_option that takes an rvalue-reference in IP,
|
||||
- Added an overload of add_option that takes an rvalue-reference in IP,
|
||||
TCP, DHCP, ICMPv6 and Dot11.
|
||||
|
||||
- Added support for GNU/kFreeBSD.
|
||||
@@ -724,7 +744,7 @@ pseudo protocol.
|
||||
|
||||
##### v0.2 - Sat Oct 20 11:26:40 2012
|
||||
|
||||
- Added support for big endian architectures.
|
||||
- Added support for big endian architectures.
|
||||
|
||||
- Simplified several interfaces.
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ ENDIF(LIBTINS_BUILD_SHARED)
|
||||
|
||||
# The version number.
|
||||
SET(TINS_VERSION_MAJOR 4)
|
||||
SET(TINS_VERSION_MINOR 2)
|
||||
SET(TINS_VERSION_MINOR 3)
|
||||
SET(TINS_VERSION_PATCH 0)
|
||||
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";
|
||||
}
|
||||
// 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";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ private:
|
||||
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
|
||||
|
||||
@@ -5,14 +5,14 @@
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
@@ -46,11 +46,11 @@ public:
|
||||
* \brief This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::DOT11_CONTROL;
|
||||
|
||||
|
||||
/**
|
||||
* \brief Constructor for creating a 802.11 control frame PDU
|
||||
*
|
||||
* Constructs a 802.11 Control PDU taking the destination and
|
||||
* Constructs a 802.11 Control PDU taking the destination and
|
||||
* source hardware addresses.
|
||||
*
|
||||
* \param dst_addr The destination hardware address.
|
||||
@@ -59,15 +59,15 @@ public:
|
||||
|
||||
/**
|
||||
* \brief Constructs a Dot11Control object from a buffer and
|
||||
* adds all identifiable PDUs found in the buffer as children
|
||||
* adds all identifiable PDUs found in the buffer as children
|
||||
* of this one.
|
||||
*
|
||||
*
|
||||
* If the next PDU is not recognized, then a RawPDU is used.
|
||||
*
|
||||
*
|
||||
* If there is not enough size for the header in the buffer
|
||||
* or the input data is malformed, a malformed_packet exception
|
||||
* or the input data is malformed, a malformed_packet exception
|
||||
* is thrown.
|
||||
*
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
@@ -97,6 +97,11 @@ public:
|
||||
*/
|
||||
class TINS_API Dot11ControlTA : public Dot11Control {
|
||||
public:
|
||||
/**
|
||||
* \brief This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::DOT11_CONTROL_TA;
|
||||
|
||||
/**
|
||||
* \brief Getter for the target address field.
|
||||
*/
|
||||
@@ -109,30 +114,39 @@ public:
|
||||
* \param addr The new target address.
|
||||
*/
|
||||
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:
|
||||
/**
|
||||
* \brief Constructor for creating a 802.11 control frame TA PDU
|
||||
*
|
||||
* Constructs a 802.11 PDU taking the destination and source
|
||||
* Constructs a 802.11 PDU taking the destination and source
|
||||
* hardware addresses.
|
||||
*
|
||||
* \param dst_addr The destination hardware address.
|
||||
* \param target_addr The source hardware address.
|
||||
*/
|
||||
Dot11ControlTA(const address_type& dst_addr = address_type(),
|
||||
Dot11ControlTA(const address_type& dst_addr = address_type(),
|
||||
const address_type& target_addr = address_type());
|
||||
|
||||
/**
|
||||
* \brief Constructs a Dot11ControlTA object from a buffer and
|
||||
* adds all identifiable PDUs found in the buffer as children
|
||||
* adds all identifiable PDUs found in the buffer as children
|
||||
* of this one.
|
||||
*
|
||||
*
|
||||
* If the next PDU is not recognized, then a RawPDU is used.
|
||||
*
|
||||
*
|
||||
* If there is not enough size for the header in the buffer
|
||||
* or the input data is malformed, a malformed_packet exception
|
||||
* or the input data is malformed, a malformed_packet exception
|
||||
* is thrown.
|
||||
*
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
@@ -149,8 +163,8 @@ protected:
|
||||
/**
|
||||
* \brief Getter for the control ta additional fields size.
|
||||
*/
|
||||
uint32_t controlta_size() const {
|
||||
return static_cast<uint32_t>(taddr_.size() + sizeof(dot11_header));
|
||||
uint32_t controlta_size() const {
|
||||
return static_cast<uint32_t>(taddr_.size() + sizeof(dot11_header));
|
||||
}
|
||||
|
||||
void write_ext_header(Memory::OutputMemoryStream& stream);
|
||||
@@ -178,19 +192,19 @@ public:
|
||||
* \param dst_addr The destination hardware address.
|
||||
* \param target_addr The source hardware address.
|
||||
*/
|
||||
Dot11RTS(const address_type& dst_addr = address_type(),
|
||||
Dot11RTS(const address_type& dst_addr = address_type(),
|
||||
const address_type& target_addr = address_type());
|
||||
|
||||
|
||||
/**
|
||||
* \brief Constructs a Dot11RTS object from a buffer and adds all
|
||||
* \brief Constructs a Dot11RTS object from a buffer and adds all
|
||||
* identifiable PDUs found in the buffer as children of this one.
|
||||
*
|
||||
*
|
||||
* If the next PDU is not recognized, then a RawPDU is used.
|
||||
*
|
||||
*
|
||||
* If there is not enough size for the header in the buffer
|
||||
* or the input data is malformed, a malformed_packet exception
|
||||
* or the input data is malformed, a malformed_packet exception
|
||||
* is thrown.
|
||||
*
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
@@ -233,26 +247,26 @@ public:
|
||||
/**
|
||||
* \brief Constructor for creating a 802.11 PS-Poll frame PDU
|
||||
*
|
||||
* Constructs a 802.11 PDU taking the destination and source
|
||||
* Constructs a 802.11 PDU taking the destination and source
|
||||
* hardware addresses.
|
||||
*
|
||||
* \param dst_addr The destination hardware address.
|
||||
* \param target_addr The source hardware address.
|
||||
*/
|
||||
Dot11PSPoll(const address_type& dst_addr = address_type(),
|
||||
Dot11PSPoll(const address_type& dst_addr = address_type(),
|
||||
const address_type& target_addr = address_type());
|
||||
|
||||
/**
|
||||
* \brief Constructs a Dot11PSPoll object from a buffer and
|
||||
* adds all identifiable PDUs found in the buffer as children of
|
||||
* adds all identifiable PDUs found in the buffer as children of
|
||||
* this one.
|
||||
*
|
||||
*
|
||||
* If the next PDU is not recognized, then a RawPDU is used.
|
||||
*
|
||||
*
|
||||
* If there is not enough size for the header in the buffer
|
||||
* or the input data is malformed, a malformed_packet exception
|
||||
* or the input data is malformed, a malformed_packet exception
|
||||
* is thrown.
|
||||
*
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
@@ -295,26 +309,26 @@ public:
|
||||
/**
|
||||
* \brief Constructor for creating a 802.11 CF-End frame PDU
|
||||
*
|
||||
* Constructs a 802.11 PDU taking the destination and source
|
||||
* Constructs a 802.11 PDU taking the destination and source
|
||||
* hardware addresses.
|
||||
*
|
||||
* \param dst_addr The destination hardware address.
|
||||
* \param target_addr The source hardware address.
|
||||
*/
|
||||
Dot11CFEnd(const address_type& dst_addr = address_type(),
|
||||
Dot11CFEnd(const address_type& dst_addr = address_type(),
|
||||
const address_type& target_addr = address_type());
|
||||
|
||||
|
||||
/**
|
||||
* \brief Constructs a Dot11CFEnd object from a buffer and adds
|
||||
* all identifiable PDUs found in the buffer as children of this
|
||||
* \brief Constructs a Dot11CFEnd object from a buffer and adds
|
||||
* all identifiable PDUs found in the buffer as children of this
|
||||
* one.
|
||||
*
|
||||
*
|
||||
* If the next PDU is not recognized, then a RawPDU is used.
|
||||
*
|
||||
*
|
||||
* If there is not enough size for the header in the buffer
|
||||
* or the input data is malformed, a malformed_packet exception
|
||||
* or the input data is malformed, a malformed_packet exception
|
||||
* is thrown.
|
||||
*
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
@@ -357,26 +371,26 @@ public:
|
||||
/**
|
||||
* \brief Constructor for creating a 802.11 End-CF-Ack frame PDU
|
||||
*
|
||||
* Constructs a 802.11 PDU taking the destination and source
|
||||
* Constructs a 802.11 PDU taking the destination and source
|
||||
* hardware addresses.
|
||||
*
|
||||
*
|
||||
* \param dst_addr The destination hardware address.
|
||||
* \param target_addr The source hardware address.
|
||||
*/
|
||||
Dot11EndCFAck(const address_type& dst_addr = address_type(),
|
||||
Dot11EndCFAck(const address_type& dst_addr = address_type(),
|
||||
const address_type& target_addr = address_type());
|
||||
|
||||
/**
|
||||
* \brief Constructs a Dot11EndCFAck frame object from a buffer
|
||||
* and adds all identifiable PDUs found in the buffer as children
|
||||
* \brief Constructs a Dot11EndCFAck frame object from a buffer
|
||||
* and adds all identifiable PDUs found in the buffer as children
|
||||
* of this one.
|
||||
*
|
||||
*
|
||||
* If the next PDU is not recognized, then a RawPDU is used.
|
||||
*
|
||||
*
|
||||
* If there is not enough size for the header in the buffer
|
||||
* or the input data is malformed, a malformed_packet exception
|
||||
* or the input data is malformed, a malformed_packet exception
|
||||
* is thrown.
|
||||
*
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
@@ -419,7 +433,7 @@ public:
|
||||
/**
|
||||
* \brief Constructor for creating a 802.11 Ack frame PDU
|
||||
*
|
||||
* Constructs a 802.11 PDU taking the destination and source
|
||||
* Constructs a 802.11 PDU taking the destination and source
|
||||
* hardware addresses.
|
||||
*
|
||||
* \param dst_addr The destination hardware address.
|
||||
@@ -428,15 +442,15 @@ public:
|
||||
|
||||
/**
|
||||
* \brief Constructs a Dot11Ack frame object from a buffer and
|
||||
* adds all identifiable PDUs found in the buffer as children of
|
||||
* adds all identifiable PDUs found in the buffer as children of
|
||||
* this one.
|
||||
*
|
||||
*
|
||||
* If the next PDU is not recognized, then a RawPDU is used.
|
||||
*
|
||||
*
|
||||
* If there is not enough size for the header in the buffer
|
||||
* or the input data is malformed, a malformed_packet exception
|
||||
* or the input data is malformed, a malformed_packet exception
|
||||
* is thrown.
|
||||
*
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
@@ -482,26 +496,26 @@ public:
|
||||
/**
|
||||
* \brief Constructor for creating a 802.11 Block Ack request frame PDU
|
||||
*
|
||||
* Constructs a 802.11 PDU taking the destination and source
|
||||
* Constructs a 802.11 PDU taking the destination and source
|
||||
* hardware addresses.
|
||||
*
|
||||
*
|
||||
* \param dst_addr The destination hardware address.
|
||||
* \param target_addr The source hardware address.
|
||||
*/
|
||||
Dot11BlockAckRequest(const address_type& dst_addr = address_type(),
|
||||
Dot11BlockAckRequest(const address_type& dst_addr = address_type(),
|
||||
const address_type& target_addr = address_type());
|
||||
|
||||
/**
|
||||
* \brief Constructs a Dot11BlockAckRequest object from a buffer
|
||||
* and adds all identifiable PDUs found in the buffer as children
|
||||
* \brief Constructs a Dot11BlockAckRequest object from a buffer
|
||||
* and adds all identifiable PDUs found in the buffer as children
|
||||
* of this one.
|
||||
*
|
||||
*
|
||||
* If the next PDU is not recognized, then a RawPDU is used.
|
||||
*
|
||||
*
|
||||
* If there is not enough size for the header in the buffer
|
||||
* or the input data is malformed, a malformed_packet exception
|
||||
* or the input data is malformed, a malformed_packet exception
|
||||
* is thrown.
|
||||
*
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
@@ -513,11 +527,11 @@ public:
|
||||
* \brief Getter for the bar control field.
|
||||
* \return The stored bar control field.
|
||||
*/
|
||||
small_uint<4> bar_control() const {
|
||||
small_uint<4> bar_control() const {
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
return bar_control_ & 0xf;
|
||||
return bar_control_ & 0xf;
|
||||
#else
|
||||
return (bar_control_ >> 8) & 0xf;
|
||||
return (bar_control_ >> 8) & 0xf;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -525,26 +539,26 @@ public:
|
||||
* \brief Getter for the start sequence field.
|
||||
* \return The stored start sequence.
|
||||
*/
|
||||
small_uint<12> start_sequence() const {
|
||||
small_uint<12> start_sequence() const {
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
return (start_sequence_ >> 4) & 0xfff;
|
||||
return (start_sequence_ >> 4) & 0xfff;
|
||||
#else
|
||||
return (Endian::le_to_host<uint16_t>(start_sequence_) >> 4) & 0xfff;
|
||||
return (Endian::le_to_host<uint16_t>(start_sequence_) >> 4) & 0xfff;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Getter for the fragment number field.
|
||||
* \return The stored fragment number field.
|
||||
*/
|
||||
small_uint<4> fragment_number() const {
|
||||
small_uint<4> fragment_number() const {
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
return start_sequence_ & 0xf;
|
||||
return start_sequence_ & 0xf;
|
||||
#else
|
||||
return (start_sequence_ >> 8) & 0xf;
|
||||
return (start_sequence_ >> 8) & 0xf;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Returns the 802.11 frame's header length.
|
||||
*
|
||||
@@ -566,7 +580,7 @@ public:
|
||||
* \param bar The start sequence field to be set.
|
||||
*/
|
||||
void start_sequence(small_uint<12> seq);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Setter for the fragment number field.
|
||||
* \param frag The fragment number field to be set.
|
||||
@@ -614,7 +628,7 @@ public:
|
||||
* \brief This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::DOT11_BLOCK_ACK;
|
||||
|
||||
|
||||
/**
|
||||
* The size of the bitmap field.
|
||||
*/
|
||||
@@ -623,26 +637,26 @@ public:
|
||||
/**
|
||||
* \brief Constructor for creating a 802.11 Block Ack frame PDU
|
||||
*
|
||||
* Constructs a 802.11 PDU taking the destination and source
|
||||
* Constructs a 802.11 PDU taking the destination and source
|
||||
* hardware addresses.
|
||||
*
|
||||
*
|
||||
* \param dst_addr The destination hardware address.
|
||||
* \param target_addr The source hardware address.
|
||||
*/
|
||||
Dot11BlockAck(const address_type& dst_addr = address_type(),
|
||||
Dot11BlockAck(const address_type& dst_addr = address_type(),
|
||||
const address_type& target_addr = address_type());
|
||||
|
||||
/**
|
||||
* \brief Constructs a Dot11BlockAck frame object from a buffer
|
||||
* and adds all identifiable PDUs found in the buffer as children
|
||||
* \brief Constructs a Dot11BlockAck frame object from a buffer
|
||||
* and adds all identifiable PDUs found in the buffer as children
|
||||
* of this one.
|
||||
*
|
||||
*
|
||||
* If the next PDU is not recognized, then a RawPDU is used.
|
||||
*
|
||||
*
|
||||
* If there is not enough size for the header in the buffer
|
||||
* or the input data is malformed, a malformed_packet exception
|
||||
* or the input data is malformed, a malformed_packet exception
|
||||
* is thrown.
|
||||
*
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
@@ -654,11 +668,11 @@ public:
|
||||
* \brief Getter for the bar control field.
|
||||
* \return The stored bar control field.
|
||||
*/
|
||||
small_uint<4> bar_control() const {
|
||||
small_uint<4> bar_control() const {
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
return bar_control_ & 0xf;
|
||||
return bar_control_ & 0xf;
|
||||
#else
|
||||
return (bar_control_ >> 8) & 0xf;
|
||||
return (bar_control_ >> 8) & 0xf;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -666,26 +680,26 @@ public:
|
||||
* \brief Getter for the start sequence field.
|
||||
* \return The stored start sequence.
|
||||
*/
|
||||
small_uint<12> start_sequence() const {
|
||||
small_uint<12> start_sequence() const {
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
return (start_sequence_ >> 4) & 0xfff;
|
||||
return (start_sequence_ >> 4) & 0xfff;
|
||||
#else
|
||||
return (Endian::le_to_host<uint16_t>(start_sequence_) >> 4) & 0xfff;
|
||||
return (Endian::le_to_host<uint16_t>(start_sequence_) >> 4) & 0xfff;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Getter for the fragment number field.
|
||||
* \return The stored fragment number field.
|
||||
*/
|
||||
small_uint<4> fragment_number() const {
|
||||
small_uint<4> fragment_number() const {
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
return start_sequence_ & 0xf;
|
||||
return start_sequence_ & 0xf;
|
||||
#else
|
||||
return (start_sequence_ >> 8) & 0xf;
|
||||
return (start_sequence_ >> 8) & 0xf;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Returns the 802.11 frame's header length.
|
||||
*
|
||||
@@ -707,7 +721,7 @@ public:
|
||||
* \param bar The start sequence field to be set.
|
||||
*/
|
||||
void start_sequence(small_uint<12> seq);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Setter for the fragment number field.
|
||||
* \param frag The fragment number field to be set.
|
||||
@@ -716,9 +730,9 @@ public:
|
||||
|
||||
/**
|
||||
* \brief Getter for the bitmap field.
|
||||
*
|
||||
*
|
||||
* The returned pointer <b>must not</b> be free'd.
|
||||
*
|
||||
*
|
||||
* \return The bitmap field.
|
||||
*/
|
||||
const uint8_t* bitmap() const {
|
||||
|
||||
@@ -173,7 +173,7 @@ public:
|
||||
|
||||
addr_list_type(const addresses_type& addresses = addresses_type())
|
||||
: 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);
|
||||
@@ -199,7 +199,7 @@ public:
|
||||
|
||||
naack_type(uint8_t code = 0, uint8_t status = 0)
|
||||
: 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);
|
||||
@@ -323,7 +323,7 @@ public:
|
||||
* The key_hash member will be 0-initialized.
|
||||
*/
|
||||
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);
|
||||
@@ -489,7 +489,7 @@ public:
|
||||
|
||||
timestamp_type(uint64_t timestamp = 0)
|
||||
: 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);
|
||||
|
||||
@@ -174,9 +174,9 @@ public:
|
||||
option_identifier(OptionNumber number, OptionClass op_class,
|
||||
small_uint<1> copied)
|
||||
#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
|
||||
: 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
|
||||
|
||||
/**
|
||||
|
||||
@@ -230,6 +230,14 @@ public:
|
||||
*/
|
||||
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.
|
||||
*
|
||||
|
||||
@@ -236,7 +236,7 @@ public:
|
||||
* \return The LLC frame format.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,14 +5,14 @@
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
@@ -26,7 +26,7 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TINS_PDU_H
|
||||
#define TINS_PDU_H
|
||||
|
||||
@@ -49,22 +49,22 @@ class NetworkInterface;
|
||||
*/
|
||||
typedef std::vector<uint8_t> byte_array;
|
||||
|
||||
/**
|
||||
/**
|
||||
* \class PDU
|
||||
* \brief Base class for protocol data units.
|
||||
*
|
||||
* Every PDU implementation inherits from this class.
|
||||
* Every PDU implementation inherits from this class.
|
||||
*
|
||||
* PDUs can contain 0 or 1 inner PDU. By stacking several PDUs together,
|
||||
* you can construct packets. These are created upwards: upper layers
|
||||
* will be children of the lower ones.
|
||||
* you can construct packets. These are created upwards: upper layers
|
||||
* will be children of the lower ones.
|
||||
*
|
||||
* If you want to find a specific protocol within a PDU chain, you can use
|
||||
* PDU::find_pdu and PDU::rfind_pdu. Both of them take a template parameter
|
||||
* that indicates the PDU type you are looking for. The first one returns a
|
||||
* pointer to the first object of that type, and the second one returns a
|
||||
* reference (and throws if it is not found).
|
||||
*
|
||||
* that indicates the PDU type you are looking for. The first one returns a
|
||||
* pointer to the first object of that type, and the second one returns a
|
||||
* reference (and throws if it is not found).
|
||||
*
|
||||
* For example:
|
||||
*
|
||||
* \code
|
||||
@@ -86,7 +86,7 @@ typedef std::vector<uint8_t> byte_array;
|
||||
* stack into a vector of bytes. This process might modify some parameters
|
||||
* on packets depending on which protocols are used in it. For example:
|
||||
*
|
||||
* - If the lowest protocol layer is IP (this means that there is no
|
||||
* - If the lowest protocol layer is IP (this means that there is no
|
||||
* link layer protocol in the packet), then it calculates the source address
|
||||
* that should be used in that IP PDU. \sa IP
|
||||
* - If a protocol contains a checksum field, its value will be calculated
|
||||
@@ -179,10 +179,11 @@ public:
|
||||
IPSEC_ESP,
|
||||
PKTAP,
|
||||
MPLS,
|
||||
DOT11_CONTROL_TA,
|
||||
UNKNOWN = 999,
|
||||
USER_DEFINED_PDU = 1000
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The endianness used by this PDU. This can be overriden
|
||||
* by subclasses.
|
||||
@@ -197,10 +198,10 @@ public:
|
||||
* \brief Default constructor
|
||||
*/
|
||||
metadata();
|
||||
|
||||
|
||||
/**
|
||||
* \brief Constructs an instance of metadata using the given values
|
||||
|
||||
|
||||
*/
|
||||
metadata(uint32_t header_size, PDUType current_type, PDUType next_type);
|
||||
|
||||
@@ -220,28 +221,28 @@ public:
|
||||
PDUType next_pdu_type;
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* \brief Default constructor.
|
||||
*/
|
||||
PDU();
|
||||
|
||||
|
||||
#if TINS_IS_CXX11
|
||||
/**
|
||||
* \brief Move constructor.
|
||||
*
|
||||
*
|
||||
* \param rhs The PDU to be moved.
|
||||
*/
|
||||
PDU(PDU &&rhs) TINS_NOEXCEPT
|
||||
PDU(PDU &&rhs) TINS_NOEXCEPT
|
||||
: inner_pdu_(0), parent_pdu_(0) {
|
||||
std::swap(inner_pdu_, rhs.inner_pdu_);
|
||||
if (inner_pdu_) {
|
||||
inner_pdu_->parent_pdu(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Move assignment operator.
|
||||
*
|
||||
*
|
||||
* \param rhs The PDU to be moved.
|
||||
*/
|
||||
PDU& operator=(PDU &&rhs) TINS_NOEXCEPT {
|
||||
@@ -255,7 +256,7 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
/**
|
||||
* \brief PDU destructor.
|
||||
*
|
||||
* Deletes the inner pdu, as a consequence every child pdu is
|
||||
@@ -302,18 +303,18 @@ public:
|
||||
PDU* parent_pdu() const {
|
||||
return parent_pdu_;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Releases the inner PDU.
|
||||
*
|
||||
*
|
||||
* This method makes this PDU to <b>no longer own</b> the inner
|
||||
* PDU. The current inner PDU is returned, and is <b>not</b>
|
||||
* destroyed. That means after calling this function, you are
|
||||
* destroyed. That means after calling this function, you are
|
||||
* responsible for using operator delete on the returned pointer.
|
||||
*
|
||||
*
|
||||
* Use this method if you want to somehow re-use a PDU that
|
||||
* is already owned by another PDU.
|
||||
*
|
||||
*
|
||||
* \return The current inner PDU. Might be 0.
|
||||
*/
|
||||
PDU* release_inner_pdu();
|
||||
@@ -323,26 +324,26 @@ public:
|
||||
*
|
||||
* When setting a new inner_pdu, the instance takesownership of
|
||||
* the object, therefore deleting it when it's no longer required.
|
||||
*
|
||||
*
|
||||
* \param next_pdu The new child PDU.
|
||||
*/
|
||||
void inner_pdu(PDU* next_pdu);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Sets the child PDU.
|
||||
*
|
||||
* The PDU parameter is cloned using PDU::clone.
|
||||
*
|
||||
*
|
||||
* \param next_pdu The new child PDU.
|
||||
*/
|
||||
void inner_pdu(const PDU& next_pdu);
|
||||
|
||||
/**
|
||||
/**
|
||||
* \brief Serializes the whole chain of PDU's, including this one.
|
||||
*
|
||||
* This allocates a std::vector of size size(), and fills it
|
||||
* with the serialization this PDU, and all of the inner ones'.
|
||||
*
|
||||
*
|
||||
* \return serialization_type containing the serialization
|
||||
* of the whole stack of PDUs.
|
||||
*/
|
||||
@@ -356,7 +357,7 @@ public:
|
||||
* If no PDU matches, 0 is returned.
|
||||
* \param flag The flag which being searched.
|
||||
*/
|
||||
template<typename T>
|
||||
template<typename T>
|
||||
T* find_pdu(PDUType type = T::pdu_flag) {
|
||||
PDU* pdu = this;
|
||||
while (pdu) {
|
||||
@@ -367,24 +368,24 @@ public:
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Finds and returns the first PDU that matches the given flag.
|
||||
*
|
||||
* \param flag The flag which being searched.
|
||||
*/
|
||||
template<typename T>
|
||||
template<typename T>
|
||||
const T* find_pdu(PDUType type = T::pdu_flag) const {
|
||||
return const_cast<PDU*>(this)->find_pdu<T>(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Finds and returns the first PDU that matches the given flag.
|
||||
*
|
||||
*
|
||||
* If the PDU is not found, a pdu_not_found exception is thrown.
|
||||
*
|
||||
*
|
||||
* \sa PDU::find_pdu
|
||||
*
|
||||
*
|
||||
* \param flag The flag which being searched.
|
||||
*/
|
||||
template<typename T>
|
||||
@@ -401,7 +402,7 @@ public:
|
||||
*
|
||||
* \param flag The flag which being searched.
|
||||
*/
|
||||
template<typename T>
|
||||
template<typename T>
|
||||
const T& rfind_pdu(PDUType type = T::pdu_flag) const {
|
||||
return const_cast<PDU*>(this)->rfind_pdu<T>(type);
|
||||
}
|
||||
@@ -416,36 +417,36 @@ public:
|
||||
*/
|
||||
virtual PDU* clone() const = 0;
|
||||
|
||||
/**
|
||||
/**
|
||||
* \brief Send the stack of PDUs through a PacketSender.
|
||||
*
|
||||
* This method will be called only for the PDU on the bottom of the stack,
|
||||
* therefore it should only implement this method if it can be sent.
|
||||
*
|
||||
*
|
||||
* PacketSender implements specific methods to send packets which start
|
||||
* on every valid TCP/IP stack layer; this should only be a proxy for
|
||||
* those methods.
|
||||
*
|
||||
*
|
||||
* If this PDU does not represent a link layer protocol, then
|
||||
* the interface argument will be ignored.
|
||||
*
|
||||
*
|
||||
* \param sender The PacketSender which will send the packet.
|
||||
* \param iface The network interface in which this packet will
|
||||
* \param iface The network interface in which this packet will
|
||||
* be sent.
|
||||
*/
|
||||
virtual void send(PacketSender& sender, const NetworkInterface& iface);
|
||||
|
||||
/**
|
||||
/**
|
||||
* \brief Receives a matching response for this packet.
|
||||
*
|
||||
* This method should act as a proxy for PacketSender::recv_lX methods.
|
||||
*
|
||||
*
|
||||
* \param sender The packet sender which will receive the packet.
|
||||
* \param iface The interface in which to expect the response.
|
||||
*/
|
||||
virtual PDU* recv_response(PacketSender& sender, const NetworkInterface& iface);
|
||||
|
||||
/**
|
||||
/**
|
||||
* \brief Check whether ptr points to a valid response for this PDU.
|
||||
*
|
||||
* This method must check whether the buffer pointed by ptr is a valid
|
||||
@@ -494,18 +495,18 @@ protected:
|
||||
|
||||
/**
|
||||
* \brief Prepares this PDU for serialization.
|
||||
*
|
||||
*
|
||||
* This method is called before the inner PDUs are serialized.
|
||||
* It's useful in situations such as when serializing IP PDUs,
|
||||
* which don't contain any link layer encapsulation, and therefore
|
||||
* require to set the source IP address before the TCP/UDP checksum
|
||||
* is calculated.
|
||||
*
|
||||
*
|
||||
* By default, this method does nothing
|
||||
*/
|
||||
virtual void prepare_for_serialize();
|
||||
|
||||
/**
|
||||
/**
|
||||
* \brief Serializes this PDU and propagates this action to child PDUs.
|
||||
*
|
||||
* \param buffer The buffer in which to store this PDU's serialization.
|
||||
@@ -513,7 +514,7 @@ protected:
|
||||
*/
|
||||
void serialize(uint8_t* buffer, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
/**
|
||||
* \brief Serializes this TCP PDU.
|
||||
*
|
||||
* Each PDU must override this method and implement it's own
|
||||
@@ -531,18 +532,18 @@ private:
|
||||
|
||||
/**
|
||||
* \brief Concatenation operator.
|
||||
*
|
||||
* This operator concatenates several PDUs. A copy of the right
|
||||
*
|
||||
* This operator concatenates several PDUs. A copy of the right
|
||||
* operand is set at the end of the left one's inner PDU chain.
|
||||
* This means that:
|
||||
*
|
||||
*
|
||||
* IP some_ip = IP("127.0.0.1") / TCP(12, 13) / RawPDU("bleh");
|
||||
*
|
||||
* Works as expected, meaning the output PDU will look like the
|
||||
*
|
||||
* Works as expected, meaning the output PDU will look like the
|
||||
* following:
|
||||
*
|
||||
*
|
||||
* IP - TCP - RawPDU
|
||||
*
|
||||
*
|
||||
* \param lop The left operand, which will be the one modified.
|
||||
* \param rop The right operand, the one which will be appended
|
||||
* to lop.
|
||||
@@ -559,7 +560,7 @@ T& operator/= (T& lop, const PDU& rop) {
|
||||
|
||||
/**
|
||||
* \brief Concatenation operator.
|
||||
*
|
||||
*
|
||||
* \sa operator/=
|
||||
*/
|
||||
template<typename T>
|
||||
@@ -570,7 +571,7 @@ T operator/ (T lop, const PDU& rop) {
|
||||
|
||||
/**
|
||||
* \brief Concatenation operator on PDU pointers.
|
||||
*
|
||||
*
|
||||
* \sa operator/=
|
||||
*/
|
||||
template<typename T>
|
||||
|
||||
@@ -288,13 +288,29 @@ public:
|
||||
* \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 */
|
||||
|
||||
|
||||
@@ -49,16 +49,19 @@
|
||||
#include <tins/ipv6.h>
|
||||
#include <tins/mpls.h>
|
||||
#include <tins/packet_sender.h>
|
||||
#include <tins/packet_writer.h>
|
||||
#include <tins/pdu.h>
|
||||
#include <tins/radiotap.h>
|
||||
#include <tins/rawpdu.h>
|
||||
#include <tins/snap.h>
|
||||
#include <tins/sniffer.h>
|
||||
#include <tins/tcp.h>
|
||||
#include <tins/udp.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>
|
||||
#endif
|
||||
#include <tins/crypto.h>
|
||||
#include <tins/pdu_cacher.h>
|
||||
#include <tins/rsn_information.h>
|
||||
@@ -75,7 +78,7 @@
|
||||
#include <tins/pdu_allocator.h>
|
||||
#include <tins/ipsec.h>
|
||||
#include <tins/ip_reassembler.h>
|
||||
#include <tins/ppi.h>
|
||||
|
||||
#include <tins/pdu_iterator.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) {
|
||||
return header_id == HOP_BY_HOP || header_id == DESTINATION_ROUTING_OPTIONS
|
||||
|| header_id == ROUTING || header_id == FRAGMENT || header_id == AUTHENTICATION
|
||||
|| header_id == SECURITY_ENCAPSULATION || header_id == DESTINATION_OPTIONS
|
||||
|| header_id == MOBILITY || header_id == NO_NEXT_HEADER;
|
||||
|| header_id == DESTINATION_OPTIONS || header_id == MOBILITY
|
||||
|| header_id == NO_NEXT_HEADER;
|
||||
}
|
||||
|
||||
uint32_t IPv6::get_padding_size(const ext_header& header) {
|
||||
|
||||
@@ -57,6 +57,7 @@ namespace Tins {
|
||||
|
||||
const IPv6Address loopback_address = "::1";
|
||||
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 address;
|
||||
@@ -138,6 +139,10 @@ bool IPv6Address::is_multicast() const {
|
||||
return multicast_range.contains(*this);
|
||||
}
|
||||
|
||||
bool IPv6Address::is_local_unicast() const {
|
||||
return local_unicast_range.contains(*this);
|
||||
}
|
||||
|
||||
ostream& operator<<(ostream& os, const IPv6Address& addr) {
|
||||
return os << addr.to_string();
|
||||
}
|
||||
|
||||
@@ -37,11 +37,14 @@ using std::string;
|
||||
namespace Tins {
|
||||
|
||||
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) {
|
||||
string_filter_ = other.string_filter_;
|
||||
pcap_freecode(&filter_);
|
||||
pcap_close(handle_);
|
||||
init(string_filter_, pcap_datalink(other.handle_), pcap_snapshot(other.handle_));
|
||||
return* this;
|
||||
}
|
||||
@@ -58,8 +61,14 @@ void OfflinePacketFilter::init(const string& pcap_filter,
|
||||
link_type,
|
||||
snap_len
|
||||
);
|
||||
if (!handle_) {
|
||||
throw pcap_open_failed();
|
||||
}
|
||||
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());
|
||||
if (!dumper_) {
|
||||
string error(pcap_geterr(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;
|
||||
}
|
||||
|
||||
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:
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -84,7 +84,9 @@ 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)) {
|
||||
// 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->second.setup_flows_callbacks();
|
||||
if (on_new_connection_) {
|
||||
@@ -93,7 +95,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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -131,7 +131,7 @@ struct RadioTapFlags {
|
||||
} TINS_END_PACK;
|
||||
#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);
|
||||
if (offset) {
|
||||
offset = n - offset;
|
||||
@@ -278,7 +278,7 @@ bool RadioTapParser::advance_to_next_field() {
|
||||
if (current_bit_ < MAX_RADIOTAP_FIELD) {
|
||||
const uint8_t* radiotap_start = start_ - sizeof(uint32_t);
|
||||
// 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);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -41,11 +41,12 @@ namespace Tins {
|
||||
namespace Utils {
|
||||
|
||||
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) {
|
||||
return log(value) / log(2);
|
||||
return round(log2(value));
|
||||
}
|
||||
|
||||
RadioTapWriter::RadioTapWriter(vector<uint8_t>& buffer)
|
||||
@@ -54,7 +55,7 @@ RadioTapWriter::RadioTapWriter(vector<uint8_t>& buffer)
|
||||
|
||||
void RadioTapWriter::write_option(const RadioTap::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();
|
||||
}
|
||||
const bool is_empty = buffer_.empty();
|
||||
|
||||
@@ -62,7 +62,7 @@ private:
|
||||
|
||||
template <typename T>
|
||||
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
|
||||
|
||||
@@ -58,7 +58,7 @@ const uint8_t DHCPTest::expected_packet[] = {
|
||||
TEST_F(DHCPTest, DefaultConstructor) {
|
||||
DHCP dhcp;
|
||||
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) {
|
||||
@@ -280,7 +280,7 @@ TEST_F(DHCPTest, ConstructorFromBuffer) {
|
||||
|
||||
EXPECT_EQ(dhcp1.opcode(), DHCP::DISCOVER);
|
||||
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.xid(), 0x3fab23deU);
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user