@@ -82,6 +82,32 @@ class IPAddr
82
82
\z
83
83
}xi
84
84
85
+ # Raised when the provided IP address is an invalid address.
86
+ class InvalidAddress < ArgumentError ; end
87
+
88
+ # Raised when the provided IP address is of an unsupported address family.
89
+ class UnsupportedAddressFamily < ArgumentError ; end
90
+
91
+ # Raised when an octet contains a zero-filled number.
92
+ # Example: 192.162.022.001
93
+ class ZeroFilledNumber < ArgumentError ; end
94
+
95
+ # Raised when an address is a mix of address families.
96
+ class InconsistentAddressFamily < ArgumentError ; end
97
+
98
+ # Raised when an address family is unspecified and cannot be reliability
99
+ # determined (for example: if an Integer is provided instead of a string).
100
+ class UnspecifiedAddressFamily < ArgumentError ; end
101
+
102
+ # Raised when the address is an invalid IPv4 address.
103
+ class InvalidIPv4 < ArgumentError ; end
104
+
105
+ # Raised when the address is an invalid IPv6 address.
106
+ class InvalidIPv6 < ArgumentError ; end
107
+
108
+ # Raised when the address is an invalid length.
109
+ class InvalidLength < ArgumentError ; end
110
+
85
111
# Returns the address family of this IP address.
86
112
attr_reader :family
87
113
@@ -100,7 +126,7 @@ def IPAddr::ntop(addr)
100
126
when 16
101
127
s = IN6FORMAT % addr . unpack ( 'n8' )
102
128
else
103
- raise ArgumentError , "unsupported address family"
129
+ raise UnsupportedAddressFamily , "unsupported address family"
104
130
end
105
131
return s
106
132
end
@@ -226,7 +252,7 @@ def hton
226
252
( @addr >> ( 112 - 16 * i ) ) & 0xffff
227
253
} . pack ( 'n8' )
228
254
else
229
- raise "unsupported address family"
255
+ raise UnsupportedAddressFamily , "unsupported address family"
230
256
end
231
257
end
232
258
@@ -258,7 +284,7 @@ def ipv4_compat?
258
284
# into an IPv4-mapped IPv6 address.
259
285
def ipv4_mapped
260
286
if !ipv4?
261
- raise ArgumentError , "not an IPv4 address"
287
+ raise InvalidIPv4 , "not an IPv4 address"
262
288
end
263
289
return self . clone . set ( @addr | 0xffff00000000 , Socket ::AF_INET6 )
264
290
end
@@ -267,7 +293,7 @@ def ipv4_mapped
267
293
# into an IPv4-compatible IPv6 address.
268
294
def ipv4_compat
269
295
if !ipv4?
270
- raise ArgumentError , "not an IPv4 address"
296
+ raise InvalidIPv4 , "not an IPv4 address"
271
297
end
272
298
return self . clone . set ( @addr , Socket ::AF_INET6 )
273
299
end
@@ -291,22 +317,22 @@ def reverse
291
317
when Socket ::AF_INET6
292
318
return ip6_arpa
293
319
else
294
- raise "unsupported address family"
320
+ raise UnsupportedAddressFamily , "unsupported address family"
295
321
end
296
322
end
297
323
298
324
# Returns a string for DNS reverse lookup compatible with RFC3172.
299
325
def ip6_arpa
300
326
if !ipv6?
301
- raise ArgumentError , "not an IPv6 address"
327
+ raise InvalidIPv6 , "not an IPv6 address"
302
328
end
303
329
return _reverse + ".ip6.arpa"
304
330
end
305
331
306
332
# Returns a string for DNS reverse lookup compatible with RFC1886.
307
333
def ip6_int
308
334
if !ipv6?
309
- raise ArgumentError , "not an IPv6 address"
335
+ raise InvalidIPv6 , "not an IPv6 address"
310
336
end
311
337
return _reverse + ".ip6.int"
312
338
end
@@ -346,7 +372,7 @@ def to_range
346
372
when Socket ::AF_INET6
347
373
end_addr = ( @addr | ( IN6MASK ^ @mask_addr ) )
348
374
else
349
- raise "unsupported address family"
375
+ raise UnsupportedAddressFamily , "unsupported address family"
350
376
end
351
377
352
378
return clone . set ( begin_addr , @family ) ..clone . set ( end_addr , @family )
@@ -361,29 +387,31 @@ def inspect
361
387
when Socket ::AF_INET6
362
388
af = "IPv6"
363
389
else
364
- raise "unsupported address family"
390
+ raise UnsupportedAddressFamily , "unsupported address family"
365
391
end
366
392
return sprintf ( "#<%s: %s:%s/%s>" , self . class . name ,
367
393
af , _to_string ( @addr ) , _to_string ( @mask_addr ) )
368
394
end
369
395
370
396
protected
371
397
398
+
399
+
372
400
# Set +@addr+, the internal stored ip address, to given +addr+. The
373
401
# parameter +addr+ is validated using the first +family+ member,
374
402
# which is +Socket::AF_INET+ or +Socket::AF_INET6+.
375
403
def set ( addr , *family )
376
404
case family [ 0 ] ? family [ 0 ] : @family
377
405
when Socket ::AF_INET
378
406
if addr < 0 || addr > IN4MASK
379
- raise ArgumentError , "invalid address"
407
+ raise InvalidAddress , "invalid address"
380
408
end
381
409
when Socket ::AF_INET6
382
410
if addr < 0 || addr > IN6MASK
383
- raise ArgumentError , "invalid address"
411
+ raise InvalidAddress , "invalid address"
384
412
end
385
413
else
386
- raise ArgumentError , "unsupported address family"
414
+ raise UnsupportedAddressFamily , "unsupported address family"
387
415
end
388
416
@addr = addr
389
417
if family [ 0 ]
@@ -400,7 +428,7 @@ def mask!(mask)
400
428
else
401
429
m = IPAddr . new ( mask )
402
430
if m . family != @family
403
- raise ArgumentError , "address family is not same"
431
+ raise InconsistentAddressFamily , "address family is not same"
404
432
end
405
433
@mask_addr = m . to_i
406
434
@addr &= @mask_addr
@@ -412,18 +440,18 @@ def mask!(mask)
412
440
case @family
413
441
when Socket ::AF_INET
414
442
if prefixlen < 0 || prefixlen > 32
415
- raise ArgumentError , "invalid length"
443
+ raise InvalidLength , "invalid length"
416
444
end
417
445
masklen = 32 - prefixlen
418
446
@mask_addr = ( ( IN4MASK >> masklen ) << masklen )
419
447
when Socket ::AF_INET6
420
448
if prefixlen < 0 || prefixlen > 128
421
- raise ArgumentError , "invalid length"
449
+ raise InvalidLength , "invalid length"
422
450
end
423
451
masklen = 128 - prefixlen
424
452
@mask_addr = ( ( IN6MASK >> masklen ) << masklen )
425
453
else
426
- raise "unsupported address family"
454
+ raise UnsupportedAddressFamily , "unsupported address family"
427
455
end
428
456
@addr = ( ( @addr >> masklen ) << masklen )
429
457
return self
@@ -457,9 +485,9 @@ def initialize(addr = '::', family = Socket::AF_UNSPEC)
457
485
@mask_addr = ( family == Socket ::AF_INET ) ? IN4MASK : IN6MASK
458
486
return
459
487
when Socket ::AF_UNSPEC
460
- raise ArgumentError , "address family must be specified"
488
+ raise UnspecifiedAddressFamily , "address family must be specified"
461
489
else
462
- raise ArgumentError , "unsupported address family: #{ family } "
490
+ raise UnsupportedAddressFamily , "unsupported address family: #{ family } "
463
491
end
464
492
end
465
493
prefix , prefixlen = addr . split ( '/' )
@@ -482,7 +510,7 @@ def initialize(addr = '::', family = Socket::AF_UNSPEC)
482
510
@family = Socket ::AF_INET6
483
511
end
484
512
if family != Socket ::AF_UNSPEC && @family != family
485
- raise ArgumentError , "address family mismatch"
513
+ raise InconsistentAddressFamily , "address family mismatch"
486
514
end
487
515
if prefixlen
488
516
mask! ( prefixlen )
@@ -511,8 +539,8 @@ def in_addr(addr)
511
539
octets = m . captures
512
540
end
513
541
octets . inject ( 0 ) { |i , s |
514
- ( n = s . to_i ) < 256 or raise ArgumentError , "invalid address"
515
- s . match ( /\A 0./ ) and raise ArgumentError , "zero-filled number is ambiguous"
542
+ ( n = s . to_i ) < 256 or raise InvalidAddress , "invalid address"
543
+ s . match ( /\A 0./ ) and raise ZeroFilledNumber , "zero-filled number is ambiguous"
516
544
i << 8 | n
517
545
}
518
546
end
@@ -529,18 +557,18 @@ def in6_addr(left)
529
557
right = ''
530
558
when RE_IPV6ADDRLIKE_COMPRESSED
531
559
if $4
532
- left . count ( ':' ) <= 6 or raise ArgumentError , "invalid address"
560
+ left . count ( ':' ) <= 6 or raise InvalidAddress , "invalid address"
533
561
addr = in_addr ( $~[ 4 , 4 ] )
534
562
left = $1
535
563
right = $3 + '0:0'
536
564
else
537
- left . count ( ':' ) <= 7 or raise ArgumentError , "invalid address"
565
+ left . count ( ':' ) <= 7 or raise InvalidAddress , "invalid address"
538
566
left = $1
539
567
right = $2
540
568
addr = 0
541
569
end
542
570
else
543
- raise ArgumentError , "invalid address"
571
+ raise InvalidAddress , "invalid address"
544
572
end
545
573
l = left . split ( ':' )
546
574
r = right . split ( ':' )
@@ -560,7 +588,7 @@ def addr_mask(addr)
560
588
when Socket ::AF_INET6
561
589
return addr & IN6MASK
562
590
else
563
- raise "unsupported address family"
591
+ raise UnsupportedAddressFamily , "unsupported address family"
564
592
end
565
593
end
566
594
@@ -573,7 +601,7 @@ def _reverse
573
601
when Socket ::AF_INET6
574
602
return ( "%.32x" % @addr ) . reverse! . gsub! ( /.(?!$)/ , '\&.' )
575
603
else
576
- raise "unsupported address family"
604
+ raise UnsupportedAddressFamily , "unsupported address family"
577
605
end
578
606
end
579
607
@@ -586,7 +614,7 @@ def _to_string(addr)
586
614
when Socket ::AF_INET6
587
615
return ( ( "%.32x" % addr ) . gsub! ( /.{4}(?!$)/ , '\&:' ) )
588
616
else
589
- raise "unsupported address family"
617
+ raise UnsupportedAddressFamily , "unsupported address family"
590
618
end
591
619
end
592
620
@@ -713,19 +741,13 @@ def test_s_new
713
741
714
742
assert_equal("2001:200:300::", IPAddr.new("[2001:200:300::]/48").to_s)
715
743
716
- [
717
- ["192.168.0.256"],
718
- ["192.168.0.011"],
719
- ["fe80::1%fxp0"],
720
- ["::1/255.255.255.0"],
721
- [IPAddr.new("::1").to_i],
722
- ["::ffff:192.168.1.2/120", Socket::AF_INET],
723
- ["[192.168.1.2]/120"],
724
- ].each { |args|
725
- assert_raises(ArgumentError) {
726
- IPAddr.new(*args)
727
- }
728
- }
744
+ assert_raises(IPAddr::InvalidAddress) { IPAddr.new('192.168.0.256') }
745
+ assert_raises(IPAddr::ZeroFilledNumber) { IPAddr.new('192.168.0.011') }
746
+ assert_raises(IPAddr::InvalidAddress) { IPAddr.new("fe80::1%fxp0") }
747
+ assert_raises(IPAddr::InconsistentAddressFamily) { IPAddr.new("::1/255.255.255.0") }
748
+ assert_raises(IPAddr::UnspecifiedAddressFamily) { IPAddr.new(1) }
749
+ assert_raises(IPAddr::InconsistentAddressFamily) { IPAddr.new("::ffff:192.168.1.2/120", Socket::AF_INET) }
750
+ assert_raises(IPAddr::InvalidAddress) { IPAddr.new("[192.168.1.2]/120") }
729
751
end
730
752
731
753
def test_s_new_ntoh
@@ -786,14 +808,14 @@ def test_reverse
786
808
787
809
def test_ip6_arpa
788
810
assert_equal("f.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.5.0.5.0.e.f.f.3.ip6.arpa", IPAddr.new("3ffe:505:2::f").ip6_arpa)
789
- assert_raises(ArgumentError ) {
811
+ assert_raises(IPAddr::InvalidIPv6 ) {
790
812
IPAddr.new("192.168.2.1").ip6_arpa
791
813
}
792
814
end
793
815
794
816
def test_ip6_int
795
817
assert_equal("f.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.5.0.5.0.e.f.f.3.ip6.int", IPAddr.new("3ffe:505:2::f").ip6_int)
796
- assert_raises(ArgumentError ) {
818
+ assert_raises(IPAddr::InvalidIPv6 ) {
797
819
IPAddr.new("192.168.2.1").ip6_int
798
820
}
799
821
end
0 commit comments