[ONOS-5427] Add LISP Info-Request and Info-Reply message type

Change-Id: Ia54919945609a57e45b34af3bbe7b04e4a7efbec
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispInfo.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispInfo.java
new file mode 100644
index 0000000..14cd884
--- /dev/null
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispInfo.java
@@ -0,0 +1,230 @@
+/*
+ * 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 implements LispInfo {
+
+    protected final boolean infoReply;
+    protected final long nonce;
+    protected final short keyId;
+    protected final short authDataLength;
+    protected final byte[] authenticationData;
+    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 authenticationData 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[] authenticationData, int ttl, byte maskLength,
+                              LispAfiAddress eidPrefix) {
+        this.infoReply = infoReply;
+        this.nonce = nonce;
+        this.keyId = keyId;
+        this.authDataLength = authDataLength;
+        this.authenticationData = authenticationData;
+        this.ttl = ttl;
+        this.maskLength = maskLength;
+        this.eidPrefix = eidPrefix;
+    }
+
+    @Override
+    public LispType getType() {
+        return LispType.LISP_INFO;
+    }
+
+    @Override
+    public void writeTo(ByteBuf byteBuf) {
+        // TODO: serialize LispMapRegister message
+    }
+
+    @Override
+    public Builder createBuilder() {
+        return new DefaultLispInfoRequest.DefaultInfoRequestBuilder();
+    }
+
+    @Override
+    public boolean hasInfoReply() {
+        return infoReply;
+    }
+
+    @Override
+    public long getNonce() {
+        return nonce;
+    }
+
+    @Override
+    public short getKeyId() {
+        return keyId;
+    }
+
+    @Override
+    public short getAuthDataLength() {
+        return authDataLength;
+    }
+
+    @Override
+    public byte[] getAuthenticationData() {
+        if (authenticationData != null && authenticationData.length != 0) {
+            return ImmutableByteSequence.copyFrom(authenticationData).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();
+
+        // authenticationData -> 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.hasInfoReply()) {
+            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.getAuthenticationData();
+        byte[] clone;
+        if (data != null) {
+            clone = data.clone();
+            Arrays.fill(clone, (byte) UNUSED_ZERO);
+        }
+
+        byteBuf.writeBytes(data);
+
+        // TODO: need to implement MAC authentication mechanism
+
+        /// 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());
+    }
+}
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispInfoReply.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispInfoReply.java
new file mode 100644
index 0000000..9576dee
--- /dev/null
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispInfoReply.java
@@ -0,0 +1,219 @@
+/*
+ * 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 com.google.common.base.Objects;
+import io.netty.buffer.ByteBuf;
+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.LispNatLcafAddress;
+import org.onosproject.lisp.msg.types.LispNatLcafAddress.NatLcafAddressWriter;
+
+import java.util.Arrays;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Default LISP info reply message class.
+ */
+public final class DefaultLispInfoReply extends DefaultLispInfo implements LispInfoReply {
+
+    private final LispNatLcafAddress natLcafAddress;
+
+    /**
+     * 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 authenticationData authentication data
+     * @param ttl                Time-To-Live value
+     * @param maskLength         EID prefix mask length
+     * @param eidPrefix          EID prefix
+     * @param natLcafAddress     NAT LCAF address
+     */
+    protected DefaultLispInfoReply(boolean infoReply, long nonce, short keyId, short authDataLength,
+                                 byte[] authenticationData, int ttl, byte maskLength,
+                                 LispAfiAddress eidPrefix, LispNatLcafAddress natLcafAddress) {
+        super(infoReply, nonce, keyId, authDataLength, authenticationData, ttl, maskLength, eidPrefix);
+        this.natLcafAddress = natLcafAddress;
+    }
+
+    @Override
+    public LispNatLcafAddress getNatLcafAddress() {
+        return natLcafAddress;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this)
+                .add("type", getType())
+                .add("nonce", nonce)
+                .add("keyId", keyId)
+                .add("authentication data length", authDataLength)
+                .add("authentication data", authenticationData)
+                .add("TTL", ttl)
+                .add("EID mask length", maskLength)
+                .add("EID prefix", eidPrefix)
+                .add("NAT LCAF address", natLcafAddress).toString();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        DefaultLispInfoReply that = (DefaultLispInfoReply) o;
+        return Objects.equal(nonce, that.nonce) &&
+                Objects.equal(keyId, that.keyId) &&
+                Objects.equal(authDataLength, that.authDataLength) &&
+                Arrays.equals(authenticationData, that.authenticationData) &&
+                Objects.equal(ttl, that.ttl) &&
+                Objects.equal(maskLength, that.maskLength) &&
+                Objects.equal(eidPrefix, that.eidPrefix) &&
+                Objects.equal(natLcafAddress, that.natLcafAddress);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(nonce, keyId, authDataLength, ttl, maskLength,
+                eidPrefix, natLcafAddress) + Arrays.hashCode(authenticationData);
+    }
+
+    public static final class DefaultInfoReplyBuilder implements InfoReplyBuilder {
+
+        private boolean infoReply;
+        private long nonce;
+        private short keyId;
+        private short authDataLength;
+        private byte[] authenticationData = new byte[0];
+        private int ttl;
+        private byte maskLength;
+        private LispAfiAddress eidPrefix;
+        private LispNatLcafAddress natLcafAddress;
+
+        @Override
+        public LispType getType() {
+            return LispType.LISP_INFO;
+        }
+
+
+        @Override
+        public InfoReplyBuilder withInfoReply(boolean infoReply) {
+            this.infoReply = infoReply;
+            return this;
+        }
+
+        @Override
+        public InfoReplyBuilder withNonce(long nonce) {
+            this.nonce = nonce;
+            return this;
+        }
+
+        @Override
+        public InfoReplyBuilder withAuthDataLength(short authDataLength) {
+            this.authDataLength = authDataLength;
+            return this;
+        }
+
+        @Override
+        public InfoReplyBuilder withKeyId(short keyId) {
+            this.keyId = keyId;
+            return this;
+        }
+
+        @Override
+        public InfoReplyBuilder withAuthenticationData(byte[] authenticationData) {
+            if (authenticationData != null) {
+                this.authenticationData = authenticationData;
+            }
+            return this;
+        }
+
+        @Override
+        public InfoReplyBuilder withTtl(int ttl) {
+            this.ttl = ttl;
+            return this;
+        }
+
+        @Override
+        public InfoReplyBuilder withMaskLength(byte maskLength) {
+            this.maskLength = maskLength;
+            return this;
+        }
+
+        @Override
+        public InfoReplyBuilder withEidPrefix(LispAfiAddress eidPrefix) {
+            this.eidPrefix = eidPrefix;
+            return this;
+        }
+
+
+        @Override
+        public InfoReplyBuilder withNatLcafAddress(LispNatLcafAddress natLcafAddress) {
+            this.natLcafAddress = natLcafAddress;
+            return this;
+        }
+
+        @Override
+        public LispInfoReply build() {
+            return new DefaultLispInfoReply(infoReply, nonce, keyId, authDataLength,
+                    authenticationData, ttl, maskLength, eidPrefix, natLcafAddress);
+        }
+    }
+
+    /**
+     * A LISP message reader for InfoReply message.
+     */
+    public static final class InfoReplyReader implements LispMessageReader<LispInfoReply> {
+
+        @Override
+        public LispInfoReply readFrom(ByteBuf byteBuf) throws LispParseError, LispReaderException {
+            LispInfo lispInfo = DefaultLispInfo.deserialize(byteBuf);
+            LispNatLcafAddress natLcafAddress = new LispNatLcafAddress.NatLcafAddressReader().readFrom(byteBuf);
+
+            return new DefaultInfoReplyBuilder()
+                    .withInfoReply(lispInfo.hasInfoReply())
+                    .withNonce(lispInfo.getNonce())
+                    .withKeyId(lispInfo.getKeyId())
+                    .withAuthDataLength(lispInfo.getAuthDataLength())
+                    .withAuthenticationData(lispInfo.getAuthenticationData())
+                    .withTtl(lispInfo.getTtl())
+                    .withMaskLength(lispInfo.getMaskLength())
+                    .withEidPrefix(lispInfo.getPrefix())
+                    .withNatLcafAddress(natLcafAddress).build();
+        }
+    }
+
+    public static final class InfoReplyWriter implements LispMessageWriter<LispInfoReply> {
+
+        @Override
+        public void writeTo(ByteBuf byteBuf, LispInfoReply message) throws LispWriterException {
+            DefaultLispInfo.serialize(byteBuf, message);
+
+            // NAT LCAF address
+            NatLcafAddressWriter writer = new NatLcafAddressWriter();
+            writer.writeTo(byteBuf, message.getNatLcafAddress());
+        }
+    }
+}
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispInfoRequest.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispInfoRequest.java
new file mode 100644
index 0000000..afe473f
--- /dev/null
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispInfoRequest.java
@@ -0,0 +1,196 @@
+/*
+ * 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 com.google.common.base.Objects;
+import io.netty.buffer.ByteBuf;
+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 java.util.Arrays;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Default LISP info request message class.
+ */
+public class DefaultLispInfoRequest extends DefaultLispInfo implements LispInfoRequest {
+
+    /**
+     * 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 authenticationData authentication data
+     * @param ttl                Time-To-Live value
+     * @param maskLength         EID prefix mask length
+     * @param eidPrefix          EID prefix
+     */
+    protected DefaultLispInfoRequest(boolean infoReply, long nonce, short keyId, short authDataLength,
+                                     byte[] authenticationData, int ttl, byte maskLength,
+                                     LispAfiAddress eidPrefix) {
+        super(infoReply, nonce, keyId, authDataLength, authenticationData, ttl, maskLength, eidPrefix);
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this)
+                .add("type", getType())
+                .add("nonce", nonce)
+                .add("keyId", keyId)
+                .add("authentication data length", authDataLength)
+                .add("authentication data", authenticationData)
+                .add("TTL", ttl)
+                .add("EID mask length", maskLength)
+                .add("EID prefix", eidPrefix).toString();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        DefaultLispInfoRequest that = (DefaultLispInfoRequest) o;
+        return Objects.equal(nonce, that.nonce) &&
+                Objects.equal(keyId, that.keyId) &&
+                Objects.equal(authDataLength, that.authDataLength) &&
+                Arrays.equals(authenticationData, that.authenticationData) &&
+                Objects.equal(ttl, that.ttl) &&
+                Objects.equal(maskLength, that.maskLength) &&
+                Objects.equal(eidPrefix, that.eidPrefix);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(nonce, keyId, authDataLength, ttl, maskLength,
+                eidPrefix) + Arrays.hashCode(authenticationData);
+    }
+
+    public static final class DefaultInfoRequestBuilder implements InfoRequestBuilder {
+
+        private boolean infoReply;
+        private long nonce;
+        private short keyId;
+        private short authDataLength;
+        private byte[] authenticationData = new byte[0];
+        private int ttl;
+        private byte maskLength;
+        private LispAfiAddress eidPrefix;
+
+        @Override
+        public LispType getType() {
+            return LispType.LISP_INFO;
+        }
+
+
+        @Override
+        public InfoRequestBuilder withInfoReply(boolean infoReply) {
+            this.infoReply = infoReply;
+            return this;
+        }
+
+        @Override
+        public InfoRequestBuilder withNonce(long nonce) {
+            this.nonce = nonce;
+            return this;
+        }
+
+        @Override
+        public InfoRequestBuilder withAuthDataLength(short authDataLength) {
+            this.authDataLength = authDataLength;
+            return this;
+        }
+
+        @Override
+        public InfoRequestBuilder withKeyId(short keyId) {
+            this.keyId = keyId;
+            return this;
+        }
+
+        @Override
+        public InfoRequestBuilder withAuthenticationData(byte[] authenticationData) {
+            if (authenticationData != null) {
+                this.authenticationData = authenticationData;
+            }
+            return this;
+        }
+
+        @Override
+        public InfoRequestBuilder withTtl(int ttl) {
+            this.ttl = ttl;
+            return this;
+        }
+
+        @Override
+        public InfoRequestBuilder withMaskLength(byte maskLength) {
+            this.maskLength = maskLength;
+            return this;
+        }
+
+        @Override
+        public InfoRequestBuilder withEidPrefix(LispAfiAddress eidPrefix) {
+            this.eidPrefix = eidPrefix;
+            return this;
+        }
+
+        @Override
+        public LispInfoRequest build() {
+            return new DefaultLispInfoRequest(infoReply, nonce, keyId,
+                    authDataLength, authenticationData, ttl, maskLength, eidPrefix);
+        }
+    }
+
+    /**
+     * A LISP message reader for InfoRequest message.
+     */
+    public static class InfoRequestReader implements LispMessageReader<LispInfoRequest> {
+
+        @Override
+        public LispInfoRequest readFrom(ByteBuf byteBuf) throws LispParseError, LispReaderException {
+
+            LispInfo lispInfo = DefaultLispInfo.deserialize(byteBuf);
+
+            return new DefaultInfoRequestBuilder()
+                    .withInfoReply(lispInfo.hasInfoReply())
+                    .withNonce(lispInfo.getNonce())
+                    .withKeyId(lispInfo.getKeyId())
+                    .withAuthDataLength(lispInfo.getAuthDataLength())
+                    .withAuthenticationData(lispInfo.getAuthenticationData())
+                    .withTtl(lispInfo.getTtl())
+                    .withMaskLength(lispInfo.getMaskLength())
+                    .withEidPrefix(lispInfo.getPrefix()).build();
+        }
+    }
+
+    /**
+     * A LISP message writer for InfoRequest message.
+     */
+    public static final class InfoRequestWriter implements LispMessageWriter<LispInfoRequest> {
+
+        @Override
+        public void writeTo(ByteBuf byteBuf, LispInfoRequest message) throws LispWriterException {
+            DefaultLispInfo.serialize(byteBuf, message);
+        }
+    }
+}
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRegister.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRegister.java
index 7ccc7b6..2d1ff43 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRegister.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/DefaultLispMapRegister.java
@@ -51,6 +51,7 @@
      *
      * @param nonce              nonce
      * @param keyId              key identifier
