diff --git a/slp_message_handler.cpp b/slp_message_handler.cpp
new file mode 100644
index 0000000..fd6670a
--- /dev/null
+++ b/slp_message_handler.cpp
@@ -0,0 +1,372 @@
+#include "slp.hpp"
+
+#include <arpa/inet.h>
+#include <ifaddrs.h>
+#include <net/if.h>
+#include <string.h>
+
+#include <algorithm>
+
+#include "endian.hpp"
+#include "slp_meta.hpp"
+
+namespace slp
+{
+namespace handler
+{
+
+namespace internal
+{
+
+buffer prepareHeader(const Message& req)
+{
+    uint8_t length =  slp::header::MIN_LEN +   /* 14 bytes for header     */
+                      req.header.langtag.length() + /* Actual length of lang tag */
+                      slp::response::SIZE_ERROR; /*  2 bytes for error code */
+
+    buffer buff(length, 0);
+
+    buff[slp::header::OFFSET_VERSION] = req.header.version;
+
+    //will increment the function id from 1 as reply
+    buff[slp::header::OFFSET_FUNCTION] = req.header.functionID + 1;
+
+    std::copy_n(&length, slp::header::SIZE_LENGTH,
+                buff.data() +
+                slp::header::OFFSET_LENGTH);
+
+    auto flags = endian::to_network(req.header.flags);
+
+    std::copy_n((uint8_t*)&flags, slp::header::SIZE_FLAGS,
+                buff.data() +
+                slp::header::OFFSET_FLAGS);
+
+    std::copy_n(req.header.extOffset.data(), slp::header::SIZE_EXT,
+                buff.data() +
+                slp::header::OFFSET_EXT);
+
+    auto xid = endian::to_network(req.header.xid);
+
+    std::copy_n((uint8_t*)&xid, slp::header::SIZE_XID,
+                buff.data() +
+                slp::header::OFFSET_XID);
+
+    uint16_t langtagLen = req.header.langtag.length();
+    langtagLen = endian::to_network(langtagLen);
+    std::copy_n((uint8_t*)&langtagLen, slp::header::SIZE_LANG,
+                buff.data() +
+                slp::header::OFFSET_LANG_LEN);
+
+    std::copy_n((uint8_t*)req.header.langtag.c_str(), req.header.langtag.length(),
+                buff.data() +
+                slp::header::OFFSET_LANG);
+    return buff;
+
+}
+
+std::tuple<int, buffer> processSrvTypeRequest(
+    const Message& req)
+{
+
+    /*
+       0                   1                   2                   3
+       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+      |      Service Location header (function = SrvTypeRply = 10)    |
+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+      |           Error Code          |    length of <srvType-list>   |
+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+      |                       <srvtype--list>                         \
+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    */
+
+    buffer buff;
+
+    //read the slp service info from conf and create the service type string
+    slp::handler::internal::ServiceList svcList =
+        slp::handler::internal::readSLPServiceInfo(slp::CONF_FILE);
+    if (svcList.size() <= 0)
+    {
+        buff.resize(0);
+        return std::make_tuple((int)slp::Error::INTERNAL_ERROR, buff);
+    }
+
+    std::string service;
+    bool firstIteration = true;
+    for_each(svcList.cbegin(), svcList.cend(),
+             [&service, &firstIteration](const auto& svc)
+    {
+        if (firstIteration == true)
+        {
+            service = svc.first;
+            firstIteration = false;
+        }
+        else
+        {
+            service += ",";
+            service += svc.first;
+        }
+    });
+
+    buff = prepareHeader(req);
+
+    /* Need to modify the length and the function type field of the header
+     * as it is dependent on the handler of the service */
+
+    std::cout << "service=" << service.c_str() << "\n";
+
+    uint8_t length =  buff.size() +   /* 14 bytes header + length of langtag */
+                      slp::response::SIZE_ERROR +    /* 2 byte err code */
+                      slp::response::SIZE_SERVICE +  /* 2 byte srvtype len */
+                      service.length();
+
+
+    buff.resize(length);
+
+    std::copy_n(&length, slp::header::SIZE_LENGTH,
+                buff.data() +
+                slp::header::OFFSET_LENGTH);
+
+    /* error code is already set to 0 moving to service type len */
+
+    uint16_t serviceTypeLen = service.length();
+    serviceTypeLen = endian::to_network(serviceTypeLen);
+
+    std::copy_n((uint8_t*)&serviceTypeLen, slp::response::SIZE_SERVICE,
+                buff.data() +
+                slp::response::OFFSET_SERVICE_LEN);
+
+    /* service type data */
+    std::copy_n((uint8_t*)service.c_str(), service.length(),
+                (buff.data() +
+                 slp::response::OFFSET_SERVICE));
+
+    return std::make_tuple(slp::SUCCESS, buff);
+}
+
+std::tuple<int, buffer> processSrvRequest(
+    const Message& req)
+{
+
+    /*
+          Service Reply
+          0                   1                   2                   3
+          0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+         |        Service Location header (function = SrvRply = 2)       |
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+         |        Error Code             |        URL Entry count        |
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+         |       <URL Entry 1>          ...       <URL Entry N>          \
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+         URL Entry
+          0                   1                   2                   3
+          0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+         |   Reserved    |          Lifetime             |   URL Length  |
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+         |URL len, contd.|            URL (variable length)              \
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+         |# of URL auths |            Auth. blocks (if any)              \
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    */
+
+    buffer buff;
+    //Get all the services which are registered
+    slp::handler::internal::ServiceList svcList =
+        slp::handler::internal::readSLPServiceInfo(slp::CONF_FILE);
+    if (svcList.size() <= 0)
+    {
+        buff.resize(0);
+        return std::make_tuple((int)slp::Error::INTERNAL_ERROR, buff);
+    }
+
+    //return error if serice type doesn't match
+    auto& svcName = req.body.srvrqst.srvType;
+    auto svcIt = svcList.find(svcName);
+    if (svcIt == svcList.end())
+    {
+        buff.resize(0);
+        return std::make_tuple((int)slp::Error::INTERNAL_ERROR, buff);
+    }
+    //Get all the interface address
+    auto ifaddrList = slp::handler::internal::getIntfAddrs();
+    if (ifaddrList.size() <= 0)
+    {
+        buff.resize(0);
+        return std::make_tuple((int)slp::Error::INTERNAL_ERROR, buff);
+    }
+
+    buff = prepareHeader(req);
+    //Calculate the length and resize the buffer
+    uint8_t length =  buff.size() + /* 14 bytes header + length of langtag */
+                      slp::response::SIZE_ERROR +    /* 2 bytes error code */
+                      slp::response::SIZE_URL_COUNT; /* 2 bytes srvtype len */
+
+    buff.resize(length);
+
+    //Populate the url count
+    uint16_t urlCount = ifaddrList.size();
+    urlCount = endian::to_network(urlCount);
+
+    std::copy_n((uint8_t*)&urlCount, slp::response::SIZE_URL_COUNT,
+                buff.data() +
+                slp::response::OFFSET_URL_ENTRY);
+
+    //Find the service
+    const slp::ConfigData& svc = svcIt->second;
+    //Populate the URL Entrys
+    auto pos = slp::response::OFFSET_URL_ENTRY + slp::response::SIZE_URL_COUNT;
+    for (const auto& addr : ifaddrList)
+    {
+        std::string url = svc.name + ':' + svc.type +
+                          "//" + addr + ',' + svc.port;
+
+
+        buff.resize(buff.size() +
+                    slp::response::SIZE_URL_ENTRY +
+                    url.length());
+
+        uint8_t reserved = 0;
+        uint16_t auth = 0;
+        uint16_t lifetime = endian::to_network<uint16_t>(slp::LIFETIME);
+        uint16_t urlLength = url.length();
+
+        std::copy_n((uint8_t*)&reserved, slp::response::SIZE_RESERVED,
+                    buff.data() + pos);
+
+        pos += slp::response::SIZE_RESERVED;
+
+
+        std::copy_n((uint8_t*)&lifetime, slp::response::SIZE_LIFETIME,
+                    buff.data() + pos);
+
+        pos += slp::response::SIZE_LIFETIME;
+
+        urlLength = endian::to_network(urlLength);
+        std::copy_n((uint8_t*)&urlLength, slp::response::SIZE_URLLENGTH,
+                    buff.data() + pos);
+        pos += slp::response::SIZE_URLLENGTH;
+
+        std::copy_n((uint8_t*)url.c_str(), url.length(),
+                    buff.data() + pos);
+        pos += url.length();
+
+        std::copy_n((uint8_t*)&auth, slp::response::SIZE_AUTH,
+                    buff.data() + pos);
+        pos += slp::response::SIZE_AUTH;
+    }
+    uint8_t packetLength = buff.size();
+    std::copy_n((uint8_t*)&packetLength, slp::header::SIZE_VERSION,
+                buff.data() +
+                slp::header::OFFSET_LENGTH);
+
+    return std::make_tuple((int)slp::SUCCESS, buff);
+}
+
+std::list<std::string> getIntfAddrs()
+{
+    std::list<std::string> addrList;
+
+    struct ifaddrs* ifaddr;
+    // attempt to fill struct with ifaddrs
+    if (getifaddrs(&ifaddr) == -1)
+    {
+        return addrList;
+    }
+
+    slp::deleted_unique_ptr<ifaddrs> ifaddrPtr(ifaddr, [](ifaddrs * addr)
+    {
+        freeifaddrs(addr);
+    });
+
+    ifaddr = nullptr;
+
+    for (ifaddrs* ifa = ifaddrPtr.get(); ifa != nullptr; ifa = ifa->ifa_next)
+    {
+        // walk interfaces
+        if (ifa->ifa_addr == nullptr)
+        {
+            continue;
+        }
+
+        // get only INET interfaces not ipv6
+        if (ifa->ifa_addr->sa_family == AF_INET)
+        {
+            // if loopback, or not running ignore
+            if ((ifa->ifa_flags & IFF_LOOPBACK) ||
+                !(ifa->ifa_flags & IFF_RUNNING))
+            {
+                continue;
+            }
+
+            char tmp[INET_ADDRSTRLEN] = { 0 };
+
+            inet_ntop(AF_INET,
+                      &(((struct sockaddr_in*)(ifa->ifa_addr))->sin_addr),
+                      tmp,
+                      sizeof(tmp));
+            addrList.emplace_back(tmp);
+        }
+    }
+
+    return addrList;
+}
+
+slp::handler::internal::ServiceList  readSLPServiceInfo(
+    const std::string& filename)
+{
+    using namespace std::string_literals;
+    /*Conf File format would be
+      ServiceName serviceType Port */
+
+    slp::handler::internal::ServiceList svcLst;
+
+    std::ifstream readFile(filename);
+    slp::ConfigData service;
+    //Read all the service from the file
+    while (readFile >> service)
+    {
+        std::string tmp = "service:"s + service.name;
+        service.name = tmp;
+        svcLst.emplace(service.name, service);
+    }
+
+    return svcLst;
+}
+}//namespace internal
+
+std::tuple<int, buffer> processRequest(
+    const Message& msg)
+{
+    int rc = slp::SUCCESS;
+    buffer resp(0);
+    switch (msg.header.functionID)
+    {
+        case (uint8_t)slp::FunctionType::SRVTYPERQST:
+            std::tie(rc, resp) = slp::handler::internal::processSrvTypeRequest(msg);
+            break;
+        case (uint8_t)slp::FunctionType::SRVRQST:
+            std::tie(rc, resp) = slp::handler::internal::processSrvRequest(msg);
+            break;
+        default:
+            rc = (uint8_t)slp::Error::MSG_NOT_SUPPORTED;
+    }
+    return std::make_tuple(rc, resp);
+}
+
+buffer processError(const Message& req,
+                    uint8_t err)
+{
+    buffer buff;
+    buff = slp::handler::internal::prepareHeader(req);
+
+    std::copy_n(&err, slp::response::SIZE_ERROR,
+                buff.data() +
+                slp::response::OFFSET_ERROR);
+    return buff;
+
+}
+}//namespace handler
+}//namespace slp
