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