]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/Ip4ConfigDxe/NicIp4Variable.c
Remove the unnecessary include, such as PiDxe.h, PiPei.h, Base.h and Uefi.h in header...
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Ip4ConfigDxe / NicIp4Variable.c
CommitLineData
b2570da8 1/** @file\r
2\r
7659d0c9 3Copyright (c) 2006 - 2008, Intel Corporation \r
b2570da8 4All rights reserved. This program and the accompanying materials\r
5are licensed and made available under the terms and conditions of the BSD License\r
6which accompanies this distribution. The full text of the license may be found at\r
7http://opensource.org/licenses/bsd-license.php\r
8\r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11\r
12Module Name:\r
13\r
14 NicIp4Variable.c\r
15\r
16Abstract:\r
17\r
18 Routines used to operate the Ip4 configure variable\r
19\r
20\r
21**/\r
22\r
19034421 23#include <Uefi.h>\r
b2570da8 24\r
25#include <Library/NetLib.h>\r
26#include <Library/DebugLib.h>\r
27#include <Library/BaseMemoryLib.h>\r
28#include <Library/MemoryAllocationLib.h>\r
29#include <Library/UefiBootServicesTableLib.h>\r
30#include <Library/UefiRuntimeServicesTableLib.h>\r
31\r
32#include "NicIp4Variable.h"\r
33\r
34\r
35/**\r
36 Check whether the configure parameter is valid.\r
37\r
38 @param NicConfig The configure parameter to check\r
39\r
40 @return TRUE if the parameter is valid for the interface, otherwise FALSE.\r
41\r
42**/\r
43BOOLEAN\r
44Ip4ConfigIsValid (\r
45 IN NIC_IP4_CONFIG_INFO *NicConfig\r
46 )\r
47{\r
48 EFI_IP4_IPCONFIG_DATA *IpConfig;\r
49 IP4_ADDR Station;\r
50 IP4_ADDR Netmask;\r
51 IP4_ADDR Gateway;\r
52 UINT32 Index;\r
53\r
54 IpConfig = &NicConfig->Ip4Info;\r
55\r
56 if (NicConfig->Source == IP4_CONFIG_SOURCE_STATIC) {\r
57 //\r
58 // Validate that the addresses are unicast and mask\r
59 // is properly formated\r
60 //\r
61 Station = EFI_NTOHL (IpConfig->StationAddress);\r
62 Netmask = EFI_NTOHL (IpConfig->SubnetMask);\r
63\r
64 if ((Netmask == 0) || !IP4_IS_VALID_NETMASK (Netmask) ||\r
65 (Station == 0) || !Ip4IsUnicast (Station, Netmask)) {\r
66 return FALSE;\r
67 }\r
68\r
69 //\r
70 // Validate that the next hops are on the connected network\r
71 // or that is a direct route (Gateway == 0).\r
72 //\r
73 for (Index = 0; Index < IpConfig->RouteTableSize; Index++) {\r
74 Gateway = EFI_NTOHL (IpConfig->RouteTable[Index].GatewayAddress);\r
75\r
76 if ((Gateway != 0) && (!IP4_NET_EQUAL (Station, Gateway, Netmask) ||\r
77 !Ip4IsUnicast (Gateway, Netmask))) {\r
78 return FALSE;\r
79 }\r
80 }\r
81\r
82 return TRUE;\r
83 }\r
84\r
85 //\r
86 // return false if it is an unkown configure source. Valid\r
87 // sources are static and dhcp.\r
88 //\r
89 return (BOOLEAN) (NicConfig->Source == IP4_CONFIG_SOURCE_DHCP);\r
90}\r
91\r
92\r
93\r
94/**\r
7bce0c5a 95 Read the ip4 configure variable from the EFI variable.\r
b2570da8 96\r
97 None\r
98\r
99 @return The IP4 configure read if it is there and is valid, otherwise NULL\r
100\r
101**/\r
102IP4_CONFIG_VARIABLE *\r
103Ip4ConfigReadVariable (\r
104 VOID\r
105 )\r
106{\r
107 IP4_CONFIG_VARIABLE *Variable;\r
108 EFI_STATUS Status;\r
109 UINTN Size;\r
110 UINT16 CheckSum;\r
111\r
112 //\r
113 // Get the size of variable, then allocate a buffer to read the variable.\r
114 //\r
115 Size = 0;\r
116 Variable = NULL;\r
117 Status = gRT->GetVariable (\r
118 EFI_NIC_IP4_CONFIG_VARIABLE,\r
119 &gEfiNicIp4ConfigVariableGuid,\r
120 NULL,\r
121 &Size,\r
122 NULL\r
123 );\r
124\r
125 if (Status != EFI_BUFFER_TOO_SMALL) {\r
126 return NULL;\r
127 }\r
128\r
129 if (Size < sizeof (IP4_CONFIG_VARIABLE)) {\r
130 goto REMOVE_VARIABLE;\r
131 }\r
132\r
e48e37fc 133 Variable = AllocatePool (Size);\r
b2570da8 134\r
135 if (Variable == NULL) {\r
136 return NULL;\r
137 }\r
138\r
139 Status = gRT->GetVariable (\r
140 EFI_NIC_IP4_CONFIG_VARIABLE,\r
141 &gEfiNicIp4ConfigVariableGuid,\r
142 NULL,\r
143 &Size,\r
144 Variable\r
145 );\r
146\r
147 if (EFI_ERROR (Status)) {\r
148 goto ON_ERROR;\r
149 }\r
150\r
151 //\r
152 // Verify the checksum, variable size and count\r
153 //\r
4eb65aff 154 CheckSum = (UINT16) (~NetblockChecksum ((UINT8 *) Variable, (UINT32)Size));\r
b2570da8 155\r
156 if ((CheckSum != 0) || (Size != Variable->Len)) {\r
157 goto REMOVE_VARIABLE;\r
158 }\r
159\r
160 if ((Variable->Count < 1) || (Variable->Count > MAX_IP4_CONFIG_IN_VARIABLE)) {\r
161 goto REMOVE_VARIABLE;\r
162 }\r
163\r
164 return Variable;\r
165\r
166REMOVE_VARIABLE:\r
167 Ip4ConfigWriteVariable (NULL);\r
168\r
169ON_ERROR:\r
170 if (Variable != NULL) {\r
e48e37fc 171 gBS->FreePool (Variable);\r
b2570da8 172 }\r
173\r
174 return NULL;\r
175}\r
176\r
177\r
178/**\r
179 Write the IP4 configure variable to the NVRAM. If Config\r
180 is NULL, remove the variable.\r
181\r
182 @param Config The IP4 configure data to write\r
183\r
184 @retval EFI_SUCCESS The variable is written to the NVRam\r
185 @retval Others Failed to write the variable.\r
186\r
187**/\r
188EFI_STATUS\r
189Ip4ConfigWriteVariable (\r
7bce0c5a 190 IN IP4_CONFIG_VARIABLE *Config OPTIONAL\r
b2570da8 191 )\r
192{\r
193 EFI_STATUS Status;\r
194\r
195 Status = gRT->SetVariable (\r
196 EFI_NIC_IP4_CONFIG_VARIABLE,\r
197 &gEfiNicIp4ConfigVariableGuid,\r
198 IP4_CONFIG_VARIABLE_ATTRIBUTES,\r
199 (Config == NULL) ? 0 : Config->Len,\r
200 Config\r
201 );\r
202\r
203 return Status;\r
204}\r
205\r
206\r
207/**\r
208 Locate the IP4 configure parameters from the variable.If a\r
209 configuration is found, copy it to a newly allocated block\r
210 of memory to avoid the alignment problem. Caller should\r
211 release the memory after use.\r
212\r
213 @param Variable The IP4 configure variable to search in\r
214 @param NicAddr The interface address to check\r
215\r
216 @return The point to the NIC's IP4 configure info if it is found\r
217 @return in the IP4 variable, otherwise NULL.\r
218\r
219**/\r
220NIC_IP4_CONFIG_INFO *\r
221Ip4ConfigFindNicVariable (\r
222 IN IP4_CONFIG_VARIABLE *Variable,\r
223 IN NIC_ADDR *NicAddr\r
224 )\r
225{\r
226 NIC_IP4_CONFIG_INFO Temp;\r
227 NIC_IP4_CONFIG_INFO *Config;\r
228 UINT32 Index;\r
229 UINT8 *Cur;\r
230 UINT32 Len;\r
231\r
232 Cur = (UINT8*)&Variable->ConfigInfo;\r
233\r
234 for (Index = 0; Index < Variable->Count; Index++) {\r
235 //\r
236 // Copy the data to Temp to avoid the alignment problems\r
237 //\r
e48e37fc 238 CopyMem (&Temp, Cur, sizeof (NIC_IP4_CONFIG_INFO));\r
b2570da8 239 Len = SIZEOF_NIC_IP4_CONFIG_INFO (&Temp);\r
240\r
241 //\r
242 // Found the matching configuration parameters, allocate\r
243 // a block of memory then copy it out.\r
244 //\r
245 if (NIC_ADDR_EQUAL (&Temp.NicAddr, NicAddr)) {\r
e48e37fc 246 Config = AllocatePool (Len);\r
b2570da8 247\r
248 if (Config == NULL) {\r
249 return NULL;\r
250 }\r
251\r
e48e37fc 252 CopyMem (Config, Cur, Len);\r
7659d0c9 253 Ip4ConfigFixRouteTablePointer (&Config->Ip4Info);\r
b2570da8 254 return Config;\r
255 }\r
256\r
257 Cur += Len;\r
258 }\r
259\r
260 return NULL;\r
261}\r
262\r
263\r
264/**\r
265 Modify the configuration parameter for the NIC in the variable.\r
266 If Config is NULL, old configuration will be remove from the new\r
267 variable. Otherwise, append it or replace the old one.\r
268\r
269 @param Variable The IP4 variable to change\r
270 @param NicAddr The interface to search\r
271 @param Config The new configuration parameter (NULL to remove the old)\r
272\r
273 @return The new IP4_CONFIG_VARIABLE variable if the new variable has at\r
274 @return least one NIC configure and no EFI_OUT_OF_RESOURCES failure.\r
275 @return Return NULL either because failed to locate memory for new variable\r
276 @return or the only NIC configure is removed from the Variable.\r
277\r
278**/\r
279IP4_CONFIG_VARIABLE *\r
280Ip4ConfigModifyVariable (\r
281 IN IP4_CONFIG_VARIABLE *Variable, OPTIONAL\r
282 IN NIC_ADDR *NicAddr,\r
283 IN NIC_IP4_CONFIG_INFO *Config OPTIONAL\r
284 )\r
285{\r
286 NIC_IP4_CONFIG_INFO Temp;\r
287 NIC_IP4_CONFIG_INFO *Old;\r
288 IP4_CONFIG_VARIABLE *NewVar;\r
289 UINT32 Len;\r
290 UINT32 TotalLen;\r
291 UINT32 Count;\r
292 UINT8 *Next;\r
293 UINT8 *Cur;\r
294 UINT32 Index;\r
295\r
296 ASSERT ((Variable != NULL) || (Config != NULL));\r
297\r
298 //\r
299 // Compute the total length\r
300 //\r
301 if (Variable != NULL) {\r
302 //\r
303 // Variable != NULL, then Config can be NULL or not. and so is\r
304 // the Old. If old configure exists, it is removed from the\r
305 // Variable. New configure is append to the variable.\r
306 //\r
307 //\r
308 Count = Variable->Count;\r
309 Cur = (UINT8 *)&Variable->ConfigInfo;\r
310 TotalLen = Variable->Len;\r
311\r
312 Old = Ip4ConfigFindNicVariable (Variable, NicAddr);\r
313\r
314 if (Old != NULL) {\r
315 TotalLen -= SIZEOF_NIC_IP4_CONFIG_INFO (Old);\r
e48e37fc 316 gBS->FreePool (Old);\r
b2570da8 317 }\r
318\r
319 if (Config != NULL) {\r
320 TotalLen += SIZEOF_NIC_IP4_CONFIG_INFO (Config);\r
321 }\r
322\r
323 //\r
324 // Return NULL if the only NIC_IP4_CONFIG_INFO is being removed.\r
325 //\r
326 if (TotalLen < sizeof (IP4_CONFIG_VARIABLE)) {\r
327 return NULL;\r
328 }\r
329\r
330 } else {\r
331 //\r
332 // Variable == NULL and Config != NULL, Create a new variable with\r
333 // this NIC configure.\r
334 //\r
335 Count = 0;\r
336 Cur = NULL;\r
337 TotalLen = sizeof (IP4_CONFIG_VARIABLE) - sizeof (NIC_IP4_CONFIG_INFO)\r
338 + SIZEOF_NIC_IP4_CONFIG_INFO (Config);\r
339 }\r
340\r
341 ASSERT (TotalLen >= sizeof (IP4_CONFIG_VARIABLE));\r
342\r
e48e37fc 343 NewVar = AllocateZeroPool (TotalLen);\r
b2570da8 344\r
345 if (NewVar == NULL) {\r
346 return NULL;\r
347 }\r
348\r
349 NewVar->Len = TotalLen;\r
350\r
351 //\r
352 // Copy the other configure parameters from the old variable\r
353 //\r
354 Next = (UINT8 *)&NewVar->ConfigInfo;\r
355\r
356 for (Index = 0; Index < Count; Index++) {\r
e48e37fc 357 CopyMem (&Temp, Cur, sizeof (NIC_IP4_CONFIG_INFO));\r
b2570da8 358 Len = SIZEOF_NIC_IP4_CONFIG_INFO (&Temp);\r
359\r
360 if (!NIC_ADDR_EQUAL (&Temp.NicAddr, NicAddr)) {\r
e48e37fc 361 CopyMem (Next, Cur, Len);\r
b2570da8 362 Next += Len;\r
363 NewVar->Count++;\r
364 }\r
365\r
366 Cur += Len;\r
367 }\r
368\r
369 //\r
370 // Append the new configure if it isn't NULL.\r
371 //\r
372 Len = 0;\r
373\r
374 if (Config != NULL) {\r
375 Len = SIZEOF_NIC_IP4_CONFIG_INFO (Config);\r
376\r
e48e37fc 377 CopyMem (Next, Config, Len);\r
b2570da8 378 NewVar->Count++;\r
379 }\r
380\r
381 ASSERT (Next + Len == (UINT8 *) NewVar + TotalLen);\r
382\r
4eb65aff 383 NewVar->CheckSum = (UINT16) (~NetblockChecksum ((UINT8 *) NewVar, TotalLen));\r
b2570da8 384 return NewVar;\r
385}\r
7659d0c9 386\r
387VOID\r
388Ip4ConfigFixRouteTablePointer (\r
389 IN EFI_IP4_IPCONFIG_DATA *ConfigData\r
390 )\r
391{\r
392 //\r
393 // The memory used for route table entries must immediately follow \r
394 // the ConfigData and be not packed.\r
395 //\r
396 if (ConfigData->RouteTableSize > 0) {\r
397 ConfigData->RouteTable = (EFI_IP4_ROUTE_TABLE *) (ConfigData + 1);\r
398 } else {\r
399 ConfigData->RouteTable = NULL;\r
400 }\r
401}\r
402\r