+     * @param authDataLength     authentication data length
      * @param authenticationData authentication data
      * @param mapRecords         a collection of map records
      * @param proxyMapReply      proxy map reply flag
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/InfoBuilder.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/InfoBuilder.java
new file mode 100644
index 0000000..0b6f381
--- /dev/null
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/InfoBuilder.java
@@ -0,0 +1,89 @@
+/*
+ * 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 org.onosproject.lisp.msg.protocols.LispMessage.Builder;
+import org.onosproject.lisp.msg.types.LispAfiAddress;
+
+/**
+ * LISP info message interface.
+ */
+public interface InfoBuilder<T> extends Builder {
+
+    /**
+     * Sets info reply flag value.
+     *
+     * @param infoReply info reply
+     * @return T object
+     */
+    T withInfoReply(boolean infoReply);
+
+    /**
+     * Sets nonce value.
+     *
+     * @param nonce nonce value
+     * @return T object
+     */
+    T withNonce(long nonce);
+
+    /**
+     * Sets authentication data length.
+     *
+     * @param authDataLength authentication data length
+     * @return T object
+     */
+    T withAuthDataLength(short authDataLength);
+
+    /**
+     * Sets key identifier.
+     *
+     * @param keyId key identifier
+     * @return T object
+     */
+    T withKeyId(short keyId);
+
+    /**
+     * Sets authentication data.
+     *
+     * @param authenticationData authentication data
+     * @return T object
+     */
+    T withAuthenticationData(byte[] authenticationData);
+
+    /**
+     * Sets Time-To-Live value.
+     *
+     * @param ttl Time-To-Live value
+     * @return T object
+     */
+    T withTtl(int ttl);
+
+    /**
+     * Sets EID prefix mask length.
+     *
+     * @param maskLength EID prefix mask length
+     * @return T object
+     */
+    T withMaskLength(byte maskLength);
+
+    /**
+     * Sets EID prefix.
+     *
+     * @param eidPrefix EID prefix
+     * @return T object
+     */
+    T withEidPrefix(LispAfiAddress eidPrefix);
+}
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispInfo.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispInfo.java
new file mode 100644
index 0000000..1fd9b46
--- /dev/null
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispInfo.java
@@ -0,0 +1,80 @@
+/*
+ * 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 org.onosproject.lisp.msg.types.LispAfiAddress;
+
+/**
+ * LISP info super interface.
+ */
+public interface LispInfo extends LispMessage {
+
+    /**
+     * Obtains has info reply flag value.
+     *
+     * @return has info reply flag value
+     */
+    boolean hasInfoReply();
+
+    /**
+     * Obtains nonce value.
+     *
+     * @return nonce value
+     */
+    long getNonce();
+
+    /**
+     * Obtains key identifier.
+     *
+     * @return key identifier
+     */
+    short getKeyId();
+
+    /**
+     * Obtains authentication data length.
+     *
+     * @return authentication data length
+     */
+    short getAuthDataLength();
+
+    /**
+     * Obtains authentication data.
+     *
+     * @return authentication data
+     */
+    byte[] getAuthenticationData();
+
+    /**
+     * Obtains TTL value.
+     *
+     * @return record TTL value
+     */
+    int getTtl();
+
+    /**
+     * Obtains mask length of the EID Record.
+     *
+     * @return mask length of the EID Record
+     */
+    byte getMaskLength();
+
+    /**
+     * Obtains EID prefix.
+     *
+     * @return EID prefix
+     */
+    LispAfiAddress getPrefix();
+}
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispInfoReply.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispInfoReply.java
new file mode 100644
index 0000000..05c642c
--- /dev/null
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispInfoReply.java
@@ -0,0 +1,91 @@
+/*
+ * 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 org.onosproject.lisp.msg.types.LispNatLcafAddress;
+
+/**
+ * LISP info reply message interface.
+ * <p>
+ * LISP info reply message format is defined in draft-ermagan-lisp-nat-traversal-01.
+ * https://tools.ietf.org/html/draft-ermagan-lisp-nat-traversal-01#page-8
+ *
+ * <pre>
+ * {@literal
+ *     0                   1                   2                   3
+ *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *    |Type=7 |R|               Reserved                              |
+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *    |                         Nonce . . .                           |
+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *    |                      . . . Nonce                              |
+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *    |            Key ID             |  Authentication Data Length   |
+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *    ~                     Authentication Data                       ~
+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *    |                              TTL                              |
+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *    |   Reserved    | EID mask-len  |        EID-prefix-AFI         |
+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *    |                          EID-prefix                           |
+ * +->+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |  |           AFI = 16387         |    Rsvd1      |     Flags     |
+ * |  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |  |    Type = 7     |     Rsvd2   |             4 + n             |
+ * |  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * N  |        MS UDP Port Number     |      ETR UDP Port Number      |
+ * A  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * T  |              AFI = x          | Global ETR RLOC Address  ...  |
+ *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * L  |              AFI = x          |       MS RLOC Address  ...    |
+ * C  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * A  |              AFI = x          | Private ETR RLOC Address ...  |
+ * F  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |  |              AFI = x          |      RTR RLOC Address 1 ...   |
+ * |  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |  |              AFI = x          |       RTR RLOC Address n ...  |
+ * +->+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * }</pre>
+ */
+public interface LispInfoReply extends LispInfo {
+
+    /**
+     * Obtains NAT LCAF address.
+     *
+     * @return NAT LCAF address
+     */
+    LispNatLcafAddress getNatLcafAddress();
+
+    interface InfoReplyBuilder extends InfoBuilder<InfoReplyBuilder> {
+
+        /**
+         * Sets NAT LCAF address.
+         *
+         * @param natLcafAddress NAT LCAF address
+         * @return InfoReplyBuilder object
+         */
+        InfoReplyBuilder withNatLcafAddress(LispNatLcafAddress natLcafAddress);
+
+        /**
+         * Builds LISP info reply message.
+         *
+         * @return LISP info reply message
+         */
+        LispInfoReply build();
+    }
+}
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispInfoRequest.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispInfoRequest.java
new file mode 100644
index 0000000..81a9dcf
--- /dev/null
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispInfoRequest.java
@@ -0,0 +1,60 @@
+/*
+ * 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;
+
+/**
+ * LISP info request message interface.
+ * <p>
+ * LISP info request message format is defined in draft-ermagan-lisp-nat-traversal-01.
+ * https://tools.ietf.org/html/draft-ermagan-lisp-nat-traversal-01#page-7
+ *
+ * <pre>
+ * {@literal
+ *  0                   1                   2                     3
+ *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |Type=7 |R|            Reserved                                 |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                         Nonce . . .                           |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                      . . . Nonce                              |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |              Key ID           |  Authentication Data Length   |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * ~                     Authentication Data                       ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                              TTL                              |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |   Reserved    | EID mask-len  |        EID-prefix-AFI         |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |                          EID-prefix                           |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |             AFI = 0           |   <Nothing Follows AFI=0>     |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * }</pre>
+ */
+public interface LispInfoRequest extends LispInfo {
+
+    interface InfoRequestBuilder extends InfoBuilder<InfoRequestBuilder> {
+
+        /**
+         * Builds LISP info request message.
+         *
+         * @return LISP info request message
+         */
+        LispInfoRequest build();
+    }
+}
diff --git a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispType.java b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispType.java
index 401f10b..aeacc00 100644
--- a/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispType.java
+++ b/protocols/lisp/msg/src/main/java/org/onosproject/lisp/msg/protocols/LispType.java
@@ -27,6 +27,7 @@
     LISP_MAP_REPLY(2),              // LISP Map-Reply Message
     LISP_MAP_REGISTER(3),           // LISP Map-Register Message
     LISP_MAP_NOTIFY(4),             // LISP Map-Notify Message
