@@ -82,6 +82,21 @@ class IPAddr
82
82
\z
83
83
}xi
84
84
85
+ # Generic IPAddr related error. Exceptions raised in this class should
86
+ # inherit from Error.
87
+ class Error < ArgumentError ; end
88
+
89
+ # Raised when the provided IP address is an invalid address.
90
+ class InvalidAddressError < Error ; end
91
+
92
+ # Raised when the address family is invalid such as an address with an
93
+ # unsupported family, an address with an inconsistent family, or an address
94
+ # who's family cannot be determined.
95
+ class AddressFamilyError < Error ; end
96
+
97
+ # Raised when the address is an invalid length.
98
+ class InvalidPrefixError < InvalidAddressError ; end
99
+
85
100
# Returns the address family of this IP address.
86
101
attr_reader :family
87
102
@@ -100,7 +115,7 @@ def IPAddr::ntop(addr)
100
115
when 16
101
116
s = IN6FORMAT % addr . unpack ( 'n8' )
102
117
else
103
- raise ArgumentError , "unsupported address family"
118
+ raise AddressFamilyError , "unsupported address family"
104
119
end
105
120
return s
106
121
end
@@ -226,7 +241,7 @@ def hton
226
241
( @addr >> ( 112 - 16 * i ) ) & 0xffff
227
242
} . pack ( 'n8' )
228
243
else
229
- raise "unsupported address family"
244
+ raise AddressFamilyError , "unsupported address family"
230
245
end
231
246
end
232
247
@@ -258,7 +273,7 @@ def ipv4_compat?
258
273
# into an IPv4-mapped IPv6 address.
259
274
def ipv4_mapped
260
275
if !ipv4?
261
- raise ArgumentError , "not an IPv4 address"
276
+ raise InvalidAddressError , "not an IPv4 address"
262
277
end
263
278
return self . clone . set ( @addr | 0xffff00000000 , Socket ::AF_INET6 )
264
279
end
@@ -267,7 +282,7 @@ def ipv4_mapped
267
282
# into an IPv4-compatible IPv6 address.
268
283
def ipv4_compat
269
284
if !ipv4?
270
- raise ArgumentError , "not an IPv4 address"
285
+ raise InvalidAddressError , "not an IPv4 address"
271
286
end
272
287
return self . clone . set ( @addr , Socket ::AF_INET6 )
273
288
end
@@ -291,22 +306,22 @@ def reverse
291
306
when Socket ::AF_INET6
292
307
return ip6_arpa
293
308
else
294
- raise "unsupported address family"
309
+ raise AddressFamilyError , "unsupported address family"
295
310
end
296
311
end
297
312
298
313
# Returns a string for DNS reverse lookup compatible with RFC3172.
299
314
def ip6_arpa
300
315
if !ipv6?
301
- raise ArgumentError , "not an IPv6 address"
316
+ raise InvalidAddressError , "not an IPv6 address"
302
317
end
303
318
return _reverse + ".ip6.arpa"
304
319
end
305
320
306
321
# Returns a string for DNS reverse lookup compatible with RFC1886.
307
322
def ip6_int
308
323
if !ipv6?
309
- raise ArgumentError , "not an IPv6 address"
324
+ raise InvalidAddressError , "not an IPv6 address"
310
325
end
311
326
return _reverse + ".ip6.int"
312
327
end
@@ -346,7 +361,7 @@ def to_range
346
361
when Socket ::AF_INET6
347
362
end_addr = ( @addr | ( IN6MASK ^ @mask_addr ) )
348
363
else
349
- raise "unsupported address family"
364
+ raise AddressFamilyError , "unsupported address family"
350
365
end
351
366
352
367
return clone . set ( begin_addr , @family ) ..clone . set ( end_addr , @family )
@@ -361,7 +376,7 @@ def inspect
361
376
when Socket ::AF_INET6
362
377
af = "IPv6"
363
378
else
364
- raise "unsupported address family"
379
+ raise AddressFamilyError , "unsupported address family"
365
380
end
366
381
return sprintf ( "#<%s: %s:%s/%s>" , self . class . name ,
367
382
af , _to_string ( @addr ) , _to_string ( @mask_addr ) )
@@ -376,14 +391,14 @@ def set(addr, *family)
376
391
case family [ 0 ] ? family [ 0 ] : @family
377
392
when Socket ::AF_INET
378
393
if addr < 0 || addr > IN4MASK
379
- raise ArgumentError , "invalid address"
394
+ raise InvalidAddressError , "invalid address"
380
395
end
381
396
when Socket ::AF_INET6
382
397
if addr < 0 || addr > IN6MASK
383
- raise ArgumentError , "invalid address"
398
+ raise InvalidAddressError , "invalid address"
384
399
end
385
400
else
386
- raise ArgumentError , "unsupported address family"
401
+ raise AddressFamilyError , "unsupported address family"
387
402
end
388
403
@addr = addr
389
404
if family [ 0 ]
@@ -400,7 +415,7 @@ def mask!(mask)
400
415
else
401
416
m = IPAddr . new ( mask )
402
417
if m . family != @family
403
- raise ArgumentError , "address family is not same"
418
+ raise InvalidPrefixError , "address family is not same"
404
419
end
405
420
@mask_addr = m . to_i
406
421
@addr &= @mask_addr
@@ -412,18 +427,18 @@ def mask!(mask)
412
427
case @family
413
428
when Socket ::AF_INET
414
429
if prefixlen < 0 || prefixlen > 32
415
- raise ArgumentError , "invalid length"
430
+ raise InvalidPrefixError , "invalid length"
416
431
end
417
432
masklen = 32 - prefixlen
418
433
@mask_addr = ( ( IN4MASK >> masklen ) << masklen )
419
434
when Socket ::AF_INET6
420
435
if prefixlen < 0 || prefixlen > 128
421
- raise ArgumentError , "invalid length"
436
+ raise InvalidPrefixError , "invalid length"
422
437
end
423
438
masklen = 128 - prefixlen
424
439
@mask_addr = ( ( IN6MASK >> masklen ) << masklen )
425
440
else
426
- raise "unsupported address family"
441
+ raise AddressFamilyError , "unsupported address family"
427
442
end
428
443
@addr = ( ( @addr >> masklen ) << masklen )
429
444
return self
@@ -457,9 +472,9 @@ def initialize(addr = '::', family = Socket::AF_UNSPEC)
457
472
@mask_addr = ( family == Socket ::AF_INET ) ? IN4MASK : IN6MASK
458
473
return
459
474
when Socket ::AF_UNSPEC
460
- raise ArgumentError , "address family must be specified"
475
+ raise AddressFamilyError , "address family must be specified"
461
476
else
462
- raise ArgumentError , "unsupported address family: #{ family } "
477
+ raise AddressFamilyError , "unsupported address family: #{ family } "
463
478
end
464
479
end
465
480
prefix , prefixlen = addr . split ( '/' )
@@ -482,7 +497,7 @@ def initialize(addr = '::', family = Socket::AF_UNSPEC)
482
497
@family = Socket ::AF_INET6
483
498
end
484
499
if family != Socket ::AF_UNSPEC && @family != family
485
- raise ArgumentError , "address family mismatch"
500
+ raise AddressFamilyError , "address family mismatch"
486
501
end
487
502
if prefixlen
488
503
mask! ( prefixlen )
@@ -511,8 +526,8 @@ def in_addr(addr)
511
526
octets = m . captures
512
527
end
513
528
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"
529
+ ( n = s . to_i ) < 256 or raise InvalidAddressError , "invalid address"
530
+ s . match ( /\A 0./ ) and raise InvalidAddressError , "zero-filled number in IPv4 address is ambiguous"
516
531
i << 8 | n
517
532
}
518
533
end
@@ -529,18 +544,18 @@ def in6_addr(left)
529
544
right = ''
530
545
when RE_IPV6ADDRLIKE_COMPRESSED
531
546
if $4
532
- left . count ( ':' ) <= 6 or raise ArgumentError , "invalid address"
547
+ left . count ( ':' ) <= 6 or raise InvalidAddressError , "invalid address"
533
548
addr = in_addr ( $~[ 4 , 4 ] )
534
549
left = $1
535
550
right = $3 + '0:0'
536
551
else
537
- left . count ( ':' ) <= 7 or raise ArgumentError , "invalid address"
552
+ left . count ( ':' ) <= 7 or raise InvalidAddressError , "invalid address"
538
553
left = $1
539
554
right = $2
540
555
addr = 0
541
556
end
542
557
else
543
- raise ArgumentError , "invalid address"
558
+ raise InvalidAddressError , "invalid address"
544
559
end
545
560
l = left . split ( ':' )
546
561
r = right . split ( ':' )
@@ -560,7 +575,7 @@ def addr_mask(addr)
560
575
when Socket ::AF_INET6
561
576
return addr & IN6MASK
562
577
else
563
- raise "unsupported address family"
578
+ raise AddressFamilyError , "unsupported address family"
564
579
end
565
580
end
566
581
@@ -573,7 +588,7 @@ def _reverse
573
588
when Socket ::AF_INET6
574
589
return ( "%.32x" % @addr ) . reverse! . gsub! ( /.(?!$)/ , '\&.' )
575
590
else
576
- raise "unsupported address family"
591
+ raise AddressFamilyError , "unsupported address family"
577
592
end
578
593
end
579
594
@@ -586,7 +601,7 @@ def _to_string(addr)
586
601
when Socket ::AF_INET6
587
602
return ( ( "%.32x" % addr ) . gsub! ( /.{4}(?!$)/ , '\&:' ) )
588
603
else
589
- raise "unsupported address family"
604
+ raise AddressFamilyError , "unsupported address family"
590
605
end
591
606
end
592
607
@@ -713,19 +728,15 @@ def test_s_new
713
728
714
729
assert_equal("2001:200:300::", IPAddr.new("[2001:200:300::]/48").to_s)
715
730
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
- }
731
+ assert_raises(IPAddr::InvalidAddressError) { IPAddr.new("192.168.0.256") }
732
+ assert_raises(IPAddr::InvalidAddressError) { IPAddr.new("192.168.0.011") }
733
+ assert_raises(IPAddr::InvalidAddressError) { IPAddr.new("fe80::1%fxp0") }
734
+ assert_raises(IPAddr::InvalidAddressError) { IPAddr.new("[192.168.1.2]/120") }
735
+ assert_raises(IPAddr::InvalidPrefixError) { IPAddr.new("::1/255.255.255.0") }
736
+ assert_raises(IPAddr::InvalidPrefixError) { IPAddr.new("::1/129") }
737
+ assert_raises(IPAddr::InvalidPrefixError) { IPAddr.new("192.168.0.1/33") }
738
+ assert_raises(IPAddr::AddressFamilyError) { IPAddr.new(1) }
739
+ assert_raises(IPAddr::AddressFamilyError) { IPAddr.new("::ffff:192.168.1.2/120", Socket::AF_INET) }
729
740
end
730
741
731
742
def test_s_new_ntoh
@@ -786,14 +797,14 @@ def test_reverse
786
797
787
798
def test_ip6_arpa
788
799
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 ) {
800
+ assert_raises(IPAddr::InvalidAddressError ) {
790
801
IPAddr.new("192.168.2.1").ip6_arpa
791
802
}
792
803
end
793
804
794
805
def test_ip6_int
795
806
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 ) {
807
+ assert_raises(IPAddr::InvalidAddressError ) {
797
808
IPAddr.new("192.168.2.1").ip6_int
798
809
}
799
810
end
0 commit comments