| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657 |
- import * as os from "node:os";
- import * as net from "node:net";
- export class IpUtil {
- // 常见虚拟机网络地址范围
- private static readonly VM_NETWORKS = [
- '192.168.56.0/24', // VirtualBox Host-Only
- '192.168.122.0/24', // KVM
- '172.16.0.0/12', // VMware NAT
- '192.168.99.0/24', // Docker Machine
- '192.168.65.0/24', // Docker Desktop
- '192.168.250.0/24', // Parallels
- '192.168.131.0/24' // Hyper-V
- ];
- public static async getLocalIp(): Promise<string> {
- return new Promise((resolve, reject) => {
- const addressArray = IpUtil.getActiveIPv4Addresses()
- if (addressArray && addressArray.length > 0) {
- resolve(addressArray[0])
- }
- reject('未找到可用的IP地址')
- })
- }
- private static getActiveIPv4Addresses() {
- const interfaces = os.networkInterfaces()
- const addresses: Array<string> = []
- for (const interfaceName in interfaces) {
- const interfaceInfo = interfaces[interfaceName]
- // @ts-ignore
- for (const info of interfaceInfo) {
- // 过滤条件:IPv4、不是内部地址、不是回环地址、不是虚拟机IP
- if (info.family === 'IPv4' &&
- !info.internal &&
- net.isIPv4(info.address) &&
- !IpUtil.isVMIP(info.address)) {
- addresses.push(info.address)
- }
- }
- }
- return addresses
- }
- private static isVMIP(ip) {
- const ipLong = ip.split('.').reduce((acc, octet) => (acc << 8) + parseInt(octet, 10), 0)
- return IpUtil.VM_NETWORKS.some(range => {
- const [base, maskBits] = range.split('/')
- const mask = ~(0xFFFFFFFF >>> parseInt(maskBits, 10));
- const baseLong = base.split('.').reduce((acc, octet) => (acc << 8) + parseInt(octet, 10), 0)
- return (ipLong & mask) === (baseLong & mask)
- });
- }
- }
|