--*/\r
{\r
EFI_PXE_BASE_CODE_MODE *PxebcMode;\r
+ EFI_STATUS StatCode;\r
PXE_BASECODE_DEVICE *Private;\r
+ UINT32 SubnetMask;\r
\r
//\r
// Lock the instance data and make sure started\r
//\r
+ StatCode = EFI_SUCCESS;\r
\r
if (This == NULL) {\r
DEBUG ((EFI_D_ERROR, "BC *This pointer == NULL"));\r
\r
if (This->Mode == NULL || !This->Mode->Started) {\r
DEBUG ((EFI_D_ERROR, "BC was not started."));\r
- EfiReleaseLock (&Private->Lock);\r
- return EFI_NOT_STARTED;\r
+ StatCode = EFI_NOT_STARTED;\r
+ goto RELEASE_LOCK;\r
}\r
\r
PxebcMode = Private->EfiBc.Mode;\r
\r
- if (StationIpPtr != NULL) {\r
- CopyMem (&PxebcMode->StationIp, StationIpPtr, sizeof (EFI_IP_ADDRESS));\r
- Private->GoodStationIp = TRUE;\r
+ if (!Private->GoodStationIp && ((StationIpPtr == NULL) || (SubnetMaskPtr == NULL))) {\r
+ //\r
+ // It's not allowed to only set one of the two addresses while there isn't a previous\r
+ // GOOD address configuration.\r
+ //\r
+ StatCode = EFI_INVALID_PARAMETER;\r
+ goto RELEASE_LOCK;\r
}\r
\r
if (SubnetMaskPtr != NULL) {\r
- CopyMem (&PxebcMode->SubnetMask, SubnetMaskPtr, sizeof (EFI_IP_ADDRESS));\r
+ SubnetMask = SubnetMaskPtr->Addr[0];\r
+\r
+ if (SubnetMask & (SubnetMask + 1)) {\r
+ //\r
+ // the subnet mask is valid if it's with leading continuous 1 bits.\r
+ //\r
+ StatCode = EFI_INVALID_PARAMETER;\r
+ goto RELEASE_LOCK;\r
+ }\r
+ } else {\r
+ SubnetMaskPtr = &PxebcMode->SubnetMask;\r
+ SubnetMask = SubnetMaskPtr->Addr[0];\r
}\r
+\r
+ if (StationIpPtr == NULL) {\r
+ StationIpPtr = &PxebcMode->StationIp;\r
+ }\r
+\r
+ if (!IS_INADDR_UNICAST (StationIpPtr) || \r
+ ((StationIpPtr->Addr[0] | SubnetMask) == BROADCAST_IPv4)) {\r
+ //\r
+ // The station IP is not a unicast address.\r
+ //\r
+ StatCode = EFI_INVALID_PARAMETER;\r
+ goto RELEASE_LOCK;\r
+ }\r
+\r
+ CopyMem (&PxebcMode->StationIp, StationIpPtr, sizeof (EFI_IP_ADDRESS));\r
+ CopyMem (&PxebcMode->SubnetMask, SubnetMaskPtr, sizeof (EFI_IP_ADDRESS));\r
+\r
+ Private->GoodStationIp = TRUE;\r
+\r
+RELEASE_LOCK:\r
//\r
// Unlock the instance data\r
//\r
EfiReleaseLock (&Private->Lock);\r
\r
- return EFI_SUCCESS;\r
+ return StatCode;\r
}\r
\r
EFI_DRIVER_BINDING_PROTOCOL gPxeBcDriverBinding = {\r