فهرست منبع

ip_accelerator: Adding network_traffic

Network traffic generation and handling.

Change-Id: Ia1de9cf235d732f721f93d12cb11a69739683a72
Acked-by: Eliad Ben Yishay <[email protected]>
Signed-off-by: Ilia Lin <[email protected]>
Ilia Lin 3 سال پیش
والد
کامیت
bedfbae7e6

+ 1 - 1
kernel-tests/Makefile.am

@@ -1,6 +1,6 @@
 ACLOCAL_AMFLAGS = -Im4
 EXTRA_CFLAGS	 = -DDEBUG
-AM_CXXFLAGS = -Wall -Wundef -Wno-trigraphs -Werror
+AM_CXXFLAGS = -Wall -Wundef -Wno-trigraphs -Werror -std=c++14
 
 if USE_GLIB
     ipa_kernel_tests_CPPFLAGS  = $(AM_CFLAGS) -DUSE_GLIB -Dstrlcpy=g_strlcpy @GLIB_CFLAGS@

+ 7 - 0
kernel-tests/network_traffic/CMakeLists.txt

@@ -0,0 +1,7 @@
+cmake_minimum_required(VERSION 3.17)
+project(network_traffic)
+
+set(CMAKE_CXX_STANDARD 14)
+
+add_executable(network_traffic main.cpp Header.h UdpHeader.h IPv4Header.h QmapHeader.h UlsoPacket.h bits_utils.h
+        TransportHeader.h InternetHeader.h IPv6Header.h TcpHeader.h packets.h Ethernet2Header.h)

+ 76 - 0
kernel-tests/network_traffic/Ethernet2Header.h

@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2021 The Linux Foundation. All rights reserved.
+ *
+ * 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.
+ *  * Neither the name of The Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
+ */
+#ifndef NETWORK_TRAFFIC_ETHERNET2HEADER_H
+#define NETWORK_TRAFFIC_ETHERNET2HEADER_H
+
+
+#include "Header.h"
+
+#define ETHER_TYPE 16
+
+class Ethernet2Header: public Header {
+
+public:
+
+    const static unsigned int mSize {14};
+
+    DECLARE_BITSET(DestMac, 48, 0x54E1ADB47F9F);
+    DECLARE_BITSET(SourceMac, 48, 0xA0E0AF89A93F);
+    DECLARE_BITSET(EtherType, ETHER_TYPE, 0x0800);
+
+    vector<bool> asVector() const override {
+        vector<bool> outVec;
+        auto inserter = [](vector<bool>& vec, auto val){
+            vector<bool> valAsVector = bitsetToVector<val.size()>(val);
+            toggleLsbMsb(valAsVector, CHAR_BIT);
+            vec.insert(vec.end(), valAsVector.begin(), valAsVector.end());};
+
+        inserter(outVec, mDestMac);
+        inserter(outVec, mSourceMac);
+        inserter(outVec, mEtherType);
+        return outVec;
+    }
+
+    size_t size() const override {
+        return mSize;
+    }
+
+    string name() const override {
+        return string("Ethernet 2");
+    }
+
+    void streamFields(std::ostream &out) const override {
+        out << "mDestAddress: " << mDestMac.to_ullong() << ", "
+            << "SourceMac: " << mSourceMac.to_ullong() << ", "
+            << "mEtherType: " << mEtherType.to_ulong() << "\n";
+    }
+};
+
+
+#endif //NETWORK_TRAFFIC_ETHERNET2HEADER_H

+ 131 - 0
kernel-tests/network_traffic/Header.h

@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2021 The Linux Foundation. All rights reserved.
+ *
+ * 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.
+ *  * Neither the name of The Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
+ */
+#ifndef NETWORK_TRAFFIC_HEADER_H
+#define NETWORK_TRAFFIC_HEADER_H
+
+
+#include <vector>
+#include <climits>
+#include <cassert>
+#include <ostream>
+#include <bitset>
+#include <iostream>
+#include <iomanip>
+#include <netinet/in.h>
+#include "bits_utils.h"
+
+using std::vector;
+using std::bitset;
+using std::string;
+
+// make a variable name fit for member variable name convention.
+#define MEMBERIZE_VAR(name) m##name
+// declare a bitset variable with any number of bits and also an integer setter method.
+#define DECLARE_BITSET(name, numBits, defaultVal)                               \
+bitset<numBits> MEMBERIZE_VAR(name) {defaultVal};                               \
+void setm##name(unsigned int name) {                                            \
+    for(int i = 0; i < numBits; i++){                                           \
+    MEMBERIZE_VAR(name)[i] = getUintNthBit(name, i);                            \
+    }                                                                           \
+}                                                                               \
+static_assert(true, "")
+
+class Header {
+/**
+ * class Header is an abstract class that provides the interface that is needed for every protocol header.
+ * It also provides implementation of common operations for all protocol headers.
+ * Every protocol header class must inherit from this class directly or indirectly.
+ */
+public:
+
+    virtual vector<bool> asVector() const = 0;
+
+    virtual void streamFields(std::ostream &out) const = 0;
+
+    virtual size_t size() const = 0;
+
+    virtual string name() const = 0;
+
+    virtual size_t asArray(uint8_t* buf) const {
+        vector<bool> vec = asVector();
+        size_t resSize = vec.size() / CHAR_BIT + ((vec.size() % CHAR_BIT) > 0);
+
+        for(size_t i = 0; i < vec.size(); i++){
+            changeNthBit(buf[i/8], (i%8), vec[i]);
+        }
+        return resSize;
+    }
+
+    static uint16_t computeChecksum(uint16_t *buf, size_t count){
+        uint32_t sum = 0;
+
+        while(count > 1){
+            sum += *buf++;
+            count -= 2;
+        }
+        if(count > 0){
+            sum += ((*buf)&htons(0xFF00));
+        }
+        while(sum >> 16u){
+            sum = (sum & 0xffffu) + (sum >> 16u);
+        }
+        sum = ~sum;
+        return htons(static_cast<uint16_t>(sum));
+    }
+
+    virtual ~Header() = default;
+
+};
+
+template<typename T>
+inline std::ostream& operator<< (std::ostream &out, vector<T>const& v) {
+    out << "#Bytes=" << v.size() << std::endl;
+    for (size_t i = 0; i < v.size(); i++)
+        out << std::hex << std::setfill('0') << std::setw(2) << static_cast<int>(v[i]) << " ";
+    out << std::dec;
+    return out;
+}
+
+inline std::ostream& operator<< (std::ostream &out, Header const& h) {
+    vector<bool> headerAsVec = h.asVector();
+    size_t bufSize = headerAsVec.size() / CHAR_BIT + ((headerAsVec.size() % CHAR_BIT) > 0);
+    uint8_t buf[bufSize];
+
+    out << h.name() + " Header" << std::endl;
+    out << "#Bytes=" << h.size() << std::endl;
+    h.streamFields(out);
+    memset(buf, 0, bufSize);
+    h.asArray(buf);
+    for (size_t i = 0; i < bufSize; i++)
+        out << std::hex << std::setfill('0') << std::setw(2) << static_cast<int>(buf[i]) << " ";
+    out << std::dec;
+    return out;
+}
+
+#endif //NETWORK_TRAFFIC_HEADER_H

+ 168 - 0
kernel-tests/network_traffic/IPv4Header.h

