我正在处理为ipv4编写的遗留代码。现在我已经为ipv6添加了类似的代码。我已经在主机上试过并测试了..但是我担心它是否会在powerpc上工作,因为有字节序...代码是从传入的流中提取ip头并压缩它..任何评论都会有帮助
class st_ipv6
{
//==================================================================================================
public:
//==================================================================================================
#ifdef _BIG_ENDIAN
uint32 version:4; // version
uint32 trafficclass:8; // header length
uint32 flowlabel:20; // flow label
#else
uint32 trafficclass_1:4;
uint32 version:4; // version
uint32 flowlabel_1:4;
uint32 trafficclass_2:4; // traffic class
uint32 flowlabel_2:4; // flow label
uint32 flowlabel_3:4; // flow label
uint32 flowlabel_4:4; // flow label
uint32 flowlabel_5:4; // flow label
#endif
uint16 payloadlength; // payload length
uint8 nextheader; // next header
uint8 hoplimit; // hop limit
uint32 sourceaddress[4]; // source address
uint32 destinationaddress[4]; // destination address
#ifdef _BIG_ENDIAN
//**********************************************************************************************
//* Description:
/** Specify/Return IPv6 Version
*/
//**********************************************************************************************
inline void setVersion(uint8 ubyVersion)
{
version = ubyVersion;
}
inline uint8 getVersion()
{
return version;
}
答案 0 :(得分:3)
Bitfields和便携性通常是一场噩梦。通常最好使用和/或/ shift。
参见例如下方。
只要在读/写时对各种整数调用hton *()/ ntoh *(),你就会(希望)没有问题。
我还会编写其余的访问器并将数据字段设为私有。
class st_ipv6
{
public:
uint32 version_info;
uint16 payloadlength;
uint8 nextheader;
uint8 hoplimit;
uint32 sourceaddress[4];
uint32 destinationaddress[4];
uint8 GetVersion()
{
return version_info & 0xF;
}
void SetVersion(uint8 v)
{
version_info = (version_info & ~0xF) | (v & 0xF);
}
uint8 GetTrafficClass()
{
return (version_info & 0xFF0)>>4;
}
void SetTrafficClass(uint8 c)
{
version_info = (version_info & ~0xFF0) | ((c & 0xFF) << 4);
}
uint32 GetFlowLabel()
{
return (version_info & 0xFFFFF000)>>12;
}
void SetFlowLabel(uint32 f)
{
version_info = (version_info & ~0xFFFFF000) | ((f & 0xFFFFF) << 12);
}
};
答案 1 :(得分:1)
我建议使用struct
而不是class
,因为RTTI可以在内存布局中插入额外的内容。
我认为这应该足够了
#ifdef _BIG_ENDIAN
uint32 version:4; // version
uint32 trafficclass:8; // header length
uint32 flowlabel:20; // flow label
#else
uint32 flowlabel:20; // flow label
uint32 trafficclass:8; // header length
uint32 version:4; // version
#endif
...但您在阅读流程标签时应ntohl(flowlabel)
,在设置时应htonl(flowlabel)
。
答案 2 :(得分:0)
小心使用不同的编译器并使用位域。一些编译器在高位开始位域并向下工作,而其他编译器从低位开始工作。除非您仔细测试正在使用的不同编译器,否则最好自己从原始字节中进行屏蔽。
答案 3 :(得分:0)
class ip_v6 {
公共: uint32 version_info; uint16 payload_len; uint8 next_header; uint8 hop_limit; uint32 src_addr [4]; uint32 dst_addr [4];
uint32 GetVersionInfo() { return(ntohl(version_info)); }
void SetVersionInfo(uint32 vinfo) { version_info = htonl(vinfo); }
uint8 GetVersion() { return(((GetVersionInfo())&amp;(0xf0000000))&gt;&gt; 28); }
void SetVersion(uint8 v) { SetVersionInfo((GetVersionInfo()&amp; 0x0fffffff)|(v <&lt; 28)); }
uint8 GetTrafficClass() { return(((GetVersionInfo())&amp;(0x0ff00000))&gt;&gt; 20); }
void SetTrafficClass(uint8 c) { SetVersionInfo((GetVersionInfo()&amp; 0xf00fffff)|(c <&lt; 20)); }
uint32 GetFlowLabel() { return((GetVersionInfo())&amp;(0x000fffff)); }
void SetFlowLabel(uint32 f) { SetVersionInfo((GetVersionInfo()&amp; 0xfff00000)|(f)); } };