我们知道,我们可以使用 MAC 地址来创建接口标识符,例如链路本地 IPv6 地址,该地址在网络中应该是唯一的。
该图显示了执行此操作的方法:
我的问题是:
- 如何使用
awk
或从 MAC 创建 IPv6 地址sed
? - 或者是否有任何命令可以为我提供特定 MAC 的链路本地 IPv6 地址(类似的东西
createIPv6 myMAC
)?
答案1
如果您想从 MAC(和给定的前缀)创建完整的 IPv6 地址,您可以使用ipv6calc
Peter 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 格式仅留下可能全零的另一块(最后一个块),上面的脚本将其添加回作为单个零。其他前缀可能要求在两个冒号之间留下一个零。