@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2021 The Linux Foundation. All rights reserved.
+ *
+ * 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.
+ *  * Neither the name of The Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
+ */
+#ifndef NETWORK_TRAFFIC_IPV4HEADER_H
+#define NETWORK_TRAFFIC_IPV4HEADER_H
+
+#include "InternetHeader.h"
+
+using std::bitset;
+
+class IPv4Header: public InternetHeader {
+
+public:
+
+    const static unsigned int mSize {20};
+
+    explicit IPv4Header(const uint8_t *start) {
+        unsigned int bufIndex = 0;
+
+        setBitsFromArray<uint8_t, 4>(mVersion, start, bufIndex);
+        setBitsFromArray<uint8_t, 4>(mIhl, start, bufIndex);
+        setBitsFromArray<uint8_t, 6>(mDscp, start, bufIndex);
+        setBitsFromArray<uint8_t, 2>(mEcn, start, bufIndex);
+        setBitsFromArray<uint8_t, 16>(mTotalLength, start, bufIndex);
+        setBitsFromArray<uint8_t, 16>(mId, start, bufIndex);
+        setBitsFromArray<uint8_t, 3>(mFlags, start, bufIndex);
+        setBitsFromArray<uint8_t, 13>(mFragmentOffset, start, bufIndex);
+        setBitsFromArray<uint8_t, 8>(mTimeToLive, start, bufIndex);
+        setBitsFromArray<uint8_t, 8>(mProtocol, start, bufIndex);
+        setBitsFromArray<uint8_t, 16>(mHeaderChecksum, start, bufIndex);
+        setBitsFromArray<uint8_t, 32>(mSourceIpAddress, start, bufIndex);
+        setBitsFromArray<uint8_t, 32>(mDestIpAddress, start, bufIndex);
+    }
+
+    DECLARE_BITSET(Version, 4, 4);
+    DECLARE_BITSET(Ihl, 4, 5);
+    DECLARE_BITSET(Dscp, 6, 0);
+    DECLARE_BITSET(Ecn, 2, 0);
+    DECLARE_BITSET(TotalLength, 16, mSize);
+    DECLARE_BITSET(Id, 16, 65530);
+    DECLARE_BITSET(Flags, 3, 2);
+    DECLARE_BITSET(FragmentOffset, 13, 0);
+    DECLARE_BITSET(TimeToLive, 8, 64);
+    DECLARE_BITSET(Protocol, 8, 0);
+    DECLARE_BITSET(HeaderChecksum, 16, 0);
+    DECLARE_BITSET(SourceIpAddress, 32, 3232235793);
+    DECLARE_BITSET(DestIpAddress, 32, 3232235816);
+
+    IPv4Header() = default;
+
+    IPv4Header(const IPv4Header& iPv4Header) = default;
+
+    vector<bool> asVector() const override {
+        vector<bool> outVec;
+        auto inserter = [](vector<bool>& vec, auto val){
+            vector<bool> valAsVector = bitsetToVector<val.size()>(val);
+            vec.insert(vec.end(), valAsVector.begin(), valAsVector.end());};
+
+        inserter(outVec, mVersion);
+        inserter(outVec, mIhl);
+        inserter(outVec, mDscp);
+        inserter(outVec, mEcn);
+        inserter(outVec, mTotalLength);
+        inserter(outVec, mId);
+        inserter(outVec, mFlags);
+        inserter(outVec, mFragmentOffset);
+        inserter(outVec, mTimeToLive);
+        inserter(outVec, mProtocol);
+        inserter(outVec, mHeaderChecksum);
+        inserter(outVec, mSourceIpAddress);
+        inserter(outVec, mDestIpAddress);
+        toggleLsbMsb(outVec, 8);
+        return outVec;
+    }
+
+    size_t size() const override {
+        return mSize;
+    }
+
+    void adjust(size_t payloadSize, uint8_t protocol){
+        mTotalLength = size() + payloadSize;
+        mProtocol = protocol;
+        fixChecksum();
+    }
+
+    static size_t getEtherType(){
+        return 0x0800;
+    }
+
+    string name() const override {
+        return string("IPV4");
+    }
+
+    void streamFields(std::ostream &out) const override {
+        out << "Version: " << mVersion.to_ulong() << ", "
+            << "IHL: " << mIhl.to_ulong() << ", "
+            << "DSCP: " << mDscp.to_ulong() << ", "
+            << "ECN: " << mEcn.to_ulong() << ", "
+            << "Total Length: " << mTotalLength.to_ulong() << ", "
+            << "ID: " << mId.to_ulong() << ", "
+            << "Flags: " << mFlags.to_ulong() << ", "
+            << "Fragment Offset: " << mFragmentOffset.to_ulong() << ", "
+            << "TTL: " << mTimeToLive.to_ulong() << ", "
+            << "Protocol: " << mProtocol.to_ulong() << ", "
+            << "Checksum: " << mHeaderChecksum.to_ulong() << ", "
+            << "Source IP Address: " << expandIpv4(mSourceIpAddress.to_ulong()) << ", "
+            << "Destination IP Address: " << expandIpv4(mDestIpAddress.to_ulong()) << "\n";
+    }
+
+    void tcpChecksumPseudoHeader(uint8_t *pseudoHeaderBuf, const uint8_t *ipHeader) const {
+        memcpy(pseudoHeaderBuf, ipHeader + 12, 8);
+        pseudoHeaderBuf[8] = 0;
+        pseudoHeaderBuf[9] = 6;
+        *reinterpret_cast<uint16_t*>(pseudoHeaderBuf + 10) =
+                htons(static_cast<uint16_t>(mTotalLength.to_ulong() - (mIhl.to_ulong() << 2u)));
+    }
+
+    static size_t l3ChecksumPseudoHeaderSize(){
+        return 12;
+    }
+
+    void udpChecksumPseudoHeader(uint8_t *pseudoHeaderBuf, const uint8_t *ipHeader) const {
+        memcpy(pseudoHeaderBuf, ipHeader + 12, 8);
+        pseudoHeaderBuf[8] = 0;
+        pseudoHeaderBuf[9] = 17;
+        *reinterpret_cast<uint16_t*>(pseudoHeaderBuf + 10) =
+                htons(static_cast<uint16_t>(mTotalLength.to_ulong() - (mIhl.to_ulong() << 2u)));
+    }
+
+private:
+
+    void fixChecksum(){
+        mHeaderChecksum = 0;
+        uint8_t arr[mSize];
+
+        asArray(arr);
+        mHeaderChecksum = computeChecksum(reinterpret_cast<uint16_t*>(arr), mSize);
+    }
+
+};
+
+
+#endif //NETWORK_TRAFFIC_IPV4HEADER_H

+ 142 - 0
kernel-tests/network_traffic/IPv6Header.h

@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2021 The Linux Foundation. All rights reserved.
+ *
+ * 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.
+ *  * Neither the name of The Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
+ */
+#ifndef NETWORK_TRAFFIC_IPV6HEADER_H
+#define NETWORK_TRAFFIC_IPV6HEADER_H
+
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include "InternetHeader.h"
+
+class IPv6Header: public InternetHeader {
+
+public:
+
+    const static unsigned int mSize {40};
+
+    explicit IPv6Header(const uint8_t *start) {
+        unsigned int bufIndex = 0;
+        setBitsFromArray<uint8_t, 4>(mVersion, start, bufIndex);
+        setBitsFromArray<uint8_t, 8>(mTrafficClass, start, bufIndex);
+        setBitsFromArray<uint8_t, 20>(mFlowLabel, start, bufIndex);
+        setBitsFromArray<uint8_t, 16>(mPayloadLength, start, bufIndex);
+        setBitsFromArray<uint8_t, 8>(mNextHeader, start, bufIndex);
+        setBitsFromArray<uint8_t, 8>(mHopLimit, start, bufIndex);
+        setBitsFromArray<uint8_t, 128>(mSourceIpAddress, start, bufIndex);
+        setBitsFromArray<uint8_t, 128>(mDestIpAddress, start, bufIndex);
+    }
+
+    DECLARE_BITSET(Version, 4, 6);
+    DECLARE_BITSET(TrafficClass, 8, 0);
+    DECLARE_BITSET(FlowLabel, 20, 377341);
+    DECLARE_BITSET(PayloadLength, 16, 0);
+    DECLARE_BITSET(NextHeader, 8, 0);
+    DECLARE_BITSET(HopLimit, 8, 1);
+    DECLARE_BITSET(SourceIpAddress, 128, 3232236051);
+    DECLARE_BITSET(DestIpAddress, 128, 3232236136);
+
+    IPv6Header() = default;
+
+    vector<bool> asVector() const override {
+        vector<bool> outVec;
+        auto inserter = [](vector<bool>& vec, auto val){
+            vector<bool> valAsVector = bitsetToVector<val.size()>(val);
+            toggleLsbMsb(valAsVector, CHAR_BIT);
+            vec.insert(vec.end(), valAsVector.begin(), valAsVector.end());};
+
+        vector<bool> v = bitsetToVector<4>(mVersion);
+        vector<bool> v2 = bitsetToVector<8>(mTrafficClass);
+        v.insert(v.end(), v2.begin(), v2.end());
+        v2 = bitsetToVector<20>(mFlowLabel);
+        v.insert(v.end(), v2.begin(), v2.end());
+        toggleLsbMsb(v, CHAR_BIT);
+        outVec.insert(outVec.end(), v.begin(), v.end());
+        inserter(outVec, mPayloadLength);
+        inserter(outVec, mNextHeader);
+        inserter(outVec, mHopLimit);
+        inserter(outVec, mSourceIpAddress);
+        inserter(outVec, mDestIpAddress);
+        return outVec;
+    }
+
+    size_t size() const override {
+        return mSize;
+    }
+
+    void adjust(size_t payloadSize, uint8_t protocol){
+        mPayloadLength = payloadSize;
+        mNextHeader = protocol;
+    }
+
+    void tcpChecksumPseudoHeader(uint8_t* pseudoHeaderBuf, uint8_t* ipHeader) const {
+        memcpy(pseudoHeaderBuf, ipHeader + 8, 32);
+        *reinterpret_cast<uint32_t*>(pseudoHeaderBuf + 32) =
+                htons(static_cast<uint16_t>(mPayloadLength.to_ulong()));
+        *reinterpret_cast<uint32_t*>(pseudoHeaderBuf + 36) = 0;
+        pseudoHeaderBuf[39] = 6;
+    }
+
+    void udpChecksumPseudoHeader(uint8_t* pseudoHeaderBuf, const uint8_t* ipHeader) const {
+        memcpy(pseudoHeaderBuf, ipHeader + 8, 32);
+        *reinterpret_cast<uint32_t*>(pseudoHeaderBuf + 32) = htons(static_cast<uint16_t>(mPayloadLength.to_ulong()));
+        *reinterpret_cast<uint32_t*>(pseudoHeaderBuf + 36) = 0;
+        pseudoHeaderBuf[39] = 17;
+    }
+
+    static size_t l3ChecksumPseudoHeaderSize(){
+        return 40;
+    }
+
+    static size_t getEtherType(){
+        return 0x86dd;
+    }
+
+    string name() const override {
+        return string("IPV6");
+    }
+
+    void streamFields(std::ostream &out) const override {
+        uint8_t buf[32];
+        vector<bool> v = asVector();
+
+        v = vector<bool>(v.begin() + 8, v.end());
+        toArray(v, buf);
+        out << "Version: " << mVersion.to_ulong() << ", "
+            << "IHL: " << mTrafficClass.to_ulong() << ", "
+            << "DSCP: " << mFlowLabel.to_ulong() << ", "
+            << "ECN: " << mPayloadLength.to_ulong() << ", "
+            << "Total Length: " << mNextHeader.to_ulong() << ", "
+            << "ID: " << mHopLimit.to_ulong() << ", "
+            << "Source IP Address: " << expandIpv6(buf) << ", "
+            << "Destination IP Address: " << expandIpv6(buf) << "\n";
+    }
+
+};
+
+#endif //NETWORK_TRAFFIC_IPV6HEADER_H

+ 70 - 0
kernel-tests/network_traffic/InternetHeader.h

