1 martin 1.71 //%LICENSE////////////////////////////////////////////////////////////////
|
2 martin 1.72 //
|
3 martin 1.71 // Licensed to The Open Group (TOG) under one or more contributor license
4 // agreements. Refer to the OpenPegasusNOTICE.txt file distributed with
5 // this work for additional information regarding copyright ownership.
6 // Each contributor licenses this file to you under the OpenPegasus Open
7 // Source License; you may not use this file except in compliance with the
8 // License.
|
9 martin 1.72 //
|
10 martin 1.71 // Permission is hereby granted, free of charge, to any person obtaining a
11 // copy of this software and associated documentation files (the "Software"),
12 // to deal in the Software without restriction, including without limitation
13 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 // and/or sell copies of the Software, and to permit persons to whom the
15 // Software is furnished to do so, subject to the following conditions:
|
16 martin 1.72 //
|
17 martin 1.71 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
|
19 martin 1.72 //
|
20 martin 1.71 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
21 martin 1.72 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
22 martin 1.71 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
27 martin 1.72 //
|
28 martin 1.71 //////////////////////////////////////////////////////////////////////////
|
29 mike 1.6 //
30 //%/////////////////////////////////////////////////////////////////////////////
|
31 mike 1.8
|
32 r.kieninger 1.21 #include <Pegasus/Common/Config.h>
|
33 sage 1.12
|
34 mike 1.8 #include <fstream>
|
35 kumpf 1.13 #include <cctype> // for tolower()
|
36 kumpf 1.14 #include <cstring>
|
37 mike 1.6 #include "System.h"
|
38 r.kieninger 1.21 #include "Socket.h"
|
39 mike 1.39 #include "Network.h"
|
40 kumpf 1.10 #include <Pegasus/Common/PegasusVersion.h>
|
41 mateus.baur 1.50 #include <Pegasus/Common/FileSystem.h>
|
42 dave.sudlik 1.52 #include <Pegasus/Common/HostAddress.h>
43 #include <Pegasus/Common/Array.h>
|
44 kumpf 1.10
|
45 mike 1.6 #if defined(PEGASUS_OS_TYPE_WINDOWS)
46 # include "SystemWindows.cpp"
|
47 john.eisenbraun 1.74 #elif defined(PEGASUS_OS_TYPE_UNIX)
|
48 mike 1.40 # include "SystemPOSIX.cpp"
|
49 john.eisenbraun 1.74 # include "SystemUnix.cpp"
50 #elif defined(PEGASUS_OS_VMS)
51 # include "SystemPOSIX.cpp"
52 # include "SystemVms.cpp"
|
53 mike 1.6 #else
54 # error "Unsupported platform"
55 #endif
|
56 mike 1.8
57 PEGASUS_USING_STD;
58
59 PEGASUS_NAMESPACE_BEGIN
60
|
61 kumpf 1.20 Boolean System::bindVerbose = false;
62
|
63 marek 1.80 Mutex System::_mutexForGetHostName;
64
65 Mutex System::_mutexForGetFQHN;
66
67 String System::_hostname;
68 String System::_fullyQualifiedHostname;
|
69 sahana.prabhakar 1.78
70
|
71 mike 1.8 Boolean System::copyFile(const char* fromPath, const char* toPath)
72 {
|
73 ramnath 1.9 ifstream is(fromPath PEGASUS_IOS_BINARY);
|
74 mateus.baur 1.50 fstream os(toPath, ios::out PEGASUS_OR_IOS_BINARY);
|
75 mike 1.8
76 char c;
77
78 while (is.get(c))
79 {
|
80 kumpf 1.44 if (!os.put(c))
81 return false;
|
82 mike 1.8 }
83
|
84 mateus.baur 1.50 FileSystem::syncWithDirectoryUpdates(os);
|
85 kumpf 1.42 return is.eof();
|
86 kumpf 1.13 }
87
|
88 kumpf 1.44 static const Uint8 _toLowerTable[256] =
|
89 mike 1.32 {
90 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
91 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
92 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
93 0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
94 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
95 0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
96 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
97 0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
98 0x40,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
99 0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
100 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
101 0x78,0x79,0x7A,0x5B,0x5C,0x5D,0x5E,0x5F,
102 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
103 0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
104 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
105 0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
106 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,
107 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
108 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,
109 0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
110 mike 1.32 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
111 0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
112 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,
113 0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
114 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,
115 0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
116 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,
117 0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,
118 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,
119 0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
120 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,
121 0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,
122 };
123
|
124 kumpf 1.13 Sint32 System::strcasecmp(const char* s1, const char* s2)
125 {
|
126 mike 1.32 // Note: this is faster than glibc strcasecmp().
127
128 Uint8* p = (Uint8*)s1;
129 Uint8* q = (Uint8*)s2;
130 int r;
131
132 for (;;)
|
133 kumpf 1.13 {
|
134 kumpf 1.44 if ((r = _toLowerTable[p[0]] - _toLowerTable[q[0]]) || !p[0] ||
135 (r = _toLowerTable[p[1]] - _toLowerTable[q[1]]) || !p[1] ||
136 (r = _toLowerTable[p[2]] - _toLowerTable[q[2]]) || !p[2] ||
137 (r = _toLowerTable[p[3]] - _toLowerTable[q[3]]) || !p[3])
138 break;
|
139 kumpf 1.13
|
140 kumpf 1.44 p += 4;
141 q += 4;
|
142 kumpf 1.13 }
143
|
144 mike 1.32 return r;
|
145 mike 1.8 }
146
|
147 thilo.boehm 1.77 bool System::strncasecmp(
148 const char* s1,
149 size_t s1_l,
150 const char* s2,
151 size_t s2_l)
152 {
153 // Function is even faster than System::strcasecmp()
154 if (s1_l != s2_l)
155 {
156 return false;
157 }
158 Uint8* p = (Uint8*)s1;
159 Uint8* q = (Uint8*)s2;
160 register int len = s1_l;
161 // lets do a loop-unrolling optimized compare here
162 while (len >= 8)
163 {
164 if ((_toLowerTable[p[0]]-_toLowerTable[q[0]]) ||
165 (_toLowerTable[p[1]]-_toLowerTable[q[1]]) ||
166 (_toLowerTable[p[2]]-_toLowerTable[q[2]]) ||
167 (_toLowerTable[p[3]]-_toLowerTable[q[3]]) ||
168 thilo.boehm 1.77 (_toLowerTable[p[4]]-_toLowerTable[q[4]]) ||
169 (_toLowerTable[p[5]]-_toLowerTable[q[5]]) ||
170 (_toLowerTable[p[6]]-_toLowerTable[q[6]]) ||
171 (_toLowerTable[p[7]]-_toLowerTable[q[7]]))
172 {
173 return false;
174 }
175 len -= 8;
176 p += 8;
177 q += 8;
178 }
179 while (len >= 4)
180 {
181 if ((_toLowerTable[p[0]]-_toLowerTable[q[0]]) ||
182 (_toLowerTable[p[1]]-_toLowerTable[q[1]]) ||
183 (_toLowerTable[p[2]]-_toLowerTable[q[2]]) ||
184 (_toLowerTable[p[3]]-_toLowerTable[q[3]]))
185 {
186 return false;
187 }
188 len -= 4;
189 thilo.boehm 1.77 p += 4;
190 q += 4;
191 }
192 while (len--)
193 {
194 if ((_toLowerTable[p[0]]-_toLowerTable[q[0]]))
195 {
196 return false;
197 }
198 p++;
199 q++;
200 }
201 return true;
202 }
203
204
|
205 tony 1.15 // Return the just the file name from the path into basename
206 char *System::extract_file_name(const char *fullpath, char *basename)
207 {
|
208 kumpf 1.44 if (fullpath == NULL)
209 {
210 basename[0] = '\0';
211 return basename;
212 }
|
213 kumpf 1.31
|
214 kumpf 1.44 for (const char* p = fullpath + strlen(fullpath) - 1; p >= fullpath; p--)
215 {
216 if (*p == '\\' || *p == '/')
217 {
218 strcpy(basename, p+1);
219 return basename;
220 }
221 }
222
223 strcpy(basename, fullpath);
224 return basename;
|
225 tony 1.15 }
226
227 // Return the just the path to the file name into dirname
228 char *System::extract_file_path(const char *fullpath, char *dirname)
229 {
|
230 kumpf 1.44 char *p;
231 char buff[4096];
232 if (fullpath == NULL)
233 {
234 dirname[0] = '\0';
235 return dirname;
236 }
237 strncpy(buff, fullpath, sizeof(buff)-1);
238 buff[sizeof(buff)-1] = '\0';
239 for (p = buff + strlen(buff); p >= buff; p--)
|
240 tony 1.15 {
|
241 kumpf 1.44 if (*p == '\\' || *p == '/')
|
242 tony 1.15 {
243 strncpy(dirname, buff, p+1 - buff);
244 dirname[p+1 - buff] = '\0';
245 return dirname;
246 }
247 }
|
248 kumpf 1.44 strcpy(dirname, fullpath);
249 return dirname;
|
250 tony 1.15 }
251
|
252 kumpf 1.66 String System::getHostName()
253 {
254 // Use double-checked locking pattern to avoid overhead of
255 // mutex on subsequent calls.
256
257 if (0 == _hostname.size())
258 {
|
259 marek 1.80 AutoMutex lock(_mutexForGetHostName);
|
260 kumpf 1.66
261 if (0 == _hostname.size())
262 {
263 char hostname[PEGASUS_MAXHOSTNAMELEN + 1];
264 // If gethostname() fails, an empty or truncated value is used.
265 hostname[0] = 0;
266 gethostname(hostname, sizeof(hostname));
267 hostname[sizeof(hostname)-1] = 0;
268 _hostname.assign(hostname);
269 }
270 }
271
272 return _hostname;
273 }
274
275 static String _getFullyQualifiedHostName()
276 {
277 char hostName[PEGASUS_MAXHOSTNAMELEN + 1];
278
279 // Get the short name of the local host.
280 // If gethostname() fails, an empty or truncated value is used.
281 kumpf 1.66 hostName[0] = 0;
282 gethostname(hostName, sizeof(hostName));
283 hostName[sizeof(hostName)-1] = 0;
284
285 #if defined(PEGASUS_OS_ZOS)|| \
286 defined(PEGASUS_OS_VMS)
287
288 String fqName;
289 struct addrinfo *resolv;
290 struct addrinfo hint;
291 struct hostent *he;
292
293 memset (&hint, 0, sizeof(struct addrinfo));
294 hint.ai_flags = AI_CANONNAME;
295 hint.ai_family = AF_UNSPEC; // any family
296 hint.ai_socktype = 0; // any socket type
297 hint.ai_protocol = 0; // any protocol
|
298 carson.hovey 1.68 int success = System::getAddrInfo(hostName, NULL, &hint, &resolv);
|
299 kumpf 1.66 if (success==0)
300 {
301 // assign fully qualified hostname
302 fqName.assign(resolv->ai_canonname);
303 }
304 else
305 {
|
306 carson.hovey 1.68 if ((he = System::getHostByName(hostName)))
|
307 kumpf 1.66 {
308 strncpy(hostName, he->h_name, sizeof(hostName) - 1);
309 }
310 // assign hostName
311 // if gethostbyname was successful assign that result
312 // else assign unqualified hostname
313 fqName.assign(hostName);
314 }
315 if (resolv)
316 {
317 freeaddrinfo(resolv);
318 }
319
320 return fqName;
321
322 #else /* !PEGASUS_OS_ZOS && !PEGASUS_OS_VMS */
323
324 char hostEntryBuffer[8192];
325 struct hostent hostEntryStruct;
326 struct hostent* hostEntry = System::getHostByName(
327 hostName, &hostEntryStruct, hostEntryBuffer, sizeof (hostEntryBuffer));
328 kumpf 1.66
329 if (hostEntry)
330 {
331 strncpy(hostName, hostEntry->h_name, sizeof(hostName) - 1);
332 }
333 return String(hostName);
334
335 #endif
336 }
337
338 String System::getFullyQualifiedHostName()
339 {
340 // Use double-checked locking pattern to avoid overhead of
341 // mutex on subsequent calls.
342
|
343 marek 1.80 if (0 == _fullyQualifiedHostname.size())
|
344 kumpf 1.66 {
|
345 marek 1.80 AutoMutex lock(_mutexForGetFQHN);
|
346 kumpf 1.66
|
347 marek 1.80 if (0 == _fullyQualifiedHostname.size())
|
348 kumpf 1.66 {
|
349 marek 1.80 _fullyQualifiedHostname = _getFullyQualifiedHostName();
|
350 kumpf 1.66 }
|
351 marek 1.80 }
352
353 return _fullyQualifiedHostname;
354 }
|
355 kumpf 1.66
|
356 marek 1.80 void System::setHostName(const String & hostName)
357 {
358 AutoMutex lock(_mutexForGetHostName);
359 _hostname.assign(hostName);
360 }
|
361 kumpf 1.66
|
362 marek 1.80 void System::setFullyQualifiedHostName(const String & fullHostName)
363 {
364 AutoMutex lock(_mutexForGetFQHN);
365 _fullyQualifiedHostname.assign(fullHostName);
|
366 kumpf 1.66 }
367
|
368 marek 1.80
|
369 dave.sudlik 1.52 Boolean System::getHostIP(const String &hostName, int *af, String &hostIP)
|
370 marek 1.24 {
|
371 marek 1.80 CString hostNameCString = hostName.getCString();
|
372 marek 1.81 char localHostName[PEGASUS_MAXHOSTNAMELEN+1] = {};
|
373 marek 1.80 const char* hostNamePtr;
374
375 // In case hostName equals _hostname or _fullyQualifiedHostname
376 // we need to use the system-supplied hostname instead for IP resolution
377 // _hostname or _fullyQualifiedHostname might be configured values
378 // which cannot be resolved by the system to an IP address
379 if (String::equalNoCase(hostName, _hostname) ||
380 String::equalNoCase(hostName, _fullyQualifiedHostname))
381 {
382 gethostname(localHostName, PEGASUS_MAXHOSTNAMELEN);
383 hostNamePtr= (const char*) localHostName;
384 }
385 else
386 {
387 hostNamePtr = hostNameCString;
388 }
|
389 dave.sudlik 1.52 #ifdef PEGASUS_ENABLE_IPV6
390 struct addrinfo *info, hints;
391 memset (&hints, 0, sizeof(struct addrinfo));
392
393 // Check for valid IPV4 address, if found return ipv4 address
394 *af = AF_INET;
395 hints.ai_family = *af;
|
396 kumpf 1.73 hints.ai_protocol = IPPROTO_TCP;
|
397 dave.sudlik 1.52 hints.ai_socktype = SOCK_STREAM;
|
398 marek 1.80 if (!getAddrInfo(hostNamePtr, 0, &hints, &info))
|
399 dave.sudlik 1.52 {
400 char ipAddress[PEGASUS_INET_ADDRSTR_LEN];
|
401 kumpf 1.73 HostAddress::convertBinaryToText(info->ai_family,
|
402 kumpf 1.54 &(reinterpret_cast<struct sockaddr_in*>(info->ai_addr))->sin_addr,
403 ipAddress,
|
404 dave.sudlik 1.52 PEGASUS_INET_ADDRSTR_LEN);
405 hostIP = ipAddress;
406 freeaddrinfo(info);
407 return true;
408 }
409
|
410 kumpf 1.73 // Check for valid IPV6 Address.
|
411 dave.sudlik 1.52 *af = AF_INET6;
412 hints.ai_family = *af;
413 hints.ai_protocol = IPPROTO_TCP;
414 hints.ai_socktype = SOCK_STREAM;
|
415 marek 1.80 if (!getAddrInfo(hostNamePtr, 0, &hints, &info))
|
416 dave.sudlik 1.52 {
417 char ipAddress[PEGASUS_INET6_ADDRSTR_LEN];
418 HostAddress::convertBinaryToText(info->ai_family,
|
419 kumpf 1.54 &(reinterpret_cast<struct sockaddr_in6*>(info->ai_addr))->sin6_addr,
420 ipAddress,
|
421 dave.sudlik 1.52 PEGASUS_INET6_ADDRSTR_LEN);
422 hostIP = ipAddress;
423 freeaddrinfo(info);
424 return true;
425 }
426
427 return false;
428 #else
429 *af = AF_INET;
|
430 kumpf 1.36 struct hostent* hostEntry;
431 struct in_addr inaddr;
432 String ipAddress;
433
434 char hostEntryBuffer[8192];
435 struct hostent hostEntryStruct;
|
436 kumpf 1.73 hostEntry = getHostByName(hostNamePtr, &hostEntryStruct,
|
437 dmitry.mikulin 1.59 hostEntryBuffer, sizeof (hostEntryBuffer));
|
438 kumpf 1.36
439 if (hostEntry)
|
440 marek 1.24 {
|
441 kumpf 1.36 ::memcpy( &inaddr, hostEntry->h_addr,4);
|
442 marek 1.24 ipAddress = ::inet_ntoa( inaddr );
|
443 dmitry.mikulin 1.59 hostIP = ipAddress;
444 return true;
|
445 marek 1.24 }
|
446 dmitry.mikulin 1.59 return false;
|
447 dave.sudlik 1.52 #endif
|
448 marek 1.24 }
|
449 r.kieninger 1.21
|
450 venkat.puvvada 1.56
451 #ifdef PEGASUS_ENABLE_IPV6
452 Boolean System::isIPv6StackActive()
453 {
454 SocketHandle ip6Socket;
455 if ((ip6Socket = Socket::createSocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP))
456 == PEGASUS_INVALID_SOCKET)
457 {
458 if (getSocketError() == PEGASUS_INVALID_ADDRESS_FAMILY)
459 {
460 return false;
461 }
462 }
463 else
464 {
|
465 carson.hovey 1.64 #if defined(PEGASUS_OS_VMS)
466 // vms has tcpipv6 support in the kernel so socket
467 // will always work so a call to "bind" is needed
468 // to complete this test.
469
470 struct sockaddr_storage listenAddress;
471 memset(&listenAddress, 0, sizeof (listenAddress));
472 SocketLength addressLength;
473
474 HostAddress::convertTextToBinary(
475 HostAddress::AT_IPV6,
476 "::1",
477 &reinterpret_cast<struct sockaddr_in6*>(&listenAddress)->sin6_addr);
478 listenAddress.ss_family = AF_INET6;
479 reinterpret_cast<struct sockaddr_in6*>(&listenAddress)->sin6_port = 0;
480
481 addressLength = sizeof(struct sockaddr_in6);
482
483 if (::bind(
484 ip6Socket,
485 reinterpret_cast<struct sockaddr*>(&listenAddress),
486 carson.hovey 1.64 addressLength) < 0)
487 {
488 Socket::close(ip6Socket);
489 return false;
490 }
491 #endif // PEGASUS_OS_VMS
492
|
493 venkat.puvvada 1.56 Socket::close(ip6Socket);
494 }
495
496 return true;
497 }
498 #endif
499
|
500 r.kieninger 1.21 // ------------------------------------------------------------------------
501 // Convert a hostname into a a single host unique integer representation
502 // ------------------------------------------------------------------------
|
503 marek 1.63 Boolean System::acquireIP(const char* hostname, int *af, void *dst)
|
504 dave.sudlik 1.52 {
505 #ifdef PEGASUS_ENABLE_IPV6
506 String ipAddress;
507 if(getHostIP(hostname, af, ipAddress))
|
508 dmitry.mikulin 1.59 {
|
509 dave.sudlik 1.52 HostAddress::convertTextToBinary(*af, ipAddress.getCString(), dst);
510 return true;
511 }
512 return false;
513 #else
514 *af = AF_INET;
|
515 kumpf 1.44 Uint32 ip = 0xFFFFFFFF;
|
516 marek 1.65 if (!hostname)
|
517 kumpf 1.73 {
|
518 marek 1.65 *af = 0xFFFFFFFF;
519 return false;
520 }
|
521 r.kieninger 1.21
|
522 dave.sudlik 1.22 ////////////////////////////////////////////////////////////////////////////////
523 // This code used to check if the first character of "hostname" was alphabetic
|
524 kumpf 1.44 // to indicate hostname instead of IP address. But RFC 1123, section 2.1,
525 // relaxed this requirement to alphabetic character *or* digit. So bug 1462
526 // changed the flow here to call inet_addr first to check for a valid IP
527 // address in dotted decimal notation. If it's not a valid IP address, then
528 // try to validate it as a hostname.
529 // RFC 1123 states: The host SHOULD check the string syntactically for a
530 // dotted-decimal number before looking it up in the Domain Name System.
|
531 dave.sudlik 1.22 // Hence the call to inet_addr() first.
532 ////////////////////////////////////////////////////////////////////////////////
533
|
534 kumpf 1.44 Uint32 tmp_addr = inet_addr((char *) hostname);
|
535 kumpf 1.36 struct hostent* hostEntry;
|
536 r.kieninger 1.21
|
537 dave.sudlik 1.22 // Note: 0xFFFFFFFF is actually a valid IP address (255.255.255.255).
538 // A better solution would be to use inet_aton() or equivalent, as
539 // inet_addr() is now considered "obsolete".
540
541 if (tmp_addr == 0xFFFFFFFF) // if hostname is not an IP address
|
542 kumpf 1.36 {
543 char hostEntryBuffer[8192];
544 struct hostent hostEntryStruct;
|
545 kumpf 1.73 hostEntry = getHostByName(hostname, &hostEntryStruct,
|
546 dmitry.mikulin 1.59 hostEntryBuffer, sizeof (hostEntryBuffer));
|
547 kumpf 1.36
548 if (!hostEntry)
|
549 kumpf 1.44 {
|
550 dave.sudlik 1.52 // error, couldn't resolve the ip
551 memcpy(dst, &ip, sizeof (Uint32));
552 return false;
|
553 kumpf 1.44 }
554 unsigned char ip_part1,ip_part2,ip_part3,ip_part4;
555
556 ip_part1 = hostEntry->h_addr[0];
557 ip_part2 = hostEntry->h_addr[1];
558 ip_part3 = hostEntry->h_addr[2];
559 ip_part4 = hostEntry->h_addr[3];
560 ip = ip_part1;
561 ip = (ip << 8) + ip_part2;
562 ip = (ip << 8) + ip_part3;
563 ip = (ip << 8) + ip_part4;
564 }
|
565 dave.sudlik 1.22 else // else hostname *is* a dotted-decimal IP address
|
566 kumpf 1.44 {
567 // resolve hostaddr to a real host entry
568 // casting to (const char *) as (char *) will work as (void *) too,
569 // those it fits all platforms
|
570 ms.aruran 1.45 char hostEntryBuffer[8192];
571 struct hostent hostEntryStruct;
|
572 kumpf 1.73 hostEntry =
573 getHostByAddr((const char*) &tmp_addr, sizeof(tmp_addr), AF_INET,
|
574 dmitry.mikulin 1.59 &hostEntryStruct, hostEntryBuffer, sizeof (hostEntryBuffer));
|
575 ms.aruran 1.45
|
576 kumpf 1.44 if (hostEntry == 0)
577 {
578 // error, couldn't resolve the ip
|
579 dave.sudlik 1.52 memcpy(dst, &ip, sizeof (Uint32));
580 return false;
|
581 kumpf 1.44 }
582 else
583 {
584 unsigned char ip_part1,ip_part2,ip_part3,ip_part4;
|
585 r.kieninger 1.21
|
586 kumpf 1.44 ip_part1 = hostEntry->h_addr[0];
587 ip_part2 = hostEntry->h_addr[1];
588 ip_part3 = hostEntry->h_addr[2];
589 ip_part4 = hostEntry->h_addr[3];
590 ip = ip_part1;
591 ip = (ip << 8) + ip_part2;
592 ip = (ip << 8) + ip_part3;
593 ip = (ip << 8) + ip_part4;
594 }
595 }
|
596 dave.sudlik 1.52 memcpy(dst, &ip, sizeof (Uint32));
|
597 carolann.graves 1.29
598 return true;
|
599 dave.sudlik 1.52 #endif
|
600 carolann.graves 1.29 }
601
|
602 kumpf 1.44 Boolean System::resolveHostNameAtDNS(
603 const char* hostname,
604 Uint32* resolvedNameIP)
|
605 marek 1.43 {
|
606 dmitry.mikulin 1.59 struct hostent* hostEntry;
607
|
608 marek 1.43 // ask the DNS for hostname resolution to IP address
609 // this can mean a time delay for as long as the DNS
|
610 kumpf 1.44 // takes to answer
611 char hostEntryBuffer[8192];
612 struct hostent hostEntryStruct;
|
613 kumpf 1.73 hostEntry = getHostByName(hostname, &hostEntryStruct,
|
614 dmitry.mikulin 1.59 hostEntryBuffer, sizeof (hostEntryBuffer));
|
615 marek 1.43
616 if (hostEntry == 0)
617 {
618 // error, couldn't resolve the hostname to an ip address
619 return false;
|
620 kumpf 1.44 }
621 else
|
622 marek 1.43 {
623 unsigned char ip_part1,ip_part2,ip_part3,ip_part4;
624 ip_part1 = hostEntry->h_addr[0];
625 ip_part2 = hostEntry->h_addr[1];
626 ip_part3 = hostEntry->h_addr[2];
627 ip_part4 = hostEntry->h_addr[3];
628 *resolvedNameIP = ip_part1;
629 *resolvedNameIP = (*resolvedNameIP << 8) + ip_part2;
630 *resolvedNameIP = (*resolvedNameIP << 8) + ip_part3;
631 *resolvedNameIP = (*resolvedNameIP << 8) + ip_part4;
632 }
633 return true;
634 }
635
636 Boolean System::resolveIPAtDNS(Uint32 ip_addr, Uint32 * resolvedIP)
637 {
|
638 kumpf 1.44 struct hostent *entry;
|
639 marek 1.43
|
640 dmitry.mikulin 1.59 entry = getHostByAddr((const char *) &ip_addr, sizeof(ip_addr), AF_INET);
|
641 kumpf 1.73
|
642 kumpf 1.44 if (entry == 0)
643 {
644 // error, couldn't resolve the ip
645 return false;
646 }
647 else
648 {
649 unsigned char ip_part1,ip_part2,ip_part3,ip_part4;
650 ip_part1 = entry->h_addr[0];
651 ip_part2 = entry->h_addr[1];
652 ip_part3 = entry->h_addr[2];
653 ip_part4 = entry->h_addr[3];
654 *resolvedIP = ip_part1;
655 *resolvedIP = (*resolvedIP << 8) + ip_part2;
656 *resolvedIP = (*resolvedIP << 8) + ip_part3;
657 *resolvedIP = (*resolvedIP << 8) + ip_part4;
658 }
659 return true;
|
660 marek 1.43 }
661
662
|
663 dave.sudlik 1.52 Boolean System::isLoopBack(int af, void *binIPAddress)
664 {
665 #ifdef PEGASUS_ENABLE_IPV6
666 struct in6_addr ip6 = PEGASUS_IPV6_LOOPBACK_INIT;
667 #endif
668 switch (af)
669 {
670 #ifdef PEGASUS_ENABLE_IPV6
671 case AF_INET6:
672 return !memcmp(&ip6, binIPAddress, sizeof (ip6));
673 #endif
674 case AF_INET:
|
675 karl 1.69 {
676 Uint32 tmp;
677 memcpy(&tmp, binIPAddress, sizeof(Uint32));
678 Uint32 n = ntohl(tmp);
|
679 venkat.puvvada 1.75 return n >= PEGASUS_IPV4_LOOPBACK_RANGE_START &&
680 n <= PEGASUS_IPV4_LOOPBACK_RANGE_END;
|
681 karl 1.69 }
|
682 dave.sudlik 1.52 }
683
684 return false;
685 }
686
|
687 marek 1.43 Boolean System::isLocalHost(const String &hostName)
688 {
|
689 marek 1.80 // if value of hostName is "localhost" or equals the value of _hostname or
690 // equals the value of _fullyQualifiedHostname we can safely assume it to
691 // be the local host
692 if (String::equalNoCase(hostName,String("localhost")) ||
693 String::equalNoCase(hostName, _hostname) ||
694 String::equalNoCase(hostName, _fullyQualifiedHostname))
695 {
696 return true;
697 }
698
|
699 dave.sudlik 1.52 // Get all ip addresses on the node and compare them with the given hostname.
700 #ifdef PEGASUS_ENABLE_IPV6
701 CString csName = hostName.getCString();
|
702 dave.sudlik 1.53 struct addrinfo hints, *res1, *res2, *res1root, *res2root;
|
703 dave.sudlik 1.52 char localHostName[PEGASUS_MAXHOSTNAMELEN];
704 gethostname(localHostName, PEGASUS_MAXHOSTNAMELEN);
705 Boolean isLocal = false;
706
707 memset(&hints, 0, sizeof(hints));
708 hints.ai_family = AF_INET;
709 hints.ai_socktype = SOCK_STREAM;
710 hints.ai_protocol = IPPROTO_TCP;
|
711 dave.sudlik 1.53 res1root = res2root = 0;
|
712 dmitry.mikulin 1.59 getAddrInfo(csName, 0, &hints, &res1root);
713 getAddrInfo(localHostName, 0, &hints, &res2root);
|
714 dave.sudlik 1.52
|
715 dave.sudlik 1.53 res1 = res1root;
|
716 dave.sudlik 1.52 while (res1 && !isLocal)
717 {
718 if (isLoopBack(AF_INET,
|
719 kumpf 1.54 &(reinterpret_cast<struct sockaddr_in*>(res1->ai_addr))->sin_addr))
|
720 dave.sudlik 1.52 {
721 isLocal = true;
722 break;
723 }
724
|
725 dave.sudlik 1.53 res2 = res2root;
|
726 kumpf 1.73 while (res2)
|
727 dave.sudlik 1.52 {
|
728 kumpf 1.54 if (!memcmp(
729 &(reinterpret_cast<struct sockaddr_in*>(res1->ai_addr))->
730 sin_addr,
731 &(reinterpret_cast<struct sockaddr_in*>(res2->ai_addr))->
732 sin_addr,
733 sizeof (struct in_addr)))
|
734 dave.sudlik 1.52 {
735 isLocal = true;
736 break;
737 }
|
738 dave.sudlik 1.53 res2 = res2->ai_next;
|
739 dave.sudlik 1.52 }
740 res1 = res1->ai_next;
|
741 kumpf 1.73 }
|
742 kumpf 1.62 if (res1root)
743 {
744 freeaddrinfo(res1root);
745 }
746 if (res2root)
747 {
748 freeaddrinfo(res2root);
749 }
|
750 dave.sudlik 1.52 if (isLocal)
751 {
752 return true;
|
753 kumpf 1.73 }
|
754 dave.sudlik 1.52
755 hints.ai_family = AF_INET6;
|
756 dave.sudlik 1.53 res1root = res2root = 0;
|
757 dmitry.mikulin 1.59 getAddrInfo(csName, 0, &hints, &res1root);
758 getAddrInfo(localHostName, 0, &hints, &res2root);
|
759 dave.sudlik 1.53
760 res1 = res1root;
|
761 dave.sudlik 1.52 while (res1 && !isLocal)
762 {
|
763 kumpf 1.54 if (isLoopBack(
764 AF_INET6,
765 &(reinterpret_cast<struct sockaddr_in6*>(res1->ai_addr))->
766 sin6_addr))
|
767 dave.sudlik 1.52 {
768 isLocal = true;
769 break;
770 }
771
|
772 dave.sudlik 1.53 res2 = res2root;
773 while (res2)
|
774 dave.sudlik 1.52 {
|
775 kumpf 1.54 if (!memcmp(
776 &(reinterpret_cast<struct sockaddr_in6*>(res1->ai_addr))->
777 sin6_addr,
778 &(reinterpret_cast<struct sockaddr_in6*>(res2->ai_addr))->
779 sin6_addr,
780 sizeof (struct in6_addr)))
|
781 dave.sudlik 1.52 {
782 isLocal = true;
783 break;
784 }
|
785 dave.sudlik 1.53 res2 = res2->ai_next;
|
786 dave.sudlik 1.52 }
787 res1 = res1->ai_next;
788 }
|
789 kumpf 1.62 if (res1root)
790 {
791 freeaddrinfo(res1root);
792 }
793 if (res2root)
794 {
795 freeaddrinfo(res2root);
796 }
|
797 dave.sudlik 1.52 return isLocal;
798 #else
799
|
800 marek 1.43 // differentiate between a dotted IP address given
801 // and a real hostname given
802 CString csName = hostName.getCString();
|
803 marek 1.46 char cc_hostname[PEGASUS_MAXHOSTNAMELEN];
804 strcpy(cc_hostname, (const char*) csName);
|
805 marek 1.43 Uint32 tmp_addr = 0xFFFFFFFF;
806 Boolean hostNameIsIPNotation;
807
808 // Note: Platforms already supporting the inet_aton()
809 // should define their platform here,
810 // as this is the superior way to work
|
811 kumpf 1.54 #if defined(PEGASUS_OS_LINUX) || \
812 defined(PEGASUS_OS_AIX) || \
|
813 ouyang.jian 1.55 defined(PEGASUS_OS_HPUX) || \
|
814 carson.hovey 1.60 defined(PEGASUS_OS_PASE) || \
815 defined(PEGASUS_OS_VMS)
|
816 kumpf 1.44
|
817 marek 1.43 struct in_addr inaddr;
818 // if inet_aton failed(return=0),
819 // we do not have a valip IP address (x.x.x.x)
820 int atonSuccess = inet_aton(cc_hostname, &inaddr);
821 if (atonSuccess == 0) hostNameIsIPNotation = false;
822 else
823 {
824 hostNameIsIPNotation = true;
825 tmp_addr = inaddr.s_addr;
826 }
827 #else
828 // Note: 0xFFFFFFFF is actually a valid IP address (255.255.255.255).
829 // A better solution would be to use inet_aton() or equivalent, as
830 // inet_addr() is now considered "obsolete".
831 // Note: inet_aton() not yet supported on all Pegasus platforms
|
832 kumpf 1.44 tmp_addr = inet_addr((char *) cc_hostname);
|
833 marek 1.43 if (tmp_addr == 0xFFFFFFFF) hostNameIsIPNotation = false;
834 else hostNameIsIPNotation = true;
835 #endif
|
836 kumpf 1.44
|
837 marek 1.43 if (!hostNameIsIPNotation) // if hostname is not an IP address
|
838 kumpf 1.44 {
|
839 marek 1.46 char localHostName[PEGASUS_MAXHOSTNAMELEN];
|
840 marek 1.47 CString cstringLocalHostName = System::getHostName().getCString();
|
841 kumpf 1.73 strcpy(localHostName, (const char*) cstringLocalHostName);
|
842 marek 1.43 // given hostname equals what system returns as local hostname ?
843 if (String::equalNoCase(hostName,localHostName)) return true;
844 Uint32 hostIP;
845 // bail out if hostname unresolveable
846 if (!System::resolveHostNameAtDNS(cc_hostname, &hostIP)) return false;
847 // lets see if the IP is defined on one of the network interfaces
848 // this can help us avoid another call to DNS
849 if (System::isIpOnNetworkInterface(hostIP)) return true;
850 // need to check if the local hosts name is possibly
851 // registered at the DNS with the IP address equal resolvedNameIP
852 Uint32 localHostIP;
|
853 kumpf 1.44 if (!System::resolveHostNameAtDNS(localHostName, &localHostIP))
854 return false;
|
855 marek 1.43 if (localHostIP == hostIP) return true;
|
856 kumpf 1.44 }
857 else
|
858 marek 1.43 { // hostname is an IP address
859 // 127.0.0.1 is always the loopback
860 // inet_addr returns network byte order
861 if (tmp_addr == htonl(0x7F000001)) return true;
862 // IP defined on a local AF_INET network interface
863 if (System::isIpOnNetworkInterface(tmp_addr)) return true;
864 // out of luck so far, lets ask the DNS what our IP is
865 // and check against what we got
866 Uint32 localHostIP;
|
867 kumpf 1.44 if (!System::resolveHostNameAtDNS(
868 (const char*) System::getHostName().getCString(), &localHostIP))
869 return false;
|
870 marek 1.43 if (localHostIP == tmp_addr) return true;
871 // not yet, sometimes resolving the IP address we got against the DNS
872 // can solve the problem
|
873 kumpf 1.44 // casting to (const char *) as (char *) will work as (void *) too,
874 // those it fits all platforms
|
875 marek 1.43 Uint32 hostIP;
876 if (!System::resolveIPAtDNS(tmp_addr, &hostIP)) return false;
877 if (hostIP == localHostIP) return true;
878 }
879 return false;
|
880 dave.sudlik 1.52 #endif
|
881 marek 1.43 }
882
|
883 dmitry.mikulin 1.59 struct hostent* System::getHostByName(
|
884 kumpf 1.73 const char* name,
885 struct hostent* he,
886 char* buf,
|
887 dmitry.mikulin 1.59 size_t len)
888 {
889 int hostEntryErrno = 0;
890 struct hostent* hostEntry = 0;
891 unsigned int maxTries = 5;
892
893 do
894 {
895 #if defined(PEGASUS_OS_LINUX)
|
896 kumpf 1.73 gethostbyname_r(name,
897 he,
898 buf,
899 len,
900 &hostEntry,
|
901 dmitry.mikulin 1.59 &hostEntryErrno);
902 #elif defined(PEGASUS_OS_SOLARIS)
|
903 kumpf 1.73 hostEntry = gethostbyname_r((char *)name,
904 he,
905 buf,
906 len,
|
907 dmitry.mikulin 1.59 &hostEntryErrno);
908 #elif defined(PEGASUS_OS_ZOS)
909 char hostName[PEGASUS_MAXHOSTNAMELEN + 1];
910 if (String::equalNoCase("localhost", String(name)))
911 {
912 gethostname(hostName, PEGASUS_MAXHOSTNAMELEN);
913 hostName[sizeof(hostName) - 1] = 0;
914 hostEntry = gethostbyname(hostName);
915 }
916 else
917 {
918 hostEntry = gethostbyname((char *)name);
919 }
920 hostEntryErrno = h_errno;
921 #else
922 hostEntry = gethostbyname((char *)name);
923 hostEntryErrno = h_errno;
924 #endif
925 } while (hostEntry == 0 && hostEntryErrno == TRY_AGAIN &&
926 maxTries-- > 0);
927
928 dmitry.mikulin 1.59 return hostEntry;
929 }
930
931 struct hostent* System::getHostByAddr(
|
932 kumpf 1.73 const char *addr,
933 int len,
|
934 dmitry.mikulin 1.59 int type,
|
935 kumpf 1.73 struct hostent* he,
936 char* buf,
|
937 dmitry.mikulin 1.59 size_t buflen)
938 {
939 int hostEntryErrno = 0;
940 struct hostent* hostEntry = 0;
941 unsigned int maxTries = 5;
942
943 do
944 {
945 #if defined(PEGASUS_OS_LINUX)
|
946 kumpf 1.73 gethostbyaddr_r(addr,
947 len,
948 type,
949 he,
950 buf,
951 buflen,
952 &hostEntry,
|
953 dmitry.mikulin 1.59 &hostEntryErrno);
954 #elif defined(PEGASUS_OS_SOLARIS)
955 char hostEntryBuffer[8192];
956 struct hostent hostEntryStruct;
957
|
958 kumpf 1.73 hostEntry = gethostbyaddr_r(addr,
959 len,
960 type,
961 he,
962 buf,
963 buflen,
|
964 dmitry.mikulin 1.59 &hostEntryErrno);
965 #else
|
966 kumpf 1.73 hostEntry = gethostbyaddr(addr,
967 len,
|
968 dmitry.mikulin 1.59 type);
969 hostEntryErrno = h_errno;
970 #endif
971 } while (hostEntry == 0 && hostEntryErrno == TRY_AGAIN &&
972 maxTries-- > 0);
973
974 return hostEntry;
975 }
976
|
977 dmitry.mikulin 1.61
|
978 dmitry.mikulin 1.59 int System::getAddrInfo(
|
979 kumpf 1.73 const char *hostname,
|
980 dmitry.mikulin 1.59 const char *servname,
|
981 kumpf 1.73 const struct addrinfo *hints,
|
982 dmitry.mikulin 1.59 struct addrinfo **res)
983 {
984 int rc = 0;
|
985 dev.meetei 1.82 Uint16 maxTries = 5;
|
986 dmitry.mikulin 1.59
|
987 ouyang.jian 1.67 #ifdef PEGASUS_OS_PASE
988 CString hostNameCString;
989 if (String::equalNoCase(hostname, "localhost"))
990 {
991 hostNameCString = getHostName().getCString();
992 hostname = (const char*)hostNameCString;
993 }
994 #endif
995
|
996 dev.meetei 1.82 do
997 {
998 rc = getaddrinfo(hostname,
|
999 kumpf 1.73 servname,
1000 hints,
|
1001 dev.meetei 1.82 res);
1002 if( rc != EAI_AGAIN)
1003 {
1004 PEG_TRACE((TRC_OS_ABSTRACTION, Tracer::LEVEL1,
1005 "getaddrinfo failed: %s",gai_strerror(rc)));
1006 break;
1007 }
1008 } while( rc == EAI_AGAIN && --maxTries > 0);
|
1009 dmitry.mikulin 1.59 return rc;
1010 }
1011
1012 int System::getNameInfo(
|
1013 kumpf 1.73 const struct sockaddr *sa,
|
1014 dmitry.mikulin 1.59 size_t salen,
|
1015 kumpf 1.73 char *host,
1016 size_t hostlen,
1017 char *serv,
1018 size_t servlen,
|
1019 dmitry.mikulin 1.59 int flags)
1020 {
1021 int rc = 0;
|
1022 dev.meetei 1.82 Uint16 maxTries = 5;
1023 do
1024 {
1025 rc = getnameinfo(sa,
1026 salen,
1027 host,
1028 hostlen,
1029 serv,
1030 servlen,
1031 flags);
1032 if( rc != EAI_AGAIN)
1033 {
1034 PEG_TRACE((TRC_OS_ABSTRACTION, Tracer::LEVEL1,
1035 "getnameinfo failed: %s",gai_strerror(rc)));
1036 break;
1037 }
1038 } while( rc == EAI_AGAIN && --maxTries > 0);
|
1039 dmitry.mikulin 1.59 return rc;
1040 }
1041
1042
|
1043 tony 1.17 // System ID constants for Logger::put and Logger::trace
|
1044 s.kodali 1.76 #ifdef PEGASUS_FLAVOR
|
1045 dev.meetei 1.82 const String System::CIMLISTENER = "cimlistener" PEGASUS_FLAVOR;
|
1046 s.kodali 1.76 #else
|
1047 dev.meetei 1.82 const String System::CIMLISTENER = "cimlistener"; // Listener systme ID
|
1048 s.kodali 1.76 #endif
|
1049 tony 1.17
|
1050 mike 1.8 PEGASUS_NAMESPACE_END
|