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 if (!getaddrinfo(hostName.getCString(), 0, &hints, &info))
198 {
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 if (!getaddrinfo(hostName.getCString(), 0, &hints, &info))
215 {
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 #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 char hostEntryBuffer[8192];
249 struct hostent hostEntryStruct;
250 kumpf 1.36 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 humberto 1.27 #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 dave.sudlik 1.52 hostIP = ipAddress;
268 return true;
269 #endif
|
270 marek 1.24 }
|
271 r.kieninger 1.21
272 // ------------------------------------------------------------------------
273 // Convert a hostname into a a single host unique integer representation
274 // ------------------------------------------------------------------------
|
275 dave.sudlik 1.52 Boolean System::_acquireIP(const char* hostname, int *af, void *dst)
276 {
277 #ifdef PEGASUS_ENABLE_IPV6
278 String ipAddress;
279 if(getHostIP(hostname, af, ipAddress))
|
280 r.kieninger 1.21 {
|
281 dave.sudlik 1.52 HostAddress::convertTextToBinary(*af, ipAddress.getCString(), dst);
282 return true;
283 }
284 return false;
285 #else
286 *af = AF_INET;
|
287 kumpf 1.44 Uint32 ip = 0xFFFFFFFF;
288 if (!hostname) return 0xFFFFFFFF;
|
289 r.kieninger 1.21
|
290 dave.sudlik 1.22 ////////////////////////////////////////////////////////////////////////////////
291 // This code used to check if the first character of "hostname" was alphabetic
|
292 kumpf 1.44 // to indicate hostname instead of IP address. But RFC 1123, section 2.1,
293 // relaxed this requirement to alphabetic character *or* digit. So bug 1462
294 // changed the flow here to call inet_addr first to check for a valid IP
295 // address in dotted decimal notation. If it's not a valid IP address, then
296 // try to validate it as a hostname.
297 // RFC 1123 states: The host SHOULD check the string syntactically for a
298 // dotted-decimal number before looking it up in the Domain Name System.
|
299 dave.sudlik 1.22 // Hence the call to inet_addr() first.
300 ////////////////////////////////////////////////////////////////////////////////
301
|
302 kumpf 1.44 Uint32 tmp_addr = inet_addr((char *) hostname);
|
303 dave.sudlik 1.22
|
304 kumpf 1.36 struct hostent* hostEntry;
|
305 r.kieninger 1.21
|
306 dave.sudlik 1.22 // Note: 0xFFFFFFFF is actually a valid IP address (255.255.255.255).
307 // A better solution would be to use inet_aton() or equivalent, as
308 // inet_addr() is now considered "obsolete".
309
310 if (tmp_addr == 0xFFFFFFFF) // if hostname is not an IP address
|
311 kumpf 1.36 {
312 #if defined(PEGASUS_OS_LINUX)
313 char hostEntryBuffer[8192];
314 struct hostent hostEntryStruct;
315 int hostEntryErrno;
316
317 gethostbyname_r(
318 hostname,
319 &hostEntryStruct,
320 hostEntryBuffer,
321 sizeof(hostEntryBuffer),
322 &hostEntry,
323 &hostEntryErrno);
324 #elif defined(PEGASUS_OS_SOLARIS)
325 char hostEntryBuffer[8192];
326 struct hostent hostEntryStruct;
327 int hostEntryErrno;
328
329 hostEntry = gethostbyname_r(
330 (char *)hostname,
331 &hostEntryStruct,
332 kumpf 1.36 hostEntryBuffer,
333 sizeof(hostEntryBuffer),
334 &hostEntryErrno);
|
335 r.kieninger 1.21 #elif defined(PEGASUS_OS_ZOS)
|
336 kumpf 1.36 char hostName[PEGASUS_MAXHOSTNAMELEN + 1];
337 if (String::equalNoCase("localhost",String(hostname)))
338 {
339 gethostname( hostName, PEGASUS_MAXHOSTNAMELEN );
340 hostName[sizeof(hostName)-1] = 0;
341 hostEntry = gethostbyname(hostName);
|
342 kumpf 1.44 }
343 else
|
344 kumpf 1.36 {
345 hostEntry = gethostbyname((char *)hostname);
346 }
|
347 r.kieninger 1.21 #else
|
348 kumpf 1.36 hostEntry = gethostbyname((char *)hostname);
|
349 r.kieninger 1.21 #endif
|
350 kumpf 1.36 if (!hostEntry)
|
351 kumpf 1.44 {
|
352 dave.sudlik 1.52 // error, couldn't resolve the ip
353 memcpy(dst, &ip, sizeof (Uint32));
354 return false;
|
355 kumpf 1.44 }
356 unsigned char ip_part1,ip_part2,ip_part3,ip_part4;
357
358 ip_part1 = hostEntry->h_addr[0];
359 ip_part2 = hostEntry->h_addr[1];
360 ip_part3 = hostEntry->h_addr[2];
361 ip_part4 = hostEntry->h_addr[3];
362 ip = ip_part1;
363 ip = (ip << 8) + ip_part2;
364 ip = (ip << 8) + ip_part3;
365 ip = (ip << 8) + ip_part4;
366 }
|
367 dave.sudlik 1.22 else // else hostname *is* a dotted-decimal IP address
|
368 kumpf 1.44 {
369 // resolve hostaddr to a real host entry
370 // casting to (const char *) as (char *) will work as (void *) too,
371 // those it fits all platforms
|
372 ms.aruran 1.45 #if defined(PEGASUS_OS_LINUX)
373 char hostEntryBuffer[8192];
374 struct hostent hostEntryStruct;
375 int hostEntryErrno;
376
377 gethostbyaddr_r(
378 (const char*) &tmp_addr,
379 sizeof(tmp_addr),
380 AF_INET,
381 &hostEntryStruct,
382 hostEntryBuffer,
383 sizeof(hostEntryBuffer),
384 &hostEntry,
385 &hostEntryErrno);
386 #elif defined(PEGASUS_OS_SOLARIS)
387 char hostEntryBuffer[8192];
388 struct hostent hostEntryStruct;
389 int hostEntryErrno;
390
391 hostEntry = gethostbyaddr_r(
392 (const char *) &tmp_addr,
393 ms.aruran 1.45 sizeof(tmp_addr),
394 AF_INET,
395 &hostEntryStruct,
396 hostEntryBuffer,
397 sizeof(hostEntryBuffer),
398 &hostEntryErrno);
|
399 humberto 1.27 #else
|
400 kumpf 1.44 hostEntry =
|
401 ms.aruran 1.45 gethostbyaddr((const char *) &tmp_addr, sizeof(tmp_addr), AF_INET);
|
402 humberto 1.27 #endif
|
403 kumpf 1.44 if (hostEntry == 0)
404 {
405 // error, couldn't resolve the ip
|
406 dave.sudlik 1.52 memcpy(dst, &ip, sizeof (Uint32));
407 return false;
|
408 kumpf 1.44 }
409 else
410 {
411 unsigned char ip_part1,ip_part2,ip_part3,ip_part4;
|
412 r.kieninger 1.21
|
413 kumpf 1.44 ip_part1 = hostEntry->h_addr[0];
414 ip_part2 = hostEntry->h_addr[1];
415 ip_part3 = hostEntry->h_addr[2];
416 ip_part4 = hostEntry->h_addr[3];
417 ip = ip_part1;
418 ip = (ip << 8) + ip_part2;
419 ip = (ip << 8) + ip_part3;
420 ip = (ip << 8) + ip_part4;
421 }
422 }
|
423 dave.sudlik 1.52 memcpy(dst, &ip, sizeof (Uint32));
|
424 carolann.graves 1.29
425 return true;
|
426 dave.sudlik 1.52 #endif
|
427 carolann.graves 1.29 }
428
|
429 kumpf 1.44 Boolean System::resolveHostNameAtDNS(
430 const char* hostname,
431 Uint32* resolvedNameIP)
|
432 marek 1.43 {
433 // ask the DNS for hostname resolution to IP address
434 // this can mean a time delay for as long as the DNS
|
435 kumpf 1.44 // takes to answer
|
436 marek 1.43 struct hostent* hostEntry;
437
438 #if defined(PEGASUS_OS_LINUX)
|
439 kumpf 1.44 char hostEntryBuffer[8192];
440 struct hostent hostEntryStruct;
441 int hostEntryErrno;
|
442 marek 1.43
|
443 kumpf 1.44 gethostbyname_r(
444 hostname,
445 &hostEntryStruct,
446 hostEntryBuffer,
447 sizeof(hostEntryBuffer),
448 &hostEntry,
449 &hostEntryErrno);
|
450 marek 1.43 #elif defined(PEGASUS_OS_SOLARIS)
|
451 kumpf 1.44 char hostEntryBuffer[8192];
452 struct hostent hostEntryStruct;
453 int hostEntryErrno;
|
454 marek 1.43
|
455 kumpf 1.44 hostEntry = gethostbyname_r(
456 (char *)hostname,
457 &hostEntryStruct,
458 hostEntryBuffer,
459 sizeof(hostEntryBuffer),
460 &hostEntryErrno);
|
461 marek 1.43 #else
|
462 kumpf 1.44 hostEntry = gethostbyname((char *)hostname);
|
463 marek 1.43 #endif
464 if (hostEntry == 0)
465 {
466 // error, couldn't resolve the hostname to an ip address
467 return false;
|
468 kumpf 1.44 }
469 else
|
470 marek 1.43 {
471 unsigned char ip_part1,ip_part2,ip_part3,ip_part4;
472 ip_part1 = hostEntry->h_addr[0];
473 ip_part2 = hostEntry->h_addr[1];
474 ip_part3 = hostEntry->h_addr[2];
475 ip_part4 = hostEntry->h_addr[3];
476 *resolvedNameIP = ip_part1;
477 *resolvedNameIP = (*resolvedNameIP << 8) + ip_part2;
478 *resolvedNameIP = (*resolvedNameIP << 8) + ip_part3;
479 *resolvedNameIP = (*resolvedNameIP << 8) + ip_part4;
480 }
481 return true;
482 }
483
484 Boolean System::resolveIPAtDNS(Uint32 ip_addr, Uint32 * resolvedIP)
485 {
|
486 kumpf 1.44 struct hostent *entry;
|
487 marek 1.43
|
488 kumpf 1.44 entry = gethostbyaddr((const char *) &ip_addr, sizeof(ip_addr), AF_INET);
|
489 ouyang.jian 1.51
|
490 kumpf 1.44 if (entry == 0)
491 {
492 // error, couldn't resolve the ip
493 return false;
494 }
495 else
496 {
497 unsigned char ip_part1,ip_part2,ip_part3,ip_part4;
498 ip_part1 = entry->h_addr[0];
499 ip_part2 = entry->h_addr[1];
500 ip_part3 = entry->h_addr[2];
501 ip_part4 = entry->h_addr[3];
502 *resolvedIP = ip_part1;
503 *resolvedIP = (*resolvedIP << 8) + ip_part2;
504 *resolvedIP = (*resolvedIP << 8) + ip_part3;
505 *resolvedIP = (*resolvedIP << 8) + ip_part4;
506 }
507 return true;
|
508 marek 1.43 }
509
510
|
511 dave.sudlik 1.52 Boolean System::isLoopBack(int af, void *binIPAddress)
512 {
513 #ifdef PEGASUS_ENABLE_IPV6
514 struct in6_addr ip6 = PEGASUS_IPV6_LOOPBACK_INIT;
515 #endif
516 Uint32 ip4 = PEGASUS_IPV4_LOOPBACK_INIT;
517 switch (af)
518 {
519 #ifdef PEGASUS_ENABLE_IPV6
520 case AF_INET6:
521 return !memcmp(&ip6, binIPAddress, sizeof (ip6));
522 #endif
523 case AF_INET:
524 Uint32 n = ntohl( *(Uint32*)binIPAddress);
525 return !memcmp(&ip4, &n, sizeof (ip4));
526 }
527
528 return false;
529 }
530
|
531 marek 1.43 Boolean System::isLocalHost(const String &hostName)
532 {
|
533 dave.sudlik 1.52 // Get all ip addresses on the node and compare them with the given hostname.
534 #ifdef PEGASUS_ENABLE_IPV6
535 CString csName = hostName.getCString();
|
536 dave.sudlik 1.53 struct addrinfo hints, *res1, *res2, *res1root, *res2root;
|
537 dave.sudlik 1.52 char localHostName[PEGASUS_MAXHOSTNAMELEN];
538 gethostname(localHostName, PEGASUS_MAXHOSTNAMELEN);
539 Boolean isLocal = false;
540
541 memset(&hints, 0, sizeof(hints));
542 hints.ai_family = AF_INET;
543 hints.ai_socktype = SOCK_STREAM;
544 hints.ai_protocol = IPPROTO_TCP;
|
545 dave.sudlik 1.53 res1root = res2root = 0;
546 getaddrinfo(csName, 0, &hints, &res1root);
547 getaddrinfo(localHostName, 0, &hints, &res2root);
|
548 dave.sudlik 1.52
|
549 dave.sudlik 1.53 res1 = res1root;
|
550 dave.sudlik 1.52 while (res1 && !isLocal)
551 {
552 if (isLoopBack(AF_INET,
|
553 kumpf 1.54 &(reinterpret_cast<struct sockaddr_in*>(res1->ai_addr))->sin_addr))
|
554 dave.sudlik 1.52 {
555 isLocal = true;
556 break;
557 }
558
|
559 dave.sudlik 1.53 res2 = res2root;
560 while (res2)
|
561 dave.sudlik 1.52 {
|
562 kumpf 1.54 if (!memcmp(
563 &(reinterpret_cast<struct sockaddr_in*>(res1->ai_addr))->
564 sin_addr,
565 &(reinterpret_cast<struct sockaddr_in*>(res2->ai_addr))->
566 sin_addr,
567 sizeof (struct in_addr)))
|
568 dave.sudlik 1.52 {
569 isLocal = true;
570 break;
571 }
|
572 dave.sudlik 1.53 res2 = res2->ai_next;
|
573 dave.sudlik 1.52 }
574 res1 = res1->ai_next;
575 }
|
576 dave.sudlik 1.53 freeaddrinfo(res1root);
577 freeaddrinfo(res2root);
|
578 dave.sudlik 1.52 if (isLocal)
579 {
580 return true;
581 }
582
583 hints.ai_family = AF_INET6;
|
584 dave.sudlik 1.53 res1root = res2root = 0;
585 getaddrinfo(csName, 0, &hints, &res1root);
586 getaddrinfo(localHostName, 0, &hints, &res2root);
587
588 res1 = res1root;
|
589 dave.sudlik 1.52 while (res1 && !isLocal)
590 {
|
591 kumpf 1.54 if (isLoopBack(
592 AF_INET6,
593 &(reinterpret_cast<struct sockaddr_in6*>(res1->ai_addr))->
594 sin6_addr))
|
595 dave.sudlik 1.52 {
596 isLocal = true;
597 break;
598 }
599
|
600 dave.sudlik 1.53 res2 = res2root;
601 while (res2)
|
602 dave.sudlik 1.52 {
|
603 kumpf 1.54 if (!memcmp(
604 &(reinterpret_cast<struct sockaddr_in6*>(res1->ai_addr))->
605 sin6_addr,
606 &(reinterpret_cast<struct sockaddr_in6*>(res2->ai_addr))->
607 sin6_addr,
608 sizeof (struct in6_addr)))
|
609 dave.sudlik 1.52 {
610 isLocal = true;
611 break;
612 }
|
613 dave.sudlik 1.53 res2 = res2->ai_next;
|
614 dave.sudlik 1.52 }
615 res1 = res1->ai_next;
616 }
|
617 dave.sudlik 1.53 freeaddrinfo(res1root);
618 freeaddrinfo(res2root);
|
619 dave.sudlik 1.52
620 return isLocal;
621 #else
622
|
623 marek 1.43 // differentiate between a dotted IP address given
624 // and a real hostname given
625 CString csName = hostName.getCString();
|
626 marek 1.46 char cc_hostname[PEGASUS_MAXHOSTNAMELEN];
627 strcpy(cc_hostname, (const char*) csName);
|
628 marek 1.43 Uint32 tmp_addr = 0xFFFFFFFF;
629 Boolean hostNameIsIPNotation;
630
631 // Note: Platforms already supporting the inet_aton()
632 // should define their platform here,
633 // as this is the superior way to work
|
634 kumpf 1.54 #if defined(PEGASUS_OS_LINUX) || \
635 defined(PEGASUS_OS_AIX) || \
636 defined(PEGASUS_OS_HPUX)
|
637 kumpf 1.44
|
638 marek 1.43 struct in_addr inaddr;
639 // if inet_aton failed(return=0),
640 // we do not have a valip IP address (x.x.x.x)
641 int atonSuccess = inet_aton(cc_hostname, &inaddr);
642 if (atonSuccess == 0) hostNameIsIPNotation = false;
643 else
644 {
645 hostNameIsIPNotation = true;
646 tmp_addr = inaddr.s_addr;
647 }
648 #else
649 // Note: 0xFFFFFFFF is actually a valid IP address (255.255.255.255).
650 // A better solution would be to use inet_aton() or equivalent, as
651 // inet_addr() is now considered "obsolete".
652 // Note: inet_aton() not yet supported on all Pegasus platforms
|
653 kumpf 1.44 tmp_addr = inet_addr((char *) cc_hostname);
|
654 marek 1.43 if (tmp_addr == 0xFFFFFFFF) hostNameIsIPNotation = false;
655 else hostNameIsIPNotation = true;
656 #endif
|
657 kumpf 1.44
|
658 marek 1.43 if (!hostNameIsIPNotation) // if hostname is not an IP address
|
659 kumpf 1.44 {
|
660 marek 1.43 // localhost ?
661 if (String::equalNoCase(hostName,String("localhost"))) return true;
|
662 marek 1.46 char localHostName[PEGASUS_MAXHOSTNAMELEN];
|
663 marek 1.47 CString cstringLocalHostName = System::getHostName().getCString();
|
664 marek 1.46 strcpy(localHostName, (const char*) cstringLocalHostName);
|
665 marek 1.43 // given hostname equals what system returns as local hostname ?
666 if (String::equalNoCase(hostName,localHostName)) return true;
667 Uint32 hostIP;
668 // bail out if hostname unresolveable
669 if (!System::resolveHostNameAtDNS(cc_hostname, &hostIP)) return false;
670 // lets see if the IP is defined on one of the network interfaces
671 // this can help us avoid another call to DNS
672 if (System::isIpOnNetworkInterface(hostIP)) return true;
673 // need to check if the local hosts name is possibly
674 // registered at the DNS with the IP address equal resolvedNameIP
675 Uint32 localHostIP;
|
676 kumpf 1.44 if (!System::resolveHostNameAtDNS(localHostName, &localHostIP))
677 return false;
|
678 marek 1.43 if (localHostIP == hostIP) return true;
|
679 kumpf 1.44 }
680 else
|
681 marek 1.43 { // hostname is an IP address
682 // 127.0.0.1 is always the loopback
683 // inet_addr returns network byte order
684 if (tmp_addr == htonl(0x7F000001)) return true;
685 // IP defined on a local AF_INET network interface
686 if (System::isIpOnNetworkInterface(tmp_addr)) return true;
687 // out of luck so far, lets ask the DNS what our IP is
688 // and check against what we got
689 Uint32 localHostIP;
|
690 kumpf 1.44 if (!System::resolveHostNameAtDNS(
691 (const char*) System::getHostName().getCString(), &localHostIP))
692 return false;
|
693 marek 1.43 if (localHostIP == tmp_addr) return true;
694 // not yet, sometimes resolving the IP address we got against the DNS
695 // can solve the problem
|
696 kumpf 1.44 // casting to (const char *) as (char *) will work as (void *) too,
697 // those it fits all platforms
|
698 marek 1.43 Uint32 hostIP;
699 if (!System::resolveIPAtDNS(tmp_addr, &hostIP)) return false;
700 if (hostIP == localHostIP) return true;
701 }
702 return false;
|
703 dave.sudlik 1.52 #endif
|
704 marek 1.43 }
705
|
706 tony 1.17 // System ID constants for Logger::put and Logger::trace
707 const String System::CIMLISTENER = "cimlistener"; // Listener systme ID
708
|
709 mike 1.8 PEGASUS_NAMESPACE_END
|
710 ms.aruran 1.45
|