Move LAN handling commands to the new xyz interfaces

Change-Id: I4631c79c171883e5f0d531cfb5957a09496e4b3a
Signed-off-by: Ratan Gupta <ratagupt@in.ibm.com>
diff --git a/apphandler.cpp b/apphandler.cpp
index 6759462..7b30edd 100644
--- a/apphandler.cpp
+++ b/apphandler.cpp
@@ -1,6 +1,9 @@
 #include "apphandler.h"
 #include "host-ipmid/ipmid-api.h"
 #include "ipmid.hpp"
+#include "types.hpp"
+#include "utils.hpp"
+
 #include <stdio.h>
 #include <string.h>
 #include <stdint.h>
@@ -8,7 +11,12 @@
 #include <mapper.h>
 #include <array>
 #include <arpa/inet.h>
-#include "transporthandler.h"
+#include "transporthandler.hpp"
+
+#include <phosphor-logging/log.hpp>
+#include <phosphor-logging/elog-errors.hpp>
+#include "xyz/openbmc_project/Common/error.hpp"
+
 
 extern sd_bus *bus;
 
@@ -16,8 +24,13 @@
 constexpr auto app_ifc = "org.openbmc.NetworkManager";
 constexpr auto app_nwinterface = "eth0";
 
+constexpr auto ipv4Protocol = "xyz.openbmc_project.Network.IP.Protocol.IPv4";
+
 void register_netfn_app_functions() __attribute__((constructor));
 
+using namespace phosphor::logging;
+using namespace sdbusplus::xyz::openbmc_project::Common::Error;
+
 // Offset in get device id command.
 typedef struct
 {
@@ -508,114 +521,146 @@
     return rc;
 }
 
-extern struct channel_config_t channel_config;
+extern struct ChannelConfig_t channelConfig;
 
