diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c
index 9bd4c9197a..54ef2e2783 100644
--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c
+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Driver.c
@@ -166,7 +166,8 @@ Dhcp6CreateService (
);
//
- // Generate client Duid in the format of Duid-llt.
+ // Generate client Duid: If SMBIOS system UUID is located, generate DUID in DUID-UUID format.
+ // Otherwise, in DUID-LLT format.
//
Dhcp6Srv->ClientId = Dhcp6GenerateClientId (Dhcp6Srv->Snp->Mode);
diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h
index 8fb1dfa382..84d50ad244 100644
--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h
+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Impl.h
@@ -1,7 +1,7 @@
/** @file
Dhcp6 internal data structure and definition declaration.
- Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
@@ -184,7 +184,8 @@ typedef enum {
typedef enum {
Dhcp6DuidTypeLlt = 1,
Dhcp6DuidTypeEn = 2,
- Dhcp6DuidTypeLl = 3
+ Dhcp6DuidTypeLl = 3,
+ Dhcp6DuidTypeUuid = 4
} DHCP6_DUID_TYPE;
//
diff --git a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c
index f4e7649e6c..ac0e577f5e 100644
--- a/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c
+++ b/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.c
@@ -34,6 +34,8 @@ Dhcp6GenerateClientId (
EFI_DHCP6_DUID *Duid;
EFI_TIME Time;
UINT32 Stamp;
+ EFI_GUID Uuid;
+
//
// Attempt to get client Id from variable to keep it constant.
@@ -44,17 +46,6 @@ Dhcp6GenerateClientId (
return Duid;
}
- //
- // Generate a time stamp of the seconds from 2000/1/1, assume 30day/month.
- //
- gRT->GetTime (&Time, NULL);
- Stamp = (UINT32)
- (
- (((((Time.Year - 2000) * 360 + (Time.Month - 1)) * 30 + (Time.Day - 1)) * 24 + Time.Hour) * 60 + Time.Minute) *
- 60 +
- Time.Second
- );
-
//
// The format of client identifier option:
//
@@ -68,43 +59,97 @@ Dhcp6GenerateClientId (
// . .
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
- //
- // The format of DUID-LLT:
- //
- // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- // | Duid type (1) | hardware type (16 bits) |
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- // | time (32 bits) |
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- // . .
- // . link-layer address (variable length) .
- // . .
- // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- //
//
- // sizeof (option-len + Duid-type + hardware-type + time) = 10 bytes
+ // If System UUID is found from SMBIOS Table, use DUID-UUID type.
//
- Duid = AllocateZeroPool (10 + Mode->HwAddressSize);
- if (Duid == NULL) {
- return NULL;
+ if (!EFI_ERROR (NetLibGetSystemGuid (&Uuid))) {
+ //
+ //
+ // The format of DUID-UUID:
+ //
+ // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // | DUID-Type (4) | UUID (128 bits) |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
+ // | |
+ // | |
+ // | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // | |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
+
+ //
+ // sizeof (option-len + Duid-type + UUID-size) = 20 bytes
+ //
+ Duid = AllocateZeroPool (2 + 2 + sizeof (EFI_GUID));
+ if (Duid == NULL) {
+ return NULL;
+ }
+
+ //
+ // sizeof (Duid-type + UUID-size) = 18 bytes
+ //
+ Duid->Length = (UINT16) (18);
+
+ //
+ // Set the Duid-type and copy UUID.
+ //
+ WriteUnaligned16 ((UINT16 *) (Duid->Duid), HTONS (Dhcp6DuidTypeUuid));
+
+ CopyMem (Duid->Duid + 2, &Uuid, sizeof(EFI_GUID));
+
+ } else {
+
+ //
+ //
+ // The format of DUID-LLT:
+ //
+ // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // | Duid type (1) | hardware type (16 bits) |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // | time (32 bits) |
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ // . .
+ // . link-layer address (variable length) .
+ // . .
+ // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ //
+
+ //
+ // Generate a time stamp of the seconds from 2000/1/1, assume 30day/month.
+ //
+ gRT->GetTime (&Time, NULL);
+ Stamp = (UINT32)
+ (
+ (((((Time.Year - 2000) * 360 + (Time.Month - 1)) * 30 + (Time.Day - 1)) * 24 + Time.Hour) * 60 + Time.Minute) *
+ 60 +
+ Time.Second
+ );
+
+ //
+ // sizeof (option-len + Duid-type + hardware-type + time) = 10 bytes
+ //
+ Duid = AllocateZeroPool (10 + Mode->HwAddressSize);
+ if (Duid == NULL) {
+ return NULL;
+ }
+
+ //
+ // sizeof (Duid-type + hardware-type + time) = 8 bytes
+ //
+ Duid->Length = (UINT16) (Mode->HwAddressSize + 8);
+
+ //
+ // Set the Duid-type, hardware-type, time and copy the hardware address.
+ //
+ WriteUnaligned16 ((UINT16 *) (Duid->Duid), HTONS (Dhcp6DuidTypeLlt));
+ WriteUnaligned16 ((UINT16 *) (Duid->Duid + 2), HTONS (NET_IFTYPE_ETHERNET));
+ WriteUnaligned32 ((UINT32 *) (Duid->Duid + 4), HTONL (Stamp));
+
+ CopyMem (Duid->Duid + 8, &Mode->CurrentAddress, Mode->HwAddressSize);
}
- //
- // sizeof (Duid-type + hardware-type + time) = 8 bytes
- //
- Duid->Length = (UINT16) (Mode->HwAddressSize + 8);
-
- //
- // Set the Duid-type, hardware-type, time and copy the hardware address.
- //
- WriteUnaligned16 ((UINT16 *) (Duid->Duid), HTONS (Dhcp6DuidTypeLlt));
- WriteUnaligned16 ((UINT16 *) (Duid->Duid + 2), HTONS (NET_IFTYPE_ETHERNET));
- WriteUnaligned32 ((UINT32 *) (Duid->Duid + 4), HTONL (Stamp));
-
- CopyMem (Duid->Duid + 8, &Mode->CurrentAddress, Mode->HwAddressSize);
-
Status = gRT->SetVariable (
L"ClientId",
&gEfiDhcp6ServiceBindingProtocolGuid,