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"dmesgは、AND予約されているすべてのMACに対してこの操作を自動的に実行する魔法です(NIC固有の文字列、別の文字列に置き換えます)。例:wlan0 MACはX、wlan1 MACはY)

質問:出力でNIC固有のMACアドレス文字列を調べながら、異なるdmesgMACアドレスが複数ある可能性を維持するにはどうすればよいですか?

アップデート#1:「私」の方法で、例に示すように、約1,600万行(16 * 16 * 16 * 16 * 16 * 16 = 16 ^ 2 = 16,777,216)のテーブルを作成できます。もともとMACが何であるかを把握できるので、それは良くありません!

アップデート#2:ソリューションは大文字と小文字を区別する必要があるため、MACが大文字か小文字であるかは問題ではありません。

答え1

大文字と小文字を区別しないMacアドレスの場合、grepより良い一致を得るには、16進数値に一致するようにパターンを拡張し、6つの16進文字のペアとすべて一致するように正数を減らす必要があります。

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を一致させるには、まずこれがリストLであると仮定し、dmesg出力テキストに表示される他のMACをすべて知る必要があります。次に、Lの各要素をLにない任意のMACにマッピングし、マッピングに従って各MACアドレスを置き換えます。

私は初心者ではありませんが、awk上記の要件はその能力を超えていると思います。私はpython/ruby/perlでこのようなことを真剣に考えます。

ただし、出力にMACアドレスのみがあり、グローバルに一意のdmesgOrganitional Unique Identifier(OUI)ビットが設定されている場合は、ショートカットがある可能性があります。これは、最初の16進文字にビット1(1)が設定されている文字です(つまり、値は2、、、、、、、、、)。これは正式にリリースされたハードウェアの場合の正常な現象です。この場合、各MACアドレスを「ローカル管理」MACアドレス(ビット1クリア)にマッピングすると、任意のMACアドレス(ビット1クリア)が既存のMACアドレスと一致することを心配する必要はありません。この場合、実際のMACで発生する可能性のあるランダムな衝突をバッファリングするのではなく、マッピング(後でファイルで発生するアクション)を維持するだけです。この制限は、たとえば、要件を実装できる ようにプログラムを単純化するのに十分です(より制限的な場合には達成できないと仮定)。367abef
awk

6バイトMAC-48の使用は、8バイト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()

関連情報