-ipmi_ret_t ipmi_set_channel_access(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
-                             ipmi_request_t request, ipmi_response_t response,
-                             ipmi_data_len_t data_len, ipmi_context_t context)
+ipmi_ret_t ipmi_set_channel_access(ipmi_netfn_t netfn,
+                                   ipmi_cmd_t cmd,
+                                   ipmi_request_t request,
+                                   ipmi_response_t response,
+                                   ipmi_data_len_t data_len,
+                                   ipmi_context_t context)
 {
     ipmi_ret_t rc = IPMI_CC_OK;
 
-    sd_bus *bus = ipmid_get_sd_bus_connection();
-    sd_bus_message *reply = nullptr;
-    sd_bus_error error = SD_BUS_ERROR_NULL;
-    int r = 0;
-    char *app = nullptr;
-    int family = 0;
-    unsigned char prefixlen = 0;
-    char* ipaddr = nullptr;
-    uint32_t mask = 0xFFFFFFFF;
-    char* gateway = nullptr;
-    char tmp_netmask[INET_ADDRSTRLEN];
+    std::string ipaddress;
+    std::string gateway;
+    uint8_t prefix {};
 
     // Todo: parse the request data if needed.
 
     // Using Set Channel cmd to apply changes of Set Lan Cmd.
+    try
+    {
 
-    r = mapper_get_service(bus, app_obj, &app);
-    if (r < 0) {
-        fprintf(stderr, "Failed to get %s bus name: %s\n",
-                app_obj, strerror(-r));
-        rc = IPMI_CC_UNSPECIFIED_ERROR;
-        goto finish;
+        sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());
+
+        log<level::INFO>("Network data from Cache",
+                         entry("PREFIX=%s", channelConfig.netmask.c_str()),
+                         entry("ADDRESS=%s", channelConfig.ipaddr.c_str()),
+                         entry("GATEWAY=%s", channelConfig.gateway.c_str()));
+
+        auto systemObject = ipmi::getDbusObject(bus,
+                                 ipmi::network::SYSTEMCONFIG_INTERFACE,
+                                 ipmi::network::ROOT);
+
+        // TODO Currently IPMI supports single interface,need to handle
+        // Multiple interface through
+        // https://github.com/openbmc/openbmc/issues/2138
+
+        auto networkInterfaceObject = ipmi::getDbusObject(
+                    bus,
+                    ipmi::network::ETHERNET_INTERFACE,
+                    ipmi::network::ROOT,
+                    ipmi::network::INTERFACE);
+
+
+
+        // check wthether user has given all the data
+        if (!channelConfig.ipaddr.empty() &&
+            !channelConfig.netmask.empty() &&
+            !channelConfig.gateway.empty())
+        {
+            //convert mask into prefix
+            ipaddress = channelConfig.ipaddr;
+            prefix = ipmi::network::toPrefix(AF_INET, channelConfig.netmask);
+            gateway = channelConfig.gateway;
+        }
+        else
+        {
+            // gets the network data from the system as user has
+            // not given all the data then use the data fetched from the
+            // system but it is implementation dependent,IPMI spec doesn't
+            // force it.
+
+            // if system is not having any ip object don't throw error,
+            try
+            {
+
+                auto ipObjectInfo = ipmi::getDbusObject(bus,
+                        ipmi::network::IP_INTERFACE,
+                        ipmi::network::ROOT,
+                        ipmi::network::IP_TYPE);
+
+                auto properties = ipmi::getAllDbusProperties(bus,
+                        ipObjectInfo.second,
+                        ipObjectInfo.first,
+                        ipmi::network::IP_INTERFACE);
+
+                ipaddress = channelConfig.ipaddr.empty() ?
+                    std::move(properties["Address"].get<std::string>()) :
+                    channelConfig.ipaddr;
+
+                prefix = channelConfig.netmask.empty() ?
+                    properties["PrefixLength"].get<uint8_t>() :
+                    ipmi::network::toPrefix(AF_INET,
+                                            channelConfig.netmask);
+
+            }
+            catch (InternalFailure& e)
+            {
+                log<level::INFO>("Failed to get IP object which matches",
+                        entry("INTERFACE=%s", ipmi::network::IP_INTERFACE),
+                        entry("MATCH=%s", ipmi::network::IP_TYPE));
+            }
+
+            auto systemProperties = ipmi::getAllDbusProperties(
+                    bus,
+                    systemObject.second,
+                    systemObject.first,
+                    ipmi::network::SYSTEMCONFIG_INTERFACE);
+
+            gateway = channelConfig.gateway.empty() ?
+                std::move(systemProperties["DefaultGateway"].get<std::string>()) :
+                channelConfig.gateway;
+
+        }
+
+        // Currently network manager doesn't support purging of all the
+        // ip addresses from the parent interface,
+        // TODO once the support is there, will make the change here.
+        // https://github.com/openbmc/openbmc/issues/2141.
+
+        // TODO Currently IPMI supports single interface,need to handle
+        // Multiple interface through
+        // https://github.com/openbmc/openbmc/issues/2138
+
+        //delete all the ipv4  addresses
+
+        ipmi::deleteAllDbusObjects(bus, ipmi::network::ROOT,
+                                   ipmi::network::IP_INTERFACE,
+                                   ipmi::network::IP_TYPE);
+
+        ipmi::network::createIP(bus, networkInterfaceObject.second,
+                                networkInterfaceObject.first,
+                                ipv4Protocol, ipaddress, prefix);
+
+        ipmi::setDbusProperty(bus, systemObject.second, systemObject.first,
+                              ipmi::network::SYSTEMCONFIG_INTERFACE,
+                              "DefaultGateway", gateway);
+
     }
+    catch (InternalFailure& e)
+    {
+        log<level::ERR>("Failed to set network data",
+                        entry("PREFIX=%d", prefix),
+                        entry("ADDRESS=%s", ipaddress),
+                        entry("GATEWAY=%s", gateway));
 
-    r = sd_bus_call_method(bus, app, app_obj, app_ifc, "GetAddress4", &error,
-                            &reply, "s", app_nwinterface);
-    if (r < 0) {
-        fprintf(stderr, "Failed to call Get Method: %s\n", strerror(-r));
-        rc = IPMI_CC_UNSPECIFIED_ERROR;
-        goto finish;
-    }
-
-    r = sd_bus_message_read(reply, "iyss",
-                            &family, &prefixlen, &ipaddr, &gateway);
-    if (r < 0) {
-        fprintf(stderr, "Failed to get a response: %s\n", strerror(-r));
-        rc = IPMI_CC_RESPONSE_ERROR;
-        goto finish;
-    }
-
-    printf("N/W data from Cache: %s:%s:%s\n",
-            channel_config.new_ipaddr.c_str(),
-            channel_config.new_netmask.c_str(),
-            channel_config.new_gateway.c_str());
-
-    if(channel_config.new_ipaddr.empty()) {
-        channel_config.new_ipaddr.assign(ipaddr);
-    }
-
-    if(channel_config.new_netmask.empty()) {
-        mask = htonl(mask<<(32-prefixlen));
-        uint8_t* p = (uint8_t*)&mask;
-
-        snprintf(tmp_netmask, INET_ADDRSTRLEN, "%d.%d.%d.%d",
-            *p, *(p+1), *(p+2), *(p+3));
-        channel_config.new_netmask.assign(tmp_netmask);
-    }
-
-    if(channel_config.new_gateway.empty()) {
-        channel_config.new_gateway.assign(gateway);
-    }
-
-    printf("N/W data from HW %s:%d:%s:%s\n",
-            family==AF_INET?"IPv4":"IPv6", prefixlen, ipaddr,gateway);
-    printf("N/W data from Cache: %s:%s:%s\n",
-            channel_config.new_ipaddr.c_str(),
-            channel_config.new_netmask.c_str(),
-            channel_config.new_gateway.c_str());
-
-    r = sd_bus_call_method(bus,            // On the System Bus
-                            app,            // Service to contact
-                            app_obj,            // Object path
-                            app_ifc,            // Interface name
-                            "SetAddress4",  // Method to be called
-                            &error,         // object to return error
-                            &reply,         // Response message on success
-                            "ssss",         // input message (Interface,
-                                            // IP Address, Netmask, Gateway)
-                            app_nwinterface,    // eth0
-                            channel_config.new_ipaddr.c_str(),
-                            channel_config.new_netmask.c_str(),
-                            channel_config.new_gateway.c_str());
-    if(r < 0) {
-        fprintf(stderr, "Failed to set network data %s:%s:%s %s\n",
-                channel_config.new_ipaddr.c_str(),
-                channel_config.new_netmask.c_str(),
-                channel_config.new_gateway.c_str(),
-                error.message);
+        commit<InternalFailure>();
         rc = IPMI_CC_UNSPECIFIED_ERROR;
     }
 
-    channel_config.new_ipaddr.clear();
-    channel_config.new_netmask.clear();
-    channel_config.new_gateway.clear();
-
-finish:
-    sd_bus_error_free(&error);
-    reply = sd_bus_message_unref(reply);
-    free(app);
-
+    channelConfig.clear();
     return rc;
 }
 
diff --git a/transporthandler.cpp b/transporthandler.cpp
index 9cbae11..4de9400 100644
--- a/transporthandler.cpp
+++ b/transporthandler.cpp
@@ -6,7 +6,12 @@
 
 #include "host-ipmid/ipmid-api.h"
 #include "ipmid.hpp"
-#include "transporthandler.h"
+#include "transporthandler.hpp"
+#include "utils.hpp"
+
+#include <phosphor-logging/log.hpp>
+#include <phosphor-logging/elog-errors.hpp>
+#include "xyz/openbmc_project/Common/error.hpp"
 
 #define SYSTEMD_NETWORKD_DBUS 1
 
@@ -23,7 +28,7 @@
 
 const int SIZE_MAC = 18; //xx:xx:xx:xx:xx:xx
 
-struct channel_config_t channel_config;
+struct ChannelConfig_t channelConfig;
 
 const uint8_t SET_COMPLETE = 0;
 const uint8_t SET_IN_PROGRESS = 1;
@@ -33,104 +38,158 @@
 // Status of Set-In-Progress Parameter (# 0)
 uint8_t lan_set_in_progress = SET_COMPLETE;
 
-
+using namespace phosphor::logging;
+using namespace sdbusplus::xyz::openbmc_project::Common::Error;
 
 void register_netfn_transport_functions() __attribute__((constructor));
 
-// Helper Function to get IP Address/NetMask/Gateway from Network Manager or
+// Helper Function to get IP Address/NetMask/Gateway/MAC Address from Network Manager or
 // Cache based on Set-In-Progress State
-ipmi_ret_t getNetworkData(uint8_t lan_param, uint8_t * data)
+ipmi_ret_t getNetworkData(uint8_t lan_param, uint8_t* data)
 {
-    sd_bus *bus = ipmid_get_sd_bus_connection();
-    sd_bus_message *reply = NULL;
-    sd_bus_error error = SD_BUS_ERROR_NULL;
-    int family;
-    unsigned char prefixlen;
-    char* ipaddr = NULL;
-    unsigned long mask = 0xFFFFFFFF;
-    char* gateway = NULL;
-    int r = 0;
     ipmi_ret_t rc = IPMI_CC_OK;
-    char *app = NULL;
-
-    r = mapper_get_service(bus, obj, &app);
-    if (r < 0) {
-        fprintf(stderr, "Failed to get %s bus name: %s\n",
-                obj, strerror(-r));
-        rc = IPMI_CC_UNSPECIFIED_ERROR;
-        goto cleanup;
-    }
-    r = sd_bus_call_method(bus, app, obj, ifc, "GetAddress4", &error,
-                            &reply, "s", nwinterface);
-    if(r < 0)
+    sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());
+    try
     {
-        fprintf(stderr, "Failed to call Get Method: %s\n", strerror(-r));
-        rc = IPMI_CC_UNSPECIFIED_ERROR;
-        goto cleanup;
-    }
-
-    r = sd_bus_message_read(reply, "iyss",
-                            &family, &prefixlen, &ipaddr, &gateway);
-    if(r < 0)
-    {
-        fprintf(stderr, "Failed to get a response: %s\n", strerror(-rc));
-        rc = IPMI_CC_RESPONSE_ERROR;
-        goto cleanup;
-    }
-
-    printf("N/W data from HW %s:%d:%s:%s\n",
-            family==AF_INET?"IPv4":"IPv6", prefixlen, ipaddr,gateway);
-    printf("N/W data from Cache: %s:%s:%s\n",
-            channel_config.new_ipaddr.c_str(),
-            channel_config.new_netmask.c_str(),
-            channel_config.new_gateway.c_str());
-
-    if(lan_param == LAN_PARM_IP)
-    {
-        if(lan_set_in_progress == SET_COMPLETE)
+        switch (lan_param)
         {
-            std::string ipaddrstr(ipaddr);
-            inet_pton(AF_INET, ipaddrstr.c_str(),(void *)data);
-        }
-        else if(lan_set_in_progress == SET_IN_PROGRESS)
-        {
-            inet_pton(AF_INET, channel_config.new_ipaddr.c_str(), (void *)data);
+            case LAN_PARM_IP:
+            {
+                std::string ipaddress;
+                if (lan_set_in_progress == SET_COMPLETE)
+                {
+                    auto ipObjectInfo = ipmi::getDbusObject(
+                                            bus,
+                                            ipmi::network::IP_INTERFACE,
+                                            ipmi::network::ROOT,
+                                            ipmi::network::IP_TYPE);
+
+                    auto properties = ipmi::getAllDbusProperties(
+                                         bus,
+                                         ipObjectInfo.second,
+                                         ipObjectInfo.first,
+                                         ipmi::network::IP_INTERFACE);
+
+                    ipaddress = properties["Address"].get<std::string>();
+                }
+                else if (lan_set_in_progress == SET_IN_PROGRESS)
+                {
+                    ipaddress = channelConfig.ipaddr;
+                }
+
+                inet_pton(AF_INET, ipaddress.c_str(),
+                          reinterpret_cast<void*>(data));
+            }
+            break;
+
+            case LAN_PARM_SUBNET:
+            {
+                if (lan_set_in_progress == SET_COMPLETE)
+                {
+                    auto ipObjectInfo = ipmi::getDbusObject(
+                                            bus,
+                                            ipmi::network::IP_INTERFACE,
+                                            ipmi::network::ROOT,
+                                            ipmi::network::IP_TYPE);
+
+                    auto properties = ipmi::getAllDbusProperties(
+                                         bus,
+                                         ipObjectInfo.second,
+                                         ipObjectInfo.first,
+                                         ipmi::network::IP_INTERFACE);
+
+                    auto prefix = properties["PrefixLength"].get<uint8_t>();
+                    unsigned long mask = ipmi::network::MASK_32_BIT;
+                    mask = htonl(mask << (ipmi::network::BITS_32 - prefix));
+                    memcpy(data, &mask, ipmi::network::IPV4_ADDRESS_SIZE_BYTE);
+                }
+                else if (lan_set_in_progress == SET_IN_PROGRESS)
+                {
+                    inet_pton(AF_INET, channelConfig.netmask.c_str(),
+                              reinterpret_cast<void*>(data));
+
+                }
+
+            }
+            break;
+
+            case LAN_PARM_GATEWAY:
+            {
+                std::string gateway;
+
+                if (lan_set_in_progress == SET_COMPLETE)
+                {
+                    auto systemObject = ipmi::getDbusObject(
+                            bus,
+                            ipmi::network::SYSTEMCONFIG_INTERFACE,
+                            ipmi::network::ROOT);
+
+                    auto systemProperties = ipmi::getAllDbusProperties(
+                            bus,
+                            systemObject.second,
+                            systemObject.first,
+                            ipmi::network::SYSTEMCONFIG_INTERFACE);
+
+                    gateway = systemProperties["DefaultGateway"].get<
+                                 std::string>();
+
+                }
+                else if (lan_set_in_progress == SET_IN_PROGRESS)
+                {
+                    gateway = channelConfig.gateway;
+                }
+
+                inet_pton(AF_INET, gateway.c_str(),
+                          reinterpret_cast<void*>(data));
+
+            }
+            break;
+
+            case LAN_PARM_MAC:
+            {
+                std::string macAddress;
+                if (lan_set_in_progress == SET_COMPLETE)
+                {
+                    auto macObjectInfo = ipmi::getDbusObject(
+                                             bus,
+                                             ipmi::network::MAC_INTERFACE,
+                                             ipmi::network::ROOT);
+
+                    auto variant = ipmi::getDbusProperty(
+                                     bus,
+                                     macObjectInfo.second,
+                                     macObjectInfo.first,
+                                     ipmi::network::MAC_INTERFACE,
+                                     "MACAddress");
+
+                    macAddress = variant.get<std::string>();
+
+                }
+                else if (lan_set_in_progress == SET_IN_PROGRESS)
+                {
+                    macAddress = channelConfig.macAddress;
+                }
+
+                sscanf(macAddress.c_str(), ipmi::network::MAC_ADDRESS_FORMAT,
+                       (data),
+                       (data + 1),
+                       (data + 2),
+                       (data + 3),
+                       (data + 4),
+                       (data + 5));
+            }
+            break;
+
+            default:
+                rc = IPMI_CC_PARM_OUT_OF_RANGE;
         }
     }
-    else if(lan_param == LAN_PARM_SUBNET)
+    catch (InternalFailure& e)
     {
-        if(lan_set_in_progress == SET_COMPLETE)
-         {
-            mask = htonl(mask<<(32-prefixlen));
-            memcpy(data, &mask, 4);
-         }
-         else if(lan_set_in_progress == SET_IN_PROGRESS)
-         {
-             inet_pton(AF_INET, channel_config.new_netmask.c_str(), (void *)data);
-         }
+        commit<InternalFailure>();
+        rc = IPMI_CC_UNSPECIFIED_ERROR;
+        return rc;
     }
-    else if(lan_param == LAN_PARM_GATEWAY)
-    {
-        if(lan_set_in_progress == SET_COMPLETE)
-         {
-            std::string gatewaystr(gateway);
-            inet_pton(AF_INET, gatewaystr.c_str(), (void *)data);
-         }
-         else if(lan_set_in_progress == SET_IN_PROGRESS)
-         {
-             inet_pton(AF_INET, channel_config.new_gateway.c_str(),(void *)data);
-         }
-    }
-    else
-    {
-        rc = IPMI_CC_PARM_OUT_OF_RANGE;
-    }
-
-cleanup:
-    sd_bus_error_free(&error);
-    reply = sd_bus_message_unref(reply);
-    free(app);
-
     return rc;
 }
 
