Directory Structuring
diff --git a/nlsr.conf b/nlsr.conf
new file mode 100644
index 0000000..2f2287b
--- /dev/null
+++ b/nlsr.conf
@@ -0,0 +1,14 @@
+network ndn
+site-name memphis.edu
+router-name cs/macbook
+
+ndnneighbor /ndn/memphis.edu/cs/maia 7
+link-cost /ndn/memphis.edu/cs/maia 30
+ndnneighbor /ndn/memphis.edu/cs/pollux 10
+link-cost /ndn/memphis.edu/cs/pollux 25
+
+ndnname /ndn/memphis.edu/cs/macbook/name1
+ndnname /ndn/memphis.edu/cs/macbook/name2
+
+
+!logdir /Users/akmhoque/NLSR-CPP/log
diff --git a/src/communication/nlsr_dm.cpp b/src/communication/nlsr_dm.cpp
new file mode 100644
index 0000000..92a911d
--- /dev/null
+++ b/src/communication/nlsr_dm.cpp
@@ -0,0 +1,202 @@
+#include<iostream>
+#include<cstdlib>
+
+#include <ndn-cpp-dev/security/signature-sha256-with-rsa.hpp>
+#include <ndn-cpp-dev/security/identity-certificate.hpp>
+#include <ndn-cpp-dev/util/io.hpp>
+
+#include "nlsr.hpp"
+#include "nlsr_dm.hpp"
+#include "utility/nlsr_tokenizer.hpp"
+#include "nlsr_lsdb.hpp"
+
+namespace nlsr
+{
+
+    using namespace std;
+    using namespace ndn;
+
+    void
+    DataManager::processContent(Nlsr& pnlsr, const ndn::Interest &interest,
+                                const ndn::Data & data, interestManager& im)
+    {
+        cout << "I: " << interest.toUri() << endl;
+        string dataName(data.getName().toUri());
+        //cout << "D: " << dataName << endl;
+        //cout << "Data Content: " << dataContent << endl;
+        nlsrTokenizer nt(dataName,"/");
+        //SignatureSha256WithRsa sig(data.getSignature());
+        //ndn::Name keyName=sig.getKeyLocator().getName();
+        //cout<<"Key Locator Name: "<<keyName.toUri()<<endl;
+        string chkString("info");
+        if( nt.doesTokenExist(chkString) )
+        {
+            string dataContent((char *)data.getContent().value());
+            processContentInfo(pnlsr,dataName,dataContent);
+        }
+        chkString="LSA";
+        if( nt.doesTokenExist(chkString) )
+        {
+            string dataContent((char *)data.getContent().value());
+            processContentLsa(pnlsr, dataName, dataContent);
+        }
+        chkString="keys";
+        if( nt.doesTokenExist(chkString) )
+        {
+            processContentKeys(pnlsr, data);
+        }
+    }
+
+    void
+    DataManager::processContentInfo(Nlsr& pnlsr, string& dataName,
+                                    string& dataContent)
+    {
+        nlsrTokenizer nt(dataName,"/");
+        string chkString("info");
+        string neighbor=nt.getTokenString(0,nt.getTokenPosition(chkString)-1);
+        int oldStatus=pnlsr.getAdl().getStatusOfNeighbor(neighbor);
+        int infoIntTimedOutCount=pnlsr.getAdl().getTimedOutInterestCount(neighbor);
+        //debugging purpose start
+        cout <<"Before Updates: " <<endl;
+        cout <<"Neighbor : "<<neighbor<<endl;
+        cout<<"Status: "<< oldStatus << endl;
+        cout<<"Info Interest Timed out: "<< infoIntTimedOutCount <<endl;
+        //debugging purpose end
+        pnlsr.getAdl().setStatusOfNeighbor(neighbor,1);
+        pnlsr.getAdl().setTimedOutInterestCount(neighbor,0);
+        int newStatus=pnlsr.getAdl().getStatusOfNeighbor(neighbor);
+        infoIntTimedOutCount=pnlsr.getAdl().getTimedOutInterestCount(neighbor);
+        //debugging purpose
+        cout <<"After Updates: " <<endl;
+        cout <<"Neighbor : "<<neighbor<<endl;
+        cout<<"Status: "<< newStatus << endl;
+        cout<<"Info Interest Timed out: "<< infoIntTimedOutCount <<endl;
+        //debugging purpose end
+        if ( ( oldStatus-newStatus)!= 0 ) // change in Adjacency list
+        {
+            pnlsr.incrementAdjBuildCount();
+            /* Need to schedule event for Adjacency LSA building */
+            if ( pnlsr.getIsBuildAdjLsaSheduled() == 0 )
+            {
+                pnlsr.setIsBuildAdjLsaSheduled(1);
+                // event here
+                pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(5),
+                                                   ndn::bind(&Lsdb::scheduledAdjLsaBuild, pnlsr.getLsdb(),
+                                                           boost::ref(pnlsr)));
+            }
+        }
+    }
+
+    void
+    DataManager::processContentLsa(Nlsr& pnlsr, string& dataName,
+                                   string& dataContent)
+    {
+        nlsrTokenizer nt(dataName,"/");
+        string chkString("LSA");
+        string origRouter=nt.getTokenString(nt.getTokenPosition(chkString)+1,
+                                            nt.getTokenNumber()-4);
+        string lsTypeString=nt.getToken(nt.getTokenNumber()-3);
+        string lsSeNoString=nt.getToken(nt.getTokenNumber()-2);
+        uint32_t interestedLsSeqNo;
+        try
+        {
+            interestedLsSeqNo=boost::lexical_cast<uint32_t>(lsSeNoString);
+        }
+        catch(std::exception &e)
+        {
+            return;
+        }
+        if( lsTypeString == "1" ) //Name Lsa
+        {
+            processContentNameLsa(pnlsr, origRouter+"/"+lsTypeString,
+                                  interestedLsSeqNo, dataContent);
+        }
+        else if( lsTypeString == "2" ) //Adj Lsa
+        {
+            processContentAdjLsa(pnlsr, origRouter+"/"+lsTypeString,
+                                 interestedLsSeqNo, dataContent);
+        }
+        else if( lsTypeString == "3" ) //Cor Lsa
+        {
+            processContentCorLsa(pnlsr, origRouter+"/"+lsTypeString,
+                                 interestedLsSeqNo, dataContent);
+        }
+        else
+        {
+            cout<<"Unrecognized LSA Type :("<<endl;
+        }
+    }
+
+    void
+    DataManager::processContentNameLsa(Nlsr& pnlsr, string lsaKey,
+                                       uint32_t lsSeqNo, string& dataContent)
+    {
+        if ( pnlsr.getLsdb().isNameLsaNew(lsaKey,lsSeqNo))
+        {
+            NameLsa nameLsa;
+            if( nameLsa.initNameLsaFromContent(dataContent) )
+            {
+                pnlsr.getLsdb().installNameLsa(pnlsr, nameLsa);
+            }
+            else
+            {
+                cout<<"LSA data decoding error :("<<endl;
+            }
+        }
+    }
+
+    void
+    DataManager::processContentAdjLsa(Nlsr& pnlsr, string lsaKey,
+                                      uint32_t lsSeqNo, string& dataContent)
+    {
+        if ( pnlsr.getLsdb().isAdjLsaNew(lsaKey,lsSeqNo))
+        {
+            AdjLsa adjLsa;
+            if( adjLsa.initAdjLsaFromContent(dataContent) )
+            {
+                pnlsr.getLsdb().installAdjLsa(pnlsr, adjLsa);
+            }
+            else
+            {
+                cout<<"LSA data decoding error :("<<endl;
+            }
+        }
+    }
+
+    void
+    DataManager::processContentCorLsa(Nlsr& pnlsr, string lsaKey,
+                                      uint32_t lsSeqNo, string& dataContent)
+    {
+        if ( pnlsr.getLsdb().isCorLsaNew(lsaKey,lsSeqNo))
+        {
+            CorLsa corLsa;
+            if( corLsa.initCorLsaFromContent(dataContent) )
+            {
+                pnlsr.getLsdb().installCorLsa(pnlsr, corLsa);
+            }
+            else
+            {
+                cout<<"LSA data decoding error :("<<endl;
+            }
+        }
+    }
+    
+    void 
+    DataManager::processContentKeys(Nlsr& pnlsr, const ndn::Data& data)
+    {
+        std::ofstream outFile("data_received");
+        ndn::io::save(data,outFile,ndn::io::NO_ENCODING);
+        cout<<" processContentKeys called "<<endl;
+        SignatureSha256WithRsa signature(data.getSignature());
+        cout<<"D: <<"<<data<<endl;
+        cout<<"Key Locator: "<<signature.getKeyLocator().getName().toUri()<<endl;
+        ndn::shared_ptr<ndn::IdentityCertificate> cert=ndn::make_shared<ndn::IdentityCertificate>();
+        cert->wireDecode(data.getContent().blockFromValue());
+        cout<<*(cert)<<endl;
+        
+        if( pnlsr.getKeyManager().verifySignature(*(cert),cert->getPublicKeyInfo()))
+        {
+            cout<<"Verified Data"<<endl;
+        }
+    }
+}//namespace nlsr
diff --git a/src/communication/nlsr_dm.hpp b/src/communication/nlsr_dm.hpp
new file mode 100644
index 0000000..fdb45db
--- /dev/null
+++ b/src/communication/nlsr_dm.hpp
@@ -0,0 +1,40 @@
+#ifndef NLSR_DM_HPP
+#define NLSR_DM_HPP
+
+#include <ndn-cpp-dev/face.hpp>
+#include <ndn-cpp-dev/security/key-chain.hpp>
+#include <ndn-cpp-dev/util/scheduler.hpp>
+
+#include "nlsr_im.hpp"
+
+namespace nlsr
+{
+
+    using namespace ndn;
+    using namespace std;
+
+    class Nlsr;
+
+    class DataManager
+    {
+    public:
+        void processContent(Nlsr& pnlsr, const ndn::Interest &interest,
+                            const ndn::Data& data, interestManager& im);
+    private:
+        void processContentInfo(Nlsr& pnlsr, string& dataName,
+                                string& dataContent);
+        void processContentLsa(Nlsr& pnlsr, string& dataName,
+                               string& dataContent);
+        void processContentNameLsa(Nlsr& pnlsr, string lsaKey,
+                                   uint32_t lsSeqNo, string& dataContent);
+        void processContentAdjLsa(Nlsr& pnlsr, string lsaKey,
+                                  uint32_t lsSeqNo, string& dataContent);
+        void processContentCorLsa(Nlsr& pnlsr, string lsaKey,
+                                  uint32_t lsSeqNo, string& dataContent);
+        void processContentKeys(Nlsr& pnlsr, const ndn::Data& data);
+        
+
+    };
+
+}//namespace nlsr
+#endif
diff --git a/src/communication/nlsr_im.cpp b/src/communication/nlsr_im.cpp
new file mode 100644
index 0000000..7495265
--- /dev/null
+++ b/src/communication/nlsr_im.cpp
@@ -0,0 +1,300 @@
+#include<iostream>
+#include<cstdlib>
+
+
+#include <ndn-cpp-dev/security/identity-certificate.hpp>
+#include <ndn-cpp-dev/util/io.hpp>
+
+#include "nlsr.hpp"
+#include "nlsr_im.hpp"
+#include "nlsr_dm.hpp"
+#include "utility/nlsr_tokenizer.hpp"
+#include "nlsr_lsdb.hpp"
+
+namespace nlsr
+{
+
+    using namespace std;
+    using namespace ndn;
+
+    void
+    interestManager::processInterest( Nlsr& pnlsr,
+                                      const ndn::Name &name,
+                                      const ndn::Interest &interest)
+    {
+        cout << "<< I: " << interest << endl;
+        string intName=interest.getName().toUri();
+        cout << "Interest Received for Name: "<< intName <<endl;
+        nlsrTokenizer nt(intName,"/");
+        string chkString("info");
+        if( nt.doesTokenExist(chkString) )
+        {
+            string nbr=nt.getTokenString(nt.getTokenPosition(chkString)+1);
+            cout <<"Neighbor: " << nbr <<endl;
+            processInterestInfo(pnlsr,nbr,interest);
+        }
+        chkString="LSA";
+        if( nt.doesTokenExist(chkString) )
+        {
+            processInterestLsa(pnlsr,interest);
+        }
+        chkString="keys";
+        if( nt.doesTokenExist(chkString) )
+        {
+            processInterestKeys(pnlsr,interest);
+        }
+        //Data data(ndn::Name(interest->getName()).append("testApp").appendVersion());
+        //data.setFreshnessPeriod(1000); // 10 sec
+        //data.setContent((const uint8_t*)"HELLO KITTY", sizeof("HELLO KITTY"));
+        //pnlsr.getKeyChain().sign(data);
+        //cout << ">> D: " << data << endl;
+        //pnlsr.getNlsrFace().put(data);
+    }
+
+    void
+    interestManager::processInterestInfo(Nlsr& pnlsr, string& neighbor,
+                                         const ndn::Interest &interest)
+    {
+        if ( pnlsr.getAdl().isNeighbor(neighbor) )
+        {
+            Data data(ndn::Name(interest.getName()).appendVersion());
+            data.setFreshnessPeriod(1000); // 10 sec
+            data.setContent((const uint8_t*)"info", sizeof("info"));
+            pnlsr.getKeyManager().signData(data);
+            cout << ">> D: " << data << endl;
+            pnlsr.getNlsrFace()->put(data);
+            int status=pnlsr.getAdl().getStatusOfNeighbor(neighbor);
+            if ( status == 0 )
+            {
+                string intName=neighbor +"/"+"info"+
+                               pnlsr.getConfParameter().getRouterPrefix();
+                expressInterest(	pnlsr,intName,2,
+                                    pnlsr.getConfParameter().getInterestResendTime());
+            }
+        }
+    }
+
+    void
+    interestManager::processInterestLsa(Nlsr& pnlsr,const ndn::Interest &interest)
+    {
+        string intName=interest.getName().toUri();
+        nlsrTokenizer nt(intName,"/");
+        string chkString("LSA");
+        string origRouter=nt.getTokenString(nt.getTokenPosition(chkString)+1,
+                                            nt.getTokenNumber()-3);
+        string lsTypeString=nt.getToken(nt.getTokenNumber()-2);
+        string lsSeqString=nt.getToken(nt.getTokenNumber()-1);
+        cout<<"Router Name: "<<origRouter<<endl;
+        cout<<"Ls Type    : "<<lsTypeString<<endl;
+        cout<<"Ls Seq     : "<<lsSeqString<<endl;
+        uint8_t interestedLsType;
+        uint32_t interestedLsSeqNo;
+        try
+        {
+            interestedLsType=boost::lexical_cast<uint8_t>(lsTypeString);
+            interestedLsSeqNo=boost::lexical_cast<uint32_t>(lsSeqString);
+        }
+        catch(std::exception &e)
+        {
+            return;
+        }
+        cout <<"Ls Type: "<<interestedLsType<<endl;
+        if( lsTypeString == "1" ) //Name Lsa
+        {
+            processInterestForNameLsa(pnlsr, interest,
+                                      origRouter+"/"+lsTypeString, interestedLsSeqNo);
+        }
+        else if( lsTypeString == "2" ) //Adj Lsa
+        {
+            processInterestForAdjLsa(pnlsr, interest,
+                                     origRouter+"/"+lsTypeString, interestedLsSeqNo);
+        }
+        else if( lsTypeString == "3" ) //Cor Lsa
+        {
+            processInterestForCorLsa(pnlsr, interest,
+                                     origRouter+"/"+lsTypeString, interestedLsSeqNo);
+        }
+        else
+        {
+            cout<<"Unrecognized LSA Type :("<<endl;
+        }
+    }
+
+    void
+    interestManager::processInterestForNameLsa(Nlsr& pnlsr,
+            const ndn::Interest &interest,
+            string lsaKey, uint32_t interestedlsSeqNo)
+    {
+        std::pair<NameLsa&, bool>  nameLsa=pnlsr.getLsdb().getNameLsa(lsaKey);
+        if( nameLsa.second )
+        {
+            if ( nameLsa.first.getLsSeqNo() >= interestedlsSeqNo )
+            {
+                Data data(ndn::Name(interest.getName()).appendVersion());
+                data.setFreshnessPeriod(1000); // 10 sec
+                string content=nameLsa.first.getNameLsaData();
+                data.setContent((const uint8_t*)content.c_str(),content.size());
+                pnlsr.getKeyManager().signData(data);
+                cout << ">> D: " << data << endl;
+                pnlsr.getNlsrFace()->put(data);
+            }
+        }
+    }
+
+    void
+    interestManager::processInterestForAdjLsa(Nlsr& pnlsr,
+            const ndn::Interest &interest,
+            string lsaKey, uint32_t interestedlsSeqNo)
+    {
+        std::pair<AdjLsa&, bool>  adjLsa=pnlsr.getLsdb().getAdjLsa(lsaKey);
+        if( adjLsa.second )
+        {
+            if ( adjLsa.first.getLsSeqNo() >= interestedlsSeqNo )
+            {
+                Data data(ndn::Name(interest.getName()).appendVersion());
+                data.setFreshnessPeriod(1000); // 10 sec
+                string content=adjLsa.first.getAdjLsaData();
+                data.setContent((const uint8_t*)content.c_str(),content.size());
+                pnlsr.getKeyManager().signData(data);
+                cout << ">> D: " << data << endl;
+                pnlsr.getNlsrFace()->put(data);
+            }
+        }
+    }
+
+    void
+    interestManager::processInterestForCorLsa(Nlsr& pnlsr,
+            const ndn::Interest &interest,
+            string lsaKey, uint32_t interestedlsSeqNo)
+    {
+        std::pair<CorLsa&, bool>  corLsa=pnlsr.getLsdb().getCorLsa(lsaKey);
+        if( corLsa.second )
+        {
+            if ( corLsa.first.getLsSeqNo() >= interestedlsSeqNo )
+            {
+                Data data(ndn::Name(interest.getName()).appendVersion());
+                data.setFreshnessPeriod(1000); // 10 sec
+                string content=corLsa.first.getCorLsaData();
+                data.setContent((const uint8_t*)content.c_str(),content.size());
+                pnlsr.getKeyManager().signData(data);
+                cout << ">> D: " << data << endl;
+                pnlsr.getNlsrFace()->put(data);
+            }
+        }
+    }
+
+    void
+    interestManager::processInterestKeys(Nlsr& pnlsr,const ndn::Interest &interest)
+    {
+        cout<<" processInterestKeys called "<<endl;
+        ndn::shared_ptr<ndn::IdentityCertificate> cert=pnlsr.getKeyManager().getCertificate("dummy");
+        Data data(ndn::Name(interest.getName()).appendVersion());
+        data.setFreshnessPeriod(1000); // 10 sec
+        data.setContent(cert->wireEncode());
+        pnlsr.getKeyManager().signData(data);
+        std::ofstream outFile("data_sent");
+        ndn::io::save(data,outFile,ndn::io::NO_ENCODING);
+        pnlsr.getNlsrFace()->put(data);
+    }
+
+
+    void
+    interestManager::processInterestTimedOut(Nlsr& pnlsr,
+            const ndn::Interest &interest)
+    {
+        cout << "Timed out interest : " << interest.getName().toUri() << endl;
+        string intName=	interest.getName().toUri();
+        nlsrTokenizer nt(intName,"/");
+        string chkString("info");
+        if( nt.doesTokenExist(chkString) )
+        {
+            string nbr=nt.getTokenString(0,nt.getTokenPosition(chkString)-1);
+            processInterestTimedOutInfo( pnlsr , nbr , interest);
+        }
+        chkString="LSA";
+        if( nt.doesTokenExist(chkString) )
+        {
+            processInterestTimedOutLsa(pnlsr, interest);
+        }
+    }
+
+    void
+    interestManager::processInterestTimedOutInfo(Nlsr& pnlsr, string& neighbor,
+            const ndn::Interest &interest)
+    {
+        pnlsr.getAdl().incrementTimedOutInterestCount(neighbor);
+        int status=pnlsr.getAdl().getStatusOfNeighbor(neighbor);
+        int infoIntTimedOutCount=pnlsr.getAdl().getTimedOutInterestCount(neighbor);
+        cout<<"Neighbor: "<< neighbor << endl;
+        cout<<"Status: "<< status << endl;
+        cout<<"Info Interest Timed out: "<< infoIntTimedOutCount <<endl;
+        if((infoIntTimedOutCount < pnlsr.getConfParameter().getInterestRetryNumber()))
+        {
+            string intName=neighbor +"/"+"info"+
+                           pnlsr.getConfParameter().getRouterPrefix();
+            expressInterest(	pnlsr,intName,2,
+                                pnlsr.getConfParameter().getInterestResendTime());
+        }
+        else if ( (status == 1) &&
+                  (infoIntTimedOutCount == pnlsr.getConfParameter().getInterestRetryNumber()))
+        {
+            pnlsr.getAdl().setStatusOfNeighbor(neighbor,0);
+            pnlsr.incrementAdjBuildCount();
+            if ( pnlsr.getIsBuildAdjLsaSheduled() == 0 )
+            {
+                pnlsr.setIsBuildAdjLsaSheduled(1);
+                // event here
+                pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(5),
+                                                   ndn::bind(&Lsdb::scheduledAdjLsaBuild,&pnlsr.getLsdb(),
+                                                           boost::ref(pnlsr)));
+            }
+        }
+    }
+
+    void
+    interestManager::processInterestTimedOutLsa(Nlsr& pnlsr,
+            const ndn::Interest &interest)
+    {
+    }
+
+    void
+    interestManager::expressInterest(Nlsr& pnlsr,const string& interestNamePrefix,
+                                     int scope, int seconds)
+    {
+        cout<<"Expressing Interest :"<<interestNamePrefix<<endl;
+        ndn::Interest i((ndn::Name(interestNamePrefix)));
+        //i.setScope(scope);
+        i.setInterestLifetime(seconds*1000);
+        i.setMustBeFresh(true);
+        pnlsr.getNlsrFace()->expressInterest(i,
+                                             ndn::func_lib::bind(&DataManager::processContent,
+                                                     &pnlsr.getDm(), boost::ref(pnlsr),_1, _2,boost::ref(*this)),
+                                             ndn::func_lib::bind(&interestManager::processInterestTimedOut,
+                                                     this,boost::ref(pnlsr),_1));
+    }
+
+
+    void
+    interestManager::sendScheduledInfoInterest(Nlsr& pnlsr, int seconds)
+    {
+        std::list<Adjacent> adjList=pnlsr.getAdl().getAdjList();
+        for(std::list<Adjacent>::iterator it=adjList.begin(); it!=adjList.end(); ++it)
+        {
+            string adjName=(*it).getAdjacentName()+"/"+"info"+
+                           pnlsr.getConfParameter().getRouterPrefix();
+            expressInterest(	pnlsr,adjName,2,
+                                pnlsr.getConfParameter().getInterestResendTime());
+        }
+        scheduleInfoInterest(pnlsr, pnlsr.getConfParameter().getInfoInterestInterval());
+    }
+
+    void
+    interestManager::scheduleInfoInterest(Nlsr& pnlsr, int seconds)
+    {
+        EventId eid=pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(seconds),
+                    ndn::bind(&interestManager::sendScheduledInfoInterest, this,
+                              boost::ref(pnlsr),seconds));
+    }
+
+
+} //namespace nlsr
diff --git a/src/communication/nlsr_im.hpp b/src/communication/nlsr_im.hpp
new file mode 100644
index 0000000..330874f
--- /dev/null
+++ b/src/communication/nlsr_im.hpp
@@ -0,0 +1,52 @@
+#ifndef NLSR_IM_HPP
+#define NLSR_IM_HPP
+
+#include <ndn-cpp-dev/face.hpp>
+#include <ndn-cpp-dev/security/key-chain.hpp>
+#include <ndn-cpp-dev/util/scheduler.hpp>
+
+namespace nlsr
+{
+
+    using namespace ndn;
+    using namespace std;
+
+    class Nlsr;
+
+    class interestManager
+    {
+    public:
+        interestManager()
+        {
+        }
+        void processInterest(Nlsr& pnlsr, const ndn::Name &name,
+                             const ndn::Interest &interest);
+        void processInterestInfo(Nlsr& pnlsr, string& neighbor,
+                                 const ndn::Interest &interest);
+        void processInterestLsa(Nlsr& pnlsr,const ndn::Interest &interest);
+        void processInterestForNameLsa(Nlsr& pnlsr, const ndn::Interest &interest,
+                                       string lsaKey, uint32_t interestedlsSeqNo);
+        void processInterestForAdjLsa(Nlsr& pnlsr, const ndn::Interest &interest,
+                                      string lsaKey, uint32_t interestedlsSeqNo);
+        void processInterestForCorLsa(Nlsr& pnlsr, const ndn::Interest &interest,
+                                      string lsaKey, uint32_t interestedlsSeqNo);
+
+        void processInterestKeys(Nlsr& pnlsr,const ndn::Interest &interest);
+
+        void processInterestTimedOut(Nlsr& pnlsr, const ndn::Interest &interest);
+        void processInterestTimedOutInfo(Nlsr& pnlsr, string& neighbor,
+                                         const ndn::Interest &interest);
+        void processInterestTimedOutLsa(Nlsr& pnlsr,const ndn::Interest &interest);
+        void expressInterest(Nlsr& pnlsr,const string& interestNamePrefix, int scope,
+                             int seconds);
+        void sendScheduledInfoInterest(Nlsr& pnlsr, int seconds);
+        void scheduleInfoInterest(Nlsr& pnlsr, int seconds);
+
+    private:
+
+
+    };
+
+}//namespace nlsr
+
+#endif
diff --git a/src/communication/nlsr_slh.cpp b/src/communication/nlsr_slh.cpp
new file mode 100644
index 0000000..ac29148
--- /dev/null
+++ b/src/communication/nlsr_slh.cpp
@@ -0,0 +1,147 @@
+#include "nlsr.hpp"
+#include "nlsr_slh.hpp"
+#include "security/nlsr_km.hpp"
+#include "utility/nlsr_tokenizer.hpp"
+
+
+namespace nlsr
+{
+    void
+    SyncLogicHandler::createSyncSocket(Nlsr &pnlsr )
+    {
+        cout<<"Creating Sync socket ......"<<endl;
+        cout<<"Sync prefix: "<<syncPrefix.toUri()<<endl;
+        syncSocket=make_shared<SyncSocket>(syncPrefix, validator, syncFace,
+                                           bind(&SyncLogicHandler::nsyncUpdateCallBack,this,
+                                                _1, _2,boost::ref(pnlsr)),
+                                           bind(&SyncLogicHandler::nsyncRemoveCallBack, this,
+                                                _1,boost::ref(pnlsr)));
+    }
+
+    void
+    SyncLogicHandler::nsyncUpdateCallBack(const vector<MissingDataInfo> &v,
+                                          SyncSocket *socket, Nlsr& pnlsr)
+    {
+        cout<<"nsyncUpdateCallBack called ...."<<endl;
+        int n = v.size();
+        for(int i=0; i < n; i++)
+        {
+            std::cout<<"Data Name: "<<v[i].prefix<<" Seq: "<<v[i].high.getSeq()<<endl;
+            processUpdateFromSync(v[i].prefix,v[i].high.getSeq(),pnlsr);
+        }
+    }
+
+    void
+    SyncLogicHandler::nsyncRemoveCallBack(const string& prefix, Nlsr& pnlsr)
+    {
+        cout<<"nsyncRemoveCallBack called ...."<<endl;
+    }
+
+    void
+    SyncLogicHandler::removeRouterFromSyncing(string& routerPrefix)
+    {
+    }
+
+    void
+    SyncLogicHandler::processUpdateFromSync(std::string updateName,
+                                            uint64_t seqNo,  Nlsr& pnlsr)
+    {
+        nlsrTokenizer nt(updateName,"/");
+        string chkString("LSA");
+        if( nt.doesTokenExist(chkString) )
+        {
+            //process LSA Update here
+            string routerName=nt.getTokenString(nt.getTokenPosition(chkString)+1);
+            processRoutingUpdateFromSync(routerName, seqNo, pnlsr);
+        }
+        chkString="keys";
+        if( nt.doesTokenExist(chkString) )
+        {
+            //process keys update here
+            processKeysUpdateFromSync(updateName,seqNo, pnlsr);
+        }
+    }
+
+    void
+    SyncLogicHandler::processRoutingUpdateFromSync(std::string routerName,
+            uint64_t seqNo,  Nlsr& pnlsr)
+    {
+        if( routerName != pnlsr.getConfParameter().getRouterPrefix() )
+        {
+            SequencingManager sm(seqNo);
+            cout<<sm;
+            cout<<"Router Name: "<<routerName<<endl;
+            if ( pnlsr.getLsdb().isNameLsaNew(routerName+"/1",sm.getNameLsaSeq()))
+            {
+                cout<<"Updated Name LSA. Need to fetch it"<<endl;
+                string lsaPrefix=
+                    pnlsr.getConfParameter().getChronosyncLsaPrefix() +
+                    routerName + "/1/" +
+                    boost::lexical_cast<std::string>(sm.getNameLsaSeq());
+                pnlsr.getIm().expressInterest(pnlsr, lsaPrefix, 3,
+                                              pnlsr.getConfParameter().getInterestResendTime());
+            }
+            if ( pnlsr.getLsdb().isAdjLsaNew(routerName+"/2",sm.getAdjLsaSeq()))
+            {
+                cout<<"Updated Adj LSA. Need to fetch it"<<endl;
+                string lsaPrefix=
+                    pnlsr.getConfParameter().getChronosyncLsaPrefix() +
+                    routerName + "/2/" +
+                    boost::lexical_cast<std::string>(sm.getAdjLsaSeq());
+                pnlsr.getIm().expressInterest(pnlsr, lsaPrefix, 3,
+                                              pnlsr.getConfParameter().getInterestResendTime());
+            }
+            if ( pnlsr.getLsdb().isCorLsaNew(routerName+"/3",sm.getCorLsaSeq()))
+            {
+                cout<<"Updated Cor LSA. Need to fetch it"<<endl;
+                string lsaPrefix=
+                    pnlsr.getConfParameter().getChronosyncLsaPrefix() +
+                    routerName + "/3/" +
+                    boost::lexical_cast<std::string>(sm.getCorLsaSeq());
+                pnlsr.getIm().expressInterest(pnlsr, lsaPrefix, 3,
+                                              pnlsr.getConfParameter().getInterestResendTime());
+            }
+        }
+    }
+
+    void
+    SyncLogicHandler::processKeysUpdateFromSync(std::string certName,
+            uint64_t seqNo, Nlsr& pnlsr)
+    {
+        string certNamePrefix=certName + "/" + boost::lexical_cast<string>(seqNo);
+        pnlsr.getIm().expressInterest(pnlsr, certNamePrefix, 3,
+                                      pnlsr.getConfParameter().getInterestResendTime());
+    }
+
+    void
+    SyncLogicHandler::publishRoutingUpdate(SequencingManager& sm,
+                                           string updatePrefix)
+    {
+        sm.writeSeqNoToFile();
+        publishSyncUpdate(updatePrefix,sm.getCombinedSeqNo());
+    }
+
+    void
+    SyncLogicHandler::publishKeyUpdate(KeyManager& km)
+    {
+        publishSyncUpdate(km.getRouterCertName().toUri(),km.getCertSeqNo());
+    }
+
+    void
+    SyncLogicHandler::publishIdentityUpdate(string identityName)
+    {
+        publishSyncUpdate(identityName,0);
+    }
+
+    void
+    SyncLogicHandler::publishSyncUpdate(string updatePrefix, uint64_t seqNo)
+    {
+        cout<<"Publishing Sync Update ......"<<endl;
+        cout<<"Update in prefix: "<<updatePrefix<<endl;
+        cout<<"Seq No: "<<seqNo<<endl;
+        ndn::Name updateName(updatePrefix);
+        string data("NoData");
+        syncSocket->publishData(updateName,0,data.c_str(),data.size(),1000,seqNo);
+    }
+
+}
diff --git a/src/communication/nlsr_slh.hpp b/src/communication/nlsr_slh.hpp
new file mode 100644
index 0000000..3fef612
--- /dev/null
+++ b/src/communication/nlsr_slh.hpp
@@ -0,0 +1,65 @@
+#ifndef NLSR_SLH_HPP
+#define NLSR_SLH_HPP
+
+#include <iostream>
+
+#include <ndn-cpp-dev/face.hpp>
+#include <nsync/sync-socket.h>
+#include <ndn-cpp-dev/security/validator-null.hpp>
+#include <ndn-cpp-dev/util/scheduler.hpp>
+
+#include "nlsr_sm.hpp"
+
+class KeyManager;
+
+extern "C" {
+#include <unistd.h>
+}
+
+using namespace ndn;
+using namespace Sync;
+using namespace std;
+
+class interestManager;
+class ConfParameter;
+
+namespace nlsr
+{
+    class SyncLogicHandler
+    {
+    public:
+        SyncLogicHandler(ndn::shared_ptr<boost::asio::io_service> ioService)
+            : validator(new ndn::ValidatorNull())
+            , syncFace(new ndn::Face(ioService))
+        {}
+
+
+        void createSyncSocket(Nlsr& pnlsr);
+        void nsyncUpdateCallBack(const vector<MissingDataInfo> &v,
+                                 SyncSocket *socket, Nlsr& pnlsr );
+        void nsyncRemoveCallBack(const string& prefix, Nlsr &pnlsr);
+        void removeRouterFromSyncing(string& routerPrefix);
+        void publishRoutingUpdate(SequencingManager& sm, string updatePrefix);
+        void publishKeyUpdate(KeyManager& km);
+        void publishIdentityUpdate(string identityName);
+        void setSyncPrefix(string sp)
+        {
+            syncPrefix.clear();
+            syncPrefix.set(sp);
+        }
+    private:
+        void processUpdateFromSync(std::string updateName, uint64_t seqNo,
+                                   Nlsr& pnlsr);
+        void processRoutingUpdateFromSync(std::string routerName, uint64_t seqNo,
+                                          Nlsr& pnlsr);
+        void processKeysUpdateFromSync(std::string certName, uint64_t seqNo,
+                                       Nlsr& pnlsr);
+        void publishSyncUpdate(string updatePrefix, uint64_t seqNo);
+    private:
+        ndn::shared_ptr<ndn::ValidatorNull> validator;
+        ndn::shared_ptr<ndn::Face> syncFace;
+        ndn::shared_ptr<SyncSocket> syncSocket;
+        ndn::Name syncPrefix;
+    };
+}
+#endif
diff --git a/src/route/nlsr_fe.cpp b/src/route/nlsr_fe.cpp
new file mode 100644
index 0000000..5f4811c
--- /dev/null
+++ b/src/route/nlsr_fe.cpp
@@ -0,0 +1,48 @@
+#include <list>
+#include "nlsr_fe.hpp"
+#include "nlsr_nexthop.hpp"
+
+namespace nlsr
+{
+
+    using namespace std;
+
+    bool
+    FibEntry::isEqualNextHops(Nhl &nhlOther)
+    {
+        if ( nhl.getNhlSize() != nhlOther.getNhlSize() )
+        {
+            return false;
+        }
+        else
+        {
+            int nhCount=0;
+            std::list<NextHop>::iterator it1, it2;
+            for ( it1=nhl.getNextHopList().begin(),
+                    it2 = nhlOther.getNextHopList().begin() ;
+                    it1 != nhl.getNextHopList().end() ; it1++, it2++)
+            {
+                if ((*it1).getConnectingFace() == (*it2).getConnectingFace() )
+                {
+                    (*it1).setRouteCost((*it2).getRouteCost());
+                    nhCount++;
+                }
+                else
+                {
+                    break;
+                }
+            }
+            return nhCount == nhl.getNhlSize();
+        }
+    }
+
+    ostream&
+    operator<<(ostream& os, FibEntry& fe)
+    {
+        os<<"Name Prefix: "<<fe.getName()<<endl;
+        os<<"Time to Refresh: "<<fe.getTimeToRefresh()<<endl;
+        os<<fe.getNhl()<<endl;
+        return os;
+    }
+
+}//namespace nlsr
diff --git a/src/route/nlsr_fe.hpp b/src/route/nlsr_fe.hpp
new file mode 100644
index 0000000..c85e045
--- /dev/null
+++ b/src/route/nlsr_fe.hpp
@@ -0,0 +1,85 @@
+#ifndef NLSR_FE_HPP
+#define NLSR_FE_HPP
+
+#include<list>
+#include <iostream>
+#include <ndn-cpp-dev/util/scheduler.hpp>
+
+#include "nlsr_nexthop.hpp"
+#include "nlsr_nhl.hpp"
+
+namespace nlsr
+{
+
+    using namespace std;
+
+    class FibEntry
+    {
+    public:
+        FibEntry()
+            : name()
+            , timeToRefresh(0)
+            , feSeqNo(0)
+        {
+        }
+
+        FibEntry(string n)
+        {
+            name=n;
+        }
+
+        string getName()
+        {
+            return name;
+        }
+
+        Nhl& getNhl()
+        {
+            return nhl;
+        }
+
+        int getTimeToRefresh()
+        {
+            return timeToRefresh;
+        }
+
+        void setTimeToRefresh(int ttr)
+        {
+            timeToRefresh=ttr;
+        }
+
+        void setFeExpiringEventId(ndn::EventId feid)
+        {
+            feExpiringEventId=feid;
+        }
+
+        ndn::EventId getFeExpiringEventId()
+        {
+            return feExpiringEventId;
+        }
+
+        void setFeSeqNo(int fsn)
+        {
+            feSeqNo=fsn;
+        }
+
+        int getFeSeqNo()
+        {
+            return feSeqNo;
+        }
+
+        bool isEqualNextHops(Nhl &nhlOther);
+
+    private:
+        string name;
+        int timeToRefresh;
+        ndn::EventId feExpiringEventId;
+        int feSeqNo;
+        Nhl nhl;
+    };
+
+    ostream& operator<<(ostream& os, FibEntry& fe);
+
+} //namespace nlsr
+
+#endif
diff --git a/src/route/nlsr_fib.cpp b/src/route/nlsr_fib.cpp
new file mode 100644
index 0000000..8fb7928
--- /dev/null
+++ b/src/route/nlsr_fib.cpp
@@ -0,0 +1,168 @@
+#include<list>
+#include "nlsr_fe.hpp"
+#include "nlsr_fib.hpp"
+#include "nlsr_nhl.hpp"
+#include "nlsr.hpp"
+
+namespace nlsr
+{
+
+    using namespace std;
+    using namespace ndn;
+
+    static bool
+    fibEntryNameCompare(FibEntry& fe, string name)
+    {
+        return fe.getName() == name ;
+    }
+
+    void
+    Fib::cancelScheduledFeExpiringEvent(Nlsr& pnlsr, EventId eid)
+    {
+        pnlsr.getScheduler().cancelEvent(eid);
+    }
+
+
+    ndn::EventId
+    Fib::scheduleFibEntryRefreshing(Nlsr& pnlsr, string name, int feSeqNum,
+                                    int refreshTime)
+    {
+        return pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(refreshTime),
+                ndn::bind(&Fib::refreshFibEntry,this,name,feSeqNum));
+    }
+
+    void
+    Fib::refreshFibEntry(string name, int feSeqNum)
+    {
+    }
+
+    void
+    Fib::removeFromFib(Nlsr& pnlsr, string name)
+    {
+        std::list<FibEntry >::iterator it = std::find_if( fibTable.begin(),
+                                            fibTable.end(), bind(&fibEntryNameCompare, _1, name));
+        if( it != fibTable.end() )
+        {
+            for(std::list<NextHop>::iterator nhit=(*it).getNhl().getNextHopList().begin();
+                    nhit != (*it).getNhl().getNextHopList().begin(); nhit++)
+            {
+                //remove entry from NDN-FIB
+            }
+            cancelScheduledFeExpiringEvent(pnlsr, (*it).getFeExpiringEventId());
+            fibTable.erase(it);
+        }
+    }
+
+
+    void
+    Fib::updateFib(Nlsr& pnlsr,string name, Nhl& nextHopList, int maxFacesPerPrefix)
+    {
+        int startFace=0;
+        int endFace=getNumberOfFacesForName(nextHopList,maxFacesPerPrefix);
+        std::list<FibEntry >::iterator it = std::find_if( fibTable.begin(),
+                                            fibTable.end(), bind(&fibEntryNameCompare, _1, name));
+        if( it != fibTable.end() )
+        {
+            nextHopList.sortNhl();
+            if ( !(*it).isEqualNextHops(nextHopList) )
+            {
+                std::list<NextHop>::iterator nhit=nextHopList.getNextHopList().begin();
+                (*it).getNhl().addNextHop((*nhit));
+                removeFibEntryHop((*it).getNhl(),(*nhit).getConnectingFace());
+                startFace++;
+                nhit++;
+                for( int i=startFace; i< endFace; nhit++,i++)
+                {
+                    (*it).getNhl().addNextHop((*nhit));
+                }
+                (*it).setTimeToRefresh(fibEntryRefreshTime);
+            }
+            (*it).getNhl().sortNhl();
+            cancelScheduledFeExpiringEvent(pnlsr, (*it).getFeExpiringEventId());
+            (*it).setFeSeqNo((*it).getFeSeqNo()+1);
+            (*it).setFeExpiringEventId(scheduleFibEntryRefreshing(pnlsr,
+                                       (*it).getName() ,
+                                       (*it).getFeSeqNo(),fibEntryRefreshTime));
+            //update NDN-FIB
+        }
+        else
+        {
+            nextHopList.sortNhl();
+            FibEntry newEntry(name);
+            std::list<NextHop>::iterator nhit=nextHopList.getNextHopList().begin();
+            for(int i=startFace; i< endFace ; i++)
+            {
+                newEntry.getNhl().addNextHop((*nhit));
+                ++nhit;
+            }
+            newEntry.getNhl().sortNhl();
+            newEntry.setTimeToRefresh(fibEntryRefreshTime);
+            newEntry.setFeSeqNo(1);
+            fibTable.push_back(newEntry);
+            //cancelScheduledFeExpiringEvent(pnlsr, newEntry().getFeExpiringEventId());
+            //Update NDN-FIB
+        }
+    }
+
+
+
+    void Fib::cleanFib(Nlsr& pnlsr)
+    {
+        for( std::list<FibEntry >::iterator it=fibTable.begin(); it != fibTable.end();
+                ++it)
+        {
+            for(std::list<NextHop>::iterator nhit=(*it).getNhl().getNextHopList().begin();
+                    nhit != (*it).getNhl().getNextHopList().begin(); nhit++)
+            {
+                cancelScheduledFeExpiringEvent(pnlsr,(*it).getFeExpiringEventId());
+                //remove entry from NDN-FIB
+            }
+        }
+        if ( fibTable.size() > 0 )
+        {
+            fibTable.clear();
+        }
+    }
+
+
+    void
+    Fib::removeFibEntryHop(Nhl& nl, int doNotRemoveHopFaceId)
+    {
+        for( std::list<NextHop >::iterator it=nl.getNextHopList().begin();
+                it != nl.getNextHopList().end();   ++it)
+        {
+            if ( (*it).getConnectingFace() != doNotRemoveHopFaceId )
+            {
+                nl.getNextHopList().erase(it);
+            }
+        }
+    }
+
+
+    int
+    Fib::getNumberOfFacesForName(Nhl& nextHopList, int maxFacesPerPrefix)
+    {
+        int endFace=0;
+        if((maxFacesPerPrefix == 0) || (nextHopList.getNhlSize() <= maxFacesPerPrefix))
+        {
+            return nextHopList.getNhlSize();
+        }
+        else
+        {
+            return maxFacesPerPrefix;
+        }
+        return endFace;
+    }
+
+    void
+    Fib::printFib()
+    {
+        cout<<"-------------------FIB-----------------------------"<<endl;
+        for(std::list<FibEntry>::iterator it = fibTable.begin(); it!=fibTable.end();
+                ++it)
+        {
+            cout<<(*it);
+        }
+    }
+
+} //namespace nlsr
diff --git a/src/route/nlsr_fib.hpp b/src/route/nlsr_fib.hpp
new file mode 100644
index 0000000..d93d972
--- /dev/null
+++ b/src/route/nlsr_fib.hpp
@@ -0,0 +1,48 @@
+#ifndef NLSR_FIB_HPP
+#define NLSR_FIB_HPP
+
+#include <list>
+#include "nlsr_fe.hpp"
+
+namespace nlsr
+{
+
+    class Nlsr;
+
+    using namespace std;
+    using namespace ndn;
+
+    class Fib
+    {
+    public:
+        Fib()
+        {
+        }
+
+        void removeFromFib(Nlsr& pnlsr, string name);
+        void updateFib(Nlsr& pnlsr, string name, Nhl& nextHopList,
+                       int maxFacesPerPrefix);
+        void cleanFib(Nlsr& pnlsr);
+        void setFibEntryRefreshTime(int fert)
+        {
+            fibEntryRefreshTime=fert;
+        }
+
+        void printFib();
+
+    private:
+        void removeFibEntryHop(Nhl& nl, int doNotRemoveHopFaceId);
+        int getNumberOfFacesForName(Nhl& nextHopList, int maxFacesPerPrefix);
+        ndn::EventId
+        scheduleFibEntryRefreshing(Nlsr& pnlsr, string name, int feSeqNum,
+                                   int refreshTime);
+        void cancelScheduledFeExpiringEvent(Nlsr& pnlsr, EventId eid);
+        void refreshFibEntry(string name, int feSeqNum);
+
+    private:
+        std::list<FibEntry> fibTable;
+        int fibEntryRefreshTime;
+    };
+
+}//namespace nlsr
+#endif
diff --git a/src/route/nlsr_map.cpp b/src/route/nlsr_map.cpp
new file mode 100644
index 0000000..47b02ec
--- /dev/null
+++ b/src/route/nlsr_map.cpp
@@ -0,0 +1,124 @@
+#include<iostream>
+#include<list>
+
+#include "nlsr.hpp"
+#include "nlsr_adjacent.hpp"
+#include "nlsr_lsa.hpp"
+#include "nlsr_lsdb.hpp"
+#include "nlsr_map.hpp"
+
+namespace nlsr
+{
+
+    using namespace std;
+
+    ostream&
+    operator<<(ostream& os, MapEntry& mpe)
+    {
+        os<<"MapEntry: ( Router: "<<mpe.getRouter()<<" Mapping No: ";
+        os<<mpe.getMappingNumber()<<" )"<<endl;
+        return os;
+    }
+
+    static bool
+    mapEntryCompareByRouter(MapEntry& mpe1, string& rtrName)
+    {
+        return mpe1.getRouter()==rtrName;
+    }
+
+    static bool
+    mapEntryCompareByMappingNo(MapEntry& mpe1, int mappingNo)
+    {
+        return mpe1.getMappingNumber()==mappingNo;
+    }
+
+    void
+    Map::addMapElement(string& rtrName)
+    {
+        MapEntry me(rtrName,mappingIndex);
+        if (  addMapElement(me) )
+        {
+            mappingIndex++;
+        }
+    }
+
+    bool
+    Map::addMapElement(MapEntry& mpe)
+    {
+        //cout << mpe;
+        std::list<MapEntry >::iterator it = std::find_if( rMap.begin(),
+                                            rMap.end(),
+                                            bind(&mapEntryCompareByRouter, _1, mpe.getRouter()));
+        if ( it == rMap.end() )
+        {
+            rMap.push_back(mpe);
+            return true;
+        }
+        return false;
+    }
+
+    string
+    Map::getRouterNameByMappingNo(int mn)
+    {
+        std::list<MapEntry >::iterator it = std::find_if( rMap.begin(),
+                                            rMap.end(),
+                                            bind(&mapEntryCompareByMappingNo, _1, mn));
+        if ( it != rMap.end() )
+        {
+            return (*it).getRouter();
+        }
+        return "";
+    }
+
+    int
+    Map::getMappingNoByRouterName(string& rName)
+    {
+        std::list<MapEntry >::iterator it = std::find_if( rMap.begin(),
+                                            rMap.end(),
+                                            bind(&mapEntryCompareByRouter, _1, rName));
+        if ( it != rMap.end() )
+        {
+            return (*it).getMappingNumber();
+        }
+        return -1;
+    }
+
+    void
+    Map::createMapFromAdjLsdb(Nlsr& pnlsr)
+    {
+        std::list<AdjLsa> adjLsdb=pnlsr.getLsdb().getAdjLsdb();
+        for( std::list<AdjLsa>::iterator it=adjLsdb.begin();
+                it!= adjLsdb.end() ; it++)
+        {
+            string linkStartRouter=(*it).getOrigRouter();
+            addMapElement(linkStartRouter);
+            std::list<Adjacent> adl=(*it).getAdl().getAdjList();
+            for( std::list<Adjacent>::iterator itAdl=adl.begin();
+                    itAdl!= adl.end() ; itAdl++)
+            {
+                string linkEndRouter=(*itAdl).getAdjacentName();
+                addMapElement(linkEndRouter);
+            }
+        }
+    }
+
+    void
+    Map::resetMap()
+    {
+        rMap.clear();
+        mappingIndex=0;
+    }
+
+    ostream&
+    operator<<(ostream& os, Map& rMap)
+    {
+        os<<"---------------Map----------------------"<<endl;
+        std::list< MapEntry > ml=rMap.getMapList();
+        for( std::list<MapEntry>::iterator it=ml.begin(); it!= ml.end() ; it++)
+        {
+            os<< (*it);
+        }
+        return os;
+    }
+
+} //namespace nlsr
diff --git a/src/route/nlsr_map.hpp b/src/route/nlsr_map.hpp
new file mode 100644
index 0000000..0352d1d
--- /dev/null
+++ b/src/route/nlsr_map.hpp
@@ -0,0 +1,88 @@
+#ifndef NLSR_MAP_HPP
+#define NLSR_MAP_HPP
+
+#include <iostream>
+#include <list>
+
+#include <ndn-cpp-dev/face.hpp>
+
+namespace nlsr
+{
+
+    class Nlsr;
+
+    using namespace std;
+
+    class MapEntry
+    {
+    public:
+        MapEntry()
+            : router()
+            , mappingNumber(-1)
+        {
+        }
+
+        ~MapEntry()
+        {
+        }
+
+        MapEntry(string rtr, int mn)
+        {
+            router=rtr;
+            mappingNumber=mn;
+        }
+
+        string getRouter()
+        {
+            return router;
+        }
+
+        int getMappingNumber()
+        {
+            return mappingNumber;
+        }
+    private:
+        string router;
+        int mappingNumber;
+    };
+
+    ostream&
+    operator<<(ostream& os, MapEntry& mpe);
+
+    class Map
+    {
+    public:
+        Map()
+            : mappingIndex(0)
+        {
+        }
+
+
+        void addMapElement(string& rtrName);
+        void createMapFromAdjLsdb(Nlsr& pnlsr);
+        string getRouterNameByMappingNo(int mn);
+        int getMappingNoByRouterName(string& rName);
+        void resetMap();
+        std::list< MapEntry >& getMapList()
+        {
+            return rMap;
+        }
+
+        int getMapSize()
+        {
+            return rMap.size();
+        }
+
+
+    private:
+        bool addMapElement(MapEntry& mpe);
+
+        int mappingIndex;
+        std::list< MapEntry > rMap;
+    };
+
+    ostream&
+    operator<<(ostream& os, Map& rMap);
+
+} // namespace nlsr
+#endif
diff --git a/src/route/nlsr_nexthop.cpp b/src/route/nlsr_nexthop.cpp
new file mode 100644
index 0000000..e58b23c
--- /dev/null
+++ b/src/route/nlsr_nexthop.cpp
@@ -0,0 +1,13 @@
+#include "nlsr_nexthop.hpp"
+
+namespace nlsr
+{
+
+    ostream&
+    operator<<(ostream& os, NextHop& nh)
+    {
+        os<<"Face: "<<nh.getConnectingFace()<<"  Route Cost: "<<nh.getRouteCost();
+        return os;
+    }
+
+}//namespace nlsr
diff --git a/src/route/nlsr_nexthop.hpp b/src/route/nlsr_nexthop.hpp
new file mode 100644
index 0000000..1361d52
--- /dev/null
+++ b/src/route/nlsr_nexthop.hpp
@@ -0,0 +1,56 @@
+#ifndef NLSR_NEXTHOP_HPP
+#define NLSR_NEXTHOP_HPP
+
+#include<iostream>
+
+namespace nlsr
+{
+
+    using namespace std;
+
+    class NextHop
+    {
+    public:
+        NextHop()
+            : connectingFace(0)
+            , routeCost(0)
+        {
+        }
+
+        NextHop(int cf, double rc)
+        {
+            connectingFace=cf;
+            routeCost=rc;
+        }
+
+        int getConnectingFace()
+        {
+            return connectingFace;
+        }
+
+        void setConnectingFace(int cf)
+        {
+            connectingFace=cf;
+        }
+
+        double getRouteCost()
+        {
+            return routeCost;
+        }
+
+        void setRouteCost(double rc)
+        {
+            routeCost=rc;
+        }
+    private:
+        int connectingFace;
+        double routeCost;
+    };
+
+
+    ostream&
+    operator<<(ostream& os, NextHop& nh);
+
+}//namespace nlsr
+
+#endif
diff --git a/src/route/nlsr_nhl.cpp b/src/route/nlsr_nhl.cpp
new file mode 100644
index 0000000..2aaa2a6
--- /dev/null
+++ b/src/route/nlsr_nhl.cpp
@@ -0,0 +1,90 @@
+#include <iostream>
+
+#include "nlsr_nhl.hpp"
+#include "nlsr_nexthop.hpp"
+
+namespace nlsr
+{
+
+    using namespace std;
+
+    static bool
+    nexthopCompare(NextHop& nh1, NextHop& nh2)
+    {
+        return nh1.getConnectingFace()==nh2.getConnectingFace();
+    }
+
+    static bool
+    nexthopRemoveCompare(NextHop& nh1, NextHop& nh2)
+    {
+        return (nh1.getConnectingFace()==nh2.getConnectingFace() &&
+                nh1.getRouteCost() == nh2.getRouteCost()) ;
+    }
+
+    static bool
+    nextHopSortingComparator(NextHop& nh1, NextHop& nh2)
+    {
+        return nh1.getRouteCost() < nh2.getRouteCost();
+    }
+
+    /**
+    Add next hop to the Next Hop list
+    If next hop is new it is added
+    If next hop already exists in next
+    hop list then updates the route
+    cost with new next hop's route cost
+    */
+
+    void
+    Nhl::addNextHop(NextHop& nh)
+    {
+        std::list<NextHop >::iterator it = std::find_if( nexthopList.begin(),
+                                           nexthopList.end(),
+                                           bind(&nexthopCompare, _1, nh));
+        if ( it == nexthopList.end() )
+        {
+            nexthopList.push_back(nh);
+        }
+        if ( (*it).getRouteCost() > nh.getRouteCost() )
+        {
+            (*it).setRouteCost(nh.getRouteCost());
+        }
+    }
+
+    /**
+    Remove a next hop only if both next hop face and route cost are same
+
+    */
+
+    void
+    Nhl::removeNextHop(NextHop &nh)
+    {
+        std::list<NextHop >::iterator it = std::find_if( nexthopList.begin(),
+                                           nexthopList.end(),
+                                           bind(&nexthopRemoveCompare, _1, nh));
+        if ( it != nexthopList.end() )
+        {
+            nexthopList.erase(it);
+        }
+    }
+
+    void
+    Nhl::sortNhl()
+    {
+        nexthopList.sort(nextHopSortingComparator);
+    }
+
+    ostream&
+    operator<<(ostream& os, Nhl& nhl)
+    {
+        std::list< NextHop > nexthopList = nhl.getNextHopList();
+        int i=1;
+        for( std::list<NextHop>::iterator it=nexthopList.begin();
+                it!= nexthopList.end() ; it++,i++)
+        {
+            os << "Nexthop "<<i<<": "<<(*it)<<endl;
+        }
+        return os;
+    }
+
+}//namespace nlsr
diff --git a/src/route/nlsr_nhl.hpp b/src/route/nlsr_nhl.hpp
new file mode 100644
index 0000000..9f6bd76
--- /dev/null
+++ b/src/route/nlsr_nhl.hpp
@@ -0,0 +1,54 @@
+#ifndef NLSR_NHL_HPP
+#define NLSR_NHL_HPP
+
+#include <ndn-cpp-dev/face.hpp>
+#include "nlsr_adjacent.hpp"
+#include <list>
+#include <iostream>
+
+#include "nlsr_nexthop.hpp"
+
+namespace nlsr
+{
+
+    using namespace std;
+
+    class Nhl
+    {
+    public:
+        Nhl()
+        {
+        }
+
+        ~Nhl()
+        {
+        }
+        void addNextHop(NextHop &nh);
+        void removeNextHop(NextHop &nh);
+        void sortNhl();
+        int getNhlSize()
+        {
+            return nexthopList.size();
+        }
+        void resetNhl()
+        {
+            if (nexthopList.size() > 0 )
+            {
+                nexthopList.clear();
+            }
+        }
+        std::list< NextHop >& getNextHopList()
+        {
+            return nexthopList;
+        }
+
+    private:
+        std::list< NextHop > nexthopList;
+    };
+
+    ostream&
+    operator<<(ostream& os, Nhl& nhl);
+
+}//namespace nlsr
+
+#endif
diff --git a/src/route/nlsr_npt.cpp b/src/route/nlsr_npt.cpp
new file mode 100644
index 0000000..9c4d4cb
--- /dev/null
+++ b/src/route/nlsr_npt.cpp
@@ -0,0 +1,142 @@
+#include <list>
+#include <utility>
+#include <algorithm>
+
+#include "nlsr_npt.hpp"
+#include "nlsr_npte.hpp"
+#include "nlsr.hpp"
+
+namespace nlsr
+{
+
+    using namespace std;
+
+    static bool
+    npteCompare(Npte& npte, string& name)
+    {
+        return npte.getNamePrefix()==name;
+    }
+
+// Following two methods will update FIB with response to change in NPT
+
+    void
+    Npt::addNpte(string name, RoutingTableEntry& rte, Nlsr& pnlsr)
+    {
+        std::list<Npte >::iterator it = std::find_if( npteList.begin(),
+                                        npteList.end(), bind(&npteCompare, _1, name));
+        if ( it == npteList.end() )
+        {
+            Npte newEntry(	name);
+            newEntry.addRoutingTableEntry(rte);
+            newEntry.generateNhlfromRteList();
+            npteList.push_back(newEntry);
+            // update FIB here with nhl list newEntry.getNhl()
+            pnlsr.getFib().updateFib(pnlsr, name,newEntry.getNhl(),
+                                     pnlsr.getConfParameter().getMaxFacesPerPrefix());
+        }
+        else
+        {
+            (*it).addRoutingTableEntry(rte);
+            (*it).generateNhlfromRteList();
+            // update FIB here with nhl list from (*it).getNhl()
+            pnlsr.getFib().updateFib(pnlsr, name,(*it).getNhl() ,
+                                     pnlsr.getConfParameter().getMaxFacesPerPrefix());
+        }
+    }
+
+    void
+    Npt::removeNpte(string name, RoutingTableEntry& rte, Nlsr& pnlsr)
+    {
+        std::list<Npte >::iterator it = std::find_if( npteList.begin(),
+                                        npteList.end(), bind(&npteCompare, _1, name));
+        if ( it != npteList.end() )
+        {
+            string destRouter=rte.getDestination();
+            (*it).removeRoutingTableEntry(rte);
+            if ( ((*it).getRteListSize() == 0 ) &&
+                    (!pnlsr.getLsdb().doesLsaExist(destRouter+"/1",1) ) &&
+                    (!pnlsr.getLsdb().doesLsaExist(destRouter+"/2",2) ) &&
+                    (!pnlsr.getLsdb().doesLsaExist(destRouter+"/3",3) )   )
+            {
+                npteList.erase(it); // remove entry from NPT
+                // remove FIB entry with this name
+                pnlsr.getFib().removeFromFib(pnlsr,name);
+            }
+            else
+            {
+                (*it).generateNhlfromRteList();
+                // update FIB entry with new NHL
+                pnlsr.getFib().updateFib(pnlsr, name,(*it).getNhl(),
+                                         pnlsr.getConfParameter().getMaxFacesPerPrefix());
+            }
+        }
+    }
+
+
+    void
+    Npt::addNpte(string name, string destRouter, Nlsr& pnlsr)
+    {
+        std::pair<RoutingTableEntry& , bool> rteCheck=
+            pnlsr.getRoutingTable().findRoutingTableEntry(destRouter);
+        if(rteCheck.second)
+        {
+            addNpte(name,rteCheck.first,pnlsr);
+        }
+        else
+        {
+            RoutingTableEntry rte(destRouter);
+            addNpte(name, rte,pnlsr);
+        }
+    }
+
+    void
+    Npt::removeNpte(string name, string destRouter, Nlsr& pnlsr)
+    {
+        std::pair<RoutingTableEntry& , bool> rteCheck=
+            pnlsr.getRoutingTable().findRoutingTableEntry(destRouter);
+        if(rteCheck.second)
+        {
+            removeNpte(name,rteCheck.first,pnlsr);
+        }
+        else
+        {
+            RoutingTableEntry rte(destRouter);
+            removeNpte(name, rte,pnlsr);
+        }
+    }
+
+    void
+    Npt::updateNptWithNewRoute(Nlsr& pnlsr)
+    {
+        for(std::list<Npte >::iterator it=npteList.begin(); it!=npteList.end(); ++it)
+        {
+            std::list<RoutingTableEntry> rteList=(*it).getRteList();
+            for(std::list<RoutingTableEntry >::iterator rteit=rteList.begin();
+                    rteit !=rteList.end(); ++rteit)
+            {
+                std::pair<RoutingTableEntry& , bool> rteCheck=
+                    pnlsr.getRoutingTable().findRoutingTableEntry((*rteit).getDestination());
+                if(rteCheck.second)
+                {
+                    addNpte((*it).getNamePrefix(),rteCheck.first,pnlsr);
+                }
+                else
+                {
+                    RoutingTableEntry rte((*rteit).getDestination());
+                    addNpte((*it).getNamePrefix(), rte,pnlsr);
+                }
+            }
+        }
+    }
+
+    void
+    Npt::printNpt()
+    {
+        cout<<"----------------NPT----------------------"<<endl;
+        for(std::list<Npte >::iterator it=npteList.begin(); it!=npteList.end(); ++it)
+        {
+            cout <<(*it)<<endl;
+        }
+    }
+
+}
diff --git a/src/route/nlsr_npt.hpp b/src/route/nlsr_npt.hpp
new file mode 100644
index 0000000..f4ddbf9
--- /dev/null
+++ b/src/route/nlsr_npt.hpp
@@ -0,0 +1,34 @@
+#ifndef NLSR_NPT_HPP
+#define NLSR_NPT_HPP
+
+#include <list>
+#include "nlsr_npte.hpp"
+#include "nlsr_rte.hpp"
+
+namespace nlsr
+{
+
+    using namespace std;
+
+    class Nlsr;
+
+    class Npt
+    {
+    public:
+        Npt()
+        {
+        }
+        void addNpte(string name, string destRouter, Nlsr& pnlsr);
+        void removeNpte(string name, string destRouter, Nlsr& pnlsr);
+        void updateNptWithNewRoute(Nlsr& pnlsr);
+        void printNpt();
+    private:
+        void addNpte(string name, RoutingTableEntry& rte, Nlsr& pnlsr);
+        void removeNpte(string name, RoutingTableEntry& rte, Nlsr& pnlsr);
+    private:
+        std::list<Npte> npteList;
+    };
+
+}//namespace nlsr
+
+#endif
diff --git a/src/route/nlsr_npte.cpp b/src/route/nlsr_npte.cpp
new file mode 100644
index 0000000..60013ff
--- /dev/null
+++ b/src/route/nlsr_npte.cpp
@@ -0,0 +1,83 @@
+#include <list>
+#include <utility>
+#include "nlsr_npte.hpp"
+#include "nlsr_rte.hpp"
+#include "nlsr_nexthop.hpp"
+
+namespace nlsr
+{
+
+    using namespace std;
+
+    void
+    Npte::generateNhlfromRteList()
+    {
+        nhl.resetNhl();
+        for( std::list<RoutingTableEntry>::iterator it=rteList.begin();
+                it != rteList.end(); ++it )
+        {
+            for(std::list< NextHop >::iterator nhit=(*it).getNhl().getNextHopList().begin();
+                    nhit != (*it).getNhl().getNextHopList().end(); ++nhit)
+            {
+                nhl.addNextHop((*nhit));
+            }
+        }
+    }
+
+
+
+    static bool
+    rteCompare(RoutingTableEntry& rte, string& destRouter)
+    {
+        return rte.getDestination()==destRouter;
+    }
+
+    void
+    Npte::removeRoutingTableEntry(RoutingTableEntry& rte)
+    {
+        std::list<RoutingTableEntry >::iterator it = std::find_if( rteList.begin(),
+                rteList.end(),
+                bind(&rteCompare, _1, rte.getDestination()));
+        if ( it != rteList.end() )
+        {
+            rteList.erase(it);
+        }
+    }
+
+    void
+    Npte::addRoutingTableEntry(RoutingTableEntry &rte)
+    {
+        std::list<RoutingTableEntry >::iterator it = std::find_if( rteList.begin(),
+                rteList.end(),
+                bind(&rteCompare, _1, rte.getDestination()));
+        if ( it == rteList.end() )
+        {
+            rteList.push_back(rte);
+        }
+        else
+        {
+            (*it).getNhl().resetNhl(); // reseting existing routing table's next hop
+            for(std::list< NextHop >::iterator nhit=rte.getNhl().getNextHopList().begin();
+                    nhit != rte.getNhl().getNextHopList().end(); ++nhit)
+            {
+                (*it).getNhl().addNextHop((*nhit));
+            }
+        }
+    }
+
+//debugging purpose
+    ostream&
+    operator<<(ostream& os, Npte& npte)
+    {
+        os<<"Name: "<<npte.getNamePrefix()<<endl;
+        std::list<RoutingTableEntry> rteList=npte.getRteList();
+        for(std::list<RoutingTableEntry >::iterator it=rteList.begin();
+                it !=rteList.end(); ++it)
+        {
+            cout<<(*it);
+        }
+        os<<npte.getNhl();
+        return os;
+    }
+
+}//namespace nlsr
diff --git a/src/route/nlsr_npte.hpp b/src/route/nlsr_npte.hpp
new file mode 100644
index 0000000..e64328c
--- /dev/null
+++ b/src/route/nlsr_npte.hpp
@@ -0,0 +1,61 @@
+#ifndef NLSR_NPTE_HPP
+#define NLSR_NPTE_HPP
+
+#include <list>
+#include <utility>
+#include "nlsr_rte.hpp"
+
+namespace nlsr
+{
+
+    using namespace std;
+
+    class Npte
+    {
+    public:
+        Npte()
+            : namePrefix()
+            , nhl()
+        {
+        }
+        Npte(string np)
+            : nhl()
+        {
+            namePrefix=np;
+        }
+
+        string getNamePrefix()
+        {
+            return namePrefix;
+        }
+
+        std::list<RoutingTableEntry>& getRteList()
+        {
+            return rteList;
+        }
+
+        int getRteListSize()
+        {
+            return rteList.size();
+        }
+
+        Nhl& getNhl()
+        {
+            return nhl;
+        }
+        void generateNhlfromRteList();
+        void removeRoutingTableEntry(RoutingTableEntry& rte);
+        void addRoutingTableEntry(RoutingTableEntry &rte);
+
+    private:
+        string namePrefix;
+        std::list<RoutingTableEntry> rteList;
+        Nhl nhl;
+    };
+
+    ostream&
+    operator<<(ostream& os, Npte& npte);
+
+}//namespace nlsr
+
+#endif
diff --git a/src/route/nlsr_rt.cpp b/src/route/nlsr_rt.cpp
new file mode 100644
index 0000000..f9923f2
--- /dev/null
+++ b/src/route/nlsr_rt.cpp
@@ -0,0 +1,231 @@
+#include<iostream>
+#include<string>
+#include<list>
+
+#include "nlsr_rt.hpp"
+#include "nlsr.hpp"
+#include "nlsr_map.hpp"
+#include "nlsr_rtc.hpp"
+#include "nlsr_rte.hpp"
+#include "nlsr_npt.hpp"
+
+namespace nlsr
+{
+
+    using namespace std;
+
+    void
+    RoutingTable::calculate(Nlsr& pnlsr)
+    {
+        //debugging purpose
+        pnlsr.getNpt().printNpt();
+        pnlsr.getLsdb().printAdjLsdb();
+        pnlsr.getLsdb().printCorLsdb();
+        pnlsr.getLsdb().printNameLsdb();
+        if ( 	pnlsr.getIsRoutingTableCalculating() == 0 )
+        {
+            pnlsr.setIsRoutingTableCalculating(1); //setting routing table calculation
+            if ( pnlsr.getLsdb().doesLsaExist(
+                        pnlsr.getConfParameter().getRouterPrefix()+"/"+"2",2) )
+            {
+                if(pnlsr.getIsBuildAdjLsaSheduled() != 1)
+                {
+                    cout<<"CLearing old routing table ....."<<endl;
+                    clearRoutingTable();
+                    clearDryRoutingTable(); // for dry run options
+                    // calculate Link State routing
+                    if( (pnlsr.getConfParameter().getIsHyperbolicCalc() == 0 )
+                            || (pnlsr.getConfParameter().getIsHyperbolicCalc() == 2 ) )
+                    {
+                        calculateLsRoutingTable(pnlsr);
+                    }
+                    //calculate hyperbolic routing
+                    if ( pnlsr.getConfParameter().getIsHyperbolicCalc() == 1 )
+                    {
+                        calculateHypRoutingTable(pnlsr);
+                    }
+                    //calculate dry hyperbolic routing
+                    if ( pnlsr.getConfParameter().getIsHyperbolicCalc() == 2 )
+                    {
+                        calculateHypDryRoutingTable(pnlsr);
+                    }
+                    //need to update NPT here
+                    pnlsr.getNpt().updateNptWithNewRoute(pnlsr);
+                    //debugging purpose
+                    printRoutingTable();
+                    pnlsr.getNpt().printNpt();
+                    pnlsr.getFib().printFib();
+                    //debugging purpose end
+                }
+                else
+                {
+                    cout<<"Adjacency building is scheduled, so ";
+                    cout<<"routing table can not be calculated :("<<endl;
+                }
+            }
+            else
+            {
+                cout<<"No Adj LSA of router itself,";
+                cout<<	" so Routing table can not be calculated :("<<endl;
+                clearRoutingTable();
+                clearDryRoutingTable(); // for dry run options
+                // need to update NPT here
+                pnlsr.getNpt().updateNptWithNewRoute(pnlsr);
+                //debugging purpose
+                printRoutingTable();
+                pnlsr.getNpt().printNpt();
+                pnlsr.getFib().printFib();
+                //debugging purpose end
+            }
+            pnlsr.setIsRouteCalculationScheduled(0); //clear scheduled flag
+            pnlsr.setIsRoutingTableCalculating(0); //unsetting routing table calculation
+        }
+        else
+        {
+            scheduleRoutingTableCalculation(pnlsr);
+        }
+    }
+
+
+    void
+    RoutingTable::calculateLsRoutingTable(Nlsr& pnlsr)
+    {
+        cout<<"RoutingTable::calculateLsRoutingTable Called"<<endl;
+        Map vMap;
+        vMap.createMapFromAdjLsdb(pnlsr);
+        int numOfRouter=vMap.getMapSize();
+        LinkStateRoutingTableCalculator lsrtc(numOfRouter);
+        lsrtc.calculatePath(vMap,boost::ref(*this),pnlsr);
+    }
+
+    void
+    RoutingTable::calculateHypRoutingTable(Nlsr& pnlsr)
+    {
+        Map vMap;
+        vMap.createMapFromAdjLsdb(pnlsr);
+        int numOfRouter=vMap.getMapSize();
+        HypRoutingTableCalculator hrtc(numOfRouter,0);
+        hrtc.calculatePath(vMap,boost::ref(*this),pnlsr);
+    }
+
+    void
+    RoutingTable::calculateHypDryRoutingTable(Nlsr& pnlsr)
+    {
+        Map vMap;
+        vMap.createMapFromAdjLsdb(pnlsr);
+        int numOfRouter=vMap.getMapSize();
+        HypRoutingTableCalculator hrtc(numOfRouter,1);
+        hrtc.calculatePath(vMap,boost::ref(*this),pnlsr);
+    }
+
+    void
+    RoutingTable::scheduleRoutingTableCalculation(Nlsr& pnlsr)
+    {
+        if ( pnlsr.getIsRouteCalculationScheduled() != 1 )
+        {
+            pnlsr.getScheduler().scheduleEvent(ndn::time::seconds(15),
+                                               ndn::bind(&RoutingTable::calculate,this,boost::ref(pnlsr)));
+            pnlsr.setIsRouteCalculationScheduled(1);
+        }
+    }
+
+    static bool
+    routingTableEntryCompare(RoutingTableEntry& rte, string& destRouter)
+    {
+        return rte.getDestination()==destRouter;
+    }
+
+// function related to manipulation of routing table
+    void
+    RoutingTable::addNextHop(string destRouter, NextHop& nh)
+    {
+        std::pair<RoutingTableEntry&, bool> rte=findRoutingTableEntry(destRouter);
+        if( !rte.second )
+        {
+            RoutingTableEntry rte(destRouter);
+            rte.getNhl().addNextHop(nh);
+            rTable.push_back(rte);
+        }
+        else
+        {
+            (rte.first).getNhl().addNextHop(nh);
+        }
+    }
+
+    std::pair<RoutingTableEntry&, bool>
+    RoutingTable::findRoutingTableEntry(string destRouter)
+    {
+        std::list<RoutingTableEntry >::iterator it = std::find_if( rTable.begin(),
+                rTable.end(),
+                bind(&routingTableEntryCompare, _1, destRouter));
+        if ( it != rTable.end() )
+        {
+            return std::make_pair(boost::ref((*it)),true);
+        }
+        RoutingTableEntry rteEmpty;
+        return std::make_pair(boost::ref(rteEmpty),false);
+    }
+
+    void
+    RoutingTable::printRoutingTable()
+    {
+        cout<<"---------------Routing Table------------------"<<endl;
+        for(std::list<RoutingTableEntry>::iterator it=rTable.begin() ;
+                it != rTable.end(); ++it)
+        {
+            cout<<(*it)<<endl;
+        }
+    }
+
+
+//function related to manipulation of dry routing table
+    void
+    RoutingTable::addNextHopToDryTable(string destRouter, NextHop& nh)
+    {
+        std::list<RoutingTableEntry >::iterator it = std::find_if( dryTable.begin(),
+                dryTable.end(),
+                bind(&routingTableEntryCompare, _1, destRouter));
+        if ( it == dryTable.end() )
+        {
+            RoutingTableEntry rte(destRouter);
+            rte.getNhl().addNextHop(nh);
+            dryTable.push_back(rte);
+        }
+        else
+        {
+            (*it).getNhl().addNextHop(nh);
+        }
+    }
+
+    void
+    RoutingTable::printDryRoutingTable()
+    {
+        cout<<"--------Dry Run's Routing Table--------------"<<endl;
+        for(std::list<RoutingTableEntry>::iterator it=dryTable.begin() ;
+                it != dryTable.end(); ++it)
+        {
+            cout<<(*it)<<endl;
+        }
+    }
+
+
+    void
+    RoutingTable::clearRoutingTable()
+    {
+        if( rTable.size() > 0 )
+        {
+            rTable.clear();
+        }
+    }
+
+    void
+    RoutingTable::clearDryRoutingTable()
+    {
+        if (dryTable.size()>0 )
+        {
+            dryTable.clear();
+        }
+    }
+
+}//namespace nlsr
+
diff --git a/src/route/nlsr_rt.hpp b/src/route/nlsr_rt.hpp
new file mode 100644
index 0000000..fb9a060
--- /dev/null
+++ b/src/route/nlsr_rt.hpp
@@ -0,0 +1,50 @@
+#ifndef NLSR_RT_HPP
+#define NLSR_RT_HPP
+
+#include<iostream>
+#include<utility>
+#include<string>
+
+#include "nlsr_rte.hpp"
+
+namespace nlsr
+{
+
+    class Nlsr;
+    class NextHop;
+
+    using namespace std;
+
+    class RoutingTable
+    {
+    public:
+        RoutingTable()
+            : NO_NEXT_HOP(-12345)
+        {
+        }
+        void calculate(Nlsr& pnlsr);
+        void addNextHop(string destRouter, NextHop& nh);
+        void printRoutingTable();
+
+        void addNextHopToDryTable(string destRouter, NextHop& nh);
+        void printDryRoutingTable();
+        std::pair<RoutingTableEntry&, bool> findRoutingTableEntry(string destRouter);
+        void scheduleRoutingTableCalculation(Nlsr& pnlsr);
+
+    private:
+        void calculateLsRoutingTable(Nlsr& pnlsr);
+        void calculateHypRoutingTable(Nlsr& pnlsr);
+        void calculateHypDryRoutingTable(Nlsr&pnlsr);
+
+        void clearRoutingTable();
+        void clearDryRoutingTable();
+
+        const int NO_NEXT_HOP;
+
+        std::list< RoutingTableEntry > rTable;
+        std::list< RoutingTableEntry > dryTable;
+    };
+
+}//namespace nlsr
+
+#endif
diff --git a/src/route/nlsr_rtc.cpp b/src/route/nlsr_rtc.cpp
new file mode 100644
index 0000000..acdf6d5
--- /dev/null
+++ b/src/route/nlsr_rtc.cpp
@@ -0,0 +1,504 @@
+#include <iostream>
+#include <cmath>
+#include "nlsr_lsdb.hpp"
+#include "nlsr_rtc.hpp"
+#include "nlsr_map.hpp"
+#include "nlsr_lsa.hpp"
+#include "nlsr_nexthop.hpp"
+#include "nlsr.hpp"
+
+namespace nlsr
+{
+
+    using namespace std;
+
+    void
+    RoutingTableCalculator::allocateAdjMatrix()
+    {
+        adjMatrix = new double*[numOfRouter];
+        for(int i = 0; i < numOfRouter; ++i)
+        {
+            adjMatrix[i] = new double[numOfRouter];
+        }
+    }
+
+    void
+    RoutingTableCalculator::initMatrix()
+    {
+        for(int i=0; i<numOfRouter; i++)
+        {
+            for(int j=0; j<numOfRouter; j++)
+                adjMatrix[i][j]=0;
+        }
+    }
+
+    void
+    RoutingTableCalculator::makeAdjMatrix(Nlsr& pnlsr, Map pMap)
+    {
+        std::list<AdjLsa> adjLsdb=pnlsr.getLsdb().getAdjLsdb();
+        for( std::list<AdjLsa>::iterator it=adjLsdb.begin();
+                it!= adjLsdb.end() ; it++)
+        {
+            string linkStartRouter=(*it).getOrigRouter();
+            int row=pMap.getMappingNoByRouterName(linkStartRouter);
+            std::list<Adjacent> adl=(*it).getAdl().getAdjList();
+            for( std::list<Adjacent>::iterator itAdl=adl.begin();
+                    itAdl!= adl.end() ; itAdl++)
+            {
+                string linkEndRouter=(*itAdl).getAdjacentName();
+                int col=pMap.getMappingNoByRouterName(linkEndRouter);
+                double cost=(*itAdl).getLinkCost();
+                if ( (row >= 0 && row<numOfRouter) && (col >= 0 && col<numOfRouter) )
+                {
+                    adjMatrix[row][col]=cost;
+                }
+            }
+        }
+    }
+
+    void
+    RoutingTableCalculator::printAdjMatrix()
+    {
+        for(int i=0; i<numOfRouter; i++)
+        {
+            for(int j=0; j<numOfRouter; j++)
+                printf("%f ",adjMatrix[i][j]);
+            printf("\n");
+        }
+    }
+
+    void
+    RoutingTableCalculator::adjustAdMatrix(int source, int link, double linkCost)
+    {
+        for ( int i = 0; i < numOfRouter; i++ )
+        {
+            if ( i == link )
+            {
+                adjMatrix[source][i]=linkCost;
+            }
+            else
+            {
+                adjMatrix[source][i]=0;
+            }
+        }
+    }
+
+    int
+    RoutingTableCalculator::getNumOfLinkfromAdjMatrix(int sRouter)
+    {
+        int noLink=0;
+        for(int i=0; i<numOfRouter; i++)
+        {
+            if ( adjMatrix[sRouter][i] > 0 )
+            {
+                noLink++;
+            }
+        }
+        return noLink;
+    }
+
+    void
+    RoutingTableCalculator::getLinksFromAdjMatrix(int *links,
+            double *linkCosts, int source)
+    {
+        int j=0;
+        for (int i=0; i <numOfRouter; i++)
+        {
+            if ( adjMatrix[source][i] > 0 )
+            {
+                links[j]=i;
+                linkCosts[j]=adjMatrix[source][i];
+                j++;
+            }
+        }
+    }
+
+    void
+    RoutingTableCalculator::freeAdjMatrix()
+    {
+        for(int i = 0; i < numOfRouter; ++i)
+        {
+            delete [] adjMatrix[i];
+        }
+        delete [] adjMatrix;
+    }
+
+
+    void
+    RoutingTableCalculator::allocateLinks()
+    {
+        links=new int[vNoLink];
+    }
+
+    void RoutingTableCalculator::allocateLinkCosts()
+    {
+        linkCosts=new double[vNoLink];
+    }
+
+
+    void
+    RoutingTableCalculator::freeLinks()
+    {
+        delete [] links;
+    }
+    void
+    RoutingTableCalculator::freeLinksCosts()
+    {
+        delete [] linkCosts;
+    }
+
+    void
+    LinkStateRoutingTableCalculator::calculatePath(Map& pMap,
+            RoutingTable& rt, Nlsr& pnlsr)
+    {
+        cout<<"LinkStateRoutingTableCalculator::calculatePath Called"<<endl;
+        allocateAdjMatrix();
+        initMatrix();
+        makeAdjMatrix(pnlsr,pMap);
+        cout<<pMap;
+        printAdjMatrix();
+        string routerName=pnlsr.getConfParameter().getRouterPrefix();
+        int sourceRouter=pMap.getMappingNoByRouterName(routerName);
+        int noLink=getNumOfLinkfromAdjMatrix(sourceRouter);
+        allocateParent();
+        allocateDistance();
+        if ( pnlsr.getConfParameter().getMaxFacesPerPrefix() == 1 )
+        {
+            // Single Path
+            doDijkstraPathCalculation(sourceRouter);
+            // print all ls path -- debugging purpose
+            printAllLsPath(sourceRouter);
+            // update routing table
+            addAllLsNextHopsToRoutingTable(pnlsr, rt, pMap, sourceRouter);
+        }
+        else
+        {
+            // Multi Path
+            setNoLink(getNumOfLinkfromAdjMatrix(sourceRouter));
+            allocateLinks();
+            allocateLinkCosts();
+            getLinksFromAdjMatrix(links, linkCosts, sourceRouter);
+            for (int i=0 ; i < vNoLink; i++)
+            {
+                adjustAdMatrix(sourceRouter,links[i], linkCosts[i]);
+                printAdjMatrix();
+                doDijkstraPathCalculation(sourceRouter);
+                // print all ls path -- debugging purpose
+                printAllLsPath(sourceRouter);
+                //update routing table
+                addAllLsNextHopsToRoutingTable(pnlsr, rt, pMap, sourceRouter);
+            }
+            freeLinks();
+            freeLinksCosts();
+        }
+        freeParent();
+        freeDistance();
+        freeAdjMatrix();
+    }
+
+    void
+    LinkStateRoutingTableCalculator::doDijkstraPathCalculation(int sourceRouter)
+    {
+        int i;
+        int v,u;
+        int *Q=new int[numOfRouter];
+        int head=0;
+        /* Initiate the Parent */
+        for (i = 0 ; i < numOfRouter; i++)
+        {
+            parent[i]=EMPTY_PARENT;
+            distance[i]=INF_DISTANCE;
+            Q[i]=i;
+        }
+        if ( sourceRouter != NO_MAPPING_NUM )
+        {
+            distance[sourceRouter]=0;
+            sortQueueByDistance(Q,distance,head,numOfRouter);
+            while (head < numOfRouter )
+            {
+                u=Q[head];
+                if(distance[u] == INF_DISTANCE)
+                {
+                    break;
+                }
+                for(v=0 ; v <numOfRouter; v++)
+                {
+                    if( adjMatrix[u][v] > 0 )
+                    {
+                        if ( isNotExplored(Q,v,head+1,numOfRouter) )
+                        {
+                            if( distance[u] + adjMatrix[u][v] <  distance[v])
+                            {
+                                distance[v]=distance[u] + adjMatrix[u][v] ;
+                                parent[v]=u;
+                            }
+                        }
+                    }
+                }
+                head++;
+                sortQueueByDistance(Q,distance,head,numOfRouter);
+            }
+        }
+        delete [] Q;
+    }
+
+    void
+    LinkStateRoutingTableCalculator::addAllLsNextHopsToRoutingTable(Nlsr& pnlsr,
+            RoutingTable& rt, Map& pMap, int sourceRouter)
+    {
+        cout<<"LinkStateRoutingTableCalculator::addAllNextHopsToRoutingTable Called";
+        cout<<endl;
+        for(int i=0; i < numOfRouter ; i++)
+        {
+            if ( i!= sourceRouter )
+            {
+                int nextHopRouter=getLsNextHop(i,sourceRouter);
+                double routeCost=distance[i];
+                string nextHopRouterName=pMap.getRouterNameByMappingNo(nextHopRouter);
+                int nxtHopFace=
+                    pnlsr.getAdl().getAdjacent(nextHopRouterName).getConnectingFace();
+                cout<<"Dest Router: "<<pMap.getRouterNameByMappingNo(i)<<endl;
+                cout<<"Next hop Router: "<<nextHopRouterName<<endl;
+                cout<<"Next hop Face: "<<nxtHopFace<<endl;
+                cout<<"Route Cost: "<<routeCost<<endl;
+                cout<<endl;
+                // Add next hop to routing table
+                NextHop nh(nxtHopFace,routeCost);
+                rt.addNextHop(pMap.getRouterNameByMappingNo(i),nh);
+            }
+        }
+    }
+
+    int
+    LinkStateRoutingTableCalculator::getLsNextHop(int dest, int source)
+    {
+        int nextHop;
+        while ( parent[dest] != EMPTY_PARENT )
+        {
+            nextHop=dest;
+            dest=parent[dest];
+        }
+        if ( dest != source )
+        {
+            nextHop=NO_NEXT_HOP;
+        }
+        return nextHop;
+    }
+
+    void
+    LinkStateRoutingTableCalculator::printAllLsPath(int sourceRouter)
+    {
+        cout<<"LinkStateRoutingTableCalculator::printAllLsPath Called"<<endl;
+        cout<<"Source Router: "<<sourceRouter<<endl;
+        for(int i=0; i < numOfRouter ; i++)
+        {
+            if ( i!= sourceRouter )
+            {
+                printLsPath(i);
+                cout<<endl;
+            }
+        }
+    }
+
+    void
+    LinkStateRoutingTableCalculator::printLsPath(int destRouter)
+    {
+        if (parent[destRouter] != EMPTY_PARENT )
+        {
+            printLsPath(parent[destRouter]);
+        }
+        cout<<" "<<destRouter;
+    }
+
+    void
+    LinkStateRoutingTableCalculator::sortQueueByDistance(int *Q,
+            double *dist,int start,int element)
+    {
+        for ( int i=start ; i < element ; i ++)
+        {
+            for( int j=i+1; j<element; j ++)
+            {
+                if (dist[Q[j]] < dist[Q[i]])
+                {
+                    int tempU=Q[j];
+                    Q[j]=Q[i];
+                    Q[i]=tempU;
+                }
+            }
+        }
+    }
+
+    int
+    LinkStateRoutingTableCalculator::isNotExplored(int *Q,
+            int u,int start, int element)
+    {
+        int ret=0;
+        for(int i=start; i< element; i++)
+        {
+            if ( Q[i] == u )
+            {
+                ret=1;
+                break;
+            }
+        }
+        return ret;
+    }
+
+    void
+    LinkStateRoutingTableCalculator::allocateParent()
+    {
+        parent=new int[numOfRouter];
+    }
+
+    void
+    LinkStateRoutingTableCalculator::allocateDistance()
+    {
+        distance= new double[numOfRouter];
+    }
+
+    void
+    LinkStateRoutingTableCalculator::freeParent()
+    {
+        delete [] parent;
+    }
+
+    void LinkStateRoutingTableCalculator::freeDistance()
+    {
+        delete [] distance;
+    }
+
+
+
+    void
+    HypRoutingTableCalculator::calculatePath(Map& pMap,
+            RoutingTable& rt, Nlsr& pnlsr)
+    {
+        makeAdjMatrix(pnlsr,pMap);
+        string routerName=pnlsr.getConfParameter().getRouterPrefix();
+        int sourceRouter=pMap.getMappingNoByRouterName(routerName);
+        int noLink=getNumOfLinkfromAdjMatrix(sourceRouter);
+        setNoLink(noLink);
+        allocateLinks();
+        allocateLinkCosts();
+        getLinksFromAdjMatrix(links, linkCosts, sourceRouter);
+        for(int i=0 ; i < numOfRouter ; ++i)
+        {
+            int k=0;
+            if ( i != sourceRouter)
+            {
+                allocateLinkFaces();
+                allocateDistanceToNeighbor();
+                allocateDistFromNbrToDest();
+                for(int j=0; j<vNoLink; j++)
+                {
+                    string nextHopRouterName=pMap.getRouterNameByMappingNo(links[j]);
+                    int nextHopFace=
+                        pnlsr.getAdl().getAdjacent(nextHopRouterName).getConnectingFace();
+                    double distToNbr=getHyperbolicDistance(pnlsr,pMap,
+                                                           sourceRouter,links[j]);
+                    double distToDestFromNbr=getHyperbolicDistance(pnlsr,
+                                             pMap,links[j],i);
+                    if ( distToDestFromNbr >= 0 )
+                    {
+                        linkFaces[k] = nextHopFace;
+                        distanceToNeighbor[k] = distToNbr;
+                        distFromNbrToDest[k] = distToDestFromNbr;
+                        k++;
+                    }
+                }
+                addHypNextHopsToRoutingTable(pnlsr,pMap,rt,k,i);
+                freeLinkFaces();
+                freeDistanceToNeighbor();
+                freeDistFromNbrToDest();
+            }
+        }
+        freeLinks();
+        freeLinksCosts();
+        freeAdjMatrix();
+    }
+
+    void
+    HypRoutingTableCalculator::addHypNextHopsToRoutingTable(Nlsr& pnlsr,Map& pMap,
+            RoutingTable& rt, int noFaces, int dest)
+    {
+        for(int i=0 ; i < noFaces ; ++i)
+        {
+            string destRouter=pMap.getRouterNameByMappingNo(dest);
+            NextHop nh(linkFaces[i],distFromNbrToDest[i]);
+            rt.addNextHop(destRouter,nh);
+            if( isDryRun == 1 )
+            {
+                rt.addNextHopToDryTable(destRouter,nh);
+            }
+        }
+    }
+
+    double
+    HypRoutingTableCalculator::getHyperbolicDistance(Nlsr& pnlsr,
+            Map& pMap, int src, int dest)
+    {
+        double distance=0.0;
+        string srcRouterKey=pMap.getRouterNameByMappingNo(src)+"/3";
+        string destRouterKey=pMap.getRouterNameByMappingNo(dest)+"/3";
+        double srcRadius=(pnlsr.getLsdb().getCorLsa(srcRouterKey).first).getCorRadius();
+        double srcTheta=(pnlsr.getLsdb().getCorLsa(srcRouterKey).first).getCorTheta();
+        double destRadius=(pnlsr.getLsdb().getCorLsa(
+                               destRouterKey).first).getCorRadius();
+        double destTheta=(pnlsr.getLsdb().getCorLsa(destRouterKey).first).getCorTheta();
+        double diffTheta = fabs (srcTheta - destTheta);
+        if (diffTheta > MATH_PI)
+        {
+            diffTheta = 2 * MATH_PI - diffTheta;
+        }
+        if ( srcRadius != -1 && destRadius != -1 )
+        {
+            if (diffTheta == 0)
+                distance = fabs (srcRadius - destRadius);
+            else
+                distance = acosh((cosh(srcRadius)*cosh(destRadius))-
+                                 (sinh(srcRadius)*sinh(destRadius)*cos(diffTheta)));
+        }
+        else
+        {
+            distance = -1;
+        }
+        return distance;
+    }
+
+    void
+    HypRoutingTableCalculator::allocateLinkFaces()
+    {
+        linkFaces=new int[vNoLink];
+    }
+
+    void
+    HypRoutingTableCalculator::allocateDistanceToNeighbor()
+    {
+        distanceToNeighbor=new double[vNoLink];
+    }
+
+    void
+    HypRoutingTableCalculator::allocateDistFromNbrToDest()
+    {
+        distFromNbrToDest=new double[vNoLink];
+    }
+
+    void
+    HypRoutingTableCalculator::freeLinkFaces()
+    {
+        delete [] linkFaces;
+    }
+
+    void
+    HypRoutingTableCalculator::freeDistanceToNeighbor()
+    {
+        delete [] distanceToNeighbor;
+    }
+
+    void
+    HypRoutingTableCalculator::freeDistFromNbrToDest()
+    {
+        delete [] distFromNbrToDest;
+    }
+
+}//namespace nlsr
diff --git a/src/route/nlsr_rtc.hpp b/src/route/nlsr_rtc.hpp
new file mode 100644
index 0000000..987686e
--- /dev/null
+++ b/src/route/nlsr_rtc.hpp
@@ -0,0 +1,145 @@
+#ifndef NLSR_RTC_HPP
+#define NLSR_RTC_HPP
+
+#include <list>
+#include <iostream>
+
+namespace nlsr
+{
+
+    class Map;
+    class RoutingTable;
+    class Nlsr;
+
+
+    using namespace std;
+
+    class RoutingTableCalculator
+    {
+    public:
+        RoutingTableCalculator()
+        {
+        }
+        RoutingTableCalculator(int rn)
+        {
+            numOfRouter=rn;
+        }
+    protected:
+        void allocateAdjMatrix();
+        void initMatrix();
+        void makeAdjMatrix(Nlsr& pnlsr,Map pMap);
+        void printAdjMatrix();
+        int getNumOfLinkfromAdjMatrix(int sRouter);
+        void freeAdjMatrix();
+        void adjustAdMatrix(int source, int link, double linkCost);
+        void getLinksFromAdjMatrix(int *links, double *linkCosts, int source);
+
+        void allocateLinks();
+        void allocateLinkCosts();
+        void freeLinks();
+        void freeLinksCosts();
+
+        void setNoLink(int nl)
+        {
+            vNoLink=nl;
+        }
+
+    protected:
+        double ** adjMatrix;
+        int numOfRouter;
+
+        int vNoLink;
+        int *links;
+        double *linkCosts;
+    };
+
+    class LinkStateRoutingTableCalculator: public RoutingTableCalculator
+    {
+    public:
+        LinkStateRoutingTableCalculator(int rn)
+            : EMPTY_PARENT(-12345)
+            , INF_DISTANCE(2147483647)
+            , NO_MAPPING_NUM(-1)
+            , NO_NEXT_HOP(-12345)
+        {
+            numOfRouter=rn;
+        }
+
+
+        void calculatePath(Map& pMap, RoutingTable& rt, Nlsr& pnlsr);
+
+
+    private:
+        void doDijkstraPathCalculation(int sourceRouter);
+        void sortQueueByDistance(int *Q, double *dist,int start,int element);
+        int isNotExplored(int *Q, int u,int start, int element);
+        void printAllLsPath(int sourceRouter);
+        void printLsPath(int destRouter);
+        void addAllLsNextHopsToRoutingTable(Nlsr& pnlsr, RoutingTable& rt,
+                                            Map& pMap,int sourceRouter);
+        int getLsNextHop(int dest, int source);
+
+        void allocateParent();
+        void allocateDistance();
+        void freeParent();
+        void freeDistance();
+
+
+
+
+    private:
+        int *parent;
+        double *distance;
+
+
+        const int EMPTY_PARENT;
+        const double INF_DISTANCE;
+        const int NO_MAPPING_NUM;
+        const int NO_NEXT_HOP;
+
+    };
+
+    class HypRoutingTableCalculator: public RoutingTableCalculator
+    {
+    public:
+        HypRoutingTableCalculator(int rn)
+            :  MATH_PI(3.141592654)
+        {
+            numOfRouter=rn;
+            isDryRun=0;
+        }
+        HypRoutingTableCalculator(int rn, int idr)
+            :  MATH_PI(3.141592654)
+        {
+            numOfRouter=rn;
+            isDryRun=idr;
+        }
+
+        void calculatePath(Map& pMap, RoutingTable& rt, Nlsr& pnlsr);
+
+    private:
+        void allocateLinkFaces();
+        void allocateDistanceToNeighbor();
+        void allocateDistFromNbrToDest();
+        void freeLinkFaces();
+        void freeDistanceToNeighbor();
+        void freeDistFromNbrToDest();
+
+        double getHyperbolicDistance(Nlsr& pnlsr,Map& pMap, int src, int dest);
+        void addHypNextHopsToRoutingTable(Nlsr& pnlsr,Map& pMap,
+                                          RoutingTable& rt, int noFaces,int dest);
+
+    private:
+        int isDryRun;
+
+        int *linkFaces;
+        double *distanceToNeighbor;
+        double *distFromNbrToDest;
+
+        const double MATH_PI;
+
+    };
+
+}//namespace nlsr
+
+#endif
diff --git a/src/route/nlsr_rte.cpp b/src/route/nlsr_rte.cpp
new file mode 100644
index 0000000..f96da11
--- /dev/null
+++ b/src/route/nlsr_rte.cpp
@@ -0,0 +1,26 @@
+#include <iostream>
+#include <string>
+
+#include "nlsr_rte.hpp"
+
+namespace nlsr
+{
+
+    using namespace std;
+
+    ostream&
+    operator<<(ostream& os, RoutingTableEntry &rte)
+    {
+        os<<"Destination: "<<rte.getDestination()<<endl;
+        os<<"Nexthops: "<<endl;
+        int i=1;
+        std::list< NextHop > nhl = rte.getNhl().getNextHopList();
+        for( std::list<NextHop>::iterator it=nhl.begin();
+                it!= nhl.end() ; it++,i++)
+        {
+            os <<"  Nexthop "<<i<<": "<<(*it)<<endl;
+        }
+        return os;
+    }
+
+}//namespace nlsr
diff --git a/src/route/nlsr_rte.hpp b/src/route/nlsr_rte.hpp
new file mode 100644
index 0000000..27d3601
--- /dev/null
+++ b/src/route/nlsr_rte.hpp
@@ -0,0 +1,52 @@
+#ifndef NLSR_RTE_HPP
+#define NLSR_RTE_HPP
+
+#include<iostream>
+
+#include "nlsr_nhl.hpp"
+
+namespace nlsr
+{
+
+    using namespace std;
+
+    class RoutingTableEntry
+    {
+    public:
+        RoutingTableEntry()
+            : destination()
+            , nhl()
+        {
+        }
+
+        ~RoutingTableEntry()
+        {
+        }
+
+        RoutingTableEntry(string dest)
+            : nhl()
+        {
+            destination=dest;
+        }
+
+        string getDestination()
+        {
+            return destination;
+        }
+
+        Nhl& getNhl()
+        {
+            return nhl;
+        }
+
+    private:
+        string destination;
+        Nhl nhl;
+    };
+
+    ostream&
+    operator<<(ostream& os, RoutingTableEntry &rte);
+
+}
+
+#endif
diff --git a/src/security/nlsr_cert_store.hpp b/src/security/nlsr_cert_store.hpp
new file mode 100644
index 0000000..5bbef9e
--- /dev/null
+++ b/src/security/nlsr_cert_store.hpp
@@ -0,0 +1,6 @@
+#ifndef NLSR_CERT_STORE_HPP
+#define NLSR_CERT_STORE_HPP
+
+
+
+#endif
diff --git a/src/security/nlsr_km.cpp b/src/security/nlsr_km.cpp
new file mode 100644
index 0000000..69052eb
--- /dev/null
+++ b/src/security/nlsr_km.cpp
@@ -0,0 +1,84 @@
+#include <ndn-cpp-dev/security/identity-certificate.hpp>
+#include <ndn-cpp-dev/encoding/block.hpp>
+#include "nlsr_sm.hpp"
+#include "nlsr_km.hpp"
+
+namespace nlsr
+{
+    void
+    KeyManager::initKeyManager(ConfParameter &cp)
+    {
+        string processIdentityName(cp.getRootKeyPrefix());
+        processIdentityName += "/";
+        processIdentityName += cp.getSiteName();
+        processIdentityName += "/";
+        processIdentityName += "R.Start";
+        processIdentityName += "/";
+        processIdentityName += cp.getRouterName();
+        processIdentityName += "/";
+        processIdentityName += "nlsr";
+        cout<<"Proces Identity Name: "<<processIdentityName<<endl;
+        ndn::Name identityName(processIdentityName);
+        routerIdentity=identityName;
+        ndn::KeyChain::deleteIdentity(routerIdentity);
+        routerCertName = ndn::KeyChain::createIdentity(routerIdentity);
+        cout<<"Certificate Name: "<<routerCertName.toUri()<<endl;
+        routerKeyName=
+            ndn::IdentityCertificate::certificateNameToPublicKeyName(routerCertName);
+        cout<<"Key Name: "<<routerKeyName.toUri()<<endl;
+        initCertSeqFromFile(cp.getSeqFileDir());
+    }
+
+    ndn::Name
+    KeyManager::getRouterCertName()
+    {
+        return routerCertName;
+    }
+
+    uint32_t
+    KeyManager::getCertSeqNo()
+    {
+        return certSeqNo;
+    }
+
+    void
+    KeyManager::setCerSeqNo(uint32_t csn)
+    {
+        certSeqNo=csn;
+    }
+
+    void
+    KeyManager::initCertSeqFromFile(string certSeqFileDir)
+    {
+        certSeqFileNameWithPath=certSeqFileDir;
+        if( certSeqFileNameWithPath.empty() )
+        {
+            SequencingManager sm;
+            certSeqFileNameWithPath=sm.getUserHomeDirectory();
+        }
+        certSeqFileNameWithPath += "/nlsrCertSeqNo.txt";
+        cout<<"Key Seq File Name: "<< certSeqFileNameWithPath<<endl;
+        std::ifstream inputFile(certSeqFileNameWithPath.c_str(),ios::binary);
+        if ( inputFile.good() )
+        {
+            inputFile>>certSeqNo;
+            certSeqNo++;
+        }
+        else
+        {
+            certSeqNo=1;
+        }
+        writeCertSeqToFile();
+    }
+
+    void
+    KeyManager::writeCertSeqToFile()
+    {
+        std::ofstream outputFile(certSeqFileNameWithPath.c_str(),ios::binary);
+        outputFile<<certSeqNo;
+        outputFile.close();
+    }
+}
+
+
+
diff --git a/src/security/nlsr_km.hpp b/src/security/nlsr_km.hpp
new file mode 100644
index 0000000..7b3b7ba
--- /dev/null
+++ b/src/security/nlsr_km.hpp
@@ -0,0 +1,158 @@
+#ifndef NLSR_KM_HPP
+#define NLSR_KM_HPP
+
+#include <ndn-cpp-dev/face.hpp>
+#include <ndn-cpp-dev/data.hpp>
+#include <ndn-cpp-dev/security/key-chain.hpp>
+#include <ndn-cpp-dev/security/validator.hpp>
+#include <ndn-cpp-dev/util/scheduler.hpp>
+#include <ndn-cpp-dev/util/random.hpp>
+#include <ndn-cpp-dev/security/identity-certificate.hpp>
+#include <ndn-cpp-dev/security/signature-sha256-with-rsa.hpp>
+
+#include <ndn-cpp-dev/security/sec-public-info-sqlite3.hpp>
+#include <ndn-cpp-dev/security/sec-public-info-memory.hpp>
+//TPM
+#include <ndn-cpp-dev/security/sec-tpm-file.hpp>
+#include <ndn-cpp-dev/security/sec-tpm-memory.hpp>
+
+#ifdef NDN_CPP_HAVE_OSX_SECURITY
+#include <ndn-cpp-dev/security/sec-tpm-osx.hpp>
+#endif
+
+#include <list>
+#include "nlsr_conf_param.hpp"
+
+namespace nlsr
+{
+    enum nlsrKeyType
+    {
+        KEY_TYPE_ROOT,
+        KEY_TYPE_SITE,
+        KEY_TYPE_OPERATOR,
+        KEY_TYPE_ROUTER,
+        KEY_TYPE_PROCESS
+    };
+
+    class KeyManager: public ndn::KeyChain, public ndn::Validator
+    {
+        typedef SecPublicInfo::Error InfoError;
+        typedef SecTpm::Error TpmError;
+    public:
+        KeyManager()
+            : certSeqNo(1)
+        {
+        }
+
+        void initKeyManager(ConfParameter &cp);
+
+        void
+        checkPolicy (const ndn::Data& data,
+                     int stepCount,
+                     const ndn::OnDataValidated &onValidated,
+                     const ndn::OnDataValidationFailed &onValidationFailed,
+                     std::vector<ndn::shared_ptr<ndn::ValidationRequest> > &nextSteps)
+        {}
+
+        void
+        checkPolicy (const ndn::Interest& interest,
+                     int stepCount,
+                     const ndn::OnInterestValidated &onValidated,
+                     const ndn::OnInterestValidationFailed &onValidationFailed,
+                     std::vector<ndn::shared_ptr<ndn::ValidationRequest> > &nextSteps)
+        {}
+
+        void signData(ndn::Data& data)
+        {
+            ndn::KeyChain::signByIdentity(data,routerIdentity);
+            //ndn::SignatureSha256WithRsa signature(data.getSignature());
+            //signature.setKeyLocator(routerCertName);
+        }
+        
+        ndn::shared_ptr<ndn::IdentityCertificate>
+        getCertificate(ndn::Name certificateName)
+        {
+            return ndn::KeyChain::getCertificate(routerCertName);
+        }
+
+        ndn::Name
+        createIdentity(const ndn::Name identityName, const ndn::Name signee)
+        {
+            ndn::KeyChain::addIdentity(identityName);
+            ndn::Name keyName;
+            try
+            {
+                keyName = ndn::KeyChain::getDefaultKeyNameForIdentity(identityName);
+            }
+            catch(InfoError& e)
+            {
+                keyName = ndn::KeyChain::generateRSAKeyPairAsDefault(identityName, true);
+            }
+            ndn::shared_ptr<ndn::PublicKey> pubKey;
+            try
+            {
+                pubKey = ndn::KeyChain::getPublicKey(keyName);
+            }
+            catch(InfoError& e)
+            {
+                //return ndn::shared_ptr<ndn::IdentityCertificate>()->getName();
+                return identityName;
+            }
+            ndn::Name certName;
+            try
+            {
+                certName = ndn::KeyChain::getDefaultCertificateNameForKey(keyName);
+            }
+            catch(InfoError& e)
+            {
+                ndn::shared_ptr<ndn::IdentityCertificate> certificate =
+                    ndn::make_shared<ndn::IdentityCertificate>();
+                ndn::Name certificateName = keyName.getPrefix(-1);
+                certificateName.append("KEY").append(
+                    keyName.get(-1)).append("ID-CERT").appendVersion();
+                certificate->setName(certificateName);
+                certificate->setNotBefore(ndn::getNow());
+                certificate->setNotAfter(ndn::getNow() + 31536000 /* 1 year*/);
+                certificate->setPublicKeyInfo(*pubKey);
+                certificate->addSubjectDescription(
+                    ndn::CertificateSubjectDescription("2.5.4.41",
+                                                       keyName.toUri()));
+                certificate->encode();
+                try
+                {
+                    ndn::KeyChain::signByIdentity(*certificate,signee);
+                }
+                catch(InfoError& e)
+                {
+                    try
+                    {
+                        ndn::KeyChain::deleteIdentity(identityName);
+                    }
+                    catch(InfoError& e)
+                    {
+                    }
+                    return identityName;
+                }
+                certName=certificate->getName();
+            }
+            return certName;
+        }
+
+        ndn::Name getRouterCertName();
+
+        uint32_t getCertSeqNo();
+        void setCerSeqNo(uint32_t csn);
+        void initCertSeqFromFile(string certSeqFileDir);
+        void writeCertSeqToFile();
+
+    private:
+        ndn::Name routerIdentity;
+        ndn::Name routerCertName;
+        ndn::Name routerKeyName;
+        uint32_t certSeqNo;
+        string certSeqFileNameWithPath;
+
+    };
+}
+
+#endif
diff --git a/src/utility/nlsr_logger.cpp b/src/utility/nlsr_logger.cpp
new file mode 100644
index 0000000..804ef98
--- /dev/null
+++ b/src/utility/nlsr_logger.cpp
@@ -0,0 +1,59 @@
+#include "nlsr_logger.hpp"
+
+namespace nlsr
+{
+
+    string
+    NlsrLogger::getEpochTime()
+    {
+        std::stringstream ss;
+        boost::posix_time::ptime time_t_epoch(boost::gregorian::date(1970,1,1));
+        boost::posix_time::ptime now = boost::posix_time::microsec_clock::local_time();
+        boost::posix_time::time_duration diff = now - time_t_epoch;
+        ss<<diff.total_seconds()<<"."<<boost::format("%06i")%(diff.total_microseconds()
+                %1000000);
+        return ss.str();
+    }
+
+    string
+    NlsrLogger::getUserHomeDirectory()
+    {
+        string homeDirPath(getpwuid(getuid())->pw_dir);
+        if( homeDirPath.empty() )
+        {
+            homeDirPath = getenv("HOME");
+        }
+        return homeDirPath;
+    }
+
+    void
+    NlsrLogger::initNlsrLogger(std::string dirPath)
+    {
+        string logDirPath(dirPath);
+        if( dirPath.empty() )
+        {
+            logDirPath=getUserHomeDirectory()+"/nlsrLog";
+        }
+        cout<<"Log Dir Path: "<< logDirPath<<endl;
+        typedef sinks::synchronous_sink< sinks::text_file_backend > file_sink;
+        shared_ptr< file_sink > sink(new file_sink(
+                                         keywords::file_name = logDirPath
+                                                 +"/NLSR%Y%m%d%H%M%S_%3N.log",
+                                         keywords::rotation_size = 128 * 1024 * 1024,
+                                         keywords::time_based_rotation = sinks::file::rotation_at_time_point(12, 0, 0),
+                                         keywords::auto_flush = true
+                                     ));
+        sink->locked_backend()->set_file_collector(sinks::file::make_collector(
+                    keywords::target = logDirPath,
+                    keywords::max_size = 16 * 1024 * 1024 * 1024,
+                    keywords::min_free_space = 128 * 1024 * 1024
+                ));
+        sink->set_formatter(
+            expr::format("%1%: %2%")
+            % getEpochTime()
+            % expr::smessage
+        );
+        logging::core::get()->add_sink(sink);
+    }
+
+}//namespace nlsr
diff --git a/src/utility/nlsr_logger.hpp b/src/utility/nlsr_logger.hpp
new file mode 100644
index 0000000..222ac52
--- /dev/null
+++ b/src/utility/nlsr_logger.hpp
@@ -0,0 +1,62 @@
+#ifndef NLSR_LOGGER_HPP
+#define NLSR_LOGGER_HPP
+
+#define BOOST_LOG_DYN_LINK 1
+
+#include <stdexcept>
+#include <string>
+#include <iostream>
+#include <sstream>
+#include <pwd.h>
+#include <cstdlib>
+#include <string>
+#include <unistd.h>
+#include <boost/format.hpp>
+#include <boost/smart_ptr/shared_ptr.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/date_time/local_time/local_time.hpp>
+#include <boost/log/common.hpp>
+#include <boost/log/expressions.hpp>
+#include <boost/log/attributes.hpp>
+#include <boost/log/sources/logger.hpp>
+#include <boost/log/sinks/sync_frontend.hpp>
+#include <boost/log/sinks/text_file_backend.hpp>
+
+namespace nlsr
+{
+
+    namespace logging = boost::log;
+    namespace attrs = boost::log::attributes;
+    namespace src = boost::log::sources;
+    namespace sinks = boost::log::sinks;
+    namespace expr = boost::log::expressions;
+    namespace keywords = boost::log::keywords;
+
+    using boost::shared_ptr;
+    using namespace std;
+
+
+    class NlsrLogger
+    {
+    public:
+        NlsrLogger()
+        {
+        }
+
+        void initNlsrLogger(std::string dirPath);
+
+        src::logger& getLogger()
+        {
+            return mLogger;
+        }
+
+    private:
+        string getEpochTime();
+        string getUserHomeDirectory();
+
+    private:
+        src::logger mLogger;
+    };
+
+}//namespace nlsr
+#endif
diff --git a/src/utility/nlsr_tokenizer.cpp b/src/utility/nlsr_tokenizer.cpp
new file mode 100644
index 0000000..809e395
--- /dev/null
+++ b/src/utility/nlsr_tokenizer.cpp
@@ -0,0 +1,110 @@
+#include <iostream>
+#include <boost/tokenizer.hpp>
+#include <boost/algorithm/string.hpp>
+#include <string>
+#include <algorithm>
+
+#include "nlsr_tokenizer.hpp"
+
+namespace nlsr
+{
+
+    using namespace std;
+    using namespace boost;
+
+    void
+    nlsrTokenizer::makeToken()
+    {
+        char_separator<char> sep(seps.c_str());
+        tokenizer< char_separator<char> >tokens(originalString, sep);
+        tokenizer< char_separator<char> >::iterator tok_iter = tokens.begin();
+        for ( ; tok_iter != tokens.end(); ++tok_iter)
+        {
+            string oneToken(*tok_iter);
+            trim(oneToken);
+            if(!oneToken.empty())
+            {
+                insertToken(oneToken);
+            }
+        }
+        firstToken=vTokenList[0];
+        makeRestOfTheLine();
+    }
+
+    void
+    nlsrTokenizer::insertToken(const string& token)
+    {
+        tokenList.push_back(token);
+        vTokenList.push_back(token);
+    }
+
+    int
+    nlsrTokenizer::getTokenPosition(string& token)
+    {
+        int pos=-1;
+        int i=0;
+        for(std::list<string>::iterator it=tokenList.begin();
+                it!=tokenList.end(); it++)
+        {
+            if( (*it) == token )
+            {
+                break;
+            }
+            i++;
+        }
+        if( i < tokenList.size() )
+        {
+            pos=i;
+        }
+        return pos;
+    }
+
+    string
+    nlsrTokenizer::getTokenString(int from , int to)
+    {
+        string returnString="";
+        if((from>=0 && to<tokenList.size()) &&
+                (to>=from && to <tokenList.size()))
+        {
+            for(int i=from; i<=to; i++)
+            {
+                returnString+=seps;
+                returnString+=vTokenList[i];
+            }
+        }
+        trim(returnString);
+        return returnString;
+    }
+
+    string
+    nlsrTokenizer::getTokenString(int from)
+    {
+        return getTokenString(from,tokenList.size()-1);
+    }
+
+    static bool
+    tokenCompare(string& s1, string& s2)
+    {
+        return s1==s2;
+    }
+
+    void
+    nlsrTokenizer::makeRestOfTheLine()
+    {
+        restOfTheLine=getTokenString(1);
+    }
+
+    bool
+    nlsrTokenizer::doesTokenExist(string token)
+    {
+        std::list<string >::iterator it = std::find_if( tokenList.begin(),
+                                          tokenList.end(),
+                                          bind(&tokenCompare, _1 , token));
+        if( it != tokenList.end() )
+        {
+            return true;
+        }
+        return false;
+    }
+
+}//namespace nlsr
diff --git a/src/utility/nlsr_tokenizer.hpp b/src/utility/nlsr_tokenizer.hpp
new file mode 100644
index 0000000..6cd97e0
--- /dev/null
+++ b/src/utility/nlsr_tokenizer.hpp
@@ -0,0 +1,104 @@
+#ifndef NLSR_TOKENIZER_HPP
+#define NLSR_TOKENIZER_HPP
+
+#include <iostream>
+#include <boost/tokenizer.hpp>
+#include <boost/algorithm/string.hpp>
+#include <string>
+#include <list>
+#include <vector>
+#include <ndn-cpp-dev/face.hpp>
+
+namespace nlsr
+{
+
+    using namespace std;
+    using namespace boost;
+
+    class nlsrTokenizer
+    {
+    public:
+        nlsrTokenizer(const string& inputString)
+            : firstToken()
+            , restOfTheLine()
+            , currentPosition(0)
+        {
+            seps = " ";
+            originalString = inputString;
+            makeToken();
+        }
+
+        nlsrTokenizer(const string& inputString, const string& separator)
+            : firstToken()
+            , restOfTheLine()
+            , currentPosition(0)
+        {
+            seps = separator;
+            originalString = inputString;
+            makeToken();
+        }
+
+        string getFirstToken()
+        {
+            return firstToken;
+        }
+
+        string getRestOfLine()
+        {
+            return restOfTheLine;
+        }
+
+        void resetCurrentPosition(uint32_t cp=0)
+        {
+            if( cp >=0 && cp <= vTokenList.size() )
+            {
+                currentPosition=cp;
+            }
+        }
+
+        string getNextToken()
+        {
+            if(currentPosition >= 0 && currentPosition <= (vTokenList.size()-1))
+            {
+                return vTokenList[currentPosition++];
+            }
+            return "";
+        }
+
+        uint32_t getTokenNumber()
+        {
+            return tokenList.size();
+        }
+
+        string getToken(int position)
+        {
+            if( position >=0 && position <vTokenList.size() )
+            {
+                return vTokenList[position];
+            }
+            return "";
+        }
+
+        int getTokenPosition(string& token);
+        string getTokenString(int from , int to);
+        string getTokenString(int from);
+        bool doesTokenExist(string token);
+
+
+    private:
+
+        void makeToken();
+        void insertToken(const string& token);
+        void makeRestOfTheLine();
+
+        string seps;
+        string originalString;
+        string firstToken;
+        string restOfTheLine;
+        std::list<string> tokenList;
+        std::vector<string> vTokenList;
+        uint32_t currentPosition;
+    };
+
+}//namespace nlsr
+#endif
diff --git a/waf-tools/boost.pyc b/waf-tools/boost.pyc
new file mode 100644
index 0000000..22854fd
--- /dev/null
+++ b/waf-tools/boost.pyc
Binary files differ
diff --git a/waf-tools/cryptopp.py b/waf-tools/cryptopp.py
new file mode 100644
index 0000000..a05326b
--- /dev/null
+++ b/waf-tools/cryptopp.py
@@ -0,0 +1,77 @@
+#! /usr/bin/env python
+# encoding: utf-8
+
+'''
+
+When using this tool, the wscript will look like:
+
+	def options(opt):
+	        opt.tool_options('cryptopp', tooldir=["waf-tools"])
+
+	def configure(conf):
+		conf.load('compiler_cxx cryptopp')
+
+	def build(bld):
+		bld(source='main.cpp', target='app', use='CRYPTOPP')
+
+Options are generated, in order to specify the location of cryptopp includes/libraries.
+
+
+'''
+import sys
+import re
+from waflib import Utils,Logs,Errors
+from waflib.Configure import conf
+CRYPTOPP_DIR=['/usr','/usr/local','/opt/local','/sw']
+CRYPTOPP_VERSION_FILE='config.h'
+CRYPTOPP_VERSION_CODE='''
+#include <iostream>
+#include <cryptopp/config.h>
+int main() { std::cout << CRYPTOPP_VERSION; }
+'''
+
+def options(opt):
+	opt.add_option('--cryptopp',type='string',default='',dest='cryptopp_dir',help='''path to where cryptopp is installed, e.g. /opt/local''')
+@conf
+def __cryptopp_get_version_file(self,dir):
+	try:
+		return self.root.find_dir(dir).find_node('%s/%s' % ('include/cryptopp', CRYPTOPP_VERSION_FILE))
+	except:
+		return None
+@conf
+def cryptopp_get_version(self,dir):
+	val=self.check_cxx(fragment=CRYPTOPP_VERSION_CODE,includes=['%s/%s' % (dir, 'include')], execute=True, define_ret = True, mandatory=True)
+	return val
+@conf
+def cryptopp_get_root(self,*k,**kw):
+	root=k and k[0]or kw.get('path',None)
+	# Logs.pprint ('RED', '   %s' %root)
+	if root and self.__cryptopp_get_version_file(root):
+		return root
+	for dir in CRYPTOPP_DIR:
+		if self.__cryptopp_get_version_file(dir):
+			return dir
+	if root:
+		self.fatal('CryptoPP not found in %s'%root)
+	else:
+		self.fatal('CryptoPP not found, please provide a --cryptopp argument (see help)')
+@conf
+def check_cryptopp(self,*k,**kw):
+	if not self.env['CXX']:
+		self.fatal('load a c++ compiler first, conf.load("compiler_cxx")')
+
+	var=kw.get('uselib_store','CRYPTOPP')
+	self.start_msg('Checking Crypto++ lib')
+	root = self.cryptopp_get_root(*k,**kw)
+	self.env.CRYPTOPP_VERSION=self.cryptopp_get_version(root)
+
+	self.env['INCLUDES_%s'%var]= '%s/%s' % (root, "include")
+	self.env['LIB_%s'%var] = "cryptopp"
+	self.env['LIBPATH_%s'%var] = '%s/%s' % (root, "lib")
+
+	self.end_msg(self.env.CRYPTOPP_VERSION)
+	if Logs.verbose:
+		Logs.pprint('CYAN','	CRYPTOPP include : %s'%self.env['INCLUDES_%s'%var])
+		Logs.pprint('CYAN','	CRYPTOPP lib     : %s'%self.env['LIB_%s'%var])
+		Logs.pprint('CYAN','	CRYPTOPP libpath : %s'%self.env['LIBPATH_%s'%var])
+
diff --git a/waf-tools/cryptopp.pyc b/waf-tools/cryptopp.pyc
new file mode 100644
index 0000000..60fed1e
--- /dev/null
+++ b/waf-tools/cryptopp.pyc
Binary files differ