Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

is it possible to do memcpy in bits instead of bytes?

Tags:

c

memcpy

ethernet

I would like to know is it possible to do memcpy by bits instead of bytes?

I am writing a C code for Ethernet frame with VLAN tagging, in which I need to fill different values for VLAN header attributes (PCP-3bits,DEI-1bit,VID-12bits).

How can I do memcpy to those bits, or any other possibility to fill values to those attributes in bits.

Thanks in advance !

like image 729
arr Avatar asked Jun 26 '13 12:06

arr


2 Answers

No. Bits are not addressable (meaning that it is not possible to read them and only them directly from memory. They have no address. Only bytes have addresses).

You need to read the byte or word that contains the bits you are interested in and do the masking yourself.

like image 79
Pascal Cuoq Avatar answered Oct 26 '22 22:10

Pascal Cuoq


I have done the 802.1Q VLAN tagging of frames for a client where they had only 802.3 Ethernet frames but wanted to migrate to 802.1Q as there was a new VLAN aware switch installed.

Firstly, you cannot copy bits. We had copied the tag in bytes using memcpy.

Illustration (refer Wikipedia for descriptions of fields):-

VLAN Tag = 4 Bytes; consisting of TPID(2 Bytes) and TCI(2 Bytes).

TPID is simple and is always 0x8100 indicating a VLAN tagged frame.

TCI consists of PCP-3bits, DEI-1bit, VID-12bits. Breakdown the TCI to nibbles i.e. 4-bits. By default, the nibble(PCP+DEI) = 0x0 assuming priority is disabled and DEI = 0. The remaining 3-nibbles(12bits) are for the VLAN-ID itself. Say, you want to tag a frame for VLAN-ID = 123. In hex this will be = 0x07B.

Group the nibbles together and there you have your 2 byte TCI field which can now be seen as 0x007B.

Then you can do the below. (code is not compiled)

unsigned short int vlanTPID, vlanTCI;
unsigned char     *dest, *src;

// Set the VLAN Tag
vlanTPID = 0x8100;
vlanTCI  = 0x007B;

// Pointer to the TPID position of ethernet frame
dest = &vlanTagPosition;
src = &vlanTPID;
memcpy(dest, src, sizeof(vlanTPID));

// Increment dest pointer by 2 bytes to insert TCI in the ethernet frame
dest += 2;
src = &vlanTCI;
memcpy(dest, src, sizeof(vlanTCI));
like image 40
ritwick87 Avatar answered Oct 26 '22 22:10

ritwick87