- Define a constant to describe the length of a printed UUID string.

- Clean up the namespace of this module and enable the encode/decode
  functions and printing functions.
- Move the code that actually generates the UUID out of the system call
  routine and into its own function.
This commit is contained in:
thorpej 2004-08-30 02:56:03 +00:00
parent 4d1e9e453b
commit e910f9082e
2 changed files with 140 additions and 61 deletions

View File

@ -1,5 +1,4 @@
/* $NetBSD: kern_uuid.c,v 1.1 2004/01/29 02:00:03 tsarna Exp $ */
/* $FreeBSD: /repoman/r/ncvs/src/sys/kern/kern_uuid.c,v 1.7 2004/01/12 13:34:11 rse Exp $ */
/* $NetBSD: kern_uuid.c,v 1.2 2004/08/30 02:56:03 thorpej Exp $ */
/*
* Copyright (c) 2002 Marcel Moolenaar
@ -25,10 +24,12 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD: /repoman/r/ncvs/src/sys/kern/kern_uuid.c,v 1.7 2004/01/12 13:34:11 rse Exp $
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_uuid.c,v 1.1 2004/01/29 02:00:03 tsarna Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_uuid.c,v 1.2 2004/08/30 02:56:03 thorpej Exp $");
#include <sys/param.h>
#include <sys/endian.h>
@ -49,9 +50,6 @@ __KERNEL_RCSID(0, "$NetBSD: kern_uuid.c,v 1.1 2004/01/29 02:00:03 tsarna Exp $")
#include <net/if_dl.h>
#include <net/if_types.h>
int sys_uuidgen(struct lwp *, void *, register_t *);
/*
* See also:
* http://www.opengroup.org/dce/info/draft-leach-uuids-guids-01.txt
@ -148,6 +146,35 @@ uuid_time(void)
return (time & ((1LL << 60) - 1LL));
}
/*
* Internal routine to actually generate the UUID.
*/
static void
uuid_generate(struct uuid_private *uuid, uint64_t *timep, int count)
{
uint64_t time;
simple_lock(&uuid_mutex);
uuid_node(uuid->node);
time = uuid_time();
*timep = time;
if (uuid_last.time.ll == 0LL || uuid_last.node[0] != uuid->node[0] ||
uuid_last.node[1] != uuid->node[1] ||
uuid_last.node[2] != uuid->node[2])
uuid->seq = (uint16_t)arc4random() & 0x3fff;
else if (uuid_last.time.ll >= time)
uuid->seq = (uuid_last.seq + 1) & 0x3fff;
else
uuid->seq = uuid_last.seq;
uuid_last = *uuid;
uuid_last.time.ll = (time + count - 1) & ((1LL << 60) - 1LL);
simple_unlock(&uuid_mutex);
}
int
sys_uuidgen(struct lwp *l, void *v, register_t *retval)
{
@ -167,24 +194,8 @@ sys_uuidgen(struct lwp *l, void *v, register_t *retval)
/* XXX: pre-validate accessibility to the whole of the UUID store? */
simple_lock(&uuid_mutex);
uuid_node(uuid.node);
time = uuid_time();
if (uuid_last.time.ll == 0LL || uuid_last.node[0] != uuid.node[0] ||
uuid_last.node[1] != uuid.node[1] ||
uuid_last.node[2] != uuid.node[2])
uuid.seq = (uint16_t)arc4random() & 0x3fff;
else if (uuid_last.time.ll >= time)
uuid.seq = (uuid_last.seq + 1) & 0x3fff;
else
uuid.seq = uuid_last.seq;
uuid_last = uuid;
uuid_last.time.ll = (time + SCARG(uap,count) - 1) & ((1LL << 60) - 1LL);
simple_unlock(&uuid_mutex);
/* Generate the base UUID. */
uuid_generate(&uuid, &time, SCARG(uap, count));
/* Set sequence and variant and deal with byte order. */
uuid.seq = htobe16(uuid.seq | 0x8000);
@ -196,22 +207,21 @@ sys_uuidgen(struct lwp *l, void *v, register_t *retval)
uuid.time.x.mid = (uint16_t)(time >> 32);
uuid.time.x.hi = ((uint16_t)(time >> 48) & 0xfff) | (1 << 12);
error = copyout(&uuid, SCARG(uap,store), sizeof(uuid));
SCARG(uap,store)++;
SCARG(uap,count)--;
SCARG(uap, store)++;
SCARG(uap, count)--;
time++;
} while (SCARG(uap,count) > 0 && !error);
} while (SCARG(uap, count) > 0 && error == 0);
return (error);
}
#ifdef notyet
int
snprintf_uuid(char *buf, size_t sz, struct uuid *uuid)
uuid_snprintf(char *buf, size_t sz, const struct uuid *uuid)
{
struct uuid_private *id;
const struct uuid_private *id;
int cnt;
id = (struct uuid_private *)uuid;
id = (const struct uuid_private *)uuid;
cnt = snprintf(buf, sz, "%08x-%04x-%04x-%04x-%04x%04x%04x",
id->time.x.low, id->time.x.mid, id->time.x.hi, be16toh(id->seq),
be16toh(id->node[0]), be16toh(id->node[1]), be16toh(id->node[2]));
@ -219,17 +229,17 @@ snprintf_uuid(char *buf, size_t sz, struct uuid *uuid)
}
int
printf_uuid(struct uuid *uuid)
uuid_printf(const struct uuid *uuid)
{
char buf[38];
char buf[UUID_STR_LEN];
snprintf_uuid(buf, sizeof(buf), uuid);
(void) uuid_snprintf(buf, sizeof(buf), uuid);
printf("%s", buf);
return 0;
return (0);
}
/*
* Encode/Decode UUID into byte-stream.
* Encode/Decode UUID into octet-stream.
* http://www.opengroup.org/dce/info/draft-leach-uuids-guids-01.txt
*
* 0 1 2 3
@ -245,13 +255,84 @@ printf_uuid(struct uuid *uuid)
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
void
le_uuid_enc(void *buf, struct uuid const *uuid)
static void
be16enc(void *buf, uint16_t u)
{
u_char *p;
uint8_t *p = buf;
p[0] = (u >> 8) & 0xff;
p[1] = u & 0xff;
}
static void
le16enc(void *buf, uint16_t u)
{
uint8_t *p = buf;
p[0] = u & 0xff;
p[1] = (u >> 8) & 0xff;
}
static uint16_t
be16dec(const void *buf)
{
const uint8_t *p = buf;
return ((p[0] << 8) | p[1]);
}
static uint16_t
le16dec(const void *buf)
{
const uint8_t *p = buf;
return ((p[1] << 8) | p[0]);
}
static void
be32enc(void *buf, uint32_t u)
{
uint8_t *p = buf;
p[0] = (u >> 24) & 0xff;
p[1] = (u >> 16) & 0xff;
p[2] = (u >> 8) & 0xff;
p[3] = u & 0xff;
}
static void
le32enc(void *buf, uint32_t u)
{
uint8_t *p = buf;
p[0] = u & 0xff;
p[1] = (u >> 8) & 0xff;
p[2] = (u >> 16) & 0xff;
p[3] = (u >> 24) & 0xff;
}
static uint32_t
be32dec(const void *buf)
{
const uint8_t *p = buf;
return ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
}
static uint32_t
le32dec(const void *buf)
{
const uint8_t *p = buf;
return ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]);
}
void
uuid_enc_le(void *buf, const struct uuid *uuid)
{
uint8_t *p = buf;
int i;
p = buf;
le32enc(p, uuid->time_low);
le16enc(p + 4, uuid->time_mid);
le16enc(p + 6, uuid->time_hi_and_version);
@ -262,12 +343,11 @@ le_uuid_enc(void *buf, struct uuid const *uuid)
}
void
le_uuid_dec(void const *buf, struct uuid *uuid)
uuid_dec_le(void const *buf, struct uuid *uuid)
{
u_char const *p;
const uint8_t *p = buf;
int i;
p = buf;
uuid->time_low = le32dec(p);
uuid->time_mid = le16dec(p + 4);
uuid->time_hi_and_version = le16dec(p + 6);
@ -276,13 +356,13 @@ le_uuid_dec(void const *buf, struct uuid *uuid)
for (i = 0; i < _UUID_NODE_LEN; i++)
uuid->node[i] = p[10 + i];
}
void
be_uuid_enc(void *buf, struct uuid const *uuid)
uuid_enc_be(void *buf, const struct uuid *uuid)
{
u_char *p;
uint8_t *p = buf;
int i;
p = buf;
be32enc(p, uuid->time_low);
be16enc(p + 4, uuid->time_mid);
be16enc(p + 6, uuid->time_hi_and_version);
@ -293,12 +373,11 @@ be_uuid_enc(void *buf, struct uuid const *uuid)
}
void
be_uuid_dec(void const *buf, struct uuid *uuid)
uuid_dec_be(void const *buf, struct uuid *uuid)
{
u_char const *p;
const uint8_t *p = buf;
int i;
p = buf;
uuid->time_low = be32dec(p);
uuid->time_mid = le16dec(p + 4);
uuid->time_hi_and_version = be16dec(p + 6);
@ -307,4 +386,3 @@ be_uuid_dec(void const *buf, struct uuid *uuid)
for (i = 0; i < _UUID_NODE_LEN; i++)
uuid->node[i] = p[10 + i];
}
#endif

View File

@ -1,5 +1,5 @@
/* $NetBSD: uuid.h,v 1.1 2004/01/29 02:00:03 tsarna Exp $ */
/* $FreeBSD: /repoman/r/ncvs/src/sys/sys/uuid.h,v 1.3 2003/05/31 16:47:07 phk Exp $ */
/* $NetBSD: uuid.h,v 1.2 2004/08/30 02:56:03 thorpej Exp $ */
/*
* Copyright (c) 2002 Marcel Moolenaar
* All rights reserved.
@ -36,6 +36,9 @@
/* Length of a node address (an IEEE 802 address). */
#define _UUID_NODE_LEN 6
/* Length of a printed UUID. */
#define _UUID_STR_LEN 38
/*
* See also:
* http://www.opengroup.org/dce/info/draft-leach-uuids-guids-01.txt
@ -55,19 +58,17 @@ struct uuid {
#ifdef _KERNEL
#define UUID_NODE_LEN _UUID_NODE_LEN
#define UUID_STR_LEN _UUID_STR_LEN
#ifdef notyet
int snprintf_uuid(char *, size_t, struct uuid *);
int printf_uuid(struct uuid *);
void be_uuid_dec(void const *buf, struct uuid *uuid);
void be_uuid_enc(void *buf, struct uuid const *uuid);
void le_uuid_dec(void const *buf, struct uuid *uuid);
void le_uuid_enc(void *buf, struct uuid const *uuid);
#endif
int uuid_snprintf(char *, size_t, const struct uuid *);
int uuid_printf(const struct uuid *);
void uuid_dec_be(const void *, struct uuid *);
void uuid_dec_le(const void *, struct uuid *);
void uuid_enc_be(void *, const struct uuid *);
void uuid_enc_le(void *, const struct uuid *);
#else /* _KERNEL */
/* XXX namespace pollution? */
typedef struct uuid uuid_t;
__BEGIN_DECLS