@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2021 The Linux Foundation. All rights reserved.
+ *
+ * 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.
+ *  * Neither the name of The Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
+ */
+#ifndef NETWORK_TRAFFIC_INTERNETHEADER_H
+#define NETWORK_TRAFFIC_INTERNETHEADER_H
+
+
+#include "Header.h"
+
+using std::string;
+
+class InternetHeader: public Header {
+/**
+ * class InternetHeader is an abstract class that inherits from class Header. It provides identification for all
+ * internet layer protocol headers and also some common functionality. Every internet layer protocol header must inherit
+ * from it directly or indirectly.
+ */
+protected:
+
+    string expandIpv4(unsigned int ip) const {
+        string ipString = std::to_string((ip >> 24u) & 0xffu);
+        ipString += "." + std::to_string((ip >> 16u) & 0xfu);
+        ipString += "." + std::to_string((ip >> 8u) & 0xffu);
+        ipString += "." + std::to_string(ip & 0xffu);
+        return ipString;
+    }
+
+    string expandIpv6(const uint8_t* buf) const {
+        char str[40];
+
+        snprintf(str, sizeof(str), "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
+                static_cast<int>(buf[0]), static_cast<int>(buf[1]),
+                static_cast<int>(buf[2]), static_cast<int>(buf[3]),
+                static_cast<int>(buf[4]), static_cast<int>(buf[5]),
+                static_cast<int>(buf[6]), static_cast<int>(buf[7]),
+                static_cast<int>(buf[8]), static_cast<int>(buf[9]),
+                static_cast<int>(buf[10]), static_cast<int>(buf[11]),
+                static_cast<int>(buf[12]), static_cast<int>(buf[13]),
+                static_cast<int>(buf[14]), static_cast<int>(buf[15]));
+        return string(str);
+    }
+};
+
+
+#endif //NETWORK_TRAFFIC_INTERNETHEADER_H

+ 126 - 0
kernel-tests/network_traffic/QmapHeader.h

@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2021 The Linux Foundation. All rights reserved.
+ *
+ * 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.
+ *  * Neither the name of The Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
+ */
+#ifndef NETWORK_TRAFFIC_QMAPHEADER_H
+#define NETWORK_TRAFFIC_QMAPHEADER_H
+
+#include "Header.h"
+
+using std::bitset;
+
+class QmapHeader: public Header {
+
+public:
+
+    const static size_t mSize {8};
+
+    DECLARE_BITSET(Pad, 6, 0);
+    DECLARE_BITSET(NextHdr, 1, 1);
+    DECLARE_BITSET(Cd, 1, 0);
+    DECLARE_BITSET(MuxId, 8, 0);
+    DECLARE_BITSET(PacketLength, 16, 0);
+    DECLARE_BITSET(ExtensionNextHeader, 1, 0);
+    DECLARE_BITSET(HeaderType, 7, 3);
+    DECLARE_BITSET(AdditionalHdrSize, 5, 0);
+    DECLARE_BITSET(Res, 1, 0);
+    DECLARE_BITSET(ZeroChecksum, 1, 0);
+    DECLARE_BITSET(IpIdCfg, 1, 0);
+    DECLARE_BITSET(SegmentSize, 16, 1);
+
+    explicit QmapHeader(const uint8_t *start) {
+        unsigned int bufIndex = 0;
+        setBitsFromArray<uint8_t, 6>(mPad, start, bufIndex);
+        setBitsFromArray<uint8_t, 1>(mNextHdr, start, bufIndex);
+        setBitsFromArray<uint8_t, 1>(mCd, start, bufIndex);
+        setBitsFromArray<uint8_t, 8>(mMuxId, start, bufIndex);
+        setBitsFromArray<uint8_t, 16>(mPacketLength, start, bufIndex);
+        setBitsFromArray<uint8_t, 1>(mExtensionNextHeader, start, bufIndex);
+        setBitsFromArray<uint8_t, 7>(mHeaderType, start, bufIndex);
+        setBitsFromArray<uint8_t, 5>(mAdditionalHdrSize, start, bufIndex);
+        setBitsFromArray<uint8_t, 1>(mRes, start, bufIndex);
+        setBitsFromArray<uint8_t, 1>(mZeroChecksum, start, bufIndex);
+        setBitsFromArray<uint8_t, 1>(mIpIdCfg, start, bufIndex);
+        setBitsFromArray<uint8_t, 16>(mSegmentSize, start, bufIndex);
+    }
+
+    QmapHeader() = default;
+
+    vector<bool> asVector() const override {
+        vector<bool> outVec;
+        auto inserter = [](vector<bool>& vec, auto val){
+            vector<bool> valAsVector = bitsetToVector<val.size()>(val);
+            vec.insert(vec.end(), valAsVector.begin(), valAsVector.end());};
+
+        inserter(outVec, mPad);
+        inserter(outVec, mNextHdr);
+        inserter(outVec, mCd);
+        inserter(outVec, mMuxId);
+        vector<bool> v = bitsetToVector<16>(mPacketLength);
+        toggleLsbMsb(v, v.size());
+        toggleEndianness(v, v.size());
+        outVec.insert(outVec.end(), v.begin(), v.end());
+        inserter(outVec, mExtensionNextHeader);
+        v = bitsetToVector<7>(mHeaderType);
+        toggleLsbMsb(v, v.size());
+        outVec.insert(outVec.end(), v.begin(), v.end());
+        inserter(outVec, mAdditionalHdrSize);
+        inserter(outVec, mRes);
+        inserter(outVec, mZeroChecksum);
+        inserter(outVec, mIpIdCfg);
+        v = bitsetToVector<16>(mSegmentSize);
+        toggleLsbMsb(v, v.size());
+        toggleEndianness(v, v.size());
+        outVec.insert(outVec.end(), v.begin(), v.end());
+        return outVec;
+    }
+
+    size_t size() const override {
+        return mSize;
+    }
+
+    string name() const override {
+        return string("QMAP");
+    }
+
+    void streamFields(std::ostream &out) const override {
+        out << "Padding: " << mPad.to_ulong() << ", "
+            << "Next Header: " << mNextHdr.to_ulong() << ", "
+            << "C\\D: " << mCd.to_ulong() << ", "
+            << "Mux ID: " << mMuxId.to_ulong() << ", "
+            << "Packet Length With Padding: " << mPacketLength.to_ulong() << ", "
+            << "Extension Next Header: " << mExtensionNextHeader.to_ulong() << ", "
+            << "Header Type: " << mHeaderType.to_ulong() << ", "
+            << "Additional Header Size: " << mAdditionalHdrSize.to_ulong() << ", "
+            << "Res: " << mRes.to_ulong() << ", "
+            << "Zero Checksum: " << mZeroChecksum.to_ulong() << ", "
+            << "IPID Cfg: " << mIpIdCfg.to_ulong() << ", "
+            << "Segment Size: " << mSegmentSize.to_ulong() << "\n";
+    }
+};
+
+#endif //NETWORK_TRAFFIC_QMAPHEADER_H

+ 207 - 0
kernel-tests/network_traffic/TcpHeader.h

