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