# 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*