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 a
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
42 IN IP4_INTERFACE
*IpIf
45 if (IpAddr
== IpIf
->Ip
) {
46 return IP4_LOCAL_HOST
;
48 } else if (IpAddr
== IpIf
->SubnetBrdcast
) {
49 return IP4_SUBNET_BROADCAST
;
51 } else if (IpAddr
== IpIf
->NetBrdcast
) {
52 return IP4_NET_BROADCAST
;
61 Find the cast type of the packet related to the local host.
62 This isn't the same as link layer cast type. For example, DHCP
63 server may send local broadcast to the local unicast MAC.
65 @param IpSb The IP4 service binding instance that received the
67 @param Dst The destination address in the packet (host byte
69 @param Src The source address in the packet (host byte order)
71 @return The cast type for the Dst, it will return on the first non-promiscuous
72 @return cast type to a configured interface. If the packet doesn't match any of
73 @return the interface, multicast address and local broadcast address are checked.
90 if (IpSb
->MnpConfigData
.EnablePromiscuousReceive
) {
91 Type
= IP4_PROMISCUOUS
;
95 // Go through the interface list of the IP service, most likely.
97 NET_LIST_FOR_EACH (Entry
, &IpSb
->Interfaces
) {
98 IpIf
= NET_LIST_USER_STRUCT (Entry
, IP4_INTERFACE
, Link
);
101 // Skip the unconfigured interface and invalid source address:
102 // source address can't be broadcast.
104 if (!IpIf
->Configured
|| IP4_IS_BROADCAST (Ip4GetNetCast (Src
, IpIf
))) {
108 if ((Class
= Ip4GetNetCast (Dst
, IpIf
)) > Type
) {
114 // If it is local broadcast address. The source address must
115 // be a unicast address on one of the direct connected network.
116 // If it is a multicast address, accept it only if we are in
119 if (Dst
== IP4_ALLONE_ADDRESS
) {
120 IpIf
= Ip4FindNet (IpSb
, Src
);
122 if (IpIf
&& !IP4_IS_BROADCAST (Ip4GetNetCast (Src
, IpIf
))) {
123 return IP4_LOCAL_BROADCAST
;
126 } else if (IP4_IS_MULTICAST (Dst
) && Ip4FindGroup (&IpSb
->IgmpCtrl
, Dst
)) {
127 return IP4_MULTICAST
;
135 Find an interface whose configured IP address is Ip
137 @param IpSb The IP4 service binding instance
138 @param Ip The Ip address (host byte order) to find
140 @return The IP4_INTERFACE point if found, otherwise NULL
145 IN IP4_SERVICE
*IpSb
,
152 NET_LIST_FOR_EACH (Entry
, &IpSb
->Interfaces
) {
153 IpIf
= NET_LIST_USER_STRUCT (Entry
, IP4_INTERFACE
, Link
);
155 if (IpIf
->Configured
&& (IpIf
->Ip
== Ip
)) {
165 Find an interface that Ip is on that connected network.
167 @param IpSb The IP4 service binding instance
168 @param Ip The Ip address (host byte order) to find
170 @return The IP4_INTERFACE point if found, otherwise NULL
175 IN IP4_SERVICE
*IpSb
,
182 NET_LIST_FOR_EACH (Entry
, &IpSb
->Interfaces
) {
183 IpIf
= NET_LIST_USER_STRUCT (Entry
, IP4_INTERFACE
, Link
);
185 if (IpIf
->Configured
&& IP4_NET_EQUAL (Ip
, IpIf
->Ip
, IpIf
->SubnetMask
)) {
195 Find an interface of the service with the same Ip/Netmask pair.
197 @param IpSb Ip4 service binding instance
198 @param Ip The Ip adress to find (host byte order)
199 @param Netmask The network to find (host byte order)
201 @return The IP4_INTERFACE point if found, otherwise NULL
205 Ip4FindStationAddress (
206 IN IP4_SERVICE
*IpSb
,
214 NET_LIST_FOR_EACH (Entry
, &IpSb
->Interfaces
) {
215 IpIf
= NET_LIST_USER_STRUCT (Entry
, IP4_INTERFACE
, Link
);
217 if (IpIf
->Configured
&& (IpIf
->Ip
== Ip
) && (IpIf
->SubnetMask
== Netmask
)) {
227 Get the MAC address for a multicast IP address. Call
228 Mnp's McastIpToMac to find the MAC address in stead of
229 hard code the NIC to be Ethernet.
231 @param Mnp The Mnp instance to get the MAC address.
232 @param Multicast The multicast IP address to translate.
233 @param Mac The buffer to hold the translated address.
235 @return Returns EFI_SUCCESS if the multicast IP is successfully
236 @return translated to a multicast MAC address. Otherwise some error.
241 IN EFI_MANAGED_NETWORK_PROTOCOL
*Mnp
,
242 IN IP4_ADDR Multicast
,
243 OUT EFI_MAC_ADDRESS
*Mac
246 EFI_IP_ADDRESS EfiIp
;
248 EFI_IP4 (EfiIp
.v4
) = HTONL (Multicast
);
249 return Mnp
->McastIpToMac (Mnp
, FALSE
, &EfiIp
, Mac
);
254 Convert the multibyte field in IP header's byter order.
255 In spite of its name, it can also be used to convert from
256 host to network byte order.
258 @param Head The IP head to convert
260 @return Point to the converted IP head
268 Head
->TotalLen
= NTOHS (Head
->TotalLen
);
269 Head
->Id
= NTOHS (Head
->Id
);
270 Head
->Fragment
= NTOHS (Head
->Fragment
);
271 Head
->Src
= NTOHL (Head
->Src
);
272 Head
->Dst
= NTOHL (Head
->Dst
);
279 Set the Ip4 variable data.
281 @param IpSb Ip4 service binding instance
283 @retval EFI_OUT_OF_RESOURCES There are not enough resources to set the variable.
284 @retval other Set variable failed.
292 UINT32 NumConfiguredInstance
;
294 UINTN VariableDataSize
;
295 EFI_IP4_VARIABLE_DATA
*Ip4VariableData
;
296 EFI_IP4_ADDRESS_PAIR
*Ip4AddressPair
;
297 IP4_PROTOCOL
*IpInstance
;
298 CHAR16
*NewMacString
;
301 NumConfiguredInstance
= 0;
304 // Go through the children list to count the configured children.
306 NET_LIST_FOR_EACH (Entry
, &IpSb
->Children
) {
307 IpInstance
= NET_LIST_USER_STRUCT_S (Entry
, IP4_PROTOCOL
, Link
, IP4_PROTOCOL_SIGNATURE
);
309 if (IpInstance
->State
== IP4_STATE_CONFIGED
) {
310 NumConfiguredInstance
++;
315 // Calculate the size of the Ip4VariableData. As there may be no IP child,
316 // we should add extra buffer for the address paris only if the number of configured
317 // children is more than 1.
319 VariableDataSize
= sizeof (EFI_IP4_VARIABLE_DATA
);
321 if (NumConfiguredInstance
> 1) {
322 VariableDataSize
+= sizeof (EFI_IP4_ADDRESS_PAIR
) * (NumConfiguredInstance
- 1);
325 Ip4VariableData
= AllocatePool (VariableDataSize
);
326 if (Ip4VariableData
== NULL
) {
327 return EFI_OUT_OF_RESOURCES
;
330 Ip4VariableData
->DriverHandle
= IpSb
->Image
;
331 Ip4VariableData
->AddressCount
= NumConfiguredInstance
;
333 Ip4AddressPair
= &Ip4VariableData
->AddressPairs
[0];
336 // Go through the children list to fill the configured children's address pairs.
338 NET_LIST_FOR_EACH (Entry
, &IpSb
->Children
) {
339 IpInstance
= NET_LIST_USER_STRUCT_S (Entry
, IP4_PROTOCOL
, Link
, IP4_PROTOCOL_SIGNATURE
);
341 if (IpInstance
->State
== IP4_STATE_CONFIGED
) {
342 Ip4AddressPair
->InstanceHandle
= IpInstance
->Handle
;
343 EFI_IP4 (Ip4AddressPair
->Ip4Address
) = NTOHL (IpInstance
->Interface
->Ip
);
344 EFI_IP4 (Ip4AddressPair
->SubnetMask
) = NTOHL (IpInstance
->Interface
->SubnetMask
);
351 // Get the mac string.
353 Status
= NetLibGetMacString (IpSb
->Controller
, IpSb
->Image
, &NewMacString
);
354 if (EFI_ERROR (Status
)) {
358 if (IpSb
->MacString
!= NULL
) {
360 // The variable is set already, we're going to update it.
362 if (StrCmp (IpSb
->MacString
, NewMacString
) != 0) {
364 // The mac address is changed, delete the previous variable first.
368 &gEfiIp4ServiceBindingProtocolGuid
,
369 EFI_VARIABLE_BOOTSERVICE_ACCESS
,
375 gBS
->FreePool (IpSb
->MacString
);
378 IpSb
->MacString
= NewMacString
;
380 Status
= gRT
->SetVariable (
382 &gEfiIp4ServiceBindingProtocolGuid
,
383 EFI_VARIABLE_BOOTSERVICE_ACCESS
,
385 (VOID
*) Ip4VariableData
390 gBS
->FreePool (Ip4VariableData
);
397 Clear the variable and free the resource.
399 @param IpSb Ip4 service binding instance
405 Ip4ClearVariableData (
409 ASSERT (IpSb
->MacString
!= NULL
);
413 &gEfiIp4ServiceBindingProtocolGuid
,
414 EFI_VARIABLE_BOOTSERVICE_ACCESS
,
419 gBS
->FreePool (IpSb
->MacString
);
420 IpSb
->MacString
= NULL
;