@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2021 The Linux Foundation. All rights reserved.
+ *
+ * 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.
+ *  * Neither the name of The Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
+ */
+#ifndef NETWORK_TRAFFIC_TCPHEADER_H
+#define NETWORK_TRAFFIC_TCPHEADER_H
+
+
+#include "TransportHeader.h"
+
+class TcpHeader: public TransportHeader {
+
+public:
+
+    const static unsigned int mSizeBits {160};
+    const static unsigned int mSize {20};
+
+    DECLARE_BITSET(SourcePort, 16, 56789);
+    DECLARE_BITSET(DestPort, 16, 64886);
+    DECLARE_BITSET(SequenceNumber, 32, 1077280711);
+    DECLARE_BITSET(AckNumber, 32, 3090542765);
+    DECLARE_BITSET(DataOffset, 4, 5);
+    DECLARE_BITSET(Reserved, 3, 0);
+    DECLARE_BITSET(NS, 1, 0);
+    DECLARE_BITSET(CWR, 1, 0);
+    DECLARE_BITSET(ECE, 1, 0);
+    DECLARE_BITSET(URG, 1, 0);
+    DECLARE_BITSET(ACK, 1, 1);
+    DECLARE_BITSET(PSH, 1, 1);
+    DECLARE_BITSET(RST, 1, 0);
+    DECLARE_BITSET(SYN, 1, 0);
+    DECLARE_BITSET(FIN, 1, 0);
+    DECLARE_BITSET(WindowSize, 16, 473);
+    DECLARE_BITSET(Checksum, 16, 0);
+    DECLARE_BITSET(UrgentPtr, 16, 0);
+
+    TcpHeader() = default;
+
+    explicit TcpHeader(const uint8_t *start) {
+        unsigned int bufIndex = 0;
+
+        setBitsFromArray<uint8_t, 16>(mSourcePort, start, bufIndex);
+        setBitsFromArray<uint8_t, 16>(mDestPort, start, bufIndex);
+        setBitsFromArray<uint8_t, 32>(mSequenceNumber, start, bufIndex);
+        setBitsFromArray<uint8_t, 32>(mAckNumber, start, bufIndex);
+        setBitsFromArray<uint8_t, 4>(mDataOffset, start, bufIndex);
+        setBitsFromArray<uint8_t, 3>(mReserved, start, bufIndex);
+        setBitsFromArray<uint8_t, 1>(mNS, start, bufIndex);
+        setBitsFromArray<uint8_t, 1>(mCWR, start, bufIndex);
+        setBitsFromArray<uint8_t, 1>(mECE, start, bufIndex);
+        setBitsFromArray<uint8_t, 1>(mURG, start, bufIndex);
+        setBitsFromArray<uint8_t, 1>(mACK, start, bufIndex);
+        setBitsFromArray<uint8_t, 1>(mPSH, start, bufIndex);
+        setBitsFromArray<uint8_t, 1>(mRST, start, bufIndex);
+        setBitsFromArray<uint8_t, 1>(mSYN, start, bufIndex);
+        setBitsFromArray<uint8_t, 1>(mFIN, start, bufIndex);
+        setBitsFromArray<uint8_t, 16>(mWindowSize, start, bufIndex);
+        setBitsFromArray<uint8_t, 16>(mChecksum, start, bufIndex);
+        setBitsFromArray<uint8_t, 16>(mUrgentPtr, start, bufIndex);
+    }
+    vector<bool> asVector() const override {
+        vector<bool> outVec;
+        auto inserter = [](vector<bool>& vec, auto val){
+            vector<bool> valAsVector = bitsetToVector<val.size()>(val);
+            vec.insert(vec.end(), valAsVector.begin(), valAsVector.end());};
+        auto inserter2 = [](vector<bool>& vec, auto val){
+            vector<bool> valAsVector = bitsetToVector<val.size()>(val);
+            toggleLsbMsb(valAsVector, CHAR_BIT);
+            vec.insert(vec.end(), valAsVector.begin(), valAsVector.end());};
+
+        inserter2(outVec, mSourcePort);
+        inserter2(outVec, mDestPort);
+        inserter2(outVec, mSequenceNumber);
+        inserter2(outVec, mAckNumber);
+        vector<bool> v = bitsetToVector<4>(mDataOffset);
+        vector<bool> v2 = bitsetToVector<3>(mReserved);
+        v.insert(v.end(), v2.begin(), v2.end());
+        v2 = bitsetToVector<1>(mNS);
+        v.insert(v.end(), v2.begin(), v2.end());
+        outVec.insert(outVec.end(), v.rbegin(), v.rend());
+        v = bitsetToVector<1>(mCWR);
+        v2 = bitsetToVector<1>(mECE);
+        v.insert(v.end(), v2.begin(), v2.end());
+        v2 = bitsetToVector<1>(mURG);
+        v.insert(v.end(), v2.begin(), v2.end());
+        v2 = bitsetToVector<1>(mACK);
+        v.insert(v.end(), v2.begin(), v2.end());
+        v2 = bitsetToVector<1>(mPSH);
+        v.insert(v.end(), v2.begin(), v2.end());
+        v2 = bitsetToVector<1>(mRST);
+        v.insert(v.end(), v2.begin(), v2.end());
+        v2 = bitsetToVector<1>(mSYN);
+        v.insert(v.end(), v2.begin(), v2.end());
+        v2 = bitsetToVector<1>(mFIN);
+        v.insert(v.end(), v2.begin(), v2.end());
+        outVec.insert(outVec.end(), v.rbegin(), v.rend());
+        inserter2(outVec, mWindowSize);
+        inserter2(outVec, mChecksum);
+        inserter(outVec, mUrgentPtr);
+        return outVec;
+    }
+
+    uint32_t getSeqNum() const {
+        return static_cast<uint32_t>(mSequenceNumber.to_ulong());
+    }
+
+    size_t size() const override {
+        return TcpHeader::mSize;
+    }
+
+    static uint8_t protocolNum(){
+        return 6;
+    }
+
+    void adjust(uint8_t *checksumBuf, size_t count){
+        fixChecksum(checksumBuf, count);
+    }
+
+    void zeroChecksum(){
+        mChecksum = 0;
+    }
+
+    string name() const override {
+        return string("TCP");
+    }
+
+    void streamFields(std::ostream &out) const override {
+        out << "Source Port: " << mSourcePort.to_ulong() << ", "
+            << "Dest Port: " << mDestPort.to_ulong() << ", "
+            << "Sequence Number: " << mSequenceNumber.to_ulong() << ", "
+            << "Ack Number: " << mAckNumber.to_ulong() << ", "
+            << "Data Offset: " << mDataOffset.to_ulong() << ", "
+            << "Reserved: " << mReserved.to_ulong() << ", "
+            << "NS: " << mNS.to_ulong() << ", "
+            << "CWR: " << mCWR.to_ulong() << ", "
+            << "URG: " << mURG.to_ulong() << ", "
+            << "ACK: " << mACK.to_ulong() << ", "
+            << "PSH: " << mPSH.to_ulong() << ", "
+            << "RST: " << mRST.to_ulong() << ", "
+            << "SYN: " << mSYN.to_ulong() << ", "
+            << "FIN: " << mFIN.to_ulong() << ", "
+            << "Window Size: " << mWindowSize.to_ulong() << ", "
+            << "Checksum: " << mChecksum.to_ulong() << ", "
+            << "Urgent Ptr: " << mUrgentPtr << std::endl;
+    }
+
+    struct flags {
+        bool ns;
+        bool cwr;
+        bool ece;
+        bool urg;
+        bool ack;
+        bool psh;
+        bool rst;
+        bool syn;
+        bool fin;
+    };
+
+    flags getFlags() const {
+        return flags {
+            .ns = mNS.test(0),
+            .cwr = mCWR.test(0),
+            .ece = mECE.test(0),
+            .urg = mURG.test(0),
+            .ack = mACK.test(0),
+            .psh = mPSH.test(0),
+            .rst = mRST.test(0),
+            .syn = mSYN.test(0),
+            .fin = mFIN.test(0)
+        };
+    }
+
+private:
+
+    void fixChecksum(uint8_t *checksumBuf, size_t count){
+        mChecksum = 0;
+        mChecksum = computeChecksum(reinterpret_cast<uint16_t*>(checksumBuf), count);
+    }
+
+};
+
+
+#endif //NETWORK_TRAFFIC_TCPHEADER_H

+ 43 - 0
kernel-tests/network_traffic/TransportHeader.h

@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2021 The Linux Foundation. All rights reserved.
+ *
+ * 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.
+ *  * Neither the name of The Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
+ */
+#ifndef NETWORK_TRAFFIC_TRANSPORTHEADER_H
+#define NETWORK_TRAFFIC_TRANSPORTHEADER_H
+
+#include "Header.h"
+
+
+class TransportHeader: public Header {
+/**
+ * class TransportHeader is an abstract class that inherits from class Header. It provides identification for all
+ * transport layer protocol headers. Every transport layer protocol header must inherit from it directly or indirectly.
+ */
+};
+
+
+#endif //NETWORK_TRAFFIC_TRANSPORTHEADER_H

+ 119 - 0
kernel-tests/network_traffic/UdpHeader.h

@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2021 The Linux Foundation. All rights reserved.
+ *
+ * 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.
+ *  * Neither the name of The Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
+ */
+#ifndef NETWORK_TRAFFIC_UDPHEADER_H
+#define NETWORK_TRAFFIC_UDPHEADER_H
+
+#include "TransportHeader.h"
+
+class UdpHeader: public TransportHeader {
+
+public:
+
+    const static unsigned int mSize {8};
+
+    DECLARE_BITSET(SourcePort, 16, 1985);
+    DECLARE_BITSET(DestPort, 16, 1985);
+    DECLARE_BITSET(Length, 16, 0);
+    DECLARE_BITSET(Checksum, 16, 0);
+
+    explicit UdpHeader(const uint8_t *start) {
+        unsigned int bufIndex = 0;
+
+        setBitsFromArray<uint8_t, 16>(mSourcePort, start, bufIndex);
+        setBitsFromArray<uint8_t, 16>(mDestPort, start, bufIndex);
+        setBitsFromArray<uint8_t, 16>(mLength, start, bufIndex);
+        setBitsFromArray<uint8_t, 16>(mChecksum, start, bufIndex);
+    }
+
+    UdpHeader(uint16_t sourcePort, uint16_t destPort, uint16_t length, uint16_t checksum) :
+            mSourcePort(sourcePort),
+            mDestPort(destPort),
+            mLength(length),
+            mChecksum(checksum) {}
+
+    UdpHeader(const UdpHeader& udpHeader) = default;
+
+    UdpHeader() = default;
+
+    vector<bool> asVector() const override {
+        vector<bool> outVec;
+        auto inserter2 = [&outVec](bitset<16>  val){
+            vector<bool> valAsVector = bitsetToVector<16>(val);
+            toggleLsbMsb(valAsVector, CHAR_BIT);
+            outVec.insert(outVec.end(), valAsVector.begin(), valAsVector.end());};
+
+        inserter2(mSourcePort);
+        inserter2(mDestPort);
+        inserter2(mLength);
+        inserter2(mChecksum);
+        return outVec;
+    }
+
+    size_t size() const override {
+        return mSize;
+    }
+
+    static uint8_t protocolNum(){
+        return 17;
+    }
+
+    void adjust(const size_t payloadSize){
+        mLength = mSize + payloadSize;
+    }
+
+    void adjust(uint8_t *checksumBuf, size_t count, size_t payloadSize){
+        mLength = mSize + payloadSize;
+        fixChecksum(checksumBuf, count);
+    }
+
+    void zeroChecksum(){
+        mChecksum = 0;
+    }
+
+    string name() const override {
+        return string("UDP");
+    }
+
+    void streamFields(std::ostream &out) const override {
+        out << "Source port: " << mSourcePort.to_ulong() << ", "
+            << "Destination port: " << mDestPort.to_ulong() << ", "
+            << "Length: " << mLength.to_ulong() << ", "
+            << "Checksum: " << mChecksum.to_ulong() << "\n";
+    }
+
+private:
+
+    void fixChecksum(uint8_t *checksumBuf, size_t count){
+        mChecksum = 0;
+        mChecksum = computeChecksum(reinterpret_cast<uint16_t*>(checksumBuf), count);
+    }
+
+};
+
+#endif //NETWORK_TRAFFIC_UDPHEADER_H

+ 415 - 0
kernel-tests/network_traffic/UlsoPacket.h

