pax_global_header00006660000000000000000000000064151242050210014502gustar00rootroot0000000000000052 comment=4991204a001259149b68f45eb5966cf1fadda904 node-macaddress-0.5.4/000077500000000000000000000000001512420502100145415ustar00rootroot00000000000000node-macaddress-0.5.4/.editorconfig000066400000000000000000000001161512420502100172140ustar00rootroot00000000000000root = true [*] charset = utf-8 [*.js] indent_style = space indent_size = 4 node-macaddress-0.5.4/.github/000077500000000000000000000000001512420502100161015ustar00rootroot00000000000000node-macaddress-0.5.4/.github/workflows/000077500000000000000000000000001512420502100201365ustar00rootroot00000000000000node-macaddress-0.5.4/.github/workflows/npm-publish.yml000066400000000000000000000016251512420502100231230ustar00rootroot00000000000000name: Publish to npm on: release: types: [published] permissions: id-token: write # Required for OIDC contents: read jobs: publish: runs-on: ubuntu-latest environment: npm-publish permissions: contents: read id-token: write steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: '24' registry-url: 'https://registry.npmjs.org' - run: npm ci - run: npm run build --if-present - run: npm test - name: Debug auth environment run: env | sort | rg 'NPM|NODE_AUTH' || true - name: Debug npm auth config run: npm config list -l | rg authToken || true - name: Ensure trusted publishing (clear token auth) run: npm config delete //registry.npmjs.org/:_authToken || true - run: npm publish --provenance env: NODE_AUTH_TOKEN: "" node-macaddress-0.5.4/.gitignore000066400000000000000000000001221512420502100165240ustar00rootroot00000000000000.* !/.gitignore !/.editorconfig !/.travis.yml !/.github /node_modules /dist *.log node-macaddress-0.5.4/.travis.yml000066400000000000000000000005601512420502100166530ustar00rootroot00000000000000language: node_js os: - linux - osx - windows node_js: - stable - lts/* - "10.5" - "8.11" - "6.14" - "4.9" - "0.12" - "0.11" - "0.10" - "0.9" - "0.8" - iojs - iojs-v1.0.4 install: - npm install jobs: exclude: - os: windows node_js: stable - os: windows node_js: iojs - os: windows node_js: iojs-v1.0.4 node-macaddress-0.5.4/AGENTS.md000066400000000000000000000037401512420502100160500ustar00rootroot00000000000000# Repository Guidelines ## Project Structure & Module Organization - `index.js` is the public entry point; `index.d.ts` provides TypeScript typings. - `lib/` contains the implementation, split by responsibility: - `lib/getmacaddress.js`, `lib/getallinterfaces.js`, `lib/networkinterfaces.js` handle core APIs. - `lib/platform/` holds OS-specific helpers. - `lib/util.js` provides shared utilities (promisify, iteration helpers). - `test.js` is a lightweight smoke test that exercises callbacks and Promises. ## Build, Test, and Development Commands - `npm install` installs dependencies (there are no runtime deps, but it ensures npm metadata is up to date). - `npm test` runs `node test.js` to print detected interfaces and validate MAC formats. - There is no build step; changes in `lib/` and `index.js` are shipped directly. ## Coding Style & Naming Conventions - Use CommonJS (`require`, `module.exports`) and `"use strict";` at the top of files. - Indentation is 4 spaces in core modules; keep the existing style in the file you edit. - Prefer double quotes in core modules (`index.js`, `lib/`), but respect local conventions. - File names are lowercase and descriptive (e.g., `getmacaddress.js`). ## Testing Guidelines - Tests are a single script in `test.js`; run with `npm test`. - The test is a smoke check: it validates format and prints detected interfaces. - When adding functionality, extend `test.js` with focused checks (e.g., new API options). ## Commit & Pull Request Guidelines - Commit messages are short and imperative (e.g., `Remove build status badge`, `Bump patch version`). - Conventional prefixes like `fix:` appear occasionally; use them if they fit the change. - PRs should include a concise description, test results (`npm test`), and any OS-specific notes if behavior differs across platforms. ## Platform & Runtime Notes - This package targets Node.js and runs on Linux, macOS, and Windows. - Avoid browser-specific APIs; the library reads host network interface data only. node-macaddress-0.5.4/LICENSE000066400000000000000000000020611512420502100155450ustar00rootroot00000000000000MIT License Copyright (c) 2018 Julian Fleischer Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. node-macaddress-0.5.4/README.md000066400000000000000000000074521512420502100160300ustar00rootroot00000000000000node-macaddress =============== Retrieve [MAC addresses](https://en.wikipedia.org/wiki/MAC_address) in Linux, OS X, and Windows. A common misconception about MAC addresses is that every *host* had *one* MAC address, while a host may have *multiple* MAC addresses – since *every network interface* may have its own MAC address. This library allows to discover the MAC address per network interface and chooses an appropriate interface if all you're interested in is *one* MAC address identifying the host system (see `API + Examples` below). A common misconception about this library is that it reports the mac address of the client that accesses some kind of backend. It does not. Reporting the mac address is not in any way similar to reporting the IP address of the client that accesses your application. This library reports the mac address of the server the application is running on. This useful for example for distributed/scaled applications, for example when generating UUIDs. Also it seems to be worth noting that this library is not intended to be used in a browser. There is no web api reporting the mac address of the machine (and that is a good thing). **Features:** + works on `Linux`, `Mac OS X`, `Windows`, and on most `UNIX` systems. + `node ≥ 0.12` and `io.js` report MAC addresses in `os.networkInterfaces()` this library utilizes this information when available. + also features a sane replacement for `os.networkInterfaces()` (see `API + Examples` below). + works with stoneage node versions ≥ v0.8 (...) + Promise support Usage ----- ``` npm install --save macaddress ``` ```JavaScript var macaddress = require('macaddress'); ``` API + Examples -------------- (async) .one(iface, callback) → string (async) .one(iface) → Promise (async) .one(callback) → string (async) .all() → Promise<{ iface: { type: address } }> (async) .all(callback) → { iface: { type: address } } (sync) .networkInterfaces() → { iface: { type: address } } --- ### `.one([iface], callback)` Retrieves the MAC address of the given `iface`. If `iface` is omitted, this function automatically chooses an appropriate device (e.g. `eth0` in Linux, `en0` in OS X, etc.). **Without `iface` parameter:** ```JavaScript macaddress.one(function (err, mac) { console.log("Mac address for this host: %s", mac); }); ``` or using Promise ```JavaScript macaddress.one().then(function (mac) { console.log("Mac address for this host: %s", mac); }); ``` ``` → Mac address for this host: ab:42:de:13:ef:37 ``` **With `iface` parameter:** ```JavaScript macaddress.one('awdl0', function (err, mac) { console.log("Mac address for awdl0: %s", mac); }); ``` or using Promise ```JavaScript macaddress.one('awdl0').then(function (mac) { console.log("Mac address for awdl0: %s", mac); }); ``` ``` → Mac address for awdl0: ab:cd:ef:34:12:56 ``` --- ### `.all(callback)` Retrieves the MAC addresses for all non-internal interfaces. ```JavaScript macaddress.all(function (err, all) { console.log(JSON.stringify(all, null, 2)); }); ``` or using Promise ```JavaScript macaddress.all().then(function (all) { console.log(JSON.stringify(all, null, 2)); }); ``` ```JavaScript { "en0": { "ipv6": "fe80::cae0:ebff:fe14:1da9", "ipv4": "192.168.178.20", "mac": "ab:42:de:13:ef:37" }, "awdl0": { "ipv6": "fe80::58b9:daff:fea9:23a9", "mac": "ab:cd:ef:34:12:56" } } ``` --- ### `.networkInterfaces()` A useful replacement of `os.networkInterfaces()`. Reports only non-internal interfaces. ```JavaScript console.log(JSON.stringify(macaddress.networkInterfaces(), null, 2)); ``` ```JavaScript { "en0": { "ipv6": "fe80::cae0:ebff:fe14:1dab", "ipv4": "192.168.178.22" }, "awdl0": { "ipv6": "fe80::58b9:daff:fea9:23a9" } } ``` node-macaddress-0.5.4/index.d.ts000066400000000000000000000007741512420502100164520ustar00rootroot00000000000000declare module 'macaddress' { export type MacAddresCallback = (err: any, data: any) => void; export type MacAddressOneCallback = (err: any, mac: string) => void; export function one(callback: MacAddressOneCallback): void; export function one(iface?: string): Promise; export function one(iface: string, callback: MacAddressOneCallback): void; export function all(callback: MacAddresCallback): void; export function all(): Promise; export function networkInterfaces(): any; } node-macaddress-0.5.4/index.js000066400000000000000000000075441512420502100162200ustar00rootroot00000000000000/* jshint node: true */ "use strict"; var util = require("./lib/util.js"); var lib = {}; lib.getMacAddress = require("./lib/getmacaddress.js"); lib.getAllInterfaces = require("./lib/getallinterfaces.js"); lib.networkInterfaces = require("./lib/networkinterfaces.js"); // devices like en0 (mac), eth3 (linux), Ethernet (windows), etc. are preferred var goodIfaces = new RegExp("^((en|eth)[0-9]+|ethernet)$", "i"); // https://github.com/scravy/node-macaddress/issues/32 var badIfaces = new RegExp("^(vboxnet[0-9]+)$", "i"); lib.one = function () { // one() can be invoked in several ways: // one() -> Promise // one(iface: string) -> Promise // one(iface: string, callback) -> async, yields a string // one(callback) -> async, yields a string var iface = null; var callback = null; if (arguments.length >= 1) { if (typeof arguments[0] === "function") { callback = arguments[0]; } else if (typeof arguments[0] === "string") { iface = arguments[0]; } if (arguments.length >= 2) { if (typeof arguments[1] === "function") { callback = arguments[1]; } } } if (!callback) { return util.promisify(function (callback) { lib.one(iface, callback); }); } if (iface) { lib.getMacAddress(iface, callback); return; } var ifaces = lib.networkInterfaces(); var addresses = {}; var best = []; var args = []; Object.keys(ifaces).forEach(function (name) { args.push(name); var score = 0; var iface = ifaces[name]; if (typeof iface.mac === "string" && iface.mac !== "00:00:00:00:00:00") { addresses[name] = iface.mac; if (iface.ipv4) { score += 1; } if (iface.ipv6) { score += 1; } if (goodIfaces.test(name)) { score += 2; } if (badIfaces.test(name)) { score -= 3; } best.push({ name: name, score: score, mac: iface.mac }); } }); if (best.length > 0) { best.sort(function (left, right) { // the following will sort items with a higher score to the beginning var comparison = right.score - left.score; if (comparison !== 0) { return comparison; } if (left.name < right.name) { return -1; } if (left.name > right.name) { return 1; } return 0; }); util.nextTick(callback.bind(null, null, best[0].mac)); return; } args.push(lib.getAllInterfaces); var getMacAddress = function (d, cb) { if (addresses[d]) { cb(null, addresses[d]); return; } lib.getMacAddress(d, cb); }; util.iterate(args, getMacAddress, callback); }; lib.all = function (callback) { if (typeof callback !== "function") { return util.promisify(lib.all); } var ifaces = lib.networkInterfaces(); var resolve = {}; Object.keys(ifaces).forEach(function (iface) { if (!ifaces[iface].mac) { resolve[iface] = lib.getMacAddress.bind(null, iface); } }); if (Object.keys(resolve).length === 0) { if (typeof callback === "function") { util.nextTick(callback.bind(null, null, ifaces)); } return ifaces; } util.parallel(resolve, function (err, result) { Object.keys(result).forEach(function (iface) { ifaces[iface].mac = result[iface]; }); if (typeof callback === "function") { callback(null, ifaces); } }); return null; }; module.exports = lib; node-macaddress-0.5.4/lib/000077500000000000000000000000001512420502100153075ustar00rootroot00000000000000node-macaddress-0.5.4/lib/getallinterfaces.js000066400000000000000000000012471512420502100211650ustar00rootroot00000000000000var os = require('os'); var _getAllInterfaces; switch (os.platform()) { case 'win32': _getAllInterfaces = require('./platform/getallinterfaces_windows.js'); break; case 'linux': _getAllInterfaces = require('./platform/getallinterfaces_linux.js'); break; case 'darwin': case 'sunos': case 'freebsd': _getAllInterfaces = require('./platform/getallinterfaces_unix.js'); break; default: console.warn("node-macaddress: Unknown os.platform(), defaulting to 'unix'."); _getAllInterfaces = require('./platform/getallinterfaces_unix.js'); break; } module.exports = _getAllInterfaces; node-macaddress-0.5.4/lib/getmacaddress.js000066400000000000000000000025031512420502100204530ustar00rootroot00000000000000var os = require('os'); var _getMacAddress; var _validIfaceRegExp = '^[a-z0-9]+$'; switch (os.platform()) { case 'win32': // windows has long interface names which may contain spaces and dashes _validIfaceRegExp = '^[a-z0-9 -]+$'; _getMacAddress = require('./platform/getmacaddress_windows.js'); break; case 'linux': _getMacAddress = require('./platform/getmacaddress_linux.js'); break; case 'darwin': case 'sunos': case 'freebsd': _getMacAddress = require('./platform/getmacaddress_unix.js'); break; default: console.warn("node-macaddress: Unknown os.platform(), defaulting to 'unix'."); _getMacAddress = require('./platform/getmacaddress_unix.js'); break; } var validIfaceRegExp = new RegExp(_validIfaceRegExp, 'i'); module.exports = function (iface, callback) { // some platform specific ways of resolving the mac address pass the name // of the interface down to some command processor, so check for a well // formed string here. if (!validIfaceRegExp.test(iface)) { callback(new Error([ 'invalid iface: \'', iface, '\' (must conform to reg exp /', validIfaceRegExp, '/)' ].join('')), null); return; } _getMacAddress(iface, callback); } node-macaddress-0.5.4/lib/networkinterfaces.js000066400000000000000000000026311512420502100214040ustar00rootroot00000000000000var os = require('os'); // Retrieves all interfaces that do feature some non-internal address. // This function does NOT employ caching as to reflect the current state // of the machine accurately. module.exports = function () { var allAddresses = {}; try { var ifaces = os.networkInterfaces(); } catch (e) { // At October 2016 WSL does not support os.networkInterfaces() and throws // Return empty object as if no interfaces were found // https://github.com/Microsoft/BashOnWindows/issues/468 if (e.syscall === 'uv_interface_addresses') { return allAddresses; } else { throw e; } } Object.keys(ifaces).forEach(function (iface) { var addresses = {}; var hasAddresses = false; ifaces[iface].forEach(function (address) { if (!address.internal) { var family = (typeof address.family === 'number') ? ("ipv" + address.family) : (address.family || "").toLowerCase(); addresses[family] = address.address; hasAddresses = true; if (address.mac && address.mac !== '00:00:00:00:00:00') { addresses.mac = address.mac; } } }); if (hasAddresses) { allAddresses[iface] = addresses; } }); return allAddresses; }; node-macaddress-0.5.4/lib/platform/000077500000000000000000000000001512420502100171335ustar00rootroot00000000000000node-macaddress-0.5.4/lib/platform/getallinterfaces_linux.js000066400000000000000000000010611512420502100242220ustar00rootroot00000000000000/* jshint node: true */ var execFile = require('child_process').execFile; module.exports = function (callback) { execFile("/bin/ls", ["/sys/class/net"], function (err, out) { if (err) { callback(err, null); return; } var ifaces = out.split(/[ \t\n]+/); var result = []; for (var i = 0; i < ifaces.length; i += 1) { var iface = ifaces[i].trim(); if (iface !== "") { result.push(iface); } } callback(null, result); }); }; node-macaddress-0.5.4/lib/platform/getallinterfaces_unix.js000066400000000000000000000010711512420502100240470ustar00rootroot00000000000000/* jshint node: true */ 'use strict'; var execFile = require('child_process').execFile; module.exports = function (callback) { execFile("/sbin/ifconfig", ["-l"], function (err, out) { if (err) { callback(err, null); return; } var ifaces = out.split(/[ \t]+/); var result = []; for (var i = 0; i < ifaces.length; i += 1) { var iface = ifaces[i].trim(); if (iface !== "") { result.push(iface); } } callback(null, result); }); }; node-macaddress-0.5.4/lib/platform/getallinterfaces_windows.js000066400000000000000000000011571512420502100245630ustar00rootroot00000000000000/* jshint node: true */ 'use strict'; var execFile = require('child_process').execFile; module.exports = function (callback) { execFile("wmic", ["nic", "get", "NetConnectionID"], function (err, out) { if (err) { callback(err, null); return; } var ifaces = out.trim().replace(/\s{2,}/g, "\n").split("\n").slice(1); var result = []; for (var i = 0; i < ifaces.length; i += 1) { var iface = ifaces[i].trim(); if (iface !== "") { result.push(iface); } } callback(null, result); }); }; node-macaddress-0.5.4/lib/platform/getmacaddress_linux.js000066400000000000000000000005411512420502100235160ustar00rootroot00000000000000/* jshint node: true */ var execFile = require('child_process').execFile; module.exports = function (iface, callback) { execFile("/bin/cat", ["/sys/class/net/" + iface + "/address"], function (err, out) { if (err) { callback(err, null); return; } callback(null, out.trim().toLowerCase()); }); }; node-macaddress-0.5.4/lib/platform/getmacaddress_unix.js000066400000000000000000000007701512420502100233460ustar00rootroot00000000000000/* jshint node: true */ var execFile = require('child_process').execFile; module.exports = function (iface, callback) { execFile("ifconfig", [iface], function (err, out) { if (err) { callback(err, null); return; } var match = /[a-f0-9]{2}(:[a-f0-9]{2}){5}/.exec(out.toLowerCase()); if (!match) { callback("did not find a mac address", null); return; } callback(null, match[0].toLowerCase()); }); }; node-macaddress-0.5.4/lib/platform/getmacaddress_windows.js000066400000000000000000000015511512420502100240530ustar00rootroot00000000000000/* jshint node: true */ var execFile = require('child_process').execFile; var regexRegex = /[-\/\\^$*+?.()|[\]{}]/g; function escape(string) { return string.replace(regexRegex, '\\$&'); } module.exports = function (iface, callback) { execFile("ipconfig", ["/all"], function (err, out) { if (err) { callback(err, null); return; } var match = new RegExp(escape(iface)).exec(out); if (!match) { callback("did not find interface in `ipconfig /all`", null); return; } out = out.substring(match.index + iface.length); match = /[A-Fa-f0-9]{2}(\-[A-Fa-f0-9]{2}){5}/.exec(out); if (!match) { callback("did not find a mac address", null); return; } callback(null, match[0].toLowerCase().replace(/\-/g, ':')); }); }; node-macaddress-0.5.4/lib/util.js000066400000000000000000000040211512420502100166170ustar00rootroot00000000000000/* jshint node: true */ "use strict"; var lib = {}; var nextTick = process.nextTick || global.setImmediate || global.setTimeout; lib.nextTick = function (func) { nextTick(func); }; lib.parallel = function (tasks, done) { var results = []; var errs = []; var length = 0; var doneLength = 0; function doneIt(ix, err, result) { if (err) { errs[ix] = err; } else { results[ix] = result; } doneLength += 1; if (doneLength >= length) { done(errs.length > 0 ? errs : errs, results); } } Object.keys(tasks).forEach(function (key) { length += 1; var task = tasks[key]; lib.nextTick(function () { task(doneIt.bind(null, key), 1); }); }); }; lib.promisify = function (func) { return new Promise(function (resolve, reject) { func(function (err, data) { if (err) { if (!(err instanceof Error)) { err = new Error(err); } reject(err); return; } resolve(data); }); }); }; lib.iterate = function (args, func, callback) { var errors = []; var f = function () { if (args.length === 0) { lib.nextTick(callback.bind(null, errors)); return; } var arg = args.shift(); if (typeof arg === "function") { arg(function (err, res) { if (err) { errors.push(err); } else { while (res.length > 0) { args.unshift(res.pop()); } } f(); }); return; } func(arg, function (err, res) { if (err) { errors.push(err); f(); } else { lib.nextTick(callback.bind(null, null, res)); } }); }; lib.nextTick(f); }; module.exports = lib; node-macaddress-0.5.4/package-lock.json000066400000000000000000000003171512420502100177560ustar00rootroot00000000000000{ "name": "macaddress", "version": "0.5.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "macaddress", "version": "0.5.2", "license": "MIT" } } } node-macaddress-0.5.4/package.json000066400000000000000000000011751512420502100170330ustar00rootroot00000000000000{ "name": "macaddress", "version": "0.5.4", "description": "Get the MAC addresses (hardware addresses) of the hosts network interfaces.", "main": "index.js", "typings": "index.d.ts", "scripts": { "test": "node test.js" }, "repository": { "type": "git", "url": "git+https://github.com/scravy/node-macaddress.git" }, "keywords": [ "mac", "mac-address", "hardware-address", "network", "system" ], "author": "Julian Bertram", "license": "MIT", "bugs": { "url": "https://github.com/scravy/node-macaddress/issues" }, "homepage": "https://github.com/scravy/node-macaddress" } node-macaddress-0.5.4/test.js000066400000000000000000000014321512420502100160560ustar00rootroot00000000000000/* jshint node: true */ 'use strict'; var macaddress = require('./index.js'); macaddress.one(function (err, mac) { if (err || !/[a-f0-9]{2}(:[a-f0-9]{2}){5}/.test(mac)) { console.log(mac + " does not work"); throw err || mac; } console.log("Mac address for this host: %s", mac); }); macaddress.all(function (err, all) { if (err) { throw err; } console.log(JSON.stringify(all, null, 2)); }); console.log(JSON.stringify(macaddress.networkInterfaces(), null, 2)); if (typeof Promise !== 'undefined') { macaddress.one().then(function (result) { console.log("Mac address for this host using Promises: %s", result); }); macaddress.all().then(function (result) { console.log("all() using promises"); console.log(JSON.stringify(result, null, 2)); }); }