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.
15 #include "NicIp4Variable.h"
19 Check whether the configure parameter is valid.
21 @param NicConfig The configure parameter to check
23 @return TRUE if the parameter is valid for the interface, otherwise FALSE.
28 IN NIC_IP4_CONFIG_INFO
*NicConfig
31 EFI_IP4_IPCONFIG_DATA
*IpConfig
;
37 IpConfig
= &NicConfig
->Ip4Info
;
39 if (NicConfig
->Source
== IP4_CONFIG_SOURCE_STATIC
) {
41 // Validate that the addresses are unicast and mask
42 // is properly formated
44 Station
= EFI_NTOHL (IpConfig
->StationAddress
);
45 Netmask
= EFI_NTOHL (IpConfig
->SubnetMask
);
47 if ((Netmask
== 0) || !IP4_IS_VALID_NETMASK (Netmask
) ||
48 (Station
== 0) || !Ip4IsUnicast (Station
, Netmask
)) {
53 // Validate that the next hops are on the connected network
54 // or that is a direct route (Gateway == 0).
56 for (Index
= 0; Index
< IpConfig
->RouteTableSize
; Index
++) {
57 Gateway
= EFI_NTOHL (IpConfig
->RouteTable
[Index
].GatewayAddress
);
59 if ((Gateway
!= 0) && (!IP4_NET_EQUAL (Station
, Gateway
, Netmask
) ||
60 !Ip4IsUnicast (Gateway
, Netmask
))) {
69 // return false if it is an unkown configure source. Valid
70 // sources are static and dhcp.
72 return (BOOLEAN
) (NicConfig
->Source
== IP4_CONFIG_SOURCE_DHCP
);
78 Read the ip4 configure variable from the EFI variable.
82 @return The IP4 configure read if it is there and is valid, otherwise NULL
86 Ip4ConfigReadVariable (
90 IP4_CONFIG_VARIABLE
*Variable
;
96 // Get the size of variable, then allocate a buffer to read the variable.
100 Status
= gRT
->GetVariable (
101 EFI_NIC_IP4_CONFIG_VARIABLE
,
102 &gEfiNicIp4ConfigVariableGuid
,
108 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
112 if (Size
< sizeof (IP4_CONFIG_VARIABLE
)) {
113 goto REMOVE_VARIABLE
;
116 Variable
= AllocatePool (Size
);
118 if (Variable
== NULL
) {
122 Status
= gRT
->GetVariable (
123 EFI_NIC_IP4_CONFIG_VARIABLE
,
124 &gEfiNicIp4ConfigVariableGuid
,
130 if (EFI_ERROR (Status
)) {
135 // Verify the checksum, variable size and count
137 CheckSum
= (UINT16
) (~NetblockChecksum ((UINT8
*) Variable
, (UINT32
)Size
));
139 if ((CheckSum
!= 0) || (Size
!= Variable
->Len
)) {
140 goto REMOVE_VARIABLE
;
143 if ((Variable
->Count
< 1) || (Variable
->Count
> MAX_IP4_CONFIG_IN_VARIABLE
)) {
144 goto REMOVE_VARIABLE
;
150 Ip4ConfigWriteVariable (NULL
);
153 if (Variable
!= NULL
) {
154 gBS
->FreePool (Variable
);
162 Write the IP4 configure variable to the NVRAM. If Config
163 is NULL, remove the variable.
165 @param Config The IP4 configure data to write
167 @retval EFI_SUCCESS The variable is written to the NVRam
168 @retval Others Failed to write the variable.
172 Ip4ConfigWriteVariable (
173 IN IP4_CONFIG_VARIABLE
*Config OPTIONAL
178 Status
= gRT
->SetVariable (
179 EFI_NIC_IP4_CONFIG_VARIABLE
,
180 &gEfiNicIp4ConfigVariableGuid
,
181 IP4_CONFIG_VARIABLE_ATTRIBUTES
,
182 (Config
== NULL
) ? 0 : Config
->Len
,
191 Locate the IP4 configure parameters from the variable.If a
192 configuration is found, copy it to a newly allocated block
193 of memory to avoid the alignment problem. Caller should
194 release the memory after use.
196 @param Variable The IP4 configure variable to search in
197 @param NicAddr The interface address to check
199 @return The point to the NIC's IP4 configure info if it is found
200 in the IP4 variable, otherwise NULL.
203 NIC_IP4_CONFIG_INFO
*
204 Ip4ConfigFindNicVariable (
205 IN IP4_CONFIG_VARIABLE
*Variable
,
209 NIC_IP4_CONFIG_INFO Temp
;
210 NIC_IP4_CONFIG_INFO
*Config
;
215 Cur
= (UINT8
*)&Variable
->ConfigInfo
;
217 for (Index
= 0; Index
< Variable
->Count
; Index
++) {
219 // Copy the data to Temp to avoid the alignment problems
221 CopyMem (&Temp
, Cur
, sizeof (NIC_IP4_CONFIG_INFO
));
222 Len
= SIZEOF_NIC_IP4_CONFIG_INFO (&Temp
);
225 // Found the matching configuration parameters, allocate
226 // a block of memory then copy it out.
228 if (NIC_ADDR_EQUAL (&Temp
.NicAddr
, NicAddr
)) {
229 Config
= AllocatePool (Len
);
231 if (Config
== NULL
) {
235 CopyMem (Config
, Cur
, Len
);
236 Ip4ConfigFixRouteTablePointer (&Config
->Ip4Info
);
248 Modify the configuration parameter for the NIC in the variable.
249 If Config is NULL, old configuration will be remove from the new
250 variable. Otherwise, append it or replace the old one.
252 @param Variable The IP4 variable to change
253 @param NicAddr The interface to search
254 @param Config The new configuration parameter (NULL to remove the old)
256 @return The new IP4_CONFIG_VARIABLE variable if the new variable has at
257 least one NIC configure and no EFI_OUT_OF_RESOURCES failure.
258 Return NULL either because failed to locate memory for new variable
259 or the only NIC configure is removed from the Variable.
262 IP4_CONFIG_VARIABLE
*
263 Ip4ConfigModifyVariable (
264 IN IP4_CONFIG_VARIABLE
*Variable OPTIONAL
,
265 IN NIC_ADDR
*NicAddr
,
266 IN NIC_IP4_CONFIG_INFO
*Config OPTIONAL
269 NIC_IP4_CONFIG_INFO Temp
;
270 NIC_IP4_CONFIG_INFO
*Old
;
271 IP4_CONFIG_VARIABLE
*NewVar
;
279 ASSERT ((Variable
!= NULL
) || (Config
!= NULL
));
282 // Compute the total length
284 if (Variable
!= NULL
) {
286 // Variable != NULL, then Config can be NULL or not. and so is
287 // the Old. If old configure exists, it is removed from the
288 // Variable. New configure is append to the variable.
291 Count
= Variable
->Count
;
292 Cur
= (UINT8
*)&Variable
->ConfigInfo
;
293 TotalLen
= Variable
->Len
;
295 Old
= Ip4ConfigFindNicVariable (Variable
, NicAddr
);
298 TotalLen
-= SIZEOF_NIC_IP4_CONFIG_INFO (Old
);
302 if (Config
!= NULL
) {
303 TotalLen
+= SIZEOF_NIC_IP4_CONFIG_INFO (Config
);
307 // Return NULL if the only NIC_IP4_CONFIG_INFO is being removed.
309 if (TotalLen
< sizeof (IP4_CONFIG_VARIABLE
)) {
315 // Variable == NULL and Config != NULL, Create a new variable with
316 // this NIC configure.
320 TotalLen
= sizeof (IP4_CONFIG_VARIABLE
) - sizeof (NIC_IP4_CONFIG_INFO
)
321 + SIZEOF_NIC_IP4_CONFIG_INFO (Config
);
324 ASSERT (TotalLen
>= sizeof (IP4_CONFIG_VARIABLE
));
326 NewVar
= AllocateZeroPool (TotalLen
);
328 if (NewVar
== NULL
) {
332 NewVar
->Len
= TotalLen
;
335 // Copy the other configure parameters from the old variable
337 Next
= (UINT8
*)&NewVar
->ConfigInfo
;
339 for (Index
= 0; Index
< Count
; Index
++) {
340 CopyMem (&Temp
, Cur
, sizeof (NIC_IP4_CONFIG_INFO
));
341 Len
= SIZEOF_NIC_IP4_CONFIG_INFO (&Temp
);
343 if (!NIC_ADDR_EQUAL (&Temp
.NicAddr
, NicAddr
)) {
344 CopyMem (Next
, Cur
, Len
);
353 // Append the new configure if it isn't NULL.
357 if (Config
!= NULL
) {
358 Len
= SIZEOF_NIC_IP4_CONFIG_INFO (Config
);
360 CopyMem (Next
, Config
, Len
);
364 ASSERT (Next
+ Len
== (UINT8
*) NewVar
+ TotalLen
);
366 NewVar
->CheckSum
= (UINT16
) (~NetblockChecksum ((UINT8
*) NewVar
, TotalLen
));
371 Fix the RouteTable pointer in an EFI_IP4_IPCONFIG_DATA structure.
373 The pointer is set to be immediately follow the ConfigData if there're entries
374 in the RouteTable. Otherwise it is set to NULL.
376 @param ConfigData The IP4 IP configure data.
380 Ip4ConfigFixRouteTablePointer (
381 IN OUT EFI_IP4_IPCONFIG_DATA
*ConfigData
385 // The memory used for route table entries must immediately follow
386 // the ConfigData and be not packed.
388 if (ConfigData
->RouteTableSize
> 0) {
389 ConfigData
->RouteTable
= (EFI_IP4_ROUTE_TABLE
*) (ConfigData
+ 1);
391 ConfigData
->RouteTable
= NULL
;