blob: 284ebe4c15490667fc0504ea3a46243246f233e1 [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;
GUNiba871702016-08-22 21:06:02 +090021import org.onosproject.lisp.msg.exceptions.LispWriterException;
Jian Li115d8602016-08-15 20:21:53 +090022
23import java.nio.ByteBuffer;
Jian Lic7e20a52016-07-18 19:03:49 +090024import java.util.Objects;
25
26import static com.google.common.base.MoreObjects.toStringHelper;
27
28/**
29 * Application data type LCAF address class.
Jian Li8fc2d2f2016-08-08 14:43:53 +090030 * <p>
Jian Lic7e20a52016-07-18 19:03:49 +090031 * Application data type is defined in draft-ietf-lisp-lcaf-13
32 * https://tools.ietf.org/html/draft-ietf-lisp-lcaf-13#page-26
33 *
Jian Li8fc2d2f2016-08-08 14:43:53 +090034 * <pre>
35 * {@literal
Jian Lic7e20a52016-07-18 19:03:49 +090036 * 0 1 2 3
37 * 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
38 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
39 * | AFI = 16387 | Rsvd1 | Flags |
40 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
41 * | Type = 4 | Rsvd2 | 12 + n |
42 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
43 * | IP TOS, IPv6 TC, or Flow Label | Protocol |
44 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
45 * | Local Port (lower-range) | Local Port (upper-range) |
46 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
47 * | Remote Port (lower-range) | Remote Port (upper-range) |
48 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
49 * | AFI = x | Address ... |
50 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Jian Li8fc2d2f2016-08-08 14:43:53 +090051 * }</pre>
Jian Lic7e20a52016-07-18 19:03:49 +090052 */
Jian Li115d8602016-08-15 20:21:53 +090053public final class LispAppDataLcafAddress extends LispLcafAddress {
Jian Lic7e20a52016-07-18 19:03:49 +090054
55 private final byte protocol;
56 private final int ipTos;
Jian Li115d8602016-08-15 20:21:53 +090057 private final short localPortLow;
58 private final short localPortHigh;
59 private final short remotePortLow;
60 private final short remotePortHigh;
Jian Lic7e20a52016-07-18 19:03:49 +090061 private LispAfiAddress address;
62
63 /**
Jian Lia7b394d2016-08-21 23:11:46 +090064 * Initializes application data type LCAF address.
65 *
Jian Li115d8602016-08-15 20:21:53 +090066 * @param protocol protocol number
67 * @param ipTos IP type of service
68 * @param localPortLow low-ranged local port number
69 * @param localPortHigh high-ranged local port number
70 * @param remotePortLow low-ranged remote port number
71 * @param remotePortHigh high-ranged remote port number
72 * @param address address
Jian Lic7e20a52016-07-18 19:03:49 +090073 */
Jian Li115d8602016-08-15 20:21:53 +090074 private LispAppDataLcafAddress(byte protocol, int ipTos, short localPortLow,
75 short localPortHigh, short remotePortLow,
76 short remotePortHigh, LispAfiAddress address) {
Jian Lic7e20a52016-07-18 19:03:49 +090077 super(LispCanonicalAddressFormatEnum.APPLICATION_DATA);
78 this.protocol = protocol;
79 this.ipTos = ipTos;
Jian Li115d8602016-08-15 20:21:53 +090080 this.localPortLow = localPortLow;
81 this.localPortHigh = localPortHigh;
82 this.remotePortLow = remotePortLow;
83 this.remotePortHigh = remotePortHigh;
Jian Lic7e20a52016-07-18 19:03:49 +090084 this.address = address;
85 }
86
87 /**
Jian Lia7b394d2016-08-21 23:11:46 +090088 * Initializes application data type LCAF address.
89 *
90 * @param reserved1 reserved1
91 * @param reserved2 reserved2
92 * @param flag flag
93 * @param length length
94 * @param protocol protocol number
95 * @param ipTos IP type of service
96 * @param localPortLow low-ranged local port number
97 * @param localPortHigh high-ranged local port number
98 * @param remotePortLow low-ranged remote port number
99 * @param remotePortHigh high-ranged remote port number
100 * @param address address
101 */
102 private LispAppDataLcafAddress(byte reserved1, byte reserved2, byte flag, short length,
103 byte protocol, int ipTos, short localPortLow,
104 short localPortHigh, short remotePortLow,
105 short remotePortHigh, LispAfiAddress address) {
106 super(LispCanonicalAddressFormatEnum.APPLICATION_DATA, reserved1, reserved2, flag, length);
107 this.protocol = protocol;
108 this.ipTos = ipTos;
109 this.localPortLow = localPortLow;
110 this.localPortHigh = localPortHigh;
111 this.remotePortLow = remotePortLow;
112 this.remotePortHigh = remotePortHigh;
113 this.address = address;
114 }
115
116 /**
Jian Lic7e20a52016-07-18 19:03:49 +0900117 * Obtains protocol number.
118 *
119 * @return protocol number
120 */
121 public byte getProtocol() {
122 return protocol;
123 }
124
125 /**
126 * Obtains IP type of service.
127 *
128 * @return IP type of service
129 */
130 public int getIpTos() {
131 return ipTos;
132 }
133
134 /**
Jian Li115d8602016-08-15 20:21:53 +0900135 * Obtains low-ranged local port number.
Jian Lic7e20a52016-07-18 19:03:49 +0900136 *
Jian Li115d8602016-08-15 20:21:53 +0900137 * @return low-ranged local port number
Jian Lic7e20a52016-07-18 19:03:49 +0900138 */
Jian Li115d8602016-08-15 20:21:53 +0900139 public short getLocalPortLow() {
140 return localPortLow;
Jian Lic7e20a52016-07-18 19:03:49 +0900141 }
142
143 /**
Jian Li115d8602016-08-15 20:21:53 +0900144 * Obtains high-ranged local port number.
Jian Lic7e20a52016-07-18 19:03:49 +0900145 *
Jian Li115d8602016-08-15 20:21:53 +0900146 * @return high-ranged local port number
Jian Lic7e20a52016-07-18 19:03:49 +0900147 */
Jian Li115d8602016-08-15 20:21:53 +0900148 public short getLocalPortHigh() {
149 return localPortHigh;
150 }
151
152 /**
153 * Obtains low-ranged remote port number.
154 *
155 * @return low-ranged remote port number
156 */
157 public short getRemotePortLow() {
158 return remotePortLow;
159 }
160
161 /**
162 * Obtains high-ranged remote port number.
163 *
164 * @return high-ranged remote port number
165 */
166 public short getRemotePortHigh() {
167 return remotePortHigh;
Jian Lic7e20a52016-07-18 19:03:49 +0900168 }
169
170 /**
171 * Obtains address.
172 *
173 * @return address
174 */
175 public LispAfiAddress getAddress() {
176 return address;
177 }
178
179 @Override
180 public int hashCode() {
Jian Li115d8602016-08-15 20:21:53 +0900181 return Objects.hash(address, protocol, ipTos, localPortLow,
182 localPortHigh, remotePortLow, remotePortHigh);
Jian Lic7e20a52016-07-18 19:03:49 +0900183 }
184
185 @Override
186 public boolean equals(Object obj) {
187 if (this == obj) {
188 return true;
189 }
190
191 if (obj instanceof LispAppDataLcafAddress) {
192 final LispAppDataLcafAddress other = (LispAppDataLcafAddress) obj;
193 return Objects.equals(this.address, other.address) &&
194 Objects.equals(this.protocol, other.protocol) &&
195 Objects.equals(this.ipTos, other.ipTos) &&
Jian Li115d8602016-08-15 20:21:53 +0900196 Objects.equals(this.localPortLow, other.localPortLow) &&
197 Objects.equals(this.localPortHigh, other.localPortHigh) &&
198 Objects.equals(this.remotePortLow, other.remotePortLow) &&
199 Objects.equals(this.remotePortHigh, other.remotePortHigh);
Jian Lic7e20a52016-07-18 19:03:49 +0900200 }
201 return false;
202 }
203
204 @Override
205 public String toString() {
206 return toStringHelper(this)
207 .add("address", address)
208 .add("protocol", protocol)
209 .add("ip type of service", ipTos)
Jian Li115d8602016-08-15 20:21:53 +0900210 .add("low-ranged local port number", localPortLow)
211 .add("high-ranged local port number", localPortHigh)
212 .add("low-ranged remote port number", remotePortLow)
213 .add("high-ranged remote port number", remotePortHigh)
Jian Lic7e20a52016-07-18 19:03:49 +0900214 .toString();
215 }
Jian Li115d8602016-08-15 20:21:53 +0900216
Jian Lia7b394d2016-08-21 23:11:46 +0900217 public static final class AppDataAddressBuilder
218 extends LcafAddressBuilder<AppDataAddressBuilder> {
Jian Li115d8602016-08-15 20:21:53 +0900219 private byte protocol;
220 private int ipTos;
221 private short localPortLow;
222 private short localPortHigh;
223 private short remotePortLow;
224 private short remotePortHigh;
225 private LispAfiAddress address;
226
227 /**
228 * Sets protocol number.
229 *
230 * @param protocol protocol number
231 * @return AppDataAddressBuilder object
232 */
Jian Lia7b394d2016-08-21 23:11:46 +0900233 public AppDataAddressBuilder withProtocol(byte protocol) {
Jian Li115d8602016-08-15 20:21:53 +0900234 this.protocol = protocol;
235 return this;
236 }
237
238 /**
239 * Sets IP type of service.
240 *
241 * @param ipTos IP type of service
242 * @return AppDataAddressBuilder object
243 */
Jian Lia7b394d2016-08-21 23:11:46 +0900244 public AppDataAddressBuilder withIpTos(int ipTos) {
Jian Li115d8602016-08-15 20:21:53 +0900245 this.ipTos = ipTos;
246 return this;
247 }
248
249 /**
250 * Sets low-ranged local port number.
251 *
252 * @param localPortLow low-ranged local port number
253 * @return AppDataAddressBuilder object
254 */
Jian Lia7b394d2016-08-21 23:11:46 +0900255 public AppDataAddressBuilder withLocalPortLow(short localPortLow) {
Jian Li115d8602016-08-15 20:21:53 +0900256 this.localPortLow = localPortLow;
257 return this;
258 }
259
260 /**
261 * Sets high-ranged local port number.
262 *
263 * @param localPortHigh high-ranged local port number
264 * @return AppDataAddressBuilder object
265 */
Jian Lia7b394d2016-08-21 23:11:46 +0900266 public AppDataAddressBuilder withLocalPortHigh(short localPortHigh) {
Jian Li115d8602016-08-15 20:21:53 +0900267 this.localPortHigh = localPortHigh;
268 return this;
269 }
270
271 /**
272 * Sets low-ranged remote port number.
273 *
274 * @param remotePortLow low-ranged remote port number
275 * @return AppDataAddressBuilder object
276 */
Jian Lia7b394d2016-08-21 23:11:46 +0900277 public AppDataAddressBuilder withRemotePortLow(short remotePortLow) {
Jian Li115d8602016-08-15 20:21:53 +0900278 this.remotePortLow = remotePortLow;
279 return this;
280 }
281
282 /**
283 * Sets high-ranged remote port number.
284 *
285 * @param remotePortHigh high-ranged remote port number
286 * @return AppDataAddressBuilder object
287 */
Jian Lia7b394d2016-08-21 23:11:46 +0900288 public AppDataAddressBuilder withRemotePortHigh(short remotePortHigh) {
Jian Li115d8602016-08-15 20:21:53 +0900289 this.remotePortHigh = remotePortHigh;
290 return this;
291 }
292
293 /**
294 * Sets AFI address.
295 *
296 * @param address AFI address
297 * @return AppDataAddressBuilder object
298 */
Jian Lia7b394d2016-08-21 23:11:46 +0900299 public AppDataAddressBuilder withAddress(LispAfiAddress address) {
Jian Li115d8602016-08-15 20:21:53 +0900300 this.address = address;
301 return this;
302 }
303
304 /**
305 * Builds LispAppDataLcafAddress instance.
306 *
307 * @return LispAddDataLcafAddress instance
308 */
Jian Lia7b394d2016-08-21 23:11:46 +0900309 public LispAppDataLcafAddress build() {
310 return new LispAppDataLcafAddress(reserved1, reserved2, flag, length,
311 protocol, ipTos, localPortLow, localPortHigh, remotePortLow,
312 remotePortHigh, address);
Jian Li115d8602016-08-15 20:21:53 +0900313 }
314 }
315
316 /**
317 * Application data LCAF address reader class.
318 */
319 public static class AppDataLcafAddressReader
320 implements LispAddressReader<LispAppDataLcafAddress> {
321
322 @Override
323 public LispAppDataLcafAddress readFrom(ByteBuf byteBuf) throws LispParseError, LispReaderException {
324
Jian Lia7b394d2016-08-21 23:11:46 +0900325 LispLcafAddress lcafAddress = LispLcafAddress.deserializeCommon(byteBuf);
326
Jian Li115d8602016-08-15 20:21:53 +0900327 byte[] ipTosByte = new byte[3];
328 byteBuf.readBytes(ipTosByte);
329
330 byte protocol = (byte) byteBuf.readUnsignedByte();
331 int ipTos = getPartialInt(ipTosByte);
332 short localPortLow = (short) byteBuf.readUnsignedShort();
333 short localPortHigh = (short) byteBuf.readUnsignedShort();
334 short remotePortLow = (short) byteBuf.readUnsignedShort();
335 short remotePortHigh = (short) byteBuf.readUnsignedShort();
336
Jian Lia7b394d2016-08-21 23:11:46 +0900337 LispAfiAddress address = new LispAfiAddress.AfiAddressReader().readFrom(byteBuf);
Jian Li115d8602016-08-15 20:21:53 +0900338
339 return new AppDataAddressBuilder()
Jian Lia7b394d2016-08-21 23:11:46 +0900340 .withReserved1(lcafAddress.getReserved1())
341 .withReserved2(lcafAddress.getReserved2())
342 .withFlag(lcafAddress.getFlag())
343 .withLength(lcafAddress.getLength())
344 .withProtocol(protocol)
345 .withIpTos(ipTos)
346 .withLocalPortLow(localPortLow)
347 .withLocalPortHigh(localPortHigh)
348 .withRemotePortLow(remotePortLow)
349 .withRemotePortHigh(remotePortHigh)
350 .withAddress(address)
351 .build();
Jian Li115d8602016-08-15 20:21:53 +0900352 }
353
354 /**
355 * A utility function that obtains the partial int value from byte arrays.
356 *
357 * @param bytes an array of bytes
358 * @return converted integer
359 */
360 public static int getPartialInt(byte[] bytes) {
361 ByteBuffer buffer = ByteBuffer.allocate(4);
362 buffer.position(4 - bytes.length);
363 buffer.put(bytes);
364 buffer.position(0);
365 return buffer.getInt();
366 }
367 }
GUNiba871702016-08-22 21:06:02 +0900368
369 /**
370 * Application data LCAF address writer class.
371 */
372 public static class AppDataLcafAddressWriter
373 implements LispAddressWriter<LispAppDataLcafAddress> {
374
375 @Override
376 public void writeTo(ByteBuf byteBuf, LispAppDataLcafAddress address)
377 throws LispWriterException {
378
379 LispLcafAddress.serializeCommon(byteBuf, address);
380
381 // TODO: need to handle TOS
382
383 byteBuf.writeByte(address.getProtocol());
384 byteBuf.writeShort(address.getLocalPortLow());
385 byteBuf.writeShort(address.getLocalPortHigh());
386 byteBuf.writeShort(address.getRemotePortLow());
387 byteBuf.writeShort(address.getRemotePortHigh());
388
389 AfiAddressWriter writer = new LispAfiAddress.AfiAddressWriter();
390 writer.writeTo(byteBuf, address.getAddress());
391 }
392 }
Jian Lic7e20a52016-07-18 19:03:49 +0900393}