1 /* $OpenBSD: kern_uuid.c,v 1.2 2014/08/31 20:15:54 miod Exp $ */ 2 /* $NetBSD: kern_uuid.c,v 1.18 2011/11/19 22:51:25 tls Exp $ */ 3 4 /*- 5 * Copyright (c) 2002 Marcel Moolenaar 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * 29 * $FreeBSD: /repoman/r/ncvs/src/sys/kern/kern_uuid.c,v 1.7 2004/01/12 30 13:34:11 rse Exp $ 31 */ 32 /*- 33 * Copyright (c) 2002 Thomas Moestl <tmm@FreeBSD.org> 34 * All rights reserved. 35 * 36 * Redistribution and use in source and binary forms, with or without 37 * modification, are permitted provided that the following conditions 38 * are met: 39 * 1. Redistributions of source code must retain the above copyright 40 * notice, this list of conditions and the following disclaimer. 41 * 2. Redistributions in binary form must reproduce the above copyright 42 * notice, this list of conditions and the following disclaimer in the 43 * documentation and/or other materials provided with the distribution. 44 * 45 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 48 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 55 * SUCH DAMAGE. 56 * 57 * $FreeBSD: src/sys/sys/endian.h,v 1.7 2010/05/20 06:16:13 phk Exp $ 58 */ 59 60 #include <sys/param.h> 61 #include <sys/endian.h> 62 #include <sys/systm.h> 63 #include <sys/uuid.h> 64 65 /* 66 * For a description of UUIDs see RFC 4122. 67 */ 68 69 struct uuid_private { 70 struct { 71 uint32_t low; 72 uint16_t mid; 73 uint16_t hi; 74 } time; 75 uint16_t seq; 76 uint16_t node[_UUID_NODE_LEN>>1]; 77 }; 78 79 #ifdef DEBUG 80 int 81 uuid_snprintf(char *buf, size_t sz, const struct uuid *uuid) 82 { 83 const struct uuid_private *id; 84 int cnt; 85 86 id = (const struct uuid_private *)uuid; 87 cnt = snprintf(buf, sz, "%08x-%04x-%04x-%04x-%04x%04x%04x", 88 id->time.low, id->time.mid, id->time.hi, betoh16(id->seq), 89 betoh16(id->node[0]), betoh16(id->node[1]), betoh16(id->node[2])); 90 return (cnt); 91 } 92 93 int 94 uuid_printf(const struct uuid *uuid) 95 { 96 char buf[_UUID_BUF_LEN]; 97 98 (void) uuid_snprintf(buf, sizeof(buf), uuid); 99 printf("%s", buf); 100 return (0); 101 } 102 #endif 103 104 /* 105 * Encode/Decode UUID into octet-stream. 106 * http://www.opengroup.org/dce/info/draft-leach-uuids-guids-01.txt 107 * 108 * 0 1 2 3 109 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 110 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 111 * | time_low | 112 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 113 * | time_mid | time_hi_and_version | 114 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 115 * |clk_seq_hi_res | clk_seq_low | node (0-1) | 116 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 117 * | node (2-5) | 118 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 119 */ 120 121 /* Alignment-agnostic encode/decode bytestream to/from little/big endian. */ 122 123 static __inline uint16_t 124 be16dec(const void *pp) 125 { 126 uint8_t const *p = (uint8_t const *)pp; 127 128 return ((p[0] << 8) | p[1]); 129 } 130 131 static __inline uint32_t 132 be32dec(const void *pp) 133 { 134 uint8_t const *p = (uint8_t const *)pp; 135 136 return (((unsigned)p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]); 137 } 138 139 static __inline uint16_t 140 le16dec(const void *pp) 141 { 142 uint8_t const *p = (uint8_t const *)pp; 143 144 return ((p[1] << 8) | p[0]); 145 } 146 147 static __inline uint32_t 148 le32dec(const void *pp) 149 { 150 uint8_t const *p = (uint8_t const *)pp; 151 152 return (((unsigned)p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]); 153 } 154 155 static __inline void 156 be16enc(void *pp, uint16_t u) 157 { 158 uint8_t *p = (uint8_t *)pp; 159 160 p[0] = (u >> 8) & 0xff; 161 p[1] = u & 0xff; 162 } 163 164 static __inline void 165 be32enc(void *pp, uint32_t u) 166 { 167 uint8_t *p = (uint8_t *)pp; 168 169 p[0] = (u >> 24) & 0xff; 170 p[1] = (u >> 16) & 0xff; 171 p[2] = (u >> 8) & 0xff; 172 p[3] = u & 0xff; 173 } 174 175 static __inline void 176 le16enc(void *pp, uint16_t u) 177 { 178 uint8_t *p = (uint8_t *)pp; 179 180 p[0] = u & 0xff; 181 p[1] = (u >> 8) & 0xff; 182 } 183 184 static __inline void 185 le32enc(void *pp, uint32_t u) 186 { 187 uint8_t *p = (uint8_t *)pp; 188 189 p[0] = u & 0xff; 190 p[1] = (u >> 8) & 0xff; 191 p[2] = (u >> 16) & 0xff; 192 p[3] = (u >> 24) & 0xff; 193 } 194 195 void 196 uuid_enc_le(void *buf, const struct uuid *uuid) 197 { 198 uint8_t *p = buf; 199 int i; 200 201 le32enc(p, uuid->time_low); 202 le16enc(p + 4, uuid->time_mid); 203 le16enc(p + 6, uuid->time_hi_and_version); 204 p[8] = uuid->clock_seq_hi_and_reserved; 205 p[9] = uuid->clock_seq_low; 206 for (i = 0; i < _UUID_NODE_LEN; i++) 207 p[10 + i] = uuid->node[i]; 208 } 209 210 void 211 uuid_dec_le(const void *buf, struct uuid *uuid) 212 { 213 const uint8_t *p = buf; 214 int i; 215 216 uuid->time_low = le32dec(p); 217 uuid->time_mid = le16dec(p + 4); 218 uuid->time_hi_and_version = le16dec(p + 6); 219 uuid->clock_seq_hi_and_reserved = p[8]; 220 uuid->clock_seq_low = p[9]; 221 for (i = 0; i < _UUID_NODE_LEN; i++) 222 uuid->node[i] = p[10 + i]; 223 } 224 225 void 226 uuid_enc_be(void *buf, const struct uuid *uuid) 227 { 228 uint8_t *p = buf; 229 int i; 230 231 be32enc(p, uuid->time_low); 232 be16enc(p + 4, uuid->time_mid); 233 be16enc(p + 6, uuid->time_hi_and_version); 234 p[8] = uuid->clock_seq_hi_and_reserved; 235 p[9] = uuid->clock_seq_low; 236 for (i = 0; i < _UUID_NODE_LEN; i++) 237 p[10 + i] = uuid->node[i]; 238 } 239 240 void 241 uuid_dec_be(const void *buf, struct uuid *uuid) 242 { 243 const uint8_t *p = buf; 244 int i; 245 246 uuid->time_low = be32dec(p); 247 uuid->time_mid = be16dec(p + 4); 248 uuid->time_hi_and_version = be16dec(p + 6); 249 uuid->clock_seq_hi_and_reserved = p[8]; 250 uuid->clock_seq_low = p[9]; 251 for (i = 0; i < _UUID_NODE_LEN; i++) 252 uuid->node[i] = p[10 + i]; 253 } 254