aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/onos/bgp/bgpio/src/main/java/org/onosproject/bgpio/util/Validation.java
blob: 23dd1a7597859cd3cccd4947128f1b99cceb858a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
/*
 * 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;
    }
}