blob: 23dd1a7597859cd3cccd4947128f1b99cceb858a [file] [log] [blame]
/*
* Copyright 2015 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.bgpio.util;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onosproject.bgpio.exceptions.BgpParseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.primitives.Ints;
/**
* Provides methods to parse attribute header, validate length and type.
*/
public class Validation {
private static final Logger log = LoggerFactory.getLogger(Validation.class);
public static final byte FIRST_BIT = (byte) 0x80;
public static final byte SECOND_BIT = 0x40;
public static final byte THIRD_BIT = 0x20;
public static final byte FOURTH_BIT = (byte) 0x10;
public static final byte IPV4_SIZE = 4;
private boolean firstBit;
private boolean secondBit;
private boolean thirdBit;
private boolean fourthBit;
private int len;
private boolean isShort;
/**
* Constructor to initialize parameter.
*
* @param firstBit in AttributeFlags
* @param secondBit in AttributeFlags
* @param thirdBit in AttributeFlags
* @param fourthBit in AttributeFlags
* @param len length
* @param isShort true if length is read as short otherwise false
*/
Validation(boolean firstBit, boolean secondBit, boolean thirdBit, boolean fourthBit, int len, boolean isShort) {
this.firstBit = firstBit;
this.secondBit = secondBit;
this.thirdBit = thirdBit;
this.fourthBit = fourthBit;
this.len = len;
this.isShort = isShort;
}
/**
* Parses attribute Header.
*
* @param cb ChannelBuffer
* @return object of Validation
*/
public static Validation parseAttributeHeader(ChannelBuffer cb) {
boolean firstBit;
boolean secondBit;
boolean thirdBit;
boolean fourthBit;
boolean isShort;
byte flags = cb.readByte();
byte typeCode = cb.readByte();
byte temp = flags;
//first Bit : Optional (1) or well-known (0)
firstBit = ((temp & FIRST_BIT) == FIRST_BIT);
//second Bit : Transitive (1) or non-Transitive (0)
secondBit = ((temp & SECOND_BIT) == SECOND_BIT);
//third Bit : partial (1) or complete (0)
thirdBit = ((temp & THIRD_BIT) == THIRD_BIT);
//forth Bit(Extended Length bit) : Attribute Length is 1 octects (0) or 2 octects (1)
fourthBit = ((temp & FOURTH_BIT) == FOURTH_BIT);
int len;
if (fourthBit) {
isShort = true;
short length = cb.readShort();
len = length;
} else {
isShort = false;
byte length = cb.readByte();
len = length;
}
return new Validation(firstBit, secondBit, thirdBit, fourthBit, len, isShort);
}
/**
* Throws exception if length is not correct.
*
* @param errorCode Error code
* @param subErrCode Sub Error Code
* @param length erroneous length
* @throws BgpParseException for erroneous length
*/
public static void validateLen(byte errorCode, byte subErrCode, int length) throws BgpParseException {
byte[] errLen = Ints.toByteArray(length);
ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
buffer.writeBytes(errLen);
throw new BgpParseException(errorCode, subErrCode, buffer);
}
/**
* Throws exception if type is not correct.
*
* @param errorCode Error code
* @param subErrCode Sub Error Code
* @param type erroneous type
* @throws BgpParseException for erroneous type
*/
public static void validateType(byte errorCode, byte subErrCode, int type) throws BgpParseException {
byte[] errType = Ints.toByteArray(type);
ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
buffer.writeBytes(errType);
throw new BgpParseException(errorCode, subErrCode, buffer);
}
/**
* Convert byte array to InetAddress.
*
* @param length of IpAddress
* @param cb channelBuffer
* @return InetAddress
*/
public static InetAddress toInetAddress(int length, ChannelBuffer cb) {
byte[] address = new byte[length];
cb.readBytes(address, 0, length);
InetAddress ipAddress = null;
try {
ipAddress = InetAddress.getByAddress(address);
} catch (UnknownHostException e) {
log.info("InetAddress convertion failed");
}
return ipAddress;
}
/**
* Returns first bit in type flags.
*
* @return first bit in type flags
*/
public boolean getFirstBit() {
return this.firstBit;
}
/**
* Returns second bit in type flags.
*
* @return second bit in type flags
*/
public boolean getSecondBit() {
return this.secondBit;
}
/**
* Returns third bit in type flags.
*
* @return third bit in type flags
*/
public boolean getThirdBit() {
return this.thirdBit;
}
/**
* Returns fourth bit in type flags.
*
* @return fourth bit in type flags
*/
public boolean getFourthBit() {
return this.fourthBit;
}
/**
* Returns attribute length.
*
* @return attribute length
*/
public int getLength() {
return this.len;
}
/**
* Returns whether attribute length read in short or byte.
*
* @return whether attribute length read in short or byte
*/
public boolean isShort() {
return this.isShort;
}
/**
* Converts byte array of prefix value to IpPrefix object.
*
* @param value byte array of prefix value
* @param length prefix length in bits
* @return object of IpPrefix
*/
public static IpPrefix bytesToPrefix(byte[] value, int length) {
if (value.length != IPV4_SIZE) {
value = Arrays.copyOf(value, IPV4_SIZE);
}
IpPrefix ipPrefix = IpPrefix.valueOf(IpAddress.Version.INET, value, length);
return ipPrefix;
}
}