1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.jboss.netty.handler.ipfilter;
17
18 import java.math.BigInteger;
19 import java.net.Inet4Address;
20 import java.net.Inet6Address;
21 import java.net.InetAddress;
22 import java.net.UnknownHostException;
23
24 import org.jboss.netty.logging.InternalLogger;
25 import org.jboss.netty.logging.InternalLoggerFactory;
26
27
28
29 public class CIDR6 extends CIDR {
30
31 private static final InternalLogger logger = InternalLoggerFactory.getInstance(CIDR6.class);
32
33
34 private BigInteger addressBigInt;
35
36
37 private final BigInteger addressEndBigInt;
38
39
40
41
42
43 protected CIDR6(Inet6Address newaddress, int newmask) {
44 cidrMask = newmask;
45 addressBigInt = ipv6AddressToBigInteger(newaddress);
46 BigInteger mask = ipv6CidrMaskToMask(newmask);
47 try {
48 addressBigInt = addressBigInt.and(mask);
49 baseAddress = bigIntToIPv6Address(addressBigInt);
50 } catch (UnknownHostException e) {
51
52 }
53 addressEndBigInt = addressBigInt.add(ipv6CidrMaskToBaseAddress(cidrMask)).subtract(BigInteger.ONE);
54 }
55
56 @Override
57 public InetAddress getEndAddress() {
58 try {
59 return bigIntToIPv6Address(addressEndBigInt);
60 } catch (UnknownHostException e) {
61 if (logger.isErrorEnabled()) {
62 logger.error("invalid ip address calculated as an end address");
63 }
64 return null;
65 }
66 }
67
68
69 public int compareTo(CIDR arg) {
70 if (arg instanceof CIDR4) {
71 BigInteger net = ipv6AddressToBigInteger(arg.baseAddress);
72 int res = net.compareTo(addressBigInt);
73 if (res == 0) {
74 if (arg.cidrMask == cidrMask) {
75 return 0;
76 } else if (arg.cidrMask < cidrMask) {
77 return -1;
78 }
79 return 1;
80 }
81 return res;
82 }
83 CIDR6 o = (CIDR6) arg;
84 if (o.addressBigInt.equals(addressBigInt) && o.cidrMask == cidrMask) {
85 return 0;
86 }
87 int res = o.addressBigInt.compareTo(addressBigInt);
88 if (res == 0) {
89 if (o.cidrMask < cidrMask) {
90
91 return -1;
92 }
93 return 1;
94 }
95 return res;
96 }
97
98 @Override
99 public boolean contains(InetAddress inetAddress) {
100 BigInteger search = ipv6AddressToBigInteger(inetAddress);
101 return search.compareTo(addressBigInt) >= 0 && search.compareTo(addressEndBigInt) <= 0;
102 }
103
104
105
106
107
108 private static BigInteger ipv6CidrMaskToBaseAddress(int cidrMask) {
109 return BigInteger.ONE.shiftLeft(128 - cidrMask);
110 }
111
112 private static BigInteger ipv6CidrMaskToMask(int cidrMask) {
113 return BigInteger.ONE.shiftLeft(128 - cidrMask).subtract(BigInteger.ONE).not();
114 }
115
116
117
118
119
120
121
122
123 private static BigInteger ipv6AddressToBigInteger(InetAddress addr) {
124 byte[] ipv6;
125 if (addr instanceof Inet4Address) {
126 ipv6 = getIpV6FromIpV4((Inet4Address) addr);
127 } else {
128 ipv6 = addr.getAddress();
129 }
130 if (ipv6[0] == -1) {
131 return new BigInteger(1, ipv6);
132 }
133 return new BigInteger(ipv6);
134 }
135
136
137
138
139
140
141
142
143 private static InetAddress bigIntToIPv6Address(BigInteger addr) throws UnknownHostException {
144 byte[] a = new byte[16];
145 byte[] b = addr.toByteArray();
146 if (b.length > 16 && !(b.length == 17 && b[0] == 0)) {
147 throw new UnknownHostException("invalid IPv6 address (too big)");
148 }
149 if (b.length == 16) {
150 return InetAddress.getByAddress(b);
151 }
152
153 if (b.length == 17) {
154 System.arraycopy(b, 1, a, 0, 16);
155 } else {
156
157 int p = 16 - b.length;
158 System.arraycopy(b, 0, a, p + 0, b.length);
159 }
160 return InetAddress.getByAddress(a);
161 }
162 }