blob: 511f000c47d31f894e84ea2fed251453f83dccbc [file] [log] [blame]
mohamed rahile04626f2016-04-05 20:42:53 +05301/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2016-present Open Networking Foundation
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;
Dhruv Dhodye64b93e2016-04-20 19:26:55 +053020import org.onlab.packet.MacAddress;
21import org.onosproject.isis.controller.IsisInterface;
22import org.onosproject.isis.controller.IsisInterfaceState;
23import org.onosproject.isis.controller.IsisNeighbor;
24import org.onosproject.isis.controller.IsisPduType;
sunish vk4b5ce002016-05-09 20:18:35 +053025import org.onosproject.isis.controller.IsisRouterType;
Dhruv Dhodye64b93e2016-04-20 19:26:55 +053026import org.onosproject.isis.io.isispacket.IsisHeader;
27import org.onosproject.isis.io.isispacket.pdu.L1L2HelloPdu;
28import org.onosproject.isis.io.isispacket.pdu.P2PHelloPdu;
29import org.onosproject.isis.io.isispacket.tlv.AdjacencyStateTlv;
30import org.onosproject.isis.io.isispacket.tlv.AreaAddressTlv;
31import org.onosproject.isis.io.isispacket.tlv.IpInterfaceAddressTlv;
32import org.onosproject.isis.io.isispacket.tlv.IsisNeighborTlv;
mohamed rahile04626f2016-04-05 20:42:53 +053033import org.onosproject.isis.io.isispacket.tlv.PaddingTlv;
Dhruv Dhodye64b93e2016-04-20 19:26:55 +053034import org.onosproject.isis.io.isispacket.tlv.ProtocolSupportedTlv;
mohamed rahile04626f2016-04-05 20:42:53 +053035import org.onosproject.isis.io.isispacket.tlv.TlvHeader;
sunishvka1dfc3e2016-04-16 12:24:47 +053036import org.onosproject.isis.io.isispacket.tlv.TlvType;
37import org.slf4j.Logger;
38import org.slf4j.LoggerFactory;
mohamed rahile04626f2016-04-05 20:42:53 +053039
40import javax.xml.bind.DatatypeConverter;
41import java.util.ArrayList;
42import java.util.List;
Dhruv Dhodye64b93e2016-04-20 19:26:55 +053043import java.util.Set;
mohamed rahile04626f2016-04-05 20:42:53 +053044import java.util.StringTokenizer;
45
46/**
sunishvka1dfc3e2016-04-16 12:24:47 +053047 * Representation of ISIS utils.
mohamed rahile04626f2016-04-05 20:42:53 +053048 */
49public final class IsisUtil {
sunishvka1dfc3e2016-04-16 12:24:47 +053050 public static final int ETHER_HEADER_LEN = 17;
mohamed rahile04626f2016-04-05 20:42:53 +053051 public static final int ID_SIX_BYTES = 6;
52 public static final int ID_PLUS_ONE_BYTE = 7;
53 public static final int ID_PLUS_TWO_BYTE = 8;
54 public static final int THREE_BYTES = 3;
Dhruv Dhodye64b93e2016-04-20 19:26:55 +053055 public static final int TWO_BYTES = 2;
mohamed rahile04626f2016-04-05 20:42:53 +053056 public static final int SIX_BYTES = 6;
sunishvka1dfc3e2016-04-16 12:24:47 +053057 public static final int EIGHT_BYTES = 8;
mohamed rahile04626f2016-04-05 20:42:53 +053058 public static final int FOUR_BYTES = 4;
59 public static final int PADDING_FIXED_LENGTH = 255;
sunishvka1dfc3e2016-04-16 12:24:47 +053060 public static final int TLVHEADERLENGTH = 2;
61 public static final int INITIAL_BANDWIDTH = 12500000;
62 private static final Logger log = LoggerFactory.getLogger(IsisUtil.class);
mohamed rahile04626f2016-04-05 20:42:53 +053063
64 /**
sunishvka1dfc3e2016-04-16 12:24:47 +053065 * Creates an instance.
mohamed rahile04626f2016-04-05 20:42:53 +053066 */
67 private IsisUtil() {
68
69 }
70
71 /**
sunishvka1dfc3e2016-04-16 12:24:47 +053072 * Checks given IPs are in same network or not.
73 *
74 * @param ip1 IP address
75 * @param ip2 IP address
76 * @param mask network mask
77 * @return true if both are in same network else false
78 */
79 public static boolean sameNetwork(Ip4Address ip1, Ip4Address ip2, byte[] mask) {
80 try {
81 byte[] a1 = ip1.toOctets();
82 byte[] a2 = ip2.toOctets();
83 for (int i = 0; i < a1.length; i++) {
84 if ((a1[i] & mask[i]) != (a2[i] & mask[i])) {
85 return false;
86 }
87 }
88 } catch (Exception e) {
89 log.debug("Exception::IsisUtil::sameNetwork:: {}", e.getMessage());
90 }
91 return true;
92 }
93
94 /**
mohamed rahile04626f2016-04-05 20:42:53 +053095 * Parse byte array to string system ID.
96 *
97 * @param bytes system ID
sunishvka1dfc3e2016-04-16 12:24:47 +053098 * @return systemId system ID
mohamed rahile04626f2016-04-05 20:42:53 +053099 */
100 public static String systemId(byte[] bytes) {
101 String systemId = "";
102 for (Byte byt : bytes) {
103 String hexa = Integer.toHexString(Byte.toUnsignedInt(byt));
104 if (hexa.length() % 2 != 0) {
105 hexa = "0" + hexa;
106 }
107 systemId = systemId + hexa;
108 if (systemId.length() == 4 || systemId.length() == 9) {
109 systemId = systemId + ".";
110 }
111 }
112 return systemId;
113 }
114
115 /**
116 * Parse byte array to LAN ID.
117 *
118 * @param bytes LAN ID
sunishvka1dfc3e2016-04-16 12:24:47 +0530119 * @return systemIdPlus system ID
mohamed rahile04626f2016-04-05 20:42:53 +0530120 */
121 public static String systemIdPlus(byte[] bytes) {
Dhruv Dhodye64b93e2016-04-20 19:26:55 +0530122 int count = 1;
mohamed rahile04626f2016-04-05 20:42:53 +0530123 String systemId = "";
124 for (Byte byt : bytes) {
125 String hexa = Integer.toHexString(Byte.toUnsignedInt(byt));
126 if (hexa.length() % 2 != 0) {
127 hexa = "0" + hexa;
128 }
Dhruv Dhodye64b93e2016-04-20 19:26:55 +0530129 if (count == 7 && bytes.length == 8) {
130 systemId = systemId + hexa + "-";
131 } else {
132 systemId = systemId + hexa;
133 }
mohamed rahile04626f2016-04-05 20:42:53 +0530134 if (systemId.length() == 4 || systemId.length() == 9
135 || systemId.length() == 14) {
136 systemId = systemId + ".";
137 }
Dhruv Dhodye64b93e2016-04-20 19:26:55 +0530138 count++;
mohamed rahile04626f2016-04-05 20:42:53 +0530139 }
140 return systemId;
141 }
142
143 /**
144 * Parse byte array to area address.
145 *
146 * @param bytes area address
Ray Milkeyc108a6b2017-08-23 15:23:50 -0700147 * @return areaAddress area address
mohamed rahile04626f2016-04-05 20:42:53 +0530148 */
Ray Milkeyc108a6b2017-08-23 15:23:50 -0700149 public static String areaAddress(byte[] bytes) {
sunishvka1dfc3e2016-04-16 12:24:47 +0530150 String areaAddres = "";
mohamed rahile04626f2016-04-05 20:42:53 +0530151 for (Byte byt : bytes) {
152 String hexa = Integer.toHexString(Byte.toUnsignedInt(byt));
153 if (hexa.length() % 2 != 0) {
154 hexa = "0" + hexa;
155 }
sunishvka1dfc3e2016-04-16 12:24:47 +0530156 areaAddres = areaAddres + hexa;
mohamed rahile04626f2016-04-05 20:42:53 +0530157 }
sunishvka1dfc3e2016-04-16 12:24:47 +0530158 return areaAddres;
mohamed rahile04626f2016-04-05 20:42:53 +0530159 }
160
161 /**
162 * Parse area address to bytes.
163 *
164 * @param address area address
165 * @return areaAddress area address
166 */
sunishvka1dfc3e2016-04-16 12:24:47 +0530167 public static List<Byte> areaAddressToBytes(String address) {
168 List<Byte> idList = new ArrayList<>();
169 for (int i = 0; i < address.length(); i = i + 2) {
170 Character c1 = address.charAt(i);
171 Character c2 = address.charAt(i + 1);
172 String str = c1.toString() + c2.toString();
173 idList.add((byte) Integer.parseInt(str, 16));
mohamed rahile04626f2016-04-05 20:42:53 +0530174 }
sunishvka1dfc3e2016-04-16 12:24:47 +0530175 return idList;
mohamed rahile04626f2016-04-05 20:42:53 +0530176 }
177
178 /**
Dhruv Dhodye64b93e2016-04-20 19:26:55 +0530179 * Returns PDU headaer length.
180 *
181 * @param pduType PDU type
182 * @return headerLength header length
183 */
184 public static int getPduHeaderLength(int pduType) {
185 int headerLength = 0;
186 switch (IsisPduType.get(pduType)) {
187 case L1HELLOPDU:
188 case L2HELLOPDU:
189 case L1LSPDU:
190 case L2LSPDU:
191 headerLength = IsisConstants.HELLOHEADERLENGTH;
192 break;
193 case P2PHELLOPDU:
194 headerLength = IsisConstants.P2PHELLOHEADERLENGTH;
195 break;
196 case L1PSNP:
197 case L2PSNP:
198 headerLength = IsisConstants.PSNPDUHEADERLENGTH;
199 break;
200 case L1CSNP:
201 case L2CSNP:
202 headerLength = IsisConstants.CSNPDUHEADERLENGTH;
203 break;
204 default:
205 break;
206 }
207 return headerLength;
208 }
209
210 /**
sunishvka1dfc3e2016-04-16 12:24:47 +0530211 * Adds the PDU length in packet.
mohamed rahile04626f2016-04-05 20:42:53 +0530212 *
sunishvka1dfc3e2016-04-16 12:24:47 +0530213 * @param isisPacket ISIS packet
214 * @param lengthBytePos1 length byte position
215 * @param lengthBytePos2 length byte position
216 * @param reservedBytePos reserved byte position
217 * @return byte array with PDU length
mohamed rahile04626f2016-04-05 20:42:53 +0530218 */
sunishvka1dfc3e2016-04-16 12:24:47 +0530219 public static byte[] addLengthAndMarkItInReserved(byte[] isisPacket, int lengthBytePos1,
220 int lengthBytePos2, int reservedBytePos) {
221 //Set the length of the packet
222 //Get the total length of the packet
223 int length = isisPacket.length;
224 //Convert the lenth to two bytes as the length field is 2 bytes
225 byte[] lenthInTwoBytes = IsisUtil.convertToTwoBytes(length);
226 //isis header 3rd and 4th position represents length
227 isisPacket[lengthBytePos1] = lenthInTwoBytes[0]; //assign 1st byte in lengthBytePos1
228 isisPacket[lengthBytePos2] = lenthInTwoBytes[1]; //assign 2st byte in lengthBytePos2
229 isisPacket[reservedBytePos] = (byte) lengthBytePos1;
230 return isisPacket;
231 }
232
233 /**
234 * Adds the checksum in packet.
235 *
236 * @param isisPacket ISIS packet
237 * @param checksumBytePos1 checksum byte position
238 * @param checksumBytePos2 checksum byte position
239 * @return byte array with PDU length
240 */
241 public static byte[] addChecksum(byte[] isisPacket, int checksumBytePos1, int checksumBytePos2) {
242 //Set the checksum for the packet
Dhruv Dhodye64b93e2016-04-20 19:26:55 +0530243 //Convert the length to two bytes as the length field is 2 bytes
sunishvka1dfc3e2016-04-16 12:24:47 +0530244 byte[] checksumInTwoBytes = new ChecksumCalculator().calculateLspChecksum(
245 isisPacket, checksumBytePos1, checksumBytePos2);
246 //isis header 3rd and 4th position represents length
247 isisPacket[checksumBytePos1] = checksumInTwoBytes[0];
248 isisPacket[checksumBytePos2] = checksumInTwoBytes[1];
249 return isisPacket;
250 }
251
252 /**
253 * Adds frame a packet of 1498 of size.
254 *
255 * @param isisPacket ISIS packet
256 * @param interfaceIndex interface index
257 * @return byte array with 1498 is the length
258 */
259 public static byte[] framePacket(byte[] isisPacket, int interfaceIndex) {
260 //Set the length of the packet
261 //Get the total length of the packet
262 int length = isisPacket.length;
263 //PDU_LENGTH + 1 byte for interface index
264 if (length < IsisConstants.PDU_LENGTH + 1) {
265 byte[] bytes = new byte[IsisConstants.PDU_LENGTH + 1];
266 System.arraycopy(isisPacket, 0, bytes, 0, length);
267 bytes[IsisConstants.PDU_LENGTH] = (byte) interfaceIndex;
268 return bytes;
mohamed rahile04626f2016-04-05 20:42:53 +0530269 }
sunishvka1dfc3e2016-04-16 12:24:47 +0530270 return isisPacket;
mohamed rahile04626f2016-04-05 20:42:53 +0530271 }
272
273 /**
274 * Parse source and LAN ID.
275 *
276 * @param id source and LAN ID
sunishvka1dfc3e2016-04-16 12:24:47 +0530277 * @return source and LAN ID
mohamed rahile04626f2016-04-05 20:42:53 +0530278 */
279 public static List<Byte> sourceAndLanIdToBytes(String id) {
sunishvka1dfc3e2016-04-16 12:24:47 +0530280 List<Byte> idList = new ArrayList<>();
281 StringTokenizer tokenizer = new StringTokenizer(id, "." + "-");
mohamed rahile04626f2016-04-05 20:42:53 +0530282 while (tokenizer.hasMoreElements()) {
283 int i = 0;
284 String str = tokenizer.nextToken();
sunishvka1dfc3e2016-04-16 12:24:47 +0530285 idList.add((byte) Integer.parseInt(str.substring(0, i + 2), 16));
mohamed rahile04626f2016-04-05 20:42:53 +0530286 if (str.length() > 2) {
sunishvka1dfc3e2016-04-16 12:24:47 +0530287 idList.add((byte) Integer.parseInt(str.substring(i + 2, str.length()), 16));
mohamed rahile04626f2016-04-05 20:42:53 +0530288 }
mohamed rahile04626f2016-04-05 20:42:53 +0530289 }
sunishvka1dfc3e2016-04-16 12:24:47 +0530290 return idList;
mohamed rahile04626f2016-04-05 20:42:53 +0530291 }
292
293 /**
294 * Parse padding for PDU based on current length.
295 *
296 * @param currentLength current length
297 * @return byteArray padding array
298 */
sunishvka1dfc3e2016-04-16 12:24:47 +0530299 public static byte[] getPaddingTlvs(int currentLength) {
mohamed rahile04626f2016-04-05 20:42:53 +0530300 List<Byte> bytes = new ArrayList<>();
sunishvka1dfc3e2016-04-16 12:24:47 +0530301 while (IsisConstants.PDU_LENGTH > currentLength) {
302 int length = IsisConstants.PDU_LENGTH - currentLength;
mohamed rahile04626f2016-04-05 20:42:53 +0530303 TlvHeader tlvHeader = new TlvHeader();
sunishvka1dfc3e2016-04-16 12:24:47 +0530304 tlvHeader.setTlvType(TlvType.PADDING.value());
mohamed rahile04626f2016-04-05 20:42:53 +0530305 if (length >= PADDING_FIXED_LENGTH) {
306 tlvHeader.setTlvLength(PADDING_FIXED_LENGTH);
307 } else {
sunishvka1dfc3e2016-04-16 12:24:47 +0530308 tlvHeader.setTlvLength(IsisConstants.PDU_LENGTH - (currentLength + TLVHEADERLENGTH));
mohamed rahile04626f2016-04-05 20:42:53 +0530309 }
310 PaddingTlv tlv = new PaddingTlv(tlvHeader);
311 bytes.addAll(Bytes.asList(tlv.asBytes()));
sunishvka1dfc3e2016-04-16 12:24:47 +0530312 currentLength = currentLength + tlv.tlvLength() + TLVHEADERLENGTH;
mohamed rahile04626f2016-04-05 20:42:53 +0530313 }
314 byte[] byteArray = new byte[bytes.size()];
315 int i = 0;
316 for (byte byt : bytes) {
317 byteArray[i++] = byt;
318 }
319 return byteArray;
mohamed rahile04626f2016-04-05 20:42:53 +0530320 }
321
322 /**
323 * Converts an integer to two bytes.
324 *
325 * @param numberToConvert number to convert
326 * @return numInBytes given number as bytes
327 */
328 public static byte[] convertToTwoBytes(int numberToConvert) {
329
330 byte[] numInBytes = new byte[2];
331 String s1 = Integer.toHexString(numberToConvert);
332 if (s1.length() % 2 != 0) {
333 s1 = "0" + s1;
334 }
335 byte[] hexas = DatatypeConverter.parseHexBinary(s1);
336 if (hexas.length == 1) {
337 numInBytes[0] = 0;
338 numInBytes[1] = hexas[0];
339 } else {
340 numInBytes[0] = hexas[0];
341 numInBytes[1] = hexas[1];
342 }
343 return numInBytes;
344 }
345
346 /**
347 * Converts a number to four bytes.
348 *
349 * @param numberToConvert number to convert
350 * @return numInBytes given number as bytes
351 */
352 public static byte[] convertToFourBytes(int numberToConvert) {
mohamed rahile04626f2016-04-05 20:42:53 +0530353 byte[] numInBytes = new byte[4];
354 String s1 = Integer.toHexString(numberToConvert);
355 if (s1.length() % 2 != 0) {
356 s1 = "0" + s1;
357 }
358 byte[] hexas = DatatypeConverter.parseHexBinary(s1);
359 if (hexas.length == 1) {
360 numInBytes[0] = 0;
361 numInBytes[1] = 0;
362 numInBytes[2] = 0;
363 numInBytes[3] = hexas[0];
364 } else if (hexas.length == 2) {
365 numInBytes[0] = 0;
366 numInBytes[1] = 0;
367 numInBytes[2] = hexas[0];
368 numInBytes[3] = hexas[1];
369 } else if (hexas.length == 3) {
370 numInBytes[0] = 0;
371 numInBytes[1] = hexas[0];
372 numInBytes[2] = hexas[1];
373 numInBytes[3] = hexas[2];
374 } else {
375 numInBytes[0] = hexas[0];
376 numInBytes[1] = hexas[1];
377 numInBytes[2] = hexas[2];
378 numInBytes[3] = hexas[3];
379 }
380 return numInBytes;
381 }
382
sunishvka1dfc3e2016-04-16 12:24:47 +0530383 /**
Dhruv Dhodye64b93e2016-04-20 19:26:55 +0530384 * Returns the P2P hello PDU.
385 *
386 * @param isisInterface ISIS interface instance
387 * @param paddingEnabled padding enabled or not
388 * @return hello PDU
389 */
390 public static byte[] getP2pHelloPdu(IsisInterface isisInterface, boolean paddingEnabled) {
391 IsisHeader isisHeader = new IsisHeader();
392 isisHeader.setIrpDiscriminator((byte) IsisConstants.IRPDISCRIMINATOR);
393 isisHeader.setPduHeaderLength((byte) IsisConstants.P2PHELLOHEADERLENGTH);
394 isisHeader.setVersion((byte) IsisConstants.ISISVERSION);
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530395 isisHeader.setIdLength((byte) IsisConstants.SYSTEMIDLENGTH);
Dhruv Dhodye64b93e2016-04-20 19:26:55 +0530396 isisHeader.setIsisPduType(IsisPduType.P2PHELLOPDU.value());
397 isisHeader.setVersion2((byte) IsisConstants.ISISVERSION);
Dhruv Dhodye64b93e2016-04-20 19:26:55 +0530398 isisHeader.setReserved((byte) IsisConstants.PDULENGTHPOSITION);
399 isisHeader.setMaximumAreaAddresses((byte) IsisConstants.MAXAREAADDRESS);
400 P2PHelloPdu p2pHelloPdu = new P2PHelloPdu(isisHeader);
401 p2pHelloPdu.setCircuitType((byte) isisInterface.reservedPacketCircuitType());
402 p2pHelloPdu.setSourceId(isisInterface.systemId());
403 p2pHelloPdu.setHoldingTime(isisInterface.holdingTime());
404 p2pHelloPdu.setPduLength(IsisConstants.PDU_LENGTH);
405 p2pHelloPdu.setLocalCircuitId((byte) IsisConstants.LOCALCIRCUITIDFORP2P);
406
407 TlvHeader tlvHeader = new TlvHeader();
408 tlvHeader.setTlvType(TlvType.AREAADDRESS.value());
409 tlvHeader.setTlvLength(0);
410 AreaAddressTlv areaAddressTlv = new AreaAddressTlv(tlvHeader);
411 areaAddressTlv.addAddress(isisInterface.areaAddress());
412 p2pHelloPdu.addTlv(areaAddressTlv);
413
414 tlvHeader.setTlvType(TlvType.PROTOCOLSUPPORTED.value());
415 tlvHeader.setTlvLength(0);
416 ProtocolSupportedTlv protocolSupportedTlv = new ProtocolSupportedTlv(tlvHeader);
417 protocolSupportedTlv.addProtocolSupported((byte) IsisConstants.PROTOCOLSUPPORTED);
418 p2pHelloPdu.addTlv(protocolSupportedTlv);
419
420 tlvHeader.setTlvType(TlvType.ADJACENCYSTATE.value());
421 tlvHeader.setTlvLength(0);
422 AdjacencyStateTlv adjacencyStateTlv = new AdjacencyStateTlv(tlvHeader);
423 adjacencyStateTlv.setAdjacencyType((byte) IsisInterfaceState.DOWN.value());
424 adjacencyStateTlv.setLocalCircuitId(Integer.parseInt(isisInterface.circuitId()));
425 Set<MacAddress> neighbors = isisInterface.neighbors();
Jon Hallcbd1b392017-01-18 20:15:44 -0800426 if (!neighbors.isEmpty()) {
Dhruv Dhodye64b93e2016-04-20 19:26:55 +0530427 IsisNeighbor neighbor = isisInterface.lookup(neighbors.iterator().next());
428 adjacencyStateTlv.setAdjacencyType((byte) neighbor.interfaceState().value());
429 adjacencyStateTlv.setNeighborSystemId(neighbor.neighborSystemId());
430 adjacencyStateTlv.setNeighborLocalCircuitId(neighbor.localExtendedCircuitId());
431 }
432 p2pHelloPdu.addTlv(adjacencyStateTlv);
433
434 tlvHeader.setTlvType(TlvType.IPINTERFACEADDRESS.value());
435 tlvHeader.setTlvLength(0);
436 IpInterfaceAddressTlv ipInterfaceAddressTlv = new IpInterfaceAddressTlv(tlvHeader);
437 ipInterfaceAddressTlv.addInterfaceAddres(isisInterface.interfaceIpAddress());
438 p2pHelloPdu.addTlv(ipInterfaceAddressTlv);
439
440 byte[] beforePadding = p2pHelloPdu.asBytes();
441 byte[] helloMessage;
442 if (paddingEnabled) {
443 byte[] paddingTlvs = getPaddingTlvs(beforePadding.length);
444 helloMessage = Bytes.concat(beforePadding, paddingTlvs);
445 } else {
446 helloMessage = beforePadding;
447 }
448 return helloMessage;
449 }
450
451 /**
452 * Returns the L1 hello PDU.
453 *
454 * @param isisInterface ISIS interface instance
455 * @param paddingEnabled padding enabled or not
456 * @return helloMessage hello PDU
457 */
458 public static byte[] getL1HelloPdu(IsisInterface isisInterface, boolean paddingEnabled) {
459 return getL1OrL2HelloPdu(isisInterface, IsisPduType.L1HELLOPDU, paddingEnabled);
460 }
461
462 /**
463 * Returns the L2 hello PDU.
464 *
465 * @param isisInterface ISIS interface instance
466 * @param paddingEnabled padding enabled or not
467 * @return helloMessage hello PDU
468 */
469 public static byte[] getL2HelloPdu(IsisInterface isisInterface, boolean paddingEnabled) {
470 return getL1OrL2HelloPdu(isisInterface, IsisPduType.L2HELLOPDU, paddingEnabled);
471 }
472
473 /**
474 * Returns the hello PDU.
475 *
476 * @param isisInterface ISIS interface instance
477 * @param paddingEnabled padding enabled or not
478 * @return helloMessage hello PDU
479 */
480 private static byte[] getL1OrL2HelloPdu(IsisInterface isisInterface, IsisPduType isisPduType,
481 boolean paddingEnabled) {
482 String lanId = "";
483 IsisHeader isisHeader = new IsisHeader();
484 isisHeader.setIrpDiscriminator((byte) IsisConstants.IRPDISCRIMINATOR);
485 isisHeader.setPduHeaderLength((byte) IsisConstants.HELLOHEADERLENGTH);
486 isisHeader.setVersion((byte) IsisConstants.ISISVERSION);
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530487 isisHeader.setIdLength((byte) IsisConstants.SYSTEMIDLENGTH);
Dhruv Dhodye64b93e2016-04-20 19:26:55 +0530488 if (isisPduType == IsisPduType.L1HELLOPDU) {
489 isisHeader.setIsisPduType(IsisPduType.L1HELLOPDU.value());
490 lanId = isisInterface.l1LanId();
491 } else if (isisPduType == IsisPduType.L2HELLOPDU) {
492 isisHeader.setIsisPduType(IsisPduType.L2HELLOPDU.value());
493 lanId = isisInterface.l2LanId();
494 }
495 isisHeader.setVersion2((byte) IsisConstants.ISISVERSION);
496 isisHeader.setReserved((byte) IsisConstants.PDULENGTHPOSITION);
497 isisHeader.setMaximumAreaAddresses((byte) IsisConstants.MAXAREAADDRESS);
498 L1L2HelloPdu l1L2HelloPdu = new L1L2HelloPdu(isisHeader);
499 l1L2HelloPdu.setCircuitType((byte) isisInterface.reservedPacketCircuitType());
500 l1L2HelloPdu.setSourceId(isisInterface.systemId());
501 l1L2HelloPdu.setHoldingTime(isisInterface.holdingTime());
502 l1L2HelloPdu.setPduLength(IsisConstants.PDU_LENGTH);
503 l1L2HelloPdu.setPriority((byte) isisInterface.priority());
504 l1L2HelloPdu.setLanId(lanId);
505 TlvHeader tlvHeader = new TlvHeader();
506 tlvHeader.setTlvType(TlvType.AREAADDRESS.value());
507 tlvHeader.setTlvLength(0);
508 AreaAddressTlv areaAddressTlv = new AreaAddressTlv(tlvHeader);
509 areaAddressTlv.addAddress(isisInterface.areaAddress());
510 l1L2HelloPdu.addTlv(areaAddressTlv);
511 Set<MacAddress> neighbors = isisInterface.neighbors();
Jon Hallcbd1b392017-01-18 20:15:44 -0800512 if (!neighbors.isEmpty()) {
sunish vk4b5ce002016-05-09 20:18:35 +0530513 List<MacAddress> neighborMacs = new ArrayList<>();
514 for (MacAddress neighbor : neighbors) {
515 IsisNeighbor isisNeighbor = isisInterface.lookup(neighbor);
516 if (isisPduType == IsisPduType.L1HELLOPDU) {
517 if (isisNeighbor.routerType() == IsisRouterType.L1 ||
518 isisNeighbor.routerType() == IsisRouterType.L1L2) {
519 neighborMacs.add(neighbor);
520 }
521 } else if (isisPduType == IsisPduType.L2HELLOPDU) {
522 if (isisNeighbor.routerType() == IsisRouterType.L2 ||
523 isisNeighbor.routerType() == IsisRouterType.L1L2) {
524 neighborMacs.add(neighbor);
525 }
526 }
527 }
528
Dhruv Dhodye64b93e2016-04-20 19:26:55 +0530529 tlvHeader.setTlvType(TlvType.ISNEIGHBORS.value());
530 tlvHeader.setTlvLength(0);
sunish vk4b5ce002016-05-09 20:18:35 +0530531
Dhruv Dhodye64b93e2016-04-20 19:26:55 +0530532 IsisNeighborTlv isisNeighborTlv = new IsisNeighborTlv(tlvHeader);
sunish vk4b5ce002016-05-09 20:18:35 +0530533 for (MacAddress neighbor : neighborMacs) {
Dhruv Dhodye64b93e2016-04-20 19:26:55 +0530534 isisNeighborTlv.addNeighbor(neighbor);
535 }
536 l1L2HelloPdu.addTlv(isisNeighborTlv);
537 }
sunish vk4b5ce002016-05-09 20:18:35 +0530538
Dhruv Dhodye64b93e2016-04-20 19:26:55 +0530539 tlvHeader.setTlvType(TlvType.PROTOCOLSUPPORTED.value());
540 tlvHeader.setTlvLength(0);
541 ProtocolSupportedTlv protocolSupportedTlv = new ProtocolSupportedTlv(tlvHeader);
542 protocolSupportedTlv.addProtocolSupported((byte) IsisConstants.PROTOCOLSUPPORTED);
543 l1L2HelloPdu.addTlv(protocolSupportedTlv);
544
545 tlvHeader.setTlvType(TlvType.IPINTERFACEADDRESS.value());
546 tlvHeader.setTlvLength(0);
547 IpInterfaceAddressTlv ipInterfaceAddressTlv = new IpInterfaceAddressTlv(tlvHeader);
548 ipInterfaceAddressTlv.addInterfaceAddres(isisInterface.interfaceIpAddress());
549 l1L2HelloPdu.addTlv(ipInterfaceAddressTlv);
550
551 byte[] beforePadding = l1L2HelloPdu.asBytes();
552 byte[] helloMessage;
553 if (paddingEnabled) {
554 byte[] paddingTlvs = getPaddingTlvs(beforePadding.length);
555 helloMessage = Bytes.concat(beforePadding, paddingTlvs);
556 } else {
557 helloMessage = beforePadding;
558 }
559 return helloMessage;
560 }
561
562 /**
sunishvka1dfc3e2016-04-16 12:24:47 +0530563 * Converts a byte to integer variable.
564 *
565 * @param bytesToConvert bytes to convert
566 * @return integer representation of bytes
567 */
568 public static int byteToInteger(byte[] bytesToConvert) {
569 final StringBuilder builder = new StringBuilder();
570 for (byte eachByte : bytesToConvert) {
571 builder.append(String.format("%02x", eachByte));
572 }
573 int number = Integer.parseInt(builder.toString(), 16);
574 return number;
mohamed rahile04626f2016-04-05 20:42:53 +0530575 }
sunishvka1dfc3e2016-04-16 12:24:47 +0530576
577 /**
578 * Converts a byte to long variable.
579 *
580 * @param bytesToConvert bytes to convert
581 * @return long representation of bytes
582 */
583 public static long byteToLong(byte[] bytesToConvert) {
584 final StringBuilder builder = new StringBuilder();
585 for (byte eachByte : bytesToConvert) {
586 builder.append(String.format("%02x", eachByte));
587 }
588 long number = Long.parseLong(builder.toString(), 16);
589 return number;
590 }
591
592 /**
593 * Converts a number to four bytes.
594 *
595 * @param numberToConvert number to convert
596 * @return numInBytes given number as bytes
597 */
598 public static byte[] convertToFourBytes(long numberToConvert) {
599 byte[] numInBytes = new byte[4];
600 String s1 = Long.toHexString(numberToConvert);
601 if (s1.length() % 2 != 0) {
602 s1 = "0" + s1;
603 }
604 if (s1.length() == 16) {
605 s1 = s1.substring(8, s1.length());
606 }
607 byte[] hexas = DatatypeConverter.parseHexBinary(s1);
608 if (hexas.length == 1) {
609 numInBytes[0] = 0;
610 numInBytes[1] = 0;
611 numInBytes[2] = 0;
612 numInBytes[3] = hexas[0];
613 } else if (hexas.length == 2) {
614 numInBytes[0] = 0;
615 numInBytes[1] = 0;
616 numInBytes[2] = hexas[0];
617 numInBytes[3] = hexas[1];
618 } else if (hexas.length == 3) {
619 numInBytes[0] = 0;
620 numInBytes[1] = hexas[0];
621 numInBytes[2] = hexas[1];
622 numInBytes[3] = hexas[2];
623 } else {
624 numInBytes[0] = hexas[0];
625 numInBytes[1] = hexas[1];
626 numInBytes[2] = hexas[2];
627 numInBytes[3] = hexas[3];
628 }
629 return numInBytes;
630 }
631
632 /**
633 * Converts a number to eight bit binary.
634 *
635 * @param binaryString string to binary
636 * @return numInBytes given number as bytes
637 */
638 public static String toEightBitBinary(String binaryString) {
639 String eightBit = binaryString;
640 if (eightBit.length() % 8 != 0) {
641 int numOfZero = 8 - eightBit.length();
642 while (numOfZero > 0) {
643 eightBit = "0" + eightBit;
644 numOfZero--;
645 }
646 }
647 return eightBit;
648 }
649
650 /**
651 * Converts a number to four bit binary.
652 *
653 * @param binaryString string to binary
654 * @return numInBytes given number as bytes
655 */
656 public static String toFourBitBinary(String binaryString) {
657 String fourBit = binaryString;
658 if (fourBit.length() % 4 != 0) {
659 int numOfZero = 4 - fourBit.length();
660 while (numOfZero > 0) {
661 fourBit = "0" + fourBit;
662 numOfZero--;
663 }
664 }
665 return fourBit;
666 }
667
668 /**
669 * Converts a number to three bytes.
670 *
671 * @param numberToConvert number to convert
672 * @return given number as bytes
673 */
674 public static byte[] convertToThreeBytes(int numberToConvert) {
nicklesh adlakha90bfa6a2016-04-28 20:38:33 +0530675 byte[] numInBytes = new byte[3];
sunishvka1dfc3e2016-04-16 12:24:47 +0530676 String s1 = Integer.toHexString(numberToConvert);
677 if (s1.length() % 2 != 0) {
678 s1 = "0" + s1;
679 }
680 byte[] hexas = DatatypeConverter.parseHexBinary(s1);
681 if (hexas.length == 1) {
682 numInBytes[0] = 0;
683 numInBytes[1] = 0;
684 numInBytes[2] = hexas[0];
685 } else if (hexas.length == 2) {
686 numInBytes[0] = 0;
687 numInBytes[1] = hexas[0];
688 numInBytes[2] = hexas[1];
689 } else {
690 numInBytes[0] = hexas[0];
691 numInBytes[1] = hexas[1];
692 numInBytes[2] = hexas[2];
693 }
694 return numInBytes;
695 }
Dhruv Dhodye64b93e2016-04-20 19:26:55 +0530696
697 /**
698 * Converts the bytes of prefix to string type value.
699 *
700 * @param bytes array of prefix
701 * @return string value of prefix
702 */
703 public static String prefixConversion(byte[] bytes) {
704 String prefix = "";
705 for (int i = 0; i < bytes.length; i++) {
706 if (i < (bytes.length - 1)) {
707 prefix = prefix + bytes[i] + ".";
708 } else {
709 prefix = prefix + bytes[i];
710 }
711 }
712 return prefix;
713 }
tejeshwer degala3fe1ed52016-04-22 17:04:01 +0530714
715 /**
716 * Converts the prefix to bytes.
717 *
718 * @param prefix prefix
719 * @return prefix to bytes
720 */
721 public static byte[] prefixToBytes(String prefix) {
722 List<Byte> byteList = new ArrayList<>();
723 StringTokenizer tokenizer = new StringTokenizer(prefix, ".");
724 while (tokenizer.hasMoreTokens()) {
725 byteList.add((byte) Integer.parseInt(tokenizer.nextToken()));
726 }
727 return Bytes.toArray(byteList);
728 }
sunish vk7bdf4d42016-06-24 12:29:43 +0530729
730 /**
731 * Return the DIS value from the systemId.
732 *
733 * @param systemId system Id.
734 * @return return true if DIS else false
735 */
736 public static boolean checkIsDis(String systemId) {
737 StringTokenizer stringTokenizer = new StringTokenizer(systemId, "." + "-");
738 int count = 0;
739 while (stringTokenizer.hasMoreTokens()) {
740 String str = stringTokenizer.nextToken();
741 if (count == 3) {
742 int x = Integer.parseInt(str);
743 if (x > 0) {
744 return true;
745 }
746 }
747 count++;
748 }
749 return false;
750 }
751
752 /**
753 * Return the systemId.
754 *
755 * @param systemId system Id.
756 * @return return system ID
757 */
758 public static String removeTailingZeros(String systemId) {
759 StringTokenizer stringTokenizer = new StringTokenizer(systemId, "-");
760 return stringTokenizer.nextToken();
761 }
Ray Milkeyc108a6b2017-08-23 15:23:50 -0700762}