Update the remote ip addr to session properties

Add remote ip address to session properties so that it is passed to
ipmi-host. This will enable certain commands to know the remote ip
address.

Tested:
Get session info command shows the remote ip address of the active
sessions.

ipmitool -I lanplus -H <ip_addr> -U <user> -P <password> session info all
session handle                : 129
slot count                    : 45
active sessions               : 1
user id                       : 1
privilege level               : ADMINISTRATOR
session type                  : IPMIv1.5
channel number                : 0x03
console ip                    : <remote ip address>
console mac                   : 00:00:00:00:00:00
console port                  : 50854

session handle                : 0
slot count                    : 45
active sessions               : 1

Signed-off-by: Rajashekar Gade Reddy <raja.sekhar.reddy.gade@linux.intel.com>
Change-Id: I1a431437da97240941390322adc59acb2c5323d1
diff --git a/socket_channel.hpp b/socket_channel.hpp
index df7e3ae..b993f0e 100644
--- a/socket_channel.hpp
+++ b/socket_channel.hpp
@@ -14,6 +14,7 @@
 
 namespace udpsocket
 {
+static constexpr uint8_t v4v6Index = 12;
 
 /** @class Channel
  *
@@ -43,36 +44,57 @@
         socket(socket)
     {
     }
-
+    /**
+     * @brief Check if ip address is ipv4 mapped ipv6
+     *
+     *  @param v6Addr : in6_addr obj
+     *
+     * @return true if ipv4 mapped ipv6 else return false
+     */
+    bool isIpv4InIpv6(const struct in6_addr& v6Addr) const
+    {
+        constexpr uint8_t prefix[v4v6Index] = {0, 0, 0, 0, 0,    0,
+                                               0, 0, 0, 0, 0xff, 0xff};
+        return 0 == std::memcmp(&v6Addr.s6_addr[0], &prefix[0], sizeof(prefix));
+    }
     /**
      * @brief Fetch the IP address of the remote peer
      *
+     *  @param remoteIpv4Addr : ipv4 address is assigned to it.
+     *
      * Returns the IP address of the remote peer which is connected to this
      * socket
      *
      * @return IP address of the remote peer
      */
-    std::string getRemoteAddress() const
+    std::string getRemoteAddress(uint32_t& remoteIpv4Addr) const
     {
         const char* retval = nullptr;
         if (sockAddrSize == sizeof(sockaddr_in))
         {
             char ipv4addr[INET_ADDRSTRLEN];
-            retval = inet_ntop(
-                AF_INET,
-                &(reinterpret_cast<const sockaddr_in*>(&remoteSockAddr)
-                      ->sin_addr),
-                ipv4addr, sizeof(ipv4addr));
+            const sockaddr_in* sa =
+                reinterpret_cast<const sockaddr_in*>(&remoteSockAddr);
+            remoteIpv4Addr = sa->sin_addr.s_addr;
+            retval =
+                inet_ntop(AF_INET, &(sa->sin_addr), ipv4addr, sizeof(ipv4addr));
         }
         else if (sockAddrSize == sizeof(sockaddr_in6))
         {
             char ipv6addr[INET6_ADDRSTRLEN];
-            retval = inet_ntop(
-                AF_INET6,
-                &(reinterpret_cast<const sockaddr_in6*>(&remoteSockAddr)
-                      ->sin6_addr),
-                ipv6addr, sizeof(ipv6addr));
+            const sockaddr_in6* sa =
+                reinterpret_cast<const sockaddr_in6*>(&remoteSockAddr);
+
+            if (isIpv4InIpv6(sa->sin6_addr))
+            {
+                std::copy_n(&sa->sin6_addr.s6_addr[v4v6Index],
+                            sizeof(remoteIpv4Addr),
+                            reinterpret_cast<uint8_t*>(&remoteIpv4Addr));
+            }
+            retval = inet_ntop(AF_INET6, &(sa->sin6_addr), ipv6addr,
+                               sizeof(ipv6addr));
         }
+
         if (retval)
         {
             return retval;