如何从 dmesg 输出中审查 MAC?

如何从 dmesg 输出中审查 MAC?

输入:

dmesg | grep [0-9][0-9]:[0-9][0-9]
f0:de:f1:11:22:33
...

输出:

dmesg | SOMEMAGIC | grep [0-9][0-9]:[0-9][0-9]
f0:de:f1:52:22:17
...

我是如何得到“52:22:17”的?

echo 11:22:33 | cksum | sed "s/.\{2\}/&:/g" | cut -d: -f-3
52:22:17

通过这种方式,当我必须给出输出时,我可以“审查”我的 MAC 地址 NIC 特定字符串dmesg。 (“SOMEMAGIC”是一个神奇的东西,它可以自动为所有可以在dmesgAND 保留(NIC 特定字符串,只需将其替换为另一个字符串)中找到的 MAC 执行此操作,例如:wlan0 MAC 是 X,wlan1 MAC是 Y)

问题:如何从输出中审查 MAC 地址的 NIC 特定字符串dmesg,但保留可能存在多个不同的 MAC 地址?

UPDATE#1:以“我的”方式,如示例所示,我们可以生成一个包含约 1600 万行的表 (16*16 * 16*16 * 16*16 = 16^2 = 16 777 216) - 所以它是不好,因为它可以找出原来的 MAC 是什么!

UPDATE#2:解决方案必须不区分大小写,因此 MAC 是大写还是小写都没有关系

答案1

对于grep不区分大小写的 mac 地址,为了获得更好的匹配,您应该扩展模式以匹配十六进制值,并减少正数匹配所有 6 对十六进制字符:

dmesg | grep -i [0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]

取代任何可以出现多次的 MAC 的数量,其中随机的一个,以及随机的绝不匹配一个(其他)MAC,你必须首先知道 dmesg 输出文本中出现的所有不同 MAC,假设这是一个列表 L。然后将 L 中的每个元素映射到 L 中未出现的随机 MAC,并根据映射替换每个MAC地址。

我什至不是一个初学者awk,但我认为上面这些要求已经超出了它的能力。我会认真考虑在 python/ruby/perl 中做这样的事情。

但是,如果输出中只有 MAC 地址dmesg且设置了全局唯一 OUI(组织唯一标识符)位,则可能有捷径。这些是在第一个十六进制字符中设置了位一 (1) 的字符(即值为2, 3, 6, 7, a, b, e, f)。这对于正式发布的硬件来说是正常的。如果是这种情况,您可以将每个 MAC 地址映射到“本地管理”MAC 地址(清除第 1 位),而不必担心您的随机 MAC 地址(清除第 1 位)恰好与现有 MAC 地址匹配。在这种情况下,您只需保留映射(对于文件后期发生的情况),而不是缓冲可能与真实 MAC 发生的随机冲突。
此限制可能足以简化程序,例如awk能够实现您的要求(假设它们在更严格的情况下无法实现)。

请注意,六字节 MAC-48 的使用已被八字节 EUI-64 标识符“扩展”。我自己还没有看到这些,但它们可能会出现在您的dmesg输出中。

一个处理困难情况的 python 程序:

#! /usr/bin/env python
# coding: utf-8

import sys
import re
import io
from random import randint

MAC48_REGEX = re.compile(r"""
   (?x)(?i)               # free spacing mode, ignore case
   ([0-9A-F]{2}[:-]){5}   # five times two hex-characters, followed by : or -
   ([0-9A-F]{2})          # final two hex-characters
""")


class MatchMAC48(object):
    MAX_MAC = 256 ** 6 - 1
    def __init__(self):
        self._mac_map = {}
        self._buffer = io.StringIO()

    def __call__(self, line):
        """analyse the input for input MAC addresses and store them"""
        self._buffer.write(line)
        res = MAC48_REGEX.search(line)
        if not res:
            return line  # no MACs
        index = 0
        while res:
            self._mac_map[res.group()] = None
            index += res.span()[1]
            res = MAC48_REGEX.search(line[index:])

    def generate_map(self):
        """generate a unique mapping MAC for each of the MAC address keys"""
        for k in self._mac_map:
            if self._mac_map[k] is not None:
                continue
            r = None
            while (r is None or 
                  r in self._mac_map or         # not an original MAC 
                  r in self._mac_map.values()): # twice the same random MAC
                  r = randint(0, self.MAX_MAC)
            ml = []
            for i in range(6):
                ml.insert(0, u'{:02x}'.format(r & 255))
                r >>= 8
            self._mac_map[k] = u':'.join(ml)

    def dump(self, fp=sys.stdout):
        """dump the cached StringIO buffer"""
        mm48.generate_map()  # in case not yet generated
        x = self._buffer.getvalue()
        for k in self._mac_map:
            x = x.replace(k, self._mac_map[k])
        fp.write(x)


mm48 = MatchMAC48()

for line in sys.stdin:
    mm48(line.decode('utf-8'))

mm48.dump()

相关内容