NetworkPkg: Move Network library and drivers from MdeModulePkg to NetworkPkg
authorLiming Gao <liming.gao@intel.com>
Wed, 15 May 2019 12:02:18 +0000 (20:02 +0800)
committerLiming Gao <liming.gao@intel.com>
Mon, 27 May 2019 01:25:18 +0000 (09:25 +0800)
Signed-off-by: Liming Gao <liming.gao@intel.com>
Cc: Siyuan Fu <siyuan.fu@intel.com>
Cc: Jiaxin Wu <jiaxin.wu@intel.com>
Reviewed-by: Jiaxin Wu <jiaxin.wu@intel.com>
Reviewed-by: Siyuan Fu <siyuan.fu@intel.com>
291 files changed:
MdeModulePkg/Library/DxeDpcLib/DpcLib.c [deleted file]
MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf [deleted file]
MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.uni [deleted file]
MdeModulePkg/Library/DxeHttpLib/DxeHttpLib.c [deleted file]
MdeModulePkg/Library/DxeHttpLib/DxeHttpLib.h [deleted file]
MdeModulePkg/Library/DxeHttpLib/DxeHttpLib.inf [deleted file]
MdeModulePkg/Library/DxeHttpLib/DxeHttpLib.uni [deleted file]
MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.c [deleted file]
MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf [deleted file]
MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.uni [deleted file]
MdeModulePkg/Library/DxeNetLib/DxeNetLib.c [deleted file]
MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf [deleted file]
MdeModulePkg/Library/DxeNetLib/DxeNetLib.uni [deleted file]
MdeModulePkg/Library/DxeNetLib/NetBuffer.c [deleted file]
MdeModulePkg/Library/DxeTcpIoLib/DxeTcpIoLib.c [deleted file]
MdeModulePkg/Library/DxeTcpIoLib/DxeTcpIoLib.inf [deleted file]
MdeModulePkg/Library/DxeTcpIoLib/DxeTcpIoLib.uni [deleted file]
MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.c [deleted file]
MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf [deleted file]
MdeModulePkg/Library/DxeUdpIoLib/DxeUpdIoLib.uni [deleted file]
MdeModulePkg/Universal/Network/ArpDxe/ArpDriver.c [deleted file]
MdeModulePkg/Universal/Network/ArpDxe/ArpDriver.h [deleted file]
MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.inf [deleted file]
MdeModulePkg/Universal/Network/ArpDxe/ArpDxe.uni [deleted file]
MdeModulePkg/Universal/Network/ArpDxe/ArpDxeExtra.uni [deleted file]
MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.c [deleted file]
MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.h [deleted file]
MdeModulePkg/Universal/Network/ArpDxe/ArpMain.c [deleted file]
MdeModulePkg/Universal/Network/ArpDxe/ComponentName.c [deleted file]
MdeModulePkg/Universal/Network/Dhcp4Dxe/ComponentName.c [deleted file]
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Driver.c [deleted file]
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Driver.h [deleted file]
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.inf [deleted file]
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Dxe.uni [deleted file]
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4DxeExtra.uni [deleted file]
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.c [deleted file]
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.h [deleted file]
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Io.c [deleted file]
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Io.h [deleted file]
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Option.c [deleted file]
MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Option.h [deleted file]
MdeModulePkg/Universal/Network/DpcDxe/Dpc.c [deleted file]
MdeModulePkg/Universal/Network/DpcDxe/Dpc.h [deleted file]
MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.inf [deleted file]
MdeModulePkg/Universal/Network/DpcDxe/DpcDxe.uni [deleted file]
MdeModulePkg/Universal/Network/DpcDxe/DpcDxeExtra.uni [deleted file]
MdeModulePkg/Universal/Network/Ip4Dxe/ComponentName.c [deleted file]
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Common.c [deleted file]
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Common.h [deleted file]
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2.vfr [deleted file]
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.c [deleted file]
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Impl.h [deleted file]
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Nv.c [deleted file]
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Config2Nv.h [deleted file]
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c [deleted file]
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.h [deleted file]
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.inf [deleted file]
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Dxe.uni [deleted file]
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4DxeExtra.uni [deleted file]
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4DxeStrings.uni [deleted file]
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Icmp.c [deleted file]
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Icmp.h [deleted file]
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4If.c [deleted file]
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4If.h [deleted file]
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Igmp.c [deleted file]
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Igmp.h [deleted file]
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.c [deleted file]
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h [deleted file]
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c [deleted file]
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.h [deleted file]
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4NvData.h [deleted file]
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Option.c [deleted file]
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Option.h [deleted file]
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.c [deleted file]
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Output.h [deleted file]
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Route.c [deleted file]
MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Route.h [deleted file]
MdeModulePkg/Universal/Network/MnpDxe/ComponentName.c [deleted file]
MdeModulePkg/Universal/Network/MnpDxe/ComponentName.h [deleted file]
MdeModulePkg/Universal/Network/MnpDxe/MnpConfig.c [deleted file]
MdeModulePkg/Universal/Network/MnpDxe/MnpDriver.c [deleted file]
MdeModulePkg/Universal/Network/MnpDxe/MnpDriver.h [deleted file]
MdeModulePkg/Universal/Network/MnpDxe/MnpDxe.inf [deleted file]
MdeModulePkg/Universal/Network/MnpDxe/MnpDxe.uni [deleted file]
MdeModulePkg/Universal/Network/MnpDxe/MnpDxeExtra.uni [deleted file]
MdeModulePkg/Universal/Network/MnpDxe/MnpImpl.h [deleted file]
MdeModulePkg/Universal/Network/MnpDxe/MnpIo.c [deleted file]
MdeModulePkg/Universal/Network/MnpDxe/MnpMain.c [deleted file]
MdeModulePkg/Universal/Network/MnpDxe/MnpVlan.c [deleted file]
MdeModulePkg/Universal/Network/MnpDxe/MnpVlan.h [deleted file]
MdeModulePkg/Universal/Network/Mtftp4Dxe/ComponentName.c [deleted file]
MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.c [deleted file]
MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.h [deleted file]
MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.inf [deleted file]
MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Dxe.uni [deleted file]
MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4DxeExtra.uni [deleted file]
MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c [deleted file]
MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.h [deleted file]
MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Option.c [deleted file]
MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Option.h [deleted file]
MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Rrq.c [deleted file]
MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Support.c [deleted file]
MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Support.h [deleted file]
MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Wrq.c [deleted file]
MdeModulePkg/Universal/Network/SnpDxe/Callback.c [deleted file]
MdeModulePkg/Universal/Network/SnpDxe/ComponentName.c [deleted file]
MdeModulePkg/Universal/Network/SnpDxe/Get_status.c [deleted file]
MdeModulePkg/Universal/Network/SnpDxe/Initialize.c [deleted file]
MdeModulePkg/Universal/Network/SnpDxe/Mcast_ip_to_mac.c [deleted file]
MdeModulePkg/Universal/Network/SnpDxe/Nvdata.c [deleted file]
MdeModulePkg/Universal/Network/SnpDxe/Receive.c [deleted file]
MdeModulePkg/Universal/Network/SnpDxe/Receive_filters.c [deleted file]
MdeModulePkg/Universal/Network/SnpDxe/Reset.c [deleted file]
MdeModulePkg/Universal/Network/SnpDxe/Shutdown.c [deleted file]
MdeModulePkg/Universal/Network/SnpDxe/Snp.c [deleted file]
MdeModulePkg/Universal/Network/SnpDxe/Snp.h [deleted file]
MdeModulePkg/Universal/Network/SnpDxe/SnpDxe.inf [deleted file]
MdeModulePkg/Universal/Network/SnpDxe/SnpDxe.uni [deleted file]
MdeModulePkg/Universal/Network/SnpDxe/SnpDxeExtra.uni [deleted file]
MdeModulePkg/Universal/Network/SnpDxe/Start.c [deleted file]
MdeModulePkg/Universal/Network/SnpDxe/Station_address.c [deleted file]
MdeModulePkg/Universal/Network/SnpDxe/Statistics.c [deleted file]
MdeModulePkg/Universal/Network/SnpDxe/Stop.c [deleted file]
MdeModulePkg/Universal/Network/SnpDxe/Transmit.c [deleted file]
MdeModulePkg/Universal/Network/SnpDxe/WaitForPacket.c [deleted file]
MdeModulePkg/Universal/Network/Udp4Dxe/ComponentName.c [deleted file]
MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Driver.c [deleted file]
MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Driver.h [deleted file]
MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.inf [deleted file]
MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Dxe.uni [deleted file]
MdeModulePkg/Universal/Network/Udp4Dxe/Udp4DxeExtra.uni [deleted file]
MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.c [deleted file]
MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.h [deleted file]
MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Main.c [deleted file]
MdeModulePkg/Universal/Network/VlanConfigDxe/ComponentName.c [deleted file]
MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfig.vfr [deleted file]
MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigDriver.c [deleted file]
MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigDxe.inf [deleted file]
MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigDxe.uni [deleted file]
MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigDxeExtra.uni [deleted file]
MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigImpl.c [deleted file]
MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigImpl.h [deleted file]
MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigNvData.h [deleted file]
MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigStrings.uni [deleted file]
NetworkPkg/ArpDxe/ArpDriver.c [new file with mode: 0644]
NetworkPkg/ArpDxe/ArpDriver.h [new file with mode: 0644]
NetworkPkg/ArpDxe/ArpDxe.inf [new file with mode: 0644]
NetworkPkg/ArpDxe/ArpDxe.uni [new file with mode: 0644]
NetworkPkg/ArpDxe/ArpDxeExtra.uni [new file with mode: 0644]
NetworkPkg/ArpDxe/ArpImpl.c [new file with mode: 0644]
NetworkPkg/ArpDxe/ArpImpl.h [new file with mode: 0644]
NetworkPkg/ArpDxe/ArpMain.c [new file with mode: 0644]
NetworkPkg/ArpDxe/ComponentName.c [new file with mode: 0644]
NetworkPkg/Dhcp4Dxe/ComponentName.c [new file with mode: 0644]
NetworkPkg/Dhcp4Dxe/Dhcp4Driver.c [new file with mode: 0644]
NetworkPkg/Dhcp4Dxe/Dhcp4Driver.h [new file with mode: 0644]
NetworkPkg/Dhcp4Dxe/Dhcp4Dxe.inf [new file with mode: 0644]
NetworkPkg/Dhcp4Dxe/Dhcp4Dxe.uni [new file with mode: 0644]
NetworkPkg/Dhcp4Dxe/Dhcp4DxeExtra.uni [new file with mode: 0644]
NetworkPkg/Dhcp4Dxe/Dhcp4Impl.c [new file with mode: 0644]
NetworkPkg/Dhcp4Dxe/Dhcp4Impl.h [new file with mode: 0644]
NetworkPkg/Dhcp4Dxe/Dhcp4Io.c [new file with mode: 0644]
NetworkPkg/Dhcp4Dxe/Dhcp4Io.h [new file with mode: 0644]
NetworkPkg/Dhcp4Dxe/Dhcp4Option.c [new file with mode: 0644]
NetworkPkg/Dhcp4Dxe/Dhcp4Option.h [new file with mode: 0644]
NetworkPkg/DpcDxe/Dpc.c [new file with mode: 0644]
NetworkPkg/DpcDxe/Dpc.h [new file with mode: 0644]
NetworkPkg/DpcDxe/DpcDxe.inf [new file with mode: 0644]
NetworkPkg/DpcDxe/DpcDxe.uni [new file with mode: 0644]
NetworkPkg/DpcDxe/DpcDxeExtra.uni [new file with mode: 0644]
NetworkPkg/Ip4Dxe/ComponentName.c [new file with mode: 0644]
NetworkPkg/Ip4Dxe/Ip4Common.c [new file with mode: 0644]
NetworkPkg/Ip4Dxe/Ip4Common.h [new file with mode: 0644]
NetworkPkg/Ip4Dxe/Ip4Config2.vfr [new file with mode: 0644]
NetworkPkg/Ip4Dxe/Ip4Config2Impl.c [new file with mode: 0644]
NetworkPkg/Ip4Dxe/Ip4Config2Impl.h [new file with mode: 0644]
NetworkPkg/Ip4Dxe/Ip4Config2Nv.c [new file with mode: 0644]
NetworkPkg/Ip4Dxe/Ip4Config2Nv.h [new file with mode: 0644]
NetworkPkg/Ip4Dxe/Ip4Driver.c [new file with mode: 0644]
NetworkPkg/Ip4Dxe/Ip4Driver.h [new file with mode: 0644]
NetworkPkg/Ip4Dxe/Ip4Dxe.inf [new file with mode: 0644]
NetworkPkg/Ip4Dxe/Ip4Dxe.uni [new file with mode: 0644]
NetworkPkg/Ip4Dxe/Ip4DxeExtra.uni [new file with mode: 0644]
NetworkPkg/Ip4Dxe/Ip4DxeStrings.uni [new file with mode: 0644]
NetworkPkg/Ip4Dxe/Ip4Icmp.c [new file with mode: 0644]
NetworkPkg/Ip4Dxe/Ip4Icmp.h [new file with mode: 0644]
NetworkPkg/Ip4Dxe/Ip4If.c [new file with mode: 0644]
NetworkPkg/Ip4Dxe/Ip4If.h [new file with mode: 0644]
NetworkPkg/Ip4Dxe/Ip4Igmp.c [new file with mode: 0644]
NetworkPkg/Ip4Dxe/Ip4Igmp.h [new file with mode: 0644]
NetworkPkg/Ip4Dxe/Ip4Impl.c [new file with mode: 0644]
NetworkPkg/Ip4Dxe/Ip4Impl.h [new file with mode: 0644]
NetworkPkg/Ip4Dxe/Ip4Input.c [new file with mode: 0644]
NetworkPkg/Ip4Dxe/Ip4Input.h [new file with mode: 0644]
NetworkPkg/Ip4Dxe/Ip4NvData.h [new file with mode: 0644]
NetworkPkg/Ip4Dxe/Ip4Option.c [new file with mode: 0644]
NetworkPkg/Ip4Dxe/Ip4Option.h [new file with mode: 0644]
NetworkPkg/Ip4Dxe/Ip4Output.c [new file with mode: 0644]
NetworkPkg/Ip4Dxe/Ip4Output.h [new file with mode: 0644]
NetworkPkg/Ip4Dxe/Ip4Route.c [new file with mode: 0644]
NetworkPkg/Ip4Dxe/Ip4Route.h [new file with mode: 0644]
NetworkPkg/Library/DxeDpcLib/DpcLib.c [new file with mode: 0644]
NetworkPkg/Library/DxeDpcLib/DxeDpcLib.inf [new file with mode: 0644]
NetworkPkg/Library/DxeDpcLib/DxeDpcLib.uni [new file with mode: 0644]
NetworkPkg/Library/DxeHttpLib/DxeHttpLib.c [new file with mode: 0644]
NetworkPkg/Library/DxeHttpLib/DxeHttpLib.h [new file with mode: 0644]
NetworkPkg/Library/DxeHttpLib/DxeHttpLib.inf [new file with mode: 0644]
NetworkPkg/Library/DxeHttpLib/DxeHttpLib.uni [new file with mode: 0644]
NetworkPkg/Library/DxeIpIoLib/DxeIpIoLib.c [new file with mode: 0644]
NetworkPkg/Library/DxeIpIoLib/DxeIpIoLib.inf [new file with mode: 0644]
NetworkPkg/Library/DxeIpIoLib/DxeIpIoLib.uni [new file with mode: 0644]
NetworkPkg/Library/DxeNetLib/DxeNetLib.c [new file with mode: 0644]
NetworkPkg/Library/DxeNetLib/DxeNetLib.inf [new file with mode: 0644]
NetworkPkg/Library/DxeNetLib/DxeNetLib.uni [new file with mode: 0644]
NetworkPkg/Library/DxeNetLib/NetBuffer.c [new file with mode: 0644]
NetworkPkg/Library/DxeTcpIoLib/DxeTcpIoLib.c [new file with mode: 0644]
NetworkPkg/Library/DxeTcpIoLib/DxeTcpIoLib.inf [new file with mode: 0644]
NetworkPkg/Library/DxeTcpIoLib/DxeTcpIoLib.uni [new file with mode: 0644]
NetworkPkg/Library/DxeUdpIoLib/DxeUdpIoLib.c [new file with mode: 0644]
NetworkPkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf [new file with mode: 0644]
NetworkPkg/Library/DxeUdpIoLib/DxeUpdIoLib.uni [new file with mode: 0644]
NetworkPkg/MnpDxe/ComponentName.c [new file with mode: 0644]
NetworkPkg/MnpDxe/ComponentName.h [new file with mode: 0644]
NetworkPkg/MnpDxe/MnpConfig.c [new file with mode: 0644]
NetworkPkg/MnpDxe/MnpDriver.c [new file with mode: 0644]
NetworkPkg/MnpDxe/MnpDriver.h [new file with mode: 0644]
NetworkPkg/MnpDxe/MnpDxe.inf [new file with mode: 0644]
NetworkPkg/MnpDxe/MnpDxe.uni [new file with mode: 0644]
NetworkPkg/MnpDxe/MnpDxeExtra.uni [new file with mode: 0644]
NetworkPkg/MnpDxe/MnpImpl.h [new file with mode: 0644]
NetworkPkg/MnpDxe/MnpIo.c [new file with mode: 0644]
NetworkPkg/MnpDxe/MnpMain.c [new file with mode: 0644]
NetworkPkg/MnpDxe/MnpVlan.c [new file with mode: 0644]
NetworkPkg/MnpDxe/MnpVlan.h [new file with mode: 0644]
NetworkPkg/Mtftp4Dxe/ComponentName.c [new file with mode: 0644]
NetworkPkg/Mtftp4Dxe/Mtftp4Driver.c [new file with mode: 0644]
NetworkPkg/Mtftp4Dxe/Mtftp4Driver.h [new file with mode: 0644]
NetworkPkg/Mtftp4Dxe/Mtftp4Dxe.inf [new file with mode: 0644]
NetworkPkg/Mtftp4Dxe/Mtftp4Dxe.uni [new file with mode: 0644]
NetworkPkg/Mtftp4Dxe/Mtftp4DxeExtra.uni [new file with mode: 0644]
NetworkPkg/Mtftp4Dxe/Mtftp4Impl.c [new file with mode: 0644]
NetworkPkg/Mtftp4Dxe/Mtftp4Impl.h [new file with mode: 0644]
NetworkPkg/Mtftp4Dxe/Mtftp4Option.c [new file with mode: 0644]
NetworkPkg/Mtftp4Dxe/Mtftp4Option.h [new file with mode: 0644]
NetworkPkg/Mtftp4Dxe/Mtftp4Rrq.c [new file with mode: 0644]
NetworkPkg/Mtftp4Dxe/Mtftp4Support.c [new file with mode: 0644]
NetworkPkg/Mtftp4Dxe/Mtftp4Support.h [new file with mode: 0644]
NetworkPkg/Mtftp4Dxe/Mtftp4Wrq.c [new file with mode: 0644]
NetworkPkg/Network.fdf.inc
NetworkPkg/NetworkComponents.dsc.inc
NetworkPkg/NetworkLibs.dsc.inc
NetworkPkg/SnpDxe/Callback.c [new file with mode: 0644]
NetworkPkg/SnpDxe/ComponentName.c [new file with mode: 0644]
NetworkPkg/SnpDxe/Get_status.c [new file with mode: 0644]
NetworkPkg/SnpDxe/Initialize.c [new file with mode: 0644]
NetworkPkg/SnpDxe/Mcast_ip_to_mac.c [new file with mode: 0644]
NetworkPkg/SnpDxe/Nvdata.c [new file with mode: 0644]
NetworkPkg/SnpDxe/Receive.c [new file with mode: 0644]
NetworkPkg/SnpDxe/Receive_filters.c [new file with mode: 0644]
NetworkPkg/SnpDxe/Reset.c [new file with mode: 0644]
NetworkPkg/SnpDxe/Shutdown.c [new file with mode: 0644]
NetworkPkg/SnpDxe/Snp.c [new file with mode: 0644]
NetworkPkg/SnpDxe/Snp.h [new file with mode: 0644]
NetworkPkg/SnpDxe/SnpDxe.inf [new file with mode: 0644]
NetworkPkg/SnpDxe/SnpDxe.uni [new file with mode: 0644]
NetworkPkg/SnpDxe/SnpDxeExtra.uni [new file with mode: 0644]
NetworkPkg/SnpDxe/Start.c [new file with mode: 0644]
NetworkPkg/SnpDxe/Station_address.c [new file with mode: 0644]
NetworkPkg/SnpDxe/Statistics.c [new file with mode: 0644]
NetworkPkg/SnpDxe/Stop.c [new file with mode: 0644]
NetworkPkg/SnpDxe/Transmit.c [new file with mode: 0644]
NetworkPkg/SnpDxe/WaitForPacket.c [new file with mode: 0644]
NetworkPkg/Udp4Dxe/ComponentName.c [new file with mode: 0644]
NetworkPkg/Udp4Dxe/Udp4Driver.c [new file with mode: 0644]
NetworkPkg/Udp4Dxe/Udp4Driver.h [new file with mode: 0644]
NetworkPkg/Udp4Dxe/Udp4Dxe.inf [new file with mode: 0644]
NetworkPkg/Udp4Dxe/Udp4Dxe.uni [new file with mode: 0644]
NetworkPkg/Udp4Dxe/Udp4DxeExtra.uni [new file with mode: 0644]
NetworkPkg/Udp4Dxe/Udp4Impl.c [new file with mode: 0644]
NetworkPkg/Udp4Dxe/Udp4Impl.h [new file with mode: 0644]
NetworkPkg/Udp4Dxe/Udp4Main.c [new file with mode: 0644]
NetworkPkg/VlanConfigDxe/ComponentName.c [new file with mode: 0644]
NetworkPkg/VlanConfigDxe/VlanConfig.vfr [new file with mode: 0644]
NetworkPkg/VlanConfigDxe/VlanConfigDriver.c [new file with mode: 0644]
NetworkPkg/VlanConfigDxe/VlanConfigDxe.inf [new file with mode: 0644]
NetworkPkg/VlanConfigDxe/VlanConfigDxe.uni [new file with mode: 0644]
NetworkPkg/VlanConfigDxe/VlanConfigDxeExtra.uni [new file with mode: 0644]
NetworkPkg/VlanConfigDxe/VlanConfigImpl.c [new file with mode: 0644]
NetworkPkg/VlanConfigDxe/VlanConfigImpl.h [new file with mode: 0644]
NetworkPkg/VlanConfigDxe/VlanConfigNvData.h [new file with mode: 0644]
NetworkPkg/VlanConfigDxe/VlanConfigStrings.uni [new file with mode: 0644]

