Results 1 to 15 of 18

Thread: New Feature Ready for Review: VLAN Support

Threaded View

  1. #1
    Registered User
    Join Date
    May 2023
    Posts
    6

    Exclamation New Feature Ready for Review: VLAN Support

    Hello,

    This is my first contribution and I haven't worked in c/c++ for quite a while, so it took me a while to figure out the exact place and method for this feature enhancement.

    I have a working proof-of-concept (patch attached), but I'm hoping some existing contributor(s) can help me get it across the line. I'm not sure what your style and implementation preferences are.

    Problem Statement:

    Packets with VLAN tagging (802.11q) are ignored by showeq

    Solution:

    This feature allows showeq to decode packets that include VLAN tagging.

    Motivation:

    I have a network setup with a managed switch and a SPAN port that is mirroring traffic to a dedicated secondary NIC in a showeq VM. Because of my specific switch design (TP-LINK) and usage of VLANs, the mirrored traffic ends up including traffic both with and without VLAN tagging (incoming traffic is untagged, outgoing traffic is tagged).

    Implementation Details:

    I discovered that while the packets were being seen by libpcap's packet filter, they were ultimately ending up rejected by showeq. The additional 4 bytes in the ethernet header meant that VLAN-tagged packets ended up failing to decode, as the code would attempt to index into the memory buffer to access the packet payload, but would end up misaligned with the IP header, causing it to believe it was a non-IP packet.

    To solve this, I modified packetcapture.cpp PacketCaptureThread :: packetCallback

    I added a new define check, for PCAP_VLAN, which when built into the project (./configure CXXFLAGS='-DPCAP_VLAN'), examines the packet header for ETHERTYPE_VLAN, and if found, skips the 4-byte VLAN field when copying the data into the packetCache. This allows showeq to process it just like any other normal IP packet.

    I used the inspiration from the PCAP_DEBUG section (which I also modified slightly), as it already showed how to examine the packet for ETHERTYPE_IP, so I just had to add an additional check there for ETHERTYPE_VLAN so I could confirm that the packets were making it past libpcap.

    However, I don't know the full performance implications of the additional if checks at runtime, which is why I included this change as a compiler-time flag. If maintainers believe it would make sense at runtime, I'm open to changes!

    original code

    Code:
        struct packetCache *pc;
        PacketCaptureThread* myThis = (PacketCaptureThread*)param;
        pc = (struct packetCache *) malloc (sizeof (struct packetCache) + ph->len);
        pc->len = ph->len;
        memcpy (pc->data, data, ph->len);
        pc->next = NULL;
    modified code

    Code:
    #ifdef PCAP_VLAN
        // check the type from header
        struct ether_header* packetHeader = (struct ether_header*) data;
        uint16_t packetType = ntohs(packetHeader->ether_type);
        uint32_t packetLength = ph->len;
        if (packetType == ETHERTYPE_VLAN)
        {
            // will use 4 less bytes without VLAN   
            packetLength -= 4;
        }
        struct packetCache *pc;
        PacketCaptureThread* myThis = (PacketCaptureThread*)param;
        pc = (struct packetCache *) malloc (sizeof (struct packetCache) + packetLength);
        pc->len = packetLength;
        if (packetType == ETHERTYPE_VLAN)
        {
            // copy first 12 bytes (src/dst)
            memcpy (pc->data, data, 12);
            // copy remaining bytes, skipping the 4 byte VLAN header (12 + 4 = 16)
            memcpy (pc->data + 12, data + 16, packetLength - 12);
        }
        else
        {
            // copy the entire packet
            memcpy (pc->data, data, packetLength);
        }
        pc->next = NULL;
    #else
        struct packetCache *pc;
        PacketCaptureThread* myThis = (PacketCaptureThread*)param;
        pc = (struct packetCache *) malloc (sizeof (struct packetCache) + ph->len);
        pc->len = ph->len;
        memcpy (pc->data, data, ph->len);
        pc->next = NULL;
    #endif
    please see patch file and advise. TIA
    Attached Files Attached Files

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

You may post new threads
You may post replies
You may post attachments
You may edit your posts
HTML code is Off
vB code is On
Smilies are On
[IMG] code is On