version 1.37.2.2, 2006/09/19 18:25:18
|
version 1.49, 2007/02/12 12:18:53
|
|
|
// | // |
//============================================================================== | //============================================================================== |
// | // |
// Author: Mike Brasher (mbrasher@bmc.com) |
|
// |
|
// Modified By: Rudy Schuet (rudy.schuet@compaq.com) 11/12/01 |
|
// added nsk platform support |
|
// Ramnath Ravindran (Ramnath.Ravindran@compaq.com) 03/21/2002 |
|
// replaced instances of "| ios::binary" with |
|
// PEGASUS_OR_IOS_BINARY |
|
// Robert Kieninger, IBM (kieningr@de.ibm.com) for Bug#667 |
|
// Dave Sudlik, IBM (dsudlik@us.ibm.com) for Bug#1462 |
|
// Sean Keenan, Hewlett-Packard Company (sean.keenan@hp.com) |
|
// David Dillard, Symantec Corp. (david_dillard@symantec.com) |
|
// |
|
//%///////////////////////////////////////////////////////////////////////////// | //%///////////////////////////////////////////////////////////////////////////// |
| |
#if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) | #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) |
#include <Pegasus/Common/Config.h> | #include <Pegasus/Common/Config.h> |
#endif | #endif |
| |
|
|
#include <fstream> | #include <fstream> |
#include <cctype> // for tolower() | #include <cctype> // for tolower() |
#include <cstring> | #include <cstring> |
#include "System.h" | #include "System.h" |
#include "Socket.h" | #include "Socket.h" |
|
#include "Network.h" |
#ifdef PEGASUS_OS_TYPE_WINDOWS |
|
# include <windows.h> |
|
#else |
|
# include <arpa/inet.h> |
|
#endif |
|
|
|
#include <Pegasus/Common/PegasusVersion.h> | #include <Pegasus/Common/PegasusVersion.h> |
| |
#if defined(PEGASUS_OS_TYPE_WINDOWS) | #if defined(PEGASUS_OS_TYPE_WINDOWS) |
# include "SystemWindows.cpp" | # include "SystemWindows.cpp" |
#elif defined(PEGASUS_OS_TYPE_UNIX) |
#elif defined(PEGASUS_OS_TYPE_UNIX) || defined(PEGASUS_OS_VMS) |
# include "SystemUnix.cpp" |
# include "SystemPOSIX.cpp" |
#elif defined(PEGASUS_OS_TYPE_NSK) |
|
# include "SystemNsk.cpp" |
|
#elif defined(PEGASUS_OS_VMS) |
|
# include "SystemVms.cpp" |
|
#else | #else |
# error "Unsupported platform" | # error "Unsupported platform" |
#endif | #endif |
| |
#if defined(PEGASUS_OS_OS400) | #if defined(PEGASUS_OS_OS400) |
# include "OS400ConvertChar.h" |
# include "EBCDIC_OS400.h" |
#endif | #endif |
| |
PEGASUS_USING_STD; | PEGASUS_USING_STD; |
|
|
| |
//////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// |
// This code used to check if the first character of "hostname" was alphabetic | // This code used to check if the first character of "hostname" was alphabetic |
// to indicate hostname instead of IP address. But RFC 1123, section 2.1, relaxed |
// to indicate hostname instead of IP address. But RFC 1123, section 2.1, |
// this requirement to alphabetic character *or* digit. So bug 1462 changed the |
// relaxed this requirement to alphabetic character *or* digit. So bug 1462 |
// flow here to call inet_addr first to check for a valid IP address in dotted |
// changed the flow here to call inet_addr first to check for a valid IP |
// decimal notation. If it's not a valid IP address, then try to validate |
// address in dotted decimal notation. If it's not a valid IP address, then |
// it as a hostname. |
// try to validate it as a hostname. |
// RFC 1123 states: The host SHOULD check the string syntactically for a | // RFC 1123 states: The host SHOULD check the string syntactically for a |
// dotted-decimal number before looking it up in the Domain Name System. | // dotted-decimal number before looking it up in the Domain Name System. |
// Hence the call to inet_addr() first. | // Hence the call to inet_addr() first. |
|
|
gethostname( hostName, PEGASUS_MAXHOSTNAMELEN ); | gethostname( hostName, PEGASUS_MAXHOSTNAMELEN ); |
hostName[sizeof(hostName)-1] = 0; | hostName[sizeof(hostName)-1] = 0; |
hostEntry = gethostbyname(hostName); | hostEntry = gethostbyname(hostName); |
} else |
} |
|
else |
{ | { |
hostEntry = gethostbyname((char *)hostname); | hostEntry = gethostbyname((char *)hostname); |
} | } |
|
|
else // else hostname *is* a dotted-decimal IP address | else // else hostname *is* a dotted-decimal IP address |
{ | { |
// resolve hostaddr to a real host entry | // resolve hostaddr to a real host entry |
// casting to (const char *) as (char *) will work as (void *) too, those it fits all platforms |
// casting to (const char *) as (char *) will work as (void *) too, |
#ifndef PEGASUS_OS_OS400 |
// those it fits all platforms |
hostEntry = gethostbyaddr((const char *) &tmp_addr, sizeof(tmp_addr), AF_INET); |
#if defined(PEGASUS_OS_LINUX) |
|
char hostEntryBuffer[8192]; |
|
struct hostent hostEntryStruct; |
|
int hostEntryErrno; |
|
|
|
gethostbyaddr_r( |
|
(const char*) &tmp_addr, |
|
sizeof(tmp_addr), |
|
AF_INET, |
|
&hostEntryStruct, |
|
hostEntryBuffer, |
|
sizeof(hostEntryBuffer), |
|
&hostEntry, |
|
&hostEntryErrno); |
|
#elif defined(PEGASUS_OS_SOLARIS) |
|
char hostEntryBuffer[8192]; |
|
struct hostent hostEntryStruct; |
|
int hostEntryErrno; |
|
|
|
hostEntry = gethostbyaddr_r( |
|
(const char *) &tmp_addr, |
|
sizeof(tmp_addr), |
|
AF_INET, |
|
&hostEntryStruct, |
|
hostEntryBuffer, |
|
sizeof(hostEntryBuffer), |
|
&hostEntryErrno); |
|
#elif defined(PEGASUS_OS_OS400) |
|
hostEntry = |
|
gethostbyaddr((char *) &tmp_addr, sizeof(tmp_addr), AF_INET); |
#else | #else |
hostEntry = gethostbyaddr((char *) &tmp_addr, sizeof(tmp_addr), AF_INET); |
hostEntry = |
|
gethostbyaddr((const char *) &tmp_addr, sizeof(tmp_addr), AF_INET); |
#endif | #endif |
if (hostEntry == 0) | if (hostEntry == 0) |
{ | { |
// error, couldn't resolve the ip | // error, couldn't resolve the ip |
return 0xFFFFFFFF; | return 0xFFFFFFFF; |
} else |
} |
|
else |
{ | { |
|
|
unsigned char ip_part1,ip_part2,ip_part3,ip_part4; | unsigned char ip_part1,ip_part2,ip_part3,ip_part4; |
| |
ip_part1 = hostEntry->h_addr[0]; | ip_part1 = hostEntry->h_addr[0]; |
|
|
return true; | return true; |
} | } |
| |
|
Boolean System::resolveHostNameAtDNS( |
|
const char* hostname, |
|
Uint32* resolvedNameIP) |
|
{ |
|
// ask the DNS for hostname resolution to IP address |
|
// this can mean a time delay for as long as the DNS |
|
// takes to answer |
|
struct hostent* hostEntry; |
|
|
|
#if defined(PEGASUS_OS_LINUX) |
|
char hostEntryBuffer[8192]; |
|
struct hostent hostEntryStruct; |
|
int hostEntryErrno; |
|
|
|
gethostbyname_r( |
|
hostname, |
|
&hostEntryStruct, |
|
hostEntryBuffer, |
|
sizeof(hostEntryBuffer), |
|
&hostEntry, |
|
&hostEntryErrno); |
|
#elif defined(PEGASUS_OS_SOLARIS) |
|
char hostEntryBuffer[8192]; |
|
struct hostent hostEntryStruct; |
|
int hostEntryErrno; |
|
|
|
hostEntry = gethostbyname_r( |
|
(char *)hostname, |
|
&hostEntryStruct, |
|
hostEntryBuffer, |
|
sizeof(hostEntryBuffer), |
|
&hostEntryErrno); |
|
#else |
|
hostEntry = gethostbyname((char *)hostname); |
|
#endif |
|
if (hostEntry == 0) |
|
{ |
|
// error, couldn't resolve the hostname to an ip address |
|
return false; |
|
} |
|
else |
|
{ |
|
unsigned char ip_part1,ip_part2,ip_part3,ip_part4; |
|
ip_part1 = hostEntry->h_addr[0]; |
|
ip_part2 = hostEntry->h_addr[1]; |
|
ip_part3 = hostEntry->h_addr[2]; |
|
ip_part4 = hostEntry->h_addr[3]; |
|
*resolvedNameIP = ip_part1; |
|
*resolvedNameIP = (*resolvedNameIP << 8) + ip_part2; |
|
*resolvedNameIP = (*resolvedNameIP << 8) + ip_part3; |
|
*resolvedNameIP = (*resolvedNameIP << 8) + ip_part4; |
|
} |
|
return true; |
|
} |
|
|
|
Boolean System::resolveIPAtDNS(Uint32 ip_addr, Uint32 * resolvedIP) |
|
{ |
|
struct hostent *entry; |
|
|
|
#ifndef PEGASUS_OS_OS400 |
|
entry = gethostbyaddr((const char *) &ip_addr, sizeof(ip_addr), AF_INET); |
|
#else |
|
entry = gethostbyaddr((char *) &ip_addr, sizeof(ip_addr), AF_INET); |
|
#endif |
|
if (entry == 0) |
|
{ |
|
// error, couldn't resolve the ip |
|
return false; |
|
} |
|
else |
|
{ |
|
unsigned char ip_part1,ip_part2,ip_part3,ip_part4; |
|
ip_part1 = entry->h_addr[0]; |
|
ip_part2 = entry->h_addr[1]; |
|
ip_part3 = entry->h_addr[2]; |
|
ip_part4 = entry->h_addr[3]; |
|
*resolvedIP = ip_part1; |
|
*resolvedIP = (*resolvedIP << 8) + ip_part2; |
|
*resolvedIP = (*resolvedIP << 8) + ip_part3; |
|
*resolvedIP = (*resolvedIP << 8) + ip_part4; |
|
} |
|
return true; |
|
} |
|
|
|
|
|
Boolean System::isLocalHost(const String &hostName) |
|
{ |
|
// differentiate between a dotted IP address given |
|
// and a real hostname given |
|
CString csName = hostName.getCString(); |
|
char cc_hostname[PEGASUS_MAXHOSTNAMELEN]; |
|
strcpy(cc_hostname, (const char*) csName); |
|
Uint32 tmp_addr = 0xFFFFFFFF; |
|
Boolean hostNameIsIPNotation; |
|
|
|
#ifdef PEGASUS_OS_OS400 |
|
AtoE(cc_hostname); |
|
#endif |
|
|
|
// Note: Platforms already supporting the inet_aton() |
|
// should define their platform here, |
|
// as this is the superior way to work |
|
#if defined(PEGASUS_OS_LINUX) || defined(PEGASUS_OS_AIX) |
|
|
|
struct in_addr inaddr; |
|
// if inet_aton failed(return=0), |
|
// we do not have a valip IP address (x.x.x.x) |
|
int atonSuccess = inet_aton(cc_hostname, &inaddr); |
|
if (atonSuccess == 0) hostNameIsIPNotation = false; |
|
else |
|
{ |
|
hostNameIsIPNotation = true; |
|
tmp_addr = inaddr.s_addr; |
|
} |
|
#else |
|
// Note: 0xFFFFFFFF is actually a valid IP address (255.255.255.255). |
|
// A better solution would be to use inet_aton() or equivalent, as |
|
// inet_addr() is now considered "obsolete". |
|
// Note: inet_aton() not yet supported on all Pegasus platforms |
|
tmp_addr = inet_addr((char *) cc_hostname); |
|
if (tmp_addr == 0xFFFFFFFF) hostNameIsIPNotation = false; |
|
else hostNameIsIPNotation = true; |
|
#endif |
|
|
|
if (!hostNameIsIPNotation) // if hostname is not an IP address |
|
{ |
|
// localhost ? |
|
if (String::equalNoCase(hostName,String("localhost"))) return true; |
|
char localHostName[PEGASUS_MAXHOSTNAMELEN]; |
|
CString cstringLocalHostName = System::getHostName().getCString(); |
|
strcpy(localHostName, (const char*) cstringLocalHostName); |
|
// given hostname equals what system returns as local hostname ? |
|
if (String::equalNoCase(hostName,localHostName)) return true; |
|
Uint32 hostIP; |
|
// bail out if hostname unresolveable |
|
if (!System::resolveHostNameAtDNS(cc_hostname, &hostIP)) return false; |
|
// lets see if the IP is defined on one of the network interfaces |
|
// this can help us avoid another call to DNS |
|
if (System::isIpOnNetworkInterface(hostIP)) return true; |
|
// need to check if the local hosts name is possibly |
|
// registered at the DNS with the IP address equal resolvedNameIP |
|
Uint32 localHostIP; |
|
if (!System::resolveHostNameAtDNS(localHostName, &localHostIP)) |
|
return false; |
|
if (localHostIP == hostIP) return true; |
|
} |
|
else |
|
{ // hostname is an IP address |
|
// 127.0.0.1 is always the loopback |
|
// inet_addr returns network byte order |
|
if (tmp_addr == htonl(0x7F000001)) return true; |
|
// IP defined on a local AF_INET network interface |
|
if (System::isIpOnNetworkInterface(tmp_addr)) return true; |
|
// out of luck so far, lets ask the DNS what our IP is |
|
// and check against what we got |
|
Uint32 localHostIP; |
|
if (!System::resolveHostNameAtDNS( |
|
(const char*) System::getHostName().getCString(), &localHostIP)) |
|
return false; |
|
if (localHostIP == tmp_addr) return true; |
|
// not yet, sometimes resolving the IP address we got against the DNS |
|
// can solve the problem |
|
// casting to (const char *) as (char *) will work as (void *) too, |
|
// those it fits all platforms |
|
Uint32 hostIP; |
|
if (!System::resolveIPAtDNS(tmp_addr, &hostIP)) return false; |
|
if (hostIP == localHostIP) return true; |
|
} |
|
return false; |
|
} |
|
|
// System ID constants for Logger::put and Logger::trace | // System ID constants for Logger::put and Logger::trace |
const String System::CIMLISTENER = "cimlistener"; // Listener systme ID | const String System::CIMLISTENER = "cimlistener"; // Listener systme ID |
| |
PEGASUS_NAMESPACE_END | PEGASUS_NAMESPACE_END |
|
|