blob: 21dd45c8a68727917ea7e7121c492123174695fd [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
7public class Prefix {
Jonathan Hart32e18222013-08-07 22:05:42 +12008 private final int MAX_BYTES = 4;
9
10 private final int prefixLength;
11 private final byte[] address;
12
13 //For verifying the arguments and pretty printing
14 private final InetAddress inetAddress;
15
16 public Prefix(byte[] addr, int prefixLength) {
17 if (addr == null || addr.length != MAX_BYTES ||
18 prefixLength < 0 || prefixLength > MAX_BYTES * Byte.SIZE) {
19 throw new IllegalArgumentException();
20 }
pingping-lina2cbfad2013-03-07 08:39:21 +080021
Jonathan Hart32e18222013-08-07 22:05:42 +120022 address = canonicalizeAddress(addr, prefixLength);
Jonathan Hartd1b9d872013-07-23 12:17:21 +120023 this.prefixLength = prefixLength;
Jonathan Hart32e18222013-08-07 22:05:42 +120024
25 try {
26 inetAddress = InetAddress.getByAddress(address);
27 } catch (UnknownHostException e) {
28 throw new IllegalArgumentException();
29 }
pingping-lina2cbfad2013-03-07 08:39:21 +080030 }
Jonathan Hart61ba9372013-05-19 20:10:29 -070031
Jonathan Hart32e18222013-08-07 22:05:42 +120032 public Prefix(String strAddress, int prefixLength) {
33 byte[] addr = null;
34 try {
35 addr = InetAddress.getByName(strAddress).getAddress();
36 } catch (UnknownHostException e) {
37 throw new IllegalArgumentException("Invalid IP inetAddress argument");
38 }
39
40 if (addr == null || addr.length != MAX_BYTES ||
41 prefixLength < 0 || prefixLength > MAX_BYTES * Byte.SIZE) {
42 throw new IllegalArgumentException();
43 }
44
45 address = canonicalizeAddress(addr, prefixLength);
Jonathan Hartd1b9d872013-07-23 12:17:21 +120046 this.prefixLength = prefixLength;
Jonathan Hart32e18222013-08-07 22:05:42 +120047
48 try {
49 inetAddress = InetAddress.getByAddress(address);
50 } catch (UnknownHostException e) {
51 throw new IllegalArgumentException();
52 }
53 }
54
55 private byte[] canonicalizeAddress(byte[] address, int prefixLength) {
56 byte[] result = new byte[address.length];
57
58 if (prefixLength == 0) {
59 for (int i = 0; i < MAX_BYTES; i++) {
60 result[i] = 0;
61 }
62
63 return result;
64 }
65
66 result = Arrays.copyOf(address, address.length);
67
68 //Set all bytes after the end of the prefix to 0
69 int lastByteIndex = (prefixLength - 1) / Byte.SIZE;
70 for (int i = lastByteIndex; i < MAX_BYTES; i++) {
71 result[i] = 0;
72 }
73
74 byte lastByte = address[lastByteIndex];
75 byte mask = 0;
Jonathan Hart9ea31212013-08-12 21:40:34 +120076 byte msb = (byte) 0x80;
Jonathan Hart32e18222013-08-07 22:05:42 +120077 int lastBit = (prefixLength - 1) % Byte.SIZE;
78 for (int i = 0; i < Byte.SIZE; i++) {
Jonathan Hart9ea31212013-08-12 21:40:34 +120079 if (i <= lastBit) {
80 mask |= (msb >> i);
Jonathan Hart32e18222013-08-07 22:05:42 +120081 }
Jonathan Hart32e18222013-08-07 22:05:42 +120082 }
83
84 result[lastByteIndex] = (byte) (lastByte & mask);
85
86 return result;
pingping-lina2cbfad2013-03-07 08:39:21 +080087 }
Jonathan Hart61ba9372013-05-19 20:10:29 -070088
Jonathan Hartd1b9d872013-07-23 12:17:21 +120089 public int getPrefixLength() {
90 return prefixLength;
91 }
92
93 public byte[] getAddress() {
Jonathan Hart32e18222013-08-07 22:05:42 +120094 return address;
pingping-lina2cbfad2013-03-07 08:39:21 +080095 }
Jonathan Hartd1b9d872013-07-23 12:17:21 +120096
97 @Override
Jonathan Hart0ee0f022013-08-03 22:21:54 +120098 public boolean equals(Object other) {
99 if (other == null || !(other instanceof Prefix)) {
100 return false;
101 }
102
103 Prefix otherPrefix = (Prefix) other;
104
Jonathan Hart32e18222013-08-07 22:05:42 +1200105 return (Arrays.equals(address, otherPrefix.address)) &&
Jonathan Hart0ee0f022013-08-03 22:21:54 +1200106 (prefixLength == otherPrefix.prefixLength);
107 }
108
109 @Override
110 public int hashCode() {
111 int hash = 17;
112 hash = 31 * hash + prefixLength;
Jonathan Hart32e18222013-08-07 22:05:42 +1200113 hash = 31 * hash + Arrays.hashCode(address);
Jonathan Hart0ee0f022013-08-03 22:21:54 +1200114 return hash;
115 }
116
117 @Override
Jonathan Hartd1b9d872013-07-23 12:17:21 +1200118 public String toString() {
Jonathan Hart32e18222013-08-07 22:05:42 +1200119 return inetAddress.getHostAddress() + "/" + prefixLength;
120 }
121
122 public String printAsBits() {
123 String result = "";
124 for (int i = 0; i < address.length; i++) {
125 byte b = address[i];
126 for (int j = 0; j < Byte.SIZE; j++) {
127 byte mask = (byte) (0x80 >>> j);
128 result += ((b & mask) == 0)? "0" : "1";
129 if (i*Byte.SIZE+j == prefixLength-1) {
130 return result;
131 }
132 }
133 result += " ";
134 }
135 return result.substring(0, result.length() - 1);
Jonathan Hartd1b9d872013-07-23 12:17:21 +1200136 }
pingping-lina2cbfad2013-03-07 08:39:21 +0800137}