1/* 2 * Copyright (c) 2011 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of Apple Inc. ("Apple") nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * Portions of this software have been released under the following terms: 31 * 32 * (c) Copyright 1989-1993 OPEN SOFTWARE FOUNDATION, INC. 33 * (c) Copyright 1989-1993 HEWLETT-PACKARD COMPANY 34 * (c) Copyright 1989-1993 DIGITAL EQUIPMENT CORPORATION 35 * 36 * To anyone who acknowledges that this file is provided "AS IS" 37 * without any express or implied warranty: 38 * permission to use, copy, modify, and distribute this file for any 39 * purpose is hereby granted without fee, provided that the above 40 * copyright notices and this notice appears in all source code copies, 41 * and that none of the names of Open Software Foundation, Inc., Hewlett- 42 * Packard Company or Digital Equipment Corporation be used 43 * in advertising or publicity pertaining to distribution of the software 44 * without specific, written prior permission. Neither Open Software 45 * Foundation, Inc., Hewlett-Packard Company nor Digital 46 * Equipment Corporation makes any representations about the suitability 47 * of this software for any purpose. 48 * 49 * Copyright (c) 2007, Novell, Inc. All rights reserved. 50 * Redistribution and use in source and binary forms, with or without 51 * modification, are permitted provided that the following conditions 52 * are met: 53 * 54 * 1. Redistributions of source code must retain the above copyright 55 * notice, this list of conditions and the following disclaimer. 56 * 2. Redistributions in binary form must reproduce the above copyright 57 * notice, this list of conditions and the following disclaimer in the 58 * documentation and/or other materials provided with the distribution. 59 * 3. Neither the name of Novell Inc. nor the names of its contributors 60 * may be used to endorse or promote products derived from this 61 * this software without specific prior written permission. 62 * 63 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 64 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 65 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 66 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY 67 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 68 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 69 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 70 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 71 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 72 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 73 * 74 * @APPLE_LICENSE_HEADER_END@ 75 */ 76 77/* 78** 79** NAME: 80** 81** uuid.c 82** 83** FACILITY: 84** 85** UUID 86** 87** ABSTRACT: 88** 89** UUID - routines that manipulate uuid's 90** 91** 92*/ 93 94#include <config.h> 95 96#ifndef UUID_BUILD_STANDALONE 97#include <dce/dce.h> 98#include <dce/uuid.h> /* uuid idl definitions (public) */ 99#include <dce/rpcsts.h> 100#else 101#include "uuid.h" 102#endif 103 104#include <stddef.h> 105#include <stdlib.h> 106#include <string.h> 107#include <stdio.h> 108#include "uuid_i.h" /* uuid idl definitions (private) */ 109#include <uuid/uuid.h> 110 111/* 112 * structure of universal unique IDs (UUIDs). 113 * 114 * There are three "variants" of UUIDs that this code knows about. The 115 * variant #0 is what was defined in the 1989 HP/Apollo Network Computing 116 * Architecture (NCA) specification and implemented in NCS 1.x and DECrpc 117 * v1. Variant #1 is what was defined for the joint HP/DEC specification 118 * for the OSF (in DEC's "UID Architecture Functional Specification Version 119 * X1.0.4") and implemented in NCS 2.0, DECrpc v2, and OSF 1.0 DCE RPC. 120 * Variant #2 is defined by Microsoft. 121 * 122 * This code creates only variant #1 UUIDs. 123 * 124 * The three UUID variants can exist on the same wire because they have 125 * distinct values in the 3 MSB bits of octet 8 (see table below). Do 126 * NOT confuse the version number with these 3 bits. (Note the distinct 127 * use of the terms "version" and "variant".) Variant #0 had no version 128 * field in it. Changes to variant #1 (should any ever need to be made) 129 * can be accomodated using the current form's 4 bit version field. 130 * 131 * The UUID record structure MUST NOT contain padding between fields. 132 * The total size = 128 bits. 133 * 134 * To minimize confusion about bit assignment within octets, the UUID 135 * record definition is defined only in terms of fields that are integral 136 * numbers of octets. 137 * 138 * Depending on the network data representation, the multi-octet unsigned 139 * integer fields are subject to byte swapping when communicated between 140 * dissimilar endian machines. Note that all three UUID variants have 141 * the same record structure; this allows this byte swapping to occur. 142 * (The ways in which the contents of the fields are generated can and 143 * do vary.) 144 * 145 * The following information applies to variant #1 UUIDs: 146 * 147 * The lowest addressed octet contains the global/local bit and the 148 * unicast/multicast bit, and is the first octet of the address transmitted 149 * on an 802.3 LAN. 150 * 151 * The adjusted time stamp is split into three fields, and the clockSeq 152 * is split into two fields. 153 * 154 * |<------------------------- 32 bits -------------------------->| 155 * 156 * +--------------------------------------------------------------+ 157 * | low 32 bits of time | 0-3 .time_low 158 * +-------------------------------+------------------------------- 159 * | mid 16 bits of time | 4-5 .time_mid 160 * +-------+-----------------------+ 161 * | vers. | hi 12 bits of time | 6-7 .time_hi_and_version 162 * +-------+-------+---------------+ 163 * |Res| clkSeqHi | 8 .clock_seq_hi_and_reserved 164 * +---------------+ 165 * | clkSeqLow | 9 .clock_seq_low 166 * +---------------+----------...-----+ 167 * | node ID | 8-16 .node 168 * +--------------------------...-----+ 169 * 170 * -------------------------------------------------------------------------- 171 * 172 * The structure layout of all three UUID variants is fixed for all time. 173 * I.e., the layout consists of a 32 bit int, 2 16 bit ints, and 8 8 174 * bit ints. The current form version field does NOT determine/affect 175 * the layout. This enables us to do certain operations safely on the 176 * variants of UUIDs without regard to variant; this increases the utility 177 * of this code even as the version number changes (i.e., this code does 178 * NOT need to check the version field). 179 * 180 * The "Res" field in the octet #8 is the so-called "reserved" bit-field 181 * and determines whether or not the uuid is a old, current or other 182 * UUID as follows: 183 * 184 * MS-bit 2MS-bit 3MS-bit Variant 185 * --------------------------------------------- 186 * 0 x x 0 (NCS 1.5) 187 * 1 0 x 1 (DCE 1.0 RPC) 188 * 1 1 0 2 (Microsoft) 189 * 1 1 1 unspecified 190 * 191 * -------------------------------------------------------------------------- 192 * 193 * structure of variant #0 UUIDs 194 * 195 * The first 6 octets are the number of 4 usec units of time that have 196 * passed since 1/1/80 0000 GMT. The next 2 octets are reserved for 197 * future use. The next octet is an address family. The next 7 octets 198 * are a host ID in the form allowed by the specified address family. 199 * 200 * Note that while the family field (octet 8) was originally conceived 201 * of as being able to hold values in the range [0..255], only [0..13] 202 * were ever used. Thus, the 2 MSB of this field are always 0 and are 203 * used to distinguish old and current UUID forms. 204 * 205 * +--------------------------------------------------------------+ 206 * | high 32 bits of time | 0-3 .time_high 207 * +-------------------------------+------------------------------- 208 * | low 16 bits of time | 4-5 .time_low 209 * +-------+-----------------------+ 210 * | reserved | 6-7 .reserved 211 * +---------------+---------------+ 212 * | family | 8 .family 213 * +---------------+----------...-----+ 214 * | node ID | 9-16 .node 215 * +--------------------------...-----+ 216 * 217 */ 218 219/*************************************************************************** 220 * 221 * Local definitions 222 * 223 **************************************************************************/ 224 225#ifdef UUID_DEBUG 226#define DEBUG_PRINT(msg, st) RPC_DBG_GPRINTF (( "%s: %08x\n", msg, st )) 227#else 228#define DEBUG_PRINT(msg, st) do {;} while(0) 229#endif 230 231#ifndef NO_SSCANF 232# define UUID_SSCANF sscanf 233# define UUID_OLD_SSCANF sscanf 234#else 235# define UUID_SSCANF uuid__sscanf 236# define UUID_OLD_SSCANF uuid__old_sscanf 237#endif 238 239#ifndef NO_SPRINTF 240# define UUID_SPRINTF sprintf 241# define UUID_OLD_SPRINTF sprintf 242#else 243# define UUID_SPRINTF uuid__sprintf 244# define UUID_OLD_SPRINTF uuid__old_sprintf 245#endif 246 247/* 248 * the number of elements returned by sscanf() when converting 249 * string formatted uuid's to binary 250 */ 251#define UUID_ELEMENTS_NUM 11 252#define UUID_ELEMENTS_NUM_OLD 10 253 254/* 255 * local defines used in uuid bit-diddling 256 */ 257#define HI_WORD(w) ((w) >> 16) 258#define RAND_MASK 0x3fff /* same as CLOCK_SEQ_LAST */ 259 260#define TIME_MID_MASK 0x0000ffff 261#define TIME_HIGH_MASK 0x0fff0000 262#define TIME_HIGH_SHIFT_COUNT 16 263 264#define MAX_TIME_ADJUST 0x7fff 265 266#define CLOCK_SEQ_LOW_MASK 0xff 267#define CLOCK_SEQ_HIGH_MASK 0x3f00 268#define CLOCK_SEQ_HIGH_SHIFT_COUNT 8 269#define CLOCK_SEQ_FIRST 1 270#define CLOCK_SEQ_LAST 0x3fff /* same as RAND_MASK */ 271 272/* 273 * Note: If CLOCK_SEQ_BIT_BANG == TRUE, then we can avoid the modulo 274 * operation. This should save us a divide instruction and speed 275 * things up. 276 */ 277 278#ifndef CLOCK_SEQ_BIT_BANG 279#define CLOCK_SEQ_BIT_BANG 1 280#endif 281 282#if CLOCK_SEQ_BIT_BANG 283#define CLOCK_SEQ_BUMP(seq) ((*seq) = ((*seq) + 1) & CLOCK_SEQ_LAST) 284#else 285#define CLOCK_SEQ_BUMP(seq) ((*seq) = ((*seq) + 1) % (CLOCK_SEQ_LAST+1)) 286#endif 287 288#define UUID_VERSION_BITS (uuid_c_version << 12) 289#define UUID_RESERVED_BITS 0x80 290 291#define IS_OLD_UUID(uuid) (((uuid)->clock_seq_hi_and_reserved & 0xc0) != 0x80) 292 293 294/**************************************************************************** 295 * 296 * data declarations 297 * 298 ****************************************************************************/ 299 300idl_uuid_t uuid_g_nil_uuid = { 0, 0, 0, 0, 0, {0} }; 301idl_uuid_t uuid_nil = { 0, 0, 0, 0, 0, {0} }; 302 303/**************************************************************************** 304 * 305 * local data declarations 306 * 307 ****************************************************************************/ 308 309/* 310 * saved copy of our IEEE 802 address for quick reference 311 */ 312static uuid_address_t saved_addr; 313 314/* 315 * saved copy of the status associated with saved_addr 316 */ 317static unsigned32 saved_st; 318 319/* 320 * declarations used in UTC time calculations 321 */ 322static uuid_time_t time_last; /* 'saved' value of time_now */ 323static unsigned16 clock_seq; /* 'adjustment' for backwards clocks*/ 324 325/* 326 * true_random variables 327 */ 328static unsigned32 rand_m; /* multiplier */ 329static unsigned32 rand_ia; /* adder #1 */ 330static unsigned32 rand_ib; /* adder #2 */ 331static unsigned32 rand_irand; /* random value */ 332 333typedef enum 334{ 335 uuid_e_less_than, uuid_e_equal_to, uuid_e_greater_than 336} uuid_compval_t; 337 338/* 339 * boolean indicating we've already determined our IEEE 802 address 340 */ 341 342static boolean got_address = FALSE; 343 344/**************************************************************************** 345 * 346 * local function declarations 347 * 348 ****************************************************************************/ 349 350/* 351 * I N I T 352 * 353 * Startup initialization routine for UUID module. 354 */ 355 356static void init ( unsigned32 * /*st*/ ); 357 358/* 359 * T R U E _ R A N D O M _ I N I T 360 */ 361 362static void true_random_init (void); 363 364/* 365 * T R U E _ R A N D O M 366 */ 367static unsigned16 true_random (void); 368 369/* 370 * S T R U C T U R E _ I S _ K N O W N 371 * 372 * Does the UUID have the known standard structure layout? 373 */ 374boolean structure_is_known ( uuid_p_t /*uuid*/); 375 376/* 377 * U U I D _ G E T _ A D D R E S S 378 * 379 * Get our IEEE 802 address (calls uuid__get_os_address) 380 */ 381 382void uuid_get_address ( 383 uuid_address_t * /*address*/, 384 unsigned32 * /*st*/ 385 ); 386 387 388/***************************************************************************** 389 * 390 * Macro definitions 391 * 392 ****************************************************************************/ 393 394/* 395 * ensure we've been initialized 396 */ 397static boolean uuid_init_done = FALSE; 398 399#define EmptyArg 400#define UUID_VERIFY_INIT(Arg) \ 401 if (! uuid_init_done) \ 402 { \ 403 init (status); \ 404 if (*status != uuid_s_ok) \ 405 { \ 406 return Arg; \ 407 } \ 408 } 409 410/* 411 * Check the reserved bits to make sure the UUID is of the known structure. 412 */ 413 414#define CHECK_STRUCTURE(uuid) \ 415( \ 416 (((uuid)->clock_seq_hi_and_reserved & 0x80) == 0x00) || /* var #0 */ \ 417 (((uuid)->clock_seq_hi_and_reserved & 0xc0) == 0x80) || /* var #1 */ \ 418 (((uuid)->clock_seq_hi_and_reserved & 0xe0) == 0xc0) || /* var #2 */ \ 419 (((uuid)->clock_seq_hi_and_reserved & 0xe0) == 0xe0) /* var #DAMNMICROSOFT */ \ 420) 421 422/* 423 * The following macros invoke CHECK_STRUCTURE(), check that the return 424 * value is okay and if not, they set the status variable appropriately 425 * and return either a boolean FALSE, nothing (for void procedures), 426 * or a value passed to the macro. This has been done so that checking 427 * can be done more simply and values are returned where appropriate 428 * to keep compilers happy. 429 * 430 * bCHECK_STRUCTURE - returns boolean FALSE 431 * vCHECK_STRUCTURE - returns nothing (void) 432 * rCHECK_STRUCTURE - returns 'r' macro parameter 433 */ 434 435#define bCHECK_STRUCTURE(uuid, status) \ 436{ \ 437 if (!CHECK_STRUCTURE (uuid)) \ 438 { \ 439 *(status) = uuid_s_bad_version; \ 440 return (FALSE); \ 441 } \ 442} 443 444#define vCHECK_STRUCTURE(uuid, status) \ 445{ \ 446 if (!CHECK_STRUCTURE (uuid)) \ 447 { \ 448 *(status) = uuid_s_bad_version; \ 449 return; \ 450 } \ 451} 452 453#define rCHECK_STRUCTURE(uuid, status, result) \ 454{ \ 455 if (!CHECK_STRUCTURE (uuid)) \ 456 { \ 457 *(status) = uuid_s_bad_version; \ 458 return (result); \ 459 } \ 460} 461 462/* 463**++ 464** 465** ROUTINE NAME: init 466** 467** SCOPE: - declared locally 468** 469** DESCRIPTION: 470** 471** Startup initialization routine for the UUID module. 472** 473** INPUTS: none 474** 475** INPUTS/OUTPUTS: none 476** 477** OUTPUTS: 478** 479** status return status value 480** 481** uuid_s_ok 482** uuid_s_coding_error 483** 484** IMPLICIT INPUTS: none 485** 486** IMPLICIT OUTPUTS: none 487** 488** FUNCTION VALUE: void 489** 490** SIDE EFFECTS: sets uuid_init_done so this won't be done again 491** 492**-- 493**/ 494 495static void init 496( 497 unsigned32 *status 498) 499{ 500#ifdef CMA_INCLUDE 501 /* 502 * Hack for CMA pthreads. Some users will call uuid_ stuff before 503 * doing any thread stuff (CMA is uninitialized). Some uuid_ 504 * operations alloc memory and in a CMA pthread environment, 505 * the malloc wrapper uses a mutex but doesn't do self initialization 506 * (which results in segfault'ing inside of CMA). Make sure that 507 * CMA is initialized. 508 */ 509 pthread_t t; 510 t = pthread_self(); 511#endif /* CMA_INCLUDE */ 512 513 CODING_ERROR (status); 514 515 /* 516 * init the random number generator 517 */ 518 true_random_init(); 519 520 uuid__get_os_time (&time_last); 521 522#ifdef UUID_NONVOLATILE_CLOCK 523 clock_seq = uuid__read_clock(); 524#else 525 clock_seq = true_random(); 526#endif 527 528 uuid_init_done = TRUE; 529 530 *status = uuid_s_ok; 531} 532 533/* 534**++ 535** 536** ROUTINE NAME: uuid_create 537** 538** SCOPE: - declared in UUID.IDL 539** 540** DESCRIPTION: 541** 542** Create a new UUID. Note: we only know how to create the new 543** and improved UUIDs. 544** 545** INPUTS: none 546** 547** INPUTS/OUTPUTS: none 548** 549** OUTPUTS: 550** 551** uuid A new UUID value 552** 553** status return status value 554** 555** uuid_s_ok 556** uuid_s_coding_error 557** 558** IMPLICIT INPUTS: none 559** 560** IMPLICIT OUTPUTS: none 561** 562** FUNCTION VALUE: void 563** 564** SIDE EFFECTS: none 565** 566**-- 567**/ 568 569void uuid_create 570( 571 idl_uuid_t *uuid, 572 unsigned32 *status 573) 574{ 575 CODING_ERROR (status); 576 UUID_VERIFY_INIT (EmptyArg); 577 578 uuid_generate ((unsigned char *) uuid); 579 *status = uuid_s_ok; 580} 581 582/* 583**++ 584** 585** ROUTINE NAME: uuid_create_nil 586** 587** SCOPE: - declared in UUID.IDL 588** 589** DESCRIPTION: 590** 591** Create a 'nil' uuid. 592** 593** INPUTS: none 594** 595** INPUTS/OUTPUTS: none 596** 597** OUTPUTS: 598** 599** uuid A nil UUID 600** 601** status return status value 602** 603** uuid_s_ok 604** uuid_s_coding_error 605** 606** IMPLICIT INPUTS: none 607** 608** IMPLICIT OUTPUTS: none 609** 610** FUNCTION VALUE: void 611** 612** SIDE EFFECTS: none 613** 614**-- 615**/ 616 617void uuid_create_nil 618( 619 idl_uuid_t *uuid, 620 unsigned32 *status 621) 622{ 623 CODING_ERROR (status); 624 UUID_VERIFY_INIT (EmptyArg); 625 626 uuid_clear((unsigned char *) uuid); 627 628 *status = uuid_s_ok; 629} 630 631/* 632**++ 633** 634** ROUTINE NAME: uuid_to_string 635** 636** SCOPE: - declared in UUID.IDL 637** 638** DESCRIPTION: 639** 640** Encode a UUID into a printable string. 641** 642** INPUTS: 643** 644** uuid A binary UUID to be converted to a string UUID. 645** 646** INPUTS/OUTPUTS: none 647** 648** OUTPUTS: 649** 650** uuid_string The string representation of the given UUID. 651** 652** status return status value 653** 654** uuid_s_ok 655** uuid_s_bad_version 656** uuid_s_coding_error 657** 658** IMPLICIT INPUTS: none 659** 660** IMPLICIT OUTPUTS: none 661** 662** FUNCTION VALUE: void 663** 664** SIDE EFFECTS: none 665** 666**-- 667**/ 668 669void uuid_to_string 670( 671 uuid_p_t uuid, 672 unsigned_char_p_t *uuid_string, 673 unsigned32 *status 674) 675{ 676 CODING_ERROR (status); 677 UUID_VERIFY_INIT (EmptyArg); 678 679 /* 680 * don't do anything if the output argument is NULL 681 */ 682 if (uuid_string == NULL) 683 { 684 *status = uuid_s_ok; 685 return; 686 } 687 688 vCHECK_STRUCTURE (uuid, status); 689 690#ifdef DCE_BUILD_INTERNAL 691 RPC_MEM_ALLOC ( 692 *uuid_string, 693 unsigned_char_p_t, 694 UUID_C_UUID_STRING_MAX, 695 RPC_C_MEM_STRING, 696 RPC_C_MEM_WAITOK); 697#else 698 699 /* Use the standard C allocator */ 700 *uuid_string = (unsigned_char_p_t)malloc(UUID_C_UUID_STRING_MAX); 701 702#endif 703 704 if (*uuid_string == NULL) 705 { 706 *status = uuid_s_no_memory; 707 return; 708 } 709 710 uuid_unparse ((unsigned char *) uuid, (char *) *uuid_string); 711 712 *status = uuid_s_ok; 713} 714 715/* 716**++ 717** 718** ROUTINE NAME: uuid_from_string 719** 720** SCOPE: - declared in UUID.IDL 721** 722** DESCRIPTION: 723** 724** Decode a UUID from a printable string. 725** 726** INPUTS: 727** 728** uuid_string The string UUID to be converted to a binary UUID 729** 730** INPUTS/OUTPUTS: none 731** 732** OUTPUTS: 733** 734** uuid The binary representation of the given UUID 735** 736** status return status value 737** 738** uuid_s_ok 739** uuid_s_bad_version 740** uuid_s_invalid_string_uuid 741** uuid_s_coding_error 742** 743** IMPLICIT INPUTS: none 744** 745** IMPLICIT OUTPUTS: none 746** 747** FUNCTION VALUE: void 748** 749** SIDE EFFECTS: none 750** 751**-- 752**/ 753 754void uuid_from_string 755( 756 unsigned_char_p_t uuid_string, 757 idl_uuid_t *uuid, 758 unsigned32 *status 759) 760{ 761 int i; 762 763 CODING_ERROR (status); 764 UUID_VERIFY_INIT(EmptyArg); 765 766 /* 767 * If a NULL pointer or empty string, give the nil UUID. 768 */ 769 if (uuid_string == NULL || *uuid_string == '\0') 770 { 771 memcpy (uuid, &uuid_g_nil_uuid, sizeof *uuid); 772 *status = uuid_s_ok; 773 return; 774 } 775 776 /* 777 * check to see that the string length is right at least 778 */ 779 if (strlen ((char *) uuid_string) != UUID_C_UUID_STRING_MAX - 1) 780 { 781 *status = uuid_s_invalid_string_uuid; 782 return; 783 } 784 785 i = uuid_parse ((char *) uuid_string, (unsigned char *) uuid); 786 if (i == 0) { 787 *status = uuid_s_ok; 788 } 789 else { 790 *status = uuid_s_invalid_string_uuid; 791 } 792} 793 794/* 795**++ 796** 797** ROUTINE NAME: uuid_equal 798** 799** SCOPE: - declared in UUID.IDL 800** 801** DESCRIPTION: 802** 803** Compare two UUIDs. 804** 805** INPUTS: 806** 807** uuid1 The first UUID to compare 808** 809** uuid2 The second UUID to compare 810** 811** INPUTS/OUTPUTS: none 812** 813** OUTPUTS: 814** 815** status return status value 816** 817** uuid_s_ok 818** uuid_s_bad_version 819** uuid_s_coding_error 820** 821** IMPLICIT INPUTS: none 822** 823** IMPLICIT OUTPUTS: none 824** 825** FUNCTION VALUE: 826** 827** result true if UUID's are equal 828** false if UUID's are not equal 829** 830** SIDE EFFECTS: none 831** 832**-- 833**/ 834 835boolean32 uuid_equal 836( 837 register uuid_p_t uuid1, 838 register uuid_p_t uuid2, 839 register unsigned32 *status 840) 841{ 842 CODING_ERROR (status); 843 UUID_VERIFY_INIT (FALSE); 844 845 bCHECK_STRUCTURE (uuid1, status); 846 bCHECK_STRUCTURE (uuid2, status); 847 848 *status = uuid_s_ok; 849 850 if (uuid_compare((unsigned char *) uuid1, (unsigned char *) uuid2) == 0) { 851 return TRUE; 852 } 853 else { 854 return FALSE; 855 } 856} 857 858/* 859**++ 860** 861** ROUTINE NAME: uuid_is_nil 862** 863** SCOPE: - declared in UUID.IDL 864** 865** DESCRIPTION: 866** 867** Check to see if a given UUID is 'nil'. 868** 869** INPUTS: none 870** 871** uuid A UUID 872** 873** INPUTS/OUTPUTS: none 874** 875** OUTPUTS: 876** 877** status return status value 878** 879** uuid_s_ok 880** uuid_s_bad_version 881** uuid_s_coding_error 882** 883** IMPLICIT INPUTS: none 884** 885** IMPLICIT OUTPUTS: none 886** 887** FUNCTION VALUE: 888** 889** result true if UUID is nil 890** false if UUID is not nil 891** 892** SIDE EFFECTS: none 893** 894**-- 895**/ 896 897boolean32 uuid_is_nil 898( 899 uuid_p_t uuid, 900 unsigned32 *status 901) 902{ 903 CODING_ERROR (status); 904 UUID_VERIFY_INIT (FALSE); 905 906 bCHECK_STRUCTURE (uuid, status); 907 908 *status = uuid_s_ok; 909 910 if (uuid_is_null((unsigned char *) uuid) == 1) { 911 return TRUE; 912 } 913 else { 914 return FALSE; 915 } 916} 917 918/* 919**++ 920** 921** ROUTINE NAME: uuid_lexcompare 922** 923** SCOPE: - declared in UUID.IDL 924** 925** DESCRIPTION: 926** 927** Compare two UUID's "lexically" 928** 929** If either of the two arguments is given as a NULL pointer, the other 930** argument will be compared to the nil uuid. 931** 932** Note: 1) lexical ordering is not temporal ordering! 933** 2) in the interest of keeping this routine short, I have 934** violated the coding convention that says all if/else 935** constructs shall have {}'s. There are a little million 936** return()'s in this routine. FWIW, the only {}'s that 937** are really required are the ones in the for() loop. 938** 939** INPUTS: 940** 941** uuid1 The first UUID to compare 942** 943** uuid2 The second UUID to compare 944** 945** INPUTS/OUTPUTS: none 946** 947** OUTPUTS: 948** 949** status return status value 950** 951** uuid_s_ok 952** uuid_s_bad_version 953** uuid_s_coding_error 954** 955** IMPLICIT INPUTS: none 956** 957** IMPLICIT OUTPUTS: none 958** 959** FUNCTION VALUE: uuid_order_t 960** 961** -1 uuid1 is lexically before uuid2 962** 1 uuid1 is lexically after uuid2 963** 964** SIDE EFFECTS: none 965** 966**-- 967**/ 968 969signed32 uuid_lexcompare 970( 971 uuid_p_t uuid1, 972 uuid_p_t uuid2, 973 unsigned32 *status 974) 975{ 976 int i; 977 978 CODING_ERROR (status); 979 UUID_VERIFY_INIT (FALSE); 980 981 /* 982 * check to see if either of the arguments is a NULL pointer 983 * - if so, compare the other argument to the nil uuid 984 */ 985 if (uuid1 == NULL) 986 { 987 /* 988 * if both arguments are NULL, so is this routine 989 */ 990 if (uuid2 == NULL) 991 { 992 *status = uuid_s_ok; 993 return (0); 994 } 995 996 rCHECK_STRUCTURE (uuid2, status, -1); 997 return (uuid_is_nil (uuid2, status) ? 0 : -1); 998 } 999 1000 if (uuid2 == NULL) 1001 { 1002 rCHECK_STRUCTURE (uuid1, status, -1); 1003 return (uuid_is_nil (uuid1, status) ? 0 : 1); 1004 } 1005 1006 rCHECK_STRUCTURE (uuid1, status, -1); 1007 rCHECK_STRUCTURE (uuid2, status, -1); 1008 1009 *status = uuid_s_ok; 1010 1011 i = uuid_compare((unsigned char *) uuid1, (unsigned char *) uuid2); 1012 return (i); 1013} 1014 1015/* 1016**++ 1017** 1018** ROUTINE NAME: uuid_hash 1019** 1020** SCOPE: - declared in UUID.IDL 1021** 1022** DESCRIPTION: 1023** 1024** Return a hash value for a given UUID. 1025** 1026** Note: Since the length of a UUID is architecturally defined to be 1027** 128 bits (16 bytes), we have forgone using a '#defined' 1028** length. In particular, since the 'loop' has been unrolled 1029** (for performance) the length is by definition 'hard-coded'. 1030** 1031** INPUTS: 1032** 1033** uuid A UUID for which a hash value is to be computed 1034** 1035** INPUTS/OUTPUTS: none 1036** 1037** OUTPUTS: 1038** 1039** status return status value 1040** 1041** uuid_s_ok 1042** uuid_s_bad_version 1043** uuid_s_coding_error 1044** 1045** IMPLICIT INPUTS: none 1046** 1047** IMPLICIT OUTPUTS: none 1048** 1049** FUNCTION VALUE: 1050** 1051** hash_value The hash value computed from the UUID 1052** 1053** SIDE EFFECTS: none 1054** 1055**-- 1056**/ 1057 1058unsigned16 uuid_hash 1059( 1060 uuid_p_t uuid, 1061 unsigned32 *status 1062) 1063{ 1064 short c0, c1; 1065 short x, y; 1066 byte_p_t next_uuid; 1067 1068 CODING_ERROR (status); 1069 UUID_VERIFY_INIT (FALSE); 1070 1071 rCHECK_STRUCTURE (uuid, status, 0); 1072 1073 /* 1074 * initialize counters 1075 */ 1076 c0 = c1 = 0; 1077 next_uuid = (byte_p_t) uuid; 1078 1079 /* 1080 * For speed lets unroll the following loop: 1081 * 1082 * for (i = 0; i < UUID_K_LENGTH; i++) 1083 * { 1084 * c0 = c0 + *next_uuid++; 1085 * c1 = c1 + c0; 1086 * } 1087 */ 1088 c0 += *next_uuid++; 1089 c1 += c0; 1090 c0 = c0 + *next_uuid++; 1091 c1 = c1 + c0; 1092 c0 = c0 + *next_uuid++; 1093 c1 = c1 + c0; 1094 c0 = c0 + *next_uuid++; 1095 c1 = c1 + c0; 1096 1097 c0 = c0 + *next_uuid++; 1098 c1 = c1 + c0; 1099 c0 = c0 + *next_uuid++; 1100 c1 = c1 + c0; 1101 c0 = c0 + *next_uuid++; 1102 c1 = c1 + c0; 1103 c0 = c0 + *next_uuid++; 1104 c1 = c1 + c0; 1105 1106 c0 = c0 + *next_uuid++; 1107 c1 = c1 + c0; 1108 c0 = c0 + *next_uuid++; 1109 c1 = c1 + c0; 1110 c0 = c0 + *next_uuid++; 1111 c1 = c1 + c0; 1112 c0 = c0 + *next_uuid++; 1113 c1 = c1 + c0; 1114 1115 c0 = c0 + *next_uuid++; 1116 c1 = c1 + c0; 1117 c0 = c0 + *next_uuid++; 1118 c1 = c1 + c0; 1119 c0 = c0 + *next_uuid++; 1120 c1 = c1 + c0; 1121 c0 = c0 + *next_uuid; 1122 c1 = c1 + c0; 1123 1124 /* 1125 * Calculate the value for "First octet" of the hash 1126 */ 1127 x = -c1 % 255; 1128 if (x < 0) 1129 { 1130 x = x + 255; 1131 } 1132 1133 /* 1134 * Calculate the value for "second octet" of the hash 1135 */ 1136 y = (c1 - c0) % 255; 1137 if (y < 0) 1138 { 1139 y = y + 255; 1140 } 1141 1142 /* 1143 * return the pieces put together 1144 */ 1145 *status = uuid_s_ok; 1146 1147 return ((y * 256) + x); 1148} 1149 1150/***************************************************************************** 1151 * 1152 * LOCAL MATH PROCEDURES - math procedures used internally by the UUID module 1153 * 1154 ****************************************************************************/ 1155 1156/* 1157** U U I D _ _ U E M U L 1158** 1159** Functional Description: 1160** 32-bit unsigned quantity * 32-bit unsigned quantity 1161** producing 64-bit unsigned result. This routine assumes 1162** long's contain at least 32 bits. It makes no assumptions 1163** about byte orderings. 1164** 1165** Inputs: 1166** 1167** u, v Are the numbers to be multiplied passed by value 1168** 1169** Outputs: 1170** 1171** prodPtr is a pointer to the 64-bit result 1172** 1173** Note: 1174** This algorithm is taken from: "The Art of Computer 1175** Programming", by Donald E. Knuth. Vol 2. Section 4.3.1 1176** Pages: 253-255. 1177**-- 1178**/ 1179 1180void uuid__uemul 1181( 1182 unsigned32 u, 1183 unsigned32 v, 1184 unsigned64_t *prodPtr 1185) 1186{ 1187 /* 1188 * following the notation in Knuth, Vol. 2 1189 */ 1190 unsigned32 uuid1, uuid2, v1, v2, temp; 1191 1192 uuid1 = u >> 16; 1193 uuid2 = u & 0xffff; 1194 v1 = v >> 16; 1195 v2 = v & 0xffff; 1196 1197 temp = uuid2 * v2; 1198 prodPtr->lo = temp & 0xffff; 1199 temp = uuid1 * v2 + (temp >> 16); 1200 prodPtr->hi = temp >> 16; 1201 temp = uuid2 * v1 + (temp & 0xffff); 1202 prodPtr->lo += (temp & 0xffff) << 16; 1203 prodPtr->hi += uuid1 * v1 + (temp >> 16); 1204} 1205 1206/**************************************************************************** 1207** 1208** U U I D T R U E R A N D O M N U M B E R G E N E R A T O R 1209** 1210***************************************************************************** 1211** 1212** This random number generator (RNG) was found in the ALGORITHMS Notesfile. 1213** 1214** (Note 16.7, July 7, 1989 by Robert (RDVAX::)Gries, Cambridge Research Lab, 1215** Computational Quality Group) 1216** 1217** It is really a "Multiple Prime Random Number Generator" (MPRNG) and is 1218** completely discussed in reference #1 (see below). 1219** 1220** References: 1221** 1) "The Multiple Prime Random Number Generator" by Alexander Hass 1222** pp. 368 to 381 in ACM Transactions on Mathematical Software, 1223** December, 1987 1224** 2) "The Art of Computer Programming: Seminumerical Algorithms 1225** (vol 2)" by Donald E. Knuth, pp. 39 to 113. 1226** 1227** A summary of the notesfile entry follows: 1228** 1229** Gries discusses the two RNG's available for ULTRIX-C. The default RNG 1230** uses a Linear Congruential Method (very popular) and the second RNG uses 1231** a technique known as a linear feedback shift register. 1232** 1233** The first (default) RNG suffers from bit-cycles (patterns/repetition), 1234** ie. it's "not that random." 1235** 1236** While the second RNG passes all the emperical tests, there are "states" 1237** that become "stable", albeit contrived. 1238** 1239** Gries then presents the MPRNG and says that it passes all emperical 1240** tests listed in reference #2. In addition, the number of calls to the 1241** MPRNG before a sequence of bit position repeats appears to have a normal 1242** distribution. 1243** 1244** Note (mbs): I have coded the Gries's MPRNG with the same constants that 1245** he used in his paper. I have no way of knowing whether they are "ideal" 1246** for the range of numbers we are dealing with. 1247** 1248****************************************************************************/ 1249 1250/* 1251** T R U E _ R A N D O M _ I N I T 1252** 1253** Note: we "seed" the RNG with the bits from the clock and the PID 1254** 1255**/ 1256 1257static void true_random_init (void) 1258{ 1259 uuid_time_t t; 1260 unsigned16 *seedp, seed=0; 1261 1262 /* 1263 * optimal/recommended starting values according to the reference 1264 */ 1265 static unsigned32 rand_m_init = 971; 1266 static unsigned32 rand_ia_init = 11113; 1267 static unsigned32 rand_ib_init = 104322; 1268 static unsigned32 rand_irand_init = 4181; 1269 1270 rand_m = rand_m_init; 1271 rand_ia = rand_ia_init; 1272 rand_ib = rand_ib_init; 1273 rand_irand = rand_irand_init; 1274 1275 /* 1276 * Generating our 'seed' value 1277 * 1278 * We start with the current time, but, since the resolution of clocks is 1279 * system hardware dependent (eg. Ultrix is 10 msec.) and most likely 1280 * coarser than our resolution (10 usec) we 'mixup' the bits by xor'ing 1281 * all the bits together. This will have the effect of involving all of 1282 * the bits in the determination of the seed value while remaining system 1283 * independent. Then for good measure to ensure a unique seed when there 1284 * are multiple processes creating UUID's on a system, we add in the PID. 1285 */ 1286 uuid__get_os_time(&t); 1287 seedp = (unsigned16 *)(&t); 1288 seed ^= *seedp++; 1289 seed ^= *seedp++; 1290 seed ^= *seedp++; 1291 seed ^= *seedp; 1292 rand_irand += seed + uuid__get_os_pid(); 1293} 1294 1295/* 1296** T R U E _ R A N D O M 1297** 1298** Note: we return a value which is 'tuned' to our purposes. Anyone 1299** using this routine should modify the return value accordingly. 1300**/ 1301 1302static unsigned16 true_random (void) 1303{ 1304 rand_m += 7; 1305 rand_ia += 1907; 1306 rand_ib += 73939; 1307 1308 if (rand_m >= 9973) rand_m -= 9871; 1309 if (rand_ia >= 99991) rand_ia -= 89989; 1310 if (rand_ib >= 224729) rand_ib -= 96233; 1311 1312 rand_irand = (rand_irand * rand_m) + rand_ia + rand_ib; 1313 1314 return (HI_WORD (rand_irand) ^ (rand_irand & RAND_MASK)); 1315} 1316 1317/***************************************************************************** 1318 * 1319 * LOCAL PROCEDURES - procedures used staticly by the UUID module 1320 * 1321 ****************************************************************************/ 1322 1323/* 1324**++ 1325** 1326** ROUTINE NAME: uuid_get_address 1327** 1328** SCOPE: PUBLIC 1329** 1330** DESCRIPTION: 1331** 1332** Return our IEEE 802 address. 1333** 1334** This function is not really "public", but more like the SPI functions 1335** -- available but not part of the official API. We've done this so 1336** that other subsystems (of which there are hopefully few or none) 1337** that need the IEEE 802 address can use this function rather than 1338** duplicating the gore it does (or more specifically, the gore that 1339** "uuid__get_os_address" does). 1340** 1341** INPUTS: none 1342** 1343** INPUTS/OUTPUTS: none 1344** 1345** OUTPUTS: 1346** 1347** addr IEEE 802 address 1348** 1349** status return status value 1350** 1351** IMPLICIT INPUTS: none 1352** 1353** IMPLICIT OUTPUTS: none 1354** 1355** FUNCTION VALUE: none 1356** 1357** SIDE EFFECTS: none 1358** 1359**-- 1360**/ 1361 1362void uuid_get_address 1363( 1364 uuid_address_p_t addr, 1365 unsigned32 *status 1366) 1367{ 1368 /* 1369 * just return address we determined previously if we've 1370 * already got one 1371 */ 1372 if (got_address) 1373 { 1374 memcpy (addr, &saved_addr, sizeof (uuid_address_t)); 1375 *status = saved_st; 1376 return; 1377 } 1378 1379 /* 1380 * Otherwise, call the system specific routine. 1381 */ 1382 uuid__get_os_address (addr, status); 1383 1384 if (*status == uuid_s_ok) 1385 { 1386 got_address = TRUE; 1387 memcpy (&saved_addr, addr, sizeof (uuid_address_t)); 1388 1389#ifdef UUID_DEBUG 1390 RPC_DBG_GPRINTF (( 1391 "uuid_get_address: %02x-%02x-%02x-%02x-%02x-%02x\n", 1392 addr->eaddr[0], addr->eaddr[1], addr->eaddr[2], 1393 addr->eaddr[3], addr->eaddr[4], addr->eaddr[5] )); 1394#endif 1395 1396 } 1397 else 1398 { 1399 *status = uuid_s_no_address; 1400 } 1401} 1402