@@ -145,120 +204,144 @@
     return rc;
 }
 
-struct set_lan_t {
+struct set_lan_t
+{
     uint8_t channel;
     uint8_t parameter;
     uint8_t data[8]; // Per IPMI spec, not expecting more than this size
-}  __attribute__ ((packed));
+}  __attribute__((packed));
 
-ipmi_ret_t ipmi_transport_set_lan(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
-                              ipmi_request_t request, ipmi_response_t response,
-                              ipmi_data_len_t data_len, ipmi_context_t context)
+ipmi_ret_t ipmi_transport_set_lan(ipmi_netfn_t netfn,
+                                  ipmi_cmd_t cmd,
+                                  ipmi_request_t request,
+                                  ipmi_response_t response,
+                                  ipmi_data_len_t data_len,
+                                  ipmi_context_t context)
 {
     ipmi_ret_t rc = IPMI_CC_OK;
     *data_len = 0;
-    sd_bus *bus = ipmid_get_sd_bus_connection();
-    sd_bus_message *reply = nullptr;
-    sd_bus_error error = SD_BUS_ERROR_NULL;
-    int r = 0;
-    char *app = nullptr;
 
-    char tmp_ipaddr[INET_ADDRSTRLEN];
-    char tmp_netmask[INET_ADDRSTRLEN];
-    char tmp_gateway[INET_ADDRSTRLEN];
+    char ipaddr[INET_ADDRSTRLEN];
+    char netmask[INET_ADDRSTRLEN];
+    char gateway[INET_ADDRSTRLEN];
 
-    printf("IPMI SET_LAN\n");
+    auto reqptr = reinterpret_cast<const set_lan_t*>(request);
+    sdbusplus::bus::bus bus(ipmid_get_sd_bus_connection());
 
-    set_lan_t *reqptr = (set_lan_t*) request;
-
-    if (reqptr->parameter == LAN_PARM_IP) {
-        snprintf(tmp_ipaddr, INET_ADDRSTRLEN, "%d.%d.%d.%d",
-            reqptr->data[0], reqptr->data[1], reqptr->data[2], reqptr->data[3]);
-        channel_config.new_ipaddr.assign(tmp_ipaddr);
-    } else if (reqptr->parameter == LAN_PARM_MAC) {
-        char mac[SIZE_MAC];
-
-        snprintf(mac, SIZE_MAC, "%02x:%02x:%02x:%02x:%02x:%02x",
-                reqptr->data[0],
-                reqptr->data[1],
-                reqptr->data[2],
-                reqptr->data[3],
-                reqptr->data[4],
-                reqptr->data[5]);
-
-        r = mapper_get_service(bus, obj, &app);
-        if (r < 0) {
-            fprintf(stderr, "Failed to get %s bus name: %s\n",
-                    obj, strerror(-r));
-            goto finish;
-        }
-        r = sd_bus_call_method(bus, app, obj, ifc, "SetHwAddress", &error,
-                                &reply, "ss", nwinterface, mac);
-        if (r < 0) {
-            fprintf(stderr, "Failed to call the method: %s\n", strerror(-r));
-            rc = IPMI_CC_UNSPECIFIED_ERROR;
-        }
-    } else if (reqptr->parameter == LAN_PARM_SUBNET)
+    switch (reqptr->parameter)
     {
-        snprintf(tmp_netmask, INET_ADDRSTRLEN, "%d.%d.%d.%d",
-            reqptr->data[0], reqptr->data[1], reqptr->data[2], reqptr->data[3]);
-        channel_config.new_netmask.assign(tmp_netmask);
-    } else if (reqptr->parameter == LAN_PARM_GATEWAY)
-    {
-        snprintf(tmp_gateway, INET_ADDRSTRLEN, "%d.%d.%d.%d",
-            reqptr->data[0], reqptr->data[1], reqptr->data[2], reqptr->data[3]);
-        channel_config.new_gateway.assign(tmp_gateway);
-    } else if (reqptr->parameter == LAN_PARM_INPROGRESS)
-    {
-        if(reqptr->data[0] == SET_COMPLETE) {
-            lan_set_in_progress = SET_COMPLETE;
-
-            printf("N/W data from Cache: %s:%s:%s\n",
-                    channel_config.new_ipaddr.c_str(),
-                    channel_config.new_netmask.c_str(),
-                    channel_config.new_gateway.c_str());
-            printf("Use Set Channel Access command to apply them\n");
-
-        } else if(reqptr->data[0] == SET_IN_PROGRESS) // Set In Progress
+        case LAN_PARM_IP:
         {
-            lan_set_in_progress = SET_IN_PROGRESS;
-        }
-    } else
-    {
-        fprintf(stderr, "Unsupported parameter 0x%x\n", reqptr->parameter);
-        rc = IPMI_CC_PARM_NOT_SUPPORTED;
-    }
+            snprintf(ipaddr, INET_ADDRSTRLEN, ipmi::network::IP_ADDRESS_FORMAT,
+                     reqptr->data[0], reqptr->data[1],
+                     reqptr->data[2], reqptr->data[3]);
 
-finish:
-    sd_bus_error_free(&error);
-    reply = sd_bus_message_unref(reply);
-    free(app);
+            channelConfig.ipaddr.assign(ipaddr);
+
+        }
+        break;
+
+        case LAN_PARM_MAC:
+        {
+            char mac[SIZE_MAC];
+
+            snprintf(mac, SIZE_MAC, ipmi::network::MAC_ADDRESS_FORMAT,
+                     reqptr->data[0],
+                     reqptr->data[1],
+                     reqptr->data[2],
+                     reqptr->data[3],
+                     reqptr->data[4],
+                     reqptr->data[5]);
+
+            auto macObjectInfo = ipmi::getDbusObject(
+                                     bus,
+                                     ipmi::network::MAC_INTERFACE,
+                                     ipmi::network::ROOT,
+                                     ipmi::network::INTERFACE);
+
+            ipmi::setDbusProperty(bus,
+                                  macObjectInfo.second,
+                                  macObjectInfo.first,
+                                  ipmi::network::MAC_INTERFACE,
+                                  "MACAddress",
+                                  std::string(mac));
+
+            channelConfig.macAddress = mac;
+
+        }
+        break;
+
+        case LAN_PARM_SUBNET:
+        {
+            snprintf(netmask, INET_ADDRSTRLEN, ipmi::network::IP_ADDRESS_FORMAT,
+                     reqptr->data[0], reqptr->data[1],
+                     reqptr->data[2], reqptr->data[3]);
+            channelConfig.netmask.assign(netmask);
+        }
+        break;
+
+        case LAN_PARM_GATEWAY:
+        {
+            snprintf(gateway, INET_ADDRSTRLEN, ipmi::network::IP_ADDRESS_FORMAT,
+                     reqptr->data[0], reqptr->data[1],
+                     reqptr->data[2], reqptr->data[3]);
+            channelConfig.gateway.assign(gateway);
+
+        }
+        break;
+
+        case LAN_PARM_INPROGRESS:
+        {
+            if (reqptr->data[0] == SET_COMPLETE)
+            {
+                lan_set_in_progress = SET_COMPLETE;
+
+                log<level::INFO>("Network data from Cache",
+                                 entry("PREFIX=%s", channelConfig.netmask.c_str()),
+                                 entry("ADDRESS=%s", channelConfig.ipaddr.c_str()),
+                                 entry("GATEWAY=%s", channelConfig.gateway.c_str()));
+
+                log<level::INFO>("Use Set Channel Access command to apply");
+
+            }
+            else if (reqptr->data[0] == SET_IN_PROGRESS) // Set In Progress
+            {
+                lan_set_in_progress = SET_IN_PROGRESS;
+            }
+
+        }
+        break;
+
+        default:
+        {
+            log<level::ERR>("Unsupported parameter",
+                            entry("PARAMETER=0x%x", reqptr->parameter));
+            rc = IPMI_CC_PARM_NOT_SUPPORTED;
+        }
+
+    }
 
     return rc;
 }
 
