C# IP地址与本地计算机位于同一子网上(支持IPv6)

C# IP地址与本地计算机位于同一子网上(支持IPv6),c#,.net,ipv6,subnet,C#,.net,Ipv6,Subnet,是否有人拥有一些代码来确定IP地址(IPv4或IPv6)是否与运行应用程序的计算机位于同一子网中?我已经看到了许多使用IPv4实现这一点的代码示例,但我找不到任何支持IPv6的代码 编辑: 我不确定我是否理解v4和v6之间的所有差异,所以这里有更多的问题。我有一个同时服务于internet客户端和intranet客户端的应用程序,也就是说,有一些客户端与服务器位于同一物理网络上。所以有时候客户端之间有路由器,有时候没有。对于IPv4,我可以通过对照服务器IP地址和子网检查客户端IP地址来确定这一

是否有人拥有一些代码来确定IP地址(IPv4或IPv6)是否与运行应用程序的计算机位于同一子网中?我已经看到了许多使用IPv4实现这一点的代码示例,但我找不到任何支持IPv6的代码

编辑:

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

192.168.123.15 255.255.255.0

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

是否有一种方法可以在.Net中收集这些信息,或者IPv4和IPv6之间是否存在一些我误解的差异

编辑x2:

我在MS connect网站上发布了这篇文章,以了解这是否是他们正在研究的内容,或者他们没有向UnicastIPAddressInformation类添加IPv6Mask属性的原因

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


框架似乎没有办法做到这一点。最准确的方法是进行路由查找,但我认为在C#中没有好的方法。(在Linux下,我会执行
/sbin/ip-6 route get
并查看返回哪个路由。)您必须在Windows中找到一个本机调用才能执行此操作;我没有看到命令行应用程序

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

您还可以检查相邻的表。(
netsh interface ipv6 show neights
),但如果您最近没有与该主机通话,则可能不包含您要查找的条目

您需要考虑的其他潜在问题:

  • (以及多播、环回和未指定-表中的所有内容)
  • 在IPv6中,分配的地址并不意味着链路前缀。前缀表是独立的。目前尚不清楚如何在Windows下进行测试,但
    netsh interface ipv6 show siteprofixes
    可能会有所帮助。看起来Windows实际上可能比标准预期的更像IPv4
编辑:这听起来像是检查邻居表是您进行此操作阻力最小的路径;如果您正在接受来自intranet的连接,然后掉头检查邻居表,那么可以合理地确定,如果邻居是本地的,那么它将存在于表中。如果检查邻居表,请小心仅查看邻居表中的LAN接口。(默认情况下在许多Windows系统上安装的ISATAP接口将整个IPv4 internet作为链接本地“子网”公开。)

同样,IPv6地址没有“网络掩码”的概念,因为链路前缀表与地址分配是分开的但是,如果您在某处有一台服务器,您可以99%确定它位于/64上。(尽管您必须小心;如果它本身是一个隧道端点,有时我会看到为6in4隧道分配更长的前缀),因此一个快速而肮脏的算法应该是:

  • 忽略前64位为0的所有地址(本地环回)
  • 忽略所有匹配ff00::/8的地址(多播)
  • 如果地址与fe80::/10匹配,则为接口本地。注意这一点,因为如果启用了ISATAP接口,“本地链接”意味着“自动隧道到整个IPv4互联网”!(不太好。)所以最好不要信任链接本地地址,除非您确定它们来自LAN接口。(它们无法路由)
  • (现在是复杂的部分)确定地址是否是邻居。(邻居查找)黑客和斜杠解决方案是检查系统上配置的所有IPv6地址(通过无状态地址自动配置、DHCPv6或静态自动配置,如果可以确定),并检查前64位在服务器上(假设没有时髦的隧道配置非-/64前缀),这在极少数情况下会是一个错误,因为-同样-除非检查链接前缀表,否则无法确定地址是否真的在链接上。(Windows没有这个概念;它似乎存储在路由表中。)大多数可以配置为在以太网接口上发送路由器播发的网络设备将始终播发/64前缀。如果您可以检查数据包是否来自LAN接口,那么这将更不可能是一个bug
编辑2


我已经编写了一些代码来解析IPv6路由表并发布了它。它还没有解决这个问题中的难题,但它是朝着正确方向迈出的一步。

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