diff --git a/include/arp.h b/include/arp.h index 11cc85e..904b183 100644 --- a/include/arp.h +++ b/include/arp.h @@ -241,9 +241,9 @@ namespace Tins { * Creates an ARP Request PDU and embeds it within a Layer 2 PDU ready to be * sent. * - * \param target IPv4Address with the target's IP. - * \param sender IPv4Address with the sender's IP. - * \param hw_snd uint8_t array of 6 bytes containing the sender's hardware address. + * \param target The target's IP address. + * \param sender The sender's IP address. + * \param hw_snd The sender's hardware address. * \return Returns a EthernetII containing the ARP Request. */ static EthernetII make_arp_request(ipaddress_type target, @@ -255,10 +255,10 @@ namespace Tins { * Creates an ARP Reply PDU and embeds it within a Layer 2 PDU ready to be * sent. * - * \param target IPv4Address with the target's IP. - * \param sender IPv4Address with the sender's IP. - * \param hw_tgt uint8_t array of 6 bytes containing the target's hardware address. - * \param hw_snd uint8_t array of 6 bytes containing the sender's hardware address. + * \param target The target's IP address. + * \param sender The sender's IP address. + * \param hw_tgt The target's hardware address. + * \param hw_snd The sender's hardware address. * \return Returns an EthetnetII containing the ARP Replay. */ static EthernetII make_arp_reply(ipaddress_type target, diff --git a/include/tcp.h b/include/tcp.h index 3a6c07d..4797260 100644 --- a/include/tcp.h +++ b/include/tcp.h @@ -64,14 +64,14 @@ namespace Tins { * These flags identify those supported by the TCP PDU. */ enum Flags { - FIN, - SYN, - RST, - PSH, - ACK, - URG, - ECE, - CWR + FIN = 1, + SYN = 2, + RST = 4, + PSH = 8, + ACK = 16, + URG = 32, + ECE = 64, + CWR = 128 }; /** @@ -208,6 +208,32 @@ namespace Tins { * \return The value of the flag. */ small_uint<1> get_flag(Flags tcp_flag); + + /** + * \brief Gets the value of a flag. + * + * \param tcp_flag The polled flag. + * \return The value of the flag. + */ + small_uint<1> get_flag(Flags tcp_flag) const; + + /** + * + * \brief Gets the flags' values. + * + * All of the set flags will be joined together into + * a 12 bit value. This way, you can check for multiple + * flags at the same time: + * + * \code + * TCP tcp = ...; + * if(tcp.flags() == (TCP::SYN | TCP::ACK)) + * // It's a SYN+ACK! + * \endcode + * + * \return The value of the flags field. + */ + small_uint<12> flags() const; /* Setters */ @@ -353,6 +379,25 @@ namespace Tins { */ void set_flag(Flags tcp_flag, small_uint<1> value); + /** + * \brief Sets the value of the flag fields. + * + * This method can be used to set several flags at the + * same time. + * + * \code + * TCP tcp = ...; + * tcp.flags(TCP::SYN | TCP::ACK); + * // ... + * // only set the ACK, keeping the rest of the old flags. + * tcp.flags(tcp.flags() | TCP::ACK); + * \endcode + * + * \param value The new value of the flags. + */ + void flags(small_uint<12> value); + + /** * \brief Adds a TCP option. * diff --git a/src/tcp.cpp b/src/tcp.cpp index 1cab55b..8b0376c 100644 --- a/src/tcp.cpp +++ b/src/tcp.cpp @@ -209,6 +209,10 @@ TCP::AltChecksums TCP::altchecksum() const { } small_uint<1> TCP::get_flag(Flags tcp_flag) { + return static_cast(*this).get_flag(tcp_flag); +} + +small_uint<1> TCP::get_flag(Flags tcp_flag) const { switch(tcp_flag) { case FIN: return _tcp.fin; @@ -240,6 +244,18 @@ small_uint<1> TCP::get_flag(Flags tcp_flag) { }; } +small_uint<12> TCP::flags() const { + return (_tcp.res1 << 8) | + (_tcp.cwr << 7) | + (_tcp.ece << 6) | + (_tcp.urg << 5) | + (_tcp.ack << 4) | + (_tcp.psh << 3) | + (_tcp.rst << 2) | + (_tcp.syn << 1) | + _tcp.fin; +} + void TCP::set_flag(Flags tcp_flag, small_uint<1> value) { switch(tcp_flag) { case FIN: @@ -269,6 +285,17 @@ void TCP::set_flag(Flags tcp_flag, small_uint<1> value) { }; } +void TCP::flags(small_uint<12> value) { + _tcp.fin = (value & FIN) ? 1 : 0; + _tcp.syn = (value & SYN) ? 1 : 0; + _tcp.rst = (value & RST) ? 1 : 0; + _tcp.psh = (value & PSH) ? 1 : 0; + _tcp.ack = (value & ACK) ? 1 : 0; + _tcp.urg = (value & URG) ? 1 : 0; + _tcp.ece = (value & ECE) ? 1 : 0; + _tcp.cwr = (value & CWR) ? 1 : 0; +} + void TCP::add_option(const option &opt) { _options.push_back(opt); internal_add_option(opt); diff --git a/tests/src/tcp.cpp b/tests/src/tcp.cpp index 63f7ac7..13c2002 100644 --- a/tests/src/tcp.cpp +++ b/tests/src/tcp.cpp @@ -134,6 +134,16 @@ TEST_F(TCPTest, SetFlag) { EXPECT_EQ(tcp.get_flag(TCP::CWR), 0); } +TEST_F(TCPTest, Flags) { + TCP tcp; + tcp.set_flag(TCP::SYN, 1); + tcp.set_flag(TCP::FIN, 1); + + EXPECT_EQ(tcp.flags(), (TCP::SYN | TCP::FIN)); + tcp.flags(TCP::PSH | TCP::RST); + EXPECT_EQ(tcp.flags(), (TCP::PSH | TCP::RST)); +} + TEST_F(TCPTest, MSS) { TCP tcp; tcp.mss(0x456f);