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