1
1
const ip = exports ;
2
2
const { Buffer } = require ( 'buffer' ) ;
3
3
const os = require ( 'os' ) ;
4
+ const net = require ( 'net' ) ;
4
5
5
6
ip . toBuffer = function ( ip , buff , offset ) {
6
7
offset = ~ ~ offset ;
@@ -82,15 +83,28 @@ ip.toString = function (buff, offset, length) {
82
83
return result ;
83
84
} ;
84
85
85
- const ipv4Regex = / ^ ( \d { 1 , 3 } \. ) { 3 , 3 } \d { 1 , 3 } $ / ;
86
- const ipv6Regex = / ^ ( : : ) ? ( ( ( \d { 1 , 3 } \. ) { 3 } ( \d { 1 , 3 } ) { 1 } ) ? ( [ 0 - 9 a - f ] ) { 0 , 4 } : { 0 , 2 } ) { 1 , 8 } ( : : ) ? $ / i;
86
+ ip . isV4Format = net . isIPv4 ;
87
87
88
- ip . isV4Format = function ( ip ) {
89
- return ipv4Regex . test ( ip ) ;
88
+ ip . isV6Format = net . isIPv6 ;
89
+
90
+ ip . isValid = function ( addr ) {
91
+ return net . isIP ( addr ) !== 0 ;
90
92
} ;
91
93
92
- ip . isV6Format = function ( ip ) {
93
- return ipv6Regex . test ( ip ) ;
94
+ ip . normalizeStrict = function ( addr ) {
95
+ let family ;
96
+ switch ( net . isIP ( addr ) ) {
97
+ case 4 :
98
+ family = 'ipv4' ;
99
+ break ;
100
+ case 6 :
101
+ family = 'ipv6' ;
102
+ break ;
103
+ default :
104
+ throw new Error ( `Invalid ip address: ${ addr } ` ) ;
105
+ }
106
+ const { address } = new net . SocketAddress ( { address : addr , family } ) ;
107
+ return address ;
94
108
} ;
95
109
96
110
function _normalizeFamily ( family ) {
@@ -306,26 +320,13 @@ ip.isEqual = function (a, b) {
306
320
} ;
307
321
308
322
ip . isPrivate = function ( addr ) {
309
- // check loopback addresses first
310
- if ( ip . isLoopback ( addr ) ) {
311
- return true ;
312
- }
313
-
314
- // ensure the ipv4 address is valid
315
- if ( ! ip . isV6Format ( addr ) ) {
316
- const ipl = ip . normalizeToLong ( addr ) ;
317
- if ( ipl < 0 ) {
318
- throw new Error ( 'invalid ipv4 address' ) ;
319
- }
320
- // normalize the address for the private range checks that follow
321
- addr = ip . fromLong ( ipl ) ;
322
- }
323
+ addr = ip . normalizeStrict ( addr ) ;
323
324
324
325
// check private ranges
325
- return / ^ ( : : f { 4 } : ) ? 1 0 \. ( [ 0 - 9 ] { 1 , 3 } ) \. ( [ 0 - 9 ] { 1 , 3 } ) \. ( [ 0 - 9 ] { 1 , 3 } ) $ / i. test ( addr )
326
+ return / ^ ( : : f { 4 } : ) ? 1 2 7 \. ( [ 0 - 9 ] { 1 , 3 } ) \. ( [ 0 - 9 ] { 1 , 3 } ) \. ( [ 0 - 9 ] { 1 , 3 } ) $ / i. test ( addr )
327
+ || / ^ ( : : f { 4 } : ) ? 1 0 \. ( [ 0 - 9 ] { 1 , 3 } ) \. ( [ 0 - 9 ] { 1 , 3 } ) \. ( [ 0 - 9 ] { 1 , 3 } ) $ / i. test ( addr )
326
328
|| / ^ ( : : f { 4 } : ) ? 1 9 2 \. 1 6 8 \. ( [ 0 - 9 ] { 1 , 3 } ) \. ( [ 0 - 9 ] { 1 , 3 } ) $ / i. test ( addr )
327
- || / ^ ( : : f { 4 } : ) ? 1 7 2 \. ( 1 [ 6 - 9 ] | 2 \d | 3 0 | 3 1 ) \. ( [ 0 - 9 ] { 1 , 3 } ) \. ( [ 0 - 9 ] { 1 , 3 } ) $ / i
328
- . test ( addr )
329
+ || / ^ ( : : f { 4 } : ) ? 1 7 2 \. ( 1 [ 6 - 9 ] | 2 \d | 3 0 | 3 1 ) \. ( [ 0 - 9 ] { 1 , 3 } ) \. ( [ 0 - 9 ] { 1 , 3 } ) $ / i. test ( addr )
329
330
|| / ^ ( : : f { 4 } : ) ? 1 6 9 \. 2 5 4 \. ( [ 0 - 9 ] { 1 , 3 } ) \. ( [ 0 - 9 ] { 1 , 3 } ) $ / i. test ( addr )
330
331
|| / ^ f [ c d ] [ 0 - 9 a - f ] { 2 } : / i. test ( addr )
331
332
|| / ^ f e 8 0 : / i. test ( addr )
@@ -337,16 +338,26 @@ ip.isPublic = function (addr) {
337
338
return ! ip . isPrivate ( addr ) ;
338
339
} ;
339
340
340
- ip . isLoopback = function ( addr ) {
341
- // If addr is an IPv4 address in long integer form (no dots and no colons), convert it
342
- if ( ! / \. / . test ( addr ) && ! / : / . test ( addr ) ) {
343
- addr = ip . fromLong ( Number ( addr ) ) ;
341
+ ip . isValidAndPrivate = function ( addr ) {
342
+ try {
343
+ return ip . isPrivate ( addr ) ;
344
+ } catch {
345
+ return false ;
346
+ }
347
+ } ;
348
+
349
+ ip . isValidAndPublic = function ( addr ) {
350
+ try {
351
+ return ip . isPublic ( addr ) ;
352
+ } catch {
353
+ return false ;
344
354
}
355
+ } ;
356
+
357
+ ip . isLoopback = function ( addr ) {
358
+ addr = ip . normalizeStrict ( addr ) ;
345
359
346
- return / ^ ( : : f { 4 } : ) ? 1 2 7 \. ( [ 0 - 9 ] { 1 , 3 } ) \. ( [ 0 - 9 ] { 1 , 3 } ) \. ( [ 0 - 9 ] { 1 , 3 } ) /
347
- . test ( addr )
348
- || / ^ 0 1 7 7 \. / . test ( addr )
349
- || / ^ 0 x 7 f \. / i. test ( addr )
360
+ return / ^ ( : : f { 4 } : ) ? 1 2 7 \. ( [ 0 - 9 ] { 1 , 3 } ) \. ( [ 0 - 9 ] { 1 , 3 } ) \. ( [ 0 - 9 ] { 1 , 3 } ) / . test ( addr )
350
361
|| / ^ f e 8 0 : : 1 $ / i. test ( addr )
351
362
|| / ^ : : 1 $ / . test ( addr )
352
363
|| / ^ : : $ / . test ( addr ) ;
@@ -443,6 +454,8 @@ ip.fromLong = function (ipl) {
443
454
} ;
444
455
445
456
ip . normalizeToLong = function ( addr ) {
457
+ if ( typeof addr !== 'string' ) return - 1 ;
458
+
446
459
const parts = addr . split ( '.' ) . map ( part => {
447
460
// Handle hexadecimal format
448
461
if ( part . startsWith ( '0x' ) || part . startsWith ( '0X' ) ) {
@@ -469,6 +482,7 @@ ip.normalizeToLong = function (addr) {
469
482
470
483
switch ( n ) {
471
484
case 1 :
485
+ if ( parts [ 0 ] > 0xffffffff ) return - 1 ;
472
486
val = parts [ 0 ] ;
473
487
break ;
474
488
case 2 :
@@ -489,3 +503,15 @@ ip.normalizeToLong = function (addr) {
489
503
490
504
return val >>> 0 ;
491
505
} ;
506
+
507
+ ip . normalizeLax = function ( addr ) {
508
+ if ( ip . isV6Format ( addr ) ) {
509
+ const { address } = new net . SocketAddress ( { address : addr , family : 'ipv6' } ) ;
510
+ return address ;
511
+ }
512
+ const ipl = ip . normalizeToLong ( addr ) ;
513
+ if ( ipl < 0 ) {
514
+ throw Error ( `Invalid ip address: ${ addr } ` ) ;
515
+ }
516
+ return ip . fromLong ( ipl ) ;
517
+ } ;
0 commit comments