mirror of
				https://github.com/Telecominfraproject/wlan-cloud-lib-poco.git
				synced 2025-10-31 10:37:46 +00:00 
			
		
		
		
	initial import
This commit is contained in:
		
							
								
								
									
										368
									
								
								Foundation/src/UUIDGenerator.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										368
									
								
								Foundation/src/UUIDGenerator.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,368 @@ | ||||
| // | ||||
| // UUIDGenerator.cpp | ||||
| // | ||||
| // $Id: //poco/1.1.0/Foundation/src/UUIDGenerator.cpp#2 $ | ||||
| // | ||||
| // Library: Foundation | ||||
| // Package: UUID | ||||
| // Module:  UUID | ||||
| // | ||||
| // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. | ||||
| // and Contributors. | ||||
| // | ||||
| // Permission is hereby granted, free of charge, to any person or organization | ||||
| // obtaining a copy of the software and accompanying documentation covered by | ||||
| // this license (the "Software") to use, reproduce, display, distribute, | ||||
| // execute, and transmit the Software, and to prepare derivative works of the | ||||
| // Software, and to permit third-parties to whom the Software is furnished to | ||||
| // do so, all subject to the following: | ||||
| //  | ||||
| // The copyright notices in the Software and this entire statement, including | ||||
| // the above license grant, this restriction and the following disclaimer, | ||||
| // must be included in all copies of the Software, in whole or in part, and | ||||
| // all derivative works of the Software, unless such copies or derivative | ||||
| // works are solely in the form of machine-executable object code generated by | ||||
| // a source language processor. | ||||
| //  | ||||
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
| // FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT | ||||
| // SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE | ||||
| // FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, | ||||
| // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||||
| // DEALINGS IN THE SOFTWARE. | ||||
| // | ||||
|  | ||||
|  | ||||
| #include "Foundation/UUIDGenerator.h" | ||||
| #include "Foundation/Thread.h" | ||||
| #include "Foundation/RandomStream.h" | ||||
| #include "Foundation/DigestEngine.h" | ||||
| #include "Foundation/MD5Engine.h" | ||||
| #include "Foundation/SingletonHolder.h" | ||||
| #include <string.h> | ||||
|  | ||||
|  | ||||
| Foundation_BEGIN | ||||
|  | ||||
|  | ||||
| UUIDGenerator::UUIDGenerator(): _ticks(0), _haveNode(false) | ||||
| { | ||||
| } | ||||
|  | ||||
|  | ||||
| UUIDGenerator::~UUIDGenerator() | ||||
| { | ||||
| } | ||||
|  | ||||
|  | ||||
| UUID UUIDGenerator::create() | ||||
| { | ||||
| 	FastMutex::ScopedLock lock(_mutex); | ||||
|  | ||||
| 	if (!_haveNode) | ||||
| 	{ | ||||
| 		getNode(); | ||||
| 		_haveNode = true; | ||||
| 	} | ||||
| 	Timestamp::UtcTimeVal tv = timeStamp(); | ||||
| 	UInt32 timeLow = UInt32(tv & 0xFFFFFFFF); | ||||
| 	UInt16 timeMid = UInt16((tv >> 32) & 0xFFFF); | ||||
| 	UInt16 timeHiAndVersion = UInt16((tv >> 48) & 0x0FFF) + (UUID::UUID_TIME_BASED << 12); | ||||
| 	UInt16 clockSeq = (UInt16(_random.next() >> 4) & 0x3FFF) | 0x8000; | ||||
| 	return UUID(timeLow, timeMid, timeHiAndVersion, clockSeq, _node); | ||||
| } | ||||
|  | ||||
|  | ||||
| UUID UUIDGenerator::createFromName(const UUID& nsid, const std::string& name) | ||||
| { | ||||
| 	MD5Engine md5; | ||||
| 	return createFromName(nsid, name, md5); | ||||
| } | ||||
|  | ||||
|  | ||||
| UUID UUIDGenerator::createFromName(const UUID& nsid, const std::string& name, DigestEngine& de) | ||||
| { | ||||
| 	poco_assert_dbg (de.digestLength() >= 16); | ||||
|  | ||||
| 	UUID netNsid = nsid; | ||||
| 	netNsid.toNetwork(); | ||||
| 	de.reset(); | ||||
| 	de.update(&netNsid, sizeof(netNsid)); | ||||
| 	de.update(name); | ||||
| 	char buffer[16]; | ||||
| 	const DigestEngine::Digest& d = de.digest(); | ||||
| 	for (int i = 0; i < 16; ++i) | ||||
| 	{ | ||||
| 		buffer[i] = d[i]; | ||||
| 	} | ||||
| 	return UUID(buffer, UUID::UUID_NAME_BASED); | ||||
| } | ||||
|  | ||||
| 	 | ||||
| UUID UUIDGenerator::createRandom() | ||||
| { | ||||
| 	char buffer[16]; | ||||
| 	RandomInputStream ris; | ||||
| 	ris.read(buffer, sizeof(buffer)); | ||||
| 	return UUID(buffer, UUID::UUID_RANDOM); | ||||
| } | ||||
|  | ||||
|  | ||||
| Timestamp::UtcTimeVal UUIDGenerator::timeStamp() | ||||
| { | ||||
| 	Timestamp now; | ||||
| 	for (;;) | ||||
| 	{ | ||||
| 		if (now != _lastTime) | ||||
| 		{ | ||||
| 			_lastTime = now; | ||||
| 			_ticks = 0; | ||||
| 			break; | ||||
| 		} | ||||
| 		if (_ticks < 100) | ||||
| 		{ | ||||
| 			++_ticks; | ||||
| 			break; | ||||
| 		} | ||||
| 		now.update(); | ||||
| 	} | ||||
| 	Timestamp::UtcTimeVal tv = now.utcTime(); | ||||
| 	return tv + _ticks; | ||||
| } | ||||
|  | ||||
|  | ||||
| UUID UUIDGenerator::createOne() | ||||
| { | ||||
| 	try | ||||
| 	{ | ||||
| 		return create(); | ||||
| 	} | ||||
| 	catch (Exception&) | ||||
| 	{ | ||||
| 		return createRandom(); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
| UUIDGenerator& UUIDGenerator::defaultGenerator() | ||||
| { | ||||
| 	static SingletonHolder<UUIDGenerator> sh; | ||||
| 	return *sh.get(); | ||||
| } | ||||
|  | ||||
|  | ||||
| Foundation_END | ||||
|  | ||||
|  | ||||
| // | ||||
| // platform-specific code below | ||||
| // | ||||
|  | ||||
|  | ||||
| #if defined(POCO_OS_FAMILY_WINDOWS) | ||||
| // | ||||
| // Windows | ||||
| // | ||||
| // The following code is based on the example code | ||||
| // from the MSDN knowledge base article ID 118623: | ||||
| // "How To Get the MAC Address for an Ethernet Adapter". | ||||
| // | ||||
| #include <windows.h> | ||||
| #include <wincon.h> | ||||
| #include <nb30.h> | ||||
|  | ||||
|  | ||||
| Foundation_BEGIN | ||||
|  | ||||
|  | ||||
| struct ASTAT | ||||
| { | ||||
| 	ADAPTER_STATUS adapt; | ||||
| 	NAME_BUFFER    nameBuffer[30]; | ||||
| }; | ||||
|  | ||||
|  | ||||
| void UUIDGenerator::getNode() | ||||
| { | ||||
| 	ASTAT adapter; | ||||
| 	NCB ncb; | ||||
| 	LANA_ENUM lenum; | ||||
|  | ||||
| 	memset(&ncb, 0, sizeof(ncb)); | ||||
| 	ncb.ncb_command = NCBENUM; | ||||
| 	ncb.ncb_buffer  = (UCHAR*) &lenum; | ||||
| 	ncb.ncb_length  = sizeof(lenum); | ||||
| 	UCHAR rc = Netbios(&ncb); | ||||
| 	if (rc) throw SystemException("cannot enumerate network adapters"); | ||||
| 	bool foundEtherNet = false; | ||||
| 	for (int i = 0; i < lenum.length; i++) | ||||
| 	{ | ||||
| 		memset(&ncb, 0, sizeof(ncb)); | ||||
| 		ncb.ncb_command  = NCBRESET; | ||||
| 		ncb.ncb_lana_num = lenum.lana[i]; | ||||
| 		rc = Netbios(&ncb); | ||||
| 		if (rc) throw SystemException("cannot determine MAC address (NCBRESET failed)"); | ||||
|  | ||||
| 		memset(&ncb, 0, sizeof(ncb)); | ||||
| 		ncb.ncb_command  = NCBASTAT; | ||||
| 		ncb.ncb_lana_num = lenum.lana[i]; | ||||
| 		ncb.ncb_buffer   = (UCHAR*) &adapter; | ||||
| 		ncb.ncb_length   = sizeof(adapter); | ||||
| 		strcpy((char*) ncb.ncb_callname,  "*"); | ||||
| 		rc = Netbios(&ncb); | ||||
| 		if (rc) throw SystemException("cannot determine MAC address (NCBASTAT failed)"); | ||||
| 		if (adapter.adapt.adapter_type == 0xFE) | ||||
| 		{ | ||||
| 			memcpy(_node, adapter.adapt.adapter_address, sizeof(_node)); | ||||
| 			foundEtherNet = true; | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	if (!foundEtherNet) throw SystemException("cannot determine MAC address (no Ethernet adapter found)"); | ||||
| } | ||||
|  | ||||
|  | ||||
| Foundation_END | ||||
|  | ||||
|  | ||||
| #elif defined(POCO_OS_FAMILY_BSD) || POCO_OS == POCO_OS_QNX | ||||
| // | ||||
| // BSD variants | ||||
| // | ||||
| #include <sys/types.h> | ||||
| #include <sys/socket.h> | ||||
| #include <ifaddrs.h> | ||||
| #include <net/if_dl.h> | ||||
|  | ||||
|  | ||||
| Foundation_BEGIN | ||||
|  | ||||
|  | ||||
| void UUIDGenerator::getNode() | ||||
| { | ||||
| 	struct ifaddrs* ifaphead; | ||||
| 	int rc = getifaddrs(&ifaphead); | ||||
| 	if (rc) throw SystemException("cannot get network adapter list"); | ||||
|  | ||||
| 	bool foundAdapter = false; | ||||
| 	for (struct ifaddrs* ifap = ifaphead; ifap; ifap = ifap->ifa_next)  | ||||
| 	{ | ||||
| 		if (ifap->ifa_addr && ifap->ifa_addr->sa_family == AF_LINK)  | ||||
| 		{ | ||||
| 			struct sockaddr_dl* sdl = reinterpret_cast<struct sockaddr_dl*>(ifap->ifa_addr); | ||||
| 			caddr_t ap = (caddr_t) (sdl->sdl_data + sdl->sdl_nlen); | ||||
| 			int alen = sdl->sdl_alen; | ||||
| 			if (ap && alen > 0)  | ||||
| 			{ | ||||
| 				memcpy(_node, ap, sizeof(_node)); | ||||
| 				foundAdapter = true; | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	freeifaddrs(ifaphead); | ||||
| 	if (!foundAdapter) throw SystemException("cannot determine MAC address (no suitable network adapter found)"); | ||||
| } | ||||
|  | ||||
|  | ||||
| Foundation_END | ||||
|  | ||||
|  | ||||
| #elif defined(__CYGWIN__) || POCO_OS == POCO_OS_LINUX | ||||
| // | ||||
| // Linux | ||||
| // | ||||
| #include <sys/ioctl.h> | ||||
| #include <sys/socket.h> | ||||
| #include <netinet/in.h> | ||||
| #include <net/if.h> | ||||
| #include <arpa/inet.h> | ||||
| #include <unistd.h> | ||||
|  | ||||
|  | ||||
| Foundation_BEGIN | ||||
|  | ||||
|  | ||||
| void UUIDGenerator::getNode() | ||||
| { | ||||
| 	struct ifreq ifr; | ||||
|  | ||||
| 	int s = socket(PF_INET, SOCK_DGRAM, 0); | ||||
| 	if (s == -1) throw SystemException("cannot open socket"); | ||||
|  | ||||
| 	strcpy(ifr.ifr_name, "eth0"); | ||||
| 	int rc = ioctl(s, SIOCGIFHWADDR, &ifr); | ||||
| 	close(s); | ||||
| 	if (rc < 0) throw SystemException("cannot get MAC address"); | ||||
| 	struct sockaddr* sa = reinterpret_cast<struct sockaddr*>(&ifr.ifr_addr); | ||||
| 	memcpy(_node, sa->sa_data, sizeof(_node)); | ||||
| } | ||||
|  | ||||
|  | ||||
| Foundation_END | ||||
|  | ||||
|  | ||||
| #elif defined(POCO_OS_FAMILY_UNIX) || defined(POCO_OS_FAMILY_VMS) | ||||
| // | ||||
| // Unix/VMS | ||||
| // | ||||
| #if defined(__VMS) | ||||
| #include <ioctl.h> | ||||
| #else | ||||
| #include <sys/ioctl.h> | ||||
| #endif | ||||
| #if defined(sun) || defined(__sun) | ||||
| #include <sys/sockio.h> | ||||
| #endif | ||||
| #include <sys/socket.h> | ||||
| #include <sys/types.h> | ||||
| #include <netinet/in.h> | ||||
| #include <net/if.h> | ||||
| #if defined(__VMS) | ||||
| #include <inet.h> | ||||
| #else | ||||
| #include <arpa/inet.h> | ||||
| #endif | ||||
| #include <netdb.h> | ||||
| #include <net/if.h> | ||||
| #include <net/if_arp.h> | ||||
| #include <unistd.h> | ||||
|  | ||||
|  | ||||
| #if defined(__VMS) | ||||
| #define MAXHOSTNAMELEN 64 | ||||
| #endif | ||||
|  | ||||
|  | ||||
| Foundation_BEGIN | ||||
|  | ||||
|  | ||||
| void UUIDGenerator::getNode() | ||||
| { | ||||
| 	char name[MAXHOSTNAMELEN]; | ||||
| 	if (gethostname(name, sizeof(name))) | ||||
| 		throw SystemException("cannot get host name"); | ||||
|  | ||||
| 	struct hostent* pHost = gethostbyname(name); | ||||
| 	if (!pHost) throw SystemException("cannot get host IP address"); | ||||
|  | ||||
| 	int s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); | ||||
| 	if (s == -1) throw SystemException("cannot open socket"); | ||||
|  | ||||
| 	struct arpreq ar; | ||||
| 	memset(&ar, 0, sizeof(ar)); | ||||
| 	struct sockaddr_in* pAddr = reinterpret_cast<struct sockaddr_in*>(&ar.arp_pa); | ||||
| 	pAddr->sin_family = AF_INET; | ||||
| 	memcpy(&pAddr->sin_addr, *pHost->h_addr_list, sizeof(struct in_addr)); | ||||
| 	int rc = ioctl(s, SIOCGARP, &ar); | ||||
| 	close(s); | ||||
| 	if (rc < 0) throw SystemException("cannot get MAC address"); | ||||
| 	memcpy(_node, ar.arp_ha.sa_data, sizeof(_node)); | ||||
| } | ||||
|  | ||||
|  | ||||
| Foundation_END | ||||
|  | ||||
|  | ||||
| #endif | ||||
		Reference in New Issue
	
	Block a user
	 Guenter Obiltschnig
					Guenter Obiltschnig