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