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 3013: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 69struct 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 80int 81uuid_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 93int 94uuid_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 123static __inline uint16_t 124be16dec(const void *pp) 125{ 126 uint8_t const *p = (uint8_t const *)pp; 127 128 return ((p[0] << 8) | p[1]); 129} 130 131static __inline uint32_t 132be32dec(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 139static __inline uint16_t 140le16dec(const void *pp) 141{ 142 uint8_t const *p = (uint8_t const *)pp; 143 144 return ((p[1] << 8) | p[0]); 145} 146 147static __inline uint32_t 148le32dec(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 155static __inline void 156be16enc(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 164static __inline void 165be32enc(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 175static __inline void 176le16enc(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 184static __inline void 185le32enc(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 195void 196uuid_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 210void 211uuid_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 225void 226uuid_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 240void 241uuid_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