blob: b1b6fdac4d8fab2bd0653136e3d5ffcdfbb4b866 [file] [log] [blame]
Jian Lic7e20a52016-07-18 19:03:49 +09001/*
2 * Copyright 2016-present Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.lisp.msg.types;
17
Jian Li115d8602016-08-15 20:21:53 +090018import io.netty.buffer.ByteBuf;
19import org.onosproject.lisp.msg.exceptions.LispParseError;
20import org.onosproject.lisp.msg.exceptions.LispReaderException;
21
22import java.nio.ByteBuffer;
Jian Lic7e20a52016-07-18 19:03:49 +090023import java.util.Objects;
24
25import static com.google.common.base.MoreObjects.toStringHelper;
26
27/**
28 * Application data type LCAF address class.
Jian Li8fc2d2f2016-08-08 14:43:53 +090029 * <p>
Jian Lic7e20a52016-07-18 19:03:49 +090030 * Application data type is defined in draft-ietf-lisp-lcaf-13
31 * https://tools.ietf.org/html/draft-ietf-lisp-lcaf-13#page-26
32 *
Jian Li8fc2d2f2016-08-08 14:43:53 +090033 * <pre>
34 * {@literal
Jian Lic7e20a52016-07-18 19:03:49 +090035 * 0 1 2 3
36 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
37 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
38 * | AFI = 16387 | Rsvd1 | Flags |
39 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
40 * | Type = 4 | Rsvd2 | 12 + n |
41 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
42 * | IP TOS, IPv6 TC, or Flow Label | Protocol |
43 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
44 * | Local Port (lower-range) | Local Port (upper-range) |
45 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
46 * | Remote Port (lower-range) | Remote Port (upper-range) |
47 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
48 * | AFI = x | Address ... |
49 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Jian Li8fc2d2f2016-08-08 14:43:53 +090050 * }</pre>
Jian Lic7e20a52016-07-18 19:03:49 +090051 */
Jian Li115d8602016-08-15 20:21:53 +090052public final class LispAppDataLcafAddress extends LispLcafAddress {
Jian Lic7e20a52016-07-18 19:03:49 +090053
54 private final byte protocol;
55 private final int ipTos;
Jian Li115d8602016-08-15 20:21:53 +090056 private final short localPortLow;
57 private final short localPortHigh;
58 private final short remotePortLow;
59 private final short remotePortHigh;
Jian Lic7e20a52016-07-18 19:03:49 +090060 private LispAfiAddress address;
61
62 /**
Jian Lia7b394d2016-08-21 23:11:46 +090063 * Initializes application data type LCAF address.
64 *
Jian Li115d8602016-08-15 20:21:53 +090065 * @param protocol protocol number
66 * @param ipTos IP type of service
67 * @param localPortLow low-ranged local port number
68 * @param localPortHigh high-ranged local port number
69 * @param remotePortLow low-ranged remote port number
70 * @param remotePortHigh high-ranged remote port number
71 * @param address address
Jian Lic7e20a52016-07-18 19:03:49 +090072 */
Jian Li115d8602016-08-15 20:21:53 +090073 private LispAppDataLcafAddress(byte protocol, int ipTos, short localPortLow,
74 short localPortHigh, short remotePortLow,
75 short remotePortHigh, LispAfiAddress address) {
Jian Lic7e20a52016-07-18 19:03:49 +090076 super(LispCanonicalAddressFormatEnum.APPLICATION_DATA);
77 this.protocol = protocol;
78 this.ipTos = ipTos;
Jian Li115d8602016-08-15 20:21:53 +090079 this.localPortLow = localPortLow;
80 this.localPortHigh = localPortHigh;
81 this.remotePortLow = remotePortLow;
82 this.remotePortHigh = remotePortHigh;
Jian Lic7e20a52016-07-18 19:03:49 +090083 this.address = address;
84 }
85
86 /**
Jian Lia7b394d2016-08-21 23:11:46 +090087 * Initializes application data type LCAF address.
88 *
89 * @param reserved1 reserved1
90 * @param reserved2 reserved2
91 * @param flag flag
92 * @param length length
93 * @param protocol protocol number
94 * @param ipTos IP type of service
95 * @param localPortLow low-ranged local port number
96 * @param localPortHigh high-ranged local port number
97 * @param remotePortLow low-ranged remote port number
98 * @param remotePortHigh high-ranged remote port number
99 * @param address address
100 */
101 private LispAppDataLcafAddress(byte reserved1, byte reserved2, byte flag, short length,
102 byte protocol, int ipTos, short localPortLow,
103 short localPortHigh, short remotePortLow,
104 short remotePortHigh, LispAfiAddress address) {
105 super(LispCanonicalAddressFormatEnum.APPLICATION_DATA, reserved1, reserved2, flag, length);
106 this.protocol = protocol;
107 this.ipTos = ipTos;
108 this.localPortLow = localPortLow;
109 this.localPortHigh = localPortHigh;
110 this.remotePortLow = remotePortLow;
111 this.remotePortHigh = remotePortHigh;
112 this.address = address;
113 }
114
115 /**
Jian Lic7e20a52016-07-18 19:03:49 +0900116 * Obtains protocol number.
117 *
118 * @return protocol number
119 */
120 public byte getProtocol() {
121 return protocol;
122 }
123
124 /**
125 * Obtains IP type of service.
126 *
127 * @return IP type of service
128 */
129 public int getIpTos() {
130 return ipTos;
131 }
132
133 /**
Jian Li115d8602016-08-15 20:21:53 +0900134 * Obtains low-ranged local port number.
Jian Lic7e20a52016-07-18 19:03:49 +0900135 *
Jian Li115d8602016-08-15 20:21:53 +0900136 * @return low-ranged local port number
Jian Lic7e20a52016-07-18 19:03:49 +0900137 */
Jian Li115d8602016-08-15 20:21:53 +0900138 public short getLocalPortLow() {
139 return localPortLow;
Jian Lic7e20a52016-07-18 19:03:49 +0900140 }
141
142 /**
Jian Li115d8602016-08-15 20:21:53 +0900143 * Obtains high-ranged local port number.
Jian Lic7e20a52016-07-18 19:03:49 +0900144 *
Jian Li115d8602016-08-15 20:21:53 +0900145 * @return high-ranged local port number
Jian Lic7e20a52016-07-18 19:03:49 +0900146 */
Jian Li115d8602016-08-15 20:21:53 +0900147 public short getLocalPortHigh() {
148 return localPortHigh;
149 }
150
151 /**
152 * Obtains low-ranged remote port number.
153 *
154 * @return low-ranged remote port number
155 */
156 public short getRemotePortLow() {
157 return remotePortLow;
158 }
159
160 /**
161 * Obtains high-ranged remote port number.
162 *
163 * @return high-ranged remote port number
164 */
165 public short getRemotePortHigh() {
166 return remotePortHigh;
Jian Lic7e20a52016-07-18 19:03:49 +0900167 }
168
169 /**
170 * Obtains address.
171 *
172 * @return address
173 */
174 public LispAfiAddress getAddress() {
175 return address;
176 }
177
178 @Override
179 public int hashCode() {
Jian Li115d8602016-08-15 20:21:53 +0900180 return Objects.hash(address, protocol, ipTos, localPortLow,
181 localPortHigh, remotePortLow, remotePortHigh);
Jian Lic7e20a52016-07-18 19:03:49 +0900182 }
183
184 @Override
185 public boolean equals(Object obj) {
186 if (this == obj) {
187 return true;
188 }
189
190 if (obj instanceof LispAppDataLcafAddress) {
191 final LispAppDataLcafAddress other = (LispAppDataLcafAddress) obj;
192 return Objects.equals(this.address, other.address) &&
193 Objects.equals(this.protocol, other.protocol) &&
194 Objects.equals(this.ipTos, other.ipTos) &&
Jian Li115d8602016-08-15 20:21:53 +0900195 Objects.equals(this.localPortLow, other.localPortLow) &&
196 Objects.equals(this.localPortHigh, other.localPortHigh) &&
197 Objects.equals(this.remotePortLow, other.remotePortLow) &&
198 Objects.equals(this.remotePortHigh, other.remotePortHigh);
Jian Lic7e20a52016-07-18 19:03:49 +0900199 }
200 return false;
201 }
202
203 @Override
204 public String toString() {
205 return toStringHelper(this)
206 .add("address", address)
207 .add("protocol", protocol)
208 .add("ip type of service", ipTos)
Jian Li115d8602016-08-15 20:21:53 +0900209 .add("low-ranged local port number", localPortLow)
210 .add("high-ranged local port number", localPortHigh)
211 .add("low-ranged remote port number", remotePortLow)
212 .add("high-ranged remote port number", remotePortHigh)
Jian Lic7e20a52016-07-18 19:03:49 +0900213 .toString();
214 }
Jian Li115d8602016-08-15 20:21:53 +0900215
Jian Lia7b394d2016-08-21 23:11:46 +0900216 public static final class AppDataAddressBuilder
217 extends LcafAddressBuilder<AppDataAddressBuilder> {
Jian Li115d8602016-08-15 20:21:53 +0900218 private byte protocol;
219 private int ipTos;
220 private short localPortLow;
221 private short localPortHigh;
222 private short remotePortLow;
223 private short remotePortHigh;
224 private LispAfiAddress address;
225
226 /**
227 * Sets protocol number.
228 *
229 * @param protocol protocol number
230 * @return AppDataAddressBuilder object
231 */
Jian Lia7b394d2016-08-21 23:11:46 +0900232 public AppDataAddressBuilder withProtocol(byte protocol) {
Jian Li115d8602016-08-15 20:21:53 +0900233 this.protocol = protocol;
234 return this;
235 }
236
237 /**
238 * Sets IP type of service.
239 *
240 * @param ipTos IP type of service
241 * @return AppDataAddressBuilder object
242 */
Jian Lia7b394d2016-08-21 23:11:46 +0900243 public AppDataAddressBuilder withIpTos(int ipTos) {
Jian Li115d8602016-08-15 20:21:53 +0900244 this.ipTos = ipTos;
245 return this;
246 }
247
248 /**
249 * Sets low-ranged local port number.
250 *
251 * @param localPortLow low-ranged local port number
252 * @return AppDataAddressBuilder object
253 */
Jian Lia7b394d2016-08-21 23:11:46 +0900254 public AppDataAddressBuilder withLocalPortLow(short localPortLow) {
Jian Li115d8602016-08-15 20:21:53 +0900255 this.localPortLow = localPortLow;
256 return this;
257 }
258
259 /**
260 * Sets high-ranged local port number.
261 *
262 * @param localPortHigh high-ranged local port number
263 * @return AppDataAddressBuilder object
264 */
Jian Lia7b394d2016-08-21 23:11:46 +0900265 public AppDataAddressBuilder withLocalPortHigh(short localPortHigh) {
Jian Li115d8602016-08-15 20:21:53 +0900266 this.localPortHigh = localPortHigh;
267 return this;
268 }
269
270 /**
271 * Sets low-ranged remote port number.
272 *
273 * @param remotePortLow low-ranged remote port number
274 * @return AppDataAddressBuilder object
275 */
Jian Lia7b394d2016-08-21 23:11:46 +0900276 public AppDataAddressBuilder withRemotePortLow(short remotePortLow) {
Jian Li115d8602016-08-15 20:21:53 +0900277 this.remotePortLow = remotePortLow;
278 return this;
279 }
280
281 /**
282 * Sets high-ranged remote port number.
283 *
284 * @param remotePortHigh high-ranged remote port number
285 * @return AppDataAddressBuilder object
286 */
Jian Lia7b394d2016-08-21 23:11:46 +0900287 public AppDataAddressBuilder withRemotePortHigh(short remotePortHigh) {
Jian Li115d8602016-08-15 20:21:53 +0900288 this.remotePortHigh = remotePortHigh;
289 return this;
290 }
291
292 /**
293 * Sets AFI address.
294 *
295 * @param address AFI address
296 * @return AppDataAddressBuilder object
297 */
Jian Lia7b394d2016-08-21 23:11:46 +0900298 public AppDataAddressBuilder withAddress(LispAfiAddress address) {
Jian Li115d8602016-08-15 20:21:53 +0900299 this.address = address;
300 return this;
301 }
302
303 /**
304 * Builds LispAppDataLcafAddress instance.
305 *
306 * @return LispAddDataLcafAddress instance
307 */
Jian Lia7b394d2016-08-21 23:11:46 +0900308 public LispAppDataLcafAddress build() {
309 return new LispAppDataLcafAddress(reserved1, reserved2, flag, length,
310 protocol, ipTos, localPortLow, localPortHigh, remotePortLow,
311 remotePortHigh, address);
Jian Li115d8602016-08-15 20:21:53 +0900312 }
313 }
314
315 /**
316 * Application data LCAF address reader class.
317 */
318 public static class AppDataLcafAddressReader
319 implements LispAddressReader<LispAppDataLcafAddress> {
320
321 @Override
322 public LispAppDataLcafAddress readFrom(ByteBuf byteBuf) throws LispParseError, LispReaderException {
323
Jian Lia7b394d2016-08-21 23:11:46 +0900324 LispLcafAddress lcafAddress = LispLcafAddress.deserializeCommon(byteBuf);
325
Jian Li115d8602016-08-15 20:21:53 +0900326 byte[] ipTosByte = new byte[3];
327 byteBuf.readBytes(ipTosByte);
328
329 byte protocol = (byte) byteBuf.readUnsignedByte();
330 int ipTos = getPartialInt(ipTosByte);
331 short localPortLow = (short) byteBuf.readUnsignedShort();
332 short localPortHigh = (short) byteBuf.readUnsignedShort();
333 short remotePortLow = (short) byteBuf.readUnsignedShort();
334 short remotePortHigh = (short) byteBuf.readUnsignedShort();
335
Jian Lia7b394d2016-08-21 23:11:46 +0900336 LispAfiAddress address = new LispAfiAddress.AfiAddressReader().readFrom(byteBuf);
Jian Li115d8602016-08-15 20:21:53 +0900337
338 return new AppDataAddressBuilder()
Jian Lia7b394d2016-08-21 23:11:46 +0900339 .withReserved1(lcafAddress.getReserved1())
340 .withReserved2(lcafAddress.getReserved2())
341 .withFlag(lcafAddress.getFlag())
342 .withLength(lcafAddress.getLength())
343 .withProtocol(protocol)
344 .withIpTos(ipTos)
345 .withLocalPortLow(localPortLow)
346 .withLocalPortHigh(localPortHigh)
347 .withRemotePortLow(remotePortLow)
348 .withRemotePortHigh(remotePortHigh)
349 .withAddress(address)
350 .build();
Jian Li115d8602016-08-15 20:21:53 +0900351 }
352
353 /**
354 * A utility function that obtains the partial int value from byte arrays.
355 *
356 * @param bytes an array of bytes
357 * @return converted integer
358 */
359 public static int getPartialInt(byte[] bytes) {
360 ByteBuffer buffer = ByteBuffer.allocate(4);
361 buffer.position(4 - bytes.length);
362 buffer.put(bytes);
363 buffer.position(0);
364 return buffer.getInt();
365 }
366 }
Jian Lic7e20a52016-07-18 19:03:49 +0900367}