blob: 9493911c2eed866f26b246a9953d0bc0e80f9c73 [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 Li115d8602016-08-15 20:21:53 +090063 * @param protocol protocol number
64 * @param ipTos IP type of service
65 * @param localPortLow low-ranged local port number
66 * @param localPortHigh high-ranged local port number
67 * @param remotePortLow low-ranged remote port number
68 * @param remotePortHigh high-ranged remote port number
69 * @param address address
Jian Lic7e20a52016-07-18 19:03:49 +090070 */
Jian Li115d8602016-08-15 20:21:53 +090071 private LispAppDataLcafAddress(byte protocol, int ipTos, short localPortLow,
72 short localPortHigh, short remotePortLow,
73 short remotePortHigh, LispAfiAddress address) {
Jian Lic7e20a52016-07-18 19:03:49 +090074 super(LispCanonicalAddressFormatEnum.APPLICATION_DATA);
75 this.protocol = protocol;
76 this.ipTos = ipTos;
Jian Li115d8602016-08-15 20:21:53 +090077 this.localPortLow = localPortLow;
78 this.localPortHigh = localPortHigh;
79 this.remotePortLow = remotePortLow;
80 this.remotePortHigh = remotePortHigh;
Jian Lic7e20a52016-07-18 19:03:49 +090081 this.address = address;
82 }
83
84 /**
85 * Obtains protocol number.
86 *
87 * @return protocol number
88 */
89 public byte getProtocol() {
90 return protocol;
91 }
92
93 /**
94 * Obtains IP type of service.
95 *
96 * @return IP type of service
97 */
98 public int getIpTos() {
99 return ipTos;
100 }
101
102 /**
Jian Li115d8602016-08-15 20:21:53 +0900103 * Obtains low-ranged local port number.
Jian Lic7e20a52016-07-18 19:03:49 +0900104 *
Jian Li115d8602016-08-15 20:21:53 +0900105 * @return low-ranged local port number
Jian Lic7e20a52016-07-18 19:03:49 +0900106 */
Jian Li115d8602016-08-15 20:21:53 +0900107 public short getLocalPortLow() {
108 return localPortLow;
Jian Lic7e20a52016-07-18 19:03:49 +0900109 }
110
111 /**
Jian Li115d8602016-08-15 20:21:53 +0900112 * Obtains high-ranged local port number.
Jian Lic7e20a52016-07-18 19:03:49 +0900113 *
Jian Li115d8602016-08-15 20:21:53 +0900114 * @return high-ranged local port number
Jian Lic7e20a52016-07-18 19:03:49 +0900115 */
Jian Li115d8602016-08-15 20:21:53 +0900116 public short getLocalPortHigh() {
117 return localPortHigh;
118 }
119
120 /**
121 * Obtains low-ranged remote port number.
122 *
123 * @return low-ranged remote port number
124 */
125 public short getRemotePortLow() {
126 return remotePortLow;
127 }
128
129 /**
130 * Obtains high-ranged remote port number.
131 *
132 * @return high-ranged remote port number
133 */
134 public short getRemotePortHigh() {
135 return remotePortHigh;
Jian Lic7e20a52016-07-18 19:03:49 +0900136 }
137
138 /**
139 * Obtains address.
140 *
141 * @return address
142 */
143 public LispAfiAddress getAddress() {
144 return address;
145 }
146
147 @Override
148 public int hashCode() {
Jian Li115d8602016-08-15 20:21:53 +0900149 return Objects.hash(address, protocol, ipTos, localPortLow,
150 localPortHigh, remotePortLow, remotePortHigh);
Jian Lic7e20a52016-07-18 19:03:49 +0900151 }
152
153 @Override
154 public boolean equals(Object obj) {
155 if (this == obj) {
156 return true;
157 }
158
159 if (obj instanceof LispAppDataLcafAddress) {
160 final LispAppDataLcafAddress other = (LispAppDataLcafAddress) obj;
161 return Objects.equals(this.address, other.address) &&
162 Objects.equals(this.protocol, other.protocol) &&
163 Objects.equals(this.ipTos, other.ipTos) &&
Jian Li115d8602016-08-15 20:21:53 +0900164 Objects.equals(this.localPortLow, other.localPortLow) &&
165 Objects.equals(this.localPortHigh, other.localPortHigh) &&
166 Objects.equals(this.remotePortLow, other.remotePortLow) &&
167 Objects.equals(this.remotePortHigh, other.remotePortHigh);
Jian Lic7e20a52016-07-18 19:03:49 +0900168 }
169 return false;
170 }
171
172 @Override
173 public String toString() {
174 return toStringHelper(this)
175 .add("address", address)
176 .add("protocol", protocol)
177 .add("ip type of service", ipTos)
Jian Li115d8602016-08-15 20:21:53 +0900178 .add("low-ranged local port number", localPortLow)
179 .add("high-ranged local port number", localPortHigh)
180 .add("low-ranged remote port number", remotePortLow)
181 .add("high-ranged remote port number", remotePortHigh)
Jian Lic7e20a52016-07-18 19:03:49 +0900182 .toString();
183 }
Jian Li115d8602016-08-15 20:21:53 +0900184
185 public static final class AppDataAddressBuilder {
186 private byte protocol;
187 private int ipTos;
188 private short localPortLow;
189 private short localPortHigh;
190 private short remotePortLow;
191 private short remotePortHigh;
192 private LispAfiAddress address;
193
194 /**
195 * Sets protocol number.
196 *
197 * @param protocol protocol number
198 * @return AppDataAddressBuilder object
199 */
200 AppDataAddressBuilder withProtocol(byte protocol) {
201 this.protocol = protocol;
202 return this;
203 }
204
205 /**
206 * Sets IP type of service.
207 *
208 * @param ipTos IP type of service
209 * @return AppDataAddressBuilder object
210 */
211 AppDataAddressBuilder withIpTos(int ipTos) {
212 this.ipTos = ipTos;
213 return this;
214 }
215
216 /**
217 * Sets low-ranged local port number.
218 *
219 * @param localPortLow low-ranged local port number
220 * @return AppDataAddressBuilder object
221 */
222 AppDataAddressBuilder withLocalPortLow(short localPortLow) {
223 this.localPortLow = localPortLow;
224 return this;
225 }
226
227 /**
228 * Sets high-ranged local port number.
229 *
230 * @param localPortHigh high-ranged local port number
231 * @return AppDataAddressBuilder object
232 */
233 AppDataAddressBuilder withLocalPortHigh(short localPortHigh) {
234 this.localPortHigh = localPortHigh;
235 return this;
236 }
237
238 /**
239 * Sets low-ranged remote port number.
240 *
241 * @param remotePortLow low-ranged remote port number
242 * @return AppDataAddressBuilder object
243 */
244 AppDataAddressBuilder withRemotePortLow(short remotePortLow) {
245 this.remotePortLow = remotePortLow;
246 return this;
247 }
248
249 /**
250 * Sets high-ranged remote port number.
251 *
252 * @param remotePortHigh high-ranged remote port number
253 * @return AppDataAddressBuilder object
254 */
255 AppDataAddressBuilder withRemotePortHigh(short remotePortHigh) {
256 this.remotePortHigh = remotePortHigh;
257 return this;
258 }
259
260 /**
261 * Sets AFI address.
262 *
263 * @param address AFI address
264 * @return AppDataAddressBuilder object
265 */
266 AppDataAddressBuilder withAddress(LispAfiAddress address) {
267 this.address = address;
268 return this;
269 }
270
271 /**
272 * Builds LispAppDataLcafAddress instance.
273 *
274 * @return LispAddDataLcafAddress instance
275 */
276 LispAppDataLcafAddress build() {
277 return new LispAppDataLcafAddress(protocol, ipTos, localPortLow,
278 localPortHigh, remotePortLow, remotePortHigh, address);
279 }
280 }
281
282 /**
283 * Application data LCAF address reader class.
284 */
285 public static class AppDataLcafAddressReader
286 implements LispAddressReader<LispAppDataLcafAddress> {
287
288 @Override
289 public LispAppDataLcafAddress readFrom(ByteBuf byteBuf) throws LispParseError, LispReaderException {
290
291 byte[] ipTosByte = new byte[3];
292 byteBuf.readBytes(ipTosByte);
293
294 byte protocol = (byte) byteBuf.readUnsignedByte();
295 int ipTos = getPartialInt(ipTosByte);
296 short localPortLow = (short) byteBuf.readUnsignedShort();
297 short localPortHigh = (short) byteBuf.readUnsignedShort();
298 short remotePortLow = (short) byteBuf.readUnsignedShort();
299 short remotePortHigh = (short) byteBuf.readUnsignedShort();
300
301 LispAfiAddress address = new LispIpAddress.IpAddressReader().readFrom(byteBuf);
302
303 return new AppDataAddressBuilder()
304 .withProtocol(protocol)
305 .withIpTos(ipTos)
306 .withLocalPortLow(localPortLow)
307 .withLocalPortHigh(localPortHigh)
308 .withRemotePortLow(remotePortLow)
309 .withRemotePortHigh(remotePortHigh)
310 .withAddress(address)
311 .build();
312 }
313
314 /**
315 * A utility function that obtains the partial int value from byte arrays.
316 *
317 * @param bytes an array of bytes
318 * @return converted integer
319 */
320 public static int getPartialInt(byte[] bytes) {
321 ByteBuffer buffer = ByteBuffer.allocate(4);
322 buffer.position(4 - bytes.length);
323 buffer.put(bytes);
324 buffer.position(0);
325 return buffer.getInt();
326 }
327 }
Jian Lic7e20a52016-07-18 19:03:49 +0900328}