rack-auth-ip 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (21) hide show
  1. data/Rakefile +2 -2
  2. data/doc/output/coverage/-Library-Ruby-Gems-gems-diff-lcs-1_1_2-lib-diff-lcs-block_rb.html +1 -1
  3. data/doc/output/coverage/-Library-Ruby-Gems-gems-diff-lcs-1_1_2-lib-diff-lcs-callbacks_rb.html +1 -1
  4. data/doc/output/coverage/-Library-Ruby-Gems-gems-diff-lcs-1_1_2-lib-diff-lcs-change_rb.html +1 -1
  5. data/doc/output/coverage/-Library-Ruby-Gems-gems-diff-lcs-1_1_2-lib-diff-lcs-hunk_rb.html +1 -1
  6. data/doc/output/coverage/-Library-Ruby-Gems-gems-diff-lcs-1_1_2-lib-diff-lcs_rb.html +1 -1
  7. data/doc/output/coverage/-Library-Ruby-Gems-gems-rcov-0_8_1_2_0-lib-rcov_rb.html +989 -989
  8. data/doc/output/coverage/-System-Library-Frameworks-Ruby_framework-Versions-1_8-usr-lib-ruby-1_8-drb-drb_rb.html +1764 -1764
  9. data/doc/output/coverage/-System-Library-Frameworks-Ruby_framework-Versions-1_8-usr-lib-ruby-1_8-drb-eq_rb.html +17 -17
  10. data/doc/output/coverage/-System-Library-Frameworks-Ruby_framework-Versions-1_8-usr-lib-ruby-1_8-drb-invokemethod_rb.html +37 -37
  11. data/doc/output/coverage/-System-Library-Frameworks-Ruby_framework-Versions-1_8-usr-lib-ruby-1_8-forwardable_rb.html +219 -219
  12. data/doc/output/coverage/-System-Library-Frameworks-Ruby_framework-Versions-1_8-usr-lib-ruby-1_8-ipaddr_rb.html +530 -530
  13. data/doc/output/coverage/-System-Library-Frameworks-Ruby_framework-Versions-1_8-usr-lib-ruby-1_8-pp_rb.html +648 -648
  14. data/doc/output/coverage/-System-Library-Frameworks-Ruby_framework-Versions-1_8-usr-lib-ruby-1_8-prettyprint_rb.html +897 -897
  15. data/doc/output/coverage/-System-Library-Frameworks-Ruby_framework-Versions-1_8-usr-lib-ruby-1_8-timeout_rb.html +106 -106
  16. data/doc/output/coverage/index.html +11 -65
  17. data/doc/output/coverage/lib-rack-auth-ip_rb.html +51 -53
  18. data/lib/rack/auth/ip.rb +1 -1
  19. metadata +2 -4
  20. data/doc/output/coverage/-Library-Ruby-Gems-gems-rack-0_3_0-lib-rack-auth-abstract-handler_rb.html +0 -638
  21. data/doc/output/coverage/-Library-Ruby-Gems-gems-rack-0_3_0-lib-rack-auth-abstract-request_rb.html +0 -647
