blob: 318eb1b3da56dedc668fe3d024e313f43bda3df3 [file] [log] [blame]
/*
* Copyright 2016-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.isis.io.util;
import com.google.common.primitives.Bytes;
import org.onlab.packet.Ip4Address;
import org.onosproject.isis.io.isispacket.tlv.PaddingTlv;
import org.onosproject.isis.io.isispacket.tlv.TlvHeader;
import org.onosproject.isis.io.isispacket.tlv.TlvType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.xml.bind.DatatypeConverter;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
/**
* Representation of ISIS utils.
*/
public final class IsisUtil {
public static final int ETHER_HEADER_LEN = 17;
public static final int ID_SIX_BYTES = 6;
public static final int ID_PLUS_ONE_BYTE = 7;
public static final int ID_PLUS_TWO_BYTE = 8;
public static final int THREE_BYTES = 3;
public static final int SIX_BYTES = 6;
public static final int EIGHT_BYTES = 8;
public static final int FOUR_BYTES = 4;
public static final int PADDING_FIXED_LENGTH = 255;
public static final int TLVHEADERLENGTH = 2;
public static final int INITIAL_BANDWIDTH = 12500000;
private static final Logger log = LoggerFactory.getLogger(IsisUtil.class);
/**
* Creates an instance.
*/
private IsisUtil() {
}
/**
* Checks given IPs are in same network or not.
*
* @param ip1 IP address
* @param ip2 IP address
* @param mask network mask
* @return true if both are in same network else false
*/
public static boolean sameNetwork(Ip4Address ip1, Ip4Address ip2, byte[] mask) {
try {
byte[] a1 = ip1.toOctets();
byte[] a2 = ip2.toOctets();
for (int i = 0; i < a1.length; i++) {
if ((a1[i] & mask[i]) != (a2[i] & mask[i])) {
return false;
}
}
} catch (Exception e) {
log.debug("Exception::IsisUtil::sameNetwork:: {}", e.getMessage());
}
return true;
}
/**
* Parse byte array to string system ID.
*
* @param bytes system ID
* @return systemId system ID
*/
public static String systemId(byte[] bytes) {
String systemId = "";
for (Byte byt : bytes) {
String hexa = Integer.toHexString(Byte.toUnsignedInt(byt));
if (hexa.length() % 2 != 0) {
hexa = "0" + hexa;
}
systemId = systemId + hexa;
if (systemId.length() == 4 || systemId.length() == 9) {
systemId = systemId + ".";
}
}
return systemId;
}
/**
* Parse byte array to LAN ID.
*
* @param bytes LAN ID
* @return systemIdPlus system ID
*/
public static String systemIdPlus(byte[] bytes) {
String systemId = "";
for (Byte byt : bytes) {
String hexa = Integer.toHexString(Byte.toUnsignedInt(byt));
if (hexa.length() % 2 != 0) {
hexa = "0" + hexa;
}
systemId = systemId + hexa;
if (systemId.length() == 4 || systemId.length() == 9
|| systemId.length() == 14) {
systemId = systemId + ".";
}
}
return systemId;
}
/**
* Parse byte array to area address.
*
* @param bytes area address
* @return areaAddres area address
*/
public static String areaAddres(byte[] bytes) {
String areaAddres = "";
for (Byte byt : bytes) {
String hexa = Integer.toHexString(Byte.toUnsignedInt(byt));
if (hexa.length() % 2 != 0) {
hexa = "0" + hexa;
}
areaAddres = areaAddres + hexa;
}
return areaAddres;
}
/**
* Parse area address to bytes.
*
* @param address area address
* @return areaAddress area address
*/
public static List<Byte> areaAddressToBytes(String address) {
List<Byte> idList = new ArrayList<>();
for (int i = 0; i < address.length(); i = i + 2) {
Character c1 = address.charAt(i);
Character c2 = address.charAt(i + 1);
String str = c1.toString() + c2.toString();
idList.add((byte) Integer.parseInt(str, 16));
}
return idList;
}
/**
* Adds the PDU length in packet.
*
* @param isisPacket ISIS packet
* @param lengthBytePos1 length byte position
* @param lengthBytePos2 length byte position
* @param reservedBytePos reserved byte position
* @return byte array with PDU length
*/
public static byte[] addLengthAndMarkItInReserved(byte[] isisPacket, int lengthBytePos1,
int lengthBytePos2, int reservedBytePos) {
//Set the length of the packet
//Get the total length of the packet
int length = isisPacket.length;
//Convert the lenth to two bytes as the length field is 2 bytes
byte[] lenthInTwoBytes = IsisUtil.convertToTwoBytes(length);
//isis header 3rd and 4th position represents length
isisPacket[lengthBytePos1] = lenthInTwoBytes[0]; //assign 1st byte in lengthBytePos1
isisPacket[lengthBytePos2] = lenthInTwoBytes[1]; //assign 2st byte in lengthBytePos2
isisPacket[reservedBytePos] = (byte) lengthBytePos1;
return isisPacket;
}
/**
* Adds the checksum in packet.
*
* @param isisPacket ISIS packet
* @param checksumBytePos1 checksum byte position
* @param checksumBytePos2 checksum byte position
* @return byte array with PDU length
*/
public static byte[] addChecksum(byte[] isisPacket, int checksumBytePos1, int checksumBytePos2) {
//Set the checksum for the packet
//Convert the lenth to two bytes as the length field is 2 bytes
byte[] checksumInTwoBytes = new ChecksumCalculator().calculateLspChecksum(
isisPacket, checksumBytePos1, checksumBytePos2);
//isis header 3rd and 4th position represents length
isisPacket[checksumBytePos1] = checksumInTwoBytes[0];
isisPacket[checksumBytePos2] = checksumInTwoBytes[1];
return isisPacket;
}
/**
* Adds frame a packet of 1498 of size.
*
* @param isisPacket ISIS packet
* @param interfaceIndex interface index
* @return byte array with 1498 is the length
*/
public static byte[] framePacket(byte[] isisPacket, int interfaceIndex) {
//Set the length of the packet
//Get the total length of the packet
int length = isisPacket.length;
//PDU_LENGTH + 1 byte for interface index
if (length < IsisConstants.PDU_LENGTH + 1) {
byte[] bytes = new byte[IsisConstants.PDU_LENGTH + 1];
System.arraycopy(isisPacket, 0, bytes, 0, length);
bytes[IsisConstants.PDU_LENGTH] = (byte) interfaceIndex;
return bytes;
}
return isisPacket;
}
/**
* Parse source and LAN ID.
*
* @param id source and LAN ID
* @return source and LAN ID
*/
public static List<Byte> sourceAndLanIdToBytes(String id) {
List<Byte> idList = new ArrayList<>();
StringTokenizer tokenizer = new StringTokenizer(id, "." + "-");
while (tokenizer.hasMoreElements()) {
int i = 0;
String str = tokenizer.nextToken();
idList.add((byte) Integer.parseInt(str.substring(0, i + 2), 16));
if (str.length() > 2) {
idList.add((byte) Integer.parseInt(str.substring(i + 2, str.length()), 16));
}
}
return idList;
}
/**
* Parse padding for PDU based on current length.
*
* @param currentLength current length
* @return byteArray padding array
*/
public static byte[] getPaddingTlvs(int currentLength) {
List<Byte> bytes = new ArrayList<>();
while (IsisConstants.PDU_LENGTH > currentLength) {
int length = IsisConstants.PDU_LENGTH - currentLength;
TlvHeader tlvHeader = new TlvHeader();
tlvHeader.setTlvType(TlvType.PADDING.value());
if (length >= PADDING_FIXED_LENGTH) {
tlvHeader.setTlvLength(PADDING_FIXED_LENGTH);
} else {
tlvHeader.setTlvLength(IsisConstants.PDU_LENGTH - (currentLength + TLVHEADERLENGTH));
}
PaddingTlv tlv = new PaddingTlv(tlvHeader);
bytes.addAll(Bytes.asList(tlv.asBytes()));
currentLength = currentLength + tlv.tlvLength() + TLVHEADERLENGTH;
}
byte[] byteArray = new byte[bytes.size()];
int i = 0;
for (byte byt : bytes) {
byteArray[i++] = byt;
}
return byteArray;
}
/**
* Converts an integer to two bytes.
*
* @param numberToConvert number to convert
* @return numInBytes given number as bytes
*/
public static byte[] convertToTwoBytes(int numberToConvert) {
byte[] numInBytes = new byte[2];
String s1 = Integer.toHexString(numberToConvert);
if (s1.length() % 2 != 0) {
s1 = "0" + s1;
}
byte[] hexas = DatatypeConverter.parseHexBinary(s1);
if (hexas.length == 1) {
numInBytes[0] = 0;
numInBytes[1] = hexas[0];
} else {
numInBytes[0] = hexas[0];
numInBytes[1] = hexas[1];
}
return numInBytes;
}
/**
* Converts a number to four bytes.
*
* @param numberToConvert number to convert
* @return numInBytes given number as bytes
*/
public static byte[] convertToFourBytes(int numberToConvert) {
byte[] numInBytes = new byte[4];
String s1 = Integer.toHexString(numberToConvert);
if (s1.length() % 2 != 0) {
s1 = "0" + s1;
}
byte[] hexas = DatatypeConverter.parseHexBinary(s1);
if (hexas.length == 1) {
numInBytes[0] = 0;
numInBytes[1] = 0;
numInBytes[2] = 0;
numInBytes[3] = hexas[0];
} else if (hexas.length == 2) {
numInBytes[0] = 0;
numInBytes[1] = 0;
numInBytes[2] = hexas[0];
numInBytes[3] = hexas[1];
} else if (hexas.length == 3) {
numInBytes[0] = 0;
numInBytes[1] = hexas[0];
numInBytes[2] = hexas[1];
numInBytes[3] = hexas[2];
} else {
numInBytes[0] = hexas[0];
numInBytes[1] = hexas[1];
numInBytes[2] = hexas[2];
numInBytes[3] = hexas[3];
}
return numInBytes;
}
/**
* Converts a byte to integer variable.
*
* @param bytesToConvert bytes to convert
* @return integer representation of bytes
*/
public static int byteToInteger(byte[] bytesToConvert) {
final StringBuilder builder = new StringBuilder();
for (byte eachByte : bytesToConvert) {
builder.append(String.format("%02x", eachByte));
}
int number = Integer.parseInt(builder.toString(), 16);
return number;
}
/**
* Converts a byte to long variable.
*
* @param bytesToConvert bytes to convert
* @return long representation of bytes
*/
public static long byteToLong(byte[] bytesToConvert) {
final StringBuilder builder = new StringBuilder();
for (byte eachByte : bytesToConvert) {
builder.append(String.format("%02x", eachByte));
}
long number = Long.parseLong(builder.toString(), 16);
return number;
}
/**
* Converts a number to four bytes.
*
* @param numberToConvert number to convert
* @return numInBytes given number as bytes
*/
public static byte[] convertToFourBytes(long numberToConvert) {
byte[] numInBytes = new byte[4];
String s1 = Long.toHexString(numberToConvert);
if (s1.length() % 2 != 0) {
s1 = "0" + s1;
}
if (s1.length() == 16) {
s1 = s1.substring(8, s1.length());
}
byte[] hexas = DatatypeConverter.parseHexBinary(s1);
if (hexas.length == 1) {
numInBytes[0] = 0;
numInBytes[1] = 0;
numInBytes[2] = 0;
numInBytes[3] = hexas[0];
} else if (hexas.length == 2) {
numInBytes[0] = 0;
numInBytes[1] = 0;
numInBytes[2] = hexas[0];
numInBytes[3] = hexas[1];
} else if (hexas.length == 3) {
numInBytes[0] = 0;
numInBytes[1] = hexas[0];
numInBytes[2] = hexas[1];
numInBytes[3] = hexas[2];
} else {
numInBytes[0] = hexas[0];
numInBytes[1] = hexas[1];
numInBytes[2] = hexas[2];
numInBytes[3] = hexas[3];
}
return numInBytes;
}
/**
* Converts a number to eight bit binary.
*
* @param binaryString string to binary
* @return numInBytes given number as bytes
*/
public static String toEightBitBinary(String binaryString) {
String eightBit = binaryString;
if (eightBit.length() % 8 != 0) {
int numOfZero = 8 - eightBit.length();
while (numOfZero > 0) {
eightBit = "0" + eightBit;
numOfZero--;
}
}
return eightBit;
}
/**
* Converts a number to four bit binary.
*
* @param binaryString string to binary
* @return numInBytes given number as bytes
*/
public static String toFourBitBinary(String binaryString) {
String fourBit = binaryString;
if (fourBit.length() % 4 != 0) {
int numOfZero = 4 - fourBit.length();
while (numOfZero > 0) {
fourBit = "0" + fourBit;
numOfZero--;
}
}
return fourBit;
}
/**
* Converts a number to three bytes.
*
* @param numberToConvert number to convert
* @return given number as bytes
*/
public static byte[] convertToThreeBytes(int numberToConvert) {
byte[] numInBytes = new byte[4];
String s1 = Integer.toHexString(numberToConvert);
if (s1.length() % 2 != 0) {
s1 = "0" + s1;
}
byte[] hexas = DatatypeConverter.parseHexBinary(s1);
if (hexas.length == 1) {
numInBytes[0] = 0;
numInBytes[1] = 0;
numInBytes[2] = hexas[0];
} else if (hexas.length == 2) {
numInBytes[0] = 0;
numInBytes[1] = hexas[0];
numInBytes[2] = hexas[1];
} else {
numInBytes[0] = hexas[0];
numInBytes[1] = hexas[1];
numInBytes[2] = hexas[2];
}
return numInBytes;
}
}