Skip to content

Commit 6c98053

Browse files
authored
fix: should return scopeid = 0 address on IPv6 (#41)
1 parent 96f778a commit 6c98053

4 files changed

Lines changed: 63 additions & 10 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@ npm-debug.log
1919
test/fixtures/ts/*.js
2020
.tshy*
2121
dist/
22+
package-lock.json

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,5 +75,6 @@
7575
}
7676
}
7777
},
78-
"types": "./dist/commonjs/index.d.ts"
78+
"types": "./dist/commonjs/index.d.ts",
79+
"main": "./dist/commonjs/index.js"
7980
}

src/address.ts

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,28 @@ function matchName(actualFamily: string | number, expectedFamily: string | numbe
5858
return actualFamily === expectedFamily;
5959
}
6060

61+
function findAddressFromInterface(items: os.NetworkInterfaceInfo[], expectedFamily: string | number,
62+
ignoreLoAddress = false) {
63+
let firstMatchItem;
64+
for (const item of items) {
65+
if (matchName(item.family, expectedFamily)) {
66+
if (ignoreLoAddress && item.address.startsWith('127.')) {
67+
continue;
68+
}
69+
if (expectedFamily === 'IPv6') {
70+
// find the scopeid = 0 item
71+
if (item.scopeid === 0) return item;
72+
if (!firstMatchItem) {
73+
firstMatchItem = item;
74+
}
75+
} else {
76+
return item;
77+
}
78+
}
79+
}
80+
return firstMatchItem;
81+
}
82+
6183
export function getInterfaceAddress(family?: string, name?: string) {
6284
const interfaces = os.networkInterfaces();
6385
const noName = !name;
@@ -68,10 +90,9 @@ export function getInterfaceAddress(family?: string, name?: string) {
6890
const interfaceName = name + (i >= 0 ? i : ''); // support 'lo' and 'lo0'
6991
const items = interfaces[interfaceName];
7092
if (items) {
71-
for (const item of items) {
72-
if (matchName(item.family, family)) {
73-
return item;
74-
}
93+
const item = findAddressFromInterface(items, family);
94+
if (item) {
95+
return item;
7596
}
7697
}
7798
}
@@ -82,11 +103,10 @@ export function getInterfaceAddress(family?: string, name?: string) {
82103
for (const k in interfaces) {
83104
const items = interfaces[k];
84105
if (items) {
85-
for (const item of items) {
86-
// all 127 addresses are local and should be ignored
87-
if (matchName(item.family, family) && !item.address.startsWith('127.')) {
88-
return item;
89-
}
106+
// all 127 addresses are local and should be ignored
107+
const item = findAddressFromInterface(items, family, true);
108+
if (item) {
109+
return item;
90110
}
91111
}
92112
}

test/address.test.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,37 @@ describe('test/address.test.ts', () => {
232232
assert.equal(addressAll.ip('utun'), '10.206.52.79');
233233
assert.equal(addressAll.ipv6('utun'), 'fe80::696:ad3d:eeec:1722');
234234
});
235+
236+
it('should return scopeid = 0 address', () => {
237+
mm(os, 'networkInterfaces', () => {
238+
return {
239+
lo:
240+
[{ address: '127.0.0.1',
241+
family: 'IPv4',
242+
internal: true }],
243+
utun0:
244+
[
245+
{
246+
address: 'fe80::696:ad3d:eeec:1722',
247+
family: 'IPv6',
248+
internal: false,
249+
scopeid: 20,
250+
},
251+
{
252+
address: 'fe80::696:ad3d:eeee:ffff:1:1000:3380:b81a:2dd4:373e:1234',
253+
family: 'IPv6',
254+
internal: false,
255+
scopeid: 0,
256+
},
257+
],
258+
utun1:
259+
[{ address: '10.206.52.79',
260+
family: 'IPv4',
261+
internal: false }] };
262+
});
263+
assert.equal(addressAll.ip('utun'), '10.206.52.79');
264+
assert.equal(addressAll.ipv6('utun'), 'fe80::696:ad3d:eeee:ffff:1:1000:3380:b81a:2dd4:373e:1234');
265+
});
235266
});
236267

237268
describe('address.dns()', () => {

0 commit comments

Comments
 (0)