org.onosproject.lisp.msg.protocols.DefaultLispInfo.java Source code

Java tutorial

Introduction

Here is the source code for org.onosproject.lisp.msg.protocols.DefaultLispInfo.java

Source

/*
 * Copyright 2016-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.lisp.msg.protocols;

import io.netty.buffer.ByteBuf;
import org.onlab.util.ByteOperator;
import org.onlab.util.ImmutableByteSequence;
import org.onosproject.lisp.msg.exceptions.LispParseError;
import org.onosproject.lisp.msg.exceptions.LispReaderException;
import org.onosproject.lisp.msg.exceptions.LispWriterException;
import org.onosproject.lisp.msg.types.LispAfiAddress;
import org.onosproject.lisp.msg.types.LispAfiAddress.AfiAddressWriter;

import java.util.Arrays;

/**
 * A class that contains a set of helper methods for LISP info request and reply.
 */
public class DefaultLispInfo extends AbstractLispMessage implements LispInfo {

    protected final boolean infoReply;
    protected final long nonce;
    protected final short keyId;
    protected final short authDataLength;
    protected final byte[] authData;
    protected final int ttl;
    protected final byte maskLength;
    protected final LispAfiAddress eidPrefix;

    private static final int INFO_REPLY_INDEX = 3;
    private static final int RESERVED_SKIP_LENGTH_1 = 3;
    private static final int RESERVED_SKIP_LENGTH_2 = 1;

    private static final int INFO_REQUEST_SHIFT_BIT = 4;

    private static final int ENABLE_BIT = 1;
    private static final int DISABLE_BIT = 0;

    private static final int UNUSED_ZERO = 0;

    /**
     * A private constructor that protects object instantiation from external.
     *
     * @param infoReply      info reply flag
     * @param nonce          nonce
     * @param keyId          key identifier
     * @param authDataLength authentication data length
     * @param authData       authentication data
     * @param ttl            Time-To-Live value
     * @param maskLength     EID prefix mask length
     * @param eidPrefix      EID prefix
     */
    protected DefaultLispInfo(boolean infoReply, long nonce, short keyId, short authDataLength, byte[] authData,
            int ttl, byte maskLength, LispAfiAddress eidPrefix) {
        this.infoReply = infoReply;
        this.nonce = nonce;
        this.keyId = keyId;
        this.authDataLength = authDataLength;
        this.authData = authData;
        this.ttl = ttl;
        this.maskLength = maskLength;
        this.eidPrefix = eidPrefix;
    }

    @Override
    public LispType getType() {
        return LispType.LISP_INFO;
    }

    @Override
    public void writeTo(ByteBuf byteBuf) throws LispWriterException {
        serialize(byteBuf, this);
    }

    @Override
    public Builder createBuilder() {
        return new DefaultLispInfoRequest.DefaultInfoRequestBuilder();
    }

    @Override
    public boolean isInfoReply() {
        return infoReply;
    }

    @Override
    public long getNonce() {
        return nonce;
    }

    @Override
    public short getKeyId() {
        return keyId;
    }

    @Override
    public short getAuthDataLength() {
        return authDataLength;
    }

    @Override
    public byte[] getAuthData() {
        if (authData != null && authData.length != 0) {
            return ImmutableByteSequence.copyFrom(authData).asArray();
        } else {
            return new byte[0];
        }
    }

    @Override
    public int getTtl() {
        return ttl;
    }

    @Override
    public byte getMaskLength() {
        return maskLength;
    }

    @Override
    public LispAfiAddress getPrefix() {
        return eidPrefix;
    }

    public static LispInfo deserialize(ByteBuf byteBuf) throws LispParseError, LispReaderException {

        if (byteBuf.readerIndex() != 0) {
            return null;
        }

        // infoReply -> 1 bit
        boolean infoReplyFlag = ByteOperator.getBit(byteBuf.readByte(), INFO_REPLY_INDEX);

        // let's skip the reserved field
        byteBuf.skipBytes(RESERVED_SKIP_LENGTH_1);

        // nonce -> 64 bits
        long nonce = byteBuf.readLong();

        // keyId -> 16 bits
        short keyId = byteBuf.readShort();

        // authenticationDataLength -> 16 bits
        short authLength = byteBuf.readShort();

        // authData -> depends on the authenticationDataLength
        byte[] authData = new byte[authLength];
        byteBuf.readBytes(authData);

        // ttl -> 32 bits
        int ttl = byteBuf.readInt();

        // let's skip the reserved field
        byteBuf.skipBytes(RESERVED_SKIP_LENGTH_2);

        // mask length -> 8 bits
        short maskLength = byteBuf.readUnsignedByte();

        LispAfiAddress prefix = new LispAfiAddress.AfiAddressReader().readFrom(byteBuf);

        return new DefaultLispInfo(infoReplyFlag, nonce, keyId, authLength, authData, ttl, (byte) maskLength,
                prefix);
    }

    public static void serialize(ByteBuf byteBuf, LispInfo message) throws LispWriterException {

        // specify LISP message type
        byte msgType = (byte) (LispType.LISP_INFO.getTypeCode() << INFO_REQUEST_SHIFT_BIT);

        // info reply flag
        byte infoReply = DISABLE_BIT;
        if (message.isInfoReply()) {
            infoReply = (byte) (ENABLE_BIT << INFO_REPLY_INDEX);
        }

        byteBuf.writeByte(msgType + infoReply);

        // fill zero into reserved filed
        byteBuf.writeByte((short) UNUSED_ZERO);
        byteBuf.writeByte((short) UNUSED_ZERO);
        byteBuf.writeByte((short) UNUSED_ZERO);

        // nonce
        byteBuf.writeLong(message.getNonce());

        // keyId
        byteBuf.writeShort(message.getKeyId());

        // authentication data length in octet
        byteBuf.writeShort(message.getAuthDataLength());

        // authentication data
        byte[] data = message.getAuthData();
        byte[] clone;
        if (data != null) {
            clone = data.clone();
            Arrays.fill(clone, (byte) UNUSED_ZERO);
        }

        byteBuf.writeBytes(data);

        /// TTL
        byteBuf.writeInt(message.getTtl());

        // fill zero into reserved filed
        byteBuf.writeByte((short) UNUSED_ZERO);

        // mask length
        byteBuf.writeByte(message.getMaskLength());

        // EID prefix AFI with EID prefix
        AfiAddressWriter afiAddressWriter = new AfiAddressWriter();
        afiAddressWriter.writeTo(byteBuf, message.getPrefix());
    }
}