TianoCore EDK2 master
Loading...
Searching...
No Matches
Ip6Common.c
Go to the documentation of this file.
1
10#include "Ip6Impl.h"
11
30 IN IP6_SERVICE *IpSb,
31 OUT UINT32 *AddressCount,
32 OUT EFI_IP6_ADDRESS_INFO **AddressList OPTIONAL
33 )
34{
35 UINT32 Count;
36 LIST_ENTRY *Entry;
37 EFI_IP6_ADDRESS_INFO *EfiAddrInfo;
38 IP6_ADDRESS_INFO *AddrInfo;
39
40 if (AddressCount == NULL) {
41 return EFI_INVALID_PARAMETER;
42 }
43
44 if (IpSb->LinkLocalOk) {
45 Count = 1 + IpSb->DefaultInterface->AddressCount;
46 } else {
47 Count = 0;
48 }
49
50 *AddressCount = Count;
51
52 if ((AddressList == NULL) || (Count == 0)) {
53 return EFI_SUCCESS;
54 }
55
56 if (*AddressList == NULL) {
57 *AddressList = AllocatePool (sizeof (EFI_IP6_ADDRESS_INFO) * Count);
58 if (*AddressList == NULL) {
59 return EFI_OUT_OF_RESOURCES;
60 }
61 }
62
63 EfiAddrInfo = *AddressList;
64
65 IP6_COPY_ADDRESS (&EfiAddrInfo->Address, &IpSb->LinkLocalAddr);
66 EfiAddrInfo->PrefixLength = IP6_LINK_LOCAL_PREFIX_LENGTH;
67
68 EfiAddrInfo++;
69 Count = 1;
70
71 NET_LIST_FOR_EACH (Entry, &IpSb->DefaultInterface->AddressList) {
72 AddrInfo = NET_LIST_USER_STRUCT_S (Entry, IP6_ADDRESS_INFO, Link, IP6_ADDR_INFO_SIGNATURE);
73
74 IP6_COPY_ADDRESS (&EfiAddrInfo->Address, &AddrInfo->Address);
75 EfiAddrInfo->PrefixLength = AddrInfo->PrefixLength;
76
77 EfiAddrInfo++;
78 Count++;
79 }
80
81 ASSERT (Count == *AddressCount);
82
83 return EFI_SUCCESS;
84}
85
104 IN BOOLEAN Router,
105 IN UINT8 Scope,
106 OUT EFI_IPv6_ADDRESS *Ip6Addr
107 )
108{
109 if (Ip6Addr == NULL) {
110 return EFI_INVALID_PARAMETER;
111 }
112
113 if (!Router && (Scope == IP6_SITE_LOCAL_SCOPE)) {
114 return EFI_INVALID_PARAMETER;
115 }
116
117 ZeroMem (Ip6Addr, sizeof (EFI_IPv6_ADDRESS));
118 Ip6Addr->Addr[0] = 0xFF;
119 Ip6Addr->Addr[1] = Scope;
120
121 if (!Router) {
122 Ip6Addr->Addr[15] = 0x1;
123 } else {
124 Ip6Addr->Addr[15] = 0x2;
125 }
126
127 return EFI_SUCCESS;
128}
129
141UINT8 *
143 IN OUT IP6_SERVICE *IpSb
144 )
145{
146 UINT8 InterfaceId[8];
147 UINT8 Byte;
148 EFI_MAC_ADDRESS *MacAddr;
149 UINT32 AddrLen;
150
151 NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);
152
153 AddrLen = IpSb->SnpMode.HwAddressSize;
154
155 //
156 // Currently only IEEE 802 48-bit MACs are supported to create link local address.
157 //
158 if ((AddrLen != IP6_MAC_LEN) || (IpSb->InterfaceIdLen != IP6_IF_ID_LEN)) {
159 return NULL;
160 }
161
162 MacAddr = &IpSb->SnpMode.CurrentAddress;
163
164 //
165 // Convert MAC address to 64 bits interface ID according to Appendix A of RFC4291:
166 // 1. Insert 0xFFFE to the middle
167 // 2. Invert the universal/local bit - bit 6 in network order
168 //
169 CopyMem (InterfaceId, MacAddr, 3);
170 InterfaceId[3] = 0xFF;
171 InterfaceId[4] = 0xFE;
172 CopyMem (&InterfaceId[5], &MacAddr->Addr[3], 3);
173
174 Byte = (UINT8)(InterfaceId[0] & IP6_U_BIT);
175 if (Byte == IP6_U_BIT) {
176 InterfaceId[0] &= ~IP6_U_BIT;
177 } else {
178 InterfaceId[0] |= IP6_U_BIT;
179 }
180
181 //
182 // Return the interface ID.
183 //
184 return AllocateCopyPool (IpSb->InterfaceIdLen, InterfaceId);
185}
186
201 IN OUT IP6_SERVICE *IpSb
202 )
203{
204 EFI_IPv6_ADDRESS *Ip6Addr;
205 EFI_IP6_CONFIG_PROTOCOL *Ip6Config;
206 UINTN DataSize;
207 EFI_IP6_CONFIG_INTERFACE_ID InterfaceId;
208 EFI_STATUS Status;
209
210 NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);
211
212 if (IpSb->InterfaceId != NULL) {
213 FreePool (IpSb->InterfaceId);
214 }
215
216 //
217 // Get the interface id if it is manually configured.
218 //
219 Ip6Config = &IpSb->Ip6ConfigInstance.Ip6Config;
220 DataSize = sizeof (EFI_IP6_CONFIG_INTERFACE_ID);
221 ZeroMem (&InterfaceId, DataSize);
222
223 Status = Ip6Config->GetData (
224 Ip6Config,
226 &DataSize,
227 &InterfaceId
228 );
229 if (Status == EFI_NOT_FOUND) {
230 //
231 // Since the interface id is not configured, generate the interface id from
232 // MAC address.
233 //
234 IpSb->InterfaceId = Ip6CreateInterfaceID (IpSb);
235 if (IpSb->InterfaceId == NULL) {
236 return NULL;
237 }
238
239 CopyMem (&InterfaceId, IpSb->InterfaceId, IpSb->InterfaceIdLen);
240 //
241 // Record the interface id.
242 //
243 Status = Ip6Config->SetData (
244 Ip6Config,
246 DataSize,
247 &InterfaceId
248 );
249 if (EFI_ERROR (Status)) {
250 FreePool (IpSb->InterfaceId);
251 IpSb->InterfaceId = NULL;
252 return NULL;
253 }
254 } else if (!EFI_ERROR (Status)) {
255 IpSb->InterfaceId = AllocateCopyPool (DataSize, &InterfaceId);
256 if (IpSb->InterfaceId == NULL) {
257 return NULL;
258 }
259 } else {
260 return NULL;
261 }
262
263 //
264 // Append FE80::/64 to the left of IPv6 address then return.
265 //
266 Ip6Addr = AllocateZeroPool (sizeof (EFI_IPv6_ADDRESS));
267 if (Ip6Addr == NULL) {
268 FreePool (IpSb->InterfaceId);
269 IpSb->InterfaceId = NULL;
270 return NULL;
271 }
272
273 CopyMem (&Ip6Addr->Addr[8], IpSb->InterfaceId, IpSb->InterfaceIdLen);
274 Ip6Addr->Addr[1] = 0x80;
275 Ip6Addr->Addr[0] = 0xFE;
276
277 return Ip6Addr;
278}
279
290VOID
292 IN EFI_IPv6_ADDRESS *Ip6Addr,
293 OUT EFI_IPv6_ADDRESS *MulticastAddr
294 )
295{
296 ASSERT (Ip6Addr != NULL && MulticastAddr != NULL);
297
298 ZeroMem (MulticastAddr, sizeof (EFI_IPv6_ADDRESS));
299
300 MulticastAddr->Addr[0] = 0xFF;
301 MulticastAddr->Addr[1] = 0x02;
302 MulticastAddr->Addr[11] = 0x1;
303 MulticastAddr->Addr[12] = 0xFF;
304
305 CopyMem (&MulticastAddr->Addr[13], &Ip6Addr->Addr[13], 3);
306}
307
315VOID
317 IN OUT IP6_INTERFACE *IpIf,
318 IN IP6_ADDRESS_INFO *AddrInfo
319 )
320{
321 InsertHeadList (&IpIf->AddressList, &AddrInfo->Link);
322 IpIf->AddressCount++;
323}
324
336EFIAPI
338 IN LIST_ENTRY *Entry,
339 IN VOID *Context
340 )
341{
342 IP6_PROTOCOL *Instance;
343 EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
344 EFI_IPv6_ADDRESS *Address;
345
346 Instance = NET_LIST_USER_STRUCT_S (Entry, IP6_PROTOCOL, Link, IP6_PROTOCOL_SIGNATURE);
347 ServiceBinding = ((IP6_DESTROY_CHILD_BY_ADDR_CALLBACK_CONTEXT *)Context)->ServiceBinding;
348 Address = ((IP6_DESTROY_CHILD_BY_ADDR_CALLBACK_CONTEXT *)Context)->Address;
349
350 if ((Instance->State == IP6_STATE_CONFIGED) && EFI_IP6_EQUAL (&Instance->ConfigData.StationAddress, Address)) {
351 return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);
352 }
353
354 return EFI_SUCCESS;
355}
356
365VOID
367 IN OUT IP6_SERVICE *IpSb,
368 IN EFI_IPv6_ADDRESS *Address
369 )
370{
371 LIST_ENTRY *List;
373
374 NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);
375
376 List = &IpSb->Children;
377 Context.ServiceBinding = &IpSb->ServiceBinding;
378 Context.Address = Address;
380 List,
382 &Context,
383 NULL
384 );
385}
386
412 IN IP6_SERVICE *IpSb OPTIONAL,
413 IN OUT LIST_ENTRY *AddressList,
414 IN OUT UINT32 *AddressCount,
415 IN EFI_IPv6_ADDRESS *Prefix OPTIONAL,
416 IN UINT8 PrefixLength
417 )
418{
419 EFI_STATUS Status;
420 LIST_ENTRY *Entry;
421 LIST_ENTRY *Next;
422 IP6_ADDRESS_INFO *AddrInfo;
423 EFI_IPv6_ADDRESS SnMCastAddr;
424
425 if (IsListEmpty (AddressList) || (*AddressCount < 1) || (PrefixLength > IP6_PREFIX_MAX)) {
426 return EFI_INVALID_PARAMETER;
427 }
428
429 Status = EFI_NOT_FOUND;
430
431 NET_LIST_FOR_EACH_SAFE (Entry, Next, AddressList) {
432 AddrInfo = NET_LIST_USER_STRUCT_S (Entry, IP6_ADDRESS_INFO, Link, IP6_ADDR_INFO_SIGNATURE);
433
434 if ((Prefix == NULL) ||
435 ((PrefixLength == 128) && EFI_IP6_EQUAL (Prefix, &AddrInfo->Address)) ||
436 ((PrefixLength == AddrInfo->PrefixLength) && NetIp6IsNetEqual (Prefix, &AddrInfo->Address, PrefixLength))
437 )
438 {
439 if (IpSb != NULL) {
440 NET_CHECK_SIGNATURE (IpSb, IP6_SERVICE_SIGNATURE);
441 Ip6CreateSNMulticastAddr (&AddrInfo->Address, &SnMCastAddr);
442 Ip6LeaveGroup (IpSb, &SnMCastAddr);
443
444 //
445 // Destroy any instance who is using the dying address as the source address.
446 //
447 Ip6DestroyInstanceByAddress (IpSb, &AddrInfo->Address);
448 }
449
450 RemoveEntryList (Entry);
451 FreePool (AddrInfo);
452 (*AddressCount)--;
453
454 Status = EFI_SUCCESS;
455 }
456 }
457
458 return Status;
459}
460
470BOOLEAN
473 )
474{
476 BOOLEAN Flag;
477
478 Ip6CreateSNMulticastAddr (Ip6, &Sn);
479 Flag = FALSE;
480
481 if (CompareMem (Sn.Addr, Ip6->Addr, 13) == 0) {
482 Flag = TRUE;
483 }
484
485 return Flag;
486}
487
503BOOLEAN
505 IN IP6_SERVICE *IpSb,
506 IN EFI_IPv6_ADDRESS *Address,
507 OUT IP6_INTERFACE **Interface OPTIONAL,
508 OUT IP6_ADDRESS_INFO **AddressInfo OPTIONAL
509 )
510{
511 LIST_ENTRY *Entry;
512 LIST_ENTRY *Entry2;
513 IP6_INTERFACE *IpIf;
514 IP6_ADDRESS_INFO *TmpAddressInfo;
515
516 //
517 // Check link-local address first
518 //
519 if (IpSb->LinkLocalOk && EFI_IP6_EQUAL (&IpSb->LinkLocalAddr, Address)) {
520 if (Interface != NULL) {
521 *Interface = IpSb->DefaultInterface;
522 }
523
524 if (AddressInfo != NULL) {
525 *AddressInfo = NULL;
526 }
527
528 return TRUE;
529 }
530
531 NET_LIST_FOR_EACH (Entry, &IpSb->Interfaces) {
532 IpIf = NET_LIST_USER_STRUCT_S (Entry, IP6_INTERFACE, Link, IP6_INTERFACE_SIGNATURE);
533
534 NET_LIST_FOR_EACH (Entry2, &IpIf->AddressList) {
535 TmpAddressInfo = NET_LIST_USER_STRUCT_S (Entry2, IP6_ADDRESS_INFO, Link, IP6_ADDR_INFO_SIGNATURE);
536
537 if (EFI_IP6_EQUAL (&TmpAddressInfo->Address, Address)) {
538 if (Interface != NULL) {
539 *Interface = IpIf;
540 }
541
542 if (AddressInfo != NULL) {
543 *AddressInfo = TmpAddressInfo;
544 }
545
546 return TRUE;
547 }
548 }
549 }
550
551 return FALSE;
552}
553
564BOOLEAN
566 IN IP6_SERVICE *IpSb,
567 IN EFI_MAC_ADDRESS *LinkAddress
568 )
569{
570 UINT32 Index;
571
572 //
573 // TODO: might be updated later to be more acceptable.
574 //
575 for (Index = IpSb->SnpMode.HwAddressSize; Index < sizeof (EFI_MAC_ADDRESS); Index++) {
576 if (LinkAddress->Addr[Index] != 0) {
577 return FALSE;
578 }
579 }
580
581 return TRUE;
582}
583
592VOID
594 OUT EFI_IPv6_ADDRESS *Dest,
595 IN EFI_IPv6_ADDRESS *Src,
596 IN UINT8 PrefixLength
597 )
598{
599 UINT8 Byte;
600 UINT8 Bit;
601 UINT8 Mask;
602
603 ASSERT (Dest != NULL && Src != NULL);
604 ASSERT (PrefixLength <= IP6_PREFIX_MAX);
605
606 Byte = (UINT8)(PrefixLength / 8);
607 Bit = (UINT8)(PrefixLength % 8);
608
609 ZeroMem (Dest, sizeof (EFI_IPv6_ADDRESS));
610
611 CopyMem (Dest, Src, Byte);
612
613 if (Bit > 0) {
614 Mask = (UINT8)(0xFF << (8 - Bit));
615 ASSERT (Byte < 16);
616 Dest->Addr[Byte] = (UINT8)(Src->Addr[Byte] & Mask);
617 }
618}
619
637 IN EFI_IPv6_ADDRESS *Multicast,
639 )
640{
641 EFI_IP_ADDRESS EfiIp;
642
643 IP6_COPY_ADDRESS (&EfiIp.v6, Multicast);
644
645 return Mnp->McastIpToMac (Mnp, TRUE, &EfiIp, Mac);
646}
647
660 IN OUT EFI_IP6_HEADER *Head
661 )
662{
663 Head->FlowLabelL = NTOHS (Head->FlowLabelL);
664 Head->PayloadLength = NTOHS (Head->PayloadLength);
665
666 return Head;
667}
UINT64 UINTN
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
Definition: LinkedList.c:403
LIST_ENTRY *EFIAPI InsertHeadList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:218
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
Definition: LinkedList.c:590
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
VOID Ip6CreateSNMulticastAddr(IN EFI_IPv6_ADDRESS *Ip6Addr, OUT EFI_IPv6_ADDRESS *MulticastAddr)
Definition: Ip6Common.c:291
EFI_STATUS Ip6GetMulticastMac(IN EFI_MANAGED_NETWORK_PROTOCOL *Mnp, IN EFI_IPv6_ADDRESS *Multicast, OUT EFI_MAC_ADDRESS *Mac)
Definition: Ip6Common.c:635
EFI_STATUS Ip6SetToAllNodeMulticast(IN BOOLEAN Router, IN UINT8 Scope, OUT EFI_IPv6_ADDRESS *Ip6Addr)
Definition: Ip6Common.c:103
EFI_IP6_HEADER * Ip6NtohHead(IN OUT EFI_IP6_HEADER *Head)
Definition: Ip6Common.c:659
BOOLEAN Ip6IsSNMulticastAddr(IN EFI_IPv6_ADDRESS *Ip6)
Definition: Ip6Common.c:471
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)
Definition: Ip6Common.c:411
VOID Ip6AddAddr(IN OUT IP6_INTERFACE *IpIf, IN IP6_ADDRESS_INFO *AddrInfo)
Definition: Ip6Common.c:316
BOOLEAN Ip6IsOneOfSetAddress(IN IP6_SERVICE *IpSb, IN EFI_IPv6_ADDRESS *Address, OUT IP6_INTERFACE **Interface OPTIONAL, OUT IP6_ADDRESS_INFO **AddressInfo OPTIONAL)
Definition: Ip6Common.c:504
VOID Ip6DestroyInstanceByAddress(IN OUT IP6_SERVICE *IpSb, IN EFI_IPv6_ADDRESS *Address)
Definition: Ip6Common.c:366
UINT8 * Ip6CreateInterfaceID(IN OUT IP6_SERVICE *IpSb)
Definition: Ip6Common.c:142
BOOLEAN Ip6IsValidLinkAddress(IN IP6_SERVICE *IpSb, IN EFI_MAC_ADDRESS *LinkAddress)
Definition: Ip6Common.c:565
EFI_IPv6_ADDRESS * Ip6CreateLinkLocalAddr(IN OUT IP6_SERVICE *IpSb)
Definition: Ip6Common.c:200
EFI_STATUS Ip6BuildEfiAddressList(IN IP6_SERVICE *IpSb, OUT UINT32 *AddressCount, OUT EFI_IP6_ADDRESS_INFO **AddressList OPTIONAL)
Definition: Ip6Common.c:29
VOID Ip6CopyAddressByPrefix(OUT EFI_IPv6_ADDRESS *Dest, IN EFI_IPv6_ADDRESS *Src, IN UINT8 PrefixLength)
Definition: Ip6Common.c:593
EFI_STATUS EFIAPI Ip6DestroyChildEntryByAddr(IN LIST_ENTRY *Entry, IN VOID *Context)
Definition: Ip6Common.c:337
@ Ip6ConfigDataTypeAltInterfaceId
Definition: Ip6Config.h:42
EFI_STATUS Ip6LeaveGroup(IN IP6_SERVICE *IpSb, IN EFI_IPv6_ADDRESS *Address)
Definition: Ip6Mld.c:547
#define NULL
Definition: Base.h:319
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
BOOLEAN EFIAPI NetIp6IsNetEqual(EFI_IPv6_ADDRESS *Ip1, EFI_IPv6_ADDRESS *Ip2, UINT8 PrefixLength)
Definition: DxeNetLib.c:837
EFI_STATUS EFIAPI NetDestroyLinkList(IN LIST_ENTRY *List, IN NET_DESTROY_LINK_LIST_CALLBACK CallBack, IN VOID *Context OPTIONAL, OUT UINTN *ListLength OPTIONAL)
Definition: DxeNetLib.c:1236
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
UINT8 PrefixLength
The length of the prefix associated with the Address.
Definition: Ip6.h:222
EFI_IPv6_ADDRESS Address
The IPv6 address.
Definition: Ip6.h:221
EFI_IPv6_ADDRESS StationAddress
Definition: Ip6.h:188