-struct get_lan_t {
+struct get_lan_t
+{
     uint8_t rev_channel;
     uint8_t parameter;
     uint8_t parameter_set;
     uint8_t parameter_block;
-}  __attribute__ ((packed));
+}  __attribute__((packed));
 
-ipmi_ret_t ipmi_transport_get_lan(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
-                              ipmi_request_t request, ipmi_response_t response,
-                              ipmi_data_len_t data_len, ipmi_context_t context)
+ipmi_ret_t ipmi_transport_get_lan(ipmi_netfn_t netfn,
+                                  ipmi_cmd_t cmd,
+                                  ipmi_request_t request,
+                                  ipmi_response_t response,
+                                  ipmi_data_len_t data_len,
+                                  ipmi_context_t context)
 {
     ipmi_ret_t rc = IPMI_CC_OK;
     *data_len = 0;
-    sd_bus *bus = ipmid_get_sd_bus_connection();
-    sd_bus_message *reply = NULL;
-    sd_bus_error error = SD_BUS_ERROR_NULL;
-    int r = 0;
     const uint8_t current_revision = 0x11; // Current rev per IPMI Spec 2.0
-    int i = 0;
-    char *app = NULL;
-
-    printf("IPMI GET_LAN\n");
 
     get_lan_t *reqptr = (get_lan_t*) request;
 
@@ -270,9 +353,6 @@
         return IPMI_CC_OK;
     }
 
