4 * Copyright 2016 Red Hat, Inc.
7 * Fam Zheng <famz@redhat.com>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the Free
11 * Software Foundation; either version 2 of the License, or (at your option)
16 #include "qemu/osdep.h"
17 #include "qemu-common.h"
18 #include "qemu/uuid.h"
19 #include "qemu/bswap.h"
21 void qemu_uuid_generate(QemuUUID
*uuid
)
26 QEMU_BUILD_BUG_ON(sizeof(QemuUUID
) != 16);
28 for (i
= 0; i
< 4; ++i
) {
29 tmp
[i
] = g_random_int();
31 memcpy(uuid
, tmp
, sizeof(tmp
));
32 /* Set the two most significant bits (bits 6 and 7) of the
33 clock_seq_hi_and_reserved to zero and one, respectively. */
34 uuid
->data
[8] = (uuid
->data
[8] & 0x3f) | 0x80;
35 /* Set the four most significant bits (bits 12 through 15) of the
36 time_hi_and_version field to the 4-bit version number.
38 uuid
->data
[6] = (uuid
->data
[6] & 0xf) | 0x40;
41 int qemu_uuid_is_null(const QemuUUID
*uu
)
43 static QemuUUID null_uuid
;
44 return memcmp(uu
, &null_uuid
, sizeof(QemuUUID
)) == 0;
47 void qemu_uuid_unparse(const QemuUUID
*uuid
, char *out
)
49 const unsigned char *uu
= &uuid
->data
[0];
50 snprintf(out
, UUID_FMT_LEN
+ 1, UUID_FMT
,
51 uu
[0], uu
[1], uu
[2], uu
[3], uu
[4], uu
[5], uu
[6], uu
[7],
52 uu
[8], uu
[9], uu
[10], uu
[11], uu
[12], uu
[13], uu
[14], uu
[15]);
55 char *qemu_uuid_unparse_strdup(const QemuUUID
*uuid
)
57 const unsigned char *uu
= &uuid
->data
[0];
58 return g_strdup_printf(UUID_FMT
,
59 uu
[0], uu
[1], uu
[2], uu
[3], uu
[4], uu
[5], uu
[6],
60 uu
[7], uu
[8], uu
[9], uu
[10], uu
[11], uu
[12],
61 uu
[13], uu
[14], uu
[15]);
64 static bool qemu_uuid_is_valid(const char *str
)
68 for (i
= 0; i
< strlen(str
); i
++) {
69 const char c
= str
[i
];
70 if (i
== 8 || i
== 13 || i
== 18 || i
== 23) {
75 if ((c
>= '0' && c
<= '9') ||
76 (c
>= 'A' && c
<= 'F') ||
77 (c
>= 'a' && c
<= 'f')) {
86 int qemu_uuid_parse(const char *str
, QemuUUID
*uuid
)
88 unsigned char *uu
= &uuid
->data
[0];
91 if (!qemu_uuid_is_valid(str
)) {
95 ret
= sscanf(str
, UUID_FMT
, &uu
[0], &uu
[1], &uu
[2], &uu
[3],
96 &uu
[4], &uu
[5], &uu
[6], &uu
[7], &uu
[8], &uu
[9],
97 &uu
[10], &uu
[11], &uu
[12], &uu
[13], &uu
[14],
106 /* Swap from UUID format endian (BE) to the opposite or vice versa.
108 void qemu_uuid_bswap(QemuUUID
*uuid
)
110 assert(QEMU_PTR_IS_ALIGNED(uuid
, sizeof(uint32_t)));
111 bswap32s(&uuid
->fields
.time_low
);
112 bswap16s(&uuid
->fields
.time_mid
);
113 bswap16s(&uuid
->fields
.time_high_and_version
);