BUG#: 8034
authorjohn.eisenbraun <john.eisenbraun>
Tue, 18 Nov 2008 20:53:17 +0000 (20:53 +0000)
committerjohn.eisenbraun <john.eisenbraun>
Tue, 18 Nov 2008 20:53:17 +0000 (20:53 +0000)
TITLE: IP provider on OpenVMS doesn't implement most methods in IP_Vms.cpp

DESCRIPTION: Most methods return 'not implemented'.

src/Providers/ManagedSystem/IP/IP_Vms.cpp
src/Providers/ManagedSystem/IP/IP_Vms.h

index 85b44ab2cf1f685f8d36fb55f923bd2bfd076798..5f2505354aec886cb430df833fd1551c4779843c 100755 (executable)
@@ -17,7 +17,7 @@
 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 // sell copies of the Software, and to permit persons to whom the Software is
 // furnished to do so, subject to the following conditions:
-// 
+//
 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 /* ==========================================================================
    Includes.
    ========================================================================== */
-
 #include "IPPlatform.h"
+#include <pthread.h>
 
 PEGASUS_USING_STD;
 PEGASUS_USING_PEGASUS;
+/*
+=============================================================================
+Structer declration
+==============================================================================
+*/
+
+typedef struct
+{
+    string destAddr;
+    string subnetMask;
+    string nextHop;
+}ipInfo;
+
+/*
+==============================================================================
+Function Prototype
+==============================================================================
+*/
+
+static int _findNetworkProtocolType(int *findNetProtoType,const char *Str);
+static int _getIpRoutingInfo(string lineStr,ipInfo *ipInfoStr);
 
 IPInterface::IPInterface()
 {
@@ -60,8 +81,8 @@ NOTES             :
 */
 Boolean IPInterface::getCaption(String& s) const
 {
-  s = String::EMPTY;
-  return true;
+    s = _address;
+    return true;
 }
 
 /*
@@ -76,8 +97,21 @@ NOTES             :
 */
 Boolean IPInterface::getDescription(String& s) const
 {
-  s = String::EMPTY;
-  return true;
+    String sn;
+
+    if (getSystemName(sn))
+    {
+        s = "IP Protocol Endpoint for ";
+        s.append(sn);
+        s.append(" (");
+        s.append(_address);
+        s.append(")");
+        return true;
+    }
+    else
+    {
+        return false;
+    }
 }
 
 /*
@@ -92,11 +126,11 @@ NOTES             :
 */
 Boolean IPInterface::getInstallDate(CIMDateTime& d) const
 {
-  // Not supported. This property is inherited from
-  // CIM_ManagedSystemElement, but has no useful meaning
-  // for an IP address.
+    // Not supported. This property is inherited from
+    // CIM_ManagedSystemElement, but has no useful meaning
+    // for an IP address.
 
-  return false;
+    return false;
 }
 
 /*
@@ -111,8 +145,10 @@ NOTES             :
 */
 Boolean IPInterface::getName(String& s) const
 {
-  // not supported
-  return false;
+    s = _protocol;
+    s.append("_");
+    s.append(_simpleIfName);
+    return true;
 }
 
 /*
@@ -127,13 +163,12 @@ NOTES             :
 */
 Boolean IPInterface::getStatus(String& s) const
 {
-  // This property is inherited from CIM_ManagedSystemElement,
-  // is not relevant.
+    // This property is inherited from CIM_ManagedSystemElement,
+    // is not relevant.
 
-  return false;
+    return false;
 }
 
-
 /*
 ================================================================================
 NAME              : getSystemName
@@ -146,8 +181,48 @@ NOTES             :
 */
 Boolean IPInterface::getSystemName(String& s)
 {
-  // not supported
-  return false;
+    char hostName[PEGASUS_MAXHOSTNAMELEN + 1];
+    struct addrinfo *info, hints;
+    int rc;
+
+    if (gethostname(hostName, sizeof(hostName)) != 0)
+    {
+        s.assign("Unknown");
+        return true;
+    }
+    hostName[sizeof(hostName)-1] = 0;
+
+    // Now get the official hostname.  If this call fails then return
+    // the value from gethostname().
+    // Note: gethostbyname() is not reentrant and VMS does not
+    // have gethostbyname_r() so use getaddrinfo().
+
+    info = 0;
+    memset (&hints, 0, sizeof(struct addrinfo));
+    hints.ai_flags = AI_CANONNAME;
+    hints.ai_family = AF_INET;
+    hints.ai_protocol = IPPROTO_TCP;
+    hints.ai_socktype = SOCK_STREAM;
+
+    while ((rc = getaddrinfo(hostName, 0, &hints, &info)) == EAI_AGAIN)
+    {
+        if (NULL != info)
+        {
+            freeaddrinfo(info);
+            info = NULL;
+        }
+    }
+
+    if ((!rc) && (info) && (info->ai_canonname))
+    {
+        // Note: if assign throws an exception, freeaddrinfo is not called.
+        s.assign(info->ai_canonname);
+    }
+    else
+    {
+        s.assign(hostName);
+    }
+    return true;
 }
 
 
@@ -163,8 +238,8 @@ NOTES             :
 */
 Boolean IPInterface::getNameFormat(String& s) const
 {
-  // not supported
-  return false;
+    s = "<Protocol>_<InterfaceName>";
+    return true;
 }
 
 /*
@@ -179,8 +254,20 @@ NOTES             :
 */
 Boolean IPInterface::getProtocolType(Uint16& i16) const
 {
-  // not supported
-  return false;
+    if (String::equal(_protocol,PROTOCOL_IPV4))
+    {
+        i16 = 2;  // IPv4
+        return true;
+    }
+    else if (String::equal(_protocol,PROTOCOL_IPV6))
+    {
+        i16 = 3;  // IPv6
+        return true;
+    }
+    else
+    {
+        return false;
+    }
 }
 
 /*
@@ -195,8 +282,9 @@ NOTES             :
 */
 Boolean IPInterface::getOtherTypeDescription(String& s) const
 {
-  // not supported
-  return false;
+    // The caller must know to set the value to NULL (XML: no <VALUE> element)
+    s = String::EMPTY;
+    return true;
 }
 
 /*
@@ -211,8 +299,8 @@ NOTES             :
 */
 Boolean IPInterface::getAddress(String& s) const
 {
-  // not supported
-  return false;
+    // not supported
+    return false;
 }
 
 /*
@@ -227,8 +315,8 @@ NOTES             :
 */
 Boolean IPInterface::getIPv4Address(String& s) const
 {
-  // not supported
-  return false;
+    s = _address;
+    return true;
 }
 
 /*
@@ -243,8 +331,8 @@ NOTES             :
 */
 Boolean IPInterface::getIPv6Address(String& s) const
 {
-  // not supported
-  return false;
+    // not supported
+    return false;
 }
 
 /*
@@ -259,8 +347,8 @@ NOTES             :
 */
 Boolean IPInterface::getPrefixLength(Uint8& i8) const
 {
-  // not supported
-  return false;
+    // not supported
+    return false;
 }
 
 /*
@@ -275,8 +363,8 @@ NOTES             :
 */
 Boolean IPInterface::getSubnetMask(String& s) const
 {
-  // not supported
-  return false;
+    s = _subnetMask;
+    return true;
 }
 
 /*
@@ -291,8 +379,26 @@ NOTES             :
 */
 Boolean IPInterface::getAddressType(Uint16& i16) const
 {
-  // not supported
-  return false;
+    /*
+        From CIM v2.6.0 MOF for CIM_IPProtocolEndpoint.AddressType:
+           ValueMap {"0", "1", "2"},
+           Values {"Unknown", "IPv4", "IPv6"} ]
+    */
+
+    if (String::equal(_protocol,PROTOCOL_IPV4))
+    {
+        i16 = 1;  // IPv4
+        return true;
+    }
+    else if (String::equal(_protocol,PROTOCOL_IPV6))
+    {
+        i16 = 2;  // IPv6
+        return true;
+    }
+    else
+    {
+        return false;
+    }
 }
 
 /*
@@ -307,8 +413,26 @@ NOTES             :
 */
 Boolean IPInterface::getIPVersionSupport(Uint16& i16) const
 {
-  // not supported
-  return false;
+    /*
+        From CIM v2.6.0 MOF for CIM_IPProtocolEndpoint.IPVersionSupport:
+           ValueMap {"0", "1", "2"},
+           Values {"Unknown", "IPv4 Only", "IPv6 Only"} ]
+    */
+
+    if (String::equal(_protocol,PROTOCOL_IPV4))
+    {
+        i16 = 1;  // IPv4 Only
+        return true;
+    }
+    else if (String::equal(_protocol,PROTOCOL_IPV6))
+    {
+        i16 = 2;  // IPv6 Only
+        return true;
+    }
+    else
+    {
+        return false;
+    }
 }
 
 /*
@@ -323,8 +447,8 @@ NOTES             : Deprecated by ProtocolIFType
 */
 Boolean IPInterface::getProtocolIFType(Uint16& i16) const
 {
-  // not supported
-  return false;
+    //not supported
+    return false;
 }
 
 /*
@@ -339,8 +463,14 @@ NOTES             :
 */
 Boolean IPInterface::getFrameType(Uint16& i16) const
 {
-  // not supported
-  return false;
+    /*
+       From CIM v2.6.0 MOF for CIM_BindsToLANEndpoint.FrameType
+          ValueMap {"0", "1", "2", "3", "4"},
+          Values {"Unknown", "Ethernet", "802.2", "SNAP", "Raw802.3"} ]
+    */
+
+    i16 = 1;  // Ethernet
+    return true;
 }
 
 
@@ -356,8 +486,21 @@ NOTES             :
 */
 String IPInterface::get_LANInterfaceName() const
 {
-  // This routine must be written to return a value.
-  return String::EMPTY;
+    // Get rid of everything after the colon (":") if the name is of the
+    // form "EIAX:Y", e.g. "EIA0:1".
+
+    Uint32 pos = _simpleIfName.find(":");
+
+    if (pos == PEG_NOT_FOUND)
+    {
+        return _simpleIfName;
+    }
+    else
+    {
+        String s = _simpleIfName;
+        s.remove(pos,PEG_NOT_FOUND);
+        return s;
+    }
 }
 
 /*
@@ -372,7 +515,17 @@ NOTES             :
 */
 Boolean IPInterface::bindsToLANInterface() const
 {
-  return false;
+    // if this is a local ("lo") interface, then it doesn't bind to
+    // an actual LAN Interface
+
+    if (_simpleIfName.find("lo") == PEG_NOT_FOUND)
+    {
+        return true;
+    }
+    else
+    {
+        return false;
+    }
 }
 
 
@@ -388,9 +541,71 @@ NOTES             :
 */
 void IPInterface::initSystemName()
 {
-  // Do nothing
+    //not supported
+
+}
+
+/*
+================================================================================
+NAME              : set_address
+DESCRIPTION       : Platform-specific routine to set the IP Address
+ASSUMPTIONS       : None
+PRE-CONDITIONS    :
+POST-CONDITIONS   :
+NOTES             :
+================================================================================
+*/
+void IPInterface::set_address(const String& addr)
+{
+    _address = addr;
+}
+
+/*
+================================================================================
+NAME              : set_subnetMask
+DESCRIPTION       : Platform-specific routine to set the Subnet Mask
+ASSUMPTIONS       : None
+PRE-CONDITIONS    :
+POST-CONDITIONS   :
+NOTES             :
+================================================================================
+*/
+void IPInterface::set_subnetMask(const String& snm)
+{
+    _subnetMask = snm;
+}
+
+/*
+================================================================================
+NAME              : set_protocol
+DESCRIPTION       : Platform-specific routine to set the IP Protocol
+ASSUMPTIONS       : None
+PRE-CONDITIONS    :
+POST-CONDITIONS   :
+NOTES             :
+================================================================================
+*/
+void IPInterface::set_protocol(const String& proto)
+{
+    _protocol = proto;
+}
+
+/*
+================================================================================
+NAME              : set_simpleIfName
+DESCRIPTION       : Platform-specific routine to set the Interface Name
+ASSUMPTIONS       : None
+PRE-CONDITIONS    :
+POST-CONDITIONS   :
+NOTES             :
+================================================================================
+*/
+void IPInterface::set_simpleIfName(const String& name)
+{
+    _simpleIfName = name;
 }
 
+
 /*
 ================================================================================
 NAME              : InterfaceList Constructor
@@ -403,6 +618,281 @@ NOTES             :
 */
 InterfaceList::InterfaceList()
 {
+    IPP_DEBUG_OUT("InterfaceList::InterfaceList()");
+    short channel;
+    short sck_parm[2] = {IPPROTO_UDP, SOCK_DGRAM};
+    int status;
+    short iosb [4];      /* I/O status block - should check errors */
+    char buffer[MYBUF], addr[64];
+    struct ifconf ifc = {MYBUF, buffer};
+    struct ifconf bad_ifc = {0, NULL};
+    struct ifreq *ifr, *next;
+    struct ip6ifreq *ifr6;
+
+    $DESCRIPTOR(inet_dev, "TCPIP$DEVICE");
+    struct
+    {
+        int cmd;
+        void *ptr;
+    } ioctl_desc = {NEW_SIOCGIFCONF, &ifc};
+    struct
+    {
+        int cmd;
+        void *ptr;
+    } bad_ioctl_desc = {NEW_SIOCGIFCONF, &bad_ifc};
+    struct
+    {
+        short len, param;
+        void *ptr;
+    }
+    p6 = {sizeof(ioctl_desc), TCPIP$C_IOCTL, &ioctl_desc};
+    struct
+    {
+        short len, param;
+        void *ptr;
+    }
+    bad_p6 = {sizeof(ioctl_desc), TCPIP$C_IOCTL, &bad_ioctl_desc};
+
+    status = sys$assign(&inet_dev, &channel, 0, 0);
+    if (!(status & 1))
+    {
+        IPP_DEBUG_OUT("Error in assigning the channel, "
+            "st: 0x" << hex << status);
+        throw CIMOperationFailedException(
+            "Error in assign the channel: "
+            + String(strerror(errno)));
+
+    }
+    try
+    {
+        status = sys$qiow(
+            EFN$C_ENF,          /* Event flag */
+            channel,            /* Channel number */
+            IO$_SETMODE,        /* I/O function */
+            iosb,               /* I/O status block */
+            0, 0, &sck_parm,    /* P1 socket creation param */
+            0, 0, 0, 0, 0);
+        if (status & 1)
+        {
+            status = iosb[0];
+        }
+        if (!(status & 1))
+        {
+            IPP_DEBUG_OUT("Error in setmode, st: 0x"
+                << hex << status);
+            throw CIMOperationFailedException(
+                "Error in setmode: " + String(strerror(errno)));
+        }
+
+        /* Find out the size of the structure, to show how that's done */
+        status = sys$qiow(
+            EFN$C_ENF, channel, IO$_SENSEMODE, iosb,
+            0, 0, 0, 0, 0, 0, 0, &bad_p6);
+        if (status & 1)
+        {
+            status = iosb[0];
+        }
+        if (!(status & 1))
+        {
+            IPP_DEBUG_OUT("Error in bad sensemode, st: 0x"
+                << hex << status);
+            throw CIMOperationFailedException(
+                "Error in bad sensemode: " + String(strerror(errno)));
+        }
+
+        IPP_DEBUG_OUT("Size of returned ifconf struct will be: "
+            << bad_ifc.ifc_len);
+
+        /* Now find out what other addresses are on the host */
+        status = sys$qiow(
+            EFN$C_ENF, channel, IO$_SENSEMODE, iosb,
+            0, 0, 0, 0, 0, 0, 0, &p6);
+        if (status & 1)
+        {
+            status = iosb[0];
+        }
+        if (!(status & 1))
+        {
+            IPP_DEBUG_OUT("Error in sensemode, st: 0x" << hex << status);
+            throw CIMOperationFailedException(
+                "Error in sensemode: " + String(strerror(errno)));
+        }
+
+        for (ifr = ifc.ifc_req ; ifr->ifr_name[0] ; ifr = next )
+        {
+            //IPInterface _ipif;
+            struct sockaddr_in *sin =
+                (struct sockaddr_in *)&ifr->ifr_addr;
+            struct sockaddr_in sad;
+            next = (struct ifreq *) (sin->sin_len + (char *)sin);
+            if (sin->sin_family == AF_INET)
+    {
+                IPInterface _ipif;
+                IPP_DEBUG_OUT(ifr->ifr_name
+                    << "ProtocolType: IPv4   "
+                    << "Addr: " << inet_ntoa(sin->sin_addr));
+                _ipif.set_simpleIfName(ifr->ifr_name);
+                _ipif.set_address(inet_ntoa(sin->sin_addr));
+                _ipif.set_protocol(PROTOCOL_IPV4);
+
+                /* Look up the network mask*/
+                /*for this particular address */
+                ioctl_desc.cmd = NEW_SIOCGIFNETMASK;
+                ioctl_desc.ptr = ifr;
+                ifr->ifr_addr.sa_len = sizeof(struct sockaddr_in);
+                ifr->ifr_addr.sa_family = AF_INET;
+                memcpy(&sad, sin, sizeof(struct sockaddr_in));
+                status = sys$qiow(
+                    EFN$C_ENF, channel, IO$_SENSEMODE, iosb,
+                    0, 0, 0, 0, 0, 0, 0, &p6);
+                if (status & 1)
+                {
+                    status = iosb[0];
+                }
+                if (!(status & 1))
+                {
+                    IPP_DEBUG_OUT("  no mask, err: 0x\n"
+                        << hex << status);
+                }
+                else
+                {
+                    _ipif.set_subnetMask(inet_ntoa(sin->sin_addr));
+                    IPP_DEBUG_OUT("   Msk: "
+                        << inet_ntoa(sin->sin_addr));
+                }
+
+                /* Now look up the broadcast */
+                /* address (same input as above) */
+                ioctl_desc.cmd = NEW_SIOCGIFBRDADDR;
+                memcpy(sin, &sad, sizeof(struct sockaddr_in));
+                status = sys$qiow(
+                    EFN$C_ENF, channel, IO$_SENSEMODE, iosb,
+                    0, 0, 0, 0, 0, 0, 0, &p6);
+                if (status & 1)
+                {
+                    status = iosb[0];
+                }
+                if (!(status & 1))
+                {
+                    IPP_DEBUG_OUT("  no broadcast, err: 0x" << hex << status);
+                }
+                else
+                {
+                    IPP_DEBUG_OUT("   Brd: "
+                        << inet_ntoa(sin->sin_addr));
+                }
+                // Add another IP interface to the list
+                _ifl.push_back(_ipif);
+            }
+            else if (sin->sin_family == AF_INET6)
+            {
+                IPInterface _ipif;
+                struct sockaddr_in6 *sin6 =
+                    (struct sockaddr_in6 *)&ifr->ifr_addr;
+                struct sockaddr_in6 sad6;
+                IPP_DEBUG_OUT(ifr->ifr_name
+                    << "ProtocolType: IPv6   "
+                    << "Addr: " << inet_ntoa(sin->sin_addr));
+                _ipif.set_simpleIfName(ifr->ifr_name);
+                inet_ntop(TCPIP$C_AF_INET6,
+                    &sin6->sin6_addr,
+                    addr,
+                    sizeof(addr));
+                _ipif.set_address(addr);
+                _ipif.set_protocol(PROTOCOL_IPV6);
+
+                IPP_DEBUG_OUT(ifr->ifr_name
+                    << "ProtocolType: IPv6   "
+                    << "Addr: " << addr);
+
+                /* Look up the network mask for this address */
+                ioctl_desc.cmd = NEW_SIOCGIFNETMASK;
+                ioctl_desc.ptr = ifr;
+                memcpy(&sad, sin, sizeof(struct sockaddr_in6));
+                status = sys$qiow(
+                    EFN$C_ENF, channel, IO$_SENSEMODE, iosb,
+                    0, 0, 0, 0, 0, 0, 0, &p6);
+                if (status & 1)
+                {
+                    status = iosb[0];
+                }
+                if (!(status & 1))
+                {
+                    IPP_DEBUG_OUT("  no mask, err: 0x"
+                        << hex << status);
+                }
+                else
+                {
+                    inet_ntop(
+                        TCPIP$C_AF_INET6,
+                        &sin6->sin6_addr,
+                        addr,
+                        sizeof(addr));
+                    _ipif.set_subnetMask(addr);
+                    IPP_DEBUG_OUT("   Msk: " << addr);
+                }
+
+                /* Now look up the broadcast address */
+                ioctl_desc.cmd = NEW_SIOCGIFBRDADDR;
+                memcpy(sin, &sad, sizeof(struct sockaddr_in6));
+                status = sys$qiow(
+                    EFN$C_ENF, channel, IO$_SENSEMODE, iosb,
+                    0, 0, 0, 0, 0, 0, 0, &p6);
+                if (status & 1)
+                {
+                    status = iosb[0];
+                }
+                if (!(status & 1))
+                {
+                    IPP_DEBUG_OUT("  no broadcast, err: 0x"
+                        << hex << status);
+                }
+                else
+                {
+                    inet_ntop(
+                        TCPIP$C_AF_INET6,
+                        &sin6->sin6_addr,
+                        addr,
+                        sizeof(addr));
+                    IPP_DEBUG_OUT("   Brd: " << addr);
+                }
+                _ifl.push_back(_ipif);   // Add another IP interface to the list
+            }
+            else if (sin->sin_family == AF_LINK)
+            {
+                IPP_DEBUG_OUT("Ignoring AF_LINK interface");
+            }
+            else
+            {
+                IPP_DEBUG_OUT("Ignoring interface type: "
+                    << sin->sin_family);
+            }
+
+        }
+    }
+    catch (...)
+    {
+        status = sys$dassgn(channel);
+        if (!(status & 1))
+        {
+            IPP_DEBUG_OUT("Error in dassgn, st: 0x"
+                          << hex << status);
+            throw CIMOperationFailedException(
+                "Inside handler, error in deassigning the channel: "
+                + String(strerror(errno)));
+        }
+        throw;
+    }
+    status = sys$dassgn(channel);
+    if (!(status & 1))
+    {
+        IPP_DEBUG_OUT("Error in dassgn, st: 0x"
+                      << hex << status);
+        throw CIMOperationFailedException(
+            "Error in deassigning the channel: "
+            + String(strerror(errno)));
+    }
+    IPP_DEBUG_OUT("InterfaceList::InterfaceList() -- done");
 }
 
 /*
@@ -419,7 +909,6 @@ InterfaceList::~InterfaceList()
 {
 }
 
-
 /*
 ================================================================================
 NAME              : findInterface
@@ -434,7 +923,23 @@ Boolean InterfaceList::findInterface(
     const String &ifName,
     IPInterface &ipIfInst) const
 {
-    // Always return interface not found
+    // ifName has the format <Protocol>_<InterfaceName>,
+    // for example "IPv4_l00".
+
+    int i;
+
+    for (i = 0; i < _ifl.size(); i++)
+    {
+        String s;
+
+        if (_ifl[i].getName(s) && String::equal(s,ifName))
+        {
+            ipIfInst = _ifl[i];
+            return true;
+        }
+    }
+
+    // Interface not found
     return false;
 }
 
@@ -451,10 +956,7 @@ NOTES             :
 */
 IPInterface InterfaceList::getInterface(const int index) const
 {
-    // give an interface (this should never get called since size will
-    // always be zero).
-    IPInterface i;
-    return i;
+    return _ifl[index];
 }
 
 /*
@@ -469,8 +971,7 @@ NOTES             :
 */
 int InterfaceList::size() const
 {
-    // no interfaces
-    return 0;
+    return _ifl.size();
 }
 
 /////////////////////////////////////////////////////////////////////////
@@ -499,8 +1000,8 @@ NOTES             :
 */
 Boolean IPRoute::getCaption(String& s) const
 {
-  s = String::EMPTY;
-  return true;
+    s = _destAddr;
+    return true;
 }
 
 /*
@@ -515,8 +1016,12 @@ NOTES             :
 */
 Boolean IPRoute::getDescription(String& s) const
 {
-  s = String::EMPTY;
-  return true;
+    s = "IP Route for Destination Address: ";
+    s.append(_destAddr);
+    s.append(" (");
+    s.append(_protocolType);
+    s.append(")");
+    return true;
 }
 
 /*
@@ -531,11 +1036,11 @@ NOTES             :
 */
 Boolean IPRoute::getInstallDate(CIMDateTime& d) const
 {
-  // Not supported. This property is inherited from
-  // CIM_ManagedSystemElement, but has no useful meaning
-  // for an IP Route.
+    // Not supported. This property is inherited from
+    // CIM_ManagedSystemElement, but has no useful meaning
+    // for an IP Route.
 
-  return false;
+    return false;
 }
 
 /*
@@ -550,8 +1055,8 @@ NOTES             :
 */
 Boolean IPRoute::getName(String& s) const
 {
-  // not supported
-  return false;
+    s = _destAddr;
+    return true;
 }
 
 /*
@@ -566,10 +1071,10 @@ NOTES             :
 */
 Boolean IPRoute::getStatus(String& s) const
 {
-  // This property, inherited from CIM_ManagedSystemElement,
-  // is not relevant.
+    // This property, inherited from CIM_ManagedSystemElement,
+    // is not relevant.
 
-  return false;
+    return false;
 }
 
 /*
@@ -584,8 +1089,8 @@ NOTES             :
 */
 Boolean IPRoute::getDestinationAddress(String& s) const
 {
-  // not supported
-  return false;
+    s = _destAddr;
+    return true;
 }
 
 /*
@@ -600,8 +1105,8 @@ NOTES             :
 */
 Boolean IPRoute::getDestinationMask(String& s) const
 {
-  // not supported
-  return false;
+    s = _destMask;
+    return true;
 }
 
 /*
@@ -616,8 +1121,8 @@ NOTES             :
 */
 Boolean IPRoute::getNextHop(String& s) const
 {
-  // not supported
-  return false;
+    s = _nextHop;
+    return true;
 }
 
 /*
@@ -632,8 +1137,8 @@ NOTES             :
 */
 Boolean IPRoute::getIsStatic(Boolean& s) const
 {
-  // not supported
-  return false;
+    // not supported
+    return false;
 }
 
 /*
@@ -648,10 +1153,98 @@ NOTES             :
 */
 Boolean IPRoute::getAddressType(Uint16& i16) const
 {
-  // not supported
-  return false;
+    /*
+        From CIM v2.6.0 MOF for CIM_IPRoute.AddressType:
+           ValueMap {"0", "1", "2"},
+           Values {"Unknown", "IPv4", "IPv6"} ]
+    */
+
+    if (String::equal(_protocolType,PROTOCOL_IPV4))
+    {
+        i16 = 1;  // IPv4
+        return true;
+    }
+    else if (String::equal(_protocolType,PROTOCOL_IPV6))
+    {
+        i16 = 2;  // IPv6
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+/*
+================================================================================
+NAME              : set_destAddress
+DESCRIPTION       : Platform-specific routine to set the IP Destination Address
+ASSUMPTIONS       : None
+PRE-CONDITIONS    :
+POST-CONDITIONS   :
+NOTES             :
+================================================================================
+*/
+void IPRoute::set_destAddr(const String& addr)
+{
+    _destAddr = addr;
+}
+
+/*
+================================================================================
+NAME              : set_destMask
+DESCRIPTION       : Platform-specific routine to set the IP Destination Mask
+ASSUMPTIONS       : None
+PRE-CONDITIONS    :
+POST-CONDITIONS   :
+NOTES             :
+================================================================================
+*/
+void IPRoute::set_destMask(const String& dm)
+{
+    _destMask = dm;
+}
+
+/*
+================================================================================
+NAME              : set_nextHop
+DESCRIPTION       : Platform-specific routine to set the Next Hop Address
+ASSUMPTIONS       : None
+PRE-CONDITIONS    :
+POST-CONDITIONS   :
+NOTES             :
+================================================================================
+*/
+void IPRoute::set_nextHop(const String& nh)
+{
+    _nextHop = nh;
 }
 
+/*
+================================================================================
+NAME              : set_protocolType
+DESCRIPTION       : Platform-specific routine to set the Protocol Type
+ASSUMPTIONS       : None
+PRE-CONDITIONS    :
+POST-CONDITIONS   :
+NOTES             :
+================================================================================
+*/
+void IPRoute::set_protocolType(const String& pt)
+{
+    _protocolType = pt;
+}
+
+/*
+================================================================================
+NAME              : RouteList Constructor
+DESCRIPTION       : Build the list of IP Routes
+ASSUMPTIONS       : None
+PRE-CONDITIONS    :
+POST-CONDITIONS   :
+NOTES             :
+================================================================================
+*/
+
 /*
 ================================================================================
 NAME              : RouteList Constructor
@@ -664,6 +1257,176 @@ NOTES             :
 */
 RouteList::RouteList()
 {
+    FILE* fp = NULL;
+    char buffer[257];
+    int lineNo = 0,foundNetProtoType=0,ret=0;;
+    static pthread_mutex_t sIplock = PTHREAD_MUTEX_INITIALIZER;
+    const char *networkType[] = {"TCPIP" , "MultiNet" , "TCPware"};
+
+    IPP_DEBUG_OUT("RouteList::RouteList()");
+
+    try
+    {
+        /* Lock the mutex sIplock */
+        pthread_mutex_lock (&sIplock);
+
+        /* TCPIP */
+        ret = _findNetworkProtocolType(
+            &foundNetProtoType,
+            networkType[0]);
+        if (ret != 0)
+        {
+            switch (ret)
+            {
+                case 1:
+                    throw CIMOperationFailedException(
+                        "Error in Opening the file WBEM_TMP:mydata.txt: "
+                        + String(strerror(errno)));
+                    break;
+                default:
+                    throw CIMOperationFailedException(
+                        "Error in function findNetworkProtocolType  "
+                        + String(strerror(errno)));
+            }
+        }
+
+        /* MUltinet */
+        if (foundNetProtoType != 1)
+        {
+            ret = _findNetworkProtocolType(
+                &foundNetProtoType,
+                networkType[1]);
+            if (ret != 0)
+            {
+                switch (ret)
+                {
+                    case 1:
+                        throw CIMOperationFailedException(
+                            "Error in Opening the file WBEM_TMP:mydata.txt: "
+                            + String(strerror(errno)));
+                        break;
+
+                    default:
+                        throw CIMOperationFailedException(
+                            "Error in function findNetworkProtocolType  "
+                            + String(strerror(errno)));
+                }
+            }
+        }
+
+        /* Test for TCPware */
+        if (foundNetProtoType != 1)
+        {
+            ret = _findNetworkProtocolType(
+                &foundNetProtoType,
+                networkType[2]);
+            if (ret != 0)
+            {
+                switch (ret)
+                {
+                    case 1:
+                        throw CIMOperationFailedException(
+                            "Error in Opening the file WBEM_TMP:mydata.txt: "
+                            + String(strerror(errno)));
+                        break;
+
+                    default:
+                        throw CIMOperationFailedException(
+                            "Error in function findNetworkProtocolType  "
+                            + String(strerror(errno)));
+                }
+            }
+        }
+
+        if (foundNetProtoType != 1)
+        {
+            system("delete WBEM_TMP:mydata.txt;*");
+            throw CIMOperationFailedException(
+                "Error in finding the Network Protocol Type  "
+                + String(strerror(errno)));
+        }
+
+        /* Open  Start Parsing the contains of txt file */
+        fp = fopen ("WBEM_TMP:mydata.txt", "r");
+
+        if (NULL == fp)
+        {
+            IPP_DEBUG_OUT("Unable to open the file WBEM_TMP:mydata.txt");
+            throw CIMOperationFailedException(
+                "Error in Opening the file WBEM_TMP:mydata.txt: "
+                + String(strerror(errno)));
+        }
+
+        while (!feof(fp))
+        {
+            char *temp = NULL;
+            if (NULL == fgets (buffer, 257, fp))
+            {
+                break;
+            }
+            else
+            {
+                string  line(buffer);
+
+                if ((line.at(0) == 'R') || (line.at(0) == 'D') ||
+                    (line.at(0) == ' ' &&
+                    (line.at(1) == 'T' || line.at(1) == 'D' ||
+                    line.at(1) == ' ' || line.at(1) == '-')) ||
+                    (line.at(0) == '\n') ||(line.at(0) == 'M') ||
+                    (line.at(0) == '-') || (line.at(0) == 'T'))
+                {
+                    continue;
+                }
+                else
+                {
+                    IPRoute _ipr;
+                    ipInfo ipInfoStr = {"","",""};
+
+                    /* process each line and Create the IP
+                    Route info  List entries */
+                    ret = _getIpRoutingInfo(line,&ipInfoStr);
+
+                    if ( ret != 0)
+                    {
+                        throw CIMOperationFailedException(
+                            "Error in function getIpRoutingInfo  "
+                            + String(strerror(errno)));
+                    }
+                    /* set the destination address */
+                    _ipr.set_destAddr(ipInfoStr.destAddr.data());
+
+                    /* set the destination Mask */
+                    _ipr.set_destMask(ipInfoStr.subnetMask.data());
+
+                    /* set the nextHop */
+                    _ipr.set_nextHop(ipInfoStr.nextHop.data());
+
+                    /* set the  protocolType */
+                    _ipr.set_protocolType(PROTOCOL_IPV4);
+
+                    // Add another IP Route to the list
+                    _iprl.push_back(_ipr);
+                }
+            }
+        }
+        fclose(fp);
+        system("delete WBEM_TMP:mydata.txt;*");
+        /* UnLock the mutex sIplock */
+        pthread_mutex_unlock (&sIplock);
+    }
+    catch (...)
+    {
+        /* check and close file pointer, if it's still opened */
+        if (NULL != fp)
+        {
+            fclose(fp);
+            system("delete WBEM_TMP:mydata.txt;*");
+        }
+        /* UnLock the mutex sIplock */
+        pthread_mutex_unlock (&sIplock);
+        throw;
+    }
+
 }
 
 /*
@@ -680,7 +1443,6 @@ RouteList::~RouteList()
 {
 }
 
-
 /*
 ================================================================================
 NAME              : findRoute
@@ -698,7 +1460,31 @@ Boolean RouteList::findRoute(
     const Uint16 &addrType,
     IPRoute &ipRInst) const
 {
-    // Always return route not found
+    int i;
+
+    for (i = 0; i < _iprl.size(); i++)
+    {
+        String sda, sdm;
+        Uint16 sat;
+
+        if (_iprl[i].getDestinationAddress(sda) &&
+            String::equal(sda,destAddr) &&
+            _iprl[i].getDestinationMask(sdm) &&
+            String::equal(sdm,destMask) &&
+            _iprl[i].getAddressType(sat) &&
+            sat == addrType)
+        {
+            ipRInst = _iprl[i];
+            return true;
+        }
+    }
+
+    IPP_DEBUG_OUT("RouteList::findRoute(): NOT FOUND destAddr=" << destAddr <<
+        ", destMask=" << destMask <<
+        ", addrType=" << addrType);
+
+    // IP Route not found
+
     return false;
 }
 
@@ -715,10 +1501,7 @@ NOTES             :
 */
 IPRoute RouteList::getRoute(const int index) const
 {
-    // give a route (this should never get called since size will
-    // always be zero).
-    IPRoute i;
-    return i;
+    return _iprl[index];
 }
 
 /*
@@ -733,7 +1516,7 @@ NOTES             :
 */
 int RouteList::size() const
 {
-    return 0;
+    return _iprl.size();
 }
 
 /////////////////////////////////////////////////////////////////////////
@@ -1287,4 +2070,280 @@ int RSApList::size() const
 {
     return 0;
 }
+/*
+================================================================================
+NAME              : _findNetworkProtocolType.
+DESCRIPTION       : Find the correct Network Protocol Type.
+ASSUMPTIONS       : None.
+PRE-CONDITIONS    :
+POST-CONDITIONS   :
+NOTES             :
+================================================================================
+*/
+
+static int _findNetworkProtocolType(int *findNetProtoType,const char *Str)
+{
+    FILE* fp = NULL;
+    char buffer[257];
+    const string networkStr=Str;
+    if (networkStr.compare("TCPIP")== 0)
+    {
+        system("pipe tcpip netstat -rn | "
+            "copy sys$input WBEM_TMP:mydata.txt");
+    }
+    else if (networkStr.compare("MultiNet")== 0)
+    {
+        system(
+            "pipe multinet show/route/NOSYMBOLIC_ADDRESSES | "
+            "copy sys$input WBEM_TMP:mydata.txt");
+    }
+    else if (networkStr.compare("TCPware")== 0)
+    {
+        system("pipe @tcpware:netstat.com | "
+            "copy sys$input WBEM_TMP:mydata.txt");
+    }
+    else
+    {
+        IPP_DEBUG_OUT("No match found for networkStr ");
+        return 2;
+    }
+
+    /* open the file */
+    fp = fopen ("WBEM_TMP:mydata.txt", "r");
+
+    if (NULL == fp)
+    {
+        IPP_DEBUG_OUT("Unable to open the file WBEM_TMP:mydata.txt ");
+        return 1;
+    }
+    while (!feof(fp))
+    {
+        if (NULL == fgets (buffer, 257, fp))
+        {
+            break;
+        }
+        else
+        {
+            string  line(buffer);
+            string::size_type pos1 = line.find_first_not_of(" \t\r\n");
+            string::size_type pos2;
+
+            if (networkStr.compare("TCPware")== 0)
+            {
+                pos2 = line.find_first_of("(");
+            }
+            else
+            {
+                pos2 = line.find_first_of(" \t\r\n");
+            }
+            string substring = line.substr(
+                pos1 == string::npos ? 0 : pos1,
+                pos2 == string::npos ? line.length() - 1 : pos2 - pos1);
+            if (substring.compare("Routing")== 0)
+            {
+                *findNetProtoType = 1;
+                IPP_DEBUG_OUT("TCP/IP Configurartion");
+            }
+            else if (substring.compare("MultiNet") == 0)
+            {
+                *findNetProtoType = 1;
+                IPP_DEBUG_OUT("Multinet Configuration");
+            }
+            else if (substring.compare("TCPware") == 0)
+            {
+                *findNetProtoType = 1;
+                IPP_DEBUG_OUT("TCPware Configuration");
+            }
+            else
+            {
+                IPP_DEBUG_OUT("Error in finding the Networkprotocol type");
+                fclose(fp);
+                return 2;
+            }
+            break;
+        }
+    }
+    if (*findNetProtoType == 1)
+    {
+        fclose(fp);
+    }
+    else
+    {
+        fclose(fp);
+        system("delete WBEM_TMP:mydata.txt;*");
+        *findNetProtoType = 0;
+    }
+    return 0;
 
+}
+
+/*
+===============================================================================
+NAME              : _getIpRoutingInfo.
+DESCRIPTION       : Parse the input line and fill the IP Route info.
+ASSUMPTIONS       : None.
+PRE-CONDITIONS    :
+POST-CONDITIONS   :
+NOTES             :
+===============================================================================
+*/
+
+static int _getIpRoutingInfo(string lineStr,ipInfo *ipInfoStr)
+{
+    /* trim the line */
+    string line = "";
+    line=lineStr;
+    string::size_type pos1 = line.find_first_not_of(" \t\r\n");
+    string::size_type pos2 = line.find_last_not_of(" \t\r\n");
+    string substring = line.substr(
+        pos1 == string::npos ? 0 : pos1,
+        pos2 == string::npos ? line.length() - 1 : pos2 - pos1 + 1);
+    int pos = 0;
+    string temp;
+    while (!substring.empty())
+    {
+
+        string::size_type pos3 =
+            substring.find_first_not_of(" \t\r\n");
+        string::size_type pos0 = substring.find_last_of(")");
+        string::size_type pos4;
+        if (pos0 == string::npos)
+        {
+            pos4 = substring.find_first_of(" \t\r\n");
+        }
+        else
+        {
+            pos4 = pos0+1;
+        }
+        if (pos4 == string::npos)
+        {
+            break;
+        }
+        else
+        {
+            temp=substring.substr(pos3,pos4);
+        }
+        /* find the position of mask string */
+        string::size_type pos8=temp.find("/");
+        switch (pos)
+        {
+            case 0:
+                if ((temp.compare("default")== 0) ||
+                    (temp.compare("all others (default)")== 0))
+                {
+                    ipInfoStr->destAddr="0.0.0.0";
+                    ipInfoStr->subnetMask="0.0.0.0";
+                }
+                else if (pos8 != string::npos)
+                {
+                    int cnt=0;
+                    char ch;
+                    char *tempstr=NULL;
+                    char *str1=NULL,*str2=NULL;
+                    tempstr=strdup(temp.data());
+                    str1=strtok(tempstr,"/");
+                    str2=strtok(NULL,"/");
+                    for (int j=0;j<strlen(str1);j++)
+                    {
+                        ch=str1[j];
+                        switch (ch)
+                        {
+                            case '.':
+                                cnt++;
+                        }
+                    }
+                    int k = atoi(str2);
+                    const char *subnetMaskParts[] =
+                        {"0", "128", "192", "224", "240",
+                         "248", "252", "254", "255"
+                        };
+                    switch (cnt)
+                    {
+                        case 0:
+                            ipInfoStr->subnetMask = subnetMaskParts[k];
+                            ipInfoStr->subnetMask.append(".0.0.0");
+                            strcat(str1,".0.0.0");
+                            ipInfoStr->destAddr=str1;
+                            break;
+                        case 1:
+                            ipInfoStr->subnetMask="255.";
+                            ipInfoStr->subnetMask.append(subnetMaskParts[k-8]);
+                            ipInfoStr->subnetMask.append(".0.0");
+                            strcat(str1,".0.0");
+                            ipInfoStr->destAddr=str1;
+                            break;
+
+                        case 2:
+                            ipInfoStr->subnetMask="255.255.";
+                            ipInfoStr->subnetMask.append(
+                                subnetMaskParts[k-16]);
+                            ipInfoStr->subnetMask.append(".0");
+                            strcat(str1,".0");
+                            ipInfoStr->destAddr=str1;
+                            break;
+                        case 3:
+                            ipInfoStr->destAddr=str1;
+                            if (k < 8)
+                            {
+                                ipInfoStr->subnetMask = subnetMaskParts[k];
+                                ipInfoStr->subnetMask.append(".0.0.0");
+                            }
+                            else if (k < 16)
+                            {
+                                ipInfoStr->subnetMask = "255.";
+                                ipInfoStr->subnetMask.append(
+                                    subnetMaskParts[k-8]);
+                                ipInfoStr->subnetMask.append(".0.0");
+                            }
+                            else if (k < 24)
+                            {
+                                ipInfoStr->subnetMask = "255.255.";
+                                ipInfoStr->subnetMask.append(
+                                    subnetMaskParts[k-16]);
+                                ipInfoStr->subnetMask.append(".0");
+                            }
+                            else
+                            {
+                                ipInfoStr->subnetMask="255.255.255.";
+                                ipInfoStr->subnetMask.append(
+                                    subnetMaskParts[k-24]);
+                            }
+                    }
+                    free(tempstr);
+                }
+                else if (temp.compare("127.0.0.0") == 0)
+                {
+                    ipInfoStr->destAddr=temp.data();
+                    ipInfoStr->subnetMask="255.0.0.0";
+                }
+                else
+                {
+                    ipInfoStr->destAddr=temp.data();
+                    ipInfoStr->subnetMask="0.0.0.0";
+                }
+                IPP_DEBUG_OUT("DestAddr: " << ipInfoStr->destAddr.data()
+                              << "DestMask: " << ipInfoStr->subnetMask.data());
+
+                pos++;
+                break;
+            case 1:
+                ipInfoStr->nextHop=temp.data();
+                IPP_DEBUG_OUT("nextHop: " << ipInfoStr->nextHop.data());
+                pos++;
+                break;
+            case 3:
+                IPP_DEBUG_OUT("ProtocolType: IPv4");
+                pos++;
+                break;
+            default:
+                pos++;
+        }
+        string::size_type pos5 = substring.find_last_of("0123456789UIL");
+        substring=substring.substr(pos4,pos5-pos4+1);
+        string::size_type pos6 = substring.find_first_not_of(" \t\r\n");
+        string::size_type pos7 = substring.find_last_of("0123456789UIL");
+        substring=substring.substr(pos6,pos7-pos6+1);
+    }
+    return 0;
+
+}
index 0c70a9dc91c33653b13ce0997bd0415f1746ae20..2a6cebe6c3bd0637cec0ec21dd2c88d1895f050d 100755 (executable)
@@ -17,7 +17,7 @@
 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 // sell copies of the Software, and to permit persons to whom the Software is
 // furnished to do so, subject to the following conditions:
-// 
+//
 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 // =============================================================================
 
 #include <Pegasus/Provider/CIMInstanceProvider.h>
+#include <vector>         // vector container
+#include <sys/types.h>
+#define _SOCKADDR_LEN
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <in.h>
+#include <in6.h>
+#include <if.h>
+#include <descrip.h>
+#include <iodef.h>
+#include <efndef.h>
+#include <sys$library:tcpip$inetdef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <socket.h>
+#include <assert.h>
+#include <descrip.h>
+#include <syidef.h>
+#include <jpidef.h>
+#include <pscandef.h>
+#include <lib$routines.h>
+#include <starlet.h>
+#include <stsdef.h>
+#include <ssdef.h>
+#include <libdtdef.h>
+#include <lnmdef.h>
+#include <netdb.h>
+#include <time.h>
+#include <tis.h>
+#include <pthread.h>
+#include <vector>
+#include <Pegasus/Client/CIMClient.h>
+#include <platforms/vms/vms_utility_routines.h>
+#include <Pegasus/Common/Mutex.h>
 
 PEGASUS_USING_STD;
 PEGASUS_USING_PEGASUS;
@@ -54,6 +91,20 @@ PEGASUS_USING_PEGASUS;
 #define PROTOCOL_IPV4_V6  "IPv4/v6"
 
 
+#define MYBUF 8192
+#define NEW_SIOCGIFCONF ((0x80000000|0x40000000) | \
+    ((sizeof(struct ifconf) & 0x1fff) << 16) | ((('i')) << 8) | ((36)))
+#define NEW_SIOCGIFNETMASK ((0x80000000|0x40000000) | ((sizeof(struct ifreq) \
+    & 0x1fff) << 16) | ((('i')) << 8) | ((37)))
+#define NEW_SIOCGIFBRDADDR ((0x80000000|0x40000000) | ((sizeof(struct ifreq) & \
+    0x1fff) << 16) | ((('i')) << 8) | ((35)))
+
+#ifdef IPPROVIDER_DEBUG
+# define IPP_DEBUG_OUT(x) cout << x << endl
+#else
+# define IPP_DEBUG_OUT(x)
+#endif
+
 // =============================================================================
 // Type Definitions.
 // =============================================================================
