| 2101 | // test whether the subnet matches the netmaskLength (according to postgres rules) |
| 2102 | // throws NumericException if sequence is not a valid subnet OR the subnet doesn't match the netmaskLength |
| 2103 | public static int parseSubnet0(CharSequence sequence, final int p, int lim, int netmaskLength) throws NumericException { |
| 2104 | int hi; |
| 2105 | int lo = p; |
| 2106 | int num; |
| 2107 | int ipv4 = 0; |
| 2108 | int count = 0; |
| 2109 | int checker = 0xffffffff; |
| 2110 | int bits = 32 - netmaskLength; |
| 2111 | int i = 1; |
| 2112 | |
| 2113 | if (lim == 0) { |
| 2114 | throw NumericException.instance().put("empty IPv4 subnet string"); |
| 2115 | } |
| 2116 | |
| 2117 | final char sign = sequence.charAt(0); |
| 2118 | |
| 2119 | if (notDigit(sign)) { |
| 2120 | throw NumericException.instance().put("invalid IPv4 subnet format: ").put(sequence); |
| 2121 | } |
| 2122 | |
| 2123 | while ((hi = Chars.indexOf(sequence, lo, '.')) > -1) { |
| 2124 | num = parseInt(sequence, lo, hi); |
| 2125 | |
| 2126 | if (num > 255) { |
| 2127 | throw NumericException.instance().put("IPv4 octet out of range [0-255]: ").put(num); |
| 2128 | } |
| 2129 | // each byte goes to left-most pos in int - accounts for issues that arise from parsing variable length subnets |
| 2130 | ipv4 = ipv4 | (num << ((4 - i) * 8)); |
| 2131 | count++; |
| 2132 | i++; |
| 2133 | lo = hi + 1; |
| 2134 | } |
| 2135 | |
| 2136 | if (count > 3) { |
| 2137 | throw NumericException.instance().put("too many octets in IPv4 subnet: ").put(sequence); |
| 2138 | } |
| 2139 | |
| 2140 | num = parseInt(sequence, lo, lim); |
| 2141 | |
| 2142 | if (num > 255) { |
| 2143 | throw NumericException.instance().put("IPv4 octet out of range [0-255]: ").put(num); |
| 2144 | } |
| 2145 | |
| 2146 | //if netmaskLength is full byte longer than subnet |
| 2147 | if (count == 0) { |
| 2148 | if (netmaskLength >= 16) { |
| 2149 | throw NumericException.instance().put("netmask length too long for single octet subnet: ").put(netmaskLength); |
| 2150 | } |
| 2151 | checker = (checker << bits); |
| 2152 | num = (num << 24) & checker; |
| 2153 | return num; |
| 2154 | } |
| 2155 | //if netmaskLength is a full byte longer than subnet |
| 2156 | else if (count == 1 && netmaskLength >= 24) { |
| 2157 | throw NumericException.instance().put("netmask length too long for two octet subnet: ").put(netmaskLength); |
| 2158 | } |
| 2159 | //if netmaskLength is a full byte longer than subnet |
| 2160 | else if (count == 2 && netmaskLength >= 32) { |