Ask Your Question

vlan tag missing in packets captured using custom socket but visible in wireshark

asked 2020-03-20 08:19:53 +0000

chakka.lokesh gravatar image

I am using


read_socket = socket( PF_PACKET, SOCK_RAW, htons(ETH_P_ALL) );

and for writing as well


write_socket = socket( PF_PACKET, SOCK_RAW, htons(ETH_P_ALL) );

while writing packet, I am writing entire packet ( i.e., ethernet header, ip header, udp header, application data and finally ethernet checksum )

but while capturing on other side using read_socket I am seeing, if it is just ethernet packet, entire packet is visible. But however, if I am sending packet with vlan tag, read_socket is capturing entire packet excluding vlan tag. As it is vlan 1ad packet, the four bytes in ethernet header are missing.

But entire packet is visible in wireshark capture. Tried identifying the socket used by wireshark, but not able to succeed. I downloaded the wireshark source code, kept logs where ever socket function call is there, compiled and used that executable to capture the packets without installing. Because I already have the one installed using "sudo apt", probably installed libraries are being used even though I am running the locally compiled executable.

To my surprise, if I open the read socket after started sending the vlan packets, I am seeing the entire packet is getting captured(i.e., including vlan tag). But If I open the read / write sockets, then start sending the packets, I am seeing vlan tag is missing....!!!

But I can't afford opening read socket after started sending packets, as I will be loosing some packets. Can someone help me in always capturing the entire packet including vlan tag

Note: Both the network cards are existing in same machine and are connected B2B. Project requirement is to send / receive packets via Tx/Rx queues.

edit retag flag offensive close merge delete


Seems to me to be off-topic as it's a programming question, not a Wireshark one.

One thing to be aware of is that as both NIC's are on the same machine the OS might take a short circuit and not generate the Ethernet\VLAN part of the packet as it never leaves the machine.

grahamb gravatar imagegrahamb ( 2020-03-20 09:24:35 +0000 )edit

3 Answers

Sort by ยป oldest newest most voted

answered 2020-03-31 19:53:11 +0000

Guy Harris gravatar image

updated 2020-04-01 05:15:51 +0000

Cliffs Notes version:

The Linux networking stack pulls VLAN tags out of the body of a packet and puts it into metadata in the "socket buffer" structure for the packet. If you're reading from a PF_PACKET/SOCK_RAW socket - whether using a socket system call or a memory-mapped buffer - the data you read will have the VLAN tags stripped out, so, to reconstruct the packet as it appeared on the wire, you'll need to get the VLAN tag information from the metadata and reconstruct it.

Libpcap will do that for you. If you really want to do the capturing yourself, see how libpcap does it. If you want to do it on non-memory-mapped sockets, you'll have to look at the libpcap 1.9 code; the master branch only uses memory-mapped sockets.

edit flag offensive delete link more

answered 2020-03-30 07:04:57 +0000

chakka.lokesh gravatar image

updated 2020-03-31 06:22:39 +0000

Solved. Thanks for the support.

edit flag offensive delete link more


Can you put the Cliff Notes version of the solution here? I read through the link above and see that it was solved but not how.

Chuckc gravatar imageChuckc ( 2020-03-30 13:22:17 +0000 )edit

please refer the attachment in that link. It is executable code.

chakka.lokesh gravatar imagechakka.lokesh ( 2020-03-31 06:23:39 +0000 )edit

answered 2020-03-20 10:06:48 +0000

Jaap gravatar image

Unfortunately the VLAN information is passed through as auxiliary data to the socket. Libpcap, the library that's actually interfacing with the network on behalve of Wireshark, does a lot of work to re-insert the VLAN data into the frame. See the pcap-linux.c file and search for 'vlan'.

edit flag offensive delete link more


Could changing the rx-vlan-offload, tx-vlan-offload settings possibly help here using ethtool's rxvlan, txvlan options? There's no mention of this on the CaptureSetup/VLAN wiki page, so I suspect not, or perhaps it would help, but only for certain NICs/drivers?

cmaynard gravatar imagecmaynard ( 2020-03-20 14:50:14 +0000 )edit

Dear Jaap,

Thanks for the valuable information.

Here is the read socket

int create_read_sock( char const * const card_name )
    const int sock = socket( PF_PACKET, SOCK_RAW, htons(ETH_P_ALL) );//Lokesh experiment with zero instead of ETH_P_ALL
    if( sock == -1 )
        perror( "read socket" );
struct ifreq ifr;
strncpy( ifr.ifr_name, card_name, IFNAMSIZ );
if( ioctl( sock, SIOCGIFFLAGS, &ifr ) == -1 )
    perror( "SIOCGIFFLAGS" );
ifr.ifr_flags |= ( IFF_PROMISC | IFF_UP );
if( ioctl( sock, SIOCSIFFLAGS, &ifr ) == -1 )
    perror( "SIOCSIFFLAGS" );

struct sockaddr_ll my_addr =
    .sll_family = PF_PACKET,
    .sll_protocol = htons(ETH_P_ALL),
    .sll_ifindex = if_nametoindex(card_name)
if( bind( sock, (struct sockaddr *)&my_addr, sizeof(my_addr) ) == -1 )
    perror( "bind read socket" );
int one = 1;
if( setsockopt( sock, SOL_PACKET, PACKET_AUXDATA, &one, sizeof(one)) < 0 )
    perror( "read socket PACKET_AUXDATA" );
return sock;

While reading the packet I am following like this:

struct tpacket_auxdata auxdata;
temp_bytes = read( read_socket, read_array, pkt_size );

        if( auxdata.tp_status & TP_STATUS_VLAN_TPID_VALID )
        {//vlan 802.1ad
            memmove( read_array+(2*ETH_ALEN), read_array ...
chakka.lokesh gravatar imagechakka.lokesh ( 2020-03-24 12:32:17 +0000 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools


Asked: 2020-03-20 08:19:53 +0000

Seen: 1,794 times

Last updated: Apr 01 '20