TianoCore EDK2 master
Loading...
Searching...
No Matches
ArpMain.c
Go to the documentation of this file.
1
9#include "ArpImpl.h"
10
40EFIAPI
42 IN EFI_ARP_PROTOCOL *This,
43 IN EFI_ARP_CONFIG_DATA *ConfigData OPTIONAL
44 )
45{
46 EFI_STATUS Status;
47 ARP_INSTANCE_DATA *Instance;
48 EFI_TPL OldTpl;
49
50 if (This == NULL) {
51 return EFI_INVALID_PARAMETER;
52 }
53
54 if ((ConfigData != NULL) &&
55 ((ConfigData->SwAddressLength == 0) ||
56 (ConfigData->StationAddress == NULL) ||
57 (ConfigData->SwAddressType <= 1500)))
58 {
59 return EFI_INVALID_PARAMETER;
60 }
61
62 Instance = ARP_INSTANCE_DATA_FROM_THIS (This);
63
64 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
65
66 //
67 // Configure this instance, the ConfigData has already passed the basic checks.
68 //
69 Status = ArpConfigureInstance (Instance, ConfigData);
70
71 gBS->RestoreTPL (OldTpl);
72
73 return Status;
74}
75
122EFIAPI
124 IN EFI_ARP_PROTOCOL *This,
125 IN BOOLEAN DenyFlag,
126 IN VOID *TargetSwAddress OPTIONAL,
127 IN VOID *TargetHwAddress OPTIONAL,
128 IN UINT32 TimeoutValue,
129 IN BOOLEAN Overwrite
130 )
131{
132 EFI_STATUS Status;
133 ARP_INSTANCE_DATA *Instance;
134 ARP_SERVICE_DATA *ArpService;
135 ARP_CACHE_ENTRY *CacheEntry;
137 NET_ARP_ADDRESS MatchAddress[2];
138 EFI_TPL OldTpl;
139
140 if (This == NULL) {
141 return EFI_INVALID_PARAMETER;
142 }
143
144 if (((!DenyFlag) && ((TargetHwAddress == NULL) || (TargetSwAddress == NULL))) ||
145 (DenyFlag && (TargetHwAddress != NULL) && (TargetSwAddress != NULL)) ||
146 ((TargetHwAddress == NULL) && (TargetSwAddress == NULL)))
147 {
148 return EFI_INVALID_PARAMETER;
149 }
150
151 Instance = ARP_INSTANCE_DATA_FROM_THIS (This);
152
153 if (!Instance->Configured) {
154 return EFI_NOT_STARTED;
155 }
156
157 Status = EFI_SUCCESS;
158 ArpService = Instance->ArpService;
159 SnpMode = &Instance->ArpService->SnpMode;
160
161 //
162 // Fill the hardware address part in the MatchAddress.
163 //
164 MatchAddress[Hardware].Type = SnpMode->IfType;
165 MatchAddress[Hardware].Length = (UINT8)SnpMode->HwAddressSize;
166 MatchAddress[Hardware].AddressPtr = TargetHwAddress;
167
168 //
169 // Fill the software address part in the MatchAddress.
170 //
171 MatchAddress[Protocol].Type = Instance->ConfigData.SwAddressType;
172 MatchAddress[Protocol].Length = Instance->ConfigData.SwAddressLength;
173 MatchAddress[Protocol].AddressPtr = TargetSwAddress;
174
175 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
176
177 //
178 // See whether the entry to add exists. Check the DeniedCacheTable first.
179 //
180 CacheEntry = ArpFindDeniedCacheEntry (
181 ArpService,
182 &MatchAddress[Protocol],
183 &MatchAddress[Hardware]
184 );
185
186 if (CacheEntry == NULL) {
187 //
188 // Check the ResolvedCacheTable
189 //
190 CacheEntry = ArpFindNextCacheEntryInTable (
191 &ArpService->ResolvedCacheTable,
192 NULL,
193 ByBoth,
194 &MatchAddress[Protocol],
195 &MatchAddress[Hardware]
196 );
197 }
198
199 if ((CacheEntry != NULL) && !Overwrite) {
200 //
201 // The entry to add exists, if not Overwrite, deny this add request.
202 //
203 Status = EFI_ACCESS_DENIED;
204 goto UNLOCK_EXIT;
205 }
206
207 if ((CacheEntry == NULL) && (TargetSwAddress != NULL)) {
208 //
209 // Check whether there are pending requests matching the entry to be added.
210 //
211 CacheEntry = ArpFindNextCacheEntryInTable (
212 &ArpService->PendingRequestTable,
213 NULL,
214 ByProtoAddress,
215 &MatchAddress[Protocol],
216 NULL
217 );
218 }
219
220 if (CacheEntry != NULL) {
221 //
222 // Remove it from the Table.
223 //
224 RemoveEntryList (&CacheEntry->List);
225 } else {
226 //
227 // It's a new entry, allocate memory for the entry.
228 //
229 CacheEntry = ArpAllocCacheEntry (Instance);
230
231 if (CacheEntry == NULL) {
232 DEBUG ((DEBUG_ERROR, "ArpAdd: Failed to allocate pool for CacheEntry.\n"));
233 Status = EFI_OUT_OF_RESOURCES;
234 goto UNLOCK_EXIT;
235 }
236 }
237
238 //
239 // Overwrite these parameters.
240 //
241 CacheEntry->DefaultDecayTime = TimeoutValue;
242 CacheEntry->DecayTime = TimeoutValue;
243
244 //
245 // Fill in the addresses.
246 //
248 CacheEntry,
249 &MatchAddress[Hardware],
250 &MatchAddress[Protocol]
251 );
252
253 //
254 // Inform the user if there is any.
255 //
256 ArpAddressResolved (CacheEntry, NULL, NULL);
257
258 //
259 // Add this CacheEntry to the corresponding CacheTable.
260 //
261 if (DenyFlag) {
262 InsertHeadList (&ArpService->DeniedCacheTable, &CacheEntry->List);
263 } else {
264 InsertHeadList (&ArpService->ResolvedCacheTable, &CacheEntry->List);
265 }
266
267UNLOCK_EXIT:
268
269 gBS->RestoreTPL (OldTpl);
270
271 return Status;
272}
273
309EFIAPI
311 IN EFI_ARP_PROTOCOL *This,
312 IN BOOLEAN BySwAddress,
313 IN VOID *AddressBuffer OPTIONAL,
314 OUT UINT32 *EntryLength OPTIONAL,
315 OUT UINT32 *EntryCount OPTIONAL,
316 OUT EFI_ARP_FIND_DATA **Entries OPTIONAL,
317 IN BOOLEAN Refresh
318 )
319{
320 EFI_STATUS Status;
321 ARP_INSTANCE_DATA *Instance;
322 EFI_TPL OldTpl;
323
324 if ((This == NULL) ||
325 (!Refresh && (EntryCount == NULL) && (EntryLength == NULL)) ||
326 ((Entries != NULL) && ((EntryLength == NULL) || (EntryCount == NULL))))
327 {
328 return EFI_INVALID_PARAMETER;
329 }
330
331 Instance = ARP_INSTANCE_DATA_FROM_THIS (This);
332
333 if (!Instance->Configured) {
334 return EFI_NOT_STARTED;
335 }
336
337 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
338
339 //
340 // All the check passed, find the cache entries now.
341 //
342 Status = ArpFindCacheEntry (
343 Instance,
344 BySwAddress,
345 AddressBuffer,
346 EntryLength,
347 EntryCount,
348 Entries,
349 Refresh
350 );
351
352 gBS->RestoreTPL (OldTpl);
353
354 return Status;
355}
356
375EFIAPI
377 IN EFI_ARP_PROTOCOL *This,
378 IN BOOLEAN BySwAddress,
379 IN VOID *AddressBuffer OPTIONAL
380 )
381{
382 ARP_INSTANCE_DATA *Instance;
383 UINTN Count;
384 EFI_TPL OldTpl;
385
386 if (This == NULL) {
387 return EFI_INVALID_PARAMETER;
388 }
389
390 Instance = ARP_INSTANCE_DATA_FROM_THIS (This);
391
392 if (!Instance->Configured) {
393 return EFI_NOT_STARTED;
394 }
395
396 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
397
398 //
399 // Delete the specified cache entries.
400 //
401 Count = ArpDeleteCacheEntry (Instance, BySwAddress, AddressBuffer, TRUE);
402
403 gBS->RestoreTPL (OldTpl);
404
405 return (Count == 0) ? EFI_NOT_FOUND : EFI_SUCCESS;
406}
407
421EFIAPI
423 IN EFI_ARP_PROTOCOL *This
424 )
425{
426 ARP_INSTANCE_DATA *Instance;
427 UINTN Count;
428 EFI_TPL OldTpl;
429
430 if (This == NULL) {
431 return EFI_INVALID_PARAMETER;
432 }
433
434 Instance = ARP_INSTANCE_DATA_FROM_THIS (This);
435
436 if (!Instance->Configured) {
437 return EFI_NOT_STARTED;
438 }
439
440 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
441
442 //
443 // Delete the dynamic entries from the cache table.
444 //
445 Count = ArpDeleteCacheEntry (Instance, FALSE, NULL, FALSE);
446
447 gBS->RestoreTPL (OldTpl);
448
449 return (Count == 0) ? EFI_NOT_FOUND : EFI_SUCCESS;
450}
451
475EFIAPI
477 IN EFI_ARP_PROTOCOL *This,
478 IN VOID *TargetSwAddress OPTIONAL,
479 IN EFI_EVENT ResolvedEvent OPTIONAL,
480 OUT VOID *TargetHwAddress
481 )
482{
483 EFI_STATUS Status;
484 ARP_INSTANCE_DATA *Instance;
485 ARP_SERVICE_DATA *ArpService;
487 ARP_CACHE_ENTRY *CacheEntry;
488 NET_ARP_ADDRESS HardwareAddress;
489 NET_ARP_ADDRESS ProtocolAddress;
490 USER_REQUEST_CONTEXT *RequestContext;
491 EFI_TPL OldTpl;
492
493 if ((This == NULL) || (TargetHwAddress == NULL)) {
494 return EFI_INVALID_PARAMETER;
495 }
496
497 Instance = ARP_INSTANCE_DATA_FROM_THIS (This);
498
499 if (!Instance->Configured) {
500 return EFI_NOT_STARTED;
501 }
502
503 Status = EFI_SUCCESS;
504 ArpService = Instance->ArpService;
505 SnpMode = &ArpService->SnpMode;
506
507 if ((TargetSwAddress == NULL) ||
508 ((Instance->ConfigData.SwAddressType == IPV4_ETHER_PROTO_TYPE) &&
509 IP4_IS_LOCAL_BROADCAST (*((UINT32 *)TargetSwAddress))))
510 {
511 //
512 // Return the hardware broadcast address.
513 //
514 CopyMem (TargetHwAddress, &SnpMode->BroadcastAddress, SnpMode->HwAddressSize);
515
516 goto SIGNAL_USER;
517 }
518
519 if ((Instance->ConfigData.SwAddressType == IPV4_ETHER_PROTO_TYPE) &&
520 IP4_IS_MULTICAST (NTOHL (*((UINT32 *)TargetSwAddress))))
521 {
522 //
523 // If the software address is an IPv4 multicast address, invoke Mnp to
524 // resolve the address.
525 //
526 Status = ArpService->Mnp->McastIpToMac (
527 ArpService->Mnp,
528 FALSE,
529 TargetSwAddress,
530 TargetHwAddress
531 );
532 goto SIGNAL_USER;
533 }
534
535 HardwareAddress.Type = SnpMode->IfType;
536 HardwareAddress.Length = (UINT8)SnpMode->HwAddressSize;
537 HardwareAddress.AddressPtr = NULL;
538
539 ProtocolAddress.Type = Instance->ConfigData.SwAddressType;
540 ProtocolAddress.Length = Instance->ConfigData.SwAddressLength;
541 ProtocolAddress.AddressPtr = TargetSwAddress;
542
543 //
544 // Initialize the TargetHwAddress to a zero address.
545 //
546 ZeroMem (TargetHwAddress, SnpMode->HwAddressSize);
547
548 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
549
550 //
551 // Check whether the software address is in the denied table.
552 //
553 CacheEntry = ArpFindDeniedCacheEntry (ArpService, &ProtocolAddress, NULL);
554 if (CacheEntry != NULL) {
555 Status = EFI_ACCESS_DENIED;
556 goto UNLOCK_EXIT;
557 }
558
559 //
560 // Check whether the software address is already resolved.
561 //
562 CacheEntry = ArpFindNextCacheEntryInTable (
563 &ArpService->ResolvedCacheTable,
564 NULL,
565 ByProtoAddress,
566 &ProtocolAddress,
567 NULL
568 );
569 if (CacheEntry != NULL) {
570 //
571 // Resolved, copy the address into the user buffer.
572 //
573 CopyMem (
574 TargetHwAddress,
575 CacheEntry->Addresses[Hardware].AddressPtr,
576 CacheEntry->Addresses[Hardware].Length
577 );
578
579 goto UNLOCK_EXIT;
580 }
581
582 if (ResolvedEvent == NULL) {
583 Status = EFI_NOT_READY;
584 goto UNLOCK_EXIT;
585 }
586
587 //
588 // Create a request context for this arp request.
589 //
590 RequestContext = AllocatePool (sizeof (USER_REQUEST_CONTEXT));
591 if (RequestContext == NULL) {
592 DEBUG ((DEBUG_ERROR, "ArpRequest: Allocate memory for RequestContext failed.\n"));
593
594 Status = EFI_OUT_OF_RESOURCES;
595 goto UNLOCK_EXIT;
596 }
597
598 RequestContext->Instance = Instance;
599 RequestContext->UserRequestEvent = ResolvedEvent;
600 RequestContext->UserHwAddrBuffer = TargetHwAddress;
601 InitializeListHead (&RequestContext->List);
602
603 //
604 // Check whether there is a same request.
605 //
606 CacheEntry = ArpFindNextCacheEntryInTable (
607 &ArpService->PendingRequestTable,
608 NULL,
609 ByProtoAddress,
610 &ProtocolAddress,
611 NULL
612 );
613 if (CacheEntry != NULL) {
614 CacheEntry->NextRetryTime = Instance->ConfigData.RetryTimeOut;
615 CacheEntry->RetryCount = Instance->ConfigData.RetryCount;
616 } else {
617 //
618 // Allocate a cache entry for this request.
619 //
620 CacheEntry = ArpAllocCacheEntry (Instance);
621 if (CacheEntry == NULL) {
622 DEBUG ((DEBUG_ERROR, "ArpRequest: Allocate memory for CacheEntry failed.\n"));
623 FreePool (RequestContext);
624
625 Status = EFI_OUT_OF_RESOURCES;
626 goto UNLOCK_EXIT;
627 }
628
629 //
630 // Fill the software address.
631 //
632 ArpFillAddressInCacheEntry (CacheEntry, &HardwareAddress, &ProtocolAddress);
633
634 //
635 // Add this entry into the PendingRequestTable.
636 //
637 InsertTailList (&ArpService->PendingRequestTable, &CacheEntry->List);
638 }
639
640 //
641 // Link this request context into the cache entry.
642 //
643 InsertHeadList (&CacheEntry->UserRequestList, &RequestContext->List);
644
645 //
646 // Send out the ARP Request frame.
647 //
648 ArpSendFrame (Instance, CacheEntry, ARP_OPCODE_REQUEST);
649 Status = EFI_NOT_READY;
650
651UNLOCK_EXIT:
652
653 gBS->RestoreTPL (OldTpl);
654
655SIGNAL_USER:
656
657 if ((ResolvedEvent != NULL) && (Status == EFI_SUCCESS)) {
658 gBS->SignalEvent (ResolvedEvent);
659
660 //
661 // Dispatch the DPC queued by the NotifyFunction of ResolvedEvent.
662 //
663 DispatchDpc ();
664 }
665
666 return Status;
667}
668
697EFIAPI
699 IN EFI_ARP_PROTOCOL *This,
700 IN VOID *TargetSwAddress OPTIONAL,
701 IN EFI_EVENT ResolvedEvent OPTIONAL
702 )
703{
704 ARP_INSTANCE_DATA *Instance;
705 UINTN Count;
706 EFI_TPL OldTpl;
707
708 if ((This == NULL) ||
709 ((TargetSwAddress != NULL) && (ResolvedEvent == NULL)) ||
710 ((TargetSwAddress == NULL) && (ResolvedEvent != NULL)))
711 {
712 return EFI_INVALID_PARAMETER;
713 }
714
715 Instance = ARP_INSTANCE_DATA_FROM_THIS (This);
716
717 if (!Instance->Configured) {
718 return EFI_NOT_STARTED;
719 }
720
721 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
722
723 //
724 // Cancel the specified request.
725 //
726 Count = ArpCancelRequest (Instance, TargetSwAddress, ResolvedEvent);
727
728 //
729 // Dispatch the DPCs queued by the NotifyFunction of the events signaled
730 // by ArpCancelRequest.
731 //
732 DispatchDpc ();
733
734 gBS->RestoreTPL (OldTpl);
735
736 return (Count == 0) ? EFI_NOT_FOUND : EFI_SUCCESS;
737}
UINT64 UINTN
EFI_STATUS ArpConfigureInstance(IN ARP_INSTANCE_DATA *Instance, IN EFI_ARP_CONFIG_DATA *ConfigData OPTIONAL)
Definition: ArpImpl.c:906
VOID ArpSendFrame(IN ARP_INSTANCE_DATA *Instance, IN ARP_CACHE_ENTRY *CacheEntry, IN UINT16 ArpOpCode)
Definition: ArpImpl.c:1027
UINTN ArpDeleteCacheEntry(IN ARP_INSTANCE_DATA *Instance, IN BOOLEAN BySwAddress, IN UINT8 *AddressBuffer OPTIONAL, IN BOOLEAN Force)
Definition: ArpImpl.c:1326
ARP_CACHE_ENTRY * ArpFindNextCacheEntryInTable(IN LIST_ENTRY *CacheTable, IN LIST_ENTRY *StartEntry, IN FIND_OPTYPE FindOpType, IN NET_ARP_ADDRESS *ProtocolAddress OPTIONAL, IN NET_ARP_ADDRESS *HardwareAddress OPTIONAL)
Definition: ArpImpl.c:589
UINTN ArpAddressResolved(IN ARP_CACHE_ENTRY *CacheEntry, IN ARP_INSTANCE_DATA *Instance OPTIONAL, IN EFI_EVENT UserEvent OPTIONAL)
Definition: ArpImpl.c:783
EFI_STATUS ArpFindCacheEntry(IN ARP_INSTANCE_DATA *Instance, IN BOOLEAN BySwAddress, IN VOID *AddressBuffer OPTIONAL, OUT UINT32 *EntryLength OPTIONAL, OUT UINT32 *EntryCount OPTIONAL, OUT EFI_ARP_FIND_DATA **Entries OPTIONAL, IN BOOLEAN Refresh)
Definition: ArpImpl.c:1448
UINTN ArpCancelRequest(IN ARP_INSTANCE_DATA *Instance, IN VOID *TargetSwAddress OPTIONAL, IN EFI_EVENT UserEvent OPTIONAL)
Definition: ArpImpl.c:1378
ARP_CACHE_ENTRY * ArpAllocCacheEntry(IN ARP_INSTANCE_DATA *Instance)
Definition: ArpImpl.c:715
VOID ArpFillAddressInCacheEntry(IN ARP_CACHE_ENTRY *CacheEntry, IN NET_ARP_ADDRESS *HwAddr OPTIONAL, IN NET_ARP_ADDRESS *SwAddr OPTIONAL)
Definition: ArpImpl.c:845
ARP_CACHE_ENTRY * ArpFindDeniedCacheEntry(IN ARP_SERVICE_DATA *ArpService, IN NET_ARP_ADDRESS *ProtocolAddress OPTIONAL, IN NET_ARP_ADDRESS *HardwareAddress OPTIONAL)
Definition: ArpImpl.c:658
#define ARP_INSTANCE_DATA_FROM_THIS(a)
Definition: ArpImpl.h:98
EFI_STATUS EFIAPI ArpCancel(IN EFI_ARP_PROTOCOL *This, IN VOID *TargetSwAddress OPTIONAL, IN EFI_EVENT ResolvedEvent OPTIONAL)
Definition: ArpMain.c:698
EFI_STATUS EFIAPI ArpRequest(IN EFI_ARP_PROTOCOL *This, IN VOID *TargetSwAddress OPTIONAL, IN EFI_EVENT ResolvedEvent OPTIONAL, OUT VOID *TargetHwAddress)
Definition: ArpMain.c:476
EFI_STATUS EFIAPI ArpConfigure(IN EFI_ARP_PROTOCOL *This, IN EFI_ARP_CONFIG_DATA *ConfigData OPTIONAL)
Definition: ArpMain.c:41
EFI_STATUS EFIAPI ArpFind(IN EFI_ARP_PROTOCOL *This, IN BOOLEAN BySwAddress, IN VOID *AddressBuffer OPTIONAL, OUT UINT32 *EntryLength OPTIONAL, OUT UINT32 *EntryCount OPTIONAL, OUT EFI_ARP_FIND_DATA **Entries OPTIONAL, IN BOOLEAN Refresh)
Definition: ArpMain.c:310
EFI_STATUS EFIAPI ArpAdd(IN EFI_ARP_PROTOCOL *This, IN BOOLEAN DenyFlag, IN VOID *TargetSwAddress OPTIONAL, IN VOID *TargetHwAddress OPTIONAL, IN UINT32 TimeoutValue, IN BOOLEAN Overwrite)
Definition: ArpMain.c:123
EFI_STATUS EFIAPI ArpDelete(IN EFI_ARP_PROTOCOL *This, IN BOOLEAN BySwAddress, IN VOID *AddressBuffer OPTIONAL)
Definition: ArpMain.c:376
EFI_STATUS EFIAPI ArpFlush(IN EFI_ARP_PROTOCOL *This)
Definition: ArpMain.c:422
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
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
Definition: LinkedList.c:182
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
Definition: LinkedList.c:259
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_STATUS EFIAPI DispatchDpc(VOID)
Definition: DpcLib.c:86
VOID EFIAPI FreePool(IN VOID *Buffer)
#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
#define DEBUG(Expression)
Definition: DebugLib.h:434
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
UINTN EFI_TPL
Definition: UefiBaseType.h:41
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
UINT32 RetryCount
Definition: Arp.h:102
UINT32 RetryTimeOut
Definition: Arp.h:109
UINT16 SwAddressType
Definition: Arp.h:76
UINT8 SwAddressLength
Definition: Arp.h:81
EFI_MAC_ADDRESS BroadcastAddress