我想知道是否可以按位而不是来执行memcpy?是否可以在位而不是字节中执行memcpy?
我正在写一个带有VLAN标记的以太网帧的C代码,其中我需要为VLAN标头属性(PCP-3bits,DEI-1bit,VID-12bits)填充不同的值。
如何对这些位执行memcpy,或者以任何其他可能性向位中的这些属性填充值。
在此先感谢!
我想知道是否可以按位而不是来执行memcpy?是否可以在位而不是字节中执行memcpy?
我正在写一个带有VLAN标记的以太网帧的C代码,其中我需要为VLAN标头属性(PCP-3bits,DEI-1bit,VID-12bits)填充不同的值。
如何对这些位执行memcpy,或者以任何其他可能性向位中的这些属性填充值。
在此先感谢!
如果您需要填写的字段,你可以使用C bit-fields与struct
,像这样:
struct box_props {
unsigned first : 1;
unsigned second : 3;
unsigned : 4;
};
凡1
,例如,表示该字段是1位长。最后一个(未命名)字段表示:4位填充。
定义struct
, memcpy
它并阅读领域,就好像他们在哪里unsigned
。写作相同。
注意:总是填充到整数字节,或者memcpy
可能会产生不必要的影响。
编号位不可寻址(意味着它不可能直接从内存中读取它们,它们没有地址,只有字节有地址)。
您需要读取包含您感兴趣的位的字节或单词,并自己执行masking。
我已经为客户端完成802.1Q VLAN标记,他们只有802.3以太网帧,但希望迁移到802.1Q,因为安装了新的VLAN感知交换机。
首先,你不能复制位。我们使用memcpy以字节复制标签。
插图(参照维基百科字段的说明): -
VLAN标记= 4字节;由TPID(2字节)和TCI(2字节)组成。
TPID很简单,始终为0x8100,指示带VLAN标记的帧。
TCI由PCP-3bits,DEI-1bit,VID-12bits组成。将TCI细分为四位,即四位。缺省情况下,半字节(PCP + DEI)= 0x0,假设优先级被禁用且DEI = 0。其余3个半字节(12位)用于VLAN-ID本身。假设你想标记一个VLAN-ID = 123的帧。在十六进制中这将是= 0x07B。
将小数点组合在一起,在那里您可以看到2字节的TCI字段,现在可以将其视为0x007B。
然后您可以执行以下操作。 (代码未编译)
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));
最重要的问题是您是否期望位作为副本的一部分相对于8位边界进行移位;你认为这些位可能会重叠吗? –
memcpy从源到目的地拷贝n'字节'。你不能使用'memcpy'作为位。 –
我需要此功能出于同样的原因,请提供有关如何解决此问题的答案。 – jwbensley