-    // TODO Use dbus interface once available. For now use ip cmd.
-    // TODO Add the rest of the parameters, like gateway
-
     if (reqptr->parameter == LAN_PARM_INPROGRESS)
     {
         uint8_t buf[] = {current_revision, lan_set_in_progress};
@@ -291,16 +371,26 @@
         *data_len = sizeof(buf);
         memcpy(response, &buf, *data_len);
     }
-    else if ((reqptr->parameter == LAN_PARM_IP) || (reqptr->parameter == LAN_PARM_SUBNET) || (reqptr->parameter == LAN_PARM_GATEWAY))
+    else if ((reqptr->parameter == LAN_PARM_IP) ||
+             (reqptr->parameter == LAN_PARM_SUBNET) ||
+             (reqptr->parameter == LAN_PARM_GATEWAY) ||
+             (reqptr->parameter == LAN_PARM_MAC))
     {
-        uint8_t buf[5];
+        uint8_t buf[ipmi::network::MAC_ADDRESS_SIZE_BYTE + 1];
 
         *data_len = sizeof(current_revision);
         memcpy(buf, &current_revision, *data_len);
 
-        if(getNetworkData(reqptr->parameter, &buf[1]) == IPMI_CC_OK)
+        if (getNetworkData(reqptr->parameter, &buf[1]) == IPMI_CC_OK)
         {
-            *data_len = sizeof(buf);
+            if (reqptr->parameter == LAN_PARM_MAC)
+            {
+                *data_len = sizeof(buf);
+            }
+            else
+            {
+                *data_len = ipmi::network::IPV4_ADDRESS_SIZE_BYTE + 1;
+            }
             memcpy(response, &buf, *data_len);
         }
         else
@@ -308,75 +398,13 @@
             rc = IPMI_CC_UNSPECIFIED_ERROR;
         }
     }