@@ -0,0 +1,415 @@
+/*
+ * Copyright (c) 2021 The Linux Foundation. All rights reserved.
+ *
+ * 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.
+ *  * Neither the name of The Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
+ */
+#ifndef NETWORK_TRAFFIC_ULSOPACKET_H
+#define NETWORK_TRAFFIC_ULSOPACKET_H
+
+
+#include <algorithm>
+#include <utility>
+#include <stdexcept>
+#include "QmapHeader.h"
+#include "UdpHeader.h"
+#include "TcpHeader.h"
+#include "IPv4Header.h"
+#include "IPv6Header.h"
+#include "packets.h"
+#include "Ethernet2Header.h"
+
+template <typename Transport=UdpHeader, typename Internet=IPv4Header>
+class UlsoPacket {
+
+    static_assert(std::is_base_of<TransportHeader, Transport>::value,
+            "Transport is not derived from TransportHeader");
+    static_assert(std::is_base_of<InternetHeader, Internet>::value,
+            "Internet is not derived from InternetHeader");
+
+private:
+
+    static constexpr uint8_t qmapIPv4UdpPacketNoSeg[] = {
+            //C=0,Next Header=1,PAD=b'63,MUXID=0,Packet length=30
+            0X7f, 0x00, 0x00, 0x1e,//QMAP header
+            //type=3,Next Header=0,IPIDCfg=1,Zero Checksum=1,Additional header size=0,segment size=2
+            0X06, 0xc0, 0x00, 0x02,//QMAP header extension
+            //IPv4 header
+            0x45, 0x00, 0x00, 0x1e,//version=4,IHL=5,DSCP=0,ECN=0,length=30
+            0x00, 0x00, 0x00, 0x00,//id=0,flags=0,fragment offset=0
+            0xff, 0x11, 0x36, 0x03,//TTL=255,Protocol=17 (TCP),checksum=
+            0xc0, 0xa8, 0x02, 0x13,//IPv4 SRC Addr 192.168.2.19
+            0xc0, 0xa8, 0x02, 0x68,//IPv4 DST Addr 192.168.2.104
+            //UDP header
+            0x04, 0x57, 0x08, 0xae,//source port=1111, destination port=2222
+            0x00, 0x0a, 0x00, 0x00,//length=10,checksum=
+            //payload
+            0x00, 0x01
+    };
+
+    /**
+     * Resembles ULSO related endpoint configurations.
+     */
+    unsigned int mMinId {0};
+    unsigned int mMaxId {65535};
+
+    bool mIsSegmented {false};
+
+public:
+
+    static constexpr int maxSize {65536};//64 KB
+
+    QmapHeader mQmapHeader;
+    Ethernet2Header mEthernetHeader;
+    Internet mInternetHeader;
+    bool mEthernetHeaderValid {false};
+    Transport mTransportHeader;
+    vector<uint8_t> mPayload {};
+
+    UlsoPacket(unsigned int segmentSize, unsigned int payloadSize, bool ethernetHeaderValid=false):
+        mEthernetHeaderValid(ethernetHeaderValid){
+        bool first = true;
+        uint32_t seqNum = 0;
+
+        mQmapHeader.setmSegmentSize(segmentSize);
+        if(mEthernetHeaderValid){
+            mEthernetHeader.setmEtherType(mInternetHeader.getEtherType());
+        }
+        mPayload = vector<uint8_t>(payloadSize);
+        for(unsigned int i = 0; i < payloadSize; i++){
+            mPayload[i] = i % UINT8_MAX;
+        }
+        mInternetHeader.adjust(mTransportHeader.size() + mPayload.size(), mTransportHeader.protocolNum());
+        mQmapHeader.setmPacketLength(mInternetHeader.size() + mTransportHeader.size() + mPayload.size());
+        adjustHeader(mTransportHeader, seqNum, first);
+    }
+
+    UlsoPacket(unsigned int segmentSize, uint8_t* payload, unsigned int payloadSize){
+        bool first = true;
+        uint32_t seqNum = 0;
+
+        mQmapHeader.setmSegmentSize(segmentSize);
+        mPayload  = vector<uint8_t>{payload, payload + payloadSize};
+        mInternetHeader.adjust(mTransportHeader.size() + mPayload.size(), mTransportHeader.protocolNum());
+        mQmapHeader.setmPacketLength(mInternetHeader.size() + mTransportHeader.size() + mPayload.size());
+        adjustHeader(mTransportHeader, seqNum, first);
+    }
+
+    size_t size() const {
+        return (!isSegmented() * mQmapHeader.size()) + (mEthernetHeaderValid * mEthernetHeader.size())
+        + mInternetHeader.size() + mTransportHeader.size() + mPayload.size();
+    }
+
+    UlsoPacket(const QmapHeader& qmapHeader, const Internet& iPv4Header, const Transport& udpHeader,
+               const vector<uint8_t>& payload) :
+            mQmapHeader(qmapHeader),
+            mInternetHeader(iPv4Header),
+            mTransportHeader(udpHeader),
+            mPayload(payload) {}
+
+    explicit UlsoPacket(size_t bufLen, uint8_t *buf=const_cast<uint8_t *>(qmapIPv4UdpPacketNoSeg)) {
+        size_t curIndex = 0;
+
+        mQmapHeader = QmapHeader(buf + curIndex);
+        curIndex += mQmapHeader.size();
+        mInternetHeader = Internet(buf + curIndex);
+        curIndex += mInternetHeader.size();
+        mTransportHeader = Transport(buf + curIndex);
+        curIndex += mTransportHeader.size();
+        mPayload = vector<uint8_t>();
+        while(curIndex < bufLen){
+            mPayload.emplace_back(buf[curIndex]);
+            curIndex++;
+        }
+    }
+
+    UlsoPacket(){
+        mQmapHeader.setmPacketLength(mInternetHeader.size() + mTransportHeader.size() + mPayload.size());
+        mInternetHeader.adjust(mTransportHeader.size() + mPayload.size(), mTransportHeader.protocolNum());
+        adjustHeader(mTransportHeader);
+    }
+
+    vector<bool> asVector() const {
+        vector<bool> outVec;
+        auto concatenateFunc = [](vector<bool>& v1, const vector<bool>& v2){
+            v1.insert(v1.end(), v2.begin(), v2.end());
+        };
+
+        if(!mIsSegmented){
+            concatenateFunc(outVec, mQmapHeader.asVector());
+        }
+        if(mEthernetHeaderValid){
+            concatenateFunc(outVec, mEthernetHeader.asVector());
+        }
+        concatenateFunc(outVec, mInternetHeader.asVector());
+        concatenateFunc(outVec, mTransportHeader.asVector());
+        std::for_each(mPayload.cbegin(), mPayload.cend(), [&outVec](char c){
+            for (int i = SIZE_OF_BITS(c) - 1; i >= 0; i--)
+                outVec.emplace_back((c & ( 1 << i )) >> i); // NOLINT(hicpp-signed-bitwise)
+        });
+        return outVec;
+    }
+
+    uint8_t* asArray() const {
+        vector<bool> vec = asVector();
+        size_t resSize = vec.size() / CHAR_BIT + ((vec.size() % CHAR_BIT) > 0);
+        auto *outArr = new uint8_t[resSize];
+
+        asArray(outArr);
+        return outArr;
+    }
+
+    size_t asArray(uint8_t* buf) const {
+        vector<bool> vec = asVector();
+        size_t bufSize = vec.size() / CHAR_BIT + ((vec.size() % CHAR_BIT) > 0);
+
+        memset(buf, 0, bufSize);
+        if(!isSegmented()){
+            buf += mQmapHeader.asArray(buf);
+        }
+        if(mEthernetHeaderValid){
+            buf += mEthernetHeader.asArray(buf);
+        }
+        buf += mInternetHeader.asArray(buf);
+        buf += mTransportHeader.asArray(buf);
+        for(auto val: mPayload){
+            *buf++ = val;
+        }
+        return bufSize;
+    }
+
+    vector<UlsoPacket> segment() const {
+        bool first = true;
+        uint32_t seqNum = 0;
+
+        if(isSegmented()){
+            throw std::logic_error("A segmented packet cannot be segmented again!");
+        }
+        unsigned int segmentSize = mQmapHeader.mSegmentSize.to_ulong();
+        vector<vector<uint8_t>> payloads = segmentPayload(segmentSize, mPayload);
+        UlsoPacket ulsoCopy(*this);
+        fixFlags(ulsoCopy.mTransportHeader);
+        vector<UlsoPacket> outVec = vector<UlsoPacket>(payloads.size(), ulsoCopy);
+        for(size_t i = 0; i < outVec.size(); i++){
+            UlsoPacket& p = outVec[i];
+            p.mPayload = payloads[i];
+        }
+        if(!outVec.empty()){
+            fixLastSegmentFlags(outVec[outVec.size() - 1].mTransportHeader);
+        }
+        if(mQmapHeader.mIpIdCfg == 0){
+            fixIpId(outVec, mMinId, mMaxId);
+        }
+        for(UlsoPacket& p: outVec){
+            p.mInternetHeader.adjust(p.mTransportHeader.size() + p.mPayload.size(), p.mTransportHeader.protocolNum());
+            p.adjustHeader(p.mTransportHeader, seqNum, first);
+            p.mIsSegmented = true;
+        }
+        return outVec;
+    }
+
+    bool isSegmented() const {
+        return mIsSegmented;
+    }
+
+    void setIpId(const uint16_t id){
+        changeIpId(mInternetHeader, mTransportHeader);
+    }
+
+    void changeIpId(IPv4Header& iPv4Header, UdpHeader& udpHeader){
+        bool first = true;
+        uint32_t seqNum = 0;
+
+        mInternetHeader.adjust(mTransportHeader.size() + mPayload.size(), mTransportHeader.protocolNum());
+        adjustHeader(mTransportHeader, seqNum, first);
+    }
+
+    void changeIpId(IPv4Header& iPv4Header, TcpHeader& tcpHeader){
+        bool first = true;
+        uint32_t seqNum = 0;
+
+        mInternetHeader.adjust(mTransportHeader.size() + mPayload.size(), mTransportHeader.protocolNum());
+        adjustHeader(mTransportHeader, seqNum, first);
+    }
+
+private:
+
+    static void fixFlags(TcpHeader& tcpHeader){
+        tcpHeader.setmFIN(0);
+        tcpHeader.setmPSH(0);
+        tcpHeader.setmRST(0);
+        tcpHeader.setmCWR(0);
+    }
+
+    static void fixFlags(UdpHeader& udpHeader){}
+
+    void fixLastSegmentFlags(TcpHeader& tcpHeader) const {
+        TcpHeader::flags flags = mTransportHeader.getFlags();
+
+        tcpHeader.setmFIN(flags.fin);
+        tcpHeader.setmPSH(flags.psh);
+        tcpHeader.setmRST(flags.rst);
+        tcpHeader.setmCWR(flags.cwr);
+    }
+
+    void fixLastSegmentFlags(UdpHeader& udpHeader) const {}
+
+    static vector<vector<uint8_t>> segmentPayload(unsigned long segmentSize, const vector<uint8_t>& payload) {
+        vector<vector<uint8_t>> outVec;
+
+        for(size_t i = 0; i < payload.size(); i += segmentSize) {
+            auto last = std::min<size_t>(static_cast<size_t>(payload.size()), i + segmentSize);
+            auto index = i / segmentSize;
+
+            outVec.emplace_back(vector<uint8_t>());
+            auto& vec = outVec[index];
+            vec.reserve(last - i);
+            move(payload.begin() + i, payload.begin() + last, back_inserter(vec));
+        }
+        return outVec;
+    }
+
+    void adjustHeader(TcpHeader& tcpHeader, uint32_t& seqNum, bool& first){
+        tcpHeader.zeroChecksum();
+        if(first){
+            seqNum = tcpHeader.getSeqNum();
+            first = false;
+        }
+        tcpHeader.setmSequenceNumber(seqNum);
+        seqNum += mPayload.size();
+        size_t checksumBufSize = mInternetHeader.l3ChecksumPseudoHeaderSize() + mTransportHeader.size() + mPayload.size();
+        uint8_t checksumBuf[checksumBufSize];
+        memset(checksumBuf, 0, checksumBufSize);
+        uint8_t *checksumBufPtr = checksumBuf;
+
+        size_t ulsoBufSize = size();
+        uint8_t ulsoBuf[ulsoBufSize];
+        memset(ulsoBuf, 0, ulsoBufSize);
+        asArray(ulsoBuf);
+        size_t ipOffset = mQmapHeader.size() + mEthernetHeaderValid * mEthernetHeader.size();
+        mInternetHeader.tcpChecksumPseudoHeader(checksumBuf, ulsoBuf + ipOffset);
+        checksumBufPtr += mInternetHeader.l3ChecksumPseudoHeaderSize();
+        checksumBufPtr += tcpHeader.asArray(checksumBufPtr);
+        for(auto val: mPayload){
+            *checksumBufPtr++ = val;
+        }
+        mTransportHeader.adjust(checksumBuf, checksumBufSize);
+    }
+
+    void adjustHeader(UdpHeader& udpHeader, uint32_t seqNum, bool first){
+        udpHeader.zeroChecksum();
+        if(mQmapHeader.mZeroChecksum.test(0)){
+            mTransportHeader.adjust(mPayload.size());
+        } else{
+            udpHeader.setmLength(udpHeader.size() + mPayload.size());
+            size_t checksumBufSize = mInternetHeader.l3ChecksumPseudoHeaderSize() + mTransportHeader.size() + mPayload.size();
+            uint8_t checksumBuf[checksumBufSize];
+            memset(checksumBuf, 0, checksumBufSize);
+            uint8_t *checksumBufPtr = checksumBuf;
+
+            size_t ulsoBufSize = size();
+            uint8_t ulsoBuf[ulsoBufSize];
+            memset(ulsoBuf, 0, ulsoBufSize);
+            asArray(ulsoBuf);
+            size_t ipOffset = mQmapHeader.size() + mEthernetHeaderValid * mEthernetHeader.size();
+            mInternetHeader.udpChecksumPseudoHeader(checksumBuf, ulsoBuf + ipOffset);
+            checksumBufPtr += mInternetHeader.l3ChecksumPseudoHeaderSize();
+            checksumBufPtr += udpHeader.asArray(checksumBufPtr);
+            for(auto val: mPayload){
+                *checksumBufPtr++ = val;
+            }
+            mTransportHeader.adjust(checksumBuf, checksumBufSize, mPayload.size());
+        }
+    }
+
+    template <typename T, typename I>
+    friend std::ostream& operator<< (std::ostream &out, UlsoPacket<Transport, Internet> const& packet);
+};
+
+template <typename Transport, typename Internet>
+constexpr uint8_t UlsoPacket<Transport, Internet>::qmapIPv4UdpPacketNoSeg[];
+
+template <typename Transport, typename Internet>
+inline std::ostream& operator << (std::ostream &out, UlsoPacket<Transport, Internet> const& packet) {
+    out << "ULSO Packet\n" << "#Bytes=" << packet.size() << std::endl;
+    if(!packet.isSegmented()){
+        out << packet.mQmapHeader << std::endl;
+    } else {
+        out << "QMAP header removed in segmentation\n";
+    }
+    if(packet.mEthernetHeaderValid){
+        out << packet.mEthernetHeader << std::endl;
+    }
+    out << packet.mInternetHeader << std::endl;
+    out << packet.mTransportHeader << std::endl;
+    out << "Payload\n" << packet.mPayload;
+    return out;
+}
+
+template<typename Transport, typename Internet>
+void fixIpId(vector<UlsoPacket<Transport, Internet>>& v, unsigned int minId, unsigned int maxId) {
+    return;
+}
+
+template<>
+void fixIpId<UdpHeader, IPv4Header>(vector<UlsoPacket<UdpHeader, IPv4Header>>& v, unsigned int minId, unsigned int maxId) {
+    unsigned int curId = 0;
+
+    if(!v.empty()){
+        curId = std::max(static_cast<unsigned int>(v[0].mInternetHeader.mId.to_ulong()), minId) % (maxId + 1);
+    }
+    for (auto &p: v) {
+        p.mInternetHeader.setmId(curId);
+        curId++;
+        if (curId == (maxId + 1)) curId = minId;
+    }
+}
+
+template<>
+void fixIpId<TcpHeader, IPv4Header>(vector<UlsoPacket<TcpHeader, IPv4Header>>& v, unsigned int minId, unsigned int maxId) {
+    unsigned int curId = 0;
+
+    if(!v.empty()){
+        curId = std::max(static_cast<unsigned int>(v[0].mInternetHeader.mId.to_ulong()), minId) % (maxId + 1);
+    }
+    for (auto &p: v) {
+        p.mInternetHeader.setmId(curId);
+        curId++;
+        if (curId == (maxId + 1)) curId = minId;
+    }
+}
+
+template<typename Internet, typename Transport>
+bool changeIpId(Internet& ipHeader, uint16_t id){
+    return false;
+}
+
+template<>
+bool changeIpId<IPv4Header, UdpHeader>(IPv4Header& iPv4Header, uint16_t id){
+    iPv4Header.setmId(id);
+    return true;
+}
+
+#endif //NETWORK_TRAFFIC_ULSOPACKET_H

