/**
    Set user name
*/
    void SCXUser::SetName()
    {
        struct passwd pwd;
        struct passwd *ppwd = NULL;
        long bufSize = sysconf(_SC_GETPW_R_SIZE_MAX);

        // Sanity check - all platforms have this, but never hurts to be certain

        if (bufSize < 1024)
        {
            bufSize = 1024;
        }

        std::vector<char> buf(bufSize);

        // Use reentrant form of getpwuid (it's reentrant, and it pacifies purify)
#if !defined(sun)
		int rc = getpwuid_r (m_uid, &pwd, &buf[0], buf.size (), &ppwd);
		if (rc != 0)
		{
			ppwd = NULL;
		}
#else
        ppwd = getpwuid_r(m_uid, &pwd, &buf[0], buf.size());
#endif

        if (ppwd)
        {
            m_name = StrFromMultibyte(ppwd->pw_name);
        }
        else
        {
            m_name = StrFrom(m_uid);
        }
    }
    /**
       Recursively translate all environment variables with their actual values.

       \param[in] input String to remove environment variables from.
       \returns String where all environment variables have been translated.
       \throws SCXRunAsConfigurationException if a loop in environmen variables is suspected.
    */
    const std::wstring RunAsConfigurator::ResolveEnvVars(const std::wstring& input) const
    {
        static const std::wstring allowedVarNameChars(L"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_");
        
        // We need to know when we run into an infinite loop.
        int numberOfVariableSubstitutionsAllowed = 100;
        std::wstring output(input);
        for (std::wstring::size_type varstart = output.find(L'$');
             varstart != std::wstring::npos;
             varstart = output.find(L'$', varstart))
        {
            std::wstring variableName;
            std::wstring::size_type varend;
            if (L'{' == output[varstart + 1])
            {
                varend = output.find(L'}', varstart + 2);
                if (varend == std::wstring::npos)
                {
                    throw SCXRunAsConfigurationException(
                        std::wstring(L"Configuration value ")
                        .append(input)
                        .append(L" seems to be malformed. '{' and '}' are not matching."), SCXSRCLOCATION);
                }
                variableName = output.substr(varstart + 2, varend - 2 - varstart);
            }
            else
            {
                varend = output.find_first_not_of(allowedVarNameChars, varstart + 1);
                if (varend == std::wstring::npos)
                {
                    varend = output.size();
                }
                --varend; // Index of the last character in the variable name.

                variableName = output.substr(varstart + 1, varend - varstart);
            }

            const char *variableValuePtr = ::getenv(StrToMultibyte(variableName).c_str());
            if (0 == variableValuePtr)
            {
                output.erase(varstart, varend - varstart + 1);
            }
            else
            {
                output.replace(varstart, varend - varstart + 1, StrFromMultibyte(variableValuePtr));
            }

            --numberOfVariableSubstitutionsAllowed;
            if (0 == numberOfVariableSubstitutionsAllowed)
            {
                throw SCXRunAsConfigurationException(
                    std::wstring(L"Configuration value ")
                    .append(input)
                    .append(L" seems to contain environment variables that form an infinite recursion loop."), SCXSRCLOCATION);
            }
        }
        return output;
    }
    /**
       Gets the Version
       \param[out]  ver
       \returns     true if this value is supported by the implementation

       According to the CIM model:
       A string describing the Operating System's version
       number. The format of the version information is as follows:
       [Major Number].[Minor Number].[Revision] or
       [Major Number].[Minor Number].[Revision Letter].
    */
    bool OSInstance::GetVersion(std::wstring& ver) const
    {
#if defined(SCX_UNIX)
        if (!m_unameIsValid)
        {
            return false;
        }
        ver.assign(StrFromMultibyte(m_unameInfo.release));
        return true;
#else
        #error Platform not supported
#endif
    }
    /**
       Returns the architecture of the current platform, as uname(3) reports it
    
       \returns     String with uname result
       \throws      < One for each exception from this function >
    
    */
    std::wstring SCXOSTypeInfo::GetUnameArchitectureString() const
    {
        assert(m_unameIsValid);
        
#if defined(linux) || defined(hpux) || defined(macos)
        if (m_unameIsValid)
        {
            return StrFromMultibyte(m_unameInfo.machine);
        }
#elif defined(sun)
        char buf[256];
        if (0 < sysinfo(SI_ARCHITECTURE, buf, sizeof(buf)))
        {
            return StrFromMultibyte(buf);
        }
#elif defined(aix)
        // Can't find a generic way to get this property on AIX. This is however the
        // only one supported right now.
        return L"powerpc";
#else
#error "Platform not supported"
#endif
        return L"Platform not supported";
    }
    /**
       Gets the OtherTypeDescription
       \param[out]  otd
       \returns     true if this value is supported by the implementation

       \note Linux: Note that the implementation is just plain wrong with
       regard to how this property is defined by the CIM model.

       According to the CIM model:
       A string describing the manufacturer and OperatingSystem
       type - used when the OperatingSystem property, OSType, is
       set to 1 or 59 (\"Other\" or \"Dedicated\"). The format of
       the string inserted in OtherTypeDescription should be
       similar in format to the Values strings defined for OSType.
       OtherTypeDescription should be set to NULL when OSType is
       any value other than 1 or 59.
    */
    bool OSInstance::GetOtherTypeDescription(std::wstring& otd) const
    {
#if defined(SCX_UNIX)
        if (!m_unameIsValid)
        {
            return false;
        }

        string tmp(m_unameInfo.release);
        tmp.append(" ");
        tmp.append(m_unameInfo.version);
        otd.assign(StrFromMultibyte(tmp));
        return true;
#else
        #error Platform not supported
#endif
    }
    /**
       Returns the architecture of the platform, e.g. PA-Risc, x86 or SPARC
    
       \returns   String with the architecture of the platform
    
    */
    std::wstring SCXOSTypeInfo::GetArchitectureString() const
    {
#if defined(hpux)
#if defined(hppa)
        return L"PA-Risc";
#else
        return L"IA64";
#endif // defined(hpux)

#elif defined(linux)

        unsigned short bitSize = 0;
        try
        {
            SystemInfo sysInfo;
            sysInfo.GetNativeBitSize(bitSize);
        }
        catch (SCXCoreLib::SCXException &e)
        {
            SCX_LOGERROR(m_log, StrAppend( StrAppend(L"Failure in SystemInstance::GetNativeBitSize: ", e.What()), e.Where()));
        }

        if (32 == bitSize)
        {
            return L"x86";
        }
        else if (64 == bitSize) 
        {
            return L"x64";
        }
        else 
        {
            assert(!"Unknown architecture");
            return L"Unknown";
        }

#elif defined(sun)
            
#if defined(sparc)
        return L"SPARC";
#else
        return L"x86";
#endif
        
#elif defined(aix)
        return L"powerpc";     // This is what uname -p says
        
#elif defined(macos)

        // On MacOS Intel platforms, the architecture appears to always be i386,
        // regardless of 32-bit vs. 64-bit capabilities.  However, since we may
        // (some day) run on something else, we'll implement this properly.
        //
        // Intel (i386) on Mac is a special case: we return 'x86' or 'x64' based
        // on 64-bit capabilities of the CPU.

        // First get the machine architecture dynamically

        int mib[2];
        char hwMachine[64];
        size_t len_hwMachine = sizeof(hwMachine);

        mib[0] = CTL_HW;
        mib[1] = HW_MACHINE;

        if (0 != sysctl(mib, 2, hwMachine, &len_hwMachine, NULL, 0))
        {
            wostringstream sout;
            sout << L"Failure calling sysctl(): Errno=" << errno;
            SCX_LOGERROR(m_log, sout.str());

            return L"";
        }

        // Now figure out our bit size (if Intel, handle the special case)

        if (0 == strncmp("i386", hwMachine, sizeof(hwMachine)))
        {
            unsigned short bitSize = 0;
            try
            {
                SystemInfo sysInfo;
                sysInfo.GetNativeBitSize(bitSize);
            }
            catch (SCXCoreLib::SCXException &e)
            {
                SCX_LOGERROR(m_log, StrAppend( StrAppend(L"Failure in SystemInstance::GetNativeBitSize: ", e.What()), e.Where()));
            }

            if (32 == bitSize)
            {
                return L"x86";
            }
            else if (64 == bitSize) 
            {
                return L"x64";
            }
        }

        // Return the actual architecture, whatever it is

        return StrFromMultibyte(hwMachine);

#else
#error "Platform not supported"
#endif
    }
    /**
       Find out operating system name and version

       This method caches system information in m_osName, m_osVersion and m_osAlias.
       It requires m_unameInfo to be set prior to call. 

    */
    void SCXOSTypeInfo::Init()  // private
    {
        m_osVersion = L"";
        m_osName = L"Unknown";

        assert(m_unameIsValid);

#if defined(hpux) || defined(sun)

        if (m_unameIsValid)
        {
            m_osName = StrFromMultibyte(m_unameInfo.sysname);
            m_osVersion = StrFromMultibyte(m_unameInfo.release);
        }

#if defined(hpux)
        m_osAlias = L"HPUX";
#elif defined(sun)
        m_osAlias = L"Solaris";
#endif

#elif defined(aix)

        if (m_unameIsValid)
        {
            m_osName = StrFromMultibyte(m_unameInfo.sysname);

            // To get "5.3" we must read "5" and "3" from different fields.
            string ver(m_unameInfo.version);
            ver.append(".");
            ver.append(m_unameInfo.release);
            m_osVersion = StrFromMultibyte(ver);
        }
        m_osAlias = L"AIX";

#elif defined(linux)

        vector<wstring> lines;
        SCXStream::NLFs nlfs;

#if defined(PF_DISTRO_SUSE)

        static const string relFileName = "/etc/SuSE-release";
        wifstream relfile(relFileName.c_str());
        wstring version(L"");
        wstring patchlevel(L"");

        SCXStream::ReadAllLines(relfile, lines, nlfs);

        if (!lines.empty()) {
            m_osName = ExtractOSName(lines[0]);
        }

        // Set the Linux Caption (get first line of the /etc/SuSE-release file)
        m_linuxDistroCaption = lines[0];
        if (0 == m_linuxDistroCaption.length())
        {
            // Fallback - should not normally happen
            m_linuxDistroCaption = L"SuSE";
        }

        // File contains one or more lines looking like this:
        // SUSE Linux Enterprise Server 10 (i586)
        // VERSION = 10
        // PATCHLEVEL = 1
        for (size_t i = 0; i<lines.size(); i++)
        {
            if (StrIsPrefix(StrTrim(lines[i]), L"VERSION", true))
            {
                wstring::size_type n = lines[i].find_first_of(L"=");
                if (n != wstring::npos)
                {
                    version = StrTrim(lines[i].substr(n+1));
                }
            }
            else if (StrIsPrefix(StrTrim(lines[i]), L"PATCHLEVEL", true))
            {
                wstring::size_type n = lines[i].find_first_of(L"=");
                if (n != wstring::npos)
                {
                    patchlevel = StrTrim(lines[i].substr(n+1));
                }
            }
        }

        if (version.length() > 0)
        {
            m_osVersion = version;

            if (patchlevel.length() > 0)
            {
                m_osVersion = version.append(L".").append(patchlevel);
            }
        }
        
        if (std::wstring::npos != m_osName.find(L"Desktop"))
        { 
            m_osAlias = L"SLED";
        }
        else
        { // Assume server.
            m_osAlias = L"SLES";
        }
#elif defined(PF_DISTRO_REDHAT)

        static const string relFileName = "/etc/redhat-release";
        wifstream relfile(relFileName.c_str());

        SCXStream::ReadAllLines(relfile, lines, nlfs);

        if (!lines.empty()) {
            m_osName = ExtractOSName(lines[0]);
        }

        // Set the Linux Caption (get first line of the /etc/redhat-release file)
        m_linuxDistroCaption = lines[0];
        if (0 == m_linuxDistroCaption.length())
        {
            // Fallback - should not normally happen
            m_linuxDistroCaption = L"Red Hat";
        }

        // File should contain one line that looks like this:
        // Red Hat Enterprise Linux Server release 5.1 (Tikanga)
        if (lines.size() > 0)
        {
            wstring::size_type n = lines[0].find_first_of(L"0123456789");
            if (n != wstring::npos)
            {
                wstring::size_type n2 = lines[0].substr(n).find_first_of(L" \t\n\t");
                m_osVersion = StrTrim(lines[0].substr(n,n2));
            }
        }
        
        if ((std::wstring::npos != m_osName.find(L"Client")) // RHED5
            || (std::wstring::npos != m_osName.find(L"Desktop"))) // RHED4
        { 
            m_osAlias = L"RHED";
        }
        else
        { // Assume server.
            m_osAlias = L"RHEL";
        }
#elif defined(PF_DISTRO_UBUNTU)

        static const string relFileName = "/etc/lsb-release";
        wifstream relfile(relFileName.c_str());
        wstring version(L"");
        wstring patchlevel(L"");

        SCXStream::ReadAllLines(relfile, lines, nlfs);

        // File contains one or more lines looking like this:
        // DISTRIB_ID=Ubuntu
        // DISTRIB_RELEASE=6.06
        // DISTRIB_CODENAME=dapper
        // DISTRIB_DESCRIPTION="Ubuntu 6.06.2 LTS"

        for (size_t i = 0; i<lines.size(); i++)
        {
            if (StrIsPrefix(StrTrim(lines[i]), L"DISTRIB_DESCRIPTION", true))
            {
                wstring::size_type n = lines[i].find_first_of(L"\"");
                if (n != wstring::npos)
                {
                    // Strip the quote (") characters ...
                    m_osName = StrTrim(lines[i].substr(n+1));
                    m_osName = m_osName.erase(m_osName.length()-1);
                    // This is an alias on Ubuntu (and not used for SCX_STACK_ONLY)
                    m_linuxDistroCaption = m_osName;
                }
            }
        }

        if (! m_osName.empty())
        {
            wstring::size_type n = m_osName.find_first_of(L"0123456789");
            if (n != wstring::npos)
            {
                wstring::size_type n2 = m_osName.substr(n).find_first_of(L" \t\n\t");
                m_osVersion = StrTrim(m_osName.substr(n,n2));
            }

            m_osName = ExtractOSName(m_osName);
        }
        m_osAlias = L"Ubuntu";

#else
#error "Linux Platform not supported"
#endif

#elif defined(macos)
        m_osAlias = L"MacOS";

        if (m_unameIsValid)
        {
            // MacOS is called "Darwin" in uname info, so we hard-code here
            m_osName = L"Mac OS";

            // This value we could read dynamically from the xml file
            // /System/Library/CoreServices/SystemVersion.plist, but that
            // file may be named differently based on client/server, and
            // reading the plist file would require framework stuff.
            //
            // Rather than using the plist, we'll use Gestalt, which is an
            // API designed to figure out versions of anything and everything.
            // Note that use of Gestalt requires the use of framework stuff
            // as well, so the Makefiles for MacOS are modified for that.

            SInt32 major, minor, bugfix;
            if (0 != Gestalt(gestaltSystemVersionMajor, &major)
                || 0 != Gestalt(gestaltSystemVersionMinor, &minor)
                || 0 != Gestalt(gestaltSystemVersionBugFix, &bugfix))
            {
                throw SCXCoreLib::SCXErrnoException(L"Gestalt", errno, SCXSRCLOCATION);
            }

            wostringstream sout;
            sout << major << L"." << minor << L"." << bugfix;
            m_osVersion = sout.str();
        }
#else
#error "Platform not supported"
#endif

    }