-    else if (reqptr->parameter == LAN_PARM_MAC)
-    {
-        //string to parse: link/ether xx:xx:xx:xx:xx:xx
-        uint8_t buf[7];
-        char *eaddr1 = NULL;
-
-        r = mapper_get_service(bus, obj, &app);
-        if (r < 0) {
-            fprintf(stderr, "Failed to get %s bus name: %s\n",
-                    obj, strerror(-r));
-            goto cleanup;
-        }
-        r = sd_bus_call_method(bus, app, obj, ifc, "GetHwAddress", &error,
-                                &reply, "s", nwinterface);
-        if(r < 0)
-        {
-            fprintf(stderr, "Failed to call Get Method: %s\n", strerror(-r));
-            rc = IPMI_CC_UNSPECIFIED_ERROR;
-            goto cleanup;
-        }
-
-        r = sd_bus_message_read(reply, "s", &eaddr1);
-        if (r < 0)
-        {
-            fprintf(stderr, "Failed to get a response: %s", strerror(-r));
-            rc = IPMI_CC_UNSPECIFIED_ERROR;
-            goto cleanup;
-        }
-        if (eaddr1 == NULL)
-        {
-            fprintf(stderr, "Failed to get a valid response: %s", strerror(-r));
-            rc = IPMI_CC_UNSPECIFIED_ERROR;
-            goto cleanup;
-        }
-
-        memcpy((void*)&buf[0], &current_revision, 1);
-
-        char *tokptr = NULL;
-        char* digit = strtok_r(eaddr1, ":", &tokptr);
-        if (digit == NULL)
-        {
-            fprintf(stderr, "Unexpected MAC format: %s", eaddr1);
-            rc = IPMI_CC_RESPONSE_ERROR;
-            goto cleanup;
-        }
-
-        i=0;
-        while (digit != NULL)
-        {
-            int resp_byte = strtoul(digit, NULL, 16);
-            memcpy((void*)&buf[i+1], &resp_byte, 1);
-            i++;
-            digit = strtok_r(NULL, ":", &tokptr);
-        }
-
-        *data_len = sizeof(buf);
-        memcpy(response, &buf, *data_len);
-    }
     else
     {
-        fprintf(stderr, "Unsupported parameter 0x%x\n", reqptr->parameter);
+        log<level::ERR>("Unsupported parameter",
+                        entry("PARAMETER=0x%x", reqptr->parameter));
         rc = IPMI_CC_PARM_NOT_SUPPORTED;
     }
 
-cleanup:
-    sd_bus_error_free(&error);
-    reply = sd_bus_message_unref(reply);
-    free(app);
-
     return rc;
 }
 
diff --git a/transporthandler.h b/transporthandler.hpp
similarity index 67%
rename from transporthandler.h
rename to transporthandler.hpp
index 171a636..f1fd410 100644
--- a/transporthandler.h
+++ b/transporthandler.hpp
@@ -1,5 +1,6 @@
-#ifndef __HOST_IPMI_TRANSPORT_HANDLER_H__
-#define __HOST_IPMI_TRANSPORT_HANDLER_H__
+#pragma once
+
+#include <string>
 
 // IPMI commands for Transport net functions.
 enum ipmi_netfn_storage_cmds
