Skip to content

Commit

Permalink
add isValidCIDR method
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremy-code committed Feb 27, 2024
1 parent 03a2b52 commit 09c46fd
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 4 deletions.
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

0 comments on commit 09c46fd

Please sign in to comment.