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

Add isValidCIDR method #176

Merged
merged 1 commit into from
Feb 27, 2024
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
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,16 @@ The API consists of several global methods and two classes: ipaddr.IPv6 and ipad

### Global methods

There are three global methods defined: `ipaddr.isValid`, `ipaddr.parse` and
`ipaddr.process`. All of them receive a string as a single parameter.
There are four global methods defined: `ipaddr.isValid`, `ipaddr.isValidCIDR`,
`ipaddr.parse`, and `ipaddr.process`. All of them receive a string as a single
parameter.

The `ipaddr.isValid` method returns `true` if the address is a valid IPv4 or
IPv6 address, and `false` otherwise. It does not throw any exceptions.

The `ipaddr.isValidCIDR` method returns `true` if the address is a valid IPv4 or
IPv6 address in CIDR notation, and `false` otherwise. It does not throw any exceptions.

The `ipaddr.parse` method returns an object representing the IP address,
or throws an `Error` if the passed string is not a valid representation of an
IP address.
Expand Down
2 changes: 1 addition & 1 deletion ipaddr.min.js

Large diffs are not rendered by default.

31 changes: 31 additions & 0 deletions lib/ipaddr.js
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,16 @@
}
};

// Checks if a given string is a valid IPv4 address in CIDR notation.
ipaddr.IPv4.isValidCIDR = function (string) {
try {
this.parseCIDR(string);
return true;
} catch (e) {
return false;
}
};

// Checks if a given string is a full four-part IPv4 Address.
ipaddr.IPv4.isValidFourPartDecimal = function (string) {
if (ipaddr.IPv4.isValid(string) && string.match(/^(0|[1-9]\d*)(\.(0|[1-9]\d*)){3}$/)) {
Expand Down Expand Up @@ -809,6 +819,22 @@
}
};

// Checks if a given string is a valid IPv6 address in CIDR notation.
ipaddr.IPv6.isValidCIDR = function (string) {

// See note in IPv6.isValid
if (typeof string === 'string' && string.indexOf(':') === -1) {
return false;
}

try {
this.parseCIDR(string);
return true;
} catch (e) {
return false;
}
};

// A utility function to return network address given the IPv6 interface and prefix length in CIDR notation
ipaddr.IPv6.networkAddressFromCIDR = function (string) {
let cidr, i, ipInterfaceOctets, octets, subnetMaskOctets;
Expand Down Expand Up @@ -946,6 +972,11 @@
return ipaddr.IPv6.isValid(string) || ipaddr.IPv4.isValid(string);
};

// Checks if the address is valid IP address in CIDR notation
ipaddr.isValidCIDR = function (string) {
return ipaddr.IPv6.isValidCIDR(string) || ipaddr.IPv4.isValidCIDR(string);
};


// Attempts to parse an IP Address, first through IPv6 then IPv4.
// Throws an error if it could not be parsed.
Expand Down
5 changes: 4 additions & 1 deletion lib/ipaddr.js.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ declare module "ipaddr.js" {
namespace Address {
export function fromByteArray(bytes: number[]): IPv4 | IPv6;
export function isValid(addr: string): boolean;
export function isValidCIDR(addr: string): boolean;
export function parse(addr: string): IPv4 | IPv6;
export function parseCIDR(mask: string): [IPv4 | IPv6, number];
export function process(addr: string): IPv4 | IPv6;
Expand All @@ -26,8 +27,9 @@ declare module "ipaddr.js" {
export class IPv4 extends IP {
static broadcastAddressFromCIDR(addr: string): IPv4;
static isIPv4(addr: string): boolean;
static isValidFourPartDecimal(addr: string): boolean;
static isValid(addr: string): boolean;
static isValidCIDR(addr: string): boolean;
static isValidFourPartDecimal(addr: string): boolean;
static networkAddressFromCIDR(addr: string): IPv4;
static parse(addr: string): IPv4;
static parseCIDR(addr: string): [IPv4, number];
Expand All @@ -46,6 +48,7 @@ declare module "ipaddr.js" {
static broadcastAddressFromCIDR(addr: string): IPv6;
static isIPv6(addr: string): boolean;
static isValid(addr: string): boolean;
static isValidCIDR(addr: string): boolean;
static networkAddressFromCIDR(addr: string): IPv6;
static parse(addr: string): IPv6;
static parseCIDR(addr: string): [IPv6, number];
Expand Down
22 changes: 22 additions & 0 deletions test/ipaddr.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,14 @@ describe('ipaddr', () => {
done();
})

it('validates IPv4 addresses in CIDR notation', (done) => {
assert.equal(ipaddr.IPv4.isValidCIDR('192.168.1.1/24'), true);
assert.equal(ipaddr.IPv4.isValidCIDR('10.5.0.1'), false);
assert.equal(ipaddr.IPv4.isValidCIDR('0.0.0.0/-1'), false);
assert.equal(ipaddr.IPv4.isValidCIDR('192.168.1.1/999'), false);
done();
})

it('parses IPv4 in several weird formats', (done) => {
assert.deepEqual(ipaddr.IPv4.parse('192.168.1.1').octets, [192, 168, 1, 1]);
assert.deepEqual(ipaddr.IPv4.parse('0xc0.168.1.1').octets, [192, 168, 1, 1]);
Expand Down Expand Up @@ -348,6 +356,20 @@ describe('ipaddr', () => {
done();
})

it('validates IPv6 addresses in CIDR notation', (done) => {
assert.equal(ipaddr.IPv6.isValidCIDR('::/0'), true);
assert.equal(ipaddr.IPv6.isValidCIDR('2001:db8:F53A::1%z/64'), true);
assert.equal(ipaddr.IPv6.isValidCIDR('2001:db8:F53A::1/-1'), false);
assert.equal(ipaddr.IPv6.isValidCIDR('2001:db8:F53A::1'), false);
assert.equal(ipaddr.IPv6.isValidCIDR('2001:db8:F53A::1/129'), false);
assert.equal(ipaddr.IPv6.isValidCIDR('2001:db8:F53A::1%z/129'), false);
assert.equal(ipaddr.IPv6.isValidCIDR('2001:db8:F53A::1/64%z'), false);
assert.equal(ipaddr.IPv6.isValidCIDR('2001:db8:F53A::1/64%'), false);
assert.equal(ipaddr.IPv6.isValidCIDR('2001:db8:F53A::1/64%z/64'), false);
assert.equal(ipaddr.IPv6.isValidCIDR(undefined), false);
done();
})

it('parses IPv6 in different formats', (done) => {
assert.deepEqual(ipaddr.IPv6.parse('2001:db8:F53A:0:0:0:0:1').parts, [0x2001, 0xdb8, 0xf53a, 0, 0, 0, 0, 1]);
assert.deepEqual(ipaddr.IPv6.parse('fe80::10').parts, [0xfe80, 0, 0, 0, 0, 0, 0, 0x10]);
Expand Down
Loading