mc: guid: Add support for non-standard encodings

There are lots of BMC implementations that violate the IPMI
specification in regard to GUID encoding and instead encode
GUIDs according to either RFC4122 or SMBIOS specifications.

This commit restores the default behavior of `mc guid` to
SMBIOS-based decoding and adds options to allow for decoding
according to IPMI or RFC4122 specifications.

It also allows to simply dump the received GUID as is
without any parsing.

It is possible that in future versions `ipmitool` will
change default behavior to 'ipmi' instead of 'smbios'.

Partially resolves ipmitool/ipmitool#25

Signed-off-by: Alexander Amelkin <alexander@amelkin.msk.ru>
This commit is contained in:
Alexander Amelkin
2018-08-01 16:34:04 +03:00
parent b44ec2fb65
commit f43a78bfc3
3 changed files with 177 additions and 51 deletions

View File

@@ -97,23 +97,58 @@ struct ipm_devid_rsp {
#define IPM_DEV_ADTL_SUPPORT_BITS (8)
/* Structure follow the IPMI V.2 Rev 1.0
* See Table 20-10 */
/* There are lots of BMC implementations that don't follow the IPMI
* specification for GUID encoding. Some send data encoded as in
* RFC4122, some follow SMBIOS specification. We support all users
* of those buggy implementations here */
typedef enum {
GUID_IPMI,
GUID_SMBIOS,
GUID_RFC4122,
GUID_DUMP
} ipmi_guid_mode_t;
#define GUID_NODE_SZ 6
/* The structure follows IPMI v2.0, rev 1.1
* See section 20.8 */
#ifdef HAVE_PRAGMA_PACK
#pragma pack(1)
#endif
struct ipmi_guid_t {
uint8_t node[6]; /* node */
uint8_t node[GUID_NODE_SZ]; /* Byte 0 is LSB */
union {
struct {
uint8_t clock_seq_low; /* clock sequence low field */
uint8_t clock_seq_hi_variant;/* clock sequence high field and variant */
uint8_t clock_seq_low; /* clock sequence low field */
uint8_t clock_seq_hi_and_rsvd;/* clock sequence high field */
};
uint16_t clock_seq_variant;
uint16_t clock_seq_and_rsvd;
};
uint16_t time_hi_and_version; /* timestamp high field and version number */
uint16_t time_mid; /* timestamp middle field */
uint32_t time_low; /* timestamp low field */
uint16_t time_hi_and_version; /* timestamp high field and version number */
uint16_t time_mid; /* timestamp middle field */
uint32_t time_low; /* timestamp low field */
} ATTRIBUTE_PACKING;
#ifdef HAVE_PRAGMA_PACK
#pragma pack(0)
#endif
/* The structure follows RFC4122 (section 4.1.2)
* and SMBIOS v3.0.0 (section 7.2.1) */
#ifdef HAVE_PRAGMA_PACK
#pragma pack(1)
#endif
struct rfc_guid_t {
uint32_t time_low; /* timestamp low field */
uint16_t time_mid; /* timestamp middle field */
uint16_t time_hi_and_version; /* timestamp high field and version number */
union {
struct {
uint8_t clock_seq_hi_and_rsvd;/* clock sequence high field */
uint8_t clock_seq_low; /* clock sequence low field */
};
uint16_t clock_seq_and_rsvd;
};
uint8_t node[GUID_NODE_SZ]; /* Byte 0 is MSB */
} ATTRIBUTE_PACKING;
#ifdef HAVE_PRAGMA_PACK
#pragma pack(0)