2 Routines used to operate the Ip4 configure variable
4 Copyright (c) 2006 - 2008, Intel Corporation.<BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at<BR>
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include <Library/NetLib.h>
18 #include <Library/DebugLib.h>
19 #include <Library/BaseMemoryLib.h>
20 #include <Library/MemoryAllocationLib.h>
21 #include <Library/UefiBootServicesTableLib.h>
22 #include <Library/UefiRuntimeServicesTableLib.h>
24 #include "NicIp4Variable.h"
28 Check whether the configure parameter is valid.
30 @param NicConfig The configure parameter to check
32 @return TRUE if the parameter is valid for the interface, otherwise FALSE.
37 IN NIC_IP4_CONFIG_INFO
*NicConfig
40 EFI_IP4_IPCONFIG_DATA
*IpConfig
;
46 IpConfig
= &NicConfig
->Ip4Info
;
48 if (NicConfig
->Source
== IP4_CONFIG_SOURCE_STATIC
) {
50 // Validate that the addresses are unicast and mask
51 // is properly formated
53 Station
= EFI_NTOHL (IpConfig
->StationAddress
);
54 Netmask
= EFI_NTOHL (IpConfig
->SubnetMask
);
56 if ((Netmask
== 0) || !IP4_IS_VALID_NETMASK (Netmask
) ||
57 (Station
== 0) || !Ip4IsUnicast (Station
, Netmask
)) {
62 // Validate that the next hops are on the connected network
63 // or that is a direct route (Gateway == 0).
65 for (Index
= 0; Index
< IpConfig
->RouteTableSize
; Index
++) {
66 Gateway
= EFI_NTOHL (IpConfig
->RouteTable
[Index
].GatewayAddress
);
68 if ((Gateway
!= 0) && (!IP4_NET_EQUAL (Station
, Gateway
, Netmask
) ||
69 !Ip4IsUnicast (Gateway
, Netmask
))) {
78 // return false if it is an unkown configure source. Valid
79 // sources are static and dhcp.
81 return (BOOLEAN
) (NicConfig
->Source
== IP4_CONFIG_SOURCE_DHCP
);
87 Read the ip4 configure variable from the EFI variable.
91 @return The IP4 configure read if it is there and is valid, otherwise NULL
95 Ip4ConfigReadVariable (
99 IP4_CONFIG_VARIABLE
*Variable
;
105 // Get the size of variable, then allocate a buffer to read the variable.
109 Status
= gRT
->GetVariable (
110 EFI_NIC_IP4_CONFIG_VARIABLE
,
111 &gEfiNicIp4ConfigVariableGuid
,
117 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
121 if (Size
< sizeof (IP4_CONFIG_VARIABLE
)) {
122 goto REMOVE_VARIABLE
;
125 Variable
= AllocatePool (Size
);
127 if (Variable
== NULL
) {
131 Status
= gRT
->GetVariable (
132 EFI_NIC_IP4_CONFIG_VARIABLE
,
133 &gEfiNicIp4ConfigVariableGuid
,
139 if (EFI_ERROR (Status
)) {
144 // Verify the checksum, variable size and count
146 CheckSum
= (UINT16
) (~NetblockChecksum ((UINT8
*) Variable
, (UINT32
)Size
));
148 if ((CheckSum
!= 0) || (Size
!= Variable
->Len
)) {
149 goto REMOVE_VARIABLE
;
152 if ((Variable
->Count
< 1) || (Variable
->Count
> MAX_IP4_CONFIG_IN_VARIABLE
)) {
153 goto REMOVE_VARIABLE
;
159 Ip4ConfigWriteVariable (NULL
);
162 if (Variable
!= NULL
) {
163 gBS
->FreePool (Variable
);
171 Write the IP4 configure variable to the NVRAM. If Config
172 is NULL, remove the variable.
174 @param Config The IP4 configure data to write
176 @retval EFI_SUCCESS The variable is written to the NVRam
177 @retval Others Failed to write the variable.
181 Ip4ConfigWriteVariable (
182 IN IP4_CONFIG_VARIABLE
*Config OPTIONAL
187 Status
= gRT
->SetVariable (
188 EFI_NIC_IP4_CONFIG_VARIABLE
,
189 &gEfiNicIp4ConfigVariableGuid
,
190 IP4_CONFIG_VARIABLE_ATTRIBUTES
,
191 (Config
== NULL
) ? 0 : Config
->Len
,
200 Locate the IP4 configure parameters from the variable.If a
201 configuration is found, copy it to a newly allocated block
202 of memory to avoid the alignment problem. Caller should
203 release the memory after use.
205 @param Variable The IP4 configure variable to search in
206 @param NicAddr The interface address to check
208 @return The point to the NIC's IP4 configure info if it is found
209 @return in the IP4 variable, otherwise NULL.
212 NIC_IP4_CONFIG_INFO
*
213 Ip4ConfigFindNicVariable (
214 IN IP4_CONFIG_VARIABLE
*Variable
,
218 NIC_IP4_CONFIG_INFO Temp
;
219 NIC_IP4_CONFIG_INFO
*Config
;
224 Cur
= (UINT8
*)&Variable
->ConfigInfo
;
226 for (Index
= 0; Index
< Variable
->Count
; Index
++) {
228 // Copy the data to Temp to avoid the alignment problems
230 CopyMem (&Temp
, Cur
, sizeof (NIC_IP4_CONFIG_INFO
));
231 Len
= SIZEOF_NIC_IP4_CONFIG_INFO (&Temp
);
234 // Found the matching configuration parameters, allocate
235 // a block of memory then copy it out.
237 if (NIC_ADDR_EQUAL (&Temp
.NicAddr
, NicAddr
)) {
238 Config
= AllocatePool (Len
);
240 if (Config
== NULL
) {
244 CopyMem (Config
, Cur
, Len
);
245 Ip4ConfigFixRouteTablePointer (&Config
->Ip4Info
);
257 Modify the configuration parameter for the NIC in the variable.
258 If Config is NULL, old configuration will be remove from the new
259 variable. Otherwise, append it or replace the old one.
261 @param Variable The IP4 variable to change
262 @param NicAddr The interface to search
263 @param Config The new configuration parameter (NULL to remove the old)
265 @return The new IP4_CONFIG_VARIABLE variable if the new variable has at
266 @return least one NIC configure and no EFI_OUT_OF_RESOURCES failure.
267 @return Return NULL either because failed to locate memory for new variable
268 @return or the only NIC configure is removed from the Variable.
271 IP4_CONFIG_VARIABLE
*
272 Ip4ConfigModifyVariable (
273 IN IP4_CONFIG_VARIABLE
*Variable
, OPTIONAL
274 IN NIC_ADDR
*NicAddr
,
275 IN NIC_IP4_CONFIG_INFO
*Config OPTIONAL
278 NIC_IP4_CONFIG_INFO Temp
;
279 NIC_IP4_CONFIG_INFO
*Old
;
280 IP4_CONFIG_VARIABLE
*NewVar
;
288 ASSERT ((Variable
!= NULL
) || (Config
!= NULL
));
291 // Compute the total length
293 if (Variable
!= NULL
) {
295 // Variable != NULL, then Config can be NULL or not. and so is
296 // the Old. If old configure exists, it is removed from the
297 // Variable. New configure is append to the variable.
300 Count
= Variable
->Count
;
301 Cur
= (UINT8
*)&Variable
->ConfigInfo
;
302 TotalLen
= Variable
->Len
;
304 Old
= Ip4ConfigFindNicVariable (Variable
, NicAddr
);
307 TotalLen
-= SIZEOF_NIC_IP4_CONFIG_INFO (Old
);
311 if (Config
!= NULL
) {
312 TotalLen
+= SIZEOF_NIC_IP4_CONFIG_INFO (Config
);
316 // Return NULL if the only NIC_IP4_CONFIG_INFO is being removed.
318 if (TotalLen
< sizeof (IP4_CONFIG_VARIABLE
)) {
324 // Variable == NULL and Config != NULL, Create a new variable with
325 // this NIC configure.
329 TotalLen
= sizeof (IP4_CONFIG_VARIABLE
) - sizeof (NIC_IP4_CONFIG_INFO
)
330 + SIZEOF_NIC_IP4_CONFIG_INFO (Config
);
333 ASSERT (TotalLen
>= sizeof (IP4_CONFIG_VARIABLE
));
335 NewVar
= AllocateZeroPool (TotalLen
);
337 if (NewVar
== NULL
) {
341 NewVar
->Len
= TotalLen
;
344 // Copy the other configure parameters from the old variable
346 Next
= (UINT8
*)&NewVar
->ConfigInfo
;
348 for (Index
= 0; Index
< Count
; Index
++) {
349 CopyMem (&Temp
, Cur
, sizeof (NIC_IP4_CONFIG_INFO
));
350 Len
= SIZEOF_NIC_IP4_CONFIG_INFO (&Temp
);
352 if (!NIC_ADDR_EQUAL (&Temp
.NicAddr
, NicAddr
)) {
353 CopyMem (Next
, Cur
, Len
);
362 // Append the new configure if it isn't NULL.
366 if (Config
!= NULL
) {
367 Len
= SIZEOF_NIC_IP4_CONFIG_INFO (Config
);
369 CopyMem (Next
, Config
, Len
);
373 ASSERT (Next
+ Len
== (UINT8
*) NewVar
+ TotalLen
);
375 NewVar
->CheckSum
= (UINT16
) (~NetblockChecksum ((UINT8
*) NewVar
, TotalLen
));
380 Fix the RouteTable pointer in an EFI_IP4_IPCONFIG_DATA structure.
382 The pointer is set to be immediately follow the ConfigData if there're entries
383 in the RouteTable. Otherwise it is set to NULL.
385 @param ConfigData The IP4 IP configure data.
389 Ip4ConfigFixRouteTablePointer (
390 IN EFI_IP4_IPCONFIG_DATA
*ConfigData
394 // The memory used for route table entries must immediately follow
395 // the ConfigData and be not packed.
397 if (ConfigData
->RouteTableSize
> 0) {
398 ConfigData
->RouteTable
= (EFI_IP4_ROUTE_TABLE
*) (ConfigData
+ 1);
400 ConfigData
->RouteTable
= NULL
;