27 #include <sys/cdefs.h>
30 #include <sys/param.h>
31 #include <sys/endian.h>
32 #include <sys/kernel.h>
34 #include <sys/mutex.h>
36 #include <sys/socket.h>
37 #include <sys/sysproto.h>
38 #include <sys/systm.h>
43 #include <net/if_dl.h>
44 #include <net/if_types.h>
69 uint16_t
node[UUID_NODE_LEN>>1];
94 struct sockaddr_dl *sdl;
97 CURVNET_SET(TD_TO_VNET(curthread));
98 IFNET_RLOCK_NOSLEEP();
99 TAILQ_FOREACH(ifp, &V_ifnet, if_link) {
102 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
103 sdl = (
struct sockaddr_dl*)ifa->ifa_addr;
104 if (sdl != NULL && sdl->sdl_family == AF_LINK &&
105 sdl->sdl_type == IFT_ETHER) {
107 bcopy(LLADDR(sdl), node, UUID_NODE_LEN);
108 IF_ADDR_RUNLOCK(ifp);
109 IFNET_RUNLOCK_NOSLEEP();
114 IF_ADDR_RUNLOCK(ifp);
116 IFNET_RUNLOCK_NOSLEEP();
118 for (i = 0; i < (UUID_NODE_LEN>>1); i++)
119 node[i] = (uint16_t)arc4random();
120 *((uint8_t*)node) |= 0x01;
134 uint64_t time = 0x01B21DD213814000LL;
137 time += (uint64_t)bt.sec * 10000000LL;
138 time += (10000000LL * (uint32_t)(bt.frac >> 32)) >> 32;
139 return (time & ((1LL << 60) - 1LL));
157 uuid.
seq = (uint16_t)arc4random() & 0x3fff;
169 uuid.
seq = htobe16(uuid.
seq | 0x8000);
171 for (n = 0; n <
count; n++) {
173 uuid.
time.
x.low = (uint32_t)time;
174 uuid.
time.
x.mid = (uint16_t)(time >> 32);
175 uuid.
time.
x.hi = ((uint16_t)(time >> 48) & 0xfff) | (1 << 12);
176 store[n] = *(
struct uuid *)&uuid;
183 #ifndef _SYS_SYSPROTO_H_
206 store =
malloc(count *
sizeof(
struct uuid), M_TEMP, M_WAITOK);
208 error = copyout(store, uap->
store, count *
sizeof(
struct uuid));
220 cnt =
snprintf(buf, sz,
"%08x-%04x-%04x-%04x-%04x%04x%04x",
222 be16toh(id->
node[0]), be16toh(id->
node[1]), be16toh(id->
node[2]));
232 return (
printf(
"%s", buf));
268 le32enc(p, uuid->time_low);
269 le16enc(p + 4, uuid->time_mid);
270 le16enc(p + 6, uuid->time_hi_and_version);
271 p[8] = uuid->clock_seq_hi_and_reserved;
272 p[9] = uuid->clock_seq_low;
273 for (i = 0; i < _UUID_NODE_LEN; i++)
274 p[10 + i] = uuid->node[i];
284 uuid->time_low = le32dec(p);
285 uuid->time_mid = le16dec(p + 4);
286 uuid->time_hi_and_version = le16dec(p + 6);
287 uuid->clock_seq_hi_and_reserved = p[8];
288 uuid->clock_seq_low = p[9];
289 for (i = 0; i < _UUID_NODE_LEN; i++)
290 uuid->node[i] = p[10 + i];
300 be32enc(p, uuid->time_low);
301 be16enc(p + 4, uuid->time_mid);
302 be16enc(p + 6, uuid->time_hi_and_version);
303 p[8] = uuid->clock_seq_hi_and_reserved;
304 p[9] = uuid->clock_seq_low;
305 for (i = 0; i < _UUID_NODE_LEN; i++)
306 p[10 + i] = uuid->node[i];
316 uuid->time_low = be32dec(p);
317 uuid->time_mid = be16dec(p + 4);
318 uuid->time_hi_and_version = be16dec(p + 6);
319 uuid->clock_seq_hi_and_reserved = p[8];
320 uuid->clock_seq_low = p[9];
321 for (i = 0; i < _UUID_NODE_LEN; i++)
322 uuid->node[i] = p[10 + i];
333 bzero(uuid,
sizeof(*uuid));
338 if (strlen(str) != 36)
350 n =
sscanf(str,
"%8x-%4x-%4x-%2x%2x-%2x%2x%2x%2x%2x%2x", c + 0, c + 1,
351 c + 2, c + 3, c + 4, c + 5, c + 6, c + 7, c + 8, c + 9, c + 10);
357 uuid->time_low = c[0];
358 uuid->time_mid = c[1];
359 uuid->time_hi_and_version = c[2];
360 uuid->clock_seq_hi_and_reserved = c[3];
361 uuid->clock_seq_low = c[4];
362 for (n = 0; n < 6; n++)
363 uuid->node[n] = c[n + 5];
366 return (((c[3] & 0x80) != 0x00 &&
367 (c[3] & 0xc0) != 0x80 &&
368 (c[3] & 0xe0) != 0xc0) ? EINVAL : 0);
int snprintf(char *str, size_t size, const char *format,...)
void * malloc(unsigned long size, struct malloc_type *mtp, int flags)
union uuid_private::@5 time
static struct uuid_private uuid_last
int parse_uuid(const char *str, struct uuid *uuid)
struct uuid_private::@5::@6 x
int sbuf_printf_uuid(struct sbuf *sb, struct uuid *uuid)
void be_uuid_enc(void *buf, struct uuid const *uuid)
uint16_t node[UUID_NODE_LEN >>1]
static uint64_t uuid_time(void)
int printf_uuid(struct uuid *uuid)
CTASSERT(sizeof(struct uuid)==16)
int sbuf_printf(struct sbuf *s, const char *fmt,...)
static struct mtx uuid_mutex
int sys_uuidgen(struct thread *td, struct uuidgen_args *uap)
struct uuid * kern_uuidgen(struct uuid *store, size_t count)
void free(void *addr, struct malloc_type *mtp)
MTX_SYSINIT(uuid_lock,&uuid_mutex,"UUID generator mutex lock", MTX_DEF)
int printf(const char *fmt,...)
void le_uuid_dec(void const *buf, struct uuid *uuid)
void bintime(struct bintime *bt)
int sscanf(const char *ibuf, const char *fmt,...)
int snprintf_uuid(char *buf, size_t sz, struct uuid *uuid)
void be_uuid_dec(void const *buf, struct uuid *uuid)
static void uuid_node(uint16_t *node)
void le_uuid_enc(void *buf, struct uuid const *uuid)