3 Copyright (c) 2005 - 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.
26 Return the cast type (Unicast/Boradcast) specific to an
27 interface. All the addresses are host byte ordered.
29 @param IpAddr The IP address to classify in host byte order
30 @param IpIf The interface that IpAddr received from
32 @return The cast type of this IP address specific to the interface.
33 @retval IP4_LOCAL_HOST The IpAddr equals to the interface's address
34 @retval IP4_SUBNET_BROADCAST The IpAddr is a directed subnet boradcast to the
36 @retval IP4_NET_BROADCAST The IpAddr is a network broadcast to the interface
43 IN IP4_INTERFACE
*IpIf
46 if (IpAddr
== IpIf
->Ip
) {
47 return IP4_LOCAL_HOST
;
49 } else if (IpAddr
== IpIf
->SubnetBrdcast
) {
50 return IP4_SUBNET_BROADCAST
;
52 } else if (IpAddr
== IpIf
->NetBrdcast
) {
53 return IP4_NET_BROADCAST
;
62 Find the cast type of the packet related to the local host.
63 This isn't the same as link layer cast type. For example, DHCP
64 server may send local broadcast to the local unicast MAC.
66 @param IpSb The IP4 service binding instance that received the
68 @param Dst The destination address in the packet (host byte
70 @param Src The source address in the packet (host byte order)
72 @return The cast type for the Dst, it will return on the first non-promiscuous
73 cast type to a configured interface. If the packet doesn't match any of
74 the interface, multicast address and local broadcast address are checked.
91 if (IpSb
->MnpConfigData
.EnablePromiscuousReceive
) {
92 Type
= IP4_PROMISCUOUS
;
96 // Go through the interface list of the IP service, most likely.
98 NET_LIST_FOR_EACH (Entry
, &IpSb
->Interfaces
) {
99 IpIf
= NET_LIST_USER_STRUCT (Entry
, IP4_INTERFACE
, Link
);
102 // Skip the unconfigured interface and invalid source address:
103 // source address can't be broadcast.
105 if (!IpIf
->Configured
|| IP4_IS_BROADCAST (Ip4GetNetCast (Src
, IpIf
))) {
109 if ((Class
= Ip4GetNetCast (Dst
, IpIf
)) > Type
) {
115 // If it is local broadcast address. The source address must
116 // be a unicast address on one of the direct connected network.
117 // If it is a multicast address, accept it only if we are in
120 if (Dst
== IP4_ALLONE_ADDRESS
) {
121 IpIf
= Ip4FindNet (IpSb
, Src
);
123 if (IpIf
!= NULL
&& !IP4_IS_BROADCAST (Ip4GetNetCast (Src
, IpIf
))) {
124 return IP4_LOCAL_BROADCAST
;
127 } else if (IP4_IS_MULTICAST (Dst
) && Ip4FindGroup (&IpSb
->IgmpCtrl
, Dst
) != NULL
) {
128 return IP4_MULTICAST
;
136 Find an interface whose configured IP address is Ip.
138 @param IpSb The IP4 service binding instance
139 @param Ip The Ip address (host byte order) to find
141 @return The IP4_INTERFACE point if found, otherwise NULL
146 IN IP4_SERVICE
*IpSb
,
153 NET_LIST_FOR_EACH (Entry
, &IpSb
->Interfaces
) {
154 IpIf
= NET_LIST_USER_STRUCT (Entry
, IP4_INTERFACE
, Link
);
156 if (IpIf
->Configured
&& (IpIf
->Ip
== Ip
)) {
166 Find an interface that Ip is on that connected network.
168 @param IpSb The IP4 service binding instance
169 @param Ip The Ip address (host byte order) to find
171 @return The IP4_INTERFACE point if found, otherwise NULL
176 IN IP4_SERVICE
*IpSb
,
183 NET_LIST_FOR_EACH (Entry
, &IpSb
->Interfaces
) {
184 IpIf
= NET_LIST_USER_STRUCT (Entry
, IP4_INTERFACE
, Link
);
186 if (IpIf
->Configured
&& IP4_NET_EQUAL (Ip
, IpIf
->Ip
, IpIf
->SubnetMask
)) {
196 Find an interface of the service with the same Ip/Netmask pair.
198 @param IpSb Ip4 service binding instance
199 @param Ip The Ip adress to find (host byte order)
200 @param Netmask The network to find (host byte order)
202 @return The IP4_INTERFACE point if found, otherwise NULL
206 Ip4FindStationAddress (
207 IN IP4_SERVICE
*IpSb
,
215 NET_LIST_FOR_EACH (Entry
, &IpSb
->Interfaces
) {
216 IpIf
= NET_LIST_USER_STRUCT (Entry
, IP4_INTERFACE
, Link
);
218 if (IpIf
->Configured
&& (IpIf
->Ip
== Ip
) && (IpIf
->SubnetMask
== Netmask
)) {
228 Get the MAC address for a multicast IP address. Call
229 Mnp's McastIpToMac to find the MAC address in stead of
230 hard code the NIC to be Ethernet.
232 @param Mnp The Mnp instance to get the MAC address.
233 @param Multicast The multicast IP address to translate.
234 @param Mac The buffer to hold the translated address.
236 @retval EFI_SUCCESS if the multicast IP is successfully translated to a
237 multicast MAC address.
238 @retval other Otherwise some error.
243 IN EFI_MANAGED_NETWORK_PROTOCOL
*Mnp
,
244 IN IP4_ADDR Multicast
,
245 OUT EFI_MAC_ADDRESS
*Mac
248 EFI_IP_ADDRESS EfiIp
;
250 EFI_IP4 (EfiIp
.v4
) = HTONL (Multicast
);
251 return Mnp
->McastIpToMac (Mnp
, FALSE
, &EfiIp
, Mac
);
256 Convert the multibyte field in IP header's byter order.
257 In spite of its name, it can also be used to convert from
258 host to network byte order.
260 @param Head The IP head to convert
262 @return Point to the converted IP head
270 Head
->TotalLen
= NTOHS (Head
->TotalLen
);
271 Head
->Id
= NTOHS (Head
->Id
);
272 Head
->Fragment
= NTOHS (Head
->Fragment
);
273 Head
->Src
= NTOHL (Head
->Src
);
274 Head
->Dst
= NTOHL (Head
->Dst
);
281 Set the Ip4 variable data.
283 Save the list of all of the IPv4 addresses and subnet masks that are currently
284 being used to volatile variable storage.
286 @param IpSb Ip4 service binding instance
288 @retval EFI_SUCCESS Successfully set variable.
289 @retval EFI_OUT_OF_RESOURCES There are not enough resources to set the variable.
290 @retval other Set variable failed.
298 UINT32 NumConfiguredInstance
;
300 UINTN VariableDataSize
;
301 EFI_IP4_VARIABLE_DATA
*Ip4VariableData
;
302 EFI_IP4_ADDRESS_PAIR
*Ip4AddressPair
;
303 IP4_PROTOCOL
*IpInstance
;
304 CHAR16
*NewMacString
;
307 NumConfiguredInstance
= 0;
310 // Go through the children list to count the configured children.
312 NET_LIST_FOR_EACH (Entry
, &IpSb
->Children
) {
313 IpInstance
= NET_LIST_USER_STRUCT_S (Entry
, IP4_PROTOCOL
, Link
, IP4_PROTOCOL_SIGNATURE
);
315 if (IpInstance
->State
== IP4_STATE_CONFIGED
) {
316 NumConfiguredInstance
++;
321 // Calculate the size of the Ip4VariableData. As there may be no IP child,
322 // we should add extra buffer for the address paris only if the number of configured
323 // children is more than 1.
325 VariableDataSize
= sizeof (EFI_IP4_VARIABLE_DATA
);
327 if (NumConfiguredInstance
> 1) {
328 VariableDataSize
+= sizeof (EFI_IP4_ADDRESS_PAIR
) * (NumConfiguredInstance
- 1);
331 Ip4VariableData
= AllocatePool (VariableDataSize
);
332 if (Ip4VariableData
== NULL
) {
333 return EFI_OUT_OF_RESOURCES
;
336 Ip4VariableData
->DriverHandle
= IpSb
->Image
;
337 Ip4VariableData
->AddressCount
= NumConfiguredInstance
;
339 Ip4AddressPair
= &Ip4VariableData
->AddressPairs
[0];
342 // Go through the children list to fill the configured children's address pairs.
344 NET_LIST_FOR_EACH (Entry
, &IpSb
->Children
) {
345 IpInstance
= NET_LIST_USER_STRUCT_S (Entry
, IP4_PROTOCOL
, Link
, IP4_PROTOCOL_SIGNATURE
);
347 if (IpInstance
->State
== IP4_STATE_CONFIGED
) {
348 Ip4AddressPair
->InstanceHandle
= IpInstance
->Handle
;
349 EFI_IP4 (Ip4AddressPair
->Ip4Address
) = NTOHL (IpInstance
->Interface
->Ip
);
350 EFI_IP4 (Ip4AddressPair
->SubnetMask
) = NTOHL (IpInstance
->Interface
->SubnetMask
);
357 // Get the mac string.
359 Status
= NetLibGetMacString (IpSb
->Controller
, IpSb
->Image
, &NewMacString
);
360 if (EFI_ERROR (Status
)) {
364 if (IpSb
->MacString
!= NULL
) {
366 // The variable is set already, we're going to update it.
368 if (StrCmp (IpSb
->MacString
, NewMacString
) != 0) {
370 // The mac address is changed, delete the previous variable first.
374 &gEfiIp4ServiceBindingProtocolGuid
,
375 EFI_VARIABLE_BOOTSERVICE_ACCESS
,
381 gBS
->FreePool (IpSb
->MacString
);
384 IpSb
->MacString
= NewMacString
;
386 Status
= gRT
->SetVariable (
388 &gEfiIp4ServiceBindingProtocolGuid
,
389 EFI_VARIABLE_BOOTSERVICE_ACCESS
,
391 (VOID
*) Ip4VariableData
396 gBS
->FreePool (Ip4VariableData
);
403 Clear the variable and free the resource.
405 @param IpSb Ip4 service binding instance
411 Ip4ClearVariableData (
415 ASSERT (IpSb
->MacString
!= NULL
);
419 &gEfiIp4ServiceBindingProtocolGuid
,
420 EFI_VARIABLE_BOOTSERVICE_ACCESS
,
425 gBS
->FreePool (IpSb
->MacString
);
426 IpSb
->MacString
= NULL
;