| /******************************************************************************* |
| * Copyright (C) 2004-2006 Intel Corp. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are met: |
| * |
| * - Redistributions of source code must retain the above copyright notice, |
| * this list of conditions and the following disclaimer. |
| * |
| * - Redistributions in binary form must reproduce the above copyright notice, |
| * this list of conditions and the following disclaimer in the documentation |
| * and/or other materials provided with the distribution. |
| * |
| * - Neither the name of Intel Corp. nor the names of its |
| * contributors may be used to endorse or promote products derived from this |
| * software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| * ARE DISCLAIMED. IN NO EVENT SHALL Intel Corp. OR THE CONTRIBUTORS |
| * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| * POSSIBILITY OF SUCH DAMAGE. |
| *******************************************************************************/ |
| |
| /** |
| * @author Anas Nashif |
| */ |
| |
| /* |
| * ** OSSP uuid - Universally Unique Identifier |
| * ** Copyright (c) 2004-2005 Ralf S. Engelschall <rse@engelschall.com> |
| * ** Copyright (c) 2004-2005 The OSSP Project <http://www.ossp.org/> |
| * ** |
| * ** This file is part of OSSP uuid, a library for the generation |
| * ** of UUIDs which can found at http://www.ossp.org/pkg/lib/uuid/ |
| * ** |
| * ** Permission to use, copy, modify, and distribute this software for |
| * ** any purpose with or without fee is hereby granted, provided that |
| * ** the above copyright notice and this permission notice appear in all |
| * ** copies. |
| * ** |
| * ** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED |
| * ** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
| * ** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| * ** IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR |
| * ** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| * ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
| * ** USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| * ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| * ** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
| * ** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| * ** SUCH DAMAGE. |
| * ** |
| * ** uuid_mac.c: Media Access Control (MAC) resolver implementation |
| * */ |
| |
| |
| #ifdef HAVE_CONFIG_H |
| #include <wsman_config.h> |
| #endif |
| |
| |
| #include <stdlib.h> |
| #include <stdio.h> |
| |
| |
| #if HAVE_CTYPE_H |
| #include <ctype.h> |
| #endif |
| |
| #ifdef HAVE_UNISTD_H |
| #include <unistd.h> |
| #endif |
| |
| #include <sys/types.h> |
| |
| #include <assert.h> |
| #ifdef HAVE_SYS_IOCTL_H |
| #include <sys/ioctl.h> |
| #endif |
| |
| #include <string.h> |
| |
| #if (defined (__SVR4) && defined (__sun)) |
| #include <uuid/uuid.h> |
| #endif |
| |
| #ifdef TIME_WITH_SYS_TIME |
| #include <sys/time.h> |
| #endif |
| #include "u/uuid.h" |
| #include "u/os.h" |
| #include "u/debug.h" |
| |
| #ifdef _WIN32 |
| #include "windows.h" |
| #include "rpcdce.h" |
| /* don't forget to link with rpcrt4.lib */ |
| int |
| generate_uuid(char *buf, int size, int bNoPrefix) |
| { |
| int ret_val = -1; |
| UUID uuid; |
| RPC_STATUS st = UuidCreate(&uuid); |
| |
| if (st == RPC_S_OK || st == RPC_S_UUID_LOCAL_ONLY) { |
| char *str = NULL; |
| if ((st = UuidToString(&uuid, (BYTE **) & str)) != RPC_S_OK) { |
| //failed |
| } else { |
| int len = 5; |
| if (!bNoPrefix && size > (len + 1)) |
| strcpy(buf, "uuid:"); |
| else |
| len = 0; |
| strncpy(buf +len, str, size - len); |
| RpcStringFree((BYTE **) & str); |
| ret_val = 0; |
| } |
| } else { |
| //failed |
| } |
| return ret_val; |
| } |
| |
| |
| #else |
| #include <netdb.h> |
| #include <sys/socket.h> |
| #include <fcntl.h> |
| #include <net/if.h> |
| #include <net/if_arp.h> |
| #include <sys/utsname.h> |
| #include <sys/param.h> |
| #include <netinet/in.h> |
| |
| #if defined(__APPLE__) || defined(__FreeBSD__) |
| #include <net/bpf.h> |
| #include <net/if_dl.h> |
| #include <net/if_types.h> |
| |
| /* return the Media Access Control (MAC) address of |
| the FIRST network interface card (NIC) */ |
| static int mac_address(unsigned char *data_ptr, size_t data_len) |
| { |
| /* sanity check arguments */ |
| if (data_ptr == NULL || data_len < MAC_LEN) |
| return 0; |
| |
| #if defined(HAVE_IFADDRS_H) && defined(HAVE_NET_IF_DL_H) && defined(HAVE_GETIFADDRS) |
| /* use getifaddrs(3) on BSD class platforms (xxxBSD, MacOS X, etc) */ |
| { |
| struct ifaddrs *ifap; |
| struct ifaddrs *ifap_head; |
| const struct sockaddr_dl *sdl; |
| unsigned char *ucp; |
| int i; |
| |
| if (getifaddrs(&ifap_head) < 0) |
| return 0; |
| for (ifap = ifap_head; ifap != NULL; ifap = ifap->ifa_next) { |
| if (ifap->ifa_addr != NULL && ifap->ifa_addr->sa_family == AF_LINK) { |
| sdl = (const struct sockaddr_dl *)(void *)ifap->ifa_addr; |
| ucp = (unsigned char *)(sdl->sdl_data + sdl->sdl_nlen); |
| if (sdl->sdl_alen > 0) { |
| for (i = 0; i < MAC_LEN && i < sdl->sdl_alen; i++, ucp++) |
| data_ptr[i] = (unsigned char)(*ucp & 0xff); |
| freeifaddrs(ifap_head); |
| return 1; |
| } |
| } |
| } |
| freeifaddrs(ifap_head); |
| } |
| #endif |
| |
| #if defined(HAVE_NET_IF_H) && defined(SIOCGIFHWADDR) |
| /* use SIOCGIFHWADDR ioctl(2) on Linux class platforms */ |
| { |
| struct ifreq ifr; |
| struct sockaddr *sa; |
| int s; |
| int i; |
| |
| if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) |
| return FALSE; |
| |
| i = snprintf(ifr.ifr_name, IFNAMSIZ, "eth0"); |
| if (i != strlen("eth0")) { |
| close(s) |
| return 0; |
| } |
| |
| if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) { |
| close(s); |
| return 0; |
| } |
| |
| sa = (struct sockaddr *)&ifr.ifr_addr; |
| for (i = 0; i < MAC_LEN; i++) { |
| data_ptr[i] = (unsigned char)(sa->sa_data[i] & 0xff); |
| } |
| |
| close(s); |
| return 1; |
| } |
| #endif |
| |
| #if defined(SIOCGARP) |
| /* use SIOCGARP ioctl(2) on SVR4 class platforms (Solaris, etc) */ |
| { |
| char hostname[MAXHOSTNAMELEN]; |
| struct hostent *he; |
| struct arpreq ar; |
| struct sockaddr_in *sa; |
| int s; |
| int i; |
| |
| if (gethostname(hostname, sizeof(hostname)) < 0) |
| return 0; |
| if ((he = gethostbyname(hostname)) == NULL) |
| return 0; |
| if ((s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) |
| return 0; |
| memset(&ar, 0, sizeof(ar)); |
| sa = (struct sockaddr_in *)((void *)&(ar.arp_pa)); |
| sa->sin_family = AF_INET; |
| memcpy(&(sa->sin_addr), *(he->h_addr_list), sizeof(struct in_addr)); |
| if (ioctl(s, SIOCGARP, &ar) < 0) { |
| close(s); |
| return 0; |
| } |
| close(s); |
| if (!(ar.arp_flags & ATF_COM)) |
| return 0; |
| for (i = 0; i < MAC_LEN; i++) |
| data_ptr[i] = (unsigned char)(ar.arp_ha.sa_data[i] & 0xff); |
| return 1; |
| } |
| #endif |
| |
| return 0; |
| } |
| |
| |
| |
| |
| |
| #elif !(defined (__SVR4) && defined (__sun)) |
| |
| static long |
| mac_addr_sys (u_char *addr) |
| { |
| struct ifreq ifr; |
| struct ifreq *IFR; |
| struct ifconf ifc; |
| char buf[1024]; |
| int s, i; |
| int ok = 0; |
| |
| s = socket(AF_INET, SOCK_DGRAM, 0); |
| if (s==-1) { |
| return -1; |
| } |
| |
| ifc.ifc_len = sizeof(buf); |
| ifc.ifc_buf = buf; |
| ioctl(s, SIOCGIFCONF, &ifc); |
| |
| IFR = ifc.ifc_req; |
| for (i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; IFR++) { |
| |
| strcpy(ifr.ifr_name, IFR->ifr_name); |
| if (ioctl(s, SIOCGIFFLAGS, &ifr) == 0) { |
| if (! (ifr.ifr_flags & IFF_LOOPBACK)) { |
| if (ioctl(s, SIOCGIFHWADDR, &ifr) == 0) { |
| ok = 1; |
| break; |
| } |
| } |
| } |
| } |
| |
| close(s); |
| if (ok) { |
| bcopy( ifr.ifr_hwaddr.sa_data, addr, 6); |
| } |
| else { |
| return -1; |
| } |
| return 0; |
| } |
| #endif |
| |
| #if !(defined (__SVR4) && defined (__sun)) |
| |
| int |
| generate_uuid ( char* buf, |
| int size, |
| int no_prefix) |
| { |
| |
| static int clock_sequence = 1; |
| u_int64_t longTimeVal; |
| int timeLow = 0; |
| int timeMid = 0; |
| int timeHigh = 0; |
| unsigned char mac[6]; |
| unsigned char uuid[16]; |
| int i; |
| char* ptr = buf; |
| struct timeval tv; |
| int max_length = SIZE_OF_UUID_STRING; |
| |
| if ( !no_prefix ) max_length += 5; // space for "uuid:" |
| if ( size < max_length ) |
| return 0; |
| |
| if ( buf == NULL ) |
| return 0; |
| |
| // get time data |
| gettimeofday( &tv, NULL ); |
| longTimeVal = (u_int64_t)1000000 * (u_int64_t)tv.tv_sec + (u_int64_t)tv.tv_usec; |
| timeLow = longTimeVal & 0xffffffff; // lower 32 bits |
| timeMid = (longTimeVal >> 32) & 0xffff; // middle 16 bits |
| timeHigh = (longTimeVal >> 32) & 0xfff; // upper 12 bits |
| |
| // update clock sequence number |
| clock_sequence++; |
| |
| // get mac address |
| #if defined(__APPLE__) || defined(__FreeBSD__) |
| if ( mac_address( mac, 6 ) == 0 ) |
| #else |
| if (mac_addr_sys(mac) == 0 ) |
| #endif |
| { |
| for( i = 0; i < 6; i++ ) |
| uuid[i] = mac[i]; // mac address |
| } else { |
| for( i = 0; i < 6; i++ ) |
| uuid[i] = clock_sequence & 0xff; // just in case we do not have a mac |
| } |
| |
| uuid[6] = clock_sequence & 0xff; // clock seq. low |
| uuid[7] = 0x80 | ((clock_sequence >> 8) & 0x3f);// clock seq. high and variant |
| uuid[8] = timeHigh & 0xff; // time high/version low bits |
| uuid[9] = timeHigh >> 8 | 0x10; // time high/version high bits |
| *(short int*)(uuid+10) = (short int)timeMid; |
| *(int*)(uuid+12) = timeLow; |
| |
| i = 0; |
| if ( !no_prefix ) |
| { |
| i = snprintf( ptr, size, "uuid:" ); |
| if ( i != strlen("uuid:") ) |
| return 0; |
| } |
| |
| i = snprintf( &ptr[i], size - i, |
| "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", |
| uuid[15], uuid[14], uuid[13], uuid[12], |
| uuid[11], uuid[10], uuid[9], uuid[8], |
| uuid[7], uuid[6], uuid[5], uuid[4], |
| uuid[3], uuid[2], uuid[1], uuid[0] ); |
| |
| if ( i != SIZE_OF_UUID_STRING) |
| return 0; |
| |
| return 1; |
| } |
| |
| #else /* Solaris */ |
| int |
| generate_uuid ( char* buf, |
| int size, |
| int no_prefix) |
| { |
| int max_length = SIZE_OF_UUID_STRING; |
| char* ptr = buf; |
| char uuid_str[UUID_PRINTABLE_STRING_LENGTH]; |
| uuid_t uuid; |
| int i; |
| |
| if ( !no_prefix ) max_length += 5; // space for "uuid:" |
| if ( size < max_length ) |
| return 0; |
| |
| if ( buf == NULL ) |
| return 0; |
| |
| i = 0; |
| if ( !no_prefix ) |
| { |
| i = snprintf( ptr, size, "uuid:" ); |
| if ( i != strlen("uuid:") ) |
| return 0; |
| } |
| ptr += i; |
| |
| uuid_generate(uuid); |
| uuid_unparse(uuid, uuid_str); |
| |
| int uuidlen = strlen(uuid_str); |
| if (((ptr - buf) + uuidlen) < size) { |
| strlcpy(ptr, uuid_str, uuidlen); |
| return 1; |
| } |
| else |
| return 0; |
| } |
| |
| #endif |
| |
| #endif /* #if _WIN32 ... #else */ |