Dell serial number to UUID transform

This week’s useless exercise is about transforming between Dell serial numbers and UUIDs (in network byte order). Here’s an example showing how it works. The vv indicates direct ascii en/decoding and xx are unused constants. Those constants might mean something, but I have no idea what.

44 45 4c 4c - 33 00 - 10 34 - 80 36 - c4 c0 4f 32 33 4a
 D  E  L  L   vv xx - xx vv   xx vv   || xx xx vv vv vv
                                      ||
            +---<---- AND 0x7f ---<---++
            +--->----  OR 0x80 --->---++
            |
            D  3          4       6             2  3  J

Doing the en/decoding in Python:

import binascii

def decodeuuid(uuid):
    data = binascii.unhexlify(uuid.replace('-',''))
    assert len(data) == 16
    return ''.join([
        chr(ord(data[10]) & 0x7f),
        data[4],
        data[7],
        data[9],
        data[13:]   
    ])

def encodeserial(serial):
    assert len(serial) == 7
    return binascii.hexlify('DELL%c%c%c%c%c%c%c%c%c%c%c%c' % (
        serial[1],  
        0x00,
        0x10,
        serial[2],  
        0x80,
        serial[3],  
        ord(serial[0]) | 0x80,
        0xc0,
        0x4f,
        serial[4],  
        serial[5],  
        serial[6],  
    ))

I originally wanted to fix a blank serial number on a system. It has UUID 44454c4c-0000-1020-8020-80c04f202020, and I thought I could derive the serial from that. Of course it turns out that the serial was just spaces after decoding. This indicates that the UUID is generated from the serial number and not the other way around.

Advertisements

Fuckin’ UUIDs, how do they work?

Pretty much any computer these days has an smbios full of lovely data. The system UUID is particularly useful for identifying and keeping track of your servers. You happily assume it’s set in stone from now until the end of time, but then someone comes along and fucks up the byte order.

Here are some brilliant wtfs from a HP server:

# dmidecode -s system-uuid
43315434-3341-3255-5832-333731303946

$ curl -ks "https://ilo4/xmldata?item=All"
34543143-4133-5532-5832-333731303946

So the first three fields are in reverse byte order. Which one is the right one? Neither. Or both? Hngh!

HP’s UUID is a simple ascii encoding of the six-digit product number plus the ten-digit serial number:

$ python -c "import binascii as b
print b.hexlify('C1T43A2UX237109F');"
43315434334132555832333731303946

So dmidecode gets it right? Yeeaano. Not according to section 7.2.1 in version 2.6 of the smbios spec. In short, assumptions and poor specs have resulted in yet another mess. Dmidecode 2.10 adds the little endian parsing for smbios versions >= 2.6.

Here’s Dell doing the same thing:

# dmidecode -s system-uuid
44454c4c-4d00-105a-8058-cac04ca8474a

Note the broken UUID format in the second field in the iDRAC’s SMASH CLP:

-> show admin1/system1
OtherIdentifyingInfo={
  4c4c4544-04d-5a10-8058-cac04ca8474a,

..and enumerating the WSMan CIM_ComputerSystem class gives the same result:

<wsinst:OtherIdentifyingInfo>
  4c4c4544-04d-5a10-8058-cac04ca8474a
</wsinst:OtherIdentifyingInfo>

Dell have later added the WSMan DCIM_SystemView:smbiosGUID value that presents the uuid in network byte order (same as dmidecode <= 2.9).

Oh, and Dell’s C6100 servers come with the same UUID and serial numbers for all nodes in the enclosure. Thanks a lot, Dell.

More details on this UUID wtfery here.