代码之家  ›  专栏  ›  技术社区  ›  Spencer Ruport

IP地址与本地计算机在同一子网上(支持IPv6)

  •  5
  • Spencer Ruport  · 技术社区  · 14 年前

    编辑:

    我不确定我是否理解v4和v6之间的所有差异,所以这里有更多的问题。我有一个同时服务于internet客户机和intranet客户机的应用程序,也就是说,有一些客户机与服务器在同一物理网络上。因此,有时客户端之间有路由器,有时没有。对于IPv4,我可以通过检查客户端IP地址与服务器IP地址和子网来确定这一点,因此如果我的服务器的IP和子网掩码分别为:

    192.168.123.15

    服务器收到来自192.168.123.100的客户端请求,我知道客户端和服务器之间没有路由器。但是,如果服务器收到来自192.168.1.100或67.7.23.4的客户机请求,我知道在这些客户机和服务器之间有一个路由器。在.Net中,我可以收集客户端和服务器IP地址(v4和v6),但找不到IPv6子网掩码。

    有没有一种方法可以在.Net中收集这些信息,或者IPv4和IPv6之间有什么区别,我误解了吗?

    https://connect.microsoft.com/VisualStudio/feedback/details/643031/unicastipaddressinformation-class-has-no-ipv6mask-property

    我也在同一时间在MSDN论坛上发布了同样的问题。1800多个视图,没有一个回复。我想我不是唯一一个对此感兴趣的人。

    http://social.msdn.microsoft.com/Forums/en-US/netfxnetcom/thread/dd30e161-9be5-4d70-97c0-22e2756ce953

    4 回复  |  直到 14 年前
        1
  •  3
  •   mpontillo    14 年前

    /sbin/ip -6 route get <ipv6-addr> 你必须找到一个本机调用才能在Windows中实现这一点;我没有看到命令行应用程序。

    netsh interface ipv6 show route verbose . 您可以查找任何非/128前缀,并对这些前缀进行最长前缀匹配。(好吧,如果你点击a/128,那就是分配给盒子的地址)

    你也可以检查邻居的桌子。( netsh interface ipv6 show neighbors ),但如果您最近没有与该主机交谈,则可能不包含您要查找的条目。

    编辑 :这听起来像是检查邻居表对您来说是阻力最小的路径;如果您正在接受来自intranet的连接,然后掉头检查邻居表,您可以合理地确定,如果邻居是本地的,它将存在于表中。如果你查一下邻居的桌子, 小心 整个IPv4 internet

    同样,IPv6地址没有“网络掩码”的概念,因为on-link前缀表与地址分配是分开的。 然而 ,如果你有一个服务器在某处,你可以99%肯定它是在一个服务器上 /64

    • 忽略前64位为0的所有地址(本地环回)
    • 忽略所有匹配ff00::/8的地址(多播)
    • 接口本地 . 注意这一点,因为如果您启用了ISATAP接口,“link local”意味着“到整个IPv4互联网的自动隧道”!所以最好不要信任链接本地地址,除非你确定它们来自局域网接口。(无法路由)
    • 在服务器上 (假设没有时髦的隧道配置了非/64前缀)这在极少数情况下会是一个错误,因为-同样-你不能确定地址是否真的在链接上,除非你检查了链接前缀表。(Windows对此没有概念;它似乎存储在路由表中。)大多数可以配置为在以太网接口上发送路由器播发的网络设备将始终播发/64前缀。如果您可以检查数据包是否来自LAN接口,那么这将更不可能是一个错误。

    编辑2

    我已经编写了一些代码来解析IPv6路由表并发布了它 here

        2
  •  2
  •   james woodyatt    14 年前

    IPv6中IPv4网络掩码的道德等价物称为 前缀长度 . (实际上,我们也喜欢讨论IPv4中的前缀长度而不是网络掩码,但有些人还没有收到备忘录。)

    IPv6中另一个没有IPv4的问题是,默认路由器通过回答来自主机的路由器请求查询来公布它们在链路上的存在。主机保留了一个列表,其中列出了他们通过这种方式找到的所有默认路由器以及它们的有效和首选生存期。路由器也可以公布零个、一个或多个前缀,作为默认路由器,主机保留这些前缀的列表及其关联的路由器和各自的有效和首选生存期。

    每个前缀在播发中都有两个辅助位A和L,当主机将它们添加到前缀列表中时,它们会被主机合并。A=1位表示是否允许主机自动配置具有该前缀的接口地址,而A=0表示要求主机通过DHCPv6或手动获取具有该前缀的地址。L=1位表示前缀为“链路上”,主机可以使用邻居发现(相当于ARP的IPv6)通过网络直接发送,而L=0表示前缀为“链路外”,主机需要将该前缀的所有流量发送到默认路由器。

    长话短说:如果你想知道一个IPv6地址是“链接上”的,那么你必须遍历IPv6前缀列表,将每个前缀与地址进行比较,还要查看L位以确保它是链接上的前缀。唉,我只知道BSD系统查看前缀列表的方式,即。 sysctl(ICMPV6CTL_ND6_PRLIST, ...) . 真的不知道MSFT是否为此向C开发者提供了什么。

        3
  •  2
  •   Andee    14 年前

    我一直在看wmi文档,试图找到ipv6前缀,我也很难找到它。不过,我有IPv4的工作代码。

    我想您可以放心地假设该网段的前缀是/64。如果你这样做,你可以只比较每个地址的前8个字节。运行应用程序的单个本地网络通常是a/64,即使点到点链接通常也会给出一个完整的/64范围,即使只使用了2个。

        4
  •  1
  •   Michael Dillon    14 年前