diff --git a/README.md b/README.md index 4bc9d0c..0b916d4 100644 --- a/README.md +++ b/README.md @@ -36,11 +36,9 @@ Netmask objects are created with an IP address and optionally a mask. There are '216.240.32.0', '255.255.255.0' '216.240.32.0', 0xffffff00 '216.240.32.4' // A /32 block. - '216.240.32' // A /24 block. - '216.240' // A /16 block. - '140' // A /8 block. - '216.240.32/24' - '216.240/16' + '0330.0360.040.04' // Octal form + '0xd8.0xf0.0x20.0x4' // Hex form + API --- @@ -67,7 +65,7 @@ License (The MIT License) -Copyright (c) 2011 Olivier Poitrey +Copyright (c) 2011 Olivier Poitrey Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/lib/netmask.coffee b/lib/netmask.coffee index 35db1b9..f2ecbf7 100644 --- a/lib/netmask.coffee +++ b/lib/netmask.coffee @@ -21,7 +21,9 @@ ip2long = (ip) -> if isNaN(byte) then throw new Error("Invalid byte: #{byte}") if byte < 0 or byte > 255 then throw new Error("Invalid byte: #{byte}") b[i] = byte - return ((b[0] or 0) << 24 | (b[1] or 0) << 16 | (b[2] or 0) << 8 | (b[3] or 0)) >>> 0 + while b.length < 4 + b.unshift(0) + return (b[0] << 24 | b[1] << 16 | b[2] << 8 | b[3]) >>> 0 class Netmask @@ -31,13 +33,7 @@ class Netmask # try to find the mask in the net (i.e.: 1.2.3.4/24 or 1.2.3.4/255.255.255.0) [net, mask] = net.split('/', 2) unless mask - switch net.split('.').length - when 1 then mask = 8 - when 2 then mask = 16 - when 3 then mask = 24 - when 4 then mask = 32 - else throw new Error("Invalid net address: #{net}") - + mask = 32 if typeof mask is 'string' and mask.indexOf('.') > -1 # Compute bitmask, the netmask as a number of bits in the network portion of the address for this block (eg.: 24) try @@ -48,7 +44,7 @@ class Netmask if @maskLong == (0xffffffff << (32 - i)) >>> 0 @bitmask = i break - else if mask + else if mask or mask == 0 # The mask was passed as bitmask, compute the mask as long from it @bitmask = parseInt(mask, 10) @maskLong = 0 diff --git a/test/netmasks.coffee b/test/netmasks.coffee index ab81dd2..b964e36 100644 --- a/test/netmasks.coffee +++ b/test/netmasks.coffee @@ -10,13 +10,13 @@ fixtures = ['209.157.68.22', '255.255.224.0', '209.157.64.0', '255.255.224.0', 19] ['209.157.70.33/19', null, '209.157.64.0', '255.255.224.0', 19] ['209.157.70.33', null, '209.157.70.33', '255.255.255.255', 32] - ['140.174.82', null, '140.174.82.0', '255.255.255.0', 24] - ['140.174', null, '140.174.0.0', '255.255.0.0', 16] - ['10', null, '10.0.0.0', '255.0.0.0', 8] - ['10/8', null, '10.0.0.0', '255.0.0.0', 8] - ['209.157.64/19', null, '209.157.64.0', '255.255.224.0', 19] + ['140.174.82', null, '0.140.174.82', '255.255.255.255', 32] + ['140.174', null, '0.0.140.174', '255.255.255.255', 32] + ['10', null, '0.0.0.10', '255.255.255.255', 32] + ['10/8', null, '0.0.0.0', '255.0.0.0', 8] + ['209.157.64/19', null, '0.209.128.0', '255.255.224.0', 19] ['216.140.48.16/32', null, '216.140.48.16', '255.255.255.255', 32] - ['209.157/17', null, '209.157.0.0', '255.255.128.0', 17] + ['209.157/17', null, '0.0.128.0', '255.255.128.0', 17] ['0.0.0.0/0', null, '0.0.0.0', '0.0.0.0', 0] ] @@ -45,14 +45,15 @@ vows.describe('Netmask contains IP') 'does not contain IP 10.168.2.0': (block) -> assert.ok not block.contains('10.168.2.0') 'does not contain IP 209.168.2.0': (block) -> assert.ok not block.contains('209.168.2.0') 'contains block 192.168.1.0/24': (block) -> assert.ok block.contains('192.168.1.0/24') - 'contains block 192.168.1': (block) -> assert.ok block.contains('192.168.1') - 'contains block 192.168.1.128/25': (block) -> assert.ok block.contains('192.168.1.128/25') + 'contains block 192.168.1 (0.192.168.10)': (block) -> assert.ok not block.contains('192.168.1') + 'does not contains block 192.168.1.128/25': (block) -> assert.ok block.contains('192.168.1.128/25') 'does not contain block 192.168.1.0/23': (block) -> assert.ok not block.contains('192.168.1.0/23') 'does not contain block 192.168.2.0/24': (block) -> assert.ok not block.contains('192.168.2.0/24') 'toString equals 192.168.1.0/24': (block) -> assert.equal block.toString(), '192.168.1.0/24' 'block 192.168.0.0/24': topic: -> new Netmask('192.168.0.0/24') - 'does not contain block 192.168': (block) -> assert.ok not block.contains('192.168') + 'does not contain block 192.168 (0.0.192.168)': (block) -> assert.ok not block.contains('192.168') + 'does not contain block 192.168.0.0/16': (block) -> assert.ok not block.contains('192.168.0.0/16') 'block 31.0.0.0/8': topic: -> new Netmask('31.0.0.0/8') 'contains IP 31.5.5.5': (block) -> assert.ok block.contains('31.5.5.5') @@ -64,6 +65,16 @@ vows.describe('Netmask contains IP') 'contains IP 127.0.0.2': (block) -> assert.ok block.contains('127.0.0.2') 'contains IP 0177.0.0.2 (127.0.0.2)': (block) -> assert.ok block.contains('0177.0.0.2') 'contains IP 0x7f.0.0.2 (127.0.0.2)': (block) -> assert.ok block.contains('0x7f.0.0.2') + 'does not contains IP 127 (0.0.0.127)': (block) -> assert.ok not block.contains('127') + 'does not contains IP 0177 (0.0.0.127)': (block) -> assert.ok not block.contains('0177') + 'block 0.0.0.0/24': + topic: -> new Netmask('0.0.0.0/0') + 'contains IP 0.0.0.0': (block) -> assert.ok block.contains('0.0.0.0') + 'contains IP 0': (block) -> assert.ok block.contains('0') + 'contains IP 10 (0.0.0.10)': (block) -> assert.ok block.contains('10') + 'contains IP 010 (0.0.0.8)': (block) -> assert.ok block.contains('010') + 'contains IP 0x10 (0.0.0.16)': (block) -> assert.ok block.contains('0x10') + .export(module) vows.describe('Netmask forEach')