├── .gitmodules ├── Code of Conduct.md ├── Edk2_Patch ├── MdePkg │ └── MdePkg.dec └── NetworkPkg │ ├── Dhcp4Dxe │ └── Dhcp4Driver.c │ ├── Dhcp6Dxe │ ├── Dhcp6Driver.c │ ├── Dhcp6Impl.h │ ├── Dhcp6Io.c │ ├── Dhcp6Io.h │ ├── Dhcp6Utility.c │ └── Dhcp6Utility.h │ ├── DnsDxe │ ├── DnsDhcp.c │ └── DnsImpl.c │ ├── HttpBootDxe │ └── HttpBootDhcp6.c │ ├── IScsiDxe │ ├── IScsiCHAP.c │ ├── IScsiMisc.c │ └── IScsiMisc.h │ ├── Include │ └── Library │ │ └── NetLib.h │ ├── Ip4Dxe │ └── Ip4Driver.c │ ├── Ip6Dxe │ ├── Ip6ConfigImpl.c │ ├── Ip6Driver.c │ ├── Ip6If.c │ ├── Ip6Mld.c │ ├── Ip6Nd.c │ ├── Ip6Nd.h │ ├── Ip6Option.c │ └── Ip6Option.h │ ├── Library │ └── DxeNetLib │ │ ├── DxeNetLib.c │ │ └── DxeNetLib.inf │ ├── NetworkPkg.dec │ ├── TcpDxe │ ├── TcpDriver.c │ ├── TcpDxe.inf │ ├── TcpFunc.h │ ├── TcpInput.c │ ├── TcpMain.h │ ├── TcpMisc.c │ └── TcpTimer.c │ ├── Udp4Dxe │ └── Udp4Driver.c │ ├── Udp6Dxe │ └── Udp6Driver.c │ └── UefiPxeBcDxe │ ├── PxeBcDhcp4.c │ ├── PxeBcDhcp6.c │ ├── PxeBcDhcp6.h │ └── PxeBcDriver.c ├── LICENSE ├── MAINTAINERS.md ├── Override_Patch.bat ├── README.md ├── Readme_VisualStudioInstall.png ├── SECURITY.md ├── Trademark.md └── governance.md /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "edk2-platforms"] 2 | path = edk2-platforms 3 | url = https://github.com/tianocore/edk2-platforms.git 4 | [submodule "edk2-non-osi"] 5 | path = edk2-non-osi 6 | url = https://github.com/tianocore/edk2-non-osi.git 7 | [submodule "FSP"] 8 | path = FSP 9 | url = https://github.com/IntelFsp/FSP.git 10 | [submodule "edk2"] 11 | path = edk2 12 | url = https://github.com/tianocore/edk2.git 13 | -------------------------------------------------------------------------------- /Code of Conduct.md: -------------------------------------------------------------------------------- 1 | **OCP Code of Conduct** 2 | 3 | This code of conduct applies to all spaces managed by OCP. This includes our website, the Wiki pages, OCP Github, the mailing lists, the project community calls, workshops, webinars or events, social media communities, and any other forums created by the Foundation or Project Leadership which the community uses for communication and exchange of information. In addition, violations of this code outside these spaces may affect a person's ability to participate within them. 4 | 5 | If a participant believes someone is violating the code of conduct, The Foundation ask that it be reported immediately by emailing conduct@opencomputeproject.org. 6 | 7 | - **All participants must be friendly and patient.** 8 | 9 | - **All participants must be welcoming**. The OCP Community strives to be a community that welcomes and supports people of all backgrounds and identities. This includes, but is not limited to members of any race, ethnicity, culture, national origin, color, immigration status, social and economic class, educational level, sex, sexual orientation, gender identity and expression, age, size, family status, political belief, religion, and mental and physical ability. 10 | 11 | - **All participants must be considerate.** The work will be used by other people, and the work in turn will depend on the work of others. Any decision that is made will affect users and colleagues, and participants should take those consequences into account when making decisions. This is a world-wide community, so communication might not be done in someone else's primary language. 12 | 13 | - **All participants must be respectful.** Not everyone will agree all the time, but disagreement is no excuse for poor behavior and poor manners. It’s important to remember that a community where people feel uncomfortable or threatened is not a productive one. Participants of the OCP Community should be respectful when dealing with other members as well as with people outside the OCP Community. 14 | 15 | - **All participants must be careful in the words that they choose.** This is a community of professionals, and professional conduct is key to success. Insults or shaming of other participants, harassment and other exclusionary behavior are not acceptable. This includes, but is not limited to: 16 | - Violent threats or language directed against another person. 17 | - Discriminatory jokes and language. 18 | - Posting sexually explicit or violent material. 19 | - Posting (or threatening to post) other people's personally identifying information ("doxing"). 20 | - Personal insults, especially those using racist or sexist terms. 21 | - Unwelcome sexual attention. 22 | - Advocating for, or encouraging, any of the above behavior. 23 | - Repeated harassment of others. In general, if someone asks you to stop, then stop. 24 | - **Disagreements are the perfect opportunity for growth and learning lessons.** Disagreements, both social and technical, happen all the time and the OCP Community is no exception. It is important that disagreements are resolved constructively and differing views are shared professionally. The strength of OCP comes from its varied community, people from a wide range of backgrounds. Different people have different perspectives on issues. Being unable to understand why someone holds a viewpoint doesn’t mean that they’re wrong. Instead, focus on helping to resolve issues. 25 | -------------------------------------------------------------------------------- /Edk2_Patch/NetworkPkg/Dhcp6Dxe/Dhcp6Io.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | Dhcp6 internal functions declaration. 3 | 4 | Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.
5 | 6 | SPDX-License-Identifier: BSD-2-Clause-Patent 7 | 8 | **/ 9 | 10 | #ifndef __EFI_DHCP6_IO_H__ 11 | #define __EFI_DHCP6_IO_H__ 12 | 13 | /** 14 | Clean up the specific nodes in the retry list. 15 | 16 | @param[in] Instance The pointer to the Dhcp6 instance. 17 | @param[in] Scope The scope of cleanup nodes. 18 | 19 | **/ 20 | VOID 21 | Dhcp6CleanupRetry ( 22 | IN DHCP6_INSTANCE *Instance, 23 | IN UINT32 Scope 24 | ); 25 | 26 | /** 27 | Clean up the session of the instance stateful exchange. 28 | 29 | @param[in, out] Instance The pointer to the Dhcp6 instance. 30 | @param[in] Status The return status from udp. 31 | 32 | **/ 33 | VOID 34 | Dhcp6CleanupSession ( 35 | IN OUT DHCP6_INSTANCE *Instance, 36 | IN EFI_STATUS Status 37 | ); 38 | 39 | /** 40 | Create the solicit message and send it. 41 | 42 | @param[in] Instance The pointer to Dhcp6 instance. 43 | 44 | @retval EFI_SUCCESS Create and send the solicit message successfully. 45 | @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. 46 | @retval Others Failed to send the solicit message. 47 | 48 | **/ 49 | EFI_STATUS 50 | Dhcp6SendSolicitMsg ( 51 | IN DHCP6_INSTANCE *Instance 52 | ); 53 | 54 | /** 55 | Create the request message and send it. 56 | 57 | @param[in] Instance The pointer to the Dhcp6 instance. 58 | 59 | @retval EFI_SUCCESS Create and send the request message successfully. 60 | @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. 61 | @retval EFI_DEVICE_ERROR An unexpected error. 62 | @retval Others Failed to send the request message. 63 | 64 | **/ 65 | EFI_STATUS 66 | Dhcp6SendRequestMsg ( 67 | IN DHCP6_INSTANCE *Instance 68 | ); 69 | 70 | /** 71 | Create the renew/rebind message and send it. 72 | 73 | @param[in] Instance The pointer to the Dhcp6 instance. 74 | @param[in] RebindRequest If TRUE, it is a Rebind type message. 75 | Otherwise, it is a Renew type message. 76 | 77 | @retval EFI_SUCCESS Create and send the renew/rebind message successfully. 78 | @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. 79 | @retval EFI_DEVICE_ERROR An unexpected error. 80 | @retval Others Failed to send the renew/rebind message. 81 | 82 | **/ 83 | EFI_STATUS 84 | Dhcp6SendRenewRebindMsg ( 85 | IN DHCP6_INSTANCE *Instance, 86 | IN BOOLEAN RebindRequest 87 | ); 88 | 89 | /** 90 | Create the decline message and send it. 91 | 92 | @param[in] Instance The pointer to the Dhcp6 instance. 93 | @param[in] DecIa The pointer to the decline Ia. 94 | 95 | @retval EFI_SUCCESS Create and send the decline message successfully. 96 | @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. 97 | @retval EFI_DEVICE_ERROR An unexpected error. 98 | @retval Others Failed to send the decline message. 99 | 100 | **/ 101 | EFI_STATUS 102 | Dhcp6SendDeclineMsg ( 103 | IN DHCP6_INSTANCE *Instance, 104 | IN EFI_DHCP6_IA *DecIa 105 | ); 106 | 107 | /** 108 | Create the release message and send it. 109 | 110 | @param[in] Instance The pointer to the Dhcp6 instance. 111 | @param[in] RelIa The pointer to the release Ia. 112 | 113 | @retval EFI_SUCCESS Create and send the release message successfully. 114 | @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. 115 | @retval EFI_DEVICE_ERROR An unexpected error. 116 | @retval Others Failed to send the release message. 117 | 118 | **/ 119 | EFI_STATUS 120 | Dhcp6SendReleaseMsg ( 121 | IN DHCP6_INSTANCE *Instance, 122 | IN EFI_DHCP6_IA *RelIa 123 | ); 124 | 125 | /** 126 | Start the information request process. 127 | 128 | @param[in] Instance The pointer to the Dhcp6 instance. 129 | @param[in] SendClientId If TRUE, the client identifier option will be included in 130 | information request message. Otherwise, the client identifier 131 | option will not be included. 132 | @param[in] OptionRequest The pointer to the option request option. 133 | @param[in] OptionCount The number options in the OptionList. 134 | @param[in] OptionList The array pointers to the appended options. 135 | @param[in] Retransmission The pointer to the retransmission control. 136 | @param[in] TimeoutEvent The event of timeout. 137 | @param[in] ReplyCallback The callback function when the reply was received. 138 | @param[in] CallbackContext The pointer to the parameter passed to the callback. 139 | 140 | @retval EFI_SUCCESS Start the info-request process successfully. 141 | @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. 142 | @retval EFI_NO_MAPPING No source address is available for use. 143 | @retval Others Failed to start the info-request process. 144 | 145 | **/ 146 | EFI_STATUS 147 | Dhcp6StartInfoRequest ( 148 | IN DHCP6_INSTANCE *Instance, 149 | IN BOOLEAN SendClientId, 150 | IN EFI_DHCP6_PACKET_OPTION *OptionRequest, 151 | IN UINT32 OptionCount, 152 | IN EFI_DHCP6_PACKET_OPTION *OptionList[] OPTIONAL, 153 | IN EFI_DHCP6_RETRANSMISSION *Retransmission, 154 | IN EFI_EVENT TimeoutEvent OPTIONAL, 155 | IN EFI_DHCP6_INFO_CALLBACK ReplyCallback, 156 | IN VOID *CallbackContext OPTIONAL 157 | ); 158 | 159 | /** 160 | Create the information request message and send it. 161 | 162 | @param[in] Instance The pointer to the Dhcp6 instance. 163 | @param[in] InfCb The pointer to the information request control block. 164 | @param[in] SendClientId If TRUE, the client identifier option will be included in 165 | information request message. Otherwise, the client identifier 166 | option will not be included. 167 | @param[in] OptionRequest The pointer to the option request option. 168 | @param[in] OptionCount The number options in the OptionList. 169 | @param[in] OptionList The array pointers to the appended options. 170 | @param[in] Retransmission The pointer to the retransmission control. 171 | 172 | @retval EFI_SUCCESS Create and send the info-request message successfully. 173 | @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. 174 | @retval Others Failed to send the info-request message. 175 | 176 | **/ 177 | EFI_STATUS 178 | Dhcp6SendInfoRequestMsg ( 179 | IN DHCP6_INSTANCE *Instance, 180 | IN DHCP6_INF_CB *InfCb, 181 | IN BOOLEAN SendClientId, 182 | IN EFI_DHCP6_PACKET_OPTION *OptionRequest, 183 | IN UINT32 OptionCount, 184 | IN EFI_DHCP6_PACKET_OPTION *OptionList[], 185 | IN EFI_DHCP6_RETRANSMISSION *Retransmission 186 | ); 187 | 188 | /** 189 | The receive callback function for the Dhcp6 exchange process. 190 | 191 | @param[in] Udp6Wrap The pointer to the received net buffer. 192 | @param[in] EndPoint The pointer to the udp end point. 193 | @param[in] IoStatus The return status from udp io. 194 | @param[in] Context The opaque parameter to the function. 195 | 196 | **/ 197 | VOID 198 | EFIAPI 199 | Dhcp6ReceivePacket ( 200 | IN NET_BUF *Udp6Wrap, 201 | IN UDP_END_POINT *EndPoint, 202 | IN EFI_STATUS IoStatus, 203 | IN VOID *Context 204 | ); 205 | 206 | /** 207 | The timer routine of the Dhcp6 instance for each second. 208 | 209 | @param[in] Event The timer event. 210 | @param[in] Context The opaque parameter to the function. 211 | 212 | **/ 213 | VOID 214 | EFIAPI 215 | Dhcp6OnTimerTick ( 216 | IN EFI_EVENT Event, 217 | IN VOID *Context 218 | ); 219 | 220 | /** 221 | Seeks the Inner Options from a DHCP6 Option 222 | 223 | @param[in] IaType The type of the IA option. 224 | @param[in] Option The pointer to the DHCP6 Option. 225 | @param[in] OptionLen The length of the DHCP6 Option. 226 | @param[out] IaInnerOpt The pointer to the IA inner option. 227 | @param[out] IaInnerLen The length of the IA inner option. 228 | 229 | @retval EFI_SUCCESS Seek the inner option successfully. 230 | @retval EFI_DEVICE_ERROR The OptionLen is invalid. On Error, 231 | the pointers are not modified 232 | **/ 233 | EFI_STATUS 234 | Dhcp6SeekInnerOptionSafe ( 235 | IN UINT16 IaType, 236 | IN UINT8 *Option, 237 | IN UINT32 OptionLen, 238 | OUT UINT8 **IaInnerOpt, 239 | OUT UINT16 *IaInnerLen 240 | ); 241 | 242 | #endif 243 | -------------------------------------------------------------------------------- /Edk2_Patch/NetworkPkg/Dhcp6Dxe/Dhcp6Utility.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | Dhcp6 support functions declaration. 3 | 4 | Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.
5 | 6 | SPDX-License-Identifier: BSD-2-Clause-Patent 7 | 8 | **/ 9 | 10 | #ifndef __EFI_DHCP6_UTILITY_H__ 11 | #define __EFI_DHCP6_UTILITY_H__ 12 | 13 | #define DHCP6_10_BIT_MASK 0x3ff 14 | #define DHCP6_DAD_ADDITIONAL_DELAY 30000000 // 3 seconds 15 | 16 | /** 17 | Generate client Duid in the format of Duid-llt. 18 | 19 | @param[in] Mode The pointer to the mode of SNP. 20 | 21 | @retval NULL if failed to generate client Id. 22 | @retval Others The pointer to the new client id. 23 | 24 | **/ 25 | EFI_DHCP6_DUID * 26 | Dhcp6GenerateClientId ( 27 | IN EFI_SIMPLE_NETWORK_MODE *Mode 28 | ); 29 | 30 | /** 31 | Copy the Dhcp6 configure data. 32 | 33 | @param[in] DstCfg The pointer to the destination configure data. 34 | @param[in] SorCfg The pointer to the source configure data. 35 | 36 | @retval EFI_SUCCESS Copy the content from SorCfg from DstCfg successfully. 37 | @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. 38 | 39 | **/ 40 | EFI_STATUS 41 | Dhcp6CopyConfigData ( 42 | IN EFI_DHCP6_CONFIG_DATA *DstCfg, 43 | IN EFI_DHCP6_CONFIG_DATA *SorCfg 44 | ); 45 | 46 | /** 47 | Clean up the configure data. 48 | 49 | @param[in, out] CfgData The pointer to the configure data. 50 | 51 | **/ 52 | VOID 53 | Dhcp6CleanupConfigData ( 54 | IN OUT EFI_DHCP6_CONFIG_DATA *CfgData 55 | ); 56 | 57 | /** 58 | Clean up the mode data. 59 | 60 | @param[in, out] ModeData The pointer to the mode data. 61 | 62 | **/ 63 | VOID 64 | Dhcp6CleanupModeData ( 65 | IN OUT EFI_DHCP6_MODE_DATA *ModeData 66 | ); 67 | 68 | /** 69 | Calculate the expire time by the algorithm defined in rfc. 70 | 71 | @param[in] Base The base value of the time. 72 | @param[in] IsFirstRt If TRUE, it is the first time to calculate expire time. 73 | @param[in] NeedSigned If TRUE, the signed factor is needed. 74 | 75 | @return Expire The calculated result for the new expire time. 76 | 77 | **/ 78 | UINT32 79 | Dhcp6CalculateExpireTime ( 80 | IN UINT32 Base, 81 | IN BOOLEAN IsFirstRt, 82 | IN BOOLEAN NeedSigned 83 | ); 84 | 85 | /** 86 | Calculate the lease time by the algorithm defined in rfc. 87 | 88 | @param[in] IaCb The pointer to the Ia control block. 89 | 90 | **/ 91 | VOID 92 | Dhcp6CalculateLeaseTime ( 93 | IN DHCP6_IA_CB *IaCb 94 | ); 95 | 96 | /** 97 | Check whether the addresses are all included by the configured Ia. 98 | 99 | @param[in] Ia The pointer to the Ia. 100 | @param[in] AddressCount The number of addresses. 101 | @param[in] Addresses The pointer to the addresses buffer. 102 | 103 | @retval EFI_SUCCESS The addresses are all included by the configured IA. 104 | @retval EFI_NOT_FOUND The addresses are not included by the configured IA. 105 | 106 | **/ 107 | EFI_STATUS 108 | Dhcp6CheckAddress ( 109 | IN EFI_DHCP6_IA *Ia, 110 | IN UINT32 AddressCount, 111 | IN EFI_IPv6_ADDRESS *Addresses 112 | ); 113 | 114 | /** 115 | Deprive the addresses from current Ia, and generate another eliminated Ia. 116 | 117 | @param[in] Ia The pointer to the Ia. 118 | @param[in] AddressCount The number of addresses. 119 | @param[in] Addresses The pointer to the addresses buffer. 120 | 121 | @retval NULL If failed to generate the deprived Ia. 122 | @retval others The pointer to the deprived Ia. 123 | 124 | **/ 125 | EFI_DHCP6_IA * 126 | Dhcp6DepriveAddress ( 127 | IN EFI_DHCP6_IA *Ia, 128 | IN UINT32 AddressCount, 129 | IN EFI_IPv6_ADDRESS *Addresses 130 | ); 131 | 132 | /** 133 | The dummy ext buffer free callback routine. 134 | 135 | @param[in] Arg The pointer to the parameter. 136 | 137 | **/ 138 | VOID 139 | EFIAPI 140 | Dhcp6DummyExtFree ( 141 | IN VOID *Arg 142 | ); 143 | 144 | /** 145 | The callback routine once message transmitted. 146 | 147 | @param[in] Wrap The pointer to the received net buffer. 148 | @param[in] EndPoint The pointer to the udp end point. 149 | @param[in] IoStatus The return status from udp io. 150 | @param[in] Context The opaque parameter to the function. 151 | 152 | **/ 153 | VOID 154 | EFIAPI 155 | Dhcp6OnTransmitted ( 156 | IN NET_BUF *Wrap, 157 | IN UDP_END_POINT *EndPoint, 158 | IN EFI_STATUS IoStatus, 159 | IN VOID *Context 160 | ); 161 | 162 | /** 163 | Append the option to Buf, update the length of packet, and move Buf to the end. 164 | 165 | @param[in, out] Packet A pointer to the packet, on success Packet->Length 166 | will be updated. 167 | @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor 168 | will be moved to the end of the option. 169 | @param[in] OptType The option type. 170 | @param[in] OptLen The length of option contents. 171 | @param[in] Data The pointer to the option content. 172 | 173 | @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid 174 | @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option. 175 | @retval EFI_SUCCESS The option is appended successfully. 176 | **/ 177 | EFI_STATUS 178 | Dhcp6AppendOption ( 179 | IN OUT EFI_DHCP6_PACKET *Packet, 180 | IN OUT UINT8 **PacketCursor, 181 | IN UINT16 OptType, 182 | IN UINT16 OptLen, 183 | IN UINT8 *Data 184 | ); 185 | 186 | /** 187 | Append the appointed Ia option to Buf, update the Ia option length, and move Buf 188 | to the end of the option. 189 | @param[in, out] Packet A pointer to the packet, on success Packet->Length 190 | will be updated. 191 | @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor 192 | will be moved to the end of the option. 193 | @param[in] Ia The pointer to the Ia. 194 | @param[in] T1 The time of T1. 195 | @param[in] T2 The time of T2. 196 | @param[in] MessageType Message type of DHCP6 package. 197 | 198 | @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid 199 | @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option. 200 | @retval EFI_SUCCESS The option is appended successfully. 201 | **/ 202 | EFI_STATUS 203 | Dhcp6AppendIaOption ( 204 | IN OUT EFI_DHCP6_PACKET *Packet, 205 | IN OUT UINT8 **PacketCursor, 206 | IN EFI_DHCP6_IA *Ia, 207 | IN UINT32 T1, 208 | IN UINT32 T2, 209 | IN UINT32 MessageType 210 | ); 211 | 212 | /** 213 | Append the appointed Elapsed time option to Buf, and move Buf to the end. 214 | 215 | @param[in, out] Packet A pointer to the packet, on success Packet->Length 216 | @param[in, out] PacketCursor The pointer in the packet, on success PacketCursor 217 | will be moved to the end of the option. 218 | @param[in] Instance The pointer to the Dhcp6 instance. 219 | @param[out] Elapsed The pointer to the elapsed time value in 220 | the generated packet. 221 | 222 | @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid 223 | @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option. 224 | @retval EFI_SUCCESS The option is appended successfully. 225 | 226 | **/ 227 | EFI_STATUS 228 | Dhcp6AppendETOption ( 229 | IN OUT EFI_DHCP6_PACKET *Packet, 230 | IN OUT UINT8 **PacketCursor, 231 | IN DHCP6_INSTANCE *Instance, 232 | OUT UINT16 **Elapsed 233 | ); 234 | 235 | /** 236 | Set the elapsed time based on the given instance and the pointer to the 237 | elapsed time option. 238 | 239 | @retval EFI_INVALID_PARAMETER An argument provided to the function was invalid 240 | @retval EFI_BUFFER_TOO_SMALL The buffer is too small to append the option. 241 | @retval EFI_SUCCESS The option is appended successfully. 242 | **/ 243 | VOID 244 | SetElapsedTime ( 245 | IN UINT16 *Elapsed, 246 | IN DHCP6_INSTANCE *Instance 247 | ); 248 | 249 | /** 250 | Seek the address of the first byte of the option header. 251 | 252 | @param[in] Buf The pointer to buffer. 253 | @param[in] SeekLen The length to seek. 254 | @param[in] OptType The option type. 255 | 256 | @retval NULL If failed to seek the option. 257 | @retval others The position to the option. 258 | 259 | **/ 260 | UINT8 * 261 | Dhcp6SeekOption ( 262 | IN UINT8 *Buf, 263 | IN UINT32 SeekLen, 264 | IN UINT16 OptType 265 | ); 266 | 267 | /** 268 | Seek the address of the first byte of the Ia option header. 269 | 270 | @param[in] Buf The pointer to the buffer. 271 | @param[in] SeekLen The length to seek. 272 | @param[in] IaDesc The pointer to the Ia descriptor. 273 | 274 | @retval NULL If failed to seek the Ia option. 275 | @retval others The position to the Ia option. 276 | 277 | **/ 278 | UINT8 * 279 | Dhcp6SeekIaOption ( 280 | IN UINT8 *Buf, 281 | IN UINT32 SeekLen, 282 | IN EFI_DHCP6_IA_DESCRIPTOR *IaDesc 283 | ); 284 | 285 | /** 286 | Parse the address option and update the address info. 287 | 288 | @param[in] CurrentIa The pointer to the Ia Address in control block. 289 | @param[in] IaInnerOpt The pointer to the buffer. 290 | @param[in] IaInnerLen The length to parse. 291 | @param[out] AddrNum The number of addresses. 292 | @param[in, out] AddrBuf The pointer to the address buffer. 293 | 294 | **/ 295 | VOID 296 | Dhcp6ParseAddrOption ( 297 | IN EFI_DHCP6_IA *CurrentIa, 298 | IN UINT8 *IaInnerOpt, 299 | IN UINT16 IaInnerLen, 300 | OUT UINT32 *AddrNum, 301 | IN OUT EFI_DHCP6_IA_ADDRESS *AddrBuf 302 | ); 303 | 304 | /** 305 | Create a control block for the Ia according to the corresponding options. 306 | 307 | @param[in] Instance The pointer to DHCP6 Instance. 308 | @param[in] IaInnerOpt The pointer to the inner options in the Ia option. 309 | @param[in] IaInnerLen The length of all the inner options in the Ia option. 310 | @param[in] T1 T1 time in the Ia option. 311 | @param[in] T2 T2 time in the Ia option. 312 | 313 | @retval EFI_NOT_FOUND No valid IA option is found. 314 | @retval EFI_SUCCESS Create an IA control block successfully. 315 | @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. 316 | @retval EFI_DEVICE_ERROR An unexpected error. 317 | 318 | **/ 319 | EFI_STATUS 320 | Dhcp6GenerateIaCb ( 321 | IN DHCP6_INSTANCE *Instance, 322 | IN UINT8 *IaInnerOpt, 323 | IN UINT16 IaInnerLen, 324 | IN UINT32 T1, 325 | IN UINT32 T2 326 | ); 327 | 328 | /** 329 | Cache the current IA configuration information. 330 | 331 | @param[in] Instance The pointer to DHCP6 Instance. 332 | 333 | @retval EFI_SUCCESS Cache the current IA successfully. 334 | @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. 335 | 336 | **/ 337 | EFI_STATUS 338 | Dhcp6CacheIa ( 339 | IN DHCP6_INSTANCE *Instance 340 | ); 341 | 342 | /** 343 | Append CacheIa to the current IA. Meanwhile, clear CacheIa.ValidLifetime to 0. 344 | 345 | @param[in] Instance The pointer to DHCP6 instance. 346 | 347 | **/ 348 | VOID 349 | Dhcp6AppendCacheIa ( 350 | IN DHCP6_INSTANCE *Instance 351 | ); 352 | 353 | /** 354 | Calculate the Dhcp6 get mapping timeout by adding additional delay to the IP6 DAD transmits count. 355 | 356 | @param[in] Ip6Cfg The pointer to Ip6 config protocol. 357 | @param[out] TimeOut The time out value in 100ns units. 358 | 359 | @retval EFI_INVALID_PARAMETER Input parameters are invalid. 360 | @retval EFI_SUCCESS Calculate the time out value successfully. 361 | **/ 362 | EFI_STATUS 363 | Dhcp6GetMappingTimeOut ( 364 | IN EFI_IP6_CONFIG_PROTOCOL *Ip6Cfg, 365 | OUT UINTN *TimeOut 366 | ); 367 | 368 | #endif 369 | -------------------------------------------------------------------------------- /Edk2_Patch/NetworkPkg/DnsDxe/DnsDhcp.c: -------------------------------------------------------------------------------- 1 | /** @file 2 | Functions implementation related with DHCPv4/v6 for DNS driver. 3 | 4 | Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
5 | Copyright (c) Microsoft Corporation 6 | SPDX-License-Identifier: BSD-2-Clause-Patent 7 | 8 | **/ 9 | 10 | #include "DnsImpl.h" 11 | 12 | /** 13 | This function initialize the DHCP4 message instance. 14 | 15 | This function will pad each item of dhcp4 message packet. 16 | 17 | @param Seed Pointer to the message instance of the DHCP4 packet. 18 | @param InterfaceInfo Pointer to the EFI_IP4_CONFIG2_INTERFACE_INFO instance. 19 | 20 | **/ 21 | VOID 22 | DnsInitSeedPacket ( 23 | OUT EFI_DHCP4_PACKET *Seed, 24 | IN EFI_IP4_CONFIG2_INTERFACE_INFO *InterfaceInfo 25 | ) 26 | { 27 | EFI_DHCP4_HEADER *Header; 28 | 29 | // 30 | // Get IfType and HwAddressSize from SNP mode data. 31 | // 32 | Seed->Size = sizeof (EFI_DHCP4_PACKET); 33 | Seed->Length = sizeof (Seed->Dhcp4); 34 | Header = &Seed->Dhcp4.Header; 35 | ZeroMem (Header, sizeof (EFI_DHCP4_HEADER)); 36 | Header->OpCode = DHCP4_OPCODE_REQUEST; 37 | Header->HwType = InterfaceInfo->IfType; 38 | Header->HwAddrLen = (UINT8)InterfaceInfo->HwAddressSize; 39 | CopyMem (Header->ClientHwAddr, &(InterfaceInfo->HwAddress), Header->HwAddrLen); 40 | 41 | Seed->Dhcp4.Magik = DHCP4_MAGIC; 42 | Seed->Dhcp4.Option[0] = DHCP4_TAG_EOP; 43 | } 44 | 45 | /** 46 | The common notify function. 47 | 48 | @param[in] Event The event signaled. 49 | @param[in] Context The context. 50 | 51 | **/ 52 | VOID 53 | EFIAPI 54 | DhcpCommonNotify ( 55 | IN EFI_EVENT Event, 56 | IN VOID *Context 57 | ) 58 | { 59 | if ((Event == NULL) || (Context == NULL)) { 60 | return; 61 | } 62 | 63 | *((BOOLEAN *)Context) = TRUE; 64 | } 65 | 66 | /** 67 | Parse the ACK to get required information 68 | 69 | @param Dhcp4 The DHCP4 protocol. 70 | @param Packet Packet waiting for parse. 71 | @param DnsServerInfor The required Dns4 server information. 72 | 73 | @retval EFI_SUCCESS The DNS information is got from the DHCP ACK. 74 | @retval EFI_NO_MAPPING DHCP failed to acquire address and other information. 75 | @retval EFI_DEVICE_ERROR Other errors as indicated. 76 | @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. 77 | 78 | **/ 79 | EFI_STATUS 80 | ParseDhcp4Ack ( 81 | IN EFI_DHCP4_PROTOCOL *Dhcp4, 82 | IN EFI_DHCP4_PACKET *Packet, 83 | IN DNS4_SERVER_INFOR *DnsServerInfor 84 | ) 85 | { 86 | EFI_STATUS Status; 87 | UINT32 OptionCount; 88 | EFI_DHCP4_PACKET_OPTION **OptionList; 89 | UINT32 ServerCount; 90 | EFI_IPv4_ADDRESS *ServerList; 91 | UINT32 Index; 92 | UINT32 Count; 93 | 94 | ServerCount = 0; 95 | ServerList = NULL; 96 | 97 | OptionCount = 0; 98 | OptionList = NULL; 99 | 100 | Status = Dhcp4->Parse (Dhcp4, Packet, &OptionCount, OptionList); 101 | if (Status != EFI_BUFFER_TOO_SMALL) { 102 | return EFI_DEVICE_ERROR; 103 | } 104 | 105 | OptionList = AllocatePool (OptionCount * sizeof (EFI_DHCP4_PACKET_OPTION *)); 106 | if (OptionList == NULL) { 107 | return EFI_OUT_OF_RESOURCES; 108 | } 109 | 110 | Status = Dhcp4->Parse (Dhcp4, Packet, &OptionCount, OptionList); 111 | if (EFI_ERROR (Status)) { 112 | gBS->FreePool (OptionList); 113 | return EFI_DEVICE_ERROR; 114 | } 115 | 116 | Status = EFI_NOT_FOUND; 117 | 118 | for (Index = 0; Index < OptionCount; Index++) { 119 | // 120 | // Get DNS server addresses 121 | // 122 | if (OptionList[Index]->OpCode == DHCP4_TAG_DNS_SERVER) { 123 | if (((OptionList[Index]->Length & 0x3) != 0) || (OptionList[Index]->Length == 0)) { 124 | Status = EFI_DEVICE_ERROR; 125 | break; 126 | } 127 | 128 | ServerCount = OptionList[Index]->Length/4; 129 | ServerList = AllocatePool (ServerCount * sizeof (EFI_IPv4_ADDRESS)); 130 | if (ServerList == NULL) { 131 | return EFI_OUT_OF_RESOURCES; 132 | } 133 | 134 | for (Count = 0; Count < ServerCount; Count++) { 135 | CopyMem (ServerList + Count, &OptionList[Index]->Data[4 * Count], sizeof (EFI_IPv4_ADDRESS)); 136 | } 137 | 138 | *(DnsServerInfor->ServerCount) = ServerCount; 139 | DnsServerInfor->ServerList = ServerList; 140 | 141 | Status = EFI_SUCCESS; 142 | } 143 | } 144 | 145 | gBS->FreePool (OptionList); 146 | 147 | return Status; 148 | } 149 | 150 | /** 151 | EFI_DHCP6_INFO_CALLBACK is provided by the consumer of the EFI DHCPv6 Protocol 152 | instance to intercept events that occurs in the DHCPv6 Information Request 153 | exchange process. 154 | 155 | @param This Pointer to the EFI_DHCP6_PROTOCOL instance that 156 | is used to configure this callback function. 157 | @param Context Pointer to the context that is initialized in 158 | the EFI_DHCP6_PROTOCOL.InfoRequest(). 159 | @param Packet Pointer to Reply packet that has been received. 160 | The EFI DHCPv6 Protocol instance is responsible 161 | for freeing the buffer. 162 | 163 | @retval EFI_SUCCESS The DNS information is got from the DHCP ACK. 164 | @retval EFI_DEVICE_ERROR Other errors as indicated. 165 | @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. 166 | **/ 167 | EFI_STATUS 168 | EFIAPI 169 | ParseDhcp6Ack ( 170 | IN EFI_DHCP6_PROTOCOL *This, 171 | IN VOID *Context, 172 | IN EFI_DHCP6_PACKET *Packet 173 | ) 174 | { 175 | EFI_STATUS Status; 176 | UINT32 OptionCount; 177 | EFI_DHCP6_PACKET_OPTION **OptionList; 178 | DNS6_SERVER_INFOR *DnsServerInfor; 179 | UINT32 ServerCount; 180 | EFI_IPv6_ADDRESS *ServerList; 181 | UINT32 Index; 182 | UINT32 Count; 183 | 184 | OptionCount = 0; 185 | ServerCount = 0; 186 | ServerList = NULL; 187 | 188 | Status = This->Parse (This, Packet, &OptionCount, NULL); 189 | if (Status != EFI_BUFFER_TOO_SMALL) { 190 | return EFI_DEVICE_ERROR; 191 | } 192 | 193 | OptionList = AllocateZeroPool (OptionCount * sizeof (EFI_DHCP6_PACKET_OPTION *)); 194 | if (OptionList == NULL) { 195 | return EFI_OUT_OF_RESOURCES; 196 | } 197 | 198 | Status = This->Parse (This, Packet, &OptionCount, OptionList); 199 | if (EFI_ERROR (Status)) { 200 | gBS->FreePool (OptionList); 201 | return EFI_DEVICE_ERROR; 202 | } 203 | 204 | DnsServerInfor = (DNS6_SERVER_INFOR *)Context; 205 | 206 | for (Index = 0; Index < OptionCount; Index++) { 207 | OptionList[Index]->OpCode = NTOHS (OptionList[Index]->OpCode); 208 | OptionList[Index]->OpLen = NTOHS (OptionList[Index]->OpLen); 209 | 210 | // 211 | // Get DNS server addresses from this reply packet. 212 | // 213 | if (OptionList[Index]->OpCode == DHCP6_TAG_DNS_SERVER) { 214 | if (((OptionList[Index]->OpLen & 0xf) != 0) || (OptionList[Index]->OpLen == 0)) { 215 | Status = EFI_DEVICE_ERROR; 216 | gBS->FreePool (OptionList); 217 | return Status; 218 | } 219 | 220 | ServerCount = OptionList[Index]->OpLen/16; 221 | ServerList = AllocatePool (ServerCount * sizeof (EFI_IPv6_ADDRESS)); 222 | if (ServerList == NULL) { 223 | gBS->FreePool (OptionList); 224 | return EFI_OUT_OF_RESOURCES; 225 | } 226 | 227 | for (Count = 0; Count < ServerCount; Count++) { 228 | CopyMem (ServerList + Count, &OptionList[Index]->Data[16 * Count], sizeof (EFI_IPv6_ADDRESS)); 229 | } 230 | 231 | *(DnsServerInfor->ServerCount) = ServerCount; 232 | DnsServerInfor->ServerList = ServerList; 233 | } 234 | } 235 | 236 | gBS->FreePool (OptionList); 237 | 238 | return Status; 239 | } 240 | 241 | /** 242 | Parse the DHCP ACK to get Dns4 server information. 243 | 244 | @param Instance The DNS instance. 245 | @param DnsServerCount Retrieved Dns4 server Ip count. 246 | @param DnsServerList Retrieved Dns4 server Ip list. 247 | 248 | @retval EFI_SUCCESS The Dns4 information is got from the DHCP ACK. 249 | @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. 250 | @retval EFI_NO_MEDIA There was a media error. 251 | @retval Others Other errors as indicated. 252 | 253 | **/ 254 | EFI_STATUS 255 | GetDns4ServerFromDhcp4 ( 256 | IN DNS_INSTANCE *Instance, 257 | OUT UINT32 *DnsServerCount, 258 | OUT EFI_IPv4_ADDRESS **DnsServerList 259 | ) 260 | { 261 | EFI_STATUS Status; 262 | EFI_HANDLE Image; 263 | EFI_HANDLE Controller; 264 | EFI_STATUS MediaStatus; 265 | EFI_HANDLE MnpChildHandle; 266 | EFI_MANAGED_NETWORK_PROTOCOL *Mnp; 267 | EFI_MANAGED_NETWORK_CONFIG_DATA MnpConfigData; 268 | EFI_HANDLE Dhcp4Handle; 269 | EFI_DHCP4_PROTOCOL *Dhcp4; 270 | EFI_IP4_CONFIG2_PROTOCOL *Ip4Config2; 271 | UINTN DataSize; 272 | VOID *Data; 273 | EFI_IP4_CONFIG2_INTERFACE_INFO *InterfaceInfo; 274 | EFI_DHCP4_PACKET SeedPacket; 275 | EFI_DHCP4_PACKET_OPTION *ParaList[2]; 276 | DNS4_SERVER_INFOR DnsServerInfor; 277 | 278 | EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN Token; 279 | BOOLEAN IsDone; 280 | UINTN Index; 281 | UINT32 Random; 282 | 283 | Image = Instance->Service->ImageHandle; 284 | Controller = Instance->Service->ControllerHandle; 285 | 286 | MnpChildHandle = NULL; 287 | Mnp = NULL; 288 | 289 | Dhcp4Handle = NULL; 290 | Dhcp4 = NULL; 291 | 292 | Ip4Config2 = NULL; 293 | DataSize = 0; 294 | Data = NULL; 295 | InterfaceInfo = NULL; 296 | 297 | Status = PseudoRandomU32 (&Random); 298 | if (EFI_ERROR (Status)) { 299 | DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status)); 300 | return Status; 301 | } 302 | 303 | ZeroMem ((UINT8 *)ParaList, sizeof (ParaList)); 304 | 305 | ZeroMem (&MnpConfigData, sizeof (EFI_MANAGED_NETWORK_CONFIG_DATA)); 306 | 307 | ZeroMem (&DnsServerInfor, sizeof (DNS4_SERVER_INFOR)); 308 | 309 | ZeroMem (&Token, sizeof (EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN)); 310 | 311 | DnsServerInfor.ServerCount = DnsServerCount; 312 | 313 | IsDone = FALSE; 314 | 315 | // 316 | // Check media. 317 | // 318 | MediaStatus = EFI_SUCCESS; 319 | NetLibDetectMediaWaitTimeout (Controller, DNS_CHECK_MEDIA_GET_DHCP_WAITING_TIME, &MediaStatus); 320 | if (MediaStatus != EFI_SUCCESS) { 321 | return EFI_NO_MEDIA; 322 | } 323 | 324 | // 325 | // Create a Mnp child instance, get the protocol and config for it. 326 | // 327 | Status = NetLibCreateServiceChild ( 328 | Controller, 329 | Image, 330 | &gEfiManagedNetworkServiceBindingProtocolGuid, 331 | &MnpChildHandle 332 | ); 333 | if (EFI_ERROR (Status)) { 334 | return Status; 335 | } 336 | 337 | Status = gBS->OpenProtocol ( 338 | MnpChildHandle, 339 | &gEfiManagedNetworkProtocolGuid, 340 | (VOID **)&Mnp, 341 | Image, 342 | Controller, 343 | EFI_OPEN_PROTOCOL_BY_DRIVER 344 | ); 345 | if (EFI_ERROR (Status)) { 346 | goto ON_EXIT; 347 | } 348 | 349 | MnpConfigData.ReceivedQueueTimeoutValue = 0; 350 | MnpConfigData.TransmitQueueTimeoutValue = 0; 351 | MnpConfigData.ProtocolTypeFilter = IP4_ETHER_PROTO; 352 | MnpConfigData.EnableUnicastReceive = TRUE; 353 | MnpConfigData.EnableMulticastReceive = TRUE; 354 | MnpConfigData.EnableBroadcastReceive = TRUE; 355 | MnpConfigData.EnablePromiscuousReceive = FALSE; 356 | MnpConfigData.FlushQueuesOnReset = TRUE; 357 | MnpConfigData.EnableReceiveTimestamps = FALSE; 358 | MnpConfigData.DisableBackgroundPolling = FALSE; 359 | 360 | Status = Mnp->Configure (Mnp, &MnpConfigData); 361 | if (EFI_ERROR (Status)) { 362 | goto ON_EXIT; 363 | } 364 | 365 | // 366 | // Create a DHCP4 child instance and get the protocol. 367 | // 368 | Status = NetLibCreateServiceChild ( 369 | Controller, 370 | Image, 371 | &gEfiDhcp4ServiceBindingProtocolGuid, 372 | &Dhcp4Handle 373 | ); 374 | if (EFI_ERROR (Status)) { 375 | goto ON_EXIT; 376 | } 377 | 378 | Status = gBS->OpenProtocol ( 379 | Dhcp4Handle, 380 | &gEfiDhcp4ProtocolGuid, 381 | (VOID **)&Dhcp4, 382 | Image, 383 | Controller, 384 | EFI_OPEN_PROTOCOL_BY_DRIVER 385 | ); 386 | if (EFI_ERROR (Status)) { 387 | goto ON_EXIT; 388 | } 389 | 390 | // 391 | // Get Ip4Config2 instance info. 392 | // 393 | Status = gBS->HandleProtocol (Controller, &gEfiIp4Config2ProtocolGuid, (VOID **)&Ip4Config2); 394 | if (EFI_ERROR (Status)) { 395 | goto ON_EXIT; 396 | } 397 | 398 | Status = Ip4Config2->GetData (Ip4Config2, Ip4Config2DataTypeInterfaceInfo, &DataSize, Data); 399 | if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) { 400 | goto ON_EXIT; 401 | } 402 | 403 | Data = AllocateZeroPool (DataSize); 404 | if (Data == NULL) { 405 | Status = EFI_OUT_OF_RESOURCES; 406 | goto ON_EXIT; 407 | } 408 | 409 | Status = Ip4Config2->GetData (Ip4Config2, Ip4Config2DataTypeInterfaceInfo, &DataSize, Data); 410 | if (EFI_ERROR (Status)) { 411 | goto ON_EXIT; 412 | } 413 | 414 | InterfaceInfo = (EFI_IP4_CONFIG2_INTERFACE_INFO *)Data; 415 | 416 | // 417 | // Build required Token. 418 | // 419 | Status = gBS->CreateEvent ( 420 | EVT_NOTIFY_SIGNAL, 421 | TPL_NOTIFY, 422 | DhcpCommonNotify, 423 | &IsDone, 424 | &Token.CompletionEvent 425 | ); 426 | if (EFI_ERROR (Status)) { 427 | goto ON_EXIT; 428 | } 429 | 430 | SetMem (&Token.RemoteAddress, sizeof (EFI_IPv4_ADDRESS), 0xff); 431 | 432 | Token.RemotePort = 67; 433 | 434 | Token.ListenPointCount = 1; 435 | 436 | Token.ListenPoints = AllocateZeroPool (Token.ListenPointCount * sizeof (EFI_DHCP4_LISTEN_POINT)); 437 | if (Token.ListenPoints == NULL) { 438 | Status = EFI_OUT_OF_RESOURCES; 439 | goto ON_EXIT; 440 | } 441 | 442 | if (Instance->Dns4CfgData.UseDefaultSetting) { 443 | CopyMem (&(Token.ListenPoints[0].ListenAddress), &(InterfaceInfo->StationAddress), sizeof (EFI_IPv4_ADDRESS)); 444 | CopyMem (&(Token.ListenPoints[0].SubnetMask), &(InterfaceInfo->SubnetMask), sizeof (EFI_IPv4_ADDRESS)); 445 | } else { 446 | CopyMem (&(Token.ListenPoints[0].ListenAddress), &(Instance->Dns4CfgData.StationIp), sizeof (EFI_IPv4_ADDRESS)); 447 | CopyMem (&(Token.ListenPoints[0].SubnetMask), &(Instance->Dns4CfgData.SubnetMask), sizeof (EFI_IPv4_ADDRESS)); 448 | } 449 | 450 | Token.ListenPoints[0].ListenPort = 68; 451 | 452 | Token.TimeoutValue = DNS_TIME_TO_GETMAP; 453 | 454 | DnsInitSeedPacket (&SeedPacket, InterfaceInfo); 455 | 456 | ParaList[0] = AllocateZeroPool (sizeof (EFI_DHCP4_PACKET_OPTION)); 457 | if (ParaList[0] == NULL) { 458 | Status = EFI_OUT_OF_RESOURCES; 459 | goto ON_EXIT; 460 | } 461 | 462 | ParaList[0]->OpCode = DHCP4_TAG_TYPE; 463 | ParaList[0]->Length = 1; 464 | ParaList[0]->Data[0] = DHCP4_MSG_REQUEST; 465 | 466 | ParaList[1] = AllocateZeroPool (sizeof (EFI_DHCP4_PACKET_OPTION)); 467 | if (ParaList[1] == NULL) { 468 | Status = EFI_OUT_OF_RESOURCES; 469 | goto ON_EXIT; 470 | } 471 | 472 | ParaList[1]->OpCode = DHCP4_TAG_PARA_LIST; 473 | ParaList[1]->Length = 1; 474 | ParaList[1]->Data[0] = DHCP4_TAG_DNS_SERVER; 475 | 476 | Status = Dhcp4->Build (Dhcp4, &SeedPacket, 0, NULL, 2, ParaList, &Token.Packet); 477 | 478 | Token.Packet->Dhcp4.Header.Xid = Random; 479 | 480 | Token.Packet->Dhcp4.Header.Reserved = HTONS ((UINT16)0x8000); 481 | 482 | if (Instance->Dns4CfgData.UseDefaultSetting) { 483 | CopyMem (&(Token.Packet->Dhcp4.Header.ClientAddr), &(InterfaceInfo->StationAddress), sizeof (EFI_IPv4_ADDRESS)); 484 | } else { 485 | CopyMem (&(Token.Packet->Dhcp4.Header.ClientAddr), &(Instance->Dns4CfgData.StationIp), sizeof (EFI_IPv4_ADDRESS)); 486 | } 487 | 488 | CopyMem (Token.Packet->Dhcp4.Header.ClientHwAddr, &(InterfaceInfo->HwAddress), InterfaceInfo->HwAddressSize); 489 | 490 | Token.Packet->Dhcp4.Header.HwAddrLen = (UINT8)(InterfaceInfo->HwAddressSize); 491 | 492 | // 493 | // TransmitReceive Token 494 | // 495 | Status = Dhcp4->TransmitReceive (Dhcp4, &Token); 496 | if (EFI_ERROR (Status)) { 497 | goto ON_EXIT; 498 | } 499 | 500 | // 501 | // Poll the packet 502 | // 503 | do { 504 | Status = Mnp->Poll (Mnp); 505 | } while (!IsDone); 506 | 507 | // 508 | // Parse the ACK to get required information if received done. 509 | // 510 | if (IsDone && !EFI_ERROR (Token.Status)) { 511 | for (Index = 0; Index < Token.ResponseCount; Index++) { 512 | Status = ParseDhcp4Ack (Dhcp4, &Token.ResponseList[Index], &DnsServerInfor); 513 | if (!EFI_ERROR (Status)) { 514 | break; 515 | } 516 | } 517 | 518 | *DnsServerList = DnsServerInfor.ServerList; 519 | } else { 520 | Status = Token.Status; 521 | } 522 | 523 | ON_EXIT: 524 | 525 | if (Data != NULL) { 526 | FreePool (Data); 527 | } 528 | 529 | for (Index = 0; Index < 2; Index++) { 530 | if (ParaList[Index] != NULL) { 531 | FreePool (ParaList[Index]); 532 | } 533 | } 534 | 535 | if (Token.ListenPoints) { 536 | FreePool (Token.ListenPoints); 537 | } 538 | 539 | if (Token.Packet) { 540 | FreePool (Token.Packet); 541 | } 542 | 543 | if (Token.ResponseList != NULL) { 544 | FreePool (Token.ResponseList); 545 | } 546 | 547 | if (Token.CompletionEvent != NULL) { 548 | gBS->CloseEvent (Token.CompletionEvent); 549 | } 550 | 551 | if (Dhcp4 != NULL) { 552 | Dhcp4->Stop (Dhcp4); 553 | Dhcp4->Configure (Dhcp4, NULL); 554 | 555 | gBS->CloseProtocol ( 556 | Dhcp4Handle, 557 | &gEfiDhcp4ProtocolGuid, 558 | Image, 559 | Controller 560 | ); 561 | } 562 | 563 | if (Dhcp4Handle != NULL) { 564 | NetLibDestroyServiceChild ( 565 | Controller, 566 | Image, 567 | &gEfiDhcp4ServiceBindingProtocolGuid, 568 | Dhcp4Handle 569 | ); 570 | } 571 | 572 | if (Mnp != NULL) { 573 | Mnp->Configure (Mnp, NULL); 574 | 575 | gBS->CloseProtocol ( 576 | MnpChildHandle, 577 | &gEfiManagedNetworkProtocolGuid, 578 | Image, 579 | Controller 580 | ); 581 | } 582 | 583 | NetLibDestroyServiceChild ( 584 | Controller, 585 | Image, 586 | &gEfiManagedNetworkServiceBindingProtocolGuid, 587 | MnpChildHandle 588 | ); 589 | 590 | return Status; 591 | } 592 | 593 | /** 594 | Parse the DHCP ACK to get Dns6 server information. 595 | 596 | @param Image The handle of the driver image. 597 | @param Controller The handle of the controller. 598 | @param DnsServerCount Retrieved Dns6 server Ip count. 599 | @param DnsServerList Retrieved Dns6 server Ip list. 600 | 601 | @retval EFI_SUCCESS The Dns6 information is got from the DHCP ACK. 602 | @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. 603 | @retval EFI_NO_MEDIA There was a media error. 604 | @retval Others Other errors as indicated. 605 | 606 | **/ 607 | EFI_STATUS 608 | GetDns6ServerFromDhcp6 ( 609 | IN EFI_HANDLE Image, 610 | IN EFI_HANDLE Controller, 611 | OUT UINT32 *DnsServerCount, 612 | OUT EFI_IPv6_ADDRESS **DnsServerList 613 | ) 614 | { 615 | EFI_HANDLE Dhcp6Handle; 616 | EFI_DHCP6_PROTOCOL *Dhcp6; 617 | EFI_STATUS Status; 618 | EFI_STATUS TimerStatus; 619 | EFI_DHCP6_PACKET_OPTION *Oro; 620 | EFI_DHCP6_RETRANSMISSION InfoReqReXmit; 621 | EFI_EVENT Timer; 622 | EFI_STATUS MediaStatus; 623 | DNS6_SERVER_INFOR DnsServerInfor; 624 | 625 | Dhcp6Handle = NULL; 626 | Dhcp6 = NULL; 627 | Oro = NULL; 628 | Timer = NULL; 629 | 630 | ZeroMem (&DnsServerInfor, sizeof (DNS6_SERVER_INFOR)); 631 | 632 | DnsServerInfor.ServerCount = DnsServerCount; 633 | 634 | // 635 | // Check media status before doing DHCP. 636 | // 637 | MediaStatus = EFI_SUCCESS; 638 | NetLibDetectMediaWaitTimeout (Controller, DNS_CHECK_MEDIA_GET_DHCP_WAITING_TIME, &MediaStatus); 639 | if (MediaStatus != EFI_SUCCESS) { 640 | return EFI_NO_MEDIA; 641 | } 642 | 643 | // 644 | // Create a DHCP6 child instance and get the protocol. 645 | // 646 | Status = NetLibCreateServiceChild ( 647 | Controller, 648 | Image, 649 | &gEfiDhcp6ServiceBindingProtocolGuid, 650 | &Dhcp6Handle 651 | ); 652 | if (EFI_ERROR (Status)) { 653 | return Status; 654 | } 655 | 656 | Status = gBS->OpenProtocol ( 657 | Dhcp6Handle, 658 | &gEfiDhcp6ProtocolGuid, 659 | (VOID **)&Dhcp6, 660 | Image, 661 | Controller, 662 | EFI_OPEN_PROTOCOL_BY_DRIVER 663 | ); 664 | if (EFI_ERROR (Status)) { 665 | goto ON_EXIT; 666 | } 667 | 668 | Oro = AllocateZeroPool (sizeof (EFI_DHCP6_PACKET_OPTION) + 1); 669 | if (Oro == NULL) { 670 | Status = EFI_OUT_OF_RESOURCES; 671 | goto ON_EXIT; 672 | } 673 | 674 | // 675 | // Ask the server to reply with DNS options. 676 | // All members in EFI_DHCP6_PACKET_OPTION are in network order. 677 | // 678 | Oro->OpCode = HTONS (DHCP6_TAG_DNS_REQUEST); 679 | Oro->OpLen = HTONS (2); 680 | Oro->Data[1] = DHCP6_TAG_DNS_SERVER; 681 | 682 | InfoReqReXmit.Irt = 4; 683 | InfoReqReXmit.Mrc = 1; 684 | InfoReqReXmit.Mrt = 10; 685 | InfoReqReXmit.Mrd = 30; 686 | 687 | Status = Dhcp6->InfoRequest ( 688 | Dhcp6, 689 | TRUE, 690 | Oro, 691 | 0, 692 | NULL, 693 | &InfoReqReXmit, 694 | NULL, 695 | ParseDhcp6Ack, 696 | &DnsServerInfor 697 | ); 698 | if (Status == EFI_NO_MAPPING) { 699 | Status = gBS->CreateEvent (EVT_TIMER, TPL_CALLBACK, NULL, NULL, &Timer); 700 | if (EFI_ERROR (Status)) { 701 | goto ON_EXIT; 702 | } 703 | 704 | Status = gBS->SetTimer ( 705 | Timer, 706 | TimerRelative, 707 | DNS_TIME_TO_GETMAP * TICKS_PER_SECOND 708 | ); 709 | 710 | if (EFI_ERROR (Status)) { 711 | goto ON_EXIT; 712 | } 713 | 714 | do { 715 | TimerStatus = gBS->CheckEvent (Timer); 716 | if (!EFI_ERROR (TimerStatus)) { 717 | Status = Dhcp6->InfoRequest ( 718 | Dhcp6, 719 | TRUE, 720 | Oro, 721 | 0, 722 | NULL, 723 | &InfoReqReXmit, 724 | NULL, 725 | ParseDhcp6Ack, 726 | &DnsServerInfor 727 | ); 728 | } 729 | } while (TimerStatus == EFI_NOT_READY); 730 | } 731 | 732 | *DnsServerList = DnsServerInfor.ServerList; 733 | 734 | ON_EXIT: 735 | 736 | if (Oro != NULL) { 737 | FreePool (Oro); 738 | } 739 | 740 | if (Timer != NULL) { 741 | gBS->CloseEvent (Timer); 742 | } 743 | 744 | if (Dhcp6 != NULL) { 745 | gBS->CloseProtocol ( 746 | Dhcp6Handle, 747 | &gEfiDhcp6ProtocolGuid, 748 | Image, 749 | Controller 750 | ); 751 | } 752 | 753 | NetLibDestroyServiceChild ( 754 | Controller, 755 | Image, 756 | &gEfiDhcp6ServiceBindingProtocolGuid, 757 | Dhcp6Handle 758 | ); 759 | 760 | return Status; 761 | } 762 | -------------------------------------------------------------------------------- /Edk2_Patch/NetworkPkg/IScsiDxe/IScsiCHAP.c: -------------------------------------------------------------------------------- 1 | /** @file 2 | This file is for Challenge-Handshake Authentication Protocol (CHAP) 3 | Configuration. 4 | 5 | Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.
6 | Copyright (c) Microsoft Corporation 7 | SPDX-License-Identifier: BSD-2-Clause-Patent 8 | 9 | **/ 10 | 11 | #include "IScsiImpl.h" 12 | 13 | // 14 | // Supported CHAP hash algorithms, mapped to sets of BaseCryptLib APIs and 15 | // macros. CHAP_HASH structures at lower subscripts in the array are preferred 16 | // by the initiator. 17 | // 18 | STATIC CONST CHAP_HASH mChapHash[] = { 19 | { 20 | ISCSI_CHAP_ALGORITHM_SHA256, 21 | SHA256_DIGEST_SIZE, 22 | Sha256GetContextSize, 23 | Sha256Init, 24 | Sha256Update, 25 | Sha256Final 26 | }, 27 | #ifdef ENABLE_MD5_DEPRECATED_INTERFACES 28 | // 29 | // Keep the deprecated MD5 entry at the end of the array (making MD5 the 30 | // least preferred choice of the initiator). 31 | // 32 | { 33 | ISCSI_CHAP_ALGORITHM_MD5, 34 | MD5_DIGEST_SIZE, 35 | Md5GetContextSize, 36 | Md5Init, 37 | Md5Update, 38 | Md5Final 39 | }, 40 | #endif // ENABLE_MD5_DEPRECATED_INTERFACES 41 | }; 42 | 43 | // 44 | // Ordered list of mChapHash[*].Algorithm values. It is formatted for the 45 | // CHAP_A= value string, by the IScsiCHAPInitHashList() function. It 46 | // is sent by the initiator in ISCSI_CHAP_STEP_ONE. 47 | // 48 | STATIC CHAR8 mChapHashListString[ 49 | 3 + // UINT8 identifier in 50 | // decimal 51 | (1 + 3) * (ARRAY_SIZE (mChapHash) - 1) + // comma prepended for 52 | // entries after the 53 | // first 54 | 1 + // extra character for 55 | // AsciiSPrint() 56 | // truncation check 57 | 1 // terminating NUL 58 | ]; 59 | 60 | /** 61 | Initiator calculates its own expected hash value. 62 | 63 | @param[in] ChapIdentifier iSCSI CHAP identifier sent by authenticator. 64 | @param[in] ChapSecret iSCSI CHAP secret of the authenticator. 65 | @param[in] SecretLength The length of iSCSI CHAP secret. 66 | @param[in] ChapChallenge The challenge message sent by authenticator. 67 | @param[in] ChallengeLength The length of iSCSI CHAP challenge message. 68 | @param[in] Hash Pointer to the CHAP_HASH structure that 69 | determines the hashing algorithm to use. The 70 | caller is responsible for making Hash point 71 | to an "mChapHash" element. 72 | @param[out] ChapResponse The calculation of the expected hash value. 73 | 74 | @retval EFI_SUCCESS The expected hash value was calculatedly 75 | successfully. 76 | @retval EFI_PROTOCOL_ERROR The length of the secret should be at least 77 | the length of the hash value for the hashing 78 | algorithm chosen. 79 | @retval EFI_PROTOCOL_ERROR Hash operation fails. 80 | @retval EFI_OUT_OF_RESOURCES Failure to allocate resource to complete 81 | hashing. 82 | 83 | **/ 84 | EFI_STATUS 85 | IScsiCHAPCalculateResponse ( 86 | IN UINT32 ChapIdentifier, 87 | IN CHAR8 *ChapSecret, 88 | IN UINT32 SecretLength, 89 | IN UINT8 *ChapChallenge, 90 | IN UINT32 ChallengeLength, 91 | IN CONST CHAP_HASH *Hash, 92 | OUT UINT8 *ChapResponse 93 | ) 94 | { 95 | UINTN ContextSize; 96 | VOID *Ctx; 97 | CHAR8 IdByte[1]; 98 | EFI_STATUS Status; 99 | 100 | if (SecretLength < ISCSI_CHAP_SECRET_MIN_LEN) { 101 | return EFI_PROTOCOL_ERROR; 102 | } 103 | 104 | ASSERT (Hash != NULL); 105 | 106 | ContextSize = Hash->GetContextSize (); 107 | Ctx = AllocatePool (ContextSize); 108 | if (Ctx == NULL) { 109 | return EFI_OUT_OF_RESOURCES; 110 | } 111 | 112 | Status = EFI_PROTOCOL_ERROR; 113 | 114 | if (!Hash->Init (Ctx)) { 115 | goto Exit; 116 | } 117 | 118 | // 119 | // Hash Identifier - Only calculate 1 byte data (RFC1994) 120 | // 121 | IdByte[0] = (CHAR8)ChapIdentifier; 122 | if (!Hash->Update (Ctx, IdByte, 1)) { 123 | goto Exit; 124 | } 125 | 126 | // 127 | // Hash Secret 128 | // 129 | if (!Hash->Update (Ctx, ChapSecret, SecretLength)) { 130 | goto Exit; 131 | } 132 | 133 | // 134 | // Hash Challenge received from Target 135 | // 136 | if (!Hash->Update (Ctx, ChapChallenge, ChallengeLength)) { 137 | goto Exit; 138 | } 139 | 140 | if (Hash->Final (Ctx, ChapResponse)) { 141 | Status = EFI_SUCCESS; 142 | } 143 | 144 | Exit: 145 | FreePool (Ctx); 146 | return Status; 147 | } 148 | 149 | /** 150 | The initiator checks the CHAP response replied by target against its own 151 | calculation of the expected hash value. 152 | 153 | @param[in] AuthData iSCSI CHAP authentication data. 154 | @param[in] TargetResponse The response from target. 155 | 156 | @retval EFI_SUCCESS The response from target passed 157 | authentication. 158 | @retval EFI_SECURITY_VIOLATION The response from target was not expected 159 | value. 160 | @retval Others Other errors as indicated. 161 | 162 | **/ 163 | EFI_STATUS 164 | IScsiCHAPAuthTarget ( 165 | IN ISCSI_CHAP_AUTH_DATA *AuthData, 166 | IN UINT8 *TargetResponse 167 | ) 168 | { 169 | EFI_STATUS Status; 170 | UINT32 SecretSize; 171 | UINT8 VerifyRsp[ISCSI_CHAP_MAX_DIGEST_SIZE]; 172 | INTN Mismatch; 173 | 174 | Status = EFI_SUCCESS; 175 | 176 | SecretSize = (UINT32)AsciiStrLen (AuthData->AuthConfig->ReverseCHAPSecret); 177 | 178 | ASSERT (AuthData->Hash != NULL); 179 | 180 | Status = IScsiCHAPCalculateResponse ( 181 | AuthData->OutIdentifier, 182 | AuthData->AuthConfig->ReverseCHAPSecret, 183 | SecretSize, 184 | AuthData->OutChallenge, 185 | AuthData->Hash->DigestSize, // ChallengeLength 186 | AuthData->Hash, 187 | VerifyRsp 188 | ); 189 | 190 | Mismatch = CompareMem ( 191 | VerifyRsp, 192 | TargetResponse, 193 | AuthData->Hash->DigestSize 194 | ); 195 | if (Mismatch != 0) { 196 | Status = EFI_SECURITY_VIOLATION; 197 | } 198 | 199 | return Status; 200 | } 201 | 202 | /** 203 | This function checks the received iSCSI Login Response during the security 204 | negotiation stage. 205 | 206 | @param[in] Conn The iSCSI connection. 207 | 208 | @retval EFI_SUCCESS The Login Response passed the CHAP validation. 209 | @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. 210 | @retval EFI_PROTOCOL_ERROR Some kind of protocol error occurred. 211 | @retval Others Other errors as indicated. 212 | 213 | **/ 214 | EFI_STATUS 215 | IScsiCHAPOnRspReceived ( 216 | IN ISCSI_CONNECTION *Conn 217 | ) 218 | { 219 | EFI_STATUS Status; 220 | ISCSI_SESSION *Session; 221 | ISCSI_CHAP_AUTH_DATA *AuthData; 222 | CHAR8 *Value; 223 | UINT8 *Data; 224 | UINT32 Len; 225 | LIST_ENTRY *KeyValueList; 226 | UINTN Algorithm; 227 | CHAR8 *Identifier; 228 | CHAR8 *Challenge; 229 | CHAR8 *Name; 230 | CHAR8 *Response; 231 | UINT8 TargetRsp[ISCSI_CHAP_MAX_DIGEST_SIZE]; 232 | UINT32 RspLen; 233 | UINTN Result; 234 | UINTN HashIndex; 235 | 236 | ASSERT (Conn->CurrentStage == ISCSI_SECURITY_NEGOTIATION); 237 | ASSERT (Conn->RspQue.BufNum != 0); 238 | 239 | Session = Conn->Session; 240 | AuthData = &Session->AuthData.CHAP; 241 | Len = Conn->RspQue.BufSize; 242 | Data = AllocateZeroPool (Len); 243 | if (Data == NULL) { 244 | return EFI_OUT_OF_RESOURCES; 245 | } 246 | 247 | // 248 | // Copy the data in case the data spans over multiple PDUs. 249 | // 250 | NetbufQueCopy (&Conn->RspQue, 0, Len, Data); 251 | 252 | // 253 | // Build the key-value list from the data segment of the Login Response. 254 | // 255 | KeyValueList = IScsiBuildKeyValueList ((CHAR8 *)Data, Len); 256 | if (KeyValueList == NULL) { 257 | Status = EFI_OUT_OF_RESOURCES; 258 | goto ON_EXIT; 259 | } 260 | 261 | Status = EFI_PROTOCOL_ERROR; 262 | 263 | switch (Conn->AuthStep) { 264 | case ISCSI_AUTH_INITIAL: 265 | // 266 | // The first Login Response. 267 | // 268 | Value = IScsiGetValueByKeyFromList ( 269 | KeyValueList, 270 | ISCSI_KEY_TARGET_PORTAL_GROUP_TAG 271 | ); 272 | if (Value == NULL) { 273 | goto ON_EXIT; 274 | } 275 | 276 | Result = IScsiNetNtoi (Value); 277 | if (Result > 0xFFFF) { 278 | goto ON_EXIT; 279 | } 280 | 281 | Session->TargetPortalGroupTag = (UINT16)Result; 282 | 283 | Value = IScsiGetValueByKeyFromList ( 284 | KeyValueList, 285 | ISCSI_KEY_AUTH_METHOD 286 | ); 287 | if (Value == NULL) { 288 | goto ON_EXIT; 289 | } 290 | 291 | // 292 | // Initiator mandates CHAP authentication but target replies without 293 | // "CHAP", or initiator suggets "None" but target replies with some kind of 294 | // auth method. 295 | // 296 | if (Session->AuthType == ISCSI_AUTH_TYPE_NONE) { 297 | if (AsciiStrCmp (Value, ISCSI_KEY_VALUE_NONE) != 0) { 298 | goto ON_EXIT; 299 | } 300 | } else if (Session->AuthType == ISCSI_AUTH_TYPE_CHAP) { 301 | if (AsciiStrCmp (Value, ISCSI_AUTH_METHOD_CHAP) != 0) { 302 | goto ON_EXIT; 303 | } 304 | } else { 305 | goto ON_EXIT; 306 | } 307 | 308 | // 309 | // Transit to CHAP step one. 310 | // 311 | Conn->AuthStep = ISCSI_CHAP_STEP_ONE; 312 | Status = EFI_SUCCESS; 313 | break; 314 | 315 | case ISCSI_CHAP_STEP_TWO: 316 | // 317 | // The Target replies with CHAP_A= CHAP_I= CHAP_C= 318 | // 319 | Value = IScsiGetValueByKeyFromList ( 320 | KeyValueList, 321 | ISCSI_KEY_CHAP_ALGORITHM 322 | ); 323 | if (Value == NULL) { 324 | goto ON_EXIT; 325 | } 326 | 327 | Algorithm = IScsiNetNtoi (Value); 328 | for (HashIndex = 0; HashIndex < ARRAY_SIZE (mChapHash); HashIndex++) { 329 | if (Algorithm == mChapHash[HashIndex].Algorithm) { 330 | break; 331 | } 332 | } 333 | 334 | if (HashIndex == ARRAY_SIZE (mChapHash)) { 335 | // 336 | // Unsupported algorithm is chosen by target. 337 | // 338 | goto ON_EXIT; 339 | } 340 | 341 | // 342 | // Remember the target's chosen hash algorithm. 343 | // 344 | ASSERT (AuthData->Hash == NULL); 345 | AuthData->Hash = &mChapHash[HashIndex]; 346 | 347 | Identifier = IScsiGetValueByKeyFromList ( 348 | KeyValueList, 349 | ISCSI_KEY_CHAP_IDENTIFIER 350 | ); 351 | if (Identifier == NULL) { 352 | goto ON_EXIT; 353 | } 354 | 355 | Challenge = IScsiGetValueByKeyFromList ( 356 | KeyValueList, 357 | ISCSI_KEY_CHAP_CHALLENGE 358 | ); 359 | if (Challenge == NULL) { 360 | goto ON_EXIT; 361 | } 362 | 363 | // 364 | // Process the CHAP identifier and CHAP Challenge from Target. 365 | // Calculate Response value. 366 | // 367 | Result = IScsiNetNtoi (Identifier); 368 | if (Result > 0xFF) { 369 | goto ON_EXIT; 370 | } 371 | 372 | AuthData->InIdentifier = (UINT32)Result; 373 | AuthData->InChallengeLength = (UINT32)sizeof (AuthData->InChallenge); 374 | Status = IScsiHexToBin ( 375 | (UINT8 *)AuthData->InChallenge, 376 | &AuthData->InChallengeLength, 377 | Challenge 378 | ); 379 | if (EFI_ERROR (Status)) { 380 | Status = EFI_PROTOCOL_ERROR; 381 | goto ON_EXIT; 382 | } 383 | 384 | Status = IScsiCHAPCalculateResponse ( 385 | AuthData->InIdentifier, 386 | AuthData->AuthConfig->CHAPSecret, 387 | (UINT32)AsciiStrLen (AuthData->AuthConfig->CHAPSecret), 388 | AuthData->InChallenge, 389 | AuthData->InChallengeLength, 390 | AuthData->Hash, 391 | AuthData->CHAPResponse 392 | ); 393 | 394 | // 395 | // Transit to next step. 396 | // 397 | Conn->AuthStep = ISCSI_CHAP_STEP_THREE; 398 | break; 399 | 400 | case ISCSI_CHAP_STEP_THREE: 401 | // 402 | // One way CHAP authentication and the target would like to 403 | // authenticate us. 404 | // 405 | Status = EFI_SUCCESS; 406 | break; 407 | 408 | case ISCSI_CHAP_STEP_FOUR: 409 | ASSERT (AuthData->AuthConfig->CHAPType == ISCSI_CHAP_MUTUAL); 410 | // 411 | // The forth step, CHAP_N= CHAP_R= is received from Target. 412 | // 413 | Name = IScsiGetValueByKeyFromList (KeyValueList, ISCSI_KEY_CHAP_NAME); 414 | if (Name == NULL) { 415 | goto ON_EXIT; 416 | } 417 | 418 | Response = IScsiGetValueByKeyFromList ( 419 | KeyValueList, 420 | ISCSI_KEY_CHAP_RESPONSE 421 | ); 422 | if (Response == NULL) { 423 | goto ON_EXIT; 424 | } 425 | 426 | ASSERT (AuthData->Hash != NULL); 427 | RspLen = AuthData->Hash->DigestSize; 428 | Status = IScsiHexToBin (TargetRsp, &RspLen, Response); 429 | if (EFI_ERROR (Status) || (RspLen != AuthData->Hash->DigestSize)) { 430 | Status = EFI_PROTOCOL_ERROR; 431 | goto ON_EXIT; 432 | } 433 | 434 | // 435 | // Check the CHAP Name and Response replied by Target. 436 | // 437 | Status = IScsiCHAPAuthTarget (AuthData, TargetRsp); 438 | break; 439 | 440 | default: 441 | break; 442 | } 443 | 444 | ON_EXIT: 445 | 446 | if (KeyValueList != NULL) { 447 | IScsiFreeKeyValueList (KeyValueList); 448 | } 449 | 450 | FreePool (Data); 451 | 452 | return Status; 453 | } 454 | 455 | /** 456 | This function fills the CHAP authentication information into the login PDU 457 | during the security negotiation stage in the iSCSI connection login. 458 | 459 | @param[in] Conn The iSCSI connection. 460 | @param[in, out] Pdu The PDU to send out. 461 | 462 | @retval EFI_SUCCESS All check passed and the phase-related CHAP 463 | authentication info is filled into the iSCSI 464 | PDU. 465 | @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. 466 | @retval EFI_PROTOCOL_ERROR Some kind of protocol error occurred. 467 | 468 | **/ 469 | EFI_STATUS 470 | IScsiCHAPToSendReq ( 471 | IN ISCSI_CONNECTION *Conn, 472 | IN OUT NET_BUF *Pdu 473 | ) 474 | { 475 | EFI_STATUS Status; 476 | ISCSI_SESSION *Session; 477 | ISCSI_LOGIN_REQUEST *LoginReq; 478 | ISCSI_CHAP_AUTH_DATA *AuthData; 479 | CHAR8 *Value; 480 | CHAR8 ValueStr[256]; 481 | CHAR8 *Response; 482 | UINT32 RspLen; 483 | CHAR8 *Challenge; 484 | UINT32 ChallengeLen; 485 | EFI_STATUS BinToHexStatus; 486 | 487 | ASSERT (Conn->CurrentStage == ISCSI_SECURITY_NEGOTIATION); 488 | 489 | Session = Conn->Session; 490 | AuthData = &Session->AuthData.CHAP; 491 | LoginReq = (ISCSI_LOGIN_REQUEST *)NetbufGetByte (Pdu, 0, 0); 492 | if (LoginReq == NULL) { 493 | return EFI_PROTOCOL_ERROR; 494 | } 495 | 496 | Status = EFI_SUCCESS; 497 | 498 | RspLen = 2 * ISCSI_CHAP_MAX_DIGEST_SIZE + 3; 499 | Response = AllocateZeroPool (RspLen); 500 | if (Response == NULL) { 501 | return EFI_OUT_OF_RESOURCES; 502 | } 503 | 504 | ChallengeLen = 2 * ISCSI_CHAP_MAX_DIGEST_SIZE + 3; 505 | Challenge = AllocateZeroPool (ChallengeLen); 506 | if (Challenge == NULL) { 507 | FreePool (Response); 508 | return EFI_OUT_OF_RESOURCES; 509 | } 510 | 511 | switch (Conn->AuthStep) { 512 | case ISCSI_AUTH_INITIAL: 513 | // 514 | // It's the initial Login Request. Fill in the key=value pairs mandatory 515 | // for the initial Login Request. 516 | // 517 | IScsiAddKeyValuePair ( 518 | Pdu, 519 | ISCSI_KEY_INITIATOR_NAME, 520 | mPrivate->InitiatorName 521 | ); 522 | IScsiAddKeyValuePair (Pdu, ISCSI_KEY_SESSION_TYPE, "Normal"); 523 | IScsiAddKeyValuePair ( 524 | Pdu, 525 | ISCSI_KEY_TARGET_NAME, 526 | Session->ConfigData->SessionConfigData.TargetName 527 | ); 528 | 529 | if (Session->AuthType == ISCSI_AUTH_TYPE_NONE) { 530 | Value = ISCSI_KEY_VALUE_NONE; 531 | ISCSI_SET_FLAG (LoginReq, ISCSI_LOGIN_REQ_PDU_FLAG_TRANSIT); 532 | } else { 533 | Value = ISCSI_AUTH_METHOD_CHAP; 534 | } 535 | 536 | IScsiAddKeyValuePair (Pdu, ISCSI_KEY_AUTH_METHOD, Value); 537 | 538 | break; 539 | 540 | case ISCSI_CHAP_STEP_ONE: 541 | // 542 | // First step, send the Login Request with CHAP_A= key-value 543 | // pair. 544 | // 545 | IScsiAddKeyValuePair (Pdu, ISCSI_KEY_CHAP_ALGORITHM, mChapHashListString); 546 | 547 | Conn->AuthStep = ISCSI_CHAP_STEP_TWO; 548 | break; 549 | 550 | case ISCSI_CHAP_STEP_THREE: 551 | // 552 | // Third step, send the Login Request with CHAP_N= CHAP_R= or 553 | // CHAP_N= CHAP_R= CHAP_I= CHAP_C= if target authentication is 554 | // required too. 555 | // 556 | // CHAP_N= 557 | // 558 | IScsiAddKeyValuePair ( 559 | Pdu, 560 | ISCSI_KEY_CHAP_NAME, 561 | (CHAR8 *)&AuthData->AuthConfig->CHAPName 562 | ); 563 | // 564 | // CHAP_R= 565 | // 566 | ASSERT (AuthData->Hash != NULL); 567 | BinToHexStatus = IScsiBinToHex ( 568 | (UINT8 *)AuthData->CHAPResponse, 569 | AuthData->Hash->DigestSize, 570 | Response, 571 | &RspLen 572 | ); 573 | ASSERT_EFI_ERROR (BinToHexStatus); 574 | IScsiAddKeyValuePair (Pdu, ISCSI_KEY_CHAP_RESPONSE, Response); 575 | 576 | if (AuthData->AuthConfig->CHAPType == ISCSI_CHAP_MUTUAL) { 577 | // 578 | // CHAP_I= 579 | // 580 | Status = IScsiGenRandom ((UINT8 *)&AuthData->OutIdentifier, 1); 581 | if (EFI_ERROR (Status)) { 582 | break; 583 | } 584 | 585 | AsciiSPrint (ValueStr, sizeof (ValueStr), "%d", AuthData->OutIdentifier); 586 | IScsiAddKeyValuePair (Pdu, ISCSI_KEY_CHAP_IDENTIFIER, ValueStr); 587 | // 588 | // CHAP_C= 589 | // 590 | Status = IScsiGenRandom ( 591 | (UINT8 *)AuthData->OutChallenge, 592 | AuthData->Hash->DigestSize 593 | ); 594 | if (EFI_ERROR (Status)) { 595 | break; 596 | } 597 | 598 | BinToHexStatus = IScsiBinToHex ( 599 | (UINT8 *)AuthData->OutChallenge, 600 | AuthData->Hash->DigestSize, 601 | Challenge, 602 | &ChallengeLen 603 | ); 604 | ASSERT_EFI_ERROR (BinToHexStatus); 605 | IScsiAddKeyValuePair (Pdu, ISCSI_KEY_CHAP_CHALLENGE, Challenge); 606 | 607 | Conn->AuthStep = ISCSI_CHAP_STEP_FOUR; 608 | } 609 | 610 | // 611 | // Set the stage transition flag. 612 | // 613 | ISCSI_SET_FLAG (LoginReq, ISCSI_LOGIN_REQ_PDU_FLAG_TRANSIT); 614 | break; 615 | 616 | default: 617 | Status = EFI_PROTOCOL_ERROR; 618 | break; 619 | } 620 | 621 | FreePool (Response); 622 | FreePool (Challenge); 623 | 624 | return Status; 625 | } 626 | 627 | /** 628 | Initialize the CHAP_A= *value* string for the entire driver, to be 629 | sent by the initiator in ISCSI_CHAP_STEP_ONE. 630 | 631 | This function sanity-checks the internal table of supported CHAP hashing 632 | algorithms, as well. 633 | **/ 634 | VOID 635 | IScsiCHAPInitHashList ( 636 | VOID 637 | ) 638 | { 639 | CHAR8 *Position; 640 | UINTN Left; 641 | UINTN HashIndex; 642 | CONST CHAP_HASH *Hash; 643 | UINTN Printed; 644 | 645 | Position = mChapHashListString; 646 | Left = sizeof (mChapHashListString); 647 | for (HashIndex = 0; HashIndex < ARRAY_SIZE (mChapHash); HashIndex++) { 648 | Hash = &mChapHash[HashIndex]; 649 | 650 | // 651 | // Format the next hash identifier. 652 | // 653 | // Assert that we can format at least one non-NUL character, i.e. that we 654 | // can progress. Truncation is checked after printing. 655 | // 656 | ASSERT (Left >= 2); 657 | Printed = AsciiSPrint ( 658 | Position, 659 | Left, 660 | "%a%d", 661 | (HashIndex == 0) ? "" : ",", 662 | Hash->Algorithm 663 | ); 664 | // 665 | // There's no way to differentiate between the "buffer filled to the brim, 666 | // but not truncated" result and the "truncated" result of AsciiSPrint(). 667 | // This is why "mChapHashListString" has an extra byte allocated, and the 668 | // reason why we use the less-than (rather than the less-than-or-equal-to) 669 | // relational operator in the assertion below -- we enforce "no truncation" 670 | // by excluding the "completely used up" case too. 671 | // 672 | ASSERT (Printed + 1 < Left); 673 | 674 | Position += Printed; 675 | Left -= Printed; 676 | 677 | // 678 | // Sanity-check the digest size for Hash. 679 | // 680 | ASSERT (Hash->DigestSize <= ISCSI_CHAP_MAX_DIGEST_SIZE); 681 | } 682 | } 683 | -------------------------------------------------------------------------------- /Edk2_Patch/NetworkPkg/IScsiDxe/IScsiMisc.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | Miscellaneous definitions for iSCSI driver. 3 | 4 | Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.
5 | Copyright (c) Microsoft Corporation 6 | SPDX-License-Identifier: BSD-2-Clause-Patent 7 | 8 | **/ 9 | 10 | #ifndef _ISCSI_MISC_H_ 11 | #define _ISCSI_MISC_H_ 12 | 13 | typedef struct _ISCSI_DRIVER_DATA ISCSI_DRIVER_DATA; 14 | 15 | /// 16 | /// IPv4 Device Path Node Length 17 | /// 18 | #define IP4_NODE_LEN_NEW_VERSIONS 27 19 | 20 | /// 21 | /// IPv6 Device Path Node Length 22 | /// 23 | #define IP6_NODE_LEN_OLD_VERSIONS 43 24 | #define IP6_NODE_LEN_NEW_VERSIONS 60 25 | 26 | /// 27 | /// The ignored field StaticIpAddress's offset in old IPv6 Device Path 28 | /// 29 | #define IP6_OLD_IPADDRESS_OFFSET 42 30 | 31 | #pragma pack(1) 32 | typedef struct _ISCSI_SESSION_CONFIG_NVDATA { 33 | UINT16 TargetPort; 34 | UINT8 Enabled; 35 | UINT8 IpMode; 36 | 37 | EFI_IP_ADDRESS LocalIp; 38 | EFI_IPv4_ADDRESS SubnetMask; 39 | EFI_IP_ADDRESS Gateway; 40 | 41 | BOOLEAN InitiatorInfoFromDhcp; 42 | BOOLEAN TargetInfoFromDhcp; 43 | 44 | CHAR8 TargetName[ISCSI_NAME_MAX_SIZE]; 45 | EFI_IP_ADDRESS TargetIp; 46 | UINT8 PrefixLength; 47 | UINT8 BootLun[8]; 48 | 49 | UINT16 ConnectTimeout; ///< timeout value in milliseconds. 50 | UINT8 ConnectRetryCount; 51 | UINT8 IsId[6]; 52 | 53 | BOOLEAN RedirectFlag; 54 | UINT16 OriginalTargetPort; // The port of proxy/virtual target. 55 | EFI_IP_ADDRESS OriginalTargetIp; // The address of proxy/virtual target. 56 | 57 | BOOLEAN DnsMode; // Flag indicate whether the Target address is expressed as URL format. 58 | CHAR8 TargetUrl[ISCSI_TARGET_URI_MAX_SIZE]; 59 | } ISCSI_SESSION_CONFIG_NVDATA; 60 | #pragma pack() 61 | 62 | /** 63 | Calculate the prefix length of the IPv4 subnet mask. 64 | 65 | @param[in] SubnetMask The IPv4 subnet mask. 66 | 67 | @return The prefix length of the subnet mask. 68 | @retval 0 Other errors as indicated. 69 | 70 | **/ 71 | UINT8 72 | IScsiGetSubnetMaskPrefixLength ( 73 | IN EFI_IPv4_ADDRESS *SubnetMask 74 | ); 75 | 76 | /** 77 | Convert the hexadecimal encoded LUN string into the 64-bit LUN. 78 | 79 | @param[in] Str The hexadecimal encoded LUN string. 80 | @param[out] Lun Storage to return the 64-bit LUN. 81 | 82 | @retval EFI_SUCCESS The 64-bit LUN is stored in Lun. 83 | @retval EFI_INVALID_PARAMETER The string is malformatted. 84 | 85 | **/ 86 | EFI_STATUS 87 | IScsiAsciiStrToLun ( 88 | IN CHAR8 *Str, 89 | OUT UINT8 *Lun 90 | ); 91 | 92 | /** 93 | Convert the 64-bit LUN into the hexadecimal encoded LUN string. 94 | 95 | @param[in] Lun The 64-bit LUN. 96 | @param[out] String The storage to return the hexadecimal encoded LUN string. 97 | 98 | **/ 99 | VOID 100 | IScsiLunToUnicodeStr ( 101 | IN UINT8 *Lun, 102 | OUT CHAR16 *String 103 | ); 104 | 105 | /** 106 | Convert the mac address into a hexadecimal encoded "-" separated string. 107 | 108 | @param[in] Mac The mac address. 109 | @param[in] Len Length in bytes of the mac address. 110 | @param[in] VlanId VLAN ID of the network device. 111 | @param[out] Str The storage to return the mac string. 112 | 113 | **/ 114 | VOID 115 | IScsiMacAddrToStr ( 116 | IN EFI_MAC_ADDRESS *Mac, 117 | IN UINT32 Len, 118 | IN UINT16 VlanId, 119 | OUT CHAR16 *Str 120 | ); 121 | 122 | /** 123 | Convert the formatted IP address into the binary IP address. 124 | 125 | @param[in] Str The UNICODE string. 126 | @param[in] IpMode Indicates whether the IP address is v4 or v6. 127 | @param[out] Ip The storage to return the ASCII string. 128 | 129 | @retval EFI_SUCCESS The binary IP address is returned in Ip. 130 | @retval EFI_INVALID_PARAMETER The IP string is malformatted or IpMode is 131 | invalid. 132 | 133 | **/ 134 | EFI_STATUS 135 | IScsiAsciiStrToIp ( 136 | IN CHAR8 *Str, 137 | IN UINT8 IpMode, 138 | OUT EFI_IP_ADDRESS *Ip 139 | ); 140 | 141 | /** 142 | Convert the binary encoded buffer into a hexadecimal encoded string. 143 | 144 | @param[in] BinBuffer The buffer containing the binary data. 145 | @param[in] BinLength Length of the binary buffer. 146 | @param[in, out] HexStr Pointer to the string. 147 | @param[in, out] HexLength The length of the string. 148 | 149 | @retval EFI_SUCCESS The binary data is converted to the hexadecimal string 150 | and the length of the string is updated. 151 | @retval EFI_BUFFER_TOO_SMALL The string is too small. 152 | @retval EFI_BAD_BUFFER_SIZE BinLength is too large for hex encoding. 153 | @retval EFI_INVALID_PARAMETER The IP string is malformatted. 154 | 155 | **/ 156 | EFI_STATUS 157 | IScsiBinToHex ( 158 | IN UINT8 *BinBuffer, 159 | IN UINT32 BinLength, 160 | IN OUT CHAR8 *HexStr, 161 | IN OUT UINT32 *HexLength 162 | ); 163 | 164 | /** 165 | Convert the hexadecimal string into a binary encoded buffer. 166 | 167 | @param[in, out] BinBuffer The binary buffer. 168 | @param[in, out] BinLength Length of the binary buffer. 169 | @param[in] HexStr The hexadecimal string. 170 | 171 | @retval EFI_SUCCESS The hexadecimal string is converted into a 172 | binary encoded buffer. 173 | @retval EFI_INVALID_PARAMETER Invalid hex encoding found in HexStr. 174 | @retval EFI_BAD_BUFFER_SIZE The length of HexStr is too large for decoding: 175 | the decoded size cannot be expressed in 176 | BinLength on output. 177 | @retval EFI_BUFFER_TOO_SMALL The binary buffer is too small to hold the 178 | converted data. 179 | **/ 180 | EFI_STATUS 181 | IScsiHexToBin ( 182 | IN OUT UINT8 *BinBuffer, 183 | IN OUT UINT32 *BinLength, 184 | IN CHAR8 *HexStr 185 | ); 186 | 187 | /** 188 | Convert the decimal-constant string or hex-constant string into a numerical value. 189 | 190 | @param[in] Str String in decimal or hex. 191 | 192 | @return The numerical value. 193 | 194 | **/ 195 | UINTN 196 | IScsiNetNtoi ( 197 | IN CHAR8 *Str 198 | ); 199 | 200 | /** 201 | Generate random numbers. 202 | 203 | @param[in, out] Rand The buffer to contain random numbers. 204 | @param[in] RandLength The length of the Rand buffer. 205 | 206 | @retval EFI_SUCCESS on success 207 | @retval others on error 208 | 209 | **/ 210 | EFI_STATUS 211 | IScsiGenRandom ( 212 | IN OUT UINT8 *Rand, 213 | IN UINTN RandLength 214 | ); 215 | 216 | /** 217 | Record the NIC information in a global structure. 218 | 219 | @param[in] Controller The handle of the controller. 220 | @param[in] Image Handle of the image. 221 | 222 | @retval EFI_SUCCESS The operation is completed. 223 | @retval EFI_OUT_OF_RESOURCES Do not have sufficient resource to finish this 224 | operation. 225 | 226 | **/ 227 | EFI_STATUS 228 | IScsiAddNic ( 229 | IN EFI_HANDLE Controller, 230 | IN EFI_HANDLE Image 231 | ); 232 | 233 | /** 234 | Delete the recorded NIC information from a global structure. Also delete corresponding 235 | attempts. 236 | 237 | @param[in] Controller The handle of the controller. 238 | 239 | @retval EFI_SUCCESS The operation completed. 240 | @retval EFI_NOT_FOUND The NIC information to be deleted is not recorded. 241 | 242 | **/ 243 | EFI_STATUS 244 | IScsiRemoveNic ( 245 | IN EFI_HANDLE Controller 246 | ); 247 | 248 | /** 249 | Create and initialize the Attempts. 250 | 251 | @param[in] AttemptNum The number of Attempts will be created. 252 | 253 | @retval EFI_SUCCESS The Attempts have been created successfully. 254 | @retval Others Failed to create the Attempt. 255 | 256 | **/ 257 | EFI_STATUS 258 | IScsiCreateAttempts ( 259 | IN UINTN AttemptNum 260 | ); 261 | 262 | /** 263 | Create the iSCSI configuration Keywords for each attempt. 264 | 265 | @param[in] KeywordNum The number Sets of Keywords will be created. 266 | 267 | @retval EFI_SUCCESS The operation is completed. 268 | @retval Others Failed to create the Keywords. 269 | 270 | **/ 271 | EFI_STATUS 272 | IScsiCreateKeywords ( 273 | IN UINTN KeywordNum 274 | ); 275 | 276 | /** 277 | 278 | Free the attempt configure data variable. 279 | 280 | **/ 281 | VOID 282 | IScsiCleanAttemptVariable ( 283 | IN VOID 284 | ); 285 | 286 | /** 287 | Get the recorded NIC information from a global structure by the Index. 288 | 289 | @param[in] NicIndex The index indicates the position of NIC info. 290 | 291 | @return Pointer to the NIC info or NULL if not found. 292 | 293 | **/ 294 | ISCSI_NIC_INFO * 295 | IScsiGetNicInfoByIndex ( 296 | IN UINT8 NicIndex 297 | ); 298 | 299 | /** 300 | Get the NIC's PCI location and return it according to the composited 301 | format defined in iSCSI Boot Firmware Table. 302 | 303 | @param[in] Controller The handle of the controller. 304 | @param[out] Bus The bus number. 305 | @param[out] Device The device number. 306 | @param[out] Function The function number. 307 | 308 | @return The composited representation of the NIC PCI location. 309 | 310 | **/ 311 | UINT16 312 | IScsiGetNICPciLocation ( 313 | IN EFI_HANDLE Controller, 314 | OUT UINTN *Bus, 315 | OUT UINTN *Device, 316 | OUT UINTN *Function 317 | ); 318 | 319 | /** 320 | Read the EFI variable (VendorGuid/Name) and return a dynamically allocated 321 | buffer, and the size of the buffer. If failure, return NULL. 322 | 323 | @param[in] Name String part of EFI variable name. 324 | @param[in] VendorGuid GUID part of EFI variable name. 325 | @param[out] VariableSize Returns the size of the EFI variable that was read. 326 | 327 | @return Dynamically allocated memory that contains a copy of the EFI variable. 328 | @return Caller is responsible freeing the buffer. 329 | @retval NULL Variable was not read. 330 | 331 | **/ 332 | VOID * 333 | IScsiGetVariableAndSize ( 334 | IN CHAR16 *Name, 335 | IN EFI_GUID *VendorGuid, 336 | OUT UINTN *VariableSize 337 | ); 338 | 339 | /** 340 | Create the iSCSI driver data. 341 | 342 | @param[in] Image The handle of the driver image. 343 | @param[in] Controller The handle of the controller. 344 | 345 | @return The iSCSI driver data created. 346 | @retval NULL Other errors as indicated. 347 | 348 | **/ 349 | ISCSI_DRIVER_DATA * 350 | IScsiCreateDriverData ( 351 | IN EFI_HANDLE Image, 352 | IN EFI_HANDLE Controller 353 | ); 354 | 355 | /** 356 | Clean the iSCSI driver data. 357 | 358 | @param[in] Private The iSCSI driver data. 359 | 360 | @retval EFI_SUCCESS The clean operation is successful. 361 | @retval Others Other errors as indicated. 362 | 363 | **/ 364 | EFI_STATUS 365 | IScsiCleanDriverData ( 366 | IN ISCSI_DRIVER_DATA *Private 367 | ); 368 | 369 | /** 370 | Check wheather the Controller handle is configured to use DHCP protocol. 371 | 372 | @param[in] Controller The handle of the controller. 373 | @param[in] IpVersion IP_VERSION_4 or IP_VERSION_6. 374 | 375 | @retval TRUE The handle of the controller need the Dhcp protocol. 376 | @retval FALSE The handle of the controller does not need the Dhcp protocol. 377 | 378 | **/ 379 | BOOLEAN 380 | IScsiDhcpIsConfigured ( 381 | IN EFI_HANDLE Controller, 382 | IN UINT8 IpVersion 383 | ); 384 | 385 | /** 386 | Check wheather the Controller handle is configured to use DNS protocol. 387 | 388 | @param[in] Controller The handle of the controller. 389 | 390 | @retval TRUE The handle of the controller need the DNS protocol. 391 | @retval FALSE The handle of the controller does not need the DNS protocol. 392 | 393 | **/ 394 | BOOLEAN 395 | IScsiDnsIsConfigured ( 396 | IN EFI_HANDLE Controller 397 | ); 398 | 399 | /** 400 | Get the various configuration data of this iSCSI instance. 401 | 402 | @param[in] Private The iSCSI driver data. 403 | 404 | @retval EFI_SUCCESS Obtained the configuration of this instance. 405 | @retval EFI_ABORTED The operation was aborted. 406 | @retval Others Other errors as indicated. 407 | 408 | **/ 409 | EFI_STATUS 410 | IScsiGetConfigData ( 411 | IN ISCSI_DRIVER_DATA *Private 412 | ); 413 | 414 | /** 415 | Get the device path of the iSCSI tcp connection and update it. 416 | 417 | @param[in] Session The iSCSI session data. 418 | 419 | @return The updated device path. 420 | @retval NULL Other errors as indicated. 421 | 422 | **/ 423 | EFI_DEVICE_PATH_PROTOCOL * 424 | IScsiGetTcpConnDevicePath ( 425 | IN ISCSI_SESSION *Session 426 | ); 427 | 428 | /** 429 | Abort the session when the transition from BS to RT is initiated. 430 | 431 | @param[in] Event The event signaled. 432 | @param[in] Context The iSCSI driver data. 433 | 434 | **/ 435 | VOID 436 | EFIAPI 437 | IScsiOnExitBootService ( 438 | IN EFI_EVENT Event, 439 | IN VOID *Context 440 | ); 441 | 442 | /** 443 | Tests whether a controller handle is being managed by IScsi driver. 444 | 445 | This function tests whether the driver specified by DriverBindingHandle is 446 | currently managing the controller specified by ControllerHandle. This test 447 | is performed by evaluating if the protocol specified by ProtocolGuid is 448 | present on ControllerHandle and is was opened by DriverBindingHandle and Nic 449 | Device handle with an attribute of EFI_OPEN_PROTOCOL_BY_DRIVER. 450 | If ProtocolGuid is NULL, then ASSERT(). 451 | 452 | @param ControllerHandle A handle for a controller to test. 453 | @param DriverBindingHandle Specifies the driver binding handle for the 454 | driver. 455 | @param ProtocolGuid Specifies the protocol that the driver specified 456 | by DriverBindingHandle opens in its Start() 457 | function. 458 | 459 | @retval EFI_SUCCESS ControllerHandle is managed by the driver 460 | specified by DriverBindingHandle. 461 | @retval EFI_UNSUPPORTED ControllerHandle is not managed by the driver 462 | specified by DriverBindingHandle. 463 | 464 | **/ 465 | EFI_STATUS 466 | EFIAPI 467 | IScsiTestManagedDevice ( 468 | IN EFI_HANDLE ControllerHandle, 469 | IN EFI_HANDLE DriverBindingHandle, 470 | IN EFI_GUID *ProtocolGuid 471 | ); 472 | 473 | #endif 474 | -------------------------------------------------------------------------------- /Edk2_Patch/NetworkPkg/Ip6Dxe/Ip6Option.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | Definition of IP6 option process routines. 3 | 4 | Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
5 | 6 | SPDX-License-Identifier: BSD-2-Clause-Patent 7 | 8 | **/ 9 | 10 | #ifndef __EFI_IP6_OPTION_H__ 11 | #define __EFI_IP6_OPTION_H__ 12 | 13 | #define IP6_FRAGMENT_OFFSET_MASK (~0x3) 14 | 15 | // 16 | // For more information see RFC 8200, Section 4.3, 4.4, and 4.6 17 | // 18 | // This example format is from section 4.6 19 | // This does not apply to fragment headers 20 | // 21 | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 22 | // | Next Header | Hdr Ext Len | | 23 | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + 24 | // | | 25 | // . . 26 | // . Header-Specific Data . 27 | // . . 28 | // | | 29 | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 30 | // 31 | // Next Header 8-bit selector. Identifies the type of 32 | // header immediately following the extension 33 | // header. Uses the same values as the IPv4 34 | // Protocol field [IANA-PN]. 35 | // 36 | // Hdr Ext Len 8-bit unsigned integer. Length of the 37 | // Destination Options header in 8-octet units, 38 | // not including the first 8 octets. 39 | 40 | // 41 | // These defines apply to the following: 42 | // 1. Hop by Hop 43 | // 2. Routing 44 | // 3. Destination 45 | // 46 | typedef struct _IP6_EXT_HDR { 47 | /// 48 | /// The Next Header field identifies the type of header immediately 49 | /// 50 | UINT8 NextHeader; 51 | /// 52 | /// The Hdr Ext Len field specifies the length of the Hop-by-Hop Options 53 | /// 54 | UINT8 HdrExtLen; 55 | /// 56 | /// Header-Specific Data 57 | /// 58 | } IP6_EXT_HDR; 59 | 60 | STATIC_ASSERT ( 61 | sizeof (IP6_EXT_HDR) == 2, 62 | "The combined size of Next Header and Len is two 8 bit fields" 63 | ); 64 | 65 | // 66 | // IPv6 extension headers contain an 8-bit length field which describes the size of 67 | // the header. However, the length field only includes the size of the extension 68 | // header options, not the size of the first 8 bytes of the header. Therefore, in 69 | // order to calculate the full size of the extension header, we add 1 (to account 70 | // for the first 8 bytes omitted by the length field reporting) and then multiply 71 | // by 8 (since the size is represented in 8-byte units). 72 | // 73 | // a is the length field of the extension header (UINT8) 74 | // The result may be up to 2046 octets (UINT16) 75 | // 76 | #define IP6_HDR_EXT_LEN(a) (((UINT16)((UINT8)(a)) + 1) * 8) 77 | 78 | // This is the maxmimum length permissible by a extension header 79 | // Length is UINT8 of 8 octets not including the first 8 octets 80 | #define IP6_MAX_EXT_DATA_LENGTH (IP6_HDR_EXT_LEN (MAX_UINT8) - sizeof(IP6_EXT_HDR)) 81 | STATIC_ASSERT ( 82 | IP6_MAX_EXT_DATA_LENGTH == 2046, 83 | "Maximum data length is ((MAX_UINT8 + 1) * 8) - 2" 84 | ); 85 | 86 | typedef struct _IP6_FRAGMENT_HEADER { 87 | UINT8 NextHeader; 88 | UINT8 Reserved; 89 | UINT16 FragmentOffset; 90 | UINT32 Identification; 91 | } IP6_FRAGMENT_HEADER; 92 | 93 | typedef struct _IP6_ROUTING_HEADER { 94 | UINT8 NextHeader; 95 | UINT8 HeaderLen; 96 | UINT8 RoutingType; 97 | UINT8 SegmentsLeft; 98 | } IP6_ROUTING_HEADER; 99 | 100 | typedef enum { 101 | Ip6OptionPad1 = 0, 102 | Ip6OptionPadN = 1, 103 | Ip6OptionRouterAlert = 5, 104 | Ip6OptionSkip = 0, 105 | Ip6OptionDiscard = 0x40, 106 | Ip6OptionParameterProblem = 0x80, 107 | Ip6OptionMask = 0xc0, 108 | 109 | Ip6OptionEtherSource = 1, 110 | Ip6OptionEtherTarget = 2, 111 | Ip6OptionPrefixInfo = 3, 112 | Ip6OptionRedirected = 4, 113 | Ip6OptionMtu = 5 114 | } IP6_OPTION_TYPE; 115 | 116 | /** 117 | Validate the IP6 extension header format for both the packets we received 118 | and that we will transmit. It will compute the ICMPv6 error message fields 119 | if the option is mal-formatted. 120 | 121 | @param[in] IpSb The IP6 service instance. This is an optional parameter. 122 | @param[in] Packet The data of the packet. Ignored if NULL. 123 | @param[in] NextHeader The next header field in IPv6 basic header. 124 | @param[in] ExtHdrs The first byte of the option. 125 | @param[in] ExtHdrsLen The length of the whole option. 126 | @param[in] Rcvd The option is from the packet we received if TRUE, 127 | otherwise, the option we want to transmit. 128 | @param[out] FormerHeader The offset of NextHeader which points to Fragment 129 | Header when we received, of the ExtHdrs. 130 | Ignored if we transmit. 131 | @param[out] LastHeader The pointer of NextHeader of the last extension 132 | header processed by IP6. 133 | @param[out] RealExtsLen The length of extension headers processed by IP6 layer. 134 | This is an optional parameter that may be NULL. 135 | @param[out] UnFragmentLen The length of unfragmented length of extension headers. 136 | This is an optional parameter that may be NULL. 137 | @param[out] Fragmented Indicate whether the packet is fragmented. 138 | This is an optional parameter that may be NULL. 139 | 140 | @retval TRUE The option is properly formatted. 141 | @retval FALSE The option is malformatted. 142 | 143 | **/ 144 | BOOLEAN 145 | Ip6IsExtsValid ( 146 | IN IP6_SERVICE *IpSb OPTIONAL, 147 | IN NET_BUF *Packet OPTIONAL, 148 | IN UINT8 *NextHeader, 149 | IN UINT8 *ExtHdrs, 150 | IN UINT32 ExtHdrsLen, 151 | IN BOOLEAN Rcvd, 152 | OUT UINT32 *FormerHeader OPTIONAL, 153 | OUT UINT8 **LastHeader, 154 | OUT UINT32 *RealExtsLen OPTIONAL, 155 | OUT UINT32 *UnFragmentLen OPTIONAL, 156 | OUT BOOLEAN *Fragmented OPTIONAL 157 | ); 158 | 159 | /** 160 | Generate an IPv6 router alert option in network order and output it through Buffer. 161 | 162 | @param[out] Buffer Points to a buffer to record the generated option. 163 | @param[in, out] BufferLen The length of Buffer, in bytes. 164 | @param[in] NextHeader The 8-bit selector indicates the type of header 165 | immediately following the Hop-by-Hop Options header. 166 | 167 | @retval EFI_BUFFER_TOO_SMALL The Buffer is too small to contain the generated 168 | option. BufferLen is updated for the required size. 169 | 170 | @retval EFI_SUCCESS The option is generated and filled in to Buffer. 171 | 172 | **/ 173 | EFI_STATUS 174 | Ip6FillHopByHop ( 175 | OUT UINT8 *Buffer, 176 | IN OUT UINTN *BufferLen, 177 | IN UINT8 NextHeader 178 | ); 179 | 180 | /** 181 | Insert a Fragment Header to the Extension headers and output it in UpdatedExtHdrs. 182 | 183 | @param[in] IpSb The IP6 service instance to transmit the packet. 184 | @param[in] NextHeader The extension header type of first extension header. 185 | @param[in] LastHeader The extension header type of last extension header. 186 | @param[in] ExtHdrs The length of the original extension header. 187 | @param[in] ExtHdrsLen The length of the extension headers. 188 | @param[in] FragmentOffset The fragment offset of the data following the header. 189 | @param[out] UpdatedExtHdrs The updated ExtHdrs with Fragment header inserted. 190 | It's caller's responsibility to free this buffer. 191 | 192 | @retval EFI_OUT_OF_RESOURCES Failed to finish the operation due to lake of 193 | resource. 194 | @retval EFI_UNSUPPORTED The extension header specified in ExtHdrs is not 195 | supported currently. 196 | @retval EFI_SUCCESS The operation performed successfully. 197 | 198 | **/ 199 | EFI_STATUS 200 | Ip6FillFragmentHeader ( 201 | IN IP6_SERVICE *IpSb, 202 | IN UINT8 NextHeader, 203 | IN UINT8 LastHeader, 204 | IN UINT8 *ExtHdrs, 205 | IN UINT32 ExtHdrsLen, 206 | IN UINT16 FragmentOffset, 207 | OUT UINT8 **UpdatedExtHdrs 208 | ); 209 | 210 | /** 211 | Copy the extension headers from the original to buffer. A Fragment header is 212 | appended to the end. 213 | 214 | @param[in] NextHeader The 8-bit selector indicates the type of 215 | the fragment header's next header. 216 | @param[in] ExtHdrs The length of the original extension header. 217 | @param[in] LastHeader The pointer of next header of last extension header. 218 | @param[in] FragmentOffset The fragment offset of the data following the header. 219 | @param[in] UnFragmentHdrLen The length of unfragmented length of extension headers. 220 | @param[in, out] Buf The buffer to copy options to. 221 | @param[in, out] BufLen The length of the buffer. 222 | 223 | @retval EFI_SUCCESS The options are copied over. 224 | @retval EFI_BUFFER_TOO_SMALL The buffer caller provided is too small. 225 | 226 | **/ 227 | EFI_STATUS 228 | Ip6CopyExts ( 229 | IN UINT8 NextHeader, 230 | IN UINT8 *ExtHdrs, 231 | IN UINT8 *LastHeader, 232 | IN UINT16 FragmentOffset, 233 | IN UINT32 UnFragmentHdrLen, 234 | IN OUT UINT8 *Buf, 235 | IN OUT UINT32 *BufLen 236 | ); 237 | 238 | /** 239 | Validate the IP6 option format for both the packets we received 240 | and that we will transmit. It supports the defined options in Neighbor 241 | Discovery messages. 242 | 243 | @param[in] Option The first byte of the option. 244 | @param[in] OptionLen The length of the whole option. 245 | 246 | @retval TRUE The option is properly formatted. 247 | @retval FALSE The option is malformatted. 248 | 249 | **/ 250 | BOOLEAN 251 | Ip6IsNDOptionValid ( 252 | IN UINT8 *Option, 253 | IN UINT16 OptionLen 254 | ); 255 | 256 | #endif 257 | -------------------------------------------------------------------------------- /Edk2_Patch/NetworkPkg/Library/DxeNetLib/DxeNetLib.inf: -------------------------------------------------------------------------------- 1 | ## @file 2 | # This library instance provides the basic network services. 3 | # 4 | # Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
5 | # (C) Copyright 2015 Hewlett Packard Enterprise Development LP
6 | # Copyright (c) Microsoft Corporation 7 | # SPDX-License-Identifier: BSD-2-Clause-Patent 8 | # 9 | ## 10 | 11 | 12 | [Defines] 13 | INF_VERSION = 0x00010005 14 | BASE_NAME = DxeNetLib 15 | MODULE_UNI_FILE = DxeNetLib.uni 16 | FILE_GUID = db6dcef3-9f4e-4340-9351-fc35aa8a5888 17 | MODULE_TYPE = DXE_DRIVER 18 | VERSION_STRING = 1.0 19 | LIBRARY_CLASS = NetLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER 20 | 21 | # 22 | # The following information is for reference only and not required by the build tools. 23 | # 24 | # VALID_ARCHITECTURES = IA32 X64 EBC 25 | # 26 | 27 | [Sources] 28 | DxeNetLib.c 29 | NetBuffer.c 30 | 31 | 32 | [Packages] 33 | MdePkg/MdePkg.dec 34 | NetworkPkg/NetworkPkg.dec 35 | 36 | 37 | [LibraryClasses] 38 | BaseLib 39 | DebugLib 40 | BaseMemoryLib 41 | UefiBootServicesTableLib 42 | UefiRuntimeServicesTableLib 43 | UefiLib 44 | MemoryAllocationLib 45 | DevicePathLib 46 | PrintLib 47 | 48 | 49 | [Guids] 50 | gEfiSmbiosTableGuid ## SOMETIMES_CONSUMES ## SystemTable 51 | gEfiSmbios3TableGuid ## SOMETIMES_CONSUMES ## SystemTable 52 | gEfiAdapterInfoMediaStateGuid ## SOMETIMES_CONSUMES 53 | gEfiRngAlgorithmRaw ## CONSUMES 54 | gEfiRngAlgorithmSp80090Ctr256Guid ## CONSUMES 55 | gEfiRngAlgorithmSp80090Hmac256Guid ## CONSUMES 56 | gEfiRngAlgorithmSp80090Hash256Guid ## CONSUMES 57 | gEfiRngAlgorithmArmRndr ## CONSUMES 58 | 59 | [Protocols] 60 | gEfiSimpleNetworkProtocolGuid ## SOMETIMES_CONSUMES 61 | gEfiManagedNetworkProtocolGuid ## SOMETIMES_CONSUMES 62 | gEfiManagedNetworkServiceBindingProtocolGuid ## SOMETIMES_CONSUMES 63 | gEfiIp4Config2ProtocolGuid ## SOMETIMES_CONSUMES 64 | gEfiComponentNameProtocolGuid ## SOMETIMES_CONSUMES 65 | gEfiComponentName2ProtocolGuid ## SOMETIMES_CONSUMES 66 | gEfiAdapterInformationProtocolGuid ## SOMETIMES_CONSUMES 67 | gEfiRngProtocolGuid ## CONSUMES 68 | 69 | [FixedPcd] 70 | gEfiNetworkPkgTokenSpaceGuid.PcdEnforceSecureRngAlgorithms ## CONSUMES 71 | 72 | [Depex] 73 | gEfiRngProtocolGuid 74 | -------------------------------------------------------------------------------- /Edk2_Patch/NetworkPkg/NetworkPkg.dec: -------------------------------------------------------------------------------- 1 | ## @file 2 | # Network Package. 3 | # 4 | # This package provides network modules that conform to UEFI 2.4 specification. 5 | # 6 | # Copyright (c) 2009 - 2021, Intel Corporation. All rights reserved.
7 | # (C) Copyright 2015-2020 Hewlett Packard Enterprise Development LP
8 | # Copyright (c) Microsoft Corporation 9 | # 10 | # SPDX-License-Identifier: BSD-2-Clause-Patent 11 | # 12 | ## 13 | 14 | [Defines] 15 | DEC_SPECIFICATION = 0x00010005 16 | PACKAGE_NAME = NetworkPkg 17 | PACKAGE_GUID = 947988BE-8D5C-471a-893D-AD181C46BEBB 18 | PACKAGE_VERSION = 0.98 19 | PACKAGE_UNI_FILE = NetworkPkg.uni 20 | 21 | [Includes] 22 | Include 23 | 24 | [LibraryClasses] 25 | ## @libraryclass IpIo layer upon EFI IP4 Protocol. 26 | # This library is only intended to be used by UEFI network stack modules. 27 | IpIoLib|Include/Library/IpIoLib.h 28 | 29 | ## @libraryclass Basic function for UEFI network stack. 30 | # This library is only intended to be used by UEFI network stack modules. 31 | NetLib|Include/Library/NetLib.h 32 | 33 | ## @libraryclass The helper routines to access UDP service. 34 | # This library is only intended to be used by UEFI network stack modules. 35 | UdpIoLib|Include/Library/UdpIoLib.h 36 | 37 | ## @libraryclass The helper routines to access TCP service. 38 | # This library is only intended to be used by UEFI network stack modules. 39 | TcpIoLib|Include/Library/TcpIoLib.h 40 | 41 | ## @libraryclass The helper routines to access HTTP service. 42 | # This library is only intended to be used by UEFI network stack modules. 43 | HttpLib|Include/Library/HttpLib.h 44 | 45 | ## @libraryclass Http IO helper routines for HTTP transfer. 46 | # This library is only intended to be used by UEFI network stack modules. 47 | HttpIoLib|Include/Library/HttpIoLib.h 48 | 49 | ## @libraryclass Library for Deferred Procedure Calls. 50 | DpcLib|Include/Library/DpcLib.h 51 | 52 | [Guids] 53 | ## Network package token space guid. 54 | # Include/Guid/NetworkPkgTokenSpace.h 55 | gEfiNetworkPkgTokenSpaceGuid = { 0x40e064b2, 0x0ae0, 0x48b1, { 0xa0, 0x7d, 0xf8, 0xcf, 0x1e, 0x1a, 0x23, 0x10}} 56 | 57 | # Include/Guid/Ip6ConfigHii.h 58 | gIp6ConfigNvDataGuid = { 0x2eea107, 0x98db, 0x400e, { 0x98, 0x30, 0x46, 0xa, 0x15, 0x42, 0xd7, 0x99}} 59 | 60 | # Include/Guid/IscsiConfigHii.h 61 | gIScsiConfigGuid = { 0x4b47d616, 0xa8d6, 0x4552, { 0x9d, 0x44, 0xcc, 0xad, 0x2e, 0xf, 0x4c, 0xf9}} 62 | 63 | # Include/Guid/HttpBootConfigHii.h 64 | gHttpBootConfigGuid = { 0x4d20583a, 0x7765, 0x4e7a, { 0x8a, 0x67, 0xdc, 0xde, 0x74, 0xee, 0x3e, 0xc5 }} 65 | 66 | # Include/Guid/TlsAuthConfigHii.h 67 | gTlsAuthConfigGuid = { 0xb0eae4f8, 0x9a04, 0x4c6d, { 0xa7, 0x48, 0x79, 0x3d, 0xaa, 0xf, 0x65, 0xdf }} 68 | 69 | # Include/Guid/TlsAuthentication.h 70 | gEfiTlsCaCertificateGuid = { 0xfd2340D0, 0x3dab, 0x4349, { 0xa6, 0xc7, 0x3b, 0x4f, 0x12, 0xb4, 0x8e, 0xae }} 71 | 72 | # Include/Guid/HttpTlsCipherList.h 73 | gEdkiiHttpTlsCipherListGuid = { 0x46ddb415, 0x5244, 0x49c7, { 0x93, 0x74, 0xf0, 0xe2, 0x98, 0xe7, 0xd3, 0x86 }} 74 | 75 | # Include/Guid/WifiConnectionManagerConfigHii.h 76 | gWifiConfigGuid = { 0x9f94d327, 0x0b18, 0x4245, { 0x8f, 0xf2, 0x83, 0x2e, 0x30, 0xd, 0x2c, 0xef }} 77 | 78 | ## Include/Guid/Ip4Config2Hii.h 79 | gIp4Config2NvDataGuid = { 0x9b942747, 0x154e, 0x4d29, { 0xa4, 0x36, 0xbf, 0x71, 0x0, 0xc8, 0xb5, 0x3b }} 80 | 81 | ## Include/Guid/VlanConfigHii.h 82 | gVlanConfigFormSetGuid = { 0xd79df6b0, 0xef44, 0x43bd, { 0x97, 0x97, 0x43, 0xe9, 0x3b, 0xcf, 0x5f, 0xa8 }} 83 | 84 | ## Include/Guid/Ip4IScsiConfigHii.h 85 | gIp4IScsiConfigGuid = { 0x6456ed61, 0x3579, 0x41c9, { 0x8a, 0x26, 0x0a, 0x0b, 0xd6, 0x2b, 0x78, 0xfc }} 86 | gIScsiCHAPAuthInfoGuid = { 0x786ec0ac, 0x65ae, 0x4d1b, { 0xb1, 0x37, 0xd, 0x11, 0xa, 0x48, 0x37, 0x97 }} 87 | 88 | [Protocols] 89 | ## Include/Protocol/Dpc.h 90 | gEfiDpcProtocolGuid = {0x480f8ae9, 0xc46, 0x4aa9, { 0xbc, 0x89, 0xdb, 0x9f, 0xba, 0x61, 0x98, 0x6 }} 91 | 92 | ## Include/Protocol/HttpCallback.h 93 | gEdkiiHttpCallbackProtocolGuid = {0x611114f1, 0xa37b, 0x4468, {0xa4, 0x36, 0x5b, 0xdd, 0xa1, 0x6a, 0xa2, 0x40}} 94 | 95 | ## Include/Protocol/WiFiProfileSyncProtocol.h 96 | gEdkiiWiFiProfileSyncProtocolGuid = {0x399a2b8a, 0xc267, 0x44aa, {0x9a, 0xb4, 0x30, 0x58, 0x8c, 0xd2, 0x2d, 0xcc}} 97 | 98 | [PcdsFixedAtBuild] 99 | ## The max attempt number will be created by iSCSI driver. 100 | # @Prompt Max attempt number. 101 | gEfiNetworkPkgTokenSpaceGuid.PcdMaxIScsiAttemptNumber|0x08|UINT8|0x0000000D 102 | 103 | ## The maximum size of total HTTP chunk transfer. 104 | # @Prompt Max size of total HTTP chunk transfer. the default value is 12MB. 105 | gEfiNetworkPkgTokenSpaceGuid.PcdMaxHttpChunkTransfer|0x0C00000|UINT32|0x0000000E 106 | 107 | [PcdsFixedAtBuild, PcdsPatchableInModule] 108 | ## Indicates whether HTTP connections (i.e., unsecured) are permitted or not. 109 | # TRUE - HTTP connections are allowed. Both the "https://" and "http://" URI schemes are permitted. 110 | # FALSE - HTTP connections are denied. Only the "https://" URI scheme is permitted. 111 | # @Prompt Indicates whether HTTP connections are permitted or not. 112 | gEfiNetworkPkgTokenSpaceGuid.PcdAllowHttpConnections|FALSE|BOOLEAN|0x00000008 113 | 114 | ## This setting is to specify the MTFTP windowsize used by UEFI PXE driver. 115 | # A value of 0 indicates the default value of windowsize(1). 116 | # A non-zero value will be used as windowsize. 117 | # @Prompt PXE TFTP windowsize. 118 | gEfiNetworkPkgTokenSpaceGuid.PcdPxeTftpWindowSize|0x4|UINT64|0x10000008 119 | 120 | 121 | ## This setting can override the default TFTP block size. A value of 0 computes 122 | # the default from MTU information. A non-zero value will be used as block size 123 | # in bytes. 124 | # @Prompt TFTP block size. 125 | gEfiNetworkPkgTokenSpaceGuid.PcdTftpBlockSize|0x0|UINT64|0x1000000B 126 | 127 | ## Indicates whether SnpDxe driver will create an event that will be notified 128 | # upon gBS->ExitBootServices() call. 129 | # TRUE - Event being triggered upon ExitBootServices call will be created 130 | # FALSE - Event being triggered upon ExitBootServices call will NOT be created 131 | # @Prompt Indicates whether SnpDxe creates event for ExitBootServices() call. 132 | gEfiNetworkPkgTokenSpaceGuid.PcdSnpCreateExitBootServicesEvent|TRUE|BOOLEAN|0x1000000C 133 | 134 | ## Enforces the use of Secure UEFI spec defined RNG algorithms for all network connections. 135 | # TRUE - Enforce the use of Secure UEFI spec defined RNG algorithms. 136 | # FALSE - Do not enforce and depend on the default implementation of RNG algorithm from the provider. 137 | # @Prompt Enforce the use of Secure UEFI spec defined RNG algorithms. 138 | gEfiNetworkPkgTokenSpaceGuid.PcdEnforceSecureRngAlgorithms|TRUE|BOOLEAN|0x1000000D 139 | 140 | [PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx] 141 | ## IPv6 DHCP Unique Identifier (DUID) Type configuration (From RFCs 3315 and 6355). 142 | # 01 = DUID Based on Link-layer Address Plus Time [DUID-LLT] 143 | # 04 = UUID-Based DHCPv6 Unique Identifier (DUID-UUID) 144 | # 02 = DUID Assigned by Vendor Based on Enterprise Number [DUID-EN] (not supported) 145 | # 03 = DUID Based on Link-layer Address [DUID-LL] (not supported) 146 | # @Prompt Type Value of Dhcp6 Unique Identifier (DUID). 147 | gEfiNetworkPkgTokenSpaceGuid.PcdDhcp6UidType|4|UINT8|0x10000001 148 | 149 | ## Network boot policy to stop UEFI iSCSI if applicable. 150 | # 0x00 = Always use UEFI iSCSI and ignore iSCSI HBA. 151 | # 0x01 = Stop UEFI iSCSI if iSCSI HBA adapter produces AIP protocol with Network Boot. 152 | # 0x02 = Stop UEFI iSCSI if iSCSI HBA adapter supports booting from iSCSI IPv4 targets. 153 | # 0x04 = Stop UEFI iSCSI if iSCSI HBA adapter supports booting from iSCSI IPv6 targets. 154 | # 0x08 = Stop UEFI iSCSI if iSCSI HBA adapter supports an offload engine for iSCSI boot. 155 | # 0x10 = Stop UEFI iSCSI if iSCSI HBA adapter supports multipath I/O for iSCSI boot. 156 | # 0x20 = Stop UEFI iSCSI if iSCSI HBA adapter is currently configured to boot from iSCSI IPv4 targets. 157 | # 0x40 = Stop UEFI iSCSI if iSCSI HBA adapter is currently configured to boot from iSCSI IPv6 targets. 158 | # 0xFF = Always use iSCSI HBA and ignore UEFI iSCSI. 159 | # @Prompt Type Value of network boot policy used in iSCSI. 160 | gEfiNetworkPkgTokenSpaceGuid.PcdIScsiAIPNetworkBootPolicy|0x08|UINT8|0x10000007 161 | 162 | ## IPv4 PXE support 163 | # 0x01 = PXE Enabled 164 | # 0x00 = PXE Disabled 165 | gEfiNetworkPkgTokenSpaceGuid.PcdIPv4PXESupport|0x01|UINT8|0x10000009 166 | 167 | ## IPv6 PXE support 168 | # 0x01 = PXE Enabled 169 | # 0x00 = PXE Disabled 170 | gEfiNetworkPkgTokenSpaceGuid.PcdIPv6PXESupport|0x01|UINT8|0x1000000a 171 | 172 | ## The Timeout value of HTTP IO. 173 | # @Prompt The Timeout value of HTTP Io. Default value is 5000. 174 | gEfiNetworkPkgTokenSpaceGuid.PcdHttpIoTimeout|5000|UINT32|0x0000000F 175 | 176 | ## The Retry Interval of HTTP DNS in seconds. If the Retry Interval is less than 177 | # DNS_DEFAULT_TIMEOUT, then use the DNS_DEFAULT_TIMEOUT. 178 | # @Prompt The value of Retry Interval. Default value is 0 179 | gEfiNetworkPkgTokenSpaceGuid.PcdHttpDnsRetryInterval|0|UINT32|0x00000010 180 | 181 | ## The Retry Count of HTTP DNS if no DNS response received after Retry Interval. 182 | # @Prompt The value of Retry Count, Default value is 0. 183 | gEfiNetworkPkgTokenSpaceGuid.PcdHttpDnsRetryCount|0|UINT32|0x00000011 184 | 185 | [UserExtensions.TianoCore."ExtraFiles"] 186 | NetworkPkgExtra.uni 187 | -------------------------------------------------------------------------------- /Edk2_Patch/NetworkPkg/TcpDxe/TcpDxe.inf: -------------------------------------------------------------------------------- 1 | ## @file 2 | # TCPv4 I/O and TCPv6 I/O services. 3 | # 4 | # This module provides EFI TCPv4 Protocol and EFI TCPv6 Protocol to send and receive data stream. 5 | # It might provide TCPv4 Protocol or TCPv6 Protocol or both of them that depends on which network 6 | # stack has been loaded in system. This driver supports both IPv4 and IPv6 network stack. 7 | # 8 | # Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
9 | # Copyright (c) Microsoft Corporation 10 | # 11 | # SPDX-License-Identifier: BSD-2-Clause-Patent 12 | # 13 | ## 14 | 15 | [Defines] 16 | INF_VERSION = 0x00010005 17 | BASE_NAME = TcpDxe 18 | FILE_GUID = 1A7E4468-2F55-4a56-903C-01265EB7622B 19 | MODULE_TYPE = UEFI_DRIVER 20 | VERSION_STRING = 1.0 21 | ENTRY_POINT = TcpDriverEntryPoint 22 | UNLOAD_IMAGE = NetLibDefaultUnload 23 | MODULE_UNI_FILE = TcpDxe.uni 24 | 25 | # 26 | # The following information is for reference only and not required by the build tools. 27 | # 28 | # VALID_ARCHITECTURES = IA32 X64 EBC 29 | # 30 | 31 | [Sources] 32 | TcpDriver.c 33 | SockImpl.c 34 | SockInterface.c 35 | TcpDispatcher.c 36 | TcpOutput.c 37 | TcpMain.c 38 | SockImpl.h 39 | TcpMisc.c 40 | TcpProto.h 41 | TcpOption.c 42 | TcpInput.c 43 | TcpFunc.h 44 | TcpOption.h 45 | TcpTimer.c 46 | TcpMain.h 47 | Socket.h 48 | ComponentName.c 49 | TcpIo.c 50 | TcpDriver.h 51 | 52 | 53 | [Packages] 54 | MdePkg/MdePkg.dec 55 | NetworkPkg/NetworkPkg.dec 56 | 57 | 58 | [LibraryClasses] 59 | BaseLib 60 | BaseMemoryLib 61 | DevicePathLib 62 | DebugLib 63 | MemoryAllocationLib 64 | UefiLib 65 | UefiBootServicesTableLib 66 | UefiDriverEntryPoint 67 | UefiRuntimeServicesTableLib 68 | DpcLib 69 | NetLib 70 | IpIoLib 71 | 72 | 73 | [Protocols] 74 | ## SOMETIMES_CONSUMES 75 | ## SOMETIMES_PRODUCES 76 | gEfiDevicePathProtocolGuid 77 | gEfiIp4ProtocolGuid ## TO_START 78 | gEfiIp4ServiceBindingProtocolGuid ## TO_START 79 | gEfiTcp4ProtocolGuid ## BY_START 80 | gEfiTcp4ServiceBindingProtocolGuid ## BY_START 81 | gEfiIp6ProtocolGuid ## TO_START 82 | gEfiIp6ServiceBindingProtocolGuid ## TO_START 83 | gEfiTcp6ProtocolGuid ## BY_START 84 | gEfiTcp6ServiceBindingProtocolGuid ## BY_START 85 | gEfiHash2ProtocolGuid ## BY_START 86 | gEfiHash2ServiceBindingProtocolGuid ## BY_START 87 | 88 | [Guids] 89 | gEfiHashAlgorithmMD5Guid ## CONSUMES 90 | gEfiHashAlgorithmSha256Guid ## CONSUMES 91 | 92 | [Depex] 93 | gEfiHash2ServiceBindingProtocolGuid 94 | 95 | [UserExtensions.TianoCore."ExtraFiles"] 96 | TcpDxeExtra.uni 97 | -------------------------------------------------------------------------------- /Edk2_Patch/NetworkPkg/TcpDxe/TcpFunc.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | Declaration of external functions shared in TCP driver. 3 | 4 | Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved.
5 | Copyright (c) Microsoft Corporation 6 | SPDX-License-Identifier: BSD-2-Clause-Patent 7 | 8 | **/ 9 | 10 | #ifndef _TCP_FUNC_H_ 11 | #define _TCP_FUNC_H_ 12 | 13 | #include "TcpOption.h" 14 | 15 | #define TCP_COMP_VAL(Min, Max, Default, Val) \ 16 | ((((Val) <= (Max)) && ((Val) >= (Min))) ? (Val) : (Default)) 17 | 18 | /** 19 | Timeout handler prototype. 20 | 21 | @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance. 22 | 23 | **/ 24 | typedef 25 | VOID 26 | (*TCP_TIMER_HANDLER) ( 27 | IN OUT TCP_CB *Tcb 28 | ); 29 | 30 | // 31 | // Functions in TcpMisc.c 32 | // 33 | 34 | /** 35 | Initialize the Tcb locally related members. 36 | 37 | @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance. 38 | 39 | @retval EFI_SUCCESS The operation completed successfully 40 | @retval others The underlying functions failed and could not complete the operation 41 | 42 | **/ 43 | EFI_STATUS 44 | TcpInitTcbLocal ( 45 | IN OUT TCP_CB *Tcb 46 | ); 47 | 48 | /** 49 | Initialize the peer related members. 50 | 51 | @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance. 52 | @param[in] Seg Pointer to the segment that contains the peer's initial information. 53 | @param[in] Opt Pointer to the options announced by the peer. 54 | 55 | **/ 56 | VOID 57 | TcpInitTcbPeer ( 58 | IN OUT TCP_CB *Tcb, 59 | IN TCP_SEG *Seg, 60 | IN TCP_OPTION *Opt 61 | ); 62 | 63 | /** 64 | Try to find one Tcb whose equals to . 65 | 66 | @param[in] Addr Pointer to the IP address needs to match. 67 | @param[in] Port The port number needs to match. 68 | @param[in] Version IP_VERSION_4 indicates TCP is running on IP4 stack. 69 | IP_VERSION_6 indicates TCP is running on IP6 stack. 70 | 71 | 72 | @retval TRUE The Tcb which matches the pairs exists. 73 | @retval FALSE Otherwise 74 | 75 | **/ 76 | BOOLEAN 77 | TcpFindTcbByPeer ( 78 | IN EFI_IP_ADDRESS *Addr, 79 | IN TCP_PORTNO Port, 80 | IN UINT8 Version 81 | ); 82 | 83 | /** 84 | Locate the TCP_CB related to the socket pair. 85 | 86 | @param[in] LocalPort The local port number. 87 | @param[in] LocalIp The local IP address. 88 | @param[in] RemotePort The remote port number. 89 | @param[in] RemoteIp The remote IP address. 90 | @param[in] Version IP_VERSION_4 indicates TCP is running on IP4 stack, 91 | IP_VERSION_6 indicates TCP is running on IP6 stack. 92 | @param[in] Syn If TRUE, the listen sockets are searched. 93 | 94 | @return Pointer to the related TCP_CB. If NULL, no match is found. 95 | 96 | **/ 97 | TCP_CB * 98 | TcpLocateTcb ( 99 | IN TCP_PORTNO LocalPort, 100 | IN EFI_IP_ADDRESS *LocalIp, 101 | IN TCP_PORTNO RemotePort, 102 | IN EFI_IP_ADDRESS *RemoteIp, 103 | IN UINT8 Version, 104 | IN BOOLEAN Syn 105 | ); 106 | 107 | /** 108 | Insert a Tcb into the proper queue. 109 | 110 | @param[in] Tcb Pointer to the TCP_CB to be inserted. 111 | 112 | @retval 0 The Tcb was inserted successfully. 113 | @retval -1 An error condition occurred. 114 | 115 | **/ 116 | INTN 117 | TcpInsertTcb ( 118 | IN TCP_CB *Tcb 119 | ); 120 | 121 | /** 122 | Clone a TCP_CB from Tcb. 123 | 124 | @param[in] Tcb Pointer to the TCP_CB to be cloned. 125 | 126 | @return Pointer to the new cloned TCP_CB. If NULL, an error condition occurred. 127 | 128 | **/ 129 | TCP_CB * 130 | TcpCloneTcb ( 131 | IN TCP_CB *Tcb 132 | ); 133 | 134 | /** 135 | Get the local mss. 136 | 137 | @param[in] Sock Pointer to the socket to get mss. 138 | 139 | @return The mss size. 140 | 141 | **/ 142 | UINT16 143 | TcpGetRcvMss ( 144 | IN SOCKET *Sock 145 | ); 146 | 147 | /** 148 | Set the Tcb's state. 149 | 150 | @param[in] Tcb Pointer to the TCP_CB of this TCP instance. 151 | @param[in] State The state to be set. 152 | 153 | **/ 154 | VOID 155 | TcpSetState ( 156 | IN TCP_CB *Tcb, 157 | IN UINT8 State 158 | ); 159 | 160 | /** 161 | Compute the TCP segment's checksum. 162 | 163 | @param[in] Nbuf Pointer to the buffer that contains the TCP segment. 164 | @param[in] HeadSum The checksum value of the fixed part of pseudo header. 165 | 166 | @return The checksum value. 167 | 168 | **/ 169 | UINT16 170 | TcpChecksum ( 171 | IN NET_BUF *Nbuf, 172 | IN UINT16 HeadSum 173 | ); 174 | 175 | /** 176 | Translate the information from the head of the received TCP 177 | segment Nbuf contains, and fill it into a TCP_SEG structure. 178 | 179 | @param[in] Tcb Pointer to the TCP_CB of this TCP instance. 180 | @param[in, out] Nbuf Pointer to the buffer contains the TCP segment. 181 | 182 | @return Pointer to the TCP_SEG that contains the translated TCP head information. 183 | 184 | **/ 185 | TCP_SEG * 186 | TcpFormatNetbuf ( 187 | IN TCP_CB *Tcb, 188 | IN OUT NET_BUF *Nbuf 189 | ); 190 | 191 | /** 192 | Initialize an active connection, 193 | 194 | @param[in, out] Tcb Pointer to the TCP_CB that wants to initiate a 195 | connection. 196 | 197 | @retval EFI_SUCCESS The operation completed successfully 198 | @retval others The underlying functions failed and could not complete the operation 199 | 200 | **/ 201 | EFI_STATUS 202 | TcpOnAppConnect ( 203 | IN OUT TCP_CB *Tcb 204 | ); 205 | 206 | /** 207 | Application has consumed some data, check whether 208 | to send a window update ack or a delayed ack. 209 | 210 | @param[in] Tcb Pointer to the TCP_CB of this TCP instance. 211 | 212 | **/ 213 | VOID 214 | TcpOnAppConsume ( 215 | IN TCP_CB *Tcb 216 | ); 217 | 218 | /** 219 | Initiate the connection close procedure, called when 220 | applications want to close the connection. 221 | 222 | @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance. 223 | 224 | **/ 225 | VOID 226 | TcpOnAppClose ( 227 | IN OUT TCP_CB *Tcb 228 | ); 229 | 230 | /** 231 | Check whether the application's newly delivered data can be sent out. 232 | 233 | @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance. 234 | 235 | @retval 0 The data has been sent out successfully. 236 | @retval -1 The Tcb is not in a state that data is permitted to 237 | be sent out. 238 | 239 | **/ 240 | INTN 241 | TcpOnAppSend ( 242 | IN OUT TCP_CB *Tcb 243 | ); 244 | 245 | /** 246 | Abort the connection by sending a reset segment: called 247 | when the application wants to abort the connection. 248 | 249 | @param[in] Tcb Pointer to the TCP_CB of the TCP instance. 250 | 251 | **/ 252 | VOID 253 | TcpOnAppAbort ( 254 | IN TCP_CB *Tcb 255 | ); 256 | 257 | /** 258 | Reset the connection related with Tcb. 259 | 260 | @param[in] Tcb Pointer to the TCP_CB of the connection to be reset. 261 | 262 | **/ 263 | VOID 264 | TcpResetConnection ( 265 | IN TCP_CB *Tcb 266 | ); 267 | 268 | /** 269 | Install the device path protocol on the TCP instance. 270 | 271 | @param[in] Sock Pointer to the socket representing the TCP instance. 272 | 273 | @retval EFI_SUCCESS The device path protocol installed. 274 | @retval other Failed to install the device path protocol. 275 | 276 | **/ 277 | EFI_STATUS 278 | TcpInstallDevicePath ( 279 | IN SOCKET *Sock 280 | ); 281 | 282 | // 283 | // Functions in TcpOutput.c 284 | // 285 | 286 | /** 287 | Compute the sequence space left in the old receive window. 288 | 289 | @param[in] Tcb Pointer to the TCP_CB of this TCP instance. 290 | 291 | @return The sequence space left in the old receive window. 292 | 293 | **/ 294 | UINT32 295 | TcpRcvWinOld ( 296 | IN TCP_CB *Tcb 297 | ); 298 | 299 | /** 300 | Compute the current receive window. 301 | 302 | @param[in] Tcb Pointer to the TCP_CB of this TCP instance. 303 | 304 | @return The size of the current receive window, in bytes. 305 | 306 | **/ 307 | UINT32 308 | TcpRcvWinNow ( 309 | IN TCP_CB *Tcb 310 | ); 311 | 312 | /** 313 | Get the maximum SndNxt. 314 | 315 | @param[in] Tcb Pointer to the TCP_CB of this TCP instance. 316 | 317 | @return The sequence number of the maximum SndNxt. 318 | 319 | **/ 320 | TCP_SEQNO 321 | TcpGetMaxSndNxt ( 322 | IN TCP_CB *Tcb 323 | ); 324 | 325 | /** 326 | Compute how much data to send. 327 | 328 | @param[in] Tcb Pointer to the TCP_CB of this TCP instance. 329 | @param[in] Force If TRUE, ignore the sender's SWS avoidance algorithm 330 | and send out data by force. 331 | 332 | @return The length of the data that can be sent. If 0, no data can be sent. 333 | 334 | **/ 335 | UINT32 336 | TcpDataToSend ( 337 | IN TCP_CB *Tcb, 338 | IN INTN Force 339 | ); 340 | 341 | /** 342 | Retransmit the segment from sequence Seq. 343 | 344 | @param[in] Tcb Pointer to the TCP_CB of this TCP instance. 345 | @param[in] Seq The sequence number of the segment to be retransmitted. 346 | 347 | @retval 0 The retransmission succeeded. 348 | @retval -1 An error condition occurred. 349 | 350 | **/ 351 | INTN 352 | TcpRetransmit ( 353 | IN TCP_CB *Tcb, 354 | IN TCP_SEQNO Seq 355 | ); 356 | 357 | /** 358 | Check whether to send data/SYN/FIN and piggyback an ACK. 359 | 360 | @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance. 361 | @param[in] Force If TRUE, ignore the sender's SWS avoidance algorithm 362 | and send out data by force. 363 | 364 | @return The number of bytes sent. 365 | 366 | **/ 367 | INTN 368 | TcpToSendData ( 369 | IN OUT TCP_CB *Tcb, 370 | IN INTN Force 371 | ); 372 | 373 | /** 374 | Check whether to send an ACK or delayed ACK. 375 | 376 | @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance. 377 | 378 | **/ 379 | VOID 380 | TcpToSendAck ( 381 | IN OUT TCP_CB *Tcb 382 | ); 383 | 384 | /** 385 | Send an ACK immediately. 386 | 387 | @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance. 388 | 389 | **/ 390 | VOID 391 | TcpSendAck ( 392 | IN OUT TCP_CB *Tcb 393 | ); 394 | 395 | /** 396 | Send a zero probe segment. It can be used by keepalive and zero window probe. 397 | 398 | @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance. 399 | 400 | @retval 0 The zero probe segment was sent out successfully. 401 | @retval other An error condition occurred. 402 | 403 | **/ 404 | INTN 405 | TcpSendZeroProbe ( 406 | IN OUT TCP_CB *Tcb 407 | ); 408 | 409 | /** 410 | Send a RESET segment in response to the segment received. 411 | 412 | @param[in] Tcb Pointer to the TCP_CB of this TCP instance, may be NULL. 413 | @param[in] Head TCP header of the segment that triggers the reset. 414 | @param[in] Len Length of the segment that triggers the reset. 415 | @param[in] Local Local IP address. 416 | @param[in] Remote Remote peer's IP address. 417 | @param[in] Version IP_VERSION_4 indicates TCP is running on IP4 stack, 418 | IP_VERSION_6 indicates TCP is running on IP6 stack. 419 | 420 | @retval 0 A reset is sent or no need to send it. 421 | @retval -1 No reset is sent. 422 | 423 | **/ 424 | INTN 425 | TcpSendReset ( 426 | IN TCP_CB *Tcb, 427 | IN TCP_HEAD *Head, 428 | IN INT32 Len, 429 | IN EFI_IP_ADDRESS *Local, 430 | IN EFI_IP_ADDRESS *Remote, 431 | IN UINT8 Version 432 | ); 433 | 434 | /** 435 | Verify that the segment is in good shape. 436 | 437 | @param[in] Nbuf Buffer that contains the segment to be checked. 438 | 439 | @retval 0 The segment is broken. 440 | @retval 1 The segment is in good shape. 441 | 442 | **/ 443 | INTN 444 | TcpVerifySegment ( 445 | IN NET_BUF *Nbuf 446 | ); 447 | 448 | // 449 | // Functions from TcpInput.c 450 | // 451 | 452 | /** 453 | Process the received ICMP error messages for TCP. 454 | 455 | @param[in] Nbuf Buffer that contains part of the TCP segment without IP header 456 | truncated from the ICMP error packet. 457 | @param[in] IcmpErr The ICMP error code interpreted from an ICMP error packet. 458 | @param[in] Src Source address of the ICMP error message. 459 | @param[in] Dst Destination address of the ICMP error message. 460 | @param[in] Version IP_VERSION_4 indicates IP4 stack, IP_VERSION_6 indicates 461 | IP6 stack. 462 | 463 | **/ 464 | VOID 465 | TcpIcmpInput ( 466 | IN NET_BUF *Nbuf, 467 | IN UINT8 IcmpErr, 468 | IN EFI_IP_ADDRESS *Src, 469 | IN EFI_IP_ADDRESS *Dst, 470 | IN UINT8 Version 471 | ); 472 | 473 | /** 474 | Process the received TCP segments. 475 | 476 | @param[in] Nbuf Buffer that contains received TCP segment without an IP header. 477 | @param[in] Src Source address of the segment, or the peer's IP address. 478 | @param[in] Dst Destination address of the segment, or the local end's IP 479 | address. 480 | @param[in] Version IP_VERSION_4 indicates IP4 stack, IP_VERSION_6 indicates 481 | IP6 stack. 482 | 483 | @retval 0 The segment processed successfully. It is either accepted or 484 | discarded. But no connection is reset by the segment. 485 | @retval -1 A connection is reset by the segment. 486 | 487 | **/ 488 | INTN 489 | TcpInput ( 490 | IN NET_BUF *Nbuf, 491 | IN EFI_IP_ADDRESS *Src, 492 | IN EFI_IP_ADDRESS *Dst, 493 | IN UINT8 Version 494 | ); 495 | 496 | // 497 | // Functions in TcpTimer.c 498 | // 499 | 500 | /** 501 | Close the TCP connection. 502 | 503 | @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance. 504 | 505 | **/ 506 | VOID 507 | TcpClose ( 508 | IN OUT TCP_CB *Tcb 509 | ); 510 | 511 | /** 512 | Heart beat timer handler, queues the DPC at TPL_CALLBACK. 513 | 514 | @param[in] Event Timer event signaled, ignored. 515 | @param[in] Context Context of the timer event, ignored. 516 | 517 | **/ 518 | VOID 519 | EFIAPI 520 | TcpTicking ( 521 | IN EFI_EVENT Event, 522 | IN VOID *Context 523 | ); 524 | 525 | /** 526 | Enable a TCP timer. 527 | 528 | @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance. 529 | @param[in] Timer The index of the timer to be enabled. 530 | @param[in] TimeOut The timeout value of this timer. 531 | 532 | **/ 533 | VOID 534 | TcpSetTimer ( 535 | IN OUT TCP_CB *Tcb, 536 | IN UINT16 Timer, 537 | IN UINT32 TimeOut 538 | ); 539 | 540 | /** 541 | Clear one TCP timer. 542 | 543 | @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance. 544 | @param[in] Timer The index of the timer to be cleared. 545 | 546 | **/ 547 | VOID 548 | TcpClearTimer ( 549 | IN OUT TCP_CB *Tcb, 550 | IN UINT16 Timer 551 | ); 552 | 553 | /** 554 | Clear all TCP timers. 555 | 556 | @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance. 557 | 558 | **/ 559 | VOID 560 | TcpClearAllTimer ( 561 | IN OUT TCP_CB *Tcb 562 | ); 563 | 564 | /** 565 | Enable the window prober timer and set the timeout value. 566 | 567 | @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance. 568 | 569 | **/ 570 | VOID 571 | TcpSetProbeTimer ( 572 | IN OUT TCP_CB *Tcb 573 | ); 574 | 575 | /** 576 | Enable the keepalive timer and set the timeout value. 577 | 578 | @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance. 579 | 580 | **/ 581 | VOID 582 | TcpSetKeepaliveTimer ( 583 | IN OUT TCP_CB *Tcb 584 | ); 585 | 586 | // 587 | // Functions in TcpIo.c 588 | // 589 | 590 | /** 591 | Packet receive callback function provided to IP_IO. Used to call 592 | the proper function to handle the packet received by IP. 593 | 594 | @param[in] Status Result of the receive request. 595 | @param[in] IcmpErr Valid when Status is EFI_ICMP_ERROR. 596 | @param[in] NetSession The IP session for the received packet. 597 | @param[in] Pkt Packet received. 598 | @param[in] Context The data provided by the user for the received packet when 599 | the callback is registered in IP_IO_OPEN_DATA::RcvdContext. 600 | This is an optional parameter that may be NULL. 601 | 602 | **/ 603 | VOID 604 | EFIAPI 605 | TcpRxCallback ( 606 | IN EFI_STATUS Status, 607 | IN UINT8 IcmpErr, 608 | IN EFI_NET_SESSION_DATA *NetSession, 609 | IN NET_BUF *Pkt, 610 | IN VOID *Context OPTIONAL 611 | ); 612 | 613 | /** 614 | Send the segment to IP via IpIo function. 615 | 616 | @param[in] Tcb Pointer to the TCP_CB of this TCP instance. 617 | @param[in] Nbuf Pointer to the TCP segment to be sent. 618 | @param[in] Src Source address of the TCP segment. 619 | @param[in] Dest Destination address of the TCP segment. 620 | @param[in] Version IP_VERSION_4 or IP_VERSION_6 621 | 622 | @retval 0 The segment was sent out successfully. 623 | @retval -1 The segment failed to be sent. 624 | 625 | **/ 626 | INTN 627 | TcpSendIpPacket ( 628 | IN TCP_CB *Tcb, 629 | IN NET_BUF *Nbuf, 630 | IN EFI_IP_ADDRESS *Src, 631 | IN EFI_IP_ADDRESS *Dest, 632 | IN UINT8 Version 633 | ); 634 | 635 | /** 636 | Refresh the remote peer's Neighbor Cache State if already exists. 637 | 638 | @param[in] Tcb Pointer to the TCP_CB of this TCP instance. 639 | @param[in] Neighbor Source address of the TCP segment. 640 | @param[in] Timeout Time in 100-ns units that this entry will remain 641 | in the neighbor cache. A value of zero means that 642 | the entry is permanent. A value of non-zero means 643 | that the entry is dynamic and will be deleted 644 | after Timeout. 645 | 646 | @retval EFI_SUCCESS Successfully updated the neighbor relationship. 647 | @retval EFI_NOT_STARTED The IpIo is not configured. 648 | @retval EFI_INVALID_PARAMETER Any input parameter is invalid. 649 | @retval EFI_OUT_OF_RESOURCES Failed to allocate some resources. 650 | @retval EFI_NOT_FOUND This entry is not in the neighbor table. 651 | 652 | **/ 653 | EFI_STATUS 654 | Tcp6RefreshNeighbor ( 655 | IN TCP_CB *Tcb, 656 | IN EFI_IP_ADDRESS *Neighbor, 657 | IN UINT32 Timeout 658 | ); 659 | 660 | // 661 | // Functions in TcpDispatcher.c 662 | // 663 | 664 | /** 665 | The protocol handler provided to the socket layer, used to 666 | dispatch the socket level requests by calling the corresponding 667 | TCP layer functions. 668 | 669 | @param[in] Sock Pointer to the socket of this TCP instance. 670 | @param[in] Request The code of this operation request. 671 | @param[in] Data Pointer to the operation specific data passed in 672 | together with the operation request. This is an 673 | optional parameter that may be NULL. 674 | 675 | @retval EFI_SUCCESS The socket request completed successfully. 676 | @retval other The error status returned by the corresponding TCP 677 | layer function. 678 | 679 | **/ 680 | EFI_STATUS 681 | TcpDispatcher ( 682 | IN SOCKET *Sock, 683 | IN UINT8 Request, 684 | IN VOID *Data OPTIONAL 685 | ); 686 | 687 | #endif 688 | -------------------------------------------------------------------------------- /Edk2_Patch/NetworkPkg/TcpDxe/TcpTimer.c: -------------------------------------------------------------------------------- 1 | /** @file 2 | TCP timer related functions. 3 | 4 | Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
5 | Copyright (c) Microsoft Corporation 6 | SPDX-License-Identifier: BSD-2-Clause-Patent 7 | 8 | **/ 9 | 10 | #include "TcpMain.h" 11 | 12 | UINT32 mTcpTick = 1000; 13 | 14 | /** 15 | Connect timeout handler. 16 | 17 | @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance. 18 | 19 | **/ 20 | VOID 21 | TcpConnectTimeout ( 22 | IN OUT TCP_CB *Tcb 23 | ); 24 | 25 | /** 26 | Timeout handler for TCP retransmission timer. 27 | 28 | @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance. 29 | 30 | **/ 31 | VOID 32 | TcpRexmitTimeout ( 33 | IN OUT TCP_CB *Tcb 34 | ); 35 | 36 | /** 37 | Timeout handler for window probe timer. 38 | 39 | @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance. 40 | 41 | **/ 42 | VOID 43 | TcpProbeTimeout ( 44 | IN OUT TCP_CB *Tcb 45 | ); 46 | 47 | /** 48 | Timeout handler for keepalive timer. 49 | 50 | @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance. 51 | 52 | **/ 53 | VOID 54 | TcpKeepaliveTimeout ( 55 | IN OUT TCP_CB *Tcb 56 | ); 57 | 58 | /** 59 | Timeout handler for FIN_WAIT_2 timer. 60 | 61 | @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance. 62 | 63 | **/ 64 | VOID 65 | TcpFinwait2Timeout ( 66 | IN OUT TCP_CB *Tcb 67 | ); 68 | 69 | /** 70 | Timeout handler for 2MSL timer. 71 | 72 | @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance. 73 | 74 | **/ 75 | VOID 76 | Tcp2MSLTimeout ( 77 | IN OUT TCP_CB *Tcb 78 | ); 79 | 80 | TCP_TIMER_HANDLER mTcpTimerHandler[TCP_TIMER_NUMBER] = { 81 | TcpConnectTimeout, 82 | TcpRexmitTimeout, 83 | TcpProbeTimeout, 84 | TcpKeepaliveTimeout, 85 | TcpFinwait2Timeout, 86 | Tcp2MSLTimeout, 87 | }; 88 | 89 | /** 90 | Close the TCP connection. 91 | 92 | @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance. 93 | 94 | **/ 95 | VOID 96 | TcpClose ( 97 | IN OUT TCP_CB *Tcb 98 | ) 99 | { 100 | NetbufFreeList (&Tcb->SndQue); 101 | NetbufFreeList (&Tcb->RcvQue); 102 | 103 | TcpSetState (Tcb, TCP_CLOSED); 104 | } 105 | 106 | /** 107 | Backoff the RTO. 108 | 109 | @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance. 110 | 111 | **/ 112 | VOID 113 | TcpBackoffRto ( 114 | IN OUT TCP_CB *Tcb 115 | ) 116 | { 117 | // 118 | // Fold the RTT estimate if too many times, the estimate 119 | // may be wrong, fold it. So the next time a valid 120 | // measurement is sampled, we can start fresh. 121 | // 122 | if ((Tcb->LossTimes >= TCP_FOLD_RTT) && (Tcb->SRtt != 0)) { 123 | Tcb->RttVar += Tcb->SRtt >> 2; 124 | Tcb->SRtt = 0; 125 | } 126 | 127 | Tcb->Rto <<= 1; 128 | 129 | if (Tcb->Rto < TCP_RTO_MIN) { 130 | Tcb->Rto = TCP_RTO_MIN; 131 | } else if (Tcb->Rto > TCP_RTO_MAX) { 132 | Tcb->Rto = TCP_RTO_MAX; 133 | } 134 | } 135 | 136 | /** 137 | Connect timeout handler. 138 | 139 | @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance. 140 | 141 | **/ 142 | VOID 143 | TcpConnectTimeout ( 144 | IN OUT TCP_CB *Tcb 145 | ) 146 | { 147 | if (!TCP_CONNECTED (Tcb->State)) { 148 | DEBUG ( 149 | (DEBUG_ERROR, 150 | "TcpConnectTimeout: connection closed because connection timer timeout for TCB %p\n", 151 | Tcb) 152 | ); 153 | 154 | if (EFI_ABORTED == Tcb->Sk->SockError) { 155 | SOCK_ERROR (Tcb->Sk, EFI_TIMEOUT); 156 | } 157 | 158 | if (TCP_SYN_RCVD == Tcb->State) { 159 | DEBUG ( 160 | (DEBUG_WARN, 161 | "TcpConnectTimeout: send reset because connection timer timeout for TCB %p\n", 162 | Tcb) 163 | ); 164 | 165 | TcpResetConnection (Tcb); 166 | } 167 | 168 | TcpClose (Tcb); 169 | } 170 | } 171 | 172 | /** 173 | Timeout handler for TCP retransmission timer. 174 | 175 | @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance. 176 | 177 | **/ 178 | VOID 179 | TcpRexmitTimeout ( 180 | IN OUT TCP_CB *Tcb 181 | ) 182 | { 183 | UINT32 FlightSize; 184 | 185 | DEBUG ( 186 | (DEBUG_WARN, 187 | "TcpRexmitTimeout: transmission timeout for TCB %p\n", 188 | Tcb) 189 | ); 190 | 191 | // 192 | // Set the congestion window. FlightSize is the 193 | // amount of data that has been sent but not 194 | // yet ACKed. 195 | // 196 | FlightSize = TCP_SUB_SEQ (Tcb->SndNxt, Tcb->SndUna); 197 | Tcb->Ssthresh = MAX ((UINT32)(2 * Tcb->SndMss), FlightSize / 2); 198 | 199 | Tcb->CWnd = Tcb->SndMss; 200 | Tcb->LossRecover = Tcb->SndNxt; 201 | 202 | Tcb->LossTimes++; 203 | if ((Tcb->LossTimes > Tcb->MaxRexmit) && !TCP_TIMER_ON (Tcb->EnabledTimer, TCP_TIMER_CONNECT)) { 204 | DEBUG ( 205 | (DEBUG_ERROR, 206 | "TcpRexmitTimeout: connection closed because too many timeouts for TCB %p\n", 207 | Tcb) 208 | ); 209 | 210 | if (EFI_ABORTED == Tcb->Sk->SockError) { 211 | SOCK_ERROR (Tcb->Sk, EFI_TIMEOUT); 212 | } 213 | 214 | TcpClose (Tcb); 215 | return; 216 | } 217 | 218 | TcpBackoffRto (Tcb); 219 | TcpRetransmit (Tcb, Tcb->SndUna); 220 | TcpSetTimer (Tcb, TCP_TIMER_REXMIT, Tcb->Rto); 221 | 222 | Tcb->CongestState = TCP_CONGEST_LOSS; 223 | 224 | TCP_CLEAR_FLG (Tcb->CtrlFlag, TCP_CTRL_RTT_ON); 225 | } 226 | 227 | /** 228 | Timeout handler for window probe timer. 229 | 230 | @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance. 231 | 232 | **/ 233 | VOID 234 | TcpProbeTimeout ( 235 | IN OUT TCP_CB *Tcb 236 | ) 237 | { 238 | // 239 | // This is the timer for sender's SWSA. RFC1122 requires 240 | // a timer set for sender's SWSA, and suggest combine it 241 | // with window probe timer. If data is sent, don't set 242 | // the probe timer, since retransmit timer is on. 243 | // 244 | if ((TcpDataToSend (Tcb, 1) != 0) && (TcpToSendData (Tcb, 1) > 0)) { 245 | ASSERT (TCP_TIMER_ON (Tcb->EnabledTimer, TCP_TIMER_REXMIT) != 0); 246 | Tcb->ProbeTimerOn = FALSE; 247 | return; 248 | } 249 | 250 | TcpSendZeroProbe (Tcb); 251 | TcpSetProbeTimer (Tcb); 252 | } 253 | 254 | /** 255 | Timeout handler for keepalive timer. 256 | 257 | @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance. 258 | 259 | **/ 260 | VOID 261 | TcpKeepaliveTimeout ( 262 | IN OUT TCP_CB *Tcb 263 | ) 264 | { 265 | Tcb->KeepAliveProbes++; 266 | 267 | // 268 | // Too many Keep-alive probes, drop the connection 269 | // 270 | if (Tcb->KeepAliveProbes > Tcb->MaxKeepAlive) { 271 | if (EFI_ABORTED == Tcb->Sk->SockError) { 272 | SOCK_ERROR (Tcb->Sk, EFI_TIMEOUT); 273 | } 274 | 275 | TcpClose (Tcb); 276 | return; 277 | } 278 | 279 | TcpSendZeroProbe (Tcb); 280 | TcpSetKeepaliveTimer (Tcb); 281 | } 282 | 283 | /** 284 | Timeout handler for FIN_WAIT_2 timer. 285 | 286 | @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance. 287 | 288 | **/ 289 | VOID 290 | TcpFinwait2Timeout ( 291 | IN OUT TCP_CB *Tcb 292 | ) 293 | { 294 | DEBUG ( 295 | (DEBUG_WARN, 296 | "TcpFinwait2Timeout: connection closed because FIN_WAIT2 timer timeouts for TCB %p\n", 297 | Tcb) 298 | ); 299 | 300 | TcpClose (Tcb); 301 | } 302 | 303 | /** 304 | Timeout handler for 2MSL timer. 305 | 306 | @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance. 307 | 308 | **/ 309 | VOID 310 | Tcp2MSLTimeout ( 311 | IN OUT TCP_CB *Tcb 312 | ) 313 | { 314 | DEBUG ( 315 | (DEBUG_WARN, 316 | "Tcp2MSLTimeout: connection closed because TIME_WAIT timer timeouts for TCB %p\n", 317 | Tcb) 318 | ); 319 | 320 | TcpClose (Tcb); 321 | } 322 | 323 | /** 324 | Update the timer status and the next expire time according to the timers 325 | to expire in a specific future time slot. 326 | 327 | @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance. 328 | 329 | **/ 330 | VOID 331 | TcpUpdateTimer ( 332 | IN OUT TCP_CB *Tcb 333 | ) 334 | { 335 | UINT16 Index; 336 | 337 | // 338 | // Don't use a too large value to init NextExpire 339 | // since mTcpTick wraps around as sequence no does. 340 | // 341 | Tcb->NextExpire = TCP_EXPIRE_TIME; 342 | TCP_CLEAR_FLG (Tcb->CtrlFlag, TCP_CTRL_TIMER_ON); 343 | 344 | for (Index = 0; Index < TCP_TIMER_NUMBER; Index++) { 345 | if (TCP_TIMER_ON (Tcb->EnabledTimer, Index) && 346 | TCP_TIME_LT (Tcb->Timer[Index], mTcpTick + Tcb->NextExpire) 347 | ) 348 | { 349 | Tcb->NextExpire = TCP_SUB_TIME (Tcb->Timer[Index], mTcpTick); 350 | TCP_SET_FLG (Tcb->CtrlFlag, TCP_CTRL_TIMER_ON); 351 | } 352 | } 353 | } 354 | 355 | /** 356 | Enable a TCP timer. 357 | 358 | @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance. 359 | @param[in] Timer The index of the timer to be enabled. 360 | @param[in] TimeOut The timeout value of this timer. 361 | 362 | **/ 363 | VOID 364 | TcpSetTimer ( 365 | IN OUT TCP_CB *Tcb, 366 | IN UINT16 Timer, 367 | IN UINT32 TimeOut 368 | ) 369 | { 370 | TCP_SET_TIMER (Tcb->EnabledTimer, Timer); 371 | Tcb->Timer[Timer] = mTcpTick + TimeOut; 372 | 373 | TcpUpdateTimer (Tcb); 374 | } 375 | 376 | /** 377 | Clear one TCP timer. 378 | 379 | @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance. 380 | @param[in] Timer The index of the timer to be cleared. 381 | 382 | **/ 383 | VOID 384 | TcpClearTimer ( 385 | IN OUT TCP_CB *Tcb, 386 | IN UINT16 Timer 387 | ) 388 | { 389 | TCP_CLEAR_TIMER (Tcb->EnabledTimer, Timer); 390 | TcpUpdateTimer (Tcb); 391 | } 392 | 393 | /** 394 | Clear all TCP timers. 395 | 396 | @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance. 397 | 398 | **/ 399 | VOID 400 | TcpClearAllTimer ( 401 | IN OUT TCP_CB *Tcb 402 | ) 403 | { 404 | Tcb->EnabledTimer = 0; 405 | TcpUpdateTimer (Tcb); 406 | } 407 | 408 | /** 409 | Enable the window prober timer and set the timeout value. 410 | 411 | @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance. 412 | 413 | **/ 414 | VOID 415 | TcpSetProbeTimer ( 416 | IN OUT TCP_CB *Tcb 417 | ) 418 | { 419 | if (!Tcb->ProbeTimerOn) { 420 | Tcb->ProbeTime = Tcb->Rto; 421 | Tcb->ProbeTimerOn = TRUE; 422 | } else { 423 | Tcb->ProbeTime <<= 1; 424 | } 425 | 426 | if (Tcb->ProbeTime < TCP_RTO_MIN) { 427 | Tcb->ProbeTime = TCP_RTO_MIN; 428 | } else if (Tcb->ProbeTime > TCP_RTO_MAX) { 429 | Tcb->ProbeTime = TCP_RTO_MAX; 430 | } 431 | 432 | TcpSetTimer (Tcb, TCP_TIMER_PROBE, Tcb->ProbeTime); 433 | } 434 | 435 | /** 436 | Enable the keepalive timer and set the timeout value. 437 | 438 | @param[in, out] Tcb Pointer to the TCP_CB of this TCP instance. 439 | 440 | **/ 441 | VOID 442 | TcpSetKeepaliveTimer ( 443 | IN OUT TCP_CB *Tcb 444 | ) 445 | { 446 | if (TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_NO_KEEPALIVE)) { 447 | return; 448 | } 449 | 450 | // 451 | // Set the timer to KeepAliveIdle if either 452 | // 1. the keepalive timer is off 453 | // 2. The keepalive timer is on, but the idle 454 | // is less than KeepAliveIdle, that means the 455 | // connection is alive since our last probe. 456 | // 457 | if (!TCP_TIMER_ON (Tcb->EnabledTimer, TCP_TIMER_KEEPALIVE) || 458 | (Tcb->Idle < Tcb->KeepAliveIdle) 459 | ) 460 | { 461 | TcpSetTimer (Tcb, TCP_TIMER_KEEPALIVE, Tcb->KeepAliveIdle); 462 | Tcb->KeepAliveProbes = 0; 463 | } else { 464 | TcpSetTimer (Tcb, TCP_TIMER_KEEPALIVE, Tcb->KeepAlivePeriod); 465 | } 466 | } 467 | 468 | /** 469 | Heart beat timer handler. 470 | 471 | @param[in] Context Context of the timer event, ignored. 472 | 473 | **/ 474 | VOID 475 | EFIAPI 476 | TcpTickingDpc ( 477 | IN VOID *Context 478 | ) 479 | { 480 | LIST_ENTRY *Entry; 481 | LIST_ENTRY *Next; 482 | TCP_CB *Tcb; 483 | INT16 Index; 484 | 485 | mTcpTick++; 486 | 487 | // 488 | // Don't use LIST_FOR_EACH, which isn't delete safe. 489 | // 490 | for (Entry = mTcpRunQue.ForwardLink; Entry != &mTcpRunQue; Entry = Next) { 491 | Next = Entry->ForwardLink; 492 | 493 | Tcb = NET_LIST_USER_STRUCT (Entry, TCP_CB, List); 494 | 495 | if (Tcb->State == TCP_CLOSED) { 496 | continue; 497 | } 498 | 499 | // 500 | // The connection is doing RTT measurement. 501 | // 502 | if (TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_RTT_ON)) { 503 | Tcb->RttMeasure++; 504 | } 505 | 506 | Tcb->Idle++; 507 | 508 | if (Tcb->DelayedAck != 0) { 509 | TcpSendAck (Tcb); 510 | } 511 | 512 | if ((Tcb->IpInfo->IpVersion == IP_VERSION_6) && (Tcb->Tick > 0)) { 513 | Tcb->Tick--; 514 | } 515 | 516 | // 517 | // No timer is active or no timer expired 518 | // 519 | if (!TCP_FLG_ON (Tcb->CtrlFlag, TCP_CTRL_TIMER_ON) || ((--Tcb->NextExpire) > 0)) { 520 | continue; 521 | } 522 | 523 | // 524 | // Call the timeout handler for each expired timer. 525 | // 526 | for (Index = 0; Index < TCP_TIMER_NUMBER; Index++) { 527 | if (TCP_TIMER_ON (Tcb->EnabledTimer, Index) && TCP_TIME_LEQ (Tcb->Timer[Index], mTcpTick)) { 528 | // 529 | // disable the timer before calling the handler 530 | // in case the handler enables it again. 531 | // 532 | TCP_CLEAR_TIMER (Tcb->EnabledTimer, Index); 533 | mTcpTimerHandler[Index](Tcb); 534 | 535 | // 536 | // The Tcb may have been deleted by the timer, or 537 | // no other timer is set. 538 | // 539 | if ((Next->BackLink != Entry) || (Tcb->EnabledTimer == 0)) { 540 | break; 541 | } 542 | } 543 | } 544 | 545 | // 546 | // If the Tcb still exist or some timer is set, update the timer 547 | // 548 | if (Index == TCP_TIMER_NUMBER) { 549 | TcpUpdateTimer (Tcb); 550 | } 551 | } 552 | } 553 | 554 | /** 555 | Heart beat timer handler, queues the DPC at TPL_CALLBACK. 556 | 557 | @param[in] Event Timer event signaled, ignored. 558 | @param[in] Context Context of the timer event, ignored. 559 | 560 | **/ 561 | VOID 562 | EFIAPI 563 | TcpTicking ( 564 | IN EFI_EVENT Event, 565 | IN VOID *Context 566 | ) 567 | { 568 | QueueDpc (TPL_CALLBACK, TcpTickingDpc, Context); 569 | } 570 | -------------------------------------------------------------------------------- /Edk2_Patch/NetworkPkg/Udp4Dxe/Udp4Driver.c: -------------------------------------------------------------------------------- 1 | /** @file 2 | 3 | Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
4 | Copyright (c) Microsoft Corporation 5 | SPDX-License-Identifier: BSD-2-Clause-Patent 6 | 7 | **/ 8 | 9 | #include "Udp4Impl.h" 10 | 11 | EFI_DRIVER_BINDING_PROTOCOL gUdp4DriverBinding = { 12 | Udp4DriverBindingSupported, 13 | Udp4DriverBindingStart, 14 | Udp4DriverBindingStop, 15 | 0xa, 16 | NULL, 17 | NULL 18 | }; 19 | 20 | EFI_SERVICE_BINDING_PROTOCOL mUdp4ServiceBinding = { 21 | Udp4ServiceBindingCreateChild, 22 | Udp4ServiceBindingDestroyChild 23 | }; 24 | 25 | /** 26 | Callback function which provided by user to remove one node in NetDestroyLinkList process. 27 | 28 | @param[in] Entry The entry to be removed. 29 | @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList. 30 | 31 | @retval EFI_SUCCESS The entry has been removed successfully. 32 | @retval Others Fail to remove the entry. 33 | 34 | **/ 35 | EFI_STATUS 36 | EFIAPI 37 | Udp4DestroyChildEntryInHandleBuffer ( 38 | IN LIST_ENTRY *Entry, 39 | IN VOID *Context 40 | ) 41 | { 42 | UDP4_INSTANCE_DATA *Instance; 43 | EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; 44 | UINTN NumberOfChildren; 45 | EFI_HANDLE *ChildHandleBuffer; 46 | 47 | if ((Entry == NULL) || (Context == NULL)) { 48 | return EFI_INVALID_PARAMETER; 49 | } 50 | 51 | Instance = NET_LIST_USER_STRUCT_S (Entry, UDP4_INSTANCE_DATA, Link, UDP4_INSTANCE_DATA_SIGNATURE); 52 | ServiceBinding = ((UDP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *)Context)->ServiceBinding; 53 | NumberOfChildren = ((UDP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *)Context)->NumberOfChildren; 54 | ChildHandleBuffer = ((UDP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *)Context)->ChildHandleBuffer; 55 | 56 | if (!NetIsInHandleBuffer (Instance->ChildHandle, NumberOfChildren, ChildHandleBuffer)) { 57 | return EFI_SUCCESS; 58 | } 59 | 60 | return ServiceBinding->DestroyChild (ServiceBinding, Instance->ChildHandle); 61 | } 62 | 63 | /** 64 | Test to see if this driver supports ControllerHandle. This service 65 | is called by the EFI boot service ConnectController(). In 66 | order to make drivers as small as possible, there are a few calling 67 | restrictions for this service. ConnectController() must 68 | follow these calling restrictions. If any other agent wishes to call 69 | Supported() it must also follow these calling restrictions. 70 | 71 | @param[in] This Protocol instance pointer. 72 | @param[in] ControllerHandle Handle of device to test 73 | @param[in] RemainingDevicePath Optional parameter use to pick a specific child 74 | device to start. 75 | 76 | @retval EFI_SUCCESS This driver supports this device 77 | @retval EFI_ALREADY_STARTED This driver is already running on this device 78 | @retval other This driver does not support this device 79 | 80 | **/ 81 | EFI_STATUS 82 | EFIAPI 83 | Udp4DriverBindingSupported ( 84 | IN EFI_DRIVER_BINDING_PROTOCOL *This, 85 | IN EFI_HANDLE ControllerHandle, 86 | IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL 87 | ) 88 | { 89 | EFI_STATUS Status; 90 | 91 | // 92 | // Test for the Udp4ServiceBinding Protocol 93 | // 94 | Status = gBS->OpenProtocol ( 95 | ControllerHandle, 96 | &gEfiUdp4ServiceBindingProtocolGuid, 97 | NULL, 98 | This->DriverBindingHandle, 99 | ControllerHandle, 100 | EFI_OPEN_PROTOCOL_TEST_PROTOCOL 101 | ); 102 | if (!EFI_ERROR (Status)) { 103 | return EFI_ALREADY_STARTED; 104 | } 105 | 106 | // 107 | // Test for the Ip4 Protocol 108 | // 109 | Status = gBS->OpenProtocol ( 110 | ControllerHandle, 111 | &gEfiIp4ServiceBindingProtocolGuid, 112 | NULL, 113 | This->DriverBindingHandle, 114 | ControllerHandle, 115 | EFI_OPEN_PROTOCOL_TEST_PROTOCOL 116 | ); 117 | 118 | return Status; 119 | } 120 | 121 | /** 122 | Start this driver on ControllerHandle. This service is called by the 123 | EFI boot service ConnectController(). In order to make 124 | drivers as small as possible, there are a few calling restrictions for 125 | this service. ConnectController() must follow these 126 | calling restrictions. If any other agent wishes to call Start() it 127 | must also follow these calling restrictions. 128 | 129 | @param[in] This Protocol instance pointer. 130 | @param[in] ControllerHandle Handle of device to bind driver to 131 | @param[in] RemainingDevicePath Optional parameter use to pick a specific child 132 | device to start. 133 | 134 | @retval EFI_SUCCESS This driver is added to ControllerHandle 135 | @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle 136 | @retval other This driver does not support this device 137 | 138 | **/ 139 | EFI_STATUS 140 | EFIAPI 141 | Udp4DriverBindingStart ( 142 | IN EFI_DRIVER_BINDING_PROTOCOL *This, 143 | IN EFI_HANDLE ControllerHandle, 144 | IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL 145 | ) 146 | { 147 | EFI_STATUS Status; 148 | UDP4_SERVICE_DATA *Udp4Service; 149 | 150 | // 151 | // Allocate Private Context Data Structure. 152 | // 153 | Udp4Service = AllocatePool (sizeof (UDP4_SERVICE_DATA)); 154 | if (Udp4Service == NULL) { 155 | return EFI_OUT_OF_RESOURCES; 156 | } 157 | 158 | Status = Udp4CreateService (Udp4Service, This->DriverBindingHandle, ControllerHandle); 159 | if (EFI_ERROR (Status)) { 160 | FreePool (Udp4Service); 161 | return Status; 162 | } 163 | 164 | // 165 | // Install the Udp4ServiceBindingProtocol on the ControllerHandle. 166 | // 167 | Status = gBS->InstallMultipleProtocolInterfaces ( 168 | &ControllerHandle, 169 | &gEfiUdp4ServiceBindingProtocolGuid, 170 | &Udp4Service->ServiceBinding, 171 | NULL 172 | ); 173 | if (EFI_ERROR (Status)) { 174 | Udp4CleanService (Udp4Service); 175 | FreePool (Udp4Service); 176 | } 177 | 178 | return Status; 179 | } 180 | 181 | /** 182 | Stop this driver on ControllerHandle. This service is called by the 183 | EFI boot service DisconnectController(). In order to 184 | make drivers as small as possible, there are a few calling 185 | restrictions for this service. DisconnectController() 186 | must follow these calling restrictions. If any other agent wishes 187 | to call Stop() it must also follow these calling restrictions. 188 | 189 | @param[in] This Protocol instance pointer. 190 | @param[in] ControllerHandle Handle of device to stop driver on 191 | @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If number of 192 | children is zero stop the entire bus driver. 193 | @param[in] ChildHandleBuffer List of Child Handles to Stop. 194 | 195 | @retval EFI_SUCCESS This driver is removed ControllerHandle 196 | @retval other This driver was not removed from this device 197 | 198 | **/ 199 | EFI_STATUS 200 | EFIAPI 201 | Udp4DriverBindingStop ( 202 | IN EFI_DRIVER_BINDING_PROTOCOL *This, 203 | IN EFI_HANDLE ControllerHandle, 204 | IN UINTN NumberOfChildren, 205 | IN EFI_HANDLE *ChildHandleBuffer 206 | ) 207 | { 208 | EFI_STATUS Status; 209 | EFI_HANDLE NicHandle; 210 | EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; 211 | UDP4_SERVICE_DATA *Udp4Service; 212 | UDP4_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context; 213 | LIST_ENTRY *List; 214 | 215 | // 216 | // Find the NicHandle where UDP4 ServiceBinding Protocol is installed. 217 | // 218 | NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp4ProtocolGuid); 219 | if (NicHandle == NULL) { 220 | return EFI_SUCCESS; 221 | } 222 | 223 | // 224 | // Retrieve the UDP4 ServiceBinding Protocol. 225 | // 226 | Status = gBS->OpenProtocol ( 227 | NicHandle, 228 | &gEfiUdp4ServiceBindingProtocolGuid, 229 | (VOID **)&ServiceBinding, 230 | This->DriverBindingHandle, 231 | NicHandle, 232 | EFI_OPEN_PROTOCOL_GET_PROTOCOL 233 | ); 234 | if (EFI_ERROR (Status)) { 235 | return EFI_DEVICE_ERROR; 236 | } 237 | 238 | Udp4Service = UDP4_SERVICE_DATA_FROM_THIS (ServiceBinding); 239 | if (NumberOfChildren != 0) { 240 | // 241 | // NumberOfChildren is not zero, destroy the children instances in ChildHandleBuffer. 242 | // 243 | List = &Udp4Service->ChildrenList; 244 | Context.ServiceBinding = ServiceBinding; 245 | Context.NumberOfChildren = NumberOfChildren; 246 | Context.ChildHandleBuffer = ChildHandleBuffer; 247 | Status = NetDestroyLinkList ( 248 | List, 249 | Udp4DestroyChildEntryInHandleBuffer, 250 | &Context, 251 | NULL 252 | ); 253 | } else { 254 | gBS->UninstallMultipleProtocolInterfaces ( 255 | NicHandle, 256 | &gEfiUdp4ServiceBindingProtocolGuid, 257 | &Udp4Service->ServiceBinding, 258 | NULL 259 | ); 260 | 261 | Udp4CleanService (Udp4Service); 262 | 263 | if (gUdpControllerNameTable != NULL) { 264 | FreeUnicodeStringTable (gUdpControllerNameTable); 265 | gUdpControllerNameTable = NULL; 266 | } 267 | 268 | FreePool (Udp4Service); 269 | } 270 | 271 | return Status; 272 | } 273 | 274 | /** 275 | Creates a child handle and installs a protocol. 276 | 277 | The CreateChild() function installs a protocol on ChildHandle. 278 | If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle. 279 | If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle. 280 | 281 | @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance. 282 | @param[in] ChildHandle Pointer to the handle of the child to create. If it is NULL, 283 | then a new handle is created. If it is a pointer to an existing UEFI handle, 284 | then the protocol is added to the existing UEFI handle. 285 | 286 | @retval EFI_SUCCESS The protocol was added to ChildHandle. 287 | @retval EFI_INVALID_PARAMETER ChildHandle is NULL. 288 | @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create 289 | the child 290 | @retval other The child handle was not created 291 | 292 | **/ 293 | EFI_STATUS 294 | EFIAPI 295 | Udp4ServiceBindingCreateChild ( 296 | IN EFI_SERVICE_BINDING_PROTOCOL *This, 297 | IN EFI_HANDLE *ChildHandle 298 | ) 299 | { 300 | EFI_STATUS Status; 301 | UDP4_SERVICE_DATA *Udp4Service; 302 | UDP4_INSTANCE_DATA *Instance; 303 | EFI_TPL OldTpl; 304 | VOID *Ip4; 305 | 306 | if ((This == NULL) || (ChildHandle == NULL)) { 307 | return EFI_INVALID_PARAMETER; 308 | } 309 | 310 | Udp4Service = UDP4_SERVICE_DATA_FROM_THIS (This); 311 | 312 | // 313 | // Allocate the instance private data structure. 314 | // 315 | Instance = AllocateZeroPool (sizeof (UDP4_INSTANCE_DATA)); 316 | if (Instance == NULL) { 317 | return EFI_OUT_OF_RESOURCES; 318 | } 319 | 320 | Udp4InitInstance (Udp4Service, Instance); 321 | 322 | // 323 | // Add an IpInfo for this instance. 324 | // 325 | Instance->IpInfo = IpIoAddIp (Udp4Service->IpIo); 326 | if (Instance->IpInfo == NULL) { 327 | Status = EFI_OUT_OF_RESOURCES; 328 | goto ON_ERROR; 329 | } 330 | 331 | // 332 | // Install the Udp4Protocol for this instance. 333 | // 334 | Status = gBS->InstallMultipleProtocolInterfaces ( 335 | ChildHandle, 336 | &gEfiUdp4ProtocolGuid, 337 | &Instance->Udp4Proto, 338 | NULL 339 | ); 340 | if (EFI_ERROR (Status)) { 341 | goto ON_ERROR; 342 | } 343 | 344 | Instance->ChildHandle = *ChildHandle; 345 | 346 | // 347 | // Open the default Ip4 protocol in the IP_IO BY_CHILD. 348 | // 349 | Status = gBS->OpenProtocol ( 350 | Udp4Service->IpIo->ChildHandle, 351 | &gEfiIp4ProtocolGuid, 352 | (VOID **)&Ip4, 353 | gUdp4DriverBinding.DriverBindingHandle, 354 | Instance->ChildHandle, 355 | EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER 356 | ); 357 | if (EFI_ERROR (Status)) { 358 | goto ON_ERROR; 359 | } 360 | 361 | // 362 | // Open this instance's Ip4 protocol in the IpInfo BY_CHILD. 363 | // 364 | Status = gBS->OpenProtocol ( 365 | Instance->IpInfo->ChildHandle, 366 | &gEfiIp4ProtocolGuid, 367 | (VOID **)&Ip4, 368 | gUdp4DriverBinding.DriverBindingHandle, 369 | Instance->ChildHandle, 370 | EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER 371 | ); 372 | if (EFI_ERROR (Status)) { 373 | goto ON_ERROR; 374 | } 375 | 376 | OldTpl = gBS->RaiseTPL (TPL_CALLBACK); 377 | 378 | // 379 | // Link this instance into the service context data and increase the ChildrenNumber. 380 | // 381 | InsertTailList (&Udp4Service->ChildrenList, &Instance->Link); 382 | Udp4Service->ChildrenNumber++; 383 | 384 | gBS->RestoreTPL (OldTpl); 385 | 386 | return EFI_SUCCESS; 387 | 388 | ON_ERROR: 389 | 390 | if (Instance->ChildHandle != NULL) { 391 | gBS->UninstallMultipleProtocolInterfaces ( 392 | Instance->ChildHandle, 393 | &gEfiUdp4ProtocolGuid, 394 | &Instance->Udp4Proto, 395 | NULL 396 | ); 397 | } 398 | 399 | if (Instance->IpInfo != NULL) { 400 | IpIoRemoveIp (Udp4Service->IpIo, Instance->IpInfo); 401 | } 402 | 403 | Udp4CleanInstance (Instance); 404 | 405 | FreePool (Instance); 406 | 407 | return Status; 408 | } 409 | 410 | /** 411 | Destroys a child handle with a protocol installed on it. 412 | 413 | The DestroyChild() function does the opposite of CreateChild(). It removes a protocol 414 | that was installed by CreateChild() from ChildHandle. If the removed protocol is the 415 | last protocol on ChildHandle, then ChildHandle is destroyed. 416 | 417 | @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance. 418 | @param[in] ChildHandle Handle of the child to destroy 419 | 420 | @retval EFI_SUCCESS The protocol was removed from ChildHandle. 421 | @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed. 422 | @retval EFI_INVALID_PARAMETER Child handle is NULL. 423 | @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle 424 | because its services are being used. 425 | @retval other The child handle was not destroyed 426 | 427 | **/ 428 | EFI_STATUS 429 | EFIAPI 430 | Udp4ServiceBindingDestroyChild ( 431 | IN EFI_SERVICE_BINDING_PROTOCOL *This, 432 | IN EFI_HANDLE ChildHandle 433 | ) 434 | { 435 | EFI_STATUS Status; 436 | UDP4_SERVICE_DATA *Udp4Service; 437 | EFI_UDP4_PROTOCOL *Udp4Proto; 438 | UDP4_INSTANCE_DATA *Instance; 439 | EFI_TPL OldTpl; 440 | 441 | if ((This == NULL) || (ChildHandle == NULL)) { 442 | return EFI_INVALID_PARAMETER; 443 | } 444 | 445 | Udp4Service = UDP4_SERVICE_DATA_FROM_THIS (This); 446 | 447 | // 448 | // Try to get the Udp4 protocol from the ChildHandle. 449 | // 450 | Status = gBS->OpenProtocol ( 451 | ChildHandle, 452 | &gEfiUdp4ProtocolGuid, 453 | (VOID **)&Udp4Proto, 454 | gUdp4DriverBinding.DriverBindingHandle, 455 | ChildHandle, 456 | EFI_OPEN_PROTOCOL_GET_PROTOCOL 457 | ); 458 | if (EFI_ERROR (Status)) { 459 | return EFI_UNSUPPORTED; 460 | } 461 | 462 | Instance = UDP4_INSTANCE_DATA_FROM_THIS (Udp4Proto); 463 | 464 | if (Instance->InDestroy) { 465 | return EFI_SUCCESS; 466 | } 467 | 468 | // 469 | // Use the Destroyed flag to avoid the re-entering of the following code. 470 | // 471 | Instance->InDestroy = TRUE; 472 | 473 | // 474 | // Close the Ip4 protocol. 475 | // 476 | gBS->CloseProtocol ( 477 | Udp4Service->IpIo->ChildHandle, 478 | &gEfiIp4ProtocolGuid, 479 | gUdp4DriverBinding.DriverBindingHandle, 480 | Instance->ChildHandle 481 | ); 482 | // 483 | // Close the Ip4 protocol on this instance's IpInfo. 484 | // 485 | gBS->CloseProtocol ( 486 | Instance->IpInfo->ChildHandle, 487 | &gEfiIp4ProtocolGuid, 488 | gUdp4DriverBinding.DriverBindingHandle, 489 | Instance->ChildHandle 490 | ); 491 | 492 | // 493 | // Uninstall the Udp4Protocol previously installed on the ChildHandle. 494 | // 495 | Status = gBS->UninstallMultipleProtocolInterfaces ( 496 | ChildHandle, 497 | &gEfiUdp4ProtocolGuid, 498 | (VOID *)&Instance->Udp4Proto, 499 | NULL 500 | ); 501 | if (EFI_ERROR (Status)) { 502 | Instance->InDestroy = FALSE; 503 | return Status; 504 | } 505 | 506 | // 507 | // Reset the configuration in case the instance's consumer forgets to do this. 508 | // 509 | Udp4Proto->Configure (Udp4Proto, NULL); 510 | 511 | // 512 | // Remove the IpInfo this instance consumes. 513 | // 514 | IpIoRemoveIp (Udp4Service->IpIo, Instance->IpInfo); 515 | 516 | OldTpl = gBS->RaiseTPL (TPL_CALLBACK); 517 | 518 | // 519 | // Remove this instance from the service context data's ChildrenList. 520 | // 521 | RemoveEntryList (&Instance->Link); 522 | Udp4Service->ChildrenNumber--; 523 | 524 | // 525 | // Clean the instance. 526 | // 527 | Udp4CleanInstance (Instance); 528 | 529 | gBS->RestoreTPL (OldTpl); 530 | 531 | FreePool (Instance); 532 | 533 | return EFI_SUCCESS; 534 | } 535 | 536 | /** 537 | This is the declaration of an EFI image entry point. This entry point is 538 | the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including 539 | both device drivers and bus drivers. 540 | 541 | The entry point for Udp4 driver which installs the driver binding 542 | and component name protocol on its ImageHandle. 543 | 544 | @param[in] ImageHandle The firmware allocated handle for the UEFI image. 545 | @param[in] SystemTable A pointer to the EFI System Table. 546 | 547 | @retval EFI_SUCCESS The operation completed successfully. 548 | @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. 549 | 550 | **/ 551 | EFI_STATUS 552 | EFIAPI 553 | Udp4DriverEntryPoint ( 554 | IN EFI_HANDLE ImageHandle, 555 | IN EFI_SYSTEM_TABLE *SystemTable 556 | ) 557 | { 558 | EFI_STATUS Status; 559 | UINT32 Random; 560 | 561 | Status = PseudoRandomU32 (&Random); 562 | if (EFI_ERROR (Status)) { 563 | DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status)); 564 | return Status; 565 | } 566 | 567 | // 568 | // Install the Udp4DriverBinding and Udp4ComponentName protocols. 569 | // 570 | Status = EfiLibInstallDriverBindingComponentName2 ( 571 | ImageHandle, 572 | SystemTable, 573 | &gUdp4DriverBinding, 574 | ImageHandle, 575 | &gUdp4ComponentName, 576 | &gUdp4ComponentName2 577 | ); 578 | if (!EFI_ERROR (Status)) { 579 | // 580 | // Initialize the UDP random port. 581 | // 582 | mUdp4RandomPort = (UINT16)(((UINT16)Random) % UDP4_PORT_KNOWN + UDP4_PORT_KNOWN); 583 | } 584 | 585 | return Status; 586 | } 587 | -------------------------------------------------------------------------------- /Edk2_Patch/NetworkPkg/Udp6Dxe/Udp6Driver.c: -------------------------------------------------------------------------------- 1 | /** @file 2 | Driver Binding functions and Service Binding functions for the Network driver module. 3 | 4 | Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
5 | Copyright (c) Microsoft Corporation 6 | SPDX-License-Identifier: BSD-2-Clause-Patent 7 | 8 | **/ 9 | 10 | #include "Udp6Impl.h" 11 | 12 | EFI_DRIVER_BINDING_PROTOCOL gUdp6DriverBinding = { 13 | Udp6DriverBindingSupported, 14 | Udp6DriverBindingStart, 15 | Udp6DriverBindingStop, 16 | 0xa, 17 | NULL, 18 | NULL 19 | }; 20 | 21 | EFI_SERVICE_BINDING_PROTOCOL mUdp6ServiceBinding = { 22 | Udp6ServiceBindingCreateChild, 23 | Udp6ServiceBindingDestroyChild 24 | }; 25 | 26 | /** 27 | Tests to see if this driver supports a given controller. If a child device is provided, 28 | it further tests to see if this driver supports creating a handle for the specified child device. 29 | 30 | This function checks to see if the driver specified by This supports the device specified by 31 | ControllerHandle. Drivers will typically use the device path attached to 32 | ControllerHandle and/or the services from the bus I/O abstraction attached to 33 | ControllerHandle to determine if the driver supports ControllerHandle. This function 34 | may be called many times during platform initialization. In order to reduce boot times, the tests 35 | performed by this function must be very small, and take as little time as possible to execute. This 36 | function must not change the state of any hardware devices, and this function must be aware that the 37 | device specified by ControllerHandle may already be managed by the same driver or a 38 | different driver. This function must match its calls to AllocatePages() with FreePages(), 39 | AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol(). 40 | Because ControllerHandle may have been previously started by the same driver, if a protocol is 41 | already in the opened state, then it must not be closed with CloseProtocol(). This is required 42 | to guarantee the state of ControllerHandle is not modified by this function. 43 | 44 | @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance. 45 | @param[in] ControllerHandle The handle of the controller to test. This handle 46 | must support a protocol interface that supplies 47 | an I/O abstraction to the driver. 48 | @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This 49 | parameter is ignored by device drivers, and is optional for bus 50 | drivers. For bus drivers, if this parameter is not NULL, then 51 | the bus driver must determine if the bus controller specified 52 | by ControllerHandle and the child controller specified 53 | by RemainingDevicePath are both supported by this 54 | bus driver. 55 | 56 | @retval EFI_SUCCESS The device specified by ControllerHandle and 57 | RemainingDevicePath is supported by the driver specified by This. 58 | @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and 59 | RemainingDevicePath is already being managed by the driver 60 | specified by This. 61 | @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and 62 | RemainingDevicePath is already being managed by a different 63 | driver or an application that requires exclusive access. 64 | Currently not implemented. 65 | @retval EFI_UNSUPPORTED The device specified by ControllerHandle and 66 | RemainingDevicePath is not supported by the driver specified by This. 67 | **/ 68 | EFI_STATUS 69 | EFIAPI 70 | Udp6DriverBindingSupported ( 71 | IN EFI_DRIVER_BINDING_PROTOCOL *This, 72 | IN EFI_HANDLE ControllerHandle, 73 | IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL 74 | ) 75 | { 76 | EFI_STATUS Status; 77 | 78 | // 79 | // Test for the Udp6ServiceBinding Protocol 80 | // 81 | Status = gBS->OpenProtocol ( 82 | ControllerHandle, 83 | &gEfiUdp6ServiceBindingProtocolGuid, 84 | NULL, 85 | This->DriverBindingHandle, 86 | ControllerHandle, 87 | EFI_OPEN_PROTOCOL_TEST_PROTOCOL 88 | ); 89 | if (!EFI_ERROR (Status)) { 90 | return EFI_ALREADY_STARTED; 91 | } 92 | 93 | // 94 | // Test for the Ip6ServiceBinding Protocol 95 | // 96 | Status = gBS->OpenProtocol ( 97 | ControllerHandle, 98 | &gEfiIp6ServiceBindingProtocolGuid, 99 | NULL, 100 | This->DriverBindingHandle, 101 | ControllerHandle, 102 | EFI_OPEN_PROTOCOL_TEST_PROTOCOL 103 | ); 104 | 105 | return Status; 106 | } 107 | 108 | /** 109 | Start this driver on ControllerHandle. 110 | 111 | This service is called by the EFI boot service ConnectController(). In order to make 112 | drivers as small as possible, there are a few calling restrictions for 113 | this service. ConnectController() must follow these 114 | calling restrictions. If any other agent wishes to call Start() it 115 | must also follow these calling restrictions. 116 | 117 | @param[in] This Protocol instance pointer. 118 | @param[in] ControllerHandle Handle of device to bind the driver to. 119 | @param[in] RemainingDevicePath Optional parameter use to pick a specific child 120 | device to start. 121 | 122 | @retval EFI_SUCCESS This driver is added to ControllerHandle. 123 | @retval EFI_OUT_OF_RESOURCES The required system resource can't be allocated. 124 | @retval other This driver does not support this device. 125 | 126 | **/ 127 | EFI_STATUS 128 | EFIAPI 129 | Udp6DriverBindingStart ( 130 | IN EFI_DRIVER_BINDING_PROTOCOL *This, 131 | IN EFI_HANDLE ControllerHandle, 132 | IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL 133 | ) 134 | { 135 | EFI_STATUS Status; 136 | UDP6_SERVICE_DATA *Udp6Service; 137 | 138 | // 139 | // Allocate Private Context Data Structure. 140 | // 141 | Udp6Service = AllocateZeroPool (sizeof (UDP6_SERVICE_DATA)); 142 | if (Udp6Service == NULL) { 143 | Status = EFI_OUT_OF_RESOURCES; 144 | goto EXIT; 145 | } 146 | 147 | Status = Udp6CreateService (Udp6Service, This->DriverBindingHandle, ControllerHandle); 148 | if (EFI_ERROR (Status)) { 149 | goto EXIT; 150 | } 151 | 152 | // 153 | // Install the Udp6ServiceBindingProtocol on the ControllerHandle. 154 | // 155 | Status = gBS->InstallMultipleProtocolInterfaces ( 156 | &ControllerHandle, 157 | &gEfiUdp6ServiceBindingProtocolGuid, 158 | &Udp6Service->ServiceBinding, 159 | NULL 160 | ); 161 | if (EFI_ERROR (Status)) { 162 | Udp6CleanService (Udp6Service); 163 | } 164 | 165 | EXIT: 166 | if (EFI_ERROR (Status)) { 167 | if (Udp6Service != NULL) { 168 | FreePool (Udp6Service); 169 | } 170 | } 171 | 172 | return Status; 173 | } 174 | 175 | /** 176 | Callback function which provided by user to remove one node in NetDestroyLinkList process. 177 | 178 | @param[in] Entry The entry to be removed. 179 | @param[in] Context Pointer to the callback context corresponds to the Context in NetDestroyLinkList. 180 | 181 | @retval EFI_INVALID_PARAMETER Entry is NULL or Context is NULL. 182 | @retval EFI_SUCCESS The entry has been removed successfully. 183 | @retval Others Fail to remove the entry. 184 | 185 | **/ 186 | EFI_STATUS 187 | EFIAPI 188 | Udp6DestroyChildEntryInHandleBuffer ( 189 | IN LIST_ENTRY *Entry, 190 | IN VOID *Context 191 | ) 192 | { 193 | UDP6_INSTANCE_DATA *Instance; 194 | EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; 195 | UINTN NumberOfChildren; 196 | EFI_HANDLE *ChildHandleBuffer; 197 | 198 | if ((Entry == NULL) || (Context == NULL)) { 199 | return EFI_INVALID_PARAMETER; 200 | } 201 | 202 | Instance = NET_LIST_USER_STRUCT_S (Entry, UDP6_INSTANCE_DATA, Link, UDP6_INSTANCE_DATA_SIGNATURE); 203 | ServiceBinding = ((UDP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *)Context)->ServiceBinding; 204 | NumberOfChildren = ((UDP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *)Context)->NumberOfChildren; 205 | ChildHandleBuffer = ((UDP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *)Context)->ChildHandleBuffer; 206 | 207 | if (!NetIsInHandleBuffer (Instance->ChildHandle, NumberOfChildren, ChildHandleBuffer)) { 208 | return EFI_SUCCESS; 209 | } 210 | 211 | return ServiceBinding->DestroyChild (ServiceBinding, Instance->ChildHandle); 212 | } 213 | 214 | /** 215 | Stop this driver on ControllerHandle. 216 | 217 | This service is called by the EFI boot service DisconnectController(). In order to 218 | make drivers as small as possible, there are a few calling 219 | restrictions for this service. DisconnectController() 220 | must follow these calling restrictions. If any other agent wishes 221 | to call Stop(), it must also follow these calling restrictions. 222 | 223 | @param[in] This Protocol instance pointer. 224 | @param[in] ControllerHandle Handle of device to stop the driver on. 225 | @param[in] NumberOfChildren Number of Handles in ChildHandleBuffer. If the number 226 | of children is zero stop the entire bus driver. 227 | @param[in] ChildHandleBuffer List of Child Handles to Stop. It is optional. 228 | 229 | @retval EFI_SUCCESS This driver is removed ControllerHandle. 230 | @retval EFI_DEVICE_ERROR Can't find the NicHandle from the ControllerHandle and specified GUID. 231 | @retval other This driver was not removed from this device. 232 | 233 | **/ 234 | EFI_STATUS 235 | EFIAPI 236 | Udp6DriverBindingStop ( 237 | IN EFI_DRIVER_BINDING_PROTOCOL *This, 238 | IN EFI_HANDLE ControllerHandle, 239 | IN UINTN NumberOfChildren, 240 | IN EFI_HANDLE *ChildHandleBuffer OPTIONAL 241 | ) 242 | { 243 | EFI_STATUS Status; 244 | EFI_HANDLE NicHandle; 245 | EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; 246 | UDP6_SERVICE_DATA *Udp6Service; 247 | LIST_ENTRY *List; 248 | UDP6_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context; 249 | 250 | // 251 | // Find the NicHandle where UDP6 ServiceBinding Protocol is installed. 252 | // 253 | NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp6ProtocolGuid); 254 | if (NicHandle == NULL) { 255 | return EFI_SUCCESS; 256 | } 257 | 258 | // 259 | // Retrieve the UDP6 ServiceBinding Protocol. 260 | // 261 | Status = gBS->OpenProtocol ( 262 | NicHandle, 263 | &gEfiUdp6ServiceBindingProtocolGuid, 264 | (VOID **)&ServiceBinding, 265 | This->DriverBindingHandle, 266 | NicHandle, 267 | EFI_OPEN_PROTOCOL_GET_PROTOCOL 268 | ); 269 | if (EFI_ERROR (Status)) { 270 | return EFI_DEVICE_ERROR; 271 | } 272 | 273 | Udp6Service = UDP6_SERVICE_DATA_FROM_THIS (ServiceBinding); 274 | 275 | if (NumberOfChildren != 0) { 276 | // 277 | // NumberOfChildren is not zero, destroy the children instances in ChildHandleBuffer. 278 | // 279 | List = &Udp6Service->ChildrenList; 280 | Context.ServiceBinding = ServiceBinding; 281 | Context.NumberOfChildren = NumberOfChildren; 282 | Context.ChildHandleBuffer = ChildHandleBuffer; 283 | Status = NetDestroyLinkList ( 284 | List, 285 | Udp6DestroyChildEntryInHandleBuffer, 286 | &Context, 287 | NULL 288 | ); 289 | } else if (IsListEmpty (&Udp6Service->ChildrenList)) { 290 | Status = gBS->UninstallMultipleProtocolInterfaces ( 291 | NicHandle, 292 | &gEfiUdp6ServiceBindingProtocolGuid, 293 | &Udp6Service->ServiceBinding, 294 | NULL 295 | ); 296 | 297 | Udp6CleanService (Udp6Service); 298 | FreePool (Udp6Service); 299 | } 300 | 301 | return Status; 302 | } 303 | 304 | /** 305 | Creates a child handle and installs a protocol. 306 | 307 | The CreateChild() function installs a protocol on ChildHandle. 308 | If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle. 309 | If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle. 310 | 311 | @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance. 312 | @param[in, out] ChildHandle Pointer to the handle of the child to create. If it is NULL, 313 | then a new handle is created. If it is a pointer to an existing UEFI handle, 314 | then the protocol is added to the existing UEFI handle. 315 | 316 | @retval EFI_SUCCESS The protocol was added to ChildHandle. 317 | @retval EFI_INVALID_PARAMETER This is NULL or ChildHandle is NULL. 318 | @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create 319 | the child. 320 | @retval other The child handle was not created. 321 | 322 | **/ 323 | EFI_STATUS 324 | EFIAPI 325 | Udp6ServiceBindingCreateChild ( 326 | IN EFI_SERVICE_BINDING_PROTOCOL *This, 327 | IN OUT EFI_HANDLE *ChildHandle 328 | ) 329 | { 330 | EFI_STATUS Status; 331 | UDP6_SERVICE_DATA *Udp6Service; 332 | UDP6_INSTANCE_DATA *Instance; 333 | EFI_TPL OldTpl; 334 | VOID *Ip6; 335 | 336 | if ((This == NULL) || (ChildHandle == NULL)) { 337 | return EFI_INVALID_PARAMETER; 338 | } 339 | 340 | Udp6Service = UDP6_SERVICE_DATA_FROM_THIS (This); 341 | 342 | // 343 | // Allocate the instance private data structure. 344 | // 345 | Instance = AllocateZeroPool (sizeof (UDP6_INSTANCE_DATA)); 346 | if (Instance == NULL) { 347 | return EFI_OUT_OF_RESOURCES; 348 | } 349 | 350 | Udp6InitInstance (Udp6Service, Instance); 351 | 352 | // 353 | // Add an IpInfo for this instance. 354 | // 355 | Instance->IpInfo = IpIoAddIp (Udp6Service->IpIo); 356 | if (Instance->IpInfo == NULL) { 357 | Status = EFI_OUT_OF_RESOURCES; 358 | goto ON_ERROR; 359 | } 360 | 361 | // 362 | // Install the Udp6Protocol for this instance. 363 | // 364 | Status = gBS->InstallMultipleProtocolInterfaces ( 365 | ChildHandle, 366 | &gEfiUdp6ProtocolGuid, 367 | &Instance->Udp6Proto, 368 | NULL 369 | ); 370 | if (EFI_ERROR (Status)) { 371 | goto ON_ERROR; 372 | } 373 | 374 | Instance->ChildHandle = *ChildHandle; 375 | 376 | // 377 | // Open the default Ip6 protocol in the IP_IO BY_CHILD. 378 | // 379 | Status = gBS->OpenProtocol ( 380 | Udp6Service->IpIo->ChildHandle, 381 | &gEfiIp6ProtocolGuid, 382 | (VOID **)&Ip6, 383 | gUdp6DriverBinding.DriverBindingHandle, 384 | Instance->ChildHandle, 385 | EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER 386 | ); 387 | if (EFI_ERROR (Status)) { 388 | goto ON_ERROR; 389 | } 390 | 391 | // 392 | // Open this instance's Ip6 protocol in the IpInfo BY_CHILD. 393 | // 394 | Status = gBS->OpenProtocol ( 395 | Instance->IpInfo->ChildHandle, 396 | &gEfiIp6ProtocolGuid, 397 | (VOID **)&Ip6, 398 | gUdp6DriverBinding.DriverBindingHandle, 399 | Instance->ChildHandle, 400 | EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER 401 | ); 402 | if (EFI_ERROR (Status)) { 403 | goto ON_ERROR; 404 | } 405 | 406 | OldTpl = gBS->RaiseTPL (TPL_CALLBACK); 407 | 408 | // 409 | // Link this instance into the service context data and increase the ChildrenNumber. 410 | // 411 | InsertTailList (&Udp6Service->ChildrenList, &Instance->Link); 412 | Udp6Service->ChildrenNumber++; 413 | 414 | gBS->RestoreTPL (OldTpl); 415 | 416 | return EFI_SUCCESS; 417 | 418 | ON_ERROR: 419 | 420 | if (Instance->ChildHandle != NULL) { 421 | gBS->UninstallMultipleProtocolInterfaces ( 422 | Instance->ChildHandle, 423 | &gEfiUdp6ProtocolGuid, 424 | &Instance->Udp6Proto, 425 | NULL 426 | ); 427 | } 428 | 429 | if (Instance->IpInfo != NULL) { 430 | IpIoRemoveIp (Udp6Service->IpIo, Instance->IpInfo); 431 | } 432 | 433 | Udp6CleanInstance (Instance); 434 | 435 | FreePool (Instance); 436 | 437 | return Status; 438 | } 439 | 440 | /** 441 | Destroys a child handle with a set of I/O services. 442 | The DestroyChild() function does the opposite of CreateChild(). It removes a protocol 443 | that was installed by CreateChild() from ChildHandle. If the removed protocol is the 444 | last protocol on ChildHandle, then ChildHandle is destroyed. 445 | 446 | @param[in] This Protocol instance pointer. 447 | @param[in] ChildHandle Handle of the child to destroy. 448 | 449 | @retval EFI_SUCCESS The I/O services were removed from the child 450 | handle. 451 | @retval EFI_UNSUPPORTED The child handle does not support the I/O services 452 | that are being removed. 453 | @retval EFI_INVALID_PARAMETER Child handle is NULL. 454 | @retval EFI_ACCESS_DENIED The child handle could not be destroyed because 455 | its I/O services are being used. 456 | @retval other The child handle was not destroyed. 457 | 458 | **/ 459 | EFI_STATUS 460 | EFIAPI 461 | Udp6ServiceBindingDestroyChild ( 462 | IN EFI_SERVICE_BINDING_PROTOCOL *This, 463 | IN EFI_HANDLE ChildHandle 464 | ) 465 | { 466 | EFI_STATUS Status; 467 | UDP6_SERVICE_DATA *Udp6Service; 468 | EFI_UDP6_PROTOCOL *Udp6Proto; 469 | UDP6_INSTANCE_DATA *Instance; 470 | EFI_TPL OldTpl; 471 | 472 | if ((This == NULL) || (ChildHandle == NULL)) { 473 | return EFI_INVALID_PARAMETER; 474 | } 475 | 476 | Udp6Service = UDP6_SERVICE_DATA_FROM_THIS (This); 477 | 478 | // 479 | // Try to get the Udp6 protocol from the ChildHandle. 480 | // 481 | Status = gBS->OpenProtocol ( 482 | ChildHandle, 483 | &gEfiUdp6ProtocolGuid, 484 | (VOID **)&Udp6Proto, 485 | gUdp6DriverBinding.DriverBindingHandle, 486 | ChildHandle, 487 | EFI_OPEN_PROTOCOL_GET_PROTOCOL 488 | ); 489 | if (EFI_ERROR (Status)) { 490 | return EFI_UNSUPPORTED; 491 | } 492 | 493 | Instance = UDP6_INSTANCE_DATA_FROM_THIS (Udp6Proto); 494 | 495 | if (Instance->InDestroy) { 496 | return EFI_SUCCESS; 497 | } 498 | 499 | // 500 | // Use the Destroyed flag to avoid the re-entering of the following code. 501 | // 502 | Instance->InDestroy = TRUE; 503 | 504 | // 505 | // Close the Ip6 protocol on the default IpIo. 506 | // 507 | Status = gBS->CloseProtocol ( 508 | Udp6Service->IpIo->ChildHandle, 509 | &gEfiIp6ProtocolGuid, 510 | gUdp6DriverBinding.DriverBindingHandle, 511 | Instance->ChildHandle 512 | ); 513 | if (EFI_ERROR (Status)) { 514 | Instance->InDestroy = FALSE; 515 | return Status; 516 | } 517 | 518 | // 519 | // Close the Ip6 protocol on this instance's IpInfo. 520 | // 521 | Status = gBS->CloseProtocol ( 522 | Instance->IpInfo->ChildHandle, 523 | &gEfiIp6ProtocolGuid, 524 | gUdp6DriverBinding.DriverBindingHandle, 525 | Instance->ChildHandle 526 | ); 527 | if (EFI_ERROR (Status)) { 528 | Instance->InDestroy = FALSE; 529 | return Status; 530 | } 531 | 532 | // 533 | // Uninstall the Udp6Protocol previously installed on the ChildHandle. 534 | // 535 | Status = gBS->UninstallMultipleProtocolInterfaces ( 536 | ChildHandle, 537 | &gEfiUdp6ProtocolGuid, 538 | (VOID *)&Instance->Udp6Proto, 539 | NULL 540 | ); 541 | if (EFI_ERROR (Status)) { 542 | Instance->InDestroy = FALSE; 543 | return Status; 544 | } 545 | 546 | // 547 | // Reset the configuration in case the instance's consumer forgets to do this. 548 | // 549 | Udp6Proto->Configure (Udp6Proto, NULL); 550 | 551 | // 552 | // Remove the IpInfo this instance consumes. 553 | // 554 | IpIoRemoveIp (Udp6Service->IpIo, Instance->IpInfo); 555 | 556 | OldTpl = gBS->RaiseTPL (TPL_CALLBACK); 557 | 558 | // 559 | // Remove this instance from the service context data's ChildrenList. 560 | // 561 | RemoveEntryList (&Instance->Link); 562 | Udp6Service->ChildrenNumber--; 563 | 564 | // 565 | // Clean the instance. 566 | // 567 | Udp6CleanInstance (Instance); 568 | 569 | gBS->RestoreTPL (OldTpl); 570 | 571 | FreePool (Instance); 572 | 573 | return EFI_SUCCESS; 574 | } 575 | 576 | /** 577 | This is the declaration of an EFI image entry point. This entry point is 578 | the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers, including 579 | both device drivers and bus drivers. 580 | 581 | The entry point for Udp6 driver that installs the driver binding 582 | and component name protocol on its ImageHandle. 583 | 584 | @param[in] ImageHandle The firmware allocated handle for the UEFI image. 585 | @param[in] SystemTable A pointer to the EFI System Table. 586 | 587 | @retval EFI_SUCCESS The operation completed successfully. 588 | @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. 589 | 590 | **/ 591 | EFI_STATUS 592 | EFIAPI 593 | Udp6DriverEntryPoint ( 594 | IN EFI_HANDLE ImageHandle, 595 | IN EFI_SYSTEM_TABLE *SystemTable 596 | ) 597 | { 598 | EFI_STATUS Status; 599 | UINT32 Random; 600 | 601 | Status = PseudoRandomU32 (&Random); 602 | if (EFI_ERROR (Status)) { 603 | DEBUG ((DEBUG_ERROR, "%a failed to generate random number: %r\n", __func__, Status)); 604 | return Status; 605 | } 606 | 607 | // 608 | // Install the Udp6DriverBinding and Udp6ComponentName protocols. 609 | // 610 | 611 | Status = EfiLibInstallDriverBindingComponentName2 ( 612 | ImageHandle, 613 | SystemTable, 614 | &gUdp6DriverBinding, 615 | ImageHandle, 616 | &gUdp6ComponentName, 617 | &gUdp6ComponentName2 618 | ); 619 | if (!EFI_ERROR (Status)) { 620 | // 621 | // Initialize the UDP random port. 622 | // 623 | mUdp6RandomPort = (UINT16)( 624 | ((UINT16)Random) % 625 | UDP6_PORT_KNOWN + 626 | UDP6_PORT_KNOWN 627 | ); 628 | } 629 | 630 | return Status; 631 | } 632 | -------------------------------------------------------------------------------- /Edk2_Patch/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | Functions declaration related with DHCPv6 for UefiPxeBc Driver. 3 | 4 | Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
5 | 6 | SPDX-License-Identifier: BSD-2-Clause-Patent 7 | 8 | **/ 9 | 10 | #ifndef __EFI_PXEBC_DHCP6_H__ 11 | #define __EFI_PXEBC_DHCP6_H__ 12 | 13 | #define PXEBC_DHCP6_OPTION_MAX_NUM 16 14 | #define PXEBC_DHCP6_OPTION_MAX_SIZE 312 15 | #define PXEBC_DHCP6_PACKET_MAX_SIZE (sizeof (EFI_PXE_BASE_CODE_PACKET)) 16 | #define PXEBC_IP6_POLICY_MAX 0xff 17 | #define PXEBC_IP6_ROUTE_TABLE_TIMEOUT 10 18 | 19 | #define PXEBC_DHCP6_S_PORT 547 20 | #define PXEBC_DHCP6_C_PORT 546 21 | 22 | #define PXEBC_DHCP6_ENTERPRISE_NUM 343 // TODO: IANA TBD: temporarily using Intel's 23 | #define PXEBC_DHCP6_MAX_BOOT_FILE_SIZE 65535 // It's a limitation of bit length, 65535*512 bytes. 24 | 25 | #define PXEBC_DHCP6_IDX_IA_NA 0 26 | #define PXEBC_DHCP6_IDX_BOOT_FILE_URL 1 27 | #define PXEBC_DHCP6_IDX_BOOT_FILE_PARAM 2 28 | #define PXEBC_DHCP6_IDX_VENDOR_CLASS 3 29 | #define PXEBC_DHCP6_IDX_DNS_SERVER 4 30 | #define PXEBC_DHCP6_IDX_MAX 5 31 | 32 | #define PXEBC_DHCP6_BOOT_FILE_URL_PREFIX "tftp://" 33 | #define PXEBC_TFTP_URL_SEPARATOR '/' 34 | #define PXEBC_ADDR_START_DELIMITER '[' 35 | #define PXEBC_ADDR_END_DELIMITER ']' 36 | 37 | // 38 | // A DUID consists of a 2-octet type code represented in network byte 39 | // order, followed by a variable number of octets that make up the 40 | // actual identifier. The length of the DUID (not including the type 41 | // code) is at least 1 octet and at most 128 octets. 42 | // 43 | #define PXEBC_MIN_SIZE_OF_DUID (sizeof(UINT16) + 1) 44 | #define PXEBC_MAX_SIZE_OF_DUID (sizeof(UINT16) + 128) 45 | 46 | // 47 | // This define represents the combineds code and length field from 48 | // https://datatracker.ietf.org/doc/html/rfc3315#section-22.1 49 | // 50 | #define PXEBC_COMBINED_SIZE_OF_OPT_CODE_AND_LEN \ 51 | (sizeof (((EFI_DHCP6_PACKET_OPTION *)0)->OpCode) + \ 52 | sizeof (((EFI_DHCP6_PACKET_OPTION *)0)->OpLen)) 53 | 54 | #define GET_NEXT_DHCP6_OPTION(Opt) \ 55 | (EFI_DHCP6_PACKET_OPTION *) ((UINT8 *) (Opt) + \ 56 | sizeof (EFI_DHCP6_PACKET_OPTION) + (NTOHS ((Opt)->OpLen)) - 1) 57 | 58 | #define GET_DHCP6_OPTION_SIZE(Pkt) \ 59 | ((Pkt)->Length - sizeof (EFI_DHCP6_HEADER)) 60 | 61 | #define IS_PROXY_OFFER(Type) \ 62 | ((Type) == PxeOfferTypeProxyBinl || \ 63 | (Type) == PxeOfferTypeProxyPxe10 || \ 64 | (Type) == PxeOfferTypeProxyWfm11a) 65 | 66 | #pragma pack(1) 67 | typedef struct { 68 | UINT16 OpCode[256]; 69 | } PXEBC_DHCP6_OPTION_ORO; 70 | 71 | typedef struct { 72 | UINT8 Type; 73 | UINT8 MajorVer; 74 | UINT8 MinorVer; 75 | } PXEBC_DHCP6_OPTION_UNDI; 76 | 77 | typedef struct { 78 | UINT16 Type; 79 | } PXEBC_DHCP6_OPTION_ARCH; 80 | 81 | typedef struct { 82 | UINT8 ClassIdentifier[10]; 83 | UINT8 ArchitecturePrefix[5]; 84 | UINT8 ArchitectureType[5]; 85 | UINT8 Lit3[1]; 86 | UINT8 InterfaceName[4]; 87 | UINT8 Lit4[1]; 88 | UINT8 UndiMajor[3]; 89 | UINT8 UndiMinor[3]; 90 | } PXEBC_CLASS_ID; 91 | 92 | typedef struct { 93 | UINT32 Vendor; 94 | UINT16 ClassLen; 95 | PXEBC_CLASS_ID ClassId; 96 | } PXEBC_DHCP6_OPTION_VENDOR_CLASS; 97 | 98 | #pragma pack() 99 | 100 | typedef union { 101 | PXEBC_DHCP6_OPTION_ORO *Oro; 102 | PXEBC_DHCP6_OPTION_UNDI *Undi; 103 | PXEBC_DHCP6_OPTION_ARCH *Arch; 104 | PXEBC_DHCP6_OPTION_VENDOR_CLASS *VendorClass; 105 | } PXEBC_DHCP6_OPTION_ENTRY; 106 | 107 | typedef struct { 108 | LIST_ENTRY Link; 109 | EFI_DHCP6_PACKET_OPTION *Option; 110 | UINT8 Precedence; 111 | } PXEBC_DHCP6_OPTION_NODE; 112 | 113 | #define PXEBC_CACHED_DHCP6_PACKET_MAX_SIZE (OFFSET_OF (EFI_DHCP6_PACKET, Dhcp6) + PXEBC_DHCP6_PACKET_MAX_SIZE) 114 | 115 | typedef union { 116 | EFI_DHCP6_PACKET Offer; 117 | EFI_DHCP6_PACKET Ack; 118 | UINT8 Buffer[PXEBC_CACHED_DHCP6_PACKET_MAX_SIZE]; 119 | } PXEBC_DHCP6_PACKET; 120 | 121 | typedef struct { 122 | PXEBC_DHCP6_PACKET Packet; 123 | PXEBC_OFFER_TYPE OfferType; 124 | EFI_DHCP6_PACKET_OPTION *OptList[PXEBC_DHCP6_IDX_MAX]; 125 | } PXEBC_DHCP6_PACKET_CACHE; 126 | 127 | /** 128 | Parse the Boot File URL option. 129 | 130 | @param[in] Private Pointer to PxeBc private data. 131 | @param[out] FileName The pointer to the boot file name. 132 | @param[in, out] SrvAddr The pointer to the boot server address. 133 | @param[in] BootFile The pointer to the boot file URL option data. 134 | @param[in] Length Length of the boot file URL option data. 135 | 136 | @retval EFI_ABORTED User canceled the operation. 137 | @retval EFI_SUCCESS Selected the boot menu successfully. 138 | @retval EFI_NOT_READY Read the input key from the keyboard has not finish. 139 | 140 | **/ 141 | EFI_STATUS 142 | PxeBcExtractBootFileUrl ( 143 | IN PXEBC_PRIVATE_DATA *Private, 144 | OUT UINT8 **FileName, 145 | IN OUT EFI_IPv6_ADDRESS *SrvAddr, 146 | IN CHAR8 *BootFile, 147 | IN UINT16 Length 148 | ); 149 | 150 | /** 151 | Parse the Boot File Parameter option. 152 | 153 | @param[in] BootFilePara The pointer to the boot file parameter option data. 154 | @param[out] BootFileSize The pointer to the parsed boot file size. 155 | 156 | @retval EFI_SUCCESS Successfully obtained the boot file size from parameter option. 157 | @retval EFI_NOT_FOUND Failed to extract the boot file size from parameter option. 158 | 159 | **/ 160 | EFI_STATUS 161 | PxeBcExtractBootFileParam ( 162 | IN CHAR8 *BootFilePara, 163 | OUT UINT16 *BootFileSize 164 | ); 165 | 166 | /** 167 | Parse the cached DHCPv6 packet, including all the options. 168 | 169 | @param[in] Cache6 The pointer to a cached DHCPv6 packet. 170 | 171 | @retval EFI_SUCCESS Parsed the DHCPv6 packet successfully. 172 | @retval EFI_DEVICE_ERROR Failed to parse and invalid packet. 173 | 174 | **/ 175 | EFI_STATUS 176 | PxeBcParseDhcp6Packet ( 177 | IN PXEBC_DHCP6_PACKET_CACHE *Cache6 178 | ); 179 | 180 | /** 181 | Register the ready address by Ip6Config protocol. 182 | 183 | @param[in] Private The pointer to the PxeBc private data. 184 | @param[in] Address The pointer to the ready address. 185 | 186 | @retval EFI_SUCCESS Registered the address successfully. 187 | @retval Others Failed to register the address. 188 | 189 | **/ 190 | EFI_STATUS 191 | PxeBcRegisterIp6Address ( 192 | IN PXEBC_PRIVATE_DATA *Private, 193 | IN EFI_IPv6_ADDRESS *Address 194 | ); 195 | 196 | /** 197 | Unregister the address by Ip6Config protocol. 198 | 199 | @param[in] Private The pointer to the PxeBc private data. 200 | 201 | **/ 202 | VOID 203 | PxeBcUnregisterIp6Address ( 204 | IN PXEBC_PRIVATE_DATA *Private 205 | ); 206 | 207 | /** 208 | Build and send out the request packet for the bootfile, and parse the reply. 209 | 210 | @param[in] Private The pointer to the PxeBc private data. 211 | @param[in] Type PxeBc option boot item type. 212 | @param[in] Layer The pointer to the option boot item layer. 213 | @param[in] UseBis Use BIS or not. 214 | @param[in] DestIp The pointer to the server address. 215 | 216 | @retval EFI_SUCCESS Successfully discovered theboot file. 217 | @retval EFI_OUT_OF_RESOURCES Failed to allocate resource. 218 | @retval EFI_NOT_FOUND Can't get the PXE reply packet. 219 | @retval Others Failed to discover boot file. 220 | 221 | **/ 222 | EFI_STATUS 223 | PxeBcDhcp6Discover ( 224 | IN PXEBC_PRIVATE_DATA *Private, 225 | IN UINT16 Type, 226 | IN UINT16 *Layer, 227 | IN BOOLEAN UseBis, 228 | IN EFI_IP_ADDRESS *DestIp 229 | ); 230 | 231 | /** 232 | Set the IP6 policy to Automatic. 233 | 234 | @param[in] Private The pointer to PXEBC_PRIVATE_DATA. 235 | 236 | @retval EFI_SUCCESS Switch the IP policy successfully. 237 | @retval Others Unexpected error happened. 238 | 239 | **/ 240 | EFI_STATUS 241 | PxeBcSetIp6Policy ( 242 | IN PXEBC_PRIVATE_DATA *Private 243 | ); 244 | 245 | /** 246 | This function will register the station IP address and flush IP instance to start using the new IP address. 247 | 248 | @param[in] Private The pointer to PXEBC_PRIVATE_DATA. 249 | 250 | @retval EFI_SUCCESS The new IP address has been configured successfully. 251 | @retval Others Failed to configure the address. 252 | 253 | **/ 254 | EFI_STATUS 255 | PxeBcSetIp6Address ( 256 | IN PXEBC_PRIVATE_DATA *Private 257 | ); 258 | 259 | /** 260 | Start the DHCPv6 S.A.R.R. process to acquire the IPv6 address and other PXE boot information. 261 | 262 | @param[in] Private The pointer to the PxeBc private data. 263 | @param[in] Dhcp6 The pointer to EFI_DHCP6_PROTOCOL. 264 | 265 | @retval EFI_SUCCESS The S.A.R.R. process successfully finished. 266 | @retval Others Failed to finish the S.A.R.R. process. 267 | 268 | **/ 269 | EFI_STATUS 270 | PxeBcDhcp6Sarr ( 271 | IN PXEBC_PRIVATE_DATA *Private, 272 | IN EFI_DHCP6_PROTOCOL *Dhcp6 273 | ); 274 | 275 | #endif 276 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2021, Open Compute Project 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /MAINTAINERS.md: -------------------------------------------------------------------------------- 1 | 2 | # This file describes the maintainers for Aptio OE for Tioga Pass 3 | 4 | Name = "Sowmya Narayanan" 5 | 6 | Email = "sowmyan@ami.com" 7 | 8 | Github = sowmyan 9 | 10 | Mailinglist = AMI_Project@groups.io 11 | 12 | 13 | Name = "Veera Manikantha Vattikuti" 14 | 15 | Email = "veeramanikanthav@ami.com" 16 | 17 | Github = veeramanikanthav 18 | 19 | Mailinglist = AMI_Project@groups.io 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Override_Patch.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | setlocal 3 | 4 | REM Define source and destination directories 5 | set "source_dir=Edk2_Patch" 6 | set "destination_dir=edk2" 7 | 8 | REM Check if source directory exists 9 | if not exist "%source_dir%" ( 10 | echo Source directory "%source_dir%" does not exist. 11 | exit /b 1 12 | ) 13 | 14 | REM Create destination directory if it does not exist 15 | if not exist "%destination_dir%" ( 16 | mkdir "%destination_dir%" 17 | echo Destination directory "%destination_dir%" created. 18 | ) 19 | 20 | REM Copy files and directories from source to destination 21 | xcopy "%source_dir%\*" "%destination_dir%\" /s /e /y /i 22 | 23 | REM Check the exit code of xcopy to determine if the operation was successful 24 | if %errorlevel% equ 0 ( 25 | echo Patch integration was completed successfully from "%source_dir%" to "%destination_dir%". 26 | ) else ( 27 | echo An error occurred while copying files. 28 | ) 29 | 30 | endlocal 31 | exit /b 0 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Aptio OpenEdition Firmware 2 | 3 | The Minimum Platform is a software architecture that guides uniform delivery of Intel platforms enabling firmware solutions for basic boot functionality with extensibility built-in. This project incorporates support for the OCP derived Tioga Pass platform and Junction City Platform. 4 | 5 | Package maintainers are listed in Maintainers.txt. 6 | 7 | ## Overview 8 | The key elements of the architecture are organized into a staged boot approach where each stage has requirements and 9 | functionality for specific use cases. The generic control flow through the boot process is implemented in the 10 | [`MinPlatformPkg`](https://github.com/tianocore/edk2-platforms/tree/devel-MinPlatform/Platform/Intel/MinPlatformPkg). 11 | The generic nature of the tasks performed in MinPlatformPkg lends to reuse across all Intel platforms with no 12 | source modification. Details for any particular board are made accessible to the MinPlatformPkg through a well-defined 13 | statically linked board API. A complete platform solution then consists of the MinPlatformPkg and a compatible board 14 | package. 15 | 16 | ## Board Naming Convention 17 | The board packages supported by Intel follow the naming convention \OpenBoardPkg where xxx refers to the 18 | encompassing platform name for a particular platform generation. For example, the [`KabylakeOpenBoardPkg`](https://github.com/tianocore/edk2-platforms/tree/devel-MinPlatform/Platform/Intel/KabylakeOpenBoardPkg) contains the 19 | board code for Intel Kaby Lake reference systems. Intel uses the moniker "OpenBoardPkg" to indicate that this package 20 | is the open source board code. A closed source counterpart may exist which simply uses "BoardPkg". Both directly use 21 | the MinPlatformPkg from edk2-platforms. 22 | 23 | ## Stage Selection 24 | Stage selection is controlled via the PCD `gMinPlatformPkgTokenSpaceGuid.PcdBootStage` in [`MinPlatformPkg.dec`](https://github.com/tianocore/edk2-platforms/blob/devel-MinPlatform/Platform/Intel/MinPlatformPkg/MinPlatformPkg.dec). 25 | The stage should be configured in the board package DSC file to the appropriate value. For example, a board may disable 26 | all advanced features by setting this value to 4 instead of 6. This may be used to improve boot time for a particular 27 | use case. Decrementing the stage can also be used for debug since only the actions required for that stage objective 28 | should be executed. As an example, ACPI initialization is not required for a Stage 3 boot. 29 | 30 | The stages are defined as follows: 31 | 32 | | Stage | Functional Objective | Example Capabilities | 33 | | -------|------------------------------|----------------------------------------------------------------------------------------------------| 34 | | I | Minimal Debug | Serial port output, source debug enabled, hardware debugger enabled | 35 | | II | Memory Functional | Basic hardware initialization necessary to reach memory initialization, permanent memory available | 36 | | III | Boot to UI | Simple console input and output to a UI, UEFI shell | 37 | | IV | Boot to OS | Boot an operating system with the minimally required features | 38 | | V | Security Enable | UEFI Secure Boot, TCG measured boot, DMA protections | 39 | | VI | Advanced Feature Enable | Firmware update, power management, non-essential I/O | 40 | 41 | ## Minimum Platform Firmware Solution Stack 42 | A UEFI firmware implementation using MinPlatformPkg is constructed using the following pieces. 43 | 44 | | | 45 | |------------------------------------| 46 | | [EDK II](https://github.com/tianocore/edk2) | 47 | | [Intel(r) FSP](https://github.com/IntelFsp/FSP) | 48 | | [Minimum Platform (`MinPlatformPkg`)](https://github.com/tianocore/edk2-platforms/tree/devel-MinPlatform/Platform/Intel/MinPlatformPkg) | 49 | | [Board Support (\OpenBoardPkg)](https://github.com/tianocore/edk2-platforms/tree/devel-MinPlatform/Platform/Intel) | 50 | 51 | 52 | ## Board Support 53 | * The `PurleyOpenBoardPkg` contains board implementations for Purley systems. 54 | * The `WhitleyOpenBoardPkg` contains board implementations for Whitley systems. 55 | 56 | ## Board Package Organization 57 | The board package follows the standard EDK II package structure with the following additional elements and guidelines: 58 | * Only code usable across more than one board at the root level.* Board-specific code in a directory. The directory name should match that of the board supported. 59 | * Features not essential to achieve stage 5 or earlier boots are maintained in a Features folder at the appropriate 60 | level in the package hierarchy. 61 | 62 | Shared resources in the package root directory can include interfaces described in header files, library instances, 63 | firmware modules, binaries, etc. The UEFI firmware implementation is built using the process described below from the 64 | board-specific directory. 65 | 66 | A board package must implement the board APIs defined in the MinPlatformPkg even if a "NULL" implementation is used to 67 | return back to the minimum platform caller. 68 | 69 | ## **Windows Build Instructions** 70 | 71 | ### Pre-requisites 72 | 73 | * [GIT client](https://git-scm.com/downloads): Available from https://git-scm.com/downloads 74 | * [Build Tools for Visual Studio 2019](https://visualstudio.microsoft.com/vs/older-downloads/#visual-studio-2019-and-other-products)
75 | Login with user credentials and refer the below to download the VS2019 76 | 77 | ![image](https://user-images.githubusercontent.com/80769446/170539401-dd2ba633-1e2f-4103-a137-49132a484c5f.png) 78 | 79 | 80 | - Visual Studio 2015 build tools from Visual Studio 2019. See image below for recommended install configuration. 81 | - **Please note that the VS2015 Build Tools are not enabled by default in the Visual Studio 2019 install.** 82 | - Visual Studio 2015 can be used instead. 83 | ![Visual Studio 2019 Installation](/Readme_VisualStudioInstall.png) 84 | * [ASL compiler](https://www.acpica.org/downloads/binary-tools): iasl.exe available from http://www.acpica.org 85 | - Install into ```C:\ASL``` to match default tools_def.txt configuration. 86 | - The validated version of iasl compiler that can build MinPurley is 20180629. 87 | * [NASM assembler](https://www.nasm.us/): nasm.exe available from: http://www.nasm.us/ 88 | - NASM 2.15.05 is the recommended minimum version. 89 | - Install into ```C:\NASM``` to match default tools_def.txt configuration. 90 | * [Python 3.8.10](https://www.python.org/downloads/release/python-3810/): Available from: https://www.python.org/downloads/release/python-3810/ 91 | - Install into ```C:\Python38``` to match default tools_def.txt configuration. 92 | - Add C:\Python38 to your path 93 | - Other versions of 3.8 may also work fine. 94 | 95 | ### **Supported Hardware** 96 | 97 | | Machine Name | Supported Chipsets | BoardPkg | Board Name | 98 | ----------------------------------------|--------------------------------------------|------------------------------|--------------------| 99 | | [Junction City](#junction-city-build-information) | IceLake-SP (Xeon Scalable) | WhitleyOpenBoardPkg |JunctionCity| 100 | | [Aowanda](#aowanda-build-information) | IceLake-SP (Xeon Scalable) | WhitleyOpenBoardPkg | Aowanda | 101 | | [MtJade](#mtjade-build-information) | Ampere Altra | Jade | MtJade | 102 | | [Onyx](#onyx-build-information) | Genoa | GenoaOpenBoardPkg | Onyx | 103 | 104 | 105 | 106 | ### Download the required components 107 | 108 | To download the project, clone the repository along with all the submodules and checkout required TAG using the following command: 109 | git clone --recurse-submodules https://github.com/opencomputeproject/Aptio-OE.git -b (need to be replaced with TAG name) 110 | 111 | Run Override_Patch.bat script to include below Pixiefail vulnerability patches, which are available in edk2-Stable202405. 112 | 113 | CVE-2023-45229 - Out-of-bounds read when processing IA_NA/IA_TA options in a DHCPv6 Advertise message 114 | CVE-2023-45230 - Buffer overflow in the DHCPv6 client via a long Server ID option 115 | CVE-2023-45231 - Out-of-bounds read when handling a ND Redirect message with truncated options 116 | CVE-2023-45232 - Infinite loop when parsing unknown options in the Destination Options header 117 | CVE-2023-45233 - Infinite loop when parsing a PadN option in the Destination Options header 118 | CVE-2023-45234 - Buffer overflow when processing DNSServers option in a DHCPv6 Advertise message 119 | CVE-2023-45235 - Buffer overflow when handling Server ID option from a DHCPv6 proxy Advertise message 120 | CVE-2023-45236 - Use of a Weak PseudoRandom Number Generator. 121 | CVE-2023-45237 - Predictable TCP initial sequence numbers (ISNs) generated by the TCP/IP stack. 122 | 123 | ### Junction City Build Information 124 | 125 | **Building with the python script** 126 | 127 | 1. Open command window, go to the workspace directory, e.g. c:\Edk2Workspace 128 | 2. Type "cd edk2-platforms/Platform/Intel 129 | 3. Type "python build_bios.py -p JunctionCity" 130 | 4. On successful build, IFWI (Integrated Firmware Image) JUNCTIONCITY.bin and BIOS JUNCTIONCITY.fd rom files are created. 131 | 132 | * build_bios.py arguments: 133 | 134 | | Argument | Function | 135 | | ----------------------|-------------------------------------| 136 | | -h, --help | show this help message and exit | 137 | | --platform, -p | the platform to build | 138 | | --DEBUG, -d | debug flag | 139 | | --RELEASE, -r | release flag | 140 | | --cleanall | cleans all | 141 | 142 | 143 | ### Aowanda Build Information 144 | 145 | **Building with the python script** 146 | 147 | 1. Open command window, go to the workspace directory, e.g. c:\Edk2Workspace 148 | 2. Type "cd edk2-platforms/Platform/Intel 149 | 3. Type "python build_bios.py -p Aowanda" 150 | 4. On successful build, IFWI (Integrated Firmware Image) AOWANDA.bin and BIOS AOWANDA.fd rom files are created. 151 | 152 | * build_bios.py arguments: 153 | 154 | | Argument | Function | 155 | | ----------------------|-------------------------------------| 156 | | -h, --help | show this help message and exit | 157 | | --platform, -p | the platform to build | 158 | | --DEBUG, -d | debug flag | 159 | | --RELEASE, -r | release flag | 160 | | --cleanall | cleans all | 161 | 162 | 163 | ### MtJade Build Information 164 | 165 | Refer to https://github.com/opencomputeproject/OSF-Aptio-OpenEdition/tree/OE-AMI-MtJade-202206 branch 166 | 167 | ### Onyx Build Information 168 | 169 | Refer to https://github.com/opencomputeproject/OSF-Aptio-OpenEdition/tree/OE-AMI-Genoa_openSIL branch 170 | 171 | ### **Binary and Reference Code Details** 172 | 173 | * [EDK2](https://github.com/tianocore/edk2) source based on edk2-stable202308 (Pixiefail nine Vulnerabilities included) 174 | * [EDK2-Platforms](https://github.com/tianocore/edk2-platforms) source based on commit hash bb6841e3fd1c60b3f8510b4fc0a380784e05d326 175 | * [EDK2-Non-OSI](https://github.com/tianocore/edk2-non-osi) source based on commit hash 8c09bd0955338db38813e0d8ae1faa634f545f73 176 | * [FSP](https://github.com/IntelFsp/FSP) source based on commit hash 46a88ff1e9ed45bb9bfcfa4654d292d60b30f442 177 | 178 | ### **Validation Details** 179 | 180 | * All firmware projects can only build on Windows with the validated configuration below. 181 | 182 | **WhitleyOpenBoardPkg** 183 | 184 | **This firmware project has only been tested on the Junction City hardware**. 185 | * This firmware project build has only been tested using the Microsoft Visual Studio 2015 build tools. 186 | * Booted to UEFI shell. 187 | * Booted to UEFI Windows Server 2019 on M.2 NVME Slot. 188 | * Booted to UEFI Windows Server 2019 using SATA HDD. 189 | * Booted to UEFI RHEL 8.3 using SATA HDD and U2 SSD. 190 | * Booted to Ubuntu 18.04 on SATA slot and U2 SSD. 191 | * Verified PCIE LAN card detection during POST and OS. 192 | * Verified TPM offboard chip detection 193 | 194 | **This firmware project has only been tested on the Aowanda AD1S01 hardware**. 195 | * This firmware project build has only been tested using the Microsoft Visual Studio 2015 build tools. 196 | * Booted to UEFI shell. 197 | * Booted to UEFI Windows Server 2019 on M.2 NVME Slot. 198 | * Booted to UEFI RHEL 8.3 using SATA on M.2 NVME Slot. 199 | * Verified onboard PCIE LAN card detection in POST and OS. 200 | * All the above testing is done using AMI MEGARAC SPX FW version 0.14.0 Remote KVM redirection 201 | 202 | 203 | ### **New Features** 204 | * None 205 | 206 | ### **Planned Activities** 207 | * Sync with latest EDKII and EDKII platforms 208 | 209 | ### **Additional Support and Customizations** 210 | * To get dedicated support or additional features or customizations for Aptio OpenEdition, feel free to email sales@ami.com 211 | -------------------------------------------------------------------------------- /Readme_VisualStudioInstall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opencomputeproject/OCP-OSF-Aptio_Community_Edition/ce8711dad7cfdd4fd7db6d1626f508d867c3444f/Readme_VisualStudioInstall.png -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | Use this section to tell people about which versions of your project are 6 | currently being supported with security updates. 7 | 8 | | Version | Supported | 9 | | ------- | ------------------ | 10 | | 5.1.x | :white_check_mark: | 11 | | 5.0.x | :x: | 12 | | 4.0.x | :white_check_mark: | 13 | | < 4.0 | :x: | 14 | 15 | ## Reporting a Vulnerability 16 | 17 | Use this section to tell people how to report a vulnerability. 18 | 19 | Tell them where to go, how often they can expect to get an update on a 20 | reported vulnerability, what to expect if the vulnerability is accepted or 21 | declined, etc. 22 | -------------------------------------------------------------------------------- /Trademark.md: -------------------------------------------------------------------------------- 1 | ## **American Megatrends International LLC** 2 | 3 | - American Megatrends International LLC grants a limited usage of the Aptio OpenEdition trademark for those using the source in this repository. 4 | 5 | - American Megatrends International LLC is not responsible for any damage incurred by organizations using this source code or trademark. 6 | - American Megatrends International LLC grants the usage of the Aptio OpenEdition trademark allowing individuals or organizations using the source in this repository to claim their product is "Based on Aptio OpenEdition". 7 | - American Megatrends International LLC also allows the usage of "Aptio OE" and "Aptio-OE" as alternatives for "Aptio OpenEdition". All other usage of Aptio and derivatives is specifically prohibited and those wishing to attain a more liberal usage of the Aptio and/or Aptio OpenEdition trademark can contact [Marketing@ami.com](mailto:Marketing@ami.com) for assistance. 8 | -------------------------------------------------------------------------------- /governance.md: -------------------------------------------------------------------------------- 1 | 2 | ## Project Governance Policy 3 | 1. **Introduction** 4 | The Software Project is an open source software project led by contributors, code committers, and optionally a technical steering committee (TSC). The Software Project is administered by the OCP Foundation and the IC, which has reviewed and adopted (by majority vote) the Software Project charter and its governance policy (if applicable). This governance model is based on the best practices and values of the open source culture and pursues the goals set by the OCP Foundation. The Software Project functions under the auspices of OCP. Each Software Project shall author a Project Charter that shall be accepted by a majority vote of the IC. 5 | 6 | 2. **Charter and Scope of the Software Project** 7 | The approved charter of the Software Project shall be published on the OCP website under its corresponding Project web page. 8 | 9 | - The scope of the Software Project shall include software development under an OSI-approved open source license. 10 | - The specifications must be under the [OCP Software Contributor License Agreement](https://www.opencompute.org/documents/software-contributor-license-agreement) 11 | 12 | ## Software Contribution Guidelines 13 | The Software Project accepts contributions via GitHub pull requests. The following section outlines the process for merging contributions to the source code and the spec. 14 | 15 | 1. **Issues** 16 | Issues are used as the primary method for tracking anything to do with the source code and specification repository. 17 | 2. **Issue Types** 18 | For the source code contributions, the issue types could be any of the following: 19 | - *Sub-task*: This is the sub-task of an issue. In a logged issue, there can be different tasks to resolve, which are called sub-tasks. 20 | - *Bug*: A problem that impairs or prevents the functions of the product. 21 | - *Epic*: A big user story that needs to be broken down. 22 | - *Improvement*: An improvement or enhancement to an existing feature or task. 23 | - *New feature*: A new feature of the product, which is yet to be developed. 24 | - *Task*: A task that needs to be done to achieve the team's goal. 25 | 26 | Specification issue types are listed below: 27 | 28 | - *Discussion*: These are support or functionality inquiries that we want to have a record for future reference. Depending on the discussion, these can turn into "Spec Change" issues. 29 | 30 | - *Proposal*: Used for items that propose new ideas or functionality that require a larger discussion. This allows for feedback from the community before a specification change is actually written. All issues that are proposals should both have a label and an issue title of "Proposal: [the rest of the title]." A proposal can become a "Spec Change" and does not require a milestone. 31 | 32 | - *Spec Change*: These track specific spec changes and ideas until they are complete. They can evolve from "Proposal" and "Discussion" items, or they can be submitted individually depending on the size. Each spec change should be placed into a milestone. 33 | 34 | ## Software Community & Membership 35 | The Software Project requires no admission processes, contracts, or membership fees. Any individual or organization can use and contribute to a Software Project. We welcome any contributions that lead to the success of the project - including software development, documentation, testing, delivery and advocacy. 36 | 37 | ## Software Compliance Program 38 | The Software Project may also provide a compliance or branding program for individuals or organizations to register as participants, or to register products, board support packages (BSPs), or software layers as Project Compatible. Any compliance or branding programs must be approved by the OCP Foundation. The compliance or branding program is intended to promote the use and adoption of the open sourced software, regardless of an individual or corporate affiliation with OCP. Participants in the compliance program, at the discretion of the Foundation and with their permission, may be listed on the [OCP Marketplace](http://www.opencompute.org/products/), OCP Integrated solutions and any OCP portal pages or on the [OCP GitHub](https://github.com/opencomputeproject) pages. 39 | 40 | ## Software Project Management 41 | The Software Project is developed and designed using a collaborative effort by an open community of professionals and volunteers. The success of the Software Project is based on collaboration and governance based on meritocracy. 42 | 43 | **Roles and Responsibilities** 44 | 45 | ● *PLs* are responsible for the success of the Software Project and to align with the approved charter. The PL is a volunteer position, initially appointed by OCP and approved by the IC. After initial appointment, the PL position will be elected in accordance with OCP Governance or the project specific governance policy. The PLs will be accountable for the following: 46 | 47 | ○ Wiki Maintenance 48 | ○ Meeting agenda and minutes 49 | ○ Engineering Workshops – agenda and content 50 | 51 | ● *Contributors* are people who have submitted work to the Software Project. Contributors include anyone in the technical community that contributes code, documentation or other technical artifacts to the Software Project. In addition to their actions as users, Contributors may also find themselves doing one or more of the following: 52 | 53 | ○ Supporting new users (existing users are often the best people to support new users) 54 | ○ Reporting bugs 55 | ○ Identifying requirements 56 | ○ Assisting with project infrastructure 57 | ○ Writing documentation 58 | ○ Fixing bugs 59 | ○ Adding features 60 | 61 | ● *Committers*: Committers are contributors who have earned the ability to modify (“commit”) source code, documentation or other technical artifacts in a Software Project’s repository. A contributor may become a committer by a majority approval of the existing committers. A committer may be also removed by a majority approval of the other existing committers. 62 | 63 | ● *Maintainers*: There are two types of maintainers 64 | 65 | - Source code maintainers 66 | - Specification maintainers. 67 | 68 | Source code Maintainers have permission to accept pull requests and merge them into the master branch of a given repository. Each repository contains a MAINTAINERS file listing the maintainers. There must be one or more named maintainers per repository. 69 | Specification Maintainers are responsible for organizing activities around developing, maintaining, and updating the specification(s) developed by the working project. These maintainers are also responsible for determining consensus and coordinating appeals. 70 | 71 | ● *Editor*: Editors are required for specification management only and are responsible for ensuring that the contents of the document accurately reflect the decisions that have been made by the project, and that the specification adheres to formatting and content guidelines. Project will designate an Editor. 72 | 73 | ● *Participants*: They are required for specification management only and are those that have made contributions to the Working Group or to the specification repository. 74 | 75 | ● *ICR (IC Representative)*: The ICR is an ambassador to other OCP Project Communities. They will work with the PLs and other ICRs to ensure that the Software Project is fitting within the OCP ecosystem. 76 | 77 | ● *Technical Steering Committee (TSC)* `Optional`- TSC may be formed to provide leadership and resolve technical differences that may arise from time to time. The decision to create or dissolve a TSC must be approved by the OCP Foundation 78 | 79 | - The TSC will be responsible for oversight of the open source project and assure the Software Project aligns with the approved charter. 80 | 81 | - The TSC members are initially the Software Project’s code Committers when the Software Project exits the “Incubation Phase” and enters the “Impact Phase”. The Committers will determine the Project’s code repository. 82 | 83 | - Any meetings of the TSC are intended to be open to the public and can be conducted electronically, via teleconference, or in person. 84 | - The TSC may 85 | 86 | - Establish workflow procedures for the submission, approval, and closure/archiving of Project. 87 | - Set requirements for the promotion of contributors to committer status, as applicable. 88 | - Amend, adjust, refine and/or eliminate the roles of contributors, and committers, and create new roles, and publicly document any TSC roles, as it sees fit. 89 | 90 | - The TSC shall elect a chair who will preside over meetings of the TSC. The TSC shall elect a new chair every 12 months. A current or previous chairperson is eligible to serve any number of terms as chair. 91 | - The TSC shall review its membership every 12 months, in the month following the election of the TSC chair. Membership on the TSC is limited to code committers (or persons employed by a code committing company). Members are added or removed by majority vote of the TSC. An existing TSC member that has not committed code within the prior 12 months may be disqualified from the TSC. 92 | - The TSC will be responsible for all technical aspects or oversight relating to the Software Project. When such responsibilities involve vital functions performed by the OCP Foundation, the TSC shall seek support and ratification. These responsibilities may include (but not limited to) the following: 93 | - Maintain a roadmap of planned feature additions or subtractions, with expected timeline for feature release. 94 | - Approve Software Project or system proposals (including, but not limited to, incubation, deprecation and changes to a Sub-Project’s scope); 95 | - Appointing representatives to work with other open source or open standards communities; 96 | - Establishing community norms, workflows, issuing releases, and security issue reporting policies; 97 | - Approving and implementing policies and processes for contributing (to be published in the repository) and coordinating with the OCP Foundation and IC to resolve matters or concerns that may arise; 98 | - Holding open discussions, seeking consensus, and where necessary, voting on technical matters relating to the code base that affect multiple projects; 99 | - Coordinating any marketing, events, or communications regarding the Software Project with the OCP Foundation. 100 | - Publishing the list of TSC members and contact information on the repository. 101 | 102 | ## TSC Voting 103 | 104 | - While the Software Project aims to operate as a consensus-based community, if any TSC decision requires a vote to move the Software Project forward, the voting members of the TSC will vote on a one vote per voting member basis. 105 | - Quorum for TSC meetings requires at least two-thirds of all voting members of the TSC to be present. The TSC may continue to meet if quorum is not met, but the TSC will be prevented from making any decisions at the meeting. 106 | - Decisions by vote at a meeting require a majority vote of those in attendance, provided a quorum is met. Decisions made by electronic vote without a meeting require a majority vote of all voting members of the TSC. 107 | - In the event a vote cannot be resolved by the TSC, any voting member of the TSC may refer the matter to the OCP IC for assistance in reaching a resolution. In the case of a tie vote, the IC will cast the deciding vote. 108 | --------------------------------------------------------------------------------