Newer
Older
AMI-Aptio-BIOS-Reversed / Udp6Dxe / Udp6Dxe.md
@Ajax Dong Ajax Dong 2 days ago 11 KB Init

Udp6Dxe

Function Table

Address Name Description
Udp6CreateIp6Child
Udp6DestroyIp6Child
Udp6ComponentNameGetDriverName
Udp6ComponentNameGetControllerName
Udp6DriverEntryPoint
Udp6DriverBindingSupported
Udp6DriverBindingStart
Udp6DriverBindingStop
Udp6ServiceBindingCreateChild
Udp6ServiceBindingDestroyChild
Udp6TimerHandler
Udp6DgramSent
Udp6InstanceMatchDgram
Udp6DeliverDgram
Udp6DgramRcvd
Udp6DgramRcvdIcmpError
Udp6GetModeData
Udp6Configure
Udp6Groups
Udp6Transmit
Udp6Receive
Udp6Cancel
Udp6Poll
Save global pointers
gImageHandle = ImageHandle;
Query NetworkStackVar runtime variable to check if stack is enabled
VarSize = sizeof (BOOLEAN);
Save image handle for driver binding
Install Driver Binding + Component Name protocols
Compute random port base using timer-derived value
gUdp6RandomPort = (UINT16)((Udp6GetRandomValue () & 0x3FF) + 1024);
Get open protocol information for the controller
Status = gBS->OpenProtocolInformation (
Walk the open info looking for our driver binding handle
for (Index = 0; Index < OpenInfoCount; Index++) {
Open the UDP6 service binding protocol on the controller
Status = gBS->OpenProtocol (
Verify service signature
ASSERT (Udp6Service->Signature == UDP6_SERVICE_SIGNATURE);
Create a new child instance via the service binding protocol
Status = Udp6Service->ServiceBinding.CreateChild (
No remaining path - check if we have children to destroy
if (!IsListEmpty (&Udp6Service->InstanceList)) {
No instances - tear down the service
Locate the service binding protocol on the controller
Udp6Service = UDP6_SERVICE_FROM_PROTOCOL (Udp6Service);
Already being destroyed?
if (Udp6Service->InDestroy) {
Close the IP6 protocol on the IpIo child handle
Destroy the IpInfo context via IpIo library
Udp6DestroyIp6Child (Udp6Service);
Remove from instance list
RemoveEntryList (&Udp6Service->InstanceList.ForwardLink);
Decrement instance count
Clean up token maps (Tx, Rx, Mcast)
NetMapClean (&Udp6Service->TxTokens);
Free the service structure
Allocate zero-filled instance (0x158 bytes)
Instance = AllocateZeroPool (sizeof (UDP6_INSTANCE));
Copy the protocol function table template
CopyMem (&Instance->Protocol, &gUdp6ProtocolTemplate, sizeof (EFI_UDP6_PROTOCOL));
Initialize remaining fields
Create IP info context via IpIo library
IpInfo = IpIoAddIpInfo (Udp6Service->IpIo);
Install the UDP6 protocol interface on the child handle
Status = gBS->InstallProtocolInterface (
Open IP6 protocol on the child handle (by child controller)
Link into service's instance list
InsertTailList (&Udp6Service->InstanceList, &Instance->ServiceLink);
Get the protocol interface on the child handle
Instance = CONTAINER_OF (ProtocolInterface, UDP6_INSTANCE, Protocol)
Instance = UDP6_INSTANCE_FROM_PROTOCOL (ProtocolInterface);
Uninstall protocol interface
Close IP6 protocol opened as child controller
Status = gBS->CloseProtocol (
Continue cleanup even if close fails
Destroy IpInfo
IpIoRemoveIpInfo (Instance->Service->IpIo, Instance->IpInfo);
RemoveEntryList (&Instance->ServiceLink);
Clean token maps
NetMapClean (&Instance->TxTokens);
Free instance
ZeroMem (Udp6Service, sizeof (UDP6_SERVICE));
Create the IP IO context
Register datagram received callback
Status = IpIoSetReceiveHandler (
Register ICMP error received callback
Status = IpIoSetIcmpErrorHandler (
Configure the IpIo with default UDP6 config
Status = IpIoConfigure (
Create periodic 500ms timer
Status = gBS->CreateEvent (
500ms );
Walk the instance list
for (Entry = Udp6Service->InstanceList.ForwardLink;
Process delivered datagram queue timeouts
Each entry has a UINT32 timeout field at offset +0x18 in the queue item
if (Instance->IsConfigured && !IsListEmpty (&Instance->DeliveredDgramQue)) {
Read the timeout field from the RxData structure
Timeout = ((UINT32 )((UINT8 )DgramEntry - sizeof (LIST_ENTRY)))[6];
Timeout expired: remove entry and recycle RxData
DgramEntry = DgramEntry->ForwardLink;
Dispatch as received datagram
Udp6DgramRcvd (Context, IsMulticast, Packet, Session, IpProtocol);
No service context - deliver directly
Udp6DeliverDgram (NULL, Packet, 0, NULL, 0, NULL);
Promiscuous mode: accept everything
if (Instance->ConfigData.AcceptPromiscuous) {
if (!Instance->ConfigData.AcceptAnyPort) {
Check remote port (if instance has one configured)
InstanceRemotePort = NTOHS (Instance->ConfigData.RemotePort);
Check remote address (if not unspecified)
for (Index = 0; Index < 16; Index++) {
Remote address is specified - must match
if (CompareMem (
Check local address (if not unspecified)
Station address is specified - must match destination
If destination is multicast, check membership
if (DstAddr->Addr[0] == 0xFF) {
Verify checksum if present
if (Udp6Header->Checksum != 0) {
Checksum failure - drop packet
return NetbufFree (Packet);
Extract ports from header
SrcPort = NTOHS (Udp6Header->SrcPort);
Strip the UDP header from the packet
NetbufTrim (Packet, sizeof (EFI_UDP6_HEADER), NET_BUF_HEAD);
Deliver to the matching instance
return Udp6InternalDeliver (Instance, Packet, &SrcAddr, SrcPort, &DstAddr, DstPort);
Walk all UDP6 instances on this service
Check if this instance wants this datagram
if (Udp6InstanceMatchDgram (
Session contains IP6 addresses
Deliver the datagram to this instance
Udp6DeliverDgram (
Free the NET_BUF
NetbufFree (Nbuf);
Only handle ICMPv6 protocol errors (Protocol == 6 = ICMPv6)
if (IpProtocol != 6) {
Allocate IP6 mode data to determine MTU
Ip6ModeData = AllocateZeroPool (sizeof (EFI_IP6_MODE_DATA));
Get IP6 mode data (prefer instance-specific, fall back to service)
Ip6 = (EFI_IP6_PROTOCOL *)IpIoGetIp6Protocol (Udp6Service->IpIo);
Calculate allocation size: ICMP header + UDP header + data
AllocSize = sizeof (EFI_IP6_ICMP_ERROR_HEADER) + Nbuf->TotalSize;
Build ICMP error notification
IcmpErrBuf = AllocatePool (AllocSize);
Build the ICMP error header
Reserved / checksum (set to 0)
Copy the original UDP datagram (payload portion)
CopyMem ((UINT8 *)IcmpErrHdr + 8, Nbuf->Data, Nbuf->TotalSize);
Send the ICMP error via IpIo
IpIoSend (Udp6Service->IpIo, IcmpErrBuf, AllocSize, IcmpErrHdr);
Copy the instance's config data to the caller
if (Udp6ConfigData != NULL) {
Delegate to IP6->GetModeData (the first function in EFI_IP6_PROTOCOL)
if (Instance->Ip6 != NULL) {
If not configured and no config data, just return success
if (!Instance->IsConfigured && UdpConfigData == NULL) {
Validate the config data
CopyMem (&LocalAddr, &UdpConfigData->StationAddress, sizeof (EFI_IPv6_ADDRESS));
Check for invalid addresses (multicast source = 0xFF)
If already configured with same data, just acknowledge
if (Instance->IsConfigured &&
If already configured, re-configure the IP6 layer
if (Instance->IsConfigured) {
Update IP6 configuration
CopyMem (&DefaultConfig, &gUdp6DefaultConfigData, sizeof (EFI_UDP6_CONFIG_DATA));
Copy config to instance
CopyMem (&Instance->ConfigData, UdpConfigData, sizeof (EFI_UDP6_CONFIG_DATA));
Add instance to multicast group (if configured)
if (Instance->ConfigData.StationAddress.Addr[0] != 0) {
Clean up IP6 config
Compute checksum seed for this connection
Tell IP6 layer to reset
Flush delivered datagram queue
while (!IsListEmpty (&Instance->DeliveredDgramQue)) {
if (MulticastAddress->Addr[0] != 0xFF) {
Allocate and insert multicast address into McastIps map
McastAddrCopy = AllocateCopyPool (sizeof (EFI_IPv6_ADDRESS), MulticastAddress);
Delegate multicast to IP6 layer
Status = Instance->Ip6->Groups (
Clean up map entry if IP6 failed
if (JoinFlag) {
Leaving all groups - clean up the map
NetMapRemoveTail (&Instance->McastIps, NULL);
Validate the token
Status = Udp6ValidateTxToken (Instance, Token);
Check for duplicate token (already in TX or RX map)
if **(NetMapFind (&Instance->TxTokens, Token) != NULL **
Get TX data from token
TxData = Token->Packet.TxData;
Allocate NET_BUF with UDP header space + fragment data
Nbuf = NetbufAllocWithSize (
Allocate UDP header fragment
Udp6Header = (EFI_UDP6_HEADER *)NetbufAllocFragment (Nbuf, sizeof (EFI_UDP6_HEADER), 1);
Build UDP header with ports in network byte order
Insert token into TX map
Status = NetMapInsertTail (&Instance->TxTokens, Token, Nbuf);
Send via IpIo
Status = IpIoSend (
Signal completion (I/O is synchronous in this implementation)
Check for duplicate token in TxTokens or RxTokens maps
if **(NetMapFind (&Instance->TxTokens, Token) != EFI_NOT_FOUND **
Insert the token into RxTokens map
Status = NetMapInsertTail (&Instance->RxTokens, Token, NULL);
Find the token in RxTokens map; if not found, return error
if **(NetMapFind (&Instance->RxTokens, Token) == EFI_NOT_FOUND **
Remove the token from RxTokens map
Status = NetMapRemoveItem (&Instance->RxTokens, Token, NULL);
Recycle delivered datagrams and poll the IP IO layer
Udp6RecycleDeliveredDgram (Instance);
Delegate to IP6->GetModeData to trigger packet processing

Generated by HR650X BIOS Decompilation Project