]>
Commit | Line | Data |
---|---|---|
91447636 | 1 | /* |
316670eb | 2 | * Copyright (c) 2004-2011 Apple Inc. All rights reserved. |
91447636 A |
3 | * |
4 | * %Begin-Header% | |
5 | * Redistribution and use in source and binary forms, with or without | |
6 | * modification, are permitted provided that the following conditions | |
7 | * are met: | |
8 | * 1. Redistributions of source code must retain the above copyright | |
9 | * notice, and the entire permission notice in its entirety, | |
10 | * including the disclaimer of warranties. | |
11 | * 2. Redistributions in binary form must reproduce the above copyright | |
12 | * notice, this list of conditions and the following disclaimer in the | |
13 | * documentation and/or other materials provided with the distribution. | |
14 | * 3. The name of the author may not be used to endorse or promote | |
15 | * products derived from this software without specific prior | |
16 | * written permission. | |
17 | * | |
18 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | |
19 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF | |
21 | * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE | |
22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT | |
24 | * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | |
25 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |
26 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE | |
28 | * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH | |
29 | * DAMAGE. | |
30 | * %End-Header% | |
31 | */ | |
32 | ||
33 | #include <uuid/uuid.h> | |
34 | ||
35 | #include <stdint.h> | |
36 | #include <string.h> | |
37 | ||
38 | #include <sys/random.h> | |
39 | #include <sys/socket.h> | |
40 | #include <sys/systm.h> | |
41 | #include <sys/time.h> | |
42 | ||
316670eb | 43 | extern int uuid_get_ethernet(u_int8_t *); |
91447636 | 44 | |
91447636 A |
45 | static void |
46 | read_node(uint8_t *node) | |
47 | { | |
2d21ac55 | 48 | #if NETWORKING |
316670eb A |
49 | if (uuid_get_ethernet(node) == 0) |
50 | return; | |
2d21ac55 | 51 | #endif /* NETWORKING */ |
91447636 A |
52 | |
53 | read_random(node, 6); | |
54 | node[0] |= 0x01; | |
55 | } | |
56 | ||
57 | static uint64_t | |
58 | read_time(void) | |
59 | { | |
60 | struct timespec tv; | |
61 | ||
62 | nanotime(&tv); | |
63 | ||
64 | return (tv.tv_sec * 10000000ULL) + (tv.tv_nsec / 100ULL) + 0x01B21DD213814000ULL; | |
65 | } | |
66 | ||
67 | void | |
68 | uuid_clear(uuid_t uu) | |
69 | { | |
70 | memset(uu, 0, sizeof(uuid_t)); | |
71 | } | |
72 | ||
73 | int | |
74 | uuid_compare(const uuid_t uu1, const uuid_t uu2) | |
75 | { | |
76 | return memcmp(uu1, uu2, sizeof(uuid_t)); | |
77 | } | |
78 | ||
79 | void | |
80 | uuid_copy(uuid_t dst, const uuid_t src) | |
81 | { | |
82 | memcpy(dst, src, sizeof(uuid_t)); | |
83 | } | |
84 | ||
85 | void | |
86 | uuid_generate_random(uuid_t out) | |
87 | { | |
88 | read_random(out, sizeof(uuid_t)); | |
89 | ||
90 | out[6] = (out[6] & 0x0F) | 0x40; | |
91 | out[8] = (out[8] & 0x3F) | 0x80; | |
92 | } | |
93 | ||
94 | void | |
95 | uuid_generate_time(uuid_t out) | |
96 | { | |
97 | uint64_t time; | |
98 | ||
99 | read_node(&out[10]); | |
100 | read_random(&out[8], 2); | |
101 | ||
102 | time = read_time(); | |
103 | out[0] = (uint8_t)(time >> 24); | |
104 | out[1] = (uint8_t)(time >> 16); | |
105 | out[2] = (uint8_t)(time >> 8); | |
106 | out[3] = (uint8_t)time; | |
107 | out[4] = (uint8_t)(time >> 40); | |
108 | out[5] = (uint8_t)(time >> 32); | |
109 | out[6] = (uint8_t)(time >> 56); | |
110 | out[7] = (uint8_t)(time >> 48); | |
111 | ||
112 | out[6] = (out[6] & 0x0F) | 0x10; | |
113 | out[8] = (out[8] & 0x3F) | 0x80; | |
114 | } | |
115 | ||
116 | void | |
117 | uuid_generate(uuid_t out) | |
118 | { | |
119 | uuid_generate_random(out); | |
120 | } | |
121 | ||
122 | int | |
123 | uuid_is_null(const uuid_t uu) | |
124 | { | |
125 | return !memcmp(uu, UUID_NULL, sizeof(uuid_t)); | |
126 | } | |
127 | ||
128 | int | |
b0d623f7 | 129 | uuid_parse(const uuid_string_t in, uuid_t uu) |
91447636 A |
130 | { |
131 | int n = 0; | |
132 | ||
133 | sscanf(in, | |
b0d623f7 A |
134 | "%2hhx%2hhx%2hhx%2hhx-" |
135 | "%2hhx%2hhx-" | |
136 | "%2hhx%2hhx-" | |
137 | "%2hhx%2hhx-" | |
138 | "%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%n", | |
91447636 A |
139 | &uu[0], &uu[1], &uu[2], &uu[3], |
140 | &uu[4], &uu[5], | |
141 | &uu[6], &uu[7], | |
142 | &uu[8], &uu[9], | |
143 | &uu[10], &uu[11], &uu[12], &uu[13], &uu[14], &uu[15], &n); | |
144 | ||
145 | return (n != 36 || in[n] != '\0' ? -1 : 0); | |
146 | } | |
147 | ||
148 | void | |
b0d623f7 | 149 | uuid_unparse_lower(const uuid_t uu, uuid_string_t out) |
91447636 | 150 | { |
b0d623f7 A |
151 | snprintf(out, |
152 | sizeof(uuid_string_t), | |
91447636 A |
153 | "%02x%02x%02x%02x-" |
154 | "%02x%02x-" | |
155 | "%02x%02x-" | |
156 | "%02x%02x-" | |
157 | "%02x%02x%02x%02x%02x%02x", | |
158 | uu[0], uu[1], uu[2], uu[3], | |
159 | uu[4], uu[5], | |
160 | uu[6], uu[7], | |
161 | uu[8], uu[9], | |
162 | uu[10], uu[11], uu[12], uu[13], uu[14], uu[15]); | |
163 | } | |
164 | ||
165 | void | |
b0d623f7 | 166 | uuid_unparse_upper(const uuid_t uu, uuid_string_t out) |
91447636 | 167 | { |
b0d623f7 A |
168 | snprintf(out, |
169 | sizeof(uuid_string_t), | |
91447636 A |
170 | "%02X%02X%02X%02X-" |
171 | "%02X%02X-" | |
172 | "%02X%02X-" | |
173 | "%02X%02X-" | |
174 | "%02X%02X%02X%02X%02X%02X", | |
175 | uu[0], uu[1], uu[2], uu[3], | |
176 | uu[4], uu[5], | |
177 | uu[6], uu[7], | |
178 | uu[8], uu[9], | |
179 | uu[10], uu[11], uu[12], uu[13], uu[14], uu[15]); | |
180 | } | |
181 | ||
182 | void | |
b0d623f7 | 183 | uuid_unparse(const uuid_t uu, uuid_string_t out) |
91447636 A |
184 | { |
185 | uuid_unparse_upper(uu, out); | |
186 | } |