blob: 05ce0a4e77a5a8a47d74c557932addb13d63672f [file] [log] [blame]
HIGUCHI Yutaea60e5f2013-06-12 11:10:21 -07001package net.onrc.onos.ofcontroller.bgproute;
pingping-lina2cbfad2013-03-07 08:39:21 +08002
3import java.net.InetAddress;
4import java.net.UnknownHostException;
Jonathan Hart32e18222013-08-07 22:05:42 +12005import java.util.Arrays;
pingping-lina2cbfad2013-03-07 08:39:21 +08006
Jonathan Hartabf10222013-08-13 10:19:34 +12007import com.google.common.net.InetAddresses;
8
pingping-lina2cbfad2013-03-07 08:39:21 +08009public class Prefix {
Jonathan Hart32e18222013-08-07 22:05:42 +120010 private final int MAX_BYTES = 4;
11
12 private final int prefixLength;
13 private final byte[] address;
14
15 //For verifying the arguments and pretty printing
16 private final InetAddress inetAddress;
17
18 public Prefix(byte[] addr, int prefixLength) {
19 if (addr == null || addr.length != MAX_BYTES ||
20 prefixLength < 0 || prefixLength > MAX_BYTES * Byte.SIZE) {
21 throw new IllegalArgumentException();
22 }
pingping-lina2cbfad2013-03-07 08:39:21 +080023
Jonathan Hart32e18222013-08-07 22:05:42 +120024 address = canonicalizeAddress(addr, prefixLength);
Jonathan Hartd1b9d872013-07-23 12:17:21 +120025 this.prefixLength = prefixLength;
Jonathan Hart32e18222013-08-07 22:05:42 +120026
27 try {
28 inetAddress = InetAddress.getByAddress(address);
29 } catch (UnknownHostException e) {
30 throw new IllegalArgumentException();
31 }
pingping-lina2cbfad2013-03-07 08:39:21 +080032 }
Jonathan Hart61ba9372013-05-19 20:10:29 -070033
Jonathan Hart32e18222013-08-07 22:05:42 +120034 public Prefix(String strAddress, int prefixLength) {
35 byte[] addr = null;
Jonathan Hartabf10222013-08-13 10:19:34 +120036 addr = InetAddresses.forString(strAddress).getAddress();
Jonathan Hart32e18222013-08-07 22:05:42 +120037
38 if (addr == null || addr.length != MAX_BYTES ||
39 prefixLength < 0 || prefixLength > MAX_BYTES * Byte.SIZE) {
40 throw new IllegalArgumentException();
41 }
42
43 address = canonicalizeAddress(addr, prefixLength);
Jonathan Hartd1b9d872013-07-23 12:17:21 +120044 this.prefixLength = prefixLength;
Jonathan Hart32e18222013-08-07 22:05:42 +120045
46 try {
47 inetAddress = InetAddress.getByAddress(address);
48 } catch (UnknownHostException e) {
49 throw new IllegalArgumentException();
50 }
51 }
52
53 private byte[] canonicalizeAddress(byte[] address, int prefixLength) {
54 byte[] result = new byte[address.length];
55
56 if (prefixLength == 0) {
57 for (int i = 0; i < MAX_BYTES; i++) {
58 result[i] = 0;
59 }
60
61 return result;
62 }
63
64 result = Arrays.copyOf(address, address.length);
65
66 //Set all bytes after the end of the prefix to 0
67 int lastByteIndex = (prefixLength - 1) / Byte.SIZE;
68 for (int i = lastByteIndex; i < MAX_BYTES; i++) {
69 result[i] = 0;
70 }
71
72 byte lastByte = address[lastByteIndex];
73 byte mask = 0;
Jonathan Hart9ea31212013-08-12 21:40:34 +120074 byte msb = (byte) 0x80;
Jonathan Hart32e18222013-08-07 22:05:42 +120075 int lastBit = (prefixLength - 1) % Byte.SIZE;
76 for (int i = 0; i < Byte.SIZE; i++) {
Jonathan Hart9ea31212013-08-12 21:40:34 +120077 if (i <= lastBit) {
78 mask |= (msb >> i);
Jonathan Hart32e18222013-08-07 22:05:42 +120079 }
Jonathan Hart32e18222013-08-07 22:05:42 +120080 }
81
82 result[lastByteIndex] = (byte) (lastByte & mask);
83
84 return result;
pingping-lina2cbfad2013-03-07 08:39:21 +080085 }
Jonathan Hart61ba9372013-05-19 20:10:29 -070086
Jonathan Hartd1b9d872013-07-23 12:17:21 +120087 public int getPrefixLength() {
88 return prefixLength;
89 }
90
91 public byte[] getAddress() {
Jonathan Hart32e18222013-08-07 22:05:42 +120092 return address;
pingping-lina2cbfad2013-03-07 08:39:21 +080093 }
Jonathan Hartd1b9d872013-07-23 12:17:21 +120094
95 @Override
Jonathan Hart0ee0f022013-08-03 22:21:54 +120096 public boolean equals(Object other) {
97 if (other == null || !(other instanceof Prefix)) {
98 return false;
99 }
100
101 Prefix otherPrefix = (Prefix) other;
102
Jonathan Hart32e18222013-08-07 22:05:42 +1200103 return (Arrays.equals(address, otherPrefix.address)) &&
Jonathan Hart0ee0f022013-08-03 22:21:54 +1200104 (prefixLength == otherPrefix.prefixLength);
105 }
106
107 @Override
108 public int hashCode() {
109 int hash = 17;
110 hash = 31 * hash + prefixLength;
Jonathan Hart32e18222013-08-07 22:05:42 +1200111 hash = 31 * hash + Arrays.hashCode(address);
Jonathan Hart0ee0f022013-08-03 22:21:54 +1200112 return hash;
113 }
114
115 @Override
Jonathan Hartd1b9d872013-07-23 12:17:21 +1200116 public String toString() {
Jonathan Hart32e18222013-08-07 22:05:42 +1200117 return inetAddress.getHostAddress() + "/" + prefixLength;
118 }
119
120 public String printAsBits() {
121 String result = "";
122 for (int i = 0; i < address.length; i++) {
123 byte b = address[i];
124 for (int j = 0; j < Byte.SIZE; j++) {
125 byte mask = (byte) (0x80 >>> j);
126 result += ((b & mask) == 0)? "0" : "1";
127 if (i*Byte.SIZE+j == prefixLength-1) {
128 return result;
129 }
130 }
131 result += " ";
132 }
133 return result.substring(0, result.length() - 1);
Jonathan Hartd1b9d872013-07-23 12:17:21 +1200134 }
pingping-lina2cbfad2013-03-07 08:39:21 +0800135}