blob: 21ab24442743c3f4acdb8ad39de24d0f5ae569ae [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;
Ankur Aggarwalf363d1a2019-11-11 14:56:18 +053044 public static final byte IPV6_SIZE = 16;
45 public static final int INET4_LENGTH = 32;
46
Priyanka Bb2988fa2015-10-09 12:45:36 +053047 private boolean firstBit;
48 private boolean secondBit;
49 private boolean thirdBit;
50 private boolean fourthBit;
51 private int len;
52 private boolean isShort;
53
Priyanka B03fa5e52015-10-30 12:46:40 +053054 /**
55 * Constructor to initialize parameter.
56 *
57 * @param firstBit in AttributeFlags
58 * @param secondBit in AttributeFlags
59 * @param thirdBit in AttributeFlags
60 * @param fourthBit in AttributeFlags
61 * @param len length
62 * @param isShort true if length is read as short otherwise false
63 */
Priyanka Bb2988fa2015-10-09 12:45:36 +053064 Validation(boolean firstBit, boolean secondBit, boolean thirdBit, boolean fourthBit, int len, boolean isShort) {
65 this.firstBit = firstBit;
66 this.secondBit = secondBit;
67 this.thirdBit = thirdBit;
68 this.fourthBit = fourthBit;
69 this.len = len;
70 this.isShort = isShort;
71 }
72
73 /**
74 * Parses attribute Header.
75 *
76 * @param cb ChannelBuffer
77 * @return object of Validation
78 */
79 public static Validation parseAttributeHeader(ChannelBuffer cb) {
80
81 boolean firstBit;
82 boolean secondBit;
83 boolean thirdBit;
84 boolean fourthBit;
85 boolean isShort;
86 byte flags = cb.readByte();
87 byte typeCode = cb.readByte();
88 byte temp = flags;
89 //first Bit : Optional (1) or well-known (0)
90 firstBit = ((temp & FIRST_BIT) == FIRST_BIT);
91 //second Bit : Transitive (1) or non-Transitive (0)
92 secondBit = ((temp & SECOND_BIT) == SECOND_BIT);
93 //third Bit : partial (1) or complete (0)
94 thirdBit = ((temp & THIRD_BIT) == THIRD_BIT);
95 //forth Bit(Extended Length bit) : Attribute Length is 1 octects (0) or 2 octects (1)
96 fourthBit = ((temp & FOURTH_BIT) == FOURTH_BIT);
97 int len;
98 if (fourthBit) {
99 isShort = true;
100 short length = cb.readShort();
101 len = length;
102 } else {
103 isShort = false;
104 byte length = cb.readByte();
105 len = length;
106 }
107 return new Validation(firstBit, secondBit, thirdBit, fourthBit, len, isShort);
108 }
109
110 /**
111 * Throws exception if length is not correct.
112 *
113 * @param errorCode Error code
114 * @param subErrCode Sub Error Code
115 * @param length erroneous length
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530116 * @throws BgpParseException for erroneous length
Priyanka Bb2988fa2015-10-09 12:45:36 +0530117 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530118 public static void validateLen(byte errorCode, byte subErrCode, int length) throws BgpParseException {
Priyanka Bb2988fa2015-10-09 12:45:36 +0530119 byte[] errLen = Ints.toByteArray(length);
120 ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
121 buffer.writeBytes(errLen);
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530122 throw new BgpParseException(errorCode, subErrCode, buffer);
Priyanka Bb2988fa2015-10-09 12:45:36 +0530123 }
124
125 /**
126 * Throws exception if type is not correct.
127 *
128 * @param errorCode Error code
129 * @param subErrCode Sub Error Code
130 * @param type erroneous type
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530131 * @throws BgpParseException for erroneous type
Priyanka Bb2988fa2015-10-09 12:45:36 +0530132 */
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530133 public static void validateType(byte errorCode, byte subErrCode, int type) throws BgpParseException {
Priyanka Bb2988fa2015-10-09 12:45:36 +0530134 byte[] errType = Ints.toByteArray(type);
135 ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
136 buffer.writeBytes(errType);
Shashikanth VH5dd8dbe2015-11-26 13:22:18 +0530137 throw new BgpParseException(errorCode, subErrCode, buffer);
Priyanka Bb2988fa2015-10-09 12:45:36 +0530138 }
139
140 /**
Priyanka B03fa5e52015-10-30 12:46:40 +0530141 * Convert byte array to InetAddress.
142 *
143 * @param length of IpAddress
144 * @param cb channelBuffer
145 * @return InetAddress
146 */
147 public static InetAddress toInetAddress(int length, ChannelBuffer cb) {
148 byte[] address = new byte[length];
149 cb.readBytes(address, 0, length);
150 InetAddress ipAddress = null;
151 try {
152 ipAddress = InetAddress.getByAddress(address);
153 } catch (UnknownHostException e) {
Ray Milkeyc108a6b2017-08-23 15:23:50 -0700154 log.info("InetAddress conversion failed");
Priyanka B03fa5e52015-10-30 12:46:40 +0530155 }
156 return ipAddress;
157 }
Mohammad Shahid30fedc52017-08-09 11:49:40 +0530158 /**
159 * Convert byte array to MacAddress.
160 *
161 * @param length of MacAddress
162 * @param cb channelBuffer
163 * @return macAddress
164 */
165 public static MacAddress toMacAddress(int length, ChannelBuffer cb) {
166 byte[] address = new byte[length];
167 cb.readBytes(address, 0, length);
168 MacAddress macAddress = MacAddress.valueOf(address);
169 return macAddress;
170 }
Priyanka B03fa5e52015-10-30 12:46:40 +0530171 /**
Priyanka Bb2988fa2015-10-09 12:45:36 +0530172 * Returns first bit in type flags.
173 *
174 * @return first bit in type flags
175 */
176 public boolean getFirstBit() {
177 return this.firstBit;
178 }
179
180 /**
181 * Returns second bit in type flags.
182 *
183 * @return second bit in type flags
184 */
185 public boolean getSecondBit() {
186 return this.secondBit;
187 }
188
189 /**
190 * Returns third bit in type flags.
191 *
192 * @return third bit in type flags
193 */
194 public boolean getThirdBit() {
195 return this.thirdBit;
196 }
197
198 /**
199 * Returns fourth bit in type flags.
200 *
201 * @return fourth bit in type flags
202 */
203 public boolean getFourthBit() {
204 return this.fourthBit;
205 }
206
207 /**
208 * Returns attribute length.
209 *
210 * @return attribute length
211 */
212 public int getLength() {
213 return this.len;
214 }
215
216 /**
217 * Returns whether attribute length read in short or byte.
218 *
219 * @return whether attribute length read in short or byte
220 */
221 public boolean isShort() {
222 return this.isShort;
223 }
224
225 /**
226 * Converts byte array of prefix value to IpPrefix object.
227 *
228 * @param value byte array of prefix value
229 * @param length prefix length in bits
230 * @return object of IpPrefix
231 */
232 public static IpPrefix bytesToPrefix(byte[] value, int length) {
Ankur Aggarwalf363d1a2019-11-11 14:56:18 +0530233 if (length <= INET4_LENGTH) {
234 //Treat like IPv4 address
235 if (value.length != IPV4_SIZE) {
236 value = Arrays.copyOf(value, IPV4_SIZE);
237 }
238 IpPrefix ipPrefix = IpPrefix.valueOf(IpAddress.Version.INET, value, length);
239 return ipPrefix;
240 } else {
241 //Treat this like IPv6 address
242 if (value.length != IPV6_SIZE) {
243 value = Arrays.copyOf(value, IPV6_SIZE);
244 }
245 IpPrefix ipPrefix = IpPrefix.valueOf(IpAddress.Version.INET6, value, length);
246 return ipPrefix;
Priyanka Bb2988fa2015-10-09 12:45:36 +0530247 }
Priyanka Bb2988fa2015-10-09 12:45:36 +0530248 }
Ray Milkeyc108a6b2017-08-23 15:23:50 -0700249}