@@ -24,10 +25,17 @@
 static const int LAN_PARM_SUBNET      = 6;
 static const int LAN_PARM_GATEWAY     = 12;
 
-struct channel_config_t {
-    std::string new_ipaddr;
-    std::string new_netmask;
-    std::string new_gateway;
+struct ChannelConfig_t
+{
+    std::string ipaddr;
+    std::string netmask;
+    std::string gateway;
+    std::string macAddress;
+    void clear()
+    {
+        ipaddr.clear();
+        netmask.clear();
+        gateway.clear();
+        macAddress.clear();
+    }
 };
-
-#endif
diff --git a/types.hpp b/types.hpp
index b6d27e3..5b39c38 100644
--- a/types.hpp
+++ b/types.hpp
@@ -22,6 +22,7 @@
                                           int64_t, uint64_t, std::string>;
 
 using PropertyMap = std::map<DbusProperty, Value>;
+
 using ObjectTree = std::map<DbusObjectPath,
                             std::map<DbusService, std::vector<DbusInterface>>>;
 
@@ -106,5 +107,9 @@
 constexpr auto DEFAULT_MAC_ADDRESS = "00:00:00:00:00:00";
 constexpr auto DEFAULT_ADDRESS = "0.0.0.0";
 
+constexpr auto MAC_ADDRESS_SIZE_BYTE = 6;
+constexpr auto BITS_32 = 32;
+constexpr auto MASK_32_BIT = 0xFFFFFFFF;
+
 }//namespace network
 }//namespace ipmi
diff --git a/utils.cpp b/utils.cpp
index fa92e48..11dc2d4 100644
--- a/utils.cpp
+++ b/utils.cpp
@@ -1,9 +1,12 @@
 #include "utils.hpp"
-#include "host-ipmid/ipmid-api.h"
 #include <phosphor-logging/log.hpp>
 #include <phosphor-logging/elog-errors.hpp>
 #include "xyz/openbmc_project/Common/error.hpp"
 
+#include <arpa/inet.h>
+#include <dirent.h>
+#include <net/if.h>
+
 namespace ipmi
 {
 
@@ -203,7 +206,171 @@
     return mapperResponse.begin()->first;
 }
 
+ipmi::ObjectTree getAllDbusObjects(sdbusplus::bus::bus& bus,
+                                   const std::string& serviceRoot,
+                                   const std::string& interface,
+                                   const std::string& match)
+{
+    std::vector<std::string> interfaces;
+    interfaces.emplace_back(interface);
 
+    auto depth = 0;
+
+    auto mapperCall = bus.new_method_call(MAPPER_BUS_NAME,
+                                          MAPPER_OBJ,
+                                          MAPPER_INTF,
+                                          "GetSubTree");
+
+    mapperCall.append(serviceRoot, depth, interfaces);
+
+    auto mapperReply = bus.call(mapperCall);
+    if (mapperReply.is_method_error())
+    {
+        log<level::ERR>("Error in mapper call",
+                        entry("SERVICEROOT=%s",serviceRoot.c_str()),
+                        entry("INTERFACE=%s", interface.c_str()));
+
+        elog<InternalFailure>();
+    }
+
+    ObjectTree objectTree;
+    mapperReply.read(objectTree);
+
+    for (auto it = objectTree.begin(); it != objectTree.end();)
+    {
+        if (it->first.find(match) == std::string::npos)
+        {
+            it = objectTree.erase(it);
+        }
+        else
+        {
+            ++it;
+        }
+    }
+
+    return objectTree;
+}
+
+void deleteAllDbusObjects(sdbusplus::bus::bus& bus,
+                          const std::string& serviceRoot,
+                          const std::string& interface,
+                          const std::string& match)
+{
+    try
+    {
+        auto objectTree =  getAllDbusObjects(bus, serviceRoot, interface, match);
+
+        for (auto& object : objectTree)
+        {
+            method_no_args::callDbusMethod(bus,
+                                           object.second.begin()->first,
+                                           object.first,
+                                           DELETE_INTERFACE, "Delete");
+        }
+    }
+    catch (InternalFailure& e)
+    {
+        log<level::INFO>("Unable to delete the objects having",
+                         entry("INTERFACE=%s", interface.c_str()),
+                         entry("SERVICE=%s", serviceRoot.c_str()));
+    }
+}
+
+
+namespace method_no_args
+{
+
+void callDbusMethod(sdbusplus::bus::bus& bus,
+                    const std::string& service,
+                    const std::string& objPath,
+                    const std::string& interface,
+                    const std::string& method)
+
+{
+    auto busMethod = bus.new_method_call(
+                         service.c_str(),
+                         objPath.c_str(),
+                         interface.c_str(),
+                         method.c_str());
+
+    auto reply = bus.call(busMethod);
+
+    if (reply.is_method_error())
+    {
+        log<level::ERR>("Failed to execute method",
+                        entry("METHOD=%s", method.c_str()),
+                        entry("PATH=%s", objPath.c_str()),
+                        entry("INTERFACE=%s", interface.c_str()));
+        elog<InternalFailure>();
+    }
+}
+
+}// namespace method_no_args
+
+namespace network
+{
+
+void createIP(sdbusplus::bus::bus& bus,
+              const std::string& service,
+              const std::string& objPath,
+              const std::string& protocolType,
+              const std::string& ipaddress,
+              uint8_t prefix)
+{
+    std::string gateway = "";
+
+    auto busMethod = bus.new_method_call(
+                         service.c_str(),
+                         objPath.c_str(),
+                         IP_CREATE_INTERFACE,
+                         "IP");
+
+    busMethod.append(protocolType, ipaddress, prefix, gateway);
+
+    auto reply = bus.call(busMethod);
+
+    if (reply.is_method_error())
+    {
+        log<level::ERR>("Failed to excute method",
+                        entry("METHOD=%s", "IP"),
+                        entry("PATH=%s", objPath.c_str()));
+        elog<InternalFailure>();
+    }
+
+}
+
+uint8_t toPrefix(int addressFamily, const std::string& subnetMask)
+{
+    if (addressFamily == AF_INET6)
+    {
+        return 0;
+    }
+
+    uint32_t buff {};
+
+    auto rc = inet_pton(addressFamily, subnetMask.c_str(), &buff);
+    if (rc <= 0)
+    {
+        log<level::ERR>("inet_pton failed:",
+                        entry("SUBNETMASK=%s", subnetMask));
+        return 0;
+    }
+
+    buff = be32toh(buff);
+    // total no of bits - total no of leading zero == total no of ones
+    if (((sizeof(buff) * 8) - (__builtin_ctz(buff))) == __builtin_popcount(buff))
+    {
+        return __builtin_popcount(buff);
+    }
+    else
+    {
+        log<level::ERR>("Invalid Mask",
+                        entry("SUBNETMASK=%s", subnetMask));
+        return 0;
+    }
+}
+
+} // namespace network
 } // namespace ipmi
 
 
