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

青春壹個敷衍的年華 提交于 2019-12-10 14:18:10

问题


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 !


回答1:


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.




回答2:


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));



回答3:


If you need to fill fields, you can use C bit-fields with a struct, like this:

struct box_props {
    unsigned first  : 1;
    unsigned second : 3;
    unsigned : 4;
};

Where 1, for instance, means that the field is 1bit long. The last (unnamed) field means: 4bit padding.

Define struct, memcpy to it and read fields as if they where unsigned. Same for writing.

NOTE: always pad to integer byte, or memcpy could have unwanted effects.



来源:https://stackoverflow.com/questions/17320643/is-it-possible-to-do-memcpy-in-bits-instead-of-bytes

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!