我正在尝试解码基于RFC 5389的STUN成功响应:
如果IP地址系列是IPv6,则通过获取映射的IP地址来计算X地址 在主机字节顺序中,与魔术的串联进行异或 cookie和96位事务ID,并将结果转换为 网络字节顺序。
Magic cookie是一个常量,它是0x2112A442。
我的情况下的交易ID是:0x6FA22B0D9C5F5AD75B6A4E43。
主机字节顺序中的我的X地址(IPv6)是:
0x034A67D82F4B3657B193039A8BA8FDA1
我是否需要xor Host Byte Order X-Address以及网络或主机字节顺序中Magic Cookie和Transaction ID的串联?
在第一种情况下,网络字节顺序连接等于:
0x2112A442 6FA22B0D9C5F5AD75B6A4E43
第一个字节0x03的xored为0x21,最后一个字节0xA1的xored为0x43
但在第二种情况下,Host Byte Order连接是:
0x434E6A5BD75A5F9C0D2BA26F 42A41221
第一个字节0x03的xored为0x43,最后一个字节0xA1的xored为0x21。
另一种可能的行为是,它将魔术cookie和事务ID分别转换为主机字节顺序,但它会连接它们,保留标题顺序:
0x42A41221 434E6A5BD75A5F9C0D2BA26F
第一个字节0x03的xored为0x42,最后一个字节0xA1的xored为0x6F。
答案 0 :(得分:1)
一切都在网络字节顺序中完成。
但是,对于IPv6地址,“主机字节顺序”和“网络字节顺序”之间没有区别。 IPv6地址始终被理解为16字节的数组。并且单个字节没有“字节顺序”。在“C”代码中,我们只是将IPv6地址表示为:
unsigned char ipv6address[16];
或者就sockaddr_in6结构而言;
struct sockaddr_in6 addr;
unsigned char* ipv6addresss = addr.sin6_addr.s6_addr; // points to a sequence of 16 bytes
与IPv4形成对比,后者通常在代码中作为32位整数传递。在IPv4情况下,您经常需要调用htonl
和ntohl
函数。
除非您正在将IPv6地址维护为8个16位整数而不是数组字节的数组,否则您不必过多地考虑字节序和字节顺序。 (事实上,我建议你不要考虑16字节ip地址的字节顺序。)
示例:
我的IPv6地址是:
2001:0000:9d38:6abd:347d:0d08:3f57:fefd
作为十六进制字节的数组,逻辑上写为:
200100009d386abd347d0d083f57fefd
当我的STUN服务器收到来自此IPv6地址的绑定请求时,它会应用以下XOR操作来发送回XOR-MAPPED-ADDRESS。我们假设它与您的事务ID相同,它包含表示RFC 5389支持的神奇cookie(2112A442 6FA22B0D9C5F5AD75B6A4E43)
XOR:
200100009D386ABD347D0D083F57FEFD
2112A4426FA22B0D9C5F5AD75B6A4E43
结果:
0113A442F29A41B0A82257DF643DB0BE
类似地,接收STUN绑定响应的客户端对具有相同事务ID的此字节数组应用反XOR运算。
XOR:
0113A442F29A41B0A82257DF643DB0BE
2112A4426FA22B0D9C5F5AD75B6A4E43
结果:
200100009D386ABD347D0D083F57FEFD
如果有助于提供如何应用xor映射操作的示例,则可以将源代码引用到Stuntman。 XOR操作是here on GitHub。这里的代码不区分具有魔术cookie的事务ID和不具有魔术cookie的事务ID。它只是将事务id视为16字节的逻辑序列。
以上内容负责IPv6地址。但是,如果将16位端口值视为short
或16位整数,则必须将字节翻转。在C代码中,通常通过调用ntohs
来处理。