mirror of
https://github.com/mfontanini/libtins
synced 2026-01-23 10:45:57 +01:00
Compare commits
50 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 | ||
|
|
5e52091ecf | ||
|
|
dafb299ea3 | ||
|
|
659bec56d7 | ||
|
|
8c1bea6f84 | ||
|
|
d8d1dc003b | ||
|
|
c2bb52b82f | ||
|
|
1f5456b18b | ||
|
|
dc702f4fd6 | ||
|
|
2a8101eef3 | ||
|
|
20702ddaff | ||
|
|
f4e2701705 | ||
|
|
776ae4e83b | ||
|
|
2158c7a92e | ||
|
|
b53bad7b29 | ||
|
|
6c92bcdad1 | ||
|
|
b949e56d15 | ||
|
|
18ff3e7b6a | ||
|
|
eb7628eca4 | ||
|
|
7e90c8be6a |
86
CHANGES.md
86
CHANGES.md
@@ -1,3 +1,39 @@
|
||||
##### 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)
|
||||
|
||||
- Fix check to detect cross compilation (#330)
|
||||
|
||||
- Allow getting a PDU's advertised size and use it in `PacketWriter` (#324)
|
||||
|
||||
- Install DLLs in right directory (#326)
|
||||
|
||||
- Add missing Dot11 tagged option types (#305)
|
||||
|
||||
- Add support for DLT_RAW (#313)
|
||||
|
||||
- Fix potential invalid memory accesses when parsing RadioTap (#322)
|
||||
|
||||
##### v4.1 - Tue Dec 11 02:08:48 UTC 2018
|
||||
|
||||
- Fix serialization for QinQ (#316)
|
||||
@@ -216,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
|
||||
|
||||
@@ -360,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
|
||||
@@ -410,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.
|
||||
@@ -454,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.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
@@ -475,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.
|
||||
|
||||
@@ -517,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
|
||||
@@ -533,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.
|
||||
@@ -544,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
|
||||
@@ -566,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
|
||||
@@ -598,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
|
||||
@@ -611,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.
|
||||
@@ -631,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.
|
||||
@@ -648,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.
|
||||
@@ -665,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.
|
||||
@@ -708,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 1)
|
||||
SET(TINS_VERSION_MINOR 3)
|
||||
SET(TINS_VERSION_PATCH 0)
|
||||
SET(LIBTINS_VERSION "${TINS_VERSION_MAJOR}.${TINS_VERSION_MINOR}")
|
||||
|
||||
@@ -234,6 +234,9 @@ CONFIGURE_FILE(
|
||||
IF (NOT CMAKE_INSTALL_LIBDIR)
|
||||
SET(CMAKE_INSTALL_LIBDIR lib)
|
||||
ENDIF()
|
||||
IF (NOT CMAKE_INSTALL_BINDIR)
|
||||
SET(CMAKE_INSTALL_BINDIR bin)
|
||||
ENDIF()
|
||||
# The library output directory
|
||||
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
|
||||
SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
|
||||
@@ -308,6 +311,12 @@ ENDIF()
|
||||
# CMake project configuration export
|
||||
# **********************************
|
||||
|
||||
if(UNIX)
|
||||
set(CONF_CMAKE_INSTALL_DIR lib/cmake/libtins)
|
||||
else()
|
||||
set(CONF_CMAKE_INSTALL_DIR CMake)
|
||||
endif()
|
||||
|
||||
# Add all targets to the build-tree export set
|
||||
EXPORT(
|
||||
TARGETS tins
|
||||
@@ -334,13 +343,13 @@ INSTALL(
|
||||
FILES
|
||||
"${PROJECT_BINARY_DIR}/libtinsConfig.cmake"
|
||||
"${PROJECT_BINARY_DIR}/libtinsConfigVersion.cmake"
|
||||
DESTINATION CMake
|
||||
DESTINATION ${CONF_CMAKE_INSTALL_DIR}
|
||||
COMPONENT dev
|
||||
)
|
||||
|
||||
# Install the export set for use with the install-tree
|
||||
INSTALL(
|
||||
EXPORT libtinsTargets
|
||||
DESTINATION CMake
|
||||
DESTINATION ${CONF_CMAKE_INSTALL_DIR}
|
||||
COMPONENT dev
|
||||
)
|
||||
|
||||
@@ -79,14 +79,14 @@ function(cxx11_check_feature FEATURE_NAME RESULT_VAR)
|
||||
set(_SRCFILE_FAIL "${_SRCFILE_BASE}_fail.cpp")
|
||||
set(_SRCFILE_FAIL_COMPILE "${_SRCFILE_BASE}_fail_compile.cpp")
|
||||
|
||||
if (CROSS_COMPILING)
|
||||
if (CMAKE_CROSSCOMPILING)
|
||||
try_compile(${RESULT_VAR} "${_bindir}" "${_SRCFILE}"
|
||||
COMPILE_DEFINITIONS "${CXX11_COMPILER_FLAGS}")
|
||||
if (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
|
||||
try_compile(${RESULT_VAR} "${_bindir}_fail" "${_SRCFILE_FAIL}"
|
||||
COMPILE_DEFINITIONS "${CXX11_COMPILER_FLAGS}")
|
||||
endif (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
|
||||
else (CROSS_COMPILING)
|
||||
else (CMAKE_CROSSCOMPILING)
|
||||
try_run(_RUN_RESULT_VAR _COMPILE_RESULT_VAR
|
||||
"${_bindir}" "${_SRCFILE}"
|
||||
COMPILE_DEFINITIONS "${CXX11_COMPILER_FLAGS}")
|
||||
@@ -105,7 +105,7 @@ function(cxx11_check_feature FEATURE_NAME RESULT_VAR)
|
||||
set(${RESULT_VAR} FALSE)
|
||||
endif (_COMPILE_RESULT_VAR AND _RUN_RESULT_VAR)
|
||||
endif (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL})
|
||||
endif (CROSS_COMPILING)
|
||||
endif (CMAKE_CROSSCOMPILING)
|
||||
if (${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL_COMPILE})
|
||||
try_compile(_TMP_RESULT "${_bindir}_fail_compile" "${_SRCFILE_FAIL_COMPILE}"
|
||||
COMPILE_DEFINITIONS "${CXX11_COMPILER_FLAGS}")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -41,6 +41,7 @@ class Dot3;
|
||||
class SLL;
|
||||
class Loopback;
|
||||
class PPI;
|
||||
class IP;
|
||||
|
||||
/**
|
||||
* \struct DataLinkType
|
||||
@@ -73,6 +74,7 @@ TINS_MAKE_DATA_LINK_TYPE(Loopback, DLT_LOOP)
|
||||
TINS_MAKE_DATA_LINK_TYPE(PPI, DLT_PPI)
|
||||
TINS_MAKE_DATA_LINK_TYPE(Dot11, DLT_IEEE802_11)
|
||||
TINS_MAKE_DATA_LINK_TYPE(RadioTap, DLT_IEEE802_11_RADIO)
|
||||
TINS_MAKE_DATA_LINK_TYPE(IP, DLT_RAW)
|
||||
|
||||
#undef TINS_MAKE_DATA_LINK_TYPE
|
||||
|
||||
|
||||
@@ -127,9 +127,148 @@ public:
|
||||
ERP_INFORMATION,
|
||||
TS_DELAY,
|
||||
TCLAS_PROCESSING,
|
||||
QOS_CAPABILITY = 46,
|
||||
HT_CAPABILITY,
|
||||
QOS_CAPABILITY,
|
||||
RSN = 48,
|
||||
EXT_SUPPORTED_RATES = 50,
|
||||
AP_CHANNEL_REPORT,
|
||||
NEIGHBOR_REPORT,
|
||||
RCPI,
|
||||
MOBILITY_DOMAIN_MDE,
|
||||
FAST_BSS_TRANSITION_FTE,
|
||||
TIMEOUT_INTERVAL,
|
||||
RIC_DATA_RDE,
|
||||
DSE_REG_LOC,
|
||||
SUPPORTED_OP_CLASSES,
|
||||
EXT_CH_SWITCH_ANNOUNCEMENT,
|
||||
HT_OPERATION,
|
||||
SEC_CH_OFFSET,
|
||||
BSS_AVG_ACCESS_DELAY,
|
||||
ANTENNA,
|
||||
RSNI,
|
||||
MEASUREMENT_PILOT_TRANSMISSION,
|
||||
BSS_AVAIL_ADMISSION_CAPACITY,
|
||||
BSS_AC_ACCESS_DELAY,
|
||||
TIME_ADVERTISEMENT,
|
||||
RM_ENABLED_CAP,
|
||||
MULTIPLE_BSSID,
|
||||
BSS_2040_COEX,
|
||||
BSS_2040_INTOLERANT_CH_REPORT,
|
||||
OVERLAPPING_BSS_SCAN_PARAM,
|
||||
RIC_DESCRIPTOR,
|
||||
MGMT_MIC,
|
||||
EVENT_REQ = 78,
|
||||
EVENT_REPORT,
|
||||
DIAG_REQ,
|
||||
DIAG_REPORT,
|
||||
LOCATION_PARAMS,
|
||||
NONTRANSMITTED_BSSID_CAP,
|
||||
SSID_LIST,
|
||||
MULTIPLE_BSSID_INDEX,
|
||||
FMS_DESCRIPTOR,
|
||||
FMS_REQ,
|
||||
FMS_RESP,
|
||||
QOS_TRAFFIC_CAP,
|
||||
BSS_MAX_IDLE_PERIOD,
|
||||
TFS_REQ,
|
||||
TFS_RESP,
|
||||
WNM_SLEEP_MODE,
|
||||
TIM_BROADCAST_REQ,
|
||||
TIM_BROADCAST_RESP,
|
||||
COLLOCATED_INTERFERENCE_REPORT,
|
||||
CH_USAGE,
|
||||
TIME_ZONE,
|
||||
DMS_REQ,
|
||||
DMS_RESP,
|
||||
LINK_ID,
|
||||
WAKEUP_SCHEDULE,
|
||||
CH_SWITCH_TIMING,
|
||||
PTI_CONTROL,
|
||||
TPU_BUFFER_STATUS,
|
||||
INTERWORKING,
|
||||
ADVERTISEMENT_PROTOCOL,
|
||||
EXPEDITED_BANDWIDTH_REQ,
|
||||
QOS_MAP,
|
||||
ROAMING_CONSORTIUM,
|
||||
EMERG_ALERT_ID,
|
||||
MESH_CONFIG,
|
||||
MESH_ID,
|
||||
MESH_LINK_METRIC_REPORT,
|
||||
CONGESTION_NOTIFICATION,
|
||||
MESH_PEERING_MGMT,
|
||||
MESH_CH_SWITCH_PARAMS,
|
||||
MESH_AWAKE_WINDOW,
|
||||
BEACON_TIMING,
|
||||
MCCAOP_SETUP_REQ,
|
||||
MCCAOP_SETUP_REPLY,
|
||||
MCCAOP_ADVERTISEMENT,
|
||||
MCCAOP_TEARDOWN,
|
||||
GANN,
|
||||
RANN,
|
||||
EXT_CAP,
|
||||
PREQ = 130,
|
||||
PREP,
|
||||
PERR,
|
||||
PXU = 137,
|
||||
PXUC,
|
||||
AUTH_MESH_PEER_EX,
|
||||
MIC,
|
||||
DEST_URI,
|
||||
UAPSD_COEX,
|
||||
DMG_WAKEUP_SCHEDULE,
|
||||
EXT_SCHEDULE,
|
||||
STA_AVAIL,
|
||||
DMG_TSPEC,
|
||||
NEXT_DMG_ATI,
|
||||
DMG_CAP,
|
||||
DMG_OP = 151,
|
||||
DMG_BSS_PARAM_CHG,
|
||||
DMG_BEAM_REFINEMENT,
|
||||
CH_MEASUREMENT_FEEDBACK,
|
||||
AWAKE_WINDOW = 157,
|
||||
MULTIBAND,
|
||||
ADDBA_ESXT,
|
||||
NEXTPCP_LIST,
|
||||
PCP_HANDOVER,
|
||||
DMG_LINK_MARGIN,
|
||||
SWITCHING_STREAM,
|
||||
SESSION_TRANSITION,
|
||||
DYNAMIC_TONE_PAIRING_REPORT,
|
||||
CLUSTER_REPORT,
|
||||
RELAY_CAP,
|
||||
RELAY_TRANSFER_PARAM_SET,
|
||||
BEAMLINK_MAINTENANCE,
|
||||
MULTIPLE_MAC_SUBLAYERS,
|
||||
UPID,
|
||||
DMG_LINK_ADAPTATION_ACK,
|
||||
MCCAOP_ADV_OVERVIEW = 174,
|
||||
QUIET_PERIOD_REQ,
|
||||
QUIET_PERIOD_RESP = 177,
|
||||
QMF_POLICY = 181,
|
||||
ECAPC_POLICY = 182,
|
||||
CLUSTER_TIME_OFFSET,
|
||||
INTRA_ACCESS_CAT_PRIORITY,
|
||||
SCS_DESCRIPTOR,
|
||||
QLOAD_REPORT,
|
||||
HCCA_TXOP_UPDATE_COUNT,
|
||||
HIGHER_LAYER_STREAM_ID,
|
||||
GCR_GROUP_ADDR,
|
||||
ANTENNA_SECTOR_ID_PATTERN,
|
||||
VHT_CAP,
|
||||
VHT_OP,
|
||||
EXT_BSS_LOAD,
|
||||
WIDE_BANDWIDTH_CH_SWITCH,
|
||||
TRANSMIT_POWER_ENVELOPE,
|
||||
CH_SWITCH_WRAPPER,
|
||||
AID,
|
||||
QUIET_CHANNEL,
|
||||
OP_MODE_NOTIFY,
|
||||
UPSIM,
|
||||
REDUCED_NEIGHBOR_REPORT,
|
||||
TVHT_OP,
|
||||
DEV_LOC = 204,
|
||||
WHITE_SPACE_MAP,
|
||||
FINE_TUNING_MEASUREMENT_PARAMS,
|
||||
VENDOR_SPECIFIC = 221
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
/**
|
||||
@@ -281,6 +281,10 @@ public:
|
||||
|
||||
/* Getters */
|
||||
|
||||
uint32_t advertised_size() const {
|
||||
return static_cast<uint32_t>(tot_len());
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the header length field.
|
||||
*
|
||||
|
||||
@@ -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
|
||||
@@ -281,6 +282,12 @@ public:
|
||||
*/
|
||||
uint32_t size() const;
|
||||
|
||||
/** \brief The whole chain of PDU's advertised size, including this one.
|
||||
*
|
||||
* Returns the sum of this and all children PDU's advertised size.
|
||||
*/
|
||||
virtual uint32_t advertised_size() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the inner PDU.
|
||||
* \return The current inner PDU. Might be a null pointer.
|
||||
@@ -296,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();
|
||||
@@ -317,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.
|
||||
*/
|
||||
@@ -350,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) {
|
||||
@@ -361,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>
|
||||
@@ -395,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);
|
||||
}
|
||||
@@ -410,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
|
||||
@@ -488,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.
|
||||
@@ -507,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
|
||||
@@ -525,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.
|
||||
@@ -553,7 +560,7 @@ T& operator/= (T& lop, const PDU& rop) {
|
||||
|
||||
/**
|
||||
* \brief Concatenation operator.
|
||||
*
|
||||
*
|
||||
* \sa operator/=
|
||||
*/
|
||||
template<typename T>
|
||||
@@ -564,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
|
||||
|
||||
@@ -114,7 +114,11 @@ public:
|
||||
RadioTap::option current_option();
|
||||
|
||||
/**
|
||||
* Gets the pointer at which the current option is located
|
||||
* \brief Gets the pointer at which the current option is located
|
||||
*
|
||||
* A past-the-end pointer may be returned in case of malformed input or
|
||||
* end of data. Its validity must be checked (e.g. using
|
||||
* \ref RadioTapParser.has_fields) before dereference.
|
||||
*/
|
||||
const uint8_t* current_option_ptr() const;
|
||||
|
||||
|
||||
@@ -219,6 +219,7 @@ SET_TARGET_PROPERTIES(tins PROPERTIES VERSION ${LIBTINS_VERSION} SOVERSION ${LIB
|
||||
INSTALL(
|
||||
TARGETS tins
|
||||
EXPORT libtinsTargets
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
COMPONENT dev
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -70,12 +70,12 @@ void PacketWriter::write(Packet& packet) {
|
||||
}
|
||||
|
||||
void PacketWriter::write(PDU& pdu, const struct timeval& tv) {
|
||||
PDU::serialization_type buffer = pdu.serialize();
|
||||
struct pcap_pkthdr header;
|
||||
memset(&header, 0, sizeof(header));
|
||||
header.ts = tv;
|
||||
header.len = static_cast<bpf_u_int32>(pdu.advertised_size());
|
||||
PDU::serialization_type buffer = pdu.serialize();
|
||||
header.caplen = static_cast<bpf_u_int32>(buffer.size());
|
||||
header.len = static_cast<bpf_u_int32>(buffer.size());
|
||||
pcap_dump((u_char*)dumper_, &header, &buffer[0]);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -85,6 +85,14 @@ uint32_t PDU::size() const {
|
||||
return sz;
|
||||
}
|
||||
|
||||
uint32_t PDU::advertised_size() const {
|
||||
uint32_t result = header_size() + trailer_size();
|
||||
if (inner_pdu_) {
|
||||
result += inner_pdu()->advertised_size();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void PDU::send(PacketSender &, const NetworkInterface &) {
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -65,7 +65,7 @@ const RadioTapParser::FieldMetadata RadioTapParser::RADIOTAP_METADATA[] = {
|
||||
};
|
||||
|
||||
const uint32_t RadioTapParser::MAX_RADIOTAP_FIELD = sizeof(RADIOTAP_METADATA) /
|
||||
sizeof(FieldMetadata) + 1;
|
||||
sizeof(FieldMetadata);
|
||||
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
TINS_BEGIN_PACK
|
||||
@@ -131,13 +131,10 @@ 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;
|
||||
if (TINS_UNLIKELY(offset > size)) {
|
||||
throw malformed_packet();
|
||||
}
|
||||
buffer += offset;
|
||||
}
|
||||
}
|
||||
@@ -281,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