IPv6路由广播是IPv6的新特性之一——无状态自动配置的实现途径。IPv6协议规定了两种设备自动配置方案,一种由DHCPv6实现,另一种就是无状态自动配置。
路由器广播本地子网的前缀和对应的路由器地址,新入网的设备根据这些信息自动配置网络。无状态自动配置的缺点是无法自动配置DNS。与在IPv4网络上随意发布DHCP信息相对应,在IPv6网络上发布错误的前缀也会干扰本地子网的使用者,而由于IPv6用户较少,不容易得到网络管理员的关注,故自己掌握如何解决这样的错误的IPv6路由广播是必要的。
首先必须描述一些基本知识。与IPv4地址由网路号和主机号构成相似,IPv6地址由前缀和主机号构成,且大多数场合下,前缀和主机号各有64位。可以理解为一个本地子网有的地址空间,故随意构造主机号造成撞车的概率很小。而通常IPv6无状态自动配置会给出这样的地址:2001:da8:d800:75:204:7dff:feb3:16f4
其中,黑体部分是IPv6路由广播出来的前缀,蓝色部分是你的MAC地址(前2位可能跟你看到的MAC地址不同,因为这里有编址模式的问题,但后面的几位一定相同),红色的ff:fe是固定值。一台主机可能会自己构造或者被分配多个IPv6地址,主机发送IP包时,应该在路由表上按最长前缀匹配原则选择特定的地址作为源地址——如果真的这么做,就不需要下面那么麻烦的解决方案了。问题是似乎没有人这么做。
Windows XP SP2 / Windows XP SP3
Windows XP的IPv6无状态自动配置关不掉,自动配置出来的***地址删不掉。
如果得到的错误广播是2002::开头的,那么相对容易解决一些——用prefix policy指定优先选择2001::开头的地址就可以了。
netsh int ipv6 set p 2001::/16 1 1 persistent
而如果错误广播是2001::开头的,那么就麻烦一些,prefix policy在这种情况下不管用,而且是直接把***配置的地址当作源地址。所以解决办法是首先关掉每5分钟自动生成一次临时地址的功能,然后手动配置一个正确的IPv6地址和网关。在命令行中执行netsh,进入netsh,以下将是在netsh中操作:
int ipv6
set pri dis
show int #看清楚自己的网卡对应的Idx是什么,下面Idx的位置填这个号码,Address的位置填一个自己编的IPv6地址,比如我喜欢把ff:fe改成ff:ff后的地址填在这
add addr Idx Address
add r ::0/0 Idx 网关地址
quit #退出
Windows Vista / Windows 7 / Windows Server 2008
Windows Vista之后的版本中的IPv6无状态自动配置终于可以关掉了。
netsh interface ipv6 set interface "你的本地连接的名称,比如’本地连接1‘" routerdiscovery=disable
Linux
Linux下有三种办法,前两种思路类似,一是拒绝IPv6路由广播,二是禁止自动配置。两个都是runtime kernel parameter,前者在net.ipv6.conf.
再有一种办法是用ip6tables丢弃错误广播的路由器送来的包。下面的命令将该规则添加到ip6tables。需要知道发送错误的广播的路由器的MAC地址,用tcpdump、wireshark等工具都可以轻易取得(注意观察Advertisement的发送者就是了)。
ip6tables -A INPUT -p icmpv6 -m mac --mac-source "路由器MAC地址" -j DROP
有些发行版有/etc/network/if-pre-up.d/icmpv6-routerfilt文件,可以直接在这个文件中配置。