]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdeModulePkg/Universal/Network/Ip4ConfigDxe/NicIp4Variable.c
SourceLevelDebugPkg/SecPeiDebugAgentLib: Restore CPU interrupt state
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Ip4ConfigDxe / NicIp4Variable.c
... / ...
CommitLineData
1/** @file\r
2 Routines used to operate the Ip4 configure variable.\r
3\r
4Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
5This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at<BR>\r
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
13**/\r
14\r
15#include "Ip4Config.h"\r
16#include "NicIp4Variable.h"\r
17\r
18BOOLEAN mIp4ConfigVariableReclaimed = FALSE;\r
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
50 (Station == 0) || !NetIp4IsUnicast (Station, Netmask)) {\r
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
62 !NetIp4IsUnicast (Gateway, Netmask))) {\r
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
80 Read the ip4 configure variable from the EFI variable.\r
81\r
82 @param Instance The IP4 CONFIG instance.\r
83\r
84 @return The IP4 configure read if it is there and is valid, otherwise NULL.\r
85\r
86**/\r
87NIC_IP4_CONFIG_INFO *\r
88Ip4ConfigReadVariable (\r
89 IN IP4_CONFIG_INSTANCE *Instance\r
90 )\r
91{\r
92 NIC_IP4_CONFIG_INFO *NicConfig;\r
93\r
94 GetVariable2 (Instance->MacString, &gEfiNicIp4ConfigVariableGuid, (VOID**)&NicConfig, NULL);\r
95 if (NicConfig != NULL) {\r
96 Ip4ConfigFixRouteTablePointer (&NicConfig->Ip4Info);\r
97 }\r
98\r
99 return NicConfig;\r
100}\r
101\r
102/**\r
103 Write the IP4 configure variable to the NVRAM. If Config\r
104 is NULL, remove the variable.\r
105\r
106 @param Instance The IP4 CONFIG instance.\r
107 @param NicConfig The IP4 configure data to write.\r
108\r
109 @retval EFI_SUCCESS The variable is written to the NVRam.\r
110 @retval Others Failed to write the variable.\r
111\r
112**/\r
113EFI_STATUS\r
114Ip4ConfigWriteVariable (\r
115 IN IP4_CONFIG_INSTANCE *Instance,\r
116 IN NIC_IP4_CONFIG_INFO *NicConfig OPTIONAL\r
117 )\r
118{\r
119 EFI_STATUS Status;\r
120\r
121 Status = gRT->SetVariable (\r
122 Instance->MacString,\r
123 &gEfiNicIp4ConfigVariableGuid,\r
124 IP4_CONFIG_VARIABLE_ATTRIBUTES,\r
125 (NicConfig == NULL) ? 0 : SIZEOF_NIC_IP4_CONFIG_INFO (NicConfig),\r
126 NicConfig\r
127 );\r
128\r
129 return Status;\r
130}\r
131\r
132/**\r
133 Check whether a NIC exist in the platform given its MAC address.\r
134\r
135 @param NicAddr The MAC address for the NIC to be checked.\r
136\r
137 @retval TRUE The NIC exist in the platform.\r
138 @retval FALSE The NIC doesn't exist in the platform.\r
139\r
140**/\r
141BOOLEAN\r
142Ip4ConfigIsNicExist (\r
143 IN NIC_ADDR *NicAddr\r
144 )\r
145{\r
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
153\r
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
167\r
168 Found = FALSE;\r
169 for (Index = 0; Index < NumberOfHandles; Index++) {\r
170 //\r
171 // Get MAC address.\r
172 //\r
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
178 }\r
179\r
180 if ((NicAddr->Len == AddrSize) && (CompareMem (NicAddr->MacAddr.Addr, MacAddr.Addr, AddrSize) == 0)) {\r
181 Found = TRUE;\r
182 goto Exit;\r
183 }\r
184 }\r
185\r
186Exit:\r
187 FreePool (HandleBuffer);\r
188 return Found;\r
189}\r
190\r
191/**\r
192 Reclaim Ip4Config Variables for NIC which has been removed from the platform.\r
193\r
194**/\r
195VOID\r
196Ip4ConfigReclaimVariable (\r
197 VOID\r
198 )\r
199{\r
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
207\r
208 //\r
209 // Check whether we need perform reclaim.\r
210 //\r
211 if (mIp4ConfigVariableReclaimed) {\r
212 return;\r
213 }\r
214 mIp4ConfigVariableReclaimed = TRUE;\r
215\r
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
229\r
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
242 }\r
243\r
244 if (EFI_ERROR (Status)) {\r
245 //\r
246 // No more variable available, finish search.\r
247 //\r
248 break;\r
249 }\r
250\r
251 //\r
252 // Check variable GUID.\r
253 //\r
254 if (!CompareGuid (&VendorGuid, &gEfiNicIp4ConfigVariableGuid)) {\r
255 continue;\r
256 }\r
257\r
258 GetVariable2 (VariableName, &gEfiNicIp4ConfigVariableGuid, (VOID**)&NicConfig, NULL);\r
259 if (NicConfig == NULL) {\r
260 break;\r
261 }\r
262\r
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
290 }\r
291\r
292 FreePool (VariableName);\r
293}\r
294\r
295/**\r
296 Fix the RouteTable pointer in an EFI_IP4_IPCONFIG_DATA structure.\r
297\r
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
300\r
301 @param ConfigData The IP4 IP configure data.\r
302\r
303**/\r
304VOID\r
305Ip4ConfigFixRouteTablePointer (\r
306 IN OUT EFI_IP4_IPCONFIG_DATA *ConfigData\r
307 )\r
308{\r
309 //\r
310 // The memory used for route table entries must immediately follow\r
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