ONOS-4083, ONOS-4084, ONOS-4096, ONOS-4097:ISIS PDU Data Structures

Change-Id: I22d30e8f7ba7d414e75254fdec6d0865bf471ff9
diff --git a/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/util/ChecksumCalculator.java b/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/util/ChecksumCalculator.java
index d6b91f9..31f75b4 100644
--- a/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/util/ChecksumCalculator.java
+++ b/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/util/ChecksumCalculator.java
@@ -32,6 +32,7 @@
      * @return true if valid else false
      */
     public boolean validateLspCheckSum(byte[] lspPacket, int lspChecksumPos1, int lspChecksumPos2) {
+
         byte[] checksum = calculateLspChecksum(lspPacket, lspChecksumPos1, lspChecksumPos2);
         if (lspPacket[lspChecksumPos1] == checksum[0] && lspPacket[lspChecksumPos2] == checksum[1]) {
             return true;
diff --git a/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/util/IsisConfig.java b/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/util/IsisConfig.java
new file mode 100644
index 0000000..9b37cbd
--- /dev/null
+++ b/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/util/IsisConfig.java
@@ -0,0 +1,44 @@
+/*
+ * 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.isis.io.util;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+/**
+ * Representation of ISIS config.
+ */
+public enum IsisConfig {
+    INSTANCE;
+    private JsonNode jsonNodes = null;
+
+    /**
+     * Returns the config value.
+     *
+     * @return jsonNodes json node
+     */
+    public JsonNode config() {
+        return jsonNodes;
+    }
+
+    /**
+     * Sets the config value for jsonNode.
+     *
+     * @param jsonNodes json node
+     */
+    public void setConfig(JsonNode jsonNodes) {
+        this.jsonNodes = jsonNodes;
+    }
+}
\ No newline at end of file
diff --git a/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/util/IsisConstants.java b/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/util/IsisConstants.java
index 53ef74b..fe84218 100644
--- a/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/util/IsisConstants.java
+++ b/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/util/IsisConstants.java
@@ -17,7 +17,7 @@
 package org.onosproject.isis.io.util;
 
 /**
- * Representation of ISIS constants.
+ * Representation of ISIS Constants.
  */
 public final class IsisConstants {
     public static final char PDU_LENGTH = 1497; // mtu (1500) - (3) LLC
diff --git a/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/util/IsisUtil.java b/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/util/IsisUtil.java
index 318eb1b..44ad9e0 100644
--- a/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/util/IsisUtil.java
+++ b/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/util/IsisUtil.java
@@ -17,7 +17,20 @@
 
 import com.google.common.primitives.Bytes;
 import org.onlab.packet.Ip4Address;
+import org.onlab.packet.MacAddress;
+import org.onosproject.isis.controller.IsisInterface;
+import org.onosproject.isis.controller.IsisInterfaceState;
+import org.onosproject.isis.controller.IsisNeighbor;
+import org.onosproject.isis.controller.IsisPduType;
+import org.onosproject.isis.io.isispacket.IsisHeader;
+import org.onosproject.isis.io.isispacket.pdu.L1L2HelloPdu;
+import org.onosproject.isis.io.isispacket.pdu.P2PHelloPdu;
+import org.onosproject.isis.io.isispacket.tlv.AdjacencyStateTlv;
+import org.onosproject.isis.io.isispacket.tlv.AreaAddressTlv;
+import org.onosproject.isis.io.isispacket.tlv.IpInterfaceAddressTlv;
+import org.onosproject.isis.io.isispacket.tlv.IsisNeighborTlv;
 import org.onosproject.isis.io.isispacket.tlv.PaddingTlv;
+import org.onosproject.isis.io.isispacket.tlv.ProtocolSupportedTlv;
 import org.onosproject.isis.io.isispacket.tlv.TlvHeader;
 import org.onosproject.isis.io.isispacket.tlv.TlvType;
 import org.slf4j.Logger;
@@ -26,6 +39,7 @@
 import javax.xml.bind.DatatypeConverter;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Set;
 import java.util.StringTokenizer;
 
 /**
@@ -37,6 +51,7 @@
     public static final int ID_PLUS_ONE_BYTE = 7;
     public static final int ID_PLUS_TWO_BYTE = 8;
     public static final int THREE_BYTES = 3;
+    public static final int TWO_BYTES = 2;
     public static final int SIX_BYTES = 6;
     public static final int EIGHT_BYTES = 8;
     public static final int FOUR_BYTES = 4;
@@ -103,17 +118,23 @@
      * @return systemIdPlus system ID
      */
     public static String systemIdPlus(byte[] bytes) {
+        int count = 1;
         String systemId = "";
         for (Byte byt : bytes) {
             String hexa = Integer.toHexString(Byte.toUnsignedInt(byt));
             if (hexa.length() % 2 != 0) {
                 hexa = "0" + hexa;
             }
-            systemId = systemId + hexa;
+            if (count == 7 && bytes.length == 8) {
+                systemId = systemId + hexa + "-";
+            } else {
+                systemId = systemId + hexa;
+            }
             if (systemId.length() == 4 || systemId.length() == 9
                     || systemId.length() == 14) {
                 systemId = systemId + ".";
             }
+            count++;
         }
         return systemId;
     }
@@ -154,6 +175,38 @@
     }
 
     /**
+     * Returns PDU headaer length.
+     *
+     * @param pduType PDU type
+     * @return headerLength header length
+     */
+    public static int getPduHeaderLength(int pduType) {
+        int headerLength = 0;
+        switch (IsisPduType.get(pduType)) {
+            case L1HELLOPDU:
+            case L2HELLOPDU:
+            case L1LSPDU:
+            case L2LSPDU:
+                headerLength = IsisConstants.HELLOHEADERLENGTH;
+                break;
+            case P2PHELLOPDU:
+                headerLength = IsisConstants.P2PHELLOHEADERLENGTH;
+                break;
+            case L1PSNP:
+            case L2PSNP:
+                headerLength = IsisConstants.PSNPDUHEADERLENGTH;
+                break;
+            case L1CSNP:
+            case L2CSNP:
+                headerLength = IsisConstants.CSNPDUHEADERLENGTH;
+                break;
+            default:
+                break;
+        }
+        return headerLength;
+    }
+
+    /**
      * Adds the PDU length in packet.
      *
      * @param isisPacket      ISIS packet
@@ -186,7 +239,7 @@
      */
     public static byte[] addChecksum(byte[] isisPacket, int checksumBytePos1, int checksumBytePos2) {
         //Set the checksum for the packet
-        //Convert the lenth to two bytes as the length field is 2 bytes
+        //Convert the length to two bytes as the length field is 2 bytes
         byte[] checksumInTwoBytes = new ChecksumCalculator().calculateLspChecksum(
                 isisPacket, checksumBytePos1, checksumBytePos2);
         //isis header 3rd and 4th position represents length
@@ -296,7 +349,6 @@
      * @return numInBytes given number as bytes
      */
     public static byte[] convertToFourBytes(int numberToConvert) {
-
         byte[] numInBytes = new byte[4];
         String s1 = Integer.toHexString(numberToConvert);
         if (s1.length() % 2 != 0) {
@@ -328,6 +380,168 @@
     }
 
     /**
+     * Returns the P2P hello PDU.
+     *
+     * @param isisInterface  ISIS interface instance
+     * @param paddingEnabled padding enabled or not
+     * @return hello PDU
+     */
+    public static byte[] getP2pHelloPdu(IsisInterface isisInterface, boolean paddingEnabled) {
+        IsisHeader isisHeader = new IsisHeader();
+        isisHeader.setIrpDiscriminator((byte) IsisConstants.IRPDISCRIMINATOR);
+        isisHeader.setPduHeaderLength((byte) IsisConstants.P2PHELLOHEADERLENGTH);
+        isisHeader.setVersion((byte) IsisConstants.ISISVERSION);
+        isisHeader.setIdLength((byte) IsisConstants.IDLENGTH);
+        isisHeader.setIsisPduType(IsisPduType.P2PHELLOPDU.value());
+        isisHeader.setVersion2((byte) IsisConstants.ISISVERSION);
+        //isisHeader.setReserved((byte) IsisConstants.RESERVED);
+        isisHeader.setReserved((byte) IsisConstants.PDULENGTHPOSITION);
+        isisHeader.setMaximumAreaAddresses((byte) IsisConstants.MAXAREAADDRESS);
+        P2PHelloPdu p2pHelloPdu = new P2PHelloPdu(isisHeader);
+        p2pHelloPdu.setCircuitType((byte) isisInterface.reservedPacketCircuitType());
+        p2pHelloPdu.setSourceId(isisInterface.systemId());
+        p2pHelloPdu.setHoldingTime(isisInterface.holdingTime());
+        p2pHelloPdu.setPduLength(IsisConstants.PDU_LENGTH);
+        p2pHelloPdu.setLocalCircuitId((byte) IsisConstants.LOCALCIRCUITIDFORP2P);
+
+        TlvHeader tlvHeader = new TlvHeader();
+        tlvHeader.setTlvType(TlvType.AREAADDRESS.value());
+        tlvHeader.setTlvLength(0);
+        AreaAddressTlv areaAddressTlv = new AreaAddressTlv(tlvHeader);
+        areaAddressTlv.addAddress(isisInterface.areaAddress());
+        p2pHelloPdu.addTlv(areaAddressTlv);
+
+        tlvHeader.setTlvType(TlvType.PROTOCOLSUPPORTED.value());
+        tlvHeader.setTlvLength(0);
+        ProtocolSupportedTlv protocolSupportedTlv = new ProtocolSupportedTlv(tlvHeader);
+        protocolSupportedTlv.addProtocolSupported((byte) IsisConstants.PROTOCOLSUPPORTED);
+        p2pHelloPdu.addTlv(protocolSupportedTlv);
+
+        tlvHeader.setTlvType(TlvType.ADJACENCYSTATE.value());
+        tlvHeader.setTlvLength(0);
+        AdjacencyStateTlv adjacencyStateTlv = new AdjacencyStateTlv(tlvHeader);
+        adjacencyStateTlv.setAdjacencyType((byte) IsisInterfaceState.DOWN.value());
+        adjacencyStateTlv.setLocalCircuitId(Integer.parseInt(isisInterface.circuitId()));
+        Set<MacAddress> neighbors = isisInterface.neighbors();
+        if (neighbors.size() > 0) {
+            IsisNeighbor neighbor = isisInterface.lookup(neighbors.iterator().next());
+            adjacencyStateTlv.setAdjacencyType((byte) neighbor.interfaceState().value());
+            adjacencyStateTlv.setNeighborSystemId(neighbor.neighborSystemId());
+            adjacencyStateTlv.setNeighborLocalCircuitId(neighbor.localExtendedCircuitId());
+        }
+        p2pHelloPdu.addTlv(adjacencyStateTlv);
+
+        tlvHeader.setTlvType(TlvType.IPINTERFACEADDRESS.value());
+        tlvHeader.setTlvLength(0);
+        IpInterfaceAddressTlv ipInterfaceAddressTlv = new IpInterfaceAddressTlv(tlvHeader);
+        ipInterfaceAddressTlv.addInterfaceAddres(isisInterface.interfaceIpAddress());
+        p2pHelloPdu.addTlv(ipInterfaceAddressTlv);
+
+        byte[] beforePadding = p2pHelloPdu.asBytes();
+        byte[] helloMessage;
+        if (paddingEnabled) {
+            byte[] paddingTlvs = getPaddingTlvs(beforePadding.length);
+            helloMessage = Bytes.concat(beforePadding, paddingTlvs);
+        } else {
+            helloMessage = beforePadding;
+        }
+        return helloMessage;
+    }
+
+    /**
+     * Returns the L1 hello PDU.
+     *
+     * @param isisInterface  ISIS interface instance
+     * @param paddingEnabled padding enabled or not
+     * @return helloMessage hello PDU
+     */
+    public static byte[] getL1HelloPdu(IsisInterface isisInterface, boolean paddingEnabled) {
+        return getL1OrL2HelloPdu(isisInterface, IsisPduType.L1HELLOPDU, paddingEnabled);
+    }
+
+    /**
+     * Returns the L2 hello PDU.
+     *
+     * @param isisInterface  ISIS interface instance
+     * @param paddingEnabled padding enabled or not
+     * @return helloMessage hello PDU
+     */
+    public static byte[] getL2HelloPdu(IsisInterface isisInterface, boolean paddingEnabled) {
+        return getL1OrL2HelloPdu(isisInterface, IsisPduType.L2HELLOPDU, paddingEnabled);
+    }
+
+    /**
+     * Returns the hello PDU.
+     *
+     * @param isisInterface  ISIS interface instance
+     * @param paddingEnabled padding enabled or not
+     * @return helloMessage hello PDU
+     */
+    private static byte[] getL1OrL2HelloPdu(IsisInterface isisInterface, IsisPduType isisPduType,
+                                            boolean paddingEnabled) {
+        String lanId = "";
+        IsisHeader isisHeader = new IsisHeader();
+        isisHeader.setIrpDiscriminator((byte) IsisConstants.IRPDISCRIMINATOR);
+        isisHeader.setPduHeaderLength((byte) IsisConstants.HELLOHEADERLENGTH);
+        isisHeader.setVersion((byte) IsisConstants.ISISVERSION);
+        isisHeader.setIdLength((byte) IsisConstants.IDLENGTH);
+        if (isisPduType == IsisPduType.L1HELLOPDU) {
+            isisHeader.setIsisPduType(IsisPduType.L1HELLOPDU.value());
+            lanId = isisInterface.l1LanId();
+        } else if (isisPduType == IsisPduType.L2HELLOPDU) {
+            isisHeader.setIsisPduType(IsisPduType.L2HELLOPDU.value());
+            lanId = isisInterface.l2LanId();
+        }
+        isisHeader.setVersion2((byte) IsisConstants.ISISVERSION);
+        isisHeader.setReserved((byte) IsisConstants.PDULENGTHPOSITION);
+        isisHeader.setMaximumAreaAddresses((byte) IsisConstants.MAXAREAADDRESS);
+        L1L2HelloPdu l1L2HelloPdu = new L1L2HelloPdu(isisHeader);
+        l1L2HelloPdu.setCircuitType((byte) isisInterface.reservedPacketCircuitType());
+        l1L2HelloPdu.setSourceId(isisInterface.systemId());
+        l1L2HelloPdu.setHoldingTime(isisInterface.holdingTime());
+        l1L2HelloPdu.setPduLength(IsisConstants.PDU_LENGTH);
+        l1L2HelloPdu.setPriority((byte) isisInterface.priority());
+        l1L2HelloPdu.setLanId(lanId);
+        TlvHeader tlvHeader = new TlvHeader();
+        tlvHeader.setTlvType(TlvType.AREAADDRESS.value());
+        tlvHeader.setTlvLength(0);
+        AreaAddressTlv areaAddressTlv = new AreaAddressTlv(tlvHeader);
+        areaAddressTlv.addAddress(isisInterface.areaAddress());
+        l1L2HelloPdu.addTlv(areaAddressTlv);
+        Set<MacAddress> neighbors = isisInterface.neighbors();
+        if (neighbors.size() > 0) {
+            tlvHeader.setTlvType(TlvType.ISNEIGHBORS.value());
+            tlvHeader.setTlvLength(0);
+            IsisNeighborTlv isisNeighborTlv = new IsisNeighborTlv(tlvHeader);
+            for (MacAddress neighbor : neighbors) {
+                isisNeighborTlv.addNeighbor(neighbor);
+            }
+            l1L2HelloPdu.addTlv(isisNeighborTlv);
+        }
+        tlvHeader.setTlvType(TlvType.PROTOCOLSUPPORTED.value());
+        tlvHeader.setTlvLength(0);
+        ProtocolSupportedTlv protocolSupportedTlv = new ProtocolSupportedTlv(tlvHeader);
+        protocolSupportedTlv.addProtocolSupported((byte) IsisConstants.PROTOCOLSUPPORTED);
+        l1L2HelloPdu.addTlv(protocolSupportedTlv);
+
+        tlvHeader.setTlvType(TlvType.IPINTERFACEADDRESS.value());
+        tlvHeader.setTlvLength(0);
+        IpInterfaceAddressTlv ipInterfaceAddressTlv = new IpInterfaceAddressTlv(tlvHeader);
+        ipInterfaceAddressTlv.addInterfaceAddres(isisInterface.interfaceIpAddress());
+        l1L2HelloPdu.addTlv(ipInterfaceAddressTlv);
+
+        byte[] beforePadding = l1L2HelloPdu.asBytes();
+        byte[] helloMessage;
+        if (paddingEnabled) {
+            byte[] paddingTlvs = getPaddingTlvs(beforePadding.length);
+            helloMessage = Bytes.concat(beforePadding, paddingTlvs);
+        } else {
+            helloMessage = beforePadding;
+        }
+        return helloMessage;
+    }
+
+    /**
      * Converts a byte to integer variable.
      *
      * @param bytesToConvert bytes to convert
@@ -461,4 +675,22 @@
         }
         return numInBytes;
     }
-}
+
+    /**
+     * Converts the bytes of prefix to string type value.
+     *
+     * @param bytes array of prefix
+     * @return string value of prefix
+     */
+    public static String prefixConversion(byte[] bytes) {
+        String prefix = "";
+        for (int i = 0; i < bytes.length; i++) {
+            if (i < (bytes.length - 1)) {
+                prefix = prefix + bytes[i] + ".";
+            } else {
+                prefix = prefix + bytes[i];
+            }
+        }
+        return prefix;
+    }
+}
\ No newline at end of file
diff --git a/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/util/LspGenerator.java b/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/util/LspGenerator.java
new file mode 100644
index 0000000..1dfb1a4
--- /dev/null
+++ b/protocols/isis/isisio/src/main/java/org/onosproject/isis/io/util/LspGenerator.java
@@ -0,0 +1,159 @@
+/*
+ * 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.isis.io.util;
+
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.MacAddress;
+import org.onosproject.isis.controller.IsisInterface;
+import org.onosproject.isis.controller.IsisNeighbor;
+import org.onosproject.isis.controller.IsisNetworkType;
+import org.onosproject.isis.controller.IsisPduType;
+import org.onosproject.isis.io.isispacket.IsisHeader;
+import org.onosproject.isis.io.isispacket.pdu.AttachedToOtherAreas;
+import org.onosproject.isis.io.isispacket.pdu.LsPdu;
+import org.onosproject.isis.io.isispacket.tlv.AreaAddressTlv;
+import org.onosproject.isis.io.isispacket.tlv.HostNameTlv;
+import org.onosproject.isis.io.isispacket.tlv.IpInterfaceAddressTlv;
+import org.onosproject.isis.io.isispacket.tlv.IpInternalReachabilityTlv;
+import org.onosproject.isis.io.isispacket.tlv.IsReachabilityTlv;
+import org.onosproject.isis.io.isispacket.tlv.MetricOfInternalReachability;
+import org.onosproject.isis.io.isispacket.tlv.MetricsOfReachability;
+import org.onosproject.isis.io.isispacket.tlv.ProtocolSupportedTlv;
+import org.onosproject.isis.io.isispacket.tlv.TlvHeader;
+import org.onosproject.isis.io.isispacket.tlv.TlvType;
+
+import java.util.List;
+
+/**
+ * Representation of link state PDU generator.
+ */
+public class LspGenerator {
+
+    public LsPdu getLsp(IsisInterface isisInterface, String lspId, IsisPduType isisPduType,
+                        List<Ip4Address> allConfiguredInterfaceIps) {
+        IsisHeader header = getHeader(isisPduType);
+        LsPdu lsp = new LsPdu(header);
+
+        lsp.setPduLength(0);
+        lsp.setRemainingLifeTime(IsisConstants.LSPMAXAGE);
+        lsp.setLspId(lspId);
+        lsp.setSequenceNumber(isisInterface.isisLsdb().lsSequenceNumber(isisPduType));
+        lsp.setCheckSum(0);
+        if (isisPduType == IsisPduType.L1LSPDU) {
+            lsp.setTypeBlock((byte) 1);
+            lsp.setIntermediateSystemType((byte) 1);
+        } else if (isisPduType == IsisPduType.L2LSPDU) {
+            lsp.setTypeBlock((byte) 3);
+            lsp.setIntermediateSystemType((byte) 3);
+        }
+        lsp.setAttachedToOtherAreas(AttachedToOtherAreas.NONE);
+        lsp.setPartitionRepair(false);
+        lsp.setLspDbol(false);
+
+        TlvHeader tlvHeader = new TlvHeader();
+        tlvHeader.setTlvType(TlvType.AREAADDRESS.value());
+        tlvHeader.setTlvLength(0);
+        AreaAddressTlv areaAddressTlv = new AreaAddressTlv(tlvHeader);
+        areaAddressTlv.addAddress(isisInterface.areaAddress());
+        lsp.addTlv(areaAddressTlv);
+
+        tlvHeader.setTlvType(TlvType.PROTOCOLSUPPORTED.value());
+        tlvHeader.setTlvLength(0);
+        ProtocolSupportedTlv protocolSupportedTlv = new ProtocolSupportedTlv(tlvHeader);
+        protocolSupportedTlv.addProtocolSupported((byte) IsisConstants.PROTOCOLSUPPORTED);
+        lsp.addTlv(protocolSupportedTlv);
+
+        tlvHeader.setTlvType(TlvType.IPINTERFACEADDRESS.value());
+        tlvHeader.setTlvLength(0);
+        IpInterfaceAddressTlv ipInterfaceAddressTlv = new IpInterfaceAddressTlv(tlvHeader);
+        for (Ip4Address ipaddress : allConfiguredInterfaceIps) {
+            ipInterfaceAddressTlv.addInterfaceAddres(ipaddress);
+        }
+        lsp.addTlv(ipInterfaceAddressTlv);
+
+        tlvHeader.setTlvType(TlvType.HOSTNAME.value());
+        tlvHeader.setTlvLength(0);
+        HostNameTlv hostNameTlv = new HostNameTlv(tlvHeader);
+        hostNameTlv.setHostName(isisInterface.intermediateSystemName());
+        lsp.addTlv(hostNameTlv);
+
+        tlvHeader.setTlvType(TlvType.ISREACHABILITY.value());
+        tlvHeader.setTlvLength(0);
+        IsReachabilityTlv isReachabilityTlv = new IsReachabilityTlv(tlvHeader);
+        isReachabilityTlv.setReserved(0);
+        MetricsOfReachability metricsOfReachability = new MetricsOfReachability();
+        metricsOfReachability.setDefaultMetric((byte) 10);
+        metricsOfReachability.setDefaultIsInternal(true);
+        metricsOfReachability.setDelayMetric((byte) 10);
+        metricsOfReachability.setDelayIsInternal(true);
+        metricsOfReachability.setDelayMetricSupported(true);
+        metricsOfReachability.setExpenseMetric((byte) 10);
+        metricsOfReachability.setExpenseIsInternal(true);
+        metricsOfReachability.setExpenseMetricSupported(true);
+        metricsOfReachability.setErrorMetric((byte) 10);
+        metricsOfReachability.setErrorIsInternal(true);
+        metricsOfReachability.setErrorMetricSupported(true);
+        if (isisInterface.networkType() == IsisNetworkType.BROADCAST) {
+            if (isisPduType == IsisPduType.L1LSPDU) {
+                metricsOfReachability.setNeighborId(isisInterface.l1LanId());
+            } else if (isisPduType == IsisPduType.L2LSPDU) {
+                metricsOfReachability.setNeighborId(isisInterface.l2LanId());
+            }
+        } else if (isisInterface.networkType() == IsisNetworkType.P2P) {
+            MacAddress neighborMac = isisInterface.neighbors().iterator().next();
+            IsisNeighbor neighbor = isisInterface.lookup(neighborMac);
+            metricsOfReachability.setNeighborId(neighbor.neighborSystemId());
+        }
+
+        isReachabilityTlv.addMeticsOfReachability(metricsOfReachability);
+        lsp.addTlv(isReachabilityTlv);
+
+        tlvHeader.setTlvType(TlvType.IPINTERNALREACHABILITY.value());
+        tlvHeader.setTlvLength(0);
+        IpInternalReachabilityTlv ipInterReacTlv = new IpInternalReachabilityTlv(tlvHeader);
+        MetricOfInternalReachability metricOfIntRea = new MetricOfInternalReachability();
+        metricOfIntRea.setDefaultMetric((byte) 10);
+        metricOfIntRea.setDefaultIsInternal(true);
+        metricOfIntRea.setDefaultDistributionDown(true);
+        metricOfIntRea.setDelayMetric((byte) 0);
+        metricOfIntRea.setDelayMetricSupported(false);
+        metricOfIntRea.setDelayIsInternal(true);
+        metricOfIntRea.setExpenseMetric((byte) 0);
+        metricOfIntRea.setExpenseMetricSupported(false);
+        metricOfIntRea.setExpenseIsInternal(true);
+        metricOfIntRea.setErrorMetric((byte) 0);
+        metricOfIntRea.setErrorMetricSupported(false);
+        metricOfIntRea.setExpenseIsInternal(true);
+        metricOfIntRea.setIpAddress(isisInterface.interfaceIpAddress());
+        metricOfIntRea.setSubnetAddres(Ip4Address.valueOf(isisInterface.networkMask()));
+        ipInterReacTlv.addInternalReachabilityMetric(metricOfIntRea);
+        lsp.addTlv(ipInterReacTlv);
+        return lsp;
+    }
+
+    public IsisHeader getHeader(IsisPduType pduType) {
+        IsisHeader isisHeader = new IsisHeader();
+        isisHeader.setIrpDiscriminator((byte) IsisConstants.IRPDISCRIMINATOR);
+        isisHeader.setPduHeaderLength((byte) IsisUtil.getPduHeaderLength(pduType.value()));
+        isisHeader.setVersion((byte) IsisConstants.ISISVERSION);
+        isisHeader.setIdLength((byte) IsisConstants.IDLENGTH);
+        isisHeader.setIsisPduType(pduType.value());
+        isisHeader.setVersion2((byte) IsisConstants.ISISVERSION);
+        isisHeader.setReserved((byte) IsisConstants.RESERVED);
+        isisHeader.setMaximumAreaAddresses((byte) IsisConstants.MAXAREAADDRESS);
+        return isisHeader;
+    }
+}
\ No newline at end of file