blob: 23dd1a7597859cd3cccd4947128f1b99cceb858a [file] [log] [blame]
Priyanka Bb2988fa2015-10-09 12:45:36 +05301/*
2 * Copyright 2015 Open Networking Laboratory
3 *
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 */
16
17package org.onosproject.bgpio.util;
18
Priyanka B03fa5e52015-10-30 12:46:40 +053019import java.net.InetAddress;
20import java.net.UnknownHostException;
Priyanka Bb2988fa2015-10-09 12:45:36 +053021import java.util.Arrays;
22
23import org.jboss.netty.buffer.ChannelBuffer;
24import org.jboss.netty.buffer.ChannelBuffers;
25import org.onlab.packet.IpAddress;
26import org.onlab.packet.IpPrefix;
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +053027import org.onosproject.bgpio.exceptions.BgpParseException;
Priyanka B03fa5e52015-10-30 12:46:40 +053028import org.slf4j.Logger;
29import org.slf4j.LoggerFactory;
Priyanka Bb2988fa2015-10-09 12:45:36 +053030
31import com.google.common.primitives.Ints;
32
33/**
34 * Provides methods to parse attribute header, validate length and type.
35 */
36public class Validation {
Priyanka B03fa5e52015-10-30 12:46:40 +053037 private static final Logger log = LoggerFactory.getLogger(Validation.class);
Priyanka Bb2988fa2015-10-09 12:45:36 +053038 public static final byte FIRST_BIT = (byte) 0x80;
39 public static final byte SECOND_BIT = 0x40;
40 public static final byte THIRD_BIT = 0x20;
Priyanka B03fa5e52015-10-30 12:46:40 +053041 public static final byte FOURTH_BIT = (byte) 0x10;
Priyanka Bb2988fa2015-10-09 12:45:36 +053042 public static final byte IPV4_SIZE = 4;
43 private boolean firstBit;
44 private boolean secondBit;
45 private boolean thirdBit;
46 private boolean fourthBit;
47 private int len;
48 private boolean isShort;
49
Priyanka B03fa5e52015-10-30 12:46:40 +053050 /**
51 * Constructor to initialize parameter.
52 *
53 * @param firstBit in AttributeFlags
54 * @param secondBit in AttributeFlags
55 * @param thirdBit in AttributeFlags
56 * @param fourthBit in AttributeFlags
57 * @param len length
58 * @param isShort true if length is read as short otherwise false
59 */
Priyanka Bb2988fa2015-10-09 12:45:36 +053060 Validation(boolean firstBit, boolean secondBit, boolean thirdBit, boolean fourthBit, int len, boolean isShort) {
61 this.firstBit = firstBit;
62 this.secondBit = secondBit;
63 this.thirdBit = thirdBit;
64 this.fourthBit = fourthBit;
65 this.len = len;
66 this.isShort = isShort;
67 }
68
69 /**
70 * Parses attribute Header.
71 *
72 * @param cb ChannelBuffer
73 * @return object of Validation
74 */
75 public static Validation parseAttributeHeader(ChannelBuffer cb) {
76
77 boolean firstBit;
78 boolean secondBit;
79 boolean thirdBit;
80 boolean fourthBit;
81 boolean isShort;
82 byte flags = cb.readByte();
83 byte typeCode = cb.readByte();
84 byte temp = flags;
85 //first Bit : Optional (1) or well-known (0)
86 firstBit = ((temp & FIRST_BIT) == FIRST_BIT);
87 //second Bit : Transitive (1) or non-Transitive (0)
88 secondBit = ((temp & SECOND_BIT) == SECOND_BIT);
89 //third Bit : partial (1) or complete (0)
90 thirdBit = ((temp & THIRD_BIT) == THIRD_BIT);
91 //forth Bit(Extended Length bit) : Attribute Length is 1 octects (0) or 2 octects (1)
92 fourthBit = ((temp & FOURTH_BIT) == FOURTH_BIT);
93 int len;
94 if (fourthBit) {
95 isShort = true;
96 short length = cb.readShort();
97 len = length;
98 } else {
99 isShort = false;
100 byte length = cb.readByte();
101 len = length;
102 }
103 return new Validation(firstBit, secondBit, thirdBit, fourthBit, len, isShort);
104 }
105
106 /**
107 * Throws exception if length is not correct.
108 *
109 * @param errorCode Error code
110 * @param subErrCode Sub Error Code
111 * @param length erroneous length
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530112 * @throws BgpParseException for erroneous length
Priyanka Bb2988fa2015-10-09 12:45:36 +0530113 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530114 public static void validateLen(byte errorCode, byte subErrCode, int length) throws BgpParseException {
Priyanka Bb2988fa2015-10-09 12:45:36 +0530115 byte[] errLen = Ints.toByteArray(length);
116 ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
117 buffer.writeBytes(errLen);
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530118 throw new BgpParseException(errorCode, subErrCode, buffer);
Priyanka Bb2988fa2015-10-09 12:45:36 +0530119 }
120
121 /**
122 * Throws exception if type is not correct.
123 *
124 * @param errorCode Error code
125 * @param subErrCode Sub Error Code
126 * @param type erroneous type
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530127 * @throws BgpParseException for erroneous type
Priyanka Bb2988fa2015-10-09 12:45:36 +0530128 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530129 public static void validateType(byte errorCode, byte subErrCode, int type) throws BgpParseException {
Priyanka Bb2988fa2015-10-09 12:45:36 +0530130 byte[] errType = Ints.toByteArray(type);
131 ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
132 buffer.writeBytes(errType);
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530133 throw new BgpParseException(errorCode, subErrCode, buffer);
Priyanka Bb2988fa2015-10-09 12:45:36 +0530134 }
135
136 /**
Priyanka B03fa5e52015-10-30 12:46:40 +0530137 * Convert byte array to InetAddress.
138 *
139 * @param length of IpAddress
140 * @param cb channelBuffer
141 * @return InetAddress
142 */
143 public static InetAddress toInetAddress(int length, ChannelBuffer cb) {
144 byte[] address = new byte[length];
145 cb.readBytes(address, 0, length);
146 InetAddress ipAddress = null;
147 try {
148 ipAddress = InetAddress.getByAddress(address);
149 } catch (UnknownHostException e) {
150 log.info("InetAddress convertion failed");
151 }
152 return ipAddress;
153 }
154
155 /**
Priyanka Bb2988fa2015-10-09 12:45:36 +0530156 * Returns first bit in type flags.
157 *
158 * @return first bit in type flags
159 */
160 public boolean getFirstBit() {
161 return this.firstBit;
162 }
163
164 /**
165 * Returns second bit in type flags.
166 *
167 * @return second bit in type flags
168 */
169 public boolean getSecondBit() {
170 return this.secondBit;
171 }
172
173 /**
174 * Returns third bit in type flags.
175 *
176 * @return third bit in type flags
177 */
178 public boolean getThirdBit() {
179 return this.thirdBit;
180 }
181
182 /**
183 * Returns fourth bit in type flags.
184 *
185 * @return fourth bit in type flags
186 */
187 public boolean getFourthBit() {
188 return this.fourthBit;
189 }
190
191 /**
192 * Returns attribute length.
193 *
194 * @return attribute length
195 */
196 public int getLength() {
197 return this.len;
198 }
199
200 /**
201 * Returns whether attribute length read in short or byte.
202 *
203 * @return whether attribute length read in short or byte
204 */
205 public boolean isShort() {
206 return this.isShort;
207 }
208
209 /**
210 * Converts byte array of prefix value to IpPrefix object.
211 *
212 * @param value byte array of prefix value
213 * @param length prefix length in bits
214 * @return object of IpPrefix
215 */
216 public static IpPrefix bytesToPrefix(byte[] value, int length) {
217 if (value.length != IPV4_SIZE) {
218 value = Arrays.copyOf(value, IPV4_SIZE);
219 }
220 IpPrefix ipPrefix = IpPrefix.valueOf(IpAddress.Version.INET, value, length);
221 return ipPrefix;
222 }
223}