| /* |
| * Copyright 2015-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.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; |
| } |
| } |