Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add WireGuard protocol support #1557

Merged
merged 38 commits into from
Sep 28, 2024
Merged

Add WireGuard protocol support #1557

merged 38 commits into from
Sep 28, 2024

Conversation

nadongjun
Copy link
Contributor

Reference

Summary:

  • This PR introduces WireGuard protocol parsing capabilities to the parseNextLayer function within the UDP layer. The following features are included in this enhancement:

What's Changed:

WireGuard Message Structures

  • Common Header (wg_common_header): Base structure for all WireGuard messages containing the message type and reserved fields.
  • Handshake Initiation (wg_handshake_initiation): Structure representing the Handshake Initiation message with fields such as sender index, ephemeral keys, and MACs.
  • Handshake Response (wg_handshake_response): Structure representing the Handshake Response message with fields such as sender and receiver indexes, ephemeral keys, and MACs.
  • Cookie Reply (wg_cookie_reply): Structure representing the Cookie Reply message with fields such as receiver index, nonce, and encrypted cookie.
  • Transport Data (wg_transport_data): Structure representing the Transport Data message with fields such as receiver index, counter, and encrypted data.

WireGuardLayer Class Methods

  • Constructor: Initializes the WireGuardLayer object with raw data, data length, previous layer, and packet pointer.
  • Message Getters: Methods to get pointers to specific WireGuard messages (Handshake Initiation, Handshake Response, Cookie Reply, Transport Data).

Static Methods

  • isWireguardPorts(uint16_t portSrc, uint16_t portDst): Checks if the given ports match the WireGuard port (51820).
  • isWireGuard(uint8_t* data, size_t dataLen): Validates if the provided data represents a WireGuard message based on its type.

Layer Methods

  • parseNextLayer(): No operation as WireGuard does not have subsequent layers.
  • getHeaderLen(): Returns the length of data
  • computeCalculateFields(): No fields to compute; method is left empty.
  • toString(): Converts the WireGuard layer to a string representation for easier debugging and logging.
  • getOsiModelLayer(): Returns the OSI model layer corresponding to the Network layer.

UDP Layer function

  • UDPLayer::parseNextLayer(): Integrates the ability to recognize and parse WireGuard messages

Example Usage:

#include <iostream>
#include <cstring>
#include <cstdint>
#include "UdpLayer.h"
#include "WireGuardLayer.h"
#include "Packet.h"
#include "PcapFileDevice.h"

int main(int argc, char* argv[])
{
    if (argc < 2)
    {
        std::cerr << "Usage: " << argv[0] << " <pcap file>" << std::endl;
        return 1;
    }

    std::string pcapFile = argv[1];

    pcpp::PcapFileReaderDevice reader(pcapFile);
    if (!reader.open())
    {
        std::cerr << "Error opening pcap file" << std::endl;
        return 1;
    }

    pcpp::RawPacket rawPacket;
    while (reader.getNextPacket(rawPacket))
    {
        pcpp::Packet parsedPacket(&rawPacket);

        if (parsedPacket.isPacketOfType(pcpp::IPv4))
        {
            pcpp::UdpLayer* udpLayer = parsedPacket.getLayerOfType<pcpp::UdpLayer>();
            if (udpLayer != nullptr)
            {
                // Parse the next layer from the UDP layer (in this case, WireGuard layer).   
                udpLayer->parseNextLayer();

                // Check if the parsed next layer is a WireGuard layer.
                pcpp::WireGuardLayer* wgLayer = dynamic_cast<pcpp::WireGuardLayer*>(udpLayer->getNextLayer());
                if (wgLayer != nullptr)
                {
                    // Output the WireGuard layer information as a string.
                    std::cout << wgLayer->toString() << std::endl;
                }
            }
        }
    }

    reader.close();
    return 0;
}

Example Usage::Result

image

Copy link

codecov bot commented Aug 31, 2024

Codecov Report

Attention: Patch coverage is 97.65458% with 11 lines in your changes missing coverage. Please review.

Project coverage is 83.03%. Comparing base (32ba869) to head (f8a36c7).
Report is 1 commits behind head on dev.

Files with missing lines Patch % Lines
Packet++/header/WireGuardLayer.h 91.78% 6 Missing ⚠️
Packet++/src/WireGuardLayer.cpp 98.00% 4 Missing ⚠️
Packet++/src/UdpLayer.cpp 83.33% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##              dev    #1557      +/-   ##
==========================================
+ Coverage   82.89%   83.03%   +0.14%     
==========================================
  Files         273      276       +3     
  Lines       46220    46689     +469     
  Branches     9422     9389      -33     
