Skip to content

Commit

Permalink
Accept mixed IPv4/IPv6 range lists in ipaddr.subnetMatch.
Browse files Browse the repository at this point in the history
x
  • Loading branch information
Bittrance authored and whitequark committed Jun 26, 2017
1 parent e0f2a07 commit 9e22317
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 7 deletions.
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,7 @@ in the source: [IPv6 ranges] and [IPv4 ranges]. Some common ones include `"unica
(the default one) and `"reserved"`.

You can match against your own range list by using
`ipaddr.subnetMatch(address, rangeList, defaultName)` method. It can work with both
IPv6 and IPv4 addresses, and accepts a name-to-subnet map as the range list. For example:
`ipaddr.subnetMatch(address, rangeList, defaultName)` method. It can work with a mix of IPv6 or IPv4 addresses, and accepts a name-to-subnet map as the range list. For example:

```js
var rangeList = {
Expand All @@ -108,7 +107,7 @@ var rangeList = {
[ ipaddr.parse('2001:5c0::'), 32 ] // freenet6
]
};
ipaddr.subnetMatch(ipaddr.parse('2001:470:8:66::1'), rangeList, 'unknown'); // => "he.net"
ipaddr.subnetMatch(ipaddr.parse('2001:470:8:66::1'), rangeList, 'unknown'); // => "tunnelProviders"
```

The addresses can be converted to their byte representation with `toByteArray()`.
Expand Down
2 changes: 1 addition & 1 deletion ipaddr.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions lib/ipaddr.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,10 @@
}
for (k = 0, len = rangeSubnets.length; k < len; k++) {
subnet = rangeSubnets[k];
if (address.match.apply(address, subnet)) {
return rangeName;
if (address.kind === subnet[0].kind) {
if (address.match.apply(address, subnet)) {
return rangeName;
}
}
}
}
Expand Down
6 changes: 5 additions & 1 deletion src/ipaddr.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,18 @@ matchCIDR = (first, second, partSize, cidrBits) ->
return true

# An utility function to ease named range matching. See examples below.
# rangeList can contain both IPv4 and IPv6 subnet entries and will not throw errors
# on matching IPv4 addresses to IPv6 ranges or vice versa.
ipaddr.subnetMatch = (address, rangeList, defaultName='unicast') ->
for rangeName, rangeSubnets of rangeList
# ECMA5 Array.isArray isn't available everywhere
if rangeSubnets[0] && !(rangeSubnets[0] instanceof Array)
rangeSubnets = [ rangeSubnets ]

for subnet in rangeSubnets
return rangeName if address.match.apply(address, subnet)
if address.kind == subnet[0].kind
if address.match.apply(address, subnet)
return rangeName

return defaultName

Expand Down
16 changes: 16 additions & 0 deletions test/ipaddr.test.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,22 @@ module.exports =
test.equal(ipaddr.subnetMatch(new ipaddr.IPv4([1,2,3,4]), {subnet: []}, false), false)
test.done()

'subnetMatch does not fail on IPv4 when looking for IPv6': (test) ->
rangelist = {subnet6: ipaddr.parseCIDR('fe80::/64')}
test.equal(ipaddr.subnetMatch(new ipaddr.IPv4([1,2,3,4]), rangelist, false), false)
test.done()

'subnetMatch does not fail on IPv6 when looking for IPv4': (test) ->
rangelist = {subnet4: ipaddr.parseCIDR('1.2.3.0/24')}
test.equal(ipaddr.subnetMatch(new ipaddr.IPv6([0xfe80, 0, 0, 0, 0, 0, 0, 1]), rangelist, false), false)
test.done()

'subnetMatch can use a hybrid IPv4/IPv6 range list': (test) ->
rangelist = {dual64: [ipaddr.parseCIDR('1.2.4.0/24'), ipaddr.parseCIDR('2001:1:2:3::/64')]}
test.equal(ipaddr.subnetMatch(new ipaddr.IPv4([1,2,4,1]), rangelist, false), 'dual64')
test.equal(ipaddr.subnetMatch(new ipaddr.IPv6([0x2001, 1, 2, 3, 0, 0, 0, 1]), rangelist, false), 'dual64')
test.done()

'is able to determine IP address type from byte array input': (test) ->
test.equal(ipaddr.fromByteArray([0x7f, 0, 0, 1]).kind(), 'ipv4')
test.equal(ipaddr.fromByteArray([0x20, 0x01, 0xd, 0xb8, 0xf5, 0x3a, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]).kind(), 'ipv6')
Expand Down

0 comments on commit 9e22317

Please sign in to comment.