【问题标题】:Comparing a peer's IPv6 address with localhost将对等方的 IPv6 地址与 localhost 进行比较
【发布时间】:2010-05-18 23:40:32
【问题描述】:

我在连接的套接字上调用了getpeername,现在有了连接对等方的 IPv6 地址。如何判断对端的 IP 地址是否为 localhost?

编辑:澄清一下,我的意思是 localhost,就像在环回 IP 地址中一样。

【问题讨论】:

  • 问题含糊不清。 R Samuel Klatchko 假设您的意思是“localhost”(::1),Remy Lebeau - TeamB 假设您的意思是“本地主机”(所有本地 IPv6 地址)。请澄清。

标签: c sockets ipv6


【解决方案1】:

在 IPv6 中,环回地址为 ::1

在二进制级别,即 127 个 0 后跟一个 1。

【讨论】:

  • 有时显示为0:0:0:0:0:0:0:1,而不是::1的缩写形式。
  • jschmier:正确但不需要使用文本形式,getpeername返回二进制,明确无误。
【解决方案2】:

排除环回地址后,检索本地计算机的当前活动 IP 列表(该计算机可能为不同的网络分配了多个 IP),然后遍历该列表直到找到匹配项。您实际获得该列表的方式取决于您使用的操作系统。操作系统可能有自己的 API(例如,Windows 有 GetAdaptersInfo() 和相关函数),或者您可以尝试将 gethostname() 与 gethostbyname() 或 getaddrinfo() 一起使用。

【讨论】:

    【解决方案3】:

    我想这是如何查看传入连接是否为 localhost,假设您在 struct sockaddr_in6 中有对等点,从 getpeername 获得,如下所示:

        struct sockaddr_in6 peer;
        socklen_t len = sizeof(peer);
        getpeername( sock, (struct sockaddr *) &peer, &len); // todo: error check
    

    从那里,您可以使用本地地址::1 填写您自己的struct sockaddr_in6 并比较内存是否相等:

        struct sockaddr_in6 localhost;
        memset(localhost.sin6_addr.s6_addr, 0, 16);
        localhost.sin6_addr.s6_addr[15] = 1;
    
        if( memcmp(peer.sin6_addr.s6_addr, localhost.sin6_addr.s6_addr, 16) == 0)
            printf("localhost!\n");
    

    或者您可以创建一个与 localhost 地址对应的字节数组:

        static const unsigned char localhost_bytes[] =
            { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
    
        if( memcmp(peer.sin6_addr.s6_addr, localhost_bytes, 16) == 0)
            printf("localhost!\n");
    

    并注意映射的 IPv4 本地主机 ::ffff:127.0.0.1。你可能也需要检查一下。

        static const unsigned char mapped_ipv4_localhost[] =
            { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0x7f, 0, 0, 1 };
    
        if( memcmp(peer.sin6_addr.s6_addr, mapped_ipv4_localhost, 16) == 0)
            printf("mapped IPv4 localhost!\n");
    

    【讨论】:

    • 您可能需要考虑仅比较前 13 个字节来检查 IPv4 映射的 localhost。 (无论如何,在 Linux 上 - 如果您 p​​ing 127.0.0.0/8 网络中的任何内容,它会被视为 localhost。)RFC 3330 将整个范围定义为环回:tools.ietf.org/html/rfc3330
    猜你喜欢
    • 2012-02-08
    • 2010-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-27
    • 1970-01-01
    • 2017-07-20
    相关资源
    最近更新 更多