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

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

by
chakka.lokesh
from LinuxQuestions.org on (#50PV5)
I am using

Code:read_socket = socket( PF_PACKET, SOCK_RAW, htons(ETH_P_ALL) );and for writing as well

Code: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.

Here is the full code I have written

Code:#include <linux/if_packet.h>
#include <linux/if_ether.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <net/if.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <sys/ioctl.h>
#include <stdbool.h>

_Atomic ssize_t total_bytes_written, total_pkts = 0;

char *card1 = "eth0";
char *card2 = "eth1";

const int num_of_threads = 1;
const int pkt_size = 1200;
int write_socket, read_socket;
char *array;

int create_write_sock( char const * const card_name )
{
const int sock = socket( PF_PACKET, SOCK_RAW, htons(ETH_P_ALL) );
if( sock == -1 )
{
perror( "write socket" );
exit(EXIT_FAILURE);
}
struct sockaddr_ll my_addr =
{
.sll_family = AF_PACKET,
.sll_protocol = htons(ETH_P_ALL),
.sll_ifindex = if_nametoindex(card_name)
};
if( bind( sock, (struct sockaddr *)&my_addr, sizeof(struct sockaddr_ll) ) == -1 )
{
perror( "bind socket" );
exit(EXIT_FAILURE);
}
if( 0 )
{
int one = 1;
if( setsockopt( sock, SOL_PACKET, PACKET_QDISC_BYPASS, &one, sizeof(one)) < 0 )
{
perror( "PACKET_QDISC_BYPASS" );
exit(EXIT_FAILURE);
}
}
return sock;
}

int create_read_sock( char const * const card_name )
{
const int sock = socket( PF_PACKET, SOCK_RAW, htons(ETH_P_ALL) );
if( sock == -1 )
{
perror( "read socket" );
exit(EXIT_FAILURE);
}
struct ifreq ifr;
strncpy( ifr.ifr_name, card_name, IFNAMSIZ );
if( ioctl( sock, SIOCGIFFLAGS, &ifr ) == -1 )
{
perror( "SIOCGIFFLAGS" );
exit(EXIT_FAILURE);
}
ifr.ifr_flags |= ( IFF_PROMISC | IFF_UP );
if( ioctl( sock, SIOCSIFFLAGS, &ifr ) == -1 )
{
perror( "SIOCSIFFLAGS" );
exit(EXIT_FAILURE);
}

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" );
exit(EXIT_FAILURE);
}
return sock;
}

const _Bool stripping_vlan_tag = true;

void *read_pkts( void *param )
{
char read_array[2000];
ssize_t temp_bytes;
int i, j;
if( stripping_vlan_tag == false )
read_socket = create_read_sock( card2 );
for( i=0; i<5; i++ )
{
temp_bytes = read( read_socket, read_array, pkt_size );
if( temp_bytes == pkt_size )
{
if( (uint8_t)read_array[12] == 0x81 )
{
if( read_array[13] == 0 )
{
printf( "%s %d SUCCESS......!!!!!\n", __func__, __LINE__ );
}
}
else
printf( "%s %d fail......!!!!!\n", __func__, __LINE__ );
}
else
printf( "%s %d temp bytes: %ld pkt_size: %u fail......!!!!!\n", __func__, __LINE__, temp_bytes, pkt_size );
}
}

void *write_pkts( void *param )
{
const int count = 100/num_of_threads;
ssize_t bytes_written_local = 0, total_pkts_local = 0;
ssize_t temp_bytes;
int i;
for( i=0; i<count; i++ )
{
temp_bytes = write( write_socket, array, pkt_size );
if( temp_bytes == pkt_size )
{
total_pkts_local++;
bytes_written_local += temp_bytes;
}
if( temp_bytes < 0 )
{
printf( "%s %d local pkts: %ld local bytes: %ld bits: %ld \n", __func__, __LINE__, total_pkts_local, bytes_written_local, bytes_written_local*8 );
perror( "Unable to write" );
return NULL;
}
else if( temp_bytes < pkt_size )
{
printf( "%s %d local pkts: %ld local bytes: %ld bits: %ld \n", __func__, __LINE__, total_pkts_local, bytes_written_local, bytes_written_local*8 );
perror( "Shouldn't be here." );
return NULL;
}
}
total_pkts += total_pkts_local;
total_bytes_written += bytes_written_local;
//printf( "%s %d success pkts local: %ld bytes local: %ld\n", __func__, __LINE__, total_pkts_local, bytes_written_local );
return NULL;
}

int main()
{
write_socket = create_write_sock( card1 );
if( stripping_vlan_tag == true )
read_socket = create_read_sock( card2 );
array = calloc( sizeof(char), pkt_size );
int i;
for( i=0; i<pkt_size; i++ )
{
array[i] = 'a';
}
array[12] = 0x81;
array[13] = 0;
array[14] = 0xef;
array[15] = 0xbd;
array[16] = 0x08;
array[17] = 0;

const time_t t1 = time(NULL);
pthread_t *write_threads = calloc( sizeof(pthread_t), num_of_threads );
for( i=0; i<num_of_threads; i++ )
{
pthread_create( &write_threads[i], NULL, write_pkts, NULL );
}
pthread_t read_thread;
pthread_create( &read_thread, NULL, read_pkts, NULL );
for( i=0; i<num_of_threads; i++ )
{
pthread_join( write_threads[i], NULL );
}
const time_t t2 = time(NULL);

printf("time: %ldsecs thread count: %d card: %s packet_size: %d pkts: %ld total bytes: %ld ", t2-t1, num_of_threads, card1, pkt_size, total_pkts, total_bytes_written );

const uint32_t KILO = 1000;
const double giga = KILO*KILO*KILO, mega = KILO*KILO;
const uint64_t value = total_bytes_written*8;

if( value >= giga )
printf( "%.02fGbps", (double)value/giga/(t2-t1) );
else if( value > mega )
printf( "%.02fMbps", (double)value/mega/(t2-t1) );
else if( value > KILO )
printf( "%.02fKbps", (double)value/KILO/(t2-t1) );
else
printf( "%.02fbps", (double)value/(t2-t1) );
printf( "\n" );
}latest?d=yIl2AUoC8zA latest?i=G42FH-MfTfA:fbNr4iEkbOo:F7zBnMy latest?i=G42FH-MfTfA:fbNr4iEkbOo:V_sGLiP latest?d=qj6IDK7rITs latest?i=G42FH-MfTfA:fbNr4iEkbOo:gIN9vFwG42FH-MfTfA
External Content
Source RSS or Atom Feed
Feed Location https://feeds.feedburner.com/linuxquestions/latest
Feed Title LinuxQuestions.org
Feed Link https://www.linuxquestions.org/questions/
Reply 0 comments