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
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.
18 Routines used to operate the Ip4 configure variable
25 #include <Library/NetLib.h>
26 #include <Library/DebugLib.h>
27 #include <Library/BaseMemoryLib.h>
28 #include <Library/MemoryAllocationLib.h>
29 #include <Library/UefiBootServicesTableLib.h>
30 #include <Library/UefiRuntimeServicesTableLib.h>
32 #include "NicIp4Variable.h"
36 Check whether the configure parameter is valid.
38 @param NicConfig The configure parameter to check
40 @return TRUE if the parameter is valid for the interface, otherwise FALSE.
45 IN NIC_IP4_CONFIG_INFO
*NicConfig
48 EFI_IP4_IPCONFIG_DATA
*IpConfig
;
54 IpConfig
= &NicConfig
->Ip4Info
;
56 if (NicConfig
->Source
== IP4_CONFIG_SOURCE_STATIC
) {
58 // Validate that the addresses are unicast and mask
59 // is properly formated
61 Station
= EFI_NTOHL (IpConfig
->StationAddress
);
62 Netmask
= EFI_NTOHL (IpConfig
->SubnetMask
);
64 if ((Netmask
== 0) || !IP4_IS_VALID_NETMASK (Netmask
) ||
65 (Station
== 0) || !Ip4IsUnicast (Station
, Netmask
)) {
70 // Validate that the next hops are on the connected network
71 // or that is a direct route (Gateway == 0).
73 for (Index
= 0; Index
< IpConfig
->RouteTableSize
; Index
++) {
74 Gateway
= EFI_NTOHL (IpConfig
->RouteTable
[Index
].GatewayAddress
);
76 if ((Gateway
!= 0) && (!IP4_NET_EQUAL (Station
, Gateway
, Netmask
) ||
77 !Ip4IsUnicast (Gateway
, Netmask
))) {
86 // return false if it is an unkown configure source. Valid
87 // sources are static and dhcp.
89 return (BOOLEAN
) (NicConfig
->Source
== IP4_CONFIG_SOURCE_DHCP
);
95 Read the ip4 configure variable from the EFI variable.
99 @return The IP4 configure read if it is there and is valid, otherwise NULL
102 IP4_CONFIG_VARIABLE
*
103 Ip4ConfigReadVariable (
107 IP4_CONFIG_VARIABLE
*Variable
;
113 // Get the size of variable, then allocate a buffer to read the variable.
117 Status
= gRT
->GetVariable (
118 EFI_NIC_IP4_CONFIG_VARIABLE
,
119 &gEfiNicIp4ConfigVariableGuid
,
125 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
129 if (Size
< sizeof (IP4_CONFIG_VARIABLE
)) {
130 goto REMOVE_VARIABLE
;
133 Variable
= AllocatePool (Size
);
135 if (Variable
== NULL
) {
139 Status
= gRT
->GetVariable (
140 EFI_NIC_IP4_CONFIG_VARIABLE
,
141 &gEfiNicIp4ConfigVariableGuid
,
147 if (EFI_ERROR (Status
)) {
152 // Verify the checksum, variable size and count
154 CheckSum
= (UINT16
) (~NetblockChecksum ((UINT8
*) Variable
, (UINT32
)Size
));
156 if ((CheckSum
!= 0) || (Size
!= Variable
->Len
)) {
157 goto REMOVE_VARIABLE
;
160 if ((Variable
->Count
< 1) || (Variable
->Count
> MAX_IP4_CONFIG_IN_VARIABLE
)) {
161 goto REMOVE_VARIABLE
;
167 Ip4ConfigWriteVariable (NULL
);
170 if (Variable
!= NULL
) {
171 gBS
->FreePool (Variable
);
179 Write the IP4 configure variable to the NVRAM. If Config
180 is NULL, remove the variable.
182 @param Config The IP4 configure data to write
184 @retval EFI_SUCCESS The variable is written to the NVRam
185 @retval Others Failed to write the variable.
189 Ip4ConfigWriteVariable (
190 IN IP4_CONFIG_VARIABLE
*Config OPTIONAL
195 Status
= gRT
->SetVariable (
196 EFI_NIC_IP4_CONFIG_VARIABLE
,
197 &gEfiNicIp4ConfigVariableGuid
,
198 IP4_CONFIG_VARIABLE_ATTRIBUTES
,
199 (Config
== NULL
) ? 0 : Config
->Len
,
208 Locate the IP4 configure parameters from the variable.If a
209 configuration is found, copy it to a newly allocated block
210 of memory to avoid the alignment problem. Caller should
211 release the memory after use.
213 @param Variable The IP4 configure variable to search in
214 @param NicAddr The interface address to check
216 @return The point to the NIC's IP4 configure info if it is found
217 @return in the IP4 variable, otherwise NULL.
220 NIC_IP4_CONFIG_INFO
*
221 Ip4ConfigFindNicVariable (
222 IN IP4_CONFIG_VARIABLE
*Variable
,
226 NIC_IP4_CONFIG_INFO Temp
;
227 NIC_IP4_CONFIG_INFO
*Config
;
232 Cur
= (UINT8
*)&Variable
->ConfigInfo
;
234 for (Index
= 0; Index
< Variable
->Count
; Index
++) {
236 // Copy the data to Temp to avoid the alignment problems
238 CopyMem (&Temp
, Cur
, sizeof (NIC_IP4_CONFIG_INFO
));
239 Len
= SIZEOF_NIC_IP4_CONFIG_INFO (&Temp
);
242 // Found the matching configuration parameters, allocate
243 // a block of memory then copy it out.
245 if (NIC_ADDR_EQUAL (&Temp
.NicAddr
, NicAddr
)) {
246 Config
= AllocatePool (Len
);
248 if (Config
== NULL
) {
252 CopyMem (Config
, Cur
, Len
);
253 Ip4ConfigFixRouteTablePointer (&Config
->Ip4Info
);
265 Modify the configuration parameter for the NIC in the variable.
266 If Config is NULL, old configuration will be remove from the new
267 variable. Otherwise, append it or replace the old one.
269 @param Variable The IP4 variable to change
270 @param NicAddr The interface to search
271 @param Config The new configuration parameter (NULL to remove the old)
273 @return The new IP4_CONFIG_VARIABLE variable if the new variable has at
274 @return least one NIC configure and no EFI_OUT_OF_RESOURCES failure.
275 @return Return NULL either because failed to locate memory for new variable
276 @return or the only NIC configure is removed from the Variable.
279 IP4_CONFIG_VARIABLE
*
280 Ip4ConfigModifyVariable (
281 IN IP4_CONFIG_VARIABLE
*Variable
, OPTIONAL
282 IN NIC_ADDR
*NicAddr
,
283 IN NIC_IP4_CONFIG_INFO
*Config OPTIONAL
286 NIC_IP4_CONFIG_INFO Temp
;
287 NIC_IP4_CONFIG_INFO
*Old
;
288 IP4_CONFIG_VARIABLE
*NewVar
;
296 ASSERT ((Variable
!= NULL
) || (Config
!= NULL
));
299 // Compute the total length
301 if (Variable
!= NULL
) {
303 // Variable != NULL, then Config can be NULL or not. and so is
304 // the Old. If old configure exists, it is removed from the
305 // Variable. New configure is append to the variable.
308 Count
= Variable
->Count
;
309 Cur
= (UINT8
*)&Variable
->ConfigInfo
;
310 TotalLen
= Variable
->Len
;
312 Old
= Ip4ConfigFindNicVariable (Variable
, NicAddr
);
315 TotalLen
-= SIZEOF_NIC_IP4_CONFIG_INFO (Old
);
319 if (Config
!= NULL
) {
320 TotalLen
+= SIZEOF_NIC_IP4_CONFIG_INFO (Config
);
324 // Return NULL if the only NIC_IP4_CONFIG_INFO is being removed.
326 if (TotalLen
< sizeof (IP4_CONFIG_VARIABLE
)) {
332 // Variable == NULL and Config != NULL, Create a new variable with
333 // this NIC configure.
337 TotalLen
= sizeof (IP4_CONFIG_VARIABLE
) - sizeof (NIC_IP4_CONFIG_INFO
)
338 + SIZEOF_NIC_IP4_CONFIG_INFO (Config
);
341 ASSERT (TotalLen
>= sizeof (IP4_CONFIG_VARIABLE
));
343 NewVar
= AllocateZeroPool (TotalLen
);
345 if (NewVar
== NULL
) {
349 NewVar
->Len
= TotalLen
;
352 // Copy the other configure parameters from the old variable
354 Next
= (UINT8
*)&NewVar
->ConfigInfo
;
356 for (Index
= 0; Index
< Count
; Index
++) {
357 CopyMem (&Temp
, Cur
, sizeof (NIC_IP4_CONFIG_INFO
));
358 Len
= SIZEOF_NIC_IP4_CONFIG_INFO (&Temp
);
360 if (!NIC_ADDR_EQUAL (&Temp
.NicAddr
, NicAddr
)) {
361 CopyMem (Next
, Cur
, Len
);
370 // Append the new configure if it isn't NULL.
374 if (Config
!= NULL
) {
375 Len
= SIZEOF_NIC_IP4_CONFIG_INFO (Config
);
377 CopyMem (Next
, Config
, Len
);
381 ASSERT (Next
+ Len
== (UINT8
*) NewVar
+ TotalLen
);
383 NewVar
->CheckSum
= (UINT16
) (~NetblockChecksum ((UINT8
*) NewVar
, TotalLen
));
388 Ip4ConfigFixRouteTablePointer (
389 IN EFI_IP4_IPCONFIG_DATA
*ConfigData
393 // The memory used for route table entries must immediately follow
394 // the ConfigData and be not packed.
396 if (ConfigData
->RouteTableSize
> 0) {
397 ConfigData
->RouteTable
= (EFI_IP4_ROUTE_TABLE
*) (ConfigData
+ 1);
399 ConfigData
->RouteTable
= NULL
;