@@ -104,6 +155,14 @@ public:
     void set_subnetMask(const String& snm);
     void set_protocol(const String& proto);
     void set_simpleIfName(const String& name);
+private:
+
+    String _address;           // dot (IPv4) colon (IPv6) notation
+    String _subnetMask;        // dot (IPv4) notation
+    String _protocol;          // e.g. IPv4, IPv6
+    String _simpleIfName;      // e.g. lan0, lan0:1, lan1, lo0
+    static String _hostname;   // fully qualified hostname
+
 
 };
 
@@ -126,6 +185,9 @@ public:
 
     // Number of Elements in the InterfaceList
     int size() const;
+private:
+
+    vector<IPInterface> _ifl;
 
 };
 
@@ -155,6 +217,13 @@ public:
     void set_destMask(const String& mask);
     void set_nextHop(const String& nhop);
     void set_protocolType(const String& pt);
+private:
+    String _destAddr;          // dot (IPv4) or colon (IPv6) notation
+    String _destMask;          // dot (IPv4) or colon (IPv6) notation
+    String _nextHop;           // dot (IPv4) or colon (IPv6) notation
+    String _protocolType;      // IPv4 or IPv6
+    static String _hostname;   // fully qualified hostname
+
 
 };
 
@@ -180,6 +249,9 @@ public:
 
     // Number of Elements in the IP Route
     int size() const;
+private:
+
+    vector<IPRoute> _iprl;
 
 };
 
@@ -196,7 +268,7 @@ public:
     Boolean getDescription(String&) const;
     Boolean getInstallDate(CIMDateTime&) const;
     Boolean getName(String&) const;
-    Boolean getStatus(String&) const;  
+    Boolean getStatus(String&) const;
     Boolean getDestinationAddress(String&) const;
     Boolean getDestinationMask(String&) const;
     Boolean getRouteDerivation(Uint16&) const;
@@ -221,6 +293,7 @@ public:
     void set_destMask(const String& dm);
     void set_protocolType(const String& pt);
 
+
 };
 
 class NextHopRouteList
@@ -239,7 +312,7 @@ public:
 
     // Method to get a particular element based on an index
     NextHopIPRoute getRoute(const int index) const;
+
     // Number of Elements in the IP Route
     int size() const;