33 OUT UINT32 *SourceCount
44 if (IpSb->LinkLocalOk) {
47 return EFI_OUT_OF_RESOURCES;
50 Copy->Signature = IP6_ADDR_INFO_SIGNATURE;
51 IP6_COPY_ADDRESS (&Copy->Address, &IpSb->LinkLocalAddr);
52 Copy->IsAnycast =
FALSE;
53 Copy->PrefixLength = IP6_LINK_LOCAL_PREFIX_LENGTH;
54 Copy->ValidLifetime = (UINT32)IP6_INFINIT_LIFETIME;
55 Copy->PreferredLifetime = (UINT32)IP6_INFINIT_LIFETIME;
61 NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) {
64 NET_LIST_FOR_EACH (Entry2, &IpIf->AddressList) {
65 AddrInfo = NET_LIST_USER_STRUCT_S (Entry2,
IP6_ADDRESS_INFO, Link, IP6_ADDR_INFO_SIGNATURE);
67 if (AddrInfo->IsAnycast) {
76 return EFI_OUT_OF_RESOURCES;
112 ByteA = AddressA->Addr[Index];
113 ByteB = AddressB->Addr[Index];
115 if (ByteA == ByteB) {
125 ByteA = (UINT8)(ByteA ^ ByteB);
129 ByteA = (UINT8)(ByteA >> 1);
132 return (UINT8)(Count + NumBits);
166 UINT8 LastCommonLength;
167 UINT8 CurrentCommonLength;
170 NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);
175 if (!IpSb->LinkLocalOk) {
176 return EFI_NO_MAPPING;
183 IP6_COPY_ADDRESS (Source, Destination);
190 if (IP6_IS_MULTICAST (Destination)) {
191 ScopeD = (UINT8)(Destination->Addr[1] >> 4);
203 IP6_COPY_ADDRESS (Source, &IpSb->LinkLocalAddr);
212 if (SourceCount == 0) {
213 Status = EFI_NO_MAPPING;
217 IP6_COPY_ADDRESS (Source, &IpSb->LinkLocalAddr);
219 if (SourceCount == 1) {
227 NET_LIST_FOR_EACH (Entry, &IpSb->AutonomousPrefix) {
229 if (Prefix->PreferredLifetime == 0) {
230 Ip6RemoveAddr (
NULL, &SourceList, &SourceCount, &Prefix->Prefix, Prefix->PrefixLength);
232 if (SourceCount == 1) {
251 for (Entry = SourceList.ForwardLink; Entry != &SourceList; Entry = Entry->ForwardLink) {
252 AddrInfo = NET_LIST_USER_STRUCT_S (Entry,
IP6_ADDRESS_INFO, Link, IP6_ADDR_INFO_SIGNATURE);
255 if (CurrentCommonLength > LastCommonLength) {
256 LastCommonLength = CurrentCommonLength;
257 TmpAddress = &AddrInfo->Address;
261 if (TmpAddress !=
NULL) {
262 IP6_COPY_ADDRESS (Source, TmpAddress);
297 NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);
298 ASSERT (Destination !=
NULL && Source !=
NULL);
315 if (EFI_ERROR (Status)) {
316 return IpSb->DefaultInterface;
320 IP6_COPY_ADDRESS (Source, &SelectedSource);
371 IN UINT16 FragmentOffset,
373 IN UINT32 ExtHdrsLen,
379 UINT32 UnFragExtHdrsLen;
381 UINT8 *UpdatedExtHdrs;
385 UpdatedExtHdrs =
NULL;
392 if (PacketHead ==
NULL) {
393 return EFI_BAD_BUFFER_SIZE;
400 PacketHead->PayloadLength = HTONS ((UINT16)(Packet->TotalSize - sizeof (
EFI_IP6_HEADER)));
401 Packet->Ip.Ip6 = PacketHead;
406 if (UnFragExtHdrsLen == 0) {
407 PacketHead->NextHeader = IP6_FRAGMENT;
414 if ((FragmentOffset & IP6_FRAGMENT_OFFSET_MASK) == 0) {
415 NextHeader = Head->NextHeader;
417 NextHeader = PacketHead->NextHeader;
429 if (EFI_ERROR (Status)) {
434 (UINT8 *)(PacketHead + 1),
483 IN UINT32 ExtHdrsLen,
484 IN IP6_FRAME_CALLBACK Callback,
495 UINT16 FragmentOffset;
497 UINT32 UnFragmentLen;
498 UINT32 UnFragmentHdrsLen;
499 UINT32 FragmentHdrsLen;
501 UINT16 PacketChecksum;
502 UINT16 PseudoChecksum;
515 UINT8 *UpdatedExtHdrs;
517 UINT8 LastHeaderBackup;
518 BOOLEAN FragmentHeadInserted;
519 UINT8 *ExtHdrsBackup;
520 UINT8 NextHeaderBackup;
524 NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);
530 if ((ExtHdrsLen & 0x7) != 0) {
531 return EFI_INVALID_PARAMETER;
560 if ((IpInstance ==
NULL) || (IpInstance->Interface ==
NULL)) {
562 if (IpInstance !=
NULL) {
563 IpInstance->Interface = IpIf;
566 IpIf = IpInstance->Interface;
571 return EFI_NO_MAPPING;
578 Head->TrafficClassL = 0;
579 Head->TrafficClassH = 0;
582 NextHeader = *LastHeader;
584 switch (NextHeader) {
585 case EFI_IP_PROTO_UDP:
587 ASSERT (Packet->Udp !=
NULL);
588 if (Packet->Udp->Checksum == 0) {
589 Checksum = &Packet->Udp->Checksum;
594 case EFI_IP_PROTO_TCP:
596 ASSERT (Packet->Tcp !=
NULL);
597 if (Packet->Tcp->Checksum == 0) {
598 Checksum = &Packet->Tcp->Checksum;
608 return EFI_INVALID_PARAMETER;
612 ASSERT (IcmpHead !=
NULL);
613 if (IcmpHead->Checksum == 0) {
614 Checksum = &IcmpHead->Checksum;
623 if (Checksum !=
NULL) {
630 &Head->SourceAddress,
631 &Head->DestinationAddress,
635 *Checksum = (UINT16) ~
NetAddChecksum (PacketChecksum, PseudoChecksum);
649 if (EFI_ERROR (Status)) {
671 return EFI_INVALID_PARAMETER;
674 if ((RealExtLen & 0x7) != 0) {
675 return EFI_INVALID_PARAMETER;
678 LastHeaderBackup = *LastHeader;
685 if (IP6_IS_MULTICAST (&Head->DestinationAddress)) {
686 IP6_COPY_ADDRESS (&NextHop, &Head->DestinationAddress);
694 if (NeighborCache !=
NULL) {
698 IP6_COPY_ADDRESS (&NextHop, &Head->DestinationAddress);
703 RouteCache =
Ip6Route (IpSb, &Head->DestinationAddress, &Head->SourceAddress);
704 if (RouteCache ==
NULL) {
705 return EFI_NOT_FOUND;
708 IP6_COPY_ADDRESS (&NextHop, &RouteCache->NextHop);
717 if (!IP6_IS_MULTICAST (&NextHop) && !EFI_IP6_EQUAL (&Head->DestinationAddress, &Head->SourceAddress)) {
719 if (NeighborCache ==
NULL) {
722 if (NeighborCache ==
NULL) {
723 return EFI_OUT_OF_RESOURCES;
731 if (EFI_ERROR (Status)) {
739 &NeighborCache->Neighbor,
740 &IpSb->SnpMode.CurrentAddress
742 if (EFI_ERROR (Status)) {
746 --NeighborCache->Transmit;
747 NeighborCache->Ticks = IP6_GET_TICKS (IpSb->RetransTimer) + 1;
750 NeighborCache->Interface = IpIf;
753 UpdatedExtHdrs =
NULL;
754 ExtHdrsBackup =
NULL;
755 NextHeaderBackup = 0;
756 FragmentHeadInserted =
FALSE;
764 &Head->DestinationAddress,
767 if (RouteEntry !=
NULL) {
768 if ((RouteEntry->Flag & IP6_PACKET_TOO_BIG) == IP6_PACKET_TOO_BIG) {
784 if (EFI_ERROR (Status)) {
788 if ((ExtHdrs ==
NULL) && (ExtHdrsLen == 0)) {
789 NextHeaderBackup = Head->NextHeader;
790 Head->NextHeader = IP6_FRAGMENT;
793 ExtHdrsBackup = ExtHdrs;
794 ExtHdrs = UpdatedExtHdrs;
800 FragmentHeadInserted =
TRUE;
815 if (Packet->TotalSize + HeadLen > Mtu) {
819 if (FragmentHeadInserted) {
820 ExtHdrs = ExtHdrsBackup;
823 if ((ExtHdrs ==
NULL) && (ExtHdrsLen == 0)) {
824 Head->NextHeader = NextHeaderBackup;
828 FragmentHdrsLen = ExtHdrsLen - UnFragmentHdrsLen;
834 if ((((Packet->TotalSize + FragmentHdrsLen) >> 3) & (~0x1fff)) != 0) {
835 Status = EFI_BAD_BUFFER_SIZE;
839 if (FragmentHdrsLen != 0) {
846 ASSERT (TmpPacket !=
NULL);
852 ASSERT (Buf !=
NULL);
853 CopyMem (Buf, ExtHdrs + UnFragmentHdrsLen, FragmentHdrsLen);
871 Mtu = (Mtu - UnFragmentLen) & (~0x07);
872 Num = (Packet->TotalSize + Mtu - 1) / Mtu;
874 for (Index = 0, Offset = 0, PacketLen = Mtu; Index < Num; Index++) {
880 if (Fragment ==
NULL) {
881 Status = EFI_OUT_OF_RESOURCES;
885 FragmentOffset = (UINT16)((UINT16)Offset | 0x1);
886 if (Index == Num - 1) {
890 FragmentOffset &= (~0x1);
913 if (EFI_ERROR (Status)) {
920 if ((Index == Num -1) && (Context !=
NULL)) {
922 Wrap->Token->
Status = Status;
926 PacketLen = Packet->TotalSize - Offset;
927 if (PacketLen > Mtu) {
935 if (UpdatedExtHdrs !=
NULL) {
946 if (PacketHead ==
NULL) {
947 Status = EFI_BAD_BUFFER_SIZE;
952 Packet->Ip.Ip6 = PacketHead;
954 if (ExtHdrs !=
NULL) {
955 Buf = (UINT8 *)(PacketHead + 1);
956 CopyMem (Buf, ExtHdrs, ExtHdrsLen);
959 if (UpdatedExtHdrs !=
NULL) {
963 PacketHead->PayloadLength = (UINT16)(NTOHS (PacketHead->PayloadLength) +
965 PacketHead->PayloadLength = HTONS (PacketHead->PayloadLength);
979 if (UpdatedExtHdrs !=
NULL) {
1004 if ((Frame->Packet == (
NET_BUF *)Context) || (Frame->Context == Context)) {
1027 IN IP6_FRAME_TO_CANCEL FrameToCancel OPTIONAL,
1028 IN VOID *Context OPTIONAL
1038 IpSb = Interface->Service;
1039 NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);
1044 NET_LIST_FOR_EACH_SAFE (Entry, Next, &Interface->ArpQues) {
1063 NET_LIST_FOR_EACH_SAFE (Entry, Next, &Interface->SentFrames) {
1066 if ((FrameToCancel ==
NULL) || FrameToCancel (Token, Context)) {
1067 IpSb->Mnp->Cancel (IpSb->Mnp, &Token->MnpToken);
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
struct _EFI_IP6_HEADER EFI_IP6_HEADER
VOID Ip6CreateSNMulticastAddr(IN EFI_IPv6_ADDRESS *Ip6Addr, OUT EFI_IPv6_ADDRESS *MulticastAddr)
EFI_STATUS Ip6RemoveAddr(IN IP6_SERVICE *IpSb OPTIONAL, IN OUT LIST_ENTRY *AddressList, IN OUT UINT32 *AddressCount, IN EFI_IPv6_ADDRESS *Prefix OPTIONAL, IN UINT8 PrefixLength)
BOOLEAN Ip6IsOneOfSetAddress(IN IP6_SERVICE *IpSb, IN EFI_IPv6_ADDRESS *Address, OUT IP6_INTERFACE **Interface OPTIONAL, OUT IP6_ADDRESS_INFO **AddressInfo OPTIONAL)
BOOLEAN Ip6IsAnycast(IN IP6_SERVICE *IpSb, IN EFI_IPv6_ADDRESS *DestinationAddress)
EFI_STATUS Ip6SendFrame(IN IP6_INTERFACE *Interface, IN IP6_PROTOCOL *IpInstance OPTIONAL, IN NET_BUF *Packet, IN EFI_IPv6_ADDRESS *NextHop, IN IP6_FRAME_CALLBACK CallBack, IN VOID *Context)
EFI_STATUS Ip6SendNeighborSolicit(IN IP6_SERVICE *IpSb, IN EFI_IPv6_ADDRESS *SourceAddress, IN EFI_IPv6_ADDRESS *DestinationAddress, IN EFI_IPv6_ADDRESS *TargetIp6Address, IN EFI_MAC_ADDRESS *SourceLinkAddress OPTIONAL)
VOID Ip6OnArpResolved(IN VOID *Context)
IP6_NEIGHBOR_ENTRY * Ip6CreateNeighborEntry(IN IP6_SERVICE *IpSb, IN IP6_ARP_CALLBACK CallBack, IN EFI_IPv6_ADDRESS *Ip6Address, IN EFI_MAC_ADDRESS *LinkAddress OPTIONAL)
EFI_STATUS Ip6FreeNeighborEntry(IN IP6_SERVICE *IpSb, IN IP6_NEIGHBOR_ENTRY *NeighborCache, IN BOOLEAN SendIcmpError, IN BOOLEAN FullFree, IN EFI_STATUS IoStatus, IN IP6_FRAME_TO_CANCEL FrameToCancel OPTIONAL, IN VOID *Context OPTIONAL)
IP6_NEIGHBOR_ENTRY * Ip6FindNeighborEntry(IN IP6_SERVICE *IpSb, IN EFI_IPv6_ADDRESS *Ip6Address)
BOOLEAN Ip6IsExtsValid(IN IP6_SERVICE *IpSb OPTIONAL, IN NET_BUF *Packet OPTIONAL, IN UINT8 *NextHeader, IN UINT8 *ExtHdrs, IN UINT32 ExtHdrsLen, IN BOOLEAN Rcvd, OUT UINT32 *FormerHeader OPTIONAL, OUT UINT8 **LastHeader, OUT UINT32 *RealExtsLen OPTIONAL, OUT UINT32 *UnFragmentLen OPTIONAL, OUT BOOLEAN *Fragmented OPTIONAL)
EFI_STATUS Ip6FillFragmentHeader(IN IP6_SERVICE *IpSb, IN UINT8 NextHeader, IN UINT8 LastHeader, IN UINT8 *ExtHdrs, IN UINT32 ExtHdrsLen, IN UINT16 FragmentOffset, OUT UINT8 **UpdatedExtHdrs)
UINT8 Ip6CommonPrefixLen(IN EFI_IPv6_ADDRESS *AddressA, IN EFI_IPv6_ADDRESS *AddressB)
VOID Ip6CancelFrames(IN IP6_INTERFACE *Interface, IN EFI_STATUS IoStatus, IN IP6_FRAME_TO_CANCEL FrameToCancel OPTIONAL, IN VOID *Context OPTIONAL)
EFI_STATUS Ip6PrependHead(IN IP6_SERVICE *IpSb, IN NET_BUF *Packet, IN EFI_IP6_HEADER *Head, IN UINT16 FragmentOffset, IN UINT8 *ExtHdrs, IN UINT32 ExtHdrsLen, IN UINT8 LastHeader, IN UINT32 HeadLen)
IP6_INTERFACE * Ip6SelectInterface(IN IP6_SERVICE *IpSb, IN EFI_IPv6_ADDRESS *Destination, IN OUT EFI_IPv6_ADDRESS *Source)
EFI_STATUS Ip6CandidateSource(IN IP6_SERVICE *IpSb, OUT LIST_ENTRY *SourceList, OUT UINT32 *SourceCount)
EFI_STATUS Ip6Output(IN IP6_SERVICE *IpSb, IN IP6_INTERFACE *Interface OPTIONAL, IN IP6_PROTOCOL *IpInstance OPTIONAL, IN NET_BUF *Packet, IN EFI_IP6_HEADER *Head, IN UINT8 *ExtHdrs, IN UINT32 ExtHdrsLen, IN IP6_FRAME_CALLBACK Callback, IN VOID *Context)
VOID Ip6CancelPacket(IN IP6_INTERFACE *IpIf, IN NET_BUF *Packet, IN EFI_STATUS IoStatus)
BOOLEAN Ip6CancelPacketFragments(IN IP6_LINK_TX_TOKEN *Frame, IN VOID *Context)
EFI_STATUS Ip6SelectSourceAddress(IN IP6_SERVICE *IpSb, IN EFI_IPv6_ADDRESS *Destination, OUT EFI_IPv6_ADDRESS *Source)
VOID Ip6SysPacketSent(NET_BUF *Packet, EFI_STATUS IoStatus, UINT32 LinkFlag, VOID *Context)
VOID Ip6FreeRouteCacheEntry(IN OUT IP6_ROUTE_CACHE_ENTRY *RtCacheEntry)
IP6_ROUTE_ENTRY * Ip6FindRouteEntry(IN IP6_ROUTE_TABLE *RtTable, IN EFI_IPv6_ADDRESS *Destination OPTIONAL, IN EFI_IPv6_ADDRESS *NextHop OPTIONAL)
IP6_ROUTE_CACHE_ENTRY * Ip6Route(IN IP6_SERVICE *IpSb, IN EFI_IPv6_ADDRESS *Dest, IN EFI_IPv6_ADDRESS *Src)
VOID Ip6FreeRouteEntry(IN OUT IP6_ROUTE_ENTRY *RtEntry)
#define ASSERT_EFI_ERROR(StatusParameter)
VOID EFIAPI NetbufFree(IN NET_BUF *Nbuf)
UINT16 EFIAPI NetIp6PseudoHeadChecksum(IN EFI_IPv6_ADDRESS *Src, IN EFI_IPv6_ADDRESS *Dst, IN UINT8 NextHeader, IN UINT32 Len)
UINT16 EFIAPI NetbufChecksum(IN NET_BUF *Nbuf)
BOOLEAN EFIAPI NetIp6IsLinkLocalAddr(IN EFI_IPv6_ADDRESS *Ip6)
UINT16 EFIAPI NetAddChecksum(IN UINT16 Checksum1, IN UINT16 Checksum2)
NET_BUF *EFIAPI NetbufGetFragment(IN NET_BUF *Nbuf, IN UINT32 Offset, IN UINT32 Len, IN UINT32 HeadSpace)
BOOLEAN EFIAPI NetIp6IsUnspecifiedAddr(IN EFI_IPv6_ADDRESS *Ip6)
UINT8 *EFIAPI NetbufAllocSpace(IN OUT NET_BUF *Nbuf, IN UINT32 Len, IN BOOLEAN FromHead)
UINT8 *EFIAPI NetbufGetByte(IN NET_BUF *Nbuf, IN UINT32 Offset, OUT UINT32 *Index OPTIONAL)
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
VOID EFIAPI Exit(IN EFI_STATUS Status)