简体   繁体   English

比较IPV4套接字(sockaddr_in)和IPV6套接字(sockaddr_in6)

[英]Comparing IPV4 socket(sockaddr_in) with IPV6 Socket(sockaddr_in6)

I have a UDP Server which has to serve clients on both IPV4 and IPV6 address. 我有一个UDP服务器,它必须在IPV4和IPV6地址上为客户端提供服务。 I have created a single IPV6 socket to serve both the IPV4 and IPV6 clients. 我创建了一个IPV6套接字来为IPV4和IPV6客户端提供服务。

The server stores IPAddress of the client on the very first communication. 服务器在第一次通信时存储客户端的IPAddress。 If it is a IPV4 client it stores as IPV4 Address and if it is a IPV6 client the server stores as IPV6 address. 如果它是IPV4客户端,则它存储为IPV4地址,如果是IPV6客户端,则服务器存储为IPV6地址。 For all future communication it checks the storage whether this client is already known(stored) and then acts accordingly. 对于将来的所有通信,它会检查存储器是否已知(存储)此客户端,然后相应地执行操作。 For comparing the client address with the stored address I do a memcmp based on the family type (AF_INET and AF_INET6). 为了比较客户端地址和存储的地址,我根据族类型(AF_INET和AF_INET6)执行memcmp。

While communicating with IPV6 client the system is working normally but while communicating with IPV4 client the system behaves as if it never knew the client. 在与IPV6客户端通信时,系统正常工作,但在与IPV4客户端通信时,系统表现得好像从不知道客户端。 While debugging I found that due to IPV6 the Socket Type the IPAddresss of the IPV4 client is received as IPV6 mapped IPV4 Address with family set to IPV6. 在调试时我发现由于IPV6的套接字类型,IPV4客户端的IPAddress被接收为IPV6映射的IPV4地址,其中系列设置为IPV6。 To Solve this I need to compare between the IPV4 Stored address and the IPV6 mapped address. 要解决这个问题,我需要比较IPV4存储地址和IPV6映射地址。 For this I am using sin_addr.s_addr of IPV4 structure and sin6_addr.in6_u.u6_addr32 of IPV6 structure. 为此我使用了IPV4结构的sin_addr.s_addr和IPV6结构的sin6_addr.in6_u.u6_addr32。 Please find the code snippet below. 请在下面找到代码段。

ipv6_clientdata = (const struct sockaddr_in6 *)&sockStor;
ipv4_storeddata = (const struct sockaddr_in *)&(_stData[index].clientaddr);
if( (ipv6_clientdata->sin6_port == ipv4_storeddata->sin_port) && 
    (ipv6_clientdata->sin6_addr.in6_u.u6_addr32[3] == ipv4_storeddata->sin_addr.s_addr) 
  )
{
    addrfound = true;
}

I would like to know whether this method is the proper solution for comparing IPV6 Mapped IPV4 address with IPV4 address or is there any other better way. 我想知道这种方法是否是将IPV6映射IPV4地址与IPV4地址进行比较的正确解决方案,还是有其他更好的方法。

As Joachim Pileborg reasoned, you don't need to care about this when the IPv4 address comes from an earlier packet received on the same socket because you will be comparing one mapped IPv4 address to another. 正如Joachim Pileborg所说 ,当IPv4地址来自同一套接字上收到的早期数据包时,您不需要关心这一点,因为您将比较一个映射的IPv4地址。 It is only in the case that the IPv4 address was obtained from an external source that you have to care. 只有在IPv4地址是从您需要关注的外部源获得的情况下才是这样。

As João Augusto pointed out, you neglected to check that the IPv6 address indeed is an IPv4 mapped address before comparing the last 32 bits. 正如JoãoAugusto指出的那样,在比较最后32位之前,你忽略了检查IPv6地址确实是IPv4映射地址。 There is a macro IN6_IS_ADDR_V4MAPPED that will help you do this: 有一个宏IN6_IS_ADDR_V4MAPPED可以帮助你这样做:

if (
    IN6_IS_ADDR_V4MAPPED(&(ipv6_clientdata->sin6_addr)) &&
    (ipv6_clientdata->sin6_port == ipv4_storeddata->sin_port) &&
    (ipv6_clientdata->sin6_addr.in6_u.u6_addr32[3] == ipv4_storeddata->sin_addr.s_addr)
) {
    addrfound = true;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM