blob: 77b792f83318d2d8db48c59f3b6b29bc7781b047 [file] [log] [blame]
Yotam Harcholf3f11152013-09-05 16:47:16 -07001package org.projectfloodlight.openflow.types;
2
Andreas Wundsam85c961f2013-09-29 21:22:12 -07003import java.util.Arrays;
4
Yotam Harcholf3f11152013-09-05 16:47:16 -07005import org.jboss.netty.buffer.ChannelBuffer;
6
Andreas Wundsam85c961f2013-09-29 21:22:12 -07007import com.google.common.primitives.UnsignedInts;
8
Yotam Harcholf3f11152013-09-05 16:47:16 -07009
10
11/**
Yotam Harchola289d552013-09-16 10:10:40 -070012 * Wrapper around an IPv4Address address
Yotam Harcholf3f11152013-09-05 16:47:16 -070013 *
14 * @author Andreas Wundsam <andreas.wundsam@bigswitch.com>
15 */
Yotam Harchol4d634682013-09-26 13:21:06 -070016public class IPv4Address extends IPAddress<IPv4Address> {
Yotam Harcholf3f11152013-09-05 16:47:16 -070017 static final int LENGTH = 4;
18 private final int rawValue;
Yotam Harcholf3f11152013-09-05 16:47:16 -070019
Andreas Wundsamb75c4ad2013-09-23 14:45:35 -070020 private final static int NONE_VAL = 0x0;
21 public final static IPv4Address NONE = new IPv4Address(NONE_VAL);
22
Yotam Harchola289d552013-09-16 10:10:40 -070023 public static final IPv4Address NO_MASK = IPv4Address.of(0xFFFFFFFF);
24 public static final IPv4Address FULL_MASK = IPv4Address.of(0x00000000);
25
26 private IPv4Address(final int rawValue) {
Yotam Harcholf3f11152013-09-05 16:47:16 -070027 this.rawValue = rawValue;
28 }
29
Yotam Harchol4d634682013-09-26 13:21:06 -070030 @Override
Yotam Harcholeb023dc2013-09-26 15:45:44 -070031 public IPVersion getIpVersion() {
32 return IPVersion.IPv4;
Yotam Harchol4d634682013-09-26 13:21:06 -070033 }
34
Yotam Harchola289d552013-09-16 10:10:40 -070035 public static IPv4Address of(final byte[] address) {
Yotam Harcholf3f11152013-09-05 16:47:16 -070036 if (address.length != LENGTH) {
37 throw new IllegalArgumentException(
Andreas Wundsamc85b5c52013-09-24 13:01:43 -070038 "Invalid byte array length for IPv4Address address: " + address.length);
Yotam Harcholf3f11152013-09-05 16:47:16 -070039 }
40
41 int raw =
42 (address[0] & 0xFF) << 24 | (address[1] & 0xFF) << 16
43 | (address[2] & 0xFF) << 8 | (address[3] & 0xFF) << 0;
Yotam Harchola289d552013-09-16 10:10:40 -070044 return IPv4Address.of(raw);
Yotam Harcholf3f11152013-09-05 16:47:16 -070045 }
46
Yotam Harchola289d552013-09-16 10:10:40 -070047 public static IPv4Address of(final int raw) {
Andreas Wundsamb75c4ad2013-09-23 14:45:35 -070048 if(raw == NONE_VAL)
49 return NONE;
Yotam Harchola289d552013-09-16 10:10:40 -070050 return new IPv4Address(raw);
Yotam Harcholf3f11152013-09-05 16:47:16 -070051 }
52
Yotam Harchola289d552013-09-16 10:10:40 -070053 public static IPv4Address of(final String string) {
Yotam Harcholf3f11152013-09-05 16:47:16 -070054 int start = 0;
55 int shift = 24;
56
57 int raw = 0;
58 while (shift >= 0) {
59 int end = string.indexOf('.', start);
60 if (end == start || !((shift > 0) ^ (end < 0)))
61 throw new IllegalArgumentException("IP Address not well formed: " + string);
62
63 String substr =
64 end > 0 ? string.substring(start, end) : string.substring(start);
65 int val = Integer.parseInt(substr);
66 if (val < 0 || val > 255)
67 throw new IllegalArgumentException("IP Address not well formed: " + string);
68
69 raw |= val << shift;
70
71 shift -= 8;
72 start = end + 1;
73 }
Yotam Harchola289d552013-09-16 10:10:40 -070074 return IPv4Address.of(raw);
Yotam Harcholf3f11152013-09-05 16:47:16 -070075 }
76
77 public int getInt() {
78 return rawValue;
79 }
80
81 volatile byte[] bytesCache = null;
82
83 public byte[] getBytes() {
84 if (bytesCache == null) {
85 synchronized (this) {
86 if (bytesCache == null) {
87 bytesCache =
88 new byte[] { (byte) ((rawValue >>> 24) & 0xFF),
89 (byte) ((rawValue >>> 16) & 0xFF),
90 (byte) ((rawValue >>> 8) & 0xFF),
91 (byte) ((rawValue >>> 0) & 0xFF) };
92 }
93 }
94 }
95 return bytesCache;
96 }
97
98 @Override
99 public int getLength() {
100 return LENGTH;
101 }
102
103 @Override
104 public String toString() {
105 StringBuilder res = new StringBuilder();
106 res.append((rawValue >> 24) & 0xFF).append('.');
107 res.append((rawValue >> 16) & 0xFF).append('.');
108 res.append((rawValue >> 8) & 0xFF).append('.');
109 res.append((rawValue >> 0) & 0xFF);
110 return res.toString();
111 }
112
Yotam Harcholf3f11152013-09-05 16:47:16 -0700113 public void write4Bytes(ChannelBuffer c) {
114 c.writeInt(rawValue);
115 }
Yotam Harchola289d552013-09-16 10:10:40 -0700116
117 public static IPv4Address read4Bytes(ChannelBuffer c) {
118 return IPv4Address.of(c.readInt());
Yotam Harcholf3f11152013-09-05 16:47:16 -0700119 }
120
121 @Override
Yotam Harchola289d552013-09-16 10:10:40 -0700122 public IPv4Address applyMask(IPv4Address mask) {
123 return IPv4Address.of(this.rawValue & mask.rawValue);
Yotam Harcholf3f11152013-09-05 16:47:16 -0700124 }
125
Andreas Wundsam85c961f2013-09-29 21:22:12 -0700126 @Override
127 public int hashCode() {
128 final int prime = 31;
129 int result = 1;
130 result = prime * result + Arrays.hashCode(bytesCache);
131 result = prime * result + rawValue;
132 return result;
133 }
Yotam Harchola289d552013-09-16 10:10:40 -0700134
Andreas Wundsam85c961f2013-09-29 21:22:12 -0700135 @Override
136 public boolean equals(Object obj) {
137 if (this == obj)
138 return true;
139 if (obj == null)
140 return false;
141 if (getClass() != obj.getClass())
142 return false;
143 IPv4Address other = (IPv4Address) obj;
144 if (!Arrays.equals(bytesCache, other.bytesCache))
145 return false;
146 if (rawValue != other.rawValue)
147 return false;
148 return true;
149 }
150
151 @Override
152 public int compareTo(IPv4Address o) {
153 return UnsignedInts.compare(rawValue, o.rawValue);
154 }
Yotam Harcholf3f11152013-09-05 16:47:16 -0700155}