1 karl 1.37 //%2006////////////////////////////////////////////////////////////////////////
|
2 mike 1.6 //
|
3 karl 1.23 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
4 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
5 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
|
6 karl 1.19 // IBM Corp.; EMC Corporation, The Open Group.
|
7 karl 1.23 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
|
9 karl 1.25 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 karl 1.37 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
|
13 mike 1.6 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
|
15 kumpf 1.11 // of this software and associated documentation files (the "Software"), to
16 // deal in the Software without restriction, including without limitation the
17 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
18 mike 1.6 // sell copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
|
20 karl 1.23 //
|
21 kumpf 1.11 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
|
22 mike 1.6 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
23 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
24 kumpf 1.11 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
25 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
27 mike 1.6 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 //==============================================================================
31 //
32 //%/////////////////////////////////////////////////////////////////////////////
|
33 mike 1.8
|
34 sage 1.12 #if defined(PEGASUS_PLATFORM_ZOS_ZSERIES_IBM)
|
35 r.kieninger 1.21 #include <Pegasus/Common/Config.h>
36 #endif
|
37 sage 1.12
|
38 mike 1.8 #include <fstream>
|
39 kumpf 1.13 #include <cctype> // for tolower()
|
40 kumpf 1.14 #include <cstring>
|
41 mike 1.6 #include "System.h"
|
42 r.kieninger 1.21 #include "Socket.h"
|
43 mike 1.39 #include "Network.h"
|
44 kumpf 1.10 #include <Pegasus/Common/PegasusVersion.h>
|
45 mateus.baur 1.50 #include <Pegasus/Common/FileSystem.h>
|
46 dave.sudlik 1.52 #include <Pegasus/Common/HostAddress.h>
47 #include <Pegasus/Common/Array.h>
|
48 kumpf 1.10
|
49 mike 1.6 #if defined(PEGASUS_OS_TYPE_WINDOWS)
50 # include "SystemWindows.cpp"
|
51 kumpf 1.41 #elif defined(PEGASUS_OS_TYPE_UNIX) || defined(PEGASUS_OS_VMS)
|
52 mike 1.40 # include "SystemPOSIX.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 mike 1.8 Boolean System::copyFile(const char* fromPath, const char* toPath)
64 {
|
65 ramnath 1.9 ifstream is(fromPath PEGASUS_IOS_BINARY);
|
66 mateus.baur 1.50 fstream os(toPath, ios::out PEGASUS_OR_IOS_BINARY);
|
67 mike 1.8
68 char c;
69
70 while (is.get(c))
71 {
|
72 kumpf 1.44 if (!os.put(c))
73 return false;
|
74 mike 1.8 }
75
|
76 mateus.baur 1.50 FileSystem::syncWithDirectoryUpdates(os);
|
77 kumpf 1.42 return is.eof();
|
78 kumpf 1.13 }
79
|
80 kumpf 1.44 static const Uint8 _toLowerTable[256] =
|
81 mike 1.32 {
82 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
83 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
84 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
85 0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
86 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
87 0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
88 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
89 0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
90 0x40,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,0x5B,0x5C,0x5D,0x5E,0x5F,
94 0x60,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,0x7B,0x7C,0x7D,0x7E,0x7F,
98 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,
99 0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
100 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,
101 0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
102 mike 1.32 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
103 0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
104 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,
105 0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
106 0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,
107 0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
108 0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,
109 0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,
110 0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,
111 0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
112 0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,
113 0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,
114 };
115
|
116 kumpf 1.13 Sint32 System::strcasecmp(const char* s1, const char* s2)
117 {
|
118 mike 1.32 // Note: this is faster than glibc strcasecmp().
119
120 Uint8* p = (Uint8*)s1;
121 Uint8* q = (Uint8*)s2;
122 int r;
123
124 for (;;)
|
125 kumpf 1.13 {
|
126 kumpf 1.44 if ((r = _toLowerTable[p[0]] - _toLowerTable[q[0]]) || !p[0] ||
127 (r = _toLowerTable[p[1]] - _toLowerTable[q[1]]) || !p[1] ||
128 (r = _toLowerTable[p[2]] - _toLowerTable[q[2]]) || !p[2] ||
129 (r = _toLowerTable[p[3]] - _toLowerTable[q[3]]) || !p[3])
130 break;
|
131 kumpf 1.13
|
132 kumpf 1.44 p += 4;
133 q += 4;
|
134 kumpf 1.13 }
135
|
136 mike 1.32 return r;
|
137 mike 1.8 }
138
|
139 tony 1.15 // Return the just the file name from the path into basename
140 char *System::extract_file_name(const char *fullpath, char *basename)
141 {
|
142 kumpf 1.44 if (fullpath == NULL)
143 {
144 basename[0] = '\0';
145 return basename;
146 }
|
147 kumpf 1.31
|
148 kumpf 1.44 for (const char* p = fullpath + strlen(fullpath) - 1; p >= fullpath; p--)
149 {
150 if (*p == '\\' || *p == '/')
151 {
152 strcpy(basename, p+1);
153 return basename;
154 }
155 }
156
157 strcpy(basename, fullpath);
158 return basename;
|
159 tony 1.15 }
160
161 // Return the just the path to the file name into dirname
162 char *System::extract_file_path(const char *fullpath, char *dirname)
163 {
|
164 kumpf 1.44 char *p;
165 char buff[4096];
166 if (fullpath == NULL)
167 {
168 dirname[0] = '\0';
169 return dirname;
170 }
171 strncpy(buff, fullpath, sizeof(buff)-1);
172 buff[sizeof(buff)-1] = '\0';
173 for (p = buff + strlen(buff); p >= buff; p--)
|
174 tony 1.15 {
|
175 kumpf 1.44 if (*p == '\\' || *p == '/')
|
176 tony 1.15 {
177 strncpy(dirname, buff, p+1 - buff);
178 dirname[p+1 - buff] = '\0';
179 return dirname;
180 }
181 }
|
182 kumpf 1.44 strcpy(dirname, fullpath);
183 return dirname;
|
184 tony 1.15 }
185
|
186 dave.sudlik 1.52 Boolean System::getHostIP(const String &hostName, int *af, String &hostIP)
|
187 marek 1.24 {
|
188 dave.sudlik 1.52 #ifdef PEGASUS_ENABLE_IPV6
189 struct addrinfo *info, hints;
190 memset (&hints, 0, sizeof(struct addrinfo));
191
192 // Check for valid IPV4 address, if found return ipv4 address
193 *af = AF_INET;
194 hints.ai_family = *af;
195 hints.ai_protocol = IPPROTO_TCP;
196 hints.ai_socktype = SOCK_STREAM;
|
197 dmitry.mikulin 1.58 if (!getaddrinfo(hostName.getCString(), 0, &hints, &info))
|
198 dave.sudlik 1.52 {
199 char ipAddress[PEGASUS_INET_ADDRSTR_LEN];
200 HostAddress::convertBinaryToText(info->ai_family,
|
201 kumpf 1.54 &(reinterpret_cast<struct sockaddr_in*>(info->ai_addr))->sin_addr,
202 ipAddress,
|
203 dave.sudlik 1.52 PEGASUS_INET_ADDRSTR_LEN);
204 hostIP = ipAddress;
205 freeaddrinfo(info);
206 return true;
207 }
208
209 // Check for valid IPV6 Address.
210 *af = AF_INET6;
211 hints.ai_family = *af;
212 hints.ai_protocol = IPPROTO_TCP;
213 hints.ai_socktype = SOCK_STREAM;
|
214 dmitry.mikulin 1.58 if (!getaddrinfo(hostName.getCString(), 0, &hints, &info))
|
215 dave.sudlik 1.52 {
216 char ipAddress[PEGASUS_INET6_ADDRSTR_LEN];
217 HostAddress::convertBinaryToText(info->ai_family,
|
218 kumpf 1.54 &(reinterpret_cast<struct sockaddr_in6*>(info->ai_addr))->sin6_addr,
219 ipAddress,
|
220 dave.sudlik 1.52 PEGASUS_INET6_ADDRSTR_LEN);
221 hostIP = ipAddress;
222 freeaddrinfo(info);
223 return true;
224 }
225
226 return false;
227 #else
228 *af = AF_INET;
|
229 kumpf 1.36 struct hostent* hostEntry;
230 struct in_addr inaddr;
231 String ipAddress;
232 CString hostNameCString = hostName.getCString();
233 const char* hostNamePtr = hostNameCString;
234
|
235 dmitry.mikulin 1.58 #if defined(PEGASUS_OS_LINUX)
236 char hostEntryBuffer[8192];
237 struct hostent hostEntryStruct;
238 int hostEntryErrno;
239
240 gethostbyname_r(
241 hostNamePtr,
242 &hostEntryStruct,
243 hostEntryBuffer,
244 sizeof(hostEntryBuffer),
245 &hostEntry,
246 &hostEntryErrno);
247 #elif defined(PEGASUS_OS_SOLARIS)
|
248 kumpf 1.36 char hostEntryBuffer[8192];
249 struct hostent hostEntryStruct;
|
250 dmitry.mikulin 1.58 int hostEntryErrno;
251
252 hostEntry = gethostbyname_r(
253 (char *)hostNamePtr,
254 &hostEntryStruct,
255 hostEntryBuffer,
256 sizeof(hostEntryBuffer),
257 &hostEntryErrno);
258 #else
259 hostEntry = gethostbyname(hostNamePtr);
260 #endif
|
261 kumpf 1.36
262 if (hostEntry)
|
263 marek 1.24 {
|
264 kumpf 1.36 ::memcpy( &inaddr, hostEntry->h_addr,4);
|
265 marek 1.24 ipAddress = ::inet_ntoa( inaddr );
266 }
|
267 dmitry.mikulin 1.58 hostIP = ipAddress;
268 return true;
|
269 dave.sudlik 1.52 #endif
|
270 marek 1.24 }
|
271 r.kieninger 1.21
|
272 venkat.puvvada 1.56
273 #ifdef PEGASUS_ENABLE_IPV6
274 Boolean System::isIPv6StackActive()
275 {
276 SocketHandle ip6Socket;
277 if ((ip6Socket = Socket::createSocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP))
278 == PEGASUS_INVALID_SOCKET)
279 {
280 if (getSocketError() == PEGASUS_INVALID_ADDRESS_FAMILY)
281 {
282 return false;
283 }
284 }
285 else
286 {
287 Socket::close(ip6Socket);
288 }
289
290 return true;
291 }
292 #endif
293 venkat.puvvada 1.56
|
294 r.kieninger 1.21 // ------------------------------------------------------------------------
295 // Convert a hostname into a a single host unique integer representation
296 // ------------------------------------------------------------------------
|
297 dave.sudlik 1.52 Boolean System::_acquireIP(const char* hostname, int *af, void *dst)
298 {
299 #ifdef PEGASUS_ENABLE_IPV6
300 String ipAddress;
301 if(getHostIP(hostname, af, ipAddress))
|
302 dmitry.mikulin 1.58 {
|
303 dave.sudlik 1.52 HostAddress::convertTextToBinary(*af, ipAddress.getCString(), dst);
304 return true;
305 }
306 return false;
307 #else
308 *af = AF_INET;
|
309 kumpf 1.44 Uint32 ip = 0xFFFFFFFF;
310 if (!hostname) return 0xFFFFFFFF;
|
311 r.kieninger 1.21
|
312 dave.sudlik 1.22 ////////////////////////////////////////////////////////////////////////////////
313 // This code used to check if the first character of "hostname" was alphabetic
|
314 kumpf 1.44 // to indicate hostname instead of IP address. But RFC 1123, section 2.1,
315 // relaxed this requirement to alphabetic character *or* digit. So bug 1462
316 // changed the flow here to call inet_addr first to check for a valid IP
317 // address in dotted decimal notation. If it's not a valid IP address, then
318 // try to validate it as a hostname.
319 // RFC 1123 states: The host SHOULD check the string syntactically for a
320 // dotted-decimal number before looking it up in the Domain Name System.
|
321 dave.sudlik 1.22 // Hence the call to inet_addr() first.
322 ////////////////////////////////////////////////////////////////////////////////
323
|
324 kumpf 1.44 Uint32 tmp_addr = inet_addr((char *) hostname);
|
325 dmitry.mikulin 1.58
|
326 kumpf 1.36 struct hostent* hostEntry;
|
327 r.kieninger 1.21
|
328 dave.sudlik 1.22 // Note: 0xFFFFFFFF is actually a valid IP address (255.255.255.255).
329 // A better solution would be to use inet_aton() or equivalent, as
330 // inet_addr() is now considered "obsolete".
331
332 if (tmp_addr == 0xFFFFFFFF) // if hostname is not an IP address
|
333 kumpf 1.36 {
|
334 dmitry.mikulin 1.58 #if defined(PEGASUS_OS_LINUX)
335 char hostEntryBuffer[8192];
336 struct hostent hostEntryStruct;
337 int hostEntryErrno;
338
339 gethostbyname_r(
340 hostname,
341 &hostEntryStruct,
342 hostEntryBuffer,
343 sizeof(hostEntryBuffer),
344 &hostEntry,
345 &hostEntryErrno);
346 #elif defined(PEGASUS_OS_SOLARIS)
|
347 kumpf 1.36 char hostEntryBuffer[8192];
348 struct hostent hostEntryStruct;
|
349 dmitry.mikulin 1.58 int hostEntryErrno;
|
350 kumpf 1.36
|
351 dmitry.mikulin 1.58 hostEntry = gethostbyname_r(
352 (char *)hostname,
353 &hostEntryStruct,
354 hostEntryBuffer,
355 sizeof(hostEntryBuffer),
356 &hostEntryErrno);
357 #elif defined(PEGASUS_OS_ZOS)
358 char hostName[PEGASUS_MAXHOSTNAMELEN + 1];
359 if (String::equalNoCase("localhost",String(hostname)))
360 {
361 gethostname( hostName, PEGASUS_MAXHOSTNAMELEN );
362 hostName[sizeof(hostName)-1] = 0;
363 hostEntry = gethostbyname(hostName);
364 }
365 else
366 {
367 hostEntry = gethostbyname((char *)hostname);
368 }
369 #else
370 hostEntry = gethostbyname((char *)hostname);
371 #endif
|
372 kumpf 1.36 if (!hostEntry)
|
373 kumpf 1.44 {
|
374 dave.sudlik 1.52 // error, couldn't resolve the ip
375 memcpy(dst, &ip, sizeof (Uint32));
376 return false;
|
377 kumpf 1.44 }
378 unsigned char ip_part1,ip_part2,ip_part3,ip_part4;
379
380 ip_part1 = hostEntry->h_addr[0];
381 ip_part2 = hostEntry->h_addr[1];
382 ip_part3 = hostEntry->h_addr[2];
383 ip_part4 = hostEntry->h_addr[3];
384 ip = ip_part1;
385 ip = (ip << 8) + ip_part2;
386 ip = (ip << 8) + ip_part3;
387 ip = (ip << 8) + ip_part4;
388 }
|
389 dave.sudlik 1.22 else // else hostname *is* a dotted-decimal IP address
|
390 kumpf 1.44 {
391 // resolve hostaddr to a real host entry
392 // casting to (const char *) as (char *) will work as (void *) too,
393 // those it fits all platforms
|
394 dmitry.mikulin 1.58 #if defined(PEGASUS_OS_LINUX)
395 char hostEntryBuffer[8192];
396 struct hostent hostEntryStruct;
397 int hostEntryErrno;
398
399 gethostbyaddr_r(
400 (const char*) &tmp_addr,
401 sizeof(tmp_addr),
402 AF_INET,
403 &hostEntryStruct,
404 hostEntryBuffer,
405 sizeof(hostEntryBuffer),
406 &hostEntry,
407 &hostEntryErrno);
408 #elif defined(PEGASUS_OS_SOLARIS)
|
409 ms.aruran 1.45 char hostEntryBuffer[8192];
410 struct hostent hostEntryStruct;
|
411 dmitry.mikulin 1.58 int hostEntryErrno;
|
412 ms.aruran 1.45
|
413 dmitry.mikulin 1.58 hostEntry = gethostbyaddr_r(
414 (const char *) &tmp_addr,
415 sizeof(tmp_addr),
416 AF_INET,
417 &hostEntryStruct,
418 hostEntryBuffer,
419 sizeof(hostEntryBuffer),
420 &hostEntryErrno);
421 #else
422 hostEntry =
423 gethostbyaddr((const char *) &tmp_addr, sizeof(tmp_addr), AF_INET);
424 #endif
|
425 kumpf 1.44 if (hostEntry == 0)
426 {
427 // error, couldn't resolve the ip
|
428 dave.sudlik 1.52 memcpy(dst, &ip, sizeof (Uint32));
429 return false;
|
430 kumpf 1.44 }
431 else
432 {
433 unsigned char ip_part1,ip_part2,ip_part3,ip_part4;
|
434 r.kieninger 1.21
|
435 kumpf 1.44 ip_part1 = hostEntry->h_addr[0];
436 ip_part2 = hostEntry->h_addr[1];
437 ip_part3 = hostEntry->h_addr[2];
438 ip_part4 = hostEntry->h_addr[3];
439 ip = ip_part1;
440 ip = (ip << 8) + ip_part2;
441 ip = (ip << 8) + ip_part3;
442 ip = (ip << 8) + ip_part4;
443 }
444 }
|
445 dave.sudlik 1.52 memcpy(dst, &ip, sizeof (Uint32));
|
446 carolann.graves 1.29
447 return true;
|
448 dave.sudlik 1.52 #endif
|
449 carolann.graves 1.29 }
450
|
451 kumpf 1.44 Boolean System::resolveHostNameAtDNS(
452 const char* hostname,
453 Uint32* resolvedNameIP)
|
454 marek 1.43 {
455 // ask the DNS for hostname resolution to IP address
456 // this can mean a time delay for as long as the DNS
|
457 kumpf 1.44 // takes to answer
|
458 dmitry.mikulin 1.58 struct hostent* hostEntry;
459
460 #if defined(PEGASUS_OS_LINUX)
|
461 kumpf 1.44 char hostEntryBuffer[8192];
462 struct hostent hostEntryStruct;
|
463 dmitry.mikulin 1.58 int hostEntryErrno;
|
464 marek 1.43
|
465 dmitry.mikulin 1.58 gethostbyname_r(
466 hostname,
467 &hostEntryStruct,
468 hostEntryBuffer,
469 sizeof(hostEntryBuffer),
470 &hostEntry,
471 &hostEntryErrno);
472 #elif defined(PEGASUS_OS_SOLARIS)
473 char hostEntryBuffer[8192];
474 struct hostent hostEntryStruct;
475 int hostEntryErrno;
476
477 hostEntry = gethostbyname_r(
478 (char *)hostname,
479 &hostEntryStruct,
480 hostEntryBuffer,
481 sizeof(hostEntryBuffer),
482 &hostEntryErrno);
483 #else
484 hostEntry = gethostbyname((char *)hostname);
485 #endif
|
486 marek 1.43 if (hostEntry == 0)
487 {
488 // error, couldn't resolve the hostname to an ip address
489 return false;
|
490 kumpf 1.44 }
491 else
|
492 marek 1.43 {
493 unsigned char ip_part1,ip_part2,ip_part3,ip_part4;
494 ip_part1 = hostEntry->h_addr[0];
495 ip_part2 = hostEntry->h_addr[1];
496 ip_part3 = hostEntry->h_addr[2];
497 ip_part4 = hostEntry->h_addr[3];
498 *resolvedNameIP = ip_part1;
499 *resolvedNameIP = (*resolvedNameIP << 8) + ip_part2;
500 *resolvedNameIP = (*resolvedNameIP << 8) + ip_part3;
501 *resolvedNameIP = (*resolvedNameIP << 8) + ip_part4;
502 }
503 return true;
504 }
505
506 Boolean System::resolveIPAtDNS(Uint32 ip_addr, Uint32 * resolvedIP)
507 {
|
508 kumpf 1.44 struct hostent *entry;
|
509 marek 1.43
|
510 dmitry.mikulin 1.58 entry = gethostbyaddr((const char *) &ip_addr, sizeof(ip_addr), AF_INET);
|
511 ouyang.jian 1.51
|
512 kumpf 1.44 if (entry == 0)
513 {
514 // error, couldn't resolve the ip
515 return false;
516 }
517 else
518 {
519 unsigned char ip_part1,ip_part2,ip_part3,ip_part4;
520 ip_part1 = entry->h_addr[0];
521 ip_part2 = entry->h_addr[1];
522 ip_part3 = entry->h_addr[2];
523 ip_part4 = entry->h_addr[3];
524 *resolvedIP = ip_part1;
525 *resolvedIP = (*resolvedIP << 8) + ip_part2;
526 *resolvedIP = (*resolvedIP << 8) + ip_part3;
527 *resolvedIP = (*resolvedIP << 8) + ip_part4;
528 }
529 return true;
|
530 marek 1.43 }
531
532
|
533 dave.sudlik 1.52 Boolean System::isLoopBack(int af, void *binIPAddress)
534 {
535 #ifdef PEGASUS_ENABLE_IPV6
536 struct in6_addr ip6 = PEGASUS_IPV6_LOOPBACK_INIT;
537 #endif
538 Uint32 ip4 = PEGASUS_IPV4_LOOPBACK_INIT;
539 switch (af)
540 {
541 #ifdef PEGASUS_ENABLE_IPV6
542 case AF_INET6:
543 return !memcmp(&ip6, binIPAddress, sizeof (ip6));
544 #endif
545 case AF_INET:
546 Uint32 n = ntohl( *(Uint32*)binIPAddress);
547 return !memcmp(&ip4, &n, sizeof (ip4));
548 }
549
550 return false;
551 }
552
|
553 marek 1.43 Boolean System::isLocalHost(const String &hostName)
554 {
|
555 dave.sudlik 1.52 // Get all ip addresses on the node and compare them with the given hostname.
556 #ifdef PEGASUS_ENABLE_IPV6
557 CString csName = hostName.getCString();
|
558 dave.sudlik 1.53 struct addrinfo hints, *res1, *res2, *res1root, *res2root;
|
559 dave.sudlik 1.52 char localHostName[PEGASUS_MAXHOSTNAMELEN];
560 gethostname(localHostName, PEGASUS_MAXHOSTNAMELEN);
561 Boolean isLocal = false;
562
563 memset(&hints, 0, sizeof(hints));
564 hints.ai_family = AF_INET;
565 hints.ai_socktype = SOCK_STREAM;
566 hints.ai_protocol = IPPROTO_TCP;
|
567 dave.sudlik 1.53 res1root = res2root = 0;
|
568 dmitry.mikulin 1.58 getaddrinfo(csName, 0, &hints, &res1root);
569 getaddrinfo(localHostName, 0, &hints, &res2root);
|
570 dave.sudlik 1.52
|
571 dave.sudlik 1.53 res1 = res1root;
|
572 dave.sudlik 1.52 while (res1 && !isLocal)
573 {
574 if (isLoopBack(AF_INET,
|
575 kumpf 1.54 &(reinterpret_cast<struct sockaddr_in*>(res1->ai_addr))->sin_addr))
|
576 dave.sudlik 1.52 {
577 isLocal = true;
578 break;
579 }
580
|
581 dave.sudlik 1.53 res2 = res2root;
582 while (res2)
|
583 dave.sudlik 1.52 {
|
584 kumpf 1.54 if (!memcmp(
585 &(reinterpret_cast<struct sockaddr_in*>(res1->ai_addr))->
586 sin_addr,
587 &(reinterpret_cast<struct sockaddr_in*>(res2->ai_addr))->
588 sin_addr,
589 sizeof (struct in_addr)))
|
590 dave.sudlik 1.52 {
591 isLocal = true;
592 break;
593 }
|
594 dave.sudlik 1.53 res2 = res2->ai_next;
|
595 dave.sudlik 1.52 }
596 res1 = res1->ai_next;
597 }
|
598 dave.sudlik 1.53 freeaddrinfo(res1root);
599 freeaddrinfo(res2root);
|
600 dave.sudlik 1.52 if (isLocal)
601 {
602 return true;
603 }
604
605 hints.ai_family = AF_INET6;
|
606 dave.sudlik 1.53 res1root = res2root = 0;
|
607 dmitry.mikulin 1.58 getaddrinfo(csName, 0, &hints, &res1root);
608 getaddrinfo(localHostName, 0, &hints, &res2root);
|
609 dave.sudlik 1.53
610 res1 = res1root;
|
611 dave.sudlik 1.52 while (res1 && !isLocal)
612 {
|
613 kumpf 1.54 if (isLoopBack(
614 AF_INET6,
615 &(reinterpret_cast<struct sockaddr_in6*>(res1->ai_addr))->
616 sin6_addr))
|
617 dave.sudlik 1.52 {
618 isLocal = true;
619 break;
620 }
621
|
622 dave.sudlik 1.53 res2 = res2root;
623 while (res2)
|
624 dave.sudlik 1.52 {
|
625 kumpf 1.54 if (!memcmp(
626 &(reinterpret_cast<struct sockaddr_in6*>(res1->ai_addr))->
627 sin6_addr,
628 &(reinterpret_cast<struct sockaddr_in6*>(res2->ai_addr))->
629 sin6_addr,
630 sizeof (struct in6_addr)))
|
631 dave.sudlik 1.52 {
632 isLocal = true;
633 break;
634 }
|
635 dave.sudlik 1.53 res2 = res2->ai_next;
|
636 dave.sudlik 1.52 }
637 res1 = res1->ai_next;
638 }
|
639 dave.sudlik 1.53 freeaddrinfo(res1root);
640 freeaddrinfo(res2root);
|
641 dave.sudlik 1.52
642 return isLocal;
643 #else
644
|
645 marek 1.43 // differentiate between a dotted IP address given
646 // and a real hostname given
647 CString csName = hostName.getCString();
|
648 marek 1.46 char cc_hostname[PEGASUS_MAXHOSTNAMELEN];
649 strcpy(cc_hostname, (const char*) csName);
|
650 marek 1.43 Uint32 tmp_addr = 0xFFFFFFFF;
651 Boolean hostNameIsIPNotation;
652
653 // Note: Platforms already supporting the inet_aton()
654 // should define their platform here,
655 // as this is the superior way to work
|
656 kumpf 1.54 #if defined(PEGASUS_OS_LINUX) || \
657 defined(PEGASUS_OS_AIX) || \
|
658 ouyang.jian 1.55 defined(PEGASUS_OS_HPUX) || \
659 defined(PEGASUS_OS_PASE)
|
660 kumpf 1.44
|
661 marek 1.43 struct in_addr inaddr;
662 // if inet_aton failed(return=0),
663 // we do not have a valip IP address (x.x.x.x)
664 int atonSuccess = inet_aton(cc_hostname, &inaddr);
665 if (atonSuccess == 0) hostNameIsIPNotation = false;
666 else
667 {
668 hostNameIsIPNotation = true;
669 tmp_addr = inaddr.s_addr;
670 }
671 #else
672 // Note: 0xFFFFFFFF is actually a valid IP address (255.255.255.255).
673 // A better solution would be to use inet_aton() or equivalent, as
674 // inet_addr() is now considered "obsolete".
675 // Note: inet_aton() not yet supported on all Pegasus platforms
|
676 kumpf 1.44 tmp_addr = inet_addr((char *) cc_hostname);
|
677 marek 1.43 if (tmp_addr == 0xFFFFFFFF) hostNameIsIPNotation = false;
678 else hostNameIsIPNotation = true;
679 #endif
|
680 kumpf 1.44
|
681 marek 1.43 if (!hostNameIsIPNotation) // if hostname is not an IP address
|
682 kumpf 1.44 {
|
683 marek 1.43 // localhost ?
684 if (String::equalNoCase(hostName,String("localhost"))) return true;
|
685 marek 1.46 char localHostName[PEGASUS_MAXHOSTNAMELEN];
|
686 marek 1.47 CString cstringLocalHostName = System::getHostName().getCString();
|
687 marek 1.46 strcpy(localHostName, (const char*) cstringLocalHostName);
|
688 marek 1.43 // given hostname equals what system returns as local hostname ?
689 if (String::equalNoCase(hostName,localHostName)) return true;
690 Uint32 hostIP;
691 // bail out if hostname unresolveable
692 if (!System::resolveHostNameAtDNS(cc_hostname, &hostIP)) return false;
693 // lets see if the IP is defined on one of the network interfaces
694 // this can help us avoid another call to DNS
695 if (System::isIpOnNetworkInterface(hostIP)) return true;
696 // need to check if the local hosts name is possibly
697 // registered at the DNS with the IP address equal resolvedNameIP
698 Uint32 localHostIP;
|
699 kumpf 1.44 if (!System::resolveHostNameAtDNS(localHostName, &localHostIP))
700 return false;
|
701 marek 1.43 if (localHostIP == hostIP) return true;
|
702 kumpf 1.44 }
703 else
|
704 marek 1.43 { // hostname is an IP address
705 // 127.0.0.1 is always the loopback
706 // inet_addr returns network byte order
707 if (tmp_addr == htonl(0x7F000001)) return true;
708 // IP defined on a local AF_INET network interface
709 if (System::isIpOnNetworkInterface(tmp_addr)) return true;
710 // out of luck so far, lets ask the DNS what our IP is
711 // and check against what we got
712 Uint32 localHostIP;
|
713 kumpf 1.44 if (!System::resolveHostNameAtDNS(
714 (const char*) System::getHostName().getCString(), &localHostIP))
715 return false;
|
716 marek 1.43 if (localHostIP == tmp_addr) return true;
717 // not yet, sometimes resolving the IP address we got against the DNS
718 // can solve the problem
|
719 kumpf 1.44 // casting to (const char *) as (char *) will work as (void *) too,
720 // those it fits all platforms
|
721 marek 1.43 Uint32 hostIP;
722 if (!System::resolveIPAtDNS(tmp_addr, &hostIP)) return false;
723 if (hostIP == localHostIP) return true;
724 }
725 return false;
|
726 dave.sudlik 1.52 #endif
|
727 marek 1.43 }
728
|
729 tony 1.17 // System ID constants for Logger::put and Logger::trace
730 const String System::CIMLISTENER = "cimlistener"; // Listener systme ID
731
|
732 mike 1.8 PEGASUS_NAMESPACE_END
|
733 dmitry.mikulin 1.58
|