==========================================
+ Hits        38314    38769     +455     
- Misses       7055     7119      +64     
+ Partials      851      801      -50     
Flag Coverage Δ
fedora40 74.57% <96.05%> (+0.19%) ⬆️
macos-12 81.01% <96.69%> (+0.14%) ⬆️
macos-13 80.44% <96.78%> (+0.15%) ⬆️
macos-14 80.36% <96.78%> (+0.15%) ⬆️
mingw32 70.46% <91.51%> (+0.22%) ⬆️
mingw64 70.42% <91.51%> (+0.22%) ⬆️
npcap 84.94% <95.83%> (+0.10%) ⬆️
rhel94 74.45% <95.96%> (+0.17%) ⬆️
ubuntu2004 57.93% <72.31%> (+0.14%) ⬆️
ubuntu2004-zstd 58.03% <72.31%> (+0.12%) ⬆️
ubuntu2204 74.35% <95.81%> (+0.18%) ⬆️
ubuntu2204-icpx 58.56% <80.87%> (+0.23%) ⬆️
ubuntu2404 74.60% <95.81%> (+0.17%) ⬆️
unittest 83.03% <97.65%> (+0.14%) ⬆️
windows-2019 84.98% <95.83%> (+0.10%) ⬆️
windows-2022 84.98% <95.83%> (+0.09%) ⬆️
winpcap 84.96% <95.83%> (+0.13%) ⬆️
xdp 49.48% <95.81%> (+0.37%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@Dimi1010
Copy link
Collaborator

Looks good. Can you please add tests for the layer in Test/Packet++?

@nadongjun
Copy link
Contributor Author

@Dimi1010 Sure, I'm working on adding the tests for the layer in Test/Packet++ and will push the commits shortly.

Packet++/header/WireGuardLayer.h Outdated Show resolved Hide resolved
Packet++/header/WireGuardLayer.h Outdated Show resolved Hide resolved
Packet++/header/WireGuardLayer.h Outdated Show resolved Hide resolved
Packet++/header/WireGuardLayer.h Outdated Show resolved Hide resolved
Packet++/header/WireGuardLayer.h Outdated Show resolved Hide resolved
Packet++/header/WireGuardLayer.h Outdated Show resolved Hide resolved
Packet++/header/WireGuardLayer.h Outdated Show resolved Hide resolved
Packet++/src/WireGuardLayer.cpp Outdated Show resolved Hide resolved
Copy link
Collaborator

@Dimi1010 Dimi1010 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Packet++/header/ProtocolType.h Outdated Show resolved Hide resolved
Tests/Packet++Test/TestDefinition.h Outdated Show resolved Hide resolved
Packet++/header/WireGuardLayer.h Outdated Show resolved Hide resolved
Copy link
Owner

@seladb seladb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nadongjun I have some comments about the current implementation, so I didn't review the tests yet. Once we finalize the implementation I'll review the tests

Packet++/header/WireGuardLayer.h Show resolved Hide resolved
Packet++/header/WireGuardLayer.h Outdated Show resolved Hide resolved
Packet++/header/WireGuardLayer.h Outdated Show resolved Hide resolved
Packet++/header/WireGuardLayer.h Outdated Show resolved Hide resolved
Packet++/header/WireGuardLayer.h Show resolved Hide resolved
Packet++/src/WireGuardLayer.cpp Outdated Show resolved Hide resolved
README.md Show resolved Hide resolved
Signed-off-by: Dongjun Na <kmu5544616@gmail.com>
Signed-off-by: Dongjun Na <kmu5544616@gmail.com>
Signed-off-by: Dongjun Na <kmu5544616@gmail.com>
Signed-off-by: Dongjun Na <kmu5544616@gmail.com>
Signed-off-by: Dongjun Na <kmu5544616@gmail.com>
…tructures

Signed-off-by: Dongjun Na <kmu5544616@gmail.com>
Signed-off-by: Dongjun Na <kmu5544616@gmail.com>
…ge to handle nextLayer

Signed-off-by: Dongjun Na <kmu5544616@gmail.com>
…tor and message creation

Signed-off-by: Dongjun Na <kmu5544616@gmail.com>
Packet++/header/WireGuardLayer.h Outdated Show resolved Hide resolved
Packet++/header/WireGuardLayer.h Outdated Show resolved Hide resolved
Packet++/header/WireGuardLayer.h Outdated Show resolved Hide resolved
Packet++/header/WireGuardLayer.h Outdated Show resolved Hide resolved
Packet++/header/WireGuardLayer.h Show resolved Hide resolved
Packet++/src/WireGuardLayer.cpp Outdated Show resolved Hide resolved
Packet++/src/WireGuardLayer.cpp Outdated Show resolved Hide resolved
Packet++/src/WireGuardLayer.cpp Outdated Show resolved Hide resolved
Packet++/header/WireGuardLayer.h Outdated Show resolved Hide resolved
Packet++/header/WireGuardLayer.h Outdated Show resolved Hide resolved
…ta handling

Signed-off-by: Dongjun Na <kmu5544616@gmail.com>
Signed-off-by: Dongjun Na <kmu5544616@gmail.com>
@seladb
Copy link
Owner

seladb commented Sep 25, 2024

@nadongjun I resolved the comments that were fixed and kept open those that weren't. Can you please go over the open comments and resolve them?

@nadongjun
Copy link
Contributor Author

@seladb I’ll take a look at the open comments and address them soon. Thank you for your detailed feedback.

Signed-off-by: Dongjun Na <kmu5544616@gmail.com>
Signed-off-by: Dongjun Na <kmu5544616@gmail.com>
Packet++/header/WireGuardLayer.h Outdated Show resolved Hide resolved
Packet++/header/WireGuardLayer.h Outdated Show resolved Hide resolved
Packet++/header/WireGuardLayer.h Outdated Show resolved Hide resolved
Packet++/src/WireGuardLayer.cpp Outdated Show resolved Hide resolved
Packet++/src/WireGuardLayer.cpp Outdated Show resolved Hide resolved
Packet++/src/WireGuardLayer.cpp Show resolved Hide resolved
Packet++/header/WireGuardLayer.h Outdated Show resolved Hide resolved
Packet++/header/WireGuardLayer.h Outdated Show resolved Hide resolved
Packet++/header/WireGuardLayer.h Outdated Show resolved Hide resolved
*
* @return The sender index as a 32-bit integer.
*/
uint32_t getSenderIndex() const;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have getter methods for all fields (in this class and the other classes), but we don't have setter methods. Do we want to add setter methods also?

For example:

void setSenderIndex(uint32_t senderIndex);
void setInitiatorEphemeral(std::array<uint8_t, 32> initEphemeral);
...
void setReceiverIndex(uint32_t receiverIndex);
...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm... Would it be alright if I create a separate PR to work on adding setter methods and WireGuard packet edit tests later?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes sure 👍

Tests/Packet++Test/PacketExamples/WireGuard.pcap Outdated Show resolved Hide resolved
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please include tests for all methods and properties in the wireguard layer classes

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I've made the changes.

… WireGuardCookieReply

Signed-off-by: Dongjun Na <kmu5544616@gmail.com>
Signed-off-by: Dongjun Na <kmu5544616@gmail.com>
Packet++/src/WireGuardLayer.cpp Outdated Show resolved Hide resolved
*
* @return The sender index as a 32-bit integer.
*/
uint32_t getSenderIndex() const;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes sure 👍

Copy link
Owner

@seladb seladb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nadongjun overall looks good!

Please find a few more comments, we're getting close to getting this PR ready to merge 🙂

Tests/Packet++Test/Tests/WireGuardTests.cpp Outdated Show resolved Hide resolved
Tests/Packet++Test/Tests/WireGuardTests.cpp Outdated Show resolved Hide resolved
Tests/Packet++Test/Tests/WireGuardTests.cpp Outdated Show resolved Hide resolved
Tests/Packet++Test/Tests/WireGuardTests.cpp Outdated Show resolved Hide resolved
Tests/Packet++Test/Tests/WireGuardTests.cpp Outdated Show resolved Hide resolved
Tests/Packet++Test/Tests/WireGuardTests.cpp Show resolved Hide resolved
Tests/Packet++Test/Tests/WireGuardTests.cpp Show resolved Hide resolved
Tests/Packet++Test/Tests/WireGuardTests.cpp Outdated Show resolved Hide resolved
Tests/Packet++Test/Tests/WireGuardTests.cpp Outdated Show resolved Hide resolved
@nadongjun
Copy link
Contributor Author

@seladb Thank you! I’ll address the remaining feedback quickly.

Signed-off-by: Dongjun Na <kmu5544616@gmail.com>
Signed-off-by: Dongjun Na <kmu5544616@gmail.com>
@seladb seladb changed the title Add WireGuard Protocol Parsing Support in UDP Packets Add WireGuard protocol support Sep 28, 2024
@seladb seladb merged commit 3919812 into seladb:dev Sep 28, 2024
40 checks passed
@seladb
Copy link
Owner

seladb commented Sep 28, 2024

Thank you so much @nadongjun for working on it, much appreciated! 🙏 🥇

@tigercosmos
Copy link
Collaborator

@nadongjun nice job :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add WireGuard Packet Parsing Support
4 participants