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