Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added ipv6 scoped architecture text format #1160

Merged
merged 3 commits into from
Nov 11, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 49 additions & 1 deletion src/lib/isIP.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,33 @@
import assertString from './util/assertString';
/**
11.3. Examples

The following addresses

fe80::1234 (on the 1st link of the node)
ff02::5678 (on the 5th link of the node)
ff08::9abc (on the 10th organization of the node)

would be represented as follows:

fe80::1234%1
ff02::5678%5
ff08::9abc%10

(Here we assume a natural translation from a zone index to the
<zone_id> part, where the Nth zone of any scope is translated into
"N".)

If we use interface names as <zone_id>, those addresses could also be
represented as follows:

fe80::1234%ne0
ff02::5678%pvc1.3
ff08::9abc%interface10

where the interface "ne0" belongs to the 1st link, "pvc1.3" belongs
to the 5th link, and "interface10" belongs to the 10th organization.
* * */
const ipv4Maybe = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
const ipv6Block = /^[0-9A-F]{1,4}$/i;

Expand All @@ -15,7 +43,27 @@ export default function isIP(str, version = '') {
const parts = str.split('.').sort((a, b) => a - b);
return parts[3] <= 255;
} else if (version === '6') {
const blocks = str.split(':');
let addressAndZone = [str];
// ipv6 addresses could have scoped architecture
// according to https://tools.ietf.org/html/rfc4007#section-11
if (str.includes('%')) {
addressAndZone = str.split('%');
if (addressAndZone.length !== 2) {
// it must be just two parts
return false;
}
if (!addressAndZone[0].includes(':')) {
// the first part must be the address
return false;
}

if (addressAndZone[1] === '') {
// the second part must not be empty
return false;
}
}

const blocks = addressAndZone[0].split(':');
let foundOmissionBlock = false; // marker to indicate ::

// At least some OS accept the last 32 bits of an IPv6 address
Expand Down
8 changes: 8 additions & 0 deletions test/validators.js
Original file line number Diff line number Diff line change
Expand Up @@ -748,13 +748,21 @@ describe('Validators', () => {
'::1',
'2001:db8:0000:1:1:1:1:1',
'::ffff:127.0.0.1',
'fe80::1234%1',
'ff08::9abc%10',
'ff08::9abc%interface10',
'ff02::5678%pvc1.3',
],
invalid: [
'127.0.0.1',
'0.0.0.0',
'255.255.255.255',
'1.2.3.4',
'::ffff:287.0.0.1',
'%',
'fe80::1234%',
'fe80::1234%1%3%4',
'fe80%fe80%',
],
});
test({
Expand Down