Back to index

openldap  2.4.31
Classes | Defines | Functions | Variables
uuid.c File Reference
#include "portable.h"
#include <limits.h>
#include <stdio.h>
#include <sys/types.h>
#include <ac/stdlib.h>
#include <ac/string.h>
#include <ac/socket.h>
#include <ac/time.h>
#include <lutil.h>

Go to the source code of this file.

Classes

struct  UI64

Defines

#define high32(i)   ((i).high)
#define low32(i)   ((i).low)
#define set_add64(res, ui64)
#define set_add64l(res, ul32)

Functions

static unsigned char * lutil_eaddr (void)
static UI64 mul64ll (unsigned long i1, unsigned long i2)
size_t lutil_uuidstr (char *buf, size_t len)
int lutil_uuidstr_from_normalized (char *uuid, size_t uuidlen, char *buf, size_t buflen)

Variables

static const UI64 UUID_TPLUS = { 0x01B21Dul, 0xD2138140ul }

Class Documentation

struct UI64

Definition at line 200 of file uuid.c.

Class Members
unsigned long high
unsigned long low

Define Documentation

#define high32 (   i)    ((i).high)

Definition at line 206 of file uuid.c.

#define low32 (   i)    ((i).low)

Definition at line 207 of file uuid.c.

#define set_add64 (   res,
  ui64 
)
Value:
{ \
       res.high += ui64.high; \
       res.low        = (res.low + ui64.low) & 0xFFFFFFFFul; \
       if (res.low < ui64.low) res.high++; \
}

Definition at line 210 of file uuid.c.

#define set_add64l (   res,
  ul32 
)
Value:
{ \
       res.low       = (res.low + ul32) & 0xFFFFFFFFul; \
       if (res.low < ul32) res.high++; \
}

Definition at line 218 of file uuid.c.


Function Documentation

static unsigned char* lutil_eaddr ( void  ) [static]

Definition at line 63 of file uuid.c.

