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