]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/Ip4ConfigDxe/NicIp4Variable.c
SourceLevelDebugPkg/SecPeiDebugAgentLib: Restore CPU interrupt state
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Ip4ConfigDxe / NicIp4Variable.c
CommitLineData
b2570da8 1/** @file\r
3e8c18da 2 Routines used to operate the Ip4 configure variable.\r
b2570da8 3\r
bf4a3dbd 4Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
e5eed7d3 5This program and the accompanying materials\r
b2570da8 6are licensed and made available under the terms and conditions of the BSD License\r
402fa70f 7which accompanies this distribution. The full text of the license may be found at<BR>\r
b2570da8 8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
b2570da8 13**/\r
14\r
74df5026 15#include "Ip4Config.h"\r
b2570da8 16#include "NicIp4Variable.h"\r
17\r
74df5026 18BOOLEAN mIp4ConfigVariableReclaimed = FALSE;\r
b2570da8 19\r
20/**\r
21 Check whether the configure parameter is valid.\r
22\r
23 @param NicConfig The configure parameter to check\r
24\r
25 @return TRUE if the parameter is valid for the interface, otherwise FALSE.\r
26\r
27**/\r
28BOOLEAN\r
29Ip4ConfigIsValid (\r
30 IN NIC_IP4_CONFIG_INFO *NicConfig\r
31 )\r
32{\r
33 EFI_IP4_IPCONFIG_DATA *IpConfig;\r
34 IP4_ADDR Station;\r
35 IP4_ADDR Netmask;\r
36 IP4_ADDR Gateway;\r
37 UINT32 Index;\r
38\r
39 IpConfig = &NicConfig->Ip4Info;\r
40\r
41 if (NicConfig->Source == IP4_CONFIG_SOURCE_STATIC) {\r
42 //\r
43 // Validate that the addresses are unicast and mask\r
44 // is properly formated\r
45 //\r
46 Station = EFI_NTOHL (IpConfig->StationAddress);\r
47 Netmask = EFI_NTOHL (IpConfig->SubnetMask);\r
48\r
49 if ((Netmask == 0) || !IP4_IS_VALID_NETMASK (Netmask) ||\r
f6b7393c 50 (Station == 0) || !NetIp4IsUnicast (Station, Netmask)) {\r
b2570da8 51 return FALSE;\r
52 }\r
53\r
54 //\r
55 // Validate that the next hops are on the connected network\r
56 // or that is a direct route (Gateway == 0).\r
57 //\r
58 for (Index = 0; Index < IpConfig->RouteTableSize; Index++) {\r
59 Gateway = EFI_NTOHL (IpConfig->RouteTable[Index].GatewayAddress);\r
60\r
61 if ((Gateway != 0) && (!IP4_NET_EQUAL (Station, Gateway, Netmask) ||\r
f6b7393c 62 !NetIp4IsUnicast (Gateway, Netmask))) {\r
b2570da8 63 return FALSE;\r
64 }\r
65 }\r
66\r
67 return TRUE;\r
68 }\r
69\r
70 //\r
71 // return false if it is an unkown configure source. Valid\r
72 // sources are static and dhcp.\r
73 //\r
74 return (BOOLEAN) (NicConfig->Source == IP4_CONFIG_SOURCE_DHCP);\r
75}\r
76\r
77\r
78\r
79/**\r
7bce0c5a 80 Read the ip4 configure variable from the EFI variable.\r
b2570da8 81\r
74df5026 82 @param Instance The IP4 CONFIG instance.\r
b2570da8 83\r
74df5026 84 @return The IP4 configure read if it is there and is valid, otherwise NULL.\r
b2570da8 85\r
86**/\r
74df5026 87NIC_IP4_CONFIG_INFO *\r
b2570da8 88Ip4ConfigReadVariable (\r
74df5026 89 IN IP4_CONFIG_INSTANCE *Instance\r
b2570da8 90 )\r
91{\r
74df5026 92 NIC_IP4_CONFIG_INFO *NicConfig;\r
b2570da8 93\r
f01b91ae 94 GetVariable2 (Instance->MacString, &gEfiNicIp4ConfigVariableGuid, (VOID**)&NicConfig, NULL);\r
74df5026 95 if (NicConfig != NULL) {\r
96 Ip4ConfigFixRouteTablePointer (&NicConfig->Ip4Info);\r
b2570da8 97 }\r
98\r
74df5026 99 return NicConfig;\r
b2570da8 100}\r
101\r
b2570da8 102/**\r
103 Write the IP4 configure variable to the NVRAM. If Config\r
104 is NULL, remove the variable.\r
105\r
74df5026 106 @param Instance The IP4 CONFIG instance.\r
107 @param NicConfig The IP4 configure data to write.\r
b2570da8 108\r
74df5026 109 @retval EFI_SUCCESS The variable is written to the NVRam.\r
b2570da8 110 @retval Others Failed to write the variable.\r
111\r
112**/\r
113EFI_STATUS\r
114Ip4ConfigWriteVariable (\r
74df5026 115 IN IP4_CONFIG_INSTANCE *Instance,\r
116 IN NIC_IP4_CONFIG_INFO *NicConfig OPTIONAL\r
b2570da8 117 )\r
118{\r
74df5026 119 EFI_STATUS Status;\r
b2570da8 120\r
121 Status = gRT->SetVariable (\r
74df5026 122 Instance->MacString,\r
b2570da8 123 &gEfiNicIp4ConfigVariableGuid,\r
124 IP4_CONFIG_VARIABLE_ATTRIBUTES,\r
74df5026 125 (NicConfig == NULL) ? 0 : SIZEOF_NIC_IP4_CONFIG_INFO (NicConfig),\r
126 NicConfig\r
b2570da8 127 );\r
128\r
129 return Status;\r
130}\r
131\r
b2570da8 132/**\r
74df5026 133 Check whether a NIC exist in the platform given its MAC address.\r
b2570da8 134\r
74df5026 135 @param NicAddr The MAC address for the NIC to be checked.\r
b2570da8 136\r
74df5026 137 @retval TRUE The NIC exist in the platform.\r
138 @retval FALSE The NIC doesn't exist in the platform.\r
b2570da8 139\r
140**/\r
74df5026 141BOOLEAN\r
142Ip4ConfigIsNicExist (\r
b2570da8 143 IN NIC_ADDR *NicAddr\r
144 )\r
145{\r
74df5026 146 EFI_STATUS Status;\r
147 EFI_HANDLE *HandleBuffer;\r
148 UINTN NumberOfHandles;\r
149 UINTN Index;\r
150 BOOLEAN Found;\r
151 UINTN AddrSize;\r
152 EFI_MAC_ADDRESS MacAddr;\r
b2570da8 153\r
74df5026 154 //\r
155 // Locate Service Binding handles.\r
156 //\r
157 Status = gBS->LocateHandleBuffer (\r
158 ByProtocol,\r
159 &gEfiManagedNetworkServiceBindingProtocolGuid,\r
160 NULL,\r
161 &NumberOfHandles,\r
162 &HandleBuffer\r
163 );\r
164 if (EFI_ERROR (Status)) {\r
165 return FALSE;\r
166 }\r
b2570da8 167\r
74df5026 168 Found = FALSE;\r
169 for (Index = 0; Index < NumberOfHandles; Index++) {\r
b2570da8 170 //\r
74df5026 171 // Get MAC address.\r
b2570da8 172 //\r
74df5026 173 AddrSize = 0;\r
174 Status = NetLibGetMacAddress (HandleBuffer[Index], &MacAddr, &AddrSize);\r
175 if (EFI_ERROR (Status)) {\r
176 Found = FALSE;\r
177 goto Exit;\r
b2570da8 178 }\r
179\r
74df5026 180 if ((NicAddr->Len == AddrSize) && (CompareMem (NicAddr->MacAddr.Addr, MacAddr.Addr, AddrSize) == 0)) {\r
181 Found = TRUE;\r
182 goto Exit;\r
183 }\r
b2570da8 184 }\r
185\r
74df5026 186Exit:\r
187 FreePool (HandleBuffer);\r
188 return Found;\r
b2570da8 189}\r
190\r
b2570da8 191/**\r
74df5026 192 Reclaim Ip4Config Variables for NIC which has been removed from the platform.\r
b2570da8 193\r
194**/\r
74df5026 195VOID\r
196Ip4ConfigReclaimVariable (\r
197 VOID\r
b2570da8 198 )\r
199{\r
74df5026 200 EFI_STATUS Status;\r
201 UINTN VariableNameSize;\r
202 CHAR16 *VariableName;\r
203 CHAR16 *CurrentVariableName;\r
204 EFI_GUID VendorGuid;\r
205 UINTN VariableNameBufferSize;\r
206 NIC_IP4_CONFIG_INFO *NicConfig;\r
b2570da8 207\r
208 //\r
74df5026 209 // Check whether we need perform reclaim.\r
b2570da8 210 //\r
74df5026 211 if (mIp4ConfigVariableReclaimed) {\r
212 return;\r
213 }\r
214 mIp4ConfigVariableReclaimed = TRUE;\r
b2570da8 215\r
74df5026 216 //\r
217 // Get all Ip4Config Variable.\r
218 //\r
219 VariableNameSize = sizeof (CHAR16);\r
220 VariableName = AllocateZeroPool (VariableNameSize);\r
221 VariableNameBufferSize = VariableNameSize;\r
222\r
223 while (TRUE) {\r
224 Status = gRT->GetNextVariableName (\r
225 &VariableNameSize,\r
226 VariableName,\r
227 &VendorGuid\r
228 );\r
b2570da8 229\r
74df5026 230Check:\r
231 if (Status == EFI_BUFFER_TOO_SMALL) {\r
232 VariableName = ReallocatePool (VariableNameBufferSize, VariableNameSize, VariableName);\r
233 VariableNameBufferSize = VariableNameSize;\r
234 //\r
235 // Try again using the new buffer.\r
236 //\r
237 Status = gRT->GetNextVariableName (\r
238 &VariableNameSize,\r
239 VariableName,\r
240 &VendorGuid\r
241 );\r
b2570da8 242 }\r
243\r
74df5026 244 if (EFI_ERROR (Status)) {\r
245 //\r
246 // No more variable available, finish search.\r
247 //\r
248 break;\r
b2570da8 249 }\r
250\r
251 //\r
74df5026 252 // Check variable GUID.\r
b2570da8 253 //\r
74df5026 254 if (!CompareGuid (&VendorGuid, &gEfiNicIp4ConfigVariableGuid)) {\r
255 continue;\r
b2570da8 256 }\r
257\r
f01b91ae 258 GetVariable2 (VariableName, &gEfiNicIp4ConfigVariableGuid, (VOID**)&NicConfig, NULL);\r
74df5026 259 if (NicConfig == NULL) {\r
260 break;\r
b2570da8 261 }\r
262\r
74df5026 263 if (!Ip4ConfigIsNicExist (&NicConfig->NicAddr)) {\r
264 //\r
265 // No NIC found for this Ip4Config variable, remove it.\r
266 // Since we are in loop of GetNextVariableName(), we need move on to next\r
267 // Variable first and then delete current Variable.\r
268 //\r
269 CurrentVariableName = AllocateCopyPool (VariableNameSize, VariableName);\r
270 Status = gRT->GetNextVariableName (\r
271 &VariableNameSize,\r
272 VariableName,\r
273 &VendorGuid\r
274 );\r
275\r
276 gRT->SetVariable (\r
277 CurrentVariableName,\r
278 &gEfiNicIp4ConfigVariableGuid,\r
279 IP4_CONFIG_VARIABLE_ATTRIBUTES,\r
280 0,\r
281 NULL\r
282 );\r
283 FreePool (CurrentVariableName);\r
284\r
285 //\r
286 // We already get next variable, go to check it.\r
287 //\r
288 goto Check;\r
289 }\r
b2570da8 290 }\r
291\r
74df5026 292 FreePool (VariableName);\r
b2570da8 293}\r
7659d0c9 294\r
402fa70f 295/**\r
74df5026 296 Fix the RouteTable pointer in an EFI_IP4_IPCONFIG_DATA structure.\r
297\r
402fa70f 298 The pointer is set to be immediately follow the ConfigData if there're entries\r
299 in the RouteTable. Otherwise it is set to NULL.\r
74df5026 300\r
402fa70f 301 @param ConfigData The IP4 IP configure data.\r
302\r
303**/\r
7659d0c9 304VOID\r
305Ip4ConfigFixRouteTablePointer (\r
c8d8f1e3 306 IN OUT EFI_IP4_IPCONFIG_DATA *ConfigData\r
7659d0c9 307 )\r
308{\r
309 //\r
74df5026 310 // The memory used for route table entries must immediately follow\r
7659d0c9 311 // the ConfigData and be not packed.\r
312 //\r
313 if (ConfigData->RouteTableSize > 0) {\r
314 ConfigData->RouteTable = (EFI_IP4_ROUTE_TABLE *) (ConfigData + 1);\r
315 } else {\r
316 ConfigData->RouteTable = NULL;\r
317 }\r
318}\r
319\r