3 Copyright (c) 2006, 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
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>
31 #include "NicIp4Variable.h"
35 Check whether the configure parameter is valid.
37 @param NicConfig The configure parameter to check
39 @return TRUE if the parameter is valid for the interface, otherwise FALSE.
44 IN NIC_IP4_CONFIG_INFO
*NicConfig
47 EFI_IP4_IPCONFIG_DATA
*IpConfig
;
53 IpConfig
= &NicConfig
->Ip4Info
;
55 if (NicConfig
->Source
== IP4_CONFIG_SOURCE_STATIC
) {
57 // Validate that the addresses are unicast and mask
58 // is properly formated
60 Station
= EFI_NTOHL (IpConfig
->StationAddress
);
61 Netmask
= EFI_NTOHL (IpConfig
->SubnetMask
);
63 if ((Netmask
== 0) || !IP4_IS_VALID_NETMASK (Netmask
) ||
64 (Station
== 0) || !Ip4IsUnicast (Station
, Netmask
)) {
69 // Validate that the next hops are on the connected network
70 // or that is a direct route (Gateway == 0).
72 for (Index
= 0; Index
< IpConfig
->RouteTableSize
; Index
++) {
73 Gateway
= EFI_NTOHL (IpConfig
->RouteTable
[Index
].GatewayAddress
);
75 if ((Gateway
!= 0) && (!IP4_NET_EQUAL (Station
, Gateway
, Netmask
) ||
76 !Ip4IsUnicast (Gateway
, Netmask
))) {
85 // return false if it is an unkown configure source. Valid
86 // sources are static and dhcp.
88 return (BOOLEAN
) (NicConfig
->Source
== IP4_CONFIG_SOURCE_DHCP
);
94 Read the ip4 configure variable from the EFI variable
98 @return The IP4 configure read if it is there and is valid, otherwise NULL
101 IP4_CONFIG_VARIABLE
*
102 Ip4ConfigReadVariable (
106 IP4_CONFIG_VARIABLE
*Variable
;
112 // Get the size of variable, then allocate a buffer to read the variable.
116 Status
= gRT
->GetVariable (
117 EFI_NIC_IP4_CONFIG_VARIABLE
,
118 &gEfiNicIp4ConfigVariableGuid
,
124 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
128 if (Size
< sizeof (IP4_CONFIG_VARIABLE
)) {
129 goto REMOVE_VARIABLE
;
132 Variable
= NetAllocatePool (Size
);
134 if (Variable
== NULL
) {
138 Status
= gRT
->GetVariable (
139 EFI_NIC_IP4_CONFIG_VARIABLE
,
140 &gEfiNicIp4ConfigVariableGuid
,
146 if (EFI_ERROR (Status
)) {
151 // Verify the checksum, variable size and count
153 CheckSum
= (UINT16
) (~NetblockChecksum ((UINT8
*) Variable
, (UINT32
)Size
));
155 if ((CheckSum
!= 0) || (Size
!= Variable
->Len
)) {
156 goto REMOVE_VARIABLE
;
159 if ((Variable
->Count
< 1) || (Variable
->Count
> MAX_IP4_CONFIG_IN_VARIABLE
)) {
160 goto REMOVE_VARIABLE
;
166 Ip4ConfigWriteVariable (NULL
);
169 if (Variable
!= NULL
) {
170 NetFreePool (Variable
);
178 Write the IP4 configure variable to the NVRAM. If Config
179 is NULL, remove the variable.
181 @param Config The IP4 configure data to write
183 @retval EFI_SUCCESS The variable is written to the NVRam
184 @retval Others Failed to write the variable.
188 Ip4ConfigWriteVariable (
189 IN IP4_CONFIG_VARIABLE
* Config OPTIONAL
194 Status
= gRT
->SetVariable (
195 EFI_NIC_IP4_CONFIG_VARIABLE
,
196 &gEfiNicIp4ConfigVariableGuid
,
197 IP4_CONFIG_VARIABLE_ATTRIBUTES
,
198 (Config
== NULL
) ? 0 : Config
->Len
,
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.
212 @param Variable The IP4 configure variable to search in
213 @param NicAddr The interface address to check
215 @return The point to the NIC's IP4 configure info if it is found
216 @return in the IP4 variable, otherwise NULL.
219 NIC_IP4_CONFIG_INFO
*
220 Ip4ConfigFindNicVariable (
221 IN IP4_CONFIG_VARIABLE
*Variable
,
225 NIC_IP4_CONFIG_INFO Temp
;
226 NIC_IP4_CONFIG_INFO
*Config
;
231 Cur
= (UINT8
*)&Variable
->ConfigInfo
;
233 for (Index
= 0; Index
< Variable
->Count
; Index
++) {
235 // Copy the data to Temp to avoid the alignment problems
237 NetCopyMem (&Temp
, Cur
, sizeof (NIC_IP4_CONFIG_INFO
));
238 Len
= SIZEOF_NIC_IP4_CONFIG_INFO (&Temp
);
241 // Found the matching configuration parameters, allocate
242 // a block of memory then copy it out.
244 if (NIC_ADDR_EQUAL (&Temp
.NicAddr
, NicAddr
)) {
245 Config
= NetAllocatePool (Len
);
247 if (Config
== NULL
) {
251 NetCopyMem (Config
, Cur
, Len
);
263 Modify the configuration parameter for the NIC in the variable.
264 If Config is NULL, old configuration will be remove from the new
265 variable. Otherwise, append it or replace the old one.
267 @param Variable The IP4 variable to change
268 @param NicAddr The interface to search
269 @param Config The new configuration parameter (NULL to remove the old)
271 @return The new IP4_CONFIG_VARIABLE variable if the new variable has at
272 @return least one NIC configure and no EFI_OUT_OF_RESOURCES failure.
273 @return Return NULL either because failed to locate memory for new variable
274 @return or the only NIC configure is removed from the Variable.
277 IP4_CONFIG_VARIABLE
*
278 Ip4ConfigModifyVariable (
279 IN IP4_CONFIG_VARIABLE
*Variable
, OPTIONAL
280 IN NIC_ADDR
*NicAddr
,
281 IN NIC_IP4_CONFIG_INFO
*Config OPTIONAL
284 NIC_IP4_CONFIG_INFO Temp
;
285 NIC_IP4_CONFIG_INFO
*Old
;
286 IP4_CONFIG_VARIABLE
*NewVar
;
294 ASSERT ((Variable
!= NULL
) || (Config
!= NULL
));
297 // Compute the total length
299 if (Variable
!= NULL
) {
301 // Variable != NULL, then Config can be NULL or not. and so is
302 // the Old. If old configure exists, it is removed from the
303 // Variable. New configure is append to the variable.
306 Count
= Variable
->Count
;
307 Cur
= (UINT8
*)&Variable
->ConfigInfo
;
308 TotalLen
= Variable
->Len
;
310 Old
= Ip4ConfigFindNicVariable (Variable
, NicAddr
);
313 TotalLen
-= SIZEOF_NIC_IP4_CONFIG_INFO (Old
);
317 if (Config
!= NULL
) {
318 TotalLen
+= SIZEOF_NIC_IP4_CONFIG_INFO (Config
);
322 // Return NULL if the only NIC_IP4_CONFIG_INFO is being removed.
324 if (TotalLen
< sizeof (IP4_CONFIG_VARIABLE
)) {
330 // Variable == NULL and Config != NULL, Create a new variable with
331 // this NIC configure.
335 TotalLen
= sizeof (IP4_CONFIG_VARIABLE
) - sizeof (NIC_IP4_CONFIG_INFO
)
336 + SIZEOF_NIC_IP4_CONFIG_INFO (Config
);
339 ASSERT (TotalLen
>= sizeof (IP4_CONFIG_VARIABLE
));
341 NewVar
= NetAllocateZeroPool (TotalLen
);
343 if (NewVar
== NULL
) {
347 NewVar
->Len
= TotalLen
;
350 // Copy the other configure parameters from the old variable
352 Next
= (UINT8
*)&NewVar
->ConfigInfo
;
354 for (Index
= 0; Index
< Count
; Index
++) {
355 NetCopyMem (&Temp
, Cur
, sizeof (NIC_IP4_CONFIG_INFO
));
356 Len
= SIZEOF_NIC_IP4_CONFIG_INFO (&Temp
);
358 if (!NIC_ADDR_EQUAL (&Temp
.NicAddr
, NicAddr
)) {
359 NetCopyMem (Next
, Cur
, Len
);
368 // Append the new configure if it isn't NULL.
372 if (Config
!= NULL
) {
373 Len
= SIZEOF_NIC_IP4_CONFIG_INFO (Config
);
375 NetCopyMem (Next
, Config
, Len
);
379 ASSERT (Next
+ Len
== (UINT8
*) NewVar
+ TotalLen
);
381 NewVar
->CheckSum
= (UINT16
) (~NetblockChecksum ((UINT8
*) NewVar
, TotalLen
));