blob: 318eb1b3da56dedc668fe3d024e313f43bda3df3 [file] [log] [blame]
mohamed rahile04626f2016-04-05 20:42:53 +05301/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2016-present Open Networking Laboratory
mohamed rahile04626f2016-04-05 20:42:53 +05303 *
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.isis.io.util;
17
mohamed rahile04626f2016-04-05 20:42:53 +053018import com.google.common.primitives.Bytes;
sunishvka1dfc3e2016-04-16 12:24:47 +053019import org.onlab.packet.Ip4Address;
mohamed rahile04626f2016-04-05 20:42:53 +053020import org.onosproject.isis.io.isispacket.tlv.PaddingTlv;
21import org.onosproject.isis.io.isispacket.tlv.TlvHeader;
sunishvka1dfc3e2016-04-16 12:24:47 +053022import org.onosproject.isis.io.isispacket.tlv.TlvType;
23import org.slf4j.Logger;
24import org.slf4j.LoggerFactory;
mohamed rahile04626f2016-04-05 20:42:53 +053025
26import javax.xml.bind.DatatypeConverter;
27import java.util.ArrayList;
28import java.util.List;
29import java.util.StringTokenizer;
30
31/**
sunishvka1dfc3e2016-04-16 12:24:47 +053032 * Representation of ISIS utils.
mohamed rahile04626f2016-04-05 20:42:53 +053033 */
34public final class IsisUtil {
sunishvka1dfc3e2016-04-16 12:24:47 +053035 public static final int ETHER_HEADER_LEN = 17;
mohamed rahile04626f2016-04-05 20:42:53 +053036 public static final int ID_SIX_BYTES = 6;
37 public static final int ID_PLUS_ONE_BYTE = 7;
38 public static final int ID_PLUS_TWO_BYTE = 8;
39 public static final int THREE_BYTES = 3;
40 public static final int SIX_BYTES = 6;
sunishvka1dfc3e2016-04-16 12:24:47 +053041 public static final int EIGHT_BYTES = 8;
mohamed rahile04626f2016-04-05 20:42:53 +053042 public static final int FOUR_BYTES = 4;
43 public static final int PADDING_FIXED_LENGTH = 255;
sunishvka1dfc3e2016-04-16 12:24:47 +053044 public static final int TLVHEADERLENGTH = 2;
45 public static final int INITIAL_BANDWIDTH = 12500000;
46 private static final Logger log = LoggerFactory.getLogger(IsisUtil.class);
mohamed rahile04626f2016-04-05 20:42:53 +053047
48 /**
sunishvka1dfc3e2016-04-16 12:24:47 +053049 * Creates an instance.
mohamed rahile04626f2016-04-05 20:42:53 +053050 */
51 private IsisUtil() {
52
53 }
54
55 /**
sunishvka1dfc3e2016-04-16 12:24:47 +053056 * Checks given IPs are in same network or not.
57 *
58 * @param ip1 IP address
59 * @param ip2 IP address
60 * @param mask network mask
61 * @return true if both are in same network else false
62 */
63 public static boolean sameNetwork(Ip4Address ip1, Ip4Address ip2, byte[] mask) {
64 try {
65 byte[] a1 = ip1.toOctets();
66 byte[] a2 = ip2.toOctets();
67 for (int i = 0; i < a1.length; i++) {
68 if ((a1[i] & mask[i]) != (a2[i] & mask[i])) {
69 return false;
70 }
71 }
72 } catch (Exception e) {
73 log.debug("Exception::IsisUtil::sameNetwork:: {}", e.getMessage());
74 }
75 return true;
76 }
77
78 /**
mohamed rahile04626f2016-04-05 20:42:53 +053079 * Parse byte array to string system ID.
80 *
81 * @param bytes system ID
sunishvka1dfc3e2016-04-16 12:24:47 +053082 * @return systemId system ID
mohamed rahile04626f2016-04-05 20:42:53 +053083 */
84 public static String systemId(byte[] bytes) {
85 String systemId = "";
86 for (Byte byt : bytes) {
87 String hexa = Integer.toHexString(Byte.toUnsignedInt(byt));
88 if (hexa.length() % 2 != 0) {
89 hexa = "0" + hexa;
90 }
91 systemId = systemId + hexa;
92 if (systemId.length() == 4 || systemId.length() == 9) {
93 systemId = systemId + ".";
94 }
95 }
96 return systemId;
97 }
98
99 /**
100 * Parse byte array to LAN ID.
101 *
102 * @param bytes LAN ID
sunishvka1dfc3e2016-04-16 12:24:47 +0530103 * @return systemIdPlus system ID
mohamed rahile04626f2016-04-05 20:42:53 +0530104 */
105 public static String systemIdPlus(byte[] bytes) {
106 String systemId = "";
107 for (Byte byt : bytes) {
108 String hexa = Integer.toHexString(Byte.toUnsignedInt(byt));
109 if (hexa.length() % 2 != 0) {
110 hexa = "0" + hexa;
111 }
112 systemId = systemId + hexa;
113 if (systemId.length() == 4 || systemId.length() == 9
114 || systemId.length() == 14) {
115 systemId = systemId + ".";
116 }
117 }
118 return systemId;
119 }
120
121 /**
122 * Parse byte array to area address.
123 *
124 * @param bytes area address
sunishvka1dfc3e2016-04-16 12:24:47 +0530125 * @return areaAddres area address
mohamed rahile04626f2016-04-05 20:42:53 +0530126 */
127 public static String areaAddres(byte[] bytes) {
sunishvka1dfc3e2016-04-16 12:24:47 +0530128 String areaAddres = "";
mohamed rahile04626f2016-04-05 20:42:53 +0530129 for (Byte byt : bytes) {
130 String hexa = Integer.toHexString(Byte.toUnsignedInt(byt));
131 if (hexa.length() % 2 != 0) {
132 hexa = "0" + hexa;
133 }
sunishvka1dfc3e2016-04-16 12:24:47 +0530134 areaAddres = areaAddres + hexa;
mohamed rahile04626f2016-04-05 20:42:53 +0530135 }
sunishvka1dfc3e2016-04-16 12:24:47 +0530136 return areaAddres;
mohamed rahile04626f2016-04-05 20:42:53 +0530137 }
138
139 /**
140 * Parse area address to bytes.
141 *
142 * @param address area address
143 * @return areaAddress area address
144 */
sunishvka1dfc3e2016-04-16 12:24:47 +0530145 public static List<Byte> areaAddressToBytes(String address) {
146 List<Byte> idList = new ArrayList<>();
147 for (int i = 0; i < address.length(); i = i + 2) {
148 Character c1 = address.charAt(i);
149 Character c2 = address.charAt(i + 1);
150 String str = c1.toString() + c2.toString();
151 idList.add((byte) Integer.parseInt(str, 16));
mohamed rahile04626f2016-04-05 20:42:53 +0530152 }
sunishvka1dfc3e2016-04-16 12:24:47 +0530153 return idList;
mohamed rahile04626f2016-04-05 20:42:53 +0530154 }
155
156 /**
sunishvka1dfc3e2016-04-16 12:24:47 +0530157 * Adds the PDU length in packet.
mohamed rahile04626f2016-04-05 20:42:53 +0530158 *
sunishvka1dfc3e2016-04-16 12:24:47 +0530159 * @param isisPacket ISIS packet
160 * @param lengthBytePos1 length byte position
161 * @param lengthBytePos2 length byte position
162 * @param reservedBytePos reserved byte position
163 * @return byte array with PDU length
mohamed rahile04626f2016-04-05 20:42:53 +0530164 */
sunishvka1dfc3e2016-04-16 12:24:47 +0530165 public static byte[] addLengthAndMarkItInReserved(byte[] isisPacket, int lengthBytePos1,
166 int lengthBytePos2, int reservedBytePos) {
167 //Set the length of the packet
168 //Get the total length of the packet
169 int length = isisPacket.length;
170 //Convert the lenth to two bytes as the length field is 2 bytes
171 byte[] lenthInTwoBytes = IsisUtil.convertToTwoBytes(length);
172 //isis header 3rd and 4th position represents length
173 isisPacket[lengthBytePos1] = lenthInTwoBytes[0]; //assign 1st byte in lengthBytePos1
174 isisPacket[lengthBytePos2] = lenthInTwoBytes[1]; //assign 2st byte in lengthBytePos2
175 isisPacket[reservedBytePos] = (byte) lengthBytePos1;
176 return isisPacket;
177 }
178
179 /**
180 * Adds the checksum in packet.
181 *
182 * @param isisPacket ISIS packet
183 * @param checksumBytePos1 checksum byte position
184 * @param checksumBytePos2 checksum byte position
185 * @return byte array with PDU length
186 */
187 public static byte[] addChecksum(byte[] isisPacket, int checksumBytePos1, int checksumBytePos2) {
188 //Set the checksum for the packet
189 //Convert the lenth to two bytes as the length field is 2 bytes
190 byte[] checksumInTwoBytes = new ChecksumCalculator().calculateLspChecksum(
191 isisPacket, checksumBytePos1, checksumBytePos2);
192 //isis header 3rd and 4th position represents length
193 isisPacket[checksumBytePos1] = checksumInTwoBytes[0];
194 isisPacket[checksumBytePos2] = checksumInTwoBytes[1];
195 return isisPacket;
196 }
197
198 /**
199 * Adds frame a packet of 1498 of size.
200 *
201 * @param isisPacket ISIS packet
202 * @param interfaceIndex interface index
203 * @return byte array with 1498 is the length
204 */
205 public static byte[] framePacket(byte[] isisPacket, int interfaceIndex) {
206 //Set the length of the packet
207 //Get the total length of the packet
208 int length = isisPacket.length;
209 //PDU_LENGTH + 1 byte for interface index
210 if (length < IsisConstants.PDU_LENGTH + 1) {
211 byte[] bytes = new byte[IsisConstants.PDU_LENGTH + 1];
212 System.arraycopy(isisPacket, 0, bytes, 0, length);
213 bytes[IsisConstants.PDU_LENGTH] = (byte) interfaceIndex;
214 return bytes;
mohamed rahile04626f2016-04-05 20:42:53 +0530215 }
sunishvka1dfc3e2016-04-16 12:24:47 +0530216 return isisPacket;
mohamed rahile04626f2016-04-05 20:42:53 +0530217 }
218
219 /**
220 * Parse source and LAN ID.
221 *
222 * @param id source and LAN ID
sunishvka1dfc3e2016-04-16 12:24:47 +0530223 * @return source and LAN ID
mohamed rahile04626f2016-04-05 20:42:53 +0530224 */
225 public static List<Byte> sourceAndLanIdToBytes(String id) {
sunishvka1dfc3e2016-04-16 12:24:47 +0530226 List<Byte> idList = new ArrayList<>();
227 StringTokenizer tokenizer = new StringTokenizer(id, "." + "-");
mohamed rahile04626f2016-04-05 20:42:53 +0530228 while (tokenizer.hasMoreElements()) {
229 int i = 0;
230 String str = tokenizer.nextToken();
sunishvka1dfc3e2016-04-16 12:24:47 +0530231 idList.add((byte) Integer.parseInt(str.substring(0, i + 2), 16));
mohamed rahile04626f2016-04-05 20:42:53 +0530232 if (str.length() > 2) {
sunishvka1dfc3e2016-04-16 12:24:47 +0530233 idList.add((byte) Integer.parseInt(str.substring(i + 2, str.length()), 16));
mohamed rahile04626f2016-04-05 20:42:53 +0530234 }
mohamed rahile04626f2016-04-05 20:42:53 +0530235 }
sunishvka1dfc3e2016-04-16 12:24:47 +0530236 return idList;
mohamed rahile04626f2016-04-05 20:42:53 +0530237 }
238
239 /**
240 * Parse padding for PDU based on current length.
241 *
242 * @param currentLength current length
243 * @return byteArray padding array
244 */
sunishvka1dfc3e2016-04-16 12:24:47 +0530245 public static byte[] getPaddingTlvs(int currentLength) {
mohamed rahile04626f2016-04-05 20:42:53 +0530246 List<Byte> bytes = new ArrayList<>();
sunishvka1dfc3e2016-04-16 12:24:47 +0530247 while (IsisConstants.PDU_LENGTH > currentLength) {
248 int length = IsisConstants.PDU_LENGTH - currentLength;
mohamed rahile04626f2016-04-05 20:42:53 +0530249 TlvHeader tlvHeader = new TlvHeader();
sunishvka1dfc3e2016-04-16 12:24:47 +0530250 tlvHeader.setTlvType(TlvType.PADDING.value());
mohamed rahile04626f2016-04-05 20:42:53 +0530251 if (length >= PADDING_FIXED_LENGTH) {
252 tlvHeader.setTlvLength(PADDING_FIXED_LENGTH);
253 } else {
sunishvka1dfc3e2016-04-16 12:24:47 +0530254 tlvHeader.setTlvLength(IsisConstants.PDU_LENGTH - (currentLength + TLVHEADERLENGTH));
mohamed rahile04626f2016-04-05 20:42:53 +0530255 }
256 PaddingTlv tlv = new PaddingTlv(tlvHeader);
257 bytes.addAll(Bytes.asList(tlv.asBytes()));
sunishvka1dfc3e2016-04-16 12:24:47 +0530258 currentLength = currentLength + tlv.tlvLength() + TLVHEADERLENGTH;
mohamed rahile04626f2016-04-05 20:42:53 +0530259 }
260 byte[] byteArray = new byte[bytes.size()];
261 int i = 0;
262 for (byte byt : bytes) {
263 byteArray[i++] = byt;
264 }
265 return byteArray;
mohamed rahile04626f2016-04-05 20:42:53 +0530266 }
267
268 /**
269 * Converts an integer to two bytes.
270 *
271 * @param numberToConvert number to convert
272 * @return numInBytes given number as bytes
273 */
274 public static byte[] convertToTwoBytes(int numberToConvert) {
275
276 byte[] numInBytes = new byte[2];
277 String s1 = Integer.toHexString(numberToConvert);
278 if (s1.length() % 2 != 0) {
279 s1 = "0" + s1;
280 }
281 byte[] hexas = DatatypeConverter.parseHexBinary(s1);
282 if (hexas.length == 1) {
283 numInBytes[0] = 0;
284 numInBytes[1] = hexas[0];
285 } else {
286 numInBytes[0] = hexas[0];
287 numInBytes[1] = hexas[1];
288 }
289 return numInBytes;
290 }
291
292 /**
293 * Converts a number to four bytes.
294 *
295 * @param numberToConvert number to convert
296 * @return numInBytes given number as bytes
297 */
298 public static byte[] convertToFourBytes(int numberToConvert) {
299
300 byte[] numInBytes = new byte[4];
301 String s1 = Integer.toHexString(numberToConvert);
302 if (s1.length() % 2 != 0) {
303 s1 = "0" + s1;
304 }
305 byte[] hexas = DatatypeConverter.parseHexBinary(s1);
306 if (hexas.length == 1) {
307 numInBytes[0] = 0;
308 numInBytes[1] = 0;
309 numInBytes[2] = 0;
310 numInBytes[3] = hexas[0];
311 } else if (hexas.length == 2) {
312 numInBytes[0] = 0;
313 numInBytes[1] = 0;
314 numInBytes[2] = hexas[0];
315 numInBytes[3] = hexas[1];
316 } else if (hexas.length == 3) {
317 numInBytes[0] = 0;
318 numInBytes[1] = hexas[0];
319 numInBytes[2] = hexas[1];
320 numInBytes[3] = hexas[2];
321 } else {
322 numInBytes[0] = hexas[0];
323 numInBytes[1] = hexas[1];
324 numInBytes[2] = hexas[2];
325 numInBytes[3] = hexas[3];
326 }
327 return numInBytes;
328 }
329
sunishvka1dfc3e2016-04-16 12:24:47 +0530330 /**
331 * Converts a byte to integer variable.
332 *
333 * @param bytesToConvert bytes to convert
334 * @return integer representation of bytes
335 */
336 public static int byteToInteger(byte[] bytesToConvert) {
337 final StringBuilder builder = new StringBuilder();
338 for (byte eachByte : bytesToConvert) {
339 builder.append(String.format("%02x", eachByte));
340 }
341 int number = Integer.parseInt(builder.toString(), 16);
342 return number;
mohamed rahile04626f2016-04-05 20:42:53 +0530343 }
sunishvka1dfc3e2016-04-16 12:24:47 +0530344
345 /**
346 * Converts a byte to long variable.
347 *
348 * @param bytesToConvert bytes to convert
349 * @return long representation of bytes
350 */
351 public static long byteToLong(byte[] bytesToConvert) {
352 final StringBuilder builder = new StringBuilder();
353 for (byte eachByte : bytesToConvert) {
354 builder.append(String.format("%02x", eachByte));
355 }
356 long number = Long.parseLong(builder.toString(), 16);
357 return number;
358 }
359
360 /**
361 * Converts a number to four bytes.
362 *
363 * @param numberToConvert number to convert
364 * @return numInBytes given number as bytes
365 */
366 public static byte[] convertToFourBytes(long numberToConvert) {
367 byte[] numInBytes = new byte[4];
368 String s1 = Long.toHexString(numberToConvert);
369 if (s1.length() % 2 != 0) {
370 s1 = "0" + s1;
371 }
372 if (s1.length() == 16) {
373 s1 = s1.substring(8, s1.length());
374 }
375 byte[] hexas = DatatypeConverter.parseHexBinary(s1);
376 if (hexas.length == 1) {
377 numInBytes[0] = 0;
378 numInBytes[1] = 0;
379 numInBytes[2] = 0;
380 numInBytes[3] = hexas[0];
381 } else if (hexas.length == 2) {
382 numInBytes[0] = 0;
383 numInBytes[1] = 0;
384 numInBytes[2] = hexas[0];
385 numInBytes[3] = hexas[1];
386 } else if (hexas.length == 3) {
387 numInBytes[0] = 0;
388 numInBytes[1] = hexas[0];
389 numInBytes[2] = hexas[1];
390 numInBytes[3] = hexas[2];
391 } else {
392 numInBytes[0] = hexas[0];
393 numInBytes[1] = hexas[1];
394 numInBytes[2] = hexas[2];
395 numInBytes[3] = hexas[3];
396 }
397 return numInBytes;
398 }
399
400 /**
401 * Converts a number to eight bit binary.
402 *
403 * @param binaryString string to binary
404 * @return numInBytes given number as bytes
405 */
406 public static String toEightBitBinary(String binaryString) {
407 String eightBit = binaryString;
408 if (eightBit.length() % 8 != 0) {
409 int numOfZero = 8 - eightBit.length();
410 while (numOfZero > 0) {
411 eightBit = "0" + eightBit;
412 numOfZero--;
413 }
414 }
415 return eightBit;
416 }
417
418 /**
419 * Converts a number to four bit binary.
420 *
421 * @param binaryString string to binary
422 * @return numInBytes given number as bytes
423 */
424 public static String toFourBitBinary(String binaryString) {
425 String fourBit = binaryString;
426 if (fourBit.length() % 4 != 0) {
427 int numOfZero = 4 - fourBit.length();
428 while (numOfZero > 0) {
429 fourBit = "0" + fourBit;
430 numOfZero--;
431 }
432 }
433 return fourBit;
434 }
435
436 /**
437 * Converts a number to three bytes.
438 *
439 * @param numberToConvert number to convert
440 * @return given number as bytes
441 */
442 public static byte[] convertToThreeBytes(int numberToConvert) {
443 byte[] numInBytes = new byte[4];
444 String s1 = Integer.toHexString(numberToConvert);
445 if (s1.length() % 2 != 0) {
446 s1 = "0" + s1;
447 }
448 byte[] hexas = DatatypeConverter.parseHexBinary(s1);
449 if (hexas.length == 1) {
450 numInBytes[0] = 0;
451 numInBytes[1] = 0;
452 numInBytes[2] = hexas[0];
453 } else if (hexas.length == 2) {
454 numInBytes[0] = 0;
455 numInBytes[1] = hexas[0];
456 numInBytes[2] = hexas[1];
457 } else {
458 numInBytes[0] = hexas[0];
459 numInBytes[1] = hexas[1];
460 numInBytes[2] = hexas[2];
461 }
462 return numInBytes;
463 }
464}