xref: /openbsd/sys/kern/kern_uuid.c (revision fbb823f2)
1*fbb823f2Smiod /*	$OpenBSD: kern_uuid.c,v 1.2 2014/08/31 20:15:54 miod Exp $	*/
226e78ed6Smiod /*	$NetBSD: kern_uuid.c,v 1.18 2011/11/19 22:51:25 tls Exp $	*/
326e78ed6Smiod 
4*fbb823f2Smiod /*-
526e78ed6Smiod  * Copyright (c) 2002 Marcel Moolenaar
626e78ed6Smiod  * All rights reserved.
726e78ed6Smiod  *
826e78ed6Smiod  * Redistribution and use in source and binary forms, with or without
926e78ed6Smiod  * modification, are permitted provided that the following conditions
1026e78ed6Smiod  * are met:
1126e78ed6Smiod  *
1226e78ed6Smiod  * 1. Redistributions of source code must retain the above copyright
1326e78ed6Smiod  *    notice, this list of conditions and the following disclaimer.
1426e78ed6Smiod  * 2. Redistributions in binary form must reproduce the above copyright
1526e78ed6Smiod  *    notice, this list of conditions and the following disclaimer in the
1626e78ed6Smiod  *    documentation and/or other materials provided with the distribution.
1726e78ed6Smiod  *
1826e78ed6Smiod  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1926e78ed6Smiod  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2026e78ed6Smiod  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2126e78ed6Smiod  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2226e78ed6Smiod  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2326e78ed6Smiod  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2426e78ed6Smiod  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2526e78ed6Smiod  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2626e78ed6Smiod  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2726e78ed6Smiod  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2826e78ed6Smiod  *
2926e78ed6Smiod  * $FreeBSD: /repoman/r/ncvs/src/sys/kern/kern_uuid.c,v 1.7 2004/01/12
3026e78ed6Smiod 13:34:11 rse Exp $
3126e78ed6Smiod  */
32*fbb823f2Smiod /*-
33*fbb823f2Smiod  * Copyright (c) 2002 Thomas Moestl <tmm@FreeBSD.org>
34*fbb823f2Smiod  * All rights reserved.
35*fbb823f2Smiod  *
36*fbb823f2Smiod  * Redistribution and use in source and binary forms, with or without
37*fbb823f2Smiod  * modification, are permitted provided that the following conditions
38*fbb823f2Smiod  * are met:
39*fbb823f2Smiod  * 1. Redistributions of source code must retain the above copyright
40*fbb823f2Smiod  *    notice, this list of conditions and the following disclaimer.
41*fbb823f2Smiod  * 2. Redistributions in binary form must reproduce the above copyright
42*fbb823f2Smiod  *    notice, this list of conditions and the following disclaimer in the
43*fbb823f2Smiod  *    documentation and/or other materials provided with the distribution.
44*fbb823f2Smiod  *
45*fbb823f2Smiod  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
46*fbb823f2Smiod  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47*fbb823f2Smiod  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48*fbb823f2Smiod  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
49*fbb823f2Smiod  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50*fbb823f2Smiod  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51*fbb823f2Smiod  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52*fbb823f2Smiod  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53*fbb823f2Smiod  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54*fbb823f2Smiod  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55*fbb823f2Smiod  * SUCH DAMAGE.
56*fbb823f2Smiod  *
57*fbb823f2Smiod  * $FreeBSD: src/sys/sys/endian.h,v 1.7 2010/05/20 06:16:13 phk Exp $
58*fbb823f2Smiod  */
5926e78ed6Smiod 
6026e78ed6Smiod #include <sys/param.h>
6126e78ed6Smiod #include <sys/endian.h>
6226e78ed6Smiod #include <sys/systm.h>
6326e78ed6Smiod #include <sys/uuid.h>
6426e78ed6Smiod 
6526e78ed6Smiod /*
6626e78ed6Smiod  * For a description of UUIDs see RFC 4122.
6726e78ed6Smiod  */
6826e78ed6Smiod 
6926e78ed6Smiod struct uuid_private {
7026e78ed6Smiod 	struct {
7126e78ed6Smiod 		uint32_t low;
7226e78ed6Smiod 		uint16_t mid;
7326e78ed6Smiod 		uint16_t hi;
7426e78ed6Smiod 	} time;
7526e78ed6Smiod 	uint16_t seq;
76*fbb823f2Smiod 	uint16_t node[_UUID_NODE_LEN>>1];
7726e78ed6Smiod };
7826e78ed6Smiod 
7926e78ed6Smiod #ifdef DEBUG
8026e78ed6Smiod int
uuid_snprintf(char * buf,size_t sz,const struct uuid * uuid)8126e78ed6Smiod uuid_snprintf(char *buf, size_t sz, const struct uuid *uuid)
8226e78ed6Smiod {
8326e78ed6Smiod 	const struct uuid_private *id;
8426e78ed6Smiod 	int cnt;
8526e78ed6Smiod 
8626e78ed6Smiod 	id = (const struct uuid_private *)uuid;
8726e78ed6Smiod 	cnt = snprintf(buf, sz, "%08x-%04x-%04x-%04x-%04x%04x%04x",
8826e78ed6Smiod 	    id->time.low, id->time.mid, id->time.hi, betoh16(id->seq),
8926e78ed6Smiod 	    betoh16(id->node[0]), betoh16(id->node[1]), betoh16(id->node[2]));
9026e78ed6Smiod 	return (cnt);
9126e78ed6Smiod }
9226e78ed6Smiod 
9326e78ed6Smiod int
uuid_printf(const struct uuid * uuid)9426e78ed6Smiod uuid_printf(const struct uuid *uuid)
9526e78ed6Smiod {
9626e78ed6Smiod 	char buf[_UUID_BUF_LEN];
9726e78ed6Smiod 
9826e78ed6Smiod 	(void) uuid_snprintf(buf, sizeof(buf), uuid);
9926e78ed6Smiod 	printf("%s", buf);
10026e78ed6Smiod 	return (0);
10126e78ed6Smiod }
10226e78ed6Smiod #endif
10326e78ed6Smiod 
10426e78ed6Smiod /*
10526e78ed6Smiod  * Encode/Decode UUID into octet-stream.
106*fbb823f2Smiod  *   http://www.opengroup.org/dce/info/draft-leach-uuids-guids-01.txt
10726e78ed6Smiod  *
10826e78ed6Smiod  * 0                   1                   2                   3
10926e78ed6Smiod  *   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
11026e78ed6Smiod  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
11126e78ed6Smiod  *  |                          time_low                             |
11226e78ed6Smiod  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
11326e78ed6Smiod  *  |       time_mid                |         time_hi_and_version   |
11426e78ed6Smiod  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
11526e78ed6Smiod  *  |clk_seq_hi_res |  clk_seq_low  |         node (0-1)            |
11626e78ed6Smiod  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
11726e78ed6Smiod  *  |                         node (2-5)                            |
11826e78ed6Smiod  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
11926e78ed6Smiod  */
12026e78ed6Smiod 
121*fbb823f2Smiod /* Alignment-agnostic encode/decode bytestream to/from little/big endian. */
122*fbb823f2Smiod 
123*fbb823f2Smiod static __inline uint16_t
be16dec(const void * pp)124*fbb823f2Smiod be16dec(const void *pp)
125*fbb823f2Smiod {
126*fbb823f2Smiod 	uint8_t const *p = (uint8_t const *)pp;
127*fbb823f2Smiod 
128*fbb823f2Smiod 	return ((p[0] << 8) | p[1]);
129*fbb823f2Smiod }
130*fbb823f2Smiod 
131*fbb823f2Smiod static __inline uint32_t
be32dec(const void * pp)132*fbb823f2Smiod be32dec(const void *pp)
133*fbb823f2Smiod {
134*fbb823f2Smiod 	uint8_t const *p = (uint8_t const *)pp;
135*fbb823f2Smiod 
136*fbb823f2Smiod 	return (((unsigned)p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
137*fbb823f2Smiod }
138*fbb823f2Smiod 
139*fbb823f2Smiod static __inline uint16_t
le16dec(const void * pp)140*fbb823f2Smiod le16dec(const void *pp)
141*fbb823f2Smiod {
142*fbb823f2Smiod 	uint8_t const *p = (uint8_t const *)pp;
143*fbb823f2Smiod 
144*fbb823f2Smiod 	return ((p[1] << 8) | p[0]);
145*fbb823f2Smiod }
146*fbb823f2Smiod 
147*fbb823f2Smiod static __inline uint32_t
le32dec(const void * pp)148*fbb823f2Smiod le32dec(const void *pp)
149*fbb823f2Smiod {
150*fbb823f2Smiod 	uint8_t const *p = (uint8_t const *)pp;
151*fbb823f2Smiod 
152*fbb823f2Smiod 	return (((unsigned)p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]);
153*fbb823f2Smiod }
154*fbb823f2Smiod 
155*fbb823f2Smiod static __inline void
be16enc(void * pp,uint16_t u)156*fbb823f2Smiod be16enc(void *pp, uint16_t u)
157*fbb823f2Smiod {
158*fbb823f2Smiod 	uint8_t *p = (uint8_t *)pp;
159*fbb823f2Smiod 
160*fbb823f2Smiod 	p[0] = (u >> 8) & 0xff;
161*fbb823f2Smiod 	p[1] = u & 0xff;
162*fbb823f2Smiod }
163*fbb823f2Smiod 
164*fbb823f2Smiod static __inline void
be32enc(void * pp,uint32_t u)165*fbb823f2Smiod be32enc(void *pp, uint32_t u)
166*fbb823f2Smiod {
167*fbb823f2Smiod 	uint8_t *p = (uint8_t *)pp;
168*fbb823f2Smiod 
169*fbb823f2Smiod 	p[0] = (u >> 24) & 0xff;
170*fbb823f2Smiod 	p[1] = (u >> 16) & 0xff;
171*fbb823f2Smiod 	p[2] = (u >> 8) & 0xff;
172*fbb823f2Smiod 	p[3] = u & 0xff;
173*fbb823f2Smiod }
174*fbb823f2Smiod 
175*fbb823f2Smiod static __inline void
le16enc(void * pp,uint16_t u)176*fbb823f2Smiod le16enc(void *pp, uint16_t u)
177*fbb823f2Smiod {
178*fbb823f2Smiod 	uint8_t *p = (uint8_t *)pp;
179*fbb823f2Smiod 
180*fbb823f2Smiod 	p[0] = u & 0xff;
181*fbb823f2Smiod 	p[1] = (u >> 8) & 0xff;
182*fbb823f2Smiod }
183*fbb823f2Smiod 
184*fbb823f2Smiod static __inline void
le32enc(void * pp,uint32_t u)185*fbb823f2Smiod le32enc(void *pp, uint32_t u)
186*fbb823f2Smiod {
187*fbb823f2Smiod 	uint8_t *p = (uint8_t *)pp;
188*fbb823f2Smiod 
189*fbb823f2Smiod 	p[0] = u & 0xff;
190*fbb823f2Smiod 	p[1] = (u >> 8) & 0xff;
191*fbb823f2Smiod 	p[2] = (u >> 16) & 0xff;
192*fbb823f2Smiod 	p[3] = (u >> 24) & 0xff;
193*fbb823f2Smiod }
194*fbb823f2Smiod 
19526e78ed6Smiod void
uuid_enc_le(void * buf,const struct uuid * uuid)19626e78ed6Smiod uuid_enc_le(void *buf, const struct uuid *uuid)
19726e78ed6Smiod {
19826e78ed6Smiod 	uint8_t *p = buf;
19926e78ed6Smiod 	int i;
20026e78ed6Smiod 
201*fbb823f2Smiod 	le32enc(p, uuid->time_low);
202*fbb823f2Smiod 	le16enc(p + 4, uuid->time_mid);
203*fbb823f2Smiod 	le16enc(p + 6, uuid->time_hi_and_version);
20426e78ed6Smiod 	p[8] = uuid->clock_seq_hi_and_reserved;
20526e78ed6Smiod 	p[9] = uuid->clock_seq_low;
206*fbb823f2Smiod 	for (i = 0; i < _UUID_NODE_LEN; i++)
20726e78ed6Smiod 		p[10 + i] = uuid->node[i];
20826e78ed6Smiod }
20926e78ed6Smiod 
21026e78ed6Smiod void
uuid_dec_le(const void * buf,struct uuid * uuid)211*fbb823f2Smiod uuid_dec_le(const void *buf, struct uuid *uuid)
21226e78ed6Smiod {
21326e78ed6Smiod 	const uint8_t *p = buf;
21426e78ed6Smiod 	int i;
21526e78ed6Smiod 
216*fbb823f2Smiod 	uuid->time_low = le32dec(p);
217*fbb823f2Smiod 	uuid->time_mid = le16dec(p + 4);
218*fbb823f2Smiod 	uuid->time_hi_and_version = le16dec(p + 6);
21926e78ed6Smiod 	uuid->clock_seq_hi_and_reserved = p[8];
22026e78ed6Smiod 	uuid->clock_seq_low = p[9];
221*fbb823f2Smiod 	for (i = 0; i < _UUID_NODE_LEN; i++)
22226e78ed6Smiod 		uuid->node[i] = p[10 + i];
22326e78ed6Smiod }
22426e78ed6Smiod 
22526e78ed6Smiod void
uuid_enc_be(void * buf,const struct uuid * uuid)22626e78ed6Smiod uuid_enc_be(void *buf, const struct uuid *uuid)
22726e78ed6Smiod {
22826e78ed6Smiod 	uint8_t *p = buf;
22926e78ed6Smiod 	int i;
23026e78ed6Smiod 
231*fbb823f2Smiod 	be32enc(p, uuid->time_low);
232*fbb823f2Smiod 	be16enc(p + 4, uuid->time_mid);
233*fbb823f2Smiod 	be16enc(p + 6, uuid->time_hi_and_version);
23426e78ed6Smiod 	p[8] = uuid->clock_seq_hi_and_reserved;
23526e78ed6Smiod 	p[9] = uuid->clock_seq_low;
236*fbb823f2Smiod 	for (i = 0; i < _UUID_NODE_LEN; i++)
23726e78ed6Smiod 		p[10 + i] = uuid->node[i];
23826e78ed6Smiod }
23926e78ed6Smiod 
24026e78ed6Smiod void
uuid_dec_be(const void * buf,struct uuid * uuid)241*fbb823f2Smiod uuid_dec_be(const void *buf, struct uuid *uuid)
24226e78ed6Smiod {
24326e78ed6Smiod 	const uint8_t *p = buf;
24426e78ed6Smiod 	int i;
24526e78ed6Smiod 
246*fbb823f2Smiod 	uuid->time_low = be32dec(p);
247*fbb823f2Smiod 	uuid->time_mid = be16dec(p + 4);
248*fbb823f2Smiod 	uuid->time_hi_and_version = be16dec(p + 6);
24926e78ed6Smiod 	uuid->clock_seq_hi_and_reserved = p[8];
25026e78ed6Smiod 	uuid->clock_seq_low = p[9];
251*fbb823f2Smiod 	for (i = 0; i < _UUID_NODE_LEN; i++)
25226e78ed6Smiod 		uuid->node[i] = p[10 + i];
25326e78ed6Smiod }
254