如何使用shell从MAC地址导出IPv6地址?

如何使用shell从MAC地址导出IPv6地址?

我们知道,我们可以使用 MAC 地址来创建接口标识符,例如链路本地 IPv6 地址,该地址在网络中应该是唯一的。

该图显示了执行此操作的方法:

从 MAC 地址创建接口标识符

我的问题是:

  • 如何使用awk或从 MAC 创建 IPv6 地址sed
  • 或者是否有任何命令可以为我提供特定 MAC 的链路本地 IPv6 地址(类似的东西createIPv6 myMAC)?

答案1

如果您想从 MAC(和给定的前缀)创建完整的 IPv6 地址,您可以使用ipv6calcPeter Bieringer 提供的优秀工具。

fe80::以下命令从 MAC 地址创建链路本地 IPv6 地址(前缀):

$ ipv6calc --action prefixmac2ipv6 --in prefix+mac --out ipv6addr fe80:: 00:21:5b:f7:25:1b
fe80::221:5bff:fef7:251b

您可以保留大部分选项,让命令猜测要做什么:

$ ipv6calc --in prefix+mac fe80:: 00:21:5b:f7:25:1b
No action type specified, try autodetection...found type: prefixmac2ipv6
fe80::221:5bff:fef7:251b

对于 Debian 发行版,ipv6calc位于主存储库中。

答案2

来自IPv6 维基百科输入更多文字描述:

64 位接口标识符通常源自其 48 位 MAC 地址。

通过在中间插入 FF:FE,MAC 地址 00:0C:29:0C:47:D5 将转换为 64 位 EUI-64:00:0C:29:FF:FE:0C:47:D5。

因此,将第三个替换::FF:FE:应该可以解决问题:

echo  00:0C:29:0C:47:D5 | sed s/:/:FF:FE:/3
00:0C:29:FF:FE:0C:47:D5

不知道该语法是否特定于 GNU sed。


工作正在进行中:

将其转换为位:

for HEX in $(tr ":" " " <<< 00:0C:29:FF:FE:0C:47:D5) 
  do 
    printf "%08d " $(bc <<< "ibase=16;obase=2;$HEX") 
  done

应该导致这些位00000000 00001100 00101001 11111111 11111110 00001100 01000111 11010101只留下第 7 位的翻转。

答案3

#! /usr/bin/env python
import sys
n=[int(x, 16) for x in sys.argv[1].split(":")]
print "fe80::%02x%02x:%02xff:fe%02x:%02x%02x" % tuple([n[0]^2]+n[1:])

答案4

我必须向上面的 @rubo77 致敬,以获得上面我正在寻找的纯 shell(除非你算上 printf)答案。

这增加了一些 sed :

(a) 删除每个 16 位块中的任何前导零;和

(b) 删除 IID 开头的任何其他全零块

...按照地址简洁的通用约定。

mac_to_eui64() {
 IFS=':'; set $1; unset IFS
 echo "fe80::$(printf %x $((0x$1 ^ 2)))$2:${3}ff:fe$4:$5$6" |
  sed -E 's/:0+/:/g; s/:{3,}/::/; s/:$/:0/'
}

请注意,如果您希望将其重新用于其他(任意)前缀,那么您可能会这样做,因为 EUI-64 可以在任何范围内使用(尽管出于隐私原因建议不要将其用于全局地址),您需要稍微更复杂的 sed 脚本。这是因为fe80::前缀已包含与 IID 开头相邻的三个零块(省略了双冒号)。因此,即使 IID 的第一个块全为零(即,如果 MAC 以 开头02:00),它也会被忽略。 EUI-64 格式仅留下可能全零的另一块(最后一个块),上面的脚本将其添加回作为单个零。其他前缀可能要求在两个冒号之间留下一个零。

相关内容