From b1f4a81afd822fce9d45d840b48cf233d8e61321 Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Wed, 31 Aug 2016 20:03:06 -0700 Subject: [PATCH] Allow TCP traffic (from unsecure ports) to pass through IPv6 filter (#508) This commit changes the `ipv6_filter` module to allow TCP traffic from unsecure dst port to pass through. It also adds a new module/class to parse TCP header and get different feilds. --- include/openthread.h | 1 + src/core/Makefile.am | 1 + src/core/net/ip6.hpp | 2 + src/core/net/ip6_filter.cpp | 38 ++++++--- src/core/net/tcp.hpp | 148 ++++++++++++++++++++++++++++++++++++ 5 files changed, 180 insertions(+), 10 deletions(-) create mode 100644 src/core/net/tcp.hpp diff --git a/include/openthread.h b/include/openthread.h index 510db6236..4aedc0dcc 100644 --- a/include/openthread.h +++ b/include/openthread.h @@ -95,6 +95,7 @@ extern "C" { * @defgroup core-tasklet Tasklet * @defgroup core-timer Timer * @defgroup core-udp UDP + * @defgroup core-tcp TCP * @defgroup core-link-quality Link Quality * * @} diff --git a/src/core/Makefile.am b/src/core/Makefile.am index 11e9a6b36..8a357138e 100644 --- a/src/core/Makefile.am +++ b/src/core/Makefile.am @@ -101,6 +101,7 @@ noinst_HEADERS = \ net/netif.hpp \ net/socket.hpp \ net/udp6.hpp \ + net/tcp.hpp \ thread/address_resolver.hpp \ thread/key_manager.hpp \ thread/link_quality.hpp \ diff --git a/src/core/net/ip6.hpp b/src/core/net/ip6.hpp index fec0f20fa..a72473f83 100644 --- a/src/core/net/ip6.hpp +++ b/src/core/net/ip6.hpp @@ -44,6 +44,7 @@ #include using Thread::Encoding::BigEndian::HostSwap16; +using Thread::Encoding::BigEndian::HostSwap32; namespace Thread { @@ -89,6 +90,7 @@ namespace Ip6 { enum IpProto { kProtoHopOpts = 0, ///< IPv6 Hop-by-Hop Option + kProtoTcp = 6, ///< Transmission Control Protocol kProtoUdp = 17, ///< User Datagram kProtoIp6 = 41, ///< IPv6 encapsulation kProtoRouting = 43, ///< Routing Header for IPv6 diff --git a/src/core/net/ip6_filter.cpp b/src/core/net/ip6_filter.cpp index 3a450b759..1df683d01 100644 --- a/src/core/net/ip6_filter.cpp +++ b/src/core/net/ip6_filter.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include namespace Thread { @@ -52,6 +53,7 @@ bool Filter::Accept(Message &aMessage) const bool rval = false; Header ip6; UdpHeader udp; + TcpHeader tcp; uint16_t dstport; // Allow all received IPv6 datagrams with link security enabled @@ -66,17 +68,33 @@ bool Filter::Accept(Message &aMessage) const // Allow only link-local unicast or multicast VerifyOrExit(ip6.GetDestination().IsLinkLocal() || ip6.GetDestination().IsLinkLocalMulticast(), ;); - // Allow only UDP traffic - VerifyOrExit(ip6.GetNextHeader() == kProtoUdp, ;); - - // Read UDP header - VerifyOrExit(sizeof(udp) == aMessage.Read(sizeof(ip6), sizeof(udp), &udp), ;); - dstport = udp.GetDestinationPort(); - - // Check for MLE traffic - if (dstport == Mle::kUdpPort) + switch (ip6.GetNextHeader()) { - ExitNow(rval = true); + case kProtoUdp: + // Read the UDP header and get the dst port + VerifyOrExit(sizeof(udp) == aMessage.Read(sizeof(ip6), sizeof(udp), &udp), ;); + + dstport = udp.GetDestinationPort(); + + // Allow MLE traffic + if (dstport == Mle::kUdpPort) + { + ExitNow(rval = true); + } + + break; + + case kProtoTcp: + // Read the TCP header and get the dst port + VerifyOrExit(sizeof(tcp) == aMessage.Read(sizeof(ip6), sizeof(tcp), &tcp), ;); + + dstport = tcp.GetDestinationPort(); + + break; + + default: + // Allow UDP or TCP traffic only + ExitNow(); } // Check against allowed unsecure port list diff --git a/src/core/net/tcp.hpp b/src/core/net/tcp.hpp new file mode 100644 index 000000000..e7acb13d8 --- /dev/null +++ b/src/core/net/tcp.hpp @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2016, Nest Labs, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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 A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file + * This file includes definitions for parsing TCP header. + */ + +#ifndef TCP_HPP_ +#define TCP_HPP_ + +#include +#include + +namespace Thread { +namespace Ip6 { + +/** + * @addtogroup core-tcp + * + * @brief + * This module includes definitions for parsing TCP header + * + * @{ + * + */ + +OT_TOOL_PACKED_BEGIN +struct TcpHeaderPoD +{ + uint16_t mSource; + uint16_t mDestination; + uint32_t mSequenceNumber; + uint32_t mAckNumber; + uint16_t mFlags; + uint16_t mWindow; + uint16_t mChecksum; + uint16_t mUrgentPointer; +} OT_TOOL_PACKED_END; + +/** + * This class implements TCP header parsing. + * + */ +OT_TOOL_PACKED_BEGIN +class TcpHeader: private TcpHeaderPoD +{ +public: + /** + * This method returns the TCP Source Port. + * + * @returns The TCP Source Port. + * + */ + uint16_t GetSourcePort(void) const { return HostSwap16(mSource); } + + /** + * This method returns the TCP Destination Port. + * + * @returns The TCP Destination Port. + * + */ + uint16_t GetDestinationPort(void) const { return HostSwap16(mDestination); } + + /** + * This method returns the TCP Sequence Number. + * + * @returns The TCP Sequence Number. + * + */ + uint32_t GetSequenceNumber(void) const { return HostSwap32(mSequenceNumber); } + + /** + * This method returns the TCP Acknowledgment Sequence Number. + * + * @returns The TCP Acknowledgment Sequence Number. + * + */ + uint32_t GetAcknowledgmentNumber(void) const { return HostSwap32(mAckNumber); } + + /** + * This method returns the TCP Flags. + * + * @returns The TCP Flags. + * + */ + uint16_t GetFlags(void) const { return HostSwap16(mFlags); } + + /** + * This method returns the TCP Window. + * + * @returns The TCP Window. + * + */ + uint16_t GetWindow(void) const { return HostSwap16(mWindow); } + + /** + * This method returns the TCP Checksum. + * + * @returns The TCP Checksum. + * + */ + uint16_t GetChecksum(void) const { return HostSwap16(mChecksum); } + + /** + * This method returns the TCP Urgent Pointer. + * + * @returns The TCP Urgent Pointer. + * + */ + uint16_t GetUrgentPointer(void) const { return HostSwap16(mUrgentPointer); } + +} OT_TOOL_PACKED_END; + +/** + * @} + * + */ + +} // namespace Ip6 +} // namespace Thread + +#endif // TCP_HPP_