+ 190 - 0
kernel-tests/network_traffic/bits_utils.h

@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2021 The Linux Foundation. All rights reserved.
+ *
+ * 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.
+ *  * Neither the name of The Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
+ */
+#ifndef NETWORK_TRAFFIC_BITS_UTILS_H
+#define NETWORK_TRAFFIC_BITS_UTILS_H
+
+
+#include <vector>
+#include <bitset>
+
+
+#define SIZE_OF_BITS(x) (sizeof(x) * CHAR_BIT)
+
+
+using std::vector;
+using std::bitset;
+
+/**
+ * bitwise get the n-th bit of val.
+ * @tparam T - some unsigned integer type
+ * @param num - number to get the bit from
+ * @param n - index of bit to return
+ * @return 1 if the n-th bit of val is 1, 0 otherwise
+ */
+template<typename T>
+bool getUintNthBit(T num, unsigned int n) {
+    assert(n >= 0 && n < (SIZE_OF_BITS(num)));
+    return (num & ( 1 << n )) >> n; // NOLINT(hicpp-signed-bitwise)
+}
+
+/**
+ * Transforms a vector<bool> from a bitset<N>.
+ * @tparam N - Number of bits.
+ * @param bits - Bits to transform.
+ * @return vector<bool> that represents the bitset
+ */
+template<int N>
+static vector<bool> bitsetToVector(const bitset<N>& bits){
+    vector<bool> outVec;
+
+    for(int i = 0; i < N; i++){
+        outVec.insert(outVec.begin(), bits[i]);
+    }
+    return outVec;
+}
+
+template<typename T>
+static vector<bool> uintToVector(T n) {
+    vector<bool> outVec;
+
+    for (int i = 0; i < SIZE_OF_BITS(n); i++) {
+        outVec.insert(outVec.begin(), getUintNthBit(n, i));
+    }
+    return outVec;
+}
+
+/**
+ * Copies a range of bits in an array of integer-like elements to a bitset.
+ * The range is [bufIndex, N-1]
+ * @tparam T - The type of the elements in the array.
+ * @tparam N - The size of the range.
+ * @param bits - the bits object to copy into.
+ * @param buf - Input array.
+ * @param bufIndex - starting bit.
+ */
+template<typename T, unsigned int N>
+static void setBitsFromArray(bitset<N>& bits, const T* buf, unsigned int& bufIndex) {
+    for (int i = N-1; i >= 0; i--) {
+        unsigned int bitIndex = SIZE_OF_BITS(T) - 1 - (bufIndex % SIZE_OF_BITS(T));
+        bool bit = getUintNthBit(*(buf + (bufIndex / 8)), bitIndex);
+        bits.set(i, bit);
+        bufIndex++;
+    }
+}
+
+template<typename T, unsigned int N>
+static void setBitsFromArray(bitset<N>& bits, const T* buf) {
+    unsigned int idx = 0;
+
+    for (int i = N - 1; i >= 0; i--) {
+        unsigned int bitIndex = SIZE_OF_BITS(T) - 1 - (idx % SIZE_OF_BITS(T));
+        bool bit = getUintNthBit(*(buf + (idx / 8)), bitIndex);
+        bits.set(i, bit);
+        idx++;
+    }
+}
+
+template<typename T>
+void setNthBit(T& num, unsigned int n){
+    assert(n < SIZE_OF_BITS(num));
+    num |= 1UL << n;
+}
+
+/**
+ * Clears the n-th bit of num
+ * @tparam T - the type of num
+ * @param num - the number to clear a bit on
+ * @param n - the index of the bit to clear
+ */
+template<typename T>
+void clearNthBit(T& num, unsigned int n){
+    assert(n < SIZE_OF_BITS(num));
+    num &= ~(1UL << n);
+}
+
+template<typename T>
+void changeNthBit(T& num, unsigned int n, bool bitVal){
+    assert(n < SIZE_OF_BITS(num));
+    if(bitVal){
+        setNthBit(num, n);
+    } else {
+        clearNthBit(num, n);
+    }
+}
+
+void toggleLsbMsb(vector<bool>& v, unsigned int intervalSize){
+    if(v.size() % intervalSize != 0){
+        return;
+    }
+    for(size_t i = 0; i < v.size(); i += intervalSize){
+        vector<bool> tmp(intervalSize);
+        for(unsigned int j = 0; j < intervalSize; j++){
+            tmp[j] = v[i + intervalSize - 1 - j];
+        }
+        for(unsigned int j = 0; j < intervalSize; j++){
+            v[i + j] = tmp[j];
+        }
+    }
+}
+
+void toggleEndianness(vector<bool>& v, unsigned int wordSize){
+    if(wordSize % CHAR_BIT != 0 || v.size() % wordSize != 0){
+        return;
+    }
+    for(size_t i = 0; i < v.size(); i += wordSize){
+        vector<bool> tmp(wordSize);
+        for(size_t j = 0; j < wordSize; j += CHAR_BIT){
+            for(size_t k = 0; k < CHAR_BIT; k++){
+                unsigned int readIdx = i + wordSize - j - CHAR_BIT + k;
+                unsigned int writeIdx = j + k;
+                tmp[writeIdx] = v[readIdx];
+            }
+        }
+        for(unsigned int j = 0; j < wordSize; j++){
+            v[i + j] = tmp[j];
+        }
+    }
+}
+
+template<typename T, typename W>
+W bitWiseConcatenate(T left, T right){
+    W wide = (static_cast<W>(left) << CHAR_BIT * (sizeof(W) - sizeof(T))) | right;
+    return wide;
+}
+
+template<typename IntType>
+void toArray(vector<bool>& v, IntType* buf){
+    for(unsigned int i = 0; i < v.size(); i++){
+        if(v[i]){
+            setNthBit(buf[i / SIZE_OF_BITS(*buf)], i % SIZE_OF_BITS(*buf));
+        }
+    }
+}
+
+#endif //NETWORK_TRAFFIC_BITS_UTILS_H