@@ -553,7 +553,7 @@ span.run100 {
553
553
  </style>
554
554
  </head>
555
555
  <body><h3>C0 code coverage information</h3>
556
- <p>Generated on Sat May 24 14:04:39 +0900 2008 with <a href='http://eigenclass.org/hiki/rcov'>rcov 0.8.1.2</a>
556
+ <p>Generated on Sat May 24 15:19:18 +0900 2008 with <a href='http://eigenclass.org/hiki/rcov'>rcov 0.8.1.2</a>
557
557
  </p>
558
558
  <hr/>
559
559
  <pre><span class='marked0'>Code reported as executed by Ruby looks like this...
@@ -598,535 +598,535 @@ span.run100 {
598
598
  </tr>
599
599
  </tbody>
600
600
  </table>
601
- <pre><span class="inferred1"><a name="line1"></a> 1 #
602
- </span><span class="inferred0"><a name="line2"></a> 2 # ipaddr.rb - A class to manipulate an IP address
603
- </span><span class="inferred1"><a name="line3"></a> 3 #
604
- </span><span class="inferred0"><a name="line4"></a> 4 # Copyright (c) 2002 Hajimu UMEMOTO &lt;ume@mahoroba.org&gt;.
605
- </span><span class="inferred1"><a name="line5"></a> 5 # All rights reserved.
606
- </span><span class="inferred0"><a name="line6"></a> 6 #
607
- </span><span class="inferred1"><a name="line7"></a> 7 # You can redistribute and/or modify it under the same terms as Ruby.
608
- </span><span class="inferred0"><a name="line8"></a> 8 #
609
- </span><span class="inferred1"><a name="line9"></a> 9 # $Id: ipaddr.rb 11708 2007-02-12 23:01:19Z shyouhei $
610
- </span><span class="inferred0"><a name="line10"></a> 10 #
611
- </span><span class="inferred1"><a name="line11"></a> 11 # TODO:
612
- </span><span class="inferred0"><a name="line12"></a> 12 # - scope_id support
613
- </span><span class="marked1"><a name="line13"></a> 13 require 'socket'
614
- </span><span class="inferred0"><a name="line14"></a> 14
615
- </span><span class="marked1"><a name="line15"></a> 15 unless Socket.const_defined? &quot;AF_INET6&quot;
616
- </span><span class="uncovered0"><a name="line16"></a> 16 class Socket
617
- </span><span class="uncovered1"><a name="line17"></a> 17 AF_INET6 = Object.new
618
- </span><span class="uncovered0"><a name="line18"></a> 18 end
619
- </span><span class="uncovered1"><a name="line19"></a> 19
620
- </span><span class="uncovered0"><a name="line20"></a> 20 class &lt;&lt; IPSocket
621
- </span><span class="uncovered1"><a name="line21"></a> 21 def valid_v4?(addr)
622
- </span><span class="uncovered0"><a name="line22"></a> 22 if /\A(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\Z/ =~ addr
623
- </span><span class="uncovered1"><a name="line23"></a> 23 return $~.captures.all? {|i| i.to_i &lt; 256}
624
- </span><span class="uncovered0"><a name="line24"></a> 24 end
625
- </span><span class="uncovered1"><a name="line25"></a> 25 return false
626
- </span><span class="uncovered0"><a name="line26"></a> 26 end
627
- </span><span class="uncovered1"><a name="line27"></a> 27
628
- </span><span class="uncovered0"><a name="line28"></a> 28 def valid_v6?(addr)
629
- </span><span class="uncovered1"><a name="line29"></a> 29 # IPv6 (normal)
630
- </span><span class="uncovered0"><a name="line30"></a> 30 return true if /\A[\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*\Z/ =~ addr
631
- </span><span class="uncovered1"><a name="line31"></a> 31 return true if /\A[\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*::([\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*)?\Z/ =~ addr
632
- </span><span class="uncovered0"><a name="line32"></a> 32 return true if /\A::([\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*)?\Z/ =~ addr
633
- </span><span class="uncovered1"><a name="line33"></a> 33 # IPv6 (IPv4 compat)
634
- </span><span class="uncovered0"><a name="line34"></a> 34 return true if /\A[\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*:/ =~ addr &amp;&amp; valid_v4?($')
635
- </span><span class="uncovered1"><a name="line35"></a> 35 return true if /\A[\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*::([\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*:)?/ =~ addr &amp;&amp; valid_v4?($')
636
- </span><span class="uncovered0"><a name="line36"></a> 36 return true if /\A::([\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*:)?/ =~ addr &amp;&amp; valid_v4?($')
637
- </span><span class="uncovered1"><a name="line37"></a> 37
638
- </span><span class="uncovered0"><a name="line38"></a> 38 false
639
- </span><span class="uncovered1"><a name="line39"></a> 39 end
640
- </span><span class="uncovered0"><a name="line40"></a> 40
641
- </span><span class="uncovered1"><a name="line41"></a> 41 def valid?(addr)
642
- </span><span class="uncovered0"><a name="line42"></a> 42 valid_v4?(addr) || valid_v6?(addr)
643
- </span><span class="uncovered1"><a name="line43"></a> 43 end
644
- </span><span class="uncovered0"><a name="line44"></a> 44
645
- </span><span class="uncovered1"><a name="line45"></a> 45 alias getaddress_orig getaddress
646
- </span><span class="uncovered0"><a name="line46"></a> 46 def getaddress(s)
647
- </span><span class="uncovered1"><a name="line47"></a> 47 if valid?(s)
648
- </span><span class="uncovered0"><a name="line48"></a> 48 s
649
- </span><span class="uncovered1"><a name="line49"></a> 49 elsif /\A[-A-Za-z\d.]+\Z/ =~ s
650
- </span><span class="uncovered0"><a name="line50"></a> 50 getaddress_orig(s)
651
- </span><span class="uncovered1"><a name="line51"></a> 51 else
652
- </span><span class="uncovered0"><a name="line52"></a> 52 raise ArgumentError, &quot;invalid address&quot;
653
- </span><span class="uncovered1"><a name="line53"></a> 53 end
654
- </span><span class="uncovered0"><a name="line54"></a> 54 end
655
- </span><span class="uncovered1"><a name="line55"></a> 55 end
656
- </span><span class="uncovered0"><a name="line56"></a> 56 end
657
- </span><span class="inferred1"><a name="line57"></a> 57
658
- </span><span class="inferred0"><a name="line58"></a> 58 # IPAddr provides a set of methods to manipulate an IP address. Both IPv4 and
659
- </span><span class="inferred1"><a name="line59"></a> 59 # IPv6 are supported.
660
- </span><span class="inferred0"><a name="line60"></a> 60 #
661
- </span><span class="inferred1"><a name="line61"></a> 61 # == Example
662
- </span><span class="inferred0"><a name="line62"></a> 62 #
663
- </span><span class="inferred1"><a name="line63"></a> 63 # require 'ipaddr'
664
- </span><span class="inferred0"><a name="line64"></a> 64 #
665
- </span><span class="inferred1"><a name="line65"></a> 65 # ipaddr1 = IPAddr.new &quot;3ffe:505:2::1&quot;
666
- </span><span class="inferred0"><a name="line66"></a> 66 #
667
- </span><span class="inferred1"><a name="line67"></a> 67 # p ipaddr1 #=&gt; #&lt;IPAddr: IPv6:3ffe:0505:0002:0000:0000:0000:0000:0001/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff&gt;
668
- </span><span class="inferred0"><a name="line68"></a> 68 #
669
- </span><span class="inferred1"><a name="line69"></a> 69 # p ipaddr1.to_s #=&gt; &quot;3ffe:505:2::1&quot;
670
- </span><span class="inferred0"><a name="line70"></a> 70 #
671
- </span><span class="inferred1"><a name="line71"></a> 71 # ipaddr2 = ipaddr1.mask(48) #=&gt; #&lt;IPAddr: IPv6:3ffe:0505:0002:0000:0000:0000:0000:0000/ffff:ffff:ffff:0000:0000:0000:0000:0000&gt;
672
- </span><span class="inferred0"><a name="line72"></a> 72 #
673
- </span><span class="inferred1"><a name="line73"></a> 73 # p ipaddr2.to_s #=&gt; &quot;3ffe:505:2::&quot;
674
- </span><span class="inferred0"><a name="line74"></a> 74 #
675
- </span><span class="inferred1"><a name="line75"></a> 75 # ipaddr3 = IPAddr.new &quot;192.168.2.0/24&quot;
676
- </span><span class="inferred0"><a name="line76"></a> 76 #
677
- </span><span class="inferred1"><a name="line77"></a> 77 # p ipaddr3 #=&gt; #&lt;IPAddr: IPv4:192.168.2.0/255.255.255.0&gt;
678
- </span><span class="inferred0"><a name="line78"></a> 78
679
- </span><span class="marked1"><a name="line79"></a> 79 class IPAddr
680
- </span><span class="inferred0"><a name="line80"></a> 80
681
- </span><span class="marked1"><a name="line81"></a> 81 IN4MASK = 0xffffffff
682
- </span><span class="marked0"><a name="line82"></a> 82 IN6MASK = 0xffffffffffffffffffffffffffffffff
683
- </span><span class="marked1"><a name="line83"></a> 83 IN6FORMAT = ([&quot;%.4x&quot;] * 8).join(':')
684
- </span><span class="inferred0"><a name="line84"></a> 84
685
- </span><span class="inferred1"><a name="line85"></a> 85 # Returns the address family of this IP address.
686
- </span><span class="marked0"><a name="line86"></a> 86 attr :family
687
- </span><span class="inferred1"><a name="line87"></a> 87
688
- </span><span class="inferred0"><a name="line88"></a> 88 # Creates a new ipaddr containing the given network byte ordered
689
- </span><span class="inferred1"><a name="line89"></a> 89 # string form of an IP address.
690
- </span><span class="marked0"><a name="line90"></a> 90 def IPAddr::new_ntoh(addr)
691
- </span><span class="uncovered1"><a name="line91"></a> 91 return IPAddr.new(IPAddr::ntop(addr))
692
- </span><span class="uncovered0"><a name="line92"></a> 92 end
693
- </span><span class="inferred1"><a name="line93"></a> 93
694
- </span><span class="inferred0"><a name="line94"></a> 94 # Convert a network byte ordered string form of an IP address into
695
- </span><span class="inferred1"><a name="line95"></a> 95 # human readable form.
696
- </span><span class="marked0"><a name="line96"></a> 96 def IPAddr::ntop(addr)
697
- </span><span class="uncovered1"><a name="line97"></a> 97 case addr.size
698
- </span><span class="uncovered0"><a name="line98"></a> 98 when 4
699
- </span><span class="uncovered1"><a name="line99"></a> 99 s = addr.unpack('C4').join('.')
700
- </span><span class="uncovered0"><a name="line100"></a>100 when 16
701
- </span><span class="uncovered1"><a name="line101"></a>101 s = IN6FORMAT % addr.unpack('n8')
702
- </span><span class="uncovered0"><a name="line102"></a>102 else
703
- </span><span class="uncovered1"><a name="line103"></a>103 raise ArgumentError, &quot;unsupported address family&quot;
704
- </span><span class="uncovered0"><a name="line104"></a>104 end
705
- </span><span class="uncovered1"><a name="line105"></a>105 return s
706
- </span><span class="uncovered0"><a name="line106"></a>106 end
707
- </span><span class="inferred1"><a name="line107"></a>107
708
- </span><span class="inferred0"><a name="line108"></a>108 # Returns a new ipaddr built by bitwise AND.
709
- </span><span class="marked1"><a name="line109"></a>109 def &amp;(other)
710
- </span><span class="uncovered0"><a name="line110"></a>110 return self.clone.set(@addr &amp; other.to_i)
711
- </span><span class="uncovered1"><a name="line111"></a>111 end
712
- </span><span class="inferred0"><a name="line112"></a>112
713
- </span><span class="inferred1"><a name="line113"></a>113 # Returns a new ipaddr built by bitwise OR.
714
- </span><span class="marked0"><a name="line114"></a>114 def |(other)
715
- </span><span class="uncovered1"><a name="line115"></a>115 return self.clone.set(@addr | other.to_i)
716
- </span><span class="uncovered0"><a name="line116"></a>116 end
717
- </span><span class="inferred1"><a name="line117"></a>117
718
- </span><span class="inferred0"><a name="line118"></a>118 # Returns a new ipaddr built by bitwise right-shift.
719
- </span><span class="marked1"><a name="line119"></a>119 def &gt;&gt;(num)
720
- </span><span class="uncovered0"><a name="line120"></a>120 return self.clone.set(@addr &gt;&gt; num)
721
- </span><span class="uncovered1"><a name="line121"></a>121 end
722
- </span><span class="inferred0"><a name="line122"></a>122
723
- </span><span class="inferred1"><a name="line123"></a>123 # Returns a new ipaddr built by bitwise left shift.
724
- </span><span class="marked0"><a name="line124"></a>124 def &lt;&lt;(num)
725
- </span><span class="uncovered1"><a name="line125"></a>125 return self.clone.set(addr_mask(@addr &lt;&lt; num))
726
- </span><span class="uncovered0"><a name="line126"></a>126 end
727
- </span><span class="inferred1"><a name="line127"></a>127
728
- </span><span class="inferred0"><a name="line128"></a>128 # Returns a new ipaddr built by bitwise negation.
729
- </span><span class="marked1"><a name="line129"></a>129 def ~
730
- </span><span class="uncovered0"><a name="line130"></a>130 return self.clone.set(addr_mask(~@addr))
731
- </span><span class="uncovered1"><a name="line131"></a>131 end
732
- </span><span class="inferred0"><a name="line132"></a>132
733
- </span><span class="inferred1"><a name="line133"></a>133 # Returns true if two ipaddr are equal.
734
- </span><span class="marked0"><a name="line134"></a>134 def ==(other)
735
- </span><span class="marked1"><a name="line135"></a>135 if other.kind_of?(IPAddr) &amp;&amp; @family != other.family
736
- </span><span class="uncovered0"><a name="line136"></a>136 return false
737
- </span><span class="uncovered1"><a name="line137"></a>137 end
738
- </span><span class="marked0"><a name="line138"></a>138 return (@addr == other.to_i)
739
- </span><span class="inferred1"><a name="line139"></a>139 end
740
- </span><span class="inferred0"><a name="line140"></a>140
741
- </span><span class="inferred1"><a name="line141"></a>141 # Returns a new ipaddr built by masking IP address with the given
742
- </span><span class="inferred0"><a name="line142"></a>142 # prefixlen/netmask. (e.g. 8, 64, &quot;255.255.255.0&quot;, etc.)
743
- </span><span class="marked1"><a name="line143"></a>143 def mask(prefixlen)
744
- </span><span class="uncovered0"><a name="line144"></a>144 return self.clone.mask!(prefixlen)
745
- </span><span class="uncovered1"><a name="line145"></a>145 end
746
- </span><span class="inferred0"><a name="line146"></a>146
747
- </span><span class="inferred1"><a name="line147"></a>147 # Returns true if the given ipaddr is in the range.
748
- </span><span class="inferred0"><a name="line148"></a>148 #
749
- </span><span class="inferred1"><a name="line149"></a>149 # e.g.:
750
- </span><span class="inferred0"><a name="line150"></a>150 # require 'ipaddr'
751
- </span><span class="inferred1"><a name="line151"></a>151 # net1 = IPAddr.new(&quot;192.168.2.0/24&quot;)
752
- </span><span class="inferred0"><a name="line152"></a>152 # p net1.include?(IPAddr.new(&quot;192.168.2.0&quot;)) #=&gt; true
753
- </span><span class="inferred1"><a name="line153"></a>153 # p net1.include?(IPAddr.new(&quot;192.168.2.255&quot;)) #=&gt; true
754
- </span><span class="inferred0"><a name="line154"></a>154 # p net1.include?(IPAddr.new(&quot;192.168.3.0&quot;)) #=&gt; false
755
- </span><span class="marked1"><a name="line155"></a>155 def include?(other)
756
- </span><span class="marked0"><a name="line156"></a>156 if ipv4_mapped?
757
- </span><span class="uncovered1"><a name="line157"></a>157 if (@mask_addr &gt;&gt; 32) != 0xffffffffffffffffffffffff
758
- </span><span class="uncovered0"><a name="line158"></a>158 return false
759
- </span><span class="uncovered1"><a name="line159"></a>159 end
760
- </span><span class="uncovered0"><a name="line160"></a>160 mask_addr = (@mask_addr &amp; IN4MASK)
761
- </span><span class="uncovered1"><a name="line161"></a>161 addr = (@addr &amp; IN4MASK)
762
- </span><span class="uncovered0"><a name="line162"></a>162 family = Socket::AF_INET
763
- </span><span class="inferred1"><a name="line163"></a>163 else
764
- </span><span class="marked0"><a name="line164"></a>164 mask_addr = @mask_addr
765
- </span><span class="marked1"><a name="line165"></a>165 addr = @addr
766
- </span><span class="marked0"><a name="line166"></a>166 family = @family
767
- </span><span class="inferred1"><a name="line167"></a>167 end
768
- </span><span class="marked0"><a name="line168"></a>168 if other.kind_of?(IPAddr)
769
- </span><span class="marked1"><a name="line169"></a>169 if other.ipv4_mapped?
770
- </span><span class="uncovered0"><a name="line170"></a>170 other_addr = (other.to_i &amp; IN4MASK)
771
- </span><span class="uncovered1"><a name="line171"></a>171 other_family = Socket::AF_INET
772
- </span><span class="inferred0"><a name="line172"></a>172 else
773
- </span><span class="marked1"><a name="line173"></a>173 other_addr = other.to_i
774
- </span><span class="marked0"><a name="line174"></a>174 other_family = other.family
775
- </span><span class="inferred1"><a name="line175"></a>175 end
776
- </span><span class="uncovered0"><a name="line176"></a>176 else # Not IPAddr - assume integer in same family as us
777
- </span><span class="uncovered1"><a name="line177"></a>177 other_addr = other.to_i
778
- </span><span class="uncovered0"><a name="line178"></a>178 other_family = family
779
- </span><span class="uncovered1"><a name="line179"></a>179 end
780
- </span><span class="inferred0"><a name="line180"></a>180
781
- </span><span class="marked1"><a name="line181"></a>181 if family != other_family
782
- </span><span class="uncovered0"><a name="line182"></a>182 return false
783
- </span><span class="uncovered1"><a name="line183"></a>183 end
784
- </span><span class="marked0"><a name="line184"></a>184 return ((addr &amp; mask_addr) == (other_addr &amp; mask_addr))
785
- </span><span class="inferred1"><a name="line185"></a>185 end
786
- </span><span class="marked0"><a name="line186"></a>186 alias === include?
787
- </span><span class="inferred1"><a name="line187"></a>187
788
- </span><span class="inferred0"><a name="line188"></a>188 # Returns the integer representation of the ipaddr.
789
- </span><span class="marked1"><a name="line189"></a>189 def to_i
790
- </span><span class="marked0"><a name="line190"></a>190 return @addr
791
- </span><span class="marked1"><a name="line191"></a>191 end
792
- </span><span class="inferred0"><a name="line192"></a>192
793
- </span><span class="inferred1"><a name="line193"></a>193 # Returns a string containing the IP address representation.
794
- </span><span class="marked0"><a name="line194"></a>194 def to_s
795
- </span><span class="uncovered1"><a name="line195"></a>195 str = to_string
796
- </span><span class="uncovered0"><a name="line196"></a>196 return str if ipv4?
797
- </span><span class="uncovered1"><a name="line197"></a>197
798
- </span><span class="uncovered0"><a name="line198"></a>198 str.gsub!(/\b0{1,3}([\da-f]+)\b/i, '\1')
799
- </span><span class="uncovered1"><a name="line199"></a>199 loop do
800
- </span><span class="uncovered0"><a name="line200"></a>200 break if str.sub!(/\A0:0:0:0:0:0:0:0\Z/, '::')
801
- </span><span class="uncovered1"><a name="line201"></a>201 break if str.sub!(/\b0:0:0:0:0:0:0\b/, ':')
802
- </span><span class="uncovered0"><a name="line202"></a>202 break if str.sub!(/\b0:0:0:0:0:0\b/, ':')
803
- </span><span class="uncovered1"><a name="line203"></a>203 break if str.sub!(/\b0:0:0:0:0\b/, ':')
804
- </span><span class="uncovered0"><a name="line204"></a>204 break if str.sub!(/\b0:0:0:0\b/, ':')
805
- </span><span class="uncovered1"><a name="line205"></a>205 break if str.sub!(/\b0:0:0\b/, ':')
806
- </span><span class="uncovered0"><a name="line206"></a>206 break if str.sub!(/\b0:0\b/, ':')
807
- </span><span class="uncovered1"><a name="line207"></a>207 break
808
- </span><span class="uncovered0"><a name="line208"></a>208 end
809
- </span><span class="uncovered1"><a name="line209"></a>209 str.sub!(/:{3,}/, '::')
810
- </span><span class="uncovered0"><a name="line210"></a>210
811
- </span><span class="uncovered1"><a name="line211"></a>211 if /\A::(ffff:)?([\da-f]{1,4}):([\da-f]{1,4})\Z/i =~ str
812
- </span><span class="uncovered0"><a name="line212"></a>212 str = sprintf('::%s%d.%d.%d.%d', $1, $2.hex / 256, $2.hex % 256, $3.hex / 256, $3.hex % 256)
813
- </span><span class="uncovered1"><a name="line213"></a>213 end
814
- </span><span class="uncovered0"><a name="line214"></a>214
815
- </span><span class="uncovered1"><a name="line215"></a>215 str
816
- </span><span class="uncovered0"><a name="line216"></a>216 end
817
- </span><span class="inferred1"><a name="line217"></a>217
818
- </span><span class="inferred0"><a name="line218"></a>218 # Returns a string containing the IP address representation in
819
- </span><span class="inferred1"><a name="line219"></a>219 # canonical form.
820
- </span><span class="marked0"><a name="line220"></a>220 def to_string
821
- </span><span class="uncovered1"><a name="line221"></a>221 return _to_string(@addr)
822
- </span><span class="uncovered0"><a name="line222"></a>222 end
823
- </span><span class="inferred1"><a name="line223"></a>223
824
- </span><span class="inferred0"><a name="line224"></a>224 # Returns a network byte ordered string form of the IP address.
825
- </span><span class="marked1"><a name="line225"></a>225 def hton
826
- </span><span class="uncovered0"><a name="line226"></a>226 case @family
827
- </span><span class="uncovered1"><a name="line227"></a>227 when Socket::AF_INET
828
- </span><span class="uncovered0"><a name="line228"></a>228 return [@addr].pack('N')
829
- </span><span class="uncovered1"><a name="line229"></a>229 when Socket::AF_INET6
830
- </span><span class="uncovered0"><a name="line230"></a>230 return (0..7).map { |i|
831
- </span><span class="uncovered1"><a name="line231"></a>231 (@addr &gt;&gt; (112 - 16 * i)) &amp; 0xffff
832
- </span><span class="uncovered0"><a name="line232"></a>232 }.pack('n8')
833
- </span><span class="uncovered1"><a name="line233"></a>233 else
834
- </span><span class="uncovered0"><a name="line234"></a>234 raise &quot;unsupported address family&quot;
835
- </span><span class="uncovered1"><a name="line235"></a>235 end
836
- </span><span class="uncovered0"><a name="line236"></a>236 end
837
- </span><span class="inferred1"><a name="line237"></a>237
838
- </span><span class="inferred0"><a name="line238"></a>238 # Returns true if the ipaddr is an IPv4 address.
839
- </span><span class="marked1"><a name="line239"></a>239 def ipv4?
840
- </span><span class="uncovered0"><a name="line240"></a>240 return @family == Socket::AF_INET
841
- </span><span class="uncovered1"><a name="line241"></a>241 end
842
- </span><span class="inferred0"><a name="line242"></a>242
843
- </span><span class="inferred1"><a name="line243"></a>243 # Returns true if the ipaddr is an IPv6 address.
844
- </span><span class="marked0"><a name="line244"></a>244 def ipv6?
845
- </span><span class="marked1"><a name="line245"></a>245 return @family == Socket::AF_INET6
846
- </span><span class="marked0"><a name="line246"></a>246 end
847
- </span><span class="inferred1"><a name="line247"></a>247
848
- </span><span class="inferred0"><a name="line248"></a>248 # Returns true if the ipaddr is an IPv4-mapped IPv6 address.
849
- </span><span class="marked1"><a name="line249"></a>249 def ipv4_mapped?
850
- </span><span class="marked0"><a name="line250"></a>250 return ipv6? &amp;&amp; (@addr &gt;&gt; 32) == 0xffff
851
- </span><span class="marked1"><a name="line251"></a>251 end
852
- </span><span class="inferred0"><a name="line252"></a>252
853
- </span><span class="inferred1"><a name="line253"></a>253 # Returns true if the ipaddr is an IPv4-compatible IPv6 address.
854
- </span><span class="marked0"><a name="line254"></a>254 def ipv4_compat?
855
- </span><span class="uncovered1"><a name="line255"></a>255 if !ipv6? || (@addr &gt;&gt; 32) != 0
856
- </span><span class="uncovered0"><a name="line256"></a>256 return false
857
- </span><span class="uncovered1"><a name="line257"></a>257 end
858
- </span><span class="uncovered0"><a name="line258"></a>258 a = (@addr &amp; IN4MASK)
859
- </span><span class="uncovered1"><a name="line259"></a>259 return a != 0 &amp;&amp; a != 1
860
- </span><span class="uncovered0"><a name="line260"></a>260 end
861
- </span><span class="inferred1"><a name="line261"></a>261
862
- </span><span class="inferred0"><a name="line262"></a>262 # Returns a new ipaddr built by converting the native IPv4 address
863
- </span><span class="inferred1"><a name="line263"></a>263 # into an IPv4-mapped IPv6 address.
864
- </span><span class="marked0"><a name="line264"></a>264 def ipv4_mapped
865
- </span><span class="uncovered1"><a name="line265"></a>265 if !ipv4?
866
- </span><span class="uncovered0"><a name="line266"></a>266 raise ArgumentError, &quot;not an IPv4 address&quot;
867
- </span><span class="uncovered1"><a name="line267"></a>267 end
868
- </span><span class="uncovered0"><a name="line268"></a>268 return self.clone.set(@addr | 0xffff00000000, Socket::AF_INET6)
869
- </span><span class="uncovered1"><a name="line269"></a>269 end
870
- </span><span class="inferred0"><a name="line270"></a>270
871
- </span><span class="inferred1"><a name="line271"></a>271 # Returns a new ipaddr built by converting the native IPv4 address
872
- </span><span class="inferred0"><a name="line272"></a>272 # into an IPv4-compatible IPv6 address.
873
- </span><span class="marked1"><a name="line273"></a>273 def ipv4_compat
874
- </span><span class="uncovered0"><a name="line274"></a>274 if !ipv4?
875
- </span><span class="uncovered1"><a name="line275"></a>275 raise ArgumentError, &quot;not an IPv4 address&quot;
876
- </span><span class="uncovered0"><a name="line276"></a>276 end
877
- </span><span class="uncovered1"><a name="line277"></a>277 return self.clone.set(@addr, Socket::AF_INET6)
878
- </span><span class="uncovered0"><a name="line278"></a>278 end
879
- </span><span class="inferred1"><a name="line279"></a>279
880
- </span><span class="inferred0"><a name="line280"></a>280 # Returns a new ipaddr built by converting the IPv6 address into a
881
- </span><span class="inferred1"><a name="line281"></a>281 # native IPv4 address. If the IP address is not an IPv4-mapped or
882
- </span><span class="inferred0"><a name="line282"></a>282 # IPv4-compatible IPv6 address, returns self.
883
- </span><span class="marked1"><a name="line283"></a>283 def native
884
- </span><span class="uncovered0"><a name="line284"></a>284 if !ipv4_mapped? &amp;&amp; !ipv4_compat?
885
- </span><span class="uncovered1"><a name="line285"></a>285 return self
886
- </span><span class="uncovered0"><a name="line286"></a>286 end
887
- </span><span class="uncovered1"><a name="line287"></a>287 return self.clone.set(@addr &amp; IN4MASK, Socket::AF_INET)
888
- </span><span class="uncovered0"><a name="line288"></a>288 end
889
- </span><span class="inferred1"><a name="line289"></a>289
890
- </span><span class="inferred0"><a name="line290"></a>290 # Returns a string for DNS reverse lookup. It returns a string in
891
- </span><span class="inferred1"><a name="line291"></a>291 # RFC3172 form for an IPv6 address.
892
- </span><span class="marked0"><a name="line292"></a>292 def reverse
893
- </span><span class="uncovered1"><a name="line293"></a>293 case @family
894
- </span><span class="uncovered0"><a name="line294"></a>294 when Socket::AF_INET
895
- </span><span class="uncovered1"><a name="line295"></a>295 return _reverse + &quot;.in-addr.arpa&quot;
896
- </span><span class="uncovered0"><a name="line296"></a>296 when Socket::AF_INET6
897
- </span><span class="uncovered1"><a name="line297"></a>297 return ip6_arpa
898
- </span><span class="uncovered0"><a name="line298"></a>298 else
899
- </span><span class="uncovered1"><a name="line299"></a>299 raise &quot;unsupported address family&quot;
900
- </span><span class="uncovered0"><a name="line300"></a>300 end
901
- </span><span class="uncovered1"><a name="line301"></a>301 end
902
- </span><span class="inferred0"><a name="line302"></a>302
903
- </span><span class="inferred1"><a name="line303"></a>303 # Returns a string for DNS reverse lookup compatible with RFC3172.
904
- </span><span class="marked0"><a name="line304"></a>304 def ip6_arpa
905
- </span><span class="uncovered1"><a name="line305"></a>305 if !ipv6?
906
- </span><span class="uncovered0"><a name="line306"></a>306 raise ArgumentError, &quot;not an IPv6 address&quot;
907
- </span><span class="uncovered1"><a name="line307"></a>307 end
908
- </span><span class="uncovered0"><a name="line308"></a>308 return _reverse + &quot;.ip6.arpa&quot;
909
- </span><span class="uncovered1"><a name="line309"></a>309 end
910
- </span><span class="inferred0"><a name="line310"></a>310
911
- </span><span class="inferred1"><a name="line311"></a>311 # Returns a string for DNS reverse lookup compatible with RFC1886.
912
- </span><span class="marked0"><a name="line312"></a>312 def ip6_int
913
- </span><span class="uncovered1"><a name="line313"></a>313 if !ipv6?
914
- </span><span class="uncovered0"><a name="line314"></a>314 raise ArgumentError, &quot;not an IPv6 address&quot;
915
- </span><span class="uncovered1"><a name="line315"></a>315 end
916
- </span><span class="uncovered0"><a name="line316"></a>316 return _reverse + &quot;.ip6.int&quot;
917
- </span><span class="uncovered1"><a name="line317"></a>317 end
918
- </span><span class="inferred0"><a name="line318"></a>318
919
- </span><span class="inferred1"><a name="line319"></a>319 # Returns a string containing a human-readable representation of the
920
- </span><span class="inferred0"><a name="line320"></a>320 # ipaddr. (&quot;#&lt;IPAddr: family:address/mask&gt;&quot;)
921
- </span><span class="marked1"><a name="line321"></a>321 def inspect
922
- </span><span class="marked0"><a name="line322"></a>322 case @family
923
- </span><span class="marked1"><a name="line323"></a>323 when Socket::AF_INET
924
- </span><span class="marked0"><a name="line324"></a>324 af = &quot;IPv4&quot;
925
- </span><span class="uncovered1"><a name="line325"></a>325 when Socket::AF_INET6
926
- </span><span class="uncovered0"><a name="line326"></a>326 af = &quot;IPv6&quot;
927
- </span><span class="uncovered1"><a name="line327"></a>327 else
928
- </span><span class="uncovered0"><a name="line328"></a>328 raise &quot;unsupported address family&quot;
929
- </span><span class="uncovered1"><a name="line329"></a>329 end
930
- </span><span class="inferred0"><a name="line330"></a>330 return sprintf(&quot;#&lt;%s: %s:%s/%s&gt;&quot;, self.class.name,
931
- </span><span class="marked1"><a name="line331"></a>331 af, _to_string(@addr), _to_string(@mask_addr))
932
- </span><span class="inferred0"><a name="line332"></a>332 end
933
- </span><span class="inferred1"><a name="line333"></a>333
934
- </span><span class="marked0"><a name="line334"></a>334 protected
935
- </span><span class="inferred1"><a name="line335"></a>335
936
- </span><span class="marked0"><a name="line336"></a>336 def set(addr, *family)
937
- </span><span class="uncovered1"><a name="line337"></a>337 case family[0] ? family[0] : @family
938
- </span><span class="uncovered0"><a name="line338"></a>338 when Socket::AF_INET
939
- </span><span class="uncovered1"><a name="line339"></a>339 if addr &lt; 0 || addr &gt; IN4MASK
940
- </span><span class="uncovered0"><a name="line340"></a>340 raise ArgumentError, &quot;invalid address&quot;
941
- </span><span class="uncovered1"><a name="line341"></a>341 end
942
- </span><span class="uncovered0"><a name="line342"></a>342 when Socket::AF_INET6
943
- </span><span class="uncovered1"><a name="line343"></a>343 if addr &lt; 0 || addr &gt; IN6MASK
944
- </span><span class="uncovered0"><a name="line344"></a>344 raise ArgumentError, &quot;invalid address&quot;
945
- </span><span class="uncovered1"><a name="line345"></a>345 end
946
- </span><span class="uncovered0"><a name="line346"></a>346 else
947
- </span><span class="uncovered1"><a name="line347"></a>347 raise ArgumentError, &quot;unsupported address family&quot;
948
- </span><span class="uncovered0"><a name="line348"></a>348 end
949
- </span><span class="uncovered1"><a name="line349"></a>349 @addr = addr
950
- </span><span class="uncovered0"><a name="line350"></a>350 if family[0]
951
- </span><span class="uncovered1"><a name="line351"></a>351 @family = family[0]
952
- </span><span class="uncovered0"><a name="line352"></a>352 end
953
- </span><span class="uncovered1"><a name="line353"></a>353 return self
954
- </span><span class="uncovered0"><a name="line354"></a>354 end
955
- </span><span class="inferred1"><a name="line355"></a>355
956
- </span><span class="marked0"><a name="line356"></a>356 def mask!(mask)
957
- </span><span class="marked1"><a name="line357"></a>357 if mask.kind_of?(String)
958
- </span><span class="marked0"><a name="line358"></a>358 if mask =~ /^\d+$/
959
- </span><span class="marked1"><a name="line359"></a>359 prefixlen = mask.to_i
960
- </span><span class="uncovered0"><a name="line360"></a>360 else
961
- </span><span class="uncovered1"><a name="line361"></a>361 m = IPAddr.new(mask)
962
- </span><span class="uncovered0"><a name="line362"></a>362 if m.family != @family
963
- </span><span class="uncovered1"><a name="line363"></a>363 raise ArgumentError, &quot;address family is not same&quot;
964
- </span><span class="uncovered0"><a name="line364"></a>364 end
965
- </span><span class="uncovered1"><a name="line365"></a>365 @mask_addr = m.to_i
966
- </span><span class="uncovered0"><a name="line366"></a>366 @addr &amp;= @mask_addr
967
- </span><span class="uncovered1"><a name="line367"></a>367 return self
968
- </span><span class="uncovered0"><a name="line368"></a>368 end
969
- </span><span class="uncovered1"><a name="line369"></a>369 else
970
- </span><span class="uncovered0"><a name="line370"></a>370 prefixlen = mask
971
- </span><span class="uncovered1"><a name="line371"></a>371 end
972
- </span><span class="marked0"><a name="line372"></a>372 case @family
973
- </span><span class="marked1"><a name="line373"></a>373 when Socket::AF_INET
974
- </span><span class="marked0"><a name="line374"></a>374 if prefixlen &lt; 0 || prefixlen &gt; 32
975
- </span><span class="uncovered1"><a name="line375"></a>375 raise ArgumentError, &quot;invalid length&quot;
976
- </span><span class="uncovered0"><a name="line376"></a>376 end
977
- </span><span class="marked1"><a name="line377"></a>377 masklen = 32 - prefixlen
978
- </span><span class="marked0"><a name="line378"></a>378 @mask_addr = ((IN4MASK &gt;&gt; masklen) &lt;&lt; masklen)
979
- </span><span class="uncovered1"><a name="line379"></a>379 when Socket::AF_INET6
980
- </span><span class="uncovered0"><a name="line380"></a>380 if prefixlen &lt; 0 || prefixlen &gt; 128
981
- </span><span class="uncovered1"><a name="line381"></a>381 raise ArgumentError, &quot;invalid length&quot;
982
- </span><span class="uncovered0"><a name="line382"></a>382 end
983
- </span><span class="uncovered1"><a name="line383"></a>383 masklen = 128 - prefixlen
984
- </span><span class="uncovered0"><a name="line384"></a>384 @mask_addr = ((IN6MASK &gt;&gt; masklen) &lt;&lt; masklen)
985
- </span><span class="uncovered1"><a name="line385"></a>385 else
986
- </span><span class="uncovered0"><a name="line386"></a>386 raise &quot;unsupported address family&quot;
987
- </span><span class="uncovered1"><a name="line387"></a>387 end
988
- </span><span class="marked0"><a name="line388"></a>388 @addr = ((@addr &gt;&gt; masklen) &lt;&lt; masklen)
989
- </span><span class="marked1"><a name="line389"></a>389 return self
990
- </span><span class="inferred0"><a name="line390"></a>390 end
991
- </span><span class="inferred1"><a name="line391"></a>391
992
- </span><span class="marked0"><a name="line392"></a>392 private
993
- </span><span class="inferred1"><a name="line393"></a>393
994
- </span><span class="inferred0"><a name="line394"></a>394 # Creates a new ipaddr containing the given human readable form of
995
- </span><span class="inferred1"><a name="line395"></a>395 # an IP address. It also accepts `address/prefixlen' and
996
- </span><span class="inferred0"><a name="line396"></a>396 # `address/mask'. When prefixlen or mask is specified, it returns a
997
- </span><span class="inferred1"><a name="line397"></a>397 # masked ipaddr. IPv6 address may beenclosed with `[' and `]'.
998
- </span><span class="inferred0"><a name="line398"></a>398 #
999
- </span><span class="inferred1"><a name="line399"></a>399 # Although an address family is determined automatically from a
1000
- </span><span class="inferred0"><a name="line400"></a>400 # specified address, you can specify an address family explicitly by
1001
- </span><span class="inferred1"><a name="line401"></a>401 # the optional second argument.
1002
- </span><span class="marked0"><a name="line402"></a>402 def initialize(addr = '::', family = Socket::AF_UNSPEC)
1003
- </span><span class="marked1"><a name="line403"></a>403 if !addr.kind_of?(String)
1004
- </span><span class="uncovered0"><a name="line404"></a>404 if family != Socket::AF_INET6 &amp;&amp; family != Socket::AF_INET
1005
- </span><span class="uncovered1"><a name="line405"></a>405 raise ArgumentError, &quot;unsupported address family&quot;
1006
- </span><span class="uncovered0"><a name="line406"></a>406 end
1007
- </span><span class="uncovered1"><a name="line407"></a>407 set(addr, family)
1008
- </span><span class="uncovered0"><a name="line408"></a>408 @mask_addr = (family == Socket::AF_INET) ? IN4MASK : IN6MASK
1009
- </span><span class="uncovered1"><a name="line409"></a>409 return
1010
- </span><span class="uncovered0"><a name="line410"></a>410 end
1011
- </span><span class="marked1"><a name="line411"></a>411 prefix, prefixlen = addr.split('/')
1012
- </span><span class="marked0"><a name="line412"></a>412 if prefix =~ /^\[(.*)\]$/i
1013
- </span><span class="uncovered1"><a name="line413"></a>413 prefix = $1
1014
- </span><span class="uncovered0"><a name="line414"></a>414 family = Socket::AF_INET6
1015
- </span><span class="uncovered1"><a name="line415"></a>415 end
1016
- </span><span class="inferred0"><a name="line416"></a>416 # It seems AI_NUMERICHOST doesn't do the job.
1017
- </span><span class="inferred1"><a name="line417"></a>417 #Socket.getaddrinfo(left, nil, Socket::AF_INET6, Socket::SOCK_STREAM, nil,
1018
- </span><span class="inferred0"><a name="line418"></a>418 # Socket::AI_NUMERICHOST)
1019
- </span><span class="marked1"><a name="line419"></a>419 begin
1020
- </span><span class="marked0"><a name="line420"></a>420 IPSocket.getaddress(prefix) # test if address is vaild
1021
- </span><span class="uncovered1"><a name="line421"></a>421 rescue
1022
- </span><span class="uncovered0"><a name="line422"></a>422 raise ArgumentError, &quot;invalid address&quot;
1023
- </span><span class="uncovered1"><a name="line423"></a>423 end
1024
- </span><span class="marked0"><a name="line424"></a>424 @addr = @family = nil
1025
- </span><span class="marked1"><a name="line425"></a>425 if family == Socket::AF_UNSPEC || family == Socket::AF_INET
1026
- </span><span class="marked0"><a name="line426"></a>426 @addr = in_addr(prefix)
1027
- </span><span class="marked1"><a name="line427"></a>427 if @addr
1028
- </span><span class="marked0"><a name="line428"></a>428 @family = Socket::AF_INET
1029
- </span><span class="inferred1"><a name="line429"></a>429 end
1030
- </span><span class="inferred0"><a name="line430"></a>430 end
1031
- </span><span class="marked1"><a name="line431"></a>431 if !@addr &amp;&amp; (family == Socket::AF_UNSPEC || family == Socket::AF_INET6)
1032
- </span><span class="uncovered0"><a name="line432"></a>432 @addr = in6_addr(prefix)
1033
- </span><span class="uncovered1"><a name="line433"></a>433 @family = Socket::AF_INET6
1034
- </span><span class="uncovered0"><a name="line434"></a>434 end
1035
- </span><span class="marked1"><a name="line435"></a>435 if family != Socket::AF_UNSPEC &amp;&amp; @family != family
1036
- </span><span class="uncovered0"><a name="line436"></a>436 raise ArgumentError, &quot;address family unmatch&quot;
1037
- </span><span class="uncovered1"><a name="line437"></a>437 end
1038
- </span><span class="marked0"><a name="line438"></a>438 if prefixlen
1039
- </span><span class="marked1"><a name="line439"></a>439 mask!(prefixlen)
1040
- </span><span class="inferred0"><a name="line440"></a>440 else
1041
- </span><span class="marked1"><a name="line441"></a>441 @mask_addr = (family == Socket::AF_INET) ? IN4MASK : IN6MASK
1042
- </span><span class="inferred0"><a name="line442"></a>442 end
1043
- </span><span class="inferred1"><a name="line443"></a>443 end
1044
- </span><span class="inferred0"><a name="line444"></a>444
1045
- </span><span class="marked1"><a name="line445"></a>445 def in_addr(addr)
1046
- </span><span class="marked0"><a name="line446"></a>446 if addr =~ /^\d+\.\d+\.\d+\.\d+$/
1047
- </span><span class="marked1"><a name="line447"></a>447 n = 0
1048
- </span><span class="marked0"><a name="line448"></a>448 addr.split('.').each { |i|
1049
- </span><span class="marked1"><a name="line449"></a>449 n &lt;&lt;= 8
1050
- </span><span class="marked0"><a name="line450"></a>450 n += i.to_i
1051
- </span><span class="inferred1"><a name="line451"></a>451 }
1052
- </span><span class="marked0"><a name="line452"></a>452 return n
1053
- </span><span class="inferred1"><a name="line453"></a>453 end
1054
- </span><span class="uncovered0"><a name="line454"></a>454 return nil
1055
- </span><span class="uncovered1"><a name="line455"></a>455 end
1056
- </span><span class="inferred0"><a name="line456"></a>456
1057
- </span><span class="marked1"><a name="line457"></a>457 def in6_addr(left)
1058
- </span><span class="uncovered0"><a name="line458"></a>458 case left
1059
- </span><span class="uncovered1"><a name="line459"></a>459 when /^::ffff:(\d+\.\d+\.\d+\.\d+)$/i
1060
- </span><span class="uncovered0"><a name="line460"></a>460 return in_addr($1) + 0xffff00000000
1061
- </span><span class="uncovered1"><a name="line461"></a>461 when /^::(\d+\.\d+\.\d+\.\d+)$/i
1062
- </span><span class="uncovered0"><a name="line462"></a>462 return in_addr($1)
1063
- </span><span class="uncovered1"><a name="line463"></a>463 when /[^0-9a-f:]/i
1064
- </span><span class="uncovered0"><a name="line464"></a>464 raise ArgumentError, &quot;invalid address&quot;
1065
- </span><span class="uncovered1"><a name="line465"></a>465 when /^(.*)::(.*)$/
1066
- </span><span class="uncovered0"><a name="line466"></a>466 left, right = $1, $2
1067
- </span><span class="uncovered1"><a name="line467"></a>467 else
1068
- </span><span class="uncovered0"><a name="line468"></a>468 right = ''
1069
- </span><span class="uncovered1"><a name="line469"></a>469 end
1070
- </span><span class="uncovered0"><a name="line470"></a>470 l = left.split(':')
1071
- </span><span class="uncovered1"><a name="line471"></a>471 r = right.split(':')
1072
- </span><span class="uncovered0"><a name="line472"></a>472 rest = 8 - l.size - r.size
1073
- </span><span class="uncovered1"><a name="line473"></a>473 if rest &lt; 0
1074
- </span><span class="uncovered0"><a name="line474"></a>474 return nil
1075
- </span><span class="uncovered1"><a name="line475"></a>475 end
1076
- </span><span class="uncovered0"><a name="line476"></a>476 a = [l, Array.new(rest, '0'), r].flatten!
1077
- </span><span class="uncovered1"><a name="line477"></a>477 n = 0
1078
- </span><span class="uncovered0"><a name="line478"></a>478 a.each { |i|
1079
- </span><span class="uncovered1"><a name="line479"></a>479 n &lt;&lt;= 16
1080
- </span><span class="uncovered0"><a name="line480"></a>480 n += i.hex
1081
- </span><span class="uncovered1"><a name="line481"></a>481 }
1082
- </span><span class="uncovered0"><a name="line482"></a>482 return n
1083
- </span><span class="uncovered1"><a name="line483"></a>483 end
1084
- </span><span class="inferred0"><a name="line484"></a>484
1085
- </span><span class="marked1"><a name="line485"></a>485 def addr_mask(addr)
1086
- </span><span class="uncovered0"><a name="line486"></a>486 case @family
1087
- </span><span class="uncovered1"><a name="line487"></a>487 when Socket::AF_INET
1088
- </span><span class="uncovered0"><a name="line488"></a>488 addr &amp;= IN4MASK
1089
- </span><span class="uncovered1"><a name="line489"></a>489 when Socket::AF_INET6
1090
- </span><span class="uncovered0"><a name="line490"></a>490 addr &amp;= IN6MASK
1091
- </span><span class="uncovered1"><a name="line491"></a>491 else
1092
- </span><span class="uncovered0"><a name="line492"></a>492 raise &quot;unsupported address family&quot;
1093
- </span><span class="uncovered1"><a name="line493"></a>493 end
1094
- </span><span class="uncovered0"><a name="line494"></a>494 return addr
1095
- </span><span class="uncovered1"><a name="line495"></a>495 end
1096
- </span><span class="inferred0"><a name="line496"></a>496
1097
- </span><span class="marked1"><a name="line497"></a>497 def _reverse
1098
- </span><span class="uncovered0"><a name="line498"></a>498 case @family
1099
- </span><span class="uncovered1"><a name="line499"></a>499 when Socket::AF_INET
1100
- </span><span class="uncovered0"><a name="line500"></a>500 return (0..3).map { |i|
1101
- </span><span class="uncovered1"><a name="line501"></a>501 (@addr &gt;&gt; (8 * i)) &amp; 0xff
1102
- </span><span class="uncovered0"><a name="line502"></a>502 }.join('.')
1103
- </span><span class="uncovered1"><a name="line503"></a>503 when Socket::AF_INET6
1104
- </span><span class="uncovered0"><a name="line504"></a>504 return (&quot;%.32x&quot; % @addr).reverse!.gsub!(/.(?!$)/, '\&amp;.')
1105
- </span><span class="uncovered1"><a name="line505"></a>505 else
1106
- </span><span class="uncovered0"><a name="line506"></a>506 raise &quot;unsupported address family&quot;
1107
- </span><span class="uncovered1"><a name="line507"></a>507 end
1108
- </span><span class="uncovered0"><a name="line508"></a>508 end
1109
- </span><span class="inferred1"><a name="line509"></a>509
1110
- </span><span class="marked0"><a name="line510"></a>510 def _to_string(addr)
1111
- </span><span class="marked1"><a name="line511"></a>511 case @family
1112
- </span><span class="marked0"><a name="line512"></a>512 when Socket::AF_INET
1113
- </span><span class="marked1"><a name="line513"></a>513 return (0..3).map { |i|
1114
- </span><span class="marked0"><a name="line514"></a>514 (addr &gt;&gt; (24 - 8 * i)) &amp; 0xff
1115
- </span><span class="marked1"><a name="line515"></a>515 }.join('.')
1116
- </span><span class="uncovered0"><a name="line516"></a>516 when Socket::AF_INET6
1117
- </span><span class="uncovered1"><a name="line517"></a>517 return ((&quot;%.32x&quot; % addr).gsub!(/.{4}(?!$)/, '\&amp;:'))
1118
- </span><span class="uncovered0"><a name="line518"></a>518 else
1119
- </span><span class="uncovered1"><a name="line519"></a>519 raise &quot;unsupported address family&quot;
1120
- </span><span class="uncovered0"><a name="line520"></a>520 end
1121
- </span><span class="marked1"><a name="line521"></a>521 end
1122
- </span><span class="inferred0"><a name="line522"></a>522
1123
- </span><span class="inferred1"><a name="line523"></a>523 end
1124
- </span><span class="inferred0"><a name="line524"></a>524
1125
- </span><span class="marked1"><a name="line525"></a>525 if $0 == __FILE__
1126
- </span><span class="uncovered0"><a name="line526"></a>526 eval DATA.read, nil, $0, __LINE__+4
1127
- </span><span class="uncovered1"><a name="line527"></a>527 end
1128
- </span><span class="inferred0"><a name="line528"></a>528
1129
- </span><span class="inferred1"><a name="line529"></a>529 __END__
601
+ <pre><span class="inferred0"><a name="line1"></a> 1 #
602
+ </span><span class="inferred1"><a name="line2"></a> 2 # ipaddr.rb - A class to manipulate an IP address
603
+ </span><span class="inferred0"><a name="line3"></a> 3 #
604
+ </span><span class="inferred1"><a name="line4"></a> 4 # Copyright (c) 2002 Hajimu UMEMOTO &lt;ume@mahoroba.org&gt;.
605
+ </span><span class="inferred0"><a name="line5"></a> 5 # All rights reserved.
606
+ </span><span class="inferred1"><a name="line6"></a> 6 #
607
+ </span><span class="inferred0"><a name="line7"></a> 7 # You can redistribute and/or modify it under the same terms as Ruby.
608
+ </span><span class="inferred1"><a name="line8"></a> 8 #
609
+ </span><span class="inferred0"><a name="line9"></a> 9 # $Id: ipaddr.rb 11708 2007-02-12 23:01:19Z shyouhei $
610
+ </span><span class="inferred1"><a name="line10"></a> 10 #
611
+ </span><span class="inferred0"><a name="line11"></a> 11 # TODO:
612
+ </span><span class="inferred1"><a name="line12"></a> 12 # - scope_id support
613
+ </span><span class="marked0"><a name="line13"></a> 13 require 'socket'
614
+ </span><span class="inferred1"><a name="line14"></a> 14
615
+ </span><span class="marked0"><a name="line15"></a> 15 unless Socket.const_defined? &quot;AF_INET6&quot;
616
+ </span><span class="uncovered1"><a name="line16"></a> 16 class Socket
617
+ </span><span class="uncovered0"><a name="line17"></a> 17 AF_INET6 = Object.new
618
+ </span><span class="uncovered1"><a name="line18"></a> 18 end
619
+ </span><span class="uncovered0"><a name="line19"></a> 19
620
+ </span><span class="uncovered1"><a name="line20"></a> 20 class &lt;&lt; IPSocket
621
+ </span><span class="uncovered0"><a name="line21"></a> 21 def valid_v4?(addr)
622
+ </span><span class="uncovered1"><a name="line22"></a> 22 if /\A(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\Z/ =~ addr
623
+ </span><span class="uncovered0"><a name="line23"></a> 23 return $~.captures.all? {|i| i.to_i &lt; 256}
624
+ </span><span class="uncovered1"><a name="line24"></a> 24 end
625
+ </span><span class="uncovered0"><a name="line25"></a> 25 return false
626
+ </span><span class="uncovered1"><a name="line26"></a> 26 end
627
+ </span><span class="uncovered0"><a name="line27"></a> 27
628
+ </span><span class="uncovered1"><a name="line28"></a> 28 def valid_v6?(addr)
629
+ </span><span class="uncovered0"><a name="line29"></a> 29 # IPv6 (normal)
630
+ </span><span class="uncovered1"><a name="line30"></a> 30 return true if /\A[\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*\Z/ =~ addr
631
+ </span><span class="uncovered0"><a name="line31"></a> 31 return true if /\A[\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*::([\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*)?\Z/ =~ addr
632
+ </span><span class="uncovered1"><a name="line32"></a> 32 return true if /\A::([\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*)?\Z/ =~ addr
633
+ </span><span class="uncovered0"><a name="line33"></a> 33 # IPv6 (IPv4 compat)
634
+ </span><span class="uncovered1"><a name="line34"></a> 34 return true if /\A[\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*:/ =~ addr &amp;&amp; valid_v4?($')
635
+ </span><span class="uncovered0"><a name="line35"></a> 35 return true if /\A[\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*::([\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*:)?/ =~ addr &amp;&amp; valid_v4?($')
636
+ </span><span class="uncovered1"><a name="line36"></a> 36 return true if /\A::([\dA-Fa-f]{1,4}(:[\dA-Fa-f]{1,4})*:)?/ =~ addr &amp;&amp; valid_v4?($')
637
+ </span><span class="uncovered0"><a name="line37"></a> 37
638
+ </span><span class="uncovered1"><a name="line38"></a> 38 false
639
+ </span><span class="uncovered0"><a name="line39"></a> 39 end
640
+ </span><span class="uncovered1"><a name="line40"></a> 40
641
+ </span><span class="uncovered0"><a name="line41"></a> 41 def valid?(addr)
642
+ </span><span class="uncovered1"><a name="line42"></a> 42 valid_v4?(addr) || valid_v6?(addr)
643
+ </span><span class="uncovered0"><a name="line43"></a> 43 end
644
+ </span><span class="uncovered1"><a name="line44"></a> 44
645
+ </span><span class="uncovered0"><a name="line45"></a> 45 alias getaddress_orig getaddress
646
+ </span><span class="uncovered1"><a name="line46"></a> 46 def getaddress(s)
647
+ </span><span class="uncovered0"><a name="line47"></a> 47 if valid?(s)
648
+ </span><span class="uncovered1"><a name="line48"></a> 48 s
649
+ </span><span class="uncovered0"><a name="line49"></a> 49 elsif /\A[-A-Za-z\d.]+\Z/ =~ s
650
+ </span><span class="uncovered1"><a name="line50"></a> 50 getaddress_orig(s)
651
+ </span><span class="uncovered0"><a name="line51"></a> 51 else
652
+ </span><span class="uncovered1"><a name="line52"></a> 52 raise ArgumentError, &quot;invalid address&quot;
653
+ </span><span class="uncovered0"><a name="line53"></a> 53 end
654
+ </span><span class="uncovered1"><a name="line54"></a> 54 end
655
+ </span><span class="uncovered0"><a name="line55"></a> 55 end
656
+ </span><span class="uncovered1"><a name="line56"></a> 56 end
657
+ </span><span class="inferred0"><a name="line57"></a> 57
658
+ </span><span class="inferred1"><a name="line58"></a> 58 # IPAddr provides a set of methods to manipulate an IP address. Both IPv4 and
659
+ </span><span class="inferred0"><a name="line59"></a> 59 # IPv6 are supported.
660
+ </span><span class="inferred1"><a name="line60"></a> 60 #
661
+ </span><span class="inferred0"><a name="line61"></a> 61 # == Example
662
+ </span><span class="inferred1"><a name="line62"></a> 62 #
663
+ </span><span class="inferred0"><a name="line63"></a> 63 # require 'ipaddr'
664
+ </span><span class="inferred1"><a name="line64"></a> 64 #
665
+ </span><span class="inferred0"><a name="line65"></a> 65 # ipaddr1 = IPAddr.new &quot;3ffe:505:2::1&quot;
666
+ </span><span class="inferred1"><a name="line66"></a> 66 #
667
+ </span><span class="inferred0"><a name="line67"></a> 67 # p ipaddr1 #=&gt; #&lt;IPAddr: IPv6:3ffe:0505:0002:0000:0000:0000:0000:0001/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff&gt;
668
+ </span><span class="inferred1"><a name="line68"></a> 68 #
669
+ </span><span class="inferred0"><a name="line69"></a> 69 # p ipaddr1.to_s #=&gt; &quot;3ffe:505:2::1&quot;
670
+ </span><span class="inferred1"><a name="line70"></a> 70 #
671
+ </span><span class="inferred0"><a name="line71"></a> 71 # ipaddr2 = ipaddr1.mask(48) #=&gt; #&lt;IPAddr: IPv6:3ffe:0505:0002:0000:0000:0000:0000:0000/ffff:ffff:ffff:0000:0000:0000:0000:0000&gt;
672
+ </span><span class="inferred1"><a name="line72"></a> 72 #
673
+ </span><span class="inferred0"><a name="line73"></a> 73 # p ipaddr2.to_s #=&gt; &quot;3ffe:505:2::&quot;
674
+ </span><span class="inferred1"><a name="line74"></a> 74 #
675
+ </span><span class="inferred0"><a name="line75"></a> 75 # ipaddr3 = IPAddr.new &quot;192.168.2.0/24&quot;
676
+ </span><span class="inferred1"><a name="line76"></a> 76 #
677
+ </span><span class="inferred0"><a name="line77"></a> 77 # p ipaddr3 #=&gt; #&lt;IPAddr: IPv4:192.168.2.0/255.255.255.0&gt;
678
+ </span><span class="inferred1"><a name="line78"></a> 78
679
+ </span><span class="marked0"><a name="line79"></a> 79 class IPAddr
680
+ </span><span class="inferred1"><a name="line80"></a> 80
681
+ </span><span class="marked0"><a name="line81"></a> 81 IN4MASK = 0xffffffff
682
+ </span><span class="marked1"><a name="line82"></a> 82 IN6MASK = 0xffffffffffffffffffffffffffffffff
683
+ </span><span class="marked0"><a name="line83"></a> 83 IN6FORMAT = ([&quot;%.4x&quot;] * 8).join(':')
684
+ </span><span class="inferred1"><a name="line84"></a> 84
685
+ </span><span class="inferred0"><a name="line85"></a> 85 # Returns the address family of this IP address.
686
+ </span><span class="marked1"><a name="line86"></a> 86 attr :family
687
+ </span><span class="inferred0"><a name="line87"></a> 87
688
+ </span><span class="inferred1"><a name="line88"></a> 88 # Creates a new ipaddr containing the given network byte ordered
689
+ </span><span class="inferred0"><a name="line89"></a> 89 # string form of an IP address.
690
+ </span><span class="marked1"><a name="line90"></a> 90 def IPAddr::new_ntoh(addr)
691
+ </span><span class="uncovered0"><a name="line91"></a> 91 return IPAddr.new(IPAddr::ntop(addr))
692
+ </span><span class="uncovered1"><a name="line92"></a> 92 end
693
+ </span><span class="inferred0"><a name="line93"></a> 93
694
+ </span><span class="inferred1"><a name="line94"></a> 94 # Convert a network byte ordered string form of an IP address into
695
+ </span><span class="inferred0"><a name="line95"></a> 95 # human readable form.
696
+ </span><span class="marked1"><a name="line96"></a> 96 def IPAddr::ntop(addr)
697
+ </span><span class="uncovered0"><a name="line97"></a> 97 case addr.size
698
+ </span><span class="uncovered1"><a name="line98"></a> 98 when 4
699
+ </span><span class="uncovered0"><a name="line99"></a> 99 s = addr.unpack('C4').join('.')
700
+ </span><span class="uncovered1"><a name="line100"></a>100 when 16
701
+ </span><span class="uncovered0"><a name="line101"></a>101 s = IN6FORMAT % addr.unpack('n8')
702
+ </span><span class="uncovered1"><a name="line102"></a>102 else
703
+ </span><span class="uncovered0"><a name="line103"></a>103 raise ArgumentError, &quot;unsupported address family&quot;
704
+ </span><span class="uncovered1"><a name="line104"></a>104 end
705
+ </span><span class="uncovered0"><a name="line105"></a>105 return s
706
+ </span><span class="uncovered1"><a name="line106"></a>106 end
707
+ </span><span class="inferred0"><a name="line107"></a>107
708
+ </span><span class="inferred1"><a name="line108"></a>108 # Returns a new ipaddr built by bitwise AND.
709
+ </span><span class="marked0"><a name="line109"></a>109 def &amp;(other)
710
+ </span><span class="uncovered1"><a name="line110"></a>110 return self.clone.set(@addr &amp; other.to_i)
711
+ </span><span class="uncovered0"><a name="line111"></a>111 end
712
+ </span><span class="inferred1"><a name="line112"></a>112
713
+ </span><span class="inferred0"><a name="line113"></a>113 # Returns a new ipaddr built by bitwise OR.
714
+ </span><span class="marked1"><a name="line114"></a>114 def |(other)
715
+ </span><span class="uncovered0"><a name="line115"></a>115 return self.clone.set(@addr | other.to_i)
716
+ </span><span class="uncovered1"><a name="line116"></a>116 end
717
+ </span><span class="inferred0"><a name="line117"></a>117
718
+ </span><span class="inferred1"><a name="line118"></a>118 # Returns a new ipaddr built by bitwise right-shift.
719
+ </span><span class="marked0"><a name="line119"></a>119 def &gt;&gt;(num)
720
+ </span><span class="uncovered1"><a name="line120"></a>120 return self.clone.set(@addr &gt;&gt; num)
721
+ </span><span class="uncovered0"><a name="line121"></a>121 end
722
+ </span><span class="inferred1"><a name="line122"></a>122
723
+ </span><span class="inferred0"><a name="line123"></a>123 # Returns a new ipaddr built by bitwise left shift.
724
+ </span><span class="marked1"><a name="line124"></a>124 def &lt;&lt;(num)
725
+ </span><span class="uncovered0"><a name="line125"></a>125 return self.clone.set(addr_mask(@addr &lt;&lt; num))
726
+ </span><span class="uncovered1"><a name="line126"></a>126 end
727
+ </span><span class="inferred0"><a name="line127"></a>127
728
+ </span><span class="inferred1"><a name="line128"></a>128 # Returns a new ipaddr built by bitwise negation.
729
+ </span><span class="marked0"><a name="line129"></a>129 def ~
730
+ </span><span class="uncovered1"><a name="line130"></a>130 return self.clone.set(addr_mask(~@addr))
731
+ </span><span class="uncovered0"><a name="line131"></a>131 end
732
+ </span><span class="inferred1"><a name="line132"></a>132
733
+ </span><span class="inferred0"><a name="line133"></a>133 # Returns true if two ipaddr are equal.
734
+ </span><span class="marked1"><a name="line134"></a>134 def ==(other)
735
+ </span><span class="marked0"><a name="line135"></a>135 if other.kind_of?(IPAddr) &amp;&amp; @family != other.family
736
+ </span><span class="uncovered1"><a name="line136"></a>136 return false
737
+ </span><span class="uncovered0"><a name="line137"></a>137 end
738
+ </span><span class="marked1"><a name="line138"></a>138 return (@addr == other.to_i)
739
+ </span><span class="inferred0"><a name="line139"></a>139 end
740
+ </span><span class="inferred1"><a name="line140"></a>140
741
+ </span><span class="inferred0"><a name="line141"></a>141 # Returns a new ipaddr built by masking IP address with the given
742
+ </span><span class="inferred1"><a name="line142"></a>142 # prefixlen/netmask. (e.g. 8, 64, &quot;255.255.255.0&quot;, etc.)
743
+ </span><span class="marked0"><a name="line143"></a>143 def mask(prefixlen)
744
+ </span><span class="uncovered1"><a name="line144"></a>144 return self.clone.mask!(prefixlen)
745
+ </span><span class="uncovered0"><a name="line145"></a>145 end
746
+ </span><span class="inferred1"><a name="line146"></a>146
747
+ </span><span class="inferred0"><a name="line147"></a>147 # Returns true if the given ipaddr is in the range.
748
+ </span><span class="inferred1"><a name="line148"></a>148 #
749
+ </span><span class="inferred0"><a name="line149"></a>149 # e.g.:
750
+ </span><span class="inferred1"><a name="line150"></a>150 # require 'ipaddr'
751
+ </span><span class="inferred0"><a name="line151"></a>151 # net1 = IPAddr.new(&quot;192.168.2.0/24&quot;)
752
+ </span><span class="inferred1"><a name="line152"></a>152 # p net1.include?(IPAddr.new(&quot;192.168.2.0&quot;)) #=&gt; true
753
+ </span><span class="inferred0"><a name="line153"></a>153 # p net1.include?(IPAddr.new(&quot;192.168.2.255&quot;)) #=&gt; true
754
+ </span><span class="inferred1"><a name="line154"></a>154 # p net1.include?(IPAddr.new(&quot;192.168.3.0&quot;)) #=&gt; false
755
+ </span><span class="marked0"><a name="line155"></a>155 def include?(other)
756
+ </span><span class="marked1"><a name="line156"></a>156 if ipv4_mapped?
757
+ </span><span class="uncovered0"><a name="line157"></a>157 if (@mask_addr &gt;&gt; 32) != 0xffffffffffffffffffffffff
758
+ </span><span class="uncovered1"><a name="line158"></a>158 return false
759
+ </span><span class="uncovered0"><a name="line159"></a>159 end
760
+ </span><span class="uncovered1"><a name="line160"></a>160 mask_addr = (@mask_addr &amp; IN4MASK)
761
+ </span><span class="uncovered0"><a name="line161"></a>161 addr = (@addr &amp; IN4MASK)
762
+ </span><span class="uncovered1"><a name="line162"></a>162 family = Socket::AF_INET
763
+ </span><span class="inferred0"><a name="line163"></a>163 else
764
+ </span><span class="marked1"><a name="line164"></a>164 mask_addr = @mask_addr
765
+ </span><span class="marked0"><a name="line165"></a>165 addr = @addr
766
+ </span><span class="marked1"><a name="line166"></a>166 family = @family
767
+ </span><span class="inferred0"><a name="line167"></a>167 end
768
+ </span><span class="marked1"><a name="line168"></a>168 if other.kind_of?(IPAddr)
769
+ </span><span class="marked0"><a name="line169"></a>169 if other.ipv4_mapped?
770
+ </span><span class="uncovered1"><a name="line170"></a>170 other_addr = (other.to_i &amp; IN4MASK)
771
+ </span><span class="uncovered0"><a name="line171"></a>171 other_family = Socket::AF_INET
772
+ </span><span class="inferred1"><a name="line172"></a>172 else
773
+ </span><span class="marked0"><a name="line173"></a>173 other_addr = other.to_i
774
+ </span><span class="marked1"><a name="line174"></a>174 other_family = other.family
775
+ </span><span class="inferred0"><a name="line175"></a>175 end
776
+ </span><span class="uncovered1"><a name="line176"></a>176 else # Not IPAddr - assume integer in same family as us
777
+ </span><span class="uncovered0"><a name="line177"></a>177 other_addr = other.to_i
778
+ </span><span class="uncovered1"><a name="line178"></a>178 other_family = family
779
+ </span><span class="uncovered0"><a name="line179"></a>179 end
780
+ </span><span class="inferred1"><a name="line180"></a>180
781
+ </span><span class="marked0"><a name="line181"></a>181 if family != other_family
782
+ </span><span class="uncovered1"><a name="line182"></a>182 return false
783
+ </span><span class="uncovered0"><a name="line183"></a>183 end
784
+ </span><span class="marked1"><a name="line184"></a>184 return ((addr &amp; mask_addr) == (other_addr &amp; mask_addr))
785
+ </span><span class="inferred0"><a name="line185"></a>185 end
786
+ </span><span class="marked1"><a name="line186"></a>186 alias === include?
787
+ </span><span class="inferred0"><a name="line187"></a>187
788
+ </span><span class="inferred1"><a name="line188"></a>188 # Returns the integer representation of the ipaddr.
789
+ </span><span class="marked0"><a name="line189"></a>189 def to_i
790
+ </span><span class="marked1"><a name="line190"></a>190 return @addr
791
+ </span><span class="marked0"><a name="line191"></a>191 end
792
+ </span><span class="inferred1"><a name="line192"></a>192
793
+ </span><span class="inferred0"><a name="line193"></a>193 # Returns a string containing the IP address representation.
794
+ </span><span class="marked1"><a name="line194"></a>194 def to_s
795
+ </span><span class="uncovered0"><a name="line195"></a>195 str = to_string
796
+ </span><span class="uncovered1"><a name="line196"></a>196 return str if ipv4?
797
+ </span><span class="uncovered0"><a name="line197"></a>197
798
+ </span><span class="uncovered1"><a name="line198"></a>198 str.gsub!(/\b0{1,3}([\da-f]+)\b/i, '\1')
799
+ </span><span class="uncovered0"><a name="line199"></a>199 loop do
800
+ </span><span class="uncovered1"><a name="line200"></a>200 break if str.sub!(/\A0:0:0:0:0:0:0:0\Z/, '::')
801
+ </span><span class="uncovered0"><a name="line201"></a>201 break if str.sub!(/\b0:0:0:0:0:0:0\b/, ':')
802
+ </span><span class="uncovered1"><a name="line202"></a>202 break if str.sub!(/\b0:0:0:0:0:0\b/, ':')
803
+ </span><span class="uncovered0"><a name="line203"></a>203 break if str.sub!(/\b0:0:0:0:0\b/, ':')
804
+ </span><span class="uncovered1"><a name="line204"></a>204 break if str.sub!(/\b0:0:0:0\b/, ':')
805
+ </span><span class="uncovered0"><a name="line205"></a>205 break if str.sub!(/\b0:0:0\b/, ':')
806
+ </span><span class="uncovered1"><a name="line206"></a>206 break if str.sub!(/\b0:0\b/, ':')
807
+ </span><span class="uncovered0"><a name="line207"></a>207 break
808
+ </span><span class="uncovered1"><a name="line208"></a>208 end
809
+ </span><span class="uncovered0"><a name="line209"></a>209 str.sub!(/:{3,}/, '::')
810
+ </span><span class="uncovered1"><a name="line210"></a>210
811
+ </span><span class="uncovered0"><a name="line211"></a>211 if /\A::(ffff:)?([\da-f]{1,4}):([\da-f]{1,4})\Z/i =~ str
812
+ </span><span class="uncovered1"><a name="line212"></a>212 str = sprintf('::%s%d.%d.%d.%d', $1, $2.hex / 256, $2.hex % 256, $3.hex / 256, $3.hex % 256)
813
+ </span><span class="uncovered0"><a name="line213"></a>213 end
814
+ </span><span class="uncovered1"><a name="line214"></a>214
815
+ </span><span class="uncovered0"><a name="line215"></a>215 str
816
+ </span><span class="uncovered1"><a name="line216"></a>216 end
817
+ </span><span class="inferred0"><a name="line217"></a>217
818
+ </span><span class="inferred1"><a name="line218"></a>218 # Returns a string containing the IP address representation in
819
+ </span><span class="inferred0"><a name="line219"></a>219 # canonical form.
820
+ </span><span class="marked1"><a name="line220"></a>220 def to_string
821
+ </span><span class="uncovered0"><a name="line221"></a>221 return _to_string(@addr)
822
+ </span><span class="uncovered1"><a name="line222"></a>222 end
823
+ </span><span class="inferred0"><a name="line223"></a>223
824
+ </span><span class="inferred1"><a name="line224"></a>224 # Returns a network byte ordered string form of the IP address.
825
+ </span><span class="marked0"><a name="line225"></a>225 def hton
826
+ </span><span class="uncovered1"><a name="line226"></a>226 case @family
827
+ </span><span class="uncovered0"><a name="line227"></a>227 when Socket::AF_INET
828
+ </span><span class="uncovered1"><a name="line228"></a>228 return [@addr].pack('N')
829
+ </span><span class="uncovered0"><a name="line229"></a>229 when Socket::AF_INET6
830
+ </span><span class="uncovered1"><a name="line230"></a>230 return (0..7).map { |i|
831
+ </span><span class="uncovered0"><a name="line231"></a>231 (@addr &gt;&gt; (112 - 16 * i)) &amp; 0xffff
832
+ </span><span class="uncovered1"><a name="line232"></a>232 }.pack('n8')
833
+ </span><span class="uncovered0"><a name="line233"></a>233 else
834
+ </span><span class="uncovered1"><a name="line234"></a>234 raise &quot;unsupported address family&quot;
835
+ </span><span class="uncovered0"><a name="line235"></a>235 end
836
+ </span><span class="uncovered1"><a name="line236"></a>236 end
837
+ </span><span class="inferred0"><a name="line237"></a>237
838
+ </span><span class="inferred1"><a name="line238"></a>238 # Returns true if the ipaddr is an IPv4 address.
839
+ </span><span class="marked0"><a name="line239"></a>239 def ipv4?
840
+ </span><span class="uncovered1"><a name="line240"></a>240 return @family == Socket::AF_INET
841
+ </span><span class="uncovered0"><a name="line241"></a>241 end
842
+ </span><span class="inferred1"><a name="line242"></a>242
843
+ </span><span class="inferred0"><a name="line243"></a>243 # Returns true if the ipaddr is an IPv6 address.
844
+ </span><span class="marked1"><a name="line244"></a>244 def ipv6?
845
+ </span><span class="marked0"><a name="line245"></a>245 return @family == Socket::AF_INET6
846
+ </span><span class="marked1"><a name="line246"></a>246 end
847
+ </span><span class="inferred0"><a name="line247"></a>247
848
+ </span><span class="inferred1"><a name="line248"></a>248 # Returns true if the ipaddr is an IPv4-mapped IPv6 address.
849
+ </span><span class="marked0"><a name="line249"></a>249 def ipv4_mapped?
850
+ </span><span class="marked1"><a name="line250"></a>250 return ipv6? &amp;&amp; (@addr &gt;&gt; 32) == 0xffff
851
+ </span><span class="marked0"><a name="line251"></a>251 end
852
+ </span><span class="inferred1"><a name="line252"></a>252
853
+ </span><span class="inferred0"><a name="line253"></a>253 # Returns true if the ipaddr is an IPv4-compatible IPv6 address.
854
+ </span><span class="marked1"><a name="line254"></a>254 def ipv4_compat?
855
+ </span><span class="uncovered0"><a name="line255"></a>255 if !ipv6? || (@addr &gt;&gt; 32) != 0
856
+ </span><span class="uncovered1"><a name="line256"></a>256 return false
857
+ </span><span class="uncovered0"><a name="line257"></a>257 end
858
+ </span><span class="uncovered1"><a name="line258"></a>258 a = (@addr &amp; IN4MASK)
859
+ </span><span class="uncovered0"><a name="line259"></a>259 return a != 0 &amp;&amp; a != 1
860
+ </span><span class="uncovered1"><a name="line260"></a>260 end
861
+ </span><span class="inferred0"><a name="line261"></a>261
862
+ </span><span class="inferred1"><a name="line262"></a>262 # Returns a new ipaddr built by converting the native IPv4 address
863
+ </span><span class="inferred0"><a name="line263"></a>263 # into an IPv4-mapped IPv6 address.
864
+ </span><span class="marked1"><a name="line264"></a>264 def ipv4_mapped
865
+ </span><span class="uncovered0"><a name="line265"></a>265 if !ipv4?
866
+ </span><span class="uncovered1"><a name="line266"></a>266 raise ArgumentError, &quot;not an IPv4 address&quot;
867
+ </span><span class="uncovered0"><a name="line267"></a>267 end
868
+ </span><span class="uncovered1"><a name="line268"></a>268 return self.clone.set(@addr | 0xffff00000000, Socket::AF_INET6)
869
+ </span><span class="uncovered0"><a name="line269"></a>269 end
870
+ </span><span class="inferred1"><a name="line270"></a>270
871
+ </span><span class="inferred0"><a name="line271"></a>271 # Returns a new ipaddr built by converting the native IPv4 address
872
+ </span><span class="inferred1"><a name="line272"></a>272 # into an IPv4-compatible IPv6 address.
873
+ </span><span class="marked0"><a name="line273"></a>273 def ipv4_compat
874
+ </span><span class="uncovered1"><a name="line274"></a>274 if !ipv4?
875
+ </span><span class="uncovered0"><a name="line275"></a>275 raise ArgumentError, &quot;not an IPv4 address&quot;
876
+ </span><span class="uncovered1"><a name="line276"></a>276 end
877
+ </span><span class="uncovered0"><a name="line277"></a>277 return self.clone.set(@addr, Socket::AF_INET6)
878
+ </span><span class="uncovered1"><a name="line278"></a>278 end
879
+ </span><span class="inferred0"><a name="line279"></a>279
880
+ </span><span class="inferred1"><a name="line280"></a>280 # Returns a new ipaddr built by converting the IPv6 address into a
881
+ </span><span class="inferred0"><a name="line281"></a>281 # native IPv4 address. If the IP address is not an IPv4-mapped or
882
+ </span><span class="inferred1"><a name="line282"></a>282 # IPv4-compatible IPv6 address, returns self.
883
+ </span><span class="marked0"><a name="line283"></a>283 def native
884
+ </span><span class="uncovered1"><a name="line284"></a>284 if !ipv4_mapped? &amp;&amp; !ipv4_compat?
885
+ </span><span class="uncovered0"><a name="line285"></a>285 return self
886
+ </span><span class="uncovered1"><a name="line286"></a>286 end
887
+ </span><span class="uncovered0"><a name="line287"></a>287 return self.clone.set(@addr &amp; IN4MASK, Socket::AF_INET)
888
+ </span><span class="uncovered1"><a name="line288"></a>288 end
889
+ </span><span class="inferred0"><a name="line289"></a>289
890
+ </span><span class="inferred1"><a name="line290"></a>290 # Returns a string for DNS reverse lookup. It returns a string in
891
+ </span><span class="inferred0"><a name="line291"></a>291 # RFC3172 form for an IPv6 address.
892
+ </span><span class="marked1"><a name="line292"></a>292 def reverse
893
+ </span><span class="uncovered0"><a name="line293"></a>293 case @family
894
+ </span><span class="uncovered1"><a name="line294"></a>294 when Socket::AF_INET
895
+ </span><span class="uncovered0"><a name="line295"></a>295 return _reverse + &quot;.in-addr.arpa&quot;
896
+ </span><span class="uncovered1"><a name="line296"></a>296 when Socket::AF_INET6
897
+ </span><span class="uncovered0"><a name="line297"></a>297 return ip6_arpa
898
+ </span><span class="uncovered1"><a name="line298"></a>298 else
899
+ </span><span class="uncovered0"><a name="line299"></a>299 raise &quot;unsupported address family&quot;
900
+ </span><span class="uncovered1"><a name="line300"></a>300 end
901
+ </span><span class="uncovered0"><a name="line301"></a>301 end
902
+ </span><span class="inferred1"><a name="line302"></a>302
903
+ </span><span class="inferred0"><a name="line303"></a>303 # Returns a string for DNS reverse lookup compatible with RFC3172.
904
+ </span><span class="marked1"><a name="line304"></a>304 def ip6_arpa
905
+ </span><span class="uncovered0"><a name="line305"></a>305 if !ipv6?
906
+ </span><span class="uncovered1"><a name="line306"></a>306 raise ArgumentError, &quot;not an IPv6 address&quot;
907
+ </span><span class="uncovered0"><a name="line307"></a>307 end
908
+ </span><span class="uncovered1"><a name="line308"></a>308 return _reverse + &quot;.ip6.arpa&quot;
909
+ </span><span class="uncovered0"><a name="line309"></a>309 end
910
+ </span><span class="inferred1"><a name="line310"></a>310
911
+ </span><span class="inferred0"><a name="line311"></a>311 # Returns a string for DNS reverse lookup compatible with RFC1886.
912
+ </span><span class="marked1"><a name="line312"></a>312 def ip6_int
913
+ </span><span class="uncovered0"><a name="line313"></a>313 if !ipv6?
914
+ </span><span class="uncovered1"><a name="line314"></a>314 raise ArgumentError, &quot;not an IPv6 address&quot;
915
+ </span><span class="uncovered0"><a name="line315"></a>315 end
916
+ </span><span class="uncovered1"><a name="line316"></a>316 return _reverse + &quot;.ip6.int&quot;
917
+ </span><span class="uncovered0"><a name="line317"></a>317 end
918
+ </span><span class="inferred1"><a name="line318"></a>318
919
+ </span><span class="inferred0"><a name="line319"></a>319 # Returns a string containing a human-readable representation of the
920
+ </span><span class="inferred1"><a name="line320"></a>320 # ipaddr. (&quot;#&lt;IPAddr: family:address/mask&gt;&quot;)
921
+ </span><span class="marked0"><a name="line321"></a>321 def inspect
922
+ </span><span class="marked1"><a name="line322"></a>322 case @family
923
+ </span><span class="marked0"><a name="line323"></a>323 when Socket::AF_INET
924
+ </span><span class="marked1"><a name="line324"></a>324 af = &quot;IPv4&quot;
925
+ </span><span class="uncovered0"><a name="line325"></a>325 when Socket::AF_INET6
926
+ </span><span class="uncovered1"><a name="line326"></a>326 af = &quot;IPv6&quot;
927
+ </span><span class="uncovered0"><a name="line327"></a>327 else
928
+ </span><span class="uncovered1"><a name="line328"></a>328 raise &quot;unsupported address family&quot;
929
+ </span><span class="uncovered0"><a name="line329"></a>329 end
930
+ </span><span class="inferred1"><a name="line330"></a>330 return sprintf(&quot;#&lt;%s: %s:%s/%s&gt;&quot;, self.class.name,
931
+ </span><span class="marked0"><a name="line331"></a>331 af, _to_string(@addr), _to_string(@mask_addr))
932
+ </span><span class="inferred1"><a name="line332"></a>332 end
933
+ </span><span class="inferred0"><a name="line333"></a>333
934
+ </span><span class="marked1"><a name="line334"></a>334 protected
935
+ </span><span class="inferred0"><a name="line335"></a>335
936
+ </span><span class="marked1"><a name="line336"></a>336 def set(addr, *family)
937
+ </span><span class="uncovered0"><a name="line337"></a>337 case family[0] ? family[0] : @family
938
+ </span><span class="uncovered1"><a name="line338"></a>338 when Socket::AF_INET
939
+ </span><span class="uncovered0"><a name="line339"></a>339 if addr &lt; 0 || addr &gt; IN4MASK
940
+ </span><span class="uncovered1"><a name="line340"></a>340 raise ArgumentError, &quot;invalid address&quot;
941
+ </span><span class="uncovered0"><a name="line341"></a>341 end
942
+ </span><span class="uncovered1"><a name="line342"></a>342 when Socket::AF_INET6
943
+ </span><span class="uncovered0"><a name="line343"></a>343 if addr &lt; 0 || addr &gt; IN6MASK
944
+ </span><span class="uncovered1"><a name="line344"></a>344 raise ArgumentError, &quot;invalid address&quot;
945
+ </span><span class="uncovered0"><a name="line345"></a>345 end
946
+ </span><span class="uncovered1"><a name="line346"></a>346 else
947
+ </span><span class="uncovered0"><a name="line347"></a>347 raise ArgumentError, &quot;unsupported address family&quot;
948
+ </span><span class="uncovered1"><a name="line348"></a>348 end
949
+ </span><span class="uncovered0"><a name="line349"></a>349 @addr = addr
950
+ </span><span class="uncovered1"><a name="line350"></a>350 if family[0]
951
+ </span><span class="uncovered0"><a name="line351"></a>351 @family = family[0]
952
+ </span><span class="uncovered1"><a name="line352"></a>352 end
953
+ </span><span class="uncovered0"><a name="line353"></a>353 return self
954
+ </span><span class="uncovered1"><a name="line354"></a>354 end
955
+ </span><span class="inferred0"><a name="line355"></a>355
956
+ </span><span class="marked1"><a name="line356"></a>356 def mask!(mask)
957
+ </span><span class="marked0"><a name="line357"></a>357 if mask.kind_of?(String)
958
+ </span><span class="marked1"><a name="line358"></a>358 if mask =~ /^\d+$/
959
+ </span><span class="marked0"><a name="line359"></a>359 prefixlen = mask.to_i
960
+ </span><span class="uncovered1"><a name="line360"></a>360 else
961
+ </span><span class="uncovered0"><a name="line361"></a>361 m = IPAddr.new(mask)
962
+ </span><span class="uncovered1"><a name="line362"></a>362 if m.family != @family
963
+ </span><span class="uncovered0"><a name="line363"></a>363 raise ArgumentError, &quot;address family is not same&quot;
964
+ </span><span class="uncovered1"><a name="line364"></a>364 end
965
+ </span><span class="uncovered0"><a name="line365"></a>365 @mask_addr = m.to_i
966
+ </span><span class="uncovered1"><a name="line366"></a>366 @addr &amp;= @mask_addr
967
+ </span><span class="uncovered0"><a name="line367"></a>367 return self
968
+ </span><span class="uncovered1"><a name="line368"></a>368 end
969
+ </span><span class="uncovered0"><a name="line369"></a>369 else
970
+ </span><span class="uncovered1"><a name="line370"></a>370 prefixlen = mask
971
+ </span><span class="uncovered0"><a name="line371"></a>371 end
972
+ </span><span class="marked1"><a name="line372"></a>372 case @family
973
+ </span><span class="marked0"><a name="line373"></a>373 when Socket::AF_INET
974
+ </span><span class="marked1"><a name="line374"></a>374 if prefixlen &lt; 0 || prefixlen &gt; 32
975
+ </span><span class="uncovered0"><a name="line375"></a>375 raise ArgumentError, &quot;invalid length&quot;
976
+ </span><span class="uncovered1"><a name="line376"></a>376 end
977
+ </span><span class="marked0"><a name="line377"></a>377 masklen = 32 - prefixlen
978
+ </span><span class="marked1"><a name="line378"></a>378 @mask_addr = ((IN4MASK &gt;&gt; masklen) &lt;&lt; masklen)
979
+ </span><span class="uncovered0"><a name="line379"></a>379 when Socket::AF_INET6
980
+ </span><span class="uncovered1"><a name="line380"></a>380 if prefixlen &lt; 0 || prefixlen &gt; 128
981
+ </span><span class="uncovered0"><a name="line381"></a>381 raise ArgumentError, &quot;invalid length&quot;
982
+ </span><span class="uncovered1"><a name="line382"></a>382 end
983
+ </span><span class="uncovered0"><a name="line383"></a>383 masklen = 128 - prefixlen
984
+ </span><span class="uncovered1"><a name="line384"></a>384 @mask_addr = ((IN6MASK &gt;&gt; masklen) &lt;&lt; masklen)
985
+ </span><span class="uncovered0"><a name="line385"></a>385 else
986
+ </span><span class="uncovered1"><a name="line386"></a>386 raise &quot;unsupported address family&quot;
987
+ </span><span class="uncovered0"><a name="line387"></a>387 end
988
+ </span><span class="marked1"><a name="line388"></a>388 @addr = ((@addr &gt;&gt; masklen) &lt;&lt; masklen)
989
+ </span><span class="marked0"><a name="line389"></a>389 return self
990
+ </span><span class="inferred1"><a name="line390"></a>390 end
991
+ </span><span class="inferred0"><a name="line391"></a>391
992
+ </span><span class="marked1"><a name="line392"></a>392 private
993
+ </span><span class="inferred0"><a name="line393"></a>393
994
+ </span><span class="inferred1"><a name="line394"></a>394 # Creates a new ipaddr containing the given human readable form of
995
+ </span><span class="inferred0"><a name="line395"></a>395 # an IP address. It also accepts `address/prefixlen' and
996
+ </span><span class="inferred1"><a name="line396"></a>396 # `address/mask'. When prefixlen or mask is specified, it returns a
997
+ </span><span class="inferred0"><a name="line397"></a>397 # masked ipaddr. IPv6 address may beenclosed with `[' and `]'.
998
+ </span><span class="inferred1"><a name="line398"></a>398 #
999
+ </span><span class="inferred0"><a name="line399"></a>399 # Although an address family is determined automatically from a
1000
+ </span><span class="inferred1"><a name="line400"></a>400 # specified address, you can specify an address family explicitly by
1001
+ </span><span class="inferred0"><a name="line401"></a>401 # the optional second argument.
1002
+ </span><span class="marked1"><a name="line402"></a>402 def initialize(addr = '::', family = Socket::AF_UNSPEC)
1003
+ </span><span class="marked0"><a name="line403"></a>403 if !addr.kind_of?(String)
1004
+ </span><span class="uncovered1"><a name="line404"></a>404 if family != Socket::AF_INET6 &amp;&amp; family != Socket::AF_INET
1005
+ </span><span class="uncovered0"><a name="line405"></a>405 raise ArgumentError, &quot;unsupported address family&quot;
1006
+ </span><span class="uncovered1"><a name="line406"></a>406 end
1007
+ </span><span class="uncovered0"><a name="line407"></a>407 set(addr, family)
1008
+ </span><span class="uncovered1"><a name="line408"></a>408 @mask_addr = (family == Socket::AF_INET) ? IN4MASK : IN6MASK
1009
+ </span><span class="uncovered0"><a name="line409"></a>409 return
1010
+ </span><span class="uncovered1"><a name="line410"></a>410 end
1011
+ </span><span class="marked0"><a name="line411"></a>411 prefix, prefixlen = addr.split('/')
1012
+ </span><span class="marked1"><a name="line412"></a>412 if prefix =~ /^\[(.*)\]$/i
1013
+ </span><span class="uncovered0"><a name="line413"></a>413 prefix = $1
1014
+ </span><span class="uncovered1"><a name="line414"></a>414 family = Socket::AF_INET6
1015
+ </span><span class="uncovered0"><a name="line415"></a>415 end
1016
+ </span><span class="inferred1"><a name="line416"></a>416 # It seems AI_NUMERICHOST doesn't do the job.
1017
+ </span><span class="inferred0"><a name="line417"></a>417 #Socket.getaddrinfo(left, nil, Socket::AF_INET6, Socket::SOCK_STREAM, nil,
1018
+ </span><span class="inferred1"><a name="line418"></a>418 # Socket::AI_NUMERICHOST)
1019
+ </span><span class="marked0"><a name="line419"></a>419 begin
1020
+ </span><span class="marked1"><a name="line420"></a>420 IPSocket.getaddress(prefix) # test if address is vaild
1021
+ </span><span class="uncovered0"><a name="line421"></a>421 rescue
1022
+ </span><span class="uncovered1"><a name="line422"></a>422 raise ArgumentError, &quot;invalid address&quot;
1023
+ </span><span class="uncovered0"><a name="line423"></a>423 end
1024
+ </span><span class="marked1"><a name="line424"></a>424 @addr = @family = nil
1025
+ </span><span class="marked0"><a name="line425"></a>425 if family == Socket::AF_UNSPEC || family == Socket::AF_INET
1026
+ </span><span class="marked1"><a name="line426"></a>426 @addr = in_addr(prefix)
1027
+ </span><span class="marked0"><a name="line427"></a>427 if @addr
1028
+ </span><span class="marked1"><a name="line428"></a>428 @family = Socket::AF_INET
1029
+ </span><span class="inferred0"><a name="line429"></a>429 end
1030
+ </span><span class="inferred1"><a name="line430"></a>430 end
1031
+ </span><span class="marked0"><a name="line431"></a>431 if !@addr &amp;&amp; (family == Socket::AF_UNSPEC || family == Socket::AF_INET6)
1032
+ </span><span class="uncovered1"><a name="line432"></a>432 @addr = in6_addr(prefix)
1033
+ </span><span class="uncovered0"><a name="line433"></a>433 @family = Socket::AF_INET6
1034
+ </span><span class="uncovered1"><a name="line434"></a>434 end
1035
+ </span><span class="marked0"><a name="line435"></a>435 if family != Socket::AF_UNSPEC &amp;&amp; @family != family
1036
+ </span><span class="uncovered1"><a name="line436"></a>436 raise ArgumentError, &quot;address family unmatch&quot;
1037
+ </span><span class="uncovered0"><a name="line437"></a>437 end
1038
+ </span><span class="marked1"><a name="line438"></a>438 if prefixlen
1039
+ </span><span class="marked0"><a name="line439"></a>439 mask!(prefixlen)
1040
+ </span><span class="inferred1"><a name="line440"></a>440 else
1041
+ </span><span class="marked0"><a name="line441"></a>441 @mask_addr = (family == Socket::AF_INET) ? IN4MASK : IN6MASK
1042
+ </span><span class="inferred1"><a name="line442"></a>442 end
1043
+ </span><span class="inferred0"><a name="line443"></a>443 end
1044
+ </span><span class="inferred1"><a name="line444"></a>444
1045
+ </span><span class="marked0"><a name="line445"></a>445 def in_addr(addr)
1046
+ </span><span class="marked1"><a name="line446"></a>446 if addr =~ /^\d+\.\d+\.\d+\.\d+$/
1047
+ </span><span class="marked0"><a name="line447"></a>447 n = 0
1048
+ </span><span class="marked1"><a name="line448"></a>448 addr.split('.').each { |i|
1049
+ </span><span class="marked0"><a name="line449"></a>449 n &lt;&lt;= 8
1050
+ </span><span class="marked1"><a name="line450"></a>450 n += i.to_i
1051
+ </span><span class="inferred0"><a name="line451"></a>451 }
1052
+ </span><span class="marked1"><a name="line452"></a>452 return n
1053
+ </span><span class="inferred0"><a name="line453"></a>453 end
1054
+ </span><span class="uncovered1"><a name="line454"></a>454 return nil
1055
+ </span><span class="uncovered0"><a name="line455"></a>455 end
1056
+ </span><span class="inferred1"><a name="line456"></a>456
1057
+ </span><span class="marked0"><a name="line457"></a>457 def in6_addr(left)
1058
+ </span><span class="uncovered1"><a name="line458"></a>458 case left
1059
+ </span><span class="uncovered0"><a name="line459"></a>459 when /^::ffff:(\d+\.\d+\.\d+\.\d+)$/i
1060
+ </span><span class="uncovered1"><a name="line460"></a>460 return in_addr($1) + 0xffff00000000
1061
+ </span><span class="uncovered0"><a name="line461"></a>461 when /^::(\d+\.\d+\.\d+\.\d+)$/i
1062
+ </span><span class="uncovered1"><a name="line462"></a>462 return in_addr($1)
1063
+ </span><span class="uncovered0"><a name="line463"></a>463 when /[^0-9a-f:]/i
1064
+ </span><span class="uncovered1"><a name="line464"></a>464 raise ArgumentError, &quot;invalid address&quot;
1065
+ </span><span class="uncovered0"><a name="line465"></a>465 when /^(.*)::(.*)$/
1066
+ </span><span class="uncovered1"><a name="line466"></a>466 left, right = $1, $2
1067
+ </span><span class="uncovered0"><a name="line467"></a>467 else
1068
+ </span><span class="uncovered1"><a name="line468"></a>468 right = ''
1069
+ </span><span class="uncovered0"><a name="line469"></a>469 end
1070
+ </span><span class="uncovered1"><a name="line470"></a>470 l = left.split(':')
1071
+ </span><span class="uncovered0"><a name="line471"></a>471 r = right.split(':')
1072
+ </span><span class="uncovered1"><a name="line472"></a>472 rest = 8 - l.size - r.size
1073
+ </span><span class="uncovered0"><a name="line473"></a>473 if rest &lt; 0
1074
+ </span><span class="uncovered1"><a name="line474"></a>474 return nil
1075
+ </span><span class="uncovered0"><a name="line475"></a>475 end
1076
+ </span><span class="uncovered1"><a name="line476"></a>476 a = [l, Array.new(rest, '0'), r].flatten!
1077
+ </span><span class="uncovered0"><a name="line477"></a>477 n = 0
1078
+ </span><span class="uncovered1"><a name="line478"></a>478 a.each { |i|
1079
+ </span><span class="uncovered0"><a name="line479"></a>479 n &lt;&lt;= 16
1080
+ </span><span class="uncovered1"><a name="line480"></a>480 n += i.hex
1081
+ </span><span class="uncovered0"><a name="line481"></a>481 }
1082
+ </span><span class="uncovered1"><a name="line482"></a>482 return n
1083
+ </span><span class="uncovered0"><a name="line483"></a>483 end
1084
+ </span><span class="inferred1"><a name="line484"></a>484
1085
+ </span><span class="marked0"><a name="line485"></a>485 def addr_mask(addr)
1086
+ </span><span class="uncovered1"><a name="line486"></a>486 case @family
1087
+ </span><span class="uncovered0"><a name="line487"></a>487 when Socket::AF_INET
1088
+ </span><span class="uncovered1"><a name="line488"></a>488 addr &amp;= IN4MASK
1089
+ </span><span class="uncovered0"><a name="line489"></a>489 when Socket::AF_INET6
1090
+ </span><span class="uncovered1"><a name="line490"></a>490 addr &amp;= IN6MASK
1091
+ </span><span class="uncovered0"><a name="line491"></a>491 else
1092
+ </span><span class="uncovered1"><a name="line492"></a>492 raise &quot;unsupported address family&quot;
1093
+ </span><span class="uncovered0"><a name="line493"></a>493 end
1094
+ </span><span class="uncovered1"><a name="line494"></a>494 return addr
1095
+ </span><span class="uncovered0"><a name="line495"></a>495 end
1096
+ </span><span class="inferred1"><a name="line496"></a>496
1097
+ </span><span class="marked0"><a name="line497"></a>497 def _reverse
1098
+ </span><span class="uncovered1"><a name="line498"></a>498 case @family
1099
+ </span><span class="uncovered0"><a name="line499"></a>499 when Socket::AF_INET
1100
+ </span><span class="uncovered1"><a name="line500"></a>500 return (0..3).map { |i|
1101
+ </span><span class="uncovered0"><a name="line501"></a>501 (@addr &gt;&gt; (8 * i)) &amp; 0xff
1102
+ </span><span class="uncovered1"><a name="line502"></a>502 }.join('.')
1103
+ </span><span class="uncovered0"><a name="line503"></a>503 when Socket::AF_INET6
1104
+ </span><span class="uncovered1"><a name="line504"></a>504 return (&quot;%.32x&quot; % @addr).reverse!.gsub!(/.(?!$)/, '\&amp;.')
1105
+ </span><span class="uncovered0"><a name="line505"></a>505 else
1106
+ </span><span class="uncovered1"><a name="line506"></a>506 raise &quot;unsupported address family&quot;
1107
+ </span><span class="uncovered0"><a name="line507"></a>507 end
1108
+ </span><span class="uncovered1"><a name="line508"></a>508 end
1109
+ </span><span class="inferred0"><a name="line509"></a>509
1110
+ </span><span class="marked1"><a name="line510"></a>510 def _to_string(addr)
1111
+ </span><span class="marked0"><a name="line511"></a>511 case @family
1112
+ </span><span class="marked1"><a name="line512"></a>512 when Socket::AF_INET
1113
+ </span><span class="marked0"><a name="line513"></a>513 return (0..3).map { |i|
1114
+ </span><span class="marked1"><a name="line514"></a>514 (addr &gt;&gt; (24 - 8 * i)) &amp; 0xff
1115
+ </span><span class="marked0"><a name="line515"></a>515 }.join('.')
1116
+ </span><span class="uncovered1"><a name="line516"></a>516 when Socket::AF_INET6
1117
+ </span><span class="uncovered0"><a name="line517"></a>517 return ((&quot;%.32x&quot; % addr).gsub!(/.{4}(?!$)/, '\&amp;:'))
1118
+ </span><span class="uncovered1"><a name="line518"></a>518 else
1119
+ </span><span class="uncovered0"><a name="line519"></a>519 raise &quot;unsupported address family&quot;
1120
+ </span><span class="uncovered1"><a name="line520"></a>520 end
1121
+ </span><span class="marked0"><a name="line521"></a>521 end
1122
+ </span><span class="inferred1"><a name="line522"></a>522
1123
+ </span><span class="inferred0"><a name="line523"></a>523 end
1124
+ </span><span class="inferred1"><a name="line524"></a>524
1125
+ </span><span class="marked0"><a name="line525"></a>525 if $0 == __FILE__
1126
+ </span><span class="uncovered1"><a name="line526"></a>526 eval DATA.read, nil, $0, __LINE__+4
1127
+ </span><span class="uncovered0"><a name="line527"></a>527 end
1128
+ </span><span class="inferred1"><a name="line528"></a>528
1129
+ </span><span class="inferred0"><a name="line529"></a>529 __END__
1130
1130
  </span></pre><hr/>
1131
1131
  <p>Generated using the <a href='http://eigenclass.org/hiki.rb?rcov'>rcov code coverage analysis tool for Ruby</a>
1132
1132
  version 0.8.1.2.</p>