diff --git a/utils.hpp b/utils.hpp
index 0c7ae76..cb64a25 100644
--- a/utils.hpp
+++ b/utils.hpp
@@ -12,16 +12,14 @@
 
 constexpr auto ROOT = "/";
 constexpr auto HOST_MATCH = "host0";
-constexpr auto PROP_INTF = "org.freedesktop.DBus.Properties";
 
-constexpr auto IP_INTERFACE = "xyz.openbmc_project.Network.IP";
-constexpr auto MAC_INTERFACE = "xyz.openbmc_project.Network.MACAddress";
+constexpr auto PROP_INTF = "org.freedesktop.DBus.Properties";
+constexpr auto DELETE_INTERFACE = "xyz.openbmc_project.Object.Delete";
 
 constexpr auto METHOD_GET = "Get";
 constexpr auto METHOD_GET_ALL = "GetAll";
 constexpr auto METHOD_SET = "Set";
 
-
 /**
  * @brief Get the DBUS Service name for the input dbus path
  *
@@ -90,6 +88,87 @@
                      const std::string& property,
                      const Value& value);
 
+/** @brief  Gets all the dbus objects from the given service root
+ *          which matches the object identifier.
+ *  @param[in] bus - DBUS Bus Object.
+ *  @param[in] serviceRoot - Service root path.
+ *  @param[in] interface - Dbus interface.
+ *  @param[in] match - Identifier for a path.
+ *  @returns map of object path and service info.
+ */
+ObjectTree getAllDbusObjects(sdbusplus::bus::bus& bus,
+                             const std::string& serviceRoot,
+                             const std::string& interface,
+                             const std::string& match);
+
+/** @brief Deletes all the dbus objects from the given service root
+           which matches the object identifier.
+ *  @param[in] bus - DBUS Bus Object.
+ *  @param[in] serviceRoot - Service root path.
+ *  @param[in] interface - Dbus interface.
+ *  @param[in] match - Identifier for object.
+ */
+void deleteAllDbusObjects(sdbusplus::bus::bus& bus,
+                          const std::string& serviceRoot,
+                          const std::string& interface,
+                          const std::string& match = {});
+
+namespace method_no_args
+{
+
+/** @brief Calls the Dbus method which waits for response.
+ *  @param[in] bus - DBUS Bus Object.
+ *  @param[in] service - Dbus service name.
+ *  @param[in] objPath - Dbus object path.
+ *  @param[in] interface - Dbus interface.
+ *  @param[in] method - Dbus method.
+ */
+void callDbusMethod(sdbusplus::bus::bus& bus,
+                    const std::string& service,
+                    const std::string& objPath,
+                    const std::string& interface,
+                    const std::string& method);
+
+} //namespace method_no_args
+
+namespace network
+{
+
+constexpr auto ROOT = "/xyz/openbmc_project/network";
+constexpr auto NETWORK_SERVICE = "xyz.openbmc_project.Network";
+constexpr auto INTERFACE = "eth0";
+constexpr auto IP_TYPE = "ipv4";
+constexpr auto IP_INTERFACE = "xyz.openbmc_project.Network.IP";
+constexpr auto MAC_INTERFACE = "xyz.openbmc_project.Network.MACAddress";
+constexpr auto SYSTEMCONFIG_INTERFACE = "xyz.openbmc_project.Network.SystemConfiguration";
+constexpr auto ETHERNET_INTERFACE = "xyz.openbmc_project.Network.EthernetInterface";
+constexpr auto IP_CREATE_INTERFACE = "xyz.openbmc_project.Network.IP.Create";
+
+/* @brief converts the given subnet into prefix notation.
+ * @param[in] addressFamily - IP address family(AF_INET/AF_INET6).
+ * @param[in] mask - Subnet Mask.
+ * @returns prefix.
+ */
+uint8_t toPrefix(int addressFamily, const std::string& subnetMask);
+
+
+/** @brief Sets the ip on the system.
+ *  @param[in] bus - DBUS Bus Object.
+ *  @param[in] service - Dbus service name.
+ *  @param[in] objPath - Dbus object path.
+ *  @param[in] protocolType - Protocol type
+ *  @param[in] ipaddress - IPaddress.
+ *  @param[in] prefix - Prefix length.
+ */
+void createIP(sdbusplus::bus::bus& bus,
+              const std::string& service,
+              const std::string& objPath,
+              const std::string& protocolType,
+              const std::string& ipaddress,
+              uint8_t prefix);
+
+}//namespace network
+
 } // namespace ipmi