+    LISP_INFO(7),                   // LISP Info-Request or Info-Reply Message
     UNKNOWN(-1);                    // Other Enums for internal use
 
     private final short type;
diff --git a/protocols/lisp/msg/src/test/java/org/onosproject/lisp/msg/protocols/DefaultLispInfoReplyTest.java b/protocols/lisp/msg/src/test/java/org/onosproject/lisp/msg/protocols/DefaultLispInfoReplyTest.java
new file mode 100644
index 0000000..1952a03
--- /dev/null
+++ b/protocols/lisp/msg/src/test/java/org/onosproject/lisp/msg/protocols/DefaultLispInfoReplyTest.java
@@ -0,0 +1,163 @@
+/*
+ * 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 com.google.common.testing.EqualsTester;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.IpAddress;
+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.protocols.DefaultLispInfoReply.DefaultInfoReplyBuilder;
+import org.onosproject.lisp.msg.protocols.DefaultLispInfoReply.InfoReplyReader;
+import org.onosproject.lisp.msg.protocols.DefaultLispInfoReply.InfoReplyWriter;
+import org.onosproject.lisp.msg.protocols.LispInfoReply.InfoReplyBuilder;
+import org.onosproject.lisp.msg.types.LispIpv4Address;
+import org.onosproject.lisp.msg.types.LispNatLcafAddress;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+
+/**
+ * Unit tests for DefaultLispInfoReply class.
+ */
+public final class DefaultLispInfoReplyTest {
+
+    private LispInfoReply reply1;
+    private LispInfoReply sameAsReply1;
+    private LispInfoReply reply2;
+
+    @Before
+    public void setup() {
+
+        InfoReplyBuilder builder1 = new DefaultInfoReplyBuilder();
+
+        short msUdpPortNumber1 = 80;
+        short etrUdpPortNumber1 = 100;
+        LispIpv4Address globalEtrRlocAddress1 = new LispIpv4Address(IpAddress.valueOf("192.168.1.1"));
+        LispIpv4Address msRlocAddress1 = new LispIpv4Address(IpAddress.valueOf("192.168.1.2"));
+        LispIpv4Address privateEtrRlocAddress1 = new LispIpv4Address(IpAddress.valueOf("192.168.1.3"));
+
+        LispIpv4Address address1 = new LispIpv4Address(IpAddress.valueOf("192.168.1.4"));
+
+        LispNatLcafAddress natLcafAddress1 = new LispNatLcafAddress.NatAddressBuilder()
+                                                        .withLength((short) 0)
+                                                        .withMsUdpPortNumber(msUdpPortNumber1)
+                                                        .withEtrUdpPortNumber(etrUdpPortNumber1)
+                                                        .withGlobalEtrRlocAddress(globalEtrRlocAddress1)
+                                                        .withMsRlocAddress(msRlocAddress1)
+                                                        .withPrivateEtrRlocAddress(privateEtrRlocAddress1)
+                                                        .build();
+
+        reply1 = builder1
+                    .withNonce(1L)
+                    .withKeyId((short) 1)
+                    .withInfoReply(false)
+                    .withMaskLength((byte) 1)
+                    .withEidPrefix(address1)
+                    .withNatLcafAddress(natLcafAddress1).build();
+
+        InfoReplyBuilder builder2 = new DefaultInfoReplyBuilder();
+
+        sameAsReply1 = builder2
+                            .withNonce(1L)
+                            .withKeyId((short) 1)
+                            .withInfoReply(false)
+                            .withMaskLength((byte) 1)
+                            .withEidPrefix(address1)
+                            .withNatLcafAddress(natLcafAddress1).build();
+
+        InfoReplyBuilder builder3 = new DefaultInfoReplyBuilder();
+
+        short msUdpPortNumber2 = 81;
+        short etrUdpPortNumber2 = 101;
+        LispIpv4Address globalEtrRlocAddress2 = new LispIpv4Address(IpAddress.valueOf("192.168.2.1"));
+        LispIpv4Address msRlocAddress2 = new LispIpv4Address(IpAddress.valueOf("192.168.2.2"));
+        LispIpv4Address privateEtrRlocAddress2 = new LispIpv4Address(IpAddress.valueOf("192.168.2.3"));
+
+        LispIpv4Address address2 = new LispIpv4Address(IpAddress.valueOf("192.168.2.4"));
+
+        LispNatLcafAddress natLcafAddress2 = new LispNatLcafAddress.NatAddressBuilder()
+                                                        .withLength((short) 0)
+                                                        .withMsUdpPortNumber(msUdpPortNumber2)
+                                                        .withEtrUdpPortNumber(etrUdpPortNumber2)
+                                                        .withGlobalEtrRlocAddress(globalEtrRlocAddress2)
+                                                        .withMsRlocAddress(msRlocAddress2)
+                                                        .withPrivateEtrRlocAddress(privateEtrRlocAddress2)
+                                                        .build();
+
+        reply2 = builder3
+                        .withNonce(2L)
+                        .withKeyId((short) 2)
+                        .withInfoReply(true)
+                        .withMaskLength((byte) 1)
+                        .withEidPrefix(address2)
+                        .withNatLcafAddress(natLcafAddress2).build();
+    }
+
+    @Test
+    public void testEquality() {
+        new EqualsTester()
+                .addEqualityGroup(reply1, sameAsReply1)
+                .addEqualityGroup(reply2).testEquals();
+    }
+
+    @Test
+    public void testConstruction() {
+        DefaultLispInfoReply reply = (DefaultLispInfoReply) reply1;
+
+        LispIpv4Address address = new LispIpv4Address(IpAddress.valueOf("192.168.1.4"));
+
+        short msUdpPortNumber1 = 80;
+        short etrUdpPortNumber1 = 100;
+        LispIpv4Address globalEtrRlocAddress1 = new LispIpv4Address(IpAddress.valueOf("192.168.1.1"));
+        LispIpv4Address msRlocAddress1 = new LispIpv4Address(IpAddress.valueOf("192.168.1.2"));
+        LispIpv4Address privateEtrRlocAddress1 = new LispIpv4Address(IpAddress.valueOf("192.168.1.3"));
+
+        LispNatLcafAddress natLcafAddress = new LispNatLcafAddress.NatAddressBuilder()
+                .withLength((short) 0)
+                .withMsUdpPortNumber(msUdpPortNumber1)
+                .withEtrUdpPortNumber(etrUdpPortNumber1)
+                .withGlobalEtrRlocAddress(globalEtrRlocAddress1)
+                .withMsRlocAddress(msRlocAddress1)
+                .withPrivateEtrRlocAddress(privateEtrRlocAddress1)
+                .build();
+
+        assertThat(reply.hasInfoReply(), is(false));
+        assertThat(reply.getNonce(), is(1L));
+        assertThat(reply.getKeyId(), is((short) 1));
+        assertThat(reply.getMaskLength(), is((byte) 1));
+        assertThat(reply.getPrefix(), is(address));
+        assertThat(reply.getNatLcafAddress(), is(natLcafAddress));
+    }
+
+    @Test
+    public void testSerialization() throws LispReaderException, LispWriterException, LispParseError {
+        ByteBuf byteBuf = Unpooled.buffer();
+
+        InfoReplyWriter writer = new InfoReplyWriter();
+        writer.writeTo(byteBuf, reply1);
+
+        InfoReplyReader reader = new InfoReplyReader();
+        LispInfoReply deserialized = reader.readFrom(byteBuf);
+
+        new EqualsTester()
+                .addEqualityGroup(reply1, deserialized).testEquals();
+    }
+}
diff --git a/protocols/lisp/msg/src/test/java/org/onosproject/lisp/msg/protocols/DefaultLispInfoRequestTest.java b/protocols/lisp/msg/src/test/java/org/onosproject/lisp/msg/protocols/DefaultLispInfoRequestTest.java
new file mode 100644
index 0000000..501b82f
--- /dev/null
+++ b/protocols/lisp/msg/src/test/java/org/onosproject/lisp/msg/protocols/DefaultLispInfoRequestTest.java
@@ -0,0 +1,114 @@
+/*
+ * 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 com.google.common.testing.EqualsTester;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.IpAddress;
+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.protocols.DefaultLispInfoRequest.DefaultInfoRequestBuilder;
+import org.onosproject.lisp.msg.protocols.DefaultLispInfoRequest.InfoRequestReader;
+import org.onosproject.lisp.msg.protocols.DefaultLispInfoRequest.InfoRequestWriter;
+import org.onosproject.lisp.msg.protocols.LispInfoRequest.InfoRequestBuilder;
+import org.onosproject.lisp.msg.types.LispIpv4Address;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+
+/**
+ * Unit tests for DefaultLispInfoRequest class.
+ */
+public final class DefaultLispInfoRequestTest {
+
+    private LispInfoRequest request1;
+    private LispInfoRequest sameAsRequest1;
+    private LispInfoRequest request2;
+
+    @Before
+    public void setup() {
+
+        InfoRequestBuilder builder1 = new DefaultInfoRequestBuilder();
+
+        LispIpv4Address address1 = new LispIpv4Address(IpAddress.valueOf("192.168.1.1"));
+
+        request1 = builder1
+                        .withNonce(1L)
+                        .withKeyId((short) 1)
+                        .withInfoReply(false)
+                        .withMaskLength((byte) 1)
+                        .withEidPrefix(address1).build();
+
+        InfoRequestBuilder builder2 = new DefaultInfoRequestBuilder();
+
+        sameAsRequest1 = builder2
+                            .withNonce(1L)
+                            .withKeyId((short) 1)
+                            .withInfoReply(false)
+                            .withMaskLength((byte) 1)
+                            .withEidPrefix(address1).build();
+
+        InfoRequestBuilder builder3 = new DefaultInfoRequestBuilder();
+
+        LispIpv4Address address2 = new LispIpv4Address(IpAddress.valueOf("192.168.2.1"));
+
+        request2 = builder3
+                        .withNonce(2L)
+                        .withKeyId((short) 2)
+                        .withInfoReply(true)
+                        .withMaskLength((byte) 1)
+                        .withEidPrefix(address2).build();
+    }
+
+    @Test
+    public void testEquality() {
+        new EqualsTester()
+                .addEqualityGroup(request1, sameAsRequest1)
+                .addEqualityGroup(request2).testEquals();
+    }
+
+    @Test
+    public void testConstruction() {
+        DefaultLispInfoRequest request = (DefaultLispInfoRequest) request1;
+
+        LispIpv4Address address = new LispIpv4Address(IpAddress.valueOf("192.168.1.1"));
+
+        assertThat(request.hasInfoReply(), is(false));
+        assertThat(request.getNonce(), is(1L));
+        assertThat(request.getKeyId(), is((short) 1));
+        assertThat(request.getMaskLength(), is((byte) 1));
+        assertThat(request.getPrefix(), is(address));
+    }
+
+
+    @Test
+    public void testSerialization() throws LispReaderException, LispWriterException, LispParseError {
+        ByteBuf byteBuf = Unpooled.buffer();
+
+        InfoRequestWriter writer = new InfoRequestWriter();
+        writer.writeTo(byteBuf, request1);
+
+        InfoRequestReader reader = new InfoRequestReader();
+        LispInfoRequest deserialized = reader.readFrom(byteBuf);
+
+        new EqualsTester()
+                .addEqualityGroup(request1, deserialized).testEquals();
+    }
+}