blob: 911e0ad9b3472e6edd92391b0a767c97ca310df7 [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 */
Jian Lif31019a2017-02-05 07:57:46 +090016package org.onosproject.lisp.msg.types.lcaf;
Jian Lic7e20a52016-07-18 19:03:49 +090017
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;
GUNiba871702016-08-22 21:06:02 +090021import org.onosproject.lisp.msg.exceptions.LispWriterException;
Jian Lif31019a2017-02-05 07:57:46 +090022import org.onosproject.lisp.msg.types.LispAddressReader;
23import org.onosproject.lisp.msg.types.LispAddressWriter;
24import org.onosproject.lisp.msg.types.LispAfiAddress;
Jian Li115d8602016-08-15 20:21:53 +090025
26import java.nio.ByteBuffer;
Jian Li76ea0572016-08-29 12:41:16 +090027import java.util.Arrays;
Jian Lic7e20a52016-07-18 19:03:49 +090028import java.util.Objects;
29
30import static com.google.common.base.MoreObjects.toStringHelper;
Jian Lid4e63702016-08-30 18:29:20 +090031import static com.google.common.base.Preconditions.checkNotNull;
Jian Lic7e20a52016-07-18 19:03:49 +090032
33/**
34 * Application data type LCAF address class.
Jian Li8fc2d2f2016-08-08 14:43:53 +090035 * <p>
Jian Lid6483cc2016-12-12 02:26:13 +090036 * Application data type is defined in draft-ietf-lisp-lcaf-22
37 * https://tools.ietf.org/html/draft-ietf-lisp-lcaf-22#page-27
Jian Lic7e20a52016-07-18 19:03:49 +090038 *
Jian Li8fc2d2f2016-08-08 14:43:53 +090039 * <pre>
40 * {@literal
Jian Lic7e20a52016-07-18 19:03:49 +090041 * 0 1 2 3
42 * 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
43 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
44 * | AFI = 16387 | Rsvd1 | Flags |
45 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Jian Li89c9ca92016-11-11 04:09:02 +090046 * | Type = 4 | Rsvd2 | Length |
Jian Lic7e20a52016-07-18 19:03:49 +090047 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
48 * | IP TOS, IPv6 TC, or Flow Label | Protocol |
49 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
50 * | Local Port (lower-range) | Local Port (upper-range) |
51 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
52 * | Remote Port (lower-range) | Remote Port (upper-range) |
53 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
54 * | AFI = x | Address ... |
55 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Jian Li8fc2d2f2016-08-08 14:43:53 +090056 * }</pre>
Jian Lic7e20a52016-07-18 19:03:49 +090057 */
Jian Li115d8602016-08-15 20:21:53 +090058public final class LispAppDataLcafAddress extends LispLcafAddress {
Jian Lic7e20a52016-07-18 19:03:49 +090059
60 private final byte protocol;
61 private final int ipTos;
Jian Li115d8602016-08-15 20:21:53 +090062 private final short localPortLow;
63 private final short localPortHigh;
64 private final short remotePortLow;
65 private final short remotePortHigh;
Jian Lic7e20a52016-07-18 19:03:49 +090066 private LispAfiAddress address;
67
68 /**
Jian Lia7b394d2016-08-21 23:11:46 +090069 * Initializes application data type LCAF address.
70 *
Jian Li115d8602016-08-15 20:21:53 +090071 * @param protocol protocol number
72 * @param ipTos IP type of service
73 * @param localPortLow low-ranged local port number
74 * @param localPortHigh high-ranged local port number
75 * @param remotePortLow low-ranged remote port number
76 * @param remotePortHigh high-ranged remote port number
77 * @param address address
Jian Lic7e20a52016-07-18 19:03:49 +090078 */
Jian Li115d8602016-08-15 20:21:53 +090079 private LispAppDataLcafAddress(byte protocol, int ipTos, short localPortLow,
80 short localPortHigh, short remotePortLow,
81 short remotePortHigh, LispAfiAddress address) {
Jian Lic7e20a52016-07-18 19:03:49 +090082 super(LispCanonicalAddressFormatEnum.APPLICATION_DATA);
83 this.protocol = protocol;
84 this.ipTos = ipTos;
Jian Li115d8602016-08-15 20:21:53 +090085 this.localPortLow = localPortLow;
86 this.localPortHigh = localPortHigh;
87 this.remotePortLow = remotePortLow;
88 this.remotePortHigh = remotePortHigh;
Jian Lic7e20a52016-07-18 19:03:49 +090089 this.address = address;
90 }
91
92 /**
Jian Lia7b394d2016-08-21 23:11:46 +090093 * Initializes application data type LCAF address.
94 *
95 * @param reserved1 reserved1
96 * @param reserved2 reserved2
97 * @param flag flag
98 * @param length length
99 * @param protocol protocol number
100 * @param ipTos IP type of service
101 * @param localPortLow low-ranged local port number
102 * @param localPortHigh high-ranged local port number
103 * @param remotePortLow low-ranged remote port number
104 * @param remotePortHigh high-ranged remote port number
105 * @param address address
106 */
107 private LispAppDataLcafAddress(byte reserved1, byte reserved2, byte flag, short length,
108 byte protocol, int ipTos, short localPortLow,
109 short localPortHigh, short remotePortLow,
110 short remotePortHigh, LispAfiAddress address) {
111 super(LispCanonicalAddressFormatEnum.APPLICATION_DATA, reserved1, reserved2, flag, length);
112 this.protocol = protocol;
113 this.ipTos = ipTos;
114 this.localPortLow = localPortLow;
115 this.localPortHigh = localPortHigh;
116 this.remotePortLow = remotePortLow;
117 this.remotePortHigh = remotePortHigh;
118 this.address = address;
119 }
120
121 /**
Jian Lic7e20a52016-07-18 19:03:49 +0900122 * Obtains protocol number.
123 *
124 * @return protocol number
125 */
126 public byte getProtocol() {
127 return protocol;
128 }
129
130 /**
131 * Obtains IP type of service.
132 *
133 * @return IP type of service
134 */
135 public int getIpTos() {
136 return ipTos;
137 }
138
139 /**
Jian Li115d8602016-08-15 20:21:53 +0900140 * Obtains low-ranged local port number.
Jian Lic7e20a52016-07-18 19:03:49 +0900141 *
Jian Li115d8602016-08-15 20:21:53 +0900142 * @return low-ranged local port number
Jian Lic7e20a52016-07-18 19:03:49 +0900143 */
Jian Li115d8602016-08-15 20:21:53 +0900144 public short getLocalPortLow() {
145 return localPortLow;
Jian Lic7e20a52016-07-18 19:03:49 +0900146 }
147
148 /**
Jian Li115d8602016-08-15 20:21:53 +0900149 * Obtains high-ranged local port number.
Jian Lic7e20a52016-07-18 19:03:49 +0900150 *
Jian Li115d8602016-08-15 20:21:53 +0900151 * @return high-ranged local port number
Jian Lic7e20a52016-07-18 19:03:49 +0900152 */
Jian Li115d8602016-08-15 20:21:53 +0900153 public short getLocalPortHigh() {
154 return localPortHigh;
155 }
156
157 /**
158 * Obtains low-ranged remote port number.
159 *
160 * @return low-ranged remote port number
161 */
162 public short getRemotePortLow() {
163 return remotePortLow;
164 }
165
166 /**
167 * Obtains high-ranged remote port number.
168 *
169 * @return high-ranged remote port number
170 */
171 public short getRemotePortHigh() {
172 return remotePortHigh;
Jian Lic7e20a52016-07-18 19:03:49 +0900173 }
174
175 /**
176 * Obtains address.
177 *
178 * @return address
179 */
180 public LispAfiAddress getAddress() {
181 return address;
182 }
183
184 @Override
185 public int hashCode() {
Jian Li115d8602016-08-15 20:21:53 +0900186 return Objects.hash(address, protocol, ipTos, localPortLow,
187 localPortHigh, remotePortLow, remotePortHigh);
Jian Lic7e20a52016-07-18 19:03:49 +0900188 }
189
190 @Override
191 public boolean equals(Object obj) {
192 if (this == obj) {
193 return true;
194 }
195
196 if (obj instanceof LispAppDataLcafAddress) {
197 final LispAppDataLcafAddress other = (LispAppDataLcafAddress) obj;
198 return Objects.equals(this.address, other.address) &&
199 Objects.equals(this.protocol, other.protocol) &&
200 Objects.equals(this.ipTos, other.ipTos) &&
Jian Li115d8602016-08-15 20:21:53 +0900201 Objects.equals(this.localPortLow, other.localPortLow) &&
202 Objects.equals(this.localPortHigh, other.localPortHigh) &&
203 Objects.equals(this.remotePortLow, other.remotePortLow) &&
204 Objects.equals(this.remotePortHigh, other.remotePortHigh);
Jian Lic7e20a52016-07-18 19:03:49 +0900205 }
206 return false;
207 }
208
209 @Override
210 public String toString() {
211 return toStringHelper(this)
212 .add("address", address)
213 .add("protocol", protocol)
214 .add("ip type of service", ipTos)
Jian Li115d8602016-08-15 20:21:53 +0900215 .add("low-ranged local port number", localPortLow)
216 .add("high-ranged local port number", localPortHigh)
217 .add("low-ranged remote port number", remotePortLow)
218 .add("high-ranged remote port number", remotePortHigh)
Jian Lic7e20a52016-07-18 19:03:49 +0900219 .toString();
220 }
Jian Li115d8602016-08-15 20:21:53 +0900221
Jian Lia7b394d2016-08-21 23:11:46 +0900222 public static final class AppDataAddressBuilder
223 extends LcafAddressBuilder<AppDataAddressBuilder> {
Jian Li115d8602016-08-15 20:21:53 +0900224 private byte protocol;
225 private int ipTos;
226 private short localPortLow;
227 private short localPortHigh;
228 private short remotePortLow;
229 private short remotePortHigh;
230 private LispAfiAddress address;
231
232 /**
233 * Sets protocol number.
234 *
235 * @param protocol protocol number
236 * @return AppDataAddressBuilder object
237 */
Jian Lia7b394d2016-08-21 23:11:46 +0900238 public AppDataAddressBuilder withProtocol(byte protocol) {
Jian Li115d8602016-08-15 20:21:53 +0900239 this.protocol = protocol;
240 return this;
241 }
242
243 /**
244 * Sets IP type of service.
245 *
246 * @param ipTos IP type of service
247 * @return AppDataAddressBuilder object
248 */
Jian Lia7b394d2016-08-21 23:11:46 +0900249 public AppDataAddressBuilder withIpTos(int ipTos) {
Jian Li115d8602016-08-15 20:21:53 +0900250 this.ipTos = ipTos;
251 return this;
252 }
253
254 /**
255 * Sets low-ranged local port number.
256 *
257 * @param localPortLow low-ranged local port number
258 * @return AppDataAddressBuilder object
259 */
Jian Lia7b394d2016-08-21 23:11:46 +0900260 public AppDataAddressBuilder withLocalPortLow(short localPortLow) {
Jian Li115d8602016-08-15 20:21:53 +0900261 this.localPortLow = localPortLow;
262 return this;
263 }
264
265 /**
266 * Sets high-ranged local port number.
267 *
268 * @param localPortHigh high-ranged local port number
269 * @return AppDataAddressBuilder object
270 */
Jian Lia7b394d2016-08-21 23:11:46 +0900271 public AppDataAddressBuilder withLocalPortHigh(short localPortHigh) {
Jian Li115d8602016-08-15 20:21:53 +0900272 this.localPortHigh = localPortHigh;
273 return this;
274 }
275
276 /**
277 * Sets low-ranged remote port number.
278 *
279 * @param remotePortLow low-ranged remote port number
280 * @return AppDataAddressBuilder object
281 */
Jian Lia7b394d2016-08-21 23:11:46 +0900282 public AppDataAddressBuilder withRemotePortLow(short remotePortLow) {
Jian Li115d8602016-08-15 20:21:53 +0900283 this.remotePortLow = remotePortLow;
284 return this;
285 }
286
287 /**
288 * Sets high-ranged remote port number.
289 *
290 * @param remotePortHigh high-ranged remote port number
291 * @return AppDataAddressBuilder object
292 */
Jian Lia7b394d2016-08-21 23:11:46 +0900293 public AppDataAddressBuilder withRemotePortHigh(short remotePortHigh) {
Jian Li115d8602016-08-15 20:21:53 +0900294 this.remotePortHigh = remotePortHigh;
295 return this;
296 }
297
298 /**
299 * Sets AFI address.
300 *
301 * @param address AFI address
302 * @return AppDataAddressBuilder object
303 */
Jian Lia7b394d2016-08-21 23:11:46 +0900304 public AppDataAddressBuilder withAddress(LispAfiAddress address) {
Jian Li115d8602016-08-15 20:21:53 +0900305 this.address = address;
306 return this;
307 }
308
309 /**
310 * Builds LispAppDataLcafAddress instance.
311 *
312 * @return LispAddDataLcafAddress instance
313 */
Jian Lia7b394d2016-08-21 23:11:46 +0900314 public LispAppDataLcafAddress build() {
Jian Lid4e63702016-08-30 18:29:20 +0900315
316 checkNotNull(address, "Must specify an address");
317
Jian Lia7b394d2016-08-21 23:11:46 +0900318 return new LispAppDataLcafAddress(reserved1, reserved2, flag, length,
319 protocol, ipTos, localPortLow, localPortHigh, remotePortLow,
320 remotePortHigh, address);
Jian Li115d8602016-08-15 20:21:53 +0900321 }
322 }
323
324 /**
325 * Application data LCAF address reader class.
326 */
327 public static class AppDataLcafAddressReader
328 implements LispAddressReader<LispAppDataLcafAddress> {
329
330 @Override
331 public LispAppDataLcafAddress readFrom(ByteBuf byteBuf) throws LispParseError, LispReaderException {
332
Jian Li3a99e712016-12-16 21:23:16 +0900333 LispLcafAddress.deserializeCommon(byteBuf);
Jian Lia7b394d2016-08-21 23:11:46 +0900334
Jian Li115d8602016-08-15 20:21:53 +0900335 byte[] ipTosByte = new byte[3];
336 byteBuf.readBytes(ipTosByte);
337
338 byte protocol = (byte) byteBuf.readUnsignedByte();
339 int ipTos = getPartialInt(ipTosByte);
340 short localPortLow = (short) byteBuf.readUnsignedShort();
341 short localPortHigh = (short) byteBuf.readUnsignedShort();
342 short remotePortLow = (short) byteBuf.readUnsignedShort();
343 short remotePortHigh = (short) byteBuf.readUnsignedShort();
344
Jian Lia7b394d2016-08-21 23:11:46 +0900345 LispAfiAddress address = new LispAfiAddress.AfiAddressReader().readFrom(byteBuf);
Jian Li115d8602016-08-15 20:21:53 +0900346
347 return new AppDataAddressBuilder()
Jian Lia7b394d2016-08-21 23:11:46 +0900348 .withProtocol(protocol)
349 .withIpTos(ipTos)
350 .withLocalPortLow(localPortLow)
351 .withLocalPortHigh(localPortHigh)
352 .withRemotePortLow(remotePortLow)
353 .withRemotePortHigh(remotePortHigh)
354 .withAddress(address)
355 .build();
Jian Li115d8602016-08-15 20:21:53 +0900356 }
357
358 /**
Jian Li76ea0572016-08-29 12:41:16 +0900359 * An utility function that obtains the partial int value from byte arrays.
Jian Li115d8602016-08-15 20:21:53 +0900360 *
361 * @param bytes an array of bytes
362 * @return converted integer
363 */
364 public static int getPartialInt(byte[] bytes) {
365 ByteBuffer buffer = ByteBuffer.allocate(4);
366 buffer.position(4 - bytes.length);
367 buffer.put(bytes);
368 buffer.position(0);
369 return buffer.getInt();
370 }
371 }
GUNiba871702016-08-22 21:06:02 +0900372
373 /**
374 * Application data LCAF address writer class.
375 */
376 public static class AppDataLcafAddressWriter
377 implements LispAddressWriter<LispAppDataLcafAddress> {
378
379 @Override
380 public void writeTo(ByteBuf byteBuf, LispAppDataLcafAddress address)
381 throws LispWriterException {
382
Jian Lief0f7232016-11-15 19:55:46 +0900383 int lcafIndex = byteBuf.writerIndex();
GUNiba871702016-08-22 21:06:02 +0900384 LispLcafAddress.serializeCommon(byteBuf, address);
385
Jian Li76ea0572016-08-29 12:41:16 +0900386 byte[] tos = getPartialByteArray(address.getIpTos());
387 byteBuf.writeBytes(tos);
GUNiba871702016-08-22 21:06:02 +0900388 byteBuf.writeByte(address.getProtocol());
389 byteBuf.writeShort(address.getLocalPortLow());
390 byteBuf.writeShort(address.getLocalPortHigh());
391 byteBuf.writeShort(address.getRemotePortLow());
392 byteBuf.writeShort(address.getRemotePortHigh());
393
Jian Lif31019a2017-02-05 07:57:46 +0900394 LispAfiAddress.AfiAddressWriter writer = new LispAfiAddress.AfiAddressWriter();
GUNiba871702016-08-22 21:06:02 +0900395 writer.writeTo(byteBuf, address.getAddress());
Jian Lief0f7232016-11-15 19:55:46 +0900396
397 LispLcafAddress.updateLength(lcafIndex, byteBuf);
GUNiba871702016-08-22 21:06:02 +0900398 }
Jian Li76ea0572016-08-29 12:41:16 +0900399
400 /**
401 * An utility function that obtains byte array from partial int value.
402 *
403 * @param value integer value
404 * @return an array of bytes
405 */
406 public static byte[] getPartialByteArray(int value) {
407 ByteBuffer buffer = ByteBuffer.allocate(4);
408 byte[] array = buffer.putInt(value).array();
409 return Arrays.copyOfRange(array, 1, 4);
410 }
GUNiba871702016-08-22 21:06:02 +0900411 }
Jian Lic7e20a52016-07-18 19:03:49 +0900412}