diff --git a/MdeModulePkg/Library/DxeDpcLib/DpcLib.c b/MdeModulePkg/Library/DxeDpcLib/DpcLib.c
deleted file mode 100644 (file)
index 29d8107..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-/** @file\r
-  Help functions to access UDP service.\r
-\r
-Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-**/\r
-\r
-#include <Uefi.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Protocol/Dpc.h>\r
-\r
-//\r
-// Pointer to the DPC Protocol\r
-//\r
-EFI_DPC_PROTOCOL  *mDpc;\r
-\r
-/**\r
-  This constructor function caches the EFI_DPC_PROTOCOL pointer.\r
-\r
-  @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
-  @param[in] SystemTable A pointer to the EFI System Table.\r
-\r
-  @retval EFI_SUCCESS The constructor always return EFI_SUCCESS.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-DpcLibConstructor (\r
-  IN EFI_HANDLE        ImageHandle,\r
-  IN EFI_SYSTEM_TABLE  *SystemTable\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-\r
-  //\r
-  // Locate the EFI_DPC_PROTOCOL in the handle database\r
-  //\r
-  Status = gBS->LocateProtocol (&gEfiDpcProtocolGuid, NULL, (VOID **)&mDpc);\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Add a Deferred Procedure Call to the end of the DPC queue.\r
-\r
-  @param[in]  DpcTpl        The EFI_TPL that the DPC should be invoked.\r
-  @param[in]  DpcProcedure  Pointer to the DPC's function.\r
-  @param[in]  DpcContext    Pointer to the DPC's context.  Passed to DpcProcedure\r
-                            when DpcProcedure is invoked.\r
-\r
-  @retval EFI_SUCCESS            The DPC was queued.\r
-  @retval EFI_INVALID_PARAMETER  DpcTpl is not a valid EFI_TPL.\r
-  @retval EFI_INVALID_PARAMETER  DpcProcedure is NULL.\r
-  @retval EFI_OUT_OF_RESOURCES   There are not enough resources available to\r
-                                 add the DPC to the queue.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-QueueDpc (\r
-  IN EFI_TPL            DpcTpl,\r
-  IN EFI_DPC_PROCEDURE  DpcProcedure,\r
-  IN VOID               *DpcContext    OPTIONAL\r
-  )\r
-{\r
-  //\r
-  // Call the EFI_DPC_PROTOCOL to queue the DPC\r
-  //\r
-  return mDpc->QueueDpc (mDpc, DpcTpl, DpcProcedure, DpcContext);\r
-}\r
-\r
-/**\r
-  Dispatch the queue of DPCs.  ALL DPCs that have been queued with a DpcTpl\r
-  value greater than or equal to the current TPL are invoked in the order that\r
-  they were queued.  DPCs with higher DpcTpl values are invoked before DPCs with\r
-  lower DpcTpl values.\r
-\r
-  @retval EFI_SUCCESS    One or more DPCs were invoked.\r
-  @retval EFI_NOT_FOUND  No DPCs were invoked.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-DispatchDpc (\r
-  VOID\r
-  )\r
-{\r
-  //\r
-  // Call the EFI_DPC_PROTOCOL to dispatch previously queued DPCs\r
-  //\r
-  return mDpc->DispatchDpc (mDpc);\r
-}\r
diff --git a/MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf b/MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
deleted file mode 100644 (file)
index 1c23729..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-## @file\r
-#  This library instance provides DPC service by consuming EFI DPC Protocol.\r
-#\r
-#  Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
-#  SPDX-License-Identifier: BSD-2-Clause-Patent\r
-#\r
-##\r
-\r
-[Defines]\r
-  INF_VERSION                    = 0x00010005\r
-  BASE_NAME                      = DxeDpcLib\r
-  MODULE_UNI_FILE                = DxeDpcLib.uni\r
-  FILE_GUID                      = 38897D86-FF36-4472-AE64-1DB9AE715C81\r
-  MODULE_TYPE                    = DXE_DRIVER\r
-  VERSION_STRING                 = 1.0\r
-  LIBRARY_CLASS                  = DpcLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER\r
-  CONSTRUCTOR                    = DpcLibConstructor\r
-\r
-#\r
-# The following information is for reference only and not required by the build tools.\r
-#\r
-#  VALID_ARCHITECTURES           = IA32 X64 EBC\r
-#\r
-\r
-[Sources]\r
-  DpcLib.c\r
-\r
-[Packages]\r
-  MdePkg/MdePkg.dec\r
-  MdeModulePkg/MdeModulePkg.dec\r
-\r
-[LibraryClasses]\r
-  DebugLib\r
-  UefiBootServicesTableLib\r
-\r
-[Protocols]\r
-  gEfiDpcProtocolGuid                  ## CONSUMES\r
-\r
-[Depex.common.DXE_DRIVER, Depex.common.DXE_RUNTIME_DRIVER, Depex.common.DXE_SAL_DRIVER, Depex.common.DXE_SMM_DRIVER]\r
-  gEfiDpcProtocolGuid\r
diff --git a/MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.uni b/MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.uni
deleted file mode 100644 (file)
index 3105bbc..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// /** @file\r
-// This library instance provides DPC service by consuming EFI DPC Protocol.\r
-//\r
-// This library instance provides the DPC service by consuming EFI DPC Protocol.\r
-//\r
-// Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
-//\r
-// SPDX-License-Identifier: BSD-2-Clause-Patent\r
-//\r
-// **/\r
-\r
-\r
-#string STR_MODULE_ABSTRACT             #language en-US "Provides the DPC service by consuming EFI DPC Protocol"\r
-\r
-#string STR_MODULE_DESCRIPTION          #language en-US "This library instance provides the DPC service by consuming EFI DPC Protocol."\r
-\r
diff --git a/MdeModulePkg/Library/DxeHttpLib/DxeHttpLib.c b/MdeModulePkg/Library/DxeHttpLib/DxeHttpLib.c
deleted file mode 100644 (file)
index 8b74554..0000000
+++ /dev/null
@@ -1,2084 +0,0 @@
-/** @file\r
-  This library is used to share code between UEFI network stack modules.\r
-  It provides the helper routines to parse the HTTP message byte stream.\r
-\r
-Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>\r
-(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "DxeHttpLib.h"\r
-\r
-\r
-\r
-/**\r
-  Decode a percent-encoded URI component to the ASCII character.\r
-\r
-  Decode the input component in Buffer according to RFC 3986. The caller is responsible to make\r
-  sure ResultBuffer points to a buffer with size equal or greater than ((AsciiStrSize (Buffer))\r
-  in bytes.\r
-\r
-  @param[in]    Buffer           The pointer to a percent-encoded URI component.\r
-  @param[in]    BufferLength     Length of Buffer in bytes.\r
-  @param[out]   ResultBuffer     Point to the buffer to store the decode result.\r
-  @param[out]   ResultLength     Length of decoded string in ResultBuffer in bytes.\r
-\r
-  @retval EFI_SUCCESS            Successfully decoded the URI.\r
-  @retval EFI_INVALID_PARAMETER  Buffer is not a valid percent-encoded string.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-UriPercentDecode (\r
-  IN      CHAR8            *Buffer,\r
-  IN      UINT32            BufferLength,\r
-     OUT  CHAR8            *ResultBuffer,\r
-     OUT  UINT32           *ResultLength\r
-  )\r
-{\r
-  UINTN           Index;\r
-  UINTN           Offset;\r
-  CHAR8           HexStr[3];\r
-\r
-  if (Buffer == NULL || BufferLength == 0 || ResultBuffer == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  Index = 0;\r
-  Offset = 0;\r
-  HexStr[2] = '\0';\r
-  while (Index < BufferLength) {\r
-    if (Buffer[Index] == '%') {\r
-      if (Index + 1 >= BufferLength || Index + 2 >= BufferLength ||\r
-          !NET_IS_HEX_CHAR (Buffer[Index+1]) || !NET_IS_HEX_CHAR (Buffer[Index+2])) {\r
-        return EFI_INVALID_PARAMETER;\r
-      }\r
-      HexStr[0] = Buffer[Index+1];\r
-      HexStr[1] = Buffer[Index+2];\r
-      ResultBuffer[Offset] = (CHAR8) AsciiStrHexToUintn (HexStr);\r
-      Index += 3;\r
-    } else {\r
-      ResultBuffer[Offset] = Buffer[Index];\r
-      Index++;\r
-    }\r
-    Offset++;\r
-  }\r
-\r
-  *ResultLength = (UINT32) Offset;\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  This function return the updated state according to the input state and next character of\r
-  the authority.\r
-\r
-  @param[in]       Char           Next character.\r
-  @param[in]       State          Current value of the parser state machine.\r
-  @param[in]       IsRightBracket TRUE if there is an sign ']' in the authority component and\r
-                                  indicates the next part is ':' before Port.\r
-\r
-  @return          Updated state value.\r
-**/\r
-HTTP_URL_PARSE_STATE\r
-NetHttpParseAuthorityChar (\r
-  IN  CHAR8                  Char,\r
-  IN  HTTP_URL_PARSE_STATE   State,\r
-  IN  BOOLEAN                *IsRightBracket\r
-  )\r
-{\r
-\r
-  //\r
-  // RFC 3986:\r
-  // The authority component is preceded by a double slash ("//") and is\r
-  // terminated by the next slash ("/"), question mark ("?"), or number\r
-  // sign ("#") character, or by the end of the URI.\r
-  //\r
-  if (Char == ' ' || Char == '\r' || Char == '\n') {\r
-    return UrlParserStateMax;\r
-  }\r
-\r
-  //\r
-  // authority   = [ userinfo "@" ] host [ ":" port ]\r
-  //\r
-  switch (State) {\r
-  case UrlParserUserInfo:\r
-    if (Char == '@') {\r
-      return UrlParserHostStart;\r
-    }\r
-    break;\r
-\r
-  case UrlParserHost:\r
-  case UrlParserHostStart:\r
-    if (Char == '[') {\r
-      return UrlParserHostIpv6;\r
-    }\r
-\r
-    if (Char == ':') {\r
-      return UrlParserPortStart;\r
-    }\r
-\r
-    return UrlParserHost;\r
-\r
-  case UrlParserHostIpv6:\r
-    if (Char == ']') {\r
-      *IsRightBracket = TRUE;\r
-    }\r
-\r
-    if (Char == ':' && *IsRightBracket) {\r
-      return UrlParserPortStart;\r
-    }\r
-    return UrlParserHostIpv6;\r
-\r
-  case UrlParserPort:\r
-  case UrlParserPortStart:\r
-    return UrlParserPort;\r
-\r
-  default:\r
-    break;\r
-  }\r
-\r
-  return State;\r
-}\r
-\r
-/**\r
-  This function parse the authority component of the input URL and update the parser.\r
-\r
-  @param[in]       Url            The pointer to a HTTP URL string.\r
-  @param[in]       FoundAt        TRUE if there is an at sign ('@') in the authority component.\r
-  @param[in, out]  UrlParser      Pointer to the buffer of the parse result.\r
-\r
-  @retval EFI_SUCCESS             Successfully parse the authority.\r
-  @retval EFI_INVALID_PARAMETER   The Url is invalid to parse the authority component.\r
-\r
-**/\r
-EFI_STATUS\r
-NetHttpParseAuthority (\r
-  IN      CHAR8              *Url,\r
-  IN      BOOLEAN            FoundAt,\r
-  IN OUT  HTTP_URL_PARSER    *UrlParser\r
-  )\r
-{\r
-  CHAR8                 *Char;\r
-  CHAR8                 *Authority;\r
-  UINT32                Length;\r
-  HTTP_URL_PARSE_STATE  State;\r
-  UINT32                Field;\r
-  UINT32                OldField;\r
-  BOOLEAN               IsrightBracket;\r
-\r
-  ASSERT ((UrlParser->FieldBitMap & BIT (HTTP_URI_FIELD_AUTHORITY)) != 0);\r
-\r
-  //\r
-  // authority   = [ userinfo "@" ] host [ ":" port ]\r
-  //\r
-  if (FoundAt) {\r
-    State = UrlParserUserInfo;\r
-  } else {\r
-    State = UrlParserHost;\r
-  }\r
-\r
-  IsrightBracket = FALSE;\r
-  Field = HTTP_URI_FIELD_MAX;\r
-  OldField = Field;\r
-  Authority = Url + UrlParser->FieldData[HTTP_URI_FIELD_AUTHORITY].Offset;\r
-  Length = UrlParser->FieldData[HTTP_URI_FIELD_AUTHORITY].Length;\r
-  for (Char = Authority; Char < Authority + Length; Char++) {\r
-    State = NetHttpParseAuthorityChar (*Char, State, &IsrightBracket);\r
-    switch (State) {\r
-    case UrlParserStateMax:\r
-      return EFI_INVALID_PARAMETER;\r
-\r
-    case UrlParserHostStart:\r
-    case UrlParserPortStart:\r
-      continue;\r
-\r
-    case UrlParserUserInfo:\r
-      Field = HTTP_URI_FIELD_USERINFO;\r
-      break;\r
-\r
-    case UrlParserHost:\r
-      Field = HTTP_URI_FIELD_HOST;\r
-      break;\r
-\r
-    case UrlParserHostIpv6:\r
-      Field = HTTP_URI_FIELD_HOST;\r
-      break;\r
-\r
-    case UrlParserPort:\r
-      Field = HTTP_URI_FIELD_PORT;\r
-      break;\r
-\r
-    default:\r
-      ASSERT (FALSE);\r
-    }\r
-\r
-    //\r
-    // Field not changed, count the length.\r
-    //\r
-    ASSERT (Field < HTTP_URI_FIELD_MAX);\r
-    if (Field == OldField) {\r
-      UrlParser->FieldData[Field].Length++;\r
-      continue;\r
-    }\r
-\r
-    //\r
-    // New field start\r
-    //\r
-    UrlParser->FieldBitMap |= BIT (Field);\r
-    UrlParser->FieldData[Field].Offset = (UINT32) (Char - Url);\r
-    UrlParser->FieldData[Field].Length = 1;\r
-    OldField = Field;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  This function return the updated state according to the input state and next character of a URL.\r
-\r
-  @param[in]       Char           Next character.\r
-  @param[in]       State          Current value of the parser state machine.\r
-\r
-  @return          Updated state value.\r
-\r
-**/\r
-HTTP_URL_PARSE_STATE\r
-NetHttpParseUrlChar (\r
-  IN  CHAR8                  Char,\r
-  IN  HTTP_URL_PARSE_STATE   State\r
-  )\r
-{\r
-  if (Char == ' ' || Char == '\r' || Char == '\n') {\r
-    return UrlParserStateMax;\r
-  }\r
-\r
-  //\r
-  // http_URL = "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]]\r
-  //\r
-  // Request-URI    = "*" | absolute-URI | path-absolute | authority\r
-  //\r
-  // absolute-URI  = scheme ":" hier-part [ "?" query ]\r
-  // path-absolute = "/" [ segment-nz *( "/" segment ) ]\r
-  // authority   = [ userinfo "@" ] host [ ":" port ]\r
-  //\r
-  switch (State) {\r
-  case UrlParserUrlStart:\r
-    if (Char == '*' || Char == '/') {\r
-      return UrlParserPath;\r
-    }\r
-    return UrlParserScheme;\r
-\r
-  case UrlParserScheme:\r
-    if (Char == ':') {\r
-      return UrlParserSchemeColon;\r
-    }\r
-    break;\r
-\r
-  case UrlParserSchemeColon:\r
-    if (Char == '/') {\r
-      return UrlParserSchemeColonSlash;\r
-    }\r
-    break;\r
-\r
-  case UrlParserSchemeColonSlash:\r
-    if (Char == '/') {\r
-      return UrlParserSchemeColonSlashSlash;\r
-    }\r
-    break;\r
-\r
-  case UrlParserAtInAuthority:\r
-    if (Char == '@') {\r
-      return UrlParserStateMax;\r
-    }\r
-\r
-  case UrlParserAuthority:\r
-  case UrlParserSchemeColonSlashSlash:\r
-    if (Char == '@') {\r
-      return UrlParserAtInAuthority;\r
-    }\r
-    if (Char == '/') {\r
-      return UrlParserPath;\r
-    }\r
-    if (Char == '?') {\r
-      return UrlParserQueryStart;\r
-    }\r
-    if (Char == '#') {\r
-      return UrlParserFragmentStart;\r
-    }\r
-    return UrlParserAuthority;\r
-\r
-  case UrlParserPath:\r
-    if (Char == '?') {\r
-      return UrlParserQueryStart;\r
-    }\r
-    if (Char == '#') {\r
-      return UrlParserFragmentStart;\r
-    }\r
-    break;\r
-\r
-  case UrlParserQuery:\r
-  case UrlParserQueryStart:\r
-    if (Char == '#') {\r
-      return UrlParserFragmentStart;\r
-    }\r
-    return UrlParserQuery;\r
-\r
-  case UrlParserFragmentStart:\r
-    return UrlParserFragment;\r
-\r
-  default:\r
-    break;\r
-  }\r
-\r
-  return State;\r
-}\r
-/**\r
-  Create a URL parser for the input URL string.\r
-\r
-  This function will parse and dereference the input HTTP URL into it components. The original\r
-  content of the URL won't be modified and the result will be returned in UrlParser, which can\r
-  be used in other functions like NetHttpUrlGetHostName().\r
-\r
-  @param[in]    Url                The pointer to a HTTP URL string.\r
-  @param[in]    Length             Length of Url in bytes.\r
-  @param[in]    IsConnectMethod    Whether the Url is used in HTTP CONNECT method or not.\r
-  @param[out]   UrlParser          Pointer to the returned buffer to store the parse result.\r
-\r
-  @retval EFI_SUCCESS              Successfully dereferenced the HTTP URL.\r
-  @retval EFI_INVALID_PARAMETER    UrlParser is NULL or Url is not a valid HTTP URL.\r
-  @retval EFI_OUT_OF_RESOURCES     Could not allocate needed resources.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-HttpParseUrl (\r
-  IN      CHAR8              *Url,\r
-  IN      UINT32             Length,\r
-  IN      BOOLEAN            IsConnectMethod,\r
-     OUT  VOID               **UrlParser\r
-  )\r
-{\r
-  HTTP_URL_PARSE_STATE  State;\r
-  CHAR8                 *Char;\r
-  UINT32                Field;\r
-  UINT32                OldField;\r
-  BOOLEAN               FoundAt;\r
-  EFI_STATUS            Status;\r
-  HTTP_URL_PARSER       *Parser;\r
-\r
-  Parser = NULL;\r
-\r
-  if (Url == NULL || Length == 0 || UrlParser == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  Parser = AllocateZeroPool (sizeof (HTTP_URL_PARSER));\r
-  if (Parser == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  if (IsConnectMethod) {\r
-    //\r
-    // According to RFC 2616, the authority form is only used by the CONNECT method.\r
-    //\r
-    State = UrlParserAuthority;\r
-  } else {\r
-    State = UrlParserUrlStart;\r
-  }\r
-\r
-  Field = HTTP_URI_FIELD_MAX;\r
-  OldField = Field;\r
-  FoundAt = FALSE;\r
-  for (Char = Url; Char < Url + Length; Char++) {\r
-    //\r
-    // Update state machine according to next char.\r
-    //\r
-    State = NetHttpParseUrlChar (*Char, State);\r
-\r
-    switch (State) {\r
-    case UrlParserStateMax:\r
-      FreePool (Parser);\r
-      return EFI_INVALID_PARAMETER;\r
-\r
-    case UrlParserSchemeColon:\r
-    case UrlParserSchemeColonSlash:\r
-    case UrlParserSchemeColonSlashSlash:\r
-    case UrlParserQueryStart:\r
-    case UrlParserFragmentStart:\r
-      //\r
-      // Skip all the delimiting char: "://" "?" "@"\r
-      //\r
-      continue;\r
-\r
-    case UrlParserScheme:\r
-      Field = HTTP_URI_FIELD_SCHEME;\r
-      break;\r
-\r
-    case UrlParserAtInAuthority:\r
-      FoundAt = TRUE;\r
-    case UrlParserAuthority:\r
-      Field = HTTP_URI_FIELD_AUTHORITY;\r
-      break;\r
-\r
-    case UrlParserPath:\r
-      Field = HTTP_URI_FIELD_PATH;\r
-      break;\r
-\r
-    case UrlParserQuery:\r
-      Field = HTTP_URI_FIELD_QUERY;\r
-      break;\r
-\r
-    case UrlParserFragment:\r
-      Field = HTTP_URI_FIELD_FRAGMENT;\r
-      break;\r
-\r
-    default:\r
-      ASSERT (FALSE);\r
-    }\r
-\r
-    //\r
-    // Field not changed, count the length.\r
-    //\r
-    ASSERT (Field < HTTP_URI_FIELD_MAX);\r
-    if (Field == OldField) {\r
-      Parser->FieldData[Field].Length++;\r
-      continue;\r
-    }\r
-\r
-    //\r
-    // New field start\r
-    //\r
-    Parser->FieldBitMap |= BIT (Field);\r
-    Parser->FieldData[Field].Offset = (UINT32) (Char - Url);\r
-    Parser->FieldData[Field].Length = 1;\r
-    OldField = Field;\r
-  }\r
-\r
-  //\r
-  // If has authority component, continue to parse the username, host and port.\r
-  //\r
-  if ((Parser->FieldBitMap & BIT (HTTP_URI_FIELD_AUTHORITY)) != 0) {\r
-    Status = NetHttpParseAuthority (Url, FoundAt, Parser);\r
-    if (EFI_ERROR (Status)) {\r
-      FreePool (Parser);\r
-      return Status;\r
-    }\r
-  }\r
-\r
-  *UrlParser = Parser;\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Get the Hostname from a HTTP URL.\r
-\r
-  This function will return the HostName according to the Url and previous parse result ,and\r
-  it is the caller's responsibility to free the buffer returned in *HostName.\r
-\r
-  @param[in]    Url                The pointer to a HTTP URL string.\r
-  @param[in]    UrlParser          URL Parse result returned by NetHttpParseUrl().\r
-  @param[out]   HostName           Pointer to a buffer to store the HostName.\r
-\r
-  @retval EFI_SUCCESS              Successfully get the required component.\r
-  @retval EFI_INVALID_PARAMETER    Uri is NULL or HostName is NULL or UrlParser is invalid.\r
-  @retval EFI_NOT_FOUND            No hostName component in the URL.\r
-  @retval EFI_OUT_OF_RESOURCES     Could not allocate needed resources.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-HttpUrlGetHostName (\r
-  IN      CHAR8              *Url,\r
-  IN      VOID               *UrlParser,\r
-     OUT  CHAR8              **HostName\r
-  )\r
-{\r
-  CHAR8                *Name;\r
-  EFI_STATUS           Status;\r
-  UINT32               ResultLength;\r
-  HTTP_URL_PARSER      *Parser;\r
-\r
-  if (Url == NULL || UrlParser == NULL || HostName == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  Parser = (HTTP_URL_PARSER *) UrlParser;\r
-\r
-  if ((Parser->FieldBitMap & BIT (HTTP_URI_FIELD_HOST)) == 0) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  Name = AllocatePool (Parser->FieldData[HTTP_URI_FIELD_HOST].Length + 1);\r
-  if (Name == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  Status = UriPercentDecode (\r
-             Url + Parser->FieldData[HTTP_URI_FIELD_HOST].Offset,\r
-             Parser->FieldData[HTTP_URI_FIELD_HOST].Length,\r
-             Name,\r
-             &ResultLength\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    FreePool (Name);\r
-    return Status;\r
-  }\r
-\r
-  Name[ResultLength] = '\0';\r
-  *HostName = Name;\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
-  Get the IPv4 address from a HTTP URL.\r
-\r
-  This function will return the IPv4 address according to the Url and previous parse result.\r
-\r
-  @param[in]    Url                The pointer to a HTTP URL string.\r
-  @param[in]    UrlParser          URL Parse result returned by NetHttpParseUrl().\r
-  @param[out]   Ip4Address         Pointer to a buffer to store the IP address.\r
-\r
-  @retval EFI_SUCCESS              Successfully get the required component.\r
-  @retval EFI_INVALID_PARAMETER    Uri is NULL or Ip4Address is NULL or UrlParser is invalid.\r
-  @retval EFI_NOT_FOUND            No IPv4 address component in the URL.\r
-  @retval EFI_OUT_OF_RESOURCES     Could not allocate needed resources.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-HttpUrlGetIp4 (\r
-  IN      CHAR8              *Url,\r
-  IN      VOID               *UrlParser,\r
-     OUT  EFI_IPv4_ADDRESS   *Ip4Address\r
-  )\r
-{\r
-  CHAR8                *Ip4String;\r
-  EFI_STATUS           Status;\r
-  UINT32               ResultLength;\r
-  HTTP_URL_PARSER      *Parser;\r
-\r
-  if (Url == NULL || UrlParser == NULL || Ip4Address == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  Parser = (HTTP_URL_PARSER *) UrlParser;\r
-\r
-  if ((Parser->FieldBitMap & BIT (HTTP_URI_FIELD_HOST)) == 0) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  Ip4String = AllocatePool (Parser->FieldData[HTTP_URI_FIELD_HOST].Length + 1);\r
-  if (Ip4String == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  Status = UriPercentDecode (\r
-             Url + Parser->FieldData[HTTP_URI_FIELD_HOST].Offset,\r
-             Parser->FieldData[HTTP_URI_FIELD_HOST].Length,\r
-             Ip4String,\r
-             &ResultLength\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    FreePool (Ip4String);\r
-    return Status;\r
-  }\r
-\r
-  Ip4String[ResultLength] = '\0';\r
-  Status = NetLibAsciiStrToIp4 (Ip4String, Ip4Address);\r
-  FreePool (Ip4String);\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Get the IPv6 address from a HTTP URL.\r
-\r
-  This function will return the IPv6 address according to the Url and previous parse result.\r
-\r
-  @param[in]    Url                The pointer to a HTTP URL string.\r
-  @param[in]    UrlParser          URL Parse result returned by NetHttpParseUrl().\r
-  @param[out]   Ip6Address         Pointer to a buffer to store the IP address.\r
-\r
-  @retval EFI_SUCCESS              Successfully get the required component.\r
-  @retval EFI_INVALID_PARAMETER    Uri is NULL or Ip6Address is NULL or UrlParser is invalid.\r
-  @retval EFI_NOT_FOUND            No IPv6 address component in the URL.\r
-  @retval EFI_OUT_OF_RESOURCES     Could not allocate needed resources.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-HttpUrlGetIp6 (\r
-  IN      CHAR8              *Url,\r
-  IN      VOID               *UrlParser,\r
-     OUT  EFI_IPv6_ADDRESS   *Ip6Address\r
-  )\r
-{\r
-  CHAR8                *Ip6String;\r
-  CHAR8                *Ptr;\r
-  UINT32               Length;\r
-  EFI_STATUS           Status;\r
-  UINT32               ResultLength;\r
-  HTTP_URL_PARSER      *Parser;\r
-\r
-  if (Url == NULL || UrlParser == NULL || Ip6Address == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  Parser = (HTTP_URL_PARSER *) UrlParser;\r
-\r
-  if ((Parser->FieldBitMap & BIT (HTTP_URI_FIELD_HOST)) == 0) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  //\r
-  // IP-literal = "[" ( IPv6address / IPvFuture  ) "]"\r
-  //\r
-  Length = Parser->FieldData[HTTP_URI_FIELD_HOST].Length;\r
-  if (Length < 2) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  Ptr    = Url + Parser->FieldData[HTTP_URI_FIELD_HOST].Offset;\r
-  if ((Ptr[0] != '[') || (Ptr[Length - 1] != ']')) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  Ip6String = AllocatePool (Length);\r
-  if (Ip6String == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  Status = UriPercentDecode (\r
-             Ptr + 1,\r
-             Length - 2,\r
-             Ip6String,\r
-             &ResultLength\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    FreePool (Ip6String);\r
-    return Status;\r
-  }\r
-\r
-  Ip6String[ResultLength] = '\0';\r
-  Status = NetLibAsciiStrToIp6 (Ip6String, Ip6Address);\r
-  FreePool (Ip6String);\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Get the port number from a HTTP URL.\r
-\r
-  This function will return the port number according to the Url and previous parse result.\r
-\r
-  @param[in]    Url                The pointer to a HTTP URL string.\r
-  @param[in]    UrlParser          URL Parse result returned by NetHttpParseUrl().\r
-  @param[out]   Port               Pointer to a buffer to store the port number.\r
-\r
-  @retval EFI_SUCCESS              Successfully get the required component.\r
-  @retval EFI_INVALID_PARAMETER    Uri is NULL or Port is NULL or UrlParser is invalid.\r
-  @retval EFI_NOT_FOUND            No port number in the URL.\r
-  @retval EFI_OUT_OF_RESOURCES     Could not allocate needed resources.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-HttpUrlGetPort (\r
-  IN      CHAR8              *Url,\r
-  IN      VOID               *UrlParser,\r
-     OUT  UINT16             *Port\r
-  )\r
-{\r
-  CHAR8                *PortString;\r
-  EFI_STATUS           Status;\r
-  UINTN                Index;\r
-  UINTN                Data;\r
-  UINT32               ResultLength;\r
-  HTTP_URL_PARSER      *Parser;\r
-\r
-  if (Url == NULL || UrlParser == NULL || Port == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  *Port = 0;\r
-  Index = 0;\r
-\r
-  Parser = (HTTP_URL_PARSER *) UrlParser;\r
-\r
-  if ((Parser->FieldBitMap & BIT (HTTP_URI_FIELD_PORT)) == 0) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  PortString = AllocatePool (Parser->FieldData[HTTP_URI_FIELD_PORT].Length + 1);\r
-  if (PortString == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  Status = UriPercentDecode (\r
-             Url + Parser->FieldData[HTTP_URI_FIELD_PORT].Offset,\r
-             Parser->FieldData[HTTP_URI_FIELD_PORT].Length,\r
-             PortString,\r
-             &ResultLength\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    goto ON_EXIT;\r
-  }\r
-\r
-  PortString[ResultLength] = '\0';\r
-\r
-  while (Index < ResultLength) {\r
-    if (!NET_IS_DIGIT (PortString[Index])) {\r
-      Status = EFI_INVALID_PARAMETER;\r
-      goto ON_EXIT;\r
-    }\r
-    Index ++;\r
-  }\r
-\r
-  Status =  AsciiStrDecimalToUintnS (Url + Parser->FieldData[HTTP_URI_FIELD_PORT].Offset, (CHAR8 **) NULL, &Data);\r
-\r
-  if (Data > HTTP_URI_PORT_MAX_NUM) {\r
-    Status = EFI_INVALID_PARAMETER;\r
-    goto ON_EXIT;\r
-  }\r
-\r
-  *Port = (UINT16) Data;\r
-\r
-ON_EXIT:\r
-  FreePool (PortString);\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Get the Path from a HTTP URL.\r
-\r
-  This function will return the Path according to the Url and previous parse result,and\r
-  it is the caller's responsibility to free the buffer returned in *Path.\r
-\r
-  @param[in]    Url                The pointer to a HTTP URL string.\r
-  @param[in]    UrlParser          URL Parse result returned by NetHttpParseUrl().\r
-  @param[out]   Path               Pointer to a buffer to store the Path.\r
-\r
-  @retval EFI_SUCCESS              Successfully get the required component.\r
-  @retval EFI_INVALID_PARAMETER    Uri is NULL or HostName is NULL or UrlParser is invalid.\r
-  @retval EFI_NOT_FOUND            No hostName component in the URL.\r
-  @retval EFI_OUT_OF_RESOURCES     Could not allocate needed resources.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-HttpUrlGetPath (\r
-  IN      CHAR8              *Url,\r
-  IN      VOID               *UrlParser,\r
-     OUT  CHAR8              **Path\r
-  )\r
-{\r
-  CHAR8                *PathStr;\r
-  EFI_STATUS           Status;\r
-  UINT32               ResultLength;\r
-  HTTP_URL_PARSER      *Parser;\r
-\r
-  if (Url == NULL || UrlParser == NULL || Path == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  Parser = (HTTP_URL_PARSER *) UrlParser;\r
-\r
-  if ((Parser->FieldBitMap & BIT (HTTP_URI_FIELD_PATH)) == 0) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  PathStr = AllocatePool (Parser->FieldData[HTTP_URI_FIELD_PATH].Length + 1);\r
-  if (PathStr == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  Status = UriPercentDecode (\r
-             Url + Parser->FieldData[HTTP_URI_FIELD_PATH].Offset,\r
-             Parser->FieldData[HTTP_URI_FIELD_PATH].Length,\r
-             PathStr,\r
-             &ResultLength\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    FreePool (PathStr);\r
-    return Status;\r
-  }\r
-\r
-  PathStr[ResultLength] = '\0';\r
-  *Path = PathStr;\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Release the resource of the URL parser.\r
-\r
-  @param[in]    UrlParser            Pointer to the parser.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-HttpUrlFreeParser (\r
-  IN      VOID               *UrlParser\r
-  )\r
-{\r
-  FreePool (UrlParser);\r
-}\r
-\r
-/**\r
-  Find a specified header field according to the field name.\r
-\r
-  @param[in]   HeaderCount      Number of HTTP header structures in Headers list.\r
-  @param[in]   Headers          Array containing list of HTTP headers.\r
-  @param[in]   FieldName        Null terminated string which describes a field name.\r
-\r
-  @return    Pointer to the found header or NULL.\r
-\r
-**/\r
-EFI_HTTP_HEADER *\r
-EFIAPI\r
-HttpFindHeader (\r
-  IN  UINTN                HeaderCount,\r
-  IN  EFI_HTTP_HEADER      *Headers,\r
-  IN  CHAR8                *FieldName\r
-  )\r
-{\r
-  UINTN                 Index;\r
-\r
-  if (HeaderCount == 0 || Headers == NULL || FieldName == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  for (Index = 0; Index < HeaderCount; Index++){\r
-    //\r
-    // Field names are case-insensitive (RFC 2616).\r
-    //\r
-    if (AsciiStriCmp (Headers[Index].FieldName, FieldName) == 0) {\r
-      return &Headers[Index];\r
-    }\r
-  }\r
-  return NULL;\r
-}\r
-\r
-typedef enum {\r
-  BodyParserBodyStart,\r
-  BodyParserBodyIdentity,\r
-  BodyParserChunkSizeStart,\r
-  BodyParserChunkSize,\r
-  BodyParserChunkSizeEndCR,\r
-  BodyParserChunkExtStart,\r
-  BodyParserChunkDataStart,\r
-  BodyParserChunkDataEnd,\r
-  BodyParserChunkDataEndCR,\r
-  BodyParserTrailer,\r
-  BodyParserLastCRLF,\r
-  BodyParserLastCRLFEnd,\r
-  BodyParserComplete,\r
-  BodyParserStateMax\r
-} HTTP_BODY_PARSE_STATE;\r
-\r
-typedef struct {\r
-  BOOLEAN                       IgnoreBody;    // "MUST NOT" include a message-body\r
-  BOOLEAN                       IsChunked;     // "chunked" transfer-coding.\r
-  BOOLEAN                       ContentLengthIsValid;\r
-  UINTN                         ContentLength; // Entity length (not the message-body length), invalid until ContentLengthIsValid is TRUE\r
-\r
-  HTTP_BODY_PARSER_CALLBACK     Callback;\r
-  VOID                          *Context;\r
-  UINTN                         ParsedBodyLength;\r
-  HTTP_BODY_PARSE_STATE         State;\r
-  UINTN                         CurrentChunkSize;\r
-  UINTN                         CurrentChunkParsedSize;\r
-} HTTP_BODY_PARSER;\r
-\r
-/**\r
-  Convert an hexadecimal char to a value of type UINTN.\r
-\r
-  @param[in]       Char           Ascii character.\r
-\r
-  @return          Value translated from Char.\r
-\r
-**/\r
-UINTN\r
-HttpIoHexCharToUintn (\r
-  IN CHAR8           Char\r
-  )\r
-{\r
-  if (Char >= '0' && Char <= '9') {\r
-    return Char - '0';\r
-  }\r
-\r
-  return (10 + AsciiCharToUpper (Char) - 'A');\r
-}\r
-\r
-/**\r
-  Get the value of the content length if there is a "Content-Length" header.\r
-\r
-  @param[in]    HeaderCount        Number of HTTP header structures in Headers.\r
-  @param[in]    Headers            Array containing list of HTTP headers.\r
-  @param[out]   ContentLength      Pointer to save the value of the content length.\r
-\r
-  @retval EFI_SUCCESS              Successfully get the content length.\r
-  @retval EFI_NOT_FOUND            No "Content-Length" header in the Headers.\r
-\r
-**/\r
-EFI_STATUS\r
-HttpIoParseContentLengthHeader (\r
-  IN     UINTN                HeaderCount,\r
-  IN     EFI_HTTP_HEADER      *Headers,\r
-     OUT UINTN                *ContentLength\r
-  )\r
-{\r
-  EFI_HTTP_HEADER       *Header;\r
-\r
-  Header = HttpFindHeader (HeaderCount, Headers, HTTP_HEADER_CONTENT_LENGTH);\r
-  if (Header == NULL) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  return AsciiStrDecimalToUintnS (Header->FieldValue, (CHAR8 **) NULL, ContentLength);\r
-}\r
-\r
-/**\r
-\r
-  Check whether the HTTP message is using the "chunked" transfer-coding.\r
-\r
-  @param[in]    HeaderCount        Number of HTTP header structures in Headers.\r
-  @param[in]    Headers            Array containing list of HTTP headers.\r
-\r
-  @return       The message is "chunked" transfer-coding (TRUE) or not (FALSE).\r
-\r
-**/\r
-BOOLEAN\r
-HttpIoIsChunked (\r
-  IN   UINTN                    HeaderCount,\r
-  IN   EFI_HTTP_HEADER          *Headers\r
-  )\r
-{\r
-  EFI_HTTP_HEADER       *Header;\r
-\r
-\r
-  Header = HttpFindHeader (HeaderCount, Headers, HTTP_HEADER_TRANSFER_ENCODING);\r
-  if (Header == NULL) {\r
-    return FALSE;\r
-  }\r
-\r
-  if (AsciiStriCmp (Header->FieldValue, "identity") != 0) {\r
-    return TRUE;\r
-  }\r
-\r
-  return FALSE;\r
-}\r
-\r
-/**\r
-  Check whether the HTTP message should have a message-body.\r
-\r
-  @param[in]    Method             The HTTP method (e.g. GET, POST) for this HTTP message.\r
-  @param[in]    StatusCode         Response status code returned by the remote host.\r
-\r
-  @return       The message should have a message-body (FALSE) or not (TRUE).\r
-\r
-**/\r
-BOOLEAN\r
-HttpIoNoMessageBody (\r
-  IN   EFI_HTTP_METHOD          Method,\r
-  IN   EFI_HTTP_STATUS_CODE     StatusCode\r
-  )\r
-{\r
-  //\r
-  // RFC 2616:\r
-  // All responses to the HEAD request method\r
-  // MUST NOT include a message-body, even though the presence of entity-\r
-  // header fields might lead one to believe they do. All 1xx\r
-  // (informational), 204 (no content), and 304 (not modified) responses\r
-  // MUST NOT include a message-body. All other responses do include a\r
-  // message-body, although it MAY be of zero length.\r
-  //\r
-  if (Method == HttpMethodHead) {\r
-    return TRUE;\r
-  }\r
-\r
-  if ((StatusCode == HTTP_STATUS_100_CONTINUE) ||\r
-      (StatusCode == HTTP_STATUS_101_SWITCHING_PROTOCOLS) ||\r
-      (StatusCode == HTTP_STATUS_204_NO_CONTENT) ||\r
-      (StatusCode == HTTP_STATUS_304_NOT_MODIFIED))\r
-  {\r
-    return TRUE;\r
-  }\r
-\r
-  return FALSE;\r
-}\r
-\r
-/**\r
-  Initialize a HTTP message-body parser.\r
-\r
-  This function will create and initialize a HTTP message parser according to caller provided HTTP message\r
-  header information. It is the caller's responsibility to free the buffer returned in *UrlParser by HttpFreeMsgParser().\r
-\r
-  @param[in]    Method             The HTTP method (e.g. GET, POST) for this HTTP message.\r
-  @param[in]    StatusCode         Response status code returned by the remote host.\r
-  @param[in]    HeaderCount        Number of HTTP header structures in Headers.\r
-  @param[in]    Headers            Array containing list of HTTP headers.\r
-  @param[in]    Callback           Callback function that is invoked when parsing the HTTP message-body,\r
-                                   set to NULL to ignore all events.\r
-  @param[in]    Context            Pointer to the context that will be passed to Callback.\r
-  @param[out]   MsgParser          Pointer to the returned buffer to store the message parser.\r
-\r
-  @retval EFI_SUCCESS              Successfully initialized the parser.\r
-  @retval EFI_OUT_OF_RESOURCES     Could not allocate needed resources.\r
-  @retval EFI_INVALID_PARAMETER    MsgParser is NULL or HeaderCount is not NULL but Headers is NULL.\r
-  @retval Others                   Failed to initialize the parser.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-HttpInitMsgParser (\r
-  IN     EFI_HTTP_METHOD               Method,\r
-  IN     EFI_HTTP_STATUS_CODE          StatusCode,\r
-  IN     UINTN                         HeaderCount,\r
-  IN     EFI_HTTP_HEADER               *Headers,\r
-  IN     HTTP_BODY_PARSER_CALLBACK     Callback,\r
-  IN     VOID                          *Context,\r
-    OUT  VOID                          **MsgParser\r
-  )\r
-{\r
-  EFI_STATUS            Status;\r
-  HTTP_BODY_PARSER      *Parser;\r
-\r
-  if (HeaderCount != 0 && Headers == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (MsgParser == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  Parser = AllocateZeroPool (sizeof (HTTP_BODY_PARSER));\r
-  if (Parser == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  Parser->State = BodyParserBodyStart;\r
-\r
-  //\r
-  // Determine the message length according to RFC 2616.\r
-  // 1. Check whether the message "MUST NOT" have a message-body.\r
-  //\r
-  Parser->IgnoreBody = HttpIoNoMessageBody (Method, StatusCode);\r
-  //\r
-  // 2. Check whether the message using "chunked" transfer-coding.\r
-  //\r
-  Parser->IsChunked  = HttpIoIsChunked (HeaderCount, Headers);\r
-  //\r
-  // 3. Check whether the message has a Content-Length header field.\r
-  //\r
-  Status = HttpIoParseContentLengthHeader (HeaderCount, Headers, &Parser->ContentLength);\r
-  if (!EFI_ERROR (Status)) {\r
-    Parser->ContentLengthIsValid = TRUE;\r
-  }\r
-  //\r
-  // 4. Range header is not supported now, so we won't meet media type "multipart/byteranges".\r
-  // 5. By server closing the connection\r
-  //\r
-\r
-  //\r
-  // Set state to skip body parser if the message shouldn't have a message body.\r
-  //\r
-  if (Parser->IgnoreBody) {\r
-    Parser->State = BodyParserComplete;\r
-  } else {\r
-    Parser->Callback = Callback;\r
-    Parser->Context  = Context;\r
-  }\r
-\r
-  *MsgParser = Parser;\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Parse message body.\r
-\r
-  Parse BodyLength of message-body. This function can be called repeatedly to parse the message-body partially.\r
-\r
-  @param[in, out]    MsgParser            Pointer to the message parser.\r
-  @param[in]         BodyLength           Length in bytes of the Body.\r
-  @param[in]         Body                 Pointer to the buffer of the message-body to be parsed.\r
-\r
-  @retval EFI_SUCCESS                Successfully parse the message-body.\r
-  @retval EFI_INVALID_PARAMETER      MsgParser is NULL or Body is NULL or BodyLength is 0.\r
-  @retval EFI_ABORTED                Operation aborted.\r
-  @retval Other                      Error happened while parsing message body.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-HttpParseMessageBody (\r
-  IN OUT VOID              *MsgParser,\r
-  IN     UINTN             BodyLength,\r
-  IN     CHAR8             *Body\r
-  )\r
-{\r
-  CHAR8                 *Char;\r
-  UINTN                 RemainderLengthInThis;\r
-  UINTN                 LengthForCallback;\r
-  EFI_STATUS            Status;\r
-  HTTP_BODY_PARSER      *Parser;\r
-\r
-  if (BodyLength == 0 || Body == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (MsgParser == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  Parser = (HTTP_BODY_PARSER *) MsgParser;\r
-\r
-  if (Parser->IgnoreBody) {\r
-    Parser->State = BodyParserComplete;\r
-    if (Parser->Callback != NULL) {\r
-      Status = Parser->Callback (\r
-                         BodyParseEventOnComplete,\r
-                         Body,\r
-                         0,\r
-                         Parser->Context\r
-                         );\r
-      if (EFI_ERROR (Status)) {\r
-        return Status;\r
-      }\r
-    }\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  if (Parser->State == BodyParserBodyStart) {\r
-    Parser->ParsedBodyLength = 0;\r
-    if (Parser->IsChunked) {\r
-      Parser->State = BodyParserChunkSizeStart;\r
-    } else {\r
-      Parser->State = BodyParserBodyIdentity;\r
-    }\r
-  }\r
-\r
-  //\r
-  // The message body might be truncated in anywhere, so we need to parse is byte-by-byte.\r
-  //\r
-  for (Char = Body; Char < Body + BodyLength; ) {\r
-\r
-    switch (Parser->State) {\r
-    case BodyParserStateMax:\r
-      return EFI_ABORTED;\r
-\r
-    case BodyParserBodyIdentity:\r
-      //\r
-      // Identity transfer-coding, just notify user to save the body data.\r
-      //\r
-      if (Parser->Callback != NULL) {\r
-        Status = Parser->Callback (\r
-                           BodyParseEventOnData,\r
-                           Char,\r
-                           MIN (BodyLength, Parser->ContentLength - Parser->ParsedBodyLength),\r
-                           Parser->Context\r
-                           );\r
-        if (EFI_ERROR (Status)) {\r
-          return Status;\r
-        }\r
-      }\r
-      Char += MIN (BodyLength, Parser->ContentLength - Parser->ParsedBodyLength);\r
-      Parser->ParsedBodyLength += MIN (BodyLength, Parser->ContentLength - Parser->ParsedBodyLength);\r
-      if (Parser->ParsedBodyLength == Parser->ContentLength) {\r
-        Parser->State = BodyParserComplete;\r
-        if (Parser->Callback != NULL) {\r
-          Status = Parser->Callback (\r
-                             BodyParseEventOnComplete,\r
-                             Char,\r
-                             0,\r
-                             Parser->Context\r
-                             );\r
-          if (EFI_ERROR (Status)) {\r
-            return Status;\r
-          }\r
-        }\r
-      }\r
-      break;\r
-\r
-    case BodyParserChunkSizeStart:\r
-      //\r
-      // First byte of chunk-size, the chunk-size might be truncated.\r
-      //\r
-      Parser->CurrentChunkSize = 0;\r
-      Parser->State = BodyParserChunkSize;\r
-    case BodyParserChunkSize:\r
-      if (!NET_IS_HEX_CHAR (*Char)) {\r
-        if (*Char == ';') {\r
-          Parser->State = BodyParserChunkExtStart;\r
-          Char++;\r
-        } else if (*Char == '\r') {\r
-          Parser->State = BodyParserChunkSizeEndCR;\r
-          Char++;\r
-        } else {\r
-          Parser->State = BodyParserStateMax;\r
-        }\r
-        break;\r
-      }\r
-\r
-      if (Parser->CurrentChunkSize > (((~((UINTN) 0)) - 16) / 16)) {\r
-        return EFI_INVALID_PARAMETER;\r
-      }\r
-      Parser->CurrentChunkSize = Parser->CurrentChunkSize * 16 + HttpIoHexCharToUintn (*Char);\r
-      Char++;\r
-      break;\r
-\r
-    case BodyParserChunkExtStart:\r
-      //\r
-      // Ignore all the chunk extensions.\r
-      //\r
-      if (*Char == '\r') {\r
-        Parser->State = BodyParserChunkSizeEndCR;\r
-       }\r
-      Char++;\r
-      break;\r
-\r
-    case BodyParserChunkSizeEndCR:\r
-      if (*Char != '\n') {\r
-        Parser->State = BodyParserStateMax;\r
-        break;\r
-      }\r
-      Char++;\r
-      if (Parser->CurrentChunkSize == 0) {\r
-        //\r
-        // The last chunk has been parsed and now assumed the state\r
-        // of HttpBodyParse is ParserLastCRLF. So it need to decide\r
-        // whether the rest message is trailer or last CRLF in the next round.\r
-        //\r
-        Parser->ContentLengthIsValid = TRUE;\r
-        Parser->State = BodyParserLastCRLF;\r
-        break;\r
-      }\r
-      Parser->State = BodyParserChunkDataStart;\r
-      Parser->CurrentChunkParsedSize = 0;\r
-      break;\r
-\r
-    case BodyParserLastCRLF:\r
-      //\r
-      // Judge the byte is belong to the Last CRLF or trailer, and then\r
-      // configure the state of HttpBodyParse to corresponding state.\r
-      //\r
-      if (*Char == '\r') {\r
-        Char++;\r
-        Parser->State = BodyParserLastCRLFEnd;\r
-        break;\r
-      } else {\r
-        Parser->State = BodyParserTrailer;\r
-        break;\r
-      }\r
-\r
-    case BodyParserLastCRLFEnd:\r
-      if (*Char == '\n') {\r
-        Parser->State = BodyParserComplete;\r
-        Char++;\r
-        if (Parser->Callback != NULL) {\r
-          Status = Parser->Callback (\r
-                             BodyParseEventOnComplete,\r
-                             Char,\r
-                             0,\r
-                             Parser->Context\r
-                             );\r
-          if (EFI_ERROR (Status)) {\r
-            return Status;\r
-          }\r
-        }\r
-        break;\r
-      } else {\r
-        Parser->State = BodyParserStateMax;\r
-        break;\r
-      }\r
-\r
-    case BodyParserTrailer:\r
-      if (*Char == '\r') {\r
-        Parser->State = BodyParserChunkSizeEndCR;\r
-      }\r
-      Char++;\r
-      break;\r
-\r
-    case BodyParserChunkDataStart:\r
-      //\r
-      // First byte of chunk-data, the chunk data also might be truncated.\r
-      //\r
-      RemainderLengthInThis = BodyLength - (Char - Body);\r
-      LengthForCallback = MIN (Parser->CurrentChunkSize - Parser->CurrentChunkParsedSize, RemainderLengthInThis);\r
-      if (Parser->Callback != NULL) {\r
-        Status = Parser->Callback (\r
-                           BodyParseEventOnData,\r
-                           Char,\r
-                           LengthForCallback,\r
-                           Parser->Context\r
-                           );\r
-        if (EFI_ERROR (Status)) {\r
-          return Status;\r
-        }\r
-      }\r
-      Char += LengthForCallback;\r
-      Parser->ContentLength += LengthForCallback;\r
-      Parser->CurrentChunkParsedSize += LengthForCallback;\r
-      if (Parser->CurrentChunkParsedSize == Parser->CurrentChunkSize) {\r
-        Parser->State = BodyParserChunkDataEnd;\r
-      }\r
-      break;\r
-\r
-    case BodyParserChunkDataEnd:\r
-      if (*Char == '\r') {\r
-        Parser->State = BodyParserChunkDataEndCR;\r
-      } else {\r
-        Parser->State = BodyParserStateMax;\r
-      }\r
-      Char++;\r
-      break;\r
-\r
-    case BodyParserChunkDataEndCR:\r
-      if (*Char != '\n') {\r
-        Parser->State = BodyParserStateMax;\r
-        break;\r
-      }\r
-      Char++;\r
-      Parser->State = BodyParserChunkSizeStart;\r
-      break;\r
-\r
-    default:\r
-      break;\r
-    }\r
-\r
-  }\r
-\r
-  if (Parser->State == BodyParserStateMax) {\r
-    return EFI_ABORTED;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Check whether the message-body is complete or not.\r
-\r
-  @param[in]    MsgParser            Pointer to the message parser.\r
-\r
-  @retval TRUE                       Message-body is complete.\r
-  @retval FALSE                      Message-body is not complete.\r
-\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-HttpIsMessageComplete (\r
-  IN VOID              *MsgParser\r
-  )\r
-{\r
-  HTTP_BODY_PARSER      *Parser;\r
-\r
-  if (MsgParser == NULL) {\r
-    return FALSE;\r
-  }\r
-\r
-  Parser = (HTTP_BODY_PARSER *) MsgParser;\r
-\r
-  if (Parser->State == BodyParserComplete) {\r
-    return TRUE;\r
-  }\r
-  return FALSE;\r
-}\r
-\r
-/**\r
-  Get the content length of the entity.\r
-\r
-  Note that in trunk transfer, the entity length is not valid until the whole message body is received.\r
-\r
-  @param[in]    MsgParser            Pointer to the message parser.\r
-  @param[out]   ContentLength        Pointer to store the length of the entity.\r
-\r
-  @retval EFI_SUCCESS                Successfully to get the entity length.\r
-  @retval EFI_NOT_READY              Entity length is not valid yet.\r
-  @retval EFI_INVALID_PARAMETER      MsgParser is NULL or ContentLength is NULL.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-HttpGetEntityLength (\r
-  IN  VOID              *MsgParser,\r
-  OUT UINTN             *ContentLength\r
-  )\r
-{\r
-  HTTP_BODY_PARSER      *Parser;\r
-\r
-  if (MsgParser == NULL || ContentLength == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  Parser = (HTTP_BODY_PARSER *) MsgParser;\r
-\r
-  if (!Parser->ContentLengthIsValid) {\r
-    return EFI_NOT_READY;\r
-  }\r
-\r
-  *ContentLength = Parser->ContentLength;\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Release the resource of the message parser.\r
-\r
-  @param[in]    MsgParser            Pointer to the message parser.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-HttpFreeMsgParser (\r
-  IN  VOID           *MsgParser\r
-  )\r
-{\r
-  FreePool (MsgParser);\r
-}\r
-\r
-\r
-/**\r
-  Get the next string, which is distinguished by specified separator.\r
-\r
-  @param[in]  String             Pointer to the string.\r
-  @param[in]  Separator          Specified separator used to distinguish where is the beginning\r
-                                 of next string.\r
-\r
-  @return     Pointer to the next string.\r
-  @return     NULL if not find or String is NULL.\r
-\r
-**/\r
-CHAR8 *\r
-AsciiStrGetNextToken (\r
-  IN CONST CHAR8 *String,\r
-  IN       CHAR8 Separator\r
-  )\r
-{\r
-  CONST CHAR8 *Token;\r
-\r
-  Token = String;\r
-  while (TRUE) {\r
-    if (*Token == 0) {\r
-      return NULL;\r
-    }\r
-    if (*Token == Separator) {\r
-      return (CHAR8 *)(Token + 1);\r
-    }\r
-    Token++;\r
-  }\r
-}\r
-\r
-/**\r
-  Set FieldName and FieldValue into specified HttpHeader.\r
-\r
-  @param[in,out]  HttpHeader      Specified HttpHeader.\r
-  @param[in]  FieldName           FieldName of this HttpHeader, a NULL terminated ASCII string.\r
-  @param[in]  FieldValue          FieldValue of this HttpHeader, a NULL terminated ASCII string.\r
-\r
-\r
-  @retval EFI_SUCCESS             The FieldName and FieldValue are set into HttpHeader successfully.\r
-  @retval EFI_INVALID_PARAMETER   The parameter is invalid.\r
-  @retval EFI_OUT_OF_RESOURCES    Failed to allocate resources.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-HttpSetFieldNameAndValue (\r
-  IN  OUT   EFI_HTTP_HEADER       *HttpHeader,\r
-  IN  CONST CHAR8                 *FieldName,\r
-  IN  CONST CHAR8                 *FieldValue\r
-  )\r
-{\r
-  UINTN                       FieldNameSize;\r
-  UINTN                       FieldValueSize;\r
-\r
-  if (HttpHeader == NULL || FieldName == NULL || FieldValue == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (HttpHeader->FieldName != NULL) {\r
-    FreePool (HttpHeader->FieldName);\r
-  }\r
-  if (HttpHeader->FieldValue != NULL) {\r
-    FreePool (HttpHeader->FieldValue);\r
-  }\r
-\r
-  FieldNameSize = AsciiStrSize (FieldName);\r
-  HttpHeader->FieldName = AllocateZeroPool (FieldNameSize);\r
-  if (HttpHeader->FieldName == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-  CopyMem (HttpHeader->FieldName, FieldName, FieldNameSize);\r
-  HttpHeader->FieldName[FieldNameSize - 1] = 0;\r
-\r
-  FieldValueSize = AsciiStrSize (FieldValue);\r
-  HttpHeader->FieldValue = AllocateZeroPool (FieldValueSize);\r
-  if (HttpHeader->FieldValue == NULL) {\r
-    FreePool (HttpHeader->FieldName);\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-  CopyMem (HttpHeader->FieldValue, FieldValue, FieldValueSize);\r
-  HttpHeader->FieldValue[FieldValueSize - 1] = 0;\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Get one key/value header pair from the raw string.\r
-\r
-  @param[in]  String             Pointer to the raw string.\r
-  @param[out] FieldName          Points directly to field name within 'HttpHeader'.\r
-  @param[out] FieldValue         Points directly to field value within 'HttpHeader'.\r
-\r
-  @return     Pointer to the next raw string.\r
-  @return     NULL if no key/value header pair from this raw string.\r
-\r
-**/\r
-CHAR8 *\r
-EFIAPI\r
-HttpGetFieldNameAndValue (\r
-  IN     CHAR8   *String,\r
-     OUT CHAR8   **FieldName,\r
-     OUT CHAR8   **FieldValue\r
-  )\r
-{\r
-  CHAR8  *FieldNameStr;\r
-  CHAR8  *FieldValueStr;\r
-  CHAR8  *StrPtr;\r
-  CHAR8  *EndofHeader;\r
-\r
-  if (String == NULL || FieldName == NULL || FieldValue == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  *FieldName    = NULL;\r
-  *FieldValue   = NULL;\r
-  FieldNameStr  = NULL;\r
-  FieldValueStr = NULL;\r
-  StrPtr        = NULL;\r
-  EndofHeader   = NULL;\r
-\r
-\r
-  //\r
-  // Check whether the raw HTTP header string is valid or not.\r
-  //\r
-  EndofHeader = AsciiStrStr (String, "\r\n\r\n");\r
-  if (EndofHeader == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  //\r
-  // Each header field consists of a name followed by a colon (":") and the field value.\r
-  // The field value MAY be preceded by any amount of LWS, though a single SP is preferred.\r
-  //\r
-  // message-header = field-name ":" [ field-value ]\r
-  // field-name = token\r
-  // field-value = *( field-content | LWS )\r
-  //\r
-  // Note: "*(element)" allows any number element, including zero; "1*(element)" requires at least one element.\r
-  //       [element] means element is optional.\r
-  //       LWS  = [CRLF] 1*(SP|HT), it can be ' ' or '\t' or '\r\n ' or '\r\n\t'.\r
-  //       CRLF = '\r\n'.\r
-  //       SP   = ' '.\r
-  //       HT   = '\t' (Tab).\r
-  //\r
-  FieldNameStr = String;\r
-  FieldValueStr = AsciiStrGetNextToken (FieldNameStr, ':');\r
-  if (FieldValueStr == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  //\r
-  // Replace ':' with 0, then FieldName has been retrived from String.\r
-  //\r
-  *(FieldValueStr - 1) = 0;\r
-\r
-  //\r
-  // Handle FieldValueStr, skip all the preceded LWS.\r
-  //\r
-  while (TRUE) {\r
-    if (*FieldValueStr == ' ' || *FieldValueStr == '\t') {\r
-      //\r
-      // Boundary condition check.\r
-      //\r
-      if ((UINTN) EndofHeader - (UINTN) FieldValueStr < 1) {\r
-        //\r
-        // Wrong String format!\r
-        //\r
-        return NULL;\r
-      }\r
-\r
-      FieldValueStr ++;\r
-    } else if (*FieldValueStr == '\r') {\r
-      //\r
-      // Boundary condition check.\r
-      //\r
-      if ((UINTN) EndofHeader - (UINTN) FieldValueStr < 3) {\r
-        //\r
-        // No more preceded LWS, so break here.\r
-        //\r
-        break;\r
-      }\r
-\r
-      if (*(FieldValueStr + 1) == '\n' ) {\r
-        if (*(FieldValueStr + 2) == ' ' || *(FieldValueStr + 2) == '\t') {\r
-          FieldValueStr = FieldValueStr + 3;\r
-        } else {\r
-          //\r
-          // No more preceded LWS, so break here.\r
-          //\r
-          break;\r
-        }\r
-      } else {\r
-        //\r
-        // Wrong String format!\r
-        //\r
-        return NULL;\r
-      }\r
-    } else {\r
-      //\r
-      // No more preceded LWS, so break here.\r
-      //\r
-      break;\r
-    }\r
-  }\r
-\r
-  StrPtr = FieldValueStr;\r
-  do {\r
-    //\r
-    // Handle the LWS within the field value.\r
-    //\r
-    StrPtr = AsciiStrGetNextToken (StrPtr, '\r');\r
-    if (StrPtr == NULL || *StrPtr != '\n') {\r
-      //\r
-      // Wrong String format!\r
-      //\r
-      return NULL;\r
-    }\r
-\r
-    StrPtr++;\r
-  } while (*StrPtr == ' ' || *StrPtr == '\t');\r
-\r
-  //\r
-  // Replace '\r' with 0\r
-  //\r
-  *(StrPtr - 2) = 0;\r
-\r
-  //\r
-  // Get FieldName and FieldValue.\r
-  //\r
-  *FieldName = FieldNameStr;\r
-  *FieldValue = FieldValueStr;\r
-\r
-  return StrPtr;\r
-}\r
-\r
-/**\r
-  Free existing HeaderFields.\r
-\r
-  @param[in]  HeaderFields       Pointer to array of key/value header pairs waitting for free.\r
-  @param[in]  FieldCount         The number of header pairs in HeaderFields.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-HttpFreeHeaderFields (\r
-  IN  EFI_HTTP_HEADER  *HeaderFields,\r
-  IN  UINTN            FieldCount\r
-  )\r
-{\r
-  UINTN                       Index;\r
-\r
-  if (HeaderFields != NULL) {\r
-    for (Index = 0; Index < FieldCount; Index++) {\r
-      if (HeaderFields[Index].FieldName != NULL) {\r
-        FreePool (HeaderFields[Index].FieldName);\r
-      }\r
-      if (HeaderFields[Index].FieldValue != NULL) {\r
-        FreePool (HeaderFields[Index].FieldValue);\r
-      }\r
-    }\r
-\r
-    FreePool (HeaderFields);\r
-  }\r
-}\r
-\r
-/**\r
-  Generate HTTP request message.\r
-\r
-  This function will allocate memory for the whole HTTP message and generate a\r
-  well formatted HTTP Request message in it, include the Request-Line, header\r
-  fields and also the message body. It is the caller's responsibility to free\r
-  the buffer returned in *RequestMsg.\r
-\r
-  @param[in]   Message            Pointer to the EFI_HTTP_MESSAGE structure which\r
-                                  contains the required information to generate\r
-                                  the HTTP request message.\r
-  @param[in]   Url                The URL of a remote host.\r
-  @param[out]  RequestMsg         Pointer to the created HTTP request message.\r
-                                  NULL if any error occured.\r
-  @param[out]  RequestMsgSize     Size of the RequestMsg (in bytes).\r
-\r
-  @retval EFI_SUCCESS             If HTTP request string was created successfully.\r
-  @retval EFI_OUT_OF_RESOURCES    Failed to allocate resources.\r
-  @retval EFI_INVALID_PARAMETER   The input arguments are invalid.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-HttpGenRequestMessage (\r
-  IN     CONST EFI_HTTP_MESSAGE        *Message,\r
-  IN     CONST CHAR8                   *Url,\r
-     OUT CHAR8                         **RequestMsg,\r
-     OUT UINTN                         *RequestMsgSize\r
-  )\r
-{\r
-  EFI_STATUS                       Status;\r
-  UINTN                            StrLength;\r
-  CHAR8                            *RequestPtr;\r
-  UINTN                            HttpHdrSize;\r
-  UINTN                            MsgSize;\r
-  BOOLEAN                          Success;\r
-  VOID                             *HttpHdr;\r
-  EFI_HTTP_HEADER                  **AppendList;\r
-  UINTN                            Index;\r
-  EFI_HTTP_UTILITIES_PROTOCOL      *HttpUtilitiesProtocol;\r
-\r
-  Status                = EFI_SUCCESS;\r
-  HttpHdrSize           = 0;\r
-  MsgSize               = 0;\r
-  Success               = FALSE;\r
-  HttpHdr               = NULL;\r
-  AppendList            = NULL;\r
-  HttpUtilitiesProtocol = NULL;\r
-\r
-  //\r
-  // 1. If we have a Request, we cannot have a NULL Url\r
-  // 2. If we have a Request, HeaderCount can not be non-zero\r
-  // 3. If we do not have a Request, HeaderCount should be zero\r
-  // 4. If we do not have Request and Headers, we need at least a message-body\r
-  //\r
-  if ((Message == NULL || RequestMsg == NULL || RequestMsgSize == NULL) ||\r
-      (Message->Data.Request != NULL && Url == NULL) ||\r
-      (Message->Data.Request != NULL && Message->HeaderCount == 0) ||\r
-      (Message->Data.Request == NULL && Message->HeaderCount != 0) ||\r
-      (Message->Data.Request == NULL && Message->HeaderCount == 0 && Message->BodyLength == 0)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (Message->HeaderCount != 0) {\r
-    //\r
-    // Locate the HTTP_UTILITIES protocol.\r
-    //\r
-    Status = gBS->LocateProtocol (\r
-                    &gEfiHttpUtilitiesProtocolGuid,\r
-                    NULL,\r
-                    (VOID **) &HttpUtilitiesProtocol\r
-                    );\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      DEBUG ((DEBUG_ERROR,"Failed to locate Http Utilities protocol. Status = %r.\n", Status));\r
-      return Status;\r
-    }\r
-\r
-    //\r
-    // Build AppendList to send into HttpUtilitiesBuild\r
-    //\r
-    AppendList = AllocateZeroPool (sizeof (EFI_HTTP_HEADER *) * (Message->HeaderCount));\r
-    if (AppendList == NULL) {\r
-      return EFI_OUT_OF_RESOURCES;\r
-    }\r
-\r
-    for(Index = 0; Index < Message->HeaderCount; Index++){\r
-      AppendList[Index] = &Message->Headers[Index];\r
-    }\r
-\r
-    //\r
-    // Build raw HTTP Headers\r
-    //\r
-    Status = HttpUtilitiesProtocol->Build (\r
-                                      HttpUtilitiesProtocol,\r
-                                      0,\r
-                                      NULL,\r
-                                      0,\r
-                                      NULL,\r
-                                      Message->HeaderCount,\r
-                                      AppendList,\r
-                                      &HttpHdrSize,\r
-                                      &HttpHdr\r
-                                      );\r
-\r
-    FreePool (AppendList);\r
-\r
-    if (EFI_ERROR (Status) || HttpHdr == NULL){\r
-      return Status;\r
-    }\r
-  }\r
-\r
-  //\r
-  // If we have headers to be sent, account for it.\r
-  //\r
-  if (Message->HeaderCount != 0) {\r
-    MsgSize = HttpHdrSize;\r
-  }\r
-\r
-  //\r
-  // If we have a request line, account for the fields.\r
-  //\r
-  if (Message->Data.Request != NULL) {\r
-    MsgSize += HTTP_METHOD_MAXIMUM_LEN + AsciiStrLen (HTTP_VERSION_CRLF_STR) + AsciiStrLen (Url);\r
-  }\r
-\r
-\r
-  //\r
-  // If we have a message body to be sent, account for it.\r
-  //\r
-  MsgSize += Message->BodyLength;\r
-\r
-  //\r
-  // memory for the string that needs to be sent to TCP\r
-  //\r
-  *RequestMsg = NULL;\r
-  *RequestMsg = AllocateZeroPool (MsgSize);\r
-  if (*RequestMsg == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto Exit;\r
-  }\r
-\r
-  RequestPtr = *RequestMsg;\r
-  //\r
-  // Construct header request\r
-  //\r
-  if (Message->Data.Request != NULL) {\r
-    switch (Message->Data.Request->Method) {\r
-    case HttpMethodGet:\r
-      StrLength = sizeof (HTTP_METHOD_GET) - 1;\r
-      CopyMem (RequestPtr, HTTP_METHOD_GET, StrLength);\r
-      RequestPtr += StrLength;\r
-      break;\r
-    case HttpMethodPut:\r
-      StrLength = sizeof (HTTP_METHOD_PUT) - 1;\r
-      CopyMem (RequestPtr, HTTP_METHOD_PUT, StrLength);\r
-      RequestPtr += StrLength;\r
-      break;\r
-    case HttpMethodPatch:\r
-      StrLength = sizeof (HTTP_METHOD_PATCH) - 1;\r
-      CopyMem (RequestPtr, HTTP_METHOD_PATCH, StrLength);\r
-      RequestPtr += StrLength;\r
-      break;\r
-    case HttpMethodPost:\r
-      StrLength = sizeof (HTTP_METHOD_POST) - 1;\r
-      CopyMem (RequestPtr, HTTP_METHOD_POST, StrLength);\r
-      RequestPtr += StrLength;\r
-      break;\r
-    case HttpMethodHead:\r
-      StrLength = sizeof (HTTP_METHOD_HEAD) - 1;\r
-      CopyMem (RequestPtr, HTTP_METHOD_HEAD, StrLength);\r
-      RequestPtr += StrLength;\r
-      break;\r
-    case HttpMethodDelete:\r
-      StrLength = sizeof (HTTP_METHOD_DELETE) - 1;\r
-      CopyMem (RequestPtr, HTTP_METHOD_DELETE, StrLength);\r
-      RequestPtr += StrLength;\r
-      break;\r
-    default:\r
-      ASSERT (FALSE);\r
-      Status = EFI_INVALID_PARAMETER;\r
-      goto Exit;\r
-    }\r
-\r
-    StrLength = AsciiStrLen(EMPTY_SPACE);\r
-    CopyMem (RequestPtr, EMPTY_SPACE, StrLength);\r
-    RequestPtr += StrLength;\r
-\r
-    StrLength = AsciiStrLen (Url);\r
-    CopyMem (RequestPtr, Url, StrLength);\r
-    RequestPtr += StrLength;\r
-\r
-    StrLength = sizeof (HTTP_VERSION_CRLF_STR) - 1;\r
-    CopyMem (RequestPtr, HTTP_VERSION_CRLF_STR, StrLength);\r
-    RequestPtr += StrLength;\r
-\r
-    if (HttpHdr != NULL) {\r
-      //\r
-      // Construct header\r
-      //\r
-      CopyMem (RequestPtr, HttpHdr, HttpHdrSize);\r
-      RequestPtr += HttpHdrSize;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Construct body\r
-  //\r
-  if (Message->Body != NULL) {\r
-    CopyMem (RequestPtr, Message->Body, Message->BodyLength);\r
-    RequestPtr += Message->BodyLength;\r
-  }\r
-\r
-  //\r
-  // Done\r
-  //\r
-  (*RequestMsgSize) = (UINTN)(RequestPtr) - (UINTN)(*RequestMsg);\r
-  Success     = TRUE;\r
-\r
-Exit:\r
-\r
-  if (!Success) {\r
-    if (*RequestMsg != NULL) {\r
-      FreePool (*RequestMsg);\r
-    }\r
-    *RequestMsg = NULL;\r
-    return Status;\r
-  }\r
-\r
-  if (HttpHdr != NULL) {\r
-    FreePool (HttpHdr);\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Translate the status code in HTTP message to EFI_HTTP_STATUS_CODE defined\r
-  in UEFI 2.5 specification.\r
-\r
-  @param[in]  StatusCode         The status code value in HTTP message.\r
-\r
-  @return                        Value defined in EFI_HTTP_STATUS_CODE .\r
-\r
-**/\r
-EFI_HTTP_STATUS_CODE\r
-EFIAPI\r
-HttpMappingToStatusCode (\r
-  IN UINTN                  StatusCode\r
-  )\r
-{\r
-  switch (StatusCode) {\r
-  case 100:\r
-    return HTTP_STATUS_100_CONTINUE;\r
-  case 101:\r
-    return HTTP_STATUS_101_SWITCHING_PROTOCOLS;\r
-  case 200:\r
-    return HTTP_STATUS_200_OK;\r
-  case 201:\r
-    return HTTP_STATUS_201_CREATED;\r
-  case 202:\r
-    return HTTP_STATUS_202_ACCEPTED;\r
-  case 203:\r
-    return HTTP_STATUS_203_NON_AUTHORITATIVE_INFORMATION;\r
-  case 204:\r
-    return HTTP_STATUS_204_NO_CONTENT;\r
-  case 205:\r
-    return HTTP_STATUS_205_RESET_CONTENT;\r
-  case 206:\r
-    return HTTP_STATUS_206_PARTIAL_CONTENT;\r
-  case 300:\r
-    return HTTP_STATUS_300_MULTIPLE_CHOICES;\r
-  case 301:\r
-    return HTTP_STATUS_301_MOVED_PERMANENTLY;\r
-  case 302:\r
-    return HTTP_STATUS_302_FOUND;\r
-  case 303:\r
-    return HTTP_STATUS_303_SEE_OTHER;\r
-  case 304:\r
-    return HTTP_STATUS_304_NOT_MODIFIED;\r
-  case 305:\r
-    return HTTP_STATUS_305_USE_PROXY;\r
-  case 307:\r
-    return HTTP_STATUS_307_TEMPORARY_REDIRECT;\r
-  case 308:\r
-    return HTTP_STATUS_308_PERMANENT_REDIRECT;\r
-  case 400:\r
-    return HTTP_STATUS_400_BAD_REQUEST;\r
-  case 401:\r
-    return HTTP_STATUS_401_UNAUTHORIZED;\r
-  case 402:\r
-    return HTTP_STATUS_402_PAYMENT_REQUIRED;\r
-  case 403:\r
-    return HTTP_STATUS_403_FORBIDDEN;\r
-  case 404:\r
-    return HTTP_STATUS_404_NOT_FOUND;\r
-  case 405:\r
-    return HTTP_STATUS_405_METHOD_NOT_ALLOWED;\r
-  case 406:\r
-    return HTTP_STATUS_406_NOT_ACCEPTABLE;\r
-  case 407:\r
-    return HTTP_STATUS_407_PROXY_AUTHENTICATION_REQUIRED;\r
-  case 408:\r
-    return HTTP_STATUS_408_REQUEST_TIME_OUT;\r
-  case 409:\r
-    return HTTP_STATUS_409_CONFLICT;\r
-  case 410:\r
-    return HTTP_STATUS_410_GONE;\r
-  case 411:\r
-    return HTTP_STATUS_411_LENGTH_REQUIRED;\r
-  case 412:\r
-    return HTTP_STATUS_412_PRECONDITION_FAILED;\r
-  case 413:\r
-    return HTTP_STATUS_413_REQUEST_ENTITY_TOO_LARGE;\r
-  case 414:\r
-    return HTTP_STATUS_414_REQUEST_URI_TOO_LARGE;\r
-  case 415:\r
-    return HTTP_STATUS_415_UNSUPPORTED_MEDIA_TYPE;\r
-  case 416:\r
-    return HTTP_STATUS_416_REQUESTED_RANGE_NOT_SATISFIED;\r
-  case 417:\r
-    return HTTP_STATUS_417_EXPECTATION_FAILED;\r
-  case 500:\r
-    return HTTP_STATUS_500_INTERNAL_SERVER_ERROR;\r
-  case 501:\r
-    return HTTP_STATUS_501_NOT_IMPLEMENTED;\r
-  case 502:\r
-    return HTTP_STATUS_502_BAD_GATEWAY;\r
-  case 503:\r
-    return HTTP_STATUS_503_SERVICE_UNAVAILABLE;\r
-  case 504:\r
-    return HTTP_STATUS_504_GATEWAY_TIME_OUT;\r
-  case 505:\r
-    return HTTP_STATUS_505_HTTP_VERSION_NOT_SUPPORTED;\r
-\r
-  default:\r
-    return HTTP_STATUS_UNSUPPORTED_STATUS;\r
-  }\r
-}\r
-\r
-/**\r
-  Check whether header field called FieldName is in DeleteList.\r
-\r
-  @param[in]  DeleteList        Pointer to array of key/value header pairs.\r
-  @param[in]  DeleteCount       The number of header pairs.\r
-  @param[in]  FieldName         Pointer to header field's name.\r
-\r
-  @return     TRUE if FieldName is not in DeleteList, that means this header field is valid.\r
-  @return     FALSE if FieldName is in DeleteList, that means this header field is invalid.\r
-\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-HttpIsValidHttpHeader (\r
-  IN  CHAR8            *DeleteList[],\r
-  IN  UINTN            DeleteCount,\r
-  IN  CHAR8            *FieldName\r
-  )\r
-{\r
-  UINTN                       Index;\r
-\r
-  if (FieldName == NULL) {\r
-    return FALSE;\r
-  }\r
-\r
-  for (Index = 0; Index < DeleteCount; Index++) {\r
-    if (DeleteList[Index] == NULL) {\r
-      continue;\r
-    }\r
-\r
-    if (AsciiStrCmp (FieldName, DeleteList[Index]) == 0) {\r
-      return FALSE;\r
-    }\r
-  }\r
-\r
-  return TRUE;\r
-}\r
-\r
diff --git a/MdeModulePkg/Library/DxeHttpLib/DxeHttpLib.h b/MdeModulePkg/Library/DxeHttpLib/DxeHttpLib.h
deleted file mode 100644 (file)
index d064a98..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/** @file\r
-Header file for HttpLib.\r
-\r
-  Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>\r
-  (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
-\r
-  SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#ifndef _DXE_HTTP_LIB_H_\r
-#define _DXE_HTTP_LIB_H_\r
-\r
-#include <Uefi.h>\r
-#include <Library/NetLib.h>\r
-#include <Library/HttpLib.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <IndustryStandard/Http11.h>\r
-#include <Protocol/HttpUtilities.h>\r
-\r
-#define BIT(x)  (1 << x)\r
-\r
-#define HTTP_VERSION_CRLF_STR  " HTTP/1.1\r\n"\r
-#define EMPTY_SPACE            " "\r
-\r
-#define NET_IS_HEX_CHAR(Ch)   \\r
-  ((('0' <= (Ch)) && ((Ch) <= '9')) ||  \\r
-   (('A' <= (Ch)) && ((Ch) <= 'F')) ||  \\r
-   (('a' <= (Ch)) && ((Ch) <= 'f')))\r
-\r
-//\r
-// Field index of the HTTP URL parse result.\r
-//\r
-#define   HTTP_URI_FIELD_SCHEME           0\r
-#define   HTTP_URI_FIELD_AUTHORITY        1\r
-#define   HTTP_URI_FIELD_PATH             2\r
-#define   HTTP_URI_FIELD_QUERY            3\r
-#define   HTTP_URI_FIELD_FRAGMENT         4\r
-#define   HTTP_URI_FIELD_USERINFO         5\r
-#define   HTTP_URI_FIELD_HOST             6\r
-#define   HTTP_URI_FIELD_PORT             7\r
-#define   HTTP_URI_FIELD_MAX              8\r
-\r
-#define   HTTP_URI_PORT_MAX_NUM           65535\r
-\r
-//\r
-// Structure to store the parse result of a HTTP URL.\r
-//\r
-typedef struct {\r
-  UINT32      Offset;\r
-  UINT32      Length;\r
-} HTTP_URL_FILED_DATA;\r
-\r
-typedef struct {\r
-  UINT16                  FieldBitMap;\r
-  HTTP_URL_FILED_DATA     FieldData[HTTP_URI_FIELD_MAX];\r
-} HTTP_URL_PARSER;\r
-\r
-typedef enum {\r
-  UrlParserUrlStart,\r
-  UrlParserScheme,\r
-  UrlParserSchemeColon,            // ":"\r
-  UrlParserSchemeColonSlash,       // ":/"\r
-  UrlParserSchemeColonSlashSlash,  // "://"\r
-  UrlParserAuthority,\r
-  UrlParserAtInAuthority,\r
-  UrlParserPath,\r
-  UrlParserQueryStart,    // "?"\r
-  UrlParserQuery,\r
-  UrlParserFragmentStart, // "#"\r
-  UrlParserFragment,\r
-  UrlParserUserInfo,\r
-  UrlParserHostStart,     // "@"\r
-  UrlParserHost,\r
-  UrlParserHostIpv6,      // "["(Ipv6 address) "]"\r
-  UrlParserPortStart,     // ":"\r
-  UrlParserPort,\r
-  UrlParserStateMax\r
-} HTTP_URL_PARSE_STATE;\r
-\r
-#endif\r
-\r
diff --git a/MdeModulePkg/Library/DxeHttpLib/DxeHttpLib.inf b/MdeModulePkg/Library/DxeHttpLib/DxeHttpLib.inf
deleted file mode 100644 (file)
index c613dc1..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-## @file\r
-#  It provides the helper routines to parse the HTTP message byte stream.\r
-#\r
-#  Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>\r
-#  (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
-#  SPDX-License-Identifier: BSD-2-Clause-Patent\r
-#\r
-##\r
-\r
-\r
-[Defines]\r
-  INF_VERSION                    = 0x00010005\r
-  BASE_NAME                      = DxeHttpLib\r
-  MODULE_UNI_FILE                = DxeHttpLib.uni\r
-  FILE_GUID                      = ABBAB4CD-EA88-45b9-8234-C8A7450531FC\r
-  MODULE_TYPE                    = DXE_DRIVER\r
-  VERSION_STRING                 = 1.0\r
-  LIBRARY_CLASS                  = HttpLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER\r
-\r
-#\r
-# The following information is for reference only and not required by the build tools.\r
-#\r
-#  VALID_ARCHITECTURES           = IA32 X64 EBC\r
-#\r
-\r
-[Sources]\r
-  DxeHttpLib.c\r
-  DxeHttpLib.h\r
-\r
-[Packages]\r
-  MdePkg/MdePkg.dec\r
-  MdeModulePkg/MdeModulePkg.dec\r
-\r
-[LibraryClasses]\r
-  BaseLib\r
-  DebugLib\r
-  UefiBootServicesTableLib\r
-  MemoryAllocationLib\r
-  NetLib\r
-\r
-[Protocols]\r
-  gEfiHttpUtilitiesProtocolGuid                 ## SOMETIMES_CONSUMES\r
diff --git a/MdeModulePkg/Library/DxeHttpLib/DxeHttpLib.uni b/MdeModulePkg/Library/DxeHttpLib/DxeHttpLib.uni
deleted file mode 100644 (file)
index a2954c0..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// /** @file\r
-// Provides the helper routines for HTTP.\r
-//\r
-// This library instance provides the helper routines to parse the HTTP message byte stream.\r
-//\r
-// Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>\r
-//\r
-// SPDX-License-Identifier: BSD-2-Clause-Patent\r
-//\r
-// **/\r
-\r
-\r
-#string STR_MODULE_ABSTRACT             #language en-US "Provides the helper routines for HTTP"\r
-\r
-#string STR_MODULE_DESCRIPTION          #language en-US "This library instance provides the helper routines to parse the HTTP message byte stream."\r
-\r
diff --git a/MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.c b/MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.c
deleted file mode 100644 (file)
index d45f007..0000000
+++ /dev/null
@@ -1,2291 +0,0 @@
-/** @file\r
-  IpIo Library.\r
-\r
-(C) Copyright 2014 Hewlett-Packard Development Company, L.P.<BR>\r
-Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-**/\r
-\r
-#include <Uefi.h>\r
-\r
-#include <Protocol/Udp4.h>\r
-\r
-#include <Library/IpIoLib.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Library/DpcLib.h>\r
-\r
-\r
-GLOBAL_REMOVE_IF_UNREFERENCED LIST_ENTRY  mActiveIpIoList = {\r
-  &mActiveIpIoList,\r
-  &mActiveIpIoList\r
-};\r
-\r
-GLOBAL_REMOVE_IF_UNREFERENCED EFI_IP4_CONFIG_DATA  mIp4IoDefaultIpConfigData = {\r
-  EFI_IP_PROTO_UDP,\r
-  FALSE,\r
-  TRUE,\r
-  FALSE,\r
-  FALSE,\r
-  FALSE,\r
-  {{0, 0, 0, 0}},\r
-  {{0, 0, 0, 0}},\r
-  0,\r
-  255,\r
-  FALSE,\r
-  FALSE,\r
-  0,\r
-  0\r
-};\r
-\r
-GLOBAL_REMOVE_IF_UNREFERENCED EFI_IP6_CONFIG_DATA  mIp6IoDefaultIpConfigData = {\r
-  EFI_IP_PROTO_UDP,\r
-  FALSE,\r
-  TRUE,\r
-  FALSE,\r
-  {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},\r
-  {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},\r
-  0,\r
-  255,\r
-  0,\r
-  0,\r
-  0\r
-};\r
-\r
-GLOBAL_REMOVE_IF_UNREFERENCED ICMP_ERROR_INFO  mIcmpErrMap[10] = {\r
-  {FALSE, TRUE }, // ICMP_ERR_UNREACH_NET\r
-  {FALSE, TRUE }, // ICMP_ERR_UNREACH_HOST\r
-  {TRUE,  TRUE }, // ICMP_ERR_UNREACH_PROTOCOL\r
-  {TRUE,  TRUE }, // ICMP_ERR_UNREACH_PORT\r
-  {TRUE,  TRUE }, // ICMP_ERR_MSGSIZE\r
-  {FALSE, TRUE }, // ICMP_ERR_UNREACH_SRCFAIL\r
-  {FALSE, TRUE }, // ICMP_ERR_TIMXCEED_INTRANS\r
-  {FALSE, TRUE }, // ICMP_ERR_TIMEXCEED_REASS\r
-  {FALSE, FALSE}, // ICMP_ERR_QUENCH\r
-  {FALSE, TRUE }  // ICMP_ERR_PARAMPROB\r
-};\r
-\r
-GLOBAL_REMOVE_IF_UNREFERENCED ICMP_ERROR_INFO  mIcmp6ErrMap[10] = {\r
-  {FALSE, TRUE}, // ICMP6_ERR_UNREACH_NET\r
-  {FALSE, TRUE}, // ICMP6_ERR_UNREACH_HOST\r
-  {TRUE,  TRUE}, // ICMP6_ERR_UNREACH_PROTOCOL\r
-  {TRUE,  TRUE}, // ICMP6_ERR_UNREACH_PORT\r
-  {TRUE,  TRUE}, // ICMP6_ERR_PACKAGE_TOOBIG\r
-  {FALSE, TRUE}, // ICMP6_ERR_TIMXCEED_HOPLIMIT\r
-  {FALSE, TRUE}, // ICMP6_ERR_TIMXCEED_REASS\r
-  {FALSE, TRUE}, // ICMP6_ERR_PARAMPROB_HEADER\r
-  {FALSE, TRUE}, // ICMP6_ERR_PARAMPROB_NEXHEADER\r
-  {FALSE, TRUE}  // ICMP6_ERR_PARAMPROB_IPV6OPTION\r
-};\r
-\r
-\r
-/**\r
-  Notify function for IP transmit token.\r
-\r
-  @param[in]  Context               The context passed in by the event notifier.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-IpIoTransmitHandlerDpc (\r
-  IN VOID      *Context\r
-  );\r
-\r
-\r
-/**\r
-  Notify function for IP transmit token.\r
-\r
-  @param[in]  Event                 The event signaled.\r
-  @param[in]  Context               The context passed in by the event notifier.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-IpIoTransmitHandler (\r
-  IN EFI_EVENT Event,\r
-  IN VOID      *Context\r
-  );\r
-\r
-\r
-/**\r
-  This function create an IP child ,open the IP protocol, and return the opened\r
-  IP protocol as Interface.\r
-\r
-  @param[in]    ControllerHandle   The controller handle.\r
-  @param[in]    ImageHandle        The image handle.\r
-  @param[in]    ChildHandle        Pointer to the buffer to save the IP child handle.\r
-  @param[in]    IpVersion          The version of the IP protocol to use, either\r
-                                   IPv4 or IPv6.\r
-  @param[out]   Interface          Pointer used to get the IP protocol interface.\r
-\r
-  @retval       EFI_SUCCESS        The IP child is created and the IP protocol\r
-                                   interface is retrieved.\r
-  @retval       EFI_UNSUPPORTED    Upsupported IpVersion.\r
-  @retval       Others             The required operation failed.\r
-\r
-**/\r
-EFI_STATUS\r
-IpIoCreateIpChildOpenProtocol (\r
-  IN  EFI_HANDLE  ControllerHandle,\r
-  IN  EFI_HANDLE  ImageHandle,\r
-  IN  EFI_HANDLE  *ChildHandle,\r
-  IN  UINT8       IpVersion,\r
-  OUT VOID        **Interface\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-  EFI_GUID    *ServiceBindingGuid;\r
-  EFI_GUID    *IpProtocolGuid;\r
-\r
-  if (IpVersion == IP_VERSION_4) {\r
-    ServiceBindingGuid = &gEfiIp4ServiceBindingProtocolGuid;\r
-    IpProtocolGuid     = &gEfiIp4ProtocolGuid;\r
-  } else if (IpVersion == IP_VERSION_6){\r
-    ServiceBindingGuid = &gEfiIp6ServiceBindingProtocolGuid;\r
-    IpProtocolGuid     = &gEfiIp6ProtocolGuid;\r
-  } else {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  //\r
-  // Create an IP child.\r
-  //\r
-  Status = NetLibCreateServiceChild (\r
-             ControllerHandle,\r
-             ImageHandle,\r
-             ServiceBindingGuid,\r
-             ChildHandle\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Open the IP protocol installed on the *ChildHandle.\r
-  //\r
-  Status = gBS->OpenProtocol (\r
-                  *ChildHandle,\r
-                  IpProtocolGuid,\r
-                  Interface,\r
-                  ImageHandle,\r
-                  ControllerHandle,\r
-                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    //\r
-    // On failure, destroy the IP child.\r
-    //\r
-    NetLibDestroyServiceChild (\r
-      ControllerHandle,\r
-      ImageHandle,\r
-      ServiceBindingGuid,\r
-      *ChildHandle\r
-      );\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-\r
-/**\r
-  This function close the previously openned IP protocol and destroy the IP child.\r
-\r
-  @param[in]  ControllerHandle    The controller handle.\r
-  @param[in]  ImageHandle         The image handle.\r
-  @param[in]  ChildHandle         The child handle of the IP child.\r
-  @param[in]  IpVersion           The version of the IP protocol to use, either\r
-                                  IPv4 or IPv6.\r
-\r
-  @retval     EFI_SUCCESS         The IP protocol is closed and the relevant IP child\r
-                                  is destroyed.\r
-  @retval     EFI_UNSUPPORTED     Upsupported IpVersion.\r
-  @retval     Others              The required operation failed.\r
-\r
-**/\r
-EFI_STATUS\r
-IpIoCloseProtocolDestroyIpChild (\r
-  IN EFI_HANDLE  ControllerHandle,\r
-  IN EFI_HANDLE  ImageHandle,\r
-  IN EFI_HANDLE  ChildHandle,\r
-  IN UINT8       IpVersion\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-  EFI_GUID    *ServiceBindingGuid;\r
-  EFI_GUID    *IpProtocolGuid;\r
-\r
-  if (IpVersion == IP_VERSION_4) {\r
-    ServiceBindingGuid = &gEfiIp4ServiceBindingProtocolGuid;\r
-    IpProtocolGuid     = &gEfiIp4ProtocolGuid;\r
-  } else if (IpVersion == IP_VERSION_6) {\r
-    ServiceBindingGuid = &gEfiIp6ServiceBindingProtocolGuid;\r
-    IpProtocolGuid     = &gEfiIp6ProtocolGuid;\r
-  } else {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  //\r
-  // Close the previously openned IP protocol.\r
-  //\r
-  Status = gBS->CloseProtocol (\r
-                  ChildHandle,\r
-                  IpProtocolGuid,\r
-                  ImageHandle,\r
-                  ControllerHandle\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Destroy the IP child.\r
-  //\r
-  return NetLibDestroyServiceChild (\r
-           ControllerHandle,\r
-           ImageHandle,\r
-           ServiceBindingGuid,\r
-           ChildHandle\r
-           );\r
-}\r
-\r
-/**\r
-  This function handles ICMPv4 packets. It is the worker function of\r
-  IpIoIcmpHandler.\r
-\r
-  @param[in]       IpIo            Pointer to the IP_IO instance.\r
-  @param[in, out]  Pkt             Pointer to the ICMPv4 packet.\r
-  @param[in]       Session         Pointer to the net session of this ICMPv4 packet.\r
-\r
-  @retval          EFI_SUCCESS     The ICMPv4 packet is handled successfully.\r
-  @retval          EFI_ABORTED     This type of ICMPv4 packet is not supported.\r
-\r
-**/\r
-EFI_STATUS\r
-IpIoIcmpv4Handler (\r
-  IN     IP_IO                *IpIo,\r
-  IN OUT NET_BUF              *Pkt,\r
-  IN     EFI_NET_SESSION_DATA *Session\r
-  )\r
-{\r
-  IP4_ICMP_ERROR_HEAD  *IcmpHdr;\r
-  EFI_IP4_HEADER       *IpHdr;\r
-  UINT8                IcmpErr;\r
-  UINT8                *PayLoadHdr;\r
-  UINT8                Type;\r
-  UINT8                Code;\r
-  UINT32               TrimBytes;\r
-\r
-  ASSERT (IpIo != NULL);\r
-  ASSERT (Pkt != NULL);\r
-  ASSERT (Session != NULL);\r
-  ASSERT (IpIo->IpVersion == IP_VERSION_4);\r
-\r
-  //\r
-  // Check the ICMP packet length.\r
-  //\r
-  if (Pkt->TotalSize < sizeof (IP4_ICMP_ERROR_HEAD)) {\r
-    return EFI_ABORTED;\r
-  }\r
-\r
-  IcmpHdr = NET_PROTO_HDR (Pkt, IP4_ICMP_ERROR_HEAD);\r
-  IpHdr   = (EFI_IP4_HEADER *) (&IcmpHdr->IpHead);\r
-\r
-  if (Pkt->TotalSize < ICMP_ERRLEN (IpHdr)) {\r
-\r
-    return EFI_ABORTED;\r
-  }\r
-\r
-  Type = IcmpHdr->Head.Type;\r
-  Code = IcmpHdr->Head.Code;\r
-\r
-  //\r
-  // Analyze the ICMP Error in this ICMP pkt\r
-  //\r
-  switch (Type) {\r
-  case ICMP_TYPE_UNREACH:\r
-    switch (Code) {\r
-    case ICMP_CODE_UNREACH_NET:\r
-    case ICMP_CODE_UNREACH_HOST:\r
-    case ICMP_CODE_UNREACH_PROTOCOL:\r
-    case ICMP_CODE_UNREACH_PORT:\r
-    case ICMP_CODE_UNREACH_SRCFAIL:\r
-      IcmpErr = (UINT8) (ICMP_ERR_UNREACH_NET + Code);\r
-\r
-      break;\r
-\r
-    case ICMP_CODE_UNREACH_NEEDFRAG:\r
-      IcmpErr = ICMP_ERR_MSGSIZE;\r
-\r
-      break;\r
-\r
-    case ICMP_CODE_UNREACH_NET_UNKNOWN:\r
-    case ICMP_CODE_UNREACH_NET_PROHIB:\r
-    case ICMP_CODE_UNREACH_TOSNET:\r
-      IcmpErr = ICMP_ERR_UNREACH_NET;\r
-\r
-      break;\r
-\r
-    case ICMP_CODE_UNREACH_HOST_UNKNOWN:\r
-    case ICMP_CODE_UNREACH_ISOLATED:\r
-    case ICMP_CODE_UNREACH_HOST_PROHIB:\r
-    case ICMP_CODE_UNREACH_TOSHOST:\r
-      IcmpErr = ICMP_ERR_UNREACH_HOST;\r
-\r
-      break;\r
-\r
-    default:\r
-      return EFI_ABORTED;\r
-    }\r
-\r
-    break;\r
-\r
-  case ICMP_TYPE_TIMXCEED:\r
-    if (Code > 1) {\r
-      return EFI_ABORTED;\r
-    }\r
-\r
-    IcmpErr = (UINT8) (Code + ICMP_ERR_TIMXCEED_INTRANS);\r
-\r
-    break;\r
-\r
-  case ICMP_TYPE_PARAMPROB:\r
-    if (Code > 1) {\r
-      return EFI_ABORTED;\r
-    }\r
-\r
-    IcmpErr = ICMP_ERR_PARAMPROB;\r
-\r
-    break;\r
-\r
-  case ICMP_TYPE_SOURCEQUENCH:\r
-    if (Code != 0) {\r
-      return EFI_ABORTED;\r
-    }\r
-\r
-    IcmpErr = ICMP_ERR_QUENCH;\r
-\r
-    break;\r
-\r
-  default:\r
-    return EFI_ABORTED;\r
-  }\r
-\r
-  //\r
-  // Notify user the ICMP pkt only containing payload except\r
-  // IP and ICMP header\r
-  //\r
-  PayLoadHdr = (UINT8 *) ((UINT8 *) IpHdr + EFI_IP4_HEADER_LEN (IpHdr));\r
-  TrimBytes  = (UINT32) (PayLoadHdr - (UINT8 *) IcmpHdr);\r
-\r
-  NetbufTrim (Pkt, TrimBytes, TRUE);\r
-\r
-  //\r
-  // If the input packet has invalid format, and TrimBytes is larger than\r
-  // the packet size, the NetbufTrim might trim the packet to zero.\r
-  //\r
-  if (Pkt->TotalSize != 0) {\r
-    IpIo->PktRcvdNotify (EFI_ICMP_ERROR, IcmpErr, Session, Pkt, IpIo->RcvdContext);\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  This function handles ICMPv6 packets. It is the worker function of\r
-  IpIoIcmpHandler.\r
-\r
-  @param[in]       IpIo            Pointer to the IP_IO instance.\r
-  @param[in, out]  Pkt             Pointer to the ICMPv6 packet.\r
-  @param[in]       Session         Pointer to the net session of this ICMPv6 packet.\r
-\r
-  @retval          EFI_SUCCESS     The ICMPv6 packet is handled successfully.\r
-  @retval          EFI_ABORTED     This type of ICMPv6 packet is not supported.\r
-\r
-**/\r
-EFI_STATUS\r
-IpIoIcmpv6Handler (\r
-  IN     IP_IO                *IpIo,\r
-  IN OUT NET_BUF              *Pkt,\r
-  IN     EFI_NET_SESSION_DATA *Session\r
-  )\r
-{\r
-  IP6_ICMP_ERROR_HEAD  *IcmpHdr;\r
-  EFI_IP6_HEADER       *IpHdr;\r
-  UINT8                IcmpErr;\r
-  UINT8                *PayLoadHdr;\r
-  UINT8                Type;\r
-  UINT8                Code;\r
-  UINT8                NextHeader;\r
-  UINT32               TrimBytes;\r
-  BOOLEAN              Flag;\r
-\r
-  ASSERT (IpIo != NULL);\r
-  ASSERT (Pkt != NULL);\r
-  ASSERT (Session != NULL);\r
-  ASSERT (IpIo->IpVersion == IP_VERSION_6);\r
-\r
-  //\r
-  // Check the ICMPv6 packet length.\r
-  //\r
-  if (Pkt->TotalSize < sizeof (IP6_ICMP_ERROR_HEAD)) {\r
-\r
-    return EFI_ABORTED;\r
-  }\r
-\r
-  IcmpHdr = NET_PROTO_HDR (Pkt, IP6_ICMP_ERROR_HEAD);\r
-  Type    = IcmpHdr->Head.Type;\r
-  Code    = IcmpHdr->Head.Code;\r
-\r
-  //\r
-  // Analyze the ICMPv6 Error in this ICMPv6 packet\r
-  //\r
-  switch (Type) {\r
-  case ICMP_V6_DEST_UNREACHABLE:\r
-    switch (Code) {\r
-    case ICMP_V6_NO_ROUTE_TO_DEST:\r
-    case ICMP_V6_BEYOND_SCOPE:\r
-    case ICMP_V6_ROUTE_REJECTED:\r
-      IcmpErr = ICMP6_ERR_UNREACH_NET;\r
-\r
-      break;\r
-\r
-    case ICMP_V6_COMM_PROHIBITED:\r
-    case ICMP_V6_ADDR_UNREACHABLE:\r
-    case ICMP_V6_SOURCE_ADDR_FAILED:\r
-      IcmpErr = ICMP6_ERR_UNREACH_HOST;\r
-\r
-      break;\r
-\r
-    case ICMP_V6_PORT_UNREACHABLE:\r
-      IcmpErr = ICMP6_ERR_UNREACH_PORT;\r
-\r
-      break;\r
-\r
-     default:\r
-      return EFI_ABORTED;\r
-    }\r
-\r
-    break;\r
-\r
-  case ICMP_V6_PACKET_TOO_BIG:\r
-    if (Code >= 1) {\r
-      return EFI_ABORTED;\r
-    }\r
-\r
-    IcmpErr = ICMP6_ERR_PACKAGE_TOOBIG;\r
-\r
-    break;\r
-\r
-  case ICMP_V6_TIME_EXCEEDED:\r
-    if (Code > 1) {\r
-      return EFI_ABORTED;\r
-    }\r
-\r
-    IcmpErr = (UINT8) (ICMP6_ERR_TIMXCEED_HOPLIMIT + Code);\r
-\r
-    break;\r
-\r
-  case ICMP_V6_PARAMETER_PROBLEM:\r
-    if (Code > 3) {\r
-      return EFI_ABORTED;\r
-    }\r
-\r
-    IcmpErr = (UINT8) (ICMP6_ERR_PARAMPROB_HEADER + Code);\r
-\r
-    break;\r
-\r
-   default:\r
-\r
-     return EFI_ABORTED;\r
-   }\r
-\r
-  //\r
-  // Notify user the ICMPv6 packet only containing payload except\r
-  // IPv6 basic header, extension header and ICMP header\r
-  //\r
-\r
-  IpHdr      = (EFI_IP6_HEADER *) (&IcmpHdr->IpHead);\r
-  NextHeader = IpHdr->NextHeader;\r
-  PayLoadHdr = (UINT8 *) ((UINT8 *) IcmpHdr + sizeof (IP6_ICMP_ERROR_HEAD));\r
-  Flag       = TRUE;\r
-\r
-  do {\r
-    switch (NextHeader) {\r
-    case EFI_IP_PROTO_UDP:\r
-    case EFI_IP_PROTO_TCP:\r
-    case EFI_IP_PROTO_ICMP:\r
-    case IP6_NO_NEXT_HEADER:\r
-      Flag = FALSE;\r
-\r
-      break;\r
-\r
-    case IP6_HOP_BY_HOP:\r
-    case IP6_DESTINATION:\r
-      //\r
-      // The Hdr Ext Len is 8-bit unsigned integer in 8-octet units, not including\r
-      // the first 8 octets.\r
-      //\r
-      NextHeader = *(PayLoadHdr);\r
-      PayLoadHdr = (UINT8 *) (PayLoadHdr + (*(PayLoadHdr + 1) + 1) * 8);\r
-\r
-      break;\r
-\r
-    case IP6_FRAGMENT:\r
-      //\r
-      // The Fragment Header Length is 8 octets.\r
-      //\r
-      NextHeader = *(PayLoadHdr);\r
-      PayLoadHdr = (UINT8 *) (PayLoadHdr + 8);\r
-\r
-      break;\r
-\r
-    default:\r
-\r
-      return EFI_ABORTED;\r
-    }\r
-  } while (Flag);\r
-\r
-  TrimBytes = (UINT32) (PayLoadHdr - (UINT8 *) IcmpHdr);\r
-\r
-  NetbufTrim (Pkt, TrimBytes, TRUE);\r
-\r
-  //\r
-  // If the input packet has invalid format, and TrimBytes is larger than\r
-  // the packet size, the NetbufTrim might trim the packet to zero.\r
-  //\r
-  if (Pkt->TotalSize != 0) {\r
-    IpIo->PktRcvdNotify (EFI_ICMP_ERROR, IcmpErr, Session, Pkt, IpIo->RcvdContext);\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  This function handles ICMP packets.\r
-\r
-  @param[in]       IpIo            Pointer to the IP_IO instance.\r
-  @param[in, out]  Pkt             Pointer to the ICMP packet.\r
-  @param[in]       Session         Pointer to the net session of this ICMP packet.\r
-\r
-  @retval          EFI_SUCCESS     The ICMP packet is handled successfully.\r
-  @retval          EFI_ABORTED     This type of ICMP packet is not supported.\r
-  @retval          EFI_UNSUPPORTED The IP protocol version in IP_IO is not supported.\r
-\r
-**/\r
-EFI_STATUS\r
-IpIoIcmpHandler (\r
-  IN     IP_IO                *IpIo,\r
-  IN OUT NET_BUF              *Pkt,\r
-  IN     EFI_NET_SESSION_DATA *Session\r
-  )\r
-{\r
-\r
-  if (IpIo->IpVersion == IP_VERSION_4) {\r
-\r
-    return IpIoIcmpv4Handler (IpIo, Pkt, Session);\r
-\r
-  } else if (IpIo->IpVersion == IP_VERSION_6) {\r
-\r
-    return IpIoIcmpv6Handler (IpIo, Pkt, Session);\r
-\r
-  } else {\r
-\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-}\r
-\r
-\r
-/**\r
-  Free function for receive token of IP_IO. It is used to\r
-  signal the recycle event to notify IP to recycle the\r
-  data buffer.\r
-\r
-  @param[in]  Event                 The event to be signaled.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-IpIoExtFree (\r
-  IN VOID  *Event\r
-  )\r
-{\r
-  gBS->SignalEvent ((EFI_EVENT) Event);\r
-}\r
-\r
-\r
-/**\r
-  Create a send entry to wrap a packet before sending\r
-  out it through IP.\r
-\r
-  @param[in, out]  IpIo                 Pointer to the IP_IO instance.\r
-  @param[in, out]  Pkt                  Pointer to the packet.\r
-  @param[in]       Sender               Pointer to the IP sender.\r
-  @param[in]       Context              Pointer to the context.\r
-  @param[in]       NotifyData           Pointer to the notify data.\r
-  @param[in]       Dest                 Pointer to the destination IP address.\r
-  @param[in]       Override             Pointer to the overriden IP_IO data.\r
-\r
-  @return Pointer to the data structure created to wrap the packet. If any error occurs,\r
-          then return NULL.\r
-\r
-**/\r
-IP_IO_SEND_ENTRY *\r
-IpIoCreateSndEntry (\r
-  IN OUT IP_IO             *IpIo,\r
-  IN OUT NET_BUF           *Pkt,\r
-  IN     IP_IO_IP_PROTOCOL Sender,\r
-  IN     VOID              *Context    OPTIONAL,\r
-  IN     VOID              *NotifyData OPTIONAL,\r
-  IN     EFI_IP_ADDRESS    *Dest       OPTIONAL,\r
-  IN     IP_IO_OVERRIDE    *Override\r
-  )\r
-{\r
-  IP_IO_SEND_ENTRY          *SndEntry;\r
-  EFI_EVENT                 Event;\r
-  EFI_STATUS                Status;\r
-  NET_FRAGMENT              *ExtFragment;\r
-  UINT32                    FragmentCount;\r
-  IP_IO_OVERRIDE            *OverrideData;\r
-  IP_IO_IP_TX_DATA          *TxData;\r
-  EFI_IP4_TRANSMIT_DATA     *Ip4TxData;\r
-  EFI_IP6_TRANSMIT_DATA     *Ip6TxData;\r
-\r
-  if ((IpIo->IpVersion != IP_VERSION_4) && (IpIo->IpVersion != IP_VERSION_6)) {\r
-    return NULL;\r
-  }\r
-\r
-  Event        = NULL;\r
-  TxData       = NULL;\r
-  OverrideData = NULL;\r
-\r
-  //\r
-  // Allocate resource for SndEntry\r
-  //\r
-  SndEntry = AllocatePool (sizeof (IP_IO_SEND_ENTRY));\r
-  if (NULL == SndEntry) {\r
-    return NULL;\r
-  }\r
-\r
-  Status = gBS->CreateEvent (\r
-                  EVT_NOTIFY_SIGNAL,\r
-                  TPL_NOTIFY,\r
-                  IpIoTransmitHandler,\r
-                  SndEntry,\r
-                  &Event\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    goto ON_ERROR;\r
-  }\r
-\r
-  FragmentCount = Pkt->BlockOpNum;\r
-\r
-  //\r
-  // Allocate resource for TxData\r
-  //\r
-  TxData = (IP_IO_IP_TX_DATA *) AllocatePool (\r
-    sizeof (IP_IO_IP_TX_DATA) + sizeof (NET_FRAGMENT) * (FragmentCount - 1)\r
-    );\r
-\r
-  if (NULL == TxData) {\r
-    goto ON_ERROR;\r
-  }\r
-\r
-  //\r
-  // Build a fragment table to contain the fragments in the packet.\r
-  //\r
-  if (IpIo->IpVersion == IP_VERSION_4) {\r
-    ExtFragment = (NET_FRAGMENT *) TxData->Ip4TxData.FragmentTable;\r
-  } else {\r
-    ExtFragment = (NET_FRAGMENT *) TxData->Ip6TxData.FragmentTable;\r
-  }\r
-\r
-  NetbufBuildExt (Pkt, ExtFragment, &FragmentCount);\r
-\r
-\r
-  //\r
-  // Allocate resource for OverrideData if needed\r
-  //\r
-  if (NULL != Override) {\r
-\r
-    OverrideData = AllocateCopyPool (sizeof (IP_IO_OVERRIDE), Override);\r
-    if (NULL == OverrideData) {\r
-      goto ON_ERROR;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Set other fields of TxData except the fragment table\r
-  //\r
-  if (IpIo->IpVersion == IP_VERSION_4) {\r
-\r
-    Ip4TxData = &TxData->Ip4TxData;\r
-\r
-    IP4_COPY_ADDRESS (&Ip4TxData->DestinationAddress, Dest);\r
-\r
-    Ip4TxData->OverrideData    = &OverrideData->Ip4OverrideData;\r
-    Ip4TxData->OptionsLength   = 0;\r
-    Ip4TxData->OptionsBuffer   = NULL;\r
-    Ip4TxData->TotalDataLength = Pkt->TotalSize;\r
-    Ip4TxData->FragmentCount   = FragmentCount;\r
-\r
-    //\r
-    // Set the fields of SndToken\r
-    //\r
-    SndEntry->SndToken.Ip4Token.Event         = Event;\r
-    SndEntry->SndToken.Ip4Token.Packet.TxData = Ip4TxData;\r
-  } else {\r
-\r
-    Ip6TxData = &TxData->Ip6TxData;\r
-\r
-    if (Dest != NULL) {\r
-      CopyMem (&Ip6TxData->DestinationAddress, Dest, sizeof (EFI_IPv6_ADDRESS));\r
-    } else {\r
-      ZeroMem (&Ip6TxData->DestinationAddress, sizeof (EFI_IPv6_ADDRESS));\r
-    }\r
-\r
-    Ip6TxData->OverrideData  = &OverrideData->Ip6OverrideData;\r
-    Ip6TxData->DataLength    = Pkt->TotalSize;\r
-    Ip6TxData->FragmentCount = FragmentCount;\r
-    Ip6TxData->ExtHdrsLength = 0;\r
-    Ip6TxData->ExtHdrs       = NULL;\r
-\r
-    //\r
-    // Set the fields of SndToken\r
-    //\r
-    SndEntry->SndToken.Ip6Token.Event         = Event;\r
-    SndEntry->SndToken.Ip6Token.Packet.TxData = Ip6TxData;\r
-  }\r
-\r
-  //\r
-  // Set the fields of SndEntry\r
-  //\r
-  SndEntry->IpIo        = IpIo;\r
-  SndEntry->Ip          = Sender;\r
-  SndEntry->Context     = Context;\r
-  SndEntry->NotifyData  = NotifyData;\r
-\r
-  SndEntry->Pkt         = Pkt;\r
-  NET_GET_REF (Pkt);\r
-\r
-  InsertTailList (&IpIo->PendingSndList, &SndEntry->Entry);\r
-\r
-  return SndEntry;\r
-\r
-ON_ERROR:\r
-\r
-  if (OverrideData != NULL) {\r
-    FreePool (OverrideData);\r
-  }\r
-\r
-  if (TxData != NULL) {\r
-    FreePool (TxData);\r
-  }\r
-\r
-  if (SndEntry != NULL) {\r
-    FreePool (SndEntry);\r
-  }\r
-\r
-  if (Event != NULL) {\r
-    gBS->CloseEvent (Event);\r
-  }\r
-\r
-  return NULL;\r
-}\r
-\r
-\r
-/**\r
-  Destroy the SndEntry.\r
-\r
-  This function pairs with IpIoCreateSndEntry().\r
-\r
-  @param[in]  SndEntry              Pointer to the send entry to be destroyed.\r
-\r
-**/\r
-VOID\r
-IpIoDestroySndEntry (\r
-  IN IP_IO_SEND_ENTRY  *SndEntry\r
-  )\r
-{\r
-  EFI_EVENT         Event;\r
-  IP_IO_IP_TX_DATA  *TxData;\r
-  IP_IO_OVERRIDE    *Override;\r
-\r
-  if (SndEntry->IpIo->IpVersion == IP_VERSION_4) {\r
-    Event              = SndEntry->SndToken.Ip4Token.Event;\r
-    TxData             = (IP_IO_IP_TX_DATA *) SndEntry->SndToken.Ip4Token.Packet.TxData;\r
-    Override           = (IP_IO_OVERRIDE *) TxData->Ip4TxData.OverrideData;\r
-  } else if (SndEntry->IpIo->IpVersion == IP_VERSION_6) {\r
-    Event              = SndEntry->SndToken.Ip6Token.Event;\r
-    TxData             = (IP_IO_IP_TX_DATA *) SndEntry->SndToken.Ip6Token.Packet.TxData;\r
-    Override           = (IP_IO_OVERRIDE *) TxData->Ip6TxData.OverrideData;\r
-  } else {\r
-    return ;\r
-  }\r
-\r
-  gBS->CloseEvent (Event);\r
-\r
-  FreePool (TxData);\r
-\r
-  if (NULL != Override) {\r
-    FreePool (Override);\r
-  }\r
-\r
-  NetbufFree (SndEntry->Pkt);\r
-\r
-  RemoveEntryList (&SndEntry->Entry);\r
-\r
-  FreePool (SndEntry);\r
-}\r
-\r
-\r
-/**\r
-  Notify function for IP transmit token.\r
-\r
-  @param[in]  Context               The context passed in by the event notifier.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-IpIoTransmitHandlerDpc (\r
-  IN VOID      *Context\r
-  )\r
-{\r
-  IP_IO             *IpIo;\r
-  IP_IO_SEND_ENTRY  *SndEntry;\r
-  EFI_STATUS        Status;\r
-\r
-  SndEntry  = (IP_IO_SEND_ENTRY *) Context;\r
-\r
-  IpIo      = SndEntry->IpIo;\r
-\r
-  if (IpIo->IpVersion == IP_VERSION_4) {\r
-    Status = SndEntry->SndToken.Ip4Token.Status;\r
-  } else if (IpIo->IpVersion == IP_VERSION_6){\r
-    Status = SndEntry->SndToken.Ip6Token.Status;\r
-  } else {\r
-    return ;\r
-  }\r
-\r
-  if ((IpIo->PktSentNotify != NULL) && (SndEntry->NotifyData != NULL)) {\r
-    IpIo->PktSentNotify (\r
-            Status,\r
-            SndEntry->Context,\r
-            SndEntry->Ip,\r
-            SndEntry->NotifyData\r
-            );\r
-  }\r
-\r
-  IpIoDestroySndEntry (SndEntry);\r
-}\r
-\r
-\r
-/**\r
-  Notify function for IP transmit token.\r
-\r
-  @param[in]  Event                 The event signaled.\r
-  @param[in]  Context               The context passed in by the event notifier.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-IpIoTransmitHandler (\r
-  IN EFI_EVENT Event,\r
-  IN VOID      *Context\r
-  )\r
-{\r
-  //\r
-  // Request IpIoTransmitHandlerDpc as a DPC at TPL_CALLBACK\r
-  //\r
-  QueueDpc (TPL_CALLBACK, IpIoTransmitHandlerDpc, Context);\r
-}\r
-\r
-\r
-/**\r
-  The dummy handler for the dummy IP receive token.\r
-\r
-  @param[in]  Context               The context passed in by the event notifier.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-IpIoDummyHandlerDpc (\r
-  IN VOID      *Context\r
-  )\r
-{\r
-  IP_IO_IP_INFO             *IpInfo;\r
-  EFI_STATUS                 Status;\r
-  EFI_EVENT                  RecycleEvent;\r
-\r
-  IpInfo      = (IP_IO_IP_INFO *) Context;\r
-\r
-  if ((IpInfo->IpVersion != IP_VERSION_4) && (IpInfo->IpVersion != IP_VERSION_6)) {\r
-    return ;\r
-  }\r
-\r
-  RecycleEvent = NULL;\r
-\r
-  if (IpInfo->IpVersion == IP_VERSION_4) {\r
-    Status = IpInfo->DummyRcvToken.Ip4Token.Status;\r
-\r
-    if (IpInfo->DummyRcvToken.Ip4Token.Packet.RxData != NULL) {\r
-      RecycleEvent = IpInfo->DummyRcvToken.Ip4Token.Packet.RxData->RecycleSignal;\r
-    }\r
-  } else {\r
-    Status = IpInfo->DummyRcvToken.Ip6Token.Status;\r
-\r
-    if (IpInfo->DummyRcvToken.Ip6Token.Packet.RxData != NULL) {\r
-      RecycleEvent = IpInfo->DummyRcvToken.Ip6Token.Packet.RxData->RecycleSignal;\r
-    }\r
-  }\r
-\r
-\r
-\r
-  if (EFI_ABORTED == Status) {\r
-    //\r
-    // The reception is actively aborted by the consumer, directly return.\r
-    //\r
-    return;\r
-  } else if (EFI_SUCCESS == Status) {\r
-    //\r
-    // Recycle the RxData.\r
-    //\r
-    ASSERT (RecycleEvent != NULL);\r
-\r
-    gBS->SignalEvent (RecycleEvent);\r
-  }\r
-\r
-  //\r
-  // Continue the receive.\r
-  //\r
-  if (IpInfo->IpVersion == IP_VERSION_4) {\r
-    IpInfo->Ip.Ip4->Receive (\r
-                      IpInfo->Ip.Ip4,\r
-                      &IpInfo->DummyRcvToken.Ip4Token\r
-                      );\r
-  } else {\r
-    IpInfo->Ip.Ip6->Receive (\r
-                      IpInfo->Ip.Ip6,\r
-                      &IpInfo->DummyRcvToken.Ip6Token\r
-                      );\r
-  }\r
-}\r
-\r
-\r
-/**\r
-  This function add IpIoDummyHandlerDpc to the end of the DPC queue.\r
-\r
-  @param[in]  Event                 The event signaled.\r
-  @param[in]  Context               The context passed in by the event notifier.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-IpIoDummyHandler (\r
-  IN EFI_EVENT Event,\r
-  IN VOID      *Context\r
-  )\r
-{\r
-  //\r
-  // Request IpIoDummyHandlerDpc as a DPC at TPL_CALLBACK\r
-  //\r
-  QueueDpc (TPL_CALLBACK, IpIoDummyHandlerDpc, Context);\r
-}\r
-\r
-\r
-/**\r
-  Notify function for the IP receive token, used to process\r
-  the received IP packets.\r
-\r
-  @param[in]  Context               The context passed in by the event notifier.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-IpIoListenHandlerDpc (\r
-  IN VOID      *Context\r
-  )\r
-{\r
-  IP_IO                 *IpIo;\r
-  EFI_STATUS            Status;\r
-  IP_IO_IP_RX_DATA      *RxData;\r
-  EFI_NET_SESSION_DATA  Session;\r
-  NET_BUF               *Pkt;\r
-\r
-  IpIo = (IP_IO *) Context;\r
-\r
-  if (IpIo->IpVersion == IP_VERSION_4) {\r
-    Status = IpIo->RcvToken.Ip4Token.Status;\r
-    RxData = (IP_IO_IP_RX_DATA *) IpIo->RcvToken.Ip4Token.Packet.RxData;\r
-  } else if (IpIo->IpVersion == IP_VERSION_6) {\r
-    Status = IpIo->RcvToken.Ip6Token.Status;\r
-    RxData = (IP_IO_IP_RX_DATA *) IpIo->RcvToken.Ip6Token.Packet.RxData;\r
-  } else {\r
-    return;\r
-  }\r
-\r
-  if (EFI_ABORTED == Status) {\r
-    //\r
-    // The reception is actively aborted by the consumer, directly return.\r
-    //\r
-    return;\r
-  }\r
-\r
-  if ((EFI_SUCCESS != Status) && (EFI_ICMP_ERROR != Status)) {\r
-    //\r
-    // Only process the normal packets and the icmp error packets.\r
-    //\r
-    if (RxData != NULL) {\r
-      goto CleanUp;\r
-    } else {\r
-      goto Resume;\r
-    }\r
-  }\r
-\r
-  //\r
-  // if RxData is NULL with Status == EFI_SUCCESS or EFI_ICMP_ERROR, this should be a code issue in the low layer (IP).\r
-  //\r
-  ASSERT (RxData != NULL);\r
-  if (RxData == NULL) {\r
-    goto Resume;\r
-  }\r
-\r
-  if (NULL == IpIo->PktRcvdNotify) {\r
-    goto CleanUp;\r
-  }\r
-\r
-  if (IpIo->IpVersion == IP_VERSION_4) {\r
-    ASSERT (RxData->Ip4RxData.Header != NULL);\r
-    if (IP4_IS_LOCAL_BROADCAST (EFI_IP4 (RxData->Ip4RxData.Header->SourceAddress))) {\r
-      //\r
-      // The source address is a broadcast address, discard it.\r
-      //\r
-      goto CleanUp;\r
-    }\r
-    if ((EFI_IP4 (RxData->Ip4RxData.Header->SourceAddress) != 0) &&\r
-        (IpIo->SubnetMask != 0) &&\r
-        IP4_NET_EQUAL (IpIo->StationIp, EFI_NTOHL (((EFI_IP4_RECEIVE_DATA *) RxData)->Header->SourceAddress), IpIo->SubnetMask) &&\r
-        !NetIp4IsUnicast (EFI_NTOHL (((EFI_IP4_RECEIVE_DATA *) RxData)->Header->SourceAddress), IpIo->SubnetMask)) {\r
-      //\r
-      // The source address doesn't match StationIp and it's not a unicast IP address, discard it.\r
-      //\r
-      goto CleanUp;\r
-    }\r
-\r
-    if (RxData->Ip4RxData.DataLength == 0) {\r
-      //\r
-      // Discard zero length data payload packet.\r
-      //\r
-      goto CleanUp;\r
-    }\r
-\r
-    //\r
-    // The fragment should always be valid for non-zero length packet.\r
-    //\r
-    ASSERT (RxData->Ip4RxData.FragmentCount != 0);\r
-\r
-    //\r
-    // Create a netbuffer representing IPv4 packet\r
-    //\r
-    Pkt = NetbufFromExt (\r
-            (NET_FRAGMENT *) RxData->Ip4RxData.FragmentTable,\r
-            RxData->Ip4RxData.FragmentCount,\r
-            0,\r
-            0,\r
-            IpIoExtFree,\r
-            RxData->Ip4RxData.RecycleSignal\r
-            );\r
-    if (NULL == Pkt) {\r
-      goto CleanUp;\r
-    }\r
-\r
-    //\r
-    // Create a net session\r
-    //\r
-    Session.Source.Addr[0] = EFI_IP4 (RxData->Ip4RxData.Header->SourceAddress);\r
-    Session.Dest.Addr[0]   = EFI_IP4 (RxData->Ip4RxData.Header->DestinationAddress);\r
-    Session.IpHdr.Ip4Hdr   = RxData->Ip4RxData.Header;\r
-    Session.IpHdrLen       = RxData->Ip4RxData.HeaderLength;\r
-    Session.IpVersion      = IP_VERSION_4;\r
-  } else {\r
-    ASSERT (RxData->Ip6RxData.Header != NULL);\r
-    if (!NetIp6IsValidUnicast(&RxData->Ip6RxData.Header->SourceAddress)) {\r
-      goto CleanUp;\r
-    }\r
-\r
-    if (RxData->Ip6RxData.DataLength == 0) {\r
-      //\r
-      // Discard zero length data payload packet.\r
-      //\r
-      goto CleanUp;\r
-    }\r
-\r
-    //\r
-    // The fragment should always be valid for non-zero length packet.\r
-    //\r
-    ASSERT (RxData->Ip6RxData.FragmentCount != 0);\r
-\r
-    //\r
-    // Create a netbuffer representing IPv6 packet\r
-    //\r
-    Pkt = NetbufFromExt (\r
-            (NET_FRAGMENT *) RxData->Ip6RxData.FragmentTable,\r
-            RxData->Ip6RxData.FragmentCount,\r
-            0,\r
-            0,\r
-            IpIoExtFree,\r
-            RxData->Ip6RxData.RecycleSignal\r
-            );\r
-    if (NULL == Pkt) {\r
-      goto CleanUp;\r
-    }\r
-\r
-    //\r
-    // Create a net session\r
-    //\r
-    CopyMem (\r
-      &Session.Source,\r
-      &RxData->Ip6RxData.Header->SourceAddress,\r
-      sizeof(EFI_IPv6_ADDRESS)\r
-      );\r
-    CopyMem (\r
-      &Session.Dest,\r
-      &RxData->Ip6RxData.Header->DestinationAddress,\r
-      sizeof(EFI_IPv6_ADDRESS)\r
-      );\r
-    Session.IpHdr.Ip6Hdr = RxData->Ip6RxData.Header;\r
-    Session.IpHdrLen     = RxData->Ip6RxData.HeaderLength;\r
-    Session.IpVersion    = IP_VERSION_6;\r
-  }\r
-\r
-  if (EFI_SUCCESS == Status) {\r
-\r
-    IpIo->PktRcvdNotify (EFI_SUCCESS, 0, &Session, Pkt, IpIo->RcvdContext);\r
-  } else {\r
-    //\r
-    // Status is EFI_ICMP_ERROR\r
-    //\r
-    Status = IpIoIcmpHandler (IpIo, Pkt, &Session);\r
-    if (EFI_ERROR (Status)) {\r
-      NetbufFree (Pkt);\r
-    }\r
-  }\r
-\r
-  goto Resume;\r
-\r
-CleanUp:\r
-\r
-  if (IpIo->IpVersion == IP_VERSION_4){\r
-    gBS->SignalEvent (RxData->Ip4RxData.RecycleSignal);\r
-  } else {\r
-    gBS->SignalEvent (RxData->Ip6RxData.RecycleSignal);\r
-  }\r
-\r
-Resume:\r
-\r
-  if (IpIo->IpVersion == IP_VERSION_4){\r
-    IpIo->Ip.Ip4->Receive (IpIo->Ip.Ip4, &(IpIo->RcvToken.Ip4Token));\r
-  } else {\r
-    IpIo->Ip.Ip6->Receive (IpIo->Ip.Ip6, &(IpIo->RcvToken.Ip6Token));\r
-  }\r
-}\r
-\r
-/**\r
-  This function add IpIoListenHandlerDpc to the end of the DPC queue.\r
-\r
-  @param[in]  Event                The event signaled.\r
-  @param[in]  Context              The context passed in by the event notifier.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-IpIoListenHandler (\r
-  IN EFI_EVENT Event,\r
-  IN VOID      *Context\r
-  )\r
-{\r
-  //\r
-  // Request IpIoListenHandlerDpc as a DPC at TPL_CALLBACK\r
-  //\r
-  QueueDpc (TPL_CALLBACK, IpIoListenHandlerDpc, Context);\r
-}\r
-\r
-\r
-/**\r
-  Create a new IP_IO instance.\r
-\r
-  If IpVersion is not IP_VERSION_4 or IP_VERSION_6, then ASSERT().\r
-\r
-  This function uses IP4/IP6 service binding protocol in Controller to create\r
-  an IP4/IP6 child (aka IP4/IP6 instance).\r
-\r
-  @param[in]  Image             The image handle of the driver or application that\r
-                                consumes IP_IO.\r
-  @param[in]  Controller        The controller handle that has IP4 or IP6 service\r
-                                binding protocol installed.\r
-  @param[in]  IpVersion         The version of the IP protocol to use, either\r
-                                IPv4 or IPv6.\r
-\r
-  @return Pointer to a newly created IP_IO instance, or NULL if failed.\r
-\r
-**/\r
-IP_IO *\r
-EFIAPI\r
-IpIoCreate (\r
-  IN EFI_HANDLE Image,\r
-  IN EFI_HANDLE Controller,\r
-  IN UINT8      IpVersion\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-  IP_IO       *IpIo;\r
-  EFI_EVENT   Event;\r
-\r
-  ASSERT ((IpVersion == IP_VERSION_4) || (IpVersion == IP_VERSION_6));\r
-\r
-  IpIo = AllocateZeroPool (sizeof (IP_IO));\r
-  if (NULL == IpIo) {\r
-    return NULL;\r
-  }\r
-\r
-  InitializeListHead (&(IpIo->PendingSndList));\r
-  InitializeListHead (&(IpIo->IpList));\r
-  IpIo->Controller  = Controller;\r
-  IpIo->Image       = Image;\r
-  IpIo->IpVersion   = IpVersion;\r
-  Event             = NULL;\r
-\r
-  Status = gBS->CreateEvent (\r
-                  EVT_NOTIFY_SIGNAL,\r
-                  TPL_NOTIFY,\r
-                  IpIoListenHandler,\r
-                  IpIo,\r
-                  &Event\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    goto ReleaseIpIo;\r
-  }\r
-\r
-  if (IpVersion == IP_VERSION_4) {\r
-    IpIo->RcvToken.Ip4Token.Event = Event;\r
-  } else {\r
-    IpIo->RcvToken.Ip6Token.Event = Event;\r
-  }\r
-\r
-  //\r
-  // Create an IP child and open IP protocol\r
-  //\r
-  Status = IpIoCreateIpChildOpenProtocol (\r
-             Controller,\r
-             Image,\r
-             &IpIo->ChildHandle,\r
-             IpVersion,\r
-             (VOID **) & (IpIo->Ip)\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    goto ReleaseIpIo;\r
-  }\r
-\r
-  return IpIo;\r
-\r
-ReleaseIpIo:\r
-\r
-  if (Event != NULL) {\r
-    gBS->CloseEvent (Event);\r
-  }\r
-\r
-  gBS->FreePool (IpIo);\r
-\r
-  return NULL;\r
-}\r
-\r
-\r
-/**\r
-  Open an IP_IO instance for use.\r
-\r
-  If Ip version is not IP_VERSION_4 or IP_VERSION_6, then ASSERT().\r
-\r
-  This function is called after IpIoCreate(). It is used for configuring the IP\r
-  instance and register the callbacks and their context data for sending and\r
-  receiving IP packets.\r
-\r
-  @param[in, out]  IpIo               Pointer to an IP_IO instance that needs\r
-                                      to open.\r
-  @param[in]       OpenData           The configuration data and callbacks for\r
-                                      the IP_IO instance.\r
-\r
-  @retval          EFI_SUCCESS            The IP_IO instance opened with OpenData\r
-                                          successfully.\r
-  @retval          EFI_ACCESS_DENIED      The IP_IO instance is configured, avoid to\r
-                                          reopen it.\r
-  @retval          EFI_UNSUPPORTED        IPv4 RawData mode is no supported.\r
-  @retval          EFI_INVALID_PARAMETER  Invalid input parameter.\r
-  @retval          Others                 Error condition occurred.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IpIoOpen (\r
-  IN OUT IP_IO           *IpIo,\r
-  IN     IP_IO_OPEN_DATA *OpenData\r
-  )\r
-{\r
-  EFI_STATUS        Status;\r
-  UINT8             IpVersion;\r
-\r
-  if (IpIo == NULL || OpenData == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (IpIo->IsConfigured) {\r
-    return EFI_ACCESS_DENIED;\r
-  }\r
-\r
-  IpVersion = IpIo->IpVersion;\r
-\r
-  ASSERT ((IpVersion == IP_VERSION_4) || (IpVersion == IP_VERSION_6));\r
-\r
-  //\r
-  // configure ip\r
-  //\r
-  if (IpVersion == IP_VERSION_4){\r
-    //\r
-    // RawData mode is no supported.\r
-    //\r
-    ASSERT (!OpenData->IpConfigData.Ip4CfgData.RawData);\r
-    if (OpenData->IpConfigData.Ip4CfgData.RawData) {\r
-      return EFI_UNSUPPORTED;\r
-    }\r
-\r
-    if (!OpenData->IpConfigData.Ip4CfgData.UseDefaultAddress) {\r
-      IpIo->StationIp = EFI_NTOHL (OpenData->IpConfigData.Ip4CfgData.StationAddress);\r
-      IpIo->SubnetMask = EFI_NTOHL (OpenData->IpConfigData.Ip4CfgData.SubnetMask);\r
-    }\r
-\r
-    Status = IpIo->Ip.Ip4->Configure (\r
-                             IpIo->Ip.Ip4,\r
-                             &OpenData->IpConfigData.Ip4CfgData\r
-                             );\r
-  } else {\r
-\r
-    Status = IpIo->Ip.Ip6->Configure (\r
-                             IpIo->Ip.Ip6,\r
-                             &OpenData->IpConfigData.Ip6CfgData\r
-                             );\r
-  }\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // @bug To delete the default route entry in this Ip, if it is:\r
-  // @bug (0.0.0.0, 0.0.0.0, 0.0.0.0). Delete this statement if Ip modified\r
-  // @bug its code\r
-  //\r
-  if (IpVersion == IP_VERSION_4){\r
-    Status = IpIo->Ip.Ip4->Routes (\r
-                             IpIo->Ip.Ip4,\r
-                             TRUE,\r
-                             &mZeroIp4Addr,\r
-                             &mZeroIp4Addr,\r
-                             &mZeroIp4Addr\r
-                             );\r
-\r
-    if (EFI_ERROR (Status) && (EFI_NOT_FOUND != Status)) {\r
-      return Status;\r
-    }\r
-  }\r
-\r
-  IpIo->PktRcvdNotify = OpenData->PktRcvdNotify;\r
-  IpIo->PktSentNotify = OpenData->PktSentNotify;\r
-\r
-  IpIo->RcvdContext   = OpenData->RcvdContext;\r
-  IpIo->SndContext    = OpenData->SndContext;\r
-\r
-  if (IpVersion == IP_VERSION_4){\r
-    IpIo->Protocol = OpenData->IpConfigData.Ip4CfgData.DefaultProtocol;\r
-\r
-    //\r
-    // start to listen incoming packet\r
-    //\r
-    Status = IpIo->Ip.Ip4->Receive (\r
-                             IpIo->Ip.Ip4,\r
-                             &(IpIo->RcvToken.Ip4Token)\r
-                             );\r
-    if (EFI_ERROR (Status)) {\r
-      IpIo->Ip.Ip4->Configure (IpIo->Ip.Ip4, NULL);\r
-      return Status;\r
-    }\r
-\r
-  } else {\r
-\r
-    IpIo->Protocol = OpenData->IpConfigData.Ip6CfgData.DefaultProtocol;\r
-    Status = IpIo->Ip.Ip6->Receive (\r
-                             IpIo->Ip.Ip6,\r
-                             &(IpIo->RcvToken.Ip6Token)\r
-                             );\r
-    if (EFI_ERROR (Status)) {\r
-      IpIo->Ip.Ip6->Configure (IpIo->Ip.Ip6, NULL);\r
-      return Status;\r
-    }\r
-  }\r
-\r
-  IpIo->IsConfigured = TRUE;\r
-  InsertTailList (&mActiveIpIoList, &IpIo->Entry);\r
-\r
-  return Status;\r
-}\r
-\r
-\r
-/**\r
-  Stop an IP_IO instance.\r
-\r
-  If Ip version is not IP_VERSION_4 or IP_VERSION_6, then ASSERT().\r
-\r
-  This function is paired with IpIoOpen(). The IP_IO will be unconfigured and all\r
-  the pending send/receive tokens will be canceled.\r
-\r
-  @param[in, out]  IpIo            Pointer to the IP_IO instance that needs to stop.\r
-\r
-  @retval          EFI_SUCCESS            The IP_IO instance stopped successfully.\r
-  @retval          EFI_INVALID_PARAMETER  Invalid input parameter.\r
-  @retval          Others                 Error condition occurred.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IpIoStop (\r
-  IN OUT IP_IO *IpIo\r
-  )\r
-{\r
-  EFI_STATUS        Status;\r
-  IP_IO_IP_INFO     *IpInfo;\r
-  UINT8             IpVersion;\r
-\r
-  if (IpIo == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (!IpIo->IsConfigured) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  IpVersion = IpIo->IpVersion;\r
-\r
-  ASSERT ((IpVersion == IP_VERSION_4) || (IpVersion == IP_VERSION_6));\r
-\r
-  //\r
-  // Remove the IpIo from the active IpIo list.\r
-  //\r
-  RemoveEntryList (&IpIo->Entry);\r
-\r
-  //\r
-  // Configure NULL Ip\r
-  //\r
-  if (IpVersion == IP_VERSION_4) {\r
-    Status = IpIo->Ip.Ip4->Configure (IpIo->Ip.Ip4, NULL);\r
-  } else {\r
-    Status = IpIo->Ip.Ip6->Configure (IpIo->Ip.Ip6, NULL);\r
-  }\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  IpIo->IsConfigured = FALSE;\r
-\r
-  //\r
-  // Detroy the Ip List used by IpIo\r
-  //\r
-\r
-  while (!IsListEmpty (&(IpIo->IpList))) {\r
-    IpInfo = NET_LIST_HEAD (&(IpIo->IpList), IP_IO_IP_INFO, Entry);\r
-\r
-    IpIoRemoveIp (IpIo, IpInfo);\r
-  }\r
-\r
-  //\r
-  // All pending send tokens should be flushed by resetting the IP instances.\r
-  //\r
-  ASSERT (IsListEmpty (&IpIo->PendingSndList));\r
-\r
-  //\r
-  // Close the receive event.\r
-  //\r
-  if (IpVersion == IP_VERSION_4){\r
-    gBS->CloseEvent (IpIo->RcvToken.Ip4Token.Event);\r
-  } else {\r
-    gBS->CloseEvent (IpIo->RcvToken.Ip6Token.Event);\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
-  Destroy an IP_IO instance.\r
-\r
-  This function is paired with IpIoCreate(). The IP_IO will be closed first.\r
-  Resource will be freed afterwards. See IpIoCloseProtocolDestroyIpChild().\r
-\r
-  @param[in, out]  IpIo         Pointer to the IP_IO instance that needs to be\r
-                                destroyed.\r
-\r
-  @retval          EFI_SUCCESS  The IP_IO instance destroyed successfully.\r
-  @retval          Others       Error condition occurred.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IpIoDestroy (\r
-  IN OUT IP_IO *IpIo\r
-  )\r
-{\r
-  EFI_STATUS    Status;\r
-\r
-  //\r
-  // Stop the IpIo.\r
-  //\r
-  Status = IpIoStop (IpIo);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Close the IP protocol and destroy the child.\r
-  //\r
-  Status = IpIoCloseProtocolDestroyIpChild (\r
-             IpIo->Controller,\r
-             IpIo->Image,\r
-             IpIo->ChildHandle,\r
-             IpIo->IpVersion\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  gBS->FreePool (IpIo);\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
-  Send out an IP packet.\r
-\r
-  This function is called after IpIoOpen(). The data to be sent is wrapped in\r
-  Pkt. The IP instance wrapped in IpIo is used for sending by default but can be\r
-  overriden by Sender. Other sending configs, like source address and gateway\r
-  address etc., are specified in OverrideData.\r
-\r
-  @param[in, out]  IpIo                  Pointer to an IP_IO instance used for sending IP\r
-                                         packet.\r
-  @param[in, out]  Pkt                   Pointer to the IP packet to be sent.\r
-  @param[in]       Sender                The IP protocol instance used for sending.\r
-  @param[in]       Context               Optional context data.\r
-  @param[in]       NotifyData            Optional notify data.\r
-  @param[in]       Dest                  The destination IP address to send this packet to.\r
-                                         This parameter is optional when using IPv6.\r
-  @param[in]       OverrideData          The data to override some configuration of the IP\r
-                                         instance used for sending.\r
-\r
-  @retval          EFI_SUCCESS           The operation is completed successfully.\r
-  @retval          EFI_INVALID_PARAMETER The input parameter is not correct.\r
-  @retval          EFI_NOT_STARTED       The IpIo is not configured.\r
-  @retval          EFI_OUT_OF_RESOURCES  Failed due to resource limit.\r
-  @retval          Others                Error condition occurred.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IpIoSend (\r
-  IN OUT IP_IO          *IpIo,\r
-  IN OUT NET_BUF        *Pkt,\r
-  IN     IP_IO_IP_INFO  *Sender        OPTIONAL,\r
-  IN     VOID           *Context       OPTIONAL,\r
-  IN     VOID           *NotifyData    OPTIONAL,\r
-  IN     EFI_IP_ADDRESS *Dest          OPTIONAL,\r
-  IN     IP_IO_OVERRIDE *OverrideData  OPTIONAL\r
-  )\r
-{\r
-  EFI_STATUS        Status;\r
-  IP_IO_IP_PROTOCOL Ip;\r
-  IP_IO_SEND_ENTRY  *SndEntry;\r
-\r
-  if ((IpIo == NULL) || (Pkt == NULL)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if ((IpIo->IpVersion == IP_VERSION_4) && (Dest == NULL)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (!IpIo->IsConfigured) {\r
-    return EFI_NOT_STARTED;\r
-  }\r
-\r
-  Ip = (NULL == Sender) ? IpIo->Ip : Sender->Ip;\r
-\r
-  //\r
-  // create a new SndEntry\r
-  //\r
-  SndEntry = IpIoCreateSndEntry (IpIo, Pkt, Ip, Context, NotifyData, Dest, OverrideData);\r
-  if (NULL == SndEntry) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  //\r
-  // Send this Packet\r
-  //\r
-  if (IpIo->IpVersion == IP_VERSION_4){\r
-    Status = Ip.Ip4->Transmit (\r
-                       Ip.Ip4,\r
-                       &SndEntry->SndToken.Ip4Token\r
-                       );\r
-  } else {\r
-    Status = Ip.Ip6->Transmit (\r
-                       Ip.Ip6,\r
-                       &SndEntry->SndToken.Ip6Token\r
-                       );\r
-  }\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    IpIoDestroySndEntry (SndEntry);\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-\r
-/**\r
-  Cancel the IP transmit token which wraps this Packet.\r
-\r
-  If IpIo is NULL, then ASSERT().\r
-  If Packet is NULL, then ASSERT().\r
-\r
-  @param[in]  IpIo                  Pointer to the IP_IO instance.\r
-  @param[in]  Packet                Pointer to the packet of NET_BUF to cancel.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-IpIoCancelTxToken (\r
-  IN IP_IO  *IpIo,\r
-  IN VOID   *Packet\r
-  )\r
-{\r
-  LIST_ENTRY        *Node;\r
-  IP_IO_SEND_ENTRY  *SndEntry;\r
-  IP_IO_IP_PROTOCOL Ip;\r
-\r
-  ASSERT ((IpIo != NULL) && (Packet != NULL));\r
-\r
-  NET_LIST_FOR_EACH (Node, &IpIo->PendingSndList) {\r
-\r
-    SndEntry = NET_LIST_USER_STRUCT (Node, IP_IO_SEND_ENTRY, Entry);\r
-\r
-    if (SndEntry->Pkt == Packet) {\r
-\r
-      Ip = SndEntry->Ip;\r
-\r
-      if (IpIo->IpVersion == IP_VERSION_4) {\r
-        Ip.Ip4->Cancel (\r
-                  Ip.Ip4,\r
-                  &SndEntry->SndToken.Ip4Token\r
-                  );\r
-      } else {\r
-        Ip.Ip6->Cancel (\r
-                  Ip.Ip6,\r
-                  &SndEntry->SndToken.Ip6Token\r
-                  );\r
-      }\r
-\r
-      break;\r
-    }\r
-  }\r
-\r
-}\r
-\r
-\r
-/**\r
-  Add a new IP instance for sending data.\r
-\r
-  If IpIo is NULL, then ASSERT().\r
-  If Ip version is not IP_VERSION_4 or IP_VERSION_6, then ASSERT().\r
-\r
-  The function is used to add the IP_IO to the IP_IO sending list. The caller\r
-  can later use IpIoFindSender() to get the IP_IO and call IpIoSend() to send\r
-  data.\r
-\r
-  @param[in, out]  IpIo               Pointer to a IP_IO instance to add a new IP\r
-                                      instance for sending purpose.\r
-\r
-  @return Pointer to the created IP_IO_IP_INFO structure, NULL if failed.\r
-\r
-**/\r
-IP_IO_IP_INFO *\r
-EFIAPI\r
-IpIoAddIp (\r
-  IN OUT IP_IO  *IpIo\r
-  )\r
-{\r
-  EFI_STATUS     Status;\r
-  IP_IO_IP_INFO  *IpInfo;\r
-  EFI_EVENT      Event;\r
-\r
-  ASSERT (IpIo != NULL);\r
-  ASSERT ((IpIo->IpVersion == IP_VERSION_4) || (IpIo->IpVersion == IP_VERSION_6));\r
-\r
-  IpInfo = AllocatePool (sizeof (IP_IO_IP_INFO));\r
-  if (IpInfo == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  //\r
-  // Init this IpInfo, set the Addr and SubnetMask to 0 before we configure the IP\r
-  // instance.\r
-  //\r
-  InitializeListHead (&IpInfo->Entry);\r
-  IpInfo->ChildHandle = NULL;\r
-  ZeroMem (&IpInfo->Addr, sizeof (IpInfo->Addr));\r
-  ZeroMem (&IpInfo->PreMask, sizeof (IpInfo->PreMask));\r
-\r
-  IpInfo->RefCnt    = 1;\r
-  IpInfo->IpVersion = IpIo->IpVersion;\r
-\r
-  //\r
-  // Create the IP instance and open the IP protocol.\r
-  //\r
-  Status = IpIoCreateIpChildOpenProtocol (\r
-             IpIo->Controller,\r
-             IpIo->Image,\r
-             &IpInfo->ChildHandle,\r
-             IpInfo->IpVersion,\r
-             (VOID **) &IpInfo->Ip\r
-             );\r
-  if (EFI_ERROR (Status)) {\r
-    goto ReleaseIpInfo;\r
-  }\r
-\r
-  //\r
-  // Create the event for the DummyRcvToken.\r
-  //\r
-  Status = gBS->CreateEvent (\r
-                  EVT_NOTIFY_SIGNAL,\r
-                  TPL_NOTIFY,\r
-                  IpIoDummyHandler,\r
-                  IpInfo,\r
-                  &Event\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    goto ReleaseIpChild;\r
-  }\r
-\r
-  if (IpInfo->IpVersion == IP_VERSION_4) {\r
-    IpInfo->DummyRcvToken.Ip4Token.Event = Event;\r
-  } else {\r
-    IpInfo->DummyRcvToken.Ip6Token.Event = Event;\r
-  }\r
-\r
-  //\r
-  // Link this IpInfo into the IpIo.\r
-  //\r
-  InsertTailList (&IpIo->IpList, &IpInfo->Entry);\r
-\r
-  return IpInfo;\r
-\r
-ReleaseIpChild:\r
-\r
-  IpIoCloseProtocolDestroyIpChild (\r
-    IpIo->Controller,\r
-    IpIo->Image,\r
-    IpInfo->ChildHandle,\r
-    IpInfo->IpVersion\r
-    );\r
-\r
-ReleaseIpInfo:\r
-\r
-  gBS->FreePool (IpInfo);\r
-\r
-  return NULL;\r
-}\r
-\r
-\r
-/**\r
-  Configure the IP instance of this IpInfo and start the receiving if IpConfigData\r
-  is not NULL.\r
-\r
-  If IpInfo is NULL, then ASSERT().\r
-  If Ip version is not IP_VERSION_4 or IP_VERSION_6, then ASSERT().\r
-\r
-  @param[in, out]  IpInfo          Pointer to the IP_IO_IP_INFO instance.\r
-  @param[in, out]  IpConfigData    The IP configure data used to configure the IP\r
-                                   instance, if NULL the IP instance is reset. If\r
-                                   UseDefaultAddress is set to TRUE, and the configure\r
-                                   operation succeeds, the default address information\r
-                                   is written back in this IpConfigData.\r
-\r
-  @retval          EFI_SUCCESS     The IP instance of this IpInfo is configured successfully\r
-                                   or no need to reconfigure it.\r
-  @retval          Others          Configuration fails.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IpIoConfigIp (\r
-  IN OUT IP_IO_IP_INFO        *IpInfo,\r
-  IN OUT VOID                 *IpConfigData OPTIONAL\r
-  )\r
-{\r
-  EFI_STATUS         Status;\r
-  IP_IO_IP_PROTOCOL  Ip;\r
-  UINT8              IpVersion;\r
-  EFI_IP4_MODE_DATA  Ip4ModeData;\r
-  EFI_IP6_MODE_DATA  Ip6ModeData;\r
-\r
-  ASSERT (IpInfo != NULL);\r
-\r
-  if (IpInfo->RefCnt > 1) {\r
-    //\r
-    // This IP instance is shared, don't reconfigure it until it has only one\r
-    // consumer. Currently, only the tcp children cloned from their passive parent\r
-    // will share the same IP. So this cases only happens while IpConfigData is NULL,\r
-    // let the last consumer clean the IP instance.\r
-    //\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  IpVersion = IpInfo->IpVersion;\r
-  ASSERT ((IpVersion == IP_VERSION_4) || (IpVersion == IP_VERSION_6));\r
-\r
-  Ip = IpInfo->Ip;\r
-\r
-  if (IpInfo->IpVersion == IP_VERSION_4) {\r
-    Status = Ip.Ip4->Configure (Ip.Ip4, IpConfigData);\r
-  } else {\r
-    Status = Ip.Ip6->Configure (Ip.Ip6, IpConfigData);\r
-  }\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  if (IpConfigData != NULL) {\r
-    if (IpInfo->IpVersion == IP_VERSION_4) {\r
-\r
-      if (((EFI_IP4_CONFIG_DATA *) IpConfigData)->UseDefaultAddress) {\r
-        Status = Ip.Ip4->GetModeData (\r
-                           Ip.Ip4,\r
-                           &Ip4ModeData,\r
-                           NULL,\r
-                           NULL\r
-                           );\r
-        if (EFI_ERROR (Status)) {\r
-          Ip.Ip4->Configure (Ip.Ip4, NULL);\r
-          return Status;\r
-        }\r
-\r
-        IP4_COPY_ADDRESS (&((EFI_IP4_CONFIG_DATA*) IpConfigData)->StationAddress, &Ip4ModeData.ConfigData.StationAddress);\r
-        IP4_COPY_ADDRESS (&((EFI_IP4_CONFIG_DATA*) IpConfigData)->SubnetMask, &Ip4ModeData.ConfigData.SubnetMask);\r
-      }\r
-\r
-      CopyMem (\r
-        &IpInfo->Addr.Addr,\r
-        &((EFI_IP4_CONFIG_DATA *) IpConfigData)->StationAddress,\r
-        sizeof (IP4_ADDR)\r
-        );\r
-      CopyMem (\r
-        &IpInfo->PreMask.SubnetMask,\r
-        &((EFI_IP4_CONFIG_DATA *) IpConfigData)->SubnetMask,\r
-        sizeof (IP4_ADDR)\r
-        );\r
-\r
-      Status = Ip.Ip4->Receive (\r
-                         Ip.Ip4,\r
-                         &IpInfo->DummyRcvToken.Ip4Token\r
-                         );\r
-      if (EFI_ERROR (Status)) {\r
-        Ip.Ip4->Configure (Ip.Ip4, NULL);\r
-      }\r
-    } else {\r
-      Status = Ip.Ip6->GetModeData (\r
-                         Ip.Ip6,\r
-                         &Ip6ModeData,\r
-                         NULL,\r
-                         NULL\r
-                         );\r
-      if (EFI_ERROR (Status)) {\r
-        Ip.Ip6->Configure (Ip.Ip6, NULL);\r
-        return Status;\r
-      }\r
-\r
-      if (Ip6ModeData.IsConfigured) {\r
-        CopyMem (\r
-          &((EFI_IP6_CONFIG_DATA *) IpConfigData)->StationAddress,\r
-          &Ip6ModeData.ConfigData.StationAddress,\r
-          sizeof (EFI_IPv6_ADDRESS)\r
-          );\r
-\r
-        if (Ip6ModeData.AddressList != NULL) {\r
-          FreePool (Ip6ModeData.AddressList);\r
-        }\r
-\r
-        if (Ip6ModeData.GroupTable != NULL) {\r
-          FreePool (Ip6ModeData.GroupTable);\r
-        }\r
-\r
-        if (Ip6ModeData.RouteTable != NULL) {\r
-          FreePool (Ip6ModeData.RouteTable);\r
-        }\r
-\r
-        if (Ip6ModeData.NeighborCache != NULL) {\r
-          FreePool (Ip6ModeData.NeighborCache);\r
-        }\r
-\r
-        if (Ip6ModeData.PrefixTable != NULL) {\r
-          FreePool (Ip6ModeData.PrefixTable);\r
-        }\r
-\r
-        if (Ip6ModeData.IcmpTypeList != NULL) {\r
-          FreePool (Ip6ModeData.IcmpTypeList);\r
-        }\r
-\r
-      } else {\r
-        Status = EFI_NO_MAPPING;\r
-        return Status;\r
-      }\r
-\r
-      CopyMem (\r
-        &IpInfo->Addr,\r
-        &Ip6ModeData.ConfigData.StationAddress,\r
-        sizeof (EFI_IPv6_ADDRESS)\r
-        );\r
-\r
-      Status = Ip.Ip6->Receive (\r
-                         Ip.Ip6,\r
-                         &IpInfo->DummyRcvToken.Ip6Token\r
-                         );\r
-      if (EFI_ERROR (Status)) {\r
-        Ip.Ip6->Configure (Ip.Ip6, NULL);\r
-      }\r
-    }\r
-  } else {\r
-    //\r
-    // The IP instance is reset, set the stored Addr and SubnetMask to zero.\r
-    //\r
-    ZeroMem (&IpInfo->Addr, sizeof (IpInfo->Addr));\r
-    ZeroMem (&IpInfo->PreMask, sizeof (IpInfo->PreMask));\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-\r
-/**\r
-  Destroy an IP instance maintained in IpIo->IpList for\r
-  sending purpose.\r
-\r
-  If Ip version is not IP_VERSION_4 or IP_VERSION_6, then ASSERT().\r
-\r
-  This function pairs with IpIoAddIp(). The IpInfo is previously created by\r
-  IpIoAddIp(). The IP_IO_IP_INFO::RefCnt is decremented and the IP instance\r
-  will be dstroyed if the RefCnt is zero.\r
-\r
-  @param[in]  IpIo                  Pointer to the IP_IO instance.\r
-  @param[in]  IpInfo                Pointer to the IpInfo to be removed.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-IpIoRemoveIp (\r
-  IN IP_IO            *IpIo,\r
-  IN IP_IO_IP_INFO    *IpInfo\r
-  )\r
-{\r
-\r
-  UINT8               IpVersion;\r
-\r
-  if (IpIo == NULL || IpInfo == NULL) {\r
-    return;\r
-  }\r
-\r
-  ASSERT (IpInfo->RefCnt > 0);\r
-\r
-  NET_PUT_REF (IpInfo);\r
-\r
-  if (IpInfo->RefCnt > 0) {\r
-\r
-    return;\r
-  }\r
-\r
-  IpVersion = IpIo->IpVersion;\r
-\r
-  ASSERT ((IpVersion == IP_VERSION_4) || (IpVersion == IP_VERSION_6));\r
-\r
-  RemoveEntryList (&IpInfo->Entry);\r
-\r
-  if (IpVersion == IP_VERSION_4){\r
-    IpInfo->Ip.Ip4->Configure (\r
-                      IpInfo->Ip.Ip4,\r
-                      NULL\r
-                      );\r
-    IpIoCloseProtocolDestroyIpChild (\r
-      IpIo->Controller,\r
-      IpIo->Image,\r
-      IpInfo->ChildHandle,\r
-      IP_VERSION_4\r
-      );\r
-\r
-    gBS->CloseEvent (IpInfo->DummyRcvToken.Ip4Token.Event);\r
-\r
-  } else {\r
-\r
-    IpInfo->Ip.Ip6->Configure (\r
-                      IpInfo->Ip.Ip6,\r
-                      NULL\r
-                      );\r
-\r
-    IpIoCloseProtocolDestroyIpChild (\r
-      IpIo->Controller,\r
-      IpIo->Image,\r
-      IpInfo->ChildHandle,\r
-      IP_VERSION_6\r
-      );\r
-\r
-    gBS->CloseEvent (IpInfo->DummyRcvToken.Ip6Token.Event);\r
-  }\r
-\r
-  FreePool (IpInfo);\r
-}\r
-\r
-\r
-/**\r
-  Find the first IP protocol maintained in IpIo whose local\r
-  address is the same as Src.\r
-\r
-  This function is called when the caller needs the IpIo to send data to the\r
-  specified Src. The IpIo was added previously by IpIoAddIp().\r
-\r
-  @param[in, out]  IpIo              Pointer to the pointer of the IP_IO instance.\r
-  @param[in]       IpVersion         The version of the IP protocol to use, either\r
-                                     IPv4 or IPv6.\r
-  @param[in]       Src               The local IP address.\r
-\r
-  @return Pointer to the IP protocol can be used for sending purpose and its local\r
-          address is the same with Src. NULL if failed.\r
-\r
-**/\r
-IP_IO_IP_INFO *\r
-EFIAPI\r
-IpIoFindSender (\r
-  IN OUT IP_IO           **IpIo,\r
-  IN     UINT8           IpVersion,\r
-  IN     EFI_IP_ADDRESS  *Src\r
-  )\r
-{\r
-  LIST_ENTRY      *IpIoEntry;\r
-  IP_IO           *IpIoPtr;\r
-  LIST_ENTRY      *IpInfoEntry;\r
-  IP_IO_IP_INFO   *IpInfo;\r
-\r
-  if (IpIo == NULL || Src == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  if ((IpVersion != IP_VERSION_4) && (IpVersion != IP_VERSION_6)) {\r
-    return NULL;\r
-  }\r
-\r
-  NET_LIST_FOR_EACH (IpIoEntry, &mActiveIpIoList) {\r
-    IpIoPtr = NET_LIST_USER_STRUCT (IpIoEntry, IP_IO, Entry);\r
-\r
-    if (((*IpIo != NULL) && (*IpIo != IpIoPtr)) || (IpIoPtr->IpVersion != IpVersion)) {\r
-      continue;\r
-    }\r
-\r
-    NET_LIST_FOR_EACH (IpInfoEntry, &IpIoPtr->IpList) {\r
-      IpInfo = NET_LIST_USER_STRUCT (IpInfoEntry, IP_IO_IP_INFO, Entry);\r
-      if (IpInfo->IpVersion == IP_VERSION_4){\r
-\r
-        if (EFI_IP4_EQUAL (&IpInfo->Addr.v4, &Src->v4)) {\r
-          *IpIo = IpIoPtr;\r
-          return IpInfo;\r
-        }\r
-\r
-      } else {\r
-\r
-        if (EFI_IP6_EQUAL (&IpInfo->Addr.v6, &Src->v6)) {\r
-          *IpIo = IpIoPtr;\r
-          return IpInfo;\r
-        }\r
-      }\r
-    }\r
-  }\r
-\r
-  //\r
-  // No match.\r
-  //\r
-  return NULL;\r
-}\r
-\r
-\r
-/**\r
-  Get the ICMP error map information.\r
-\r
-  The ErrorStatus will be returned. The IsHard and Notify are optional. If they\r
-  are not NULL, this routine will fill them.\r
-\r
-  @param[in]   IcmpError             IcmpError Type.\r
-  @param[in]   IpVersion             The version of the IP protocol to use,\r
-                                     either IPv4 or IPv6.\r
-  @param[out]  IsHard                If TRUE, indicates that it is a hard error.\r
-  @param[out]  Notify                If TRUE, SockError needs to be notified.\r
-\r
-  @retval EFI_UNSUPPORTED            Unrecognizable ICMP error code.\r
-  @return ICMP Error Status, such as EFI_NETWORK_UNREACHABLE.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IpIoGetIcmpErrStatus (\r
-  IN  UINT8       IcmpError,\r
-  IN  UINT8       IpVersion,\r
-  OUT BOOLEAN     *IsHard  OPTIONAL,\r
-  OUT BOOLEAN     *Notify  OPTIONAL\r
-  )\r
-{\r
-  if (IpVersion == IP_VERSION_4 ) {\r
-    ASSERT (IcmpError <= ICMP_ERR_PARAMPROB);\r
-\r
-    if (IsHard != NULL) {\r
-      *IsHard = mIcmpErrMap[IcmpError].IsHard;\r
-    }\r
-\r
-    if (Notify != NULL) {\r
-      *Notify = mIcmpErrMap[IcmpError].Notify;\r
-    }\r
-\r
-    switch (IcmpError) {\r
-    case ICMP_ERR_UNREACH_NET:\r
-      return  EFI_NETWORK_UNREACHABLE;\r
-\r
-    case ICMP_ERR_TIMXCEED_INTRANS:\r
-    case ICMP_ERR_TIMXCEED_REASS:\r
-    case ICMP_ERR_UNREACH_HOST:\r
-      return  EFI_HOST_UNREACHABLE;\r
-\r
-    case ICMP_ERR_UNREACH_PROTOCOL:\r
-      return  EFI_PROTOCOL_UNREACHABLE;\r
-\r
-    case ICMP_ERR_UNREACH_PORT:\r
-      return  EFI_PORT_UNREACHABLE;\r
-\r
-    case ICMP_ERR_MSGSIZE:\r
-    case ICMP_ERR_UNREACH_SRCFAIL:\r
-    case ICMP_ERR_QUENCH:\r
-    case ICMP_ERR_PARAMPROB:\r
-      return  EFI_ICMP_ERROR;\r
-\r
-    default:\r
-      ASSERT (FALSE);\r
-      return EFI_UNSUPPORTED;\r
-    }\r
-\r
-  } else if (IpVersion == IP_VERSION_6) {\r
-\r
-    ASSERT (IcmpError <= ICMP6_ERR_PARAMPROB_IPV6OPTION);\r
-\r
-    if (IsHard != NULL) {\r
-      *IsHard = mIcmp6ErrMap[IcmpError].IsHard;\r
-    }\r
-\r
-    if (Notify != NULL) {\r
-      *Notify = mIcmp6ErrMap[IcmpError].Notify;\r
-    }\r
-\r
-    switch (IcmpError) {\r
-    case ICMP6_ERR_UNREACH_NET:\r
-      return EFI_NETWORK_UNREACHABLE;\r
-\r
-    case ICMP6_ERR_UNREACH_HOST:\r
-    case ICMP6_ERR_TIMXCEED_HOPLIMIT:\r
-    case ICMP6_ERR_TIMXCEED_REASS:\r
-      return EFI_HOST_UNREACHABLE;\r
-\r
-    case ICMP6_ERR_UNREACH_PROTOCOL:\r
-      return EFI_PROTOCOL_UNREACHABLE;\r
-\r
-    case ICMP6_ERR_UNREACH_PORT:\r
-      return EFI_PORT_UNREACHABLE;\r
-\r
-    case ICMP6_ERR_PACKAGE_TOOBIG:\r
-    case ICMP6_ERR_PARAMPROB_HEADER:\r
-    case ICMP6_ERR_PARAMPROB_NEXHEADER:\r
-    case ICMP6_ERR_PARAMPROB_IPV6OPTION:\r
-      return EFI_ICMP_ERROR;\r
-\r
-    default:\r
-      ASSERT (FALSE);\r
-      return EFI_UNSUPPORTED;\r
-    }\r
-\r
-  } else {\r
-    //\r
-    // Should never be here\r
-    //\r
-    ASSERT (FALSE);\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-}\r
-\r
-\r
-/**\r
-  Refresh the remote peer's Neighbor Cache entries.\r
-\r
-  This function is called when the caller needs the IpIo to refresh the existing\r
-  IPv6 neighbor cache entries since the neighbor is considered reachable by the\r
-  node has recently received a confirmation that packets sent recently to the\r
-  neighbor were received by its IP layer.\r
-\r
-  @param[in]   IpIo                  Pointer to an IP_IO instance\r
-  @param[in]   Neighbor              The IP address of the neighbor\r
-  @param[in]   Timeout               Time in 100-ns units that this entry will\r
-                                     remain in the neighbor cache. A value of\r
-                                     zero means that the entry is permanent.\r
-                                     A value of non-zero means that the entry is\r
-                                     dynamic and will be deleted after Timeout.\r
-\r
-  @retval      EFI_SUCCESS           The operation is completed successfully.\r
-  @retval      EFI_NOT_STARTED       The IpIo is not configured.\r
-  @retval      EFI_INVALID_PARAMETER Neighbor Address is invalid.\r
-  @retval      EFI_NOT_FOUND         The neighbor cache entry is not in the\r
-                                     neighbor table.\r
-  @retval      EFI_UNSUPPORTED       IP version is IPv4, which doesn't support neighbor cache refresh.\r
-  @retval      EFI_OUT_OF_RESOURCES  Failed due to resource limit.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-IpIoRefreshNeighbor (\r
-  IN IP_IO           *IpIo,\r
-  IN EFI_IP_ADDRESS  *Neighbor,\r
-  IN UINT32          Timeout\r
-  )\r
-{\r
-  EFI_IP6_PROTOCOL  *Ip;\r
-\r
-  if (!IpIo->IsConfigured) {\r
-    return EFI_NOT_STARTED;\r
-  }\r
-\r
-  if (IpIo->IpVersion != IP_VERSION_6) {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  Ip = IpIo->Ip.Ip6;\r
-\r
-  return Ip->Neighbors (Ip, FALSE, &Neighbor->v6, NULL, Timeout, TRUE);\r
-}\r
-\r
diff --git a/MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf b/MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf
deleted file mode 100644 (file)
index a789d80..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-## @file\r
-#  This library instance provides IP services upon EFI IPv4/IPv6 Protocols.\r
-#\r
-#  Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
-#  SPDX-License-Identifier: BSD-2-Clause-Patent\r
-#\r
-##\r
-\r
-\r
-[Defines]\r
-  INF_VERSION                    = 0x00010005\r
-  BASE_NAME                      = DxeIpIoLib\r
-  MODULE_UNI_FILE                = DxeIpIoLib.uni\r
-  FILE_GUID                      = A302F877-8625-425c-B1EC-7487B62C4FDA\r
-  MODULE_TYPE                    = DXE_DRIVER\r
-  VERSION_STRING                 = 1.0\r
-  LIBRARY_CLASS                  = IpIoLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER\r
-\r
-#\r
-# The following information is for reference only and not required by the build tools.\r
-#\r
-#  VALID_ARCHITECTURES           = IA32 X64 EBC\r
-#\r
-\r
-[Sources]\r
-  DxeIpIoLib.c\r
-\r
-[Packages]\r
-  MdePkg/MdePkg.dec\r
-  MdeModulePkg/MdeModulePkg.dec\r
-\r
-\r
-[LibraryClasses]\r
-  BaseLib\r
-  DebugLib\r
-  UefiBootServicesTableLib\r
-  MemoryAllocationLib\r
-  BaseMemoryLib\r
-  DpcLib\r
-\r
-[Protocols]\r
-  gEfiIp4ProtocolGuid                           ## SOMETIMES_CONSUMES\r
-  gEfiIp4ServiceBindingProtocolGuid             ## SOMETIMES_CONSUMES\r
-  gEfiIp6ProtocolGuid                           ## SOMETIMES_CONSUMES\r
-  gEfiIp6ServiceBindingProtocolGuid             ## SOMETIMES_CONSUMES\r
-\r
diff --git a/MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.uni b/MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.uni
deleted file mode 100644 (file)
index 4af043c..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// /** @file\r
-// This library instance provides IP services upon EFI IPv4/IPv6 Protocols.\r
-//\r
-// This library instance provides IP services upon EFI IPv4/IPv6 Protocols.\r
-//\r
-// Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
-//\r
-// SPDX-License-Identifier: BSD-2-Clause-Patent\r
-//\r
-// **/\r
-\r
-\r
-#string STR_MODULE_ABSTRACT             #language en-US "EFI IPv4/IPv6 IP Services Library"\r
-\r
-#string STR_MODULE_DESCRIPTION          #language en-US "This library instance provides IP services upon EFI IPv4/IPv6 Protocols."\r
-\r
diff --git a/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c b/MdeModulePkg/Library/DxeNetLib/DxeNetLib.c
deleted file mode 100644 (file)
index 8e2f720..0000000
+++ /dev/null
@@ -1,3394 +0,0 @@
-/** @file\r
-  Network library.\r
-\r
-Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>\r
-(C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-**/\r
-\r
-#include <Uefi.h>\r
-\r
-#include <IndustryStandard/SmBios.h>\r
-\r
-#include <Protocol/DriverBinding.h>\r
-#include <Protocol/ServiceBinding.h>\r
-#include <Protocol/SimpleNetwork.h>\r
-#include <Protocol/AdapterInformation.h>\r
-#include <Protocol/ManagedNetwork.h>\r
-#include <Protocol/Ip4Config2.h>\r
-#include <Protocol/ComponentName.h>\r
-#include <Protocol/ComponentName2.h>\r
-\r
-#include <Guid/SmBios.h>\r
-\r
-#include <Library/NetLib.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/UefiRuntimeServicesTableLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Library/DevicePathLib.h>\r
-#include <Library/PrintLib.h>\r
-#include <Library/UefiLib.h>\r
-\r
-#define NIC_ITEM_CONFIG_SIZE   (sizeof (NIC_IP4_CONFIG_INFO) + sizeof (EFI_IP4_ROUTE_TABLE) * MAX_IP4_CONFIG_IN_VARIABLE)\r
-#define DEFAULT_ZERO_START     ((UINTN) ~0)\r
-\r
-//\r
-// All the supported IP4 maskes in host byte order.\r
-//\r
-GLOBAL_REMOVE_IF_UNREFERENCED IP4_ADDR  gIp4AllMasks[IP4_MASK_NUM] = {\r
-  0x00000000,\r
-  0x80000000,\r
-  0xC0000000,\r
-  0xE0000000,\r
-  0xF0000000,\r
-  0xF8000000,\r
-  0xFC000000,\r
-  0xFE000000,\r
-\r
-  0xFF000000,\r
-  0xFF800000,\r
-  0xFFC00000,\r
-  0xFFE00000,\r
-  0xFFF00000,\r
-  0xFFF80000,\r
-  0xFFFC0000,\r
-  0xFFFE0000,\r
-\r
-  0xFFFF0000,\r
-  0xFFFF8000,\r
-  0xFFFFC000,\r
-  0xFFFFE000,\r
-  0xFFFFF000,\r
-  0xFFFFF800,\r
-  0xFFFFFC00,\r
-  0xFFFFFE00,\r
-\r
-  0xFFFFFF00,\r
-  0xFFFFFF80,\r
-  0xFFFFFFC0,\r
-  0xFFFFFFE0,\r
-  0xFFFFFFF0,\r
-  0xFFFFFFF8,\r
-  0xFFFFFFFC,\r
-  0xFFFFFFFE,\r
-  0xFFFFFFFF,\r
-};\r
-\r
-GLOBAL_REMOVE_IF_UNREFERENCED EFI_IPv4_ADDRESS  mZeroIp4Addr = {{0, 0, 0, 0}};\r
-\r
-//\r
-// Any error level digitally larger than mNetDebugLevelMax\r
-// will be silently discarded.\r
-//\r
-GLOBAL_REMOVE_IF_UNREFERENCED UINTN  mNetDebugLevelMax = NETDEBUG_LEVEL_ERROR;\r
-GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mSyslogPacketSeq  = 0xDEADBEEF;\r
-\r
-//\r
-// You can change mSyslogDstMac mSyslogDstIp and mSyslogSrcIp\r
-// here to direct the syslog packets to the syslog deamon. The\r
-// default is broadcast to both the ethernet and IP.\r
-//\r
-GLOBAL_REMOVE_IF_UNREFERENCED UINT8  mSyslogDstMac[NET_ETHER_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};\r
-GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mSyslogDstIp                      = 0xffffffff;\r
-GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mSyslogSrcIp                      = 0;\r
-\r
-GLOBAL_REMOVE_IF_UNREFERENCED CHAR8 *mMonthName[] = {\r
-  "Jan",\r
-  "Feb",\r
-  "Mar",\r
-  "Apr",\r
-  "May",\r
-  "Jun",\r
-  "Jul",\r
-  "Aug",\r
-  "Sep",\r
-  "Oct",\r
-  "Nov",\r
-  "Dec"\r
-};\r
-\r
-//\r
-// VLAN device path node template\r
-//\r
-GLOBAL_REMOVE_IF_UNREFERENCED VLAN_DEVICE_PATH mNetVlanDevicePathTemplate = {\r
-  {\r
-    MESSAGING_DEVICE_PATH,\r
-    MSG_VLAN_DP,\r
-    {\r
-      (UINT8) (sizeof (VLAN_DEVICE_PATH)),\r
-      (UINT8) ((sizeof (VLAN_DEVICE_PATH)) >> 8)\r
-    }\r
-  },\r
-  0\r
-};\r
-\r
-/**\r
-  Locate the handles that support SNP, then open one of them\r
-  to send the syslog packets. The caller isn't required to close\r
-  the SNP after use because the SNP is opened by HandleProtocol.\r
-\r
-  @return The point to SNP if one is properly openned. Otherwise NULL\r
-\r
-**/\r
-EFI_SIMPLE_NETWORK_PROTOCOL *\r
-SyslogLocateSnp (\r
-  VOID\r
-  )\r
-{\r
-  EFI_SIMPLE_NETWORK_PROTOCOL *Snp;\r
-  EFI_STATUS                  Status;\r
-  EFI_HANDLE                  *Handles;\r
-  UINTN                       HandleCount;\r
-  UINTN                       Index;\r
-\r
-  //\r
-  // Locate the handles which has SNP installed.\r
-  //\r
-  Handles = NULL;\r
-  Status  = gBS->LocateHandleBuffer (\r
-                   ByProtocol,\r
-                   &gEfiSimpleNetworkProtocolGuid,\r
-                   NULL,\r
-                   &HandleCount,\r
-                   &Handles\r
-                   );\r
-\r
-  if (EFI_ERROR (Status) || (HandleCount == 0)) {\r
-    return NULL;\r
-  }\r
-\r
-  //\r
-  // Try to open one of the ethernet SNP protocol to send packet\r
-  //\r
-  Snp = NULL;\r
-\r
-  for (Index = 0; Index < HandleCount; Index++) {\r
-    Status = gBS->HandleProtocol (\r
-                    Handles[Index],\r
-                    &gEfiSimpleNetworkProtocolGuid,\r
-                    (VOID **) &Snp\r
-                    );\r
-\r
-    if ((Status == EFI_SUCCESS) && (Snp != NULL) &&\r
-        (Snp->Mode->IfType == NET_IFTYPE_ETHERNET) &&\r
-        (Snp->Mode->MaxPacketSize >= NET_SYSLOG_PACKET_LEN)) {\r
-\r
-      break;\r
-    }\r
-\r
-    Snp = NULL;\r
-  }\r
-\r
-  FreePool (Handles);\r
-  return Snp;\r
-}\r
-\r
-/**\r
-  Transmit a syslog packet synchronously through SNP. The Packet\r
-  already has the ethernet header prepended. This function should\r
-  fill in the source MAC because it will try to locate a SNP each\r
-  time it is called to avoid the problem if SNP is unloaded.\r
-  This code snip is copied from MNP.\r
-  If Packet is NULL, then ASSERT().\r
-\r
-  @param[in] Packet          The Syslog packet\r
-  @param[in] Length          The length of the packet\r
-\r
-  @retval EFI_DEVICE_ERROR   Failed to locate a usable SNP protocol\r
-  @retval EFI_TIMEOUT        Timeout happened to send the packet.\r
-  @retval EFI_SUCCESS        Packet is sent.\r
-\r
-**/\r
-EFI_STATUS\r
-SyslogSendPacket (\r
-  IN CHAR8                    *Packet,\r
-  IN UINT32                   Length\r
-  )\r
-{\r
-  EFI_SIMPLE_NETWORK_PROTOCOL *Snp;\r
-  ETHER_HEAD                  *Ether;\r
-  EFI_STATUS                  Status;\r
-  EFI_EVENT                   TimeoutEvent;\r
-  UINT8                       *TxBuf;\r
-\r
-  ASSERT (Packet != NULL);\r
-\r
-  Snp = SyslogLocateSnp ();\r
-\r
-  if (Snp == NULL) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  Ether = (ETHER_HEAD *) Packet;\r
-  CopyMem (Ether->SrcMac, Snp->Mode->CurrentAddress.Addr, NET_ETHER_ADDR_LEN);\r
-\r
-  //\r
-  // Start the timeout event.\r
-  //\r
-  Status = gBS->CreateEvent (\r
-                  EVT_TIMER,\r
-                  TPL_NOTIFY,\r
-                  NULL,\r
-                  NULL,\r
-                  &TimeoutEvent\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  Status = gBS->SetTimer (TimeoutEvent, TimerRelative, NET_SYSLOG_TX_TIMEOUT);\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    goto ON_EXIT;\r
-  }\r
-\r
-  for (;;) {\r
-    //\r
-    // Transmit the packet through SNP.\r
-    //\r
-    Status = Snp->Transmit (Snp, 0, Length, Packet, NULL, NULL, NULL);\r
-\r
-    if ((Status != EFI_SUCCESS) && (Status != EFI_NOT_READY)) {\r
-      Status = EFI_DEVICE_ERROR;\r
-      break;\r
-    }\r
-\r
-    //\r
-    // If Status is EFI_SUCCESS, the packet is put in the transmit queue.\r
-    // if Status is EFI_NOT_READY, the transmit engine of the network\r
-    // interface is busy. Both need to sync SNP.\r
-    //\r
-    TxBuf = NULL;\r
-\r
-    do {\r
-      //\r
-      // Get the recycled transmit buffer status.\r
-      //\r
-      Snp->GetStatus (Snp, NULL, (VOID **) &TxBuf);\r
-\r
-      if (!EFI_ERROR (gBS->CheckEvent (TimeoutEvent))) {\r
-        Status = EFI_TIMEOUT;\r
-        break;\r
-      }\r
-\r
-    } while (TxBuf == NULL);\r
-\r
-    if ((Status == EFI_SUCCESS) || (Status == EFI_TIMEOUT)) {\r
-      break;\r
-    }\r
-\r
-    //\r
-    // Status is EFI_NOT_READY. Restart the timer event and\r
-    // call Snp->Transmit again.\r
-    //\r
-    gBS->SetTimer (TimeoutEvent, TimerRelative, NET_SYSLOG_TX_TIMEOUT);\r
-  }\r
-\r
-  gBS->SetTimer (TimeoutEvent, TimerCancel, 0);\r
-\r
-ON_EXIT:\r
-  gBS->CloseEvent (TimeoutEvent);\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Build a syslog packet, including the Ethernet/Ip/Udp headers\r
-  and user's message.\r
-\r
-  @param[in]  Level     Syslog severity level\r
-  @param[in]  Module    The module that generates the log\r
-  @param[in]  File      The file that contains the current log\r
-  @param[in]  Line      The line of code in the File that contains the current log\r
-  @param[in]  Message   The log message\r
-  @param[in]  BufLen    The lenght of the Buf\r
-  @param[out] Buf       The buffer to put the packet data\r
-\r
-  @return The length of the syslog packet built, 0 represents no packet is built.\r
-\r
-**/\r
-UINT32\r
-SyslogBuildPacket (\r
-  IN  UINT32                Level,\r
-  IN  UINT8                 *Module,\r
-  IN  UINT8                 *File,\r
-  IN  UINT32                Line,\r
-  IN  UINT8                 *Message,\r
-  IN  UINT32                BufLen,\r
-  OUT CHAR8                 *Buf\r
-  )\r
-{\r
-  EFI_STATUS                Status;\r
-  ETHER_HEAD                *Ether;\r
-  IP4_HEAD                  *Ip4;\r
-  EFI_UDP_HEADER            *Udp4;\r
-  EFI_TIME                  Time;\r
-  UINT32                    Pri;\r
-  UINT32                    Len;\r
-\r
-  //\r
-  // Fill in the Ethernet header. Leave alone the source MAC.\r
-  // SyslogSendPacket will fill in the address for us.\r
-  //\r
-  Ether = (ETHER_HEAD *) Buf;\r
-  CopyMem (Ether->DstMac, mSyslogDstMac, NET_ETHER_ADDR_LEN);\r
-  ZeroMem (Ether->SrcMac, NET_ETHER_ADDR_LEN);\r
-\r
-  Ether->EtherType = HTONS (0x0800);    // IPv4 protocol\r
-\r
-  Buf             += sizeof (ETHER_HEAD);\r
-  BufLen          -= sizeof (ETHER_HEAD);\r
-\r
-  //\r
-  // Fill in the IP header\r
-  //\r
-  Ip4              = (IP4_HEAD *) Buf;\r
-  Ip4->HeadLen     = 5;\r
-  Ip4->Ver         = 4;\r
-  Ip4->Tos         = 0;\r
-  Ip4->TotalLen    = 0;\r
-  Ip4->Id          = (UINT16) mSyslogPacketSeq;\r
-  Ip4->Fragment    = 0;\r
-  Ip4->Ttl         = 16;\r
-  Ip4->Protocol    = 0x11;\r
-  Ip4->Checksum    = 0;\r
-  Ip4->Src         = mSyslogSrcIp;\r
-  Ip4->Dst         = mSyslogDstIp;\r
-\r
-  Buf             += sizeof (IP4_HEAD);\r
-  BufLen          -= sizeof (IP4_HEAD);\r
-\r
-  //\r
-  // Fill in the UDP header, Udp checksum is optional. Leave it zero.\r
-  //\r
-  Udp4             = (EFI_UDP_HEADER *) Buf;\r
-  Udp4->SrcPort    = HTONS (514);\r
-  Udp4->DstPort    = HTONS (514);\r
-  Udp4->Length     = 0;\r
-  Udp4->Checksum   = 0;\r
-\r
-  Buf             += sizeof (EFI_UDP_HEADER);\r
-  BufLen          -= sizeof (EFI_UDP_HEADER);\r
-\r
-  //\r
-  // Build the syslog message body with <PRI> Timestamp  machine module Message\r
-  //\r
-  Pri = ((NET_SYSLOG_FACILITY & 31) << 3) | (Level & 7);\r
-  Status = gRT->GetTime (&Time, NULL);\r
-  if (EFI_ERROR (Status)) {\r
-    return 0;\r
-  }\r
-\r
-  //\r
-  // Use %a to format the ASCII strings, %s to format UNICODE strings\r
-  //\r
-  Len  = 0;\r
-  Len += (UINT32) AsciiSPrint (\r
-                    Buf,\r
-                    BufLen,\r
-                    "<%d> %a %d %d:%d:%d ",\r
-                    Pri,\r
-                    mMonthName [Time.Month-1],\r
-                    Time.Day,\r
-                    Time.Hour,\r
-                    Time.Minute,\r
-                    Time.Second\r
-                    );\r
-\r
-  Len += (UINT32) AsciiSPrint (\r
-                    Buf + Len,\r
-                    BufLen - Len,\r
-                    "Tiano %a: %a (Line: %d File: %a)",\r
-                    Module,\r
-                    Message,\r
-                    Line,\r
-                    File\r
-                    );\r
-  Len ++;\r
-\r
-  //\r
-  // OK, patch the IP length/checksum and UDP length fields.\r
-  //\r
-  Len           += sizeof (EFI_UDP_HEADER);\r
-  Udp4->Length   = HTONS ((UINT16) Len);\r
-\r
-  Len           += sizeof (IP4_HEAD);\r
-  Ip4->TotalLen  = HTONS ((UINT16) Len);\r
-  Ip4->Checksum  = (UINT16) (~NetblockChecksum ((UINT8 *) Ip4, sizeof (IP4_HEAD)));\r
-\r
-  return Len + sizeof (ETHER_HEAD);\r
-}\r
-\r
-/**\r
-  Allocate a buffer, then format the message to it. This is a\r
-  help function for the NET_DEBUG_XXX macros. The PrintArg of\r
-  these macros treats the variable length print parameters as a\r
-  single parameter, and pass it to the NetDebugASPrint. For\r
-  example, NET_DEBUG_TRACE ("Tcp", ("State transit to %a\n", Name))\r
-  if extracted to:\r
-\r
-         NetDebugOutput (\r
-           NETDEBUG_LEVEL_TRACE,\r
-           "Tcp",\r
-           __FILE__,\r
-           __LINE__,\r
-           NetDebugASPrint ("State transit to %a\n", Name)\r
-         )\r
-\r
-  If Format is NULL, then ASSERT().\r
-\r
-  @param Format  The ASCII format string.\r
-  @param ...     The variable length parameter whose format is determined\r
-                 by the Format string.\r
-\r
-  @return        The buffer containing the formatted message,\r
-                 or NULL if failed to allocate memory.\r
-\r
-**/\r
-CHAR8 *\r
-EFIAPI\r
-NetDebugASPrint (\r
-  IN CHAR8                  *Format,\r
-  ...\r
-  )\r
-{\r
-  VA_LIST                   Marker;\r
-  CHAR8                     *Buf;\r
-\r
-  ASSERT (Format != NULL);\r
-\r
-  Buf = (CHAR8 *) AllocatePool (NET_DEBUG_MSG_LEN);\r
-\r
-  if (Buf == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  VA_START (Marker, Format);\r
-  AsciiVSPrint (Buf, NET_DEBUG_MSG_LEN, Format, Marker);\r
-  VA_END (Marker);\r
-\r
-  return Buf;\r
-}\r
-\r
-/**\r
-  Builds an UDP4 syslog packet and send it using SNP.\r
-\r
-  This function will locate a instance of SNP then send the message through it.\r
-  Because it isn't open the SNP BY_DRIVER, apply caution when using it.\r
-\r
-  @param Level    The severity level of the message.\r
-  @param Module   The Moudle that generates the log.\r
-  @param File     The file that contains the log.\r
-  @param Line     The exact line that contains the log.\r
-  @param Message  The user message to log.\r
-\r
-  @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
-  @retval EFI_OUT_OF_RESOURCES  Failed to allocate memory for the packet.\r
-  @retval EFI_DEVICE_ERROR      Device error occurs.\r
-  @retval EFI_SUCCESS           The log is discard because that it is more verbose\r
-                                than the mNetDebugLevelMax. Or, it has been sent out.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-NetDebugOutput (\r
-  IN UINT32                    Level,\r
-  IN UINT8                     *Module,\r
-  IN UINT8                     *File,\r
-  IN UINT32                    Line,\r
-  IN UINT8                     *Message\r
-  )\r
-{\r
-  CHAR8                        *Packet;\r
-  UINT32                       Len;\r
-  EFI_STATUS                   Status;\r
-\r
-  //\r
-  // Check whether the message should be sent out\r
-  //\r
-  if (Message == NULL || File == NULL || Module == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (Level > mNetDebugLevelMax) {\r
-    Status = EFI_SUCCESS;\r
-    goto ON_EXIT;\r
-  }\r
-\r
-  //\r
-  // Allocate a maxium of 1024 bytes, the caller should ensure\r
-  // that the message plus the ethernet/ip/udp header is shorter\r
-  // than this\r
-  //\r
-  Packet = (CHAR8 *) AllocatePool (NET_SYSLOG_PACKET_LEN);\r
-\r
-  if (Packet == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto ON_EXIT;\r
-  }\r
-\r
-  //\r
-  // Build the message: Ethernet header + IP header + Udp Header + user data\r
-  //\r
-  Len = SyslogBuildPacket (\r
-          Level,\r
-          Module,\r
-          File,\r
-          Line,\r
-          Message,\r
-          NET_SYSLOG_PACKET_LEN,\r
-          Packet\r
-          );\r
-  if (Len == 0) {\r
-    Status = EFI_DEVICE_ERROR;\r
-  } else {\r
-    mSyslogPacketSeq++;\r
-    Status = SyslogSendPacket (Packet, Len);\r
-  }\r
-\r
-  FreePool (Packet);\r
-\r
-ON_EXIT:\r
-  FreePool (Message);\r
-  return Status;\r
-}\r
-/**\r
-  Return the length of the mask.\r
-\r
-  Return the length of the mask, the correct value is from 0 to 32.\r
-  If the mask is invalid, return the invalid length 33, which is IP4_MASK_NUM.\r
-  NetMask is in the host byte order.\r
-\r
-  @param[in]  NetMask              The netmask to get the length from.\r
-\r
-  @return The length of the netmask, IP4_MASK_NUM if the mask is invalid.\r
-\r
-**/\r
-INTN\r
-EFIAPI\r
-NetGetMaskLength (\r
-  IN IP4_ADDR               NetMask\r
-  )\r
-{\r
-  INTN                      Index;\r
-\r
-  for (Index = 0; Index <= IP4_MASK_MAX; Index++) {\r
-    if (NetMask == gIp4AllMasks[Index]) {\r
-      break;\r
-    }\r
-  }\r
-\r
-  return Index;\r
-}\r
-\r
-\r
-\r
-/**\r
-  Return the class of the IP address, such as class A, B, C.\r
-  Addr is in host byte order.\r
-\r
-  [ATTENTION]\r
-  Classful addressing (IP class A/B/C) has been deprecated according to RFC4632.\r
-  Caller of this function could only check the returned value against\r
-  IP4_ADDR_CLASSD (multicast) or IP4_ADDR_CLASSE (reserved) now.\r
-\r
-  The address of class A  starts with 0.\r
-  If the address belong to class A, return IP4_ADDR_CLASSA.\r
-  The address of class B  starts with 10.\r
-  If the address belong to class B, return IP4_ADDR_CLASSB.\r
-  The address of class C  starts with 110.\r
-  If the address belong to class C, return IP4_ADDR_CLASSC.\r
-  The address of class D  starts with 1110.\r
-  If the address belong to class D, return IP4_ADDR_CLASSD.\r
-  The address of class E  starts with 1111.\r
-  If the address belong to class E, return IP4_ADDR_CLASSE.\r
-\r
-\r
-  @param[in]   Addr                  The address to get the class from.\r
-\r
-  @return IP address class, such as IP4_ADDR_CLASSA.\r
-\r
-**/\r
-INTN\r
-EFIAPI\r
-NetGetIpClass (\r
-  IN IP4_ADDR               Addr\r
-  )\r
-{\r
-  UINT8                     ByteOne;\r
-\r
-  ByteOne = (UINT8) (Addr >> 24);\r
-\r
-  if ((ByteOne & 0x80) == 0) {\r
-    return IP4_ADDR_CLASSA;\r
-\r
-  } else if ((ByteOne & 0xC0) == 0x80) {\r
-    return IP4_ADDR_CLASSB;\r
-\r
-  } else if ((ByteOne & 0xE0) == 0xC0) {\r
-    return IP4_ADDR_CLASSC;\r
-\r
-  } else if ((ByteOne & 0xF0) == 0xE0) {\r
-    return IP4_ADDR_CLASSD;\r
-\r
-  } else {\r
-    return IP4_ADDR_CLASSE;\r
-\r
-  }\r
-}\r
-\r
-\r
-/**\r
-  Check whether the IP is a valid unicast address according to\r
-  the netmask.\r
-\r
-  ASSERT if NetMask is zero.\r
-\r
-  If all bits of the host address of IP are 0 or 1, IP is also not a valid unicast address,\r
-  except when the originator is one of the endpoints of a point-to-point link with a 31-bit\r
-  mask (RFC3021), or a 32bit NetMask (all 0xFF) is used for special network environment (e.g.\r
-  PPP link).\r
-\r
-  @param[in]  Ip                    The IP to check against.\r
-  @param[in]  NetMask               The mask of the IP.\r
-\r
-  @return TRUE if IP is a valid unicast address on the network, otherwise FALSE.\r
-\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-NetIp4IsUnicast (\r
-  IN IP4_ADDR               Ip,\r
-  IN IP4_ADDR               NetMask\r
-  )\r
-{\r
-  INTN   MaskLength;\r
-\r
-  ASSERT (NetMask != 0);\r
-\r
-  if (Ip == 0 || IP4_IS_LOCAL_BROADCAST (Ip)) {\r
-    return FALSE;\r
-  }\r
-\r
-  MaskLength = NetGetMaskLength (NetMask);\r
-  ASSERT ((MaskLength >= 0) && (MaskLength <= IP4_MASK_NUM));\r
-  if (MaskLength < 31) {\r
-    if (((Ip &~NetMask) == ~NetMask) || ((Ip &~NetMask) == 0)) {\r
-      return FALSE;\r
-    }\r
-  }\r
-\r
-  return TRUE;\r
-}\r
-\r
-/**\r
-  Check whether the incoming IPv6 address is a valid unicast address.\r
-\r
-  ASSERT if Ip6 is NULL.\r
-\r
-  If the address is a multicast address has binary 0xFF at the start, it is not\r
-  a valid unicast address. If the address is unspecified ::, it is not a valid\r
-  unicast address to be assigned to any node. If the address is loopback address\r
-  ::1, it is also not a valid unicast address to be assigned to any physical\r
-  interface.\r
-\r
-  @param[in]  Ip6                   The IPv6 address to check against.\r
-\r
-  @return TRUE if Ip6 is a valid unicast address on the network, otherwise FALSE.\r
-\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-NetIp6IsValidUnicast (\r
-  IN EFI_IPv6_ADDRESS       *Ip6\r
-  )\r
-{\r
-  UINT8 Byte;\r
-  UINT8 Index;\r
-\r
-  ASSERT (Ip6 != NULL);\r
-\r
-  if (Ip6->Addr[0] == 0xFF) {\r
-    return FALSE;\r
-  }\r
-\r
-  for (Index = 0; Index < 15; Index++) {\r
-    if (Ip6->Addr[Index] != 0) {\r
-      return TRUE;\r
-    }\r
-  }\r
-\r
-  Byte = Ip6->Addr[Index];\r
-\r
-  if (Byte == 0x0 || Byte == 0x1) {\r
-    return FALSE;\r
-  }\r
-\r
-  return TRUE;\r
-}\r
-\r
-/**\r
-  Check whether the incoming Ipv6 address is the unspecified address or not.\r
-\r
-  ASSERT if Ip6 is NULL.\r
-\r
-  @param[in] Ip6   - Ip6 address, in network order.\r
-\r
-  @retval TRUE     - Yes, unspecified\r
-  @retval FALSE    - No\r
-\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-NetIp6IsUnspecifiedAddr (\r
-  IN EFI_IPv6_ADDRESS       *Ip6\r
-  )\r
-{\r
-  UINT8 Index;\r
-\r
-  ASSERT (Ip6 != NULL);\r
-\r
-  for (Index = 0; Index < 16; Index++) {\r
-    if (Ip6->Addr[Index] != 0) {\r
-      return FALSE;\r
-    }\r
-  }\r
-\r
-  return TRUE;\r
-}\r
-\r
-/**\r
-  Check whether the incoming Ipv6 address is a link-local address.\r
-\r
-  ASSERT if Ip6 is NULL.\r
-\r
-  @param[in] Ip6   - Ip6 address, in network order.\r
-\r
-  @retval TRUE  - Yes, link-local address\r
-  @retval FALSE - No\r
-\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-NetIp6IsLinkLocalAddr (\r
-  IN EFI_IPv6_ADDRESS *Ip6\r
-  )\r
-{\r
-  UINT8 Index;\r
-\r
-  ASSERT (Ip6 != NULL);\r
-\r
-  if (Ip6->Addr[0] != 0xFE) {\r
-    return FALSE;\r
-  }\r
-\r
-  if (Ip6->Addr[1] != 0x80) {\r
-    return FALSE;\r
-  }\r
-\r
-  for (Index = 2; Index < 8; Index++) {\r
-    if (Ip6->Addr[Index] != 0) {\r
-      return FALSE;\r
-    }\r
-  }\r
-\r
-  return TRUE;\r
-}\r
-\r
-/**\r
-  Check whether the Ipv6 address1 and address2 are on the connected network.\r
-\r
-  ASSERT if Ip1 or Ip2 is NULL.\r
-  ASSERT if PrefixLength exceeds or equals to IP6_PREFIX_MAX.\r
-\r
-  @param[in] Ip1          - Ip6 address1, in network order.\r
-  @param[in] Ip2          - Ip6 address2, in network order.\r
-  @param[in] PrefixLength - The prefix length of the checking net.\r
-\r
-  @retval TRUE            - Yes, connected.\r
-  @retval FALSE           - No.\r
-\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-NetIp6IsNetEqual (\r
-  EFI_IPv6_ADDRESS *Ip1,\r
-  EFI_IPv6_ADDRESS *Ip2,\r
-  UINT8            PrefixLength\r
-  )\r
-{\r
-  UINT8 Byte;\r
-  UINT8 Bit;\r
-  UINT8 Mask;\r
-\r
-  ASSERT ((Ip1 != NULL) && (Ip2 != NULL) && (PrefixLength < IP6_PREFIX_MAX));\r
-\r
-  if (PrefixLength == 0) {\r
-    return TRUE;\r
-  }\r
-\r
-  Byte = (UINT8) (PrefixLength / 8);\r
-  Bit  = (UINT8) (PrefixLength % 8);\r
-\r
-  if (CompareMem (Ip1, Ip2, Byte) != 0) {\r
-    return FALSE;\r
-  }\r
-\r
-  if (Bit > 0) {\r
-    Mask = (UINT8) (0xFF << (8 - Bit));\r
-\r
-    ASSERT (Byte < 16);\r
-    if (Byte >= 16) {\r
-      return FALSE;\r
-    }\r
-    if ((Ip1->Addr[Byte] & Mask) != (Ip2->Addr[Byte] & Mask)) {\r
-      return FALSE;\r
-    }\r
-  }\r
-\r
-  return TRUE;\r
-}\r
-\r
-\r
-/**\r
-  Switches the endianess of an IPv6 address\r
-\r
-  ASSERT if Ip6 is NULL.\r
-\r
-  This function swaps the bytes in a 128-bit IPv6 address to switch the value\r
-  from little endian to big endian or vice versa. The byte swapped value is\r
-  returned.\r
-\r
-  @param  Ip6 Points to an IPv6 address\r
-\r
-  @return The byte swapped IPv6 address.\r
-\r
-**/\r
-EFI_IPv6_ADDRESS *\r
-EFIAPI\r
-Ip6Swap128 (\r
-  EFI_IPv6_ADDRESS *Ip6\r
-  )\r
-{\r
-  UINT64 High;\r
-  UINT64 Low;\r
-\r
-  ASSERT (Ip6 != NULL);\r
-\r
-  CopyMem (&High, Ip6, sizeof (UINT64));\r
-  CopyMem (&Low, &Ip6->Addr[8], sizeof (UINT64));\r
-\r
-  High = SwapBytes64 (High);\r
-  Low  = SwapBytes64 (Low);\r
-\r
-  CopyMem (Ip6, &Low, sizeof (UINT64));\r
-  CopyMem (&Ip6->Addr[8], &High, sizeof (UINT64));\r
-\r
-  return Ip6;\r
-}\r
-\r
-/**\r
-  Initialize a random seed using current time and monotonic count.\r
-\r
-  Get current time and monotonic count first. Then initialize a random seed\r
-  based on some basic mathematics operation on the hour, day, minute, second,\r
-  nanosecond and year of the current time and the monotonic count value.\r
-\r
-  @return The random seed initialized with current time.\r
-\r
-**/\r
-UINT32\r
-EFIAPI\r
-NetRandomInitSeed (\r
-  VOID\r
-  )\r
-{\r
-  EFI_TIME                  Time;\r
-  UINT32                    Seed;\r
-  UINT64                    MonotonicCount;\r
-\r
-  gRT->GetTime (&Time, NULL);\r
-  Seed = (Time.Hour << 24 | Time.Day << 16 | Time.Minute << 8 | Time.Second);\r
-  Seed ^= Time.Nanosecond;\r
-  Seed ^= Time.Year << 7;\r
-\r
-  gBS->GetNextMonotonicCount (&MonotonicCount);\r
-  Seed += (UINT32) MonotonicCount;\r
-\r
-  return Seed;\r
-}\r
-\r
-\r
-/**\r
-  Extract a UINT32 from a byte stream.\r
-\r
-  ASSERT if Buf is NULL.\r
-\r
-  Copy a UINT32 from a byte stream, then converts it from Network\r
-  byte order to host byte order. Use this function to avoid alignment error.\r
-\r
-  @param[in]  Buf                 The buffer to extract the UINT32.\r
-\r
-  @return The UINT32 extracted.\r
-\r
-**/\r
-UINT32\r
-EFIAPI\r
-NetGetUint32 (\r
-  IN UINT8                  *Buf\r
-  )\r
-{\r
-  UINT32                    Value;\r
-\r
-  ASSERT (Buf != NULL);\r
-\r
-  CopyMem (&Value, Buf, sizeof (UINT32));\r
-  return NTOHL (Value);\r
-}\r
-\r
-\r
-/**\r
-  Put a UINT32 to the byte stream in network byte order.\r
-\r
-  ASSERT if Buf is NULL.\r
-\r
-  Converts a UINT32 from host byte order to network byte order. Then copy it to the\r
-  byte stream.\r
-\r
-  @param[in, out]  Buf          The buffer to put the UINT32.\r
-  @param[in]       Data         The data to be converted and put into the byte stream.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-NetPutUint32 (\r
-  IN OUT UINT8                 *Buf,\r
-  IN     UINT32                Data\r
-  )\r
-{\r
-  ASSERT (Buf != NULL);\r
-\r
-  Data = HTONL (Data);\r
-  CopyMem (Buf, &Data, sizeof (UINT32));\r
-}\r
-\r
-\r
-/**\r
-  Remove the first node entry on the list, and return the removed node entry.\r
-\r
-  Removes the first node Entry from a doubly linked list. It is up to the caller of\r
-  this function to release the memory used by the first node if that is required. On\r
-  exit, the removed node is returned.\r
-\r
-  If Head is NULL, then ASSERT().\r
-  If Head was not initialized, then ASSERT().\r
-  If PcdMaximumLinkedListLength is not zero, and the number of nodes in the\r
-  linked list including the head node is greater than or equal to PcdMaximumLinkedListLength,\r
-  then ASSERT().\r
-\r
-  @param[in, out]  Head                  The list header.\r
-\r
-  @return The first node entry that is removed from the list, NULL if the list is empty.\r
-\r
-**/\r
-LIST_ENTRY *\r
-EFIAPI\r
-NetListRemoveHead (\r
-  IN OUT LIST_ENTRY            *Head\r
-  )\r
-{\r
-  LIST_ENTRY            *First;\r
-\r
-  ASSERT (Head != NULL);\r
-\r
-  if (IsListEmpty (Head)) {\r
-    return NULL;\r
-  }\r
-\r
-  First                         = Head->ForwardLink;\r
-  Head->ForwardLink             = First->ForwardLink;\r
-  First->ForwardLink->BackLink  = Head;\r
-\r
-  DEBUG_CODE (\r
-    First->ForwardLink  = (LIST_ENTRY *) NULL;\r
-    First->BackLink     = (LIST_ENTRY *) NULL;\r
-  );\r
-\r
-  return First;\r
-}\r
-\r
-\r
-/**\r
-  Remove the last node entry on the list and and return the removed node entry.\r
-\r
-  Removes the last node entry from a doubly linked list. It is up to the caller of\r
-  this function to release the memory used by the first node if that is required. On\r
-  exit, the removed node is returned.\r
-\r
-  If Head is NULL, then ASSERT().\r
-  If Head was not initialized, then ASSERT().\r
-  If PcdMaximumLinkedListLength is not zero, and the number of nodes in the\r
-  linked list including the head node is greater than or equal to PcdMaximumLinkedListLength,\r
-  then ASSERT().\r
-\r
-  @param[in, out]  Head                  The list head.\r
-\r
-  @return The last node entry that is removed from the list, NULL if the list is empty.\r
-\r
-**/\r
-LIST_ENTRY *\r
-EFIAPI\r
-NetListRemoveTail (\r
-  IN OUT LIST_ENTRY            *Head\r
-  )\r
-{\r
-  LIST_ENTRY            *Last;\r
-\r
-  ASSERT (Head != NULL);\r
-\r
-  if (IsListEmpty (Head)) {\r
-    return NULL;\r
-  }\r
-\r
-  Last                        = Head->BackLink;\r
-  Head->BackLink              = Last->BackLink;\r
-  Last->BackLink->ForwardLink = Head;\r
-\r
-  DEBUG_CODE (\r
-    Last->ForwardLink = (LIST_ENTRY *) NULL;\r
-    Last->BackLink    = (LIST_ENTRY *) NULL;\r
-  );\r
-\r
-  return Last;\r
-}\r
-\r
-\r
-/**\r
-  Insert a new node entry after a designated node entry of a doubly linked list.\r
-\r
-  ASSERT if PrevEntry or NewEntry is NULL.\r
-\r
-  Inserts a new node entry donated by NewEntry after the node entry donated by PrevEntry\r
-  of the doubly linked list.\r
-\r
-  @param[in, out]  PrevEntry             The previous entry to insert after.\r
-  @param[in, out]  NewEntry              The new entry to insert.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-NetListInsertAfter (\r
-  IN OUT LIST_ENTRY         *PrevEntry,\r
-  IN OUT LIST_ENTRY         *NewEntry\r
-  )\r
-{\r
-  ASSERT (PrevEntry != NULL && NewEntry != NULL);\r
-\r
-  NewEntry->BackLink                = PrevEntry;\r
-  NewEntry->ForwardLink             = PrevEntry->ForwardLink;\r
-  PrevEntry->ForwardLink->BackLink  = NewEntry;\r
-  PrevEntry->ForwardLink            = NewEntry;\r
-}\r
-\r
-\r
-/**\r
-  Insert a new node entry before a designated node entry of a doubly linked list.\r
-\r
-  ASSERT if PostEntry or NewEntry is NULL.\r
-\r
-  Inserts a new node entry donated by NewEntry after the node entry donated by PostEntry\r
-  of the doubly linked list.\r
-\r
-  @param[in, out]  PostEntry             The entry to insert before.\r
-  @param[in, out]  NewEntry              The new entry to insert.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-NetListInsertBefore (\r
-  IN OUT LIST_ENTRY     *PostEntry,\r
-  IN OUT LIST_ENTRY     *NewEntry\r
-  )\r
-{\r
-  ASSERT (PostEntry != NULL && NewEntry != NULL);\r
-\r
-  NewEntry->ForwardLink             = PostEntry;\r
-  NewEntry->BackLink                = PostEntry->BackLink;\r
-  PostEntry->BackLink->ForwardLink  = NewEntry;\r
-  PostEntry->BackLink               = NewEntry;\r
-}\r
-\r
-/**\r
-  Safe destroy nodes in a linked list, and return the length of the list after all possible operations finished.\r
-\r
-  Destroy network child instance list by list traversals is not safe due to graph dependencies between nodes.\r
-  This function performs a safe traversal to destroy these nodes by checking to see if the node being destroyed\r
-  has been removed from the list or not.\r
-  If it has been removed, then restart the traversal from the head.\r
-  If it hasn't been removed, then continue with the next node directly.\r
-  This function will end the iterate and return the CallBack's last return value if error happens,\r
-  or retrun EFI_SUCCESS if 2 complete passes are made with no changes in the number of children in the list.\r
-\r
-  @param[in]    List             The head of the list.\r
-  @param[in]    CallBack         Pointer to the callback function to destroy one node in the list.\r
-  @param[in]    Context          Pointer to the callback function's context: corresponds to the\r
-                                 parameter Context in NET_DESTROY_LINK_LIST_CALLBACK.\r
-  @param[out]   ListLength       The length of the link list if the function returns successfully.\r
-\r
-  @retval EFI_SUCCESS            Two complete passes are made with no changes in the number of children.\r
-  @retval EFI_INVALID_PARAMETER  The input parameter is invalid.\r
-  @retval Others                 Return the CallBack's last return value.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-NetDestroyLinkList (\r
-  IN   LIST_ENTRY                       *List,\r
-  IN   NET_DESTROY_LINK_LIST_CALLBACK   CallBack,\r
-  IN   VOID                             *Context,    OPTIONAL\r
-  OUT  UINTN                            *ListLength  OPTIONAL\r
-  )\r
-{\r
-  UINTN                         PreviousLength;\r
-  LIST_ENTRY                    *Entry;\r
-  LIST_ENTRY                    *Ptr;\r
-  UINTN                         Length;\r
-  EFI_STATUS                    Status;\r
-\r
-  if (List == NULL || CallBack == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  Length = 0;\r
-  do {\r
-    PreviousLength = Length;\r
-    Entry = GetFirstNode (List);\r
-    while (!IsNull (List, Entry)) {\r
-      Status = CallBack (Entry, Context);\r
-      if (EFI_ERROR (Status)) {\r
-        return Status;\r
-      }\r
-      //\r
-      // Walk through the list to see whether the Entry has been removed or not.\r
-      // If the Entry still exists, just try to destroy the next one.\r
-      // If not, go back to the start point to iterate the list again.\r
-      //\r
-      for (Ptr = List->ForwardLink; Ptr != List; Ptr = Ptr->ForwardLink) {\r
-        if (Ptr == Entry) {\r
-          break;\r
-        }\r
-      }\r
-      if (Ptr == Entry) {\r
-        Entry = GetNextNode (List, Entry);\r
-      } else {\r
-        Entry = GetFirstNode (List);\r
-      }\r
-    }\r
-    for (Length = 0, Ptr = List->ForwardLink; Ptr != List; Length++, Ptr = Ptr->ForwardLink);\r
-  } while (Length != PreviousLength);\r
-\r
-  if (ListLength != NULL) {\r
-    *ListLength = Length;\r
-  }\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  This function checks the input Handle to see if it's one of these handles in ChildHandleBuffer.\r
-\r
-  @param[in]  Handle             Handle to be checked.\r
-  @param[in]  NumberOfChildren   Number of Handles in ChildHandleBuffer.\r
-  @param[in]  ChildHandleBuffer  An array of child handles to be freed. May be NULL\r
-                                 if NumberOfChildren is 0.\r
-\r
-  @retval TRUE                   Found the input Handle in ChildHandleBuffer.\r
-  @retval FALSE                  Can't find the input Handle in ChildHandleBuffer.\r
-\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-NetIsInHandleBuffer (\r
-  IN  EFI_HANDLE          Handle,\r
-  IN  UINTN               NumberOfChildren,\r
-  IN  EFI_HANDLE          *ChildHandleBuffer OPTIONAL\r
-  )\r
-{\r
-  UINTN     Index;\r
-\r
-  if (NumberOfChildren == 0 || ChildHandleBuffer == NULL) {\r
-    return FALSE;\r
-  }\r
-\r
-  for (Index = 0; Index < NumberOfChildren; Index++) {\r
-    if (Handle == ChildHandleBuffer[Index]) {\r
-      return TRUE;\r
-    }\r
-  }\r
-\r
-  return FALSE;\r
-}\r
-\r
-\r
-/**\r
-  Initialize the netmap. Netmap is a reposity to keep the <Key, Value> pairs.\r
-\r
-  Initialize the forward and backward links of two head nodes donated by Map->Used\r
-  and Map->Recycled of two doubly linked lists.\r
-  Initializes the count of the <Key, Value> pairs in the netmap to zero.\r
-\r
-  If Map is NULL, then ASSERT().\r
-  If the address of Map->Used is NULL, then ASSERT().\r
-  If the address of Map->Recycled is NULl, then ASSERT().\r
-\r
-  @param[in, out]  Map                   The netmap to initialize.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-NetMapInit (\r
-  IN OUT NET_MAP                *Map\r
-  )\r
-{\r
-  ASSERT (Map != NULL);\r
-\r
-  InitializeListHead (&Map->Used);\r
-  InitializeListHead (&Map->Recycled);\r
-  Map->Count = 0;\r
-}\r
-\r
-\r
-/**\r
-  To clean up the netmap, that is, release allocated memories.\r
-\r
-  Removes all nodes of the Used doubly linked list and free memory of all related netmap items.\r
-  Removes all nodes of the Recycled doubly linked list and free memory of all related netmap items.\r
-  The number of the <Key, Value> pairs in the netmap is set to be zero.\r
-\r
-  If Map is NULL, then ASSERT().\r
-\r
-  @param[in, out]  Map                   The netmap to clean up.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-NetMapClean (\r
-  IN OUT NET_MAP            *Map\r
-  )\r
-{\r
-  NET_MAP_ITEM              *Item;\r
-  LIST_ENTRY                *Entry;\r
-  LIST_ENTRY                *Next;\r
-\r
-  ASSERT (Map != NULL);\r
-\r
-  NET_LIST_FOR_EACH_SAFE (Entry, Next, &Map->Used) {\r
-    Item = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);\r
-\r
-    RemoveEntryList (&Item->Link);\r
-    Map->Count--;\r
-\r
-    gBS->FreePool (Item);\r
-  }\r
-\r
-  ASSERT ((Map->Count == 0) && IsListEmpty (&Map->Used));\r
-\r
-  NET_LIST_FOR_EACH_SAFE (Entry, Next, &Map->Recycled) {\r
-    Item = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);\r
-\r
-    RemoveEntryList (&Item->Link);\r
-    gBS->FreePool (Item);\r
-  }\r
-\r
-  ASSERT (IsListEmpty (&Map->Recycled));\r
-}\r
-\r
-\r
-/**\r
-  Test whether the netmap is empty and return true if it is.\r
-\r
-  If the number of the <Key, Value> pairs in the netmap is zero, return TRUE.\r
-\r
-  If Map is NULL, then ASSERT().\r
-\r
-  @param[in]  Map                   The net map to test.\r
-\r
-  @return TRUE if the netmap is empty, otherwise FALSE.\r
-\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-NetMapIsEmpty (\r
-  IN NET_MAP                *Map\r
-  )\r
-{\r
-  ASSERT (Map != NULL);\r
-  return (BOOLEAN) (Map->Count == 0);\r
-}\r
-\r
-\r
-/**\r
-  Return the number of the <Key, Value> pairs in the netmap.\r
-\r
-  If Map is NULL, then ASSERT().\r
-\r
-  @param[in]  Map                   The netmap to get the entry number.\r
-\r
-  @return The entry number in the netmap.\r
-\r
-**/\r
-UINTN\r
-EFIAPI\r
-NetMapGetCount (\r
-  IN NET_MAP                *Map\r
-  )\r
-{\r
-  ASSERT (Map != NULL);\r
-  return Map->Count;\r
-}\r
-\r
-\r
-/**\r
-  Return one allocated item.\r
-\r
-  If the Recycled doubly linked list of the netmap is empty, it will try to allocate\r
-  a batch of items if there are enough resources and add corresponding nodes to the begining\r
-  of the Recycled doubly linked list of the netmap. Otherwise, it will directly remove\r
-  the fist node entry of the Recycled doubly linked list and return the corresponding item.\r
-\r
-  If Map is NULL, then ASSERT().\r
-\r
-  @param[in, out]  Map          The netmap to allocate item for.\r
-\r
-  @return                       The allocated item. If NULL, the\r
-                                allocation failed due to resource limit.\r
-\r
-**/\r
-NET_MAP_ITEM *\r
-NetMapAllocItem (\r
-  IN OUT NET_MAP            *Map\r
-  )\r
-{\r
-  NET_MAP_ITEM              *Item;\r
-  LIST_ENTRY                *Head;\r
-  UINTN                     Index;\r
-\r
-  ASSERT (Map != NULL);\r
-\r
-  Head = &Map->Recycled;\r
-\r
-  if (IsListEmpty (Head)) {\r
-    for (Index = 0; Index < NET_MAP_INCREAMENT; Index++) {\r
-      Item = AllocatePool (sizeof (NET_MAP_ITEM));\r
-\r
-      if (Item == NULL) {\r
-        if (Index == 0) {\r
-          return NULL;\r
-        }\r
-\r
-        break;\r
-      }\r
-\r
-      InsertHeadList (Head, &Item->Link);\r
-    }\r
-  }\r
-\r
-  Item = NET_LIST_HEAD (Head, NET_MAP_ITEM, Link);\r
-  NetListRemoveHead (Head);\r
-\r
-  return Item;\r
-}\r
-\r
-\r
-/**\r
-  Allocate an item to save the <Key, Value> pair to the head of the netmap.\r
-\r
-  Allocate an item to save the <Key, Value> pair and add corresponding node entry\r
-  to the beginning of the Used doubly linked list. The number of the <Key, Value>\r
-  pairs in the netmap increase by 1.\r
-\r
-  If Map is NULL, then ASSERT().\r
-  If Key is NULL, then ASSERT().\r
-\r
-  @param[in, out]  Map                   The netmap to insert into.\r
-  @param[in]       Key                   The user's key.\r
-  @param[in]       Value                 The user's value for the key.\r
-\r
-  @retval EFI_OUT_OF_RESOURCES  Failed to allocate the memory for the item.\r
-  @retval EFI_SUCCESS           The item is inserted to the head.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-NetMapInsertHead (\r
-  IN OUT NET_MAP            *Map,\r
-  IN VOID                   *Key,\r
-  IN VOID                   *Value    OPTIONAL\r
-  )\r
-{\r
-  NET_MAP_ITEM              *Item;\r
-\r
-  ASSERT (Map != NULL && Key != NULL);\r
-\r
-  Item = NetMapAllocItem (Map);\r
-\r
-  if (Item == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  Item->Key   = Key;\r
-  Item->Value = Value;\r
-  InsertHeadList (&Map->Used, &Item->Link);\r
-\r
-  Map->Count++;\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
-  Allocate an item to save the <Key, Value> pair to the tail of the netmap.\r
-\r
-  Allocate an item to save the <Key, Value> pair and add corresponding node entry\r
-  to the tail of the Used doubly linked list. The number of the <Key, Value>\r
-  pairs in the netmap increase by 1.\r
-\r
-  If Map is NULL, then ASSERT().\r
-  If Key is NULL, then ASSERT().\r
-\r
-  @param[in, out]  Map                   The netmap to insert into.\r
-  @param[in]       Key                   The user's key.\r
-  @param[in]       Value                 The user's value for the key.\r
-\r
-  @retval EFI_OUT_OF_RESOURCES  Failed to allocate the memory for the item.\r
-  @retval EFI_SUCCESS           The item is inserted to the tail.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-NetMapInsertTail (\r
-  IN OUT NET_MAP            *Map,\r
-  IN VOID                   *Key,\r
-  IN VOID                   *Value    OPTIONAL\r
-  )\r
-{\r
-  NET_MAP_ITEM              *Item;\r
-\r
-  ASSERT (Map != NULL && Key != NULL);\r
-\r
-  Item = NetMapAllocItem (Map);\r
-\r
-  if (Item == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  Item->Key   = Key;\r
-  Item->Value = Value;\r
-  InsertTailList (&Map->Used, &Item->Link);\r
-\r
-  Map->Count++;\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
-  Check whether the item is in the Map and return TRUE if it is.\r
-\r
-  If Map is NULL, then ASSERT().\r
-  If Item is NULL, then ASSERT().\r
-\r
-  @param[in]  Map                   The netmap to search within.\r
-  @param[in]  Item                  The item to search.\r
-\r
-  @return TRUE if the item is in the netmap, otherwise FALSE.\r
-\r
-**/\r
-BOOLEAN\r
-NetItemInMap (\r
-  IN NET_MAP                *Map,\r
-  IN NET_MAP_ITEM           *Item\r
-  )\r
-{\r
-  LIST_ENTRY            *ListEntry;\r
-\r
-  ASSERT (Map != NULL && Item != NULL);\r
-\r
-  NET_LIST_FOR_EACH (ListEntry, &Map->Used) {\r
-    if (ListEntry == &Item->Link) {\r
-      return TRUE;\r
-    }\r
-  }\r
-\r
-  return FALSE;\r
-}\r
-\r
-\r
-/**\r
-  Find the key in the netmap and returns the point to the item contains the Key.\r
-\r
-  Iterate the Used doubly linked list of the netmap to get every item. Compare the key of every\r
-  item with the key to search. It returns the point to the item contains the Key if found.\r
-\r
-  If Map is NULL, then ASSERT().\r
-  If Key is NULL, then ASSERT().\r
-\r
-  @param[in]  Map                   The netmap to search within.\r
-  @param[in]  Key                   The key to search.\r
-\r
-  @return The point to the item contains the Key, or NULL if Key isn't in the map.\r
-\r
-**/\r
-NET_MAP_ITEM *\r
-EFIAPI\r
-NetMapFindKey (\r
-  IN  NET_MAP               *Map,\r
-  IN  VOID                  *Key\r
-  )\r
-{\r
-  LIST_ENTRY              *Entry;\r
-  NET_MAP_ITEM            *Item;\r
-\r
-  ASSERT (Map != NULL && Key != NULL);\r
-\r
-  NET_LIST_FOR_EACH (Entry, &Map->Used) {\r
-    Item = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);\r
-\r
-    if (Item->Key == Key) {\r
-      return Item;\r
-    }\r
-  }\r
-\r
-  return NULL;\r
-}\r
-\r
-\r
-/**\r
-  Remove the node entry of the item from the netmap and return the key of the removed item.\r
-\r
-  Remove the node entry of the item from the Used doubly linked list of the netmap.\r
-  The number of the <Key, Value> pairs in the netmap decrease by 1. Then add the node\r
-  entry of the item to the Recycled doubly linked list of the netmap. If Value is not NULL,\r
-  Value will point to the value of the item. It returns the key of the removed item.\r
-\r
-  If Map is NULL, then ASSERT().\r
-  If Item is NULL, then ASSERT().\r
-  if item in not in the netmap, then ASSERT().\r
-\r
-  @param[in, out]  Map                   The netmap to remove the item from.\r
-  @param[in, out]  Item                  The item to remove.\r
-  @param[out]      Value                 The variable to receive the value if not NULL.\r
-\r
-  @return                                The key of the removed item.\r
-\r
-**/\r
-VOID *\r
-EFIAPI\r
-NetMapRemoveItem (\r
-  IN  OUT NET_MAP             *Map,\r
-  IN  OUT NET_MAP_ITEM        *Item,\r
-  OUT VOID                    **Value           OPTIONAL\r
-  )\r
-{\r
-  ASSERT ((Map != NULL) && (Item != NULL));\r
-  ASSERT (NetItemInMap (Map, Item));\r
-\r
-  RemoveEntryList (&Item->Link);\r
-  Map->Count--;\r
-  InsertHeadList (&Map->Recycled, &Item->Link);\r
-\r
-  if (Value != NULL) {\r
-    *Value = Item->Value;\r
-  }\r
-\r
-  return Item->Key;\r
-}\r
-\r
-\r
-/**\r
-  Remove the first node entry on the netmap and return the key of the removed item.\r
-\r
-  Remove the first node entry from the Used doubly linked list of the netmap.\r
-  The number of the <Key, Value> pairs in the netmap decrease by 1. Then add the node\r
-  entry to the Recycled doubly linked list of the netmap. If parameter Value is not NULL,\r
-  parameter Value will point to the value of the item. It returns the key of the removed item.\r
-\r
-  If Map is NULL, then ASSERT().\r
-  If the Used doubly linked list is empty, then ASSERT().\r
-\r
-  @param[in, out]  Map                   The netmap to remove the head from.\r
-  @param[out]      Value                 The variable to receive the value if not NULL.\r
-\r
-  @return                                The key of the item removed.\r
-\r
-**/\r
-VOID *\r
-EFIAPI\r
-NetMapRemoveHead (\r
-  IN OUT NET_MAP            *Map,\r
-  OUT VOID                  **Value         OPTIONAL\r
-  )\r
-{\r
-  NET_MAP_ITEM  *Item;\r
-\r
-  //\r
-  // Often, it indicates a programming error to remove\r
-  // the first entry in an empty list\r
-  //\r
-  ASSERT (Map && !IsListEmpty (&Map->Used));\r
-\r
-  Item = NET_LIST_HEAD (&Map->Used, NET_MAP_ITEM, Link);\r
-  RemoveEntryList (&Item->Link);\r
-  Map->Count--;\r
-  InsertHeadList (&Map->Recycled, &Item->Link);\r
-\r
-  if (Value != NULL) {\r
-    *Value = Item->Value;\r
-  }\r
-\r
-  return Item->Key;\r
-}\r
-\r
-\r
-/**\r
-  Remove the last node entry on the netmap and return the key of the removed item.\r
-\r
-  Remove the last node entry from the Used doubly linked list of the netmap.\r
-  The number of the <Key, Value> pairs in the netmap decrease by 1. Then add the node\r
-  entry to the Recycled doubly linked list of the netmap. If parameter Value is not NULL,\r
-  parameter Value will point to the value of the item. It returns the key of the removed item.\r
-\r
-  If Map is NULL, then ASSERT().\r
-  If the Used doubly linked list is empty, then ASSERT().\r
-\r
-  @param[in, out]  Map                   The netmap to remove the tail from.\r
-  @param[out]      Value                 The variable to receive the value if not NULL.\r
-\r
-  @return                                The key of the item removed.\r
-\r
-**/\r
-VOID *\r
-EFIAPI\r
-NetMapRemoveTail (\r
-  IN OUT NET_MAP            *Map,\r
-  OUT VOID                  **Value       OPTIONAL\r
-  )\r
-{\r
-  NET_MAP_ITEM              *Item;\r
-\r
-  //\r
-  // Often, it indicates a programming error to remove\r
-  // the last entry in an empty list\r
-  //\r
-  ASSERT (Map && !IsListEmpty (&Map->Used));\r
-\r
-  Item = NET_LIST_TAIL (&Map->Used, NET_MAP_ITEM, Link);\r
-  RemoveEntryList (&Item->Link);\r
-  Map->Count--;\r
-  InsertHeadList (&Map->Recycled, &Item->Link);\r
-\r
-  if (Value != NULL) {\r
-    *Value = Item->Value;\r
-  }\r
-\r
-  return Item->Key;\r
-}\r
-\r
-\r
-/**\r
-  Iterate through the netmap and call CallBack for each item.\r
-\r
-  It will continue the traverse if CallBack returns EFI_SUCCESS, otherwise, break\r
-  from the loop. It returns the CallBack's last return value. This function is\r
-  delete safe for the current item.\r
-\r
-  If Map is NULL, then ASSERT().\r
-  If CallBack is NULL, then ASSERT().\r
-\r
-  @param[in]  Map                   The Map to iterate through.\r
-  @param[in]  CallBack              The callback function to call for each item.\r
-  @param[in]  Arg                   The opaque parameter to the callback.\r
-\r
-  @retval EFI_SUCCESS            There is no item in the netmap or CallBack for each item\r
-                                 return EFI_SUCCESS.\r
-  @retval Others                 It returns the CallBack's last return value.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-NetMapIterate (\r
-  IN NET_MAP                *Map,\r
-  IN NET_MAP_CALLBACK       CallBack,\r
-  IN VOID                   *Arg      OPTIONAL\r
-  )\r
-{\r
-\r
-  LIST_ENTRY            *Entry;\r
-  LIST_ENTRY            *Next;\r
-  LIST_ENTRY            *Head;\r
-  NET_MAP_ITEM          *Item;\r
-  EFI_STATUS            Result;\r
-\r
-  ASSERT ((Map != NULL) && (CallBack != NULL));\r
-\r
-  Head = &Map->Used;\r
-\r
-  if (IsListEmpty (Head)) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  NET_LIST_FOR_EACH_SAFE (Entry, Next, Head) {\r
-    Item   = NET_LIST_USER_STRUCT (Entry, NET_MAP_ITEM, Link);\r
-    Result = CallBack (Map, Item, Arg);\r
-\r
-    if (EFI_ERROR (Result)) {\r
-      return Result;\r
-    }\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
-  This is the default unload handle for all the network drivers.\r
-\r
-  Disconnect the driver specified by ImageHandle from all the devices in the handle database.\r
-  Uninstall all the protocols installed in the driver entry point.\r
-\r
-  @param[in]  ImageHandle       The drivers' driver image.\r
-\r
-  @retval EFI_SUCCESS           The image is unloaded.\r
-  @retval Others                Failed to unload the image.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-NetLibDefaultUnload (\r
-  IN EFI_HANDLE             ImageHandle\r
-  )\r
-{\r
-  EFI_STATUS                        Status;\r
-  EFI_HANDLE                        *DeviceHandleBuffer;\r
-  UINTN                             DeviceHandleCount;\r
-  UINTN                             Index;\r
-  UINTN                             Index2;\r
-  EFI_DRIVER_BINDING_PROTOCOL       *DriverBinding;\r
-  EFI_COMPONENT_NAME_PROTOCOL       *ComponentName;\r
-  EFI_COMPONENT_NAME2_PROTOCOL      *ComponentName2;\r
-\r
-  //\r
-  // Get the list of all the handles in the handle database.\r
-  // If there is an error getting the list, then the unload\r
-  // operation fails.\r
-  //\r
-  Status = gBS->LocateHandleBuffer (\r
-                  AllHandles,\r
-                  NULL,\r
-                  NULL,\r
-                  &DeviceHandleCount,\r
-                  &DeviceHandleBuffer\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  for (Index = 0; Index < DeviceHandleCount; Index++) {\r
-    Status = gBS->HandleProtocol (\r
-                    DeviceHandleBuffer[Index],\r
-                    &gEfiDriverBindingProtocolGuid,\r
-                    (VOID **) &DriverBinding\r
-                    );\r
-    if (EFI_ERROR (Status)) {\r
-      continue;\r
-    }\r
-\r
-    if (DriverBinding->ImageHandle != ImageHandle) {\r
-      continue;\r
-    }\r
-\r
-    //\r
-    // Disconnect the driver specified by ImageHandle from all\r
-    // the devices in the handle database.\r
-    //\r
-    for (Index2 = 0; Index2 < DeviceHandleCount; Index2++) {\r
-      Status = gBS->DisconnectController (\r
-                      DeviceHandleBuffer[Index2],\r
-                      DriverBinding->DriverBindingHandle,\r
-                      NULL\r
-                      );\r
-    }\r
-\r
-    //\r
-    // Uninstall all the protocols installed in the driver entry point\r
-    //\r
-    gBS->UninstallProtocolInterface (\r
-          DriverBinding->DriverBindingHandle,\r
-          &gEfiDriverBindingProtocolGuid,\r
-          DriverBinding\r
-          );\r
-\r
-    Status = gBS->HandleProtocol (\r
-                    DeviceHandleBuffer[Index],\r
-                    &gEfiComponentNameProtocolGuid,\r
-                    (VOID **) &ComponentName\r
-                    );\r
-    if (!EFI_ERROR (Status)) {\r
-      gBS->UninstallProtocolInterface (\r
-             DriverBinding->DriverBindingHandle,\r
-             &gEfiComponentNameProtocolGuid,\r
-             ComponentName\r
-             );\r
-    }\r
-\r
-    Status = gBS->HandleProtocol (\r
-                    DeviceHandleBuffer[Index],\r
-                    &gEfiComponentName2ProtocolGuid,\r
-                    (VOID **) &ComponentName2\r
-                    );\r
-    if (!EFI_ERROR (Status)) {\r
-      gBS->UninstallProtocolInterface (\r
-             DriverBinding->DriverBindingHandle,\r
-             &gEfiComponentName2ProtocolGuid,\r
-             ComponentName2\r
-             );\r
-    }\r
-  }\r
-\r
-  //\r
-  // Free the buffer containing the list of handles from the handle database\r
-  //\r
-  if (DeviceHandleBuffer != NULL) {\r
-    gBS->FreePool (DeviceHandleBuffer);\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-\r
-/**\r
-  Create a child of the service that is identified by ServiceBindingGuid.\r
-\r
-  Get the ServiceBinding Protocol first, then use it to create a child.\r
-\r
-  If ServiceBindingGuid is NULL, then ASSERT().\r
-  If ChildHandle is NULL, then ASSERT().\r
-\r
-  @param[in]       Controller            The controller which has the service installed.\r
-  @param[in]       Image                 The image handle used to open service.\r
-  @param[in]       ServiceBindingGuid    The service's Guid.\r
-  @param[in, out]  ChildHandle           The handle to receive the create child.\r
-\r
-  @retval EFI_SUCCESS           The child is successfully created.\r
-  @retval Others                Failed to create the child.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-NetLibCreateServiceChild (\r
-  IN  EFI_HANDLE            Controller,\r
-  IN  EFI_HANDLE            Image,\r
-  IN  EFI_GUID              *ServiceBindingGuid,\r
-  IN  OUT EFI_HANDLE        *ChildHandle\r
-  )\r
-{\r
-  EFI_STATUS                    Status;\r
-  EFI_SERVICE_BINDING_PROTOCOL  *Service;\r
-\r
-\r
-  ASSERT ((ServiceBindingGuid != NULL) && (ChildHandle != NULL));\r
-\r
-  //\r
-  // Get the ServiceBinding Protocol\r
-  //\r
-  Status = gBS->OpenProtocol (\r
-                  Controller,\r
-                  ServiceBindingGuid,\r
-                  (VOID **) &Service,\r
-                  Image,\r
-                  Controller,\r
-                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Create a child\r
-  //\r
-  Status = Service->CreateChild (Service, ChildHandle);\r
-  return Status;\r
-}\r
-\r
-\r
-/**\r
-  Destroy a child of the service that is identified by ServiceBindingGuid.\r
-\r
-  Get the ServiceBinding Protocol first, then use it to destroy a child.\r
-\r
-  If ServiceBindingGuid is NULL, then ASSERT().\r
-\r
-  @param[in]   Controller            The controller which has the service installed.\r
-  @param[in]   Image                 The image handle used to open service.\r
-  @param[in]   ServiceBindingGuid    The service's Guid.\r
-  @param[in]   ChildHandle           The child to destroy.\r
-\r
-  @retval EFI_SUCCESS           The child is successfully destroyed.\r
-  @retval Others                Failed to destroy the child.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-NetLibDestroyServiceChild (\r
-  IN  EFI_HANDLE            Controller,\r
-  IN  EFI_HANDLE            Image,\r
-  IN  EFI_GUID              *ServiceBindingGuid,\r
-  IN  EFI_HANDLE            ChildHandle\r
-  )\r
-{\r
-  EFI_STATUS                    Status;\r
-  EFI_SERVICE_BINDING_PROTOCOL  *Service;\r
-\r
-  ASSERT (ServiceBindingGuid != NULL);\r
-\r
-  //\r
-  // Get the ServiceBinding Protocol\r
-  //\r
-  Status = gBS->OpenProtocol (\r
-                  Controller,\r
-                  ServiceBindingGuid,\r
-                  (VOID **) &Service,\r
-                  Image,\r
-                  Controller,\r
-                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // destroy the child\r
-  //\r
-  Status = Service->DestroyChild (Service, ChildHandle);\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Get handle with Simple Network Protocol installed on it.\r
-\r
-  There should be MNP Service Binding Protocol installed on the input ServiceHandle.\r
-  If Simple Network Protocol is already installed on the ServiceHandle, the\r
-  ServiceHandle will be returned. If SNP is not installed on the ServiceHandle,\r
-  try to find its parent handle with SNP installed.\r
-\r
-  @param[in]   ServiceHandle    The handle where network service binding protocols are\r
-                                installed on.\r
-  @param[out]  Snp              The pointer to store the address of the SNP instance.\r
-                                This is an optional parameter that may be NULL.\r
-\r
-  @return The SNP handle, or NULL if not found.\r
-\r
-**/\r
-EFI_HANDLE\r
-EFIAPI\r
-NetLibGetSnpHandle (\r
-  IN   EFI_HANDLE                  ServiceHandle,\r
-  OUT  EFI_SIMPLE_NETWORK_PROTOCOL **Snp  OPTIONAL\r
-  )\r
-{\r
-  EFI_STATUS                   Status;\r
-  EFI_SIMPLE_NETWORK_PROTOCOL  *SnpInstance;\r
-  EFI_DEVICE_PATH_PROTOCOL     *DevicePath;\r
-  EFI_HANDLE                   SnpHandle;\r
-\r
-  //\r
-  // Try to open SNP from ServiceHandle\r
-  //\r
-  SnpInstance = NULL;\r
-  Status = gBS->HandleProtocol (ServiceHandle, &gEfiSimpleNetworkProtocolGuid, (VOID **) &SnpInstance);\r
-  if (!EFI_ERROR (Status)) {\r
-    if (Snp != NULL) {\r
-      *Snp = SnpInstance;\r
-    }\r
-    return ServiceHandle;\r
-  }\r
-\r
-  //\r
-  // Failed to open SNP, try to get SNP handle by LocateDevicePath()\r
-  //\r
-  DevicePath = DevicePathFromHandle (ServiceHandle);\r
-  if (DevicePath == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  SnpHandle = NULL;\r
-  Status = gBS->LocateDevicePath (&gEfiSimpleNetworkProtocolGuid, &DevicePath, &SnpHandle);\r
-  if (EFI_ERROR (Status)) {\r
-    //\r
-    // Failed to find SNP handle\r
-    //\r
-    return NULL;\r
-  }\r
-\r
-  Status = gBS->HandleProtocol (SnpHandle, &gEfiSimpleNetworkProtocolGuid, (VOID **) &SnpInstance);\r
-  if (!EFI_ERROR (Status)) {\r
-    if (Snp != NULL) {\r
-      *Snp = SnpInstance;\r
-    }\r
-    return SnpHandle;\r
-  }\r
-\r
-  return NULL;\r
-}\r
-\r
-/**\r
-  Retrieve VLAN ID of a VLAN device handle.\r
-\r
-  Search VLAN device path node in Device Path of specified ServiceHandle and\r
-  return its VLAN ID. If no VLAN device path node found, then this ServiceHandle\r
-  is not a VLAN device handle, and 0 will be returned.\r
-\r
-  @param[in]   ServiceHandle    The handle where network service binding protocols are\r
-                                installed on.\r
-\r
-  @return VLAN ID of the device handle, or 0 if not a VLAN device.\r
-\r
-**/\r
-UINT16\r
-EFIAPI\r
-NetLibGetVlanId (\r
-  IN EFI_HANDLE             ServiceHandle\r
-  )\r
-{\r
-  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
-  EFI_DEVICE_PATH_PROTOCOL  *Node;\r
-\r
-  DevicePath = DevicePathFromHandle (ServiceHandle);\r
-  if (DevicePath == NULL) {\r
-    return 0;\r
-  }\r
-\r
-  Node = DevicePath;\r
-  while (!IsDevicePathEnd (Node)) {\r
-    if (Node->Type == MESSAGING_DEVICE_PATH && Node->SubType == MSG_VLAN_DP) {\r
-      return ((VLAN_DEVICE_PATH *) Node)->VlanId;\r
-    }\r
-    Node = NextDevicePathNode (Node);\r
-  }\r
-\r
-  return 0;\r
-}\r
-\r
-/**\r
-  Find VLAN device handle with specified VLAN ID.\r
-\r
-  The VLAN child device handle is created by VLAN Config Protocol on ControllerHandle.\r
-  This function will append VLAN device path node to the parent device path,\r
-  and then use LocateDevicePath() to find the correct VLAN device handle.\r
-\r
-  @param[in]   ControllerHandle The handle where network service binding protocols are\r
-                                installed on.\r
-  @param[in]   VlanId           The configured VLAN ID for the VLAN device.\r
-\r
-  @return The VLAN device handle, or NULL if not found.\r
-\r
-**/\r
-EFI_HANDLE\r
-EFIAPI\r
-NetLibGetVlanHandle (\r
-  IN EFI_HANDLE             ControllerHandle,\r
-  IN UINT16                 VlanId\r
-  )\r
-{\r
-  EFI_DEVICE_PATH_PROTOCOL  *ParentDevicePath;\r
-  EFI_DEVICE_PATH_PROTOCOL  *VlanDevicePath;\r
-  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
-  VLAN_DEVICE_PATH          VlanNode;\r
-  EFI_HANDLE                Handle;\r
-\r
-  ParentDevicePath = DevicePathFromHandle (ControllerHandle);\r
-  if (ParentDevicePath == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  //\r
-  // Construct VLAN device path\r
-  //\r
-  CopyMem (&VlanNode, &mNetVlanDevicePathTemplate, sizeof (VLAN_DEVICE_PATH));\r
-  VlanNode.VlanId = VlanId;\r
-  VlanDevicePath = AppendDevicePathNode (\r
-                     ParentDevicePath,\r
-                     (EFI_DEVICE_PATH_PROTOCOL *) &VlanNode\r
-                     );\r
-  if (VlanDevicePath == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  //\r
-  // Find VLAN device handle\r
-  //\r
-  Handle = NULL;\r
-  DevicePath = VlanDevicePath;\r
-  gBS->LocateDevicePath (\r
-         &gEfiDevicePathProtocolGuid,\r
-         &DevicePath,\r
-         &Handle\r
-         );\r
-  if (!IsDevicePathEnd (DevicePath)) {\r
-    //\r
-    // Device path is not exactly match\r
-    //\r
-    Handle = NULL;\r
-  }\r
-\r
-  FreePool (VlanDevicePath);\r
-  return Handle;\r
-}\r
-\r
-/**\r
-  Get MAC address associated with the network service handle.\r
-\r
-  If MacAddress is NULL, then ASSERT().\r
-  If AddressSize is NULL, then ASSERT().\r
-\r
-  There should be MNP Service Binding Protocol installed on the input ServiceHandle.\r
-  If SNP is installed on the ServiceHandle or its parent handle, MAC address will\r
-  be retrieved from SNP. If no SNP found, try to get SNP mode data use MNP.\r
-\r
-  @param[in]   ServiceHandle    The handle where network service binding protocols are\r
-                                installed on.\r
-  @param[out]  MacAddress       The pointer to store the returned MAC address.\r
-  @param[out]  AddressSize      The length of returned MAC address.\r
-\r
-  @retval EFI_SUCCESS           MAC address is returned successfully.\r
-  @retval Others                Failed to get SNP mode data.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-NetLibGetMacAddress (\r
-  IN  EFI_HANDLE            ServiceHandle,\r
-  OUT EFI_MAC_ADDRESS       *MacAddress,\r
-  OUT UINTN                 *AddressSize\r
-  )\r
-{\r
-  EFI_STATUS                   Status;\r
-  EFI_SIMPLE_NETWORK_PROTOCOL  *Snp;\r
-  EFI_SIMPLE_NETWORK_MODE      *SnpMode;\r
-  EFI_SIMPLE_NETWORK_MODE      SnpModeData;\r
-  EFI_MANAGED_NETWORK_PROTOCOL *Mnp;\r
-  EFI_SERVICE_BINDING_PROTOCOL *MnpSb;\r
-  EFI_HANDLE                   *SnpHandle;\r
-  EFI_HANDLE                   MnpChildHandle;\r
-\r
-  ASSERT (MacAddress != NULL);\r
-  ASSERT (AddressSize != NULL);\r
-\r
-  //\r
-  // Try to get SNP handle\r
-  //\r
-  Snp = NULL;\r
-  SnpHandle = NetLibGetSnpHandle (ServiceHandle, &Snp);\r
-  if (SnpHandle != NULL) {\r
-    //\r
-    // SNP found, use it directly\r
-    //\r
-    SnpMode = Snp->Mode;\r
-  } else {\r
-    //\r
-    // Failed to get SNP handle, try to get MAC address from MNP\r
-    //\r
-    MnpChildHandle = NULL;\r
-    Status = gBS->HandleProtocol (\r
-                    ServiceHandle,\r
-                    &gEfiManagedNetworkServiceBindingProtocolGuid,\r
-                    (VOID **) &MnpSb\r
-