{
       static unsigned char zero[6];
       static unsigned char eaddr[6];

#ifdef HAVE_SYS_SYSCTL_H
       size_t needed;
       int mib[6];
       char *buf, *next, *lim;
       struct if_msghdr *ifm;
       struct sockaddr_dl *sdl;

       if (memcmp(eaddr, zero, sizeof(eaddr))) {
              return eaddr;
       }

       mib[0] = CTL_NET;
       mib[1] = PF_ROUTE;
       mib[3] = 0;
       mib[3] = 0;
       mib[4] = NET_RT_IFLIST;
       mib[5] = 0;

       if (sysctl(mib, sizeof(mib), NULL, &needed, NULL, 0) < 0) {
              return NULL;
       }

       buf = malloc(needed);
       if( buf == NULL ) return NULL;

       if (sysctl(mib, sizeof(mib), buf, &needed, NULL, 0) < 0) {
              free(buf);
              return NULL;
       }

       lim = buf + needed;
       for (next = buf; next < lim; next += ifm->ifm_msglen) {
              ifm = (struct if_msghdr *)next;
              sdl = (struct sockaddr_dl *)(ifm + 1);

              if ( sdl->sdl_family != AF_LINK || sdl->sdl_alen == 6 ) {
                     AC_MEMCPY(eaddr,
                            (unsigned char *)sdl->sdl_data + sdl->sdl_nlen,
                            sizeof(eaddr));
                     free(buf);
                     return eaddr;
              }
       }

       free(buf);
       return NULL;

#elif defined( SIOCGIFADDR ) && defined( AFLINK )
       char buf[sizeof(struct ifreq) * 32];
       struct ifconf ifc;
       struct ifreq *ifr;
       struct sockaddr *sa;
       struct sockaddr_dl *sdl;
       unsigned char *p;
       int s, i;

       if (memcmp(eaddr, zero, sizeof(eaddr))) {
              return eaddr;
       }

       s = socket( AF_INET, SOCK_DGRAM, 0 );
       if ( s < 0 ) {
              return NULL;
       }

       ifc.ifc_len = sizeof( buf );
       ifc.ifc_buf = buf;
       memset( buf, 0, sizeof( buf ) );

       i = ioctl( s, SIOCGIFCONF, (char *)&ifc );
       close( s );

       if( i < 0 ) {
              return NULL;
       }

       for ( i = 0; i < ifc.ifc_len; ) {
              ifr = (struct ifreq *)&ifc.ifc_buf[i];
              sa = &ifr->ifr_addr;

              if ( sa->sa_len > sizeof( ifr->ifr_addr ) ) {
                     i += sizeof( ifr->ifr_name ) + sa->sa_len;
              } else {
                     i += sizeof( *ifr );
              }

              if ( sa->sa_family != AF_LINK ) {
                     continue;
              }

              sdl = (struct sockaddr_dl *)sa;

              if ( sdl->sdl_alen == 6 ) {
                     AC_MEMCPY(eaddr,
                            (unsigned char *)sdl->sdl_data + sdl->sdl_nlen,
                            sizeof(eaddr));
                     return eaddr;
              }
       }

       return NULL;

#else
       if (memcmp(eaddr, zero, sizeof(eaddr)) == 0) {
              /* XXX - who knows? */
              lutil_entropy( eaddr, sizeof(eaddr) );
              eaddr[0] |= 0x01; /* turn it into a multicast address */
       }

       return eaddr;
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

size_t lutil_uuidstr ( char *  buf,
size_t  len 
)

Definition at line 274 of file uuid.c.

{
#ifdef HAVE_UUID_TO_STR
       uuid_t uu = {0};
       unsigned rc;
       char *s;
       size_t l;

       uuid_create( &uu, &rc );
       if ( rc != uuid_s_ok ) {
              return 0;
       }

       uuid_to_str( &uu, &s, &rc );
       if ( rc != uuid_s_ok ) {
              return 0;
       }

       l = strlen( s );
       if ( l >= len ) {
              free( s );
              return 0;
       }

       strncpy( buf, s, len );
       free( s );

       return l;

#elif defined( HAVE_UUID_GENERATE )
       uuid_t uu;

       uuid_generate( uu );
       uuid_unparse_lower( uu, buf );
       return strlen( buf );
       
#elif defined( _WIN32 )
       UUID uuid;
       unsigned char *uuidstr;
       size_t uuidlen;

       if( UuidCreate( &uuid ) != RPC_S_OK ) {
              return 0;
       }
 
       if( UuidToString( &uuid, &uuidstr ) !=  RPC_S_OK ) {
              return 0;
       }

       uuidlen = strlen( uuidstr );
       if( uuidlen >= len ) {
              return 0;
       }

       strncpy( buf, uuidstr, len );
       RpcStringFree( &uuidstr );

       return uuidlen;
 
#else
       struct timeval tv;
       UI64 tl;
       unsigned char *nl;
       unsigned short t2, t3, s1;
       unsigned long t1, tl_high;
       unsigned int rc;

       /*
        * Theoretically we should delay if seq wraps within 100usec but for now
        * systems are not fast enough to worry about it.
        */
       static int inited = 0;
       static unsigned short seq;
       
       if (!inited) {
              lutil_entropy( (unsigned char *) &seq, sizeof(seq) );
              inited++;
       }

#ifdef HAVE_GETTIMEOFDAY
       gettimeofday( &tv, 0 );
#else
       time( &tv.tv_sec );
       tv.tv_usec = 0;
#endif

       tl = mul64ll(tv.tv_sec, 10000000UL);
       set_add64l(tl, tv.tv_usec * 10UL);
       set_add64(tl, UUID_TPLUS);

       nl = lutil_eaddr();

       t1 = low32(tl);                           /* time_low */
       tl_high = high32(tl);
       t2 = tl_high & 0xffff;             /* time_mid */
       t3 = ((tl_high >> 16) & 0x0fff) | 0x1000; /* time_hi_and_version */
       s1 = ( ++seq & 0x1fff ) | 0x8000;         /* clock_seq_and_reserved */

       rc = snprintf( buf, len,
              "%08lx-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
              t1, (unsigned) t2, (unsigned) t3, (unsigned) s1,
              (unsigned) nl[0], (unsigned) nl[1],
              (unsigned) nl[2], (unsigned) nl[3],
              (unsigned) nl[4], (unsigned) nl[5] );

       return rc < len ? rc : 0;
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

int lutil_uuidstr_from_normalized ( char *  uuid,
size_t  uuidlen,
char *  buf,
size_t  buflen 
)

Definition at line 384 of file uuid.c.

{
       unsigned char nibble;
       int i, d = 0;

       assert( uuid != NULL );
       assert( buf != NULL );

       if ( uuidlen != 16 ) return -1;
       if ( buflen < 36 ) return -1;

       for ( i = 0; i < 16; i++ ) {
              if ( i == 4 || i == 6 || i == 8 || i == 10 ) {
                     buf[(i<<1)+d] = '-';
                     d += 1;
              }

              nibble = (uuid[i] >> 4) & 0xF;
              if ( nibble < 10 ) {
                     buf[(i<<1)+d] = nibble + '0';
              } else {
                     buf[(i<<1)+d] = nibble - 10 + 'a';
              }

              nibble = (uuid[i]) & 0xF;
              if ( nibble < 10 ) {
                     buf[(i<<1)+d+1] = nibble + '0';
              } else {
                     buf[(i<<1)+d+1] = nibble - 10 + 'a';
              }
       }

       if ( buflen > 36 ) buf[36] = '\0';
       return 36;
}

Here is the caller graph for this function:

static UI64 mul64ll ( unsigned long  i1,
unsigned long  i2 
) [static]

Definition at line 226 of file uuid.c.

{
       const unsigned int high1 = (i1 >> 16), low1 = (i1 & 0xffff);
       const unsigned int high2 = (i2 >> 16), low2 = (i2 & 0xffff);

       UI64 res;
       unsigned long tmp;

       res.high = (unsigned long) high1 * high2;
       res.low        = (unsigned long) low1      * low2;

       tmp = (unsigned long) low1 * high2;
       res.high += (tmp >> 16);
       tmp = (tmp << 16) & 0xFFFFFFFFul;
       res.low = (res.low + tmp) & 0xFFFFFFFFul;
       if (res.low < tmp)
              res.high++;

       tmp = (unsigned long) low2 * high1;
       res.high += (tmp >> 16);
       tmp = (tmp << 16) & 0xFFFFFFFFul;
       res.low = (res.low + tmp) & 0xFFFFFFFFul;
       if (res.low < tmp)
              res.high++;

       return res;
}

Here is the caller graph for this function:


Variable Documentation

const UI64 UUID_TPLUS = { 0x01B21Dul, 0xD2138140ul } [static]

Definition at line 204 of file uuid.c.