+ 205 - 0
kernel-tests/network_traffic/main.cpp

@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2021 The Linux Foundation. All rights reserved.
+ *
+ * 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.
+ *  * Neither the name of The Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
+ */
+#include <iostream>
+#include <string>
+#include <cstring>
+#include "UlsoPacket.h"
+
+using std::cout;
+using std::endl;
+using std::string;
+
+static uint8_t buf[UlsoPacket<UdpHeader>::maxSize];
+
+static uint8_t qmapIPv4UdpPacketNoSeg[] = {
+        //C=0,Next Header=1,PAD=b'63,MUXID=0,Packet length=30
+        0X7f, 0x00, 0x00, 0x1e,//QMAP header
+        //type=3,Next Header=0,IPIDCfg=1,Zero Checksum=1,Additional header size=0,segment size=2
+        0X06, 0xc0, 0x00, 0x02,//QMAP header extension
+        //IPv4 header
+        0x45, 0x00, 0x00, 0x1e,//version=4,IHL=5,DSCP=0,ECN=0,length=30
+        0x00, 0x00, 0x00, 0x00,//id=0,flags=0,fragment offset=0
+        0xff, 0x11, 0x00, 0x00,//TTL=255,Protocol=17 (TCP),checksum=
+        0xc0, 0xa8, 0x02, 0x13,//IPv4 SRC Addr 192.168.2.19
+        0xc0, 0xa8, 0x02, 0x68,//IPv4 DST Addr 192.168.2.104
+        //UDP header
+        0x04, 0x57, 0x08, 0xae,//source port=1111, destination port=2222
+        0x00, 0x0a, 0x00, 0x00,//length=10,checksum=
+        //payload
+        0x00, 0x01
+};
+
+static uint8_t qmapIPv4UdpPacket[] = {
+        //C=0,Next Header=1,PAD=b'63,MUXID=0,Packet length=30
+        0X7f, 0x00, 0x00, 0x1e,//QMAP header
+        //type=3,Next Header=0,IPIDCfg=1,Zero Checksum=1,Additional header size=0,segment size=1
+        0X06, 0xc0, 0x00, 0x01,//QMAP header extension
+        //IPv4 header
+        0x45, 0x00, 0x00, 0x1e,//version=4,IHL=5,DSCP=0,ECN=0,length=30
+        0x00, 0x00, 0x00, 0x00,//id=0,flags=0,fragment offset=0
+        0xff, 0x11, 0x00, 0x00,//TTL=255,Protocol=17 (TCP),checksum=
+        0xc0, 0xa8, 0x02, 0x13,//IPv4 SRC Addr 192.168.2.19
+        0xc0, 0xa8, 0x02, 0x68,//IPv4 DST Addr 192.168.2.104
+        //UDP header
+        0x04, 0x57, 0x08, 0xae,//source port=1111, destination port=2222
+        0x00, 0x0a, 0x00, 0x00,//length=10,checksum=
+        //payload
+        0x00, 0x01
+};
+
+static uint8_t qmapIPv4UdpPacket2[] = {
+        //C=0,Next Header=1,PAD=b'63,MUXID=0,Packet length=30
+        0X7f, 0x00, 0x00, 0x20,//QMAP header
+        //type=3,Next Header=0,IPIDCfg=0,Zero Checksum=1,Additional header size=0,segment size=1
+        0X06, 0x00, 0x00, 0x01,//QMAP header extension
+        //IPv4 header
+        0x45, 0x00, 0x00, 0x20,//version=4,IHL=5,DSCP=0,ECN=0,length=30
+        0x00, 0x00, 0x00, 0x00,//id=0,flags=0,fragment offset=0
+        0xff, 0x11, 0x00, 0x00,//TTL=255,Protocol=17 (TCP),checksum=
+        0xc0, 0xa8, 0x02, 0x13,//IPv4 SRC Addr 192.168.2.19
+        0xc0, 0xa8, 0x02, 0x68,//IPv4 DST Addr 192.168.2.104
+        //UDP header
+        0x04, 0x57, 0x08, 0xae,//source port=1111, destination port=2222
+        0x00, 0x0c, 0x00, 0x00,//length=10,checksum=
+        //payload
+        0x00, 0x01, 0x02, 0x03
+};
+
+char sep[] = "---------------------------------------------"
+             "---------------------------------------------"
+             "---------------------------------------------"
+             "---------------------------------------------"
+             "---------------------------------------------";
+
+void printDemoHeadline(const string& name) {
+    string full = "###################################################"
+                  "###################################################";
+    string side = "############################";
+    string space = "             ";
+    cout << full << endl << side << space << "Demo " + name << space
+    << side << endl << full << endl;
+}
+
+void demo(UlsoPacket<>& ulsoPacket, const string& name) {
+    printDemoHeadline(name);
+    cout << ulsoPacket << endl;
+    cout << sep << endl;
+
+    vector<UlsoPacket<>> packets = ulsoPacket.segment();
+    std::for_each(packets.begin(), packets.end(), [](const auto& p){cout << p << endl;
+        cout << sep << endl;});
+}
+
+void testIpv4Tcp(){
+    using L2Type = IPv4Header;
+    using L3Type = TcpHeader;
+    using PacketType = UlsoPacket<L3Type, L2Type>;
+    size_t payloadSize = 91, segmentSize = 32;
+    size_t packetSize = QmapHeader::size() + L2Type::size() + L3Type::size() + payloadSize;
+
+    PacketType p1(segmentSize, payloadSize);
+    cout << p1 << endl;
+    uint8_t ipv4HeaderBuf[packetSize];
+    p1.asArray(ipv4HeaderBuf);
+    uint8_t *ipv4HeaderPtr = ipv4HeaderBuf;
+    uint8_t *goldBuf = QmapIpv4TcpPacket.l2Packet();
+    for(unsigned int i=0; i<QmapIpv4TcpPacket.l2PacketSize(); i++){
+        if(ipv4HeaderPtr[i] != goldBuf[i]){
+            cout << "ipv4HeaderBuf[" << i << "]=" << std::hex << std::setfill('0') << std::setw(2) <<
+                 static_cast<int>(ipv4HeaderPtr[i]) << std::dec << ", goldBuf[" << i << "]=" << std::setfill('0') <<
+                 std::setw(2) << std::hex << static_cast<int>(goldBuf[i]) << std::dec << endl;
+        }
+    }
+}
+
+void testIpv4Udp(){
+    using L2Type = IPv4Header;
+    using L3Type = UdpHeader;
+    using PacketType = UlsoPacket<L3Type, L2Type>;
+    size_t payloadSize = 80, segmentSize = 32;
+    size_t packetSize = QmapHeader::size() + L2Type::size() + L3Type::size() + payloadSize;
+
+    PacketType p1(segmentSize, payloadSize);
+    cout << p1 << endl;
+    uint8_t ipv4UdpHeaderBuf[packetSize];
+    p1.asArray(ipv4UdpHeaderBuf);
+    uint8_t *udpHeaderPtr = ipv4UdpHeaderBuf + QmapHeader::size() + L2Type::size();
+    uint8_t *goldBuf = udpPacket.l3Packet();
+    for(unsigned int i=0; i<udpPacket.l3PacketSize(); i++){
+        if(udpHeaderPtr[i] != goldBuf[i]){
+            cout << "udpPayload[" << i << "]=" << std::hex << std::setfill('0') << std::setw(2) <<
+                 static_cast<int>(udpHeaderPtr[i]) << std::dec << ", goldBuf[" << i << "]=" << std::setfill('0') <<
+                 std::setw(2) << std::hex << static_cast<int>(goldBuf[i]) << std::dec << endl;
+        }
+    }
+}
+
+template<typename L3Type, typename L2Type>
+size_t packetTestOffset(const struct Packet& p){
+    return QmapHeader::size() + (p.l2Size == 0) * L2Type::size() + (p.l3Size == 0) * L3Type::size();
+}
+
+template<typename L3Type, typename L2Type>
+bool testPacketConstruction(struct Packet packet, size_t segmentSize=20){
+    auto testOffsetFunc = packetTestOffset<L3Type, L2Type>;
+    using PacketType = UlsoPacket<L3Type, L2Type>;
+    size_t ipPacketSize = packet.l2PacketSize();
+    PacketType ulsoPacket(segmentSize, packet.payload(), packet.payloadSize);
+    if(ulsoPacket.size() - testOffsetFunc(packet) != ipPacketSize){
+        cout << "Error: ULSO packet size = " << ulsoPacket.size() << " expected size = " << ipPacketSize << endl;
+        return false;
+    }
+    uint8_t ulsoPacketBuf[ulsoPacket.size()];
+    ulsoPacket.asArray(ulsoPacketBuf);
+    uint8_t *ulsoCmpBuf = ulsoPacketBuf + testOffsetFunc(packet);
+    uint8_t *goldBuf = packet.l2Packet();
+    for(unsigned int i=0; i<ipPacketSize; i++){
+        if(ulsoCmpBuf[i] != goldBuf[i]){
+            cout << "afterQmapPtr[" << i << "]=" << std::hex << std::setfill('0') << std::setw(2) <<
+                 static_cast<int>(ulsoCmpBuf[i]) << std::dec << ", goldBuf[" << i << "]=" << std::setfill('0') <<
+                 std::setw(2) << std::hex << static_cast<int>(goldBuf[i]) << std::dec << endl;
+        }
+    }
+    return true;
+}
+
+int main() {
+
+    uint8_t arr[UlsoPacket<>::maxSize] = {0};
+    UlsoPacket<UdpHeader, IPv4Header> p(19, 100, false);
+    p.mQmapHeader.setmIpIdCfg(0);
+    cout << p << endl;
+    auto v = p.segment();
+    for(auto& pSeg: v){
+        memset(arr, 0, UlsoPacket<>::maxSize);
+        cout << pSeg << endl;
+    }
+
+    return 0;
+}