std::vector<NetworkInterfaceConfigurationInstance> NetworkInterfaceConfigurationEnumeration::FindAll()
{
    // Use NetworkInterface provider to get all the interfaces
    std::vector<NetworkInterfaceInfo> interfaces = NetworkInterfaceInfo::FindAll(m_deps);

    std::vector<NetworkInterfaceConfigurationInstance> resultList;
    for (size_t nr = 0; nr < interfaces.size(); nr++)
    {
        NetworkInterfaceConfigurationInstance instance(interfaces[nr]);

        // Set m_Index
        instance.m_Index = static_cast<Uint32>(nr);
        instance.SetKnown(NetworkInterfaceConfigurationInstance::eIndex);

        // Get if interface is enabled. If up interface has the address set. If running inteface has the resources
        // allocated and is ready to receive/transmit.
        if (interfaces[nr].IsKnownIfUp() && interfaces[nr].IsKnownIfRunning())
        {
            instance.SetKnown(NetworkInterfaceConfigurationInstance::eIPEnabled);
            instance.m_IPEnabled = false;
            if (interfaces[nr].IsUp() && interfaces[nr].IsRunning())
            {
                instance.m_IPEnabled = true;
            }
        }

        // (WI 468917) Activate MAC Address to be reported by the provider.
        interfaces[nr].GetMACAddress(instance.m_MACAddress);
        instance.SetKnown(NetworkInterfaceConfigurationInstance::eMACAddress);

        instance.m_IPAddress.clear();
        if (interfaces[nr].IsIPAddressKnown())
        {
            instance.m_IPAddress.push_back(interfaces[nr].GetIPAddress());
        }
        vector<wstring> tmpIPv6 = interfaces[nr].GetIPV6Address();
        instance.m_IPAddress.insert(instance.m_IPAddress.end(), tmpIPv6.begin(), tmpIPv6.end());
        if (instance.m_IPAddress.empty() == false)
        {
            instance.SetKnown(NetworkInterfaceConfigurationInstance::eIPAddress);
        }

        if (interfaces[nr].IsNetmaskKnown())
        {
            instance.m_IPSubnet.resize(1);
            instance.m_IPSubnet[0] = interfaces[nr].GetNetmask();
            instance.SetKnown(NetworkInterfaceConfigurationInstance::eIPSubnet);
        }

        // Determine m_ArpUseEtherSNAP
        // ARP packets can be sent using EtherType fields in Ethernet II (DIX) format or in 802.3 (SNAP) format.
        // Both are permitted.  Some operating systems can force ARP packets to be sent in the newer 802.3
        // format, but due to its simplicity, the older DIX format is still widely used.
#if defined(linux) || defined(sun)
        instance.m_ArpUseEtherSNAP = false;
        instance.SetKnown(NetworkInterfaceConfigurationInstance::eArpUseEtherSNAP);
#endif

        // Determine m_Caption
        // Index in format [nnnnnnnn] followed by a short textual description (one-line string) of the object.
        ostringstream ixstr;
        ixstr << '[' << setfill('0') << setw(8) << nr << "] ";
        instance.m_Caption = StrFromMultibyte(ixstr.str()) + instance.GetName();
        instance.SetKnown(NetworkInterfaceConfigurationInstance::eCaption);

        // Determine m_Description
        // Description of the CIM_Setting object. This property is inherited from CIM_Setting.
        instance.m_Description = instance.GetName();
        instance.SetKnown(NetworkInterfaceConfigurationInstance::eDescription);

        // Determine m_DeadGWDetectEnabled
        // If TRUE, dead gateway detection occurs. With this feature enabled, Transmission
        // Control Protocol (TCP) asks Internet Protocol (IP) to change to a backup gateway
        // if it retransmits a segment several times without receiving a response.
        // 
        // For Linux, this capability was added with IPv6 via its Neighbor Discovery protocol
        // Solaris also.
#if defined(linux)
        // Subset of neighbor reachability problems solved by IPv6
        instance.m_DeadGWDetectEnabled = SCXDirectory::Exists(L"/proc/sys/net/ipv6");
        instance.SetKnown(NetworkInterfaceConfigurationInstance::eDeadGWDetectEnabled);
#endif

        // Determine m_DefaultTOS
        // Default Type Of Service (TOS) value set in the header of outgoing IP packets.
        // Request for Comments (RFC) 791 defines the values. Default: 0 (zero),
        // Valid Range: 0 - 255.
        // This is deprecated.  Implementations also are not uniform.
        // NOT SET--------------

        // Determine m_DefaultTTL
        // Default Time To Live (TTL) value set in the header of outgoing IP packets.
        // The TTL specifies the number of routers an IP packet can pass through to
        // reach its destination before being discarded. Each router decrements by
        // one the TTL count of a packet as it passes through and discards the
        // packets if the TTL is 0 (zero). Default: 32, Valid Range: 1 - 255.
        std::vector<wstring> lines;
        SCXStream::NLFs nlfs;
#if defined(PF_DISTRO_REDHAT) || defined(sun)
        // This is hardcoded in Linux microkernel source.  Since V2.2 it has been in net/ipv4/ipconfig.c
        // For Solaris it has been 64 since version 2.8
        instance.m_DefaultTTL = 64;
        instance.SetKnown(NetworkInterfaceConfigurationInstance::eDefaultTTL);
#elif defined(PF_DISTRO_SUSE) || defined(PF_DISTRO_ULINUX)
        // if /proc/sys/net/ipv4/ip_default_ttl exists, then override 64 as the default with what is contained
        SCXFile::ReadAllLines(SCXFilePath(L"/proc/sys/net/ipv4/ip_default_ttl"), lines, nlfs);
        if (lines.size() > 0)
        {
            instance.m_DefaultTTL = (Uint8) StrToUInt(lines[0]);
            instance.SetKnown(NetworkInterfaceConfigurationInstance::eDefaultTTL);
        }
#endif

        // Determine m_DHCPEnabled
        // If TRUE, the dynamic host configuration protocol (DHCP) server automatically
        // assigns an IP address to the computer system when establishing a network connection.
        
        // First fetch config data from the appropriate file
        wstring interface = instance.GetName();

        lines.clear();
        bool performRead = true;
#if defined(PF_DISTRO_SUSE)
        // Determine DHCP Enabled by looking for process dhcpcd w/param matching this interface name
        instance.m_DHCPEnabled = GetDHCPEnabledFromProcessList(interface);
#elif defined(PF_DISTRO_REDHAT)
        SCXFile::ReadAllLines(SCXFilePath(SCXCoreLib::StrAppend(L"/etc/sysconfig/network-scripts/ifcfg-", interface)), lines, nlfs);
#elif defined(PF_DISTRO_ULINUX)
        instance.m_DHCPEnabled = GetDHCPEnabledFromProcessList(interface);
        if (!instance.m_DHCPEnabled)
        {
            if (SCXFile::Exists(SCXCoreLib::StrAppend(L"/etc/sysconfig/network-scripts/ifcfg-", interface)))
            {
                SCXFile::ReadAllLines(SCXFilePath(SCXCoreLib::StrAppend(L"/etc/sysconfig/network-scripts/ifcfg-", interface)), lines, nlfs);
            }
            else if (SCXFile::Exists(SCXCoreLib::StrAppend(L"/etc/sysconfig/network/ifcfg-", interface)))
            {
                SCXFile::ReadAllLines(SCXFilePath(SCXCoreLib::StrAppend(L"/etc/sysconfig/network/ifcfg-", interface)), lines, nlfs);
            }
            else
            {
                performRead = false;
            }
        }
#elif defined(sun)
        SCXFile::ReadAllLines(SCXFilePath(SCXCoreLib::StrAppend(L"/etc/hostname.", interface)), lines, nlfs);
#elif defined(hpux)
        SCXFile::ReadAllLines(SCXFilePath(L"/etc/rc.config.d/netconf"), lines, nlfs);
#elif defined(aix)
        SCXFile::ReadAllLines(SCXFilePath(L"/etc/dhcpcd.ini"), lines, nlfs);
#endif

        if (performRead)
        {
            instance.m_DHCPEnabled = GetDHCPEnabledFromConfigData(lines, interface);
        }

#if defined(linux)
        // Determine DHCP Enabled by looking for process dhcpcd w/param matching this interface name
        if (!instance.m_DHCPEnabled)
        {
            instance.m_DHCPEnabled = GetDHCPEnabledFromProcessList(interface);
        }
#endif

        instance.SetKnown(NetworkInterfaceConfigurationInstance::eDHCPEnabled);
        
#if defined(linux) || defined(sun) || defined(hpux)
        // Initialize the DHCP lease information
        DHCPLeaseInfo dhcpLeaseInfo(interface);
        
        // Determine m_DHCPLeaseExpires
        // Expiration date and time for a leased IP address that was assigned to the
        // computer by the dynamic host configuration protocol (DHCP) server.
        // Example: 20521201000230.000000000
        instance.m_DHCPLeaseExpires = dhcpLeaseInfo.getLeaseExpires();
        if (instance.m_DHCPLeaseExpires.IsInitialized())
        {
            instance.SetKnown(NetworkInterfaceConfigurationInstance::eDHCPLeaseExpires);
        }
        
        // Determine m_DHCPLeaseObtained
        // Date and time the lease was obtained for the IP address assigned to the
        // computer by the dynamic host configuration protocol (DHCP) server.
        // Example: 19521201000230.000000000
        instance.m_DHCPLeaseObtained = dhcpLeaseInfo.getLeaseObtained();
        if (instance.m_DHCPLeaseObtained.IsInitialized())
        {
            instance.SetKnown(NetworkInterfaceConfigurationInstance::eDHCPLeaseObtained);
        }
#endif

        // Determine m_DHCPServer
        // IP address of the dynamic host configuration protocol (DHCP) server.
        // Example: 10.55.34.2
#if defined(linux)
        instance.m_DHCPServer = dhcpLeaseInfo.getDHCPServer();
        instance.SetKnown(NetworkInterfaceConfigurationInstance::eDHCPServer);
#endif

        // Determine m_DefaultIPGateway
        // Array of IP addresses of default gateways that the computer system uses.
        // Example: 192.168.12.1 192.168.46.1
#if defined(linux) || defined(sun)
        wstring gwip;
        if (GatewayInfo::get_gatewayip(gwip, m_deps))
        {
            instance.m_DefaultIPGateway.push_back(gwip);
            instance.SetKnown(NetworkInterfaceConfigurationInstance::eDefaultIPGateway);
        }
#elif defined(hpux)
        // The HPUX DHCP info file also contains the default gateway
        wstring defaultGateway = dhcpLeaseInfo.getDefaultGateway();
        if (defaultGateway.size() > 0)
        {
            instance.m_DefaultIPGateway.push_back(defaultGateway);
            instance.SetKnown(NetworkInterfaceConfigurationInstance::eDefaultIPGateway);
        }
#endif

        // Determine m_DNSDomain
        // Organization name followed by a period and an extension that indicates
        // the type of organization, such as microsoft.com. The name can be any
        // combination of the letters A through Z, the numerals 0 through 9, and
        // the hyphen (-), plus the period (.) character used as a separator.
        // Example: microsoft.com
#if defined(linux) || defined(sun) || defined(hpux)
        instance.m_DNSDomain = dhcpLeaseInfo.getDomainName();
        instance.SetKnown(NetworkInterfaceConfigurationInstance::eDNSDomain);
#endif

        // Determine m_DNSDomainSuffixSearchOrder
        // Array of DNS domain suffixes to be appended to the end of host names
        // during name resolution. When attempting to resolve a fully qualified
        // domain name (FQDN) from a host-only name, the system will first append
        // the local domain name. If this is not successful, the system will use
        // the domain suffix list to create additional FQDNs in the order listed
        // and query DNS servers for each.
        // Example: samples.microsoft.com example.microsoft.com
        // Linux doesn't add missing suffixes -----NOT SET

        // Determine m_DNSEnabledForWINSResolution
        // If TRUE, the Domain Name System (DNS) is enabled for name resolution
        // over Windows Internet Naming Service (WINS) resolution. If the name
        // cannot be resolved using DNS, the name request is forwarded to WINS
        // for resolution.
        // Windows only --------NOT SET

        // Determine m_DNSHostName
        // Host name used to identify the local computer for authentication by
        // some utilities. Other TCP/IP-based utilities can use this value to
        // acquire the name of the local computer. Host names are stored on DNS
        // servers in a table that maps names to IP addresses for use by DNS.
        // The name can be any combination of the letters A through Z, the
        // numerals 0 through 9, and the hyphen (-), plus the period (.) character
        // used as a separator. By default, this value is the Microsoft networking
        // computer name, but the network administrator can assign another host
        // name without affecting the computer name.
        // Example: corpdns
        // Probably utility authentication for Windows only ----------NOT SET

        // Determine m_DNSServerSearchOrder
        // Array of server IP addresses to be used in querying for DNS servers.
#if defined(linux) || defined(sun) || defined(hpux)
        lines.clear();
        instance.m_DNSServerSearchOrder.clear();
        SCXFile::ReadAllLines(SCXFilePath(L"/etc/resolv.conf"), lines, nlfs);
        for (uint i = 0; i < lines.size(); i++)
        {
            // remove all comments from the current line, as they should be ignored
            wstring curLine = lines[i];
            wstring::size_type pos;
            pos = curLine.find(L";");
            if (pos != wstring::npos)
            {
                curLine.erase(pos, curLine.length());
            }
            if (curLine.empty())
            {
                continue;
            }
            
            std::vector<wstring> tokens;
            StrTokenize(curLine, tokens, L" \t");
            if (tokens.size() > 1 && tokens[0].compare(L"nameserver") == 0)
            {
                instance.m_DNSServerSearchOrder.push_back(tokens[1]);
            }
        }
        if(instance.m_DNSServerSearchOrder.size() > 0)
        {
            instance.SetKnown(NetworkInterfaceConfigurationInstance::eDNSServerSearchOrder);
        }
#endif

        // Determine m_DomainDNSRegistrationEnabled
        // If TRUE, the IP addresses for this connection are registered in DNS under the domain
        // name of this connection in addition to being registered under the computer's
        // full DNS name. The domain name of this connection is either set using the
        // SetDNSDomain() method or assigned by DSCP. The registered name is the host
        // name of the computer with the domain name appended.
        // Windows 2000:  This property is not available.
        // NOT SET for Linux------------------------------------------------------
        
        // Determine m_ArpAlwaysSourceRoute
        // If TRUE, TCP/IP transmits Address Resolution Protocol (ARP) queries with
        // source routing enabled on Token Ring networks. By default (FALSE), ARP first
        // queries without source routing, and then retries with source routing enabled
        // if no reply is received. Source routing allows the routing of network packets
        // across different types of networks.
        // See http://www.rapid7.com/vulndb/lookup/generic-ip-source-routing-enabled for AIX/Linux/Solaris

        // This property seems to be set to prevent ARP spoofing.  The
        // principle of ARP spoofing is to send fake ARP messages onto a LAN.
        // Generally, the aim is to associate the attacker's MAC address with
        // the IP address of another host (such as the default gateway).
        // 
        // Operating System Approaches
        // Static ARP entries: entries in the local ARP cache can be defined as
        // static to prevent overwrite. While static entries provide perfect security
        // against spoofing if the operating systems handles them correctly, they
        // result in quadratic maintenance efforts as IP-MAC mappings of all machines
        // in the network have to be distributed to all other machines.
        // OS security: Operating systems react differently, e.g. Linux ignores
        // unsolicited replies, but on the other hand uses seen requests from
        // other machines to update its cache. Solaris only accepts updates on
        // entries after a timeout. In Microsoft Windows, the behavior of the
        // ARP cache can be configured through several registry entries under
        // HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters,
        // namely ArpCacheLife, ArpCacheMinReferenceLife, ArpUseEtherSNAP, ArpTRSingleRoute,
        // ArpAlwaysSourceRoute, ArpRetryCount.
#if defined(linux)
        instance.m_ArpAlwaysSourceRoute = false;
        lines.clear();
        SCXFile::ReadAllLines(SCXFilePath(L"/etc/sysctl.conf"), lines, nlfs);
        SCXRegex r(L"accept_source_route\\s*=\\s*([01])");

        instance.m_ArpAlwaysSourceRoute = false;
        for (int i = 0; i < (int)lines.size(); i++)
        {
            if (r.IsMatch(lines[i]))
            {
                instance.m_ArpAlwaysSourceRoute = true;
                break;
            }
        }
        instance.SetKnown(NetworkInterfaceConfigurationInstance::eArpAlwaysSourceRoute);
#endif
        resultList.push_back(instance);
    }
    return resultList;
}