+++ /dev/null
-/** @file\r
-\r
-Copyright (c) 2005 - 2017, Intel Corporation. All rights reserved.<BR>\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "Ip4Impl.h"\r
-\r
-\r
-/**\r
- Return the cast type (Unicast/Boradcast) specific to an\r
- interface. All the addresses are host byte ordered.\r
-\r
- @param[in] IpAddr The IP address to classify in host byte order\r
- @param[in] IpIf The interface that IpAddr received from\r
-\r
- @return The cast type of this IP address specific to the interface.\r
- @retval IP4_LOCAL_HOST The IpAddr equals to the interface's address\r
- @retval IP4_SUBNET_BROADCAST The IpAddr is a directed subnet boradcast to the\r
- interface\r
- @retval IP4_NET_BROADCAST The IpAddr is a network broadcast to the interface\r
- @retval 0 Otherwise.\r
-\r
-**/\r
-INTN\r
-Ip4GetNetCast (\r
- IN IP4_ADDR IpAddr,\r
- IN IP4_INTERFACE *IpIf\r
- )\r
-{\r
- if (IpAddr == IpIf->Ip) {\r
- return IP4_LOCAL_HOST;\r
-\r
- } else if (IpAddr == IpIf->SubnetBrdcast) {\r
- return IP4_SUBNET_BROADCAST;\r
-\r
- } else if (IpAddr == IpIf->NetBrdcast) {\r
- return IP4_NET_BROADCAST;\r
-\r
- }\r
-\r
- return 0;\r
-}\r
-\r
-\r
-/**\r
- Find the cast type of the packet related to the local host.\r
- This isn't the same as link layer cast type. For example, DHCP\r
- server may send local broadcast to the local unicast MAC.\r
-\r
- @param[in] IpSb The IP4 service binding instance that received the\r
- packet\r
- @param[in] Dst The destination address in the packet (host byte\r
- order)\r
- @param[in] Src The source address in the packet (host byte order)\r
-\r
- @return The cast type for the Dst, it will return on the first non-promiscuous\r
- cast type to a configured interface. If the packet doesn't match any of\r
- the interface, multicast address and local broadcast address are checked.\r
-\r
-**/\r
-INTN\r
-Ip4GetHostCast (\r
- IN IP4_SERVICE *IpSb,\r
- IN IP4_ADDR Dst,\r
- IN IP4_ADDR Src\r
- )\r
-{\r
- LIST_ENTRY *Entry;\r
- IP4_INTERFACE *IpIf;\r
- INTN Type;\r
- INTN Class;\r
-\r
- Type = 0;\r
-\r
- if (IpSb->MnpConfigData.EnablePromiscuousReceive) {\r
- Type = IP4_PROMISCUOUS;\r
- }\r
-\r
- //\r
- // Go through the interface list of the IP service, most likely.\r
- //\r
- NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) {\r
- IpIf = NET_LIST_USER_STRUCT (Entry, IP4_INTERFACE, Link);\r
-\r
- //\r
- // Skip the unconfigured interface and invalid source address:\r
- // source address can't be broadcast.\r
- //\r
- if (!IpIf->Configured || IP4_IS_BROADCAST (Ip4GetNetCast (Src, IpIf))) {\r
- continue;\r
- }\r
-\r
- if ((Class = Ip4GetNetCast (Dst, IpIf)) > Type) {\r
- return Class;\r
- }\r
- }\r
-\r
- //\r
- // If it is local broadcast address. The source address must\r
- // be a unicast address on one of the direct connected network.\r
- // If it is a multicast address, accept it only if we are in\r
- // the group.\r
- //\r
- if (Dst == IP4_ALLONE_ADDRESS) {\r
- IpIf = Ip4FindNet (IpSb, Src);\r
-\r
- if (IpIf != NULL && !IP4_IS_BROADCAST (Ip4GetNetCast (Src, IpIf))) {\r
- return IP4_LOCAL_BROADCAST;\r
- }\r
-\r
- } else if (IP4_IS_MULTICAST (Dst) && Ip4FindGroup (&IpSb->IgmpCtrl, Dst) != NULL) {\r
- return IP4_MULTICAST;\r
- }\r
-\r
- return Type;\r
-}\r
-\r
-\r
-/**\r
- Find an interface whose configured IP address is Ip.\r
-\r
- @param[in] IpSb The IP4 service binding instance\r
- @param[in] Ip The Ip address (host byte order) to find\r
-\r
- @return The IP4_INTERFACE point if found, otherwise NULL\r
-\r
-**/\r
-IP4_INTERFACE *\r
-Ip4FindInterface (\r
- IN IP4_SERVICE *IpSb,\r
- IN IP4_ADDR Ip\r
- )\r
-{\r
- LIST_ENTRY *Entry;\r
- IP4_INTERFACE *IpIf;\r
-\r
- NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) {\r
- IpIf = NET_LIST_USER_STRUCT (Entry, IP4_INTERFACE, Link);\r
-\r
- if (IpIf->Configured && (IpIf->Ip == Ip)) {\r
- return IpIf;\r
- }\r
- }\r
-\r
- return NULL;\r
-}\r
-\r
-\r
-/**\r
- Find an interface that Ip is on that connected network.\r
-\r
- @param[in] IpSb The IP4 service binding instance\r
- @param[in] Ip The Ip address (host byte order) to find\r
-\r
- @return The IP4_INTERFACE point if found, otherwise NULL\r
-\r
-**/\r
-IP4_INTERFACE *\r
-Ip4FindNet (\r
- IN IP4_SERVICE *IpSb,\r
- IN IP4_ADDR Ip\r
- )\r
-{\r
- LIST_ENTRY *Entry;\r
- IP4_INTERFACE *IpIf;\r
-\r
- NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) {\r
- IpIf = NET_LIST_USER_STRUCT (Entry, IP4_INTERFACE, Link);\r
-\r
- if (IpIf->Configured && IP4_NET_EQUAL (Ip, IpIf->Ip, IpIf->SubnetMask)) {\r
- return IpIf;\r
- }\r
- }\r
-\r
- return NULL;\r
-}\r
-\r
-\r
-/**\r
- Find an interface of the service with the same Ip/Netmask pair.\r
-\r
- @param[in] IpSb Ip4 service binding instance\r
- @param[in] Ip The Ip adress to find (host byte order)\r
- @param[in] Netmask The network to find (host byte order)\r
-\r
- @return The IP4_INTERFACE point if found, otherwise NULL\r
-\r
-**/\r
-IP4_INTERFACE *\r
-Ip4FindStationAddress (\r
- IN IP4_SERVICE *IpSb,\r
- IN IP4_ADDR Ip,\r
- IN IP4_ADDR Netmask\r
- )\r
-{\r
- LIST_ENTRY *Entry;\r
- IP4_INTERFACE *IpIf;\r
-\r
- NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) {\r
- IpIf = NET_LIST_USER_STRUCT (Entry, IP4_INTERFACE, Link);\r
-\r
- if (IpIf->Configured && (IpIf->Ip == Ip) && (IpIf->SubnetMask == Netmask)) {\r
- return IpIf;\r
- }\r
- }\r
-\r
- return NULL;\r
-}\r
-\r
-\r
-/**\r
- Get the MAC address for a multicast IP address. Call\r
- Mnp's McastIpToMac to find the MAC address in stead of\r
- hard code the NIC to be Ethernet.\r
-\r
- @param[in] Mnp The Mnp instance to get the MAC address.\r
- @param[in] Multicast The multicast IP address to translate.\r
- @param[out] Mac The buffer to hold the translated address.\r
-\r
- @retval EFI_SUCCESS if the multicast IP is successfully translated to a\r
- multicast MAC address.\r
- @retval other Otherwise some error.\r
-\r
-**/\r
-EFI_STATUS\r
-Ip4GetMulticastMac (\r
- IN EFI_MANAGED_NETWORK_PROTOCOL *Mnp,\r
- IN IP4_ADDR Multicast,\r
- OUT EFI_MAC_ADDRESS *Mac\r
- )\r
-{\r
- EFI_IP_ADDRESS EfiIp;\r
-\r
- EFI_IP4 (EfiIp.v4) = HTONL (Multicast);\r
- return Mnp->McastIpToMac (Mnp, FALSE, &EfiIp, Mac);\r
-}\r
-\r
-\r
-/**\r
- Convert the multibyte field in IP header's byter order.\r
- In spite of its name, it can also be used to convert from\r
- host to network byte order.\r
-\r
- @param[in] Head The IP head to convert\r
-\r
- @return Point to the converted IP head\r
-\r
-**/\r
-IP4_HEAD *\r
-Ip4NtohHead (\r
- IN IP4_HEAD *Head\r
- )\r
-{\r
- Head->TotalLen = NTOHS (Head->TotalLen);\r
- Head->Id = NTOHS (Head->Id);\r
- Head->Fragment = NTOHS (Head->Fragment);\r
- Head->Src = NTOHL (Head->Src);\r
- Head->Dst = NTOHL (Head->Dst);\r
-\r
- return Head;\r
-}\r
-\r
-\r
-/**\r
- Validate that Ip/Netmask pair is OK to be used as station\r
- address. Only continuous netmasks are supported. and check\r
- that StationAddress is a unicast address on the newtwork.\r
-\r
- @param[in] Ip The IP address to validate.\r
- @param[in] Netmask The netmaks of the IP.\r
-\r
- @retval TRUE The Ip/Netmask pair is valid.\r
- @retval FALSE The Ip/Netmask pair is invalid.\r
-\r
-**/\r
-BOOLEAN\r
-Ip4StationAddressValid (\r
- IN IP4_ADDR Ip,\r
- IN IP4_ADDR Netmask\r
- )\r
-{\r
- //\r
- // Only support the station address with 0.0.0.0/0 to enable DHCP client.\r
- //\r
- if (Netmask == IP4_ALLZERO_ADDRESS) {\r
- return (BOOLEAN) (Ip == IP4_ALLZERO_ADDRESS);\r
- }\r
-\r
- //\r
- // Only support the continuous net masks\r
- //\r
- if (NetGetMaskLength (Netmask) == (IP4_MASK_MAX + 1)) {\r
- return FALSE;\r
- }\r
-\r
- //\r
- // Station address can't be class D or class E address\r
- //\r
- if (NetGetIpClass (Ip) > IP4_ADDR_CLASSC) {\r
- return FALSE;\r
- }\r
-\r
- return NetIp4IsUnicast (Ip, Netmask);\r
-}\r