+ 198 - 0
kernel-tests/network_traffic/packets.h

@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2021 The Linux Foundation. All rights reserved.
+ *
+ * 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.
+ *  * Neither the name of The Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
+ */
+#ifndef NETWORK_TRAFFIC_PACKETS_H
+#define NETWORK_TRAFFIC_PACKETS_H
+
+#include <cstdint>
+#include <cstddef>
+
+struct Packet{
+    size_t size;
+    size_t preL2Size;
+    size_t l2Size;
+    size_t l3Size;
+    size_t payloadSize;
+    uint8_t* packet;
+
+    uint8_t* payload() const {
+        return packet + preL2Size + l2Size + l3Size;
+    }
+
+    uint8_t* l2Packet() const {
+        return packet + preL2Size;
+    }
+
+    size_t l2PacketSize() const {
+        return size - preL2Size;
+    }
+
+    uint8_t* l3Packet() const {
+        return packet + preL2Size + l2Size;
+    }
+
+    size_t l3PacketSize() const {
+        return size - preL2Size - l2Size;
+    }
+};
+
+constexpr size_t qmapIpv4TcpPacketArrSize = 139;
+uint8_t qmapIpv4TcpPacketArr[qmapIpv4TcpPacketArrSize] = {
+        0x40, 0x00, 0x00, 0x83,
+        0x06, 0x80, 0x00, 0x20,
+        0x45, 0x00, 0x00, 0x83,
+        0xf5, 0x7a, 0x40, 0x00,
+        0x40, 0x06, 0xc1, 0x70,
+        0xc0, 0xa8, 0x01, 0x11,
+        0xc0, 0xa8, 0x01, 0x28,
+        0xdd, 0xd5, 0xfd, 0x76,
+        0x40, 0x35, 0xff, 0xc7,
+        0xb8, 0x35, 0xf0, 0xad,
+        0x50, 0x18, 0x01, 0xd9,
+        0x40, 0xa0, 0x00, 0x00,
+        0x48, 0x54, 0x54, 0x50,
+        0x2f, 0x31, 0x2e, 0x31,
+        0x20, 0x34, 0x30, 0x34,
+        0x20, 0x4e, 0x6f, 0x74,
+        0x20, 0x46, 0x6f, 0x75,
+        0x6e, 0x64, 0x0d, 0x0a,
+        0x43, 0x6f, 0x6e, 0x74,
+        0x65, 0x6e, 0x74, 0x2d,
+        0x54, 0x79, 0x70, 0x65,
+        0x3a, 0x20, 0x74, 0x65,
+        0x78, 0x74, 0x2f, 0x70,
+        0x6c, 0x61, 0x69, 0x6e,
+        0x0d, 0x0a, 0x43, 0x6f,
+        0x6e, 0x74, 0x65, 0x6e,
+        0x74, 0x2d, 0x4c, 0x65,
+        0x6e, 0x67, 0x74, 0x68,
+        0x3a, 0x20, 0x33, 0x30,
+        0x0d, 0x0a, 0x43, 0x6f,
+        0x6e, 0x6e, 0x65, 0x63,
+        0x74, 0x69, 0x6f, 0x6e,
+        0x3a, 0x20, 0x63, 0x6c,
+        0x6f, 0x73, 0x65, 0x0d,
+        0x0a, 0x0d, 0x0a
+};
+constexpr size_t ipv4UdpPacketArrSize = 46;
+uint8_t ipv4UdpPacketArr[ipv4UdpPacketArrSize] = {
+        0x45, 0x00, 0x00, 0x25,
+        0xd7, 0xa9, 0x00, 0x00,
+        0x72, 0x11, 0xeb, 0x8f,
+        0x0a, 0x3f, 0x8d, 0xc4,
+        0xac, 0x10, 0x41, 0x7b,
+        0x0d, 0x3d, 0xe8, 0x19,
+        0x00, 0x11, 0x88, 0xd7,
+        0x00, 0x04, 0xc0, 0x1a,
+        0x3b, 0x00, 0x00, 0xf0,
+        0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00
+};
+
+constexpr size_t udpPacketArrSize = 80;
+uint8_t udpPacketArr[udpPacketArrSize] = {
+        0x07, 0xc1, 0x07, 0xc1,
+        0x00, 0x50, 0x39, 0x1a,
+        0x01, 0x28, 0x02, 0x00,
+        0x05, 0x04, 0x00, 0x03,
+        0xa0, 0xe0, 0xaf, 0x89,
+        0xb7, 0x3f, 0x00, 0x00,
+        0x00, 0x5a, 0x00, 0x00,
+        0x03, 0xe8, 0x00, 0x00,
+        0x0b, 0xb8, 0xac, 0x10,
+        0x41, 0x01, 0x61, 0x6e,
+        0x2d, 0x72, 0x74, 0x2d,
+        0x30, 0x32, 0x2e, 0x71,
+        0x75, 0x61, 0x04, 0x1c,
+        0x01, 0x00, 0x00, 0x00,
+        0xac, 0x10, 0x41, 0x02,
+        0x00, 0x00, 0x00, 0x01,
+        0x74, 0x18, 0x26, 0xc7,
+        0xa5, 0x29, 0x24, 0xa1,
+        0xcc, 0x77, 0x76, 0xdc,
+        0x6f, 0x52, 0xfb, 0xbf
+};
+
+constexpr size_t ipv6UdpPacketArrSize = 64;
+uint8_t ipv6UdpPacketArr[ipv6UdpPacketArrSize] = {
+        0x60, 0x05, 0xc1, 0xfd,
+        0x00, 0x18, 0x11, 0x01,
+        0xfe, 0x80, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00,
+        0x8a, 0x51, 0xfb, 0xff,
+        0xfe, 0x41, 0xf5, 0xbd,
+        0xff, 0x02, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x01,
+        0x21, 0xa4, 0x21, 0xa4,
+        0x00, 0x18, 0xb2, 0x04,
+        0x42, 0x4a, 0x4e, 0x50,
+        0x02, 0x01, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00
+};
+
+Packet QmapIpv4TcpPacket{
+        .size=qmapIpv4TcpPacketArrSize,
+        .preL2Size=8,
+        .l2Size=20,
+        .l3Size=20,
+        .payloadSize=91,
+        .packet=qmapIpv4TcpPacketArr
+};
+
+Packet ipv4UdpPacket{
+        .size=ipv4UdpPacketArrSize,
+        .preL2Size=0,
+        .l2Size=20,
+        .l3Size=8,
+        .payloadSize=18,
+        .packet=ipv4UdpPacketArr
+};
+
+Packet udpPacket{
+        .size=udpPacketArrSize,
+        .preL2Size=0,
+        .l2Size=0,
+        .l3Size=8,
+        .payloadSize=72,
+        .packet=udpPacketArr
+};
+
+Packet ipv6UdpPacket{
+        .size=ipv6UdpPacketArrSize,
+        .preL2Size=0,
+        .l2Size=40,
+        .l3Size=8,
+        .payloadSize=16,
+        .packet=ipv6UdpPacketArr
+};
+
+#endif //NETWORK_TRAFFIC_PACKETS_H