获取物理网卡的MAC地址

前段时间又遇到了一个奇奇怪怪的需求, 就是在程序中获取物理网卡的MAC地址, 之所以强调是物理网卡, 是因为不想要虚拟机和VPN的虚拟网卡的MAC地址. 当然了, 这个需求还是有其实际意义的, 就是做软件的反盗版功能. 看似简单的功能, 其实花费了好长时间, 而且还没写出来, 就把写的部分代码和找的资料贴在这里吧.

其实思路很简单, 就是通过接口名, MAC地址前缀和注册表过滤掉虚拟网卡, 我用JavaScript写的代码如下(没写完):

const os = require('os');
const regedit = require('regedit').promisified;

const VIRTUAL_IF_PREFIX = [
    "00:00:00:00:00:00", // 空地址
    "00:05:69", // VMware1
    "00:0c:29", // VMware2
    "00:50:56", // VMware3
    "00:1c:14", // VMware4
    "08:00:27", // VirtualBox1
    "0a:00:27", // VirtualBox2
    "00:03:ff", // Microsoft Virtual PC
    "00:15:5d", // Hyper-V
    "00:1c:42", // parallels1
    "00:0f:4b", // virtual iron 4
    "00:16:3e", // red hat xen, oracle vm, xen source, novell xen
];
const NCF = {
    NCF_VIRTUAL: 0x1, // 虚拟适配器
    NCF_SOFTWARE_ENUMERATED: 0x2, // 软件模拟的适配器
    NCF_PHYSICAL: 0x4, // 物理适配器
    NCF_HIDDEN: 0x8, // 不显示用户接口
    NCF_NO_SERVICE: 0x10, // 没有相关的服务(设备驱动程序)
    NCF_NOT_USER_REMOVABLE: 0x20, // 不能被用户删除(通过控制面板或设备管理器)
    NCF_MULTIPORT_INSTANCED_ADAPTER: 0x40, // 有多个端口, 每个端口作为单独的设备安装
    NCF_HAS_UI: 0x80, // 支持用户接口(例如Advanced Page或Customer Properties Sheet)
    NCF_FILTER: 0x400, // 过滤器
};

function readRegistry() {
    try {
        let registry = cp.execSync("REG QUERY HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Control\\Class\\{4d36e972-e325-11ce-bfc1-08002be10318}", { encoding: "utf-8" });
        console.log(registry);
    } catch (err) {
        console.error(err);
    }
    return null;
}

function getPhysicsIf() {
    const ifaces = os.networkInterfaces();
    return Object.entries(ifaces)
        .filter(([dev, iface]) => {
            // 过滤掉名称中有virtual的网卡
            if (dev.toLowerCase().includes("virtual")) {
                return false;
            }
            for (let item of iface) {
                // 过滤掉127.0.0.1和::1
                if (item.ernal) {
                    return false;
                }
                // 通过前缀过滤掉虚拟网卡
                if (VIRTUAL_IF_PREFIX.some(value => item.mac.startsWith(value))) {
                    return false;
                }
                // TODO 通过注册表过滤掉虚拟网卡
            }
            return true;
        })
        .map(([dev, iface]) => {
            return iface[0].mac;
        });
}

function getMac() {
    const ifaces = getPhysicsIf();
    return ifaces[0];
}

console.log(`本机物理网卡的MAC地址为: ${getMac()}`);

这还只考虑了Windows上, 还没考虑跨平台, 不想玩了…接下来就贴点我找到的资料吧

标题: 获取物理网卡的MAC地址
作者: QingChenW
链接: https://dawncraft.cc/2023/01/448/
本文遵循 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 许可
禁止商用, 非商业转载请注明作者及